From 6540474ff527fdab39c315bbb04a28ab33683c9d Mon Sep 17 00:00:00 2001 From: Matysh Date: Fri, 28 Aug 2026 02:44:26 +0300 Subject: [PATCH] refactor: centralize i18n language registry Issue: #62 User-Visible: no --- CONTRIBUTING.md | 33 ++- .../houseplan/frontend/houseplan-card.js | 280 +++++++++--------- dist/houseplan-card.js | 280 +++++++++--------- docs/images/06-device-editor.png | Bin 297802 -> 297803 bytes docs/images/screenshots.json | 24 +- docs/specs/062-i18n-registry.md | 8 +- src/editor.ts | 7 +- src/i18n.ts | 38 ++- src/i18n/registry.ts | 88 ++++++ src/types.ts | 3 +- test/i18n.test.mjs | 118 +++++++- tsconfig.test.json | 2 +- 12 files changed, 549 insertions(+), 332 deletions(-) create mode 100644 src/i18n/registry.ts diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 54c224a6..4bb6a5f0 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -9,6 +9,35 @@ User-visible changes go into **both** changelogs in the same commit: `docs/CHANGELOG.md` (English) and `docs/CHANGELOG.ru.md` (Russian). Entries older than v1.42.0 exist only in the English file — no need to backfill them. +## Translations + +A shipped UI language has three matching parts: + +1. `src/i18n/.json` for the card; +2. `custom_components/houseplan/translations/.json` for the Home Assistant + integration; +3. one static entry (dictionary import, code and native label) in + `src/i18n/registry.ts`. + +Use the canonical Home Assistant/BCP 47 language tag as `` (for example, +`fr` or `pt-BR`) and use that exact spelling for both JSON filenames. Lookup is +case-insensitive and also accepts `_` from legacy locale sources. + +The registry drives language resolution, the visual-editor selector and parity +tests. The tests reject missing or extra locale files; frontend dictionaries +also fail on mismatched keys, empty values and changed placeholders. +Placeholders such as `{name}` and `{n}` are a contract: do not translate, add +or remove them. + +The current `subst()` helper does not implement plural rules. Phrase strings so +their grammar does not depend on the numeric value (for example, use a neutral +label followed by `{n}` rather than an English singular/plural pair). + +Adding a UI locale does not automatically create another full documentation +set; maintain the existing English and Russian documentation according to the +project's normal rules. Right-to-left layout is a separate product project, +because the plan canvas and editors cannot be mirrored by translations alone. + ## Where to ask Not sure whether something is a bug, or just want to discuss an idea before @@ -45,8 +74,8 @@ every push — locally they are skipped when `homeassistant` is not importable. - **Docs in the same commit**: CHANGELOG entry for user-visible changes; `docs/STATUS.md` for state changes; `docs/DEVELOPMENT.md` for new gotchas. -- Every UI string goes through `src/i18n/.json` (tests enforce en/ru key parity). - Adding a language = adding one JSON file + registering it in `src/i18n.ts`. +- Every UI string goes through `src/i18n/.json`; follow the + [Translations](#translations) flow for registry and backend parity. - The built card must be committed in sync: `cp dist/houseplan-card.js custom_components/houseplan/frontend/` (CI compares them byte-for-byte). - Tap actions have a security model (locks/alarms never toggle from the plan) — diff --git a/custom_components/houseplan/frontend/houseplan-card.js b/custom_components/houseplan/frontend/houseplan-card.js index 8b02af02..ebf4642f 100755 --- a/custom_components/houseplan/frontend/houseplan-card.js +++ b/custom_components/houseplan/frontend/houseplan-card.js @@ -1,4 +1,4 @@ -globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="30d20d6f6822065e2d5226b18abbb05d8d26bc9ddfff42a327dc483b2446800c";const e=globalThis,t=e.ShadowRoot&&(void 0===e.ShadyCSS||e.ShadyCSS.nativeShadow)&&"adoptedStyleSheets"in Document.prototype&&"replace"in CSSStyleSheet.prototype,i=Symbol(),s=new WeakMap;let n=class{constructor(e,t,s){if(this._$cssResult$=!0,s!==i)throw Error("CSSResult is not constructable. Use `unsafeCSS` or `css` instead.");this.cssText=e,this.t=t}get styleSheet(){let e=this.o;const i=this.t;if(t&&void 0===e){const t=void 0!==i&&1===i.length;t&&(e=s.get(i)),void 0===e&&((this.o=e=new CSSStyleSheet).replaceSync(this.cssText),t&&s.set(i,e))}return e}toString(){return this.cssText}};const o=(e,...t)=>{const s=1===e.length?e[0]:t.reduce((t,i,s)=>t+(e=>{if(!0===e._$cssResult$)return e.cssText;if("number"==typeof e)return e;throw Error("Value passed to 'css' function must be a 'css' function result: "+e+". Use 'unsafeCSS' to pass non-literal values, but take care to ensure page security.")})(i)+e[s+1],e[0]);return new n(s,e,i)},a=t?e=>e:e=>e instanceof CSSStyleSheet?(e=>{let t="";for(const i of e.cssRules)t+=i.cssText;return(e=>new n("string"==typeof e?e:e+"",void 0,i))(t)})(e):e,{is:r,defineProperty:l,getOwnPropertyDescriptor:c,getOwnPropertyNames:h,getOwnPropertySymbols:d,getPrototypeOf:p}=Object,u=globalThis,_=u.trustedTypes,m=_?_.emptyScript:"",g=u.reactiveElementPolyfillSupport,f=(e,t)=>e,v={toAttribute(e,t){switch(t){case Boolean:e=e?m:null;break;case Object:case Array:e=null==e?e:JSON.stringify(e)}return e},fromAttribute(e,t){let i=e;switch(t){case Boolean:i=null!==e;break;case Number:i=null===e?null:Number(e);break;case Object:case Array:try{i=JSON.parse(e)}catch(e){i=null}}return i}},b=(e,t)=>!r(e,t),y={attribute:!0,type:String,converter:v,reflect:!1,useDefault:!1,hasChanged:b};Symbol.metadata??=Symbol("metadata"),u.litPropertyMetadata??=new WeakMap;let w=class extends HTMLElement{static addInitializer(e){this._$Ei(),(this.l??=[]).push(e)}static get observedAttributes(){return this.finalize(),this._$Eh&&[...this._$Eh.keys()]}static createProperty(e,t=y){if(t.state&&(t.attribute=!1),this._$Ei(),this.prototype.hasOwnProperty(e)&&((t=Object.create(t)).wrapped=!0),this.elementProperties.set(e,t),!t.noAccessor){const i=Symbol(),s=this.getPropertyDescriptor(e,i,t);void 0!==s&&l(this.prototype,e,s)}}static getPropertyDescriptor(e,t,i){const{get:s,set:n}=c(this.prototype,e)??{get(){return this[t]},set(e){this[t]=e}};return{get:s,set(t){const o=s?.call(this);n?.call(this,t),this.requestUpdate(e,o,i)},configurable:!0,enumerable:!0}}static getPropertyOptions(e){return this.elementProperties.get(e)??y}static _$Ei(){if(this.hasOwnProperty(f("elementProperties")))return;const e=p(this);e.finalize(),void 0!==e.l&&(this.l=[...e.l]),this.elementProperties=new Map(e.elementProperties)}static finalize(){if(this.hasOwnProperty(f("finalized")))return;if(this.finalized=!0,this._$Ei(),this.hasOwnProperty(f("properties"))){const e=this.properties,t=[...h(e),...d(e)];for(const i of t)this.createProperty(i,e[i])}const e=this[Symbol.metadata];if(null!==e){const t=litPropertyMetadata.get(e);if(void 0!==t)for(const[e,i]of t)this.elementProperties.set(e,i)}this._$Eh=new Map;for(const[e,t]of this.elementProperties){const i=this._$Eu(e,t);void 0!==i&&this._$Eh.set(i,e)}this.elementStyles=this.finalizeStyles(this.styles)}static finalizeStyles(e){const t=[];if(Array.isArray(e)){const i=new Set(e.flat(1/0).reverse());for(const e of i)t.unshift(a(e))}else void 0!==e&&t.push(a(e));return t}static _$Eu(e,t){const i=t.attribute;return!1===i?void 0:"string"==typeof i?i:"string"==typeof e?e.toLowerCase():void 0}constructor(){super(),this._$Ep=void 0,this.isUpdatePending=!1,this.hasUpdated=!1,this._$Em=null,this._$Ev()}_$Ev(){this._$ES=new Promise(e=>this.enableUpdating=e),this._$AL=new Map,this._$E_(),this.requestUpdate(),this.constructor.l?.forEach(e=>e(this))}addController(e){(this._$EO??=new Set).add(e),void 0!==this.renderRoot&&this.isConnected&&e.hostConnected?.()}removeController(e){this._$EO?.delete(e)}_$E_(){const e=new Map,t=this.constructor.elementProperties;for(const i of t.keys())this.hasOwnProperty(i)&&(e.set(i,this[i]),delete this[i]);e.size>0&&(this._$Ep=e)}createRenderRoot(){const i=this.shadowRoot??this.attachShadow(this.constructor.shadowRootOptions);return((i,s)=>{if(t)i.adoptedStyleSheets=s.map(e=>e instanceof CSSStyleSheet?e:e.styleSheet);else for(const t of s){const s=document.createElement("style"),n=e.litNonce;void 0!==n&&s.setAttribute("nonce",n),s.textContent=t.cssText,i.appendChild(s)}})(i,this.constructor.elementStyles),i}connectedCallback(){this.renderRoot??=this.createRenderRoot(),this.enableUpdating(!0),this._$EO?.forEach(e=>e.hostConnected?.())}enableUpdating(e){}disconnectedCallback(){this._$EO?.forEach(e=>e.hostDisconnected?.())}attributeChangedCallback(e,t,i){this._$AK(e,i)}_$ET(e,t){const i=this.constructor.elementProperties.get(e),s=this.constructor._$Eu(e,i);if(void 0!==s&&!0===i.reflect){const n=(void 0!==i.converter?.toAttribute?i.converter:v).toAttribute(t,i.type);this._$Em=e,null==n?this.removeAttribute(s):this.setAttribute(s,n),this._$Em=null}}_$AK(e,t){const i=this.constructor,s=i._$Eh.get(e);if(void 0!==s&&this._$Em!==s){const e=i.getPropertyOptions(s),n="function"==typeof e.converter?{fromAttribute:e.converter}:void 0!==e.converter?.fromAttribute?e.converter:v;this._$Em=s;const o=n.fromAttribute(t,e.type);this[s]=o??this._$Ej?.get(s)??o,this._$Em=null}}requestUpdate(e,t,i,s=!1,n){if(void 0!==e){const o=this.constructor;if(!1===s&&(n=this[e]),i??=o.getPropertyOptions(e),!((i.hasChanged??b)(n,t)||i.useDefault&&i.reflect&&n===this._$Ej?.get(e)&&!this.hasAttribute(o._$Eu(e,i))))return;this.C(e,t,i)}!1===this.isUpdatePending&&(this._$ES=this._$EP())}C(e,t,{useDefault:i,reflect:s,wrapped:n},o){i&&!(this._$Ej??=new Map).has(e)&&(this._$Ej.set(e,o??t??this[e]),!0!==n||void 0!==o)||(this._$AL.has(e)||(this.hasUpdated||i||(t=void 0),this._$AL.set(e,t)),!0===s&&this._$Em!==e&&(this._$Eq??=new Set).add(e))}async _$EP(){this.isUpdatePending=!0;try{await this._$ES}catch(e){Promise.reject(e)}const e=this.scheduleUpdate();return null!=e&&await e,!this.isUpdatePending}scheduleUpdate(){return this.performUpdate()}performUpdate(){if(!this.isUpdatePending)return;if(!this.hasUpdated){if(this.renderRoot??=this.createRenderRoot(),this._$Ep){for(const[e,t]of this._$Ep)this[e]=t;this._$Ep=void 0}const e=this.constructor.elementProperties;if(e.size>0)for(const[t,i]of e){const{wrapped:e}=i,s=this[t];!0!==e||this._$AL.has(t)||void 0===s||this.C(t,void 0,i,s)}}let e=!1;const t=this._$AL;try{e=this.shouldUpdate(t),e?(this.willUpdate(t),this._$EO?.forEach(e=>e.hostUpdate?.()),this.update(t)):this._$EM()}catch(t){throw e=!1,this._$EM(),t}e&&this._$AE(t)}willUpdate(e){}_$AE(e){this._$EO?.forEach(e=>e.hostUpdated?.()),this.hasUpdated||(this.hasUpdated=!0,this.firstUpdated(e)),this.updated(e)}_$EM(){this._$AL=new Map,this.isUpdatePending=!1}get updateComplete(){return this.getUpdateComplete()}getUpdateComplete(){return this._$ES}shouldUpdate(e){return!0}update(e){this._$Eq&&=this._$Eq.forEach(e=>this._$ET(e,this[e])),this._$EM()}updated(e){}firstUpdated(e){}};w.elementStyles=[],w.shadowRootOptions={mode:"open"},w[f("elementProperties")]=new Map,w[f("finalized")]=new Map,g?.({ReactiveElement:w}),(u.reactiveElementVersions??=[]).push("2.1.2");const k=globalThis,x=e=>e,$=k.trustedTypes,S=$?$.createPolicy("lit-html",{createHTML:e=>e}):void 0,M="$lit$",C=`lit$${Math.random().toFixed(9).slice(2)}$`,D="?"+C,P=`<${D}>`,T=document,I=()=>T.createComment(""),R=e=>null===e||"object"!=typeof e&&"function"!=typeof e,A=Array.isArray,z="[ \t\n\f\r]",F=/<(?:(!--|\/[^a-zA-Z])|(\/?[a-zA-Z][^>\s]*)|(\/?$))/g,N=/-->/g,E=/>/g,O=RegExp(`>|${z}(?:([^\\s"'>=/]+)(${z}*=${z}*(?:[^ \t\n\f\r"'\`<>=]|("|')|))|$)`,"g"),H=/'/g,L=/"/g,B=/^(?:script|style|textarea|title)$/i,j=e=>(t,...i)=>({_$litType$:e,strings:t,values:i}),q=j(1),W=j(2),U=Symbol.for("lit-noChange"),G=Symbol.for("lit-nothing"),V=new WeakMap,K=T.createTreeWalker(T,129);function Y(e,t){if(!A(e)||!e.hasOwnProperty("raw"))throw Error("invalid template strings array");return void 0!==S?S.createHTML(t):t}const J=(e,t)=>{const i=e.length-1,s=[];let n,o=2===t?"":3===t?"":"",a=F;for(let t=0;t"===l[0]?(a=n??F,c=-1):void 0===l[1]?c=-2:(c=a.lastIndex-l[2].length,r=l[1],a=void 0===l[3]?O:'"'===l[3]?L:H):a===L||a===H?a=O:a===N||a===E?a=F:(a=O,n=void 0);const d=a===O&&e[t+1].startsWith("/>")?" ":"";o+=a===F?i+P:c>=0?(s.push(r),i.slice(0,c)+M+i.slice(c)+C+d):i+C+(-2===c?t:d)}return[Y(e,o+(e[i]||"")+(2===t?"":3===t?"":"")),s]};class X{constructor({strings:e,_$litType$:t},i){let s;this.parts=[];let n=0,o=0;const a=e.length-1,r=this.parts,[l,c]=J(e,t);if(this.el=X.createElement(l,i),K.currentNode=this.el.content,2===t||3===t){const e=this.el.content.firstChild;e.replaceWith(...e.childNodes)}for(;null!==(s=K.nextNode())&&r.length0){s.textContent=$?$.emptyScript:"";for(let i=0;iA(e)||"function"==typeof e?.[Symbol.iterator])(e)?this.k(e):this._(e)}O(e){return this._$AA.parentNode.insertBefore(e,this._$AB)}T(e){this._$AH!==e&&(this._$AR(),this._$AH=this.O(e))}_(e){this._$AH!==G&&R(this._$AH)?this._$AA.nextSibling.data=e:this.T(T.createTextNode(e)),this._$AH=e}$(e){const{values:t,_$litType$:i}=e,s="number"==typeof i?this._$AC(e):(void 0===i.el&&(i.el=X.createElement(Y(i.h,i.h[0]),this.options)),i);if(this._$AH?._$AD===s)this._$AH.p(t);else{const e=new Q(s,this),i=e.u(this.options);e.p(t),this.T(i),this._$AH=e}}_$AC(e){let t=V.get(e.strings);return void 0===t&&V.set(e.strings,t=new X(e)),t}k(e){A(this._$AH)||(this._$AH=[],this._$AR());const t=this._$AH;let i,s=0;for(const n of e)s===t.length?t.push(i=new ee(this.O(I()),this.O(I()),this,this.options)):i=t[s],i._$AI(n),s++;s2||""!==i[0]||""!==i[1]?(this._$AH=Array(i.length-1).fill(new String),this.strings=i):this._$AH=G}_$AI(e,t=this,i,s){const n=this.strings;let o=!1;if(void 0===n)e=Z(this,e,t,0),o=!R(e)||e!==this._$AH&&e!==U,o&&(this._$AH=e);else{const s=e;let a,r;for(e=n[0],a=0;a{const s=i?.renderBefore??t;let n=s._$litPart$;if(void 0===n){const e=i?.renderBefore??null;s._$litPart$=n=new ee(t.insertBefore(I(),e),e,void 0,i??{})}return n._$AI(e),n},ce=globalThis;let he=class extends w{constructor(){super(...arguments),this.renderOptions={host:this},this._$Do=void 0}createRenderRoot(){const e=super.createRenderRoot();return this.renderOptions.renderBefore??=e.firstChild,e}update(e){const t=this.render();this.hasUpdated||(this.renderOptions.isConnected=this.isConnected),super.update(e),this._$Do=le(t,this.renderRoot,this.renderOptions)}connectedCallback(){super.connectedCallback(),this._$Do?.setConnected(!0)}disconnectedCallback(){super.disconnectedCallback(),this._$Do?.setConnected(!1)}render(){return U}};he._$litElement$=!0,he.finalized=!0,ce.litElementHydrateSupport?.({LitElement:he});const de=ce.litElementPolyfillSupport;de?.({LitElement:he}),(ce.litElementVersions??=[]).push("4.2.2");const pe=2,ue=e=>(...t)=>({_$litDirective$:e,values:t});let _e=class{constructor(e){}get _$AU(){return this._$AM._$AU}_$AT(e,t,i){this._$Ct=e,this._$AM=t,this._$Ci=i}_$AS(e,t){return this.update(e,t)}update(e,t){return this.render(...t)}};const me={},ge=ue(class extends _e{constructor(){super(...arguments),this.ot=me}render(e,t){return t()}update(e,[t,i]){if(Array.isArray(t)){if(Array.isArray(this.ot)&&this.ot.length===t.length&&t.every((e,t)=>e===this.ot[t]))return U}else if(this.ot===t)return U;return this.ot=Array.isArray(t)?Array.from(t):t,this.render(t,i)}}),{I:fe}=ae,ve=e=>e,be=()=>document.createComment(""),ye=(e,t,i)=>{const s=e._$AA.parentNode,n=void 0===t?e._$AB:t._$AA;if(void 0===i){const t=s.insertBefore(be(),n),o=s.insertBefore(be(),n);i=new fe(t,o,e,e.options)}else{const t=i._$AB.nextSibling,o=i._$AM,a=o!==e;if(a){let t;i._$AQ?.(e),i._$AM=e,void 0!==i._$AP&&(t=e._$AU)!==o._$AU&&i._$AP(t)}if(t!==n||a){let e=i._$AA;for(;e!==t;){const t=ve(e).nextSibling;ve(s).insertBefore(e,n),e=t}}}return i},we=(e,t,i=e)=>(e._$AI(t,i),e),ke={},xe=(e,t=ke)=>e._$AH=t,$e=e=>{e._$AR(),e._$AA.remove()},Se=(e,t,i)=>{const s=new Map;for(let n=t;n<=i;n++)s.set(e[n],n);return s},Me=ue(class extends _e{constructor(e){if(super(e),e.type!==pe)throw Error("repeat() can only be used in text expressions")}dt(e,t,i){let s;void 0===i?i=t:void 0!==t&&(s=t);const n=[],o=[];let a=0;for(const t of e)n[a]=s?s(t,a):a,o[a]=i(t,a),a++;return{values:o,keys:n}}render(e,t,i){return this.dt(e,t,i).values}update(e,[t,i,s]){const n=(e=>e._$AH)(e),{values:o,keys:a}=this.dt(t,i,s);if(!Array.isArray(n))return this.ut=a,o;const r=this.ut??=[],l=[];let c,h,d=0,p=n.length-1,u=0,_=o.length-1;for(;d<=p&&u<=_;)if(null===n[d])d++;else if(null===n[p])p--;else if(r[d]===a[u])l[u]=we(n[d],o[u]),d++,u++;else if(r[p]===a[_])l[_]=we(n[p],o[_]),p--,_--;else if(r[d]===a[_])l[_]=we(n[d],o[_]),ye(e,l[_+1],n[d]),d++,_--;else if(r[p]===a[u])l[u]=we(n[p],o[u]),ye(e,n[d],n[p]),p--,u++;else if(void 0===c&&(c=Se(a,u,_),h=Se(r,d,p)),c.has(r[d]))if(c.has(r[p])){const t=h.get(a[u]),i=void 0!==t?n[t]:null;if(null===i){const t=ye(e,n[d]);we(t,o[u]),l[u]=t}else l[u]=we(i,o[u]),ye(e,n[d],i),n[t]=null;u++}else $e(n[p]),p--;else $e(n[d]),d++;for(;u<=_;){const t=ye(e,l[_+1]);we(t,o[u]),l[u++]=t}for(;d<=p;){const e=n[d++];null!==e&&$e(e)}return this.ut=a,xe(e,l),U}}),Ce=new WeakMap;let De=0;class Pe extends he{constructor(){super(...arguments),this.title="",this.icon="",this.wide=!1,this.dismissOnScrim=!1,this.hass=null,this._opener=null,this._focusRoot=null,this._useHaDialog=!1,this._closing=!1,this._overlays=[],this._titleId="hp-dialog-title-"+ ++De,this._focusInitial=()=>{const e=this._focusableElements(),t=e.find(e=>e.hasAttribute("autofocus"))||e[0]||(this._useHaDialog?null:this.renderRoot.querySelector(".close"))||this.renderRoot.querySelector(".surface")||this.renderRoot.querySelector("ha-dialog");t?.focus({preventScroll:!0})},this._requestClose=()=>{this._closing||(this._closing=!0,this.dispatchEvent(new CustomEvent("hp-close",{bubbles:!0,composed:!0})))},this._onKeyDown=e=>{if("Escape"===e.key){e.preventDefault(),e.stopImmediatePropagation(),this._pruneOverlays();const t=this._overlays[this._overlays.length-1];return t?void this._closeOverlay(t,"escape"):void this._requestClose()}if("Tab"!==e.key||this._useHaDialog)return;const t=this.renderRoot.querySelector(".close"),i=t?[t,...this._focusableElements()]:this._focusableElements();if(!i.length)return e.preventDefault(),void this.renderRoot.querySelector(".surface")?.focus({preventScroll:!0});const s=this._deepActiveElement(),n=i[0],o=i[i.length-1];!e.shiftKey||s!==n&&i.includes(s)?e.shiftKey||s!==o||(e.preventDefault(),n.focus()):(e.preventDefault(),o.focus())},this._onFallbackCancel=e=>{e.preventDefault(),this._requestClose()},this._onFallbackClick=e=>{this.dismissOnScrim&&e.target===e.currentTarget&&this._requestClose()}}connectedCallback(){super.connectedCallback(),this._opener=this._deepActiveElement();const e=this.getRootNode();this._focusRoot=e;const t=Ce.get(e)||{dialogs:new Set,opener:this._opener};t.dialogs.add(this),Ce.set(e,t),this._useHaDialog=!!customElements.get("ha-dialog"),this.addEventListener("keydown",this._onKeyDown,!0)}disconnectedCallback(){this.removeEventListener("keydown",this._onKeyDown,!0);const e=[...this._overlays];this._overlays=[];for(const t of e.reverse())t.close("disconnect");const t=this._focusRoot,i=this._opener;this._opener=null,this._focusRoot=null;const s=t?Ce.get(t):void 0;s?.dialogs.delete(this),super.disconnectedCallback(),t&&s&&requestAnimationFrame(()=>{const e=Ce.get(t);if(!e)return;if(!e.dialogs.size)return e.opener?.isConnected&&e.opener.focus({preventScroll:!0}),void Ce.delete(t);const s=i?.closest("hp-dialog");i?.isConnected&&s&&e.dialogs.has(s)&&i.focus({preventScroll:!0})})}firstUpdated(e){if(super.firstUpdated(e),!this._useHaDialog){const e=this.renderRoot.querySelector("dialog");e&&!e.open&&e.showModal()}queueMicrotask(()=>this._focusInitial())}_deepActiveElement(){let e=document.activeElement;for(;e?.shadowRoot?.activeElement;)e=e.shadowRoot.activeElement;return e&&e!==document.body?e:null}_focusableElements(){const e=["[autofocus]","a[href]","button:not([disabled])",'input:not([disabled]):not([type="hidden"])',"select:not([disabled])","textarea:not([disabled])",'[contenteditable="true"]','[tabindex]:not([tabindex="-1"])'].join(","),t=[],i=new Set,s=n=>{if(!i.has(n)){if(i.add(n),n instanceof HTMLElement){if(n.matches(e)&&t.push(n),n instanceof HTMLSlotElement){for(const e of n.assignedNodes({flatten:!0}))s(e);return}if(n.shadowRoot){for(const e of n.shadowRoot.childNodes)s(e);return}}for(const e of n.childNodes)s(e)}};for(const e of this.childNodes)s(e);const n=this.overlayPortal();return n&&s(n),t.filter(e=>{let t=e;for(;t;){const e=getComputedStyle(t);if(t.hidden||t.inert||"true"===t.getAttribute("aria-hidden")||"none"===e.display||"hidden"===e.visibility)return!1;if(t=t.assignedSlot||t.parentElement||(t.getRootNode()instanceof ShadowRoot?t.getRootNode().host:null),t===this)break}return!0})}_pruneOverlays(){this._overlays=this._overlays.filter(e=>e.owner.isConnected)}_closeOverlay(e,t){const i=this._overlays.findIndex(t=>t.token===e.token);i>=0&&this._overlays.splice(i,1),e.close(t)}registerOverlay(e){this._pruneOverlays();const t=this._overlays.find(t=>t.owner===e.owner);t&&this._overlays.splice(this._overlays.indexOf(t),1);const i=e.group||"transient";for(const e of[...this._overlays].reverse())e.group===i&&this._closeOverlay(e,"exclusive");const s={...e,group:i,token:Symbol("hp-overlay")};this._overlays.push(s);let n=!1;return()=>{if(n)return;n=!0;const e=this._overlays.findIndex(e=>e.token===s.token);e>=0&&this._overlays.splice(e,1)}}closeTransientOverlays(e="outside"){this._pruneOverlays();const t=[...this._overlays].filter(e=>"transient"===(e.group||"transient"));for(const i of t.reverse())this._closeOverlay(i,e);return t.length>0}overlayPortal(){return this.renderRoot.querySelector(".overlay-portal")}render(){const e=q` +globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="0241463fe185294ee49595feb903f78fd0c09aeee71e050d3d9f7f51a0b99e60";const e=globalThis,t=e.ShadowRoot&&(void 0===e.ShadyCSS||e.ShadyCSS.nativeShadow)&&"adoptedStyleSheets"in Document.prototype&&"replace"in CSSStyleSheet.prototype,i=Symbol(),s=new WeakMap;let n=class{constructor(e,t,s){if(this._$cssResult$=!0,s!==i)throw Error("CSSResult is not constructable. Use `unsafeCSS` or `css` instead.");this.cssText=e,this.t=t}get styleSheet(){let e=this.o;const i=this.t;if(t&&void 0===e){const t=void 0!==i&&1===i.length;t&&(e=s.get(i)),void 0===e&&((this.o=e=new CSSStyleSheet).replaceSync(this.cssText),t&&s.set(i,e))}return e}toString(){return this.cssText}};const o=(e,...t)=>{const s=1===e.length?e[0]:t.reduce((t,i,s)=>t+(e=>{if(!0===e._$cssResult$)return e.cssText;if("number"==typeof e)return e;throw Error("Value passed to 'css' function must be a 'css' function result: "+e+". Use 'unsafeCSS' to pass non-literal values, but take care to ensure page security.")})(i)+e[s+1],e[0]);return new n(s,e,i)},a=t?e=>e:e=>e instanceof CSSStyleSheet?(e=>{let t="";for(const i of e.cssRules)t+=i.cssText;return(e=>new n("string"==typeof e?e:e+"",void 0,i))(t)})(e):e,{is:r,defineProperty:l,getOwnPropertyDescriptor:c,getOwnPropertyNames:h,getOwnPropertySymbols:d,getPrototypeOf:p}=Object,u=globalThis,_=u.trustedTypes,m=_?_.emptyScript:"",g=u.reactiveElementPolyfillSupport,f=(e,t)=>e,v={toAttribute(e,t){switch(t){case Boolean:e=e?m:null;break;case Object:case Array:e=null==e?e:JSON.stringify(e)}return e},fromAttribute(e,t){let i=e;switch(t){case Boolean:i=null!==e;break;case Number:i=null===e?null:Number(e);break;case Object:case Array:try{i=JSON.parse(e)}catch(e){i=null}}return i}},b=(e,t)=>!r(e,t),y={attribute:!0,type:String,converter:v,reflect:!1,useDefault:!1,hasChanged:b};Symbol.metadata??=Symbol("metadata"),u.litPropertyMetadata??=new WeakMap;let w=class extends HTMLElement{static addInitializer(e){this._$Ei(),(this.l??=[]).push(e)}static get observedAttributes(){return this.finalize(),this._$Eh&&[...this._$Eh.keys()]}static createProperty(e,t=y){if(t.state&&(t.attribute=!1),this._$Ei(),this.prototype.hasOwnProperty(e)&&((t=Object.create(t)).wrapped=!0),this.elementProperties.set(e,t),!t.noAccessor){const i=Symbol(),s=this.getPropertyDescriptor(e,i,t);void 0!==s&&l(this.prototype,e,s)}}static getPropertyDescriptor(e,t,i){const{get:s,set:n}=c(this.prototype,e)??{get(){return this[t]},set(e){this[t]=e}};return{get:s,set(t){const o=s?.call(this);n?.call(this,t),this.requestUpdate(e,o,i)},configurable:!0,enumerable:!0}}static getPropertyOptions(e){return this.elementProperties.get(e)??y}static _$Ei(){if(this.hasOwnProperty(f("elementProperties")))return;const e=p(this);e.finalize(),void 0!==e.l&&(this.l=[...e.l]),this.elementProperties=new Map(e.elementProperties)}static finalize(){if(this.hasOwnProperty(f("finalized")))return;if(this.finalized=!0,this._$Ei(),this.hasOwnProperty(f("properties"))){const e=this.properties,t=[...h(e),...d(e)];for(const i of t)this.createProperty(i,e[i])}const e=this[Symbol.metadata];if(null!==e){const t=litPropertyMetadata.get(e);if(void 0!==t)for(const[e,i]of t)this.elementProperties.set(e,i)}this._$Eh=new Map;for(const[e,t]of this.elementProperties){const i=this._$Eu(e,t);void 0!==i&&this._$Eh.set(i,e)}this.elementStyles=this.finalizeStyles(this.styles)}static finalizeStyles(e){const t=[];if(Array.isArray(e)){const i=new Set(e.flat(1/0).reverse());for(const e of i)t.unshift(a(e))}else void 0!==e&&t.push(a(e));return t}static _$Eu(e,t){const i=t.attribute;return!1===i?void 0:"string"==typeof i?i:"string"==typeof e?e.toLowerCase():void 0}constructor(){super(),this._$Ep=void 0,this.isUpdatePending=!1,this.hasUpdated=!1,this._$Em=null,this._$Ev()}_$Ev(){this._$ES=new Promise(e=>this.enableUpdating=e),this._$AL=new Map,this._$E_(),this.requestUpdate(),this.constructor.l?.forEach(e=>e(this))}addController(e){(this._$EO??=new Set).add(e),void 0!==this.renderRoot&&this.isConnected&&e.hostConnected?.()}removeController(e){this._$EO?.delete(e)}_$E_(){const e=new Map,t=this.constructor.elementProperties;for(const i of t.keys())this.hasOwnProperty(i)&&(e.set(i,this[i]),delete this[i]);e.size>0&&(this._$Ep=e)}createRenderRoot(){const i=this.shadowRoot??this.attachShadow(this.constructor.shadowRootOptions);return((i,s)=>{if(t)i.adoptedStyleSheets=s.map(e=>e instanceof CSSStyleSheet?e:e.styleSheet);else for(const t of s){const s=document.createElement("style"),n=e.litNonce;void 0!==n&&s.setAttribute("nonce",n),s.textContent=t.cssText,i.appendChild(s)}})(i,this.constructor.elementStyles),i}connectedCallback(){this.renderRoot??=this.createRenderRoot(),this.enableUpdating(!0),this._$EO?.forEach(e=>e.hostConnected?.())}enableUpdating(e){}disconnectedCallback(){this._$EO?.forEach(e=>e.hostDisconnected?.())}attributeChangedCallback(e,t,i){this._$AK(e,i)}_$ET(e,t){const i=this.constructor.elementProperties.get(e),s=this.constructor._$Eu(e,i);if(void 0!==s&&!0===i.reflect){const n=(void 0!==i.converter?.toAttribute?i.converter:v).toAttribute(t,i.type);this._$Em=e,null==n?this.removeAttribute(s):this.setAttribute(s,n),this._$Em=null}}_$AK(e,t){const i=this.constructor,s=i._$Eh.get(e);if(void 0!==s&&this._$Em!==s){const e=i.getPropertyOptions(s),n="function"==typeof e.converter?{fromAttribute:e.converter}:void 0!==e.converter?.fromAttribute?e.converter:v;this._$Em=s;const o=n.fromAttribute(t,e.type);this[s]=o??this._$Ej?.get(s)??o,this._$Em=null}}requestUpdate(e,t,i,s=!1,n){if(void 0!==e){const o=this.constructor;if(!1===s&&(n=this[e]),i??=o.getPropertyOptions(e),!((i.hasChanged??b)(n,t)||i.useDefault&&i.reflect&&n===this._$Ej?.get(e)&&!this.hasAttribute(o._$Eu(e,i))))return;this.C(e,t,i)}!1===this.isUpdatePending&&(this._$ES=this._$EP())}C(e,t,{useDefault:i,reflect:s,wrapped:n},o){i&&!(this._$Ej??=new Map).has(e)&&(this._$Ej.set(e,o??t??this[e]),!0!==n||void 0!==o)||(this._$AL.has(e)||(this.hasUpdated||i||(t=void 0),this._$AL.set(e,t)),!0===s&&this._$Em!==e&&(this._$Eq??=new Set).add(e))}async _$EP(){this.isUpdatePending=!0;try{await this._$ES}catch(e){Promise.reject(e)}const e=this.scheduleUpdate();return null!=e&&await e,!this.isUpdatePending}scheduleUpdate(){return this.performUpdate()}performUpdate(){if(!this.isUpdatePending)return;if(!this.hasUpdated){if(this.renderRoot??=this.createRenderRoot(),this._$Ep){for(const[e,t]of this._$Ep)this[e]=t;this._$Ep=void 0}const e=this.constructor.elementProperties;if(e.size>0)for(const[t,i]of e){const{wrapped:e}=i,s=this[t];!0!==e||this._$AL.has(t)||void 0===s||this.C(t,void 0,i,s)}}let e=!1;const t=this._$AL;try{e=this.shouldUpdate(t),e?(this.willUpdate(t),this._$EO?.forEach(e=>e.hostUpdate?.()),this.update(t)):this._$EM()}catch(t){throw e=!1,this._$EM(),t}e&&this._$AE(t)}willUpdate(e){}_$AE(e){this._$EO?.forEach(e=>e.hostUpdated?.()),this.hasUpdated||(this.hasUpdated=!0,this.firstUpdated(e)),this.updated(e)}_$EM(){this._$AL=new Map,this.isUpdatePending=!1}get updateComplete(){return this.getUpdateComplete()}getUpdateComplete(){return this._$ES}shouldUpdate(e){return!0}update(e){this._$Eq&&=this._$Eq.forEach(e=>this._$ET(e,this[e])),this._$EM()}updated(e){}firstUpdated(e){}};w.elementStyles=[],w.shadowRootOptions={mode:"open"},w[f("elementProperties")]=new Map,w[f("finalized")]=new Map,g?.({ReactiveElement:w}),(u.reactiveElementVersions??=[]).push("2.1.2");const k=globalThis,x=e=>e,$=k.trustedTypes,S=$?$.createPolicy("lit-html",{createHTML:e=>e}):void 0,M="$lit$",C=`lit$${Math.random().toFixed(9).slice(2)}$`,D="?"+C,P=`<${D}>`,T=document,I=()=>T.createComment(""),R=e=>null===e||"object"!=typeof e&&"function"!=typeof e,A=Array.isArray,z="[ \t\n\f\r]",F=/<(?:(!--|\/[^a-zA-Z])|(\/?[a-zA-Z][^>\s]*)|(\/?$))/g,N=/-->/g,E=/>/g,O=RegExp(`>|${z}(?:([^\\s"'>=/]+)(${z}*=${z}*(?:[^ \t\n\f\r"'\`<>=]|("|')|))|$)`,"g"),H=/'/g,L=/"/g,B=/^(?:script|style|textarea|title)$/i,j=e=>(t,...i)=>({_$litType$:e,strings:t,values:i}),q=j(1),W=j(2),U=Symbol.for("lit-noChange"),G=Symbol.for("lit-nothing"),V=new WeakMap,K=T.createTreeWalker(T,129);function Y(e,t){if(!A(e)||!e.hasOwnProperty("raw"))throw Error("invalid template strings array");return void 0!==S?S.createHTML(t):t}const J=(e,t)=>{const i=e.length-1,s=[];let n,o=2===t?"":3===t?"":"",a=F;for(let t=0;t"===l[0]?(a=n??F,c=-1):void 0===l[1]?c=-2:(c=a.lastIndex-l[2].length,r=l[1],a=void 0===l[3]?O:'"'===l[3]?L:H):a===L||a===H?a=O:a===N||a===E?a=F:(a=O,n=void 0);const d=a===O&&e[t+1].startsWith("/>")?" ":"";o+=a===F?i+P:c>=0?(s.push(r),i.slice(0,c)+M+i.slice(c)+C+d):i+C+(-2===c?t:d)}return[Y(e,o+(e[i]||"")+(2===t?"":3===t?"":"")),s]};class X{constructor({strings:e,_$litType$:t},i){let s;this.parts=[];let n=0,o=0;const a=e.length-1,r=this.parts,[l,c]=J(e,t);if(this.el=X.createElement(l,i),K.currentNode=this.el.content,2===t||3===t){const e=this.el.content.firstChild;e.replaceWith(...e.childNodes)}for(;null!==(s=K.nextNode())&&r.length0){s.textContent=$?$.emptyScript:"";for(let i=0;iA(e)||"function"==typeof e?.[Symbol.iterator])(e)?this.k(e):this._(e)}O(e){return this._$AA.parentNode.insertBefore(e,this._$AB)}T(e){this._$AH!==e&&(this._$AR(),this._$AH=this.O(e))}_(e){this._$AH!==G&&R(this._$AH)?this._$AA.nextSibling.data=e:this.T(T.createTextNode(e)),this._$AH=e}$(e){const{values:t,_$litType$:i}=e,s="number"==typeof i?this._$AC(e):(void 0===i.el&&(i.el=X.createElement(Y(i.h,i.h[0]),this.options)),i);if(this._$AH?._$AD===s)this._$AH.p(t);else{const e=new Q(s,this),i=e.u(this.options);e.p(t),this.T(i),this._$AH=e}}_$AC(e){let t=V.get(e.strings);return void 0===t&&V.set(e.strings,t=new X(e)),t}k(e){A(this._$AH)||(this._$AH=[],this._$AR());const t=this._$AH;let i,s=0;for(const n of e)s===t.length?t.push(i=new ee(this.O(I()),this.O(I()),this,this.options)):i=t[s],i._$AI(n),s++;s2||""!==i[0]||""!==i[1]?(this._$AH=Array(i.length-1).fill(new String),this.strings=i):this._$AH=G}_$AI(e,t=this,i,s){const n=this.strings;let o=!1;if(void 0===n)e=Z(this,e,t,0),o=!R(e)||e!==this._$AH&&e!==U,o&&(this._$AH=e);else{const s=e;let a,r;for(e=n[0],a=0;a{const s=i?.renderBefore??t;let n=s._$litPart$;if(void 0===n){const e=i?.renderBefore??null;s._$litPart$=n=new ee(t.insertBefore(I(),e),e,void 0,i??{})}return n._$AI(e),n},ce=globalThis;let he=class extends w{constructor(){super(...arguments),this.renderOptions={host:this},this._$Do=void 0}createRenderRoot(){const e=super.createRenderRoot();return this.renderOptions.renderBefore??=e.firstChild,e}update(e){const t=this.render();this.hasUpdated||(this.renderOptions.isConnected=this.isConnected),super.update(e),this._$Do=le(t,this.renderRoot,this.renderOptions)}connectedCallback(){super.connectedCallback(),this._$Do?.setConnected(!0)}disconnectedCallback(){super.disconnectedCallback(),this._$Do?.setConnected(!1)}render(){return U}};he._$litElement$=!0,he.finalized=!0,ce.litElementHydrateSupport?.({LitElement:he});const de=ce.litElementPolyfillSupport;de?.({LitElement:he}),(ce.litElementVersions??=[]).push("4.2.2");const pe=2,ue=e=>(...t)=>({_$litDirective$:e,values:t});let _e=class{constructor(e){}get _$AU(){return this._$AM._$AU}_$AT(e,t,i){this._$Ct=e,this._$AM=t,this._$Ci=i}_$AS(e,t){return this.update(e,t)}update(e,t){return this.render(...t)}};const me={},ge=ue(class extends _e{constructor(){super(...arguments),this.ot=me}render(e,t){return t()}update(e,[t,i]){if(Array.isArray(t)){if(Array.isArray(this.ot)&&this.ot.length===t.length&&t.every((e,t)=>e===this.ot[t]))return U}else if(this.ot===t)return U;return this.ot=Array.isArray(t)?Array.from(t):t,this.render(t,i)}}),{I:fe}=ae,ve=e=>e,be=()=>document.createComment(""),ye=(e,t,i)=>{const s=e._$AA.parentNode,n=void 0===t?e._$AB:t._$AA;if(void 0===i){const t=s.insertBefore(be(),n),o=s.insertBefore(be(),n);i=new fe(t,o,e,e.options)}else{const t=i._$AB.nextSibling,o=i._$AM,a=o!==e;if(a){let t;i._$AQ?.(e),i._$AM=e,void 0!==i._$AP&&(t=e._$AU)!==o._$AU&&i._$AP(t)}if(t!==n||a){let e=i._$AA;for(;e!==t;){const t=ve(e).nextSibling;ve(s).insertBefore(e,n),e=t}}}return i},we=(e,t,i=e)=>(e._$AI(t,i),e),ke={},xe=(e,t=ke)=>e._$AH=t,$e=e=>{e._$AR(),e._$AA.remove()},Se=(e,t,i)=>{const s=new Map;for(let n=t;n<=i;n++)s.set(e[n],n);return s},Me=ue(class extends _e{constructor(e){if(super(e),e.type!==pe)throw Error("repeat() can only be used in text expressions")}dt(e,t,i){let s;void 0===i?i=t:void 0!==t&&(s=t);const n=[],o=[];let a=0;for(const t of e)n[a]=s?s(t,a):a,o[a]=i(t,a),a++;return{values:o,keys:n}}render(e,t,i){return this.dt(e,t,i).values}update(e,[t,i,s]){const n=(e=>e._$AH)(e),{values:o,keys:a}=this.dt(t,i,s);if(!Array.isArray(n))return this.ut=a,o;const r=this.ut??=[],l=[];let c,h,d=0,p=n.length-1,u=0,_=o.length-1;for(;d<=p&&u<=_;)if(null===n[d])d++;else if(null===n[p])p--;else if(r[d]===a[u])l[u]=we(n[d],o[u]),d++,u++;else if(r[p]===a[_])l[_]=we(n[p],o[_]),p--,_--;else if(r[d]===a[_])l[_]=we(n[d],o[_]),ye(e,l[_+1],n[d]),d++,_--;else if(r[p]===a[u])l[u]=we(n[p],o[u]),ye(e,n[d],n[p]),p--,u++;else if(void 0===c&&(c=Se(a,u,_),h=Se(r,d,p)),c.has(r[d]))if(c.has(r[p])){const t=h.get(a[u]),i=void 0!==t?n[t]:null;if(null===i){const t=ye(e,n[d]);we(t,o[u]),l[u]=t}else l[u]=we(i,o[u]),ye(e,n[d],i),n[t]=null;u++}else $e(n[p]),p--;else $e(n[d]),d++;for(;u<=_;){const t=ye(e,l[_+1]);we(t,o[u]),l[u++]=t}for(;d<=p;){const e=n[d++];null!==e&&$e(e)}return this.ut=a,xe(e,l),U}}),Ce=new WeakMap;let De=0;class Pe extends he{constructor(){super(...arguments),this.title="",this.icon="",this.wide=!1,this.dismissOnScrim=!1,this.hass=null,this._opener=null,this._focusRoot=null,this._useHaDialog=!1,this._closing=!1,this._overlays=[],this._titleId="hp-dialog-title-"+ ++De,this._focusInitial=()=>{const e=this._focusableElements(),t=e.find(e=>e.hasAttribute("autofocus"))||e[0]||(this._useHaDialog?null:this.renderRoot.querySelector(".close"))||this.renderRoot.querySelector(".surface")||this.renderRoot.querySelector("ha-dialog");t?.focus({preventScroll:!0})},this._requestClose=()=>{this._closing||(this._closing=!0,this.dispatchEvent(new CustomEvent("hp-close",{bubbles:!0,composed:!0})))},this._onKeyDown=e=>{if("Escape"===e.key){e.preventDefault(),e.stopImmediatePropagation(),this._pruneOverlays();const t=this._overlays[this._overlays.length-1];return t?void this._closeOverlay(t,"escape"):void this._requestClose()}if("Tab"!==e.key||this._useHaDialog)return;const t=this.renderRoot.querySelector(".close"),i=t?[t,...this._focusableElements()]:this._focusableElements();if(!i.length)return e.preventDefault(),void this.renderRoot.querySelector(".surface")?.focus({preventScroll:!0});const s=this._deepActiveElement(),n=i[0],o=i[i.length-1];!e.shiftKey||s!==n&&i.includes(s)?e.shiftKey||s!==o||(e.preventDefault(),n.focus()):(e.preventDefault(),o.focus())},this._onFallbackCancel=e=>{e.preventDefault(),this._requestClose()},this._onFallbackClick=e=>{this.dismissOnScrim&&e.target===e.currentTarget&&this._requestClose()}}connectedCallback(){super.connectedCallback(),this._opener=this._deepActiveElement();const e=this.getRootNode();this._focusRoot=e;const t=Ce.get(e)||{dialogs:new Set,opener:this._opener};t.dialogs.add(this),Ce.set(e,t),this._useHaDialog=!!customElements.get("ha-dialog"),this.addEventListener("keydown",this._onKeyDown,!0)}disconnectedCallback(){this.removeEventListener("keydown",this._onKeyDown,!0);const e=[...this._overlays];this._overlays=[];for(const t of e.reverse())t.close("disconnect");const t=this._focusRoot,i=this._opener;this._opener=null,this._focusRoot=null;const s=t?Ce.get(t):void 0;s?.dialogs.delete(this),super.disconnectedCallback(),t&&s&&requestAnimationFrame(()=>{const e=Ce.get(t);if(!e)return;if(!e.dialogs.size)return e.opener?.isConnected&&e.opener.focus({preventScroll:!0}),void Ce.delete(t);const s=i?.closest("hp-dialog");i?.isConnected&&s&&e.dialogs.has(s)&&i.focus({preventScroll:!0})})}firstUpdated(e){if(super.firstUpdated(e),!this._useHaDialog){const e=this.renderRoot.querySelector("dialog");e&&!e.open&&e.showModal()}queueMicrotask(()=>this._focusInitial())}_deepActiveElement(){let e=document.activeElement;for(;e?.shadowRoot?.activeElement;)e=e.shadowRoot.activeElement;return e&&e!==document.body?e:null}_focusableElements(){const e=["[autofocus]","a[href]","button:not([disabled])",'input:not([disabled]):not([type="hidden"])',"select:not([disabled])","textarea:not([disabled])",'[contenteditable="true"]','[tabindex]:not([tabindex="-1"])'].join(","),t=[],i=new Set,s=n=>{if(!i.has(n)){if(i.add(n),n instanceof HTMLElement){if(n.matches(e)&&t.push(n),n instanceof HTMLSlotElement){for(const e of n.assignedNodes({flatten:!0}))s(e);return}if(n.shadowRoot){for(const e of n.shadowRoot.childNodes)s(e);return}}for(const e of n.childNodes)s(e)}};for(const e of this.childNodes)s(e);const n=this.overlayPortal();return n&&s(n),t.filter(e=>{let t=e;for(;t;){const e=getComputedStyle(t);if(t.hidden||t.inert||"true"===t.getAttribute("aria-hidden")||"none"===e.display||"hidden"===e.visibility)return!1;if(t=t.assignedSlot||t.parentElement||(t.getRootNode()instanceof ShadowRoot?t.getRootNode().host:null),t===this)break}return!0})}_pruneOverlays(){this._overlays=this._overlays.filter(e=>e.owner.isConnected)}_closeOverlay(e,t){const i=this._overlays.findIndex(t=>t.token===e.token);i>=0&&this._overlays.splice(i,1),e.close(t)}registerOverlay(e){this._pruneOverlays();const t=this._overlays.find(t=>t.owner===e.owner);t&&this._overlays.splice(this._overlays.indexOf(t),1);const i=e.group||"transient";for(const e of[...this._overlays].reverse())e.group===i&&this._closeOverlay(e,"exclusive");const s={...e,group:i,token:Symbol("hp-overlay")};this._overlays.push(s);let n=!1;return()=>{if(n)return;n=!0;const e=this._overlays.findIndex(e=>e.token===s.token);e>=0&&this._overlays.splice(e,1)}}closeTransientOverlays(e="outside"){this._pruneOverlays();const t=[...this._overlays].filter(e=>"transient"===(e.group||"transient"));for(const i of t.reverse())this._closeOverlay(i,e);return t.length>0}overlayPortal(){return this.renderRoot.querySelector(".overlay-portal")}render(){const e=q` ${this.icon?q``:G} ${this.title} `;return this._useHaDialog?q`${e.lqiText}`:G} - `}function Yo(e,t,i){return{kind:"none",reason:"none",generation:e,expiresAt:null,color:t,diameterScale:i,animated:!1,reducedMotionIndicator:"none"}}const Jo=new WeakMap;function Xo(e){const t=function(e){const t=e?.connection||e;return!t||"object"!=typeof t&&"function"!=typeof t?null:t}(e);if(!t)return null;let i=Jo.get(t);return i||(i={revision:0,loaded:!1,configEntries:{},manifests:{},listeners:new Set,refs:0},Jo.set(t,i)),i}function Zo(e){e.revision++;for(const t of[...e.listeners])try{t()}catch{}}function Qo(e,t){const i=Xo(e);if(!i)return()=>{};i.refs++,i.listeners.add(t),async function(e,t){t.loading||"function"!=typeof e?.callWS?t.loading:t.loaded&&t.loadedAt&&Date.now()-t.loadedAt<3e5||(t.loading=(async()=>{const[i,s]=await Promise.allSettled([e.callWS({type:"config_entries/get"}),e.callWS({type:"manifest/list"})]);"fulfilled"===i.status&&Array.isArray(i.value)&&(t.configEntries=Object.fromEntries(i.value.filter(e=>"string"==typeof e?.entry_id).map(e=>[e.entry_id,e]))),"fulfilled"===s.status&&Array.isArray(s.value)&&(t.manifests=Object.fromEntries(s.value.filter(e=>"string"==typeof e?.domain).map(e=>[e.domain,e]))),t.loaded=!0,t.loadedAt=Date.now(),t.loading=void 0,Zo(t)})().catch(()=>{t.loaded=!0,t.loadedAt=Date.now(),t.loading=void 0,Zo(t)}),t.loading)}(e,i),async function(e,t){if(t.unsubscribe||t.subscribing)return t.subscribing;const i=e?.connection?.subscribeMessage;"function"==typeof i&&(t.subscribing=(async()=>{try{t.unsubscribe=await i.call(e.connection,e=>{const i=Array.isArray(e)?e:Array.isArray(e?.entries)?e.entries:e?[e]:[];let s=!1;const n={...t.configEntries};for(const e of i){const t=e?.entry||e?.data?.entry||("string"==typeof e?.entry_id?e:null),i=t?.entry_id;if("string"!=typeof i)continue;const o=e?.type||e?.action||e?.data?.action;"removed"===o||"remove"===o?delete n[i]:n[i]=t,s=!0}s&&(t.configEntries=n,Zo(t))},{type:"config_entries/subscribe"})}catch{}finally{0===t.refs&&(t.unsubscribe?.(),t.unsubscribe=void 0),t.subscribing=void 0}})(),t.subscribing)}(e,i);let s=!1;return()=>{s||(s=!0,i.listeners.delete(t),i.refs=Math.max(0,i.refs-1),i.refs||(i.unsubscribe?.(),i.unsubscribe=void 0))}}function ea(e){const t=Xo(e);return t?{revision:t.revision,loaded:t.loaded,configEntries:t.configEntries,manifests:t.manifests}:{revision:0,loaded:!1,configEntries:{},manifests:{}}}function ta(e,t,i=ea(e),s){const n=i.manifests[t];return function(e,t){if("function"!=typeof e?.localize)return"";try{const i=`component.${t}.title`,s=e.localize(i);return"string"==typeof s&&s!==i?s:""}catch{return""}}(e,t)||String(n?.name||"")||String(s||"")||t.replace(/_/g," ")}function ia(e,t,i,s,n){const o=String(t||"").trim();if(!o)return null;const a=n?s.configEntries[n]:null;return{domain:o,label:ta(e,o,s,a?.title),configEntryId:n,configEntryTitle:a?.title,confidence:i}}function sa(e){const t={"registry-owner":0,"entity-platform":1,"identifier-fallback":2},i=new Set;return e.filter(e=>!!e).sort((e,i)=>t[e.confidence]-t[i.confidence]||e.label.localeCompare(i.label)||e.domain.localeCompare(i.domain)).filter(e=>{const t=`${e.domain}\n${e.configEntryId||""}`;return!i.has(t)&&(i.add(t),!0)})}function na(e,t,i,s=ea(e)){const n=i.entities?.[t]||e?.entities?.[t];if(!n)return null;const o=n.config_entry_id||void 0,a=o?s.configEntries[o]?.domain:"";return ia(e,n.platform||a,"entity-platform",s,o)}var oa={"editor.context_actions":"Actions: {object}","editor.tool_options":"Tool options: {tool}","editor.palette":"Palette: {tool}","editor.open_group":"Tool group: {group}","editor.group_active":"{group} — active: {item}","editor.disabled_action":"{action} is unavailable: {reason}","color_picker.title":"Color picker","color_picker.hue":"Hue","color_picker.saturation":"Saturation","color_picker.value":"Brightness","color_picker.hex":"Hex color","color_picker.invalid_hex":"Enter a 3- or 6-digit hex color","btn.properties":"Properties","btn.keep_as_walls":"Keep as walls","btn.delete_room_keep_walls":"Delete room, keep walls","btn.delete_room_with_walls":"Delete room and walls","title.markup_select":"Select and edit walls, columns and saved outlines","title.markup_column":"Column: click a grid point to place a square column","markup.partition":"Partition","markup.column":"Column","markup.hint_column":"click a grid point to place a square column","history.draft_segment":"Add room-draft segment","history.draft_merge":"Join unfinished room outlines","history.draft_segment_delete":"Remove room-draft segment","history.partition_add":"Add partition","history.column_add":"Add column","history.physical_edit":"Change physical object","history.physical_delete":"Delete physical object","history.physical_move":"Move physical object","history.contour_to_partitions":"Convert contour to closed walls","history.wall_chain_finish":"Finish wall chain","history.wall_face_batch":"Create rooms from walls","toast.column_duplicate":"A column with the same centre and outer size already exists","confirm.delete_draft":"Delete the whole unfinished room contour?","confirm.delete_draft_segment":"Delete this draft segment? The remaining contour may split in two.","physical.partition_properties":"Partition properties","physical.column_properties":"Column properties","physical.draft_properties":"Draft segment properties","physical.shape":"Shape","physical.square":"Square","physical.circle":"Circle","physical.diameter":"Diameter","physical.side":"Side","physical.rotation":"Rotation angle","physical.length":"Length","physical.allowed_range":"Allowed: {min}–{max} {unit}","physical.delete_segment":"Delete segment","physical.delete_draft":"Delete entire outline","physical.column_size_title":"Outer side of the square column placed by the click (1–150 cm).","card.title":"House plan","count.devices":"{n} dev.","empty.no_spaces":"No spaces yet.","empty.add_first":"Add the first space and upload a floor plan.","empty.install":'Install the House Plan integration and add it in "Devices & services".',"btn.add_space":"Add space","btn.cancel":"Cancel","btn.save":"Save","btn.close":"Close","btn.delete":"Delete","btn.edit":"Edit","btn.open_in_ha":"Open in HA","btn.reset":"Reset","btn.attach":"Attach…","btn.upload":"Upload…","btn.replace":"Replace…","title.zoom_in":"Zoom in","title.zoom_out":"Zoom out","title.zoom_fit":"Fit all","title.add_device":"Add a device to the plan","title.show_all":"Show hidden and disabled devices as service markers (this tab only)","title.markup":"Room markup: grid, lines, outlines","title.configure_space":"Configure space","title.add_space":"Add space","title.markup_add":"Walls: draw a continuous chain; Shift locks to 45°. Changing tool or leaving the editor finishes it as independent walls","title.markup_merge":"Merge: click one room, then the neighbour it shares a wall with","title.markup_split":"Split a room: click the room, then two points on its walls","title.markup_delroom":"Delete room: click inside a room and confirm","title.need_plan":"Upload a floor-plan image","markup.add":"Walls","markup.merge":"Merge","markup.split":"Split","markup.resize":"Resize","title.markup_resize":"Resize rooms: drag an available horizontal or vertical wall handle","markup.hint_resize":"drag an available wall handle · the wall stops at the first unsafe position · Esc cancels · Ctrl+Z — undo","resize.disabled.diagonal":"This wall is angled; Resize supports only horizontal and vertical walls","resize.disabled.side-angle":"An adjoining wall is angled; Resize requires both adjoining walls to meet this wall at right angles","resize.disabled.duplicate-physical-wall":"A separate partition, unfinished outline, or column overlaps this wall; remove or move it before resizing","resize.disabled.partial-shared":"A neighbouring room uses only part of this wall, so it cannot be moved safely as one shared wall","resize.disabled.unequal-shared":"The neighbouring room uses different endpoints or wall length, so the walls cannot move together safely","resize.disabled.multiple-rooms":"Moving this wall would affect more than two rooms","resize.disabled.thickness-conflict":"The wall thickness cannot be preserved safely","resize.disabled.opening-conflict":"An opening on this wall cannot be moved safely","resize.disabled.invalid-geometry":"This wall cannot be resized without changing the plan structure","resize.limit_stopped":"Wall stopped: the next step would break a junction limit","resize.commit_failed":"Resize was cancelled because the final plan did not pass the geometry check","resize.preview_failed":"Resize stopped at the last safe position because the plan geometry could not be preserved","markup.opening":"Opening","markup.delete_room":"Delete room","history.undo":"Undo","history.redo":"Redo","history.undo_named":"Undo: {name} (Ctrl+Z)","history.redo_named":"Redo: {name} (Ctrl+Shift+Z / Ctrl+Y)","history.undo_empty":"Nothing to undo","history.redo_empty":"Nothing to redo","history.undone":"Undone: {name}","history.redone":"Redone: {name}","history.add_room":"Create room","history.split_room":"Split room","history.merge_rooms":"Merge rooms","history.resize_room":"Resize room","history.wall_thickness":"Change wall thickness","history.add_opening":"Add door or window opening","history.edit_opening":"Edit opening","history.move_opening":"Move opening","history.delete_opening":"Delete opening","history.delete_room":"Delete room","history.delete_room_keep_walls":"Delete room, keep walls","history.delete_room_with_walls":"Delete room and walls","history.decor_add":"Add decor object","history.decor_edit":"Edit decor object","history.decor_move":"Move decor object","history.decor_transform":"Transform decor object","history.decor_delete":"Delete decor object","history.backdrop_transform":"Transform plan backdrop","title.markup_opening":"Openings: click a wall to place, click an opening to edit","opening.new":"New opening","opening.edit":"Opening","opening.door":"Door","opening.window":"Window","opening.gate":"Gate","opening.passage":"Open passage","opening.passage_binding_warning":"Saving will remove the open/close sensor and lock.","opening.invalid_passage_fields":"The open passage on plan “{room}” has unsupported settings: {fields}.","opening.type_label":"Type","opening.length_label":"Length, cm","opening.contact_label":"Open/close sensor","opening.lock_label":"Lock","opening.none":"— none —","opening.search_ph":"Search: name or entity id…","opening.invert":"Invert open/closed","opening.flip_h":"Hinge on the other jamb","opening.flip_v":"Opens to the other side","opening.open":"Open","opening.closed":"Closed","opening.locked":"Locked","opening.unlocked":"Unlocked","opening.state_unknown":"unavailable","opening.no_entities":"No sensors bound — a static symbol on the plan.","toast.opening_no_wall":"Click next to a room wall or independent wall","opening.host_partition":"Independent wall","opening.partition_orphan":"The independent wall for this opening no longer exists","opening.partition_jamb_margin":"Leave at least {distance} between the opening and the end of the wall","opening.rebind_partition":"Attach to another independent wall","confirm.delete_partition_openings_title":"Delete wall and openings?","confirm.delete_partition_openings_body":"This wall contains {count} opening(s). They will be deleted together.","confirm.delete_partition_openings_item":"• {type}, {length}","markup.delete":"Delete","markup.hint_points":"points: {n} · Shift — 45° steps · Esc — finish chain · Ctrl+Z — undo a point · closing an area offers a room","markup.hint_start":"click a grid dot to start a wall chain","tip.lqi":"average zigbee signal:","tip.area":"area: {value}","info.device_header":"Device on the plan","info.model":"Model","info.state":"State","info.link":"Link","info.manuals":"Manuals","info.none":"No additional information","marker.new_device":"New device","marker.name_label":"Name (shown on the plan)","marker.name_ph":"Name","marker.binding_label":"Bind to an HA device","marker.binding_disabled":"disabled in Home Assistant","marker.virtual_option":"Virtual device (no binding)","marker.search_ph":"Search device / group…","marker.nothing_found":"nothing found","marker.room_label":"Room","marker.room_override":" (override placement)","marker.room_choose":"— select a room —","marker.room_auto":"— by device area (auto) —","marker.icon_label":"Icon","marker.icon_ph":"mdi:… (empty = auto)","marker.display_label":"Display","display.badge":"Icon + state","display.icon_ripple":"Icon + state and activity","display.static_icon":"Always static icon","marker.display_hint":"Icon + state changes the plate for work, open, alarm and unavailable states. Icon + state and activity additionally shows a short pulse for events and a continuous pulse for ongoing work, movement or presence. Value + state replaces the icon with one unambiguous HA value. A static icon never reacts to device states.","marker.display_hint_badge":"The icon and dynamic plate show device state without the ordinary activity pulse. Red alarms remain visible.","marker.display_hint_icon":"The icon and dynamic plate show device state without the ordinary activity pulse. Red alarms remain visible.","marker.display_hint_icon_ripple":"The icon, dynamic plate and pulse show a short pulse for events and a continuous pulse for work, motion or presence. Red alarms have separate priority.","marker.display_hint_value":"One unambiguous Home Assistant value replaces the icon while the plate continues to show state. Red alarms remain visible.","marker.display_hint_static_icon":"The theme-aware shell and icon always stay the same. State, activity, unavailability and alarms do not change the face.","marker.static_alarm_warning":"This device can report alarms. Static display hides the marker's visual alarm indication.","marker.preview.title":"Display preview","marker.preview.actual":"Now","marker.preview.example":"Example","marker.preview.integration":"Provided by","marker.preview.source":"Display source","marker.preview.current_state":"Current state","marker.preview.result":"On the plan","marker.preview.details":"Source details","marker.preview.select_source":"Choose a Home Assistant device or entity to see its actual display.","marker.preview.unknown_provider":"Unknown integration","marker.preview.virtual_provider":"House Plan · virtual device","marker.preview.no_source":"No active source","marker.preview.no_state":"No current state","marker.preview.mixed_states":"Several different states","marker.preview.multiple_sources":"{n} sources","marker.preview.more_sources":"+{n} more","marker.preview.scaled":"The preview is scaled to {n}% to fit. The saved size is unchanged.","marker.preview.demo_activity":"Show activity example","marker.preview.demo_notice":"Temporary activity example; the actual device state is unchanged.","marker.preview.demo_short":"Show short activity","marker.preview.demo_continuous":"Show continuous activity","marker.preview.stop_continuous":"Stop continuous activity","marker.preview.demo_short_notice":"Short activity example; the actual device state is unchanged.","marker.preview.demo_continuous_notice":"Continuous activity example; the actual device state is unchanged.","marker.preview.demo_already_visible":"The current state already shows a real activity or alarm effect.","marker.preview.reduced_motion":"System reduced-motion is enabled, so ordinary activity is shown as a dot.","marker.preview.reason.neutral":"Neutral dark plate","marker.preview.reason.working":"Yellow plate: the device is working now","marker.preview.reason.working_activity":"Yellow plate and activity effect: the device is working now","marker.preview.reason.open":"Orange plate: physically open or unlocked","marker.preview.reason.cover_icon_state":"Neutral plate; the cover entity controls the displayed state and icon","marker.preview.reason.presence":"Activity effect while presence is detected","marker.preview.reason.event":"Short activity effect after a detected event","marker.preview.reason.transition":"Activity effect while the device is moving or changing state","marker.preview.reason.media_neutral":"Media devices stay on a neutral dark plate while available","marker.preview.reason.unavailable":"Subdued neutral plate: unavailable or off","marker.preview.reason.alarm":"Red alarm plate; alarm indication is always shown","marker.preview.reason.live_states_disabled":"Live-state styling is disabled for this card","marker.preview.reason.value_no_state":"No usable state value; the icon is shown instead","marker.preview.reason.value_ambiguous_sources":"Several possible value sources; the icon is shown instead","marker.preview.reason.value_non_scalar":"The source did not return a simple value; the icon is shown instead","marker.preview.reason.value_virtual":"A virtual device has no Home Assistant value; the icon is shown instead","marker.preview.reason.vacuum_live_plan_only":"Live vacuum position and trail are available only on the full plan","marker.preview.reason.hidden_design_preview":"The device is hidden on the plan; this design preview remains visible","marker.preview.reason.composite_power_source":"State comes from the device Power entity; auxiliary switches are ignored","marker.preview.reason.activity_display_disabled":"The selected display mode does not show ordinary activity effects","marker.preview.reason.ha_disabled":"The Home Assistant binding is disabled and will be hidden on the plan","marker.preview.reason.orphaned":"The saved Home Assistant binding can no longer be found","marker.preview.reason.static_icon":"Static mode: device state does not change the icon","marker.activity_color":"Activity pulse color","marker.ripple_size":"Activity pulse size","marker.activity_alarm_note":"Color and size affect ordinary activity only and do not change red alarms.","marker.pulse_a11y_alarm":"Alarm","marker.pulse_a11y_event":"Recent event","marker.pulse_a11y_presence":"Presence detected","marker.pulse_a11y_transition":"Changing state","marker.pulse_a11y_running":"Working","marker.state_a11y_neutral":"Default state","marker.state_a11y_working":"Working","marker.state_a11y_open":"Open","marker.state_a11y_locked":"Locked","marker.state_a11y_unlocked":"Unlocked","marker.state_a11y_alarm":"Alarm","marker.state_a11y_unavailable":"Unavailable","marker.lqi_a11y_low":"LQI {value}, low signal","marker.lqi_a11y_mid":"LQI {value}, medium signal","marker.lqi_a11y_high":"LQI {value}, high signal","marker.size_label":"Icon size / rotation","marker.angle_label":"Rotate","marker.model_label":"Model","marker.model_ph":"e.g. Aqara T&H","marker.link_label":"Link","marker.desc_label":"Description","marker.desc_ph":"Notes, specs…","marker.manuals_label":"Manuals (PDF etc.)","marker.sub_device":"device","marker.sub_z2m_group":" · Z2M group","marker.sub_group":"group","marker.sub_helper":"helper","space.new":"New space","space.header":"Space","space.title_label":"Title","space.title_ph":"e.g. Garage","space.plan_label":"Floor plan (background)","space.no_plan":"no plan image","space.plan_alt":"plan","room.new":"New room","room.name_label":"Display name","room.name_ph":"e.g. Terrace","room.area_label":"Home Assistant area (unassigned)","room.no_area_option":"— no area —","room.default_name":"Room","device.unnamed":"unnamed","device.light_group":"light group","device.fallback":"device","device.virtual":"virtual device","confirm.delete_room":'Delete room "{name}"?',"confirm.delete_room_title":'Delete room "{name}"?',"confirm.delete_room_body":"Choose whether the room's exclusive physical walls should remain. Walls shared with another room are always kept.","confirm.merge_rooms":'Merge rooms "{a}" and "{b}"?',"confirm.remove_marker":'Delete "{name}" from the plan? The device will disappear completely and stop contributing to plan data. You can add it again later.',"confirm.erase_decor":"Erase the {kind} object? You can undo this action from the editor history.","confirm.delete_space":'Delete space "{title}" with all its rooms and markup?',"space.delete_blocked":"This space is still used by {n} device(s). Move them to another space or delete them first.","toast.pos_save_failed":"Failed to save position: {err}","toast.no_entity":"The device has no suitable entity","toast.ha_disabled_action":"A Home Assistant object that is disabled cannot be used on the plan.","toast.ha_disabled_show_device":"A device disabled in Home Assistant cannot be shown on the plan. Enable it in Home Assistant first.","toast.ha_disabled_show_entity":"An entity disabled in Home Assistant cannot be shown on the plan. Enable it in Home Assistant first.","toast.ha_disabled_add":"A disabled Home Assistant object cannot be added to the plan. Enable it in Home Assistant first.","toast.ha_binding_unverified":"The object status could not be verified through the Home Assistant registry. Display and actions are temporarily unavailable.","toast.markup_needs_server":"Markup is available after the config is moved to the server","toast.space_order_changed":"Order changed. If any card pins its floor by number, check those panels.","toast.conflict":"Config was changed in another window — data refreshed, repeat your last action","toast.cfg_save_failed":"Failed to save config: {err}","toast.room_overlap":"The outline overlaps room “{name}” — rooms must not overlap","toast.contour_min_edges":"Draw at least two edges before closing the outline","toast.contour_cannot_close":"The outline cannot close because it is degenerate or intersects itself","toast.merge_not_adjacent":"Only rooms that share a wall can be merged","toast.rooms_merged":"Rooms merged into “{name}”","toast.split_pick_wall":"Start the cut on the room’s wall","toast.split_bad_cut":"The cut must run wall to wall inside the room, without crossing walls or itself","merge.header":"Merge rooms","merge.hint":"The merged room keeps one name and one area. The other area is released — its devices leave the plan until another room claims it.","merge.keep":"Keep","merge.no_area":"no area","room.split_header":"New room from the split","toast.room_saved":"Room saved ({n}). Devices added: {added}. Outline the next one or exit markup.","toast.room_saved_no_area":"Room saved ({n}, no area). Outline the next one or exit markup.","toast.marker_needs_server":"Device editing is available after the config is moved to the server","toast.virtual_name_required":"Enter a name for the virtual device","toast.marker_saved":"Device saved","toast.marker_removed":"Device deleted from the plan","toast.integration_missing":"The House Plan integration is not installed — management unavailable","toast.plan_formats":"Supported formats: SVG, PNG, JPG, WebP","toast.plan_required":"Upload a floor plan — it is required","toast.space_added_onboard":"Space added. Outline the rooms: click grid dots and close the contour.","toast.space_added":"Space added","toast.space_saved":"Space saved","toast.space_deleted":"Space deleted","toast.delete_failed":"Delete failed: {err}","toast.error":"Error: {err}","toast.toggle_target_unavailable":"Target “{name}” is unavailable — no action was performed","toast.toggle_targets_unavailable":"Targets are unavailable: {names}. No action was performed","toast.file_failed":'File "{name}" was not uploaded: {err}',"toast.files_attached":"Files attached: {n}","err.unknown":"unknown error","err.code":"code {code}","err.too_large":"file larger than {mb} MB","err.bad_ext":"unsupported type (PDF/image expected)","err.unauthorized":"administrator rights required","editor.title":"Title","editor.default_floor":"Initial space","editor.default_floor_missing":"Initial space “{id}” no longer exists. Choose another space.","editor.floor":"Fixed space","editor.floor_none":"— not fixed —","editor.floor_index":"YAML index {index} (preserved)","fixed_floor.loading":"Loading the fixed space…","fixed_floor.invalid_title":"The fixed space is unavailable","fixed_floor.invalid_body":"Check floor in the card configuration. The configured value is: {value}","editor.icon_size":"Icon size, % of plan width","editor.show_temperature":"Show temperature","editor.live_states":"Live states (on/off, open…)","editor.show_signal":"Show zigbee signal (LQI)","editor.language":"Interface language","editor.lang_auto":"Auto (HA profile)","editor.lang_en":"English","editor.lang_ru":"Русский","title.icon_rules":"Icon rules: which MDI icon devices get by name","rules.title":"Icon rules","rules.hint":"Rules are checked top-down against “device name + model” (case-insensitive regex); the first match wins. When nothing matches, the entity device class decides, then the generic chip icon.","rules.pattern_ph":"regex, e.g. plug|socket","rules.icon_ph":"mdi:power-socket-de","rules.add":"Add rule","rules.reset":"Reset to defaults","rules.test_ph":"Try a device name…","rules.invalid":"invalid regex","rules.saved":"Icon rules saved","btn.up":"Up","btn.down":"Down","tap.info":"Device card","tap.more_info":"HA more-info dialog","tap.toggle":"Toggle state","marker.tap_label":"Tap action for this device","tap.toggle_note":"The resolved state is shown below. Secure devices are never toggled from the plan.","import.title":"Create spaces from HA floors","import.hint":"Your Home Assistant already knows these floors. Pick the ones to turn into plan spaces — you will upload a floor-plan image for each one next. Rooms are then outlined by hand on the plan.","import.start":"Create {n} space(s)","import.manual":"Start from scratch","import.progress":"Floor {i} of {n}","import.done":"Spaces created. Outline the rooms: click grid dots and close the contour.","btn.skip":"Skip","space.scale_label":"Scale (grid cell size)","space.scale_unit":"cm per cell","space.scale_unit_imperial":"in per cell","space.display_section":"Display","space.show_borders":"Always show room borders","space.zero_wall_style":"Zero-thickness walls","space.zero_wall_dashed":"Dashed","space.zero_wall_solid":"Solid","space.zero_wall_help":"Dashed walls let light through. Solid walls block light even at zero thickness.","space.show_names":"Show room names (drag to move)","space.room_color":"Border & name color","space.opacity":"Opacity","space.fill_label":"Room fill","fill.none":"None","fill.lqi":"Zigbee signal","fill.light":"Lights","fill.custom":"Custom color","space.custom_fill":"Fill color","space.source_file":"I have a floor-plan image","space.source_draw":"No image — I'll outline rooms by hand","space.orientation":"Canvas","orient.landscape":"Landscape","orient.portrait":"Portrait","orient.square":"Square","fill.temp":"Temperature","space.temp_min":"Comfort from","space.temp_max":"to","tip.temp_avg":"average temperature:","tip.hum_avg":"average humidity:","space_card.button":"Open the space plan","space_card.not_found":"Space “{id}” not found","space_card.loading":"Loading…","continuity.restore_plan":"Restoring floor plan…","continuity.restore_connection":"Restoring device connection…","continuity.retry":"Try again","editor.space":"Space","editor.show_button":"Show button","editor.button_label":"Button label","editor.button_target":"Target dashboard path","marker.sub_entity":"entity","title.general_settings":"General settings","gs.title":"General settings","gs.hint":"Fill colors apply to every space; each color has its own opacity. Which fill mode a space uses is set in that space's dialog.","gs.light_group":"Fill: lights","gs.light_on":"Lights on","gs.light_off":"All lights off","gs.temp_group":"Fill: temperature","gs.temp_cold":"Cold","gs.temp_ok":"Comfortable","gs.temp_hot":"Hot","gs.lqi_group":"Fill: zigbee signal","gs.lqi_low":"Weak signal","gs.lqi_high":"Strong signal","gs.reset":"Reset to defaults","gs.saved":"General settings saved","space.show_lqi":"Show zigbee signal (LQI) next to devices","space.hide_decor":"Hide the decorative layer","space.hide_decor_tip":"Lines, shapes, labels and furniture stay where they are — visible in the backdrop editor, not on the plan.","space.hide_openings":"Hide openings","space.hide_openings_tip":"Door, window and gate symbols are not drawn, but the openings keep working: light passes through, the sun comes in at a window, contact sensors still open them. The plan editor always shows them.","gs.light_none":"No light sources","mode.plan":"Plan editor","mode.devices":"Device editor","display.value":"Value + state","marker.subarea":"no area, manual","device.new":"New device — open its editor to dismiss","opening.unlock_action":"Unlock","opening.lock_action":"Lock","opening.lock_pending":"Working…","title.close_editor":"Close editor (back to view)","devbar.add":"Add","devbar.show_all":"Hidden and disabled","devbar.rules":"Icon rules","device_inbox.button":"Devices","device_inbox.title":"Devices on the plan","device_inbox.search":"Search devices, entities and integrations…","device_inbox.add_virtual":"Add virtual device","device_inbox.tab_on_plan":"On plan","device_inbox.tab_available":"Available","device_inbox.tab_hidden":"Hidden","device_inbox.tab_readd":"Available again","device_inbox.only_new":"New only","device_inbox.show_entities":"Show entities","device_inbox.show_hidden":"Show hidden on plan","device_inbox.new":"New","device_inbox.find":"Find on plan","device_inbox.edit":"Edit","device_inbox.hide":"Hide","device_inbox.show":"Show","device_inbox.add":"Add","device_inbox.readd":"Add again","device_inbox.hide_available":"Hide from list","device_inbox.show_more":"Show more","device_inbox.more_actions":"More actions","device_inbox.find_hidden_hint":"Enable “Show hidden on plan” first","device_inbox.show_disabled":"Activate this binding in Home Assistant before showing it","device_inbox.empty_on_plan":"No matching devices are on the plan yet.","device_inbox.empty_available":"No devices are available to add.","device_inbox.empty_hidden":"There are no hidden devices.","device_inbox.empty_readd":"No removed devices are available to add again.","device_inbox.reason_visible_auto":"Discovered automatically","device_inbox.reason_visible_explicit":"Added explicitly","device_inbox.reason_manual_hidden":"Hidden by user","device_inbox.reason_automatic_hidden":"Hidden automatically","device_inbox.reason_service_entry":"Service-only registry entry","device_inbox.reason_excluded_integration":"Integration excluded by device filters","device_inbox.reason_excluded_domain":"Non-spatial entity type","device_inbox.reason_grouped_light":"Represented by a room light group","device_inbox.reason_represented_by_parent":"Represented by its parent device","device_inbox.reason_removed":"Previously removed from the plan","device_inbox.reason_available":"Available to add to the plan","device_inbox.reason_no_bound_room":"HA area is not linked to a plan room","device_inbox.status_ha_disabled":"Disabled in Home Assistant","device_inbox.status_orphaned":"Binding is no longer present in Home Assistant","device_inbox.status_unverified":"Home Assistant registry is temporarily unavailable","device_inbox.saved":"Device list updated","space.roomcard_section":"Room card shows:","space.label_temp":"Temperature","space.label_hum":"Humidity","space.label_lqi":"Average Zigbee signal","space.label_light":"Lights on/off","roomcard.light_on":"On","roomcard.light_off":"Off","roomcard.light_partial":"{on} of {total}","toast.split_pick_inside":"Intermediate cut points must be inside the room","mode.decor":"Background editor","decor.select":"Select","decor.line":"Line","decor.rect":"Rectangle","decor.ellipse":"Oval","decor.text":"Text","decor.erase":"Erase","decor.erase_confirm_title":"Erase object?","decor.color":"Color","decor.width":"Line width","decor.line_style":"Line style","decor.line_style_solid":"Solid","decor.line_style_dashed":"Dashed","decor.fill":"Fill","decor.fill_color":"Fill color","decor.length":"Length","decor.size":"Size","decor.angle":"Rotation angle, °","decor.text_size":"Text size","decor.backdrop_properties":"Plan backdrop properties","decor.text_title":"Text label","decor.object_title":"Edit {kind}","decor.text_label":"Text","decor.live_group":"Insert HA variable","decor.live_entity":"Entity","decor.live_entity_ph":"choose an entity","decor.live_attr":"Value","decor.live_attr_ph":"choose state or attribute","decor.live_state":"State","decor.backdrop":"Backdrop image","decor.backdrop_hint":"Drag to move; pull a corner to resize; use the top handle to rotate. Shift changes proportions or frees the angle.","decor.backdrop_reset":"Reset the picture","decor.backdrop_reset_done":"The picture is back at its original place and size","marker.icon_auto":"Auto: {icon} (by icon rules; pick one to override)","marker.icon_pin_auto":"Pin","mode.plan_tip":"Plan editor — the geometry of the home: draw and split/merge rooms, bind them to HA areas, place doors, windows and gates, move room cards, set the scale","mode.devices_tip":"Device editor — everything about icons: drag to position, click to edit binding/icon/display, add virtual devices, icon rules","mode.decor_tip":"Background editor — purely visual decor under the plan: lines, rectangles, ovals and text labels that never react to clicks","space.glow_enabled":"Light-source glow","gs.glow_group":"Light-source glow","gs.glow_base":"House darkness","gs.glow_light":"Default light color / intensity","gs.wall_group":"Walls","gs.wall_fill":"Wall fill","gs.glow_radius":"Glow radius","gs.unit_m":"m","gs.unit_ft":"ft","marker.controls_label":"Controls other light sources","marker.controls_hint":"With tap action “Toggle”, a click flips every source added here. The marker’s own bound entity is controlled directly and cannot be added; use the switch below to classify it as a light.","marker.controls_filter":"Search lights and switches…","info.controls":"Controls","marker.glow_radius_label":"Glow radius","marker.glow_radius.help":"Sets the glow radius in metres or feet; an empty value uses the radius from general settings.","marker.glow_radius.help.aria":"Help: glow radius","markup.wallthick":"Thickness","markup.select":"Select","title.markup_wallthick":"Thickness — click a wall to set its thickness from 0 to 100 cm.","markup.hint_wallthick":"click a wall · Esc closes without applying","wallthick.field":"Thickness","wallthick.unit_cm":"cm","wallthick.unit_in":"in","wallthick.apply_room":"Apply to all walls of this room","markup.draw_wall_title":"Thickness of each new wall segment (0–100 cm). Shared walls keep the existing value.","room.queue_progress":"Room {current} of {total}","toast.wall_rooms_saved":"Created rooms: {n}","toast.wall_chain_saved":"Wall chain saved","toast.wallthick_pick":"Click a wall","toast.wallthick_set":"Wall thickness set","toast.wallthick_cleared":"Wall thickness removed","toast.physical_range":"Enter a value from {min} to {max} {unit}","toast.zero_wall_opening_conflict":"Remove the opening on this wall segment first.","toast.zero_wall_ambiguous":"The wall segment is ambiguous. Simplify or adjust the junction.","toast.zero_wall_migration_blocked":"The space was not converted: {reason}. No data was changed.","toast.physical_angle":"Enter a rotation angle from 0° up to, but not including, 90°","toast.physical_limit":"The space has reached the limit for this type of geometry","toast.geometry_unsafe":"Change canceled: wall geometry could not be built safely.","junction.limit_angle":"The angle between walls is too sharp: {actual}°, minimum {limit}°.","junction.limit_valence":"Too many walls meet in one node: {actual}, maximum {limit}.","junction.limit_length":"The wall segment is too short: {actual} cm, minimum {limit} cm.","junction.limit_distance":"Walls and nodes are too close: {actual} cm, minimum {limit} cm.","junction.limit_clearance":"No room interior is left: {actual} cm², minimum {limit} cm².","toast.wall_model_migration_blocked":"The wall model could not be updated: {reason}. The plan was not changed. Run “Optimize plans”; if the error repeats, fix the conflicting wall geometry.","toast.wall_model_client_outdated":"Update the card and reload the page before editing the plan.","wall_model.reason.invalid-room":"invalid room contour","wall_model.reason.zero-length":"zero-length wall segment","wall_model.reason.third-owner":"wall shared by more than two rooms","wall_model.reason.duplicate-id":"conflicting wall identifiers","wall_model.reason.thickness-conflict":"conflicting wall thickness values","wall_model.reason.opening-host":"opening cannot be assigned to one wall","toast.delete_room_pick":"Click inside the room you want to delete","toast.plan_snap_ambiguous":"Zoom in to choose the wall node","toast.wall_repair_ambiguous":"The room outline has more than one possible connection. Zoom in and connect it explicitly.","toast.wall_repair_too_large":"The gap is larger than 2 cm. Connect the walls before creating the room.","toast.wall_repair_changed":"The wall geometry changed. Try creating the room again.","toast.opening_on_zero_wall":"Openings cannot sit on a zero-thickness wall","marker.from_ha_option":"Pick from the HA list","marker.show_entities":"Show entities","marker.show_entities_tip":"Adds not only devices to the list, but all their entities too","marker.pick_ph":"Choose a device…","room.open_area":"Open the HA area","view.volumetric":"Volumetric view","view.flat":"Flat view","kiosk.title":"This screen's sizes","kiosk.hint":"Stored on this device only — every wall tablet or TV can have its own comfortable sizes.","kiosk.icon_scale":"Device icon size","kiosk.font_scale":"Room card text size","editor.kiosk":"Wall device (kiosk) mode","editor.cycle":"Auto-switch spaces every N seconds (kiosk, 0 = off)","room.settings_title":"Room settings","room.settings_section":"Room settings (override the space)","room.fill_label":"Fill in THIS room","fill.inherit":"As the space","room.custom_fill_space":"Space color","room.custom_fill_own":"Room color","room.temp_src_label":"Temperature source","room.hum_src_label":"Humidity source","room.src_average":"Average over the room's sensors (default)","room.src_pick":"A specific HA device or entity","room.src_ph":"Choose a source…","toast.room_updated":"Room updated","space.card_font":"Room-card font size (whole space)","room.sizes_section":"Font sizes","room.name_scale":"Room name size","room.label_scale":"Metrics size","preview.room_name":"Living room","toast.cfg_reload_failed":"Could not reload the plan from the server: {err}","room.settings_short":"Room settings","room.unnamed":"Unnamed room","marker.use_climate_temp":"Include the device temperature in the room","marker.use_climate_temp_tip":"Adds an air conditioner or thermostat current_temperature to the room average. Configure the external value badge separately below.","marker.value_badge_title":"Value badge","marker.value_badge.help":"Shows one selected value next to the icon. It does not affect room metrics, light, Glow or the tap action.","marker.value_badge.help.aria":"Help: device value badge","marker.value_badge_enabled":"Show a value badge","marker.value_badge_source":"Value","marker.value_badge_source.help":"Choose a specific state, supported attribute, or derived value of this device.","marker.value_badge_source.help.aria":"Help: value badge source","marker.value_badge_position":"Position","marker.value_badge_position.help":"The chosen side stays fixed and does not flip automatically at a plan edge.","marker.value_badge_position.help.aria":"Help: value badge position","marker.value_badge_right":"Right","marker.value_badge_bottom":"Below","marker.value_badge_left":"Left","marker.value_badge_top":"Above","marker.value_badge_empty":"This device has no available values","marker.value_badge_static":"A static icon does not show live values. The setting is preserved.","marker.value_badge_missing":"Source unavailable","marker.value_badge_missing_hint":"The saved source is currently unavailable. Keep it, disable the badge, or choose another value.","marker.value_badge_duplicate":"The same value is already shown inside the icon.","marker.value_badge_state":"State · {name}","marker.value_badge_marker_state":"Light-source state · {name}","marker.value_badge_lqi":"Average Zigbee signal quality","marker.value_badge_attr_current_temperature":"Current temperature · {name}","marker.value_badge_attr_temperature":"Target temperature · {name}","marker.value_badge_attr_current_humidity":"Current humidity · {name}","marker.value_badge_attr_humidity":"Humidity · {name}","marker.value_badge_attr_current_position":"Position · {name}","marker.value_badge_attr_percentage":"Speed · {name}","marker.value_badge_attr_brightness":"Brightness · {name}","marker.value_badge_attr_volume_level":"Volume · {name}","marker.value_badge_attr_battery_level":"Battery · {name}","marker.value_badge_attr_fan_speed":"Fan speed · {name}","marker.light_role_label":"Is this device a light source?","marker.light_role.help":"Controls whether this marker itself is a spatial light source. Linked lights above remain independent room-light controls.","marker.light_role.help.aria":"Help: whether this device is a light source","marker.light_role_auto_yes":"Auto (light source)","marker.light_role_auto_no":"Auto (not a light source)","marker.light_role_always":"Always a light source","marker.light_role_never":"Never a light source","marker.light_entity_label":"Leading light entity","marker.light_entity.help":"For a composite device, choose the entity whose state, colour and brightness represent this plan source. The automatic fallback remains compatible with older plans.","marker.light_entity.help.aria":"Help: leading light entity","marker.light_entity_auto":"Automatic ({entity})","marker.light_entity_none":"no controllable entity","marker.light_entity_missing":"The saved entity {entity} is unavailable. House Plan temporarily uses {fallback}; the saved choice will be restored if it returns.","marker.toggle_entity_label":"Entity to toggle","marker.toggle_entity.help":"For a composite device, choose the exact own light or switch operated by a tap. Automatic keeps the previous target rules and is independent from the leading light entity.","marker.toggle_entity.help.aria":"Help: entity to toggle","marker.toggle_entity_auto":"Automatic ({entity})","marker.toggle_entity_none":"no own controllable entity","marker.toggle_entity_missing":"The saved entity {entity} is no longer among this marker’s selectable channels. House Plan temporarily uses {fallback}; the saved choice will be restored if it returns.","marker.glow_color_label":"Glow colour and brightness","marker.glow_mode.help":"Use live source values, override only its colour, or fix both colour and brightness. The minimum is 1%; to disable the source, choose “Never”.","marker.glow_mode.help.aria":"Help: glow colour and brightness","marker.glow_mode_auto":"From source","marker.glow_mode_color":"Set colour","marker.glow_mode_fixed":"Set colour and brightness","marker.glow_color":"Glow colour","marker.glow_brightness":"Brightness","marker.glow_disabled_never":"Glow settings are unavailable because this marker is explicitly not a light source.","marker.glow_disabled_auto":"Auto mode found no spatial light source for this marker.","marker.glow_disabled_no_entity":"No active controllable Home Assistant entity is available for this spatial source.","marker.glow_passive_hint":"This source has no own Home Assistant data. Set its colour and brightness manually; its radius remains available.","marker.control_broken":"Saved source is missing or no longer marked as a light","marker.control_missing_label":"Missing plan light","marker.control_passive":"passive source","toast.marker_control_cycle":"This link would create a circular chain of light controls.","toast.marker_binding_required":"Choose a Home Assistant device before linking another light source.","confirm.unlock":"Unlock “{name}”?","toast.files_migrate_failed":"Attachments could not be moved to the new binding, links keep pointing at the old files: {err}","space.pick_saved":"Already uploaded","space.pick_saved_hint":"Plans stored on the server, including ones you detached earlier","space.no_saved":"No plans stored on the server yet.","space.loading":"Loading…","space.used_by":"in use: {list}","space.in_use":"A space still uses this plan — detach it first","btn.use":"Use","confirm.delete_plan":'Delete the plan file "{name}" from the server? This cannot be undone.',"toast.plans_list_failed":"Could not list the stored plans: {err}","toast.plan_delete_failed":"Could not delete the plan: {err}","marker.hide":"Hide","marker.hide_tip":'The device will disappear from the plan after saving but will still count toward the room signal. Restore it through the "Devices" catalog in the device editor.',"marker.show":"Show","marker.show_tip":"The device will appear on the plan again after saving.","marker.hidden_ghost":"Device hidden by the user","marker.ha_disabled_device":"The device is disabled in Home Assistant and hidden from the plan.","marker.ha_disabled_entity":"The entity is disabled in Home Assistant and hidden from the plan.","marker.ha_disabled_all_entities":"The device has no active Home Assistant entities, so it is hidden from the plan.","marker.ha_registry_limited":"The full Home Assistant registry is unavailable to this user. The unverified object cannot be shown or used for now.","marker.delete_tip":"Completely delete the device from the plan and every aggregate. You can add it again later.","tap.run":"Run automation/script/scene","tap.cover":"Open/close (curtains/blinds)","marker.run_target_label":"What to run","marker.run_search_ph":"Search: automation, script or scene…","marker.run_target_gone":"Target {id} not found — pick again","marker.tap_confirm":"Ask for confirmation","marker.tap_confirm_tip":"Show a confirmation dialog before acting — a guard against accidental taps.","marker.toggle_hint_single":"Target: {name} ({id}).","marker.virtual_light_target":"Virtual light: {name}.","marker.virtual_light_current":"Manual state: {state} → {effect}.","marker.virtual_light_state_on":"on","marker.virtual_light_state_off":"off","marker.toggle_hint_group":"Will toggle {count} source(s): {names}.","marker.toggle_hint_current":"Now: {state} → {effect}.","marker.toggle_hint_group_current":"Currently on: {on} of {count} → {effect}.","marker.toggle_hint_skipped":"Will be skipped ({count}): {targets}.","marker.toggle_effect_turn_on":"will turn on","marker.toggle_effect_turn_off":"will turn off","marker.toggle_effect_open":"will open","marker.toggle_effect_close":"will close","marker.toggle_effect_stop":"will stop","marker.toggle_effect_toggle":"state will toggle","marker.toggle_skip_missing":"not found","marker.toggle_skip_ha_disabled":"disabled in HA","marker.toggle_skip_unavailable":"unavailable","marker.toggle_skip_unsupported":"toggle is unsupported","marker.toggle_skip_secure":"blocked for security","marker.toggle_none_no_binding":"This device has no binding, so there is no state to toggle. Tapping will do nothing.","marker.toggle_none_no_actionable_entity":"This device has no state that can be toggled. Tapping will do nothing.","marker.toggle_none_configured_targets_missing":"The configured targets are unavailable. The device's own entity will not be substituted for them.","marker.toggle_none_ha_disabled":"The target is disabled in Home Assistant and cannot be used on the plan.","marker.toggle_none_unavailable":"The target is currently unavailable. Tapping will do nothing.","marker.toggle_none_unsupported":"Home Assistant exposes no safe toggle operation for this entity. Tapping will do nothing.","marker.toggle_none_secure":"Toggling locks, alarms and secure gates from the plan is blocked for security.","run.automation":"automation","run.script":"script","run.scene":"scene","confirm.tap_run":'Run "{name}"?',"confirm.tap_toggle":'Toggle "{name}"?',"confirm.tap_cover":'Open/close "{name}"?',"confirm.current_state":"Current state: {state}","confirm.expected_state":"After switching: {state}","confirm.group_current":"on {on} of {total}","confirm.group_all_on":"all are on","confirm.group_all_off":"all are off","confirm.unavailable_targets":"Unavailable: {count}","confirm.expected_by_ha":"Home Assistant will determine the state","confirm.state_on":"On","confirm.state_off":"Off","confirm.state_open":"Open","confirm.state_closed":"Closed","confirm.state_opening":"Opening","confirm.state_closing":"Closing","confirm.state_stopped":"Stopped","confirm.state_unknown":"Unknown","toast.run_started":"Started: {name}","toast.run_target_missing":"Run target not found — check the device settings","toast.run_target_required":"Pick an automation, script or scene","toast.tap_target_changed":"The action target changed. Try again.","toast.virtual_light_toggle_failed":"Could not toggle the virtual light: {err}","toast.value_badge_source_required":"Choose a value for the badge","btn.run":"Run","vac.section":"Robot vacuum: live position","vac.autocal":"Set up automatically","vac.live":"Live position on the plan","vac.trail":"Show the robot's path","vac.cal_maps":"Calibrated maps: {maps}","vac.autocal_no_rooms":"The integration reports no room list — open “Fit manually”","vac.autocal_no_match":"Room names did not match (need ≥3 in common) — open “Fit manually”","vac.autocal_done":"Done: bound via {rooms} rooms. Start a cleanup and check","vac.cal_need_pos":"The robot is not reporting coordinates — start a cleanup and pause it","vac.cal_done":"Calibration saved. Start a cleanup and check","vac.cal_cancelled":"Calibration cancelled","vac.fit":"Fit manually","vac.fit_hint":"Drag the robot map into place, stretch by the corners","vac.fit_rotate":"Rotate 90°","vac.fit_mirror":"Mirror","vac.trail_never":"Never","vac.trail_cleaning":"While cleaning","vac.trail_always":"Always","gs.bg_group":"Stage background","gs.bg_color":"Background around the plan","gs.bg_default":"Theme default","gs.bg_theme":"theme default","gs.bg_mode":"Plan background","gs.bg_static":"Static color","gs.bg_daynight":"Follows the Sun","gs.bg_daynight_hint":"The background moves through dawn, day, dusk and night using sun.sun, or your local clock when sun data is unavailable. No compass is needed for the background.","gs.sun_group":"Sun","gs.sun_missing":"The sun.sun entity was not found — the background follows your local clock; window rays are unavailable.","gs.north":"North on the plan","gs.north_ph":"not set","gs.north_hint":"Set north only for window rays (1° steps, 15° with Shift); the Sun background works without it.","gs.north_clear":"Clear","gs.north_letter":"N","gs.sun_rays":"Sunlight through windows","gs.about_group":"About","gs.about_version":"Houseplan Card v{v}","gs.about_github":"GitHub · docs & issues","gs.about_telegram":"Telegram chat","space.bg_color":"Background around the plan","space.bg_inherit":"Inherit general","space.bg_inherited":"inherits general settings","space.bg_mode":"Plan background","space.north":"North on the plan (override)","space.north_inherited":"inherited: {v}","space.sun_rays":"Sunlight through windows","space.sun_inherit":"Inherit general","space.sun_on":"On","space.sun_off":"Off","canvas.far_objects":"{n} object(s) far from the plan","canvas.show_far":"Show","canvas.home_tip":"The plan is over there — click to fit it","gs.grid_group":"Plan maintenance","gs.grid_hint":"Updates data models, aligns plan elements to the grid and merges redundant wall fragments. An exact report is shown before anything is stored.","gs.align_all":"Optimize plans","gs.align_title":"Optimize plans","gs.align_none":"All plans already use the current optimized data model.","gs.optimize_no_automatic_changes":"There are no automatic changes to apply. Review the items below.","gs.align_count":"{n} of {total} elements will move, by at most {cm} cm.","gs.align_where":"The largest shift is in “{s}”.","gs.align_turned":"Openings whose angle is corrected: {n}.","gs.align_removed_drafts":"Invalid outlines collapsed by the grid and removed: {n}.","gs.optimize_redundant_drafts":"Saved wall chains hidden by solid room walls and removed: {n}.","gs.align_preflight_failed":"Could not safely verify the geometry of the following spaces: {spaces}{more}.","gs.align_preflight_hint":"Plans were not changed. Copy the diagnostics with the button below and attach them to the bug report together with a space export.","gs.preflight_reason_prepare-exception":"Could not prepare the space geometry (exception while building the model)","gs.preflight_reason_wall-null":"The wall body did not build (the union came back empty)","gs.preflight_reason_wall-degraded-extra":"The wall body degraded with extra geometry","gs.preflight_reason_wall-failed-core":"The wall body core failed to assemble","gs.preflight_reason_wall-exception":"Wall construction threw an exception","gs.preflight_reason_floor-null":"The floor outline did not build","gs.preflight_reason_floor-exception":"Floor construction threw an exception","gs.preflight_copy":"Copy diagnostics","gs.preflight_copied":"Diagnostics copied","gs.preflight_update_hint":"The card and integration versions differ — update House Plan and retry.","gs.align_preflight_space":"Space {n}","gs.align_preflight_more":", and {n} more","gs.optimize_changes":"Model migrations: {m}; spaces updated: {c}; noisy coordinate values removed: {p}; merged real-wall fragments: {w}; merged zero-thickness wall fragments: {s}; independent walls: {i}.","gs.zero_walls_migrated":"Virtual wall spans converted: {n}.","gs.wall_segments_migrated":"Wall segments stabilised: {n}.","gs.optimize_lattice_summary":"Noisy coordinate values canonicalized: {n}; maximum movement: {cm} cm.","gs.optimize_lattice_space":"{space}: coordinate values canonicalized: {n}; off-grid values left unchanged: {far}.","gs.optimize_coincident_partitions":"Hidden independent wall sections absorbed into room walls: {n}.","gs.optimize_openings_rehosted":"Openings reattached to room walls: {n}.","gs.optimize_walls_straightened":"Walls straightened: {n}; maximum movement: {cm} cm.","gs.optimize_walls_straightened_where":"Largest wall correction: {s}.","gs.optimize_walls_straighten_skipped":"Near-axis walls left unchanged because they could not be repaired safely: {n}.","gs.optimize_glow_migration":"Legacy Glow: {spaces} spaces → no data fill + independent Glow; {rooms} rooms → inherited data fill + independent Glow.","gs.optimize_references":"References repaired: spaces — {spaces}; rooms — {rooms}; positions — {positions}; devices detached from missing spaces — {detached}.","gs.optimize_reference_more":", and {n} more","gs.optimize_orphans_removed":"Forgotten records removed: {total} — room labels: {rooms}; devices: {devices}; group markers: {groups}. They belonged to spaces deleted earlier.","gs.optimize_live_positions":"Old positions in deleted spaces belong to existing objects: {n}{names}. They will be kept.","gs.optimize_live_positions_remove":"Old positions in deleted spaces belong to existing objects: {n}{names}. They are selected for removal.","gs.optimize_live_names":": {names}{more}","gs.optimize_live_remove":"Remove old positions","gs.optimize_live_keep":"Keep old positions","gs.optimize_live_selected":"Old positions will be removed after Optimize is applied.","gs.optimize_unverified":"Could not safely verify positions: {n}. They were left unchanged.","gs.optimize_registry_limited":"Full administrator access to the Home Assistant registries is required for a safe check.","gs.optimize_vacuum_warning":"Vacuum room mappings that still need review: {n}.","gs.optimize_details":"Details","gs.optimize_details_more":"And {n} more records.","gs.optimize_detail_removed":"will be removed","gs.optimize_detail_live":"will be kept","gs.optimize_detail_unverified":"not verified","gs.optimize_detail_room_label":"room label","gs.optimize_detail_device":"device","gs.optimize_detail_group":"group marker","gs.optimize_detail_unknown":"unknown owner","gs.optimize_detail_item":"{status}: {kind} {id}; old space {space}","gs.align_warn":"Elements deliberately placed between grid nodes will move. One undo is available after the operation, only until the next plan edit.","gs.align_run":"Optimize","gs.align_done":"Plans optimized: {n} elements moved, {m} records maintained, {r} references repaired","gs.optimize_undo":"Undo last optimization","gs.optimize_undone":"The last optimization was undone","decor.furniture":"Furniture","furn.title":"Furniture library","furn.symbol":"Symbol","furn.group_furniture":"Furniture","furn.group_appliance":"Appliances","furn.group_sanitary":"Plumbing","furn.group_other":"Other","furn.width":"Width","furn.depth":"Depth","furn.pick_hint":"Pick a symbol, then click on the plan.","furn.place_hint":"Click on the plan — the piece lands against the nearest wall. Shift places it free.","furn.sym_sofa":"Sofa","furn.sym_armchair":"Armchair","furn.sym_coffee_table":"Coffee table","furn.sym_table_dining":"Dining table","furn.sym_table_round":"Round table","furn.sym_chair":"Chair","furn.sym_desk":"Desk","furn.sym_bed_double":"Double bed","furn.sym_bed_single":"Single bed","furn.sym_nightstand":"Nightstand","furn.sym_wardrobe":"Wardrobe","furn.sym_bookshelf":"Bookshelf","furn.sym_fridge":"Fridge","furn.sym_stove":"Cooker","furn.sym_dishwasher":"Dishwasher","furn.sym_washer":"Washing machine","furn.sym_dryer":"Tumble dryer","furn.sym_tv":"TV","furn.sym_ac":"Air conditioner","furn.sym_water_heater":"Water heater","furn.sym_toilet":"Toilet","furn.sym_bathtub":"Bathtub","furn.sym_shower":"Shower","furn.sym_sink":"Washbasin","furn.sym_kitchen_sink":"Kitchen sink","furn.sym_bidet":"Bidet","furn.sym_stairs":"Stairs","furn.sym_fireplace":"Fireplace","furn.sym_plant":"Plant","furn.sym_rug":"Rug","common.yes":"Yes","common.no":"No","vac.diag_source":"Source","vac.diag_platform":"Integration","vac.diag_status":"Status","vac.diag_position":"Position","vac.diag_rooms":"Rooms","vac.diag_rooms_value":"{total} · {matched} names match · {readiness}","vac.autocal_ready":"auto-calibration available","vac.autocal_not_ready":"need 3 matching names","vac.diag_path":"Integration path","vac.diag_map":"Map ID","vac.source_none":"not selected","vac.source_status_ok":"Ready","vac.source_status_missing":"Missing","vac.source_status_disabled":"Disabled in Home Assistant","vac.source_status_unavailable":"Unavailable","vac.source_status_unverified":"Cannot verify with current permissions","vac.source_status_unsupported":"No position data","vac.source_status_none":"No source","vac.source_banner_missing":"The saved source no longer exists. It was not replaced automatically; choose another source or restore it in Home Assistant.","vac.source_banner_disabled":"The saved source is disabled in Home Assistant. Enable it there or choose another source.","vac.source_banner_unverified":"Current Home Assistant permissions cannot verify this saved source. It remains pinned and will not be replaced automatically.","vac.choose_source":"Choose source","vac.source_auto":"Automatic","vac.source_auto_hint":"Use a compatible entity from this device","vac.all_cameras":"All cameras","vac.all_cameras_warn":"A camera may not provide robot data. Choose one only if it is your vacuum map.","vac.all_cameras_empty":"No other camera entities found.","vac.platform_unknown":"unknown integration","vac.cap_position":"position","vac.cap_rooms_short":"rooms","vac.cap_path":"path","vac.cap_map":"map ID","vac.cap_none":"no robot data detected","vac.xcme_hint":"Enable these Xiaomi Cloud Map Extractor attributes:","vac.documentation":"Documentation","vac.residual_title":"Check automatic calibration","vac.residual_message":"The matched rooms disagree by up to {error}. Apply this approximate calibration, refine it manually, or cancel without changing the saved setup.","vac.apply_proposal":"Apply","gs.backup_group":"Backup and transfer","gs.backup_hint":"Download a portable JSON backup or preview and import a backup made by House Plan.","backup.export_open":"Export","backup.import_open":"Import","backup.export_title":"Export House Plan","backup.import_title":"Import House Plan","backup.export_hint":"Choose whether the backup should contain the whole House Plan configuration or only the current space.","backup.full":"Full backup","backup.current_space":"Current space","backup.current_space_title":"Current space: {title}","backup.no_current_space":"No current space","backup.plan_only":"Plan only","backup.plan_only_hint":"Keep rooms, walls, openings, decor and room-label positions without devices or Home Assistant bindings.","backup.plan_only_preview":"This file contains the plan only","backup.privacy_warning":"The archive keeps names, Home Assistant identifiers and exact coordinates. Internal plans and attachments are referenced, not embedded; runtime states and vacuum trails are not included.","backup.download":"Download JSON","backup.export_done":"Backup downloaded","backup.reading":"Checking the backup…","backup.revalidated":"The plan changed after this preview. The summary was refreshed; review it and confirm again.","backup.error.unauthorized":"You do not have permission to export or import this plan.","backup.error.not_ready":"House Plan is not ready yet. Try again in a moment.","backup.error.too_large":"The backup exceeds the 8 MiB limit.","backup.error.invalid_json":"The selected file is not valid JSON.","backup.error.invalid_format":"The selected file is not a House Plan backup.","backup.error.unsupported_export_version":"This backup format is not supported by the installed version.","backup.error.future_model":"The backup was created by a newer House Plan data model.","backup.error.invalid_config":"The backup contains an invalid House Plan configuration.","backup.error.wall_model_migration_blocked":"The backup wall model could not be upgraded safely. Optimize the source plan first, then export it again.","backup.error.invalid_layout":"The backup contains invalid object positions.","backup.error.invalid_content":"The backup contains invalid or inconsistent content references.","backup.error.space_not_found":"The selected space no longer exists.","backup.error.capacity_exceeded":"Adding this backup would exceed the plan limits.","backup.error.preview_expired":"The preview expired. Select the backup file again.","backup.error.preview_owner_mismatch":"This preview belongs to another Home Assistant user.","backup.error.conflict":"The plan changed after the preview. Review the refreshed summary.","backup.error.content_confirmation_required":"Confirm that unavailable local content may be detached.","backup.error.commit_failed":"The backup could not be applied safely. The previous plan was restored or is pending recovery.","backup.error.missing_plan":"A referenced plan file disappeared after the preview. Review the backup again.","backup.error.missing_content":"A referenced local attachment disappeared after the preview. Review the backup again.","backup.error.marker_control_missing":"A linked plan light is missing from the backup.","backup.error.marker_control_not_light":"A linked plan target is no longer marked as a light source.","backup.error.marker_control_self":"A light source cannot control itself.","backup.error.marker_control_cycle":"The backup contains a circular chain of light controls.","backup.error.duplicate_marker_control":"The backup contains a duplicate plan-light link.","backup.error.no_backup":"There is no import or optimization snapshot to restore.","backup.same_source":"Created on this Home Assistant instance","backup.foreign_source":"Created on another Home Assistant instance","backup.created":"Created: {value}","backup.versions":"Card {card}; integration {integration}; data model {model}","backup.count_spaces":"Spaces: {n}","backup.count_rooms":"Rooms: {n}","backup.count_walls":"Walls: {n}","backup.count_openings":"Openings: {n}","backup.count_decor":"Decor objects: {n}","backup.count_markers":"Devices: {n}","backup.count_layout":"Positions: {n}","backup.bindings":"Bindings — devices: {device}, entities: {entity}, virtual: {virtual}; positions without a space: {legacy}","backup.binding_status":"Target status — active: {active}, disabled: {disabled}, missing: {missing}","backup.missing_areas":"Areas missing on the target: {areas}","backup.dropped_marker_links":"Plan-light links outside this transferred space were omitted: {n}.","backup.repaired_target_refs":"Existing references restored by this space import: {n}.","backup.preserved_unresolved_refs":"References that could not be restored unambiguously were preserved: {n}.","backup.preserved_unresolved_hint":"No data was guessed or deleted. After the import, run Optimize plans to inspect the remaining references.","backup.import_details":"Import reference details","backup.import_detail.incoming_remapped":"References updated inside the imported copy: {n}","backup.import_detail.target_repaired":"Existing references restored: {n}","backup.import_detail.preserved_unresolved":"Unresolved references preserved: {n}","backup.import_detail.collisions":"Destination conflicts preserved safely: {n}","backup.import_detail.dropped_links":"Incoming links omitted by transfer rules: {n}","backup.import_detail.bounded_lineages":"Overly nested identifiers left bounded: {n}","backup.replace_warning":"This replaces the current configuration and layout. Uploaded files are never deleted. One undo remains available until the next plan edit.","backup.foreign_bookkeeping":"Instance-specific known/new-device bookkeeping will not be imported.","backup.final_name":"New space name","backup.target_settings":"The target instance's global settings remain unchanged.","backup.duplicates":"Bindings already present: {n}","backup.skip":"Skip duplicate devices","backup.virtual_copy":"Add safe static virtual copies","backup.content":"Referenced content","backup.content_available":"available locally","backup.content_external":"external link","backup.content_detach_required":"will be detached","backup.confirm_detach":"I understand that unavailable internal plans and attachments will be detached from the imported configuration.","backup.replace":"Replace","backup.add":"Add space","backup.space_done":"Space imported: {rooms} rooms, {markers} devices, {refs} existing references restored","backup.full_done":"Backup restored: {spaces} spaces, {rooms} rooms, {markers} devices","backup.undo_import":"Undo last full import","backup.import_undone":"Full import undone"};const aa={en:oa,ru:{"editor.context_actions":"Действия: {object}","editor.tool_options":"Параметры инструмента: {tool}","editor.palette":"Палитра: {tool}","editor.open_group":"Группа инструментов: {group}","editor.group_active":"{group} — активно: {item}","editor.disabled_action":"{action} недоступно: {reason}","color_picker.title":"Выбор цвета","color_picker.hue":"Оттенок","color_picker.saturation":"Насыщенность","color_picker.value":"Яркость","color_picker.hex":"Цвет HEX","color_picker.invalid_hex":"Введите цвет HEX из 3 или 6 цифр","btn.properties":"Свойства","btn.keep_as_walls":"Оставить стенами","btn.delete_room_keep_walls":"Удалить комнату, оставить стены","btn.delete_room_with_walls":"Удалить комнату и стены","title.markup_select":"Выбор и редактирование стен, колонн и сохранённых контуров","title.markup_column":"Колонна: кликните точку сетки для квадратной колонны","markup.partition":"Перегородка","markup.column":"Колонна","markup.hint_column":"кликните точку сетки, чтобы поставить квадратную колонну","history.draft_segment":"Добавление сегмента черновика комнаты","history.draft_merge":"Соединение незавершённых контуров комнаты","history.draft_segment_delete":"Удаление сегмента черновика комнаты","history.partition_add":"Добавление перегородки","history.column_add":"Добавление колонны","history.physical_edit":"Изменение физического объекта","history.physical_delete":"Удаление физического объекта","history.physical_move":"Перемещение физического объекта","history.contour_to_partitions":"Преобразование контура в замкнутые стены","history.wall_chain_finish":"Завершение цепочки стен","history.wall_face_batch":"Создание комнат из стен","toast.column_duplicate":"Колонна с тем же центром и внешним размером уже существует","confirm.delete_draft":"Удалить весь незавершённый контур комнаты?","confirm.delete_draft_segment":"Удалить этот сегмент черновика? Оставшийся контур может разделиться на два.","physical.partition_properties":"Свойства перегородки","physical.column_properties":"Свойства колонны","physical.draft_properties":"Свойства сегмента черновика","physical.shape":"Форма","physical.square":"Квадрат","physical.circle":"Круг","physical.diameter":"Диаметр","physical.side":"Сторона","physical.rotation":"Угол поворота","physical.length":"Длина","physical.allowed_range":"Допустимо: {min}–{max} {unit}","physical.delete_segment":"Удалить сегмент","physical.delete_draft":"Удалить весь контур","physical.column_size_title":"Внешняя сторона квадратной колонны, создаваемой кликом (1–150 см).","card.title":"План дома","count.devices":"{n} устр.","empty.no_spaces":"Пространств пока нет.","empty.add_first":"Добавьте первое пространство и загрузите план этажа.","empty.install":"Установите интеграцию House Plan и добавьте запись в «Устройства и службы».","btn.add_space":"Добавить пространство","btn.cancel":"Отмена","btn.save":"Сохранить","btn.close":"Закрыть","btn.delete":"Удалить","btn.edit":"Редактировать","btn.open_in_ha":"Открыть в HA","btn.reset":"Сброс","btn.attach":"Прикрепить…","btn.upload":"Загрузить…","btn.replace":"Заменить…","title.zoom_in":"Приблизить","title.zoom_out":"Отдалить","title.zoom_fit":"Вписать всё","title.add_device":"Добавить устройство на план","title.show_all":"Показать скрытые и деактивированные устройства служебными маркерами (только в этой вкладке)","title.markup":"Разметка комнат: сетка, линии, контуры","title.configure_space":"Настроить пространство","title.add_space":"Добавить пространство","title.markup_add":"Стены: рисуйте непрерывную цепочку; Shift фиксирует 45°. Смена инструмента или выход завершает её как независимые стены","title.markup_merge":"Объединить: клик по одной комнате, затем по соседней с общей стеной","title.markup_split":"Разделить комнату: клик по комнате, затем две точки на её стенах","title.markup_delroom":"Удалить комнату: кликните внутри комнаты и подтвердите удаление","title.need_plan":"Загрузите подложку (план этажа)","markup.add":"Стены","markup.merge":"Объединить","markup.split":"Разделить","markup.resize":"Размер","title.markup_resize":"Изменение размера комнат: тяните доступную ручку горизонтальной или вертикальной стены","markup.hint_resize":"тяните доступную ручку стены · стена упирается в первую небезопасную позицию · Esc — отмена · Ctrl+Z — отмена шага","resize.disabled.diagonal":"Стена расположена под углом: Resize поддерживает только горизонтальные и вертикальные стены","resize.disabled.side-angle":"Примыкающая стена расположена под углом: для Resize обе примыкающие стены должны образовывать прямой угол","resize.disabled.duplicate-physical-wall":"Стену перекрывает отдельная перегородка, незавершённый контур или колонна; удалите или переместите её перед изменением размера","resize.disabled.partial-shared":"Соседняя комната использует только часть этой стены, поэтому её нельзя безопасно двигать как одну общую стену","resize.disabled.unequal-shared":"У соседней комнаты другие конечные точки или длина стены, поэтому стены нельзя безопасно двигать вместе","resize.disabled.multiple-rooms":"Перемещение затронуло бы больше двух комнат","resize.disabled.thickness-conflict":"Толщину стены нельзя безопасно сохранить","resize.disabled.opening-conflict":"Проём на этой стене нельзя безопасно переместить","resize.disabled.invalid-geometry":"Эту стену нельзя переместить без изменения структуры плана","resize.limit_stopped":"Стена остановлена: дальше нарушается ограничение стыков","resize.commit_failed":"Изменение размера отменено: итоговый план не прошёл проверку геометрии","resize.preview_failed":"Стена остановлена в последней безопасной позиции: геометрию плана нельзя сохранить без потерь","markup.opening":"Проём","markup.delete_room":"Удалить комнату","history.undo":"Отменить","history.redo":"Повторить","history.undo_named":"Отменить: {name} (Ctrl+Z)","history.redo_named":"Повторить: {name} (Ctrl+Shift+Z / Ctrl+Y)","history.undo_empty":"Нет операций для отмены","history.redo_empty":"Нет операций для повтора","history.undone":"Отменено: {name}","history.redone":"Повторено: {name}","history.add_room":"Создание комнаты","history.split_room":"Разделение комнаты","history.merge_rooms":"Объединение комнат","history.resize_room":"Изменение размера комнаты","history.wall_thickness":"Изменение толщины стены","history.add_opening":"Добавление дверного или оконного проёма","history.edit_opening":"Изменение проёма","history.move_opening":"Перемещение проёма","history.delete_opening":"Удаление проёма","history.delete_room":"Удаление комнаты","history.delete_room_keep_walls":"Удаление комнаты с сохранением стен","history.delete_room_with_walls":"Удаление комнаты и её стен","history.decor_add":"Добавление объекта декора","history.decor_edit":"Изменение объекта декора","history.decor_move":"Перемещение объекта декора","history.decor_transform":"Трансформация объекта декора","history.decor_delete":"Удаление объекта декора","history.backdrop_transform":"Трансформация подложки плана","title.markup_opening":"Проёмы: клик по стене — добавить, клик по проёму — редактировать","opening.new":"Новый проём","opening.edit":"Проём","opening.door":"Дверь","opening.window":"Окно","opening.gate":"Ворота","opening.passage":"Открытый проём","opening.passage_binding_warning":"При сохранении датчик открытия и замок будут удалены.","opening.invalid_passage_fields":"У открытого проёма на плане «{room}» есть недопустимые параметры: {fields}.","opening.type_label":"Тип","opening.length_label":"Длина, см","opening.contact_label":"Датчик открытия","opening.lock_label":"Замок","opening.none":"— нет —","opening.search_ph":"Поиск: имя или entity_id…","opening.invert":"Инвертировать открыто/закрыто","opening.flip_h":"Петли с другой стороны","opening.flip_v":"Открывается в другую сторону","opening.open":"Открыто","opening.closed":"Закрыто","opening.locked":"Заперто","opening.unlocked":"Не заперто","opening.state_unknown":"недоступно","opening.no_entities":"Датчики не привязаны — статичный символ на плане.","toast.opening_no_wall":"Кликните рядом со стеной комнаты или независимой стеной","opening.host_partition":"Независимая стена","opening.partition_orphan":"Независимая стена этого проёма больше не существует","opening.partition_jamb_margin":"Оставьте от края проёма до торца стены минимум {distance}","opening.rebind_partition":"Привязать к другой независимой стене","confirm.delete_partition_openings_title":"Удалить стену и проёмы?","confirm.delete_partition_openings_body":"В стене есть проёмы: {count}. Они будут удалены вместе со стеной.","confirm.delete_partition_openings_item":"• {type}, {length}","markup.delete":"Удалить","markup.hint_points":"точек: {n} · Shift — шаг 45° · Esc — завершить цепочку · Ctrl+Z — убрать точку · при замыкании будет предложена комната","markup.hint_start":"кликните точку сетки, чтобы начать цепочку стен","tip.lqi":"средний сигнал zigbee:","tip.area":"площадь: {value}","info.device_header":"Устройство на плане","info.model":"Модель","info.state":"Состояние","info.link":"Ссылка","info.manuals":"Инструкции","info.none":"Нет дополнительной информации","marker.new_device":"Новое устройство","marker.name_label":"Имя (отображается на плане)","marker.name_ph":"Название","marker.binding_label":"Привязка к устройству HA","marker.binding_disabled":"деактивировано в Home Assistant","marker.virtual_option":"Виртуальное устройство (без привязки)","marker.search_ph":"Поиск устройства / группы…","marker.nothing_found":"ничего не найдено","marker.room_label":"Комната","marker.room_override":" (переопределить размещение)","marker.room_choose":"— выберите комнату —","marker.room_auto":"— по зоне устройства (авто) —","marker.icon_label":"Иконка","marker.icon_ph":"mdi:… (пусто = авто)","marker.display_label":"Отображение","display.badge":"Значок + состояние","display.icon_ripple":"Значок + состояние и активность","display.static_icon":"Всегда статичный значок","marker.display_hint":"Значок + состояние меняет подложку при работе, открытии, тревоге и недоступности. Значок + состояние и активность дополнительно показывает короткую пульсацию для событий и постоянную — для работы, движения или присутствия. Значение + состояние заменяет значок одним однозначным значением HA. Статичный значок не реагирует на состояния устройства.","marker.display_hint_badge":"Значок и динамическая подложка показывают состояние устройства без обычной пульсации активности. Красная тревога сохраняется.","marker.display_hint_icon":"Значок и динамическая подложка показывают состояние устройства без обычной пульсации активности. Красная тревога сохраняется.","marker.display_hint_icon_ripple":"Значок, динамическая подложка и пульсация: короткая — для событий, постоянная — для работы, движения или присутствия. Красная тревога имеет отдельный приоритет.","marker.display_hint_value":"Значок заменяется одним однозначным значением Home Assistant; подложка продолжает показывать состояние. Красная тревога сохраняется.","marker.display_hint_static_icon":"Подложка в цветах темы и значок всегда остаются одинаковыми. Состояния, активность, недоступность и тревоги не меняют отображение.","marker.static_alarm_warning":"Это устройство может сообщать о тревогах. Статичный режим скрывает визуальную тревогу маркера.","marker.preview.title":"Предпросмотр отображения","marker.preview.actual":"Сейчас","marker.preview.example":"Пример","marker.preview.integration":"Интеграция","marker.preview.source":"Источник отображения","marker.preview.current_state":"Текущее состояние","marker.preview.result":"На плане","marker.preview.details":"Подробнее об источниках","marker.preview.select_source":"Выберите устройство или сущность Home Assistant, чтобы увидеть фактическое отображение.","marker.preview.unknown_provider":"Интеграция неизвестна","marker.preview.virtual_provider":"House Plan · виртуальное устройство","marker.preview.no_source":"Нет активного источника","marker.preview.no_state":"Нет текущего состояния","marker.preview.mixed_states":"Несколько разных состояний","marker.preview.multiple_sources":"Источников: {n}","marker.preview.more_sources":"ещё {n}","marker.preview.scaled":"Предпросмотр уменьшен до {n}%, чтобы поместиться. Сохранённый размер не изменится.","marker.preview.demo_activity":"Показать пример активности","marker.preview.demo_notice":"Временный пример активности; фактическое состояние устройства не меняется.","marker.preview.demo_short":"Показать краткую активность","marker.preview.demo_continuous":"Показать постоянную активность","marker.preview.stop_continuous":"Остановить постоянную активность","marker.preview.demo_short_notice":"Пример краткой активности; фактическое состояние устройства не меняется.","marker.preview.demo_continuous_notice":"Пример постоянной активности; фактическое состояние устройства не меняется.","marker.preview.demo_already_visible":"Текущее состояние уже показывает реальную активность или тревогу.","marker.preview.reduced_motion":"В системе включено уменьшение движения, поэтому обычная активность показана точкой.","marker.preview.reason.neutral":"Нейтральная тёмная подложка","marker.preview.reason.working":"Жёлтая подложка: устройство сейчас работает","marker.preview.reason.working_activity":"Жёлтая подложка и эффект активности: устройство сейчас работает","marker.preview.reason.open":"Оранжевая подложка: физически открыто или разблокировано","marker.preview.reason.cover_icon_state":"Нейтральная подложка; состояние и значок определяет сущность шторы или заслонки","marker.preview.reason.presence":"Эффект активности, пока обнаружено присутствие","marker.preview.reason.event":"Короткий эффект активности после события","marker.preview.reason.transition":"Эффект активности во время движения или смены состояния","marker.preview.reason.media_neutral":"Медиаустройство остаётся на нейтральной тёмной подложке, пока доступно","marker.preview.reason.unavailable":"Приглушённая нейтральная подложка: отключено или недоступно","marker.preview.reason.alarm":"Красная тревожная подложка; тревога отображается всегда","marker.preview.reason.live_states_disabled":"Оформление по живым состояниям отключено в настройках карточки","marker.preview.reason.value_no_state":"Нет подходящего значения состояния — вместо него показан значок","marker.preview.reason.value_ambiguous_sources":"Подходит несколько источников значения — вместо него показан значок","marker.preview.reason.value_non_scalar":"Источник вернул не простое значение — вместо него показан значок","marker.preview.reason.value_virtual":"У виртуального устройства нет значения HA — вместо него показан значок","marker.preview.reason.vacuum_live_plan_only":"Живая позиция и след пылесоса доступны только на полном плане","marker.preview.reason.hidden_design_preview":"Устройство скрыто на плане, но его оформление видно в предпросмотре","marker.preview.reason.composite_power_source":"Состояние берётся из сущности питания устройства; вспомогательные переключатели не учитываются","marker.preview.reason.activity_display_disabled":"Выбранный режим отображения не показывает обычные эффекты активности","marker.preview.reason.ha_disabled":"Привязка отключена в Home Assistant, поэтому устройство будет скрыто на плане","marker.preview.reason.orphaned":"Сохранённая привязка Home Assistant больше не найдена","marker.preview.reason.static_icon":"Статичный режим: состояние устройства не меняет значок","marker.activity_color":"Цвет пульсации активности","marker.ripple_size":"Размер пульсации активности","marker.activity_alarm_note":"Цвет и размер относятся только к обычной активности и не влияют на красную тревогу.","marker.pulse_a11y_alarm":"Тревога","marker.pulse_a11y_event":"Недавнее событие","marker.pulse_a11y_presence":"Обнаружено присутствие","marker.pulse_a11y_transition":"Изменение состояния","marker.pulse_a11y_running":"Работает","marker.state_a11y_neutral":"Обычное состояние","marker.state_a11y_working":"Работает","marker.state_a11y_open":"Открыто","marker.state_a11y_locked":"Заблокировано","marker.state_a11y_unlocked":"Разблокировано","marker.state_a11y_alarm":"Тревога","marker.state_a11y_unavailable":"Недоступно","marker.lqi_a11y_low":"LQI {value}, слабый сигнал","marker.lqi_a11y_mid":"LQI {value}, средний сигнал","marker.lqi_a11y_high":"LQI {value}, сильный сигнал","marker.size_label":"Размер / поворот значка","marker.angle_label":"Поворот","marker.model_label":"Модель","marker.model_ph":"напр. Aqara T&H","marker.link_label":"Ссылка","marker.desc_label":"Описание","marker.desc_ph":"Заметки, характеристики…","marker.manuals_label":"Инструкции (PDF и т.п.)","marker.sub_device":"устройство","marker.sub_z2m_group":" · Z2M-группа","marker.sub_group":"группа","marker.sub_helper":"хелпер","space.new":"Новое пространство","space.header":"Пространство","space.title_label":"Название","space.title_ph":"Например: Гараж","space.plan_label":"Подложка (план)","space.no_plan":"нет подложки","space.plan_alt":"план","room.new":"Новая комната","room.name_label":"Отображаемое имя","room.name_ph":"Например: Терраса","room.area_label":"Зона Home Assistant (свободные)","room.no_area_option":"— без зоны —","room.default_name":"Комната","device.unnamed":"без имени","device.light_group":"группа света","device.fallback":"устройство","device.virtual":"виртуальное устройство","confirm.delete_room":"Удалить комнату «{name}»?","confirm.delete_room_title":"Удалить комнату «{name}»?","confirm.delete_room_body":"Выберите, нужно ли оставить физические стены, принадлежащие только этой комнате. Общие с другой комнатой стены сохраняются всегда.","confirm.merge_rooms":"Слить комнаты «{a}» и «{b}»?","confirm.remove_marker":"Удалить «{name}» с плана? Устройство исчезнет полностью и перестанет участвовать в данных плана. Позже его можно будет добавить заново.","confirm.erase_decor":"Стереть объект «{kind}»? Действие можно отменить из истории редактора.","confirm.delete_space":"Удалить пространство «{title}» со всеми комнатами и разметкой?","space.delete_blocked":"Это пространство всё ещё используется устройствами: {n}. Сначала перенесите их в другое пространство или удалите.","toast.pos_save_failed":"Не удалось сохранить позицию: {err}","toast.no_entity":"У устройства нет подходящей сущности","toast.ha_disabled_action":"Деактивированный объект Home Assistant нельзя использовать на плане.","toast.ha_disabled_show_device":"Деактивированное в Home Assistant устройство нельзя показать на плане. Сначала активируйте его в Home Assistant.","toast.ha_disabled_show_entity":"Деактивированную в Home Assistant сущность нельзя показать на плане. Сначала активируйте её в Home Assistant.","toast.ha_disabled_add":"Деактивированный объект Home Assistant нельзя добавить на план. Сначала активируйте его в Home Assistant.","toast.ha_binding_unverified":"Статус объекта не удалось подтвердить по реестру Home Assistant. Отображение и действия временно недоступны.","toast.markup_needs_server":"Разметка доступна после переноса конфига на сервер","toast.space_order_changed":"Порядок изменён. Если где-то этаж карточки задан номером, проверьте такие панели.","toast.conflict":"Конфиг изменён в другом окне — данные обновлены, повторите последнее действие","toast.cfg_save_failed":"Не удалось сохранить конфиг: {err}","toast.room_overlap":"Контур накладывается на комнату «{name}» — комнаты не должны накладываться","toast.contour_min_edges":"Чтобы замкнуть контур, сначала нарисуйте минимум две грани","toast.contour_cannot_close":"Контур нельзя замкнуть: он вырожден или пересекает сам себя","toast.merge_not_adjacent":"Объединять можно только комнаты с общей стеной","toast.rooms_merged":"Комнаты объединены в «{name}»","toast.split_pick_wall":"Начните разрез на стене комнаты","toast.split_bad_cut":"Разрез — от стены до стены внутри комнаты, без пересечения стен и самого себя","merge.header":"Объединение комнат","merge.hint":"У объединённой комнаты одно имя и одна зона. Вторая зона освобождается — её устройства уйдут с плана, пока их не заберёт другая комната.","merge.keep":"Оставить","merge.no_area":"без зоны","room.split_header":"Новая комната после разделения","toast.room_saved":"Комната сохранена ({n}). Устройств добавлено: {added}. Обведите следующую или выйдите из разметки.","toast.room_saved_no_area":"Комната сохранена ({n}, без зоны). Обведите следующую или выйдите из разметки.","toast.marker_needs_server":"Редактирование устройств доступно после переноса конфига на сервер","toast.virtual_name_required":"Укажите имя виртуального устройства","toast.marker_saved":"Устройство сохранено","toast.marker_removed":"Устройство удалено с плана","toast.integration_missing":"Интеграция House Plan не установлена — управление недоступно","toast.plan_formats":"Поддерживаются SVG, PNG, JPG, WebP","toast.plan_required":"Загрузите подложку — план этажа обязателен","toast.space_added_onboard":"Пространство добавлено. Обведите комнаты: кликайте по точкам сетки и замкните контур.","toast.space_added":"Пространство добавлено","toast.space_saved":"Пространство сохранено","toast.space_deleted":"Пространство удалено","toast.delete_failed":"Ошибка удаления: {err}","toast.error":"Ошибка: {err}","toast.toggle_target_unavailable":"Цель «{name}» недоступна — действие не выполнено","toast.toggle_targets_unavailable":"Цели недоступны: {names}. Действие не выполнено","toast.file_failed":"Файл «{name}» не загружен: {err}","toast.files_attached":"Прикреплено файлов: {n}","err.unknown":"неизвестная ошибка","err.code":"код {code}","err.too_large":"файл больше {mb} МБ","err.bad_ext":"недопустимый тип (нужен PDF/изображение)","err.unauthorized":"нужны права администратора","editor.title":"Заголовок","editor.default_floor":"Стартовое пространство","editor.default_floor_missing":"Стартовое пространство «{id}» больше не существует. Выберите другое.","editor.floor":"Закреплённое пространство","editor.floor_none":"— не закреплять —","editor.floor_index":"YAML-индекс {index} (сохранён)","fixed_floor.loading":"Загружаем закреплённое пространство…","fixed_floor.invalid_title":"Закреплённое пространство недоступно","fixed_floor.invalid_body":"Проверьте floor в конфигурации карточки. Настроенное значение: {value}","editor.icon_size":"Размер иконок, % ширины плана","editor.show_temperature":"Показывать температуру","editor.live_states":"Живые состояния (вкл/выкл, открыто…)","editor.show_signal":"Показывать сигнал zigbee (LQI)","editor.language":"Язык интерфейса","editor.lang_auto":"Авто (профиль HA)","editor.lang_en":"English","editor.lang_ru":"Русский","title.icon_rules":"Правила иконок: какая MDI-иконка достаётся устройству по имени","rules.title":"Правила иконок","rules.hint":"Правила проверяются сверху вниз по строке «имя устройства + модель» (regex без учёта регистра); срабатывает первое совпадение. Если ничего не подошло — решает device class сущности, затем — иконка-заглушка.","rules.pattern_ph":"regex, напр. розетк|plug","rules.icon_ph":"mdi:power-socket-de","rules.add":"Добавить правило","rules.reset":"Сбросить к умолчаниям","rules.test_ph":"Проверьте имя устройства…","rules.invalid":"некорректный regex","rules.saved":"Правила иконок сохранены","btn.up":"Вверх","btn.down":"Вниз","tap.info":"Карточка устройства","tap.more_info":"Диалог HA (more-info)","tap.toggle":"Переключить состояние","marker.tap_label":"Действие по нажатию для этого устройства","tap.toggle_note":"Под селектором показано, какое состояние изменится. Защищённые устройства не переключаются с плана.","import.title":"Создать пространства из этажей HA","import.hint":"Home Assistant уже знает эти этажи. Отметьте, какие превратить в пространства плана — далее для каждого попросим картинку плана. Комнаты затем обводятся вручную по плану.","import.start":"Создать: {n}","import.manual":"Начать с нуля","import.progress":"Этаж {i} из {n}","import.done":"Пространства созданы. Обведите комнаты: кликайте по точкам сетки и замкните контур.","btn.skip":"Пропустить","space.scale_label":"Масштаб (размер клетки сетки)","space.scale_unit":"см на клетку","space.scale_unit_imperial":"дюйм на клетку","space.display_section":"Отображение","space.show_borders":"Всегда отображать границы комнат","space.zero_wall_style":"Стены нулевой толщины","space.zero_wall_dashed":"Пунктирные","space.zero_wall_solid":"Сплошные","space.zero_wall_help":"Пунктирные стены пропускают свет. Сплошные стены блокируют свет, даже при нулевой толщине.","space.show_names":"Отображать названия комнат (перетаскиваются)","space.room_color":"Цвет границ и названий","space.opacity":"Прозрачность","space.fill_label":"Заливка комнат","fill.none":"Нет","fill.lqi":"По силе зигби-сигнала","fill.light":"По освещению","fill.custom":"Свой цвет","space.custom_fill":"Цвет заливки","space.source_file":"У меня есть картинка плана","space.source_draw":"Нет подложки — нарисую комнаты вручную","space.orientation":"Холст","orient.landscape":"Альбомный","orient.portrait":"Портретный","orient.square":"Квадрат","fill.temp":"По температуре","space.temp_min":"Комфорт от","space.temp_max":"до","tip.temp_avg":"средняя температура:","tip.hum_avg":"средняя влажность:","space_card.button":"Перейти к пространству","space_card.not_found":"Пространство «{id}» не найдено","space_card.loading":"Загрузка…","continuity.restore_plan":"Восстанавливаем план…","continuity.restore_connection":"Восстанавливаем подключение к устройствам…","continuity.retry":"Повторить","editor.space":"Пространство","editor.show_button":"Показывать кнопку","editor.button_label":"Текст кнопки","editor.button_target":"Путь дашборда (куда вести)","marker.sub_entity":"сущность","title.general_settings":"Общие настройки","gs.title":"Общие настройки","gs.hint":"Цвета заливок действуют на все пространства; у каждого цвета своя прозрачность. Какой режим заливки использует пространство — задаётся в его диалоге.","gs.light_group":"Заливка: освещение","gs.light_on":"Свет включён","gs.light_off":"Весь свет выключен","gs.temp_group":"Заливка: температура","gs.temp_cold":"Холодно","gs.temp_ok":"Комфорт","gs.temp_hot":"Жарко","gs.lqi_group":"Заливка: зигби-сигнал","gs.lqi_low":"Слабый сигнал","gs.lqi_high":"Сильный сигнал","gs.reset":"Сбросить к умолчаниям","gs.saved":"Общие настройки сохранены","space.show_lqi":"Показывать зигби-сигнал (LQI) у устройств","space.hide_decor":"Скрыть декоративный слой","space.hide_decor_tip":"Линии, фигуры, надписи и мебель остаются на месте — их видно в редакторе подложки, но не на плане.","space.hide_openings":"Скрыть проёмы","space.hide_openings_tip":"Двери, окна и ворота не рисуются, но продолжают работать: свет проходит, солнце светит в окна, датчики открытия срабатывают. В редакторе плана проёмы видно всегда.","gs.light_none":"Нет источников света","mode.plan":"Редактор плана","mode.devices":"Редактор устройств","display.value":"Значение + состояние","marker.subarea":"без зоны, вручную","device.new":"Новое устройство — откройте его редактор, чтобы снять отметку","opening.unlock_action":"Открыть замок","opening.lock_action":"Закрыть замок","opening.lock_pending":"Выполняется…","title.close_editor":"Закрыть редактор (вернуться к просмотру)","devbar.add":"Добавить","devbar.show_all":"Скрытые и деактивированные","devbar.rules":"Правила иконок","device_inbox.button":"Устройства","device_inbox.title":"Устройства на плане","device_inbox.search":"Поиск по устройствам, сущностям и интеграциям…","device_inbox.add_virtual":"Добавить виртуальное устройство","device_inbox.tab_on_plan":"На плане","device_inbox.tab_available":"Доступны","device_inbox.tab_hidden":"Скрытые","device_inbox.tab_readd":"Доступны снова","device_inbox.only_new":"Только новые","device_inbox.show_entities":"Показывать сущности","device_inbox.show_hidden":"Показывать скрытые на плане","device_inbox.new":"Новое","device_inbox.find":"Найти на плане","device_inbox.edit":"Настроить","device_inbox.hide":"Скрыть","device_inbox.show":"Показать","device_inbox.add":"Добавить","device_inbox.readd":"Добавить заново","device_inbox.hide_available":"Скрыть из списка","device_inbox.show_more":"Показать ещё","device_inbox.more_actions":"Другие действия","device_inbox.find_hidden_hint":"Сначала включите «Показывать скрытые на плане»","device_inbox.show_disabled":"Перед показом активируйте эту привязку в Home Assistant","device_inbox.empty_on_plan":"На плане пока нет подходящих устройств.","device_inbox.empty_available":"Нет доступных устройств для добавления.","device_inbox.empty_hidden":"Скрытых устройств нет.","device_inbox.empty_readd":"Нет удалённых устройств, доступных для повторного добавления.","device_inbox.reason_visible_auto":"Найдено автоматически","device_inbox.reason_visible_explicit":"Добавлено явно","device_inbox.reason_manual_hidden":"Скрыто пользователем","device_inbox.reason_automatic_hidden":"Скрыто автоматически","device_inbox.reason_service_entry":"Служебная запись реестра","device_inbox.reason_excluded_integration":"Интеграция исключена фильтрами устройств","device_inbox.reason_excluded_domain":"Непространственный тип сущности","device_inbox.reason_grouped_light":"Представлено группой света комнаты","device_inbox.reason_represented_by_parent":"Представлено родительским устройством","device_inbox.reason_removed":"Ранее удалено с плана","device_inbox.reason_available":"Можно добавить на план","device_inbox.reason_no_bound_room":"Зона HA не связана с комнатой плана","device_inbox.status_ha_disabled":"Отключено в Home Assistant","device_inbox.status_orphaned":"Привязка больше не найдена в Home Assistant","device_inbox.status_unverified":"Реестр Home Assistant временно недоступен","device_inbox.saved":"Список устройств обновлён","space.roomcard_section":"В карточке комнаты:","space.label_temp":"Температура","space.label_hum":"Влажность","space.label_lqi":"Средний Zigbee-сигнал","space.label_light":"Свет вкл/выкл","roomcard.light_on":"Вкл","roomcard.light_off":"Выкл","roomcard.light_partial":"{on} из {total}","toast.split_pick_inside":"Промежуточные точки разреза — внутри комнаты","mode.decor":"Редактор подложки","decor.select":"Выбрать","decor.line":"Линия","decor.rect":"Прямоугольник","decor.ellipse":"Овал","decor.text":"Надпись","decor.erase":"Стереть","decor.erase_confirm_title":"Стереть объект?","decor.color":"Цвет","decor.width":"Толщина линии","decor.line_style":"Стиль линии","decor.line_style_solid":"Сплошная","decor.line_style_dashed":"Пунктирная","decor.fill":"Заливка","decor.fill_color":"Цвет заливки","decor.length":"Длина","decor.size":"Размер","decor.angle":"Угол поворота, °","decor.text_size":"Размер текста","decor.backdrop_properties":"Свойства картинки-подложки","decor.text_title":"Надпись","decor.object_title":"Редактирование: {kind}","decor.text_label":"Текст","decor.live_group":"Вставить переменную HA","decor.live_entity":"Сущность","decor.live_entity_ph":"выберите сущность","decor.live_attr":"Значение","decor.live_attr_ph":"выберите состояние или атрибут","decor.live_state":"Состояние","decor.backdrop":"Картинка-подложка","decor.backdrop_hint":"Тяните картинку — перемещение; угол — размер; верхнюю ручку — поворот. Shift меняет пропорции или снимает шаг угла.","decor.backdrop_reset":"Вернуть картинку","decor.backdrop_reset_done":"Картинка вернулась на своё место и в свой размер","marker.icon_auto":"Авто: {icon} (по правилам иконок; выберите свою, чтобы заменить)","marker.icon_pin_auto":"Закрепить","mode.plan_tip":"Редактор плана — геометрия дома: рисование и объединение/разделение комнат, привязка к зонам HA, двери, окна и ворота, карточки комнат, масштаб","mode.devices_tip":"Редактор устройств — всё про значки: перетаскивание, клик — настройка привязки/иконки/отображения, виртуальные устройства, правила иконок","mode.decor_tip":"Редактор подложки — чисто визуальный декор под планом: линии, прямоугольники, овалы и надписи, не реагирующие на клики","space.glow_enabled":"Свечение источников света","gs.glow_group":"Свечение источников света","gs.glow_base":"Темнота дома","gs.glow_light":"Цвет света по умолчанию / интенсивность","gs.wall_group":"Стены","gs.wall_fill":"Цвет заливки стен","gs.glow_radius":"Радиус свечения","gs.unit_m":"м","gs.unit_ft":"фут","marker.controls_label":"Управляет другими источниками света","marker.controls_hint":"При действии «Переключить» клик разом переключает все добавленные здесь источники. Собственная сущность маркера управляется напрямую и сюда не добавляется; чтобы считать её светом, включите флаг ниже.","marker.controls_filter":"Поиск ламп и выключателей…","info.controls":"Управляет","marker.glow_radius_label":"Радиус свечения","marker.glow_radius.help":"Задаёт радиус свечения в метрах или футах; пустое значение использует радиус из общих настроек.","marker.glow_radius.help.aria":"Подсказка: радиус свечения","markup.wallthick":"Толщина","markup.select":"Выбрать","title.markup_wallthick":"Толщина — клик по стене задаёт толщину от 0 до 100 см.","markup.hint_wallthick":"клик по стене · Esc закрывает без применения","wallthick.field":"Толщина","wallthick.unit_cm":"см","wallthick.unit_in":"дюйм","wallthick.apply_room":"Применить ко всем стенам комнаты","markup.draw_wall_title":"Толщина каждого нового сегмента стены (0–100 см). Общие стены сохраняют существующее значение.","room.queue_progress":"Комната {current} из {total}","toast.wall_rooms_saved":"Создано комнат: {n}","toast.wall_chain_saved":"Цепочка стен сохранена","toast.wallthick_pick":"Кликните по стене","toast.wallthick_set":"Толщина стены задана","toast.wallthick_cleared":"Толщина стены убрана","toast.physical_range":"Введите значение от {min} до {max} {unit}","toast.zero_wall_opening_conflict":"Сначала удалите проём на этом участке стены.","toast.zero_wall_ambiguous":"Не удалось однозначно выбрать участок стены. Уточните геометрию узла.","toast.zero_wall_migration_blocked":"Пространство не преобразовано: {reason}. Данные не изменены.","toast.physical_angle":"Введите угол поворота от 0° до 90°, не включая 90°","toast.physical_limit":"В пространстве достигнут лимит объектов этого типа","toast.geometry_unsafe":"Изменение отменено: геометрию стен нельзя безопасно построить.","junction.limit_angle":"Слишком острый угол между стенами: {actual}°, минимум {limit}°.","junction.limit_valence":"Слишком много стен в одном узле: {actual}, максимум {limit}.","junction.limit_length":"Слишком короткий участок стены: {actual} см, минимум {limit} см.","junction.limit_distance":"Стены и узлы слишком близко: {actual} см, минимум {limit} см.","junction.limit_clearance":"Внутри комнаты не остаётся места: {actual} см², минимум {limit} см².","toast.wall_model_migration_blocked":"Не удалось обновить модель стен: {reason}. План не изменён. Запустите «Оптимизировать планы»; если ошибка повторится, исправьте конфликтующую геометрию стен.","toast.wall_model_client_outdated":"Обновите карточку и перезагрузите страницу перед редактированием плана.","wall_model.reason.invalid-room":"некорректный контур комнаты","wall_model.reason.zero-length":"отрезок стены нулевой длины","wall_model.reason.third-owner":"стена принадлежит более чем двум комнатам","wall_model.reason.duplicate-id":"конфликт идентификаторов стен","wall_model.reason.thickness-conflict":"конфликт значений толщины стены","wall_model.reason.opening-host":"проём нельзя однозначно привязать к стене","toast.delete_room_pick":"Кликните внутри комнаты, которую нужно удалить","toast.plan_snap_ambiguous":"Увеличьте масштаб, чтобы выбрать узел стены","toast.wall_repair_ambiguous":"У контура несколько возможных соединений. Увеличьте масштаб и соедините стены явно.","toast.wall_repair_too_large":"Разрыв больше 2 см. Соедините стены перед созданием комнаты.","toast.wall_repair_changed":"Геометрия стен изменилась. Попробуйте создать комнату ещё раз.","toast.opening_on_zero_wall":"Проёмы на стене нулевой толщины запрещены","marker.from_ha_option":"Выбрать из списка HA","marker.show_entities":"Показывать сущности","marker.show_entities_tip":"Добавляет в список не только устройства, но и все их сущности","marker.pick_ph":"Выберите устройство…","room.open_area":"Открыть зону в HA","view.volumetric":"Объёмный вид","view.flat":"Плоский вид","kiosk.title":"Размеры на этом экране","kiosk.hint":"Хранится только на этом устройстве — у каждого настенного планшета или ТВ свои удобные размеры.","kiosk.icon_scale":"Размер значков устройств","kiosk.font_scale":"Размер текста карточек комнат","editor.kiosk":"Режим настенного устройства (киоск)","editor.cycle":"Автосмена пространств каждые N секунд (киоск, 0 = выкл)","room.settings_title":"Настройки комнаты","room.settings_section":"Настройки комнаты (переопределяют пространство)","room.fill_label":"Заливка в ЭТОЙ комнате","fill.inherit":"Как у пространства","room.custom_fill_space":"Цвет пространства","room.custom_fill_own":"Цвет комнаты","room.temp_src_label":"Источник температуры","room.hum_src_label":"Источник влажности","room.src_average":"Средняя по датчикам комнаты (по умолчанию)","room.src_pick":"Конкретное устройство или сущность HA","room.src_ph":"Выберите источник…","toast.room_updated":"Комната обновлена","space.card_font":"Размер шрифта карточек комнат (всё пространство)","room.sizes_section":"Размеры шрифтов","room.name_scale":"Размер названия","room.label_scale":"Размер подписей","preview.room_name":"Гостиная","toast.cfg_reload_failed":"Не удалось перечитать план с сервера: {err}","room.settings_short":"Настройки комнаты","room.unnamed":"Комната без имени","marker.use_climate_temp":"Учитывать температуру устройства в комнате","marker.use_climate_temp_tip":"Добавляет current_temperature кондиционера или термостата в среднюю температуру комнаты. Внешний бейдж со значением настраивается отдельно ниже.","marker.value_badge_title":"Бейдж со значением","marker.value_badge.help":"Показывает одно выбранное значение рядом со значком. Не влияет на комнатные показатели, свет, Glow и действие по нажатию.","marker.value_badge.help.aria":"Подсказка: бейдж со значением устройства","marker.value_badge_enabled":"Отображать бейдж со значением","marker.value_badge_source":"Значение","marker.value_badge_source.help":"Выберите конкретное состояние, поддерживаемый атрибут или производное значение этого устройства.","marker.value_badge_source.help.aria":"Подсказка: источник значения бейджа","marker.value_badge_position":"Расположение","marker.value_badge_position.help":"Выбранная сторона сохраняется постоянно и не переворачивается автоматически у края плана.","marker.value_badge_position.help.aria":"Подсказка: расположение бейджа","marker.value_badge_right":"Справа","marker.value_badge_bottom":"Снизу","marker.value_badge_left":"Слева","marker.value_badge_top":"Сверху","marker.value_badge_empty":"У этого устройства нет доступных значений","marker.value_badge_static":"Статичный значок не показывает живые значения. Настройка сохранится.","marker.value_badge_missing":"Источник недоступен","marker.value_badge_missing_hint":"Сохранённый источник сейчас недоступен. Можно сохранить его, отключить бейдж или выбрать другой.","marker.value_badge_duplicate":"То же значение уже показано внутри значка.","marker.value_badge_state":"Состояние · {name}","marker.value_badge_marker_state":"Состояние источника света · {name}","marker.value_badge_lqi":"Качество Zigbee-сигнала (среднее)","marker.value_badge_attr_current_temperature":"Текущая температура · {name}","marker.value_badge_attr_temperature":"Целевая температура · {name}","marker.value_badge_attr_current_humidity":"Текущая влажность · {name}","marker.value_badge_attr_humidity":"Влажность · {name}","marker.value_badge_attr_current_position":"Положение · {name}","marker.value_badge_attr_percentage":"Скорость · {name}","marker.value_badge_attr_brightness":"Яркость · {name}","marker.value_badge_attr_volume_level":"Громкость · {name}","marker.value_badge_attr_battery_level":"Заряд батареи · {name}","marker.value_badge_attr_fan_speed":"Скорость вентилятора · {name}","marker.light_role_label":"Является источником света","marker.light_role.help":"Определяет, является ли сам маркер пространственным источником света. Привязанные выше лампы остаются независимыми источниками для комнаты.","marker.light_role.help.aria":"Подсказка: является ли устройство источником света","marker.light_role_auto_yes":"Автоматически (источник света)","marker.light_role_auto_no":"Автоматически (не источник света)","marker.light_role_always":"Всегда источник света","marker.light_role_never":"Никогда не источник света","marker.light_entity_label":"Ведущая сущность света","marker.light_entity.help":"Для составного устройства выберите сущность, состояние, цвет и яркость которой представляют этот источник на плане. Автоматический вариант сохраняет совместимость со старыми планами.","marker.light_entity.help.aria":"Подсказка: ведущая сущность света","marker.light_entity_auto":"Автоматически ({entity})","marker.light_entity_none":"нет управляемой сущности","marker.light_entity_missing":"Сохранённая сущность {entity} недоступна. Временно используется {fallback}; выбор восстановится, если сущность вернётся.","marker.toggle_entity_label":"Переключаемая сущность","marker.toggle_entity.help":"Для составного устройства выберите собственную лампу или переключатель, которой управляет нажатие. Автоматический вариант сохраняет прежние правила цели и не зависит от ведущей сущности света.","marker.toggle_entity.help.aria":"Подсказка: переключаемая сущность","marker.toggle_entity_auto":"Автоматически ({entity})","marker.toggle_entity_none":"нет собственной управляемой сущности","marker.toggle_entity_missing":"Сохранённой сущности {entity} больше нет среди выбираемых каналов этого маркера. Временно используется {fallback}; выбор восстановится, если сущность вернётся.","marker.glow_color_label":"Цвет и яркость свечения","marker.glow_mode.help":"Используйте данные источника, задайте только цвет или зафиксируйте цвет и яркость. Минимум — 1%; чтобы отключить источник, выберите «Никогда».","marker.glow_mode.help.aria":"Подсказка: цвет и яркость свечения","marker.glow_mode_auto":"Из источника","marker.glow_mode_color":"Задать цвет","marker.glow_mode_fixed":"Задать цвет и яркость","marker.glow_color":"Цвет свечения","marker.glow_brightness":"Яркость","marker.glow_disabled_never":"Настройки свечения недоступны: маркер явно исключён из источников света.","marker.glow_disabled_auto":"В автоматическом режиме у этого маркера не найден пространственный источник света.","marker.glow_disabled_no_entity":"Для пространственного источника нет активной управляемой сущности Home Assistant.","marker.glow_passive_hint":"У источника нет собственных данных Home Assistant. Задайте цвет и яркость вручную; радиус остаётся доступным.","marker.control_broken":"Сохранённый источник отсутствует или больше не отмечен как источник света","marker.control_missing_label":"Отсутствующий источник на плане","marker.control_passive":"пассивный источник","toast.marker_control_cycle":"Такая связь создаст циклическую цепочку управления светом.","toast.marker_binding_required":"Сначала выберите устройство Home Assistant, затем добавьте управляемый источник света.","confirm.unlock":"Открыть замок «{name}»?","toast.files_migrate_failed":"Не удалось перенести вложения к новой привязке, ссылки остались на старые файлы: {err}","space.pick_saved":"Уже загруженные","space.pick_saved_hint":"Планы, сохранённые на сервере, включая отцеплённые ранее","space.no_saved":"На сервере пока нет сохранённых планов.","space.loading":"Загрузка…","space.used_by":"используется: {list}","space.in_use":"План используется пространством — сначала отцепите его","btn.use":"Выбрать","confirm.delete_plan":"Удалить файл плана «{name}» с сервера? Действие необратимо.","toast.plans_list_failed":"Не удалось получить список планов: {err}","toast.plan_delete_failed":"Не удалось удалить план: {err}","marker.hide":"Скрыть","marker.hide_tip":"Устройство исчезнет с плана после сохранения, но продолжит участвовать в расчёте сигнала комнаты. Вернуть его можно через каталог «Устройства» в редакторе устройств.","marker.show":"Показать","marker.show_tip":"Устройство снова появится на плане после сохранения.","marker.hidden_ghost":"Устройство скрыто пользователем","marker.ha_disabled_device":"Устройство деактивировано в Home Assistant и скрыто с плана.","marker.ha_disabled_entity":"Сущность деактивирована в Home Assistant и скрыта с плана.","marker.ha_disabled_all_entities":"У устройства нет активных сущностей Home Assistant, поэтому оно скрыто с плана.","marker.ha_registry_limited":"Полный реестр Home Assistant недоступен этому пользователю. Неподтверждённый объект временно нельзя показывать или использовать.","marker.delete_tip":"Полностью удалить устройство с плана и из всех расчётов. Позже его можно добавить заново.","tap.run":"Запустить автоматизацию/скрипт/сцену","tap.cover":"Открыть/закрыть (шторы/жалюзи)","marker.run_target_label":"Что запускать","marker.run_search_ph":"Поиск: автоматизация, скрипт или сцена…","marker.run_target_gone":"Цель {id} не найдена — выберите заново","marker.tap_confirm":"Спрашивать подтверждение","marker.tap_confirm_tip":"Перед выполнением показать диалог подтверждения — защита от случайных нажатий.","marker.toggle_hint_single":"Цель: {name} ({id}).","marker.virtual_light_target":"Виртуальный свет: {name}.","marker.virtual_light_current":"Ручное состояние: {state} → {effect}.","marker.virtual_light_state_on":"включён","marker.virtual_light_state_off":"выключен","marker.toggle_hint_group":"Переключатся источники ({count}): {names}.","marker.toggle_hint_current":"Сейчас: {state} → {effect}.","marker.toggle_hint_group_current":"Сейчас включено {on} из {count} → {effect}.","marker.toggle_hint_skipped":"Не будут затронуты ({count}): {targets}.","marker.toggle_effect_turn_on":"включится","marker.toggle_effect_turn_off":"выключится","marker.toggle_effect_open":"откроется","marker.toggle_effect_close":"закроется","marker.toggle_effect_stop":"остановится","marker.toggle_effect_toggle":"состояние переключится","marker.toggle_skip_missing":"не найдено","marker.toggle_skip_ha_disabled":"деактивировано в HA","marker.toggle_skip_unavailable":"недоступно","marker.toggle_skip_unsupported":"переключение не поддерживается","marker.toggle_skip_secure":"заблокировано из соображений безопасности","marker.toggle_none_no_binding":"У устройства нет привязки, состояние переключать нечем. По нажатию ничего не произойдёт.","marker.toggle_none_no_actionable_entity":"У устройства нет состояния, которое можно переключить. По нажатию ничего не произойдёт.","marker.toggle_none_configured_targets_missing":"Настроенные цели сейчас недоступны. Собственная сущность устройства не будет подставлена вместо них.","marker.toggle_none_ha_disabled":"Цель деактивирована в Home Assistant и не может использоваться на плане.","marker.toggle_none_unavailable":"Цель сейчас недоступна. По нажатию ничего не произойдёт.","marker.toggle_none_unsupported":"Для этой сущности Home Assistant не предоставляет безопасного переключения. По нажатию ничего не произойдёт.","marker.toggle_none_secure":"Переключение замков, сигнализации и защитных ворот с плана заблокировано из соображений безопасности.","run.automation":"автоматизация","run.script":"скрипт","run.scene":"сцена","confirm.tap_run":"Запустить «{name}»?","confirm.tap_toggle":"Переключить «{name}»?","confirm.tap_cover":"Открыть/закрыть «{name}»?","confirm.current_state":"Текущее состояние: {state}","confirm.expected_state":"После переключения: {state}","confirm.group_current":"включено {on} из {total}","confirm.group_all_on":"все включены","confirm.group_all_off":"все выключены","confirm.unavailable_targets":"Недоступно: {count}","confirm.expected_by_ha":"Состояние определит Home Assistant","confirm.state_on":"Включено","confirm.state_off":"Выключено","confirm.state_open":"Открыто","confirm.state_closed":"Закрыто","confirm.state_opening":"Открывается","confirm.state_closing":"Закрывается","confirm.state_stopped":"Остановлено","confirm.state_unknown":"Неизвестно","toast.run_started":"Запущено: {name}","toast.run_target_missing":"Цель запуска не найдена — проверьте настройки устройства","toast.run_target_required":"Выберите автоматизацию, скрипт или сцену","toast.tap_target_changed":"Цель действия изменилась. Повторите попытку.","toast.virtual_light_toggle_failed":"Не удалось переключить виртуальный свет: {err}","toast.value_badge_source_required":"Выберите значение для бейджа","btn.run":"Выполнить","vac.section":"Робот-пылесос: живая позиция","vac.autocal":"Настроить автоматически","vac.live":"Живая позиция на плане","vac.trail":"Показывать путь робота","vac.cal_maps":"Откалиброваны карты: {maps}","vac.autocal_no_rooms":"Интеграция не отдаёт список комнат — откройте «Подогнать вручную»","vac.autocal_no_match":"Не совпали имена комнат (нужно ≥3 общих) — откройте «Подогнать вручную»","vac.autocal_done":"Готово: привязка по {rooms} комнатам. Запустите уборку и проверьте","vac.cal_need_pos":"Робот сейчас не отдаёт координаты — запустите уборку и поставьте на паузу","vac.cal_done":"Калибровка сохранена. Запустите уборку и проверьте","vac.cal_cancelled":"Калибровка отменена","vac.fit":"Подогнать вручную","vac.fit_hint":"Перетащите карту робота на место, растяните за уголки","vac.fit_rotate":"Повернуть 90°","vac.fit_mirror":"Отразить","vac.trail_never":"Не показывать никогда","vac.trail_cleaning":"Во время уборки","vac.trail_always":"Показывать всегда","gs.bg_group":"Фон сцены","gs.bg_color":"Цвет фона вокруг плана","gs.bg_default":"Как в теме","gs.bg_theme":"по умолчанию — из темы","gs.bg_mode":"Фон плана","gs.bg_static":"Статичный цвет","gs.bg_daynight":"Следует за Солнцем","gs.bg_daynight_hint":"Фон проходит рассвет, день, закат и ночь по данным sun.sun, а при их недоступности — по локальным часам. Компас для фона не нужен.","gs.sun_group":"Солнце","gs.sun_missing":"Сущность sun.sun не найдена — фон следует локальным часам, а оконные лучи недоступны.","gs.north":"Север на плане","gs.north_ph":"не задан","gs.north_hint":"Север нужен только для оконных лучей (шаг 1°, с Shift 15°); солнечный фон работает без него.","gs.north_clear":"Сбросить","gs.north_letter":"С","gs.sun_rays":"Солнце в окнах","gs.about_group":"О карточке","gs.about_version":"Houseplan Card v{v}","gs.about_github":"GitHub · документация и issues","gs.about_telegram":"Чат в Telegram","space.bg_color":"Цвет фона вокруг плана","space.bg_inherit":"Наследовать общий","space.bg_inherited":"наследуется из общих настроек","space.bg_mode":"Фон плана","space.north":"Север на плане (переопределение)","space.north_inherited":"наследуется: {v}","space.sun_rays":"Солнце в окнах","space.sun_inherit":"Наследовать общий","space.sun_on":"Вкл","space.sun_off":"Выкл","canvas.far_objects":"Объектов далеко от плана: {n}","canvas.show_far":"Показать","canvas.home_tip":"План там — нажмите, чтобы вписать","gs.grid_group":"Обслуживание планов","gs.grid_hint":"Обновляет модели данных, выравнивает элементы по сетке и объединяет лишние фрагменты стен. Перед записью будет показан точный отчёт.","gs.align_all":"Оптимизировать планы","gs.align_title":"Оптимизировать планы","gs.align_none":"Все планы уже используют актуальную и оптимальную модель данных.","gs.optimize_no_automatic_changes":"Автоматических изменений нет. Проверьте пункты ниже.","gs.align_count":"Сдвинется элементов: {n} из {total}, максимум на {cm} см.","gs.align_where":"Наибольший сдвиг — в пространстве «{s}».","gs.align_turned":"Проёмов с исправлением угла: {n}.","gs.align_removed_drafts":"Схлопнувшиеся на сетке некорректные контуры удалены: {n}.","gs.optimize_redundant_drafts":"Сохранённые цепочки стен, полностью скрытые стенами комнат, удалены: {n}.","gs.align_preflight_failed":"Не удалось безопасно проверить геометрию следующих пространств: {spaces}{more}.","gs.align_preflight_hint":"Планы не изменены. Скопируйте диагностику кнопкой ниже и приложите её к отчёту об ошибке вместе с экспортом пространства.","gs.preflight_reason_prepare-exception":"Не удалось подготовить геометрию пространства (исключение при сборке модели)","gs.preflight_reason_wall-null":"Тело стен не построилось (объединение вернуло пустоту)","gs.preflight_reason_wall-degraded-extra":"Тело стен деградировало с лишней геометрией","gs.preflight_reason_wall-failed-core":"Ядро тела стен не собралось","gs.preflight_reason_wall-exception":"Построение стен упало с исключением","gs.preflight_reason_floor-null":"Контур пола не построился","gs.preflight_reason_floor-exception":"Построение пола упало с исключением","gs.preflight_copy":"Скопировать диагностику","gs.preflight_copied":"Диагностика скопирована","gs.preflight_update_hint":"Версии карточки и интеграции различаются — обновите House Plan и повторите.","gs.align_preflight_space":"Пространство {n}","gs.align_preflight_more":" и ещё {n}","gs.optimize_changes":"Миграций модели: {m}; обновлено пространств: {c}; устранён шум координат: {p}; объединено отрезков реальных стен: {w}; объединено отрезков стен нулевой толщины: {s}; независимых: {i}.","gs.zero_walls_migrated":"Преобразовано виртуальных участков: {n}.","gs.wall_segments_migrated":"Стабилизировано сегментов стен: {n}.","gs.optimize_lattice_summary":"Канонизировано шумовых значений координат: {n}; максимальный сдвиг: {cm} см.","gs.optimize_lattice_space":"{space}: канонизировано значений координат: {n}; оставлено значений вне сетки: {far}.","gs.optimize_coincident_partitions":"Скрытые участки независимых стен поглощены стенами комнат: {n}.","gs.optimize_openings_rehosted":"Проёмы перепривязаны к стенам комнат: {n}.","gs.optimize_walls_straightened":"Выпрямлено стен: {n}; максимальное перемещение: {cm} см.","gs.optimize_walls_straightened_where":"Максимальная правка стены: {s}.","gs.optimize_walls_straighten_skipped":"Оставлено почти осевых стен, которые нельзя безопасно выпрямить: {n}.","gs.optimize_glow_migration":"Старый Glow: пространств — {spaces} → без заливки данных + независимый Glow; комнат — {rooms} → наследуемая заливка + независимый Glow.","gs.optimize_references":"Исправлено ссылок: пространства — {spaces}; комнаты — {rooms}; позиции — {positions}; устройств отвязано от отсутствующих пространств — {detached}.","gs.optimize_reference_more":", и ещё {n}","gs.optimize_orphans_removed":"Убрано забытых записей: {total} — подписи комнат: {rooms}; устройства: {devices}; групповые метки: {groups}. Все они принадлежали пространствам, удалённым ранее.","gs.optimize_live_positions":"Старые позиции в удалённых пространствах принадлежат существующим объектам: {n}{names}. Они будут сохранены.","gs.optimize_live_positions_remove":"Старые позиции в удалённых пространствах принадлежат существующим объектам: {n}{names}. Они выбраны для удаления.","gs.optimize_live_names":": {names}{more}","gs.optimize_live_remove":"Убрать старые позиции","gs.optimize_live_keep":"Сохранить старые позиции","gs.optimize_live_selected":"Старые позиции будут убраны после применения оптимизации.","gs.optimize_unverified":"Не удалось безопасно проверить позиций: {n}. Они оставлены без изменений.","gs.optimize_registry_limited":"Для безопасной проверки нужен полный доступ администратора к реестрам Home Assistant.","gs.optimize_vacuum_warning":"Сопоставления комнат пылесоса требуют проверки: {n}.","gs.optimize_details":"Подробности","gs.optimize_details_more":"И ещё записей: {n}.","gs.optimize_detail_removed":"будет удалено","gs.optimize_detail_live":"будет сохранено","gs.optimize_detail_unverified":"не проверено","gs.optimize_detail_room_label":"подпись комнаты","gs.optimize_detail_device":"устройство","gs.optimize_detail_group":"групповая метка","gs.optimize_detail_unknown":"неизвестный владелец","gs.optimize_detail_item":"{status}: {kind} {id}; прежнее пространство {space}","gs.align_warn":"Элементы, намеренно поставленные между узлами, будут сдвинуты. После операции доступна одна отмена — только до следующего изменения плана.","gs.align_run":"Оптимизировать","gs.align_done":"Планы оптимизированы: сдвинуто элементов — {n}, обслужено записей — {m}, исправлено ссылок — {r}","gs.optimize_undo":"Отменить последнюю оптимизацию","gs.optimize_undone":"Последняя оптимизация отменена","decor.furniture":"Мебель","furn.title":"Библиотека мебели","furn.symbol":"Символ","furn.group_furniture":"Мебель","furn.group_appliance":"Техника","furn.group_sanitary":"Сантехника","furn.group_other":"Прочее","furn.width":"Ширина","furn.depth":"Глубина","furn.pick_hint":"Выберите символ и кликните по плану.","furn.place_hint":"Кликните по плану — предмет встанет к ближайшей стене. Shift — свободно.","furn.sym_sofa":"Диван","furn.sym_armchair":"Кресло","furn.sym_coffee_table":"Журнальный столик","furn.sym_table_dining":"Обеденный стол","furn.sym_table_round":"Круглый стол","furn.sym_chair":"Стул","furn.sym_desk":"Письменный стол","furn.sym_bed_double":"Двуспальная кровать","furn.sym_bed_single":"Односпальная кровать","furn.sym_nightstand":"Тумбочка","furn.sym_wardrobe":"Шкаф","furn.sym_bookshelf":"Стеллаж","furn.sym_fridge":"Холодильник","furn.sym_stove":"Плита","furn.sym_dishwasher":"Посудомоечная машина","furn.sym_washer":"Стиральная машина","furn.sym_dryer":"Сушильная машина","furn.sym_tv":"Телевизор","furn.sym_ac":"Кондиционер","furn.sym_water_heater":"Бойлер","furn.sym_toilet":"Унитаз","furn.sym_bathtub":"Ванна","furn.sym_shower":"Душ","furn.sym_sink":"Раковина","furn.sym_kitchen_sink":"Кухонная мойка","furn.sym_bidet":"Биде","furn.sym_stairs":"Лестница","furn.sym_fireplace":"Камин","furn.sym_plant":"Растение","furn.sym_rug":"Ковёр","common.yes":"Да","common.no":"Нет","vac.diag_source":"Источник","vac.diag_platform":"Интеграция","vac.diag_status":"Статус","vac.diag_position":"Позиция","vac.diag_rooms":"Комнаты","vac.diag_rooms_value":"{total} · совпало имён: {matched} · {readiness}","vac.autocal_ready":"автокалибровка доступна","vac.autocal_not_ready":"нужно 3 совпавших имени","vac.diag_path":"Путь интеграции","vac.diag_map":"ID карты","vac.source_none":"не выбран","vac.source_status_ok":"Готов","vac.source_status_missing":"Не найден","vac.source_status_disabled":"Деактивирован в Home Assistant","vac.source_status_unavailable":"Недоступен","vac.source_status_unverified":"Нельзя проверить с текущими правами","vac.source_status_unsupported":"Нет данных позиции","vac.source_status_none":"Нет источника","vac.source_banner_missing":"Сохранённый источник больше не существует. Он не заменён автоматически: выберите другой или восстановите его в Home Assistant.","vac.source_banner_disabled":"Сохранённый источник деактивирован в Home Assistant. Активируйте его там или выберите другой.","vac.source_banner_unverified":"Текущих прав Home Assistant недостаточно для проверки источника. Привязка сохранена и не будет заменена автоматически.","vac.choose_source":"Выбрать источник","vac.source_auto":"Автоматически","vac.source_auto_hint":"Использовать совместимую сущность этого устройства","vac.all_cameras":"Все камеры","vac.all_cameras_warn":"Камера может не отдавать данные робота. Выбирайте её только если это карта вашего пылесоса.","vac.all_cameras_empty":"Других сущностей камеры не найдено.","vac.platform_unknown":"интеграция неизвестна","vac.cap_position":"позиция","vac.cap_rooms_short":"комнаты","vac.cap_path":"путь","vac.cap_map":"ID карты","vac.cap_none":"данные робота не обнаружены","vac.xcme_hint":"Включите атрибуты Xiaomi Cloud Map Extractor:","vac.documentation":"Документация","vac.residual_title":"Проверьте автокалибровку","vac.residual_message":"Совпавшие комнаты расходятся максимум на {error}. Примените приблизительную калибровку, подгоните её вручную либо отмените без изменения сохранённых настроек.","vac.apply_proposal":"Применить","gs.backup_group":"Резервная копия и перенос","gs.backup_hint":"Скачайте переносимую JSON-копию или проверьте и импортируйте копию, созданную House Plan.","backup.export_open":"Экспорт","backup.import_open":"Импорт","backup.export_title":"Экспорт House Plan","backup.import_title":"Импорт House Plan","backup.export_hint":"Выберите, должна ли копия содержать всю конфигурацию House Plan или только текущее пространство.","backup.full":"Полная копия","backup.current_space":"Текущее пространство","backup.current_space_title":"Текущее пространство: {title}","backup.no_current_space":"Нет текущего пространства","backup.plan_only":"Только планировка","backup.plan_only_hint":"Сохранить комнаты, стены, проёмы, декор и позиции подписей комнат без устройств и привязок Home Assistant.","backup.plan_only_preview":"Файл содержит только планировку","backup.privacy_warning":"Архив сохраняет названия, идентификаторы Home Assistant и точные координаты. Внутренние планы и вложения указываются ссылками, но не вкладываются; текущие состояния и маршруты пылесосов не включаются.","backup.download":"Скачать JSON","backup.export_done":"Резервная копия скачана","backup.reading":"Проверяем резервную копию…","backup.revalidated":"После предпросмотра план изменился. Сводка обновлена — проверьте её и подтвердите ещё раз.","backup.error.unauthorized":"У вас нет прав на экспорт или импорт этого плана.","backup.error.not_ready":"House Plan ещё не готов. Повторите попытку через несколько секунд.","backup.error.too_large":"Размер резервной копии превышает 8 МиБ.","backup.error.invalid_json":"Выбранный файл не является корректным JSON.","backup.error.invalid_format":"Выбранный файл не является резервной копией House Plan.","backup.error.unsupported_export_version":"Эта версия формата резервной копии не поддерживается установленной версией.","backup.error.future_model":"Резервная копия создана в более новой версии модели данных House Plan.","backup.error.invalid_config":"Резервная копия содержит некорректную конфигурацию House Plan.","backup.error.wall_model_migration_blocked":"Не удалось безопасно обновить модель стен из резервной копии. Сначала оптимизируйте исходный план и повторите экспорт.","backup.error.invalid_layout":"Резервная копия содержит некорректные позиции объектов.","backup.error.invalid_content":"Резервная копия содержит некорректные или несогласованные ссылки на файлы.","backup.error.space_not_found":"Выбранное пространство больше не существует.","backup.error.capacity_exceeded":"Добавление этой копии превысит ограничения размера плана.","backup.error.preview_expired":"Время предпросмотра истекло. Выберите файл резервной копии заново.","backup.error.preview_owner_mismatch":"Этот предпросмотр принадлежит другому пользователю Home Assistant.","backup.error.conflict":"После предпросмотра план изменился. Проверьте обновлённую сводку.","backup.error.content_confirmation_required":"Подтвердите отсоединение недоступных локальных файлов.","backup.error.commit_failed":"Не удалось безопасно применить копию. Предыдущий план восстановлен или ожидает восстановления.","backup.error.missing_plan":"После предпросмотра исчез связанный файл плана. Проверьте копию ещё раз.","backup.error.missing_content":"После предпросмотра исчез связанный локальный файл. Проверьте копию ещё раз.","backup.error.marker_control_missing":"В резервной копии отсутствует связанный источник света на плане.","backup.error.marker_control_not_light":"Связанная цель больше не отмечена как источник света.","backup.error.marker_control_self":"Источник света не может управлять самим собой.","backup.error.marker_control_cycle":"Резервная копия содержит циклическую цепочку управления светом.","backup.error.duplicate_marker_control":"Резервная копия содержит повторяющуюся связь с источником света.","backup.error.no_backup":"Нет снимка импорта или оптимизации, который можно восстановить.","backup.same_source":"Создано на этом экземпляре Home Assistant","backup.foreign_source":"Создано на другом экземпляре Home Assistant","backup.created":"Создано: {value}","backup.versions":"Карточка {card}; интеграция {integration}; модель данных {model}","backup.count_spaces":"Пространств: {n}","backup.count_rooms":"Комнат: {n}","backup.count_walls":"Стен: {n}","backup.count_openings":"Проёмов: {n}","backup.count_decor":"Объектов декора: {n}","backup.count_markers":"Устройств: {n}","backup.count_layout":"Позиций: {n}","backup.bindings":"Привязки — устройства: {device}, сущности: {entity}, виртуальные: {virtual}; позиций без пространства: {legacy}","backup.binding_status":"Статус на целевом экземпляре — активных: {active}, деактивированных: {disabled}, отсутствующих: {missing}","backup.missing_areas":"На целевом экземпляре отсутствуют зоны: {areas}","backup.dropped_marker_links":"Связи с источниками света вне переносимого пространства пропущены: {n}.","backup.repaired_target_refs":"Существующих ссылок восстановлено этим импортом: {n}.","backup.preserved_unresolved_refs":"Неоднозначные ссылки сохранены без изменений: {n}.","backup.preserved_unresolved_hint":"House Plan ничего не угадывал и не удалял. После импорта запустите «Оптимизировать планы», чтобы проверить оставшиеся ссылки.","backup.import_details":"Подробности восстановления ссылок","backup.import_detail.incoming_remapped":"Ссылок обновлено внутри импортируемой копии: {n}","backup.import_detail.target_repaired":"Существующих ссылок восстановлено: {n}","backup.import_detail.preserved_unresolved":"Неразрешимых ссылок сохранено: {n}","backup.import_detail.collisions":"Конфликтов назначения безопасно сохранено: {n}","backup.import_detail.dropped_links":"Входящих связей пропущено по правилам переноса: {n}","backup.import_detail.bounded_lineages":"Чрезмерно вложенных идентификаторов ограничено: {n}","backup.replace_warning":"Текущая конфигурация и расположение будут заменены. Загруженные файлы не удаляются. Одну отмену можно выполнить до следующего изменения плана.","backup.foreign_bookkeeping":"Служебные списки известных и новых устройств другого экземпляра импортированы не будут.","backup.final_name":"Название нового пространства","backup.target_settings":"Глобальные настройки целевого экземпляра не изменятся.","backup.duplicates":"Уже существующих привязок: {n}","backup.skip":"Пропустить повторяющиеся устройства","backup.virtual_copy":"Добавить безопасные статичные виртуальные копии","backup.content":"Связанное содержимое","backup.content_available":"доступно локально","backup.content_external":"внешняя ссылка","backup.content_detach_required":"будет отвязано","backup.confirm_detach":"Я понимаю, что недоступные внутренние планы и вложения будут отвязаны от импортируемой конфигурации.","backup.replace":"Заменить","backup.add":"Добавить пространство","backup.space_done":"Пространство импортировано: комнат — {rooms}, устройств — {markers}, существующих ссылок восстановлено — {refs}","backup.full_done":"Копия восстановлена: пространств — {spaces}, комнат — {rooms}, устройств — {markers}","backup.undo_import":"Отменить последний полный импорт","backup.import_undone":"Полный импорт отменён"}};function ra(e,t){if(t&&t in aa)return t;return(e?.locale?.language||e?.language||"en").toLowerCase().startsWith("ru")?"ru":"en"}function la(e,t,i){return ss(aa[e][t]??oa[t]??t,i)}function ca(e,t){const i=aa[e][t]??aa.en[t];return"string"==typeof i&&i.trim().length>0}class ha extends he{constructor(){super(...arguments),this.deviceName="",this._metadataConnection=null,this._demoUntil=0,this._demoTimer=0,this._demoGeneration=1,this._demoKind=null,this._reducedMotion=!1,this._onMotionChange=e=>{this._reducedMotion=e.matches,this.requestUpdate()},this._startShortDemo=()=>{const e=this.presentation;e&&"icon_ripple"===e.display&&"none"===e.pulse.kind&&(this._demoGeneration++,this._demoKind="short",this._demoUntil=Date.now()+3300,window.clearTimeout(this._demoTimer),this._demoTimer=window.setTimeout(()=>{this._demoUntil=0,this._demoTimer=0,this._demoKind=null,this.requestUpdate()},3330),this.requestUpdate())},this._toggleContinuousDemo=()=>{const e=this.presentation;e&&"icon_ripple"===e.display&&"none"===e.pulse.kind&&("continuous"===this._demoKind?this._clearDemo():(this._clearDemo(),this._demoGeneration++,this._demoKind="continuous",this._demoUntil=Number.POSITIVE_INFINITY),this.requestUpdate())}}connectedCallback(){super.connectedCallback(),this._motionMedia=window.matchMedia?.("(prefers-reduced-motion: reduce)"),this._reducedMotion=!!this._motionMedia?.matches,this._motionMedia?.addEventListener?.("change",this._onMotionChange),this._ensureMetadata()}disconnectedCallback(){this._metadataRelease?.(),this._metadataRelease=void 0,this._metadataConnection=null,this._clearDemo(),this._motionMedia?.removeEventListener?.("change",this._onMotionChange),this._motionMedia=void 0,super.disconnectedCallback()}willUpdate(e){e.has("hass")&&this._ensureMetadata();const t=this.presentation,i=e.get("presentation");e.has("presentation")&&i?.binding!==t?.binding&&this._clearDemo(),t&&this._demoKind&&("icon_ripple"!==t.display||"none"!==t.pulse.kind)&&this._clearDemo()}_ensureMetadata(){const e=this.hass?.connection||null;e&&e!==this._metadataConnection&&(this._metadataRelease?.(),this._metadataConnection=e,this._metadataRelease=Qo(this.hass,()=>this.requestUpdate()))}_clearDemo(){window.clearTimeout(this._demoTimer),this._demoTimer=0,this._demoUntil=0,this._demoKind=null}get _lang(){return ra(this.hass)}_t(e,t){return la(this._lang,e,t)}_providerText(e){return"houseplan"===e.domain?this._t("marker.preview.virtual_provider"):e.label.toLowerCase()===e.domain.toLowerCase()?e.domain:`${e.label} (${e.domain})`}_providers(){return this.presentation&&this.registry?function(e,t,i,s=ea(e)){if("virtual"===t)return[{domain:"houseplan",label:"House Plan",confidence:"registry-owner"}];const n=t.indexOf(":");if(n<1)return[];const o=t.slice(0,n),a=t.slice(n+1);if("entity"===o){const t=na(e,a,i,s);return t?[t]:[]}if("device"!==o)return[];const r=i.devices?.[a]||e?.devices?.[a];if(!r)return[];const l=[r.config_entry_id,...Array.isArray(r.config_entries)?r.config_entries:[]].filter(e=>"string"==typeof e&&!!e).map(t=>{const i=s.configEntries[t];return ia(e,i?.domain,"registry-owner",s,t)});if(l.some(Boolean))return sa(l);const c=[];for(const[t,n]of Object.entries(i.entities||{}))n?.device_id===a&&null==n?.disabled_by&&c.push(na(e,t,i,s));return c.some(Boolean)?sa(c):sa((Array.isArray(r.identifiers)?r.identifiers:[]).map(t=>{const i=Array.isArray(t)?t[0]:null;return ia(e,i,"identifier-fallback",s)}))}(this.hass,this.presentation.binding,this.registry,ea(this.hass)):[]}_providerSummary(e){if(!e.length)return this._t("marker.preview.unknown_provider");const t=e.slice(0,2).map(e=>this._providerText(e)),i=e.length-t.length;return t.join(", ")+(i>0?` · ${this._t("marker.preview.more_sources",{n:i})}`:"")}_sourceSummary(e){const t=e.visualSources;return t.length?1===t.length?`${t[0].name} · ${t[0].eid} · ${this._sourceProvider(t[0].eid)}`:2===t.length?t.map(e=>e.name).join(" · "):this._t("marker.preview.multiple_sources",{n:t.length}):this._t("marker.preview.no_source")}_stateSummary(e){if(!e.visualSources.length)return this._t("marker.preview.no_state");if(1===e.visualSources.length)return e.visualSources[0].stateText||this._t("marker.preview.no_state");const t=[...new Set(e.visualSources.map(e=>e.stateText).filter(Boolean))];return 1===t.length?t[0]:this._t("marker.preview.mixed_states")}_reason(e){return this._t(`marker.preview.reason.${e}`)}_sourceProvider(e){if(!this.registry)return this._t("marker.preview.unknown_provider");const t=na(this.hass,e,this.registry,ea(this.hass));return t?this._providerText(t):this._t("marker.preview.unknown_provider")}render(){const e=this.presentation;if(!e)return G;const t=!!this._demoKind&&this._demoUntil>Date.now()&&"icon_ripple"===e.display&&"none"===e.pulse.kind,i=t?(()=>{const t=function(e,t,i,s,n=null){return{kind:t,reason:"short"===t?"event":"running",generation:Math.max(1,Math.trunc(i)),expiresAt:"short"===t?n:null,color:e.color,diameterScale:s?1:e.diameterScale,animated:!s,reducedMotionIndicator:s?"dot":"none"}}(e.pulse,this._demoKind,this._demoGeneration,this._reducedMotion,"short"===this._demoKind?this._demoUntil:null);return{...e,pulse:t,classes:[...e.classes.filter(e=>!e.startsWith("pulse-")),`pulse-${t.kind}`,...t.generation%2==0?["pulse-gen2"]:[]]}})():e,s=this._providers(),n="none"!==e.pulse.kind,o=i.scale*(i.pulse.animated?i.pulse.diameterScale:1);let a=-o/2,r=o/2,l=-o/2,c=o/2;if(i.valueBadge){const e=i.scale*Math.min(4,Math.max(.9,.29*i.valueBadge.text.length+.28)),t=.7*i.scale,s=.6*i.scale;"right"===i.valueBadge.position&&(r=Math.max(r,s+e)),"left"===i.valueBadge.position&&(a=Math.min(a,-s-e)),"top"===i.valueBadge.position&&(l=Math.min(l,-s-t)),"bottom"===i.valueBadge.position&&(c=Math.max(c,s+t))}if(null!=i.lqiText){const e=i.scale*("bottom"===i.valueBadge?.position?1.55:.95);c=Math.max(c,e)}const h=Math.min(1,2.35/Math.max(1,r-a),2.35/Math.max(1,c-l)),d=Math.round(100*h),p=[`left:calc(50% - ${54*((a+r)/2)*h}px)`,`top:calc(50% - ${54*((l+c)/2)*h}px)`,h<1?`transform:scale(${h})`:""].filter(Boolean).join(";"),u=["dev",Uo(this.hass),...i.classes,"virtual"===i.binding?"virtual":"",i.haDisabled?"ghost ha-disabled":"",null!=i.valueText?"valonly":""].filter(Boolean).join(" "),_=Go(i).join(";"),m=t?this._t("continuous"===this._demoKind?"marker.preview.demo_continuous_notice":"marker.preview.demo_short_notice"):this._reason(e.explanation.reason),g=[this.deviceName,this._providerSummary(s),this._stateSummary(e),m,e.valueFullText||"",Io(e.valueBadge),null!=e.lqiText&&e.lqiBand?this._t(`marker.lqi_a11y_${e.lqiBand}`,{value:e.lqiText}):""].filter(Boolean).join(". ");return q`
+ `}function Yo(e,t,i){return{kind:"none",reason:"none",generation:e,expiresAt:null,color:t,diameterScale:i,animated:!1,reducedMotionIndicator:"none"}}const Jo=new WeakMap;function Xo(e){const t=function(e){const t=e?.connection||e;return!t||"object"!=typeof t&&"function"!=typeof t?null:t}(e);if(!t)return null;let i=Jo.get(t);return i||(i={revision:0,loaded:!1,configEntries:{},manifests:{},listeners:new Set,refs:0},Jo.set(t,i)),i}function Zo(e){e.revision++;for(const t of[...e.listeners])try{t()}catch{}}function Qo(e,t){const i=Xo(e);if(!i)return()=>{};i.refs++,i.listeners.add(t),async function(e,t){t.loading||"function"!=typeof e?.callWS?t.loading:t.loaded&&t.loadedAt&&Date.now()-t.loadedAt<3e5||(t.loading=(async()=>{const[i,s]=await Promise.allSettled([e.callWS({type:"config_entries/get"}),e.callWS({type:"manifest/list"})]);"fulfilled"===i.status&&Array.isArray(i.value)&&(t.configEntries=Object.fromEntries(i.value.filter(e=>"string"==typeof e?.entry_id).map(e=>[e.entry_id,e]))),"fulfilled"===s.status&&Array.isArray(s.value)&&(t.manifests=Object.fromEntries(s.value.filter(e=>"string"==typeof e?.domain).map(e=>[e.domain,e]))),t.loaded=!0,t.loadedAt=Date.now(),t.loading=void 0,Zo(t)})().catch(()=>{t.loaded=!0,t.loadedAt=Date.now(),t.loading=void 0,Zo(t)}),t.loading)}(e,i),async function(e,t){if(t.unsubscribe||t.subscribing)return t.subscribing;const i=e?.connection?.subscribeMessage;"function"==typeof i&&(t.subscribing=(async()=>{try{t.unsubscribe=await i.call(e.connection,e=>{const i=Array.isArray(e)?e:Array.isArray(e?.entries)?e.entries:e?[e]:[];let s=!1;const n={...t.configEntries};for(const e of i){const t=e?.entry||e?.data?.entry||("string"==typeof e?.entry_id?e:null),i=t?.entry_id;if("string"!=typeof i)continue;const o=e?.type||e?.action||e?.data?.action;"removed"===o||"remove"===o?delete n[i]:n[i]=t,s=!0}s&&(t.configEntries=n,Zo(t))},{type:"config_entries/subscribe"})}catch{}finally{0===t.refs&&(t.unsubscribe?.(),t.unsubscribe=void 0),t.subscribing=void 0}})(),t.subscribing)}(e,i);let s=!1;return()=>{s||(s=!0,i.listeners.delete(t),i.refs=Math.max(0,i.refs-1),i.refs||(i.unsubscribe?.(),i.unsubscribe=void 0))}}function ea(e){const t=Xo(e);return t?{revision:t.revision,loaded:t.loaded,configEntries:t.configEntries,manifests:t.manifests}:{revision:0,loaded:!1,configEntries:{},manifests:{}}}function ta(e,t,i=ea(e),s){const n=i.manifests[t];return function(e,t){if("function"!=typeof e?.localize)return"";try{const i=`component.${t}.title`,s=e.localize(i);return"string"==typeof s&&s!==i?s:""}catch{return""}}(e,t)||String(n?.name||"")||String(s||"")||t.replace(/_/g," ")}function ia(e,t,i,s,n){const o=String(t||"").trim();if(!o)return null;const a=n?s.configEntries[n]:null;return{domain:o,label:ta(e,o,s,a?.title),configEntryId:n,configEntryTitle:a?.title,confidence:i}}function sa(e){const t={"registry-owner":0,"entity-platform":1,"identifier-fallback":2},i=new Set;return e.filter(e=>!!e).sort((e,i)=>t[e.confidence]-t[i.confidence]||e.label.localeCompare(i.label)||e.domain.localeCompare(i.domain)).filter(e=>{const t=`${e.domain}\n${e.configEntryId||""}`;return!i.has(t)&&(i.add(t),!0)})}function na(e,t,i,s=ea(e)){const n=i.entities?.[t]||e?.entities?.[t];if(!n)return null;const o=n.config_entry_id||void 0,a=o?s.configEntries[o]?.domain:"";return ia(e,n.platform||a,"entity-platform",s,o)}var oa={"editor.context_actions":"Actions: {object}","editor.tool_options":"Tool options: {tool}","editor.palette":"Palette: {tool}","editor.open_group":"Tool group: {group}","editor.group_active":"{group} — active: {item}","editor.disabled_action":"{action} is unavailable: {reason}","color_picker.title":"Color picker","color_picker.hue":"Hue","color_picker.saturation":"Saturation","color_picker.value":"Brightness","color_picker.hex":"Hex color","color_picker.invalid_hex":"Enter a 3- or 6-digit hex color","btn.properties":"Properties","btn.keep_as_walls":"Keep as walls","btn.delete_room_keep_walls":"Delete room, keep walls","btn.delete_room_with_walls":"Delete room and walls","title.markup_select":"Select and edit walls, columns and saved outlines","title.markup_column":"Column: click a grid point to place a square column","markup.partition":"Partition","markup.column":"Column","markup.hint_column":"click a grid point to place a square column","history.draft_segment":"Add room-draft segment","history.draft_merge":"Join unfinished room outlines","history.draft_segment_delete":"Remove room-draft segment","history.partition_add":"Add partition","history.column_add":"Add column","history.physical_edit":"Change physical object","history.physical_delete":"Delete physical object","history.physical_move":"Move physical object","history.contour_to_partitions":"Convert contour to closed walls","history.wall_chain_finish":"Finish wall chain","history.wall_face_batch":"Create rooms from walls","toast.column_duplicate":"A column with the same centre and outer size already exists","confirm.delete_draft":"Delete the whole unfinished room contour?","confirm.delete_draft_segment":"Delete this draft segment? The remaining contour may split in two.","physical.partition_properties":"Partition properties","physical.column_properties":"Column properties","physical.draft_properties":"Draft segment properties","physical.shape":"Shape","physical.square":"Square","physical.circle":"Circle","physical.diameter":"Diameter","physical.side":"Side","physical.rotation":"Rotation angle","physical.length":"Length","physical.allowed_range":"Allowed: {min}–{max} {unit}","physical.delete_segment":"Delete segment","physical.delete_draft":"Delete entire outline","physical.column_size_title":"Outer side of the square column placed by the click (1–150 cm).","card.title":"House plan","count.devices":"{n} dev.","empty.no_spaces":"No spaces yet.","empty.add_first":"Add the first space and upload a floor plan.","empty.install":'Install the House Plan integration and add it in "Devices & services".',"btn.add_space":"Add space","btn.cancel":"Cancel","btn.save":"Save","btn.close":"Close","btn.delete":"Delete","btn.edit":"Edit","btn.open_in_ha":"Open in HA","btn.reset":"Reset","btn.attach":"Attach…","btn.upload":"Upload…","btn.replace":"Replace…","title.zoom_in":"Zoom in","title.zoom_out":"Zoom out","title.zoom_fit":"Fit all","title.add_device":"Add a device to the plan","title.show_all":"Show hidden and disabled devices as service markers (this tab only)","title.markup":"Room markup: grid, lines, outlines","title.configure_space":"Configure space","title.add_space":"Add space","title.markup_add":"Walls: draw a continuous chain; Shift locks to 45°. Changing tool or leaving the editor finishes it as independent walls","title.markup_merge":"Merge: click one room, then the neighbour it shares a wall with","title.markup_split":"Split a room: click the room, then two points on its walls","title.markup_delroom":"Delete room: click inside a room and confirm","title.need_plan":"Upload a floor-plan image","markup.add":"Walls","markup.merge":"Merge","markup.split":"Split","markup.resize":"Resize","title.markup_resize":"Resize rooms: drag an available horizontal or vertical wall handle","markup.hint_resize":"drag an available wall handle · the wall stops at the first unsafe position · Esc cancels · Ctrl+Z — undo","resize.disabled.diagonal":"This wall is angled; Resize supports only horizontal and vertical walls","resize.disabled.side-angle":"An adjoining wall is angled; Resize requires both adjoining walls to meet this wall at right angles","resize.disabled.duplicate-physical-wall":"A separate partition, unfinished outline, or column overlaps this wall; remove or move it before resizing","resize.disabled.partial-shared":"A neighbouring room uses only part of this wall, so it cannot be moved safely as one shared wall","resize.disabled.unequal-shared":"The neighbouring room uses different endpoints or wall length, so the walls cannot move together safely","resize.disabled.multiple-rooms":"Moving this wall would affect more than two rooms","resize.disabled.thickness-conflict":"The wall thickness cannot be preserved safely","resize.disabled.opening-conflict":"An opening on this wall cannot be moved safely","resize.disabled.invalid-geometry":"This wall cannot be resized without changing the plan structure","resize.limit_stopped":"Wall stopped: the next step would break a junction limit","resize.commit_failed":"Resize was cancelled because the final plan did not pass the geometry check","resize.preview_failed":"Resize stopped at the last safe position because the plan geometry could not be preserved","markup.opening":"Opening","markup.delete_room":"Delete room","history.undo":"Undo","history.redo":"Redo","history.undo_named":"Undo: {name} (Ctrl+Z)","history.redo_named":"Redo: {name} (Ctrl+Shift+Z / Ctrl+Y)","history.undo_empty":"Nothing to undo","history.redo_empty":"Nothing to redo","history.undone":"Undone: {name}","history.redone":"Redone: {name}","history.add_room":"Create room","history.split_room":"Split room","history.merge_rooms":"Merge rooms","history.resize_room":"Resize room","history.wall_thickness":"Change wall thickness","history.add_opening":"Add door or window opening","history.edit_opening":"Edit opening","history.move_opening":"Move opening","history.delete_opening":"Delete opening","history.delete_room":"Delete room","history.delete_room_keep_walls":"Delete room, keep walls","history.delete_room_with_walls":"Delete room and walls","history.decor_add":"Add decor object","history.decor_edit":"Edit decor object","history.decor_move":"Move decor object","history.decor_transform":"Transform decor object","history.decor_delete":"Delete decor object","history.backdrop_transform":"Transform plan backdrop","title.markup_opening":"Openings: click a wall to place, click an opening to edit","opening.new":"New opening","opening.edit":"Opening","opening.door":"Door","opening.window":"Window","opening.gate":"Gate","opening.passage":"Open passage","opening.passage_binding_warning":"Saving will remove the open/close sensor and lock.","opening.invalid_passage_fields":"The open passage on plan “{room}” has unsupported settings: {fields}.","opening.type_label":"Type","opening.length_label":"Length, cm","opening.contact_label":"Open/close sensor","opening.lock_label":"Lock","opening.none":"— none —","opening.search_ph":"Search: name or entity id…","opening.invert":"Invert open/closed","opening.flip_h":"Hinge on the other jamb","opening.flip_v":"Opens to the other side","opening.open":"Open","opening.closed":"Closed","opening.locked":"Locked","opening.unlocked":"Unlocked","opening.state_unknown":"unavailable","opening.no_entities":"No sensors bound — a static symbol on the plan.","toast.opening_no_wall":"Click next to a room wall or independent wall","opening.host_partition":"Independent wall","opening.partition_orphan":"The independent wall for this opening no longer exists","opening.partition_jamb_margin":"Leave at least {distance} between the opening and the end of the wall","opening.rebind_partition":"Attach to another independent wall","confirm.delete_partition_openings_title":"Delete wall and openings?","confirm.delete_partition_openings_body":"This wall contains {count} opening(s). They will be deleted together.","confirm.delete_partition_openings_item":"• {type}, {length}","markup.delete":"Delete","markup.hint_points":"points: {n} · Shift — 45° steps · Esc — finish chain · Ctrl+Z — undo a point · closing an area offers a room","markup.hint_start":"click a grid dot to start a wall chain","tip.lqi":"average zigbee signal:","tip.area":"area: {value}","info.device_header":"Device on the plan","info.model":"Model","info.state":"State","info.link":"Link","info.manuals":"Manuals","info.none":"No additional information","marker.new_device":"New device","marker.name_label":"Name (shown on the plan)","marker.name_ph":"Name","marker.binding_label":"Bind to an HA device","marker.binding_disabled":"disabled in Home Assistant","marker.virtual_option":"Virtual device (no binding)","marker.search_ph":"Search device / group…","marker.nothing_found":"nothing found","marker.room_label":"Room","marker.room_override":" (override placement)","marker.room_choose":"— select a room —","marker.room_auto":"— by device area (auto) —","marker.icon_label":"Icon","marker.icon_ph":"mdi:… (empty = auto)","marker.display_label":"Display","display.badge":"Icon + state","display.icon_ripple":"Icon + state and activity","display.static_icon":"Always static icon","marker.display_hint":"Icon + state changes the plate for work, open, alarm and unavailable states. Icon + state and activity additionally shows a short pulse for events and a continuous pulse for ongoing work, movement or presence. Value + state replaces the icon with one unambiguous HA value. A static icon never reacts to device states.","marker.display_hint_badge":"The icon and dynamic plate show device state without the ordinary activity pulse. Red alarms remain visible.","marker.display_hint_icon":"The icon and dynamic plate show device state without the ordinary activity pulse. Red alarms remain visible.","marker.display_hint_icon_ripple":"The icon, dynamic plate and pulse show a short pulse for events and a continuous pulse for work, motion or presence. Red alarms have separate priority.","marker.display_hint_value":"One unambiguous Home Assistant value replaces the icon while the plate continues to show state. Red alarms remain visible.","marker.display_hint_static_icon":"The theme-aware shell and icon always stay the same. State, activity, unavailability and alarms do not change the face.","marker.static_alarm_warning":"This device can report alarms. Static display hides the marker's visual alarm indication.","marker.preview.title":"Display preview","marker.preview.actual":"Now","marker.preview.example":"Example","marker.preview.integration":"Provided by","marker.preview.source":"Display source","marker.preview.current_state":"Current state","marker.preview.result":"On the plan","marker.preview.details":"Source details","marker.preview.select_source":"Choose a Home Assistant device or entity to see its actual display.","marker.preview.unknown_provider":"Unknown integration","marker.preview.virtual_provider":"House Plan · virtual device","marker.preview.no_source":"No active source","marker.preview.no_state":"No current state","marker.preview.mixed_states":"Several different states","marker.preview.multiple_sources":"{n} sources","marker.preview.more_sources":"+{n} more","marker.preview.scaled":"The preview is scaled to {n}% to fit. The saved size is unchanged.","marker.preview.demo_activity":"Show activity example","marker.preview.demo_notice":"Temporary activity example; the actual device state is unchanged.","marker.preview.demo_short":"Show short activity","marker.preview.demo_continuous":"Show continuous activity","marker.preview.stop_continuous":"Stop continuous activity","marker.preview.demo_short_notice":"Short activity example; the actual device state is unchanged.","marker.preview.demo_continuous_notice":"Continuous activity example; the actual device state is unchanged.","marker.preview.demo_already_visible":"The current state already shows a real activity or alarm effect.","marker.preview.reduced_motion":"System reduced-motion is enabled, so ordinary activity is shown as a dot.","marker.preview.reason.neutral":"Neutral dark plate","marker.preview.reason.working":"Yellow plate: the device is working now","marker.preview.reason.working_activity":"Yellow plate and activity effect: the device is working now","marker.preview.reason.open":"Orange plate: physically open or unlocked","marker.preview.reason.cover_icon_state":"Neutral plate; the cover entity controls the displayed state and icon","marker.preview.reason.presence":"Activity effect while presence is detected","marker.preview.reason.event":"Short activity effect after a detected event","marker.preview.reason.transition":"Activity effect while the device is moving or changing state","marker.preview.reason.media_neutral":"Media devices stay on a neutral dark plate while available","marker.preview.reason.unavailable":"Subdued neutral plate: unavailable or off","marker.preview.reason.alarm":"Red alarm plate; alarm indication is always shown","marker.preview.reason.live_states_disabled":"Live-state styling is disabled for this card","marker.preview.reason.value_no_state":"No usable state value; the icon is shown instead","marker.preview.reason.value_ambiguous_sources":"Several possible value sources; the icon is shown instead","marker.preview.reason.value_non_scalar":"The source did not return a simple value; the icon is shown instead","marker.preview.reason.value_virtual":"A virtual device has no Home Assistant value; the icon is shown instead","marker.preview.reason.vacuum_live_plan_only":"Live vacuum position and trail are available only on the full plan","marker.preview.reason.hidden_design_preview":"The device is hidden on the plan; this design preview remains visible","marker.preview.reason.composite_power_source":"State comes from the device Power entity; auxiliary switches are ignored","marker.preview.reason.activity_display_disabled":"The selected display mode does not show ordinary activity effects","marker.preview.reason.ha_disabled":"The Home Assistant binding is disabled and will be hidden on the plan","marker.preview.reason.orphaned":"The saved Home Assistant binding can no longer be found","marker.preview.reason.static_icon":"Static mode: device state does not change the icon","marker.activity_color":"Activity pulse color","marker.ripple_size":"Activity pulse size","marker.activity_alarm_note":"Color and size affect ordinary activity only and do not change red alarms.","marker.pulse_a11y_alarm":"Alarm","marker.pulse_a11y_event":"Recent event","marker.pulse_a11y_presence":"Presence detected","marker.pulse_a11y_transition":"Changing state","marker.pulse_a11y_running":"Working","marker.state_a11y_neutral":"Default state","marker.state_a11y_working":"Working","marker.state_a11y_open":"Open","marker.state_a11y_locked":"Locked","marker.state_a11y_unlocked":"Unlocked","marker.state_a11y_alarm":"Alarm","marker.state_a11y_unavailable":"Unavailable","marker.lqi_a11y_low":"LQI {value}, low signal","marker.lqi_a11y_mid":"LQI {value}, medium signal","marker.lqi_a11y_high":"LQI {value}, high signal","marker.size_label":"Icon size / rotation","marker.angle_label":"Rotate","marker.model_label":"Model","marker.model_ph":"e.g. Aqara T&H","marker.link_label":"Link","marker.desc_label":"Description","marker.desc_ph":"Notes, specs…","marker.manuals_label":"Manuals (PDF etc.)","marker.sub_device":"device","marker.sub_z2m_group":" · Z2M group","marker.sub_group":"group","marker.sub_helper":"helper","space.new":"New space","space.header":"Space","space.title_label":"Title","space.title_ph":"e.g. Garage","space.plan_label":"Floor plan (background)","space.no_plan":"no plan image","space.plan_alt":"plan","room.new":"New room","room.name_label":"Display name","room.name_ph":"e.g. Terrace","room.area_label":"Home Assistant area (unassigned)","room.no_area_option":"— no area —","room.default_name":"Room","device.unnamed":"unnamed","device.light_group":"light group","device.fallback":"device","device.virtual":"virtual device","confirm.delete_room":'Delete room "{name}"?',"confirm.delete_room_title":'Delete room "{name}"?',"confirm.delete_room_body":"Choose whether the room's exclusive physical walls should remain. Walls shared with another room are always kept.","confirm.merge_rooms":'Merge rooms "{a}" and "{b}"?',"confirm.remove_marker":'Delete "{name}" from the plan? The device will disappear completely and stop contributing to plan data. You can add it again later.',"confirm.erase_decor":"Erase the {kind} object? You can undo this action from the editor history.","confirm.delete_space":'Delete space "{title}" with all its rooms and markup?',"space.delete_blocked":"This space is still used by {n} device(s). Move them to another space or delete them first.","toast.pos_save_failed":"Failed to save position: {err}","toast.no_entity":"The device has no suitable entity","toast.ha_disabled_action":"A Home Assistant object that is disabled cannot be used on the plan.","toast.ha_disabled_show_device":"A device disabled in Home Assistant cannot be shown on the plan. Enable it in Home Assistant first.","toast.ha_disabled_show_entity":"An entity disabled in Home Assistant cannot be shown on the plan. Enable it in Home Assistant first.","toast.ha_disabled_add":"A disabled Home Assistant object cannot be added to the plan. Enable it in Home Assistant first.","toast.ha_binding_unverified":"The object status could not be verified through the Home Assistant registry. Display and actions are temporarily unavailable.","toast.markup_needs_server":"Markup is available after the config is moved to the server","toast.space_order_changed":"Order changed. If any card pins its floor by number, check those panels.","toast.conflict":"Config was changed in another window — data refreshed, repeat your last action","toast.cfg_save_failed":"Failed to save config: {err}","toast.room_overlap":"The outline overlaps room “{name}” — rooms must not overlap","toast.contour_min_edges":"Draw at least two edges before closing the outline","toast.contour_cannot_close":"The outline cannot close because it is degenerate or intersects itself","toast.merge_not_adjacent":"Only rooms that share a wall can be merged","toast.rooms_merged":"Rooms merged into “{name}”","toast.split_pick_wall":"Start the cut on the room’s wall","toast.split_bad_cut":"The cut must run wall to wall inside the room, without crossing walls or itself","merge.header":"Merge rooms","merge.hint":"The merged room keeps one name and one area. The other area is released — its devices leave the plan until another room claims it.","merge.keep":"Keep","merge.no_area":"no area","room.split_header":"New room from the split","toast.room_saved":"Room saved ({n}). Devices added: {added}. Outline the next one or exit markup.","toast.room_saved_no_area":"Room saved ({n}, no area). Outline the next one or exit markup.","toast.marker_needs_server":"Device editing is available after the config is moved to the server","toast.virtual_name_required":"Enter a name for the virtual device","toast.marker_saved":"Device saved","toast.marker_removed":"Device deleted from the plan","toast.integration_missing":"The House Plan integration is not installed — management unavailable","toast.plan_formats":"Supported formats: SVG, PNG, JPG, WebP","toast.plan_required":"Upload a floor plan — it is required","toast.space_added_onboard":"Space added. Outline the rooms: click grid dots and close the contour.","toast.space_added":"Space added","toast.space_saved":"Space saved","toast.space_deleted":"Space deleted","toast.delete_failed":"Delete failed: {err}","toast.error":"Error: {err}","toast.toggle_target_unavailable":"Target “{name}” is unavailable — no action was performed","toast.toggle_targets_unavailable":"Targets are unavailable: {names}. No action was performed","toast.file_failed":'File "{name}" was not uploaded: {err}',"toast.files_attached":"Files attached: {n}","err.unknown":"unknown error","err.code":"code {code}","err.too_large":"file larger than {mb} MB","err.bad_ext":"unsupported type (PDF/image expected)","err.unauthorized":"administrator rights required","editor.title":"Title","editor.default_floor":"Initial space","editor.default_floor_missing":"Initial space “{id}” no longer exists. Choose another space.","editor.floor":"Fixed space","editor.floor_none":"— not fixed —","editor.floor_index":"YAML index {index} (preserved)","fixed_floor.loading":"Loading the fixed space…","fixed_floor.invalid_title":"The fixed space is unavailable","fixed_floor.invalid_body":"Check floor in the card configuration. The configured value is: {value}","editor.icon_size":"Icon size, % of plan width","editor.show_temperature":"Show temperature","editor.live_states":"Live states (on/off, open…)","editor.show_signal":"Show zigbee signal (LQI)","editor.language":"Interface language","editor.lang_auto":"Auto (HA profile)","editor.lang_en":"English","editor.lang_ru":"Русский","title.icon_rules":"Icon rules: which MDI icon devices get by name","rules.title":"Icon rules","rules.hint":"Rules are checked top-down against “device name + model” (case-insensitive regex); the first match wins. When nothing matches, the entity device class decides, then the generic chip icon.","rules.pattern_ph":"regex, e.g. plug|socket","rules.icon_ph":"mdi:power-socket-de","rules.add":"Add rule","rules.reset":"Reset to defaults","rules.test_ph":"Try a device name…","rules.invalid":"invalid regex","rules.saved":"Icon rules saved","btn.up":"Up","btn.down":"Down","tap.info":"Device card","tap.more_info":"HA more-info dialog","tap.toggle":"Toggle state","marker.tap_label":"Tap action for this device","tap.toggle_note":"The resolved state is shown below. Secure devices are never toggled from the plan.","import.title":"Create spaces from HA floors","import.hint":"Your Home Assistant already knows these floors. Pick the ones to turn into plan spaces — you will upload a floor-plan image for each one next. Rooms are then outlined by hand on the plan.","import.start":"Create {n} space(s)","import.manual":"Start from scratch","import.progress":"Floor {i} of {n}","import.done":"Spaces created. Outline the rooms: click grid dots and close the contour.","btn.skip":"Skip","space.scale_label":"Scale (grid cell size)","space.scale_unit":"cm per cell","space.scale_unit_imperial":"in per cell","space.display_section":"Display","space.show_borders":"Always show room borders","space.zero_wall_style":"Zero-thickness walls","space.zero_wall_dashed":"Dashed","space.zero_wall_solid":"Solid","space.zero_wall_help":"Dashed walls let light through. Solid walls block light even at zero thickness.","space.show_names":"Show room names (drag to move)","space.room_color":"Border & name color","space.opacity":"Opacity","space.fill_label":"Room fill","fill.none":"None","fill.lqi":"Zigbee signal","fill.light":"Lights","fill.custom":"Custom color","space.custom_fill":"Fill color","space.source_file":"I have a floor-plan image","space.source_draw":"No image — I'll outline rooms by hand","space.orientation":"Canvas","orient.landscape":"Landscape","orient.portrait":"Portrait","orient.square":"Square","fill.temp":"Temperature","space.temp_min":"Comfort from","space.temp_max":"to","tip.temp_avg":"average temperature:","tip.hum_avg":"average humidity:","space_card.button":"Open the space plan","space_card.not_found":"Space “{id}” not found","space_card.loading":"Loading…","continuity.restore_plan":"Restoring floor plan…","continuity.restore_connection":"Restoring device connection…","continuity.retry":"Try again","editor.space":"Space","editor.show_button":"Show button","editor.button_label":"Button label","editor.button_target":"Target dashboard path","marker.sub_entity":"entity","title.general_settings":"General settings","gs.title":"General settings","gs.hint":"Fill colors apply to every space; each color has its own opacity. Which fill mode a space uses is set in that space's dialog.","gs.light_group":"Fill: lights","gs.light_on":"Lights on","gs.light_off":"All lights off","gs.temp_group":"Fill: temperature","gs.temp_cold":"Cold","gs.temp_ok":"Comfortable","gs.temp_hot":"Hot","gs.lqi_group":"Fill: zigbee signal","gs.lqi_low":"Weak signal","gs.lqi_high":"Strong signal","gs.reset":"Reset to defaults","gs.saved":"General settings saved","space.show_lqi":"Show zigbee signal (LQI) next to devices","space.hide_decor":"Hide the decorative layer","space.hide_decor_tip":"Lines, shapes, labels and furniture stay where they are — visible in the backdrop editor, not on the plan.","space.hide_openings":"Hide openings","space.hide_openings_tip":"Door, window and gate symbols are not drawn, but the openings keep working: light passes through, the sun comes in at a window, contact sensors still open them. The plan editor always shows them.","gs.light_none":"No light sources","mode.plan":"Plan editor","mode.devices":"Device editor","display.value":"Value + state","marker.subarea":"no area, manual","device.new":"New device — open its editor to dismiss","opening.unlock_action":"Unlock","opening.lock_action":"Lock","opening.lock_pending":"Working…","title.close_editor":"Close editor (back to view)","devbar.add":"Add","devbar.show_all":"Hidden and disabled","devbar.rules":"Icon rules","device_inbox.button":"Devices","device_inbox.title":"Devices on the plan","device_inbox.search":"Search devices, entities and integrations…","device_inbox.add_virtual":"Add virtual device","device_inbox.tab_on_plan":"On plan","device_inbox.tab_available":"Available","device_inbox.tab_hidden":"Hidden","device_inbox.tab_readd":"Available again","device_inbox.only_new":"New only","device_inbox.show_entities":"Show entities","device_inbox.show_hidden":"Show hidden on plan","device_inbox.new":"New","device_inbox.find":"Find on plan","device_inbox.edit":"Edit","device_inbox.hide":"Hide","device_inbox.show":"Show","device_inbox.add":"Add","device_inbox.readd":"Add again","device_inbox.hide_available":"Hide from list","device_inbox.show_more":"Show more","device_inbox.more_actions":"More actions","device_inbox.find_hidden_hint":"Enable “Show hidden on plan” first","device_inbox.show_disabled":"Activate this binding in Home Assistant before showing it","device_inbox.empty_on_plan":"No matching devices are on the plan yet.","device_inbox.empty_available":"No devices are available to add.","device_inbox.empty_hidden":"There are no hidden devices.","device_inbox.empty_readd":"No removed devices are available to add again.","device_inbox.reason_visible_auto":"Discovered automatically","device_inbox.reason_visible_explicit":"Added explicitly","device_inbox.reason_manual_hidden":"Hidden by user","device_inbox.reason_automatic_hidden":"Hidden automatically","device_inbox.reason_service_entry":"Service-only registry entry","device_inbox.reason_excluded_integration":"Integration excluded by device filters","device_inbox.reason_excluded_domain":"Non-spatial entity type","device_inbox.reason_grouped_light":"Represented by a room light group","device_inbox.reason_represented_by_parent":"Represented by its parent device","device_inbox.reason_removed":"Previously removed from the plan","device_inbox.reason_available":"Available to add to the plan","device_inbox.reason_no_bound_room":"HA area is not linked to a plan room","device_inbox.status_ha_disabled":"Disabled in Home Assistant","device_inbox.status_orphaned":"Binding is no longer present in Home Assistant","device_inbox.status_unverified":"Home Assistant registry is temporarily unavailable","device_inbox.saved":"Device list updated","space.roomcard_section":"Room card shows:","space.label_temp":"Temperature","space.label_hum":"Humidity","space.label_lqi":"Average Zigbee signal","space.label_light":"Lights on/off","roomcard.light_on":"On","roomcard.light_off":"Off","roomcard.light_partial":"{on} of {total}","toast.split_pick_inside":"Intermediate cut points must be inside the room","mode.decor":"Background editor","decor.select":"Select","decor.line":"Line","decor.rect":"Rectangle","decor.ellipse":"Oval","decor.text":"Text","decor.erase":"Erase","decor.erase_confirm_title":"Erase object?","decor.color":"Color","decor.width":"Line width","decor.line_style":"Line style","decor.line_style_solid":"Solid","decor.line_style_dashed":"Dashed","decor.fill":"Fill","decor.fill_color":"Fill color","decor.length":"Length","decor.size":"Size","decor.angle":"Rotation angle, °","decor.text_size":"Text size","decor.backdrop_properties":"Plan backdrop properties","decor.text_title":"Text label","decor.object_title":"Edit {kind}","decor.text_label":"Text","decor.live_group":"Insert HA variable","decor.live_entity":"Entity","decor.live_entity_ph":"choose an entity","decor.live_attr":"Value","decor.live_attr_ph":"choose state or attribute","decor.live_state":"State","decor.backdrop":"Backdrop image","decor.backdrop_hint":"Drag to move; pull a corner to resize; use the top handle to rotate. Shift changes proportions or frees the angle.","decor.backdrop_reset":"Reset the picture","decor.backdrop_reset_done":"The picture is back at its original place and size","marker.icon_auto":"Auto: {icon} (by icon rules; pick one to override)","marker.icon_pin_auto":"Pin","mode.plan_tip":"Plan editor — the geometry of the home: draw and split/merge rooms, bind them to HA areas, place doors, windows and gates, move room cards, set the scale","mode.devices_tip":"Device editor — everything about icons: drag to position, click to edit binding/icon/display, add virtual devices, icon rules","mode.decor_tip":"Background editor — purely visual decor under the plan: lines, rectangles, ovals and text labels that never react to clicks","space.glow_enabled":"Light-source glow","gs.glow_group":"Light-source glow","gs.glow_base":"House darkness","gs.glow_light":"Default light color / intensity","gs.wall_group":"Walls","gs.wall_fill":"Wall fill","gs.glow_radius":"Glow radius","gs.unit_m":"m","gs.unit_ft":"ft","marker.controls_label":"Controls other light sources","marker.controls_hint":"With tap action “Toggle”, a click flips every source added here. The marker’s own bound entity is controlled directly and cannot be added; use the switch below to classify it as a light.","marker.controls_filter":"Search lights and switches…","info.controls":"Controls","marker.glow_radius_label":"Glow radius","marker.glow_radius.help":"Sets the glow radius in metres or feet; an empty value uses the radius from general settings.","marker.glow_radius.help.aria":"Help: glow radius","markup.wallthick":"Thickness","markup.select":"Select","title.markup_wallthick":"Thickness — click a wall to set its thickness from 0 to 100 cm.","markup.hint_wallthick":"click a wall · Esc closes without applying","wallthick.field":"Thickness","wallthick.unit_cm":"cm","wallthick.unit_in":"in","wallthick.apply_room":"Apply to all walls of this room","markup.draw_wall_title":"Thickness of each new wall segment (0–100 cm). Shared walls keep the existing value.","room.queue_progress":"Room {current} of {total}","toast.wall_rooms_saved":"Created rooms: {n}","toast.wall_chain_saved":"Wall chain saved","toast.wallthick_pick":"Click a wall","toast.wallthick_set":"Wall thickness set","toast.wallthick_cleared":"Wall thickness removed","toast.physical_range":"Enter a value from {min} to {max} {unit}","toast.zero_wall_opening_conflict":"Remove the opening on this wall segment first.","toast.zero_wall_ambiguous":"The wall segment is ambiguous. Simplify or adjust the junction.","toast.zero_wall_migration_blocked":"The space was not converted: {reason}. No data was changed.","toast.physical_angle":"Enter a rotation angle from 0° up to, but not including, 90°","toast.physical_limit":"The space has reached the limit for this type of geometry","toast.geometry_unsafe":"Change canceled: wall geometry could not be built safely.","junction.limit_angle":"The angle between walls is too sharp: {actual}°, minimum {limit}°.","junction.limit_valence":"Too many walls meet in one node: {actual}, maximum {limit}.","junction.limit_length":"The wall segment is too short: {actual} cm, minimum {limit} cm.","junction.limit_distance":"Walls and nodes are too close: {actual} cm, minimum {limit} cm.","junction.limit_clearance":"No room interior is left: {actual} cm², minimum {limit} cm².","toast.wall_model_migration_blocked":"The wall model could not be updated: {reason}. The plan was not changed. Run “Optimize plans”; if the error repeats, fix the conflicting wall geometry.","toast.wall_model_client_outdated":"Update the card and reload the page before editing the plan.","wall_model.reason.invalid-room":"invalid room contour","wall_model.reason.zero-length":"zero-length wall segment","wall_model.reason.third-owner":"wall shared by more than two rooms","wall_model.reason.duplicate-id":"conflicting wall identifiers","wall_model.reason.thickness-conflict":"conflicting wall thickness values","wall_model.reason.opening-host":"opening cannot be assigned to one wall","toast.delete_room_pick":"Click inside the room you want to delete","toast.plan_snap_ambiguous":"Zoom in to choose the wall node","toast.wall_repair_ambiguous":"The room outline has more than one possible connection. Zoom in and connect it explicitly.","toast.wall_repair_too_large":"The gap is larger than 2 cm. Connect the walls before creating the room.","toast.wall_repair_changed":"The wall geometry changed. Try creating the room again.","toast.opening_on_zero_wall":"Openings cannot sit on a zero-thickness wall","marker.from_ha_option":"Pick from the HA list","marker.show_entities":"Show entities","marker.show_entities_tip":"Adds not only devices to the list, but all their entities too","marker.pick_ph":"Choose a device…","room.open_area":"Open the HA area","view.volumetric":"Volumetric view","view.flat":"Flat view","kiosk.title":"This screen's sizes","kiosk.hint":"Stored on this device only — every wall tablet or TV can have its own comfortable sizes.","kiosk.icon_scale":"Device icon size","kiosk.font_scale":"Room card text size","editor.kiosk":"Wall device (kiosk) mode","editor.cycle":"Auto-switch spaces every N seconds (kiosk, 0 = off)","room.settings_title":"Room settings","room.settings_section":"Room settings (override the space)","room.fill_label":"Fill in THIS room","fill.inherit":"As the space","room.custom_fill_space":"Space color","room.custom_fill_own":"Room color","room.temp_src_label":"Temperature source","room.hum_src_label":"Humidity source","room.src_average":"Average over the room's sensors (default)","room.src_pick":"A specific HA device or entity","room.src_ph":"Choose a source…","toast.room_updated":"Room updated","space.card_font":"Room-card font size (whole space)","room.sizes_section":"Font sizes","room.name_scale":"Room name size","room.label_scale":"Metrics size","preview.room_name":"Living room","toast.cfg_reload_failed":"Could not reload the plan from the server: {err}","room.settings_short":"Room settings","room.unnamed":"Unnamed room","marker.use_climate_temp":"Include the device temperature in the room","marker.use_climate_temp_tip":"Adds an air conditioner or thermostat current_temperature to the room average. Configure the external value badge separately below.","marker.value_badge_title":"Value badge","marker.value_badge.help":"Shows one selected value next to the icon. It does not affect room metrics, light, Glow or the tap action.","marker.value_badge.help.aria":"Help: device value badge","marker.value_badge_enabled":"Show a value badge","marker.value_badge_source":"Value","marker.value_badge_source.help":"Choose a specific state, supported attribute, or derived value of this device.","marker.value_badge_source.help.aria":"Help: value badge source","marker.value_badge_position":"Position","marker.value_badge_position.help":"The chosen side stays fixed and does not flip automatically at a plan edge.","marker.value_badge_position.help.aria":"Help: value badge position","marker.value_badge_right":"Right","marker.value_badge_bottom":"Below","marker.value_badge_left":"Left","marker.value_badge_top":"Above","marker.value_badge_empty":"This device has no available values","marker.value_badge_static":"A static icon does not show live values. The setting is preserved.","marker.value_badge_missing":"Source unavailable","marker.value_badge_missing_hint":"The saved source is currently unavailable. Keep it, disable the badge, or choose another value.","marker.value_badge_duplicate":"The same value is already shown inside the icon.","marker.value_badge_state":"State · {name}","marker.value_badge_marker_state":"Light-source state · {name}","marker.value_badge_lqi":"Average Zigbee signal quality","marker.value_badge_attr_current_temperature":"Current temperature · {name}","marker.value_badge_attr_temperature":"Target temperature · {name}","marker.value_badge_attr_current_humidity":"Current humidity · {name}","marker.value_badge_attr_humidity":"Humidity · {name}","marker.value_badge_attr_current_position":"Position · {name}","marker.value_badge_attr_percentage":"Speed · {name}","marker.value_badge_attr_brightness":"Brightness · {name}","marker.value_badge_attr_volume_level":"Volume · {name}","marker.value_badge_attr_battery_level":"Battery · {name}","marker.value_badge_attr_fan_speed":"Fan speed · {name}","marker.light_role_label":"Is this device a light source?","marker.light_role.help":"Controls whether this marker itself is a spatial light source. Linked lights above remain independent room-light controls.","marker.light_role.help.aria":"Help: whether this device is a light source","marker.light_role_auto_yes":"Auto (light source)","marker.light_role_auto_no":"Auto (not a light source)","marker.light_role_always":"Always a light source","marker.light_role_never":"Never a light source","marker.light_entity_label":"Leading light entity","marker.light_entity.help":"For a composite device, choose the entity whose state, colour and brightness represent this plan source. The automatic fallback remains compatible with older plans.","marker.light_entity.help.aria":"Help: leading light entity","marker.light_entity_auto":"Automatic ({entity})","marker.light_entity_none":"no controllable entity","marker.light_entity_missing":"The saved entity {entity} is unavailable. House Plan temporarily uses {fallback}; the saved choice will be restored if it returns.","marker.toggle_entity_label":"Entity to toggle","marker.toggle_entity.help":"For a composite device, choose the exact own light or switch operated by a tap. Automatic keeps the previous target rules and is independent from the leading light entity.","marker.toggle_entity.help.aria":"Help: entity to toggle","marker.toggle_entity_auto":"Automatic ({entity})","marker.toggle_entity_none":"no own controllable entity","marker.toggle_entity_missing":"The saved entity {entity} is no longer among this marker’s selectable channels. House Plan temporarily uses {fallback}; the saved choice will be restored if it returns.","marker.glow_color_label":"Glow colour and brightness","marker.glow_mode.help":"Use live source values, override only its colour, or fix both colour and brightness. The minimum is 1%; to disable the source, choose “Never”.","marker.glow_mode.help.aria":"Help: glow colour and brightness","marker.glow_mode_auto":"From source","marker.glow_mode_color":"Set colour","marker.glow_mode_fixed":"Set colour and brightness","marker.glow_color":"Glow colour","marker.glow_brightness":"Brightness","marker.glow_disabled_never":"Glow settings are unavailable because this marker is explicitly not a light source.","marker.glow_disabled_auto":"Auto mode found no spatial light source for this marker.","marker.glow_disabled_no_entity":"No active controllable Home Assistant entity is available for this spatial source.","marker.glow_passive_hint":"This source has no own Home Assistant data. Set its colour and brightness manually; its radius remains available.","marker.control_broken":"Saved source is missing or no longer marked as a light","marker.control_missing_label":"Missing plan light","marker.control_passive":"passive source","toast.marker_control_cycle":"This link would create a circular chain of light controls.","toast.marker_binding_required":"Choose a Home Assistant device before linking another light source.","confirm.unlock":"Unlock “{name}”?","toast.files_migrate_failed":"Attachments could not be moved to the new binding, links keep pointing at the old files: {err}","space.pick_saved":"Already uploaded","space.pick_saved_hint":"Plans stored on the server, including ones you detached earlier","space.no_saved":"No plans stored on the server yet.","space.loading":"Loading…","space.used_by":"in use: {list}","space.in_use":"A space still uses this plan — detach it first","btn.use":"Use","confirm.delete_plan":'Delete the plan file "{name}" from the server? This cannot be undone.',"toast.plans_list_failed":"Could not list the stored plans: {err}","toast.plan_delete_failed":"Could not delete the plan: {err}","marker.hide":"Hide","marker.hide_tip":'The device will disappear from the plan after saving but will still count toward the room signal. Restore it through the "Devices" catalog in the device editor.',"marker.show":"Show","marker.show_tip":"The device will appear on the plan again after saving.","marker.hidden_ghost":"Device hidden by the user","marker.ha_disabled_device":"The device is disabled in Home Assistant and hidden from the plan.","marker.ha_disabled_entity":"The entity is disabled in Home Assistant and hidden from the plan.","marker.ha_disabled_all_entities":"The device has no active Home Assistant entities, so it is hidden from the plan.","marker.ha_registry_limited":"The full Home Assistant registry is unavailable to this user. The unverified object cannot be shown or used for now.","marker.delete_tip":"Completely delete the device from the plan and every aggregate. You can add it again later.","tap.run":"Run automation/script/scene","tap.cover":"Open/close (curtains/blinds)","marker.run_target_label":"What to run","marker.run_search_ph":"Search: automation, script or scene…","marker.run_target_gone":"Target {id} not found — pick again","marker.tap_confirm":"Ask for confirmation","marker.tap_confirm_tip":"Show a confirmation dialog before acting — a guard against accidental taps.","marker.toggle_hint_single":"Target: {name} ({id}).","marker.virtual_light_target":"Virtual light: {name}.","marker.virtual_light_current":"Manual state: {state} → {effect}.","marker.virtual_light_state_on":"on","marker.virtual_light_state_off":"off","marker.toggle_hint_group":"Will toggle {count} source(s): {names}.","marker.toggle_hint_current":"Now: {state} → {effect}.","marker.toggle_hint_group_current":"Currently on: {on} of {count} → {effect}.","marker.toggle_hint_skipped":"Will be skipped ({count}): {targets}.","marker.toggle_effect_turn_on":"will turn on","marker.toggle_effect_turn_off":"will turn off","marker.toggle_effect_open":"will open","marker.toggle_effect_close":"will close","marker.toggle_effect_stop":"will stop","marker.toggle_effect_toggle":"state will toggle","marker.toggle_skip_missing":"not found","marker.toggle_skip_ha_disabled":"disabled in HA","marker.toggle_skip_unavailable":"unavailable","marker.toggle_skip_unsupported":"toggle is unsupported","marker.toggle_skip_secure":"blocked for security","marker.toggle_none_no_binding":"This device has no binding, so there is no state to toggle. Tapping will do nothing.","marker.toggle_none_no_actionable_entity":"This device has no state that can be toggled. Tapping will do nothing.","marker.toggle_none_configured_targets_missing":"The configured targets are unavailable. The device's own entity will not be substituted for them.","marker.toggle_none_ha_disabled":"The target is disabled in Home Assistant and cannot be used on the plan.","marker.toggle_none_unavailable":"The target is currently unavailable. Tapping will do nothing.","marker.toggle_none_unsupported":"Home Assistant exposes no safe toggle operation for this entity. Tapping will do nothing.","marker.toggle_none_secure":"Toggling locks, alarms and secure gates from the plan is blocked for security.","run.automation":"automation","run.script":"script","run.scene":"scene","confirm.tap_run":'Run "{name}"?',"confirm.tap_toggle":'Toggle "{name}"?',"confirm.tap_cover":'Open/close "{name}"?',"confirm.current_state":"Current state: {state}","confirm.expected_state":"After switching: {state}","confirm.group_current":"on {on} of {total}","confirm.group_all_on":"all are on","confirm.group_all_off":"all are off","confirm.unavailable_targets":"Unavailable: {count}","confirm.expected_by_ha":"Home Assistant will determine the state","confirm.state_on":"On","confirm.state_off":"Off","confirm.state_open":"Open","confirm.state_closed":"Closed","confirm.state_opening":"Opening","confirm.state_closing":"Closing","confirm.state_stopped":"Stopped","confirm.state_unknown":"Unknown","toast.run_started":"Started: {name}","toast.run_target_missing":"Run target not found — check the device settings","toast.run_target_required":"Pick an automation, script or scene","toast.tap_target_changed":"The action target changed. Try again.","toast.virtual_light_toggle_failed":"Could not toggle the virtual light: {err}","toast.value_badge_source_required":"Choose a value for the badge","btn.run":"Run","vac.section":"Robot vacuum: live position","vac.autocal":"Set up automatically","vac.live":"Live position on the plan","vac.trail":"Show the robot's path","vac.cal_maps":"Calibrated maps: {maps}","vac.autocal_no_rooms":"The integration reports no room list — open “Fit manually”","vac.autocal_no_match":"Room names did not match (need ≥3 in common) — open “Fit manually”","vac.autocal_done":"Done: bound via {rooms} rooms. Start a cleanup and check","vac.cal_need_pos":"The robot is not reporting coordinates — start a cleanup and pause it","vac.cal_done":"Calibration saved. Start a cleanup and check","vac.cal_cancelled":"Calibration cancelled","vac.fit":"Fit manually","vac.fit_hint":"Drag the robot map into place, stretch by the corners","vac.fit_rotate":"Rotate 90°","vac.fit_mirror":"Mirror","vac.trail_never":"Never","vac.trail_cleaning":"While cleaning","vac.trail_always":"Always","gs.bg_group":"Stage background","gs.bg_color":"Background around the plan","gs.bg_default":"Theme default","gs.bg_theme":"theme default","gs.bg_mode":"Plan background","gs.bg_static":"Static color","gs.bg_daynight":"Follows the Sun","gs.bg_daynight_hint":"The background moves through dawn, day, dusk and night using sun.sun, or your local clock when sun data is unavailable. No compass is needed for the background.","gs.sun_group":"Sun","gs.sun_missing":"The sun.sun entity was not found — the background follows your local clock; window rays are unavailable.","gs.north":"North on the plan","gs.north_ph":"not set","gs.north_hint":"Set north only for window rays (1° steps, 15° with Shift); the Sun background works without it.","gs.north_clear":"Clear","gs.north_letter":"N","gs.sun_rays":"Sunlight through windows","gs.about_group":"About","gs.about_version":"Houseplan Card v{v}","gs.about_github":"GitHub · docs & issues","gs.about_telegram":"Telegram chat","space.bg_color":"Background around the plan","space.bg_inherit":"Inherit general","space.bg_inherited":"inherits general settings","space.bg_mode":"Plan background","space.north":"North on the plan (override)","space.north_inherited":"inherited: {v}","space.sun_rays":"Sunlight through windows","space.sun_inherit":"Inherit general","space.sun_on":"On","space.sun_off":"Off","canvas.far_objects":"{n} object(s) far from the plan","canvas.show_far":"Show","canvas.home_tip":"The plan is over there — click to fit it","gs.grid_group":"Plan maintenance","gs.grid_hint":"Updates data models, aligns plan elements to the grid and merges redundant wall fragments. An exact report is shown before anything is stored.","gs.align_all":"Optimize plans","gs.align_title":"Optimize plans","gs.align_none":"All plans already use the current optimized data model.","gs.optimize_no_automatic_changes":"There are no automatic changes to apply. Review the items below.","gs.align_count":"{n} of {total} elements will move, by at most {cm} cm.","gs.align_where":"The largest shift is in “{s}”.","gs.align_turned":"Openings whose angle is corrected: {n}.","gs.align_removed_drafts":"Invalid outlines collapsed by the grid and removed: {n}.","gs.optimize_redundant_drafts":"Saved wall chains hidden by solid room walls and removed: {n}.","gs.align_preflight_failed":"Could not safely verify the geometry of the following spaces: {spaces}{more}.","gs.align_preflight_hint":"Plans were not changed. Copy the diagnostics with the button below and attach them to the bug report together with a space export.","gs.preflight_reason_prepare-exception":"Could not prepare the space geometry (exception while building the model)","gs.preflight_reason_wall-null":"The wall body did not build (the union came back empty)","gs.preflight_reason_wall-degraded-extra":"The wall body degraded with extra geometry","gs.preflight_reason_wall-failed-core":"The wall body core failed to assemble","gs.preflight_reason_wall-exception":"Wall construction threw an exception","gs.preflight_reason_floor-null":"The floor outline did not build","gs.preflight_reason_floor-exception":"Floor construction threw an exception","gs.preflight_copy":"Copy diagnostics","gs.preflight_copied":"Diagnostics copied","gs.preflight_update_hint":"The card and integration versions differ — update House Plan and retry.","gs.align_preflight_space":"Space {n}","gs.align_preflight_more":", and {n} more","gs.optimize_changes":"Model migrations: {m}; spaces updated: {c}; noisy coordinate values removed: {p}; merged real-wall fragments: {w}; merged zero-thickness wall fragments: {s}; independent walls: {i}.","gs.zero_walls_migrated":"Virtual wall spans converted: {n}.","gs.wall_segments_migrated":"Wall segments stabilised: {n}.","gs.optimize_lattice_summary":"Noisy coordinate values canonicalized: {n}; maximum movement: {cm} cm.","gs.optimize_lattice_space":"{space}: coordinate values canonicalized: {n}; off-grid values left unchanged: {far}.","gs.optimize_coincident_partitions":"Hidden independent wall sections absorbed into room walls: {n}.","gs.optimize_openings_rehosted":"Openings reattached to room walls: {n}.","gs.optimize_walls_straightened":"Walls straightened: {n}; maximum movement: {cm} cm.","gs.optimize_walls_straightened_where":"Largest wall correction: {s}.","gs.optimize_walls_straighten_skipped":"Near-axis walls left unchanged because they could not be repaired safely: {n}.","gs.optimize_glow_migration":"Legacy Glow: {spaces} spaces → no data fill + independent Glow; {rooms} rooms → inherited data fill + independent Glow.","gs.optimize_references":"References repaired: spaces — {spaces}; rooms — {rooms}; positions — {positions}; devices detached from missing spaces — {detached}.","gs.optimize_reference_more":", and {n} more","gs.optimize_orphans_removed":"Forgotten records removed: {total} — room labels: {rooms}; devices: {devices}; group markers: {groups}. They belonged to spaces deleted earlier.","gs.optimize_live_positions":"Old positions in deleted spaces belong to existing objects: {n}{names}. They will be kept.","gs.optimize_live_positions_remove":"Old positions in deleted spaces belong to existing objects: {n}{names}. They are selected for removal.","gs.optimize_live_names":": {names}{more}","gs.optimize_live_remove":"Remove old positions","gs.optimize_live_keep":"Keep old positions","gs.optimize_live_selected":"Old positions will be removed after Optimize is applied.","gs.optimize_unverified":"Could not safely verify positions: {n}. They were left unchanged.","gs.optimize_registry_limited":"Full administrator access to the Home Assistant registries is required for a safe check.","gs.optimize_vacuum_warning":"Vacuum room mappings that still need review: {n}.","gs.optimize_details":"Details","gs.optimize_details_more":"And {n} more records.","gs.optimize_detail_removed":"will be removed","gs.optimize_detail_live":"will be kept","gs.optimize_detail_unverified":"not verified","gs.optimize_detail_room_label":"room label","gs.optimize_detail_device":"device","gs.optimize_detail_group":"group marker","gs.optimize_detail_unknown":"unknown owner","gs.optimize_detail_item":"{status}: {kind} {id}; old space {space}","gs.align_warn":"Elements deliberately placed between grid nodes will move. One undo is available after the operation, only until the next plan edit.","gs.align_run":"Optimize","gs.align_done":"Plans optimized: {n} elements moved, {m} records maintained, {r} references repaired","gs.optimize_undo":"Undo last optimization","gs.optimize_undone":"The last optimization was undone","decor.furniture":"Furniture","furn.title":"Furniture library","furn.symbol":"Symbol","furn.group_furniture":"Furniture","furn.group_appliance":"Appliances","furn.group_sanitary":"Plumbing","furn.group_other":"Other","furn.width":"Width","furn.depth":"Depth","furn.pick_hint":"Pick a symbol, then click on the plan.","furn.place_hint":"Click on the plan — the piece lands against the nearest wall. Shift places it free.","furn.sym_sofa":"Sofa","furn.sym_armchair":"Armchair","furn.sym_coffee_table":"Coffee table","furn.sym_table_dining":"Dining table","furn.sym_table_round":"Round table","furn.sym_chair":"Chair","furn.sym_desk":"Desk","furn.sym_bed_double":"Double bed","furn.sym_bed_single":"Single bed","furn.sym_nightstand":"Nightstand","furn.sym_wardrobe":"Wardrobe","furn.sym_bookshelf":"Bookshelf","furn.sym_fridge":"Fridge","furn.sym_stove":"Cooker","furn.sym_dishwasher":"Dishwasher","furn.sym_washer":"Washing machine","furn.sym_dryer":"Tumble dryer","furn.sym_tv":"TV","furn.sym_ac":"Air conditioner","furn.sym_water_heater":"Water heater","furn.sym_toilet":"Toilet","furn.sym_bathtub":"Bathtub","furn.sym_shower":"Shower","furn.sym_sink":"Washbasin","furn.sym_kitchen_sink":"Kitchen sink","furn.sym_bidet":"Bidet","furn.sym_stairs":"Stairs","furn.sym_fireplace":"Fireplace","furn.sym_plant":"Plant","furn.sym_rug":"Rug","common.yes":"Yes","common.no":"No","vac.diag_source":"Source","vac.diag_platform":"Integration","vac.diag_status":"Status","vac.diag_position":"Position","vac.diag_rooms":"Rooms","vac.diag_rooms_value":"{total} · {matched} names match · {readiness}","vac.autocal_ready":"auto-calibration available","vac.autocal_not_ready":"need 3 matching names","vac.diag_path":"Integration path","vac.diag_map":"Map ID","vac.source_none":"not selected","vac.source_status_ok":"Ready","vac.source_status_missing":"Missing","vac.source_status_disabled":"Disabled in Home Assistant","vac.source_status_unavailable":"Unavailable","vac.source_status_unverified":"Cannot verify with current permissions","vac.source_status_unsupported":"No position data","vac.source_status_none":"No source","vac.source_banner_missing":"The saved source no longer exists. It was not replaced automatically; choose another source or restore it in Home Assistant.","vac.source_banner_disabled":"The saved source is disabled in Home Assistant. Enable it there or choose another source.","vac.source_banner_unverified":"Current Home Assistant permissions cannot verify this saved source. It remains pinned and will not be replaced automatically.","vac.choose_source":"Choose source","vac.source_auto":"Automatic","vac.source_auto_hint":"Use a compatible entity from this device","vac.all_cameras":"All cameras","vac.all_cameras_warn":"A camera may not provide robot data. Choose one only if it is your vacuum map.","vac.all_cameras_empty":"No other camera entities found.","vac.platform_unknown":"unknown integration","vac.cap_position":"position","vac.cap_rooms_short":"rooms","vac.cap_path":"path","vac.cap_map":"map ID","vac.cap_none":"no robot data detected","vac.xcme_hint":"Enable these Xiaomi Cloud Map Extractor attributes:","vac.documentation":"Documentation","vac.residual_title":"Check automatic calibration","vac.residual_message":"The matched rooms disagree by up to {error}. Apply this approximate calibration, refine it manually, or cancel without changing the saved setup.","vac.apply_proposal":"Apply","gs.backup_group":"Backup and transfer","gs.backup_hint":"Download a portable JSON backup or preview and import a backup made by House Plan.","backup.export_open":"Export","backup.import_open":"Import","backup.export_title":"Export House Plan","backup.import_title":"Import House Plan","backup.export_hint":"Choose whether the backup should contain the whole House Plan configuration or only the current space.","backup.full":"Full backup","backup.current_space":"Current space","backup.current_space_title":"Current space: {title}","backup.no_current_space":"No current space","backup.plan_only":"Plan only","backup.plan_only_hint":"Keep rooms, walls, openings, decor and room-label positions without devices or Home Assistant bindings.","backup.plan_only_preview":"This file contains the plan only","backup.privacy_warning":"The archive keeps names, Home Assistant identifiers and exact coordinates. Internal plans and attachments are referenced, not embedded; runtime states and vacuum trails are not included.","backup.download":"Download JSON","backup.export_done":"Backup downloaded","backup.reading":"Checking the backup…","backup.revalidated":"The plan changed after this preview. The summary was refreshed; review it and confirm again.","backup.error.unauthorized":"You do not have permission to export or import this plan.","backup.error.not_ready":"House Plan is not ready yet. Try again in a moment.","backup.error.too_large":"The backup exceeds the 8 MiB limit.","backup.error.invalid_json":"The selected file is not valid JSON.","backup.error.invalid_format":"The selected file is not a House Plan backup.","backup.error.unsupported_export_version":"This backup format is not supported by the installed version.","backup.error.future_model":"The backup was created by a newer House Plan data model.","backup.error.invalid_config":"The backup contains an invalid House Plan configuration.","backup.error.wall_model_migration_blocked":"The backup wall model could not be upgraded safely. Optimize the source plan first, then export it again.","backup.error.invalid_layout":"The backup contains invalid object positions.","backup.error.invalid_content":"The backup contains invalid or inconsistent content references.","backup.error.space_not_found":"The selected space no longer exists.","backup.error.capacity_exceeded":"Adding this backup would exceed the plan limits.","backup.error.preview_expired":"The preview expired. Select the backup file again.","backup.error.preview_owner_mismatch":"This preview belongs to another Home Assistant user.","backup.error.conflict":"The plan changed after the preview. Review the refreshed summary.","backup.error.content_confirmation_required":"Confirm that unavailable local content may be detached.","backup.error.commit_failed":"The backup could not be applied safely. The previous plan was restored or is pending recovery.","backup.error.missing_plan":"A referenced plan file disappeared after the preview. Review the backup again.","backup.error.missing_content":"A referenced local attachment disappeared after the preview. Review the backup again.","backup.error.marker_control_missing":"A linked plan light is missing from the backup.","backup.error.marker_control_not_light":"A linked plan target is no longer marked as a light source.","backup.error.marker_control_self":"A light source cannot control itself.","backup.error.marker_control_cycle":"The backup contains a circular chain of light controls.","backup.error.duplicate_marker_control":"The backup contains a duplicate plan-light link.","backup.error.no_backup":"There is no import or optimization snapshot to restore.","backup.same_source":"Created on this Home Assistant instance","backup.foreign_source":"Created on another Home Assistant instance","backup.created":"Created: {value}","backup.versions":"Card {card}; integration {integration}; data model {model}","backup.count_spaces":"Spaces: {n}","backup.count_rooms":"Rooms: {n}","backup.count_walls":"Walls: {n}","backup.count_openings":"Openings: {n}","backup.count_decor":"Decor objects: {n}","backup.count_markers":"Devices: {n}","backup.count_layout":"Positions: {n}","backup.bindings":"Bindings — devices: {device}, entities: {entity}, virtual: {virtual}; positions without a space: {legacy}","backup.binding_status":"Target status — active: {active}, disabled: {disabled}, missing: {missing}","backup.missing_areas":"Areas missing on the target: {areas}","backup.dropped_marker_links":"Plan-light links outside this transferred space were omitted: {n}.","backup.repaired_target_refs":"Existing references restored by this space import: {n}.","backup.preserved_unresolved_refs":"References that could not be restored unambiguously were preserved: {n}.","backup.preserved_unresolved_hint":"No data was guessed or deleted. After the import, run Optimize plans to inspect the remaining references.","backup.import_details":"Import reference details","backup.import_detail.incoming_remapped":"References updated inside the imported copy: {n}","backup.import_detail.target_repaired":"Existing references restored: {n}","backup.import_detail.preserved_unresolved":"Unresolved references preserved: {n}","backup.import_detail.collisions":"Destination conflicts preserved safely: {n}","backup.import_detail.dropped_links":"Incoming links omitted by transfer rules: {n}","backup.import_detail.bounded_lineages":"Overly nested identifiers left bounded: {n}","backup.replace_warning":"This replaces the current configuration and layout. Uploaded files are never deleted. One undo remains available until the next plan edit.","backup.foreign_bookkeeping":"Instance-specific known/new-device bookkeeping will not be imported.","backup.final_name":"New space name","backup.target_settings":"The target instance's global settings remain unchanged.","backup.duplicates":"Bindings already present: {n}","backup.skip":"Skip duplicate devices","backup.virtual_copy":"Add safe static virtual copies","backup.content":"Referenced content","backup.content_available":"available locally","backup.content_external":"external link","backup.content_detach_required":"will be detached","backup.confirm_detach":"I understand that unavailable internal plans and attachments will be detached from the imported configuration.","backup.replace":"Replace","backup.add":"Add space","backup.space_done":"Space imported: {rooms} rooms, {markers} devices, {refs} existing references restored","backup.full_done":"Backup restored: {spaces} spaces, {rooms} rooms, {markers} devices","backup.undo_import":"Undo last full import","backup.import_undone":"Full import undone"};const aa=[{code:"en",nativeLabel:"English",dictionary:oa},{code:"ru",nativeLabel:"Русский",dictionary:{"editor.context_actions":"Действия: {object}","editor.tool_options":"Параметры инструмента: {tool}","editor.palette":"Палитра: {tool}","editor.open_group":"Группа инструментов: {group}","editor.group_active":"{group} — активно: {item}","editor.disabled_action":"{action} недоступно: {reason}","color_picker.title":"Выбор цвета","color_picker.hue":"Оттенок","color_picker.saturation":"Насыщенность","color_picker.value":"Яркость","color_picker.hex":"Цвет HEX","color_picker.invalid_hex":"Введите цвет HEX из 3 или 6 цифр","btn.properties":"Свойства","btn.keep_as_walls":"Оставить стенами","btn.delete_room_keep_walls":"Удалить комнату, оставить стены","btn.delete_room_with_walls":"Удалить комнату и стены","title.markup_select":"Выбор и редактирование стен, колонн и сохранённых контуров","title.markup_column":"Колонна: кликните точку сетки для квадратной колонны","markup.partition":"Перегородка","markup.column":"Колонна","markup.hint_column":"кликните точку сетки, чтобы поставить квадратную колонну","history.draft_segment":"Добавление сегмента черновика комнаты","history.draft_merge":"Соединение незавершённых контуров комнаты","history.draft_segment_delete":"Удаление сегмента черновика комнаты","history.partition_add":"Добавление перегородки","history.column_add":"Добавление колонны","history.physical_edit":"Изменение физического объекта","history.physical_delete":"Удаление физического объекта","history.physical_move":"Перемещение физического объекта","history.contour_to_partitions":"Преобразование контура в замкнутые стены","history.wall_chain_finish":"Завершение цепочки стен","history.wall_face_batch":"Создание комнат из стен","toast.column_duplicate":"Колонна с тем же центром и внешним размером уже существует","confirm.delete_draft":"Удалить весь незавершённый контур комнаты?","confirm.delete_draft_segment":"Удалить этот сегмент черновика? Оставшийся контур может разделиться на два.","physical.partition_properties":"Свойства перегородки","physical.column_properties":"Свойства колонны","physical.draft_properties":"Свойства сегмента черновика","physical.shape":"Форма","physical.square":"Квадрат","physical.circle":"Круг","physical.diameter":"Диаметр","physical.side":"Сторона","physical.rotation":"Угол поворота","physical.length":"Длина","physical.allowed_range":"Допустимо: {min}–{max} {unit}","physical.delete_segment":"Удалить сегмент","physical.delete_draft":"Удалить весь контур","physical.column_size_title":"Внешняя сторона квадратной колонны, создаваемой кликом (1–150 см).","card.title":"План дома","count.devices":"{n} устр.","empty.no_spaces":"Пространств пока нет.","empty.add_first":"Добавьте первое пространство и загрузите план этажа.","empty.install":"Установите интеграцию House Plan и добавьте запись в «Устройства и службы».","btn.add_space":"Добавить пространство","btn.cancel":"Отмена","btn.save":"Сохранить","btn.close":"Закрыть","btn.delete":"Удалить","btn.edit":"Редактировать","btn.open_in_ha":"Открыть в HA","btn.reset":"Сброс","btn.attach":"Прикрепить…","btn.upload":"Загрузить…","btn.replace":"Заменить…","title.zoom_in":"Приблизить","title.zoom_out":"Отдалить","title.zoom_fit":"Вписать всё","title.add_device":"Добавить устройство на план","title.show_all":"Показать скрытые и деактивированные устройства служебными маркерами (только в этой вкладке)","title.markup":"Разметка комнат: сетка, линии, контуры","title.configure_space":"Настроить пространство","title.add_space":"Добавить пространство","title.markup_add":"Стены: рисуйте непрерывную цепочку; Shift фиксирует 45°. Смена инструмента или выход завершает её как независимые стены","title.markup_merge":"Объединить: клик по одной комнате, затем по соседней с общей стеной","title.markup_split":"Разделить комнату: клик по комнате, затем две точки на её стенах","title.markup_delroom":"Удалить комнату: кликните внутри комнаты и подтвердите удаление","title.need_plan":"Загрузите подложку (план этажа)","markup.add":"Стены","markup.merge":"Объединить","markup.split":"Разделить","markup.resize":"Размер","title.markup_resize":"Изменение размера комнат: тяните доступную ручку горизонтальной или вертикальной стены","markup.hint_resize":"тяните доступную ручку стены · стена упирается в первую небезопасную позицию · Esc — отмена · Ctrl+Z — отмена шага","resize.disabled.diagonal":"Стена расположена под углом: Resize поддерживает только горизонтальные и вертикальные стены","resize.disabled.side-angle":"Примыкающая стена расположена под углом: для Resize обе примыкающие стены должны образовывать прямой угол","resize.disabled.duplicate-physical-wall":"Стену перекрывает отдельная перегородка, незавершённый контур или колонна; удалите или переместите её перед изменением размера","resize.disabled.partial-shared":"Соседняя комната использует только часть этой стены, поэтому её нельзя безопасно двигать как одну общую стену","resize.disabled.unequal-shared":"У соседней комнаты другие конечные точки или длина стены, поэтому стены нельзя безопасно двигать вместе","resize.disabled.multiple-rooms":"Перемещение затронуло бы больше двух комнат","resize.disabled.thickness-conflict":"Толщину стены нельзя безопасно сохранить","resize.disabled.opening-conflict":"Проём на этой стене нельзя безопасно переместить","resize.disabled.invalid-geometry":"Эту стену нельзя переместить без изменения структуры плана","resize.limit_stopped":"Стена остановлена: дальше нарушается ограничение стыков","resize.commit_failed":"Изменение размера отменено: итоговый план не прошёл проверку геометрии","resize.preview_failed":"Стена остановлена в последней безопасной позиции: геометрию плана нельзя сохранить без потерь","markup.opening":"Проём","markup.delete_room":"Удалить комнату","history.undo":"Отменить","history.redo":"Повторить","history.undo_named":"Отменить: {name} (Ctrl+Z)","history.redo_named":"Повторить: {name} (Ctrl+Shift+Z / Ctrl+Y)","history.undo_empty":"Нет операций для отмены","history.redo_empty":"Нет операций для повтора","history.undone":"Отменено: {name}","history.redone":"Повторено: {name}","history.add_room":"Создание комнаты","history.split_room":"Разделение комнаты","history.merge_rooms":"Объединение комнат","history.resize_room":"Изменение размера комнаты","history.wall_thickness":"Изменение толщины стены","history.add_opening":"Добавление дверного или оконного проёма","history.edit_opening":"Изменение проёма","history.move_opening":"Перемещение проёма","history.delete_opening":"Удаление проёма","history.delete_room":"Удаление комнаты","history.delete_room_keep_walls":"Удаление комнаты с сохранением стен","history.delete_room_with_walls":"Удаление комнаты и её стен","history.decor_add":"Добавление объекта декора","history.decor_edit":"Изменение объекта декора","history.decor_move":"Перемещение объекта декора","history.decor_transform":"Трансформация объекта декора","history.decor_delete":"Удаление объекта декора","history.backdrop_transform":"Трансформация подложки плана","title.markup_opening":"Проёмы: клик по стене — добавить, клик по проёму — редактировать","opening.new":"Новый проём","opening.edit":"Проём","opening.door":"Дверь","opening.window":"Окно","opening.gate":"Ворота","opening.passage":"Открытый проём","opening.passage_binding_warning":"При сохранении датчик открытия и замок будут удалены.","opening.invalid_passage_fields":"У открытого проёма на плане «{room}» есть недопустимые параметры: {fields}.","opening.type_label":"Тип","opening.length_label":"Длина, см","opening.contact_label":"Датчик открытия","opening.lock_label":"Замок","opening.none":"— нет —","opening.search_ph":"Поиск: имя или entity_id…","opening.invert":"Инвертировать открыто/закрыто","opening.flip_h":"Петли с другой стороны","opening.flip_v":"Открывается в другую сторону","opening.open":"Открыто","opening.closed":"Закрыто","opening.locked":"Заперто","opening.unlocked":"Не заперто","opening.state_unknown":"недоступно","opening.no_entities":"Датчики не привязаны — статичный символ на плане.","toast.opening_no_wall":"Кликните рядом со стеной комнаты или независимой стеной","opening.host_partition":"Независимая стена","opening.partition_orphan":"Независимая стена этого проёма больше не существует","opening.partition_jamb_margin":"Оставьте от края проёма до торца стены минимум {distance}","opening.rebind_partition":"Привязать к другой независимой стене","confirm.delete_partition_openings_title":"Удалить стену и проёмы?","confirm.delete_partition_openings_body":"В стене есть проёмы: {count}. Они будут удалены вместе со стеной.","confirm.delete_partition_openings_item":"• {type}, {length}","markup.delete":"Удалить","markup.hint_points":"точек: {n} · Shift — шаг 45° · Esc — завершить цепочку · Ctrl+Z — убрать точку · при замыкании будет предложена комната","markup.hint_start":"кликните точку сетки, чтобы начать цепочку стен","tip.lqi":"средний сигнал zigbee:","tip.area":"площадь: {value}","info.device_header":"Устройство на плане","info.model":"Модель","info.state":"Состояние","info.link":"Ссылка","info.manuals":"Инструкции","info.none":"Нет дополнительной информации","marker.new_device":"Новое устройство","marker.name_label":"Имя (отображается на плане)","marker.name_ph":"Название","marker.binding_label":"Привязка к устройству HA","marker.binding_disabled":"деактивировано в Home Assistant","marker.virtual_option":"Виртуальное устройство (без привязки)","marker.search_ph":"Поиск устройства / группы…","marker.nothing_found":"ничего не найдено","marker.room_label":"Комната","marker.room_override":" (переопределить размещение)","marker.room_choose":"— выберите комнату —","marker.room_auto":"— по зоне устройства (авто) —","marker.icon_label":"Иконка","marker.icon_ph":"mdi:… (пусто = авто)","marker.display_label":"Отображение","display.badge":"Значок + состояние","display.icon_ripple":"Значок + состояние и активность","display.static_icon":"Всегда статичный значок","marker.display_hint":"Значок + состояние меняет подложку при работе, открытии, тревоге и недоступности. Значок + состояние и активность дополнительно показывает короткую пульсацию для событий и постоянную — для работы, движения или присутствия. Значение + состояние заменяет значок одним однозначным значением HA. Статичный значок не реагирует на состояния устройства.","marker.display_hint_badge":"Значок и динамическая подложка показывают состояние устройства без обычной пульсации активности. Красная тревога сохраняется.","marker.display_hint_icon":"Значок и динамическая подложка показывают состояние устройства без обычной пульсации активности. Красная тревога сохраняется.","marker.display_hint_icon_ripple":"Значок, динамическая подложка и пульсация: короткая — для событий, постоянная — для работы, движения или присутствия. Красная тревога имеет отдельный приоритет.","marker.display_hint_value":"Значок заменяется одним однозначным значением Home Assistant; подложка продолжает показывать состояние. Красная тревога сохраняется.","marker.display_hint_static_icon":"Подложка в цветах темы и значок всегда остаются одинаковыми. Состояния, активность, недоступность и тревоги не меняют отображение.","marker.static_alarm_warning":"Это устройство может сообщать о тревогах. Статичный режим скрывает визуальную тревогу маркера.","marker.preview.title":"Предпросмотр отображения","marker.preview.actual":"Сейчас","marker.preview.example":"Пример","marker.preview.integration":"Интеграция","marker.preview.source":"Источник отображения","marker.preview.current_state":"Текущее состояние","marker.preview.result":"На плане","marker.preview.details":"Подробнее об источниках","marker.preview.select_source":"Выберите устройство или сущность Home Assistant, чтобы увидеть фактическое отображение.","marker.preview.unknown_provider":"Интеграция неизвестна","marker.preview.virtual_provider":"House Plan · виртуальное устройство","marker.preview.no_source":"Нет активного источника","marker.preview.no_state":"Нет текущего состояния","marker.preview.mixed_states":"Несколько разных состояний","marker.preview.multiple_sources":"Источников: {n}","marker.preview.more_sources":"ещё {n}","marker.preview.scaled":"Предпросмотр уменьшен до {n}%, чтобы поместиться. Сохранённый размер не изменится.","marker.preview.demo_activity":"Показать пример активности","marker.preview.demo_notice":"Временный пример активности; фактическое состояние устройства не меняется.","marker.preview.demo_short":"Показать краткую активность","marker.preview.demo_continuous":"Показать постоянную активность","marker.preview.stop_continuous":"Остановить постоянную активность","marker.preview.demo_short_notice":"Пример краткой активности; фактическое состояние устройства не меняется.","marker.preview.demo_continuous_notice":"Пример постоянной активности; фактическое состояние устройства не меняется.","marker.preview.demo_already_visible":"Текущее состояние уже показывает реальную активность или тревогу.","marker.preview.reduced_motion":"В системе включено уменьшение движения, поэтому обычная активность показана точкой.","marker.preview.reason.neutral":"Нейтральная тёмная подложка","marker.preview.reason.working":"Жёлтая подложка: устройство сейчас работает","marker.preview.reason.working_activity":"Жёлтая подложка и эффект активности: устройство сейчас работает","marker.preview.reason.open":"Оранжевая подложка: физически открыто или разблокировано","marker.preview.reason.cover_icon_state":"Нейтральная подложка; состояние и значок определяет сущность шторы или заслонки","marker.preview.reason.presence":"Эффект активности, пока обнаружено присутствие","marker.preview.reason.event":"Короткий эффект активности после события","marker.preview.reason.transition":"Эффект активности во время движения или смены состояния","marker.preview.reason.media_neutral":"Медиаустройство остаётся на нейтральной тёмной подложке, пока доступно","marker.preview.reason.unavailable":"Приглушённая нейтральная подложка: отключено или недоступно","marker.preview.reason.alarm":"Красная тревожная подложка; тревога отображается всегда","marker.preview.reason.live_states_disabled":"Оформление по живым состояниям отключено в настройках карточки","marker.preview.reason.value_no_state":"Нет подходящего значения состояния — вместо него показан значок","marker.preview.reason.value_ambiguous_sources":"Подходит несколько источников значения — вместо него показан значок","marker.preview.reason.value_non_scalar":"Источник вернул не простое значение — вместо него показан значок","marker.preview.reason.value_virtual":"У виртуального устройства нет значения HA — вместо него показан значок","marker.preview.reason.vacuum_live_plan_only":"Живая позиция и след пылесоса доступны только на полном плане","marker.preview.reason.hidden_design_preview":"Устройство скрыто на плане, но его оформление видно в предпросмотре","marker.preview.reason.composite_power_source":"Состояние берётся из сущности питания устройства; вспомогательные переключатели не учитываются","marker.preview.reason.activity_display_disabled":"Выбранный режим отображения не показывает обычные эффекты активности","marker.preview.reason.ha_disabled":"Привязка отключена в Home Assistant, поэтому устройство будет скрыто на плане","marker.preview.reason.orphaned":"Сохранённая привязка Home Assistant больше не найдена","marker.preview.reason.static_icon":"Статичный режим: состояние устройства не меняет значок","marker.activity_color":"Цвет пульсации активности","marker.ripple_size":"Размер пульсации активности","marker.activity_alarm_note":"Цвет и размер относятся только к обычной активности и не влияют на красную тревогу.","marker.pulse_a11y_alarm":"Тревога","marker.pulse_a11y_event":"Недавнее событие","marker.pulse_a11y_presence":"Обнаружено присутствие","marker.pulse_a11y_transition":"Изменение состояния","marker.pulse_a11y_running":"Работает","marker.state_a11y_neutral":"Обычное состояние","marker.state_a11y_working":"Работает","marker.state_a11y_open":"Открыто","marker.state_a11y_locked":"Заблокировано","marker.state_a11y_unlocked":"Разблокировано","marker.state_a11y_alarm":"Тревога","marker.state_a11y_unavailable":"Недоступно","marker.lqi_a11y_low":"LQI {value}, слабый сигнал","marker.lqi_a11y_mid":"LQI {value}, средний сигнал","marker.lqi_a11y_high":"LQI {value}, сильный сигнал","marker.size_label":"Размер / поворот значка","marker.angle_label":"Поворот","marker.model_label":"Модель","marker.model_ph":"напр. Aqara T&H","marker.link_label":"Ссылка","marker.desc_label":"Описание","marker.desc_ph":"Заметки, характеристики…","marker.manuals_label":"Инструкции (PDF и т.п.)","marker.sub_device":"устройство","marker.sub_z2m_group":" · Z2M-группа","marker.sub_group":"группа","marker.sub_helper":"хелпер","space.new":"Новое пространство","space.header":"Пространство","space.title_label":"Название","space.title_ph":"Например: Гараж","space.plan_label":"Подложка (план)","space.no_plan":"нет подложки","space.plan_alt":"план","room.new":"Новая комната","room.name_label":"Отображаемое имя","room.name_ph":"Например: Терраса","room.area_label":"Зона Home Assistant (свободные)","room.no_area_option":"— без зоны —","room.default_name":"Комната","device.unnamed":"без имени","device.light_group":"группа света","device.fallback":"устройство","device.virtual":"виртуальное устройство","confirm.delete_room":"Удалить комнату «{name}»?","confirm.delete_room_title":"Удалить комнату «{name}»?","confirm.delete_room_body":"Выберите, нужно ли оставить физические стены, принадлежащие только этой комнате. Общие с другой комнатой стены сохраняются всегда.","confirm.merge_rooms":"Слить комнаты «{a}» и «{b}»?","confirm.remove_marker":"Удалить «{name}» с плана? Устройство исчезнет полностью и перестанет участвовать в данных плана. Позже его можно будет добавить заново.","confirm.erase_decor":"Стереть объект «{kind}»? Действие можно отменить из истории редактора.","confirm.delete_space":"Удалить пространство «{title}» со всеми комнатами и разметкой?","space.delete_blocked":"Это пространство всё ещё используется устройствами: {n}. Сначала перенесите их в другое пространство или удалите.","toast.pos_save_failed":"Не удалось сохранить позицию: {err}","toast.no_entity":"У устройства нет подходящей сущности","toast.ha_disabled_action":"Деактивированный объект Home Assistant нельзя использовать на плане.","toast.ha_disabled_show_device":"Деактивированное в Home Assistant устройство нельзя показать на плане. Сначала активируйте его в Home Assistant.","toast.ha_disabled_show_entity":"Деактивированную в Home Assistant сущность нельзя показать на плане. Сначала активируйте её в Home Assistant.","toast.ha_disabled_add":"Деактивированный объект Home Assistant нельзя добавить на план. Сначала активируйте его в Home Assistant.","toast.ha_binding_unverified":"Статус объекта не удалось подтвердить по реестру Home Assistant. Отображение и действия временно недоступны.","toast.markup_needs_server":"Разметка доступна после переноса конфига на сервер","toast.space_order_changed":"Порядок изменён. Если где-то этаж карточки задан номером, проверьте такие панели.","toast.conflict":"Конфиг изменён в другом окне — данные обновлены, повторите последнее действие","toast.cfg_save_failed":"Не удалось сохранить конфиг: {err}","toast.room_overlap":"Контур накладывается на комнату «{name}» — комнаты не должны накладываться","toast.contour_min_edges":"Чтобы замкнуть контур, сначала нарисуйте минимум две грани","toast.contour_cannot_close":"Контур нельзя замкнуть: он вырожден или пересекает сам себя","toast.merge_not_adjacent":"Объединять можно только комнаты с общей стеной","toast.rooms_merged":"Комнаты объединены в «{name}»","toast.split_pick_wall":"Начните разрез на стене комнаты","toast.split_bad_cut":"Разрез — от стены до стены внутри комнаты, без пересечения стен и самого себя","merge.header":"Объединение комнат","merge.hint":"У объединённой комнаты одно имя и одна зона. Вторая зона освобождается — её устройства уйдут с плана, пока их не заберёт другая комната.","merge.keep":"Оставить","merge.no_area":"без зоны","room.split_header":"Новая комната после разделения","toast.room_saved":"Комната сохранена ({n}). Устройств добавлено: {added}. Обведите следующую или выйдите из разметки.","toast.room_saved_no_area":"Комната сохранена ({n}, без зоны). Обведите следующую или выйдите из разметки.","toast.marker_needs_server":"Редактирование устройств доступно после переноса конфига на сервер","toast.virtual_name_required":"Укажите имя виртуального устройства","toast.marker_saved":"Устройство сохранено","toast.marker_removed":"Устройство удалено с плана","toast.integration_missing":"Интеграция House Plan не установлена — управление недоступно","toast.plan_formats":"Поддерживаются SVG, PNG, JPG, WebP","toast.plan_required":"Загрузите подложку — план этажа обязателен","toast.space_added_onboard":"Пространство добавлено. Обведите комнаты: кликайте по точкам сетки и замкните контур.","toast.space_added":"Пространство добавлено","toast.space_saved":"Пространство сохранено","toast.space_deleted":"Пространство удалено","toast.delete_failed":"Ошибка удаления: {err}","toast.error":"Ошибка: {err}","toast.toggle_target_unavailable":"Цель «{name}» недоступна — действие не выполнено","toast.toggle_targets_unavailable":"Цели недоступны: {names}. Действие не выполнено","toast.file_failed":"Файл «{name}» не загружен: {err}","toast.files_attached":"Прикреплено файлов: {n}","err.unknown":"неизвестная ошибка","err.code":"код {code}","err.too_large":"файл больше {mb} МБ","err.bad_ext":"недопустимый тип (нужен PDF/изображение)","err.unauthorized":"нужны права администратора","editor.title":"Заголовок","editor.default_floor":"Стартовое пространство","editor.default_floor_missing":"Стартовое пространство «{id}» больше не существует. Выберите другое.","editor.floor":"Закреплённое пространство","editor.floor_none":"— не закреплять —","editor.floor_index":"YAML-индекс {index} (сохранён)","fixed_floor.loading":"Загружаем закреплённое пространство…","fixed_floor.invalid_title":"Закреплённое пространство недоступно","fixed_floor.invalid_body":"Проверьте floor в конфигурации карточки. Настроенное значение: {value}","editor.icon_size":"Размер иконок, % ширины плана","editor.show_temperature":"Показывать температуру","editor.live_states":"Живые состояния (вкл/выкл, открыто…)","editor.show_signal":"Показывать сигнал zigbee (LQI)","editor.language":"Язык интерфейса","editor.lang_auto":"Авто (профиль HA)","editor.lang_en":"English","editor.lang_ru":"Русский","title.icon_rules":"Правила иконок: какая MDI-иконка достаётся устройству по имени","rules.title":"Правила иконок","rules.hint":"Правила проверяются сверху вниз по строке «имя устройства + модель» (regex без учёта регистра); срабатывает первое совпадение. Если ничего не подошло — решает device class сущности, затем — иконка-заглушка.","rules.pattern_ph":"regex, напр. розетк|plug","rules.icon_ph":"mdi:power-socket-de","rules.add":"Добавить правило","rules.reset":"Сбросить к умолчаниям","rules.test_ph":"Проверьте имя устройства…","rules.invalid":"некорректный regex","rules.saved":"Правила иконок сохранены","btn.up":"Вверх","btn.down":"Вниз","tap.info":"Карточка устройства","tap.more_info":"Диалог HA (more-info)","tap.toggle":"Переключить состояние","marker.tap_label":"Действие по нажатию для этого устройства","tap.toggle_note":"Под селектором показано, какое состояние изменится. Защищённые устройства не переключаются с плана.","import.title":"Создать пространства из этажей HA","import.hint":"Home Assistant уже знает эти этажи. Отметьте, какие превратить в пространства плана — далее для каждого попросим картинку плана. Комнаты затем обводятся вручную по плану.","import.start":"Создать: {n}","import.manual":"Начать с нуля","import.progress":"Этаж {i} из {n}","import.done":"Пространства созданы. Обведите комнаты: кликайте по точкам сетки и замкните контур.","btn.skip":"Пропустить","space.scale_label":"Масштаб (размер клетки сетки)","space.scale_unit":"см на клетку","space.scale_unit_imperial":"дюйм на клетку","space.display_section":"Отображение","space.show_borders":"Всегда отображать границы комнат","space.zero_wall_style":"Стены нулевой толщины","space.zero_wall_dashed":"Пунктирные","space.zero_wall_solid":"Сплошные","space.zero_wall_help":"Пунктирные стены пропускают свет. Сплошные стены блокируют свет, даже при нулевой толщине.","space.show_names":"Отображать названия комнат (перетаскиваются)","space.room_color":"Цвет границ и названий","space.opacity":"Прозрачность","space.fill_label":"Заливка комнат","fill.none":"Нет","fill.lqi":"По силе зигби-сигнала","fill.light":"По освещению","fill.custom":"Свой цвет","space.custom_fill":"Цвет заливки","space.source_file":"У меня есть картинка плана","space.source_draw":"Нет подложки — нарисую комнаты вручную","space.orientation":"Холст","orient.landscape":"Альбомный","orient.portrait":"Портретный","orient.square":"Квадрат","fill.temp":"По температуре","space.temp_min":"Комфорт от","space.temp_max":"до","tip.temp_avg":"средняя температура:","tip.hum_avg":"средняя влажность:","space_card.button":"Перейти к пространству","space_card.not_found":"Пространство «{id}» не найдено","space_card.loading":"Загрузка…","continuity.restore_plan":"Восстанавливаем план…","continuity.restore_connection":"Восстанавливаем подключение к устройствам…","continuity.retry":"Повторить","editor.space":"Пространство","editor.show_button":"Показывать кнопку","editor.button_label":"Текст кнопки","editor.button_target":"Путь дашборда (куда вести)","marker.sub_entity":"сущность","title.general_settings":"Общие настройки","gs.title":"Общие настройки","gs.hint":"Цвета заливок действуют на все пространства; у каждого цвета своя прозрачность. Какой режим заливки использует пространство — задаётся в его диалоге.","gs.light_group":"Заливка: освещение","gs.light_on":"Свет включён","gs.light_off":"Весь свет выключен","gs.temp_group":"Заливка: температура","gs.temp_cold":"Холодно","gs.temp_ok":"Комфорт","gs.temp_hot":"Жарко","gs.lqi_group":"Заливка: зигби-сигнал","gs.lqi_low":"Слабый сигнал","gs.lqi_high":"Сильный сигнал","gs.reset":"Сбросить к умолчаниям","gs.saved":"Общие настройки сохранены","space.show_lqi":"Показывать зигби-сигнал (LQI) у устройств","space.hide_decor":"Скрыть декоративный слой","space.hide_decor_tip":"Линии, фигуры, надписи и мебель остаются на месте — их видно в редакторе подложки, но не на плане.","space.hide_openings":"Скрыть проёмы","space.hide_openings_tip":"Двери, окна и ворота не рисуются, но продолжают работать: свет проходит, солнце светит в окна, датчики открытия срабатывают. В редакторе плана проёмы видно всегда.","gs.light_none":"Нет источников света","mode.plan":"Редактор плана","mode.devices":"Редактор устройств","display.value":"Значение + состояние","marker.subarea":"без зоны, вручную","device.new":"Новое устройство — откройте его редактор, чтобы снять отметку","opening.unlock_action":"Открыть замок","opening.lock_action":"Закрыть замок","opening.lock_pending":"Выполняется…","title.close_editor":"Закрыть редактор (вернуться к просмотру)","devbar.add":"Добавить","devbar.show_all":"Скрытые и деактивированные","devbar.rules":"Правила иконок","device_inbox.button":"Устройства","device_inbox.title":"Устройства на плане","device_inbox.search":"Поиск по устройствам, сущностям и интеграциям…","device_inbox.add_virtual":"Добавить виртуальное устройство","device_inbox.tab_on_plan":"На плане","device_inbox.tab_available":"Доступны","device_inbox.tab_hidden":"Скрытые","device_inbox.tab_readd":"Доступны снова","device_inbox.only_new":"Только новые","device_inbox.show_entities":"Показывать сущности","device_inbox.show_hidden":"Показывать скрытые на плане","device_inbox.new":"Новое","device_inbox.find":"Найти на плане","device_inbox.edit":"Настроить","device_inbox.hide":"Скрыть","device_inbox.show":"Показать","device_inbox.add":"Добавить","device_inbox.readd":"Добавить заново","device_inbox.hide_available":"Скрыть из списка","device_inbox.show_more":"Показать ещё","device_inbox.more_actions":"Другие действия","device_inbox.find_hidden_hint":"Сначала включите «Показывать скрытые на плане»","device_inbox.show_disabled":"Перед показом активируйте эту привязку в Home Assistant","device_inbox.empty_on_plan":"На плане пока нет подходящих устройств.","device_inbox.empty_available":"Нет доступных устройств для добавления.","device_inbox.empty_hidden":"Скрытых устройств нет.","device_inbox.empty_readd":"Нет удалённых устройств, доступных для повторного добавления.","device_inbox.reason_visible_auto":"Найдено автоматически","device_inbox.reason_visible_explicit":"Добавлено явно","device_inbox.reason_manual_hidden":"Скрыто пользователем","device_inbox.reason_automatic_hidden":"Скрыто автоматически","device_inbox.reason_service_entry":"Служебная запись реестра","device_inbox.reason_excluded_integration":"Интеграция исключена фильтрами устройств","device_inbox.reason_excluded_domain":"Непространственный тип сущности","device_inbox.reason_grouped_light":"Представлено группой света комнаты","device_inbox.reason_represented_by_parent":"Представлено родительским устройством","device_inbox.reason_removed":"Ранее удалено с плана","device_inbox.reason_available":"Можно добавить на план","device_inbox.reason_no_bound_room":"Зона HA не связана с комнатой плана","device_inbox.status_ha_disabled":"Отключено в Home Assistant","device_inbox.status_orphaned":"Привязка больше не найдена в Home Assistant","device_inbox.status_unverified":"Реестр Home Assistant временно недоступен","device_inbox.saved":"Список устройств обновлён","space.roomcard_section":"В карточке комнаты:","space.label_temp":"Температура","space.label_hum":"Влажность","space.label_lqi":"Средний Zigbee-сигнал","space.label_light":"Свет вкл/выкл","roomcard.light_on":"Вкл","roomcard.light_off":"Выкл","roomcard.light_partial":"{on} из {total}","toast.split_pick_inside":"Промежуточные точки разреза — внутри комнаты","mode.decor":"Редактор подложки","decor.select":"Выбрать","decor.line":"Линия","decor.rect":"Прямоугольник","decor.ellipse":"Овал","decor.text":"Надпись","decor.erase":"Стереть","decor.erase_confirm_title":"Стереть объект?","decor.color":"Цвет","decor.width":"Толщина линии","decor.line_style":"Стиль линии","decor.line_style_solid":"Сплошная","decor.line_style_dashed":"Пунктирная","decor.fill":"Заливка","decor.fill_color":"Цвет заливки","decor.length":"Длина","decor.size":"Размер","decor.angle":"Угол поворота, °","decor.text_size":"Размер текста","decor.backdrop_properties":"Свойства картинки-подложки","decor.text_title":"Надпись","decor.object_title":"Редактирование: {kind}","decor.text_label":"Текст","decor.live_group":"Вставить переменную HA","decor.live_entity":"Сущность","decor.live_entity_ph":"выберите сущность","decor.live_attr":"Значение","decor.live_attr_ph":"выберите состояние или атрибут","decor.live_state":"Состояние","decor.backdrop":"Картинка-подложка","decor.backdrop_hint":"Тяните картинку — перемещение; угол — размер; верхнюю ручку — поворот. Shift меняет пропорции или снимает шаг угла.","decor.backdrop_reset":"Вернуть картинку","decor.backdrop_reset_done":"Картинка вернулась на своё место и в свой размер","marker.icon_auto":"Авто: {icon} (по правилам иконок; выберите свою, чтобы заменить)","marker.icon_pin_auto":"Закрепить","mode.plan_tip":"Редактор плана — геометрия дома: рисование и объединение/разделение комнат, привязка к зонам HA, двери, окна и ворота, карточки комнат, масштаб","mode.devices_tip":"Редактор устройств — всё про значки: перетаскивание, клик — настройка привязки/иконки/отображения, виртуальные устройства, правила иконок","mode.decor_tip":"Редактор подложки — чисто визуальный декор под планом: линии, прямоугольники, овалы и надписи, не реагирующие на клики","space.glow_enabled":"Свечение источников света","gs.glow_group":"Свечение источников света","gs.glow_base":"Темнота дома","gs.glow_light":"Цвет света по умолчанию / интенсивность","gs.wall_group":"Стены","gs.wall_fill":"Цвет заливки стен","gs.glow_radius":"Радиус свечения","gs.unit_m":"м","gs.unit_ft":"фут","marker.controls_label":"Управляет другими источниками света","marker.controls_hint":"При действии «Переключить» клик разом переключает все добавленные здесь источники. Собственная сущность маркера управляется напрямую и сюда не добавляется; чтобы считать её светом, включите флаг ниже.","marker.controls_filter":"Поиск ламп и выключателей…","info.controls":"Управляет","marker.glow_radius_label":"Радиус свечения","marker.glow_radius.help":"Задаёт радиус свечения в метрах или футах; пустое значение использует радиус из общих настроек.","marker.glow_radius.help.aria":"Подсказка: радиус свечения","markup.wallthick":"Толщина","markup.select":"Выбрать","title.markup_wallthick":"Толщина — клик по стене задаёт толщину от 0 до 100 см.","markup.hint_wallthick":"клик по стене · Esc закрывает без применения","wallthick.field":"Толщина","wallthick.unit_cm":"см","wallthick.unit_in":"дюйм","wallthick.apply_room":"Применить ко всем стенам комнаты","markup.draw_wall_title":"Толщина каждого нового сегмента стены (0–100 см). Общие стены сохраняют существующее значение.","room.queue_progress":"Комната {current} из {total}","toast.wall_rooms_saved":"Создано комнат: {n}","toast.wall_chain_saved":"Цепочка стен сохранена","toast.wallthick_pick":"Кликните по стене","toast.wallthick_set":"Толщина стены задана","toast.wallthick_cleared":"Толщина стены убрана","toast.physical_range":"Введите значение от {min} до {max} {unit}","toast.zero_wall_opening_conflict":"Сначала удалите проём на этом участке стены.","toast.zero_wall_ambiguous":"Не удалось однозначно выбрать участок стены. Уточните геометрию узла.","toast.zero_wall_migration_blocked":"Пространство не преобразовано: {reason}. Данные не изменены.","toast.physical_angle":"Введите угол поворота от 0° до 90°, не включая 90°","toast.physical_limit":"В пространстве достигнут лимит объектов этого типа","toast.geometry_unsafe":"Изменение отменено: геометрию стен нельзя безопасно построить.","junction.limit_angle":"Слишком острый угол между стенами: {actual}°, минимум {limit}°.","junction.limit_valence":"Слишком много стен в одном узле: {actual}, максимум {limit}.","junction.limit_length":"Слишком короткий участок стены: {actual} см, минимум {limit} см.","junction.limit_distance":"Стены и узлы слишком близко: {actual} см, минимум {limit} см.","junction.limit_clearance":"Внутри комнаты не остаётся места: {actual} см², минимум {limit} см².","toast.wall_model_migration_blocked":"Не удалось обновить модель стен: {reason}. План не изменён. Запустите «Оптимизировать планы»; если ошибка повторится, исправьте конфликтующую геометрию стен.","toast.wall_model_client_outdated":"Обновите карточку и перезагрузите страницу перед редактированием плана.","wall_model.reason.invalid-room":"некорректный контур комнаты","wall_model.reason.zero-length":"отрезок стены нулевой длины","wall_model.reason.third-owner":"стена принадлежит более чем двум комнатам","wall_model.reason.duplicate-id":"конфликт идентификаторов стен","wall_model.reason.thickness-conflict":"конфликт значений толщины стены","wall_model.reason.opening-host":"проём нельзя однозначно привязать к стене","toast.delete_room_pick":"Кликните внутри комнаты, которую нужно удалить","toast.plan_snap_ambiguous":"Увеличьте масштаб, чтобы выбрать узел стены","toast.wall_repair_ambiguous":"У контура несколько возможных соединений. Увеличьте масштаб и соедините стены явно.","toast.wall_repair_too_large":"Разрыв больше 2 см. Соедините стены перед созданием комнаты.","toast.wall_repair_changed":"Геометрия стен изменилась. Попробуйте создать комнату ещё раз.","toast.opening_on_zero_wall":"Проёмы на стене нулевой толщины запрещены","marker.from_ha_option":"Выбрать из списка HA","marker.show_entities":"Показывать сущности","marker.show_entities_tip":"Добавляет в список не только устройства, но и все их сущности","marker.pick_ph":"Выберите устройство…","room.open_area":"Открыть зону в HA","view.volumetric":"Объёмный вид","view.flat":"Плоский вид","kiosk.title":"Размеры на этом экране","kiosk.hint":"Хранится только на этом устройстве — у каждого настенного планшета или ТВ свои удобные размеры.","kiosk.icon_scale":"Размер значков устройств","kiosk.font_scale":"Размер текста карточек комнат","editor.kiosk":"Режим настенного устройства (киоск)","editor.cycle":"Автосмена пространств каждые N секунд (киоск, 0 = выкл)","room.settings_title":"Настройки комнаты","room.settings_section":"Настройки комнаты (переопределяют пространство)","room.fill_label":"Заливка в ЭТОЙ комнате","fill.inherit":"Как у пространства","room.custom_fill_space":"Цвет пространства","room.custom_fill_own":"Цвет комнаты","room.temp_src_label":"Источник температуры","room.hum_src_label":"Источник влажности","room.src_average":"Средняя по датчикам комнаты (по умолчанию)","room.src_pick":"Конкретное устройство или сущность HA","room.src_ph":"Выберите источник…","toast.room_updated":"Комната обновлена","space.card_font":"Размер шрифта карточек комнат (всё пространство)","room.sizes_section":"Размеры шрифтов","room.name_scale":"Размер названия","room.label_scale":"Размер подписей","preview.room_name":"Гостиная","toast.cfg_reload_failed":"Не удалось перечитать план с сервера: {err}","room.settings_short":"Настройки комнаты","room.unnamed":"Комната без имени","marker.use_climate_temp":"Учитывать температуру устройства в комнате","marker.use_climate_temp_tip":"Добавляет current_temperature кондиционера или термостата в среднюю температуру комнаты. Внешний бейдж со значением настраивается отдельно ниже.","marker.value_badge_title":"Бейдж со значением","marker.value_badge.help":"Показывает одно выбранное значение рядом со значком. Не влияет на комнатные показатели, свет, Glow и действие по нажатию.","marker.value_badge.help.aria":"Подсказка: бейдж со значением устройства","marker.value_badge_enabled":"Отображать бейдж со значением","marker.value_badge_source":"Значение","marker.value_badge_source.help":"Выберите конкретное состояние, поддерживаемый атрибут или производное значение этого устройства.","marker.value_badge_source.help.aria":"Подсказка: источник значения бейджа","marker.value_badge_position":"Расположение","marker.value_badge_position.help":"Выбранная сторона сохраняется постоянно и не переворачивается автоматически у края плана.","marker.value_badge_position.help.aria":"Подсказка: расположение бейджа","marker.value_badge_right":"Справа","marker.value_badge_bottom":"Снизу","marker.value_badge_left":"Слева","marker.value_badge_top":"Сверху","marker.value_badge_empty":"У этого устройства нет доступных значений","marker.value_badge_static":"Статичный значок не показывает живые значения. Настройка сохранится.","marker.value_badge_missing":"Источник недоступен","marker.value_badge_missing_hint":"Сохранённый источник сейчас недоступен. Можно сохранить его, отключить бейдж или выбрать другой.","marker.value_badge_duplicate":"То же значение уже показано внутри значка.","marker.value_badge_state":"Состояние · {name}","marker.value_badge_marker_state":"Состояние источника света · {name}","marker.value_badge_lqi":"Качество Zigbee-сигнала (среднее)","marker.value_badge_attr_current_temperature":"Текущая температура · {name}","marker.value_badge_attr_temperature":"Целевая температура · {name}","marker.value_badge_attr_current_humidity":"Текущая влажность · {name}","marker.value_badge_attr_humidity":"Влажность · {name}","marker.value_badge_attr_current_position":"Положение · {name}","marker.value_badge_attr_percentage":"Скорость · {name}","marker.value_badge_attr_brightness":"Яркость · {name}","marker.value_badge_attr_volume_level":"Громкость · {name}","marker.value_badge_attr_battery_level":"Заряд батареи · {name}","marker.value_badge_attr_fan_speed":"Скорость вентилятора · {name}","marker.light_role_label":"Является источником света","marker.light_role.help":"Определяет, является ли сам маркер пространственным источником света. Привязанные выше лампы остаются независимыми источниками для комнаты.","marker.light_role.help.aria":"Подсказка: является ли устройство источником света","marker.light_role_auto_yes":"Автоматически (источник света)","marker.light_role_auto_no":"Автоматически (не источник света)","marker.light_role_always":"Всегда источник света","marker.light_role_never":"Никогда не источник света","marker.light_entity_label":"Ведущая сущность света","marker.light_entity.help":"Для составного устройства выберите сущность, состояние, цвет и яркость которой представляют этот источник на плане. Автоматический вариант сохраняет совместимость со старыми планами.","marker.light_entity.help.aria":"Подсказка: ведущая сущность света","marker.light_entity_auto":"Автоматически ({entity})","marker.light_entity_none":"нет управляемой сущности","marker.light_entity_missing":"Сохранённая сущность {entity} недоступна. Временно используется {fallback}; выбор восстановится, если сущность вернётся.","marker.toggle_entity_label":"Переключаемая сущность","marker.toggle_entity.help":"Для составного устройства выберите собственную лампу или переключатель, которой управляет нажатие. Автоматический вариант сохраняет прежние правила цели и не зависит от ведущей сущности света.","marker.toggle_entity.help.aria":"Подсказка: переключаемая сущность","marker.toggle_entity_auto":"Автоматически ({entity})","marker.toggle_entity_none":"нет собственной управляемой сущности","marker.toggle_entity_missing":"Сохранённой сущности {entity} больше нет среди выбираемых каналов этого маркера. Временно используется {fallback}; выбор восстановится, если сущность вернётся.","marker.glow_color_label":"Цвет и яркость свечения","marker.glow_mode.help":"Используйте данные источника, задайте только цвет или зафиксируйте цвет и яркость. Минимум — 1%; чтобы отключить источник, выберите «Никогда».","marker.glow_mode.help.aria":"Подсказка: цвет и яркость свечения","marker.glow_mode_auto":"Из источника","marker.glow_mode_color":"Задать цвет","marker.glow_mode_fixed":"Задать цвет и яркость","marker.glow_color":"Цвет свечения","marker.glow_brightness":"Яркость","marker.glow_disabled_never":"Настройки свечения недоступны: маркер явно исключён из источников света.","marker.glow_disabled_auto":"В автоматическом режиме у этого маркера не найден пространственный источник света.","marker.glow_disabled_no_entity":"Для пространственного источника нет активной управляемой сущности Home Assistant.","marker.glow_passive_hint":"У источника нет собственных данных Home Assistant. Задайте цвет и яркость вручную; радиус остаётся доступным.","marker.control_broken":"Сохранённый источник отсутствует или больше не отмечен как источник света","marker.control_missing_label":"Отсутствующий источник на плане","marker.control_passive":"пассивный источник","toast.marker_control_cycle":"Такая связь создаст циклическую цепочку управления светом.","toast.marker_binding_required":"Сначала выберите устройство Home Assistant, затем добавьте управляемый источник света.","confirm.unlock":"Открыть замок «{name}»?","toast.files_migrate_failed":"Не удалось перенести вложения к новой привязке, ссылки остались на старые файлы: {err}","space.pick_saved":"Уже загруженные","space.pick_saved_hint":"Планы, сохранённые на сервере, включая отцеплённые ранее","space.no_saved":"На сервере пока нет сохранённых планов.","space.loading":"Загрузка…","space.used_by":"используется: {list}","space.in_use":"План используется пространством — сначала отцепите его","btn.use":"Выбрать","confirm.delete_plan":"Удалить файл плана «{name}» с сервера? Действие необратимо.","toast.plans_list_failed":"Не удалось получить список планов: {err}","toast.plan_delete_failed":"Не удалось удалить план: {err}","marker.hide":"Скрыть","marker.hide_tip":"Устройство исчезнет с плана после сохранения, но продолжит участвовать в расчёте сигнала комнаты. Вернуть его можно через каталог «Устройства» в редакторе устройств.","marker.show":"Показать","marker.show_tip":"Устройство снова появится на плане после сохранения.","marker.hidden_ghost":"Устройство скрыто пользователем","marker.ha_disabled_device":"Устройство деактивировано в Home Assistant и скрыто с плана.","marker.ha_disabled_entity":"Сущность деактивирована в Home Assistant и скрыта с плана.","marker.ha_disabled_all_entities":"У устройства нет активных сущностей Home Assistant, поэтому оно скрыто с плана.","marker.ha_registry_limited":"Полный реестр Home Assistant недоступен этому пользователю. Неподтверждённый объект временно нельзя показывать или использовать.","marker.delete_tip":"Полностью удалить устройство с плана и из всех расчётов. Позже его можно добавить заново.","tap.run":"Запустить автоматизацию/скрипт/сцену","tap.cover":"Открыть/закрыть (шторы/жалюзи)","marker.run_target_label":"Что запускать","marker.run_search_ph":"Поиск: автоматизация, скрипт или сцена…","marker.run_target_gone":"Цель {id} не найдена — выберите заново","marker.tap_confirm":"Спрашивать подтверждение","marker.tap_confirm_tip":"Перед выполнением показать диалог подтверждения — защита от случайных нажатий.","marker.toggle_hint_single":"Цель: {name} ({id}).","marker.virtual_light_target":"Виртуальный свет: {name}.","marker.virtual_light_current":"Ручное состояние: {state} → {effect}.","marker.virtual_light_state_on":"включён","marker.virtual_light_state_off":"выключен","marker.toggle_hint_group":"Переключатся источники ({count}): {names}.","marker.toggle_hint_current":"Сейчас: {state} → {effect}.","marker.toggle_hint_group_current":"Сейчас включено {on} из {count} → {effect}.","marker.toggle_hint_skipped":"Не будут затронуты ({count}): {targets}.","marker.toggle_effect_turn_on":"включится","marker.toggle_effect_turn_off":"выключится","marker.toggle_effect_open":"откроется","marker.toggle_effect_close":"закроется","marker.toggle_effect_stop":"остановится","marker.toggle_effect_toggle":"состояние переключится","marker.toggle_skip_missing":"не найдено","marker.toggle_skip_ha_disabled":"деактивировано в HA","marker.toggle_skip_unavailable":"недоступно","marker.toggle_skip_unsupported":"переключение не поддерживается","marker.toggle_skip_secure":"заблокировано из соображений безопасности","marker.toggle_none_no_binding":"У устройства нет привязки, состояние переключать нечем. По нажатию ничего не произойдёт.","marker.toggle_none_no_actionable_entity":"У устройства нет состояния, которое можно переключить. По нажатию ничего не произойдёт.","marker.toggle_none_configured_targets_missing":"Настроенные цели сейчас недоступны. Собственная сущность устройства не будет подставлена вместо них.","marker.toggle_none_ha_disabled":"Цель деактивирована в Home Assistant и не может использоваться на плане.","marker.toggle_none_unavailable":"Цель сейчас недоступна. По нажатию ничего не произойдёт.","marker.toggle_none_unsupported":"Для этой сущности Home Assistant не предоставляет безопасного переключения. По нажатию ничего не произойдёт.","marker.toggle_none_secure":"Переключение замков, сигнализации и защитных ворот с плана заблокировано из соображений безопасности.","run.automation":"автоматизация","run.script":"скрипт","run.scene":"сцена","confirm.tap_run":"Запустить «{name}»?","confirm.tap_toggle":"Переключить «{name}»?","confirm.tap_cover":"Открыть/закрыть «{name}»?","confirm.current_state":"Текущее состояние: {state}","confirm.expected_state":"После переключения: {state}","confirm.group_current":"включено {on} из {total}","confirm.group_all_on":"все включены","confirm.group_all_off":"все выключены","confirm.unavailable_targets":"Недоступно: {count}","confirm.expected_by_ha":"Состояние определит Home Assistant","confirm.state_on":"Включено","confirm.state_off":"Выключено","confirm.state_open":"Открыто","confirm.state_closed":"Закрыто","confirm.state_opening":"Открывается","confirm.state_closing":"Закрывается","confirm.state_stopped":"Остановлено","confirm.state_unknown":"Неизвестно","toast.run_started":"Запущено: {name}","toast.run_target_missing":"Цель запуска не найдена — проверьте настройки устройства","toast.run_target_required":"Выберите автоматизацию, скрипт или сцену","toast.tap_target_changed":"Цель действия изменилась. Повторите попытку.","toast.virtual_light_toggle_failed":"Не удалось переключить виртуальный свет: {err}","toast.value_badge_source_required":"Выберите значение для бейджа","btn.run":"Выполнить","vac.section":"Робот-пылесос: живая позиция","vac.autocal":"Настроить автоматически","vac.live":"Живая позиция на плане","vac.trail":"Показывать путь робота","vac.cal_maps":"Откалиброваны карты: {maps}","vac.autocal_no_rooms":"Интеграция не отдаёт список комнат — откройте «Подогнать вручную»","vac.autocal_no_match":"Не совпали имена комнат (нужно ≥3 общих) — откройте «Подогнать вручную»","vac.autocal_done":"Готово: привязка по {rooms} комнатам. Запустите уборку и проверьте","vac.cal_need_pos":"Робот сейчас не отдаёт координаты — запустите уборку и поставьте на паузу","vac.cal_done":"Калибровка сохранена. Запустите уборку и проверьте","vac.cal_cancelled":"Калибровка отменена","vac.fit":"Подогнать вручную","vac.fit_hint":"Перетащите карту робота на место, растяните за уголки","vac.fit_rotate":"Повернуть 90°","vac.fit_mirror":"Отразить","vac.trail_never":"Не показывать никогда","vac.trail_cleaning":"Во время уборки","vac.trail_always":"Показывать всегда","gs.bg_group":"Фон сцены","gs.bg_color":"Цвет фона вокруг плана","gs.bg_default":"Как в теме","gs.bg_theme":"по умолчанию — из темы","gs.bg_mode":"Фон плана","gs.bg_static":"Статичный цвет","gs.bg_daynight":"Следует за Солнцем","gs.bg_daynight_hint":"Фон проходит рассвет, день, закат и ночь по данным sun.sun, а при их недоступности — по локальным часам. Компас для фона не нужен.","gs.sun_group":"Солнце","gs.sun_missing":"Сущность sun.sun не найдена — фон следует локальным часам, а оконные лучи недоступны.","gs.north":"Север на плане","gs.north_ph":"не задан","gs.north_hint":"Север нужен только для оконных лучей (шаг 1°, с Shift 15°); солнечный фон работает без него.","gs.north_clear":"Сбросить","gs.north_letter":"С","gs.sun_rays":"Солнце в окнах","gs.about_group":"О карточке","gs.about_version":"Houseplan Card v{v}","gs.about_github":"GitHub · документация и issues","gs.about_telegram":"Чат в Telegram","space.bg_color":"Цвет фона вокруг плана","space.bg_inherit":"Наследовать общий","space.bg_inherited":"наследуется из общих настроек","space.bg_mode":"Фон плана","space.north":"Север на плане (переопределение)","space.north_inherited":"наследуется: {v}","space.sun_rays":"Солнце в окнах","space.sun_inherit":"Наследовать общий","space.sun_on":"Вкл","space.sun_off":"Выкл","canvas.far_objects":"Объектов далеко от плана: {n}","canvas.show_far":"Показать","canvas.home_tip":"План там — нажмите, чтобы вписать","gs.grid_group":"Обслуживание планов","gs.grid_hint":"Обновляет модели данных, выравнивает элементы по сетке и объединяет лишние фрагменты стен. Перед записью будет показан точный отчёт.","gs.align_all":"Оптимизировать планы","gs.align_title":"Оптимизировать планы","gs.align_none":"Все планы уже используют актуальную и оптимальную модель данных.","gs.optimize_no_automatic_changes":"Автоматических изменений нет. Проверьте пункты ниже.","gs.align_count":"Сдвинется элементов: {n} из {total}, максимум на {cm} см.","gs.align_where":"Наибольший сдвиг — в пространстве «{s}».","gs.align_turned":"Проёмов с исправлением угла: {n}.","gs.align_removed_drafts":"Схлопнувшиеся на сетке некорректные контуры удалены: {n}.","gs.optimize_redundant_drafts":"Сохранённые цепочки стен, полностью скрытые стенами комнат, удалены: {n}.","gs.align_preflight_failed":"Не удалось безопасно проверить геометрию следующих пространств: {spaces}{more}.","gs.align_preflight_hint":"Планы не изменены. Скопируйте диагностику кнопкой ниже и приложите её к отчёту об ошибке вместе с экспортом пространства.","gs.preflight_reason_prepare-exception":"Не удалось подготовить геометрию пространства (исключение при сборке модели)","gs.preflight_reason_wall-null":"Тело стен не построилось (объединение вернуло пустоту)","gs.preflight_reason_wall-degraded-extra":"Тело стен деградировало с лишней геометрией","gs.preflight_reason_wall-failed-core":"Ядро тела стен не собралось","gs.preflight_reason_wall-exception":"Построение стен упало с исключением","gs.preflight_reason_floor-null":"Контур пола не построился","gs.preflight_reason_floor-exception":"Построение пола упало с исключением","gs.preflight_copy":"Скопировать диагностику","gs.preflight_copied":"Диагностика скопирована","gs.preflight_update_hint":"Версии карточки и интеграции различаются — обновите House Plan и повторите.","gs.align_preflight_space":"Пространство {n}","gs.align_preflight_more":" и ещё {n}","gs.optimize_changes":"Миграций модели: {m}; обновлено пространств: {c}; устранён шум координат: {p}; объединено отрезков реальных стен: {w}; объединено отрезков стен нулевой толщины: {s}; независимых: {i}.","gs.zero_walls_migrated":"Преобразовано виртуальных участков: {n}.","gs.wall_segments_migrated":"Стабилизировано сегментов стен: {n}.","gs.optimize_lattice_summary":"Канонизировано шумовых значений координат: {n}; максимальный сдвиг: {cm} см.","gs.optimize_lattice_space":"{space}: канонизировано значений координат: {n}; оставлено значений вне сетки: {far}.","gs.optimize_coincident_partitions":"Скрытые участки независимых стен поглощены стенами комнат: {n}.","gs.optimize_openings_rehosted":"Проёмы перепривязаны к стенам комнат: {n}.","gs.optimize_walls_straightened":"Выпрямлено стен: {n}; максимальное перемещение: {cm} см.","gs.optimize_walls_straightened_where":"Максимальная правка стены: {s}.","gs.optimize_walls_straighten_skipped":"Оставлено почти осевых стен, которые нельзя безопасно выпрямить: {n}.","gs.optimize_glow_migration":"Старый Glow: пространств — {spaces} → без заливки данных + независимый Glow; комнат — {rooms} → наследуемая заливка + независимый Glow.","gs.optimize_references":"Исправлено ссылок: пространства — {spaces}; комнаты — {rooms}; позиции — {positions}; устройств отвязано от отсутствующих пространств — {detached}.","gs.optimize_reference_more":", и ещё {n}","gs.optimize_orphans_removed":"Убрано забытых записей: {total} — подписи комнат: {rooms}; устройства: {devices}; групповые метки: {groups}. Все они принадлежали пространствам, удалённым ранее.","gs.optimize_live_positions":"Старые позиции в удалённых пространствах принадлежат существующим объектам: {n}{names}. Они будут сохранены.","gs.optimize_live_positions_remove":"Старые позиции в удалённых пространствах принадлежат существующим объектам: {n}{names}. Они выбраны для удаления.","gs.optimize_live_names":": {names}{more}","gs.optimize_live_remove":"Убрать старые позиции","gs.optimize_live_keep":"Сохранить старые позиции","gs.optimize_live_selected":"Старые позиции будут убраны после применения оптимизации.","gs.optimize_unverified":"Не удалось безопасно проверить позиций: {n}. Они оставлены без изменений.","gs.optimize_registry_limited":"Для безопасной проверки нужен полный доступ администратора к реестрам Home Assistant.","gs.optimize_vacuum_warning":"Сопоставления комнат пылесоса требуют проверки: {n}.","gs.optimize_details":"Подробности","gs.optimize_details_more":"И ещё записей: {n}.","gs.optimize_detail_removed":"будет удалено","gs.optimize_detail_live":"будет сохранено","gs.optimize_detail_unverified":"не проверено","gs.optimize_detail_room_label":"подпись комнаты","gs.optimize_detail_device":"устройство","gs.optimize_detail_group":"групповая метка","gs.optimize_detail_unknown":"неизвестный владелец","gs.optimize_detail_item":"{status}: {kind} {id}; прежнее пространство {space}","gs.align_warn":"Элементы, намеренно поставленные между узлами, будут сдвинуты. После операции доступна одна отмена — только до следующего изменения плана.","gs.align_run":"Оптимизировать","gs.align_done":"Планы оптимизированы: сдвинуто элементов — {n}, обслужено записей — {m}, исправлено ссылок — {r}","gs.optimize_undo":"Отменить последнюю оптимизацию","gs.optimize_undone":"Последняя оптимизация отменена","decor.furniture":"Мебель","furn.title":"Библиотека мебели","furn.symbol":"Символ","furn.group_furniture":"Мебель","furn.group_appliance":"Техника","furn.group_sanitary":"Сантехника","furn.group_other":"Прочее","furn.width":"Ширина","furn.depth":"Глубина","furn.pick_hint":"Выберите символ и кликните по плану.","furn.place_hint":"Кликните по плану — предмет встанет к ближайшей стене. Shift — свободно.","furn.sym_sofa":"Диван","furn.sym_armchair":"Кресло","furn.sym_coffee_table":"Журнальный столик","furn.sym_table_dining":"Обеденный стол","furn.sym_table_round":"Круглый стол","furn.sym_chair":"Стул","furn.sym_desk":"Письменный стол","furn.sym_bed_double":"Двуспальная кровать","furn.sym_bed_single":"Односпальная кровать","furn.sym_nightstand":"Тумбочка","furn.sym_wardrobe":"Шкаф","furn.sym_bookshelf":"Стеллаж","furn.sym_fridge":"Холодильник","furn.sym_stove":"Плита","furn.sym_dishwasher":"Посудомоечная машина","furn.sym_washer":"Стиральная машина","furn.sym_dryer":"Сушильная машина","furn.sym_tv":"Телевизор","furn.sym_ac":"Кондиционер","furn.sym_water_heater":"Бойлер","furn.sym_toilet":"Унитаз","furn.sym_bathtub":"Ванна","furn.sym_shower":"Душ","furn.sym_sink":"Раковина","furn.sym_kitchen_sink":"Кухонная мойка","furn.sym_bidet":"Биде","furn.sym_stairs":"Лестница","furn.sym_fireplace":"Камин","furn.sym_plant":"Растение","furn.sym_rug":"Ковёр","common.yes":"Да","common.no":"Нет","vac.diag_source":"Источник","vac.diag_platform":"Интеграция","vac.diag_status":"Статус","vac.diag_position":"Позиция","vac.diag_rooms":"Комнаты","vac.diag_rooms_value":"{total} · совпало имён: {matched} · {readiness}","vac.autocal_ready":"автокалибровка доступна","vac.autocal_not_ready":"нужно 3 совпавших имени","vac.diag_path":"Путь интеграции","vac.diag_map":"ID карты","vac.source_none":"не выбран","vac.source_status_ok":"Готов","vac.source_status_missing":"Не найден","vac.source_status_disabled":"Деактивирован в Home Assistant","vac.source_status_unavailable":"Недоступен","vac.source_status_unverified":"Нельзя проверить с текущими правами","vac.source_status_unsupported":"Нет данных позиции","vac.source_status_none":"Нет источника","vac.source_banner_missing":"Сохранённый источник больше не существует. Он не заменён автоматически: выберите другой или восстановите его в Home Assistant.","vac.source_banner_disabled":"Сохранённый источник деактивирован в Home Assistant. Активируйте его там или выберите другой.","vac.source_banner_unverified":"Текущих прав Home Assistant недостаточно для проверки источника. Привязка сохранена и не будет заменена автоматически.","vac.choose_source":"Выбрать источник","vac.source_auto":"Автоматически","vac.source_auto_hint":"Использовать совместимую сущность этого устройства","vac.all_cameras":"Все камеры","vac.all_cameras_warn":"Камера может не отдавать данные робота. Выбирайте её только если это карта вашего пылесоса.","vac.all_cameras_empty":"Других сущностей камеры не найдено.","vac.platform_unknown":"интеграция неизвестна","vac.cap_position":"позиция","vac.cap_rooms_short":"комнаты","vac.cap_path":"путь","vac.cap_map":"ID карты","vac.cap_none":"данные робота не обнаружены","vac.xcme_hint":"Включите атрибуты Xiaomi Cloud Map Extractor:","vac.documentation":"Документация","vac.residual_title":"Проверьте автокалибровку","vac.residual_message":"Совпавшие комнаты расходятся максимум на {error}. Примените приблизительную калибровку, подгоните её вручную либо отмените без изменения сохранённых настроек.","vac.apply_proposal":"Применить","gs.backup_group":"Резервная копия и перенос","gs.backup_hint":"Скачайте переносимую JSON-копию или проверьте и импортируйте копию, созданную House Plan.","backup.export_open":"Экспорт","backup.import_open":"Импорт","backup.export_title":"Экспорт House Plan","backup.import_title":"Импорт House Plan","backup.export_hint":"Выберите, должна ли копия содержать всю конфигурацию House Plan или только текущее пространство.","backup.full":"Полная копия","backup.current_space":"Текущее пространство","backup.current_space_title":"Текущее пространство: {title}","backup.no_current_space":"Нет текущего пространства","backup.plan_only":"Только планировка","backup.plan_only_hint":"Сохранить комнаты, стены, проёмы, декор и позиции подписей комнат без устройств и привязок Home Assistant.","backup.plan_only_preview":"Файл содержит только планировку","backup.privacy_warning":"Архив сохраняет названия, идентификаторы Home Assistant и точные координаты. Внутренние планы и вложения указываются ссылками, но не вкладываются; текущие состояния и маршруты пылесосов не включаются.","backup.download":"Скачать JSON","backup.export_done":"Резервная копия скачана","backup.reading":"Проверяем резервную копию…","backup.revalidated":"После предпросмотра план изменился. Сводка обновлена — проверьте её и подтвердите ещё раз.","backup.error.unauthorized":"У вас нет прав на экспорт или импорт этого плана.","backup.error.not_ready":"House Plan ещё не готов. Повторите попытку через несколько секунд.","backup.error.too_large":"Размер резервной копии превышает 8 МиБ.","backup.error.invalid_json":"Выбранный файл не является корректным JSON.","backup.error.invalid_format":"Выбранный файл не является резервной копией House Plan.","backup.error.unsupported_export_version":"Эта версия формата резервной копии не поддерживается установленной версией.","backup.error.future_model":"Резервная копия создана в более новой версии модели данных House Plan.","backup.error.invalid_config":"Резервная копия содержит некорректную конфигурацию House Plan.","backup.error.wall_model_migration_blocked":"Не удалось безопасно обновить модель стен из резервной копии. Сначала оптимизируйте исходный план и повторите экспорт.","backup.error.invalid_layout":"Резервная копия содержит некорректные позиции объектов.","backup.error.invalid_content":"Резервная копия содержит некорректные или несогласованные ссылки на файлы.","backup.error.space_not_found":"Выбранное пространство больше не существует.","backup.error.capacity_exceeded":"Добавление этой копии превысит ограничения размера плана.","backup.error.preview_expired":"Время предпросмотра истекло. Выберите файл резервной копии заново.","backup.error.preview_owner_mismatch":"Этот предпросмотр принадлежит другому пользователю Home Assistant.","backup.error.conflict":"После предпросмотра план изменился. Проверьте обновлённую сводку.","backup.error.content_confirmation_required":"Подтвердите отсоединение недоступных локальных файлов.","backup.error.commit_failed":"Не удалось безопасно применить копию. Предыдущий план восстановлен или ожидает восстановления.","backup.error.missing_plan":"После предпросмотра исчез связанный файл плана. Проверьте копию ещё раз.","backup.error.missing_content":"После предпросмотра исчез связанный локальный файл. Проверьте копию ещё раз.","backup.error.marker_control_missing":"В резервной копии отсутствует связанный источник света на плане.","backup.error.marker_control_not_light":"Связанная цель больше не отмечена как источник света.","backup.error.marker_control_self":"Источник света не может управлять самим собой.","backup.error.marker_control_cycle":"Резервная копия содержит циклическую цепочку управления светом.","backup.error.duplicate_marker_control":"Резервная копия содержит повторяющуюся связь с источником света.","backup.error.no_backup":"Нет снимка импорта или оптимизации, который можно восстановить.","backup.same_source":"Создано на этом экземпляре Home Assistant","backup.foreign_source":"Создано на другом экземпляре Home Assistant","backup.created":"Создано: {value}","backup.versions":"Карточка {card}; интеграция {integration}; модель данных {model}","backup.count_spaces":"Пространств: {n}","backup.count_rooms":"Комнат: {n}","backup.count_walls":"Стен: {n}","backup.count_openings":"Проёмов: {n}","backup.count_decor":"Объектов декора: {n}","backup.count_markers":"Устройств: {n}","backup.count_layout":"Позиций: {n}","backup.bindings":"Привязки — устройства: {device}, сущности: {entity}, виртуальные: {virtual}; позиций без пространства: {legacy}","backup.binding_status":"Статус на целевом экземпляре — активных: {active}, деактивированных: {disabled}, отсутствующих: {missing}","backup.missing_areas":"На целевом экземпляре отсутствуют зоны: {areas}","backup.dropped_marker_links":"Связи с источниками света вне переносимого пространства пропущены: {n}.","backup.repaired_target_refs":"Существующих ссылок восстановлено этим импортом: {n}.","backup.preserved_unresolved_refs":"Неоднозначные ссылки сохранены без изменений: {n}.","backup.preserved_unresolved_hint":"House Plan ничего не угадывал и не удалял. После импорта запустите «Оптимизировать планы», чтобы проверить оставшиеся ссылки.","backup.import_details":"Подробности восстановления ссылок","backup.import_detail.incoming_remapped":"Ссылок обновлено внутри импортируемой копии: {n}","backup.import_detail.target_repaired":"Существующих ссылок восстановлено: {n}","backup.import_detail.preserved_unresolved":"Неразрешимых ссылок сохранено: {n}","backup.import_detail.collisions":"Конфликтов назначения безопасно сохранено: {n}","backup.import_detail.dropped_links":"Входящих связей пропущено по правилам переноса: {n}","backup.import_detail.bounded_lineages":"Чрезмерно вложенных идентификаторов ограничено: {n}","backup.replace_warning":"Текущая конфигурация и расположение будут заменены. Загруженные файлы не удаляются. Одну отмену можно выполнить до следующего изменения плана.","backup.foreign_bookkeeping":"Служебные списки известных и новых устройств другого экземпляра импортированы не будут.","backup.final_name":"Название нового пространства","backup.target_settings":"Глобальные настройки целевого экземпляра не изменятся.","backup.duplicates":"Уже существующих привязок: {n}","backup.skip":"Пропустить повторяющиеся устройства","backup.virtual_copy":"Добавить безопасные статичные виртуальные копии","backup.content":"Связанное содержимое","backup.content_available":"доступно локально","backup.content_external":"внешняя ссылка","backup.content_detach_required":"будет отвязано","backup.confirm_detach":"Я понимаю, что недоступные внутренние планы и вложения будут отвязаны от импортируемой конфигурации.","backup.replace":"Заменить","backup.add":"Добавить пространство","backup.space_done":"Пространство импортировано: комнат — {rooms}, устройств — {markers}, существующих ссылок восстановлено — {refs}","backup.full_done":"Копия восстановлена: пространств — {spaces}, комнат — {rooms}, устройств — {markers}","backup.undo_import":"Отменить последний полный импорт","backup.import_undone":"Полный импорт отменён"}}],ra=oa,la=new Map(aa.map(e=>[e.code,e]));function ca(e){return"string"==typeof e?e.trim().replaceAll("_","-").toLowerCase():""}function ha(e){return la.get(ca(e))}function da(e,t){const i=[{value:"",label:e},...aa.map(({code:e,nativeLabel:t})=>({value:e,label:t}))],s="string"==typeof t?t:"";return s&&!i.some(e=>e.value===s)&&i.push({value:s,label:ha(s)?.nativeLabel??s}),i}function pa(e,t){return function(e,t,i,s){const n=new Map(i.map(e=>[ca(e),e])),o=n.get(ca(e));if(o)return o;const a=ca(t),r=n.get(a);return r||(n.get(a.split("-")[0]||"")??s)}(t,e?.locale?.language||e?.language,aa.map(({code:e})=>e),"en")}function ua(e,t,i){const s=ha(e)?.dictionary;return ss(s?.[t]??ra[t]??t,i)}function _a(e,t){const i=ha(e)?.dictionary[t]??ra[t];return"string"==typeof i&&i.trim().length>0}class ma extends he{constructor(){super(...arguments),this.deviceName="",this._metadataConnection=null,this._demoUntil=0,this._demoTimer=0,this._demoGeneration=1,this._demoKind=null,this._reducedMotion=!1,this._onMotionChange=e=>{this._reducedMotion=e.matches,this.requestUpdate()},this._startShortDemo=()=>{const e=this.presentation;e&&"icon_ripple"===e.display&&"none"===e.pulse.kind&&(this._demoGeneration++,this._demoKind="short",this._demoUntil=Date.now()+3300,window.clearTimeout(this._demoTimer),this._demoTimer=window.setTimeout(()=>{this._demoUntil=0,this._demoTimer=0,this._demoKind=null,this.requestUpdate()},3330),this.requestUpdate())},this._toggleContinuousDemo=()=>{const e=this.presentation;e&&"icon_ripple"===e.display&&"none"===e.pulse.kind&&("continuous"===this._demoKind?this._clearDemo():(this._clearDemo(),this._demoGeneration++,this._demoKind="continuous",this._demoUntil=Number.POSITIVE_INFINITY),this.requestUpdate())}}connectedCallback(){super.connectedCallback(),this._motionMedia=window.matchMedia?.("(prefers-reduced-motion: reduce)"),this._reducedMotion=!!this._motionMedia?.matches,this._motionMedia?.addEventListener?.("change",this._onMotionChange),this._ensureMetadata()}disconnectedCallback(){this._metadataRelease?.(),this._metadataRelease=void 0,this._metadataConnection=null,this._clearDemo(),this._motionMedia?.removeEventListener?.("change",this._onMotionChange),this._motionMedia=void 0,super.disconnectedCallback()}willUpdate(e){e.has("hass")&&this._ensureMetadata();const t=this.presentation,i=e.get("presentation");e.has("presentation")&&i?.binding!==t?.binding&&this._clearDemo(),t&&this._demoKind&&("icon_ripple"!==t.display||"none"!==t.pulse.kind)&&this._clearDemo()}_ensureMetadata(){const e=this.hass?.connection||null;e&&e!==this._metadataConnection&&(this._metadataRelease?.(),this._metadataConnection=e,this._metadataRelease=Qo(this.hass,()=>this.requestUpdate()))}_clearDemo(){window.clearTimeout(this._demoTimer),this._demoTimer=0,this._demoUntil=0,this._demoKind=null}get _lang(){return pa(this.hass)}_t(e,t){return ua(this._lang,e,t)}_providerText(e){return"houseplan"===e.domain?this._t("marker.preview.virtual_provider"):e.label.toLowerCase()===e.domain.toLowerCase()?e.domain:`${e.label} (${e.domain})`}_providers(){return this.presentation&&this.registry?function(e,t,i,s=ea(e)){if("virtual"===t)return[{domain:"houseplan",label:"House Plan",confidence:"registry-owner"}];const n=t.indexOf(":");if(n<1)return[];const o=t.slice(0,n),a=t.slice(n+1);if("entity"===o){const t=na(e,a,i,s);return t?[t]:[]}if("device"!==o)return[];const r=i.devices?.[a]||e?.devices?.[a];if(!r)return[];const l=[r.config_entry_id,...Array.isArray(r.config_entries)?r.config_entries:[]].filter(e=>"string"==typeof e&&!!e).map(t=>{const i=s.configEntries[t];return ia(e,i?.domain,"registry-owner",s,t)});if(l.some(Boolean))return sa(l);const c=[];for(const[t,n]of Object.entries(i.entities||{}))n?.device_id===a&&null==n?.disabled_by&&c.push(na(e,t,i,s));return c.some(Boolean)?sa(c):sa((Array.isArray(r.identifiers)?r.identifiers:[]).map(t=>{const i=Array.isArray(t)?t[0]:null;return ia(e,i,"identifier-fallback",s)}))}(this.hass,this.presentation.binding,this.registry,ea(this.hass)):[]}_providerSummary(e){if(!e.length)return this._t("marker.preview.unknown_provider");const t=e.slice(0,2).map(e=>this._providerText(e)),i=e.length-t.length;return t.join(", ")+(i>0?` · ${this._t("marker.preview.more_sources",{n:i})}`:"")}_sourceSummary(e){const t=e.visualSources;return t.length?1===t.length?`${t[0].name} · ${t[0].eid} · ${this._sourceProvider(t[0].eid)}`:2===t.length?t.map(e=>e.name).join(" · "):this._t("marker.preview.multiple_sources",{n:t.length}):this._t("marker.preview.no_source")}_stateSummary(e){if(!e.visualSources.length)return this._t("marker.preview.no_state");if(1===e.visualSources.length)return e.visualSources[0].stateText||this._t("marker.preview.no_state");const t=[...new Set(e.visualSources.map(e=>e.stateText).filter(Boolean))];return 1===t.length?t[0]:this._t("marker.preview.mixed_states")}_reason(e){return this._t(`marker.preview.reason.${e}`)}_sourceProvider(e){if(!this.registry)return this._t("marker.preview.unknown_provider");const t=na(this.hass,e,this.registry,ea(this.hass));return t?this._providerText(t):this._t("marker.preview.unknown_provider")}render(){const e=this.presentation;if(!e)return G;const t=!!this._demoKind&&this._demoUntil>Date.now()&&"icon_ripple"===e.display&&"none"===e.pulse.kind,i=t?(()=>{const t=function(e,t,i,s,n=null){return{kind:t,reason:"short"===t?"event":"running",generation:Math.max(1,Math.trunc(i)),expiresAt:"short"===t?n:null,color:e.color,diameterScale:s?1:e.diameterScale,animated:!s,reducedMotionIndicator:s?"dot":"none"}}(e.pulse,this._demoKind,this._demoGeneration,this._reducedMotion,"short"===this._demoKind?this._demoUntil:null);return{...e,pulse:t,classes:[...e.classes.filter(e=>!e.startsWith("pulse-")),`pulse-${t.kind}`,...t.generation%2==0?["pulse-gen2"]:[]]}})():e,s=this._providers(),n="none"!==e.pulse.kind,o=i.scale*(i.pulse.animated?i.pulse.diameterScale:1);let a=-o/2,r=o/2,l=-o/2,c=o/2;if(i.valueBadge){const e=i.scale*Math.min(4,Math.max(.9,.29*i.valueBadge.text.length+.28)),t=.7*i.scale,s=.6*i.scale;"right"===i.valueBadge.position&&(r=Math.max(r,s+e)),"left"===i.valueBadge.position&&(a=Math.min(a,-s-e)),"top"===i.valueBadge.position&&(l=Math.min(l,-s-t)),"bottom"===i.valueBadge.position&&(c=Math.max(c,s+t))}if(null!=i.lqiText){const e=i.scale*("bottom"===i.valueBadge?.position?1.55:.95);c=Math.max(c,e)}const h=Math.min(1,2.35/Math.max(1,r-a),2.35/Math.max(1,c-l)),d=Math.round(100*h),p=[`left:calc(50% - ${54*((a+r)/2)*h}px)`,`top:calc(50% - ${54*((l+c)/2)*h}px)`,h<1?`transform:scale(${h})`:""].filter(Boolean).join(";"),u=["dev",Uo(this.hass),...i.classes,"virtual"===i.binding?"virtual":"",i.haDisabled?"ghost ha-disabled":"",null!=i.valueText?"valonly":""].filter(Boolean).join(" "),_=Go(i).join(";"),m=t?this._t("continuous"===this._demoKind?"marker.preview.demo_continuous_notice":"marker.preview.demo_short_notice"):this._reason(e.explanation.reason),g=[this.deviceName,this._providerSummary(s),this._stateSummary(e),m,e.valueFullText||"",Io(e.valueBadge),null!=e.lqiText&&e.lqiBand?this._t(`marker.lqi_a11y_${e.lqiBand}`,{value:e.lqiText}):""].filter(Boolean).join(". ");return q`
${this._t("marker.preview.title")} @@ -4555,7 +4555,7 @@ globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="30d20d6f6822065e2d5226b18abbb05d8d26 ${this._t("continuous"===this._demoKind?"marker.preview.stop_continuous":"marker.preview.demo_continuous")}
`:G} -
`}}ha.properties={hass:{attribute:!1},presentation:{attribute:!1},registry:{attribute:!1},deviceName:{attribute:!1}},ha.styles=[Ke,o` +
`}}ma.properties={hass:{attribute:!1},presentation:{attribute:!1},registry:{attribute:!1},deviceName:{attribute:!1}},ma.styles=[Ke,o` :host { display: block; min-width: 0; } .devicepreview { margin: 4px 0 14px; @@ -4622,14 +4622,14 @@ globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="30d20d6f6822065e2d5226b18abbb05d8d26 .previewstage { min-height: 142px; } .previewfacts > div { grid-template-columns: minmax(0, 1fr); gap: 2px; } } - `],customElements.get("hp-device-preview")||customElements.define("hp-device-preview",ha);const da=Math.tan(.25*Math.PI/180);function pa(e,t){const i=Math.abs(Number(t[0])-Number(e[0])),s=Math.abs(Number(t[1])-Number(e[1]));if(!([i,s].every(Number.isFinite)&&i>0&&s>0))return null;const n=i>=s?"horizontal":"vertical",o=Math.max(i,s),a=Math.min(i,s);return a/o>da?null:{axis:n,major:o,minor:a,angleDegrees:180*Math.atan2(a,o)/Math.PI}}function ua(e,t){const i=pa(e,t);return i?"horizontal"===i.axis?[Number(t[0]),Number(e[1])]:[Number(e[0]),Number(t[1])]:[Number(t[0]),Number(t[1])]}const _a=e=>`${e[0]},${e[1]}`,ma=(e,t)=>e[0]===t[0]&&e[1]===t[1],ga=(e,t)=>{const i=_a(e),s=_a(t);return i{let t=0;for(let i=0;i{if(e.length<3)return!1;for(let t=0;t1e-12},ba=e=>{for(let t=0;t+1ma(e,t.from)?[...t.to]:[...e],wa=(e,t)=>e.map(e=>Array.isArray(e?.poly)?{...e,poly:e.poly.map(e=>ya(e,t))}:e),ka=(e,t,i)=>{const s=e.flatMap((e,t)=>hi(e)?.some(e=>ma(e,i.from))?[t]:[]);if(!s.length)return!1;for(const i of s){const s=hi(e[i]),n=hi(t[i]);if(!s||!n)continue;if(!va(n))return!1;const o=Math.sign(fa(s)),a=Math.sign(fa(n));if(o&&a&&o!==a)return!1}const n=new Set;for(const e of s){const i=hi(t[e]);if(i)for(let s=0;s{let i=0;for(const s of e){const e=hi(s);if(e)for(let s=0;s{const{a:i,b:s,axis:n}=e,o="horizontal"===n?{from:s,to:[s[0],i[1]]}:{from:s,to:[i[0],s[1]]},a="horizontal"===n?{from:i,to:[i[0],s[1]]}:{from:i,to:[s[0],i[1]]};return[{move:o,preservedDegree:xa(t,i)},{move:a,preservedDegree:xa(t,s)}].sort((e,t)=>t.preservedDegree-e.preservedDegree||_a(e.move.to).localeCompare(_a(t.move.to))||_a(e.move.from).localeCompare(_a(t.move.from))).map(e=>e.move)};const Sa=(e,t)=>[e[0]-t[0],e[1]-t[1]],Ma=(e,t)=>[e[0]+t[0],e[1]+t[1]],Ca=(e,t)=>e[0]*t[0]+e[1]*t[1],Da=e=>Math.hypot(e[0],e[1]);function Pa(e){let t=0;for(let i=0;ie[1]!=l>e[1]&&e[0]<(r-o)*(e[1]-a)/(l-a)+o&&(i=!i)}return i}([r[0]+a[0]*l,r[1]+a[1]*l],e)&&(a=[-a[0],-a[1]]),a}function Ra(e){const t=e.length;if(t<3)return!1;for(let i=0;i(e[0]-n[0])*r[1]-(e[1]-n[1])*r[0],c=e=>(e[0]-n[0])*r[0]+(e[1]-n[1])*r[1],h=i,d=a-i;for(const t of e){const e=Math.abs(l(t));if(e<=i)continue;const n=c(t);n<=h||n>=d||eMath.abs(a+(e-p)/g*(r-a));s=Math.min(s,f(_),f(m))}}return s}function za(e,t,i){if(Di(e,t,i))return!0;if(Ci(e,t,i)||Ci(t,e,i))return!1;let s=0;try{const i=ni([[...e.map(e=>[e[0],e[1]]),[e[0][0],e[0][1]]]],[[...t.map(e=>[e[0],e[1]]),[t[0][0],t[0][1]]]]);for(const e of i)e?.[0]&&(s+=Ti(e[0]))}catch{return!1}return s>Math.max(1e-7,i*i)}function Fa(e,t,i){for(const s of t)for(let t=0;ti)continue;const c=(e.x-n[0])*l[0]+(e.y-n[1])*l[1];if(c-e.length/2>=-i&&c+e.length/2<=r+i)return!0}return!1}function Na(e,t,i){const s=Math.abs(t[0]-e[0]),n=Math.abs(t[1]-e[1]);return s<=i&&n>i?"v":n<=i&&s>i?"h":null}function Ea(e,t,i){return Math.abs(e[0]-t[0])<=i&&Math.abs(e[1]-t[1])<=i}function Oa(e,t,i,s,n){return Ea(e,i,n)&&Ea(t,s,n)||Ea(e,s,n)&&Ea(t,i,n)}function Ha(e,t,i,s,n){const o=Na(e,t,n);return o&&Na(i,s,n)===o?"h"===o?Math.abs(e[1]-i[1])>n||Math.abs(e[1]-s[1])>n?0:Math.max(0,Math.min(Math.max(e[0],t[0]),Math.max(i[0],s[0]))-Math.max(Math.min(e[0],t[0]),Math.min(i[0],s[0]))):Math.abs(e[0]-i[0])>n||Math.abs(e[0]-s[0])>n?0:Math.max(0,Math.min(Math.max(e[1],t[1]),Math.max(i[1],s[1]))-Math.max(Math.min(e[1],t[1]),Math.min(i[1],s[1]))):0}function La(e,t,i,s){const n=e.length,o=Na(e[(t-1+n)%n],e[t],s),a=Na(e[(t+1)%n],e[(t+2)%n],s),r="h"===i?"v":"h";return o===r&&a===r}function Ba(e){let t=1/0,i=1/0,s=-1/0,n=-1/0;for(const o of e)t=Math.min(t,o[0]),i=Math.min(i,o[1]),s=Math.max(s,o[0]),n=Math.max(n,o[1]);return[t,i,s,n]}function ja(e,t,i){const s=Ba(e),n=Ba(t);return s[2]n}const Wa=(e,t)=>"h"===t?e[0]:e[1],Ua=(e,t)=>"h"===t?e[1]:e[0];function Ga(e,t,i,s,n){const o=e.find(e=>e.id===t);if(!o)return null;const a=o.poly[i],r=o.poly[(i+1)%o.poly.length],l=Na(a,r,n);if(!l)return null;const c=0===s?r:a,h=0===s?a:r,d=Wa(c,l),p=Wa(h,l),u=Ua(c,l),_=function(e,t,i,s){const n=[];for(const o of e)for(let e=0;es||Math.abs(Ua(r,t)-i)>s)continue;const l=Wa(a,t),c=Wa(r,t),h=Math.min(l,c),d=Math.max(l,c);d-h>s&&n.push({roomId:o.id,edge:e,lo:h,hi:d})}return n.sort((e,t)=>e.lo-t.lo||e.hi-t.hi||e.roomId.localeCompare(t.roomId)||e.edge-t.edge)}(e,l,u,n),m=function(e,t,i,s){const n=[t,i];for(const o of e){const e=Math.max(t,o.lo),a=Math.min(i,o.hi);a-e>s&&n.push(e,a)}const o=[...new Set(n)].sort((e,t)=>e-t),a=[];for(let t=0;t+1r>e.lo-s&&re.roomId))].sort();a.push({lo:i,hi:n,owners:l})}return a}(_,Math.min(d,p),Math.max(d,p),n);return!m.length||m.some(e=>e.owners.length<1||e.owners.length>2)?null:{roomId:t,edge:i,movedEndpoint:s,axis:l,line:u,fixed:d,moving:p,intervals:_,baseline:m}}function Va(e,t,i){const s=[];for(const n of e.intervals){const o=t.polys[n.roomId];if(!o){s.push(n);continue}if(n.edge<0||n.edge>=o.length)continue;const a=o[n.edge],r=o[(n.edge+1)%o.length];if(Na(a,r,i)!==e.axis||Math.abs(Ua(a,e.axis)-e.line)>i||Math.abs(Ua(r,e.axis)-e.line)>i)continue;const l=Wa(a,e.axis),c=Wa(r,e.axis),h=Math.min(l,c),d=Math.max(l,c);d-h>i&&s.push({...n,lo:h,hi:d})}return s}function Ka(e,t,i){return new Set(e.filter(e=>t>e.lo-i&&te.roomId)).size}function Ya(e,t,i){for(const s of t.sideOwnership){const t=e.polys[s.roomId];if(!t)return!1;const n=t[s.edge],o=t[(s.edge+1)%t.length];if(Na(n,o,i)!==s.axis)return!1;const a=Wa(0===s.movedEndpoint?n:o,s.axis),r=Va(s,e,i),l=(s.moving>=s.fixed?s.baseline[s.baseline.length-1]:s.baseline[0]).owners.length;if(l<1||l>2)return!1;const c=Math.min(s.fixed,s.moving,a),h=Math.max(s.fixed,s.moving,a),d=[c,h,s.fixed,s.moving,a];for(const e of s.intervals)d.push(e.lo,e.hi);for(const e of r)d.push(e.lo,e.hi);const p=[...new Set(d.filter(e=>e>=c&&e<=h))].sort((e,t)=>e-t),u=Math.min(s.fixed,s.moving),_=Math.max(s.fixed,s.moving),m=Math.min(s.fixed,a),g=Math.max(s.fixed,a);for(let e=0;e+1u-i&&o<_+i,c=o>m-i&&o2||d>2)return!1;if(a&&c){if(h!==d)return!1}else if(!a&&c){if(d!==l||h>0&&h!==d)return!1}else if(2===h?2!==d:d>1)return!1}}return!0}function Ja(e,t,i,s){const n=[i.n[0]*s,i.n[1]*s],o={polys:{},openings:{},movedSpans:{}};for(const t of i.roomIds){const s=e.find(e=>e.id===t),a=i.edgeByRoom[t];if(!s||null==a)continue;const r=(a+1)%s.poly.length;o.polys[t]=s.poly.map((e,t)=>t===a||t===r?Ma(e,n):[...e]),o.movedSpans[t]=[[Ma(s.poly[a],n),Ma(s.poly[r],n)]]}for(const e of t)i.movingOpeningIds.includes(e.id)&&(o.openings[e.id]=[e.x+n[0],e.y+n[1]]);return o}function Xa(e,t,i,s,n,o,a,r){if(!function(e,t,i,s){if(Ta([e.x,e.y],t,i)>2*s)return!1;const n=Da(Sa(i,t));if(n<=s)return!1;const o=[(i[0]-t[0])/n,(i[1]-t[1])/n],a=(e.x-t[0])*o[0]+(e.y-t[1])*o[1];return a>=-s&&a<=n+s}(e,t,i,r))return!0;if(Ta([e.x,e.y],s,n)>2*r)return!1;const l=0===o?s:n;return Da(Sa([e.x,e.y],l))>=e.length/2+a-r}function Za(e,t,i,s){const n=s.movingHalf||0;return"circle"===e.kind?Ta(e.center,t,i)2)return!1;const r=Ja(e,t,i,s);if(Object.keys(r.polys).length!==i.roomIds.length)return!1;if(!Ya(r,i,o))return!1;const l=new Set(i.roomIds),c=e=>r.polys[e.id]||e.poly;for(const s of i.roomIds){const l=e.find(e=>e.id===s),c=r.polys[s],h=i.edgeByRoom[s];if(!l||!c||c.length!==i.topology[s]||c.length!==l.poly.length||!Ra(c))return!1;const d=l.poly.length,p=(h-1+d)%d,u=[p,h,(h+1)%d];for(const e of u)if(pa(c[e],c[(e+1)%d]))return!1;const _=Pa(l.poly),m=Pa(c);if(Math.abs(m)e.id===t),s=r.polys[t];for(const n of e){if(n.id===t||l.has(n.id))continue;const e=c(n);if(!ja(i.poly,n.poly,o)||!ja(s,e,o))if(Ci(i.poly,n.poly,o)){if(!Ci(s,e,o))return!1}else if(Ci(n.poly,i.poly,o)){if(!Ci(e,s,o))return!1}else if(Ci(s,e,o)||Ci(e,s,o)||za(s,e,o))return!1}}e.find(e=>e.id===i.roomId);const h=r.polys[i.roomId],d=i.edgeByRoom[i.roomId],p=h[d],u=h[(d+1)%h.length];if(Math.abs(s)>o)for(const e of n.obstacles||[])if(Za(e,p,u,n))return!1;for(const e of t){if(!i.movingOpeningIds.includes(e.id))continue;const t=r.openings[e.id];if(!t||e.hosted)return!1;if(!Fa({...e,x:t[0],y:t[1]},[h],2*o))return!1}return!0}const er=new WeakMap;function tr(e,t,i){const s=i/t;return Ti(e)*s*s/1e4}function ir(e,t){return t?`${Math.round(10.7639*e)} ft²`:`${(Math.round(10*e)/10).toFixed(1)} m²`}const sr=e=>"number"==typeof e&&Number.isFinite(e),nr=(e,t)=>{const i=new Map;for(const s of e||[])!sr(s?.cm)||!t&&s.cm<=0||i.set(s.cm,(i.get(s.cm)||0)+1);return i},or=e=>[String(e),"см"].join(" ");function ar(e,t,i={}){if(i.allowClear)return[];const s=!0===i.exactMultiplicity,n=nr(e,s),o=nr(t,s),a=[];for(const[e,t]of n){const i=o.get(e)||0;0===i?a.push({invariant:"wall_records",kind:"lost",owner:or(e),reference:`было ${t}`,detail:"записи этой толщины исчезли целиком"}):s&&i!==t&&a.push({invariant:"wall_records",kind:"count",owner:or(e),reference:`было ${t}, стало ${i}`,detail:"изменилось число записей этой толщины"})}if(s)for(const[e,t]of o)n.has(e)||a.push({invariant:"wall_records",kind:"count",owner:or(e),reference:`было 0, стало ${t}`,detail:"появились записи новой толщины"});return a}class rr{constructor(){this._selectedRoomId=null,this._session=null,this._eligibility=null}get dragging(){return null!==this._session}ownsPointer(e){return this._session?.pointerId===e}get selectedRoomId(){return this._selectedRoomId}get snapshotIdentity(){return this._session?.snapshotIdentity||null}get activePointerId(){return this._session?.pointerId??null}get moved(){return!0===this._session?.moved}get delta(){return this._session?.delta||0}get rooms(){return this._session?.rooms||null}get openings(){return this._session?.openings||null}get plan(){return this._session?.plan||null}get preview(){return this._session?.accepted?.preview||null}get liveLabels(){return this._session?.accepted?.labels||null}selectRoom(e){this._selectedRoomId=e}restoreSelection(e){this._selectedRoomId=e}escapeIdle(){return this._selectedRoomId?(this._selectedRoomId=null,"selection-cleared"):"exit-tool"}resolve(e,t,i){this._eligibility&&this._eligibility.context===e||(this._eligibility={context:e,values:new Map});const s=this._eligibility.values.get(t);if(s)return s;const n=i();return this._eligibility.values.set(t,n),n}begin(e){return!this._session&&(this._session={pointerId:e.pointerId,start:[...e.start],roomId:e.roomId,plan:e.plan,options:e.options,rooms:e.rooms,openings:e.openings,snapshotIdentity:e.snapshotIdentity,before:e.before,moved:!1,delta:0,changedRoomIds:[...e.plan.roomIds],rejectionNotified:!1,wallUnionBefore:e.wallUnionBefore,accepted:null},!0)}move(e){const t=this._session;if(!t||t.pointerId!==e.pointerId)return{kind:"no-op"};const i=(s=t.start,n=e.point,o=t.plan.n,[s?.[0],s?.[1],n?.[0],n?.[1],o?.[0],o?.[1]].every(Number.isFinite)?(n[0]-s[0])*o[0]+(n[1]-s[1])*o[1]:0);var s,n,o;const a=e.snap([t.plan.a[0]+t.plan.n[0]*i,t.plan.a[1]+t.plan.n[1]*i]),r=(a[0]-t.plan.a[0])*t.plan.n[0]+(a[1]-t.plan.a[1])*t.plan.n[1],l=function(e,t,i,s,n,o){if(!Number.isFinite(s)||Math.abs(s)<1e-9)return 0;const a=Math.sign(s),r=Math.abs(s),l=Math.max(Math.abs(n),1e-6);let c=er.get(i);c&&c.opts===o||(c={opts:o,values:new Map},er.set(i,c));const h=c.values;let d=0;for(let s=Math.min(l,r),n=0;n<4096&&s<=r+1e-9;n++,s=Math.min(r,s+l)){const n=a*s,c=`${n.toFixed(9)}|${l.toFixed(9)}`;let p=h.get(c);if(void 0===p&&(p=Qa(e,t,i,n,o),h.size<4096&&h.set(c,p)),!p)break;if(d=n,Math.abs(s-r)<=1e-9)break}return d}(t.rooms,t.openings,t.plan,r,e.step,t.options);if(t.moved&&l===t.delta)return{kind:"no-op"};const c=Ja(t.rooms,t.openings,t.plan,l);let h;try{if(h=e.project(t.snapshotIdentity,c.polys,c.openings,t.changedRoomIds,t.rooms),!h.ok)return this._projectionRejected(t);if(ar(h.value.beforeWalls,h.value.afterWalls,{exactMultiplicity:!0}).length)return this._projectionRejected(t)}catch{return this._projectionRejected(t)}const d=t.accepted,p={preview:h.value.preview,labels:null,artifact:h.value.artifact,beforeWalls:h.value.beforeWalls,afterWalls:h.value.afterWalls};t.accepted=p;try{e.publish(p.preview,p.artifact),p.labels=e.measure(c,t.plan)}catch{t.accepted=d;try{e.publish(d?.preview||null,d?.artifact||null)}catch{}return this._projectionRejected(t)}return t.moved=!0,t.delta=l,{kind:"accepted",preview:h.value.preview,labels:p.labels,artifact:h.value.artifact}}finish(e){const t=this._session;if(!t||t.pointerId!==e.pointerId)return{kind:"no-op"};const i=t.accepted;let s;if(t.moved&&Math.abs(t.delta)>1e-9&&i)if(e.currentSnapshotIdentity!==t.snapshotIdentity)s={kind:"rejected",reason:"stale-snapshot"};else if(Qa(t.rooms,t.openings,t.plan,t.delta,t.options))if(ar(i.beforeWalls,i.afterWalls,{exactMultiplicity:!0}).length)s={kind:"rejected",reason:"wall-records"};else{let n=!1;try{n=e.validatePreview(i.preview)}catch{n=!1}s=n?{kind:"commit",preview:i.preview,before:t.before}:{kind:"rejected",reason:"invalid-candidate"}}else s={kind:"rejected",reason:"invalid-topology"};else s={kind:"no-op"};return this._session=null,"commit"===s.kind&&(this._eligibility=null),s}cancel(e,t){const i=this._session;return!i||void 0!==t&&i.pointerId!==t?{kind:"no-op"}:(this._session=null,this._eligibility=null,{kind:"cancelled",restoreWallUnion:e===i.snapshotIdentity?i.wallUnionBefore:null})}reset(){this._selectedRoomId=null,this._session=null,this._eligibility=null}_projectionRejected(e){const t=!e.rejectionNotified;return e.rejectionNotified=!0,{kind:"rejected",notify:t}}}const lr=(e,t)=>[(e[0]-t.x)/Math.max(1e-9,t.w)*t.stageWidth,(e[1]-t.y)/Math.max(1e-9,t.h)*t.stageHeight];function cr(e){const{poly:t,edge:i,text:s,view:n}=e,o=t[i],a=t[(i+1)%t.length],r=[(o[0]+a[0])/2,(o[1]+a[1])/2],l=function(e,t){const i=e[t],s=e[(t+1)%e.length],n=s[0]-i[0],o=s[1]-i[1],a=Math.hypot(n,o)||1;return(e=>{let t=0;for(let i=0;i=0?[-o/a,n/a]:[o/a,-n/a]}(t,i),c=Math.hypot(a[0]-o[0],a[1]-o[1])||1,h=[(a[0]-o[0])/c,(a[1]-o[1])/c],d=lr(r,n),p=lr(e.gearCenter,n),u=Math.max(34,7.2*s.length+12),_=Math.abs(l[0])>=Math.abs(l[1])?Math.max(28,u/2+4):Math.max(28,13),m=d[0]+l[0]*_,g=d[1]+l[1]*_,f=t=>{return i=m+h[0]*t,s=g+h[1]*t,n=u,o=18,a=p[0],r=p[1],l=e.gearWidthPx,c=e.gearHeightPx,2*Math.abs(i-a)=Math.abs(h[1])?h[0]:h[1])>0?-1:1,t=Math.max(n.stageWidth,n.stageHeight,64);for(let i=4;i<=t;i+=4){const t=i*e;if(!f(t)){v=t;break}const s=-t;if(!f(s)){v=s;break}}}const b=l[0]*_+h[0]*v,y=l[1]*_+h[1]*v,w=Math.hypot(b,y)||1,k=y/w*12,x=[r[0]+b/w*12*n.w/Math.max(1,n.stageWidth),r[1]+k*n.h/Math.max(1,n.stageHeight)];return{anchor:r,offsetXPx:b,offsetYPx:y,tangentOffsetPx:v,side:Math.abs(l[0])>=Math.abs(l[1])?l[0]<0?"left":"right":l[1]<0?"above":"below",leader:{a:r,b:x}}}function hr(e){const t=e%360;return t<0?t+360:t}function dr(e,t){const i=function(e,t){return hr(e+t)}(e,t)*Math.PI/180;return[Math.sin(i),-Math.cos(i)]}const pr=Object.freeze({dawn:Object.freeze({top:"#aabdd1",bottom:"#e8c8b7",horizon:"rgba(255,201,156,.56)",sun:"rgba(255,188,125,.78)",vignette:"rgba(65,72,99,.21)",outlineNear:"rgba(74,57,61,.25)",outlineMid:"rgba(255,238,224,.40)",outlineFar:"rgba(255,224,202,.18)"}),day:Object.freeze({top:"#dce9ef",bottom:"#cbdce3",horizon:"rgba(255,245,220,.45)",sun:"rgba(255,239,190,.72)",vignette:"rgba(65,91,105,.16)",outlineNear:"rgba(45,62,71,.28)",outlineMid:"rgba(255,255,255,.42)",outlineFar:"rgba(255,255,255,.20)"}),dusk:Object.freeze({top:"#48536c",bottom:"#9a7380",horizon:"rgba(242,156,114,.34)",sun:"rgba(255,167,113,.55)",vignette:"rgba(20,26,44,.39)",outlineNear:"rgba(238,219,225,.40)",outlineMid:"rgba(229,207,218,.26)",outlineFar:"rgba(215,190,205,.12)"}),night:Object.freeze({top:"#111a27",bottom:"#1f2f3e",horizon:"rgba(79,120,151,.16)",sun:"rgba(169,208,231,0)",vignette:"rgba(3,8,14,.58)",outlineNear:"rgba(218,238,249,.56)",outlineMid:"rgba(174,215,238,.30)",outlineFar:"rgba(136,194,226,.14)"})}),ur=e=>"number"==typeof e&&Number.isFinite(e),_r=(e,t,i)=>Math.min(i,Math.max(t,e));function mr(e){return e.elevation<=-6?"night":e.elevation>=6?"day":e.rising?"dawn":"dusk"}function gr(e){const t=(Math.floor(Number(e)||0)%1440+1440)%1440;return t>=300&&t<480?"dawn":t>=480&&t<1080?"day":t>=1080&&t<1260?"dusk":"night"}function fr(e){const t=mr(e),i=e.azimuth*Math.PI/180;return{sunX:50-42*Math.sin(i),sunY:78-_r(e.elevation,0,90)/90*64,sunOpacity:"night"===t?0:_r((e.elevation+6)/12,0,1)}}function vr(e){const t=(Math.floor(Number(e)||0)%1440+1440)%1440;if(t<300||t>=1260)return{sunX:50,sunY:78,sunOpacity:0};const i=(t-300)/960,s=(t-300)/120,n=(1260-t)/120;return{sunX:8+84*i,sunY:78-64*Math.sin(i*Math.PI),sunOpacity:Math.max(.18,Math.min(s,n,1))}}function br(e,t=new Date){const i=function(e){const t=e?.states?.["sun.sun"]?.attributes;return t&&ur(t.azimuth)&&ur(t.elevation)&&"boolean"==typeof t.rising?{azimuth:hr(t.azimuth),elevation:t.elevation,rising:t.rising}:null}(e);if(i)return{phase:mr(i),source:"sun",...fr(i)};const s="number"==typeof t?t:function(e=new Date){return 60*e.getHours()+e.getMinutes()}(t);return{phase:gr(s),source:"clock",...vr(s)}}function yr(e){return`${e.source}|${e.phase}|${e.sunX.toFixed(2)}|${e.sunY.toFixed(2)}|`+e.sunOpacity.toFixed(3)}const wr=[[-90,"#070c14"],[-12,"#070c14"],[-4,"#131a28"],[0,"#4a3527"],[10,"#e8ddcf"],[30,"#ffffff"],[90,"#ffffff"]],kr=e=>Math.min(1,Math.max(0,e));function xr(e,t,i=6){const s=e.angle*Math.PI/180,n=[Math.sin(s),-Math.cos(s)],o=s=>{const o=[e.x+n[0]*i*s,e.y+n[1]*i*s];return t.find(e=>e.poly.length>=3&&vi(o,e.poly))||null},a=o(1),r=o(-1);return a&&r?null:a||r?a?{normal:[-n[0],-n[1]],roomId:a.id}:{normal:n,roomId:r.id}:null}function $r(e,t,i){return i>0&&e[0]*t[0]+e[1]*t[1]>.05}function Sr(e,t,i,s){return[[e[0],e[1]],[t[0],t[1]],[t[0]+i[0]*s,t[1]+i[1]*s],[e[0]+i[0]*s,e[1]+i[1]*s]]}function Mr(e,t){try{const i=ni([[...e.map(e=>[e[0],e[1]]),[e[0][0],e[0][1]]]],[[...t.map(e=>[e[0],e[1]]),[t[0][0],t[0][1]]]]),s=[];for(const e of i){const t=e?.[0];!Array.isArray(t)||t.length<4||s.push(t.slice(0,t.length-1).map(e=>[e[0],e[1]]))}return s}catch{return[]}}function Cr(e,t,i,s,n,o,a){if(!(s>0))return[];const r=dr(i,n),l=[-r[0],-r[1]],c=function(e){const t=Math.min(90,Math.max(0,e));return.7*(.8+1.7*Math.pow(1-t/90,1.6))}(s),h=[];for(const i of t){if(!(i.length>0))continue;const t=xr(i,e);if(!t||!$r(t.normal,r,s))continue;const n=e.find(e=>e.id===t.roomId);if(!n)continue;const d=o&&o[t.roomId]||n.poly,p=i.angle*Math.PI/180,u=i.length/2,_=[-t.normal[0],-t.normal[1]],m=Math.max(0,a?.[i.id]||0),g=i.x+_[0]*m/2,f=i.y+_[1]*m/2,v=Math.cos(p)*u,b=Math.sin(p)*u,y=[g-v,f-b],w=[g+v,f+b],k=c*i.length,x=Mr(Sr(y,w,l,k),d);if(!x.length)continue;const $=l[0]*_[0]+l[1]*_[1];h.push({openingId:i.id,roomId:t.roomId,polys:x,a:y,b:w,dir:l,len:k,normal:_,depth:k*$})}return h}const Dr=e=>"number"==typeof e&&Number.isInteger(e)&&e>=0&&e<=359?e:null;function Pr(e,t){const i=Dr(t?.north_deg);return null!==i?i:Dr(e?.north_deg)}function Tr(e,t){const i=e=>"static"===e||"daynight"===e?e:null;return i(t?.bg_mode)??i(e?.bg_mode)??"static"}function Ir(e,t){const i=t?.sun_rays;return"boolean"==typeof i?i:!0===e?.sun_rays}function Rr(e){const t=e?.states?.["sun.sun"]?.attributes,i=Number(t?.azimuth),s=Number(t?.elevation);return Number.isFinite(i)&&Number.isFinite(s)?{azimuth:i,elevation:s}:null}const Ar=["dawn","day","dusk","night"];function zr(e){if(!e)return"";const t=pr[e.phase];return[`--hp-day-cycle-outline-near:${t.outlineNear}`,`--hp-day-cycle-outline-mid:${t.outlineMid}`,`--hp-day-cycle-outline-far:${t.outlineFar}`].join(";")}function Fr(e,t=1){if(!e)return G;const i=[`--hp-day-cycle-sun-x:${e.sunX.toFixed(2)}%`,`--hp-day-cycle-sun-y:${e.sunY.toFixed(2)}%`,`--hp-day-cycle-sun-opacity:${e.sunOpacity.toFixed(3)}`,`opacity:${Math.min(1,Math.max(0,t)).toFixed(4)}`].join(";");return q``}houseplanContinuityTrace(){return[...this._continuityHistory,...this._continuity.trace].slice(-80).map(e=>({...e,...e.stage?{stage:[...e.stage]}:{}}))}render(){if(!this._config)return G;const e=this._snap?.config;if(!e)return this._errorCard(ua(this._lang,"space_card.loading"));const t=this._config.space,i=this._renderDeviceSnapshot,s=Z_({hass:i?.hass||this.hass,cfg:e,layout:this._snap?.layout||{},spaceId:t,iconSize:this._config.icon_size,stageWidth:this._stageWidth,lang:this._lang,displayUrl:e=>this._signer.display(this.hass,e),assetLoaded:this._onAssetLoaded,registry:i?{revision:i.sourceSequence,authoritative:!1,access:"limited",entities:{...i.hass.entities},devices:{...i.hass.devices},lastSuccess:i.capturedAt}:An(this.hass),devices:[...i?.devices||this._devices],presentations:i?.presentations,activityRuntime:this._activityRuntime,reducedMotion:this._reducedMotion,virtualLights:this._snap?.virtualLights,liveStates:!1!==this._config.live_states,showTemperature:!1!==this._config.show_temperature,showSignal:!1!==this._config.show_signal,inert:this._continuity.overlayBlocksInteraction});if(!s)return this._errorCard(ua(this._lang,"space_card.not_found",{id:t}));const n=Eh(e).find(e=>e.id===t),o=void 0!==this._config.title?this._config.title:n?.title||"",a=!1!==this._config.show_button,r=this._config.button_label||ua(this._lang,"space_card.button"),l=this._continuity.overlayVisible||"recovery-error"===this._continuity.state?this._continuity.recoveryReason:null;return q` ${r} `:G} - `}}pm.properties={hass:{attribute:!1},_config:{state:!0},_snap:{state:!0},_continuityEpoch:{state:!0}},pm.styles=[Ke,o` + `}}fm.properties={hass:{attribute:!1},_config:{state:!0},_snap:{state:!0},_continuityEpoch:{state:!0}},fm.styles=[Ke,o` .hp-static-title { font-weight: 700; padding: 10px 14px 6px; @@ -4892,7 +4892,7 @@ globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="30d20d6f6822065e2d5226b18abbb05d8d26 text-align: center; color: var(--secondary-text-color, #9aa4ad); } - `],customElements.get("houseplan-space-card")||customElements.define("houseplan-space-card",pm),window.customCards=window.customCards||[],window.customCards.find(e=>"houseplan-space-card"===e.type)||window.customCards.push({type:"houseplan-space-card",name:"House Plan — Space (static)",description:"Read-only live schematic of a single houseplan space, with a deep-link button.",preview:!1,documentation:"https://github.com/Matysh/houseplan-card"});const um=o` + `],customElements.get("houseplan-space-card")||customElements.define("houseplan-space-card",fm),window.customCards=window.customCards||[],window.customCards.find(e=>"houseplan-space-card"===e.type)||window.customCards.push({type:"houseplan-space-card",name:"House Plan — Space (static)",description:"Read-only live schematic of a single houseplan space, with a deep-link button.",preview:!1,documentation:"https://github.com/Matysh/houseplan-card"});const vm=o` :host { --hp-editor-tray-bg-fallback: color-mix(in srgb, var(--card-background-color, var(--hp-bg)) 94%, var(--hp-line)); --hp-editor-tray-bg: color-mix(in srgb, var(--card-background-color, var(--hp-bg)) 86%, transparent); @@ -5063,7 +5063,7 @@ globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="30d20d6f6822065e2d5226b18abbb05d8d26 .editor-secondary { transition: none; } .editor-group-launcher .group-chevron { transition: none; } } -`,_m=(e,t)=>(e.composedPath?.()||[e.target]).some(e=>(e=>!!e&&"function"==typeof e.matches)(e)&&t(e));class mm{constructor(e){this.host=e,this._openGroupId=null,this._groupGeneration=0,this._renderedContext="",this._focusOwned=!1,this._currentModel=null,this._blocked=!1,this._dismissPointerTarget=null,this._globalDismissListening=!1,this._globalDismissGuard=e=>{this.handleOutsideDismiss(e)}}get hasOpenGroup(){return null!==this._openGroupId}get groupGeneration(){return this._groupGeneration}activeGroup(e){return this._openGroupId&&e.find(e=>e.id===this._openGroupId)||null}reset(){this._openGroupId=null,this._contentAnimation?.cancel(),this._contentAnimation=void 0,this._renderedContext="",this._focusOwned=!1,this._currentModel=null,this._blocked=!1,this._dismissPointerTarget=null,clearTimeout(this._dismissTimer),this._dismissTimer=void 0,this._syncGlobalDismissListener()}closeForNavigation(){const e="palette"===this._currentModel?.kind?this._currentModel.dismiss:void 0,t=!!this._openGroupId||!!e;this._openGroupId=null,e?.(),e&&(this._currentModel=null),this._clearDismissClick(),t&&this.host.requestUpdate(),this._syncGlobalDismissListener()}openPalette(){this._openGroupId&&this.closeGroup(!1)}toggleGroup(e,t){this._openGroupId!==t?e.some(e=>e.id===t)&&("palette"===this._currentModel?.kind&&this._currentModel.dismiss?.(),this._groupGeneration+=1,this._openGroupId=t,this.host.clearTip(),this.host.requestUpdate(),this._syncGlobalDismissListener()):this.closeGroup(!1)}closeGroup(e){const t=this._openGroupId;this._openGroupId=null,this.host.requestUpdate(),this._syncGlobalDismissListener(),e&&t&&this.host.updateComplete().then(()=>{const e=this.host.root(),i=[...e.querySelectorAll("[data-editor-group]")].find(e=>e.dataset.editorGroup===t&&null!==e.offsetParent);(i||e.querySelector(".editbar-tools"))?.focus?.()})}renderGroupLauncher(e,t,i){const s=this._openGroupId===e.id,n=e.items.find(t=>t.id===e.activeItemId&&!t.disabled);return q``:G} - `}houseplanContinuityTrace(){return[...this._continuityHistory,...this._continuity.trace].slice(-80).map(e=>({...e,...e.stage?{stage:[...e.stage]}:{}}))}getCardSize(){return 12}get _norm(){return!(!this._serverCfg||!this._serverCfg.spaces.length)}_cfgFingerprint(){const e=this._serverCfg?.spaces||[];let t=e.length+":";for(const i of e){t+=(i.id||"")+","+(i.plan_aspect||"")+","+(i.plan_url||"").length+","+(i.plan_x??"")+","+(i.plan_y??"")+","+(i.plan_scale??"")+","+(i.plan_scale_x??"")+","+(i.plan_scale_y??"")+","+(i.plan_angle??"")+","+(i.rooms?.length||0)+","+(i.openings?.length||0)+","+(i.decor?.length||0)+";";for(const e of i.rooms||[]){const i=e.poly?.[0],s=e.poly?.[e.poly.length-1];t+=(e.poly?.length||0)+"."+(e.id||"")+"."+(e.open_to||[]).join("+")+"."+(e.area||"")+"."+JSON.stringify(e.settings||0)+"."+(e.x??"")+","+(e.y??"")+","+(e.w??"")+","+(e.h??"")+","+(i?i[0]+"/"+i[1]:"")+","+(s?s[0]+"/"+s[1]:"")+";"}}return t}get _model(){if(!this._serverCfg)return[];const e=this._cfgEpoch+"|"+this._cfgFingerprint();if(this._modelCache&&this._modelCache.key===e)return this._modelCache.model;const t=this._buildModel();return this._modelCache={key:e,model:t},t}_buildModel(){if(!this._serverCfg)return[];const e=this._renderCfg;return Rh(e).map((t,i)=>{const s=e.spaces[i]?.plan_url;return t.bg&&s?{...t,bg:{...t.bg,href:s}}:t})}_spaceModel(){return this._hasFixedFloor?Ud(this._model,this._space):(e=this._model,t=this._space,e.find(e=>e.id===t)??e[0]);var e,t}_spaceModelById(e){return Ud(this._model,e)}_syncEmptySpaceState(){if(!!this._serverCfg&&0===this._serverCfg.spaces.length){if(!this._emptySpaceStateActive){this._emptySpaceStateActive=!0;for(const e of this._pointers.keys())for(const t of this.renderRoot.querySelectorAll("*"))try{t.hasPointerCapture?.(e)&&t.releasePointerCapture(e)}catch{}this._pointers.clear(),this._panStart=null,this._panLock=null,this._pinchStart=null,this._swipeStart=null,this._drag=null,this._rlResize=null,this._vacFit=null,this._compassDrag=!1,this._cancelModeTransition(!1),this._mode="view",this._clearGeometryGesture(),this._geometryHistory.clear(),this._resumeDraftBySpace={},this._tip=null,this._hoverRoom=null,this._openingInfo=null,this._closeInfoCard(),this._deviceInbox=null,this._deviceInboxReturn=null,this._markerDialog=null,this._physicalDialog=null,this._backdropDialog=null,this._decorShapeDialog=null,this._decorTextDialog=null,this._roomDialog=!1,"edit"===this._spaceDialog?.mode&&(this._spaceDialog=null),this._editorSecondary.closeForNavigation(),this._saveConfigDebounced.cancel(),this._frame=null,this._planSnapGeometryCache=null,this._hiddenWallDiagnosticCache=null,this._decorSnapCache=null,this._commitSpace("",!0)}}else this._emptySpaceStateActive=!1}get _areaToSpace(){const e={};for(const t of this._model)for(const i of t.rooms)i.area&&(e[i.area]={space:t.id,room:i});return e}get _settings(){return this._serverCfg?.settings||{}}get _showAll(){return this._showHidden||!this._settings.filter_seeded&&!!this._settings.show_all}_seedHiddenDevices(){if(!this._serverCfg||!this._norm||!this._canEdit)return;const e=this._serverCfg,t=function(e){const t=e.hass,i=e.registry||An(t),s=En(t,i),n=On(t,i),{areaToSpace:o,markers:a,settings:r,excluded:l,iconRules:c}=e,h=!1!==r.group_lights,d=wo(a),p=bo(s,h).filter(e=>!ko(s,e.eid,d)),u=new Set(p.map(e=>e.area)),_=jn(s),m=qn(a,n),g=new Set(a.map(e=>e.binding)),f=[];for(const e of Object.values(s.devices)){const n=e.area_id;if(!n||!o[n])continue;if("service"===e.entry_type)continue;if(g.has("device:"+e.id))continue;if("active"!==Bn(t,"device:"+e.id,i).kind)continue;const a=Wn(s,e.id,_[e.id]||[],m);if(a.partial&&!a.entityIds.length)continue;const r=a.entityIds,d=Un(s,e,r);let p=l.has(d)||"Group"===e.model||/scene/i.test(e.model||"")||/bridge/i.test((e.model||"")+(e.name||""))||"myheat"===d&&!!e.via_device_id;if(!p&&h&&u.has(n)){const t=(e.name_by_user||e.name||"").trim();"mdi:lightbulb"===yo(s,t,e.model,r,c)&&(p=!0)}p&&f.push("device:"+e.id)}return f}({hass:this.hass,registry:this._haRegistry,areaToSpace:Object.fromEntries(Object.entries(this._areaToSpace).map(([e,t])=>[e,t.space])),markers:this._markers,settings:this._settings,excluded:this._excluded,firstSpaceId:this._model[0]?.id||"",iconRules:this._iconRules});if(!t.length&&e.settings?.filter_seeded)return;e.markers=e.markers||[];const i=[];for(const s of t){const t="h"+s.slice(s.indexOf(":")+1);e.markers.push({id:t,binding:s,hidden:!0}),i.push(s.slice(s.indexOf(":")+1))}const s={...e.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(e=>!i.includes(e))),e.settings=s,this._regSignature="",this._maybeRebuildDevices(),this._saveConfig(),this.requestUpdate()}get _iconRules(){const e=this._settings.icon_rules;if(!e||!Array.isArray(e)||!e.length)return;const t=JSON.stringify(e);return t!==this._rulesCompiledSrc&&(this._rulesCompiledSrc=t,this._rulesCompiled=Xe(e)),this._rulesCompiled}get _fillColors(){return ps(this._settings)}get _excluded(){const e=this._settings.exclude_integrations;return e?new Set(e):Ye}willUpdate(e){e.has("_serverCfg")&&this._cfgEpoch++,this._syncEmptySpaceState(),e.has("hass")&&this.hass&&(this._hassSequence++,this._renderSnapshotAt=Date.now(),this._continuity.note("hass-snapshot"),this._ensureHaRegistryAuthority(),this._planHassMemo=null,this._hookConnection(),!this._loadOk&&!this._loading&&this._loadTries<8&&this._loadFromServer(),this._maybeRebuildDevices(),this._vacTick(),this._activityTick()),this._continuity.hasCompleteFrame&&"steady"===this._continuity.state&&this._continuity.refreshCompleteFrame(this._visualFrameFingerprint()),this._captureRenderDeviceSnapshot()}updated(){this._pruneDevicePressFeedback(),this._syncDayCycleClock(),this._warmSnapshot(),this._dtMeasure();const e=this._stageEl;e&&!this._roViewport&&(this._roViewport=new ResizeObserver(()=>this._refitView()),this._roViewport.observe(e)),e&&this._booting&&!this._bootTimer&&this._bootWatch();const t=this.renderRoot.querySelector(".hdr");if(t&&e&&!this._roHdr){const i=()=>{const t=this.renderRoot.querySelector("ha-card");if(!t)return;const i=e.getBoundingClientRect().top-t.getBoundingClientRect().top,s=Math.min(Math.max(t.getBoundingClientRect().top,0),120),n=Math.round(i+s);n>=0&&n!==this._hdrH&&(this._hdrH=n),n>=0&&!this._booting&&!this._config?.kiosk&&e.clientHeight>0&&this._warmPatch({hdrH:n,stageH:e.clientHeight})};this._roHdr=new ResizeObserver(()=>requestAnimationFrame(i)),this._roHdr.observe(t),this._onWinResize=()=>requestAnimationFrame(i),window.addEventListener("resize",this._onWinResize),i()}if(e&&!this._view&&this._refitView(),this._editorSecondary.afterRender(),this._settleContinuityFrame(),this._serverStorage&&this._loadOk&&0===this._model.length&&!this._spaceDialog&&!this._importDialog&&!this._onboardingShown){this._onboardingShown=!0;const e=function(e){const t=e?.floors;if(!t||"object"!=typeof t)return[];const i=[];for(const e of Object.values(t))e&&e.floor_id&&i.push({id:e.floor_id,name:e.name||e.floor_id,level:e.level??null});return i.sort((e,t)=>{const i=e.level??1e9,s=t.level??1e9;return i!==s?i-s:e.name.localeCompare(t.name)}),i}(this.hass);e.length?this._importDialog={floors:e.map(e=>({...e,checked:!0}))}:this._openSpaceDialog("create")}}_adoptStructuralResponses(e,t,i){const s=e?.config,n=s&&Array.isArray(s.spaces)?s:null,o=Bd(n),a=o!==(this._cfgContentFingerprint||Bd(this._serverCfg));if(a&&(this._geometryHistory.clear(),this._pendingPhysicalWrites.clear(),this._serverCfg&&this._clearGeometryGesture(),this._serverCfg=n,this._cfgContentFingerprint=o),this._cfgRev=e?.rev??this._cfgRev,e&&("virtual_lights"in e||"config"in e)){const t=gn(this._virtualLights,e.virtual_lights,this._cfgRev,"virtual_lights"in e);vn(t)!==vn(this._virtualLights)&&(this._virtualLights=t,this._capturedSnapshotVirtual="")}let r=!1;if(void 0!==t||void 0!==i){const e=i??t?.layout??{},s=Bd(e);r=s!==(this._layoutContentFingerprint||Bd(this._layout)),r&&(this._layout=e,this._layoutContentFingerprint=s),this._layoutRev=t?.rev??this._layoutRev}return this._canOptimizeUndo=!(!e?.can_optimize_undo&&!t?.can_optimize_undo),this._haIntegrationVersion="string"==typeof e?.integration_version?e.integration_version:this._haIntegrationVersion,this._undoKind=e?.undo_kind||t?.undo_kind||null,"boolean"==typeof e?.can_write&&(this._serverCanWrite=e.can_write),a&&this._continuity.note("config-candidate",{configRev:this._cfgRev}),r&&this._continuity.note("layout-candidate",{layoutRev:this._layoutRev}),{configChanged:a,layoutChanged:r}}_resumePendingNavMode(){if(!this._pendingNavMode||!this._canEdit||this._config?.kiosk)return!1;const e=this._pendingNavMode;return this._pendingNavMode=null,this._setMode(e,!1),!0}async _loadFromServer(){this._loading=!0,this._loadTries++;const e=this._space,t=!!this._view;try{const[i,s]=await Promise.all([this.hass.callWS({type:"houseplan/config/get"}),this.hass.callWS({type:"houseplan/layout/get"})]),n=i?.config&&Array.isArray(i.config.spaces)?i.config:null,o=Bd(n)!==(this._cfgContentFingerprint||Bd(this._serverCfg))||Bd(s?.layout??{})!==(this._layoutContentFingerprint||Bd(this._layout));if(o){if(!await this._signer.prepareImage(this.hass,this._candidateBackdrop(n)))return this._continuity.note("asset-failed"),void this._scheduleLoadRetry(!0)}o&&this._continuity.hasCompleteFrame&&"steady"===this._continuity.state&&this._beginContinuityCandidate("structural-response",!0),this._connectionWasLost=!1,this._serverStorage=!0,"boolean"==typeof i?.can_write&&(this._serverCanWrite=i.can_write),this._canOptimizeUndo=!(!i?.can_optimize_undo&&!s?.can_optimize_undo),this._haIntegrationVersion="string"==typeof i?.integration_version?i.integration_version:this._haIntegrationVersion,this._adoptStructuralResponses(i,s),this._adoptInitialSpace(this._model,!0),this._resumePendingNavMode(),this._cacheSnapshot(),this._warmVpArmed&&this._space===this._warmVp?.space?this._warmVpArmed=!1:t&&this._space===e||this._restoreZoom(),this._loadOk=!0,this.hass.callWS({type:"houseplan/trail/get"}).then(e=>{this._vacSrvTrails=e?.trails||{},this.requestUpdate()}).catch(()=>{}),this._ensureLiveSyncSubscriptions()}catch(e){if(this._serverCfg)this._scheduleLoadRetry(!0);else if(this._loadTries>=8){this._serverStorage=!1;try{this._layout=JSON.parse(localStorage.getItem(kv)||"{}")||{}}catch{this._layout={}}}}finally{this._loading=!1,this._continuityDataReady=!0,this._regSignature="",this._maybeRebuildDevices(),this.requestUpdate()}}_ensureLiveSyncSubscriptions(){const e=this.hass?.connection;if(!e)return;if(e!==this._liveSyncConnection&&(this._unsubCfg?.(),this._unsubCfg=null,this._unsubLayout?.(),this._unsubLayout=null,this._unsubTrail?.(),this._unsubTrail=void 0,this._unsubVirtual?.(),this._unsubVirtual=null,this._liveSyncGeneration++,this._liveSyncAttempt=null,this._liveSyncConnection=e),this._liveSyncAttempt)return;const t=this._liveSyncGeneration,i=[],s=(s,n,o,a)=>{s()||i.push(async()=>{const i=await e.subscribeEvents(a,o);t===this._liveSyncGeneration&&this.isConnected&&this.hass?.connection===e&&!s()?n(i):i?.()})};if(s(()=>this._unsubCfg,e=>{this._unsubCfg=e},"houseplan_config_updated",e=>{const t=Number(e?.data?.rev??-1);t!==this._cfgRev&&this._reloadConfigOnly(!1,t)}),s(()=>this._unsubTrail,e=>{this._unsubTrail=e},"houseplan_trail_updated",async()=>{try{const e=await this.hass.callWS({type:"houseplan/trail/get"});this._vacSrvTrails=e?.trails||{},this.requestUpdate()}catch{}}),s(()=>this._unsubLayout,e=>{this._unsubLayout=e},"houseplan_layout_updated",e=>this._onLayoutEvent(Number(e?.data?.rev??-1))),s(()=>this._unsubVirtual,e=>{this._unsubVirtual=e},"houseplan_virtual_light_updated",e=>{const t=wn(this._virtualLights,e?.data);t!==this._virtualLights&&(this._virtualLights=t,this._capturedSnapshotVirtual="",this._cacheSnapshot(),this.requestUpdate())}),!i.length)return;const n=function(e){return Promise.allSettled(e.map(e=>Promise.resolve().then(e)))}(i).then(()=>{});this._liveSyncAttempt=n,n.finally(()=>{this._liveSyncAttempt===n&&(this._liveSyncAttempt=null)})}async _reloadConfigOnly(e=!1,t){if(!e){if(void 0!==t&&t<=this._cfgRev)return;if(this._saveConfigDebounced.pending()&&this._saveConfigDebounced.flush(),this._cfgWriting)return clearTimeout(this._reloadRetry),void(this._reloadRetry=window.setTimeout(()=>this._reloadConfigOnly(!1,t),400))}this._beginContinuityCandidate("config-reload",!1);try{const e=await this.hass.callWS({type:"houseplan/config/get"}),t=e?.config&&Array.isArray(e.config.spaces)?e.config:null;if(Bd(t)!==(this._cfgContentFingerprint||Bd(this._serverCfg))&&!await this._signer.prepareImage(this.hass,this._candidateBackdrop(t)))return this._continuity.note("asset-failed"),void this._scheduleLoadRetry(!0);const i=this._space;this._adoptStructuralResponses(e),this._adoptInitialSpace(this._model,!0),this._resumePendingNavMode(),this._cacheSnapshot(),this._space!==i&&this._restoreZoom(),this._regSignature="",this._maybeRebuildDevices(),this.requestUpdate()}catch(e){this._showToast(this._t("toast.cfg_reload_failed",{err:this._errText(e)}))}finally{this._continuityDataReady=!0,this.requestUpdate()}}_scheduleLoadRetry(e=!1){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,!e&&this._loadOk||this._loading||!this.hass||this._loadFromServer()},t)}_ensureHaRegistryAuthority(){const e=this.hass?.connection||null;e&&e!==this._haRegistryConnection&&(this._haRegistryRelease?.(),this._haRegistryConnection=e,this._haRegistryRev=-1,this._haBindingCacheKey="",this._planHassMemo=null,this._haRegistryRelease=Rn(this.hass,this._onHaRegistryUpdate),this._onHaRegistryUpdate())}get _haRegistry(){return An(this.hass)}get _planHass(){const e=this._haRegistry,t=Fn(this.hass,e),i=this._planHassMemo;if(i&&i.hass===this.hass&&i.sig===t)return i.active;const s=En(this.hass,e),n=On(this.hass,e);return this._planHassMemo={hass:this.hass,sig:t,active:s,full:n},s}_captureRenderDeviceSnapshot(){if(!this.hass)return;const e=Date.now(),t=[...this._activityRt.entries()].map(([t,i])=>`${t}:${i.gen}:${i.flashTs}:`+(i.flashKind&&(i.expiresAt||i.flashTs+nm)>e?1:0)).join("|"),i=vn(this._virtualLights);if(this._capturedSnapshotSequence===this._hassSequence&&this._capturedSnapshotDevices===this._devices&&this._capturedSnapshotLayout===this._layout&&this._capturedSnapshotConfigEpoch===this._cfgEpoch&&this._capturedSnapshotVirtual===i&&this._capturedSnapshotActivity===t)return;const s=this._planHass,n=new Map,o=new Map,a=new Set(["sun.sun"]);this._vacFit?.source&&a.add(this._vacFit.source);const r=new Set,l=new Set,c=e=>{if(!e)return;const t=e.indexOf(":");if(t<0)return void a.add(e);const i=e.slice(0,t),s=e.slice(t+1);"device"===i?r.add(s):"entity"===i&&a.add(s)};for(const e of this._model)for(const t of e.rooms)t.area&&l.add(t.area),c(t.settings?.temp_source),c(t.settings?.hum_source);for(const e of this._serverCfg?.spaces||[])for(const t of e.openings||[])for(const e of gi(t))a.add(e);for(const e of this._serverCfg?.spaces||[])for(const t of e.decor||[])if("text"===t.kind){for(const e of String(t.text||"").matchAll(/\{([^{}\r\n]+)\}/g)){const t=Yi(e[1]);t?.entity&&a.add(t.entity)}t.entity&&a.add(t.entity),o.set(`decor:${e.id}:${t.id}`,es(t.text,t,s,e=>!!s.entities?.[e]&&!!s.states?.[e]&&!ko(s,e,wo(this._markers))))}const h=ho(s,this._devices,null,this._virtualLights);for(const e of this._devices){for(const t of[!1,!0])n.set(I_(e.id,t),C_(s,e,{liveStates:!1!==this._config?.live_states,showTemperature:!1!==this._config?.show_temperature,showSignal:t,activityRuntime:this._activityRt.get(e.id),sourceDetails:!1,lightDevices:this._devices,lightSources:h,registryHass:this._fullRegistryHass,reducedMotion:this._reducedMotion}));if(this._isVacDev(e)){const t=this._vacSource(e,s),i=t?np(s?.states?.[t]?.attributes):null,n=this._vacRt.get(e.id);o.set(`vacuum:${e.id}`,{source:t,telemetry:i,mapId:i?this._vacMapId(e,i,s):null,runtime:n?{trail:n.trail,lastTs:n.lastTs,moving:n.moving,jump:n.jump}:null,server:this._vacSrvTrails[e.id]||null})}}const d=T_({sourceSequence:this._hassSequence,hass:s,devices:this._devices,presentations:n,positions:(p=this._model.length>0,u=this._devices,_=e=>this._livePos(e),p?new Map(u.map(e=>[e.id,_(e)])):new Map),facts:o,entityIds:a,deviceIds:r,areaIds:l});var p,u,_;this._capturedSnapshotSequence=this._hassSequence,this._capturedSnapshotDevices=this._devices,this._capturedSnapshotLayout=this._layout,this._capturedSnapshotActivity=t,this._capturedSnapshotConfigEpoch=this._cfgEpoch,this._capturedSnapshotVirtual=i,this._visibleDeviceSnapshot&&"steady"!==this._continuity.state?this._candidateDeviceSnapshot=d:(this._visibleDeviceSnapshot=d,this._candidateDeviceSnapshot=null)}get _renderDeviceSnapshot(){return this._stagedDeviceSnapshotToken===this._continuity.token?this._candidateDeviceSnapshot||this._visibleDeviceSnapshot:this._visibleDeviceSnapshot||this._candidateDeviceSnapshot}get _renderPlanHass(){return this._renderDeviceSnapshot?.hass||this._planHass}get _renderDevices(){return this._renderDeviceSnapshot?.devices||this._devices}get _fullRegistryHass(){return this._planHass,this._planHassMemo?.full||this.hass}_bindingStatus(e){return Bn(this.hass,e,this._haRegistry)}houseplanDiagnostics(){const e=function(e){const t=An(e);return{access:t.access,authoritative:t.authoritative,revision:t.revision,lastSuccess:t.lastSuccess,error:t.error}}(this.hass),t={active:0,ha_disabled:0,orphaned:0,unverified:0};for(const e of this._markers)e.removed||"virtual"===e.binding||t[this._bindingStatus(e.binding).kind]++;return{registry:{...e,lastSuccessAgeMs:e.lastSuccess?Math.max(0,Date.now()-e.lastSuccess):null},bindings:t}}_openBindingInHa(e){const[t,i]=e.split(":");if(i)if("device"!==t){if("entity"===t){const e=this._fullRegistryHass.entities?.[i];e?.device_id&&Fv("/config/devices/device/"+encodeURIComponent(e.device_id))}}else Fv("/config/devices/device/"+encodeURIComponent(i))}_bindingHasHaPage(e){const[t,i]=e.split(":");return!!i&&("device"===t||"entity"===t&&!!this._fullRegistryHass.entities?.[i]?.device_id)}_toggleMarkerDialogVisibility(){const e=this._markerDialog;if(!e)return;const t="ha"===e.bindingMode?this._bindingStatus(e.binding):null,i=e.hideFromPlan||"ha_disabled"===t?.kind;i&&"ha_disabled"===t?.kind?this._showToast(this._t("entity"===t.reason?"toast.ha_disabled_show_entity":"toast.ha_disabled_show_device")):i&&"unverified"===t?.kind?this._showToast(this._t("toast.ha_binding_unverified")):this._markerDialog={...e,hideFromPlan:!i}}_hookConnection(){const e=this.hass?.connection;e&&e!==this._connHooked&&(this._connHooked?.removeEventListener?.("ready",this._onConnReady),this._connHooked?.removeEventListener?.("disconnected",this._onConnLost),this._connHooked?.removeEventListener?.("reconnect-error",this._onConnLost),e.addEventListener?.("ready",this._onConnReady),e.addEventListener?.("disconnected",this._onConnLost),e.addEventListener?.("reconnect-error",this._onConnLost),this._connHooked=e)}_display(e){return this._signer.display(this.hass,e)}_resign(){this._signer.resign(this.hass,Rs(this._serverCfg))}_onLayoutEvent(e){e<=this._layoutRev||(clearTimeout(this._layoutSyncTimer),this._layoutSyncTimer=window.setTimeout(()=>{e<=this._layoutRev||this._reloadLayoutOnly()},200))}_noteLayoutRev(e){const t=e?.rev;"number"==typeof t&&t>this._layoutRev&&(this._layoutRev=t)}async _reloadLayoutOnly(){if(!this._serverStorage||!this.hass?.callWS)return;this._beginContinuityCandidate("layout-reload",!1);const e=new Map;for(const t of this._dirtyPos)this._layout[t]&&e.set(t,this._layout[t]);this._persistLayout.pending()&&this._persistLayout.flush();for(const[t,i]of this._sentPos)e.set(t,i);try{const t=await this.hass.callWS({type:"houseplan/layout/get"}),i={...t?.layout||{}};for(const[t,s]of e)i[t]=s;const s=Bd(i);s!==(this._layoutContentFingerprint||Bd(this._layout))&&(this._layout=i,this._layoutContentFingerprint=s),this._layoutRev=t?.rev??this._layoutRev,this._canOptimizeUndo=!!t?.can_optimize_undo,this._haIntegrationVersion="string"==typeof t?.integration_version?t.integration_version:this._haIntegrationVersion,this._undoKind=t?.undo_kind||null,this._cacheSnapshot(),this.requestUpdate()}catch{}finally{this._continuityDataReady=!0,this.requestUpdate()}}_maybeRebuildDevices(){const e=this.hass;if(!e?.devices||!e?.entities||!e?.areas)return;const t=this._haRegistry,i=Fn(e,t)+":"+Object.keys(e.areas).length+":"+(this._norm?"n":"l")+":"+ra(e,this._config?.language);if(i===this._regSignature&&this._devices.length)return;this._regSignature=i;const s=new Map(this._devices.map(e=>[e.id,e.bindingStatus?.kind||"active"]));this._devices=So({hass:e,registry:t,areaToSpace:Object.fromEntries(Object.entries(this._areaToSpace).map(([e,t])=>[e,t.space])),markers:this._markers,settings:this._settings,excluded:this._excluded,showAll:this._showAll,firstSpaceId:this._model[0]?.id||"",loc:e=>this._t(e),iconRules:this._iconRules});const n=this._markers.filter(e=>!e.removed&&"virtual"!==e.binding).map(e=>e.binding).sort(),o=t.revision+":"+n.join("|");if(t.authoritative&&o!==this._haBindingCacheKey){const i=new Map;for(const s of n)i.set(s,Bn(e,s,t));!function(e){if("undefined"==typeof localStorage||!e.size)return;const t=Ln(),i=Date.now();for(const[s,n]of e)"active"===n.kind?t[s]={kind:"active",ts:i}:"ha_disabled"===n.kind&&(t[s]={kind:"ha_disabled",reason:n.reason,ts:i});const s=Object.fromEntries(Object.entries(t).sort((e,t)=>t[1].ts-e[1].ts).slice(0,1500));Mn=s;try{localStorage.setItem(Sn,JSON.stringify(s))}catch{}}(i),this._haBindingCacheKey=o}this._defPos=this._defaultPositions(),this._syncNewDevices(),this._seedHiddenDevices(),this._syncActivityRuntime();const a=new Set(this._devices.filter(e=>!e.hidden).map(e=>e.id));for(const e of this._vacRt.keys())a.has(e)||this._vacRt.delete(e);if(this._infoCard){const e=this._devices.find(e=>e.id===this._infoCard.id);this._infoCard=e&&"ha_disabled"!==e.bindingStatus?.kind?e:null}const r=this._devices.some(e=>"ha_disabled"===e.bindingStatus?.kind&&"ha_disabled"!==s.get(e.id));r&&("ha_disabled"!==this._infoCard?.bindingStatus?.kind&&"ha_disabled"!==this._devices.find(e=>e.id===this._infoCard?.id)?.bindingStatus?.kind||this._closeInfoCard(),this._drag&&"ha_disabled"===this._devices.find(e=>e.id===this._drag.id)?.bindingStatus?.kind&&(this._drag=null),clearTimeout(this._holdTimer),this._holdFired=!1,this._tip=null,this._tapConfirm=null),this._nativeMoreInfoEntity&&!this._planEntityAvailable(this._nativeMoreInfoEntity)&&(zv(this,"hass-more-info",{entityId:null}),this._nativeMoreInfoEntity=null)}_syncNewDevices(){if(!this._norm||!this._loadOk||!this._serverCfg)return;const e=this._devices.filter(e=>!e.marker&&!e.virtual).map(e=>e.id).sort(),t=e.join(",");if(t===this._newSyncKey)return;this._newSyncKey=t;const i=this._settings,{fresh:s,known:n}=function(e,t){if(!Array.isArray(t))return{fresh:[],known:[...e]};const i=new Set(t),s=e.filter(e=>!i.has(e));return{fresh:s,known:s.length?[...t,...s]:t}}(e,i.known_devices);if(!Array.isArray(i.known_devices)||s.length){const e=[...new Set([...i.new_device_ids||[],...s])];this._serverCfg={...this._serverCfg,settings:{...i,known_devices:n,new_device_ids:e}},this._saveConfig()}}get _newIds(){const e=this._settings.new_device_ids;return new Set(Array.isArray(e)?e:[])}_ackNewDevice(e){if(!this._newIds.has(e)||!this._serverCfg)return;const t=this._settings;this._serverCfg={...this._serverCfg,settings:{...t,new_device_ids:(t.new_device_ids||[]).filter(t=>t!==e)}},this._saveConfig(),this.requestUpdate()}get _markers(){return this._serverCfg?.markers||[]}_roomLqi(e){if(!e)return null;const t=[];for(const i of this._renderDevices){if(i.area!==e||i.virtual)continue;const s=_o(this._renderPlanHass,i.entities);null!=s&&t.push(s)}return Ni(t)}_roomBounds(e){if(e.poly&&e.poly.length){const t=e.poly.map(e=>e[0]),i=e.poly.map(e=>e[1]),s=Math.min(...t),n=Math.min(...i);return{x:s,y:n,w:Math.max(...t)-s,h:Math.max(...i)-n}}return{x:e.x??0,y:e.y??0,w:e.w??0,h:e.h??0}}_defaultPositions(){const e={},t=this._config?.icon_size??2.5;for(const i of this._model){const s=t/100*Qh(i)*1.3;for(const t of i.rooms){if(!t.area)continue;const n=this._devices.filter(e=>e.area===t.area&&e.space===i.id);if(!n.length)continue;const o=this._roomBounds(t),a=.1*Math.min(o.w,o.h),r=o.w-2*a,l=o.h-2*a,c=Math.max(1,Math.round(Math.sqrt(n.length*r/Math.max(l,1)))),h=Math.ceil(n.length/c),d=r/c,p=l/Math.max(h,1),u=n.map((e,t)=>({x:o.x+a+d*(t%c+.5),y:o.y+a+p*(Math.floor(t/c)+.5)}));Oi(u,o,s,.5*a),n.forEach((t,i)=>e[t.id]=Hh(u[i]))}}return e}_pos(e){const t=this._renderDeviceSnapshot?.positions.get(e.id);return t?{x:t.x,y:t.y}:this._livePos(e)}_livePos(e){const t=this._spaceModelById(e.space),i=this._layout[e.id];if(i)if(this._norm){if(i.s===e.space)return{x:i.x*Pv,y:i.y*Pv}}else if(void 0===i.s)return{x:i.x,y:i.y};return this._defPos[e.id]?this._defPos[e.id]:t?Hh(Zh(t)):{x:500,y:500}}_savePos(e,t,i){if(this._spaceModelById(e.space)){if(this._norm){const s=this._gridPitch,n=Math.round(t/s)*s,o=Math.round(i/s)*s,a=this._layout[e.id]?.k;this._layout={...this._layout,[e.id]:{s:e.space,x:Bh(n/Pv),y:Bh(o/Pv),...a?{k:a}:{}}}}else this._layout={...this._layout,[e.id]:{x:Math.round(t),y:Math.round(i)}};this._dirtyPos.add(e.id),this._persistLayout()}}_visualSamples(e){return k_(this._renderPlanHass,e,this._renderDevices,void 0,this._fullRegistryHass).samples}_devicePresentation(e,t=!1!==this._config?.show_signal,i=!1){const s=i?null:this._renderDeviceSnapshot?.presentations.get(I_(e.id,t));return s||C_(this._renderPlanHass,e,{liveStates:!1!==this._config?.live_states,showTemperature:!1!==this._config?.show_temperature,showSignal:t,designPreview:i,activityRuntime:this._activityRt.get(e.id),sourceDetails:!1,lightDevices:this._renderDevices,registryHass:this._fullRegistryHass,reducedMotion:this._reducedMotion})}_deviceVisual(e){return this._devicePresentation(e).visual}_stateClass(e,t=this._deviceVisual(e)){const i=this._devicePresentation(e);return i.effectiveHidden?"":("icon_ripple"!==i.display||!1===this._config?.live_states||"alarm"===t.status||t.activity,M_({...i,visual:t}).join(" "))}_liveTemp(e){if(!this._config?.show_temperature)return null;if(!0===e.marker?.use_climate_temp){const t=go(this._renderPlanHass,e.entities);if(null!=t)return t}return"mdi:thermometer"!==e.icon&&"mdi:air-filter"!==e.icon?null:mo(this._renderPlanHass,e.entities)}_bindingEntities(e){if("virtual"===e||!e)return[];const t=this._bindingStatus(e);return"active"===t.kind?t.enabledEntityIds:t.allEntityIds}_bindingHasClimate(e){return this._bindingEntities(e).some(e=>e.startsWith("climate."))}_bindingHasAlarm(e){return this._bindingEntities(e).some(e=>{const t=this._planHass?.states?.[e]||this.hass?.states?.[e],i=this._fullRegistryHass.entities[e]||this.hass?.entities?.[e];return Bs(e.split(".")[0],t?.attributes?.device_class||i?.device_class||i?.original_device_class)})}_liveHum(e){return this._config?.show_temperature&&e.primary&&fo(this.hass,e.primary)?vo(this.hass,e.entities):null}_deviceBindingActive(e,t=!0){if(e.virtual||"virtual"===e.bindingKind)return!0;if(!e.bindingKind||!e.bindingRef)return!1;const i=this._bindingStatus(`${e.bindingKind}:${e.bindingRef}`);return"active"===i.kind||(t&&this._showToast(this._t("ha_disabled"===i.kind?"toast.ha_disabled_action":"toast.ha_binding_unverified")),!1)}_openMoreInfo(e){e?this._planEntityAvailable(e)?(this._nativeMoreInfoEntity=e,zv(this,"hass-more-info",{entityId:e})):this._showToast(this._t("toast.ha_disabled_action")):this._showToast(this._t("toast.no_entity"))}_interruptViewGesture(e,t){if(clearTimeout(this._holdTimer),clearTimeout(this._kioskHoldTimer),void 0!==e)for(const i of[t,this._stageEl])try{i?.hasPointerCapture?.(e)&&i.releasePointerCapture(e)}catch{}this._pointers.clear(),this._panStart=null,this._panLock=null,this._pinchStart=null,this._swipeStart=null}_closeInfoCard(){this._interruptViewGesture(),this._holdFired=!1,this._infoCard=null}_ctxDevice(e,t){"view"===this._mode&&(e.preventDefault(),e.stopPropagation(),this._deviceBindingActive(t)&&(t.primary?this._openMoreInfo(t.primary):this._infoCard=t))}_clickDevice(e,t){if(e.stopPropagation(),this._drag?.moved||this._suppressClick||this._holdFired)return;if("plan"===this._mode)return;if("devices"===this._mode)return void this._openMarkerDialog(t);const i=this._devices.find(e=>e.id===t.id);if(!i)return;const s=Op(i.tapAction,i.primary?.split(".")[0]),n=(e,t)=>{i.marker?.tap_confirm?this._tapConfirm={kind:"run",text:e,exec:t}:t()};if("toggle"===s){const e=this._toggleIntent(i);if(!e)return;if(!Wp(e))return void this._showUnavailableToggleTargets(e);const t=e=>{const t=Wp(e);if(!t)return;if("virtual-light"===t.kind)return this._startDevicePressFeedback(i.id),void this.hass.callWS({type:"houseplan/virtual_light/toggle",marker_id:t.markerId}).then(e=>{const t=wn(this._virtualLights,e);t!==this._virtualLights&&(this._virtualLights=t,this._capturedSnapshotVirtual="",this._cacheSnapshot(),this.requestUpdate())}).catch(e=>this._showToast(this._t("toast.virtual_light_toggle_failed",{err:this._errText(e)})));const{command:s}=t;this._startDevicePressFeedback(i.id),this.hass.callService(s.domain,s.service,s.data).catch(e=>this._showToast(this._t("toast.error",{err:this._errText(e)})))},s=((o=e).targets.length?o.targets:o.skippedTargets).map(e=>e.name||e.entityId||e.ref).join(", ")||i.name;if(i.marker?.tap_confirm){const n=this._toggleConfirmationLines(e);if(!n.length)return;this._tapConfirm={kind:"toggle",text:this._t("confirm.tap_toggle",{name:s}),lines:n,initialIntent:e,deviceId:i.id,exec:()=>{const s=this._devices.find(e=>e.id===i.id),n=s?this._toggleIntent(s):null;n&&!Wp(n)&&this._showUnavailableToggleTargets(n)||(n&&Gp(e,n)?t(n):this._showToast(this._t("toast.tap_target_changed")))}}}else t(e);return}var o;if("info"===s)return this._interruptViewGesture(),void(this._infoCard=i);if(this._deviceBindingActive(i)){if("run"===s){const e=i.marker?.tap_target||"",t=function(e){const t=String(e||"").split(".")[0];return"automation"===t?{domain:"automation",service:"trigger"}:"script"===t?{domain:"script",service:"turn_on"}:"scene"===t?{domain:"scene",service:"turn_on"}:null}(e),s=this.hass.states[e];if(!t||!s)return void this._showToast(this._t("toast.run_target_missing"));const o=s.attributes?.friendly_name||e;return void n(this._t("confirm.tap_run",{name:o}),()=>{this._deviceBindingActive(i)&&this._planEntityAvailable(e)&&(this._startDevicePressFeedback(i.id),this.hass.callService(t.domain,t.service,{entity_id:e}).then(()=>{this._stampActivity(i.id,"event",this._activitySourceKey(i)),this.requestUpdate(),this._showToast(this._t("toast.run_started",{name:o}))}).catch(e=>this._showToast(this._t("toast.error",{err:this._errText(e)}))))})}"more-info"===s&&i.primary?this._openMoreInfo(i.primary):this._infoCard=i}}_showUnavailableToggleTargets(e){const t=function(e){if(!e||"group"!==e.kind||Wp(e)||"configured-targets-missing"!==e.noneReason)return[];if(!e.skippedTargets.length||e.skippedTargets.some(e=>!Up.has(e.reason)&&"secure"!==e.reason))return[];const t=[],i=new Set;for(const s of e.skippedTargets){if(!Up.has(s.reason))continue;const e=String(s.name||s.entityId||s.ref||"").trim();e&&!i.has(e)&&(i.add(e),t.push(e))}return t}(e);return!!t.length&&(this._showToast(1===t.length?this._t("toast.toggle_target_unavailable",{name:t[0]}):this._t("toast.toggle_targets_unavailable",{names:t.join(", ")})),!0)}_keyDevice(e,t){"Enter"!==e.key&&" "!==e.key||"view"!==this._mode&&"devices"!==this._mode||(e.preventDefault(),this._clickDevice(e,t))}_startDevicePressFeedback(e){const t=[...this.renderRoot.querySelectorAll(".dev[data-id]")].find(t=>t.dataset.id===e),i=t?.querySelector(".device-shell");if(!i||"function"!=typeof i.animate)return;const s=Number.parseFloat(this.ownerDocument.defaultView?.getComputedStyle(i).scale||""),n=Number.isFinite(s)?Math.max(.95,Math.min(1,s)):1;this._devicePressAnimations.get(e)?.cancel();const o=this._reducedMotion?[{outlineColor:"transparent",outlineStyle:"solid",outlineWidth:"0px"},{outlineColor:"var(--hp-accent, #3ea6ff)",outlineStyle:"solid",outlineWidth:"2px",outlineOffset:"2px",offset:.5},{outlineColor:"transparent",outlineStyle:"solid",outlineWidth:"0px"}]:[{scale:String(n)},{scale:"0.95",offset:.5},{scale:"1"}],a=i.animate(o,{duration:200,easing:"cubic-bezier(.22,.61,.36,1)"});this._devicePressAnimations.set(e,a);const r=()=>{this._devicePressAnimations.get(e)===a&&this._devicePressAnimations.delete(e)};a.addEventListener("finish",r,{once:!0}),a.addEventListener("cancel",r,{once:!0})}_cancelDevicePressFeedback(){for(const e of this._devicePressAnimations.values())e.cancel();this._devicePressAnimations.clear()}_pruneDevicePressFeedback(){if(!this._devicePressAnimations.size)return;const e=new Set([...this.renderRoot.querySelectorAll(".dev[data-id]")].map(e=>e.dataset.id||""));for(const[t,i]of this._devicePressAnimations)e.has(t)||(i.cancel(),this._devicePressAnimations.delete(t))}_t(e,t){return la(ra(this.hass,this._config?.language),e,t)}get _colorPickerLabels(){return{title:this._t("color_picker.title"),hue:this._t("color_picker.hue"),saturation:this._t("color_picker.saturation"),value:this._t("color_picker.value"),hex:this._t("color_picker.hex"),invalidHex:this._t("color_picker.invalid_hex")}}_help(e){const t=`${e}.aria`,i=ra(this.hass,this._config?.language);return ca(i,e)&&ca(i,t)?q``:G}get _stageEl(){return this.renderRoot.querySelector(".stage")}_contentItems(e){const t=[];for(const i of this._devices){if(i.space!==e.id||i.hidden)continue;const s=this._pos(i);t.push({minX:s.x,minY:s.y,maxX:s.x,maxY:s.y})}if(e.id===this._space){for(const e of this._openingsR){const i=Number(e.angle)*Math.PI/180,s=Math.cos(i)*e.rlen/2,n=Math.sin(i)*e.rlen/2,o=Wh([[e.rx-s,e.ry-n],[e.rx+s,e.ry+n]]);o&&t.push(o)}const i=this._decorH;for(const e of this._decorList){const s=Wh("line"===e.kind?[[e.x1*Pv,e.y1*i],[e.x2*Pv,e.y2*i]]:"text"===e.kind?[[e.x*Pv,e.y*i]]:Wr({x:e.x*Pv,y:e.y*i,w:e.w*Pv,h:e.h*i,angle:e.angle}));s&&t.push(s)}for(const i of this._physicalBodiesR(e)){const e=Wh(i);e&&t.push(e)}}return Gh(e,t)}_frameOf(){const e=this._spaceModel();if(!e){this._frame=null;const e={x:0,y:0,w:Pv,h:Pv};return{rect:e,all:e,outliers:0}}const t=this._frame,i="view"!==this._mode;if(t&&t.id===e.id&&this._bdDrag)return t;if(t&&t.id===e.id&&t.model===e&&t.layout===this._layout&&t.devs===this._devices&&t.far===this._showFar&&t.grow===i)return t;const s=Jh(this._contentItems(e));let n=s.all||Xh(e),o=this._showFar?n:s.core||Xh(e);return t&&t.id===e.id&&i&&t.grow&&(o=Iv(t.rect,o),n=Iv(t.all,n)),this._frame={id:e.id,model:e,layout:this._layout,devs:this._devices,far:this._showFar,grow:i,rect:o,all:n,outliers:s.outliers},this._frame}_isoSource(){const e=this._spaceModel();if(!e)return null;const t=this._spaceWalls,i=this._openCuts(),s=this._openingsR.map((e,t)=>({id:String(e.id||t),sourceIndex:t,type:e.type,x:e.rx,y:e.ry,angle:Number(e.angle)||0,length:e.rlen>0?e.rlen:900,flipH:!!e.flip_h,flipV:!!e.flip_v})),n=xh(64,this._cellCm),o=xh(10,this._cellCm),a=`${e.id}|${function(e){let t=2166136261;const i=e=>{if("number"!=typeof e)if("string"!=typeof e)if("boolean"!=typeof e)if(Array.isArray(e)){t=zf(t,e.length);for(const t of e)i(t)}else{if(e&&"object"==typeof e){const t=e;for(const e of Object.keys(t).sort())i(e),i(t[e]);return}t=zf(t,-1)}else t=zf(t,e?1:0);else for(const i of e)t=zf(t,i.codePointAt(0)||0);else t=zf(t,e)};return i(e),t.toString(36)}({rooms:e.rooms,walls:t,openCuts:i,openings:s,partitions:e.partitions,roomDrafts:e.room_drafts,columns:e.wall_columns,cellCm:this._cellCm,gridPitch:this._gridPitch,wallKeyPitch:this._wallKeyPitch,camera:kf,wallHeight:n,floorEdgeHeight:o,algorithm:3})}`;return{key:a,build:()=>{const o=ch(e,this._cellCm,this._gridPitch,2e-4*this._gridPitch,this._partitionOpeningCuts(e)).all,a=this._roomWallOpeningInputs(this._openingsR,e),r=t.length||o.length?Oc(e.rooms,t,i,a,this._wallKeyPitch,this._cellCm,this._gridPitch,Pv,o):null;if(r&&("failed-core"===r.status||"not-applicable"===r.status))throw new Error("wall boolean geometry failed");const l=r?.paperGeom??zc(e.rooms,t,i,this._wallKeyPitch,this._cellCm,this._gridPitch,Pv);if(!l)throw new Error("floor boolean geometry failed");const c=r?.openingIndex||qc(e.rooms,t,i,this._wallKeyPitch,this._cellCm,this._gridPitch,Pv),h=s.map(e=>{const i=this._openingsR[e.sourceIndex],s="gate"===e.type?!e.flipV:e.flipV,o=i?.partitionHost?eu(i.partitionHost,s):t.length||"gate"===e.type?Vc(c,{x:e.x,y:e.y,angle:e.angle,length:e.length,flip_v:s}):{ox:0,oy:0,cm:0,side:-1};return function(e,t=64){if(!(Ff([e.x,e.y,e.angle,e.length,e.face.ox,e.face.oy,t])&&e.length>0&&t>0))throw new Error("invalid isometric opening input");const i=e.length/2;let s;if("passage"===e.type)s=[];else if("gate"===e.type){const n=10*e.face.side;s=[Ef(e,0,[-i,0],[i,0],n,0,.88*t),Ef(e,1,[i,0],[-i,0],-n,0,.88*t)]}else s="window"===e.type?[Ef(e,0,[-i,0],[i,0],-90,.27*t,.78*t),Ef(e,1,[i,0],[-i,0],90,.27*t,.78*t)]:[Ef(e,0,[-i,0],[e.length,0],-90,0,.92*t)];return{id:e.id,sourceIndex:e.sourceIndex,type:e.type,leaves:Object.freeze(s.map(e=>Object.freeze(e)))}}({...e,face:o},n)});return{walls:r?.components.flatMap(e=>e.geom)||[],floor:l,openings:Object.freeze(h)}}}}_isoSceneKey(){if(!this._labsIso||"view"!==this._mode)return null;try{return this._isoSource()?.key??null}catch{return`${this._space}|invalid`}}_isoScene(){const e=this._isoSource();if(!e)return null;const t=this._isoGeometryCache.get(e.key);if(t)return{key:e.key,...t};const i=this._frameOf().rect,s=e.build(),n=xh(64,this._cellCm),o=xh(10,this._cellCm),a=function(e){let t=1/0,i=1/0,s=-1/0,n=-1/0;for(const o of e)for(const e of o.leaves){const o=Math.hypot(e.closedVector[0],e.closedVector[1]);t=Math.min(t,e.hinge[0]-o),i=Math.min(i,e.hinge[1]-o),s=Math.max(s,e.hinge[0]+o),n=Math.max(n,e.hinge[1]+o)}return Ff([t,i,s,n])?{x:t,y:i,w:s-t,h:n-i}:null}(s.openings),r=Cf({rect:a?Iv(i,a):i,wallHeight:n,openingHeight:n,floorDepth:o}),l=function(e,t=kf,i=64){if(!Number.isFinite(i)||i<0)throw new Error("invalid wall height");const s=[],n=[],o=[];let a=0;for(let r=0;r<(e||[]).length;r++){const l=e[r];for(let e=0;e<(l||[]).length;e++){const c=Tf(l[e],e>0);if(!(c.length<3||Math.abs(Pf(c))<1e-9)){s.push(If(c,t,i)),a+=c.length;for(let s=0;se.depth-t.depth||e.polygon-t.polygon||e.ring-t.ring||e.edge-t.edge),{topPath:s.join(" "),sides:n,contactPath:o.join(" "),edgeCount:a}}(s.walls,kf,n),c={geometry:l,floor:Af(s.floor,o),openings:s.openings,frame:r};return fv(this._isoGeometryCache,e.key,c,8),{key:e.key,...c}}_effectiveProjection(){if("iso"!==this._desiredProjection||!this._model.length)return"flat";const e=this._isoSceneKey()||`${this._space}|invalid`;if(this._isoFallback.has(e))return"flat";try{const e=this._isoScene();return e?(t="iso",i=e.key,s=this._isoFallback,"iso"===t&&i&&!s.has(i)?"iso":"flat"):"flat"}catch(t){if(!this._isoFallback.has(e)){this._isoFallback.add(e);const i=e.split("|");console.warn(`HOUSEPLAN ISO FALLBACK: #89, space ${this._space}, fingerprint ${i[i.length-1]}, ${t instanceof Error?t.message:"renderer error"}`)}return"flat"}var t,i,s}_scenePoint(e){return"iso"===this._renderProjection?$f(e,0):e}_floorView(e){if("iso"!==this._renderProjection)return e;const t=Sf([e.x,e.y]),i=Sf([e.x+e.w,e.y+e.h]);return{x:t[0],y:t[1],w:i[0]-t[0],h:i[1]-t[1]}}_baseVb(){if("iso"===this._effectiveProjection()){if(!this._spaceDisplayForRender().showBorders){const e=Cf({rect:this._frameOf().rect,wallHeight:xh(64,this._cellCm)});return[e.x,e.y,e.w,e.h]}const e=this._isoScene()?.frame??this._frameOf().rect;return[e.x,e.y,e.w,e.h]}const e=this._frameOf().rect;return[e.x,e.y,e.w,e.h]}get _outliers(){return this._showFar?0:this._frameOf().outliers}_fitFar(){this._showFar=!0,this._frame=null,this._resetZoom()}_fitAll(){this._showFar=!0,this._frame=null,this._resetZoom()}_renderFarHint(){return this._kiosk||"view"!==this._mode||this._booting||!this._outliers?G:q`
+
`}houseplanContinuityTrace(){return[...this._continuityHistory,...this._continuity.trace].slice(-80).map(e=>({...e,...e.stage?{stage:[...e.stage]}:{}}))}getCardSize(){return 12}get _norm(){return!(!this._serverCfg||!this._serverCfg.spaces.length)}_cfgFingerprint(){const e=this._serverCfg?.spaces||[];let t=e.length+":";for(const i of e){t+=(i.id||"")+","+(i.plan_aspect||"")+","+(i.plan_url||"").length+","+(i.plan_x??"")+","+(i.plan_y??"")+","+(i.plan_scale??"")+","+(i.plan_scale_x??"")+","+(i.plan_scale_y??"")+","+(i.plan_angle??"")+","+(i.rooms?.length||0)+","+(i.openings?.length||0)+","+(i.decor?.length||0)+";";for(const e of i.rooms||[]){const i=e.poly?.[0],s=e.poly?.[e.poly.length-1];t+=(e.poly?.length||0)+"."+(e.id||"")+"."+(e.open_to||[]).join("+")+"."+(e.area||"")+"."+JSON.stringify(e.settings||0)+"."+(e.x??"")+","+(e.y??"")+","+(e.w??"")+","+(e.h??"")+","+(i?i[0]+"/"+i[1]:"")+","+(s?s[0]+"/"+s[1]:"")+";"}}return t}get _model(){if(!this._serverCfg)return[];const e=this._cfgEpoch+"|"+this._cfgFingerprint();if(this._modelCache&&this._modelCache.key===e)return this._modelCache.model;const t=this._buildModel();return this._modelCache={key:e,model:t},t}_buildModel(){if(!this._serverCfg)return[];const e=this._renderCfg;return Eh(e).map((t,i)=>{const s=e.spaces[i]?.plan_url;return t.bg&&s?{...t,bg:{...t.bg,href:s}}:t})}_spaceModel(){return this._hasFixedFloor?Jd(this._model,this._space):(e=this._model,t=this._space,e.find(e=>e.id===t)??e[0]);var e,t}_spaceModelById(e){return Jd(this._model,e)}_syncEmptySpaceState(){if(!!this._serverCfg&&0===this._serverCfg.spaces.length){if(!this._emptySpaceStateActive){this._emptySpaceStateActive=!0;for(const e of this._pointers.keys())for(const t of this.renderRoot.querySelectorAll("*"))try{t.hasPointerCapture?.(e)&&t.releasePointerCapture(e)}catch{}this._pointers.clear(),this._panStart=null,this._panLock=null,this._pinchStart=null,this._swipeStart=null,this._drag=null,this._rlResize=null,this._vacFit=null,this._compassDrag=!1,this._cancelModeTransition(!1),this._mode="view",this._clearGeometryGesture(),this._geometryHistory.clear(),this._resumeDraftBySpace={},this._tip=null,this._hoverRoom=null,this._openingInfo=null,this._closeInfoCard(),this._deviceInbox=null,this._deviceInboxReturn=null,this._markerDialog=null,this._physicalDialog=null,this._backdropDialog=null,this._decorShapeDialog=null,this._decorTextDialog=null,this._roomDialog=!1,"edit"===this._spaceDialog?.mode&&(this._spaceDialog=null),this._editorSecondary.closeForNavigation(),this._saveConfigDebounced.cancel(),this._frame=null,this._planSnapGeometryCache=null,this._hiddenWallDiagnosticCache=null,this._decorSnapCache=null,this._commitSpace("",!0)}}else this._emptySpaceStateActive=!1}get _areaToSpace(){const e={};for(const t of this._model)for(const i of t.rooms)i.area&&(e[i.area]={space:t.id,room:i});return e}get _settings(){return this._serverCfg?.settings||{}}get _showAll(){return this._showHidden||!this._settings.filter_seeded&&!!this._settings.show_all}_seedHiddenDevices(){if(!this._serverCfg||!this._norm||!this._canEdit)return;const e=this._serverCfg,t=function(e){const t=e.hass,i=e.registry||An(t),s=En(t,i),n=On(t,i),{areaToSpace:o,markers:a,settings:r,excluded:l,iconRules:c}=e,h=!1!==r.group_lights,d=wo(a),p=bo(s,h).filter(e=>!ko(s,e.eid,d)),u=new Set(p.map(e=>e.area)),_=jn(s),m=qn(a,n),g=new Set(a.map(e=>e.binding)),f=[];for(const e of Object.values(s.devices)){const n=e.area_id;if(!n||!o[n])continue;if("service"===e.entry_type)continue;if(g.has("device:"+e.id))continue;if("active"!==Bn(t,"device:"+e.id,i).kind)continue;const a=Wn(s,e.id,_[e.id]||[],m);if(a.partial&&!a.entityIds.length)continue;const r=a.entityIds,d=Un(s,e,r);let p=l.has(d)||"Group"===e.model||/scene/i.test(e.model||"")||/bridge/i.test((e.model||"")+(e.name||""))||"myheat"===d&&!!e.via_device_id;if(!p&&h&&u.has(n)){const t=(e.name_by_user||e.name||"").trim();"mdi:lightbulb"===yo(s,t,e.model,r,c)&&(p=!0)}p&&f.push("device:"+e.id)}return f}({hass:this.hass,registry:this._haRegistry,areaToSpace:Object.fromEntries(Object.entries(this._areaToSpace).map(([e,t])=>[e,t.space])),markers:this._markers,settings:this._settings,excluded:this._excluded,firstSpaceId:this._model[0]?.id||"",iconRules:this._iconRules});if(!t.length&&e.settings?.filter_seeded)return;e.markers=e.markers||[];const i=[];for(const s of t){const t="h"+s.slice(s.indexOf(":")+1);e.markers.push({id:t,binding:s,hidden:!0}),i.push(s.slice(s.indexOf(":")+1))}const s={...e.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(e=>!i.includes(e))),e.settings=s,this._regSignature="",this._maybeRebuildDevices(),this._saveConfig(),this.requestUpdate()}get _iconRules(){const e=this._settings.icon_rules;if(!e||!Array.isArray(e)||!e.length)return;const t=JSON.stringify(e);return t!==this._rulesCompiledSrc&&(this._rulesCompiledSrc=t,this._rulesCompiled=Xe(e)),this._rulesCompiled}get _fillColors(){return ps(this._settings)}get _excluded(){const e=this._settings.exclude_integrations;return e?new Set(e):Ye}willUpdate(e){e.has("_serverCfg")&&this._cfgEpoch++,this._syncEmptySpaceState(),e.has("hass")&&this.hass&&(this._hassSequence++,this._renderSnapshotAt=Date.now(),this._continuity.note("hass-snapshot"),this._ensureHaRegistryAuthority(),this._planHassMemo=null,this._hookConnection(),!this._loadOk&&!this._loading&&this._loadTries<8&&this._loadFromServer(),this._maybeRebuildDevices(),this._vacTick(),this._activityTick()),this._continuity.hasCompleteFrame&&"steady"===this._continuity.state&&this._continuity.refreshCompleteFrame(this._visualFrameFingerprint()),this._captureRenderDeviceSnapshot()}updated(){this._pruneDevicePressFeedback(),this._syncDayCycleClock(),this._warmSnapshot(),this._dtMeasure();const e=this._stageEl;e&&!this._roViewport&&(this._roViewport=new ResizeObserver(()=>this._refitView()),this._roViewport.observe(e)),e&&this._booting&&!this._bootTimer&&this._bootWatch();const t=this.renderRoot.querySelector(".hdr");if(t&&e&&!this._roHdr){const i=()=>{const t=this.renderRoot.querySelector("ha-card");if(!t)return;const i=e.getBoundingClientRect().top-t.getBoundingClientRect().top,s=Math.min(Math.max(t.getBoundingClientRect().top,0),120),n=Math.round(i+s);n>=0&&n!==this._hdrH&&(this._hdrH=n),n>=0&&!this._booting&&!this._config?.kiosk&&e.clientHeight>0&&this._warmPatch({hdrH:n,stageH:e.clientHeight})};this._roHdr=new ResizeObserver(()=>requestAnimationFrame(i)),this._roHdr.observe(t),this._onWinResize=()=>requestAnimationFrame(i),window.addEventListener("resize",this._onWinResize),i()}if(e&&!this._view&&this._refitView(),this._editorSecondary.afterRender(),this._settleContinuityFrame(),this._serverStorage&&this._loadOk&&0===this._model.length&&!this._spaceDialog&&!this._importDialog&&!this._onboardingShown){this._onboardingShown=!0;const e=function(e){const t=e?.floors;if(!t||"object"!=typeof t)return[];const i=[];for(const e of Object.values(t))e&&e.floor_id&&i.push({id:e.floor_id,name:e.name||e.floor_id,level:e.level??null});return i.sort((e,t)=>{const i=e.level??1e9,s=t.level??1e9;return i!==s?i-s:e.name.localeCompare(t.name)}),i}(this.hass);e.length?this._importDialog={floors:e.map(e=>({...e,checked:!0}))}:this._openSpaceDialog("create")}}_adoptStructuralResponses(e,t,i){const s=e?.config,n=s&&Array.isArray(s.spaces)?s:null,o=Gd(n),a=o!==(this._cfgContentFingerprint||Gd(this._serverCfg));if(a&&(this._geometryHistory.clear(),this._pendingPhysicalWrites.clear(),this._serverCfg&&this._clearGeometryGesture(),this._serverCfg=n,this._cfgContentFingerprint=o),this._cfgRev=e?.rev??this._cfgRev,e&&("virtual_lights"in e||"config"in e)){const t=gn(this._virtualLights,e.virtual_lights,this._cfgRev,"virtual_lights"in e);vn(t)!==vn(this._virtualLights)&&(this._virtualLights=t,this._capturedSnapshotVirtual="")}let r=!1;if(void 0!==t||void 0!==i){const e=i??t?.layout??{},s=Gd(e);r=s!==(this._layoutContentFingerprint||Gd(this._layout)),r&&(this._layout=e,this._layoutContentFingerprint=s),this._layoutRev=t?.rev??this._layoutRev}return this._canOptimizeUndo=!(!e?.can_optimize_undo&&!t?.can_optimize_undo),this._haIntegrationVersion="string"==typeof e?.integration_version?e.integration_version:this._haIntegrationVersion,this._undoKind=e?.undo_kind||t?.undo_kind||null,"boolean"==typeof e?.can_write&&(this._serverCanWrite=e.can_write),a&&this._continuity.note("config-candidate",{configRev:this._cfgRev}),r&&this._continuity.note("layout-candidate",{layoutRev:this._layoutRev}),{configChanged:a,layoutChanged:r}}_resumePendingNavMode(){if(!this._pendingNavMode||!this._canEdit||this._config?.kiosk)return!1;const e=this._pendingNavMode;return this._pendingNavMode=null,this._setMode(e,!1),!0}async _loadFromServer(){this._loading=!0,this._loadTries++;const e=this._space,t=!!this._view;try{const[i,s]=await Promise.all([this.hass.callWS({type:"houseplan/config/get"}),this.hass.callWS({type:"houseplan/layout/get"})]),n=i?.config&&Array.isArray(i.config.spaces)?i.config:null,o=Gd(n)!==(this._cfgContentFingerprint||Gd(this._serverCfg))||Gd(s?.layout??{})!==(this._layoutContentFingerprint||Gd(this._layout));if(o){if(!await this._signer.prepareImage(this.hass,this._candidateBackdrop(n)))return this._continuity.note("asset-failed"),void this._scheduleLoadRetry(!0)}o&&this._continuity.hasCompleteFrame&&"steady"===this._continuity.state&&this._beginContinuityCandidate("structural-response",!0),this._connectionWasLost=!1,this._serverStorage=!0,"boolean"==typeof i?.can_write&&(this._serverCanWrite=i.can_write),this._canOptimizeUndo=!(!i?.can_optimize_undo&&!s?.can_optimize_undo),this._haIntegrationVersion="string"==typeof i?.integration_version?i.integration_version:this._haIntegrationVersion,this._adoptStructuralResponses(i,s),this._adoptInitialSpace(this._model,!0),this._resumePendingNavMode(),this._cacheSnapshot(),this._warmVpArmed&&this._space===this._warmVp?.space?this._warmVpArmed=!1:t&&this._space===e||this._restoreZoom(),this._loadOk=!0,this.hass.callWS({type:"houseplan/trail/get"}).then(e=>{this._vacSrvTrails=e?.trails||{},this.requestUpdate()}).catch(()=>{}),this._ensureLiveSyncSubscriptions()}catch(e){if(this._serverCfg)this._scheduleLoadRetry(!0);else if(this._loadTries>=8){this._serverStorage=!1;try{this._layout=JSON.parse(localStorage.getItem(Cv)||"{}")||{}}catch{this._layout={}}}}finally{this._loading=!1,this._continuityDataReady=!0,this._regSignature="",this._maybeRebuildDevices(),this.requestUpdate()}}_ensureLiveSyncSubscriptions(){const e=this.hass?.connection;if(!e)return;if(e!==this._liveSyncConnection&&(this._unsubCfg?.(),this._unsubCfg=null,this._unsubLayout?.(),this._unsubLayout=null,this._unsubTrail?.(),this._unsubTrail=void 0,this._unsubVirtual?.(),this._unsubVirtual=null,this._liveSyncGeneration++,this._liveSyncAttempt=null,this._liveSyncConnection=e),this._liveSyncAttempt)return;const t=this._liveSyncGeneration,i=[],s=(s,n,o,a)=>{s()||i.push(async()=>{const i=await e.subscribeEvents(a,o);t===this._liveSyncGeneration&&this.isConnected&&this.hass?.connection===e&&!s()?n(i):i?.()})};if(s(()=>this._unsubCfg,e=>{this._unsubCfg=e},"houseplan_config_updated",e=>{const t=Number(e?.data?.rev??-1);t!==this._cfgRev&&this._reloadConfigOnly(!1,t)}),s(()=>this._unsubTrail,e=>{this._unsubTrail=e},"houseplan_trail_updated",async()=>{try{const e=await this.hass.callWS({type:"houseplan/trail/get"});this._vacSrvTrails=e?.trails||{},this.requestUpdate()}catch{}}),s(()=>this._unsubLayout,e=>{this._unsubLayout=e},"houseplan_layout_updated",e=>this._onLayoutEvent(Number(e?.data?.rev??-1))),s(()=>this._unsubVirtual,e=>{this._unsubVirtual=e},"houseplan_virtual_light_updated",e=>{const t=wn(this._virtualLights,e?.data);t!==this._virtualLights&&(this._virtualLights=t,this._capturedSnapshotVirtual="",this._cacheSnapshot(),this.requestUpdate())}),!i.length)return;const n=function(e){return Promise.allSettled(e.map(e=>Promise.resolve().then(e)))}(i).then(()=>{});this._liveSyncAttempt=n,n.finally(()=>{this._liveSyncAttempt===n&&(this._liveSyncAttempt=null)})}async _reloadConfigOnly(e=!1,t){if(!e){if(void 0!==t&&t<=this._cfgRev)return;if(this._saveConfigDebounced.pending()&&this._saveConfigDebounced.flush(),this._cfgWriting)return clearTimeout(this._reloadRetry),void(this._reloadRetry=window.setTimeout(()=>this._reloadConfigOnly(!1,t),400))}this._beginContinuityCandidate("config-reload",!1);try{const e=await this.hass.callWS({type:"houseplan/config/get"}),t=e?.config&&Array.isArray(e.config.spaces)?e.config:null;if(Gd(t)!==(this._cfgContentFingerprint||Gd(this._serverCfg))&&!await this._signer.prepareImage(this.hass,this._candidateBackdrop(t)))return this._continuity.note("asset-failed"),void this._scheduleLoadRetry(!0);const i=this._space;this._adoptStructuralResponses(e),this._adoptInitialSpace(this._model,!0),this._resumePendingNavMode(),this._cacheSnapshot(),this._space!==i&&this._restoreZoom(),this._regSignature="",this._maybeRebuildDevices(),this.requestUpdate()}catch(e){this._showToast(this._t("toast.cfg_reload_failed",{err:this._errText(e)}))}finally{this._continuityDataReady=!0,this.requestUpdate()}}_scheduleLoadRetry(e=!1){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,!e&&this._loadOk||this._loading||!this.hass||this._loadFromServer()},t)}_ensureHaRegistryAuthority(){const e=this.hass?.connection||null;e&&e!==this._haRegistryConnection&&(this._haRegistryRelease?.(),this._haRegistryConnection=e,this._haRegistryRev=-1,this._haBindingCacheKey="",this._planHassMemo=null,this._haRegistryRelease=Rn(this.hass,this._onHaRegistryUpdate),this._onHaRegistryUpdate())}get _haRegistry(){return An(this.hass)}get _planHass(){const e=this._haRegistry,t=Fn(this.hass,e),i=this._planHassMemo;if(i&&i.hass===this.hass&&i.sig===t)return i.active;const s=En(this.hass,e),n=On(this.hass,e);return this._planHassMemo={hass:this.hass,sig:t,active:s,full:n},s}_captureRenderDeviceSnapshot(){if(!this.hass)return;const e=Date.now(),t=[...this._activityRt.entries()].map(([t,i])=>`${t}:${i.gen}:${i.flashTs}:`+(i.flashKind&&(i.expiresAt||i.flashTs+cm)>e?1:0)).join("|"),i=vn(this._virtualLights);if(this._capturedSnapshotSequence===this._hassSequence&&this._capturedSnapshotDevices===this._devices&&this._capturedSnapshotLayout===this._layout&&this._capturedSnapshotConfigEpoch===this._cfgEpoch&&this._capturedSnapshotVirtual===i&&this._capturedSnapshotActivity===t)return;const s=this._planHass,n=new Map,o=new Map,a=new Set(["sun.sun"]);this._vacFit?.source&&a.add(this._vacFit.source);const r=new Set,l=new Set,c=e=>{if(!e)return;const t=e.indexOf(":");if(t<0)return void a.add(e);const i=e.slice(0,t),s=e.slice(t+1);"device"===i?r.add(s):"entity"===i&&a.add(s)};for(const e of this._model)for(const t of e.rooms)t.area&&l.add(t.area),c(t.settings?.temp_source),c(t.settings?.hum_source);for(const e of this._serverCfg?.spaces||[])for(const t of e.openings||[])for(const e of gi(t))a.add(e);for(const e of this._serverCfg?.spaces||[])for(const t of e.decor||[])if("text"===t.kind){for(const e of String(t.text||"").matchAll(/\{([^{}\r\n]+)\}/g)){const t=Yi(e[1]);t?.entity&&a.add(t.entity)}t.entity&&a.add(t.entity),o.set(`decor:${e.id}:${t.id}`,es(t.text,t,s,e=>!!s.entities?.[e]&&!!s.states?.[e]&&!ko(s,e,wo(this._markers))))}const h=ho(s,this._devices,null,this._virtualLights);for(const e of this._devices){for(const t of[!1,!0])n.set(N_(e.id,t),R_(s,e,{liveStates:!1!==this._config?.live_states,showTemperature:!1!==this._config?.show_temperature,showSignal:t,activityRuntime:this._activityRt.get(e.id),sourceDetails:!1,lightDevices:this._devices,lightSources:h,registryHass:this._fullRegistryHass,reducedMotion:this._reducedMotion}));if(this._isVacDev(e)){const t=this._vacSource(e,s),i=t?cp(s?.states?.[t]?.attributes):null,n=this._vacRt.get(e.id);o.set(`vacuum:${e.id}`,{source:t,telemetry:i,mapId:i?this._vacMapId(e,i,s):null,runtime:n?{trail:n.trail,lastTs:n.lastTs,moving:n.moving,jump:n.jump}:null,server:this._vacSrvTrails[e.id]||null})}}const d=F_({sourceSequence:this._hassSequence,hass:s,devices:this._devices,presentations:n,positions:(p=this._model.length>0,u=this._devices,_=e=>this._livePos(e),p?new Map(u.map(e=>[e.id,_(e)])):new Map),facts:o,entityIds:a,deviceIds:r,areaIds:l});var p,u,_;this._capturedSnapshotSequence=this._hassSequence,this._capturedSnapshotDevices=this._devices,this._capturedSnapshotLayout=this._layout,this._capturedSnapshotActivity=t,this._capturedSnapshotConfigEpoch=this._cfgEpoch,this._capturedSnapshotVirtual=i,this._visibleDeviceSnapshot&&"steady"!==this._continuity.state?this._candidateDeviceSnapshot=d:(this._visibleDeviceSnapshot=d,this._candidateDeviceSnapshot=null)}get _renderDeviceSnapshot(){return this._stagedDeviceSnapshotToken===this._continuity.token?this._candidateDeviceSnapshot||this._visibleDeviceSnapshot:this._visibleDeviceSnapshot||this._candidateDeviceSnapshot}get _renderPlanHass(){return this._renderDeviceSnapshot?.hass||this._planHass}get _renderDevices(){return this._renderDeviceSnapshot?.devices||this._devices}get _fullRegistryHass(){return this._planHass,this._planHassMemo?.full||this.hass}_bindingStatus(e){return Bn(this.hass,e,this._haRegistry)}houseplanDiagnostics(){const e=function(e){const t=An(e);return{access:t.access,authoritative:t.authoritative,revision:t.revision,lastSuccess:t.lastSuccess,error:t.error}}(this.hass),t={active:0,ha_disabled:0,orphaned:0,unverified:0};for(const e of this._markers)e.removed||"virtual"===e.binding||t[this._bindingStatus(e.binding).kind]++;return{registry:{...e,lastSuccessAgeMs:e.lastSuccess?Math.max(0,Date.now()-e.lastSuccess):null},bindings:t}}_openBindingInHa(e){const[t,i]=e.split(":");if(i)if("device"!==t){if("entity"===t){const e=this._fullRegistryHass.entities?.[i];e?.device_id&&Lv("/config/devices/device/"+encodeURIComponent(e.device_id))}}else Lv("/config/devices/device/"+encodeURIComponent(i))}_bindingHasHaPage(e){const[t,i]=e.split(":");return!!i&&("device"===t||"entity"===t&&!!this._fullRegistryHass.entities?.[i]?.device_id)}_toggleMarkerDialogVisibility(){const e=this._markerDialog;if(!e)return;const t="ha"===e.bindingMode?this._bindingStatus(e.binding):null,i=e.hideFromPlan||"ha_disabled"===t?.kind;i&&"ha_disabled"===t?.kind?this._showToast(this._t("entity"===t.reason?"toast.ha_disabled_show_entity":"toast.ha_disabled_show_device")):i&&"unverified"===t?.kind?this._showToast(this._t("toast.ha_binding_unverified")):this._markerDialog={...e,hideFromPlan:!i}}_hookConnection(){const e=this.hass?.connection;e&&e!==this._connHooked&&(this._connHooked?.removeEventListener?.("ready",this._onConnReady),this._connHooked?.removeEventListener?.("disconnected",this._onConnLost),this._connHooked?.removeEventListener?.("reconnect-error",this._onConnLost),e.addEventListener?.("ready",this._onConnReady),e.addEventListener?.("disconnected",this._onConnLost),e.addEventListener?.("reconnect-error",this._onConnLost),this._connHooked=e)}_display(e){return this._signer.display(this.hass,e)}_resign(){this._signer.resign(this.hass,Rs(this._serverCfg))}_onLayoutEvent(e){e<=this._layoutRev||(clearTimeout(this._layoutSyncTimer),this._layoutSyncTimer=window.setTimeout(()=>{e<=this._layoutRev||this._reloadLayoutOnly()},200))}_noteLayoutRev(e){const t=e?.rev;"number"==typeof t&&t>this._layoutRev&&(this._layoutRev=t)}async _reloadLayoutOnly(){if(!this._serverStorage||!this.hass?.callWS)return;this._beginContinuityCandidate("layout-reload",!1);const e=new Map;for(const t of this._dirtyPos)this._layout[t]&&e.set(t,this._layout[t]);this._persistLayout.pending()&&this._persistLayout.flush();for(const[t,i]of this._sentPos)e.set(t,i);try{const t=await this.hass.callWS({type:"houseplan/layout/get"}),i={...t?.layout||{}};for(const[t,s]of e)i[t]=s;const s=Gd(i);s!==(this._layoutContentFingerprint||Gd(this._layout))&&(this._layout=i,this._layoutContentFingerprint=s),this._layoutRev=t?.rev??this._layoutRev,this._canOptimizeUndo=!!t?.can_optimize_undo,this._haIntegrationVersion="string"==typeof t?.integration_version?t.integration_version:this._haIntegrationVersion,this._undoKind=t?.undo_kind||null,this._cacheSnapshot(),this.requestUpdate()}catch{}finally{this._continuityDataReady=!0,this.requestUpdate()}}_maybeRebuildDevices(){const e=this.hass;if(!e?.devices||!e?.entities||!e?.areas)return;const t=this._haRegistry,i=Fn(e,t)+":"+Object.keys(e.areas).length+":"+(this._norm?"n":"l")+":"+pa(e,this._config?.language);if(i===this._regSignature&&this._devices.length)return;this._regSignature=i;const s=new Map(this._devices.map(e=>[e.id,e.bindingStatus?.kind||"active"]));this._devices=So({hass:e,registry:t,areaToSpace:Object.fromEntries(Object.entries(this._areaToSpace).map(([e,t])=>[e,t.space])),markers:this._markers,settings:this._settings,excluded:this._excluded,showAll:this._showAll,firstSpaceId:this._model[0]?.id||"",loc:e=>this._t(e),iconRules:this._iconRules});const n=this._markers.filter(e=>!e.removed&&"virtual"!==e.binding).map(e=>e.binding).sort(),o=t.revision+":"+n.join("|");if(t.authoritative&&o!==this._haBindingCacheKey){const i=new Map;for(const s of n)i.set(s,Bn(e,s,t));!function(e){if("undefined"==typeof localStorage||!e.size)return;const t=Ln(),i=Date.now();for(const[s,n]of e)"active"===n.kind?t[s]={kind:"active",ts:i}:"ha_disabled"===n.kind&&(t[s]={kind:"ha_disabled",reason:n.reason,ts:i});const s=Object.fromEntries(Object.entries(t).sort((e,t)=>t[1].ts-e[1].ts).slice(0,1500));Mn=s;try{localStorage.setItem(Sn,JSON.stringify(s))}catch{}}(i),this._haBindingCacheKey=o}this._defPos=this._defaultPositions(),this._syncNewDevices(),this._seedHiddenDevices(),this._syncActivityRuntime();const a=new Set(this._devices.filter(e=>!e.hidden).map(e=>e.id));for(const e of this._vacRt.keys())a.has(e)||this._vacRt.delete(e);if(this._infoCard){const e=this._devices.find(e=>e.id===this._infoCard.id);this._infoCard=e&&"ha_disabled"!==e.bindingStatus?.kind?e:null}const r=this._devices.some(e=>"ha_disabled"===e.bindingStatus?.kind&&"ha_disabled"!==s.get(e.id));r&&("ha_disabled"!==this._infoCard?.bindingStatus?.kind&&"ha_disabled"!==this._devices.find(e=>e.id===this._infoCard?.id)?.bindingStatus?.kind||this._closeInfoCard(),this._drag&&"ha_disabled"===this._devices.find(e=>e.id===this._drag.id)?.bindingStatus?.kind&&(this._drag=null),clearTimeout(this._holdTimer),this._holdFired=!1,this._tip=null,this._tapConfirm=null),this._nativeMoreInfoEntity&&!this._planEntityAvailable(this._nativeMoreInfoEntity)&&(Hv(this,"hass-more-info",{entityId:null}),this._nativeMoreInfoEntity=null)}_syncNewDevices(){if(!this._norm||!this._loadOk||!this._serverCfg)return;const e=this._devices.filter(e=>!e.marker&&!e.virtual).map(e=>e.id).sort(),t=e.join(",");if(t===this._newSyncKey)return;this._newSyncKey=t;const i=this._settings,{fresh:s,known:n}=function(e,t){if(!Array.isArray(t))return{fresh:[],known:[...e]};const i=new Set(t),s=e.filter(e=>!i.has(e));return{fresh:s,known:s.length?[...t,...s]:t}}(e,i.known_devices);if(!Array.isArray(i.known_devices)||s.length){const e=[...new Set([...i.new_device_ids||[],...s])];this._serverCfg={...this._serverCfg,settings:{...i,known_devices:n,new_device_ids:e}},this._saveConfig()}}get _newIds(){const e=this._settings.new_device_ids;return new Set(Array.isArray(e)?e:[])}_ackNewDevice(e){if(!this._newIds.has(e)||!this._serverCfg)return;const t=this._settings;this._serverCfg={...this._serverCfg,settings:{...t,new_device_ids:(t.new_device_ids||[]).filter(t=>t!==e)}},this._saveConfig(),this.requestUpdate()}get _markers(){return this._serverCfg?.markers||[]}_roomLqi(e){if(!e)return null;const t=[];for(const i of this._renderDevices){if(i.area!==e||i.virtual)continue;const s=_o(this._renderPlanHass,i.entities);null!=s&&t.push(s)}return Ni(t)}_roomBounds(e){if(e.poly&&e.poly.length){const t=e.poly.map(e=>e[0]),i=e.poly.map(e=>e[1]),s=Math.min(...t),n=Math.min(...i);return{x:s,y:n,w:Math.max(...t)-s,h:Math.max(...i)-n}}return{x:e.x??0,y:e.y??0,w:e.w??0,h:e.h??0}}_defaultPositions(){const e={},t=this._config?.icon_size??2.5;for(const i of this._model){const s=t/100*nd(i)*1.3;for(const t of i.rooms){if(!t.area)continue;const n=this._devices.filter(e=>e.area===t.area&&e.space===i.id);if(!n.length)continue;const o=this._roomBounds(t),a=.1*Math.min(o.w,o.h),r=o.w-2*a,l=o.h-2*a,c=Math.max(1,Math.round(Math.sqrt(n.length*r/Math.max(l,1)))),h=Math.ceil(n.length/c),d=r/c,p=l/Math.max(h,1),u=n.map((e,t)=>({x:o.x+a+d*(t%c+.5),y:o.y+a+p*(Math.floor(t/c)+.5)}));Oi(u,o,s,.5*a),n.forEach((t,i)=>e[t.id]=Wh(u[i]))}}return e}_pos(e){const t=this._renderDeviceSnapshot?.positions.get(e.id);return t?{x:t.x,y:t.y}:this._livePos(e)}_livePos(e){const t=this._spaceModelById(e.space),i=this._layout[e.id];if(i)if(this._norm){if(i.s===e.space)return{x:i.x*zv,y:i.y*zv}}else if(void 0===i.s)return{x:i.x,y:i.y};return this._defPos[e.id]?this._defPos[e.id]:t?Wh(sd(t)):{x:500,y:500}}_savePos(e,t,i){if(this._spaceModelById(e.space)){if(this._norm){const s=this._gridPitch,n=Math.round(t/s)*s,o=Math.round(i/s)*s,a=this._layout[e.id]?.k;this._layout={...this._layout,[e.id]:{s:e.space,x:Gh(n/zv),y:Gh(o/zv),...a?{k:a}:{}}}}else this._layout={...this._layout,[e.id]:{x:Math.round(t),y:Math.round(i)}};this._dirtyPos.add(e.id),this._persistLayout()}}_visualSamples(e){return C_(this._renderPlanHass,e,this._renderDevices,void 0,this._fullRegistryHass).samples}_devicePresentation(e,t=!1!==this._config?.show_signal,i=!1){const s=i?null:this._renderDeviceSnapshot?.presentations.get(N_(e.id,t));return s||R_(this._renderPlanHass,e,{liveStates:!1!==this._config?.live_states,showTemperature:!1!==this._config?.show_temperature,showSignal:t,designPreview:i,activityRuntime:this._activityRt.get(e.id),sourceDetails:!1,lightDevices:this._renderDevices,registryHass:this._fullRegistryHass,reducedMotion:this._reducedMotion})}_deviceVisual(e){return this._devicePresentation(e).visual}_stateClass(e,t=this._deviceVisual(e)){const i=this._devicePresentation(e);return i.effectiveHidden?"":("icon_ripple"!==i.display||!1===this._config?.live_states||"alarm"===t.status||t.activity,I_({...i,visual:t}).join(" "))}_liveTemp(e){if(!this._config?.show_temperature)return null;if(!0===e.marker?.use_climate_temp){const t=go(this._renderPlanHass,e.entities);if(null!=t)return t}return"mdi:thermometer"!==e.icon&&"mdi:air-filter"!==e.icon?null:mo(this._renderPlanHass,e.entities)}_bindingEntities(e){if("virtual"===e||!e)return[];const t=this._bindingStatus(e);return"active"===t.kind?t.enabledEntityIds:t.allEntityIds}_bindingHasClimate(e){return this._bindingEntities(e).some(e=>e.startsWith("climate."))}_bindingHasAlarm(e){return this._bindingEntities(e).some(e=>{const t=this._planHass?.states?.[e]||this.hass?.states?.[e],i=this._fullRegistryHass.entities[e]||this.hass?.entities?.[e];return Bs(e.split(".")[0],t?.attributes?.device_class||i?.device_class||i?.original_device_class)})}_liveHum(e){return this._config?.show_temperature&&e.primary&&fo(this.hass,e.primary)?vo(this.hass,e.entities):null}_deviceBindingActive(e,t=!0){if(e.virtual||"virtual"===e.bindingKind)return!0;if(!e.bindingKind||!e.bindingRef)return!1;const i=this._bindingStatus(`${e.bindingKind}:${e.bindingRef}`);return"active"===i.kind||(t&&this._showToast(this._t("ha_disabled"===i.kind?"toast.ha_disabled_action":"toast.ha_binding_unverified")),!1)}_openMoreInfo(e){e?this._planEntityAvailable(e)?(this._nativeMoreInfoEntity=e,Hv(this,"hass-more-info",{entityId:e})):this._showToast(this._t("toast.ha_disabled_action")):this._showToast(this._t("toast.no_entity"))}_interruptViewGesture(e,t){if(clearTimeout(this._holdTimer),clearTimeout(this._kioskHoldTimer),void 0!==e)for(const i of[t,this._stageEl])try{i?.hasPointerCapture?.(e)&&i.releasePointerCapture(e)}catch{}this._pointers.clear(),this._panStart=null,this._panLock=null,this._pinchStart=null,this._swipeStart=null}_closeInfoCard(){this._interruptViewGesture(),this._holdFired=!1,this._infoCard=null}_ctxDevice(e,t){"view"===this._mode&&(e.preventDefault(),e.stopPropagation(),this._deviceBindingActive(t)&&(t.primary?this._openMoreInfo(t.primary):this._infoCard=t))}_clickDevice(e,t){if(e.stopPropagation(),this._drag?.moved||this._suppressClick||this._holdFired)return;if("plan"===this._mode)return;if("devices"===this._mode)return void this._openMarkerDialog(t);const i=this._devices.find(e=>e.id===t.id);if(!i)return;const s=qp(i.tapAction,i.primary?.split(".")[0]),n=(e,t)=>{i.marker?.tap_confirm?this._tapConfirm={kind:"run",text:e,exec:t}:t()};if("toggle"===s){const e=this._toggleIntent(i);if(!e)return;if(!Yp(e))return void this._showUnavailableToggleTargets(e);const t=e=>{const t=Yp(e);if(!t)return;if("virtual-light"===t.kind)return this._startDevicePressFeedback(i.id),void this.hass.callWS({type:"houseplan/virtual_light/toggle",marker_id:t.markerId}).then(e=>{const t=wn(this._virtualLights,e);t!==this._virtualLights&&(this._virtualLights=t,this._capturedSnapshotVirtual="",this._cacheSnapshot(),this.requestUpdate())}).catch(e=>this._showToast(this._t("toast.virtual_light_toggle_failed",{err:this._errText(e)})));const{command:s}=t;this._startDevicePressFeedback(i.id),this.hass.callService(s.domain,s.service,s.data).catch(e=>this._showToast(this._t("toast.error",{err:this._errText(e)})))},s=((o=e).targets.length?o.targets:o.skippedTargets).map(e=>e.name||e.entityId||e.ref).join(", ")||i.name;if(i.marker?.tap_confirm){const n=this._toggleConfirmationLines(e);if(!n.length)return;this._tapConfirm={kind:"toggle",text:this._t("confirm.tap_toggle",{name:s}),lines:n,initialIntent:e,deviceId:i.id,exec:()=>{const s=this._devices.find(e=>e.id===i.id),n=s?this._toggleIntent(s):null;n&&!Yp(n)&&this._showUnavailableToggleTargets(n)||(n&&Xp(e,n)?t(n):this._showToast(this._t("toast.tap_target_changed")))}}}else t(e);return}var o;if("info"===s)return this._interruptViewGesture(),void(this._infoCard=i);if(this._deviceBindingActive(i)){if("run"===s){const e=i.marker?.tap_target||"",t=function(e){const t=String(e||"").split(".")[0];return"automation"===t?{domain:"automation",service:"trigger"}:"script"===t?{domain:"script",service:"turn_on"}:"scene"===t?{domain:"scene",service:"turn_on"}:null}(e),s=this.hass.states[e];if(!t||!s)return void this._showToast(this._t("toast.run_target_missing"));const o=s.attributes?.friendly_name||e;return void n(this._t("confirm.tap_run",{name:o}),()=>{this._deviceBindingActive(i)&&this._planEntityAvailable(e)&&(this._startDevicePressFeedback(i.id),this.hass.callService(t.domain,t.service,{entity_id:e}).then(()=>{this._stampActivity(i.id,"event",this._activitySourceKey(i)),this.requestUpdate(),this._showToast(this._t("toast.run_started",{name:o}))}).catch(e=>this._showToast(this._t("toast.error",{err:this._errText(e)}))))})}"more-info"===s&&i.primary?this._openMoreInfo(i.primary):this._infoCard=i}}_showUnavailableToggleTargets(e){const t=function(e){if(!e||"group"!==e.kind||Yp(e)||"configured-targets-missing"!==e.noneReason)return[];if(!e.skippedTargets.length||e.skippedTargets.some(e=>!Jp.has(e.reason)&&"secure"!==e.reason))return[];const t=[],i=new Set;for(const s of e.skippedTargets){if(!Jp.has(s.reason))continue;const e=String(s.name||s.entityId||s.ref||"").trim();e&&!i.has(e)&&(i.add(e),t.push(e))}return t}(e);return!!t.length&&(this._showToast(1===t.length?this._t("toast.toggle_target_unavailable",{name:t[0]}):this._t("toast.toggle_targets_unavailable",{names:t.join(", ")})),!0)}_keyDevice(e,t){"Enter"!==e.key&&" "!==e.key||"view"!==this._mode&&"devices"!==this._mode||(e.preventDefault(),this._clickDevice(e,t))}_startDevicePressFeedback(e){const t=[...this.renderRoot.querySelectorAll(".dev[data-id]")].find(t=>t.dataset.id===e),i=t?.querySelector(".device-shell");if(!i||"function"!=typeof i.animate)return;const s=Number.parseFloat(this.ownerDocument.defaultView?.getComputedStyle(i).scale||""),n=Number.isFinite(s)?Math.max(.95,Math.min(1,s)):1;this._devicePressAnimations.get(e)?.cancel();const o=this._reducedMotion?[{outlineColor:"transparent",outlineStyle:"solid",outlineWidth:"0px"},{outlineColor:"var(--hp-accent, #3ea6ff)",outlineStyle:"solid",outlineWidth:"2px",outlineOffset:"2px",offset:.5},{outlineColor:"transparent",outlineStyle:"solid",outlineWidth:"0px"}]:[{scale:String(n)},{scale:"0.95",offset:.5},{scale:"1"}],a=i.animate(o,{duration:200,easing:"cubic-bezier(.22,.61,.36,1)"});this._devicePressAnimations.set(e,a);const r=()=>{this._devicePressAnimations.get(e)===a&&this._devicePressAnimations.delete(e)};a.addEventListener("finish",r,{once:!0}),a.addEventListener("cancel",r,{once:!0})}_cancelDevicePressFeedback(){for(const e of this._devicePressAnimations.values())e.cancel();this._devicePressAnimations.clear()}_pruneDevicePressFeedback(){if(!this._devicePressAnimations.size)return;const e=new Set([...this.renderRoot.querySelectorAll(".dev[data-id]")].map(e=>e.dataset.id||""));for(const[t,i]of this._devicePressAnimations)e.has(t)||(i.cancel(),this._devicePressAnimations.delete(t))}_t(e,t){return ua(pa(this.hass,this._config?.language),e,t)}get _colorPickerLabels(){return{title:this._t("color_picker.title"),hue:this._t("color_picker.hue"),saturation:this._t("color_picker.saturation"),value:this._t("color_picker.value"),hex:this._t("color_picker.hex"),invalidHex:this._t("color_picker.invalid_hex")}}_help(e){const t=`${e}.aria`,i=pa(this.hass,this._config?.language);return _a(i,e)&&_a(i,t)?q``:G}get _stageEl(){return this.renderRoot.querySelector(".stage")}_contentItems(e){const t=[];for(const i of this._devices){if(i.space!==e.id||i.hidden)continue;const s=this._pos(i);t.push({minX:s.x,minY:s.y,maxX:s.x,maxY:s.y})}if(e.id===this._space){for(const e of this._openingsR){const i=Number(e.angle)*Math.PI/180,s=Math.cos(i)*e.rlen/2,n=Math.sin(i)*e.rlen/2,o=Yh([[e.rx-s,e.ry-n],[e.rx+s,e.ry+n]]);o&&t.push(o)}const i=this._decorH;for(const e of this._decorList){const s=Yh("line"===e.kind?[[e.x1*zv,e.y1*i],[e.x2*zv,e.y2*i]]:"text"===e.kind?[[e.x*zv,e.y*i]]:Yr({x:e.x*zv,y:e.y*i,w:e.w*zv,h:e.h*i,angle:e.angle}));s&&t.push(s)}for(const i of this._physicalBodiesR(e)){const e=Yh(i);e&&t.push(e)}}return Xh(e,t)}_frameOf(){const e=this._spaceModel();if(!e){this._frame=null;const e={x:0,y:0,w:zv,h:zv};return{rect:e,all:e,outliers:0}}const t=this._frame,i="view"!==this._mode;if(t&&t.id===e.id&&this._bdDrag)return t;if(t&&t.id===e.id&&t.model===e&&t.layout===this._layout&&t.devs===this._devices&&t.far===this._showFar&&t.grow===i)return t;const s=td(this._contentItems(e));let n=s.all||id(e),o=this._showFar?n:s.core||id(e);return t&&t.id===e.id&&i&&t.grow&&(o=Nv(t.rect,o),n=Nv(t.all,n)),this._frame={id:e.id,model:e,layout:this._layout,devs:this._devices,far:this._showFar,grow:i,rect:o,all:n,outliers:s.outliers},this._frame}_isoSource(){const e=this._spaceModel();if(!e)return null;const t=this._spaceWalls,i=this._openCuts(),s=this._openingsR.map((e,t)=>({id:String(e.id||t),sourceIndex:t,type:e.type,x:e.rx,y:e.ry,angle:Number(e.angle)||0,length:e.rlen>0?e.rlen:900,flipH:!!e.flip_h,flipV:!!e.flip_v})),n=Dh(64,this._cellCm),o=Dh(10,this._cellCm),a=`${e.id}|${function(e){let t=2166136261;const i=e=>{if("number"!=typeof e)if("string"!=typeof e)if("boolean"!=typeof e)if(Array.isArray(e)){t=Hf(t,e.length);for(const t of e)i(t)}else{if(e&&"object"==typeof e){const t=e;for(const e of Object.keys(t).sort())i(e),i(t[e]);return}t=Hf(t,-1)}else t=Hf(t,e?1:0);else for(const i of e)t=Hf(t,i.codePointAt(0)||0);else t=Hf(t,e)};return i(e),t.toString(36)}({rooms:e.rooms,walls:t,openCuts:i,openings:s,partitions:e.partitions,roomDrafts:e.room_drafts,columns:e.wall_columns,cellCm:this._cellCm,gridPitch:this._gridPitch,wallKeyPitch:this._wallKeyPitch,camera:Cf,wallHeight:n,floorEdgeHeight:o,algorithm:3})}`;return{key:a,build:()=>{const o=_h(e,this._cellCm,this._gridPitch,2e-4*this._gridPitch,this._partitionOpeningCuts(e)).all,a=this._roomWallOpeningInputs(this._openingsR,e),r=t.length||o.length?qc(e.rooms,t,i,a,this._wallKeyPitch,this._cellCm,this._gridPitch,zv,o):null;if(r&&("failed-core"===r.status||"not-applicable"===r.status))throw new Error("wall boolean geometry failed");const l=r?.paperGeom??Hc(e.rooms,t,i,this._wallKeyPitch,this._cellCm,this._gridPitch,zv);if(!l)throw new Error("floor boolean geometry failed");const c=r?.openingIndex||Kc(e.rooms,t,i,this._wallKeyPitch,this._cellCm,this._gridPitch,zv),h=s.map(e=>{const i=this._openingsR[e.sourceIndex],s="gate"===e.type?!e.flipV:e.flipV,o=i?.partitionHost?ou(i.partitionHost,s):t.length||"gate"===e.type?Zc(c,{x:e.x,y:e.y,angle:e.angle,length:e.length,flip_v:s}):{ox:0,oy:0,cm:0,side:-1};return function(e,t=64){if(!(Lf([e.x,e.y,e.angle,e.length,e.face.ox,e.face.oy,t])&&e.length>0&&t>0))throw new Error("invalid isometric opening input");const i=e.length/2;let s;if("passage"===e.type)s=[];else if("gate"===e.type){const n=10*e.face.side;s=[jf(e,0,[-i,0],[i,0],n,0,.88*t),jf(e,1,[i,0],[-i,0],-n,0,.88*t)]}else s="window"===e.type?[jf(e,0,[-i,0],[i,0],-90,.27*t,.78*t),jf(e,1,[i,0],[-i,0],90,.27*t,.78*t)]:[jf(e,0,[-i,0],[e.length,0],-90,0,.92*t)];return{id:e.id,sourceIndex:e.sourceIndex,type:e.type,leaves:Object.freeze(s.map(e=>Object.freeze(e)))}}({...e,face:o},n)});return{walls:r?.components.flatMap(e=>e.geom)||[],floor:l,openings:Object.freeze(h)}}}}_isoSceneKey(){if(!this._labsIso||"view"!==this._mode)return null;try{return this._isoSource()?.key??null}catch{return`${this._space}|invalid`}}_isoScene(){const e=this._isoSource();if(!e)return null;const t=this._isoGeometryCache.get(e.key);if(t)return{key:e.key,...t};const i=this._frameOf().rect,s=e.build(),n=Dh(64,this._cellCm),o=Dh(10,this._cellCm),a=function(e){let t=1/0,i=1/0,s=-1/0,n=-1/0;for(const o of e)for(const e of o.leaves){const o=Math.hypot(e.closedVector[0],e.closedVector[1]);t=Math.min(t,e.hinge[0]-o),i=Math.min(i,e.hinge[1]-o),s=Math.max(s,e.hinge[0]+o),n=Math.max(n,e.hinge[1]+o)}return Lf([t,i,s,n])?{x:t,y:i,w:s-t,h:n-i}:null}(s.openings),r=Rf({rect:a?Nv(i,a):i,wallHeight:n,openingHeight:n,floorDepth:o}),l=function(e,t=Cf,i=64){if(!Number.isFinite(i)||i<0)throw new Error("invalid wall height");const s=[],n=[],o=[];let a=0;for(let r=0;r<(e||[]).length;r++){const l=e[r];for(let e=0;e<(l||[]).length;e++){const c=Ff(l[e],e>0);if(!(c.length<3||Math.abs(zf(c))<1e-9)){s.push(Nf(c,t,i)),a+=c.length;for(let s=0;se.depth-t.depth||e.polygon-t.polygon||e.ring-t.ring||e.edge-t.edge),{topPath:s.join(" "),sides:n,contactPath:o.join(" "),edgeCount:a}}(s.walls,Cf,n),c={geometry:l,floor:Of(s.floor,o),openings:s.openings,frame:r};return kv(this._isoGeometryCache,e.key,c,8),{key:e.key,...c}}_effectiveProjection(){if("iso"!==this._desiredProjection||!this._model.length)return"flat";const e=this._isoSceneKey()||`${this._space}|invalid`;if(this._isoFallback.has(e))return"flat";try{const e=this._isoScene();return e?(t="iso",i=e.key,s=this._isoFallback,"iso"===t&&i&&!s.has(i)?"iso":"flat"):"flat"}catch(t){if(!this._isoFallback.has(e)){this._isoFallback.add(e);const i=e.split("|");console.warn(`HOUSEPLAN ISO FALLBACK: #89, space ${this._space}, fingerprint ${i[i.length-1]}, ${t instanceof Error?t.message:"renderer error"}`)}return"flat"}var t,i,s}_scenePoint(e){return"iso"===this._renderProjection?Pf(e,0):e}_floorView(e){if("iso"!==this._renderProjection)return e;const t=Tf([e.x,e.y]),i=Tf([e.x+e.w,e.y+e.h]);return{x:t[0],y:t[1],w:i[0]-t[0],h:i[1]-t[1]}}_baseVb(){if("iso"===this._effectiveProjection()){if(!this._spaceDisplayForRender().showBorders){const e=Rf({rect:this._frameOf().rect,wallHeight:Dh(64,this._cellCm)});return[e.x,e.y,e.w,e.h]}const e=this._isoScene()?.frame??this._frameOf().rect;return[e.x,e.y,e.w,e.h]}const e=this._frameOf().rect;return[e.x,e.y,e.w,e.h]}get _outliers(){return this._showFar?0:this._frameOf().outliers}_fitFar(){this._showFar=!0,this._frame=null,this._resetZoom()}_fitAll(){this._showFar=!0,this._frame=null,this._resetZoom()}_renderFarHint(){return this._kiosk||"view"!==this._mode||this._booting||!this._outliers?G:q`
${this._t("canvas.far_objects",{n:this._outliers})} @@ -5118,7 +5118,7 @@ globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="30d20d6f6822065e2d5226b18abbb05d8d26 style="left:${r.toFixed(1)}%;top:${l.toFixed(1)}%" @click=${e=>{e.stopPropagation(),this._fitAll()}}> - `}_stageAspect(){const e=this._stageEl,t=this._baseVb();return e&&e.clientHeight?e.clientWidth/e.clientHeight:t[2]/t[3]}_viewOr(e){return this._view&&this._view.w?this._view:Ei(e,this._stageAspect())}_roomLabelReferenceViewWidth(e){if(!this._markup)return e.w;const t=this._stageEl,i=this.renderRoot.querySelector(".editorchrome");if(!t||t.clientWidth<=0||t.clientHeight<=0)return e.w;const s=t.clientHeight+(i?.getBoundingClientRect().height||0);return s<=0?e.w:this._viewForModeTarget(this._zoom,void 0,void 0,t.clientWidth,s).w}_screenToVb(e,t){const i=this._stageEl,s=this._viewOr(this._baseVb()),n=i?.clientWidth||1,o=i?.clientHeight||1;return[s.x+e/n*s.w,s.y+t/o*s.h]}_clampView(e,t){const i=(e,t,i,s)=>{const n=1*Math.max(t,s),o=i-n,a=i+s-t+n;return Math.max(Math.min(o,a),Math.min(Math.max(o,a),e))};return{w:e.w,h:e.h,x:i(e.x,e.w,t.x,t.w),y:i(e.y,e.h,t.y,t.h)}}_applyView(e,t,i){const s=this._baseVb(),n=Ei(s,this._stageAspect()),o=Math.min(Ov.ZOOM_MAX,Math.max(Ov.ZOOM_MIN,e)),a=n.w/o,r=n.h/o,l=this._viewOr(s),c=t??l.x+l.w/2,h=i??l.y+l.h/2,d=this._clampView({x:c-a/2,y:h-r/2,w:a,h:r},n);return!(this._view&&Math.abs(this._zoom-o)<1e-9&&Math.abs(this._view.x-d.x)<1e-6&&Math.abs(this._view.y-d.y)<1e-6&&Math.abs(this._view.w-d.w)<1e-6&&Math.abs(this._view.h-d.h)<1e-6)&&("opening"===this._tool&&(this._cursorPt=null,this._clearOpeningPlacement(!1)),this._zoom=o,this._view=d,!0)}_bootWatch(){clearTimeout(this._bootTimer),this._bootStart=Date.now(),this._bootLastH=-1,this._bootLastChange=this._bootStart;const e=()=>{if(!this._booting)return;const t=Date.now(),i=this._stageEl?this._stageEl.clientHeight:0;i!==this._bootLastH&&(this._bootLastH=i,this._bootLastChange=t);const s=t-this._bootStart;s>=1200||s>=700&&i>0&&t-this._bootLastChange>=250?this._bootSettled():this._bootTimer=window.setTimeout(e,100)};this._bootTimer=window.setTimeout(e,100)}_bootSettled(){this._booting&&!this._bootSettling&&(this._bootSettling=!0,this._refitView(),this._bootSettleRaf=requestAnimationFrame(()=>{this._bootSettleRaf=0,this._finishBootSettled()}))}_finishBootSettled(){if(!this._booting)return;this._refitView(),this._booting=!1,this._bootSettling=!1;const e=this._stageEl?.clientHeight??0;!this._config?.kiosk&&e>0&&this._warmPatch({hdrH:this._hdrH,stageH:e,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},_v)}_bootSoftCancel(){this._bootSoft&&(clearTimeout(this._bootSoftTimer),this._bootSoft=!1)}_beginResumeSettle(){this._booting||this._resumeSettling||(this._modeTransitionPreparing?this._modeTransitionForceAtomic=!0:this._cancelModeTransition(!0),this._viewportInvalidAt=0,this._beginContinuityCandidate("warm-resume",!1),this._loading?this.requestUpdate():this._loadFromServer())}_refitView(){if(this._modeTransitionBusy)return;const e=this._stageEl;if(!e||"visible"!==document.visibilityState||e.clientWidth<=0||e.clientHeight<=0)return void(this._viewportInvalidAt||(this._viewportInvalidAt=Date.now()));const t=[e.clientWidth,e.clientHeight],i=this._lastValidStageSize,s=!!i&&Math.abs(i[0]-t[0])<=.5&&Math.abs(i[1]-t[1])<=.5,n=this._viewportInvalidAt?Date.now()-this._viewportInvalidAt:0;if(this._viewportInvalidAt=0,!i)return this._lastValidStageSize=t,void(this._view||this._applyView(this._zoom));s?this._pendingRefitSize=null:(this._pendingRefitSize=t,this._refitRaf||(this._refitRaf=requestAnimationFrame(()=>{this._refitRaf=0;const e=this._pendingRefitSize;this._pendingRefitSize=null;const t=this._stageEl;if(!e||!t||t.clientWidth<=0||t.clientHeight<=0)return;if(Math.abs(t.clientWidth-e[0])>.5||Math.abs(t.clientHeight-e[1])>.5)return void this._refitView();const i=this._lastValidStageSize;if(i&&Math.abs(i[0]-e[0])<=.5&&Math.abs(i[1]-e[1])<=.5)return;this._lastValidStageSize=e;const s=this._view;n>=Fd?this._beginContinuityCandidate("stage-size-restored",!0,"stage-size"):this._continuity.hasCompleteFrame&&this._beginContinuityCandidate("stage-resize",!0,"stage-size"),this._applyView(this._zoom,s?s.x+s.w/2:void 0,s?s.y+s.h/2:void 0)})))}_zoomAt(e,t,i){const s=this._stageEl;if(!s)return;const n=Ei(this._baseVb(),this._stageAspect()),o=Math.min(Ov.ZOOM_MAX,Math.max(Ov.ZOOM_MIN,i));"opening"===this._tool&&(this._cursorPt=null,this._clearOpeningPlacement(!1));const a=s.clientWidth,r=s.clientHeight,l=this._screenToVb(e,t),c=n.w/o,h=n.h/o;this._zoom=o,this._view=this._clampView({x:l[0]-e/a*c,y:l[1]-t/r*h,w:c,h:h},n)}_onWheel(e){const t=this._stageEl;if(!t)return;e.preventDefault();const i=t.getBoundingClientRect(),s=e.deltaY<0?1.15:1/1.15;this._zoomAt(e.clientX-i.left,e.clientY-i.top,this._zoom*s),this._saveZoom()}_stepZoom(e){const t=this._stageEl;t&&(this._zoomAt(t.clientWidth/2,t.clientHeight/2,this._zoom*(e>0?1.4:1/1.4)),this._saveZoom())}_resetZoom(){const e=this._baseVb();"opening"===this._tool&&(this._cursorPt=null,this._clearOpeningPlacement(!1)),this._zoom=1,this._view=Ei(e,this._stageAspect()),this._saveZoom()}_saveZoom(){if("view"===this._mode){this._zoomBySpace={...this._zoomBySpace,[this._space]:this._zoom};try{localStorage.setItem($v,JSON.stringify(this._zoomBySpace))}catch{}}}_restoreZoom(){const e=this._zoomBySpace[this._space]||1;this._zoom=e;const t=this._stageEl;if(t&&t.clientHeight){const t=this._baseVb();return this._applyView(e,t[0]+t[2]/2,t[1]+t[3]/2),void this.requestUpdate()}this._view=null,requestAnimationFrame(()=>{if(!this._stageEl)return;const t=this._baseVb();this._applyView(e,t[0]+t[2]/2,t[1]+t[3]/2),this.requestUpdate()})}_stagePointerDown(e){if(this._vacFit)return;if(this._kiosk&&(this._cyclePausedUntil=Date.now()+6e4,0===this._pointers.size?(this._swipeStart={x:e.clientX,y:e.clientY,id:e.pointerId},e.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&&e.target.closest?.(".roomlabel, .rlhandle, .rszhandle, .dev, .oplock, .op-hit, button"))return;if("devices"===this._mode&&e.target.closest(".dev"))return;if("decor"===this._mode&&this._decorPointerDown(e))return;this._pointers.set(e.pointerId,{x:e.clientX,y:e.clientY});const t=this._viewOr(this._baseVb());if(1===this._pointers.size)this._panStart={sx:e.clientX,sy:e.clientY,vx:t.x,vy:t.y},this._panLock=null,this._suppressClick=!1;else if(2===this._pointers.size){"opening"===this._tool?(this._cursorPt=null,this._clearOpeningPlacement(!1)):"draw"===this._tool&&this._clearPlanSnapHover();const e=[...this._pointers.values()],t=Math.hypot(e[0].x-e[1].x,e[0].y-e[1].y);this._pinchStart={dist:t,zoom:this._zoom},this._panStart=null,this._panLock=null}}get _swipeZone(){return!this._hasFixedFloor&&this._kiosk&&this._zoom<=1.001&&this._model.length>1}_stagePointerMove(e){if(this._physicalRotate?.pid!==e.pointerId)if(this._physicalDrag?.pid!==e.pointerId)if(this._dtDrag?.pid!==e.pointerId)if(this._bdDrag?.pid!==e.pointerId){if(this._decorDraft?.pid===e.pointerId){const t=this._decorDraft;let i=this._decorSnap(this._svgPoint(e),e.pointerType);if(e.shiftKey&&("rect"===t.kind||"ellipse"===t.kind)){const e=i[0]-t.a[0],s=i[1]-t.a[1],n=Math.max(Math.abs(e),Math.abs(s));i=this._snap([t.a[0]+(e<0?-n:n),t.a[1]+(s<0?-n:n)])}return void(this._decorDraft={...t,b:i})}if(this._decorMove?.pid!==e.pointerId)if(this._pointers.has(e.pointerId)){if(this._pointers.set(e.pointerId,{x:e.clientX,y:e.clientY}),this._markup&&1===this._pointers.size&&this._markupMove(e),this._pinchStart&&this._pointers.size>=2){"opening"===this._tool?(this._cursorPt=null,this._clearOpeningPlacement(!1)):"draw"===this._tool&&this._clearPlanSnapHover();const e=[...this._pointers.values()],t=Math.hypot(e[0].x-e[1].x,e[0].y-e[1].y)/(this._pinchStart.dist||1),i=this._stageEl.getBoundingClientRect(),s=(e[0].x+e[1].x)/2-i.left,n=(e[0].y+e[1].y)/2-i.top;this._zoomAt(s,n,this._pinchStart.zoom*t),this._suppressClick=!0,this._saveZoom()}else if(this._panStart){const t=e.clientX-this._panStart.sx,i=e.clientY-this._panStart.sy;Math.abs(t)+Math.abs(i)>4&&(this._suppressClick=!0,clearTimeout(this._holdTimer),"opening"===this._tool?(this._cursorPt=null,this._clearOpeningPlacement(!1)):"draw"===this._tool&&this._clearPlanSnapHover()),null===this._panLock&&Math.abs(t)+Math.abs(i)>8&&(this._panLock=this._swipeZone&&Math.abs(t)>1.5*Math.abs(i)?"swipe":"pan");const s=this._stageEl;if("pan"===this._panLock&&s){const e=this._baseVb(),n=this._viewOr(e),o=Ei(e,this._stageAspect());this._view=this._clampView({x:this._panStart.vx-t/(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(e);else this._decorMoveUpdate(e)}else this._bdMove(e);else this._dtMove(e);else this._physicalMove(e);else this._physicalRotateMove(e)}_stagePointerLeave(e){this._markup&&("opening"===this._tool?(this._cursorPt=null,this._clearOpeningPlacement(!1)):"draw"===this._tool&&this._clearPlanSnapHover())}_stagePointerUp(e){if(this._kiosk){clearTimeout(this._kioskHoldTimer);const t=this._swipeStart;if(this._swipeStart=null,t&&t.id===e.pointerId){const i=e.clientX-t.x,s=e.clientY-t.y;if(Math.abs(i)+Math.abs(s)<8){const e=Date.now();e-this._lastTap<350&&this._resetZoom(),this._lastTap=e}const n="pan"===this._panLock?null:function(e,t,i,s,n,o=60){if(i>1.001||s.length<2)return null;if(Math.abs(e)e.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._physicalDrag?.pid===e.pointerId)return void this._physicalUp(e);if(this._physicalRotate?.pid===e.pointerId)return void this._physicalRotateUp(e);if(this._dtDrag?.pid===e.pointerId)return void this._dtUp();if(this._bdDrag?.pid===e.pointerId)return void this._bdUp();if(this._decorDraft?.pid===e.pointerId)return void this._decorCommitDraft();if(this._decorMove?.pid===e.pointerId)return this._decorMove.moved&&(this._recordGeometry(this._t("history.decor_move"),this._decorMove.before),this._saveConfig()),void(this._decorMove=null);const t=!!this._pinchStart||!!this._panStart;this._pointers.delete(e.pointerId),this._pointers.size<2&&(this._pinchStart=null),0===this._pointers.size&&(this._panStart=null,this._panLock=null,setTimeout(()=>this._suppressClick=!1,0)),t&&0===this._pointers.size&&this.requestUpdate()}_clickRoom(e){!this._suppressClick&&e.area&&Fv("/config/areas/area/"+e.area)}_pointerDown(e,t){if("plan"===this._mode)return;if("view"===this._mode){this._holdFired=!1,clearTimeout(this._holdTimer);const i=e.pointerId,s=e.currentTarget;return void(this._holdTimer=window.setTimeout(()=>{this._holdFired=!0,this._interruptViewGesture(i,s),this._infoCard=t},600))}if("ha_disabled"===t.bindingStatus?.kind)return;e.preventDefault();const i=this._pos(t);this._drag={id:t.id,sx:e.clientX,sy:e.clientY,ox:i.x,oy:i.y,moved:!1},Ev(e),this._tip=null}_pointerMove(e,t){if(!this._drag||this._drag.id!==t.id)return;const i=this.renderRoot.querySelector(".stage");if(!i)return;const s=this._baseVb(),n=i.getBoundingClientRect(),o=this._viewOr(s),a=(e.clientX-this._drag.sx)/n.width*o.w,r=(e.clientY-this._drag.sy)/n.height*o.h;Math.abs(e.clientX-this._drag.sx)+Math.abs(e.clientY-this._drag.sy)>3&&(this._drag.moved=!0,clearTimeout(this._holdTimer));const l=Lh(this._drag.ox+a),c=Lh(this._drag.oy+r);this._savePos(t,l,c)}_pointerUp(e,t){if(clearTimeout(this._holdTimer),!this._drag||this._drag.id!==t.id)return;const i=this._drag.moved;this._drag=i?this._drag:null,i&&(this._selId=t.id,window.setTimeout(()=>this._drag=null,0))}_showToast(e){for(const e of this.renderRoot.querySelectorAll("hp-dialog"))e.closeTransientOverlays("toast");this._toast=e,clearTimeout(this._toastTimer),this._toastTimer=window.setTimeout(()=>{this._toast=""},3500)}_syncPointerHoverTargets(){const e=this._pointerModality.hoverEnabled;for(const t of this.renderRoot.querySelectorAll(Dv))t.toggleAttribute("data-pointer-hover",e)}_syncPointerHoverSubtree(e){if(e.nodeType!==Node.ELEMENT_NODE)return;const t=e,i=this._pointerModality.hoverEnabled;t.matches(Dv)&&t.toggleAttribute("data-pointer-hover",i);for(const e of t.querySelectorAll(Dv))e.toggleAttribute("data-pointer-hover",i)}_clearTransientHover(e=!1){e&&this._pointerModality.suspend(),this._tip&&(this._tip=null),this._hoverRoom&&(this._hoverRoom=null)}_notePointer(e){const t=this._pointerModality.modality,i=this._pointerModality.note(e);"touch"!==i&&"pen"!==i||t===i&&!this._tip&&!this._hoverRoom||this._clearTransientHover()}_guardTouchGesture(e){if(this._editorSecondary.handleOutsideDismiss(e))return;if("click"===e.type){if(!this._suppressClick&&!this._touchSequenceMultitouch&&Date.now()>this._touchClickBlockUntil)return;return e.preventDefault(),void e.stopImmediatePropagation()}const t=e;if(this._notePointer(t),"touch"===t.pointerType)if("pointerdown"!==e.type){if("pointermove"===e.type){const e=this._touchContacts.get(t.pointerId);if(!e)return;const i={...e,x:t.clientX,y:t.clientY};if(this._touchContacts.set(t.pointerId,i),this._touchSequenceMultitouch&&"view"===this._mode&&!this._vacFit&&this._pinchStart&&[...this._touchContacts.values()].every(e=>e.inStage)){this._pointers.set(t.pointerId,{x:t.clientX,y:t.clientY});const e=[...this._touchContacts.values()];if(e.length>=2&&this._stageEl){const[t,i]=e,s=Math.hypot(t.x-i.x,t.y-i.y)/(this._pinchStart.dist||1),n=this._stageEl.getBoundingClientRect();this._zoomAt((t.x+i.x)/2-n.left,(t.y+i.y)/2-n.top,this._pinchStart.zoom*s),this._saveZoom()}}return}if("pointerup"===e.type||"pointercancel"===e.type||"lostpointercapture"===e.type){if(this._clearTransientHover(),this._touchContacts.delete(t.pointerId),this._touchSequenceMultitouch){if(this._touchClickBlockUntil=Date.now()+500,this._pointers.delete(t.pointerId),!this._vacFit&&this._pointers.size>=2){const[e,t]=[...this._pointers.values()];this._pinchStart={dist:Math.hypot(e.x-t.x,e.y-t.y),zoom:this._zoom}}else this._pinchStart=null;0===this._pointers.size&&(this._panStart=null,this._panLock=null)}0===this._touchContacts.size&&(this._touchSequenceMultitouch=!1)}}else if(this._touchContacts.set(t.pointerId,{x:t.clientX,y:t.clientY,inStage:!!t.target?.closest?.(".stage")}),this._touchContacts.size>=2){this._clearTransientHover(),this._touchSequenceMultitouch=!0,this._touchClickBlockUntil=Number.POSITIVE_INFINITY,clearTimeout(this._holdTimer),clearTimeout(this._kioskHoldTimer),this._swipeStart=null;const e=[...this._touchContacts.values()];if("view"===this._mode&&!this._vacFit&&e.every(e=>e.inStage)){this._pointers=new Map([...this._touchContacts].map(([e,t])=>[e,{x:t.x,y:t.y}]));const[t,i]=e;this._pinchStart={dist:Math.hypot(t.x-i.x,t.y-i.y),zoom:this._zoom},this._panStart=null,this._panLock=null}else this._vacFit&&(this._pointers.clear(),this._pinchStart=null,this._panStart=null,this._panLock=null)}}_showTip(e,t,i,s,n,o){this._notePointer(e),this._pointerModality.hoverEnabled&&(this._drag||(this._tip={x:e.clientX,y:e.clientY,title:t,meta:i,lqi:s,temp:n,hum:o}))}get _gridPitch(){return Nh}get _cellCm(){const e=Number(this._curSpaceCfg?.cell_cm);return Number.isFinite(e)&&e>0?e:5}_fmtLen(e,t){const i=function(e,t,i,s){return Math.hypot(t[0]-e[0],t[1]-e[1])/i*s}(e,t,this._gridPitch,this._cellCm);return li(i,"mi"===this.hass?.config?.unit_system?.length)}get _curSpaceCfg(){const e=this._resize.preview;return e&&e.space===this._space?e.sp:this._serverCfg?.spaces.find(e=>e.id===this._space)}get _renderCfg(){const e=this._resize.preview;return e&&this._serverCfg?{...this._serverCfg,spaces:this._serverCfg.spaces.map(t=>t.id===e.space?e.sp:t)}:this._serverCfg}get _spaceH(){return this._curSpaceCfg,Pv}get _segments(){const e=this._curSpaceCfg,t=this._spaceH;return pi(e?.rooms||[]).map(e=>[e[0]*Pv,e[1]*t,e[2]*Pv,e[3]*t])}_savedNav(){if(this._hasFixedFloor)return null;try{return JSON.parse(localStorage.getItem(Sv)||"null")}catch{return null}}_saveNav(){if(!this._hasFixedFloor)try{localStorage.setItem(Sv,JSON.stringify({space:this._space}))}catch{}}_leaveCardRoute(){if(this._routeDepartureHandled)return;this._routeDepartureHandled=!0,"view"!==this._mode&&this._setMode("view",!1),this._pendingNavMode=null,this._geometryHistory.clear(),this._activeDraftId=null,this._resumeDraftBySpace={},this._draftSegmentCms=[],this._closingWallCm=null,this._drawWallField=null,this._showHidden=!1,this._tapConfirm=null,this._vacCalConfirm=null,this._decorEraseConfirm=null,this._openingInfo=null,this._closeInfoCard(),this._rulesDialog=null,this._alignDialog=null,this._preflightClipboardFallback=null,this._backupImportDialog=null,this._backupExportDialog=null,this._settingsDialog=null,this._deviceInbox=null,this._deviceInboxReturn=null,this._markerDialog=null,this._openingDialog=null,this._physicalDialog=null,this._wallDialog=null,this._backdropDialog=null,this._decorShapeDialog=null,this._decorTextDialog=null,this._mergeDialog=null,this._roomDialog=!1,this._spaceDialog=null,this._importDialog=null;const e=this._warmSlot;e?.owner===this._warmGen&&(e.vp=this._warmViewportState(),e.dlg=null,e.frameFingerprint="",clearTimeout(e.evict),e.evict=0),this._saveNav()}_setMode(e,t=!0){this._endTabDrag(),this._pendingNavMode=null;const i=this._spaceModel();if(!i)return this._cancelModeTransition(!1),void(this._mode="view");if(this._kiosk&&"view"!==e)return;if(this._mode===e){if(!t&&"view"===e&&this._modeTransitionBusy){const t=this._currentModeVisual(e),i=this._modeTransitionTargetZoom,s=this._modeTransitionTargetCenterX,n=this._modeTransitionTargetCenterY;this._cancelModeTransition(!1),this._commitViewModeAtomic(t,i,s,n)}return}if(this._bootSoftCancel(),("plan"===e||"decor"===e)&&!this._norm)return void this._showToast(this._t("toast.markup_needs_server"));if(this._wallFaceBatch&&this._roomDialogCancel(),"plan"===this._mode&&"draw"===this._tool&&!this._finishWallChain())return;this._clearTransientHover(!0),this._cancelDevicePressFeedback();const s=this._mode,n=this._effectiveProjection(),o=this._currentModeVisual(s),a=this._modeTransitionBusy,r=o&&"view"!==s&&"view"!==e?{...o,toolbarContentOpacity:this._reducedMotion?1:.35}:o;this._cancelModeTransition(!1),this._editorSecondary.closeForNavigation(),(this._decorMove||this._dtDrag||this._bdDrag)&&this._cancelDecorGesture();const l=!i.bg&&"view"===e!=("view"===s),c=a&&"view"===s&&"view"!==e?this._modeTransitionEditorCamera:null;let h=c?.zoom??(a?this._modeTransitionTargetZoom:this._zoom),d=c?c.centerX:a?this._modeTransitionTargetCenterX:r?.viewport.centerX,p=c?c.centerY:a?this._modeTransitionTargetCenterY:r?.viewport.centerY;if("view"===s&&"view"!==e&&!a){const t=this._view;if(this._viewModeSnap={space:this._space,zoom:this._zoom,cx:t?this._logicalViewCenter(n)?.x:void 0,cy:t?this._logicalViewCenter(n)?.y:void 0},"iso"===n){const t=this._logicalViewCenter("iso");d=t?.x,p=t?.y,this._view=null,this._mode=e,this._applyView(this._zoom,t?.x,t?.y)}l&&(h=1,d=void 0,p=void 0)}if("plan"===s&&this._activeDraftId&&(this._resumeDraftBySpace[this._space]=this._activeDraftId),this._mode=e,"devices"===s&&"devices"!==e&&(this._showHidden=!1,this._deviceInbox=null,this._deviceInboxReturn=null,this._deviceInboxMemo=null),this._editorChromeMode="view"===e?s:e,"view"===e){"view"===s||a||(this._modeTransitionEditorCamera={zoom:this._zoom,centerX:r?.viewport.centerX,centerY:r?.viewport.centerY});const e=this._viewModeSnap;if(e&&e.space===this._space){h=e.zoom;const t=this._labsIso&&"iso"===this._viewPreference[this._space]?"iso":"flat",i=null!=e.cx&&null!=e.cy&&"iso"===t?$f([e.cx,e.cy],0):null;d=i?.[0]??e.cx,p=i?.[1]??e.cy}else e&&(h=this._zoomBySpace[this._space]||1,d=void 0,p=void 0)}else this._modeTransitionEditorCamera={zoom:h,centerX:d,centerY:p};this._modeTransitionTargetZoom=h,this._modeTransitionTargetCenterX=d,this._modeTransitionTargetCenterY=p,("iso"===n||"view"===e&&this._labsIso&&"iso"===this._viewPreference[this._space])&&(this._modeTransitionForceAtomic=!0);const u=++this._modeTransitionRequest;t?r?(this._modeTransitionPreparing=!0,this._modeTransitionVisual=r,this._prepareModeTransition(u,r,e,h,d,p)):(this._modeTransitionPreparing=!1,this._modeTransitionVisual=null,this._zoom=h,this._view=null,requestAnimationFrame(()=>{this.isConnected&&u===this._modeTransitionRequest&&this._mode===e&&(this._applyView(h,d,p),"view"===e&&(this._viewModeSnap=null,this._modeTransitionEditorCamera=null),this.requestUpdate())})):"view"===e&&this._commitViewModeAtomic(r,h,d,p),this._path=[],this._clearPlanSnapHover(),this._clearOpeningPlacement(!0),this._tool="draw",this._mergeSel=null,this._mergeDialog=null,this._splitSel=null,this._pendingSplit=null,this._selId=null,this._physicalSel=null,this._physicalDialog=null,this._physicalDrag=null,this._rszResetController(),this._tip=null,this._hoverRoom=null,this._decorDraft=null,this._decorSel=null,this._decorMove=null,this._backdropDialog=null,this._decorTool="select",this._bdDrag=null,this._dtDrag=null,this._dtBox=null,"plan"===e&&(this._primeDrawWallField(),this._resumeLastDraft()),this._saveNav()}_primeDrawWallField(){null===this._drawWallField&&(this._drawWallField=yl(ul,this._imperial))}get _drawWallFieldValue(){return null===this._drawWallField?yl(ul,this._imperial):this._drawWallField}get _drawWallCm(){const e=mv(this._drawWallFieldValue);if(null==e||e<0)return null;const t=this._imperial?2.54*e:e,i="column"===this._tool?Xc:100;return t>=("column"===this._tool?1:0)&&t<=i?t:null}get _drawWallMaxCm(){return"column"===this._tool?Xc:100}_showPhysicalRange(e=this._drawWallMaxCm,t=0){this._showToast(this._t("toast.physical_range",{min:yl(t,this._imperial),max:yl(e,this._imperial),unit:this._t(this._imperial?"wallthick.unit_in":"wallthick.unit_cm")}))}_draftSegmentCount(e=this._curSpaceCfg){return(e?.room_drafts||[]).reduce((e,t)=>e+(Array.isArray(t.segments)?t.segments.length:0),0)}_mergeSpacePartitions(e,t){const i=e?.partitions||[];if(i.length<2)return 0;const s=Tm(i,{pitch:Eh,seedIds:t,geometry:Rm(e,{excludeDraftId:this._activeDraftId})});return s.merged?(e.partitions=s.partitions,Im(e.openings,e.partitions,s.openingMoves,{coordScale:Pv,cellCm:this._cellCm,gridPitch:this._gridPitch}),s.merged):0}_finishWallChain(){if("draw"!==this._tool||this._wallFaceBatch||this._roomDialog)return!0;const e=this._curSpaceCfg;if(!e||this._path.length<2)return this._path=[],this._activeDraftId=null,this._draftSegmentCms=[],this._closingWallCm=null,this._clearPlanSnapHover(),!0;const t=xu(this._path,ku(this._path.length-1,this._draftSegmentCms,this._drawWallCm,ul)),i=t.length;if((e.partitions||[]).length+i>Av)return this._showToast(this._t("toast.physical_limit")),!1;const s=this._geometrySnapshot();e.partitions||=[];const n=Date.now().toString(36),o=[],a=this._activeDraftId?(e.room_drafts||[]).find(e=>e.id===this._activeDraftId):null,r=this._draftSegmentsForPath(this._path,a,t.map(e=>e.cm));for(let s=0;se.id!==this._activeDraftId),e.room_drafts.length||delete e.room_drafts),this._commitPhysicalGeometry(this._t("history.wall_chain_finish"),s),delete this._resumeDraftBySpace[this._space],this._path=[],this._activeDraftId=null,this._draftSegmentCms=[],this._closingWallCm=null,this._clearPlanSnapHover(),!0}_activateMarkupTool(e){e!==this._tool&&(this._wallFaceBatch&&this._roomDialogCancel(),("draw"!==this._tool||this._finishWallChain())&&(this._cancelPath(),"resize"===this._tool&&(this._resize.dragging?this._rszCancelDrag():this._resize.reset()),this._tool=e,"draw"===e&&this._resumeLastDraft(),"resize"===e&&this._resize.selectRoom(null),"wallthick"===e&&(this._wallDialog=null)))}_limitReached(e){const t=this._curSpaceCfg;if(!t)return!0;const i="draft"===e?(t.room_drafts||[]).length>=200:"partition"===e?(t.partitions||[]).length>=Av:(t.wall_columns||[]).length>=500;return i&&this._showToast(this._t("toast.physical_limit")),i}_svgPoint(e){const t=this.renderRoot.querySelector(".stage").getBoundingClientRect();return this._screenToVb(e.clientX-t.left,e.clientY-t.top)}_snap(e){const t=this._gridPitch;return[Lh(ri(e[0],t)),Lh(ri(e[1],t))]}_snapDrawPoint(e,t=!1){const i=this._path[this._path.length-1],s=t&&i?function(e,t,i,s=1/0){if(!(i>0&&e?.every(Number.isFinite)&&t?.every(Number.isFinite)))return[t[0],t[1]];const n=t[0]-e[0],o=t[1]-e[1];if(Math.abs(n)+Math.abs(o)<=1e-12)return[e[0],e[1]];const a=Math.PI/4;let r=Math.atan2(o,n);r<0&&(r+=2*Math.PI);const l=Math.floor(r/a+.5)%8,[c,h]=[[1,0],[1,1],[0,1],[-1,1],[-1,0],[-1,-1],[0,-1],[1,-1]][l],d=c*c+h*h;let p=Math.max(0,Math.round((n*c+o*h)/(i*d)));if(Number.isFinite(s)&&s>=0){const t=(e,t)=>{if(!t)return 1/0;const n=t>0?s-e:e+s;return Math.max(0,Math.floor((n+1e-9*i)/i))};p=Math.min(p,t(e[0],c),t(e[1],h))}return[e[0]+c*p*i,e[1]+h*p*i]}(i,e,this._gridPitch,zh):e;return this._snap(s)}_planSnapOpeningCuts(e,t){if(!this._openingsR.length)return[];const i=this._openingWallIndexFor(e,t).value,s=[];for(const t of this._roomWallOpeningInputs(this._openingsR,e)){const e=Gc(i,t);if(!e.negative&&!e.positive)continue;const n=t.angle*Math.PI/180,o=Math.cos(n)*t.length/2,a=Math.sin(n)*t.length/2;s.push([t.x-o,t.y-a,t.x+o,t.y+a])}return s}_planSnapGeometrySnapshot(){const e=this._spaceModel();if(!e)return{key:`${this._space}|empty`,value:{segments:[],endpoints:[]}};const t=[this._space,this._cfgEpoch,this._activeDraftId||"",e.rooms.length,e.room_drafts.length,e.partitions.length].join("|");if(this._planSnapGeometryCache?.key===t)return this._planSnapGeometryCache;const i=this._openCuts(),s=_u({space:e,activeDraftId:this._activeDraftId,roomCuts:this._planSnapOpeningCuts(e,i),partitionCuts:this._partitionOpeningCuts(e),epsilon:2e-4*this._gridPitch});return this._planSnapGeometryCache={key:t,value:s},this._planSnapGeometryCache}_hiddenWallDiagnosticSnapshot(){const e=this._spaceModel();if(!e)return{key:`${this._space}|hidden-empty`,value:{segments:[],endpoints:[]}};const t=["hidden",this._space,this._cfgEpoch,this._activeDraftId||"",e.rooms.length,e.room_drafts.length,e.partitions.length].join("|");if(this._hiddenWallDiagnosticCache?.key===t)return this._hiddenWallDiagnosticCache;const i=uu({space:e,activeDraftId:this._activeDraftId,epsilon:2e-4*this._gridPitch});return this._hiddenWallDiagnosticCache={key:t,value:i},this._hiddenWallDiagnosticCache}_planStructuralGeometrySnapshot(){const e=this._spaceModel();if(!e)return{key:`${this._space}|structural-empty`,value:{segments:[],endpoints:[]}};const t=["structural",this._space,this._cfgEpoch,this._activeDraftId||"",e.rooms.length,e.room_drafts.length,e.partitions.length].join("|");if(this._planStructuralGeometryCache?.key===t)return this._planStructuralGeometryCache;const i=_u({space:e,activeDraftId:this._activeDraftId,epsilon:2e-4*this._gridPitch});return this._planStructuralGeometryCache={key:t,value:i},this._planStructuralGeometryCache}_planSnapContextKey(e){const t=this._path[0],i=this._path[this._path.length-1];return[e,this._tool,this._path.length,t?`${t[0]},${t[1]}`:"",i?`${i[0]},${i[1]}`:""].join("|")}_resolvePlanDrawPoint(e,t){const i=this._planSnapGeometrySnapshot(),s=this._path[this._path.length-1],n="draw"===this._tool&&this._path.length>=3?[{point:this._path[0],key:"closure:first-point"}]:[],o={tolerance:this._cssPxToRender(12),distinguishTolerance:this._cssPxToRender(8),gridStep:this._gridPitch,excludePoints:s?[s]:[],extraEndpoints:n,epsilon:2e-4*this._gridPitch},a=t&&s?yu(i.value,e,{...o,anchor:s}):function(e,t,i){if(!(ou(t)&&i.tolerance>=0))return{kind:"none",candidate:null,conflicts:[]};const s=i.epsilon??nu,n=i.excludePoints||[],o=vu(fu(e,t,i),i.distinguishTolerance||0);if(o)return o;let a=null;for(const o of e.segments){const e=[o.a[0],o.a[1],o.b[0],o.b[1]],r=Hs([t[0],t[1]],e);if(r>i.tolerance)continue;const l=bu(o,t,i.gridStep);!mu(l,n,s)&&gu(r,o.key,a)&&(a={kind:"line",point:l,key:o.key,distance:r,segment:o})}return a?{kind:"resolved",candidate:a,conflicts:[]}:{kind:"none",candidate:null,conflicts:[]}}(i.value,e,o),r="resolved"===a.kind?a.candidate:null,l=r?[...r.point]:this._snapDrawPoint(e,t),c=s?ua(s,l):l;return{point:c,candidate:r&&fi(c,r.point)?r:null,conflicts:"ambiguous"===a.kind?a.conflicts:[],ambiguous:"ambiguous"===a.kind,contextKey:this._planSnapContextKey(i.key)}}get _activePlanSnapCandidate(){if(!this._markup||"draw"!==this._tool)return null;const e=this._planSnapHover;if(!e)return null;const t=this._planSnapGeometrySnapshot();return e.contextKey===this._planSnapContextKey(t.key)?e.candidate:null}get _activePlanSnapConflicts(){if(!this._markup||"draw"!==this._tool)return[];const e=this._planSnapHover;if(!e)return[];const t=this._planSnapGeometrySnapshot();return e.contextKey===this._planSnapContextKey(t.key)?e.conflicts:[]}_clearPlanSnapHover(e=!0){this._planSnapHover=null,this._syncPlanSnapActiveMarker(null),this._syncPlanSnapConflictMarkers([]),e&&(this._cursorPt=null)}_samePt(e,t){return fi(e,t)}_dropLegacySegments(){for(const e of this._serverCfg?.markers||[])"ripple"===e.display&&(e.display="icon_ripple");for(const e of this._serverCfg?.spaces||[]){delete e.segments;const t=new Set,i=e=>"string"==typeof e&&e.length>=1&&e.length<=64&&!t.has(e),s=e=>(t.add(e),!0),n=e=>Array.isArray(e)&&2===e.length&&e.every(e=>Number.isFinite(Number(e))&&Math.abs(Number(e))<=Ah);if(Array.isArray(e.partitions)&&(e.partitions=e.partitions.filter(e=>e&&i(e.id)&&n(e.a)&&n(e.b)&&Math.hypot(e.a[0]-e.b[0],e.a[1]-e.b[1])>1e-9&&s(e.id)).map(e=>({...e,cm:Number.isFinite(Number(e.cm))?Math.max(0,Math.min(100,Number(e.cm))):15})),e.partitions.length||delete e.partitions),Array.isArray(e.wall_columns)&&(e.wall_columns=e.wall_columns.filter(e=>e&&i(e.id)&&n(e.center)&&s(e.id)).map(e=>({id:e.id,shape:"circle"===e.shape?"circle":"square",center:[Number(e.center[0]),Number(e.center[1])],cm:Qc(Number(e.cm)||15),..."circle"===e.shape?{}:{angle:eh(e.angle)}})),e.wall_columns.length||delete e.wall_columns),Array.isArray(e.room_drafts)&&(e.room_drafts=e.room_drafts.filter(e=>e&&i(e.id)&&Array.isArray(e.points)&&e.points.length>=2&&e.points.every(n)&&s(e.id)).map(e=>{const t=rg(e);return{id:e.id,...t}}).filter(e=>e.points.length>=2),e.room_drafts.length||delete e.room_drafts),Array.isArray(e.walls)){const t=Ud(Rh({spaces:[e]}),e.id),i=t?j_(e,t,Pv,.02*Nh).contour.map(e=>e.map(e=>e/Pv)):Ad(e.open_spans).map(e=>[e.a[0],e.a[1],e.b[0],e.b[1]]);e.walls=Fl(e.walls,e.rooms||[],Eh,1,i),e.walls.length||delete e.walls}}}_rollbackRejectedPhysicalWrites(e){if(!this._serverCfg||!e.length)return!1;let t=!1;for(const[i]of e){const e=this._pendingPhysicalWrites.get(i);e&&(t=this._restoreGeometryStateInConfig(this._serverCfg,e.before)||t,this._pendingPhysicalWrites.delete(i))}return!!t&&(this._clearGeometryGesture(),this._geometryHistory.clear(),this._cfgEpoch++,this._modelCache=null,this._wallUnionCache=null,this._physicalBodiesCache=null,this._frame=null,this._regSignature="",this._cfgContentFingerprint=Bd(this._serverCfg),this._maybeRebuildDevices(),this.requestUpdate(),!0)}async _reloadRejectedPhysicalWrite(){const e=this._writeChain;await e.catch(()=>{}),await this._reloadConfigOnly(!0)}get _cfgWriting(){return this._writesPending>0}_writeConfig(){var e,t;this._writesPending++,this._writeChain=(e=this._writeChain,t=async()=>{if(!this._serverCfg)return;this._dropLegacySegments();const e=pl(Xr(this._serverCfg)),t=Bd(e),i=[...this._pendingPhysicalWrites.entries()];for(const[t,s]of i){const i=Ng(e.spaces.find(e=>e.id===t));if(i===s.fingerprint)continue;let n=!1;try{n=this._checkSpacePhysicalGeometry(e,t).ok}catch{n=!1}if(!n)throw this._restoreGeometryStateLocal(s.before),this._pendingPhysicalWrites.delete(t),this._geometryHistory.clear(),this._showToast(this._t("toast.geometry_unsafe")),Object.assign(new Error("unsafe wall geometry"),{code:"geometry-unsafe"});s.fingerprint=i}let s;t!==Bd(this._serverCfg)&&(this._serverCfg=e),this._cfgContentFingerprint=t;try{s=await this.hass.callWS({type:"houseplan/config/set",config:e,expected_rev:this._cfgRev})}catch(e){if(!this._rollbackRejectedPhysicalWrites(i))throw e;const t=e&&"object"==typeof e?e:Object.assign(new Error(String(e)),{cause:e});throw t.physicalGeometryRolledBack=!0,t}this._cfgRev=s?.rev??this._cfgRev+1;for(const[e,t]of i)this._pendingPhysicalWrites.get(e)?.fingerprint===t.fingerprint&&this._pendingPhysicalWrites.delete(e)},e.catch(()=>{}).then(t));return this._writeChain.finally(()=>{this._writesPending--})}_saveConfig(){this._cfgEpoch++,this._saveConfigDebounced()}_geometrySnapshotFromConfig(e,t){const i=e?.spaces?.find(e=>e.id===t);if(!i)return null;const s=e=>JSON.parse(JSON.stringify(e)),n={};for(const e of["plan_x","plan_y","plan_scale","plan_scale_x","plan_scale_y","plan_angle"])void 0!==i[e]&&(n[e]=i[e]);return{spaceId:t,rooms:s(i.rooms||[]),...Array.isArray(i.openings)?{openings:s(i.openings)}:{},...Array.isArray(i.walls)?{walls:s(i.walls)}:{},...Array.isArray(i.wall_segments)?{wall_segments:s(i.wall_segments)}:{},...Array.isArray(i.open_spans)?{open_spans:s(i.open_spans)}:{},...Array.isArray(i.room_drafts)?{room_drafts:s(i.room_drafts)}:{},...Array.isArray(i.partitions)?{partitions:s(i.partitions)}:{},...Array.isArray(i.wall_columns)?{wall_columns:s(i.wall_columns)}:{},...Array.isArray(i.decor)?{decor:s(i.decor)}:{},plan_transform:n}}_geometrySnapshot(e=this._space){return this._geometrySnapshotFromConfig(this._serverCfg,e)}_recordGeometry(e,t){if(!t)return;const i=this._geometrySnapshot(t.spaceId);i&&JSON.stringify(t)!==JSON.stringify(i)&&(this._geometryHistory.push({name:e,before:t,after:i}),this.requestUpdate())}_restoreGeometryStateInConfig(e,t,i=!1){const s=e?.spaces?.find(e=>e.id===t.spaceId);if(!s)return!1;const n=e=>JSON.parse(JSON.stringify(e)),o=new Map((s.rooms||[]).map(e=>[e.id,e]));if(s.rooms=n(t.rooms),i)for(const e of s.rooms){const t=o.get(e.id);!Array.isArray(e.wall_ids)&&Array.isArray(t?.wall_ids)&&t.wall_ids.length===e.poly?.length&&(e.wall_ids=n(t.wall_ids))}const a=(e,t)=>{void 0!==t?s[e]=n(t):i&&"wall_segments"===e||delete s[e]},r=new Map((s.openings||[]).map(e=>[e.id,e])),l=new Map((s.room_drafts||[]).map(e=>[e.id,e]));if(a("openings",t.openings),a("walls",t.walls),a("wall_segments",t.wall_segments),a("open_spans",t.open_spans),a("room_drafts",t.room_drafts),a("partitions",t.partitions),a("wall_columns",t.wall_columns),a("decor",t.decor),i){for(const e of s.openings||[]){const t=r.get(e.id);e.host||"wall"!==t?.host?.kind||(e.host=n(t.host))}for(const e of s.room_drafts||[]){const t=l.get(e.id);for(let i=0;i<(e.segments||[]).length;i++)!e.segments[i]?.id&&t?.segments?.[i]?.id&&(e.segments[i].id=t.segments[i].id)}}for(const e of["plan_x","plan_y","plan_scale","plan_scale_x","plan_scale_y","plan_angle"])delete s[e];return Object.assign(s,n(t.plan_transform||{})),!0}_restoreGeometryStateLocal(e){return!!this._restoreGeometryStateInConfig(this._serverCfg,e)&&(this._cfgEpoch++,this._modelCache=null,this._wallUnionCache=null,this._physicalBodiesCache=null,this._frame=null,this.requestUpdate(),!0)}_wallModelBlockerLabel(e){const t=e instanceof Qm?e.reason:"invalid-room";return this._t(`wall_model.reason.${t}`)}_hasLegacyZeroWallFields(e=this._serverCfg){return(e?.spaces||[]).some(e=>Array.isArray(e?.open_spans)&&e.open_spans.length>0||(e?.rooms||[]).some(e=>Array.isArray(e?.open_to)&&e.open_to.length>0))}_showWallModelMigrationBlocked(e){const t=this._hasLegacyZeroWallFields()?"toast.zero_wall_migration_blocked":"toast.wall_model_migration_blocked";this._showToast(this._t(t,{reason:this._wallModelBlockerLabel(e)}))}_limitSegmentsOf(e){const t=[];for(const i of e?.wall_segments||[])i?.a&&i?.b&&t.push({id:String(i.id||""),a:i.a,b:i.b,cm:Number(i.cm)});for(const i of e?.partitions||[])i?.a&&i?.b&&t.push({id:String(i.id||""),a:i.a,b:i.b,cm:Number(i.cm)});for(const i of e?.room_drafts||[]){const e=Array.isArray(i?.points)?i.points:[],s=Array.isArray(i?.segments)?i.segments:[];for(let n=0;n+1e?.id===t);if(!i)return[];const s=Number(i.cell_cm)>0?Number(i.cell_cm):5,n=this._limitSegmentsOf(i),o=[...xd(n),...Md(n,s,Eh),...Dd(n,s,Eh)];for(const e of i.rooms||[]){const t=String(e?.id||"");if(!t)continue;let n=null;try{n=kc(i.rooms||[],t,i.walls||[],[],Eh,s,Eh,1)}catch{n=null}o.push(...Pd(t,n,s,Eh))}return o}_junctionLimitLabel(e){const t=e=>String(Math.round(10*e)/10);return this._t(`junction.limit_${e.rule}`,{actual:t(e.actual),limit:t(e.limit)})}_junctionLimitsIntroduced(e,t,i){let s=[];try{const e=$g(t).config;s=this._junctionLimitViolations(e,i)}catch{return[]}let n=[];try{n=this._junctionLimitViolations(e,i)}catch{return[]}return function(e,t){const i=new Map;for(const e of t||[])i.set(e.rule,(i.get(e.rule)||0)+1);const s=new Map;for(const t of e||[])s.set(t.rule,[...s.get(t.rule)||[],t]);const n=[];for(const[e,t]of s){const s=t.length-(i.get(e)||0);s>0&&n.push(...t.slice(0,s))}return n}(n,s)}_commitPhysicalGeometry(e,t,i=[]){if(!t||!this._serverCfg)return!1;const s=this._serverCfg,n=this._geometrySnapshotFromConfig(s,t.spaceId),o=s.spaces.find(e=>e.id===t.spaceId);if(!o||Ng(t)===Ng(o))return!1;let a,r=!1;try{r=this._checkSpacePhysicalGeometry(s,t.spaceId).ok}catch{r=!1}if(!r)return this._clearGeometryGesture(),this._restoreGeometryStateLocal(t),this._showToast(this._t("toast.geometry_unsafe")),!1;let l=t;try{if(Number(s.model_version||0)<9){const e=JSON.parse(JSON.stringify(s));if(!this._restoreGeometryStateInConfig(e,t))throw new Qm("invalid-room",t.spaceId);const i=$g(e).config;l=this._geometrySnapshotFromConfig(i,t.spaceId)||t;const o=JSON.parse(JSON.stringify(i));if(!n||!this._restoreGeometryStateInConfig(o,n,!0))throw new Qm("invalid-room",t.spaceId);const r=i.spaces.find(e=>e.id===t.spaceId),c=o.spaces.find(e=>e.id===t.spaceId);if(!Array.isArray(n.wall_segments)&&JSON.stringify(t.rooms)===JSON.stringify(n.rooms))for(const e of c?.wall_segments||[])e.cm=zl(n.walls,e.a,e.b,Eh,1);const h=((e,t,i)=>{const s=new Map,n=new Map((e?.rooms||[]).map(e=>[e.id,e])),o=new Map((t||[]).map(e=>[e.id,e])),{rooms:a}=bg(i,fg(e));for(const e of a){const t=o.get(e.id),a=n.get(e.id),r=hi(t),l=hi((i.rooms||[]).find(t=>t.id===e.id)),c=hi(a);if(r&&l&&c&&r.length===l.length&&c.length===a?.wall_ids?.length&&e.poly.length===e.wall_ids.length)for(let t=0;t{const n=[];for(let o=0;oZm||hg(r,i,s)>Zm)continue;const l=cg(a,i,s),c=cg(r,i,s);l<-Zm||c>1+Zm||c<=l+Zm||n.push({start:l,id:t[o]})}return n.sort((e,t)=>e.start-t.start)},n=i(c,a.wall_ids,r[t],r[(t+1)%r.length]),o=i(e.poly,e.wall_ids,l[t],l[(t+1)%l.length]);if(n.length&&n.length===o.length)for(let e=0;ee.id===t.spaceId),s=this._path.length>=2?this._path.map(e=>[e[0]/Pv,e[1]/Pv]):[];s.push(...i.map(e=>[e[0],e[1]])),c=lg(e)<=lg(l,s)&&this._checkSpacePhysicalGeometry(a,t.spaceId).ok}catch{c=!1}if(!c)return this._clearGeometryGesture(),this._restoreGeometryStateLocal(t),this._showToast(this._t("toast.geometry_unsafe")),!1;const h=JSON.parse(JSON.stringify(s));this._restoreGeometryStateInConfig(h,t);const d=this._junctionLimitsIntroduced(a,h,t.spaceId);if(d.length)return this._clearGeometryGesture(),this._restoreGeometryStateLocal(t),this._showToast(this._junctionLimitLabel(d[0])),!1;Mg(s,a),this._recordGeometry(e,l);const p=s.spaces.find(e=>e.id===t.spaceId),u=this._pendingPhysicalWrites.get(t.spaceId);return this._pendingPhysicalWrites.set(t.spaceId,{before:u?.before||l,fingerprint:Ng(p)}),this._saveConfig(),!0}_clearGeometryGesture(){this._path=[],this._clearPlanSnapHover(),this._clearOpeningPlacement(!1),this._mergeSel=null,this._mergeDialog=null,this._splitSel=null,this._pendingSplit=null,this._wallFaceBatch=null,this._wallRepairDiagnostic=null,this._roomDeleteDialog=null,this._wallDialog=null,this._physicalDialog=null,this._physicalSel=null,this._physicalDrag=null,this._physicalRotate=null,this._activeDraftId=null,this._draftSegmentCms=[],this._closingWallCm=null,this._openingDialog=null,this._rszResetController(),this._decorDraft=null,this._decorMove=null,this._dtDrag=null,this._bdDrag=null}_stagePointerCancel(e){if(clearTimeout(this._kioskHoldTimer),this._swipeStart?.id===e.pointerId&&(this._swipeStart=null),this._physicalDrag?.pid===e.pointerId||this._physicalRotate?.pid===e.pointerId)return void this._cancelPhysicalGesture();if(this._decorDraft?.pid===e.pointerId)return this._decorDraft=null,void this.requestUpdate();if(this._decorMove?.pid===e.pointerId||this._dtDrag?.pid===e.pointerId||this._bdDrag?.pid===e.pointerId)return void this._cancelDecorGesture();"opening"===this._tool?(this._cursorPt=null,this._clearOpeningPlacement(!1)):"draw"===this._tool&&this._clearPlanSnapHover();const t=!!this._pinchStart||!!this._panStart;this._pointers.delete(e.pointerId),this._pointers.size<2&&(this._pinchStart=null),0===this._pointers.size&&(this._panStart=null,this._panLock=null),t&&0===this._pointers.size&&this.requestUpdate()}_applyGeometryState(e,t=!1){if(!this._canCommitSpace(e.spaceId))return!1;const i=this._geometrySnapshot(e.spaceId);if(!i||!this._restoreGeometryStateLocal(e))return!1;const s=this._serverCfg,n=Ng(i)!==Ng(e);if(n){let n=!1;try{const i=s?this._checkSpacePhysicalGeometry(s,e.spaceId):null;n=!!i?.ok||!(!t||"wall-degraded-extra"!==i?.reason)}catch{n=!1}if(!n)return this._restoreGeometryStateLocal(i),this._showToast(this._t("toast.geometry_unsafe")),!1}let o;try{o=$g(s).config}catch(e){return this._restoreGeometryStateLocal(i),this._showWallModelMigrationBlocked(e),!1}if(n){let n=!1;try{const i=o?this._checkSpacePhysicalGeometry(o,e.spaceId):null;n=!!i?.ok||!(!t||"wall-degraded-extra"!==i?.reason)}catch{n=!1}if(!n)return this._restoreGeometryStateLocal(i),this._showToast(this._t("toast.geometry_unsafe")),!1;Mg(s,o);const a=s?.spaces.find(t=>t.id===e.spaceId),r=this._pendingPhysicalWrites.get(e.spaceId);this._pendingPhysicalWrites.set(e.spaceId,{before:r?.before||i,fingerprint:Ng(a)})}else Mg(s,o);return this._clearGeometryGesture(),this._space!==e.spaceId&&(this._commitSpace(e.spaceId),this._saveNav(),this._restoreZoom()),this._modelCache=null,this._frame=null,this._regSignature="",this._maybeRebuildDevices(),this._saveConfig(),this.requestUpdate(),!0}_roomAt(e){return this._spaceModel()?.rooms.find(t=>{const i=hi(t);return!!i&&wi(e,i)})}_overlapRoom(e){return this._spaceModel()?.rooms.find(t=>{const i=hi(t);return!!i&&Di(e,i)})}_pointInRoom(e,t){return t.poly?vi(e,t.poly):null!=t.x&&e[0]>=t.x&&e[0]<=t.x+t.w&&e[1]>=t.y&&e[1]<=t.y+t.h}_contourSelfIntersects(e){if(!Ra(e))return!0;const t=e.length,i=.001;for(let s=0;s=500)return this._showToast(this._t("toast.physical_limit")),!1;const e=this._curSpaceCfg;return!(!this._activeDraftId&&(e?.room_drafts||[]).length>=200||this._draftSegmentCount(e)>=2e3||(e?.partitions||[]).length+this._path.length>Av)||(this._showToast(this._t("toast.physical_limit")),!1)}_markupClick(e){if(this._vacFit)return;if(!this._markup)return;const t=this._spaceModel();if(!t)return void this._clearGeometryGesture();if(this._suppressClick)return;if(this._drag||this._rlResize)return;const i=e.composedPath?.()||[];if(i.some(e=>e?.classList?.contains?.("roomlabel")||e?.classList?.contains?.("rlhandle")))return;if(i.some(e=>e?.classList?.contains?.("physical-hit")))return;const s=this._svgPoint(e);if("select"===this._tool)return void(this._physicalSel=null);if("resize"===this._tool){if(this._resize.dragging||i.some(e=>e?.classList?.contains?.("rszhandle")))return;const e=[...t.rooms].reverse().find(e=>this._pointInRoom(s,e));return this._resize.selectRoom(e?.id||null),void this.requestUpdate()}if("delroom"===this._tool)return void this._deleteRoomClick(s);if("opening"===this._tool)return void this._openingClick(s);if("merge"===this._tool)return void this._mergeClick(s);if("wallthick"===this._tool)return void this._wallThickClick(s);if("split"===this._tool)return void this._splitClick(s);if("column"===this._tool)return void this._columnClick(s);this._wallRepairDiagnostic=null;const n=this._resolvePlanDrawPoint(s,e.shiftKey);if(n.ambiguous)return this._planSnapHover={contextKey:n.contextKey,candidate:null,conflicts:n.conflicts},this._syncPlanSnapActiveMarker(null),this._syncPlanSnapConflictMarkers(n.conflicts),void this._showToast(this._t("toast.plan_snap_ambiguous"));let o=n.point;if(e.ctrlKey||e.metaKey){if(e.preventDefault(),this._path.length<3)return;o=ua(this._path[this._path.length-1],this._path[0])}if(!this._path.length){if(!e.shiftKey&&!n.candidate&&this._offerExistingWallFace(s))return;const t=this._draftEndAt(o);return t?(this._activeDraftId=t.draft.id,this._resumeDraftBySpace[this._space]=t.draft.id,this._path=t.reverse?[...t.draft.points].reverse().map(e=>[...e]):t.draft.points.map(e=>[...e]),void(this._draftSegmentCms=this._adoptDraftCms(this._path,t.reverse?[...t.draft.segments].reverse().map(e=>e.cm):t.draft.segments.map(e=>e.cm),t.draft.id))):(this._activeDraftId=null,this._draftSegmentCms=[],void(this._path=[o]))}const a=this._path[this._path.length-1];if(this._samePt(o,a))return;const r=this._draftEndAt(o,this._activeDraftId||void 0);if(r)return void this._mergeDraftEndpoint(r);if(!this._canAppendRoomDraftPoint())return;const l=this._drawWallCm;if(null==l)return void this._showPhysicalRange(100);const c=this._path.map(e=>[...e]);this._path=[...this._path,o],this._draftSegmentCms=[...this._draftSegmentCms,l],this._persistActiveDraftSegment(),this._offerWallFaces(c)}_draftEndAt(e,t){const i=this._spaceModel();if(!i)return null;const s=this._viewOr(this._baseVb()),n=Math.max(.15*this._gridPitch,this._stageEl?.clientWidth?s.w/this._stageEl.clientWidth*12:0);for(const s of i.room_drafts||[]){if(s.id===t)continue;if(s.points.length<2)continue;const i=s.points[0],o=s.points[s.points.length-1];if(Math.hypot(e[0]-o[0],e[1]-o[1])<=n)return{draft:s,reverse:!1};if(Math.hypot(e[0]-i[0],e[1]-i[1])<=n)return{draft:s,reverse:!0}}return null}_mergeDraftEndpoint(e){const t=this._curSpaceCfg;if(!t||!this._path.length)return;const i=this._path.map(e=>[...e]),s=this._wallGraphSources(i),n=Array.isArray(t.room_drafts)?t.room_drafts:[],o=this._activeDraftId?n.find(e=>e.id===this._activeDraftId):null,a=n.find(t=>t.id===e.draft.id);if(!a)return;const r=e.reverse?e.draft.points.map(e=>[...e]):[...e.draft.points].reverse().map(e=>[...e]),l=e.reverse?(a.segments||[]).map(e=>({...e})):[...a.segments||[]].reverse().map(e=>({...e})),c=this._path[this._path.length-1],h=this._samePt(c,r[0]),d=h?null:this._drawWallCm;if(!h&&null==d)return void this._showPhysicalRange(100);const p=this._draftSegmentsForPath(this._path,o,this._draftSegmentCms),u=[...this._path.map(e=>[...e]),...h?r.slice(1):r],_=[...p,...null==d?[]:[{cm:d}],...l],m=u.length>=4&&this._samePt(u[0],u[u.length-1]),g=u,f=_;if(g.length>500)return void this._showToast(this._t("toast.physical_limit"));const v=(o?.segments?.length||0)+(a.segments?.length||0);if(this._draftSegmentCount(t)-v+f.length>2e3)return void this._showToast(this._t("toast.physical_limit"));if(m){const e=g.slice(0,-1);if(this._contourSelfIntersects(e)||Ti(e)<=1e-6)return void this._showToast(this._t("toast.contour_cannot_close"));const t=this._overlapRoom(e);if(t)return void this._showToast(this._t("toast.room_overlap",{name:t.name||""}))}const b=this._geometrySnapshot(),y=this._activeDraftId||e.draft.id,w={...o||a,id:y,points:g.map(e=>[e[0]/Pv,e[1]/Pv]),segments:f};t.room_drafts=n.filter(t=>t.id!==e.draft.id&&(!this._activeDraftId||t.id!==this._activeDraftId)),t.room_drafts.push(w),this._activeDraftId=y,this._resumeDraftBySpace[this._space]=y,this._path=g,this._draftSegmentCms=this._adoptDraftCms(g,f.map(e=>Number(e.cm)),y),this._physicalSel=null,this._commitPhysicalGeometry(this._t("history.draft_merge"),b),null!=d&&this._offerWallFaces(i,i.length-1,s)}_adoptDraftCms(e,t,i){const s=Math.max(0,e.length-1),n=ku(s,t,this._drawWallCm,ul);return t.length!==s&&console.debug(`[houseplan] draft ${i??"?"}: восстановлено толщин ${s-t.length} (#234)`),n}_draftSegmentsForPath(e,t,i){const s=Array.isArray(t?.points)?t.points.map(e=>[Number(e?.[0])*Pv,Number(e?.[1])*Pv]):[],n=Array.isArray(t?.segments)?t.segments:[];return ku(Math.max(0,e.length-1),i,this._drawWallCm,ul).map((t,i)=>{const o=e[i],a=e[i+1],r=s.findIndex((e,t)=>{if(t+1>=s.length)return!1;const i=s[t+1];return this._samePt(o,e)&&this._samePt(a,i)||this._samePt(o,i)&&this._samePt(a,e)});return{...r>=0?n[r]:{},cm:t}})}_persistActiveDraftSegment(){if(this._path.length<2||!this._curSpaceCfg)return;const e=this._geometrySnapshot(),t=this._curSpaceCfg;t.room_drafts||=[],this._activeDraftId||(this._activeDraftId="draft-"+Date.now().toString(36)),this._resumeDraftBySpace[this._space]=this._activeDraftId;const i=t.room_drafts.findIndex(e=>e.id===this._activeDraftId),s={...i>=0?t.room_drafts[i]:{},id:this._activeDraftId,points:this._path.map(e=>[e[0]/Pv,e[1]/Pv]),segments:this._draftSegmentsForPath(this._path,i>=0?t.room_drafts[i]:null,this._draftSegmentCms)};i>=0?t.room_drafts[i]=s:t.room_drafts.push(s),this._commitPhysicalGeometry(this._t("history.draft_segment"),e)}_activeWallSourceKey(e){return`active:${this._activeDraftId||"session"}:${e}`}_wallGraphSources(e){const t=this._planStructuralGeometrySnapshot().value.segments.map(e=>({a:e.a,b:e.b,key:`static:${e.key}`}));for(let i=0;i+1e.key===i);if(s>=0){const[e]=this._wallFaceGraphCache.splice(s,1);return this._wallFaceGraphCache.push(e),e.value}const n=Uu(e,t);return this._wallFaceGraphCache.push({key:i,value:n}),this._wallFaceGraphCache.length>4&&this._wallFaceGraphCache.shift(),n}_offerWallFaces(e,t=this._path.length-2,i){if(this._path.length<2||this._wallFaceBatch||this._roomDialog)return;const s=this._spaceModel();if(!s)return;const n=this._activeWallSourceKey(t),o=2e-4*this._gridPitch;let a,r;try{const t=i||this._wallGraphSources(e);r=this._wallGraphSources(this._path),a=function(e,t,i){const s=new Set(e.faces.map(e=>e.key));return t.faces.filter(e=>!s.has(e.key)&&e.sourceKeys.includes(i))}(this._wallFaceGraph(t,o),this._wallFaceGraph(r,o),n)}catch{return}if(!a.length){const e=s_(r,{requiredSourceKey:n,maxDistance:wl(2,this._cellCm,this._gridPitch),gridStep:this._gridPitch,epsilon:o});return"ambiguous"===e.kind?(this._wallRepairDiagnostic=e.proposals[0]||null,void this._showToast(this._t(0===this._drawWallCm?"toast.zero_wall_ambiguous":"toast.wall_repair_ambiguous"))):void("repair"!==e.kind||this._overlapRoom(e.face.ring)||this._beginWallFaceBatch([{...e.face,repair:e.proposal}]))}for(const e of s.rooms){const t=hi(e);if(!e.id||!t)continue;const i=zi(t,this._path,.02*this._gridPitch);if(!i)continue;const[s,n]=i,o=Ti(s)>=Ti(n)?s:n,r=o===s?n:s,l=[...a].sort((e,t)=>Math.abs(e.area-Ti(r))-Math.abs(t.area-Ti(r))||e.key.localeCompare(t.key))[0];if(!l)return;return void this._beginWallFaceBatch([{...l,ring:r.map(e=>[e[0],e[1]]),split:{roomId:e.id,mainPoly:o,newPoly:r},consumeAllActive:!0}])}const l=a.filter(e=>!(e.ring.length<3||this._contourSelfIntersects(e.ring))&&!this._overlapRoom(e.ring));l.length&&this._beginWallFaceBatch(l)}_beginWallFaceBatch(e){this._wallRepairDiagnostic=null,this._wallFaceBatch={candidates:[...e].sort((e,t)=>e.area-t.area||e.key.localeCompare(t.key)),index:0,decisions:[],activePath:this._path.map(e=>[...e]),activeCms:[...this._draftSegmentCms],activeDraftId:this._activeDraftId},this._clearPlanSnapHover(),this._nameSel="",this._areaSel="",this._resetRoomDialogFields(),this._roomDialog=!0}_offerExistingWallFace(e){if(this._path.length||this._wallFaceBatch||this._roomDialog)return!1;const t=2e-4*this._gridPitch;try{let i,s=Gu(this._wallFaceGraph(this._wallGraphSources([]),t),e,t);if(!s){const n=s_(this._wallGraphSources([]),{point:e,maxDistance:wl(2,this._cellCm,this._gridPitch),gridStep:this._gridPitch,epsilon:t});if("ambiguous"===n.kind)return this._wallRepairDiagnostic=n.proposals[0]||null,this._showToast(this._t(0===this._drawWallCm?"toast.zero_wall_ambiguous":"toast.wall_repair_ambiguous")),!0;if("repair"===n.kind)s=n.face,i=n.proposal;else if("none"===n.kind){const i=s_(this._wallGraphSources([]),{point:e,maxDistance:this._cssPxToRender(12),gridStep:this._gridPitch,epsilon:t});if("repair"===i.kind)return this._wallRepairDiagnostic=i.proposal,this._showToast(this._t("toast.wall_repair_too_large")),!0}}return!(!s||s.ring.length<3||this._contourSelfIntersects(s.ring)||this._overlapRoom(s.ring))&&(this._beginWallFaceBatch([{...s,existing:!i,repair:i}]),!0)}catch{return!1}}_columnClick(e){const t=this._snap(e),i=this._drawWallCm;if(null==i)return void this._showPhysicalRange(Xc,1);if(!this._curSpaceCfg||this._limitReached("column"))return;const s=this._spaceModel();if(!s)return;const n={id:"column-"+Date.now().toString(36),shape:"square",center:t,cm:Qc(i),angle:0},o=(s.wall_columns||[]).find(e=>yh(e,n,.02*this._gridPitch));if(o)return clearTimeout(this._duplicateColumnTimer),this._duplicateColumnId=o.id,this._duplicateColumnTimer=window.setTimeout(()=>{this._duplicateColumnId=null},900),void this._showToast(this._t("toast.column_duplicate"));const a=this._geometrySnapshot(),r=this._curSpaceCfg;r.wall_columns||=[],r.wall_columns.push({...n,center:[t[0]/Pv,t[1]/Pv]}),this._commitPhysicalGeometry(this._t("history.column_add"),a)}_openPhysicalDialog(e,t,i){const s=this._spaceModel();if(s)if("partition"===e){const i=s.partitions.find(e=>e.id===t);i&&(this._physicalDialog={kind:e,id:t,cm:yl(i.cm,this._imperial),length:this._fmtLen(i.a,i.b)})}else if("column"===e){const i=s.wall_columns.find(e=>e.id===t);i&&(this._physicalDialog={kind:e,id:t,cm:yl(i.cm,this._imperial),shape:i.shape,angle:this._angleField("square"===i.shape?eh(i.angle):0)})}else{const n=s.room_drafts.find(e=>e.id===t),o=Math.max(0,Math.min(n?.segments.length?n.segments.length-1:0,i||0));n?.segments[o]&&(this._physicalDialog={kind:e,id:t,segment:o,cm:yl(n.segments[o].cm,this._imperial),length:this._fmtLen(n.points[o],n.points[o+1])})}}_physicalDown(e,t,i){const s=this._spaceModel();if(!s)return;e.stopPropagation(),Ev(e);const n=this._svgPoint(e),o=[];for(const e of[...s.wall_columns].reverse())vh(n,ah(e,this._cellCm,this._gridPitch))&&o.push({kind:"column",id:e.id});for(const e of[...s.partitions].reverse()){const t=oh(e.a,e.b,e.cm,this._cellCm,this._gridPitch);t&&vh(n,t)&&o.push({kind:"partition",id:e.id})}o.some(e=>e.kind===t&&e.id===i)||o.unshift({kind:t,id:i});const a=o.map(e=>`${e.kind}:${e.id}`).sort().join("|"),r=performance.now(),l=this._physicalPickCycle,c=o.length>1&&l?.signature===a&&r-l.at>380&&r-l.at<=1200&&Math.hypot(e.clientX-l.x,e.clientY-l.y)<=10?(l.index+1)%o.length:Math.max(0,o.findIndex(e=>e.kind===t&&e.id===i));this._physicalPickCycle={signature:a,index:c,x:e.clientX,y:e.clientY,at:r},t=o[c].kind,i=o[c].id;const h="partition"===t?s.partitions.find(e=>e.id===i):s.wall_columns.find(e=>e.id===i);h&&(this._physicalSel={kind:t,id:i},this._physicalDrag={pid:e.pointerId,kind:t,id:i,start:this._svgPoint(e),startClient:[e.clientX,e.clientY],before:this._geometrySnapshot(),moved:!1,base:JSON.parse(JSON.stringify(h)),delta:[0,0]})}_clampPhysicalDelta(e,t,i){const s="partition"===e?[t.a,t.b]:[t.center],n=s.map(e=>e[0]),o=s.map(e=>e[1]);return[Math.max(-Ah*Pv-Math.min(...n),Math.min(Ah*Pv-Math.max(...n),i[0])),Math.max(-Ah*Pv-Math.min(...o),Math.min(Ah*Pv-Math.max(...o),i[1]))]}_physicalMove(e){const t=this._physicalDrag;if(!t||t.pid!==e.pointerId)return;e.stopPropagation();const i=this._svgPoint(e),s="partition"===t.kind?t.base.a:t.base.center,n=this._snap([s[0]+i[0]-t.start[0],s[1]+i[1]-t.start[1]]),o=this._clampPhysicalDelta(t.kind,t.base,[n[0]-s[0],n[1]-s[1]]);this._physicalDrag={...t,delta:o,moved:t.moved||Math.hypot(e.clientX-t.startClient[0],e.clientY-t.startClient[1])>=5}}_physicalUp(e){const t=this._physicalDrag;if(!t||t.pid!==e.pointerId)return;if(e.stopPropagation(),this._physicalDrag=null,!t.moved)return void this._registerPhysicalTap(t.kind,t.id);const i=this._spaceModel();if(!this._curSpaceCfg||!i)return;const s=this._curSpaceCfg;if("partition"===t.kind){const e=(s.partitions||[]).find(e=>e.id===t.id),i=t.base;if(e){const n={...i,a:[i.a[0]+t.delta[0],i.a[1]+t.delta[1]],b:[i.b[0]+t.delta[0],i.b[1]+t.delta[1]]};e.a=[n.a[0]/Pv,n.a[1]/Pv],e.b=[n.b[0]/Pv,n.b[1]/Pv];for(const e of s.openings||[]){if("partition"!==e.host?.kind||e.host.id!==t.id)continue;const i=Jp(e,[n],Pv,this._cellCm,this._gridPitch).resolved;i&&Object.assign(e,su(e,i,Pv))}}}else{const e=(s.wall_columns||[]).find(e=>e.id===t.id),n=t.base,o={...n,center:[n.center[0]+t.delta[0],n.center[1]+t.delta[1]]};if(i.wall_columns.some(e=>e.id!==t.id&&yh(e,o,.02*this._gridPitch)))return void this._showToast(this._t("toast.column_duplicate"));e&&(e.center=[(n.center[0]+t.delta[0])/Pv,(n.center[1]+t.delta[1])/Pv])}this._commitPhysicalGeometry(this._t("history.physical_move"),t.before)}_registerPhysicalTap(e,t,i){const s=performance.now(),n=this._physicalLastTap?.kind===e&&this._physicalLastTap.id===t&&this._physicalLastTap.segment===i&&s-this._physicalLastTap.at<=360;this._physicalLastTap={kind:e,id:t,segment:i,at:s},n&&(this._physicalLastTap=null,this._openPhysicalDialog(e,t,i))}_cancelPhysicalGesture(){this._physicalDrag=null,this._physicalRotate=null,this.requestUpdate()}_physicalRotateDown(e,t){if("square"!==t.shape||!this._spaceModel())return;e.preventDefault(),e.stopPropagation(),Ev(e);const i=this._svgPoint(e);this._physicalSel={kind:"column",id:t.id},this._physicalRotate={pid:e.pointerId,id:t.id,center:[...t.center],startAngle:180*Math.atan2(i[1]-t.center[1],i[0]-t.center[0])/Math.PI,baseAngle:eh(t.angle),angle:eh(t.angle),before:this._geometrySnapshot(),moved:!1}}_physicalRotateMove(e){const t=this._physicalRotate;if(!t||t.pid!==e.pointerId)return;e.preventDefault(),e.stopPropagation();const i=this._svgPoint(e),s=180*Math.atan2(i[1]-t.center[1],i[0]-t.center[0])/Math.PI,n=t.baseAngle+s-t.startAngle,o=eh(e.shiftKey?n:5*Math.round(n/5));this._physicalRotate={...t,angle:o,moved:t.moved||Math.abs(n-t.baseAngle)>=.5}}_physicalRotateUp(e){const t=this._physicalRotate;if(!t||t.pid!==e.pointerId)return;e.preventDefault(),e.stopPropagation(),this._physicalRotate=null;const i=this._spaceModel();if(!t.moved||!this._curSpaceCfg||!i)return;const s=i.wall_columns.find(e=>e.id===t.id);if(!s||"square"!==s.shape)return;const n={...s,angle:t.angle};if(i.wall_columns.some(e=>e.id!==t.id&&yh(e,n,.02*this._gridPitch)))return void this._showToast(this._t("toast.column_duplicate"));const o=this._curSpaceCfg.wall_columns?.find(e=>e.id===t.id);o&&(o.angle=t.angle,this._commitPhysicalGeometry(this._t("history.physical_edit"),t.before))}_rszRooms(){const e=[],t=this._spaceModel();if(!t)return e;for(const i of t.rooms){const t=i.id?hi(i):null;t&&e.push({id:i.id,poly:t,wall_ids:Array.isArray(i.wall_ids)?[...i.wall_ids]:void 0})}return i=e,s=Math.max(1e-12,1e-12*this._gridPitch),i.map(e=>{if(!Array.isArray(e.wall_ids)||e.wall_ids.length!==e.poly.length)return{...e,poly:e.poly.map(e=>[...e])};const t=e.poly.map(e=>[...e]);let i=!0;for(;i&&t.length>3;){i=!1;for(let e=0;e0){t.splice(e,1),i=!0;break}}}return{...e,poly:t}});var i,s}_rszOpenings(){return this._openingsR.map(e=>({id:e.id,x:e.rx,y:e.ry,length:e.rlen,hosted:!!e.host,angle:e.angle,type:e.type}))}_rszObstacles(){const e=this._spaceModel();if(!e)return[];const t=[];for(const i of e.partitions||[])t.push({kind:"segment",a:[...i.a],b:[...i.b],half:wl(i.cm,this._cellCm,this._gridPitch)/2});for(const i of e.room_drafts||[])for(let e=0;e+1Array.isArray(e.a)&&Array.isArray(e.b)&&e.a.length>=2&&e.b.length>=2).map(e=>({wall:e,a:[e.a[0]*Pv,e.a[1]*this._spaceH],b:[e.b[0]*Pv,e.b[1]*this._spaceH]})),n=Math.abs(e[0]-t[0])<=.05*this._gridPitch?"v":Math.abs(e[1]-t[1])<=.05*this._gridPitch?"h":null,o=s.filter(i=>!!n&&("h"===n?!(Math.abs(i.a[1]-e[1])>.05*this._gridPitch||Math.abs(i.b[1]-e[1])>.05*this._gridPitch)&&Math.min(Math.max(e[0],t[0]),Math.max(i.a[0],i.b[0]))-Math.max(Math.min(e[0],t[0]),Math.min(i.a[0],i.b[0]))>.05*this._gridPitch:!(Math.abs(i.a[0]-e[0])>.05*this._gridPitch||Math.abs(i.b[0]-e[0])>.05*this._gridPitch)&&Math.min(Math.max(e[1],t[1]),Math.max(i.a[1],i.b[1]))-Math.max(Math.min(e[1],t[1]),Math.min(i.a[1],i.b[1]))>.05*this._gridPitch)),a=new Set(o.map(e=>Number(e.wall.cm)).filter(e=>e>0));return{minDim:this._cmToUnits(30),eps:.05*this._gridPitch,step:this._gridPitch,movingHalf:i>0?wl(i,this._cellCm,this._gridPitch)/2:0,obstacles:this._rszObstacles(),thicknessConflict:a.size>1}}_rszResolution(e,t,i){const s=this._resize.snapshotIdentity||i||this._rszSnapshot(),n=`${this._space}|${this._cellCm}|${this._gridPitch}|${s}`,o=`${e}:${t}`;return this._resize.resolve(n,o,()=>{const i=[...this._resize.rooms||this._rszRooms()],s=i.find(t=>t.id===e),n=s?.poly?.[t]||[0,0],o=s?.poly?.[(t+1)%(s?.poly?.length||1)]||[0,0];return function(e,t,i,s,n){const{eps:o}=n,a=e.find(e=>e.id===i);if(!a||s<0||s>=(a.poly?.length||0)||a.poly.length<4||!Ra(a.poly))return{enabled:!1,reason:"invalid-geometry"};const r=a.poly[s],l=a.poly[(s+1)%a.poly.length],c=Na(r,l,o);if(!c)return{enabled:!1,reason:"diagonal"};if(!La(a.poly,s,c,o))return{enabled:!1,reason:"side-angle"};if(n.thicknessConflict)return{enabled:!1,reason:"thickness-conflict"};for(const e of n.obstacles||[])if(qa(e,r,l,n))return{enabled:!1,reason:"duplicate-physical-wall"};const h=Da(Sa(l,r)),d=[],p=new Set;let u=!1,_=!1;for(const t of e)if(t.id!==i)for(let e=0;e1||d.length>1)return{enabled:!1,reason:"multiple-rooms"};const m={[i]:s},g=[i];if(1===d.length){const e=d[0];if(!Ra(e.room.poly))return{enabled:!1,reason:"invalid-geometry"};if(!La(e.room.poly,e.edge,c,o))return{enabled:!1,reason:"side-angle"};g.push(e.room.id),m[e.room.id]=e.edge}const f=[];for(const e of t)if(!(Ta([e.x,e.y],r,l)>2*o)){if(e.hosted||e.length>h+2*o)return{enabled:!1,reason:"opening-conflict"};f.push(e.id)}const v=Object.fromEntries(g.map(t=>[t,e.find(e=>e.id===t).poly.length])),b=[];for(const t of g){const i=e.find(e=>e.id===t),s=m[t],n=(s-1+i.poly.length)%i.poly.length,a=(s+1)%i.poly.length,r=Ga(e,t,n,1,o),l=Ga(e,t,a,0,o);if(!r||!l)return{enabled:!1,reason:"partial-shared"};b.push(r,l)}const y={roomId:i,edge:s,a:[...r],b:[...l],n:Ia(a.poly,s),roomIds:g,edgeByRoom:m,topology:v,movingOpeningIds:f,sideOwnership:b};if(!Qa(e,t,y,0,n))return{enabled:!1,reason:"invalid-geometry"};const w=Math.abs(Number(n.step));if(Number.isFinite(w)&&w>o){const i=[-w,w];if(!i.some(i=>Qa(e,t,y,i,n))){if(!i.some(i=>Ya(Ja(e,t,y,i),y,o)))return{enabled:!1,reason:"partial-shared"};const s={...n,obstacles:[]};return i.some(i=>Qa(e,t,y,i,s))?{enabled:!1,reason:"duplicate-physical-wall"}:t.length&&i.some(t=>Qa(e,[],y,t,n))?{enabled:!1,reason:"opening-conflict"}:{enabled:!1,reason:"invalid-geometry"}}}return{enabled:!0,plan:y}}(i,[...this._resize.openings||this._rszOpenings()],e,t,this._rszOptsFor(n,o))})}_rszSnapshot(){return JSON.stringify(this._geometrySnapshot()||{spaceId:this._space,rooms:[],openings:[],walls:[],open_spans:[]})}_rszResetController(){const e=null!==this._resize.preview;this._resize.reset(),e&&this._cfgEpoch++}_rszProjectPreview(e,t,i,s,n){this._rszLimitViolation=null;const o=this._serverCfg?.spaces.find(e=>e.id===this._space);if(!o||!this._serverCfg)return{ok:!1,reason:"missing-context"};const a=JSON.parse(e),r={...o,rooms:a.rooms,openings:a.openings||[]};for(const e of["walls","wall_segments","open_spans","room_drafts","partitions","wall_columns","decor"])void 0!==a[e]?r[e]=a[e]:delete r[e];for(const e of["plan_x","plan_y","plan_scale","plan_scale_x","plan_scale_y","plan_angle"])void 0!==a.plan_transform?.[e]?r[e]=a.plan_transform[e]:delete r[e];const l=this._spaceH;for(const[e,i]of Object.entries(t)){const t=r.rooms.find(t=>t.id===e);t&&(t.poly=i.map(e=>[e[0]/Pv,e[1]/l]),delete t.x,delete t.y,delete t.w,delete t.h)}for(const[e,t]of Object.entries(i)){const i=(r.openings||[]).find(t=>t.id===e);i&&(i.x=t[0]/Pv,i.y=t[1]/l)}const c=[],h=[];for(const e of s){const t=n.find(t=>t.id===e),i=r.rooms.find(t=>t.id===e);if(!t||!i?.poly)continue;const s=i.poly.map(e=>[e[0]*Pv,e[1]*l]);if(t.poly.length!==s.length)continue;const o=Array.isArray(t.wall_ids)?t.wall_ids:[];for(let e=0;ee.id===i):null;n&&(n.a=[s[e][0]/Pv,s[e][1]/Pv],n.b=[s[(e+1)%s.length][0]/Pv,s[(e+1)%s.length][1]/Pv])}}if(c.length&&Array.isArray(r.walls)&&r.walls.length){const e=function(e,t,i,s,n=1,o="fixed-topology"){let a=!1;const r=El(e,t,i,s,n,o,()=>{a=!0});return{walls:a?(e||[]).map(e=>({...e})):r,rejected:a}}(r.walls,c,h,this._wallKeyPitch,Pv,"fixed-topology");if(e.rejected)return{ok:!1,reason:"wall-metadata"};r.walls=e.walls}const d=[];for(const e of r.rooms||[]){const t=hi(e);if(t&&!(t.length<2))for(let e=0;eJSON.stringify([e?.key,e?.cm,e?.a,e?.b]),u=new Map;for(const e of a.walls||[]){const t=p(e);u.set(t,(u.get(t)||0)+1)}const _=[];for(const e of r.walls||[]){const t=p(e),i=u.get(t)||0;i?u.set(t,i-1):_.push(e)}if(Hl(_,d,this._wallKeyPitch,Pv,a.walls||[]).length)return{ok:!1,reason:"wall-metadata"};const m=this._rszSpaceCandidateGeometry(this._space,r);if(!m.ok)return{ok:!1,reason:"physical-geometry"};const g={...this._serverCfg,spaces:(this._serverCfg?.spaces||[]).map(e=>e?.id===this._space?r:e)},f=this._junctionLimitsIntroduced(g,this._serverCfg,this._space);return f.length?(this._rszLimitViolation=f[0],{ok:!1,reason:"junction-limit"}):{ok:!0,value:{preview:{space:this._space,sp:r},beforeWalls:a.walls||[],afterWalls:r.walls||[],artifact:m.wallGeometry}}}_rszAcceptPreview(e,t){if(this._cfgEpoch++,!e||!t)return;const i=Lc(t);if(!i)return;const s=`${this._space}|${this._cfgEpoch}|${e.sp.rooms.length}`;Object.defineProperty(i,"sourceFingerprint",{value:Bd([e.sp,this._cellCm,this._gridPitch]),enumerable:!1});const n={key:s,value:i};fv(this._wallUnionPool,s,n,8),this._wallUnionCache=n}_rszSpaceCandidateGeometry(e,t){if(!this._serverCfg)return{ok:!1,wallGeometry:null};const i={...this._serverCfg,spaces:this._serverCfg.spaces.map(i=>i.id===e?t:i)};let s=null;try{return{ok:this._checkSpacePhysicalGeometry(i,e,e=>{s=e}).ok,wallGeometry:s}}catch{return{ok:!1,wallGeometry:null}}}_rszSpaceCandidateRenderable(e,t){if(!this._serverCfg)return!1;try{const i={...this._serverCfg,spaces:this._serverCfg.spaces.map(i=>i.id===e?t:i)};return this._checkSpacePhysicalGeometry(i,e).ok}catch{return!1}}_rszCandidateRenderable(e){return!!e&&e.space===this._space&&this._rszSpaceCandidateRenderable(e.space,e.sp)}_rszEdgeDown(e,t,i){if("resize"!==this._tool||this._resize.dragging)return;e.stopPropagation(),e.preventDefault();const s=this._rszRooms(),n=this._rszResolution(t,i);if(!n.enabled)return void this._showToast(this._rszReasonText(n.reason));Ev(e);const o=n.plan,a=this._svgPoint(e),r=`${this._space}|${this._cfgEpoch}|${s.length}`,l=this._wallUnionCache?.key===r?this._wallUnionCache.value:null,c=this._rszSnapshot();this._resize.begin({pointerId:e.pointerId,start:[a[0],a[1]],roomId:t,plan:o,options:this._rszOptsFor(o.a,o.b),rooms:s,openings:this._rszOpenings(),snapshotIdentity:c,before:JSON.parse(c),wallUnionBefore:l})}_rszReasonText(e){return this._t(`resize.disabled.${e}`)}_rszDisabledActivate(e,t){e.stopPropagation(),e.preventDefault(),this._showToast(this._rszReasonText(t))}_rszDisabledKey(e,t){"Enter"!==e.key&&" "!==e.key||this._rszDisabledActivate(e,t)}_rszMove(e){if(!this._resize.ownsPointer(e.pointerId))return;e.stopPropagation();const t=this._svgPoint(e),i=this._resize.move({pointerId:e.pointerId,point:[t[0],t[1]],step:this._gridPitch,snap:e=>{const t=this._snap(e);return[t[0],t[1]]},project:(e,t,i,s,n)=>this._rszProjectPreview(e,t,i,s,n),publish:(e,t)=>this._rszAcceptPreview(e,t),measure:(e,t)=>this._rszEdgeLabels(e,t)});if("rejected"===i.kind)return i.notify&&this._showToast(this._rszLimitViolation?`${this._t("resize.limit_stopped")} — `+this._junctionLimitLabel(this._rszLimitViolation):this._t("resize.preview_failed")),void this.requestUpdate();"accepted"===i.kind&&this.requestUpdate()}_rszUp(e){if(!this._resize.ownsPointer(e.pointerId))return;e.stopPropagation();const t=this._resize.finish({pointerId:e.pointerId,currentSnapshotIdentity:this._rszSnapshot(),validatePreview:e=>this._rszCandidateRenderable(e)});if("no-op"===t.kind)return this._cfgEpoch++,void this.requestUpdate();if("rejected"===t.kind)return this._cfgEpoch++,this._showToast(this._t("resize.commit_failed")),void this.requestUpdate();const i=t.preview,s=this._serverCfg?.spaces.find(e=>e.id===i.space);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.wall_segments)&&(s.wall_segments=i.sp.wall_segments)),this._suppressClick=!0,setTimeout(()=>this._suppressClick=!1,0),this._commitPhysicalGeometry(this._t("history.resize_room"),t.before),this.requestUpdate()}_rszCancelDrag(e){const t=this._resize.cancel(this._rszSnapshot(),e);if("no-op"!==t.kind){if(this._cfgEpoch++,t.restoreWallUnion){const e=this._spaceModel();if(e){const i=`${this._space}|${this._cfgEpoch}|${e.rooms.length}`,s={key:i,value:t.restoreWallUnion};fv(this._wallUnionPool,i,s,8),this._wallUnionCache=s}}this.requestUpdate()}}_rszPointerCancel(e){this._resize.ownsPointer(e.pointerId)&&(e.stopPropagation(),this._rszCancelDrag(e.pointerId))}_rszEdgeLabels(e,t,i=this._resize.rooms){const s=i,n=[],o=e.polys[t.roomId]||s?.find(e=>e.id===t.roomId).poly;if(!o||!s)return n;const a=o.length,r=this._rszInnerSpanCms(t.roomId,o,e.polys);for(const e of function(e,t){const i=e.length;return[(t-1+i)%i,(t+1)%i]}(o,t.edge)){const t=o[e],i=o[(e+1)%a],s=r?.[e];n.push({kind:"length",x:(t[0]+i[0])/2,y:(t[1]+i[1])/2,text:null==s?this._fmtLen(t,i):li(s,"mi"===this.hass?.config?.unit_system?.length),edge:{a:[t[0],t[1]],b:[i[0],i[1]]}})}const l="mi"===this.hass?.config?.unit_system?.length,c=t.roomIds,h=this._spaceWalls,d=this._physicalBodiesR(),p=this._baseVb(),u=this._view&&this._view.w>0&&this._view.h>0?this._view:{x:p[0],y:p[1],w:p[2],h:p[3]},[_,m]=this._lastValidStageSize||[u.w,u.h],g={...u,stageWidth:Math.max(1,_),stageHeight:Math.max(1,m)},f=this._spaceModel(),v=this._config?.icon_size??2.5,b=f?ed(v>8?2.5:v,f,u.w,this._kiosk?this._kioskScale.icon:1)*g.stageWidth/100:24,y=Math.max(10,.77*b),w=this._t("room.settings_short"),k=y*(1.457+.66*Math.max(1,w.length)*.42);for(const i of c){const o=e.polys[i]||s.find(e=>e.id===i).poly,a=h.length&&f&&this._innerRoomContour(f,i)||o,r=ir(d.length?mh(_h(a,d))*Math.pow(this._cellCm/this._gridPitch,2)/1e4:tr(a,this._gridPitch,this._cellCm),l),c=cr({poly:o,edge:t.edgeByRoom[i],text:r,view:g,gearCenter:$i(o),gearWidthPx:k,gearHeightPx:y});n.push({kind:"area",roomId:i,x:c.anchor[0],y:c.anchor[1],text:r,placement:c})}return n}_rszInnerSpanCms(e,t,i){const s=Object.keys(i).length?Object.entries(i).map(([e,t])=>({id:e,poly:t})):this._spaceModel()?.rooms;if(!s?.length)return null;const n=this._spaceWalls;if(!n.length)return null;const o=function(e,t,i,s,n,o,a,r=1){const l=(e||[]).find(e=>e?.id===t),c=hi(l);if(!c||c.length<3)return null;const h=mc(e,t,i,s,n,o,a,r);if(!h)return c.map(()=>0);const d=4*Zl(n,r);return c.map((e,t)=>{const i=c[(t+1)%c.length],s=[(e[0]+i[0])/2,(e[1]+i[1])/2];for(let e=0;efunction(e,t,i){const s=e?.length||0;if(s<3||!Array.isArray(i)||i.length!==s)return 0;const n=(Math.trunc(t)%s+s)%s,o=e[n],a=e[(n+1)%s],r=a[0]-o[0],l=a[1]-o[1],c=Math.hypot(r,l);if(!(c>0))return 0;const h=Math.max(0,Number(i[n])||0);if(!(h>0))return c;const d=[r/c,l/c],p=ec(e,n),u=[o[0]+p[0]*h,o[1]+p[1]*h],_=t=>{const n=Math.max(0,Number(i[t])||0);if(!(n>0))return null;const a=e[t],r=e[(t+1)%s],l=r[0]-a[0],c=r[1]-a[1],h=Math.hypot(l,c);if(!(h>0))return null;const p=ec(e,t),_=ic(u,d,[a[0]+p[0]*n,a[1]+p[1]*n],[l/h,c/h]);return _?(_[0]-o[0])*d[0]+(_[1]-o[1])*d[1]:null},m=_((n-1+s)%s)??0,g=(_((n+1)%s)??c)-m;return g>0?g:0}(t,i,o)*a)}_renderResizeMeasurements(){const e=this._resize.liveLabels;if(!e?.length)return G;const t=e.filter(e=>"length"===e.kind),i=e.filter(e=>"area"===e.kind);return W`
@@ -5887,7 +5887,7 @@ globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="30d20d6f6822065e2d5226b18abbb05d8d26 ${this._settingsDialog.bgColor?q``:q`${this._t("gs.bg_theme")}`} `:q`
${this._t("gs.bg_daynight_hint")}
`} - ${Rr(this.hass)?G:q`
${this._t("gs.sun_missing")}
`} + ${Er(this.hass)?G:q`
${this._t("gs.sun_missing")}
`}
${this._renderCompass()}
@@ -5939,7 +5939,7 @@ globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="30d20d6f6822065e2d5226b18abbb05d8d26
`:G} -
${this._t("gs.about_version",{v:cv})}
+
${this._t("gs.about_version",{v:_v})}
${this._t("gs.about_github")} @@ -5996,7 +5996,7 @@ globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="30d20d6f6822065e2d5226b18abbb05d8d26 ${e.busy?"…":this._t("btn.save")}
- `}_saveKioskScale(e){this._kioskScale={...this._kioskScale,...e};try{localStorage.setItem(Mv,JSON.stringify(this._kioskScale))}catch{}this.requestUpdate()}_renderKioskDialog(){const e=this._kioskScale,t=(t,i)=>q` + `}_saveKioskScale(e){this._kioskScale={...this._kioskScale,...e};try{localStorage.setItem(Iv,JSON.stringify(this._kioskScale))}catch{}this.requestUpdate()}_renderKioskDialog(){const e=this._kioskScale,t=(t,i)=>q`
${this._rangeInput(50,300,5,Math.round(100*e[t]),e=>this._saveKioskScale({[t]:e/100}))} ${Math.round(100*e[t])}% @@ -6053,7 +6053,7 @@ globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="30d20d6f6822065e2d5226b18abbb05d8d26 ${this._spaceDialog?this._renderSpaceDialog():G} ${this._importDialog?this._renderImportDialog():G} ${this._toast?q``:G} - `;const s=this._spaceModel();if(!s)return G;const n="valid"===i.kind?[s]:e,o=s.vb,a=this._effectiveProjection();this._renderProjection=a,this._labs.active.length&&function(e){mf||wf(e);const t=_f,i=t.active.join(",");if(!i||i===ff)return;ff=i;const s=new Map(of.map(e=>[e.id,e])),n=t.active.map(e=>{const t=s.get(e);return`${e} (#${t.issue}, expires ${t.expires})`}).join(", ");console.info(`HOUSEPLAN LABS: ${n}`)}(cv);const r="iso"===a,l="devices"===this._mode&&this._showAll,c=this._renderDevices.filter(e=>e.space===s.id&&(!e.hidden||l)),h=this._renderDeviceSnapshot,d=this._spaceDisplayForRender(),p=r?this._isoDecorationLayers(d):null,u=p?this._isoOpeningPanels(p):[],_=this._resolvedRoomFills(s,d),m=this._resolvedGlowBase(s,d,_),g=d.showLqi??this._config.show_signal??!0,f=this._config.icon_size??2.5,v=f>8?2.5:f,b=R_(v),y=this._viewOr(this._baseVb()),w=this._floorView(y),k=this._editing?"":this._stageBg(d),x=this._opMeasureView,$=this._decorMeasure,S=this._bdLive,M=this._furnLive,C="view"===this._mode?this._editorChromeMode:this._mode,D=this._roomHoverPaths(s),P=s.bg?this._display(s.bg.href):"",T=this._continuity.overlayVisible||"recovery-error"===this._continuity.state?this._continuity.recoveryReason:null,I=this._modeTransitionVisual,R=this._dayCycleState(),A=I?.viewWeight??("view"===this._mode?1:0),z=this._modeTransition.state?.from.presentedMode,F=!this._markup||!!I&&("view"===I.presentedMode||"devices"===I.presentedMode||"view"===z||"devices"===z),N=I?.stageColor||k,E=I?.sceneBrightness??1;return q` + `;const s=this._spaceModel();if(!s)return G;const n="valid"===i.kind?[s]:e,o=s.vb,a=this._effectiveProjection();this._renderProjection=a,this._labs.active.length&&function(e){yf||Mf(e);const t=bf,i=t.active.join(",");if(!i||i===kf)return;kf=i;const s=new Map(hf.map(e=>[e.id,e])),n=t.active.map(e=>{const t=s.get(e);return`${e} (#${t.issue}, expires ${t.expires})`}).join(", ");console.info(`HOUSEPLAN LABS: ${n}`)}(_v);const r="iso"===a,l="devices"===this._mode&&this._showAll,c=this._renderDevices.filter(e=>e.space===s.id&&(!e.hidden||l)),h=this._renderDeviceSnapshot,d=this._spaceDisplayForRender(),p=r?this._isoDecorationLayers(d):null,u=p?this._isoOpeningPanels(p):[],_=this._resolvedRoomFills(s,d),m=this._resolvedGlowBase(s,d,_),g=d.showLqi??this._config.show_signal??!0,f=this._config.icon_size??2.5,v=f>8?2.5:f,b=E_(v),y=this._viewOr(this._baseVb()),w=this._floorView(y),k=this._editing?"":this._stageBg(d),x=this._opMeasureView,$=this._decorMeasure,S=this._bdLive,M=this._furnLive,C="view"===this._mode?this._editorChromeMode:this._mode,D=this._roomHoverPaths(s),P=s.bg?this._display(s.bg.href):"",T=this._continuity.overlayVisible||"recovery-error"===this._continuity.state?this._continuity.recoveryReason:null,I=this._modeTransitionVisual,R=this._dayCycleState(),A=I?.viewWeight??("view"===this._mode?1:0),z=this._modeTransition.state?.from.presentedMode,F=!this._markup||!!I&&("view"===I.presentedMode||"devices"===I.presentedMode||"view"===z||"devices"===z),N=I?.stageColor||k,E=I?.sceneBrightness??1;return q` this._markupClick(e)} @wheel=${e=>this._onWheel(e)} @pointerdown=${e=>{this._notePointer(e),this._stagePointerDown(e)}} @@ -6148,7 +6148,7 @@ globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="30d20d6f6822065e2d5226b18abbb05d8d26 @pointerleave=${e=>this._stagePointerLeave(e)} @pointerup=${e=>this._stagePointerUp(e)} @pointercancel=${e=>this._stagePointerCancel(e)}> - ${Fr(R,A)} + ${Lr(R,A)} ${this._renderEditorSecondary()}
+ transform=${p?.structural?If():G}> ${""} ${this._wallHatchDefs(d.color)}${W`${this._paperShapes(s.rooms).map(e=>"path"in e?W``:"poly"in e?W``:W``)}`} ${this._editing?this._renderMarkupDefs(o):G} @@ -6250,7 +6250,7 @@ globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="30d20d6f6822065e2d5226b18abbb05d8d26 ${this._renderIsoWalls(p,u)} `:G} ${""} -
+
${c.map(e=>this._renderDevice(e,y,g))} ${this._renderVacuums(c,y)} ${this._renderVacFit(y)} @@ -6362,7 +6362,7 @@ globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="30d20d6f6822065e2d5226b18abbb05d8d26 `:G} ${this._toast?q``:G} - `}_vacCandidateStatus(e,t,i=this._planHass){const s=this._bindingStatus("entity:"+e);if("ha_disabled"===s.kind)return"disabled";if("orphaned"===s.kind)return"missing";if("unverified"===s.kind)return"unverified";const n=i?.states?.[e];return"unavailable"===n?.state?"unavailable":t?.hasPosition?"ok":"unsupported"}_vacOpenAllCameras(e){const t=this._haRegistry.entities||{},i=[];for(const[e,s]of Object.entries(this.hass?.states||{})){if(!e.startsWith("camera."))continue;const n=op(e,s,t[e]);n&&i.push(n)}this._vacAllCameraCache={devId:e.id,candidates:i},this._vacAllCamerasFor=e.id}_vacSourceResolution(e,t=!1,i=this._planHass){const s=e.marker?.vacuum,n="string"==typeof s?.source&&!!s.source,o=new Set(e.entities||[]),a=new Set(o);n&&a.add(s.source);const r=i?.entities||{},l=[];for(const e of a){const t=i?.states?.[e],o=op(e,t,r[e]);o?l.push(o):n&&e===s.source&&l.push({entityId:e,name:String(t?.attributes?.friendly_name||e),platform:r[e]?.platform?String(r[e].platform):null,category:e.startsWith("camera.")?"camera":"partial",hasPosition:!1,hasRooms:!1,hasPath:!1,hasMapId:!1,score:0})}if(t&&this._vacAllCameraCache?.devId===e.id){const e=new Set(l.map(e=>e.entityId));for(const t of this._vacAllCameraCache.candidates)e.has(t.entityId)||l.push(t)}const c={};for(const e of l)c[e.entityId]=this._vacCandidateStatus(e.entityId,e,i);return function(e,t,i,s){const n="string"==typeof e&&e.length>0,o=new Set(t),a=Array.from(i).sort((t,i)=>n&&t.entityId===e?-1:n&&i.entityId===e?1:i.score-t.score||t.entityId.localeCompare(i.entityId));if(n){const t=a.find(t=>t.entityId===e);return{entityId:e,status:s[e]||(t?.hasPosition?"ok":"unverified"),pinned:!0,candidates:a}}const r=a.find(e=>o.has(e.entityId)&&e.hasPosition&&"ok"===s[e.entityId]);return r?{entityId:r.entityId,status:"ok",pinned:!1,candidates:a}:{entityId:null,status:"none",pinned:!1,candidates:a}}(s?.source,o,l,c)}_vacSource(e,t=this._planHass){if(!1===e.marker?.vacuum?.live)return null;const i=this._vacSourceResolution(e,!1,t);return"ok"===i.status||"unsupported"===i.status?i.entityId:null}_vacEntity(e){return e.primary?.startsWith("vacuum.")?e.primary:(e.entities||[]).find(e=>e.startsWith("vacuum."))||null}_isVacDev(e){return!!this._vacEntity(e)}_activitySourceKey(e){return this._activitySnapshot(e).sourceKey}_activitySnapshot(e,t=ho(this._planHass,this._devices,null,this._virtualLights)){const i=k_(this._planHass,e,this._devices,t,this._fullRegistryHass);return{samples:i.samples,sourceKey:S_(this._planHass,e,i)}}_stampActivity(e,t,i){let s=this._activityRt.get(e);s||(s=om(i||"",[]),this._activityRt.set(e,s)),null!=i&&(s.sources=i),rm(s,t,Date.now(),window.clearTimeout.bind(window),e=>window.setTimeout(()=>this.requestUpdate(),e))}_syncActivityRuntime(){const e=new Map;if(!this.hass)return e;if(!1===this._config?.live_states){for(const e of this._activityRt.values())clearTimeout(e.timer);return this._activityRt.clear(),e}const t=new Set,i=ho(this._planHass,this._devices,null,this._virtualLights);for(const s of this._devices){if(s.hidden)continue;if("icon_ripple"!==Bi(s.marker?.display))continue;t.add(s.id);const n=this._activitySnapshot(s,i);e.set(s.id,n);const{samples:o,sourceKey:a}=n;let r=this._activityRt.get(s.id);r?r.sources!==a&&am(r,a,o,window.clearTimeout.bind(window)):(r=om(a,o),this._activityRt.set(s.id,r))}for(const[e,i]of this._activityRt)t.has(e)||(clearTimeout(i.timer),this._activityRt.delete(e));return e}_activityTick(){if(!this.hass)return;const e=this._syncActivityRuntime();for(const t of this._devices){if(t.hidden)continue;if("icon_ripple"!==Bi(t.marker?.display))continue;const i=e.get(t.id)||this._activitySnapshot(t),{samples:s,sourceKey:n}=i,o=this._activityRt.get(t.id);if(!o||o.sources!==n)continue;const a=lm(o,s,window.clearTimeout.bind(window));a&&this._stampActivity(t.id,a,n)}}_vacTick(){if(this.hass)for(const e of this._devices){if(e.hidden||!this._isVacDev(e))continue;if("static_icon"===Bi(e.marker?.display)){this._vacRt.delete(e.id);continue}const t=this._vacSource(e);if(!t)continue;const i=this._vacEntity(e),s=cp(this.hass.states[i||""]?.state),n=np(this.hass.states[t]?.attributes);let o=this._vacRt.get(e.id);o||(o={trail:[],lastKey:"",lastTs:0,moving:!1,jump:!1,endedTs:0,lastPos:null},this._vacRt.set(e.id,o)),s&&!o.moving&&(o.trail=[],o.lastPos=null);const a="never"!==_p(e.marker?.vacuum)&&!n?.path.length;!s&&o.moving&&(o.endedTs=Date.now(),a&&o.lastPos&&(o.trail=lp(o.trail,o.lastPos,40)),o.lastPos=null),o.moving=s;const r=n?.pos;if(s&&r){const e=r.x+":"+r.y;if(e!==o.lastKey){const t=Date.now();o.jump=o.lastTs>0&&t-o.lastTs>1e4,o.lastKey=e,o.lastTs=t,a&&o.lastPos&&(o.trail=lp(o.trail,o.lastPos,40)),o.lastPos=[r.x,r.y]}}}}_vacEnsureMarker(e){const t=this._serverCfg;if(!t)return null;t.markers=t.markers||[];const i=t.markers.find(t=>t.id===e.id);if(i)return i;if("device"!==e.bindingKind&&"entity"!==e.bindingKind||!e.bindingRef)return null;const s={id:e.id,binding:e.bindingKind+":"+e.bindingRef,space:e.space||null,area:e.area||null,hidden:!!e.hidden};return t.markers.push(s),s}_renderVacSection(e){const t=this._devices.find(t=>t.id===e.devId);if(!t||!this._isVacDev(t))return G;const i=t.marker?.vacuum||{},s=this._vacAllCamerasFor===t.id,n=this._vacSourceResolution(t,s),o=n.entityId,a=n.candidates.find(e=>e.entityId===o)||null,r=o?np(this.hass?.states[o]?.attributes):null,l=!1!==i.live&&("ok"===n.status||"unsupported"===n.status),c=this._vacPlanRoomAnchors(t.space),h=r?function(e,t){const i=new Set(t.map(ap).filter(Boolean)),s=new Set;for(const t of e){const e=ap(t.name||"");e&&i.has(e)&&s.add(e)}return s.size}(r.rooms,c.map(e=>e.name)):0,d=!!(l&&r&&h>=3),p=Object.keys(i.calibration||{}),u=e=>{const i=this._vacEnsureMarker(t);i&&(i.vacuum={...i.vacuum||{},...e},this._regSignature="",this._maybeRebuildDevices(),this._saveConfig(),this.requestUpdate())},_=new Set(t.entities||[]),m=n.candidates.filter(e=>_.has(e.entityId)||e.entityId===i.source),g=s?n.candidates.filter(e=>e.entityId.startsWith("camera.")&&!m.some(t=>t.entityId===e.entityId)):[],f=e=>[e.hasPosition?this._t("vac.cap_position"):"",e.hasRooms?this._t("vac.cap_rooms_short"):"",e.hasPath?this._t("vac.cap_path"):"",e.hasMapId?this._t("vac.cap_map"):""].filter(Boolean).join(" · ")||this._t("vac.cap_none"),v=e=>q` + `}_vacCandidateStatus(e,t,i=this._planHass){const s=this._bindingStatus("entity:"+e);if("ha_disabled"===s.kind)return"disabled";if("orphaned"===s.kind)return"missing";if("unverified"===s.kind)return"unverified";const n=i?.states?.[e];return"unavailable"===n?.state?"unavailable":t?.hasPosition?"ok":"unsupported"}_vacOpenAllCameras(e){const t=this._haRegistry.entities||{},i=[];for(const[e,s]of Object.entries(this.hass?.states||{})){if(!e.startsWith("camera."))continue;const n=hp(e,s,t[e]);n&&i.push(n)}this._vacAllCameraCache={devId:e.id,candidates:i},this._vacAllCamerasFor=e.id}_vacSourceResolution(e,t=!1,i=this._planHass){const s=e.marker?.vacuum,n="string"==typeof s?.source&&!!s.source,o=new Set(e.entities||[]),a=new Set(o);n&&a.add(s.source);const r=i?.entities||{},l=[];for(const e of a){const t=i?.states?.[e],o=hp(e,t,r[e]);o?l.push(o):n&&e===s.source&&l.push({entityId:e,name:String(t?.attributes?.friendly_name||e),platform:r[e]?.platform?String(r[e].platform):null,category:e.startsWith("camera.")?"camera":"partial",hasPosition:!1,hasRooms:!1,hasPath:!1,hasMapId:!1,score:0})}if(t&&this._vacAllCameraCache?.devId===e.id){const e=new Set(l.map(e=>e.entityId));for(const t of this._vacAllCameraCache.candidates)e.has(t.entityId)||l.push(t)}const c={};for(const e of l)c[e.entityId]=this._vacCandidateStatus(e.entityId,e,i);return function(e,t,i,s){const n="string"==typeof e&&e.length>0,o=new Set(t),a=Array.from(i).sort((t,i)=>n&&t.entityId===e?-1:n&&i.entityId===e?1:i.score-t.score||t.entityId.localeCompare(i.entityId));if(n){const t=a.find(t=>t.entityId===e);return{entityId:e,status:s[e]||(t?.hasPosition?"ok":"unverified"),pinned:!0,candidates:a}}const r=a.find(e=>o.has(e.entityId)&&e.hasPosition&&"ok"===s[e.entityId]);return r?{entityId:r.entityId,status:"ok",pinned:!1,candidates:a}:{entityId:null,status:"none",pinned:!1,candidates:a}}(s?.source,o,l,c)}_vacSource(e,t=this._planHass){if(!1===e.marker?.vacuum?.live)return null;const i=this._vacSourceResolution(e,!1,t);return"ok"===i.status||"unsupported"===i.status?i.entityId:null}_vacEntity(e){return e.primary?.startsWith("vacuum.")?e.primary:(e.entities||[]).find(e=>e.startsWith("vacuum."))||null}_isVacDev(e){return!!this._vacEntity(e)}_activitySourceKey(e){return this._activitySnapshot(e).sourceKey}_activitySnapshot(e,t=ho(this._planHass,this._devices,null,this._virtualLights)){const i=C_(this._planHass,e,this._devices,t,this._fullRegistryHass);return{samples:i.samples,sourceKey:T_(this._planHass,e,i)}}_stampActivity(e,t,i){let s=this._activityRt.get(e);s||(s=hm(i||"",[]),this._activityRt.set(e,s)),null!=i&&(s.sources=i),pm(s,t,Date.now(),window.clearTimeout.bind(window),e=>window.setTimeout(()=>this.requestUpdate(),e))}_syncActivityRuntime(){const e=new Map;if(!this.hass)return e;if(!1===this._config?.live_states){for(const e of this._activityRt.values())clearTimeout(e.timer);return this._activityRt.clear(),e}const t=new Set,i=ho(this._planHass,this._devices,null,this._virtualLights);for(const s of this._devices){if(s.hidden)continue;if("icon_ripple"!==Bi(s.marker?.display))continue;t.add(s.id);const n=this._activitySnapshot(s,i);e.set(s.id,n);const{samples:o,sourceKey:a}=n;let r=this._activityRt.get(s.id);r?r.sources!==a&&dm(r,a,o,window.clearTimeout.bind(window)):(r=hm(a,o),this._activityRt.set(s.id,r))}for(const[e,i]of this._activityRt)t.has(e)||(clearTimeout(i.timer),this._activityRt.delete(e));return e}_activityTick(){if(!this.hass)return;const e=this._syncActivityRuntime();for(const t of this._devices){if(t.hidden)continue;if("icon_ripple"!==Bi(t.marker?.display))continue;const i=e.get(t.id)||this._activitySnapshot(t),{samples:s,sourceKey:n}=i,o=this._activityRt.get(t.id);if(!o||o.sources!==n)continue;const a=um(o,s,window.clearTimeout.bind(window));a&&this._stampActivity(t.id,a,n)}}_vacTick(){if(this.hass)for(const e of this._devices){if(e.hidden||!this._isVacDev(e))continue;if("static_icon"===Bi(e.marker?.display)){this._vacRt.delete(e.id);continue}const t=this._vacSource(e);if(!t)continue;const i=this._vacEntity(e),s=_p(this.hass.states[i||""]?.state),n=cp(this.hass.states[t]?.attributes);let o=this._vacRt.get(e.id);o||(o={trail:[],lastKey:"",lastTs:0,moving:!1,jump:!1,endedTs:0,lastPos:null},this._vacRt.set(e.id,o)),s&&!o.moving&&(o.trail=[],o.lastPos=null);const a="never"!==bp(e.marker?.vacuum)&&!n?.path.length;!s&&o.moving&&(o.endedTs=Date.now(),a&&o.lastPos&&(o.trail=up(o.trail,o.lastPos,40)),o.lastPos=null),o.moving=s;const r=n?.pos;if(s&&r){const e=r.x+":"+r.y;if(e!==o.lastKey){const t=Date.now();o.jump=o.lastTs>0&&t-o.lastTs>1e4,o.lastKey=e,o.lastTs=t,a&&o.lastPos&&(o.trail=up(o.trail,o.lastPos,40)),o.lastPos=[r.x,r.y]}}}}_vacEnsureMarker(e){const t=this._serverCfg;if(!t)return null;t.markers=t.markers||[];const i=t.markers.find(t=>t.id===e.id);if(i)return i;if("device"!==e.bindingKind&&"entity"!==e.bindingKind||!e.bindingRef)return null;const s={id:e.id,binding:e.bindingKind+":"+e.bindingRef,space:e.space||null,area:e.area||null,hidden:!!e.hidden};return t.markers.push(s),s}_renderVacSection(e){const t=this._devices.find(t=>t.id===e.devId);if(!t||!this._isVacDev(t))return G;const i=t.marker?.vacuum||{},s=this._vacAllCamerasFor===t.id,n=this._vacSourceResolution(t,s),o=n.entityId,a=n.candidates.find(e=>e.entityId===o)||null,r=o?cp(this.hass?.states[o]?.attributes):null,l=!1!==i.live&&("ok"===n.status||"unsupported"===n.status),c=this._vacPlanRoomAnchors(t.space),h=r?function(e,t){const i=new Set(t.map(dp).filter(Boolean)),s=new Set;for(const t of e){const e=dp(t.name||"");e&&i.has(e)&&s.add(e)}return s.size}(r.rooms,c.map(e=>e.name)):0,d=!!(l&&r&&h>=3),p=Object.keys(i.calibration||{}),u=e=>{const i=this._vacEnsureMarker(t);i&&(i.vacuum={...i.vacuum||{},...e},this._regSignature="",this._maybeRebuildDevices(),this._saveConfig(),this.requestUpdate())},_=new Set(t.entities||[]),m=n.candidates.filter(e=>_.has(e.entityId)||e.entityId===i.source),g=s?n.candidates.filter(e=>e.entityId.startsWith("camera.")&&!m.some(t=>t.entityId===e.entityId)):[],f=e=>[e.hasPosition?this._t("vac.cap_position"):"",e.hasRooms?this._t("vac.cap_rooms_short"):"",e.hasPath?this._t("vac.cap_path"):"",e.hasMapId?this._t("vac.cap_map"):""].filter(Boolean).join(" · ")||this._t("vac.cap_none"),v=e=>q`
`}_vacMapId(e,t,i=this._planHass){const s=this._vacEntity(e),n=s?i?.states?.[s]?.attributes?.selected_map:null;return o=t.mapId,a=n,"default"!==o?o:null!=a?String(a):"default";var o,a}_vacSaveMatrix(e,t,i,s){const n=this._devices.find(t=>t.id===e),o=n?this._vacEnsureMarker(n):this._serverCfg?.markers?.find(t=>t.id===e);if(!o)return!1;const a={...o.vacuum||{}};return a.source=t,a.calibration={...a.calibration||{},[i]:s.map(e=>Number(e.toFixed(6)))},o.vacuum=a,this._regSignature="",this._maybeRebuildDevices(),this._saveConfig(),this.requestUpdate(),!0}_vacPlanRoomAnchors(e){return(this._spaceModelById(e)?.rooms||[]).map(e=>({room:e,poly:hi(e)})).filter(({room:e,poly:t})=>e.name&&t).map(({room:e,poly:t})=>{const i=Qd(t);return i?{name:String(e.name),cx:i[0],cy:i[1]}:null}).filter(Boolean)}_vacAutoCalibrate(e){const t=this._vacSource(e),i=t?np(this.hass?.states[t]?.attributes):null;if(!t||!i||i.rooms.length<3)return void this._showToast(this._t("vac.autocal_no_rooms"));const s=this._vacPlanRoomAnchors(e.space),n=rp(i.rooms,s);if(!n)return void this._showToast(this._t("vac.autocal_no_match"));const o=this._serverCfg?.spaces?.find(t=>t.id===e.space),a=Number(o?.cell_cm),r=Number.isFinite(a)&&a>0?a:5,l=function(e,t,i){return![e,t,i].every(Number.isFinite)||e<0||t<=0||i<=0?Number.POSITIVE_INFINITY:e/t*i}(n.residual,this._gridPitch,r),c=this._vacMapId(e,i);l>40?this._vacCalConfirm={markerId:e.id,source:t,mapId:c,matrix:n.matrix,rooms:n.matched.length,error:li(l,"mi"===this.hass?.config?.unit_system?.length)}:this._vacSaveMatrix(e.id,t,c,n.matrix)&&this._showToast(ss(this._t("vac.autocal_done"),{rooms:String(n.matched.length)}))}_vacApplyCalibrationProposal(e){const t=this._vacCalConfirm;if(t){if(this._vacCalConfirm=null,e){const e=this._devices.find(e=>e.id===t.markerId),i=pp(t.matrix);if(!e||!i)return;if(this._markerDialog=null,e.space!==this._space&&!this._commitSpace(e.space))return;return void(this._vacFit={markerId:t.markerId,source:t.source,mapId:t.mapId,p:i,drag:null})}this._vacSaveMatrix(t.markerId,t.source,t.mapId,t.matrix)&&this._showToast(ss(this._t("vac.autocal_done"),{rooms:String(t.rooms)}))}}_vacStartFit(e){const t=this._vacSource(e),i=t?np(this.hass?.states[t]?.attributes):null;if(!t||!i)return void this._showToast(this._t("vac.cal_need_pos"));const s=this._vacMapId(e,i),n=e.marker?.vacuum?.calibration?.[s],o=this._spaceModelById(e.space);if(!o)return;const a=o.vb,r=n&&6===n.length&&pp(n)||function(e,t){const i=[],s=[];for(const t of e)null!=t.x0?(i.push(t.x0,t.x1),s.push(t.y0,t.y1)):(i.push(t.cx),s.push(t.cy));if(!i.length)return{ox:t[0]+t[2]/2,oy:t[1]+t[3]/2,s:t[2]/1e4,rot:0,mir:!0};const n=Math.min(...i),o=Math.max(...i),a=Math.min(...s),r=Math.max(...s),l=Math.max(o-n,r-a)||1,c={ox:0,oy:0,s:.6*Math.min(t[2],t[3])/l,rot:0,mir:!0},h=dp(c),[d,p]=Yd(h,(n+o)/2,(a+r)/2);return c.ox=t[0]+t[2]/2-d,c.oy=t[1]+t[3]/2-p,c}(i.rooms,a);this._markerDialog=null,(e.space===this._space||this._commitSpace(e.space))&&(this._vacFit={markerId:e.id,source:t,mapId:s,p:r,drag:null})}_vacFitSave(){const e=this._vacFit;if(!e)return;const t=this._vacSaveMatrix(e.markerId,e.source,e.mapId,dp(e.p));this._vacFit=null,t&&this._showToast(this._t("vac.cal_done"))}_vacFitTurn(e){const t=this._vacFit;if(!t)return;const i=np(this.hass?.states[t.source]?.attributes),s=this._vacGhostCentre(i?.rooms||[]),n={...t.p,...e};this._vacFit={...t,p:up(n,t.p,s[0],s[1])}}_vacGhostCentre(e){const t=[],i=[];for(const s of e)t.push(s.x0??s.cx,s.x1??s.cx),i.push(s.y0??s.cy,s.y1??s.cy);return t.length?[(Math.min(...t)+Math.max(...t))/2,(Math.min(...i)+Math.max(...i))/2]:[0,0]}_vacDelta(e,t,i){const s=this._stageEl,n=s?.clientWidth||1,o=s?.clientHeight||1;return[t/n*e.w,i/o*e.h]}_vacFitPointer(e,t){const i=this._vacFit;if(!i)return;if(e.stopPropagation(),"pointerdown"===e.type){const t=e.target,s=t.getAttribute?.("data-corner");try{e.currentTarget.setPointerCapture?.(e.pointerId)}catch{}return void(this._vacFit={...i,drag:s?{kind:"scale",sx:e.clientX,sy:e.clientY,p0:{...i.p},fx:Number(s.split(",")[0]),fy:Number(s.split(",")[1])}:{kind:"move",sx:e.clientX,sy:e.clientY,p0:{...i.p},fx:0,fy:0}})}const s=i.drag;if(s){if("pointermove"===e.type){const[n,o]=this._vacDelta(t,e.clientX-s.sx,e.clientY-s.sy);if("move"===s.kind)this._vacFit={...i,p:{...s.p0,ox:s.p0.ox+n,oy:s.p0.oy+o}};else{const e=np(this.hass?.states[i.source]?.attributes),t=this._vacGhostCentre(e?.rooms||[]),a=dp(s.p0),[r,l]=Yd(a,t[0],t[1]),[c,h]=Yd(a,s.fx,s.fy),d=Math.hypot(r-c,l-h)||1,[p,u]=[2*r-c,2*l-h],_=Math.hypot(p+2*n-c,u+2*o-h)/2,m=Math.max(.05,_/d),g={...s.p0,s:s.p0.s*m};this._vacFit={...i,p:up(g,s.p0,s.fx,s.fy)}}return}"pointerup"!==e.type&&"pointercancel"!==e.type||(this._vacFit={...i,drag:null})}}_renderVacFit(e){const t=this._vacFit;if(!t)return G;const i=np(this._renderPlanHass?.states?.[t.source]?.attributes);if(!i)return G;const s=dp(t.p),n=[],o=[],a=[];for(const e of i.rooms){if(null==e.x0)continue;const t=[[e.x0,e.y0],[e.x1,e.y0],[e.x1,e.y1],[e.x0,e.y1]].map(([e,t])=>Yd(s,e,t));t.forEach(([e,t])=>{o.push(e),a.push(t)});const[i,r]=Yd(s,e.cx,e.cy);n.push(W` - ${e.name}`)}let r=G;if(i.pos){const[t,n]=Yd(s,i.pos.x,i.pos.y);r=W``}const l=[];if(o.length){const t=(()=>{const e=s[0]*s[4]-s[1]*s[3];return(t,i)=>[(s[4]*(t-s[2])-s[1]*(i-s[5]))/e,(-s[3]*(t-s[2])+s[0]*(i-s[5]))/e]})(),i=Math.min(...o),n=Math.max(...o),r=Math.min(...a),c=Math.max(...a),h=.022*e.w,d=h/4;for(const[e,s,o,a]of[[i,r,n,c],[n,r,i,c],[n,c,i,r],[i,c,n,r]]){const i=t(o,a);l.push(W``}_vacMapId(e,t,i=this._planHass){const s=this._vacEntity(e),n=s?i?.states?.[s]?.attributes?.selected_map:null;return o=t.mapId,a=n,"default"!==o?o:null!=a?String(a):"default";var o,a}_vacSaveMatrix(e,t,i,s){const n=this._devices.find(t=>t.id===e),o=n?this._vacEnsureMarker(n):this._serverCfg?.markers?.find(t=>t.id===e);if(!o)return!1;const a={...o.vacuum||{}};return a.source=t,a.calibration={...a.calibration||{},[i]:s.map(e=>Number(e.toFixed(6)))},o.vacuum=a,this._regSignature="",this._maybeRebuildDevices(),this._saveConfig(),this.requestUpdate(),!0}_vacPlanRoomAnchors(e){return(this._spaceModelById(e)?.rooms||[]).map(e=>({room:e,poly:hi(e)})).filter(({room:e,poly:t})=>e.name&&t).map(({room:e,poly:t})=>{const i=np(t);return i?{name:String(e.name),cx:i[0],cy:i[1]}:null}).filter(Boolean)}_vacAutoCalibrate(e){const t=this._vacSource(e),i=t?cp(this.hass?.states[t]?.attributes):null;if(!t||!i||i.rooms.length<3)return void this._showToast(this._t("vac.autocal_no_rooms"));const s=this._vacPlanRoomAnchors(e.space),n=pp(i.rooms,s);if(!n)return void this._showToast(this._t("vac.autocal_no_match"));const o=this._serverCfg?.spaces?.find(t=>t.id===e.space),a=Number(o?.cell_cm),r=Number.isFinite(a)&&a>0?a:5,l=function(e,t,i){return![e,t,i].every(Number.isFinite)||e<0||t<=0||i<=0?Number.POSITIVE_INFINITY:e/t*i}(n.residual,this._gridPitch,r),c=this._vacMapId(e,i);l>40?this._vacCalConfirm={markerId:e.id,source:t,mapId:c,matrix:n.matrix,rooms:n.matched.length,error:li(l,"mi"===this.hass?.config?.unit_system?.length)}:this._vacSaveMatrix(e.id,t,c,n.matrix)&&this._showToast(ss(this._t("vac.autocal_done"),{rooms:String(n.matched.length)}))}_vacApplyCalibrationProposal(e){const t=this._vacCalConfirm;if(t){if(this._vacCalConfirm=null,e){const e=this._devices.find(e=>e.id===t.markerId),i=fp(t.matrix);if(!e||!i)return;if(this._markerDialog=null,e.space!==this._space&&!this._commitSpace(e.space))return;return void(this._vacFit={markerId:t.markerId,source:t.source,mapId:t.mapId,p:i,drag:null})}this._vacSaveMatrix(t.markerId,t.source,t.mapId,t.matrix)&&this._showToast(ss(this._t("vac.autocal_done"),{rooms:String(t.rooms)}))}}_vacStartFit(e){const t=this._vacSource(e),i=t?cp(this.hass?.states[t]?.attributes):null;if(!t||!i)return void this._showToast(this._t("vac.cal_need_pos"));const s=this._vacMapId(e,i),n=e.marker?.vacuum?.calibration?.[s],o=this._spaceModelById(e.space);if(!o)return;const a=o.vb,r=n&&6===n.length&&fp(n)||function(e,t){const i=[],s=[];for(const t of e)null!=t.x0?(i.push(t.x0,t.x1),s.push(t.y0,t.y1)):(i.push(t.cx),s.push(t.cy));if(!i.length)return{ox:t[0]+t[2]/2,oy:t[1]+t[3]/2,s:t[2]/1e4,rot:0,mir:!0};const n=Math.min(...i),o=Math.max(...i),a=Math.min(...s),r=Math.max(...s),l=Math.max(o-n,r-a)||1,c={ox:0,oy:0,s:.6*Math.min(t[2],t[3])/l,rot:0,mir:!0},h=gp(c),[d,p]=ep(h,(n+o)/2,(a+r)/2);return c.ox=t[0]+t[2]/2-d,c.oy=t[1]+t[3]/2-p,c}(i.rooms,a);this._markerDialog=null,(e.space===this._space||this._commitSpace(e.space))&&(this._vacFit={markerId:e.id,source:t,mapId:s,p:r,drag:null})}_vacFitSave(){const e=this._vacFit;if(!e)return;const t=this._vacSaveMatrix(e.markerId,e.source,e.mapId,gp(e.p));this._vacFit=null,t&&this._showToast(this._t("vac.cal_done"))}_vacFitTurn(e){const t=this._vacFit;if(!t)return;const i=cp(this.hass?.states[t.source]?.attributes),s=this._vacGhostCentre(i?.rooms||[]),n={...t.p,...e};this._vacFit={...t,p:vp(n,t.p,s[0],s[1])}}_vacGhostCentre(e){const t=[],i=[];for(const s of e)t.push(s.x0??s.cx,s.x1??s.cx),i.push(s.y0??s.cy,s.y1??s.cy);return t.length?[(Math.min(...t)+Math.max(...t))/2,(Math.min(...i)+Math.max(...i))/2]:[0,0]}_vacDelta(e,t,i){const s=this._stageEl,n=s?.clientWidth||1,o=s?.clientHeight||1;return[t/n*e.w,i/o*e.h]}_vacFitPointer(e,t){const i=this._vacFit;if(!i)return;if(e.stopPropagation(),"pointerdown"===e.type){const t=e.target,s=t.getAttribute?.("data-corner");try{e.currentTarget.setPointerCapture?.(e.pointerId)}catch{}return void(this._vacFit={...i,drag:s?{kind:"scale",sx:e.clientX,sy:e.clientY,p0:{...i.p},fx:Number(s.split(",")[0]),fy:Number(s.split(",")[1])}:{kind:"move",sx:e.clientX,sy:e.clientY,p0:{...i.p},fx:0,fy:0}})}const s=i.drag;if(s){if("pointermove"===e.type){const[n,o]=this._vacDelta(t,e.clientX-s.sx,e.clientY-s.sy);if("move"===s.kind)this._vacFit={...i,p:{...s.p0,ox:s.p0.ox+n,oy:s.p0.oy+o}};else{const e=cp(this.hass?.states[i.source]?.attributes),t=this._vacGhostCentre(e?.rooms||[]),a=gp(s.p0),[r,l]=ep(a,t[0],t[1]),[c,h]=ep(a,s.fx,s.fy),d=Math.hypot(r-c,l-h)||1,[p,u]=[2*r-c,2*l-h],_=Math.hypot(p+2*n-c,u+2*o-h)/2,m=Math.max(.05,_/d),g={...s.p0,s:s.p0.s*m};this._vacFit={...i,p:vp(g,s.p0,s.fx,s.fy)}}return}"pointerup"!==e.type&&"pointercancel"!==e.type||(this._vacFit={...i,drag:null})}}_renderVacFit(e){const t=this._vacFit;if(!t)return G;const i=cp(this._renderPlanHass?.states?.[t.source]?.attributes);if(!i)return G;const s=gp(t.p),n=[],o=[],a=[];for(const e of i.rooms){if(null==e.x0)continue;const t=[[e.x0,e.y0],[e.x1,e.y0],[e.x1,e.y1],[e.x0,e.y1]].map(([e,t])=>ep(s,e,t));t.forEach(([e,t])=>{o.push(e),a.push(t)});const[i,r]=ep(s,e.cx,e.cy);n.push(W` + ${e.name}`)}let r=G;if(i.pos){const[t,n]=ep(s,i.pos.x,i.pos.y);r=W``}const l=[];if(o.length){const t=(()=>{const e=s[0]*s[4]-s[1]*s[3];return(t,i)=>[(s[4]*(t-s[2])-s[1]*(i-s[5]))/e,(-s[3]*(t-s[2])+s[0]*(i-s[5]))/e]})(),i=Math.min(...o),n=Math.max(...o),r=Math.min(...a),c=Math.max(...a),h=.022*e.w,d=h/4;for(const[e,s,o,a]of[[i,r,n,c],[n,r,i,c],[n,c,i,r],[i,c,n,r]]){const i=t(o,a);l.push(W` `)}}return q`this._vacFitPointer(t,e)} @pointermove=${t=>this._vacFitPointer(t,e)} @pointerup=${t=>this._vacFitPointer(t,e)} - @pointercancel=${t=>this._vacFitPointer(t,e)}>${n}${r}${l}`}_vacRafLoop(){this._vacRaf=requestAnimationFrame(()=>{const e=this.renderRoot,t=this._stageEl,i=this._vacLastView,s=e?.querySelectorAll?.(".vacpuck")||[];if(!t||!i||!s.length)return void(this._vacRaf=0);const n=t.getBoundingClientRect();for(const t of s){const s=t.getAttribute("data-mid"),o=t.getBoundingClientRect(),a=i.x+(o.left+o.width/2-n.left)/n.width*i.w,r=i.y+(o.top+o.height/2-n.top)/n.height*i.h;for(const t of e.querySelectorAll(`line.tip[data-mid="${s}"]`))t.setAttribute("x2",a.toFixed(1)),t.setAttribute("y2",r.toFixed(1))}this._vacRafLoop()})}_renderVacuums(e,t){if(this._markup||"decor"===this._mode)return G;const i=this._space+"|"+t.x+"|"+t.y+"|"+t.w+"|"+t.h,s=this._vacJumpOnce||i!==this._vacViewKey;this._vacViewKey=i,this._vacJumpOnce=!1;const n=[],o=[];for(const i of e){if(i.hidden||!this._isVacDev(i))continue;if("static_icon"===Bi(i.marker?.display))continue;const e=this._renderDeviceSnapshot?.facts.get(`vacuum:${i.id}`),a=e?.source??this._vacSource(i,this._renderPlanHass);if(!a)continue;const r=e?.telemetry??np(this._renderPlanHass?.states[a]?.attributes);if(!r)continue;const l=String(e?.mapId??this._vacMapId(i,r,this._renderPlanHass)),c=i.marker?.vacuum?.calibration?.[l];if(!c||6!==c.length)continue;const h=e?.runtime??this._vacRt.get(i.id),d=h?.moving??!1,p=_p(i.marker?.vacuum),u="always"===p||"cleaning"===p&&d,_=e?.server??this._vacSrvTrails[i.id],m=_?.current?.map_id===l&&Array.isArray(_.current.points)?_.current:null,g=_?.previous?.map_id===l&&Array.isArray(_.previous.points)?_.previous:null;if("always"===p&&g&&g.points.length>1){const e=g.points.map(([e,t])=>{const[i,s]=Yd(c,e,t),n=this._scenePoint([i,s]);return n[0].toFixed(1)+","+n[1].toFixed(1)}).join(" ");o.push(W``)}if(u){const e=ip(r,m,h?.trail||[]),t=!d||"integration"!==e.source&&"server"!==e.source?e.path:sp(e.path);if(t.length){const e=t.map(e=>e.map(([e,t],i)=>{const[s,n]=Yd(c,e,t),o=this._scenePoint([s,n]);return`${i?"L":"M"} ${o[0].toFixed(1)} ${o[1].toFixed(1)}`}).join(" ")).join(" ");o.push(W``);const s=t[t.length-1];if(d&&s?.length>=2){const e=s[s.length-1],[t,n]=Yd(c,e[0],e[1]),a=this._scenePoint([t,n]),r=a[0].toFixed(1),l=a[1].toFixed(1);o.push(W``)}}}if(!d||!r.pos)continue;const[f,v]=Yd(c,r.pos.x,r.pos.y),b=this._scenePoint([f,v]),y=(b[0]-t.x)/t.w*100,w=(b[1]-t.y)/t.h*100,k=h&&h.lastTs>0&&Date.now()-h.lastTs>6e4,x=i.marker?.icon||i.icon||"mdi:robot-vacuum";n.push(q`
this._vacFitPointer(t,e)}>${n}${r}${l}`}_vacRafLoop(){this._vacRaf=requestAnimationFrame(()=>{const e=this.renderRoot,t=this._stageEl,i=this._vacLastView,s=e?.querySelectorAll?.(".vacpuck")||[];if(!t||!i||!s.length)return void(this._vacRaf=0);const n=t.getBoundingClientRect();for(const t of s){const s=t.getAttribute("data-mid"),o=t.getBoundingClientRect(),a=i.x+(o.left+o.width/2-n.left)/n.width*i.w,r=i.y+(o.top+o.height/2-n.top)/n.height*i.h;for(const t of e.querySelectorAll(`line.tip[data-mid="${s}"]`))t.setAttribute("x2",a.toFixed(1)),t.setAttribute("y2",r.toFixed(1))}this._vacRafLoop()})}_renderVacuums(e,t){if(this._markup||"decor"===this._mode)return G;const i=this._space+"|"+t.x+"|"+t.y+"|"+t.w+"|"+t.h,s=this._vacJumpOnce||i!==this._vacViewKey;this._vacViewKey=i,this._vacJumpOnce=!1;const n=[],o=[];for(const i of e){if(i.hidden||!this._isVacDev(i))continue;if("static_icon"===Bi(i.marker?.display))continue;const e=this._renderDeviceSnapshot?.facts.get(`vacuum:${i.id}`),a=e?.source??this._vacSource(i,this._renderPlanHass);if(!a)continue;const r=e?.telemetry??cp(this._renderPlanHass?.states[a]?.attributes);if(!r)continue;const l=String(e?.mapId??this._vacMapId(i,r,this._renderPlanHass)),c=i.marker?.vacuum?.calibration?.[l];if(!c||6!==c.length)continue;const h=e?.runtime??this._vacRt.get(i.id),d=h?.moving??!1,p=bp(i.marker?.vacuum),u="always"===p||"cleaning"===p&&d,_=e?.server??this._vacSrvTrails[i.id],m=_?.current?.map_id===l&&Array.isArray(_.current.points)?_.current:null,g=_?.previous?.map_id===l&&Array.isArray(_.previous.points)?_.previous:null;if("always"===p&&g&&g.points.length>1){const e=g.points.map(([e,t])=>{const[i,s]=ep(c,e,t),n=this._scenePoint([i,s]);return n[0].toFixed(1)+","+n[1].toFixed(1)}).join(" ");o.push(W``)}if(u){const e=rp(r,m,h?.trail||[]),t=!d||"integration"!==e.source&&"server"!==e.source?e.path:lp(e.path);if(t.length){const e=t.map(e=>e.map(([e,t],i)=>{const[s,n]=ep(c,e,t),o=this._scenePoint([s,n]);return`${i?"L":"M"} ${o[0].toFixed(1)} ${o[1].toFixed(1)}`}).join(" ")).join(" ");o.push(W``);const s=t[t.length-1];if(d&&s?.length>=2){const e=s[s.length-1],[t,n]=ep(c,e[0],e[1]),a=this._scenePoint([t,n]),r=a[0].toFixed(1),l=a[1].toFixed(1);o.push(W``)}}}if(!d||!r.pos)continue;const[f,v]=ep(c,r.pos.x,r.pos.y),b=this._scenePoint([f,v]),y=(b[0]-t.x)/t.w*100,w=(b[1]-t.y)/t.h*100,k=h&&h.lastTs>0&&Date.now()-h.lastTs>6e4,x=i.marker?.icon||i.icon||"mdi:robot-vacuum";n.push(q`
${o}`:G} - ${n}`:G}_renderDevice(e,t,i=!0){const s=this._pos(e),n=this._scenePoint([s.x,s.y]),o=(n[0]-t.x)/t.w*100,a=(n[1]-t.y)/t.h*100,r=this._devicePresentation(e,i),l=[`left:${o}%`,`top:${a}%`,...Go(r)],c=r.disabledReason,h=r.haDisabled?this._t(`marker.ha_disabled_${c}`):e.userHidden?this._t("marker.hidden_ghost"):e.name,d=g_(r),p="view"===this._mode||"devices"===this._mode,u=[h,r.haDisabled?"":this._t(`marker.state_a11y_${d}`),"none"!==r.pulse.kind?this._t(`marker.pulse_a11y_${r.pulse.reason}`):"",r.valueFullText||r.valueText||"",Io(r.valueBadge),null!=r.lqiText&&r.lqiBand?this._t(`marker.lqi_a11y_${r.lqiBand}`,{value:r.lqiText}):""].filter(Boolean).join(", "),_=[e.model,r.valueBadge?.fullText||"",null!=r.lqiText?"LQI "+r.lqiText:""].filter(Boolean).join(" · ");return q`
`}_roomArea(e){const t=hi(e);if(!t)return null;const i=this._spaceModel();if(!i)return null;const s=this._spaceWalls.length&&e.id&&this._innerRoomContour(i,e.id)||t,n=this._cleanFloor(e,s),o=this._cellCm/this._gridPitch;return ir(n.area*o*o/1e4,"mi"===this._renderPlanHass?.config?.unit_system?.length)}_roomTemp(e){const t=e.settings?.temp_source;return t?Mo(this._renderPlanHass,t,"temp",this._markers):e.area?this._climate().get(e.area)?.temp??null:null}_roomHum(e){const t=e.settings?.hum_source;return t?Mo(this._renderPlanHass,t,"hum",this._markers):e.area?this._climate().get(e.area)?.hum??null:null}_climate(){const e=this._serverCfg?.markers,t=this._renderPlanHass,i=this._climateCache;if(i&&i.h===t&&i.r===this._iconRules&&i.mk===e)return i.m;const s=function(e,t,i){const s=new Map;if(!e?.entities)return s;const n=wo(i),o=new Set;for(const e of i||[]){if(e?.removed||!0!==e?.use_climate_temp)continue;const t=(e.binding||"").indexOf(":");t>0&&o.add(e.binding.slice(t+1))}const a=new Map;for(const[t,i]of Object.entries(e.entities)){if(i.device_id&&n.devices.has(i.device_id)&&!n.liveEntities.has(t)||!i.device_id&&n.entities.has(t)&&!n.liveEntities.has(t))continue;const s=i.device_id?e.devices?.[i.device_id]:null,r=i.area_id||s?.area_id||null;if(!r)continue;if(i.entity_category)continue;if(!(o.size>0&&t.startsWith("climate.")&&(o.has(t)||i.device_id&&o.has(i.device_id)))){if(Ye.has(i.platform))continue;if(Co.test(t))continue}let l=a.get(r);l||(l=new Map,a.set(r,l));const c=i.device_id||t;let h=l.get(c);if(!h){const n=e.states?.[t];h={name:(s?s.name_by_user||s.name:i.name||n?.attributes?.friendly_name||t)||t,model:s?.model,ents:[]},l.set(c,h)}h.ents.push(t)}for(const[i,n]of a){const a=[],r=[];for(const[i,s]of n){const n=yo(e,s.name,s.model,s.ents,t),l="mdi:thermometer"===n||"mdi:air-filter"===n;if(l){const t=mo(e,s.ents);null!=t&&a.push(t)}if(o.size>0&&(o.has(i)||s.ents.some(e=>o.has(e)))){const t=go(e,s.ents);null!=t&&a.push(t)}if(l||"mdi:water-percent"===n){const t=vo(e,s.ents);null!=t&&r.push(t)}}(a.length||r.length)&&s.set(i,{temp:a.length?Math.round(a.reduce((e,t)=>e+t,0)/a.length*10)/10:null,hum:r.length?Math.round(r.reduce((e,t)=>e+t,0)/r.length):null})}return s}(t,this._iconRules,e);return this._climateCache={h:t,r:this._iconRules,mk:e,m:s},s}_resetRoomDialogFields(){this._roomEditId=null,this._roomFill="",this._roomCustomFill=null,this._roomTempSrc="",this._roomHumSrc="",this._roomSrcOpen=null,this._roomSrcFilter="",this._roomNameScale=1,this._roomLabelScale=1}_openRoomEdit(e){if(!e.id)return;this._roomEditId=e.id,this._nameSel=e.name||"",this._areaSel=e.area||"",this._roomFill="glow"===e.settings?.fill_mode?"":e.settings?.fill_mode||"";const t=e.settings?.custom_fill;this._roomCustomFill=t&&"object"==typeof t?rs(t,cs(this._curSpaceCfg).customFill):null,this._roomTempSrc=e.settings?.temp_source||"",this._roomHumSrc=e.settings?.hum_source||"",this._roomNameScale=Ns(e.settings?.name_scale),this._roomLabelScale=Ns(e.settings?.label_scale),this._roomSrcOpen=null,this._roomSrcFilter="",this._roomDialog=!0}_roomSettingsFromDialog(){const e={};return this._roomFill&&(e.fill_mode=this._roomFill),this._roomCustomFill&&(e.custom_fill=this._roomCustomFill),this._roomTempSrc&&(e.temp_source=this._roomTempSrc),this._roomHumSrc&&(e.hum_source=this._roomHumSrc),1!==this._roomNameScale&&(e.name_scale=this._roomNameScale),1!==this._roomLabelScale&&(e.label_scale=this._roomLabelScale),Object.keys(e).length?e:null}_saveRoomEdit(){const e=this._curSpaceCfg,t=e?.rooms.find(e=>e.id===this._roomEditId);if(!t)return this._roomDialog=!1,void(this._roomEditId=null);t.name=this._nameSel.trim()||t.name,t.area=this._areaSel||null;const i=t.settings||{},s={...i};this._roomFill?s.fill_mode=this._roomFill:delete s.fill_mode,this._roomCustomFill?s.custom_fill=this._roomCustomFill:delete s.custom_fill,"glow"===i.fill_mode&&"boolean"!=typeof i.glow&&(s.glow=!0),this._roomTempSrc?s.temp_source=this._roomTempSrc:delete s.temp_source,this._roomHumSrc?s.hum_source=this._roomHumSrc:delete s.hum_source,1!==this._roomNameScale?s.name_scale=this._roomNameScale:delete s.name_scale,1!==this._roomLabelScale?s.label_scale=this._roomLabelScale:delete s.label_scale,Object.keys(s).length?t.settings=s:delete t.settings,this._saveConfig(),this._roomDialog=!1,this._roomEditId=null,this._nameSel="",this._areaSel="",this._regSignature="",this._maybeRebuildDevices(),this.requestUpdate(),this._showToast(this._t("toast.room_updated"))}_roomSrcCandidates(){const e=this._planHass,t=wo(this._markers),i=this._roomSrcFilter.trim().toLowerCase(),s=[];for(const n of Object.values(e.devices)){if("service"===n.entry_type)continue;if(t.devices.has(n.id))continue;const e=(n.name_by_user||n.name||n.id).trim();i&&!e.toLowerCase().includes(i)||s.push({value:"device:"+n.id,label:e,sub:n.model||this._t("marker.sub_device")})}for(const[n,o]of Object.entries(e.entities)){if(!n.startsWith("sensor.")||o.hidden)continue;if(ko(e,n,t))continue;const a=o.name||e.states[n]?.attributes?.friendly_name||n;i&&!(a+" "+n).toLowerCase().includes(i)||s.push({value:"entity:"+n,label:a,sub:n})}return s.sort((e,t)=>e.label.localeCompare(t.label)),s.slice(0,200)}_roomSrcLabel(e){const t=e.indexOf(":"),i=e.slice(0,t),s=e.slice(t+1);return"device"===i?this._fullRegistryHass.devices[s]?.name_by_user||this._fullRegistryHass.devices[s]?.name||s:this._fullRegistryHass.entities[s]?.name||this.hass.states[s]?.attributes?.friendly_name||s}_labelPos(e,t){const i=this._layout["rl_"+(e.id||"")];if(i&&i.s===t)return{x:i.x*Pv,y:i.y*Pv};const s=this._snap(this._roomCenter(e));return{x:s[0],y:s[1]}}_labelDown(e,t,i){if("plan"!==this._mode)return;e.preventDefault(),e.stopPropagation();const s=this._labelPos(t,i);this._drag={id:"rl_"+(t.id||""),sx:e.clientX,sy:e.clientY,ox:s.x,oy:s.y,moved:!1},Ev(e),this._tip=null}_labelMove(e,t,i){const s="rl_"+(t.id||"");if(!this._drag||this._drag.id!==s)return;const n=this._stageEl;if(!n)return;const o=this._spaceModelById(i);if(!o)return;const a=o.vb,r=n.getBoundingClientRect(),l=this._viewOr(a),c=(e.clientX-this._drag.sx)/r.width*l.w,h=(e.clientY-this._drag.sy)/r.height*l.h;Math.abs(e.clientX-this._drag.sx)+Math.abs(e.clientY-this._drag.sy)>3&&(this._drag.moved=!0);const d=Lh(this._drag.ox+c),p=Lh(this._drag.oy+h);this._savePos({id:s,space:i},d,p)}_labelUp(e){const t="rl_"+(e.id||"");if(!this._drag||this._drag.id!==t)return;const i=this._drag.moved;this._drag=i?this._drag:null,i&&window.setTimeout(()=>this._drag=null,0)}_labelScale(e){const t=this._layout["rl_"+(e.id||"")]?.k;return"number"==typeof t&&Number.isFinite(t)?Math.min(3,Math.max(.5,t)):1}_rlResizeDown(e,t,i){if("plan"!==this._mode)return;e.preventDefault(),e.stopPropagation();const s=e.target.closest(".roomlabel");if(!s)return;const n=s.getBoundingClientRect(),o=n.left+n.width/2,a=n.top+n.height/2,r=Math.max(8,Math.hypot(e.clientX-o,e.clientY-a));this._rlResize={id:"rl_"+(t.id||""),space:i,k0:this._labelScale(t),cx:o,cy:a,d0:r},Ev(e)}_rlResizeMove(e){const t=this._rlResize;if(!t)return;e.stopPropagation();const i=Math.max(8,Math.hypot(e.clientX-t.cx,e.clientY-t.cy)),s=Math.min(3,Math.max(.5,t.k0*(i/t.d0))),n=this._layout[t.id];if(n)this._layout={...this._layout,[t.id]:{...n,k:s}};else{const e=t.id.slice(3),i=this._spaceModelById(t.space);if(!i)return;const n=i.rooms.find(t=>t.id===e);if(!n)return;const o=this._labelPos(n,t.space);this._layout={...this._layout,[t.id]:{s:t.space,x:o.x/Pv,y:o.y/Pv,k:s}}}this._dirtyPos.add(t.id)}_rlResizeUp(){this._rlResize&&(this._rlResize=null,this._persistLayout())}_renderRoomGear(e,t,i){if(!e.id)return G;let s=null;if(e.poly?(s=this._gearPtCache.get(e.poly)||null,s||(s=$i(e.poly),this._gearPtCache.set(e.poly,s))):null!=e.x&&null!=e.y&&(s=[e.x+(e.w||0)/2,e.y+(e.h||0)/2]),!s)return G;const n=(s[0]-i.x)/i.w*100,o=(s[1]-i.y)/i.h*100;return q`
`}get _measureAnchor(){return this._markup&&this._cursorPt?"draw"===this._tool&&this._path.length&&!this._contourClosed?this._path[this._path.length-1]:"split"===this._tool&&this._splitSel?.pts?.length?this._splitSel.pts[this._splitSel.pts.length-1]:null:null}_renderMeasureLabel(e){const t=this._measureAnchor,i=this._cursorPt,s=(i[0]-e.x)/e.w*100,n=(i[1]-e.y)/e.h*100,o=Es(t,i),a=Math.round(10*o)/10,r=function(e,t,i=.001){if(e.length<2||t.length<2)return!1;const s=Math.abs(t[0]-e[0]),n=Math.abs(t[1]-e[1]);if(!Number.isFinite(s)||!Number.isFinite(n)||Math.hypot(s,n)<=i)return!1;const o=Math.max(s,n,1);return s<=i*o||n<=i*o||Math.abs(s-n)<=i*o}(t,i,2e-4*this._gridPitch);return q`
- ${this._fmtLen(t,i)} · ${a}°
`}get _decorMeasure(){const e=this._decorDraft;if(!e||"decor"!==this._mode)return null;const[t,i]=e.a,[s,n]=e.b;if(Math.abs(t-s)<1e-6&&Math.abs(i-n)<1e-6)return null;const o=(t+s)/2,a=(i+n)/2;if("line"===e.kind){const t=Es(e.a,e.b);return{x:o,y:a,on45:Os(t),text:`${this._fmtLen(e.a,e.b)} · ${Math.round(10*t)/10}°`}}const r=this._fmtLen([t,i],[s,i]),l=this._fmtLen([s,i],[s,n]);if("ellipse"===e.kind){const e=this._fmtLen([0,0],[Math.abs(s-t)/2,0]),r=this._fmtLen([0,0],[0,Math.abs(n-i)/2]);return{x:o,y:a,on45:!1,text:Math.abs(Math.abs(s-t)-Math.abs(n-i))<1e-6?`R ${e}`:`Rx ${e} × Ry ${r}`}}return{x:o,y:a,on45:!1,text:`${r} × ${l} · ${ir(Br(Math.abs(s-t),this._cellCm,this._gridPitch)*Br(Math.abs(n-i),this._cellCm,this._gridPitch)/1e4,this._imperial)}`}}get _alignPoint(){if(this._markup){if("draw"===this._tool&&this._path.length&&!this._contourClosed&&this._cursorPt)return this._cursorPt;if("split"===this._tool&&this._splitSel?.pts?.length&&this._cursorPt)return this._cursorPt;if(this._drag?.id.startsWith("rl_")&&this._drag.moved){const e=this._drag.id.slice(3),t=this._spaceModel()?.rooms.find(t=>t.id===e);return t?(()=>{const e=this._labelPos(t,this._space);return[e.x,e.y]})():null}return null}if("devices"===this._mode&&this._drag?.moved){const e=this._devices.find(e=>e.id===this._drag.id);return e?(()=>{const t=this._pos(e);return[t.x,t.y]})():null}if("decor"===this._mode){if(this._decorDraft)return this._decorDraft.b;if(this._decorMove){const e=this._decorList.find(e=>e.id===this._decorMove.id);if(!e)return null;const t=Pv,i=this._decorH;return"line"===e.kind?[e.x1*t,e.y1*i]:[e.x*t,e.y*i]}return null}return null}_alignCandidates(){const e=[],t=this._spaceModel();if(this._markup){if(!t)return e;if(this._drag?.id.startsWith("rl_")){const i=this._drag.id.slice(3);for(const s of t.rooms){if(!s.name||s.id===i)continue;const t=this._labelPos(s,this._space);e.push([t.x,t.y])}return e}for(const i of t.rooms){const t=hi(i);if(t)for(const i of t)e.push(i)}if("draw"===this._tool)for(const t of this._path)e.push(t);if("split"===this._tool&&this._splitSel?.pts)for(const t of this._splitSel.pts)e.push(t);return e}if("devices"===this._mode){for(const t of this._devices){if(t.space!==this._space||t.id===this._drag?.id||"ha_disabled"===t.bindingStatus?.kind)continue;const i=this._pos(t);e.push([i.x,i.y])}return e}if("decor"===this._mode){const t=this._decorMove?.id;return e.push(...this._decorSnapGeometry(t).points),this._decorDraft&&e.push(this._decorDraft.a),e}return e}_renderAlignGuides(){const e=this._alignPoint;if(!e)return W``;const t=this._drag?.id.startsWith("rl_")?.5*this._gridPitch:.05*this._gridPitch,i=function(e,t,i){let s=null,n=null;for(const o of t)if(!(Math.abs(o[0]-e[0])<1e-6&&Math.abs(o[1]-e[1])<1e-6)){if(Math.abs(o[0]-e[0])<=i){const t=Math.abs(o[1]-e[1]);t>1e-6&&(!s||t1e-6&&(!n||t + ${this._fmtLen(t,i)} · ${a}°
`}get _decorMeasure(){const e=this._decorDraft;if(!e||"decor"!==this._mode)return null;const[t,i]=e.a,[s,n]=e.b;if(Math.abs(t-s)<1e-6&&Math.abs(i-n)<1e-6)return null;const o=(t+s)/2,a=(i+n)/2;if("line"===e.kind){const t=Es(e.a,e.b);return{x:o,y:a,on45:Os(t),text:`${this._fmtLen(e.a,e.b)} · ${Math.round(10*t)/10}°`}}const r=this._fmtLen([t,i],[s,i]),l=this._fmtLen([s,i],[s,n]);if("ellipse"===e.kind){const e=this._fmtLen([0,0],[Math.abs(s-t)/2,0]),r=this._fmtLen([0,0],[0,Math.abs(n-i)/2]);return{x:o,y:a,on45:!1,text:Math.abs(Math.abs(s-t)-Math.abs(n-i))<1e-6?`R ${e}`:`Rx ${e} × Ry ${r}`}}return{x:o,y:a,on45:!1,text:`${r} × ${l} · ${rr(Gr(Math.abs(s-t),this._cellCm,this._gridPitch)*Gr(Math.abs(n-i),this._cellCm,this._gridPitch)/1e4,this._imperial)}`}}get _alignPoint(){if(this._markup){if("draw"===this._tool&&this._path.length&&!this._contourClosed&&this._cursorPt)return this._cursorPt;if("split"===this._tool&&this._splitSel?.pts?.length&&this._cursorPt)return this._cursorPt;if(this._drag?.id.startsWith("rl_")&&this._drag.moved){const e=this._drag.id.slice(3),t=this._spaceModel()?.rooms.find(t=>t.id===e);return t?(()=>{const e=this._labelPos(t,this._space);return[e.x,e.y]})():null}return null}if("devices"===this._mode&&this._drag?.moved){const e=this._devices.find(e=>e.id===this._drag.id);return e?(()=>{const t=this._pos(e);return[t.x,t.y]})():null}if("decor"===this._mode){if(this._decorDraft)return this._decorDraft.b;if(this._decorMove){const e=this._decorList.find(e=>e.id===this._decorMove.id);if(!e)return null;const t=zv,i=this._decorH;return"line"===e.kind?[e.x1*t,e.y1*i]:[e.x*t,e.y*i]}return null}return null}_alignCandidates(){const e=[],t=this._spaceModel();if(this._markup){if(!t)return e;if(this._drag?.id.startsWith("rl_")){const i=this._drag.id.slice(3);for(const s of t.rooms){if(!s.name||s.id===i)continue;const t=this._labelPos(s,this._space);e.push([t.x,t.y])}return e}for(const i of t.rooms){const t=hi(i);if(t)for(const i of t)e.push(i)}if("draw"===this._tool)for(const t of this._path)e.push(t);if("split"===this._tool&&this._splitSel?.pts)for(const t of this._splitSel.pts)e.push(t);return e}if("devices"===this._mode){for(const t of this._devices){if(t.space!==this._space||t.id===this._drag?.id||"ha_disabled"===t.bindingStatus?.kind)continue;const i=this._pos(t);e.push([i.x,i.y])}return e}if("decor"===this._mode){const t=this._decorMove?.id;return e.push(...this._decorSnapGeometry(t).points),this._decorDraft&&e.push(this._decorDraft.a),e}return e}_renderAlignGuides(){const e=this._alignPoint;if(!e)return W``;const t=this._drag?.id.startsWith("rl_")?.5*this._gridPitch:.05*this._gridPitch,i=function(e,t,i){let s=null,n=null;for(const o of t)if(!(Math.abs(o[0]-e[0])<1e-6&&Math.abs(o[1]-e[1])<1e-6)){if(Math.abs(o[0]-e[0])<=i){const t=Math.abs(o[1]-e[1]);t>1e-6&&(!s||t1e-6&&(!n||t ${i.map(t=>{const[i,o,a,r]="x"===t.axis?[t.at,t.from[1],t.at,e[1]+Math.sign(e[1]-t.from[1])*n]:[t.from[0],t.at,e[0]+Math.sign(e[0]-t.from[0])*n,t.at];return W` `})} - `}_renderOpeningCenterTick(e){const t=(e.angle+90)*Math.PI/180,i=xh(15,this._cellCm);return W``})} + `}_renderOpeningCenterTick(e){const t=(e.angle+90)*Math.PI/180,i=Dh(15,this._cellCm);return W``}_renderOpeningDimensionGuides(e){const t=e.labels.flatMap(e=>e.dimension?[e.dimension]:[]);if(!t.length)return W``;const i=this._cssPxToRender(4);return W``}_roomCenter(e){if(e.poly){const t=e.poly.length;return[e.poly.reduce((e,t)=>e+t[0],0)/t,e.poly.reduce((e,t)=>e+t[1],0)/t]}return[e.x+e.w/2,e.y+.1*Math.min(e.w,e.h)]}_openingAmt(e){const t=e.contact&&this._renderOpeningEntityAvailable(e.contact)?this._renderPlanHass.states[e.contact]?.state:null;return mi(e.type,t,!!e.invert)}_planEntityAvailable(e){return!!e&&(!ko(this._fullRegistryHass,e,wo(this._markers))&&"active"===this._bindingStatus("entity:"+e).kind)}_renderEntityAvailable(e){return!!e&&(!ko(this._renderPlanHass,e,wo(this._markers))&&(!!this._renderPlanHass.entities?.[e]&&!!this._renderPlanHass.states?.[e]))}_openingEntityAvailable(e){return function(e,t,i=An(e)){return!!t&&"active"===Bn(e,`entity:${t}`,i).kind}(this.hass,e,this._haRegistry)}_renderOpeningEntityAvailable(e){return t=this._renderPlanHass,!!(i=e)&&!!t?.states?.[i];var t,i}_renderOpeningPlacementPreview(){const e=this._openingPreview;if(!e)return W``;const t={type:e.type,length:e.renderedLength,angle:e.angle,amount:mi(e.type,null),flipH:e.flipH,flipV:e.flipV,base:"var(--hp-open)",tone:"var(--hp-open)",cellCm:this._cellCm,gridPitch:this._gridPitch,face:e.face},i="passage"===e.type?function(e,t){const i=Math.max(0,e.renderedLength)/2,s=Math.max(0,e.target.physicalHalfWidth),n=s+.18*Math.max(0,t),o=e=>({x1:e,y1:-n,x2:e,y2:n});return{rect:{x:-i,y:s?-s:0,width:2*i,height:2*s},boundaries:[o(-i),o(i)]}}(e,xh(this._gridPitch,this._cellCm)):null;return W``}_roomCenter(e){if(e.poly){const t=e.poly.length;return[e.poly.reduce((e,t)=>e+t[0],0)/t,e.poly.reduce((e,t)=>e+t[1],0)/t]}return[e.x+e.w/2,e.y+.1*Math.min(e.w,e.h)]}_openingAmt(e){const t=e.contact&&this._renderOpeningEntityAvailable(e.contact)?this._renderPlanHass.states[e.contact]?.state:null;return mi(e.type,t,!!e.invert)}_planEntityAvailable(e){return!!e&&(!ko(this._fullRegistryHass,e,wo(this._markers))&&"active"===this._bindingStatus("entity:"+e).kind)}_renderEntityAvailable(e){return!!e&&(!ko(this._renderPlanHass,e,wo(this._markers))&&(!!this._renderPlanHass.entities?.[e]&&!!this._renderPlanHass.states?.[e]))}_openingEntityAvailable(e){return function(e,t,i=An(e)){return!!t&&"active"===Bn(e,`entity:${t}`,i).kind}(this.hass,e,this._haRegistry)}_renderOpeningEntityAvailable(e){return t=this._renderPlanHass,!!(i=e)&&!!t?.states?.[i];var t,i}_renderOpeningPlacementPreview(){const e=this._openingPreview;if(!e)return W``;const t={type:e.type,length:e.renderedLength,angle:e.angle,amount:mi(e.type,null),flipH:e.flipH,flipV:e.flipV,base:"var(--hp-open)",tone:"var(--hp-open)",cellCm:this._cellCm,gridPitch:this._gridPitch,face:e.face},i="passage"===e.type?function(e,t){const i=Math.max(0,e.renderedLength)/2,s=Math.max(0,e.target.physicalHalfWidth),n=s+.18*Math.max(0,t),o=e=>({x1:e,y1:-n,x2:e,y2:n});return{rect:{x:-i,y:s?-s:0,width:2*i,height:2*s},boundaries:[o(-i),o(i)]}}(e,Dh(this._gridPitch,this._cellCm)):null;return W` `}_renderOpenings(e){const t=this._openingsR;if(!t.length)return W``;const i=this._spaceModel();if(!i)return W``;const s=e.color,n=this._spaceWalls,o=this._openCuts(),a=this._openingWallIndexFor(i,o).value;return W`${t.map(e=>{if(e.orphanReason)return W``}_renderOpenings(e){const t=this._openingsR;if(!t.length)return W``;const i=this._spaceModel();if(!i)return W``;const s=e.color,n=this._spaceWalls,o=this._openCuts(),a=this._openingWallIndexFor(i,o).value;return W`${t.map(e=>{if(e.orphanReason)return W`{t.stopPropagation(),this._editOpening(e)}}> - + ! - `;const t=this._openingAmt(e),i=t>0&&!!e.contact&&this._renderOpeningEntityAvailable(e.contact)?"var(--hp-open)":s,o="gate"===e.type?!e.flip_v:e.flip_v,r=e.partitionHost||n.length||"gate"===e.type?this._openingFace(e,a,!!o):{ox:0,oy:0,cm:0,side:-1},l={type:e.type,length:e.rlen,angle:e.angle,amount:t,flipH:!!e.flip_h,flipV:!!e.flip_v,base:s,tone:i,cellCm:this._cellCm,gridPitch:this._gridPitch,face:r},{half:c,outlineHalf:h,hitHalf:d}=d_(l),p=xh(10,this._cellCm),u=xh(12,this._cellCm);return W``;const t=this._openingAmt(e),i=t>0&&!!e.contact&&this._renderOpeningEntityAvailable(e.contact)?"var(--hp-open)":s,o="gate"===e.type?!e.flip_v:e.flip_v,r=e.partitionHost||n.length||"gate"===e.type?this._openingFace(e,a,!!o):{ox:0,oy:0,cm:0,side:-1},l={type:e.type,length:e.rlen,angle:e.angle,amount:t,flipH:!!e.flip_h,flipV:!!e.flip_v,base:s,tone:i,cellCm:this._cellCm,gridPitch:this._gridPitch,face:r},{half:c,outlineHalf:h,hitHalf:d}=g_(l),p=Dh(10,this._cellCm),u=Dh(12,this._cellCm);return W` - ${p_(l)} + ${f_(l)} + rx="${Dh(6,this._cellCm)}"> this._opClick(t,e)} @@ -6546,7 +6546,7 @@ globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="30d20d6f6822065e2d5226b18abbb05d8d26 @pointermove=${t=>this._opPointerMove(t,e)} @pointerup=${t=>this._opPointerUp(t,e)} @pointercancel=${t=>this._opPointerUp(t,e)}> - `})}`}_renderOpeningLocks(e){const t=this._openingsR.filter(e=>!e.orphanReason&&("door"===e.type||"gate"===e.type)&&e.lock&&this._renderOpeningEntityAvailable(e.lock));if(!t.length)return q``;const i=this._spaceModel();if(!i)return q``;const s=this._openCuts(),n=this._openingWallIndexFor(i,s).value;return q`${t.map(t=>{const i=this._renderPlanHass.states[t.lock]?.state,s="locked"===i,o=s||["unlocked","open","opening","unlocking","locking"].includes(String(i)),a=(t.angle+90)*Math.PI/180,r="gate"===t.type?this._openingFace(t,n,!t.flip_v):null,l=xh(16,this._cellCm),c=r?-l*r.side:l*(t.flip_v?-1:1),h=t.rx+Math.cos(a)*c,d=t.ry+Math.sin(a)*c,p=this._scenePoint([h,d]),u=(p[0]-e.x)/e.w*100,_=(p[1]-e.y)/e.h*100;return q`
`})}`}_renderOpeningLocks(e){const t=this._openingsR.filter(e=>!e.orphanReason&&("door"===e.type||"gate"===e.type)&&e.lock&&this._renderOpeningEntityAvailable(e.lock));if(!t.length)return q``;const i=this._spaceModel();if(!i)return q``;const s=this._openCuts(),n=this._openingWallIndexFor(i,s).value;return q`${t.map(t=>{const i=this._renderPlanHass.states[t.lock]?.state,s="locked"===i,o=s||["unlocked","open","opening","unlocking","locking"].includes(String(i)),a=(t.angle+90)*Math.PI/180,r="gate"===t.type?this._openingFace(t,n,!t.flip_v):null,l=Dh(16,this._cellCm),c=r?-l*r.side:l*(t.flip_v?-1:1),h=t.rx+Math.cos(a)*c,d=t.ry+Math.sin(a)*c,p=this._scenePoint([h,d]),u=(p[0]-e.x)/e.w*100,_=(p[1]-e.y)/e.h*100;return q`
{e.stopPropagation(),"view"===this._mode&&(this._openingInfo=t)}}>
- `}_renderOpeningDialog(){const e=this._openingDialog,t=this._spaceModel()?.partitions||[],i=e.id?this._curSpaceCfg?.openings?.find(t=>t.id===e.id):null,s={id:e.id||"preview",type:e.type,x:e.x/Pv,y:e.y/this._spaceH,angle:e.angle,length:i&&!e.lengthTouched?i.length:this._cmToUnits(Math.max(20,e.lengthCm))/Pv,...e.host?{host:e.host}:{}},n=Zp(i,s),o=e.host?n?Xp(s,t,Pv,this._cellCm,this._gridPitch):Jp(s,t,Pv,this._cellCm,this._gridPitch):null,a="does-not-fit-jamb"===o?.reason,r=e.host?t.find(t=>t.id===e.host.id):null,l=r?li(r.cm/2,this._imperial):"",c=!!e.host&&!o?.resolved&&!a,h="gate"===e.type?"mdi:gate":"window"===e.type?"mdi:window-closed-variant":"passage"===e.type?"mdi:arch":"mdi:door",d=(t,i)=>{const s="contact"===t?e.contact:e.lock,n="contact"===t?!!e.contactOpen:!!e.lockOpen,o="contact"===t?e.contactFilter||"":e.lockFilter||"",a=i.find(e=>e.value===s),r=a?.label||this.hass.states[s]?.attributes?.friendly_name||this._fullRegistryHass.entities[s]?.name||s,l=function(e,t,i=200){const s=t.trim().toLowerCase();return(s?e.filter(e=>e.label.toLowerCase().includes(s)||e.value.toLowerCase().includes(s)):e).slice(0,Math.max(0,i))}(i,o);return q` + `}_renderOpeningDialog(){const e=this._openingDialog,t=this._spaceModel()?.partitions||[],i=e.id?this._curSpaceCfg?.openings?.find(t=>t.id===e.id):null,s={id:e.id||"preview",type:e.type,x:e.x/zv,y:e.y/this._spaceH,angle:e.angle,length:i&&!e.lengthTouched?i.length:this._cmToUnits(Math.max(20,e.lengthCm))/zv,...e.host?{host:e.host}:{}},n=su(i,s),o=e.host?n?iu(s,t,zv,this._cellCm,this._gridPitch):tu(s,t,zv,this._cellCm,this._gridPitch):null,a="does-not-fit-jamb"===o?.reason,r=e.host?t.find(t=>t.id===e.host.id):null,l=r?li(r.cm/2,this._imperial):"",c=!!e.host&&!o?.resolved&&!a,h="gate"===e.type?"mdi:gate":"window"===e.type?"mdi:window-closed-variant":"passage"===e.type?"mdi:arch":"mdi:door",d=(t,i)=>{const s="contact"===t?e.contact:e.lock,n="contact"===t?!!e.contactOpen:!!e.lockOpen,o="contact"===t?e.contactFilter||"":e.lockFilter||"",a=i.find(e=>e.value===s),r=a?.label||this.hass.states[s]?.attributes?.friendly_name||this._fullRegistryHass.entities[s]?.name||s,l=function(e,t,i=200){const s=t.trim().toLowerCase();return(s?e.filter(e=>e.label.toLowerCase().includes(s)||e.value.toLowerCase().includes(s)):e).slice(0,Math.max(0,i))}(i,o);return q`
`:G} {const i=mv(t.target.value);null!=i&&(this._openingDialog={...e,lengthCm:i,lengthTouched:!0})}} /> + @input=${t=>{const i=yv(t.target.value);null!=i&&(this._openingDialog={...e,lengthCm:i,lengthTouched:!0})}} /> ${"passage"===e.type&&(e.contact||e.lock)?q`
@@ -6662,7 +6662,7 @@ globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="30d20d6f6822065e2d5226b18abbb05d8d26
- `}_gridLevels(){const e=this._stageEl,t=this._viewOr(this._baseVb()),i=e&&e.clientWidth&&t.w?e.clientWidth/t.w:1;return function(e,t,i=7){if(!(e>0&&t>0&&Number.isFinite(t)))return null;const s=td.find(s=>e*s*t>=i);if(void 0===s)return null;const n=td.find(e=>e>=5*s)??5*s;return{fine:s,coarse:n}}(this._gridPitch,i)}_renderMarkupDefs(e){const t=this._gridLevels();if(!t)return W``;const i=this._gridPitch*t.fine,s=this._gridPitch*t.coarse,n=this._gridPitch*t.fine*.14;return W` + `}_gridLevels(){const e=this._stageEl,t=this._viewOr(this._baseVb()),i=e&&e.clientWidth&&t.w?e.clientWidth/t.w:1;return function(e,t,i=7){if(!(e>0&&t>0&&Number.isFinite(t)))return null;const s=ad.find(s=>e*s*t>=i);if(void 0===s)return null;const n=ad.find(e=>e>=5*s)??5*s;return{fine:s,coarse:n}}(this._gridPitch,i)}_renderMarkupDefs(e){const t=this._gridLevels();if(!t)return W``;const i=this._gridPitch*t.fine,s=this._gridPitch*t.coarse,n=this._gridPitch*t.fine*.14;return W` @@ -6676,12 +6676,12 @@ globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="30d20d6f6822065e2d5226b18abbb05d8d26 - `}_renderPhysicalEditorLayer(){const e=this._spaceModel();if(!e)return W``;const t=this._gridPitch,i=this._viewOr(this._baseVb()),s=this._stageEl,n=s?.clientWidth?i.w/s.clientWidth:t/8,o=Math.max(.22*t,8*n),a=Math.max(o,12*n),r=e=>`M ${e.map(e=>`${e[0]} ${e[1]}`).join(" L ")} Z`,l=(e,t)=>this._physicalSel?.kind===e&&this._physicalSel.id===t||"column"===e&&this._duplicateColumnId===t,c=(e.room_drafts||[]).flatMap(e=>e.points.slice(0,-1).map((t,i)=>{const s=e.points[i+1],o=Number(e.segments[i]?.cm),a=wl(Number.isFinite(o)?o:15,this._cellCm,this._gridPitch);return W``}_renderPhysicalEditorLayer(){const e=this._spaceModel();if(!e)return W``;const t=this._gridPitch,i=this._viewOr(this._baseVb()),s=this._stageEl,n=s?.clientWidth?i.w/s.clientWidth:t/8,o=Math.max(.22*t,8*n),a=Math.max(o,12*n),r=e=>`M ${e.map(e=>`${e[0]} ${e[1]}`).join(" L ")} Z`,l=(e,t)=>this._physicalSel?.kind===e&&this._physicalSel.id===t||"column"===e&&this._duplicateColumnId===t,c=(e.room_drafts||[]).flatMap(e=>e.points.slice(0,-1).map((t,i)=>{const s=e.points[i+1],o=Number(e.segments[i]?.cm),a=Ml(Number.isFinite(o)?o:15,this._cellCm,this._gridPitch);return W`{this._physicalSel={kind:"draft",id:e.id,segment:i},this._registerPhysicalTap("draft",e.id,i)}}>`})),h=(e.partitions||[]).map(e=>{const t=oh(e.a,e.b,e.cm,this._cellCm,this._gridPitch);return t?W`{this._physicalSel={kind:"draft",id:e.id,segment:i},this._registerPhysicalTap("draft",e.id,i)}}>`})),h=(e.partitions||[]).map(e=>{const t=hh(e.a,e.b,e.cm,this._cellCm,this._gridPitch);return t?W`this._physicalDown(t,"partition",e.id)} @@ -6692,7 +6692,7 @@ globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="30d20d6f6822065e2d5226b18abbb05d8d26 stroke-width=${24} vector-effect="non-scaling-stroke" @pointerdown=${t=>this._physicalDown(t,"partition",e.id)} @pointermove=${e=>this._physicalMove(e)} - @pointerup=${e=>this._physicalUp(e)}>`}),d=(e.wall_columns||[]).map(e=>{const t=ah(this._physicalRotate?.id===e.id?{...e,angle:this._physicalRotate.angle}:e,this._cellCm,this._gridPitch);return W`this._physicalUp(e)}>`}),d=(e.wall_columns||[]).map(e=>{const t=dh(this._physicalRotate?.id===e.id?{...e,angle:this._physicalRotate.angle}:e,this._cellCm,this._gridPitch);return W`this._physicalDown(t,"column",e.id)} @@ -6700,20 +6700,20 @@ globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="30d20d6f6822065e2d5226b18abbb05d8d26 @pointerup=${e=>this._physicalUp(e)}>`}),p=this._physicalDrag,u=(()=>{if(!p?.moved)return G;if("partition"===p.kind&&0===Number(p.base.cm)){const e=p.base;return W``}const e="partition"===p.kind?oh(p.base.a,p.base.b,p.base.cm,this._cellCm,this._gridPitch):ah(p.base,this._cellCm,this._gridPitch);return e?W``}const e="partition"===p.kind?hh(p.base.a,p.base.b,p.base.cm,this._cellCm,this._gridPitch):dh(p.base,this._cellCm,this._gridPitch);return e?W``:G})(),_=(()=>{const i=this._physicalSel;if(!i)return G;if("draft"===i.kind){const t=e.room_drafts.find(e=>e.id===i.id);return t?W` e.join(",")).join(" ")}> ${t.points.map(e=>W``)} - `:G}if("partition"===i.kind){const t=e.partitions.find(e=>e.id===i.id);if(!t)return G;const s=oh(t.a,t.b,t.cm,this._cellCm,this._gridPitch),n=(t.a[0]+t.b[0])/2,a=(t.a[1]+t.b[1])/2;return W` + `:G}if("partition"===i.kind){const t=e.partitions.find(e=>e.id===i.id);if(!t)return G;const s=hh(t.a,t.b,t.cm,this._cellCm,this._gridPitch),n=(t.a[0]+t.b[0])/2,a=(t.a[1]+t.b[1])/2;return W` ${s?W``:W``} - `}const s=e.wall_columns.find(e=>e.id===i.id);if(!s)return G;const l=this._physicalRotate?.id===s.id?{...s,angle:this._physicalRotate.angle}:s,c=ah(l,this._cellCm,this._gridPitch);if("square"!==l.shape)return W` + `}const s=e.wall_columns.find(e=>e.id===i.id);if(!s)return G;const l=this._physicalRotate?.id===s.id?{...s,angle:this._physicalRotate.angle}:s,c=dh(l,this._cellCm,this._gridPitch);if("square"!==l.shape)return W` - `;const h=wl(l.cm,this._cellCm,this._gridPitch),d=eh(l.angle)*Math.PI/180,p=Math.sin(d),u=-Math.cos(d),_=[l.center[0]+p*h/2,l.center[1]+u*h/2],m=[_[0]+p*Math.max(t,24*n),_[1]+u*Math.max(t,24*n)];return W` + `;const h=Ml(l.cm,this._cellCm,this._gridPitch),d=oh(l.angle)*Math.PI/180,p=Math.sin(d),u=-Math.cos(d),_=[l.center[0]+p*h/2,l.center[1]+u*h/2],m=[_[0]+p*Math.max(t,24*n),_[1]+u*Math.max(t,24*n)];return W` @@ -6721,7 +6721,7 @@ globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="30d20d6f6822065e2d5226b18abbb05d8d26 data-kind="rotate" @pointerdown=${e=>this._physicalRotateDown(e,s)} @pointermove=${e=>this._physicalRotateMove(e)} @pointerup=${e=>this._physicalRotateUp(e)}>
- `})();return W`${c}${h}${d}${u}${_}`}_renderHiddenWallDiagnosticOverlay(){if(!this._markup)return W``;const e=this._hiddenWallDiagnosticSnapshot().value;if(!e.segments.length)return W``;const t=wl(5,this._cellCm,this._gridPitch);return W``})();return W`${c}${h}${d}${u}${_}`}_renderHiddenWallDiagnosticOverlay(){if(!this._markup)return W``;const e=this._hiddenWallDiagnosticSnapshot().value;if(!e.segments.length)return W``;const t=Ml(5,this._cellCm,this._gridPitch);return W``}_renderPlanSnapOverlay(){if(!this._markup)return W``;const e=this._planSnapGeometrySnapshot().value,t=this._activePlanSnapCandidate,i=new Set(this._activePlanSnapConflicts.map(e=>e.key)),s=wl(5,this._cellCm,this._gridPitch),n=wl(10,this._cellCm,this._gridPitch);return W``}_renderPlanSnapOverlay(){if(!this._markup)return W``;const e=this._planSnapGeometrySnapshot().value,t=this._activePlanSnapCandidate,i=new Set(this._activePlanSnapConflicts.map(e=>e.key)),s=Ml(5,this._cellCm,this._gridPitch),n=Ml(10,this._cellCm,this._gridPitch);return W``}_syncPlanSnapActiveMarker(e){const t=this.renderRoot?.querySelector('[data-hp="plan-snap-active-marker"]');if(t){if(t.setAttribute("class",`plan-snap-node${e?" active":""}${"line"===e?.kind?" dynamic":""}`),t.setAttribute("data-active",e?"true":"false"),t.setAttribute("visibility",e?"visible":"hidden"),!e)return t.removeAttribute("data-kind"),void t.removeAttribute("data-key");t.setAttribute("data-kind",e.kind),t.setAttribute("data-key",e.key),t.setAttribute("cx",String(e.point[0])),t.setAttribute("cy",String(e.point[1])),t.setAttribute("r",String(wl(10,this._cellCm,this._gridPitch)))}}_syncPlanSnapConflictMarkers(e){const t=new Set(e.map(e=>e.key));for(const e of this.renderRoot?.querySelectorAll('.plan-snap-node[data-kind="endpoint"]')||[])e.setAttribute("class","plan-snap-node"+(t.has(e.dataset.key||"")?" conflict":""))}_planSnapPhysicalSegment(e){let t=0;const i=this._spaceModel();if(!i)return null;if("partition"===e.sourceKind)t=Number(i.partitions.find(t=>t.id===e.sourceId)?.cm)||0;else if("draft"===e.sourceKind){const s=/^(.*):(\d+)$/.exec(e.sourceId),n=s?i.room_drafts.find(e=>e.id===s[1]):null;t=n&&s&&Number(n.segments[Number(s[2])]?.cm)||0}else t=bc(i.rooms,this._spaceWalls,this._openCuts(),[e.a[0],e.a[1],e.b[0],e.b[1]],this._wallKeyPitch,this._cellCm,this._gridPitch,Pv);return t>0?{a:[...e.a],b:[...e.b],halfDepth:wl(t,this._cellCm,this._gridPitch)/2}:null}_drawPreviewJoinPatchD(e,t){if(e.length<2)return"";const i=[];for(let s=0;s+10&&i.push({a:e[s],b:e[s+1],halfDepth:t[s]});if(!i.length)return"";const s=2e-4*this._gridPitch,n=this._planSnapGeometrySnapshot().value.segments.filter(t=>e.some(e=>Hs(e,[t.a[0],t.a[1],t.b[0],t.b[1]])<=s)).map(e=>this._planSnapPhysicalSegment(e)).filter(e=>!!e);return Yl([...i,...n],s).map(e=>`M ${e.map(e=>`${e[0]} ${e[1]}`).join(" L ")} Z`).join(" ")}_renderMarkupLayer(e){const t=this._openCuts(),i=this._thickWallCuts(),s=t.concat(i),n=s.length?Ds(this._segments,s,.02*this._gridPitch):this._segments,o=this._path,a=this._gridPitch,r=this._viewOr(this._baseVb()),l="draw"===this._tool?this._drawWallCm:null,c=(()=>"draw"===this._tool&&o.length&&null!=l?this._contourClosed?o:this._cursorPt?[...o,this._cursorPt]:o.length>=2?o:null:null)(),h=c?ku(c.length-1,this._contourClosed?[...this._draftSegmentCms,this._closingWallCm??void 0]:this._draftSegmentCms,l,ul).map(e=>wl(e,this._cellCm,this._gridPitch)/2):[],d=c?Jl(c,wl(l,this._cellCm,this._gridPitch)/2,this._contourClosed,h):"",p=c?this._drawPreviewJoinPatchD(c,h):"",u=this._wallFaceBatch?.candidates[this._wallFaceBatch.index]?.repair||this._wallRepairDiagnostic;return W` + `}_syncPlanSnapActiveMarker(e){const t=this.renderRoot?.querySelector('[data-hp="plan-snap-active-marker"]');if(t){if(t.setAttribute("class",`plan-snap-node${e?" active":""}${"line"===e?.kind?" dynamic":""}`),t.setAttribute("data-active",e?"true":"false"),t.setAttribute("visibility",e?"visible":"hidden"),!e)return t.removeAttribute("data-kind"),void t.removeAttribute("data-key");t.setAttribute("data-kind",e.kind),t.setAttribute("data-key",e.key),t.setAttribute("cx",String(e.point[0])),t.setAttribute("cy",String(e.point[1])),t.setAttribute("r",String(Ml(10,this._cellCm,this._gridPitch)))}}_syncPlanSnapConflictMarkers(e){const t=new Set(e.map(e=>e.key));for(const e of this.renderRoot?.querySelectorAll('.plan-snap-node[data-kind="endpoint"]')||[])e.setAttribute("class","plan-snap-node"+(t.has(e.dataset.key||"")?" conflict":""))}_planSnapPhysicalSegment(e){let t=0;const i=this._spaceModel();if(!i)return null;if("partition"===e.sourceKind)t=Number(i.partitions.find(t=>t.id===e.sourceId)?.cm)||0;else if("draft"===e.sourceKind){const s=/^(.*):(\d+)$/.exec(e.sourceId),n=s?i.room_drafts.find(e=>e.id===s[1]):null;t=n&&s&&Number(n.segments[Number(s[2])]?.cm)||0}else t=$c(i.rooms,this._spaceWalls,this._openCuts(),[e.a[0],e.a[1],e.b[0],e.b[1]],this._wallKeyPitch,this._cellCm,this._gridPitch,zv);return t>0?{a:[...e.a],b:[...e.b],halfDepth:Ml(t,this._cellCm,this._gridPitch)/2}:null}_drawPreviewJoinPatchD(e,t){if(e.length<2)return"";const i=[];for(let s=0;s+10&&i.push({a:e[s],b:e[s+1],halfDepth:t[s]});if(!i.length)return"";const s=2e-4*this._gridPitch,n=this._planSnapGeometrySnapshot().value.segments.filter(t=>e.some(e=>Hs(e,[t.a[0],t.a[1],t.b[0],t.b[1]])<=s)).map(e=>this._planSnapPhysicalSegment(e)).filter(e=>!!e);return ec([...i,...n],s).map(e=>`M ${e.map(e=>`${e[0]} ${e[1]}`).join(" L ")} Z`).join(" ")}_renderMarkupLayer(e){const t=this._openCuts(),i=this._thickWallCuts(),s=t.concat(i),n=s.length?Ds(this._segments,s,.02*this._gridPitch):this._segments,o=this._path,a=this._gridPitch,r=this._viewOr(this._baseVb()),l="draw"===this._tool?this._drawWallCm:null,c=(()=>"draw"===this._tool&&o.length&&null!=l?this._contourClosed?o:this._cursorPt?[...o,this._cursorPt]:o.length>=2?o:null:null)(),h=c?Cu(c.length-1,this._contourClosed?[...this._draftSegmentCms,this._closingWallCm??void 0]:this._draftSegmentCms,l,vl).map(e=>Ml(e,this._cellCm,this._gridPitch)/2):[],d=c?tc(c,Ml(l,this._cellCm,this._gridPitch)/2,this._contourClosed,h):"",p=c?this._drawPreviewJoinPatchD(c,h):"",u=this._wallFaceBatch?.candidates[this._wallFaceBatch.index]?.repair||this._wallRepairDiagnostic;return W` ${this._gridLevels()?W``:G} ${n.map(e=>W``)} ${this._renderPhysicalEditorLayer()} - ${"column"===this._tool&&this._cursorPt&&this._drawWallCm?W``M ${ah({shape:"square",center:this._cursorPt,cm:this._drawWallCm},this._cellCm,this._gridPitch).map(e=>`${e[0]} ${e[1]}`).join(" L ")} Z`)()}>`:G} + ${"column"===this._tool&&this._cursorPt&&this._drawWallCm?W``M ${dh({shape:"square",center:this._cursorPt,cm:this._drawWallCm},this._cellCm,this._gridPitch).map(e=>`${e[0]} ${e[1]}`).join(" L ")} Z`)()}>`:G} ${d?W` `:G} - ${c&&0===l?W`e.join(",")).join(" ")}>`:G} ${p?W` `:G} @@ -6772,7 +6772,7 @@ globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="30d20d6f6822065e2d5226b18abbb05d8d26 aria-hidden="true" pointer-events="none">`:G} ${"split"===this._tool&&this._splitSel?.pts?.length?W`${this._splitSel.pts.length>1?W``:G} ${this._splitSel.pts.map((e,t)=>W``)} + cx="${e[0]}" cy="${e[1]}" r="${Dh(.22*a,this._cellCm)}">`)} ${this._cursorPt?W``:G}`:G} `}_renderActiveChainInk(){const e=this._path,t=this._gridPitch;return W` @@ -6780,9 +6780,9 @@ globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="30d20d6f6822065e2d5226b18abbb05d8d26 ${e.length&&this._cursorPt&&"draw"===this._tool&&!this._contourClosed?W` ${this._activePlanSnapCandidate||this._activePlanSnapConflicts.length?G:W``}`:G} + r="${Dh(.22*t,this._cellCm)}" aria-hidden="true">`}`:G} ${e.map((e,i)=>W``)} + cx="${e[0]}" cy="${e[1]}" r="${Dh(.22*t,this._cellCm)}">`)} `}_renderPartitionDeleteDialog(){const e=this._partitionDeleteDialog,t="mi"===this.hass?.config?.unit_system?.length;return q`

${this._t("confirm.delete_partition_openings_body",{count:e.openings.length})}

    - ${e.openings.map(e=>q`
  • ${this._t("confirm.delete_partition_openings_item",{type:this._t(`opening.${e.type}`),length:li(e.length*Pv/this._gridPitch*this._cellCm,t)})}
  • `)} + ${e.openings.map(e=>q`
  • ${this._t("confirm.delete_partition_openings_item",{type:this._t(`opening.${e.type}`),length:li(e.length*zv/this._gridPitch*this._cellCm,t)})}
  • `)}
@@ -6833,8 +6833,8 @@ globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="30d20d6f6822065e2d5226b18abbb05d8d26 `:G}
this._physicalDialog={...e,cm:t.target.value}} /> ${this._t(this._imperial?"wallthick.unit_in":"wallthick.unit_cm")}
${t&&"square"===e.shape?q` @@ -7077,7 +7077,7 @@ globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="30d20d6f6822065e2d5226b18abbb05d8d26 `:G}
- `}_markerValueBadgeFields(e){return(t={touched:e.valueBadgeTouched,originalHas:e.originalHasValueBadge,original:e.originalValueBadge,enabled:e.valueBadgeEnabled,source:e.valueBadgeSource,position:e.valueBadgePosition}).touched?{value_badge:{enabled:t.enabled,source:t.source,position:t.position}}:t.originalHas?{value_badge:t.original}:{};var t}_markerDraft(e){if("ha"===e.bindingMode&&(!e.binding||"virtual"===e.binding))return null;const t=js(e.room),i=Fi(e.binding,e.devId,()=>"__hp_device_preview__"),s=this._markers.find(t=>t.id===i||t.id===e.devId),n=Zn(e.binding,e.controls,this._bindingEntities(e.binding)),o=this._effectiveStoredTapAction(e),a={id:i,binding:e.binding,name:e.name.trim()||null,icon:e.icon||null,display:"badge"!==e.display?e.display:null,ripple_color:"icon_ripple"===e.display&&e.rippleColor?e.rippleColor:null,ripple_size:"icon_ripple"===e.display&&1.5!==e.rippleSize?e.rippleSize:null,size:1!==e.size?e.size:null,angle:e.angle||null,...this._markerTapActionFields(e),...this._markerToggleEntityFields(e),tap_target:"run"===o&&e.tapTarget||null,tap_confirm:!!e.tapConfirm||null,controls:n.length?n:null,...this._markerLightFields(e),...this._markerValueBadgeFields(e),use_climate_temp:!!e.useClimateTemp||null,glow_radius_cm:(()=>{const t=mv(e.glowRadius);return null==t||t<=0?null:Math.round(this._imperial?30.48*t:100*t)})(),model:e.model.trim()||null,link:e.link.trim()||null,description:e.description.trim()||null,pdfs:e.pdfs,hidden:e.hideFromPlan,vacuum:s?.vacuum||null};return("virtual"===e.binding||e.room)&&(a.space=t?.space||("virtual"===e.binding?this._space:null),a.area=t?.area||null,a.room_id=t?.roomId||null),a}_markerPreviewDevice(e){const t=this._markerDraft(e);if(!t)return null;const i=`${this._haRegistry.revision}\n${Bd(this._markers)}\n${JSON.stringify(t)}`;if(this._markerPreviewMemo?.key===i)return this._markerPreviewMemo.device;const s=function(e){const{marker:t,siblingMarkers:i=[],...s}=e;return So({...s,markers:[...i.filter(e=>e.id!==t.id),t]}).find(e=>e.id===t.id)||null}({hass:this.hass,registry:this._haRegistry,areaToSpace:Object.fromEntries(Object.entries(this._areaToSpace).map(([e,t])=>[e,t.space])),marker:t,siblingMarkers:this._markers,settings:this._settings,excluded:this._excluded,showAll:this._showAll,firstSpaceId:this._model[0]?.id||this._space,loc:e=>this._t(e),iconRules:this._iconRules});return this._markerPreviewMemo={key:i,device:s},s}_markerPreviewDevices(e){const t=this._markerPreviewDevicesMemo;if(t?.base===this._devices&&t.preview===e)return t.devices;const i=[...this._devices.filter(t=>t.id!==e.id),e];return this._markerPreviewDevicesMemo={base:this._devices,preview:e,devices:i},i}_toggleIntent(e,t=this._devices){return jp({hass:this._planHass,registryHass:this._fullRegistryHass,devices:t,device:e,virtualLights:this._virtualLights})}_toggleIntentForDialog(e){const t=this._markerPreviewDevice(e);if(!t)return null;const i=this._markerPreviewDevices(t);return this._toggleIntent(t,i)}_toggleStateText(e,t){const i=this._planHass?.states?.[e]||this.hass?.states?.[e];try{return i&&"function"==typeof this.hass?.formatEntityState?this.hass.formatEntityState(i):t}catch{return t}}_toggleConfirmationStateText(e){const t=String(e.state||"unknown"),i=e.entityId?this._toggleStateText(e.entityId,t):t;if(i.trim().toLocaleLowerCase()!==t.trim().toLocaleLowerCase())return i;const s={on:"confirm.state_on",off:"confirm.state_off",open:"confirm.state_open",closed:"confirm.state_closed",opening:"confirm.state_opening",closing:"confirm.state_closing",unknown:"confirm.state_unknown"}[t];return s?this._t(s):t.replaceAll("_"," ").replaceAll("-"," ")}_toggleConfirmationLines(e){const t={"turn-on":"confirm.state_on","turn-off":"confirm.state_off",open:"confirm.state_open",close:"confirm.state_closed",stop:"confirm.state_stopped"};return function(e,t){if(!Wp(e)||!e.nextEffect||!e.targets.length)return[];const i="group"===e.kind,s=i?e.targets.filter(e=>"on"===e.state).length:0,n=i?0===s?t.groupAllOff():t.groupCurrent(s,e.targets.length):t.state(e.targets[0]);let o;return o="toggle"===e.nextEffect?t.expectedByHa():i&&"turn-on"===e.nextEffect?t.groupAllOn():i&&"turn-off"===e.nextEffect?t.groupAllOff():t.effect(e.nextEffect),[t.current(n),t.expected(o),...e.skippedTargets.length?[t.unavailable(e.skippedTargets.length)]:[]]}(e,{state:e=>this._toggleConfirmationStateText(e),current:e=>this._t("confirm.current_state",{state:e}),expected:e=>this._t("confirm.expected_state",{state:e}),groupCurrent:(e,t)=>this._t("confirm.group_current",{on:e,total:t}),groupAllOn:()=>this._t("confirm.group_all_on"),groupAllOff:()=>this._t("confirm.group_all_off"),unavailable:e=>this._t("confirm.unavailable_targets",{count:e}),effect:e=>this._t(t[e]),expectedByHa:()=>this._t("confirm.expected_by_ha")})}_toggleHintLines(e){if(!e)return[];const t=e=>this._t(`marker.toggle_effect_${e.replace("-","_")}`),i=e=>this._t(`marker.toggle_skip_${e.replace("-","_")}`);return function(e,t){const i=e.targets[0]||e.skippedTargets[0],s=[];return"group"===e.kind?e.targets.length&&s.push(t.group(e.targets)):i&&s.push(t.single(i)),e.nextEffect&&e.targets.length&&s.push("group"===e.kind?t.groupCurrentNext(e.targets,e.nextEffect):t.currentNext(e.targets[0],e.nextEffect)),e.skippedTargets.length&&s.push(t.skipped(e.skippedTargets)),!e.command&&e.noneReason&&s.push(t.none(e.noneReason)),s}(e,{single:e=>{if("via"in e&&"virtual-light"===e.via)return this._t("marker.virtual_light_target",{name:e.name});const t=e.entityId||("ref"in e?e.ref:""),i=e.name||t;return this._t("marker.toggle_hint_single",{name:i,id:t})},group:e=>this._t("marker.toggle_hint_group",{count:e.length,names:e.map(e=>`${e.name} (${e.entityId})`).join(", ")}),currentNext:(e,i)=>"virtual-light"===e.via?this._t("marker.virtual_light_current",{state:this._t("on"===e.state?"marker.virtual_light_state_on":"marker.virtual_light_state_off"),effect:t(i)}):this._t("marker.toggle_hint_current",{state:this._toggleStateText(e.entityId,e.state),effect:t(i)}),groupCurrentNext:(e,i)=>this._t("marker.toggle_hint_group_current",{on:e.filter(e=>"on"===e.state).length,count:e.length,effect:t(i)}),skipped:e=>this._t("marker.toggle_hint_skipped",{count:e.length,targets:e.map(e=>{const t=e.entityId||e.ref;return`${e.name||t} (${t}: ${i(e.reason)})`}).join(", ")}),none:e=>this._t(`marker.toggle_none_${e.replaceAll("-","_")}`)})}_effectiveStoredTapAction(e,t){return e.tapActionTouched?e.tapAction:Op(e.originalHasTapAction?e.originalTapAction:null,t)}_effectiveMarkerTapAction(e,t=this._markerPreviewDevice(e)){return this._effectiveStoredTapAction(e,t?.primary?.split(".")[0])}_announceToggleDraft(e){const t=this._markerPreviewDevice(e),i=e.tapActionTouched?e:{...e,tapAction:this._effectiveMarkerTapAction(e,t)},s="toggle"===i.tapAction?this._toggleHintLines(this._toggleIntentForDialog(i)).join(" "):"";return{...i,tapHintAnnouncement:s}}_valueBadgeForBinding(e,t){const i={...e,binding:t,valueBadgeEnabled:!1,valueBadgeSource:null,valueBadgeTouched:!0},s=this._markerPreviewDevice(i);if(!s)return{valueBadgeEnabled:!1,valueBadgeSource:null,valueBadgeTouched:!0};const n=[...this._devices.filter(e=>e.id!==s.id),s],o=qo(this._planHass,s,n),a=Wo(this._planHass,s,o);return{valueBadgeEnabled:e.valueBadgeEnabled&&!!a,valueBadgeSource:a,valueBadgeTouched:!0}}_markerSpatialSource(e){const t=this._markerPreviewDevice(e);if(!t)return null;const i={...t,hidden:!1};return po(ho(this._planHass,[...this._devices.filter(e=>e.id!==i.id),i],null,this._virtualLights).filter(e=>e.device.id===i.id))}_markerAutoHasSpatialSource(e){const t={...e,lightRole:"auto",lightRoleTouched:!0},i=this._markerPreviewDevice(t);return!!i&&lo(this._planHass,{...i})}_setMarkerLightRole(e){const t=this._markerDialog;t&&(this._markerDialog={...t,lightRole:e,lightRoleTouched:!0})}_controlRefInfo(e){if(!e.startsWith("marker:"))return{label:this.hass.states[e]?.attributes?.friendly_name||e,sub:e,icon:e.startsWith("light.")?"mdi:lightbulb":"mdi:toggle-switch",warning:!this._planEntityAvailable(e)};const t=e.slice(7),i=this._markers.find(e=>e.id===t),s=this._devices.find(e=>e.id===t);if(!i||i.removed||!0!==i.is_light)return{label:this._t("marker.control_missing_label"),sub:`${this._t("marker.control_broken")} (${e})`,icon:"mdi:alert-outline",warning:!0};const n=this._serverCfg?.spaces.find(e=>e.id===(s?.space||i.space)),o=!!s&&eo(s).length>0;return{label:i.name||s?.name||t,sub:[n?.title||s?.space||i.space,i.room_id||s?.area,o?"":this._t("marker.control_passive")].filter(Boolean).join(" · "),icon:i.icon||s?.icon||"mdi:lightbulb-outline",warning:!0===i.hidden||!0===s?.hidden}}_valueBadgeCandidateLabel(e){const t=e.source;if("derived_lqi"===t.kind)return this._t("marker.value_badge_lqi");if("derived_marker_state"===t.kind)return this._t("marker.value_badge_marker_state",{name:e.label});if("entity_state"===t.kind)return this._t("marker.value_badge_state",{name:e.label});const i=this.hass.states[t.entity_id]?.attributes?.friendly_name||this._fullRegistryHass.entities[t.entity_id]?.name||t.entity_id;return this._t(`marker.value_badge_attr_${t.attribute}`,{name:i})}_controlCandidates(e){const t=this._markerDraft(e)?.id||e.devId||"",i=[],s=new Set;for(const e of this._markers){if(e.id===t||e.removed||e.hidden||!0!==e.is_light)continue;if("virtual"!==e.binding&&"active"!==this._bindingStatus(e.binding).kind)continue;const n=this._devices.find(t=>t.id===e.id);if(!n||n.hidden)continue;const o=this._controlRefInfo(`marker:${e.id}`);for(const e of eo(n))s.add(e);i.push({value:`marker:${e.id}`,label:o.label,sub:o.sub,icon:o.icon,search:`${o.label} ${o.sub} ${e.id} ${eo(n).join(" ")}`.toLowerCase()})}const n=Object.keys(this.hass.states||{}).filter(t=>Ms(t)&&!s.has(t)&&Xn(e.binding,[t],this._bindingEntities(e.binding)).length>0&&this._planEntityAvailable(t)).map(e=>{const t=this._controlRefInfo(e);return{value:e,label:t.label,sub:e,icon:t.icon,search:`${t.label} ${e}`.toLowerCase()}}),o=e.controlsFilter.trim().toLowerCase();return[...i,...n].filter(t=>!e.controls.includes(t.value)&&(!o||t.search.includes(o))).slice(0,12).map(({search:e,...t})=>t)}_addControlRef(e,t){if(t.startsWith("marker:")){const i=this._markerDraft(e)?.id||e.devId||"";if(!i)return void this._showToast(this._t("toast.marker_binding_required"));const s=t.slice(7),n=this._markerDraft(e);if(function(e,t,i){if(!t||t===i)return!0;const s=new Map;for(const t of e)s.set(t.id,(t.controls||[]).filter(e=>"string"==typeof e&&e.startsWith("marker:")).map(e=>e.slice(7)));const n=new Set,o=[i];for(;o.length;){const e=o.pop();if(e===t)return!0;n.has(e)||(n.add(e),o.push(...s.get(e)||[]))}return!1}(n?[...this._markers.filter(e=>e.id!==i),n]:this._markers,i,s))return void this._showToast(this._t("toast.marker_control_cycle"))}this._markerDialog=this._announceToggleDraft({...e,controls:[...e.controls,t],controlsFilter:""})}_setMarkerGlowMode(e){const t=this._markerDialog;if(!t)return;if("auto"===e)return void(this._markerDialog={...t,glowMode:e,glowTouched:!0});const i=this._markerSpatialSource(t),s=xs(i?this._planHass.states[i.eid]:void 0,null,this._fillColors.glow_light.c),n=!t.glowColorDrafted,o="fixed"===e&&!t.glowBrightnessDrafted;this._markerDialog={...t,glowMode:e,glowColor:n?s.c:t.glowColor,glowBrightness:o?Math.max(1,Math.round(100*s.bri)):t.glowBrightness,glowColorDrafted:!0,glowBrightnessDrafted:t.glowBrightnessDrafted||"fixed"===e,glowTouched:!0}}_renderMarkerDialog(){const e=this._markerDialog,t="virtual"===e.bindingMode,i=this._bindingCandidates();this._bindingEntities(e.binding);const s=t?null:this._bindingStatus(e.binding),n=!t&&this._bindingHasHaPage(e.binding),o=this._markerPreviewDevice(e),a=this._effectiveMarkerTapAction(e,o),r=o?cs(this._serverCfg?.spaces.find(e=>e.id===o.space)):null,l=o?this._markerPreviewDevices(o):this._devices,c="toggle"===a&&o?this._toggleIntent(o,l):null,h=this._toggleHintLines(c),d=o?C_(this._planHass,o,{liveStates:!1!==this._config?.live_states,showTemperature:!1!==this._config?.show_temperature,showSignal:r?.showLqi??!1!==this._config?.show_signal,designPreview:!0,activityRuntime:this._activityRt.get(o.id),lightDevices:l,registryHass:this._fullRegistryHass,reducedMotion:this._reducedMotion}):null,p=o?qo(this._planHass,o,l):[],u=o?Wo(this._planHass,o,p):null,_=e.valueBadgeTouched?e.valueBadgeEnabled:!!d?.valueBadge,m=e.valueBadgeTouched?e.valueBadgeSource:d?.valueBadge?.source||e.valueBadgeSource,g=e.valueBadgeTouched?e.valueBadgePosition:d?.valueBadge?.position||e.valueBadgePosition,f=Ao(m),v=!!m&&!p.some(e=>e.key===f),b=p.find(e=>e.key===f),y=d?.valueSource?d.valueSource.attribute?`attr:${d.valueSource.eid}:${d.valueSource.attribute}`:`state:${d.valueSource.eid}`:"",w=this._markerAutoHasSpatialSource(e),k=!!o&&function(e,t){return io(e,t).some(e=>!!e.eid)}(this._planHass,{...o}),x=function(e,t,i,s){const n="always"===e||"auto"===e&&t,o=n&&!i;return{sourceExists:n,fromSourceEnabled:n&&i,manualEnabled:n,radiusEnabled:n,passive:o,effectiveMode:o&&"auto"===s?"fixed":s}}(e.lightRole,w,k,e.glowMode),$=!x.sourceExists,S=!x.fromSourceEnabled,M=x.passive,C=x.effectiveMode,D="never"===e.lightRole?this._t("marker.glow_disabled_never"):"auto"!==e.lightRole||w?M?this._t("marker.glow_passive_hint"):this._t("marker.glow_disabled_no_entity"):this._t("marker.glow_disabled_auto"),P=o?eo(o):[],T=o&&to(o)||"",I=!!e.lightEntity&&!P.includes(e.lightEntity),R=o?Ap(o):[],A=!!e.toggleEntity&&!R.includes(e.toggleEntity),z="toggle"===a?this._toggleIntentForDialog({...e,toggleEntity:"",toggleEntityTouched:!0}):null,F=z?[...z.targets,...z.skippedTargets].map(e=>e.entityId||("ref"in e?e.ref:"")).filter(Boolean).join(", "):"",N=(()=>{if(t)return null;const s=i.find(t=>t.value===e.binding);if(s)return s.label;const[n,o]=e.binding.split(":");return"device"===n?this._fullRegistryHass.devices[o]?.name_by_user||this._fullRegistryHass.devices[o]?.name||o:this._fullRegistryHass.entities[o]?.name||this.hass.states[o]?.attributes?.friendly_name||o})();return q``}_markerValueBadgeFields(e){return(t={touched:e.valueBadgeTouched,originalHas:e.originalHasValueBadge,original:e.originalValueBadge,enabled:e.valueBadgeEnabled,source:e.valueBadgeSource,position:e.valueBadgePosition}).touched?{value_badge:{enabled:t.enabled,source:t.source,position:t.position}}:t.originalHas?{value_badge:t.original}:{};var t}_markerDraft(e){if("ha"===e.bindingMode&&(!e.binding||"virtual"===e.binding))return null;const t=js(e.room),i=Fi(e.binding,e.devId,()=>"__hp_device_preview__"),s=this._markers.find(t=>t.id===i||t.id===e.devId),n=Zn(e.binding,e.controls,this._bindingEntities(e.binding)),o=this._effectiveStoredTapAction(e),a={id:i,binding:e.binding,name:e.name.trim()||null,icon:e.icon||null,display:"badge"!==e.display?e.display:null,ripple_color:"icon_ripple"===e.display&&e.rippleColor?e.rippleColor:null,ripple_size:"icon_ripple"===e.display&&1.5!==e.rippleSize?e.rippleSize:null,size:1!==e.size?e.size:null,angle:e.angle||null,...this._markerTapActionFields(e),...this._markerToggleEntityFields(e),tap_target:"run"===o&&e.tapTarget||null,tap_confirm:!!e.tapConfirm||null,controls:n.length?n:null,...this._markerLightFields(e),...this._markerValueBadgeFields(e),use_climate_temp:!!e.useClimateTemp||null,glow_radius_cm:(()=>{const t=yv(e.glowRadius);return null==t||t<=0?null:Math.round(this._imperial?30.48*t:100*t)})(),model:e.model.trim()||null,link:e.link.trim()||null,description:e.description.trim()||null,pdfs:e.pdfs,hidden:e.hideFromPlan,vacuum:s?.vacuum||null};return("virtual"===e.binding||e.room)&&(a.space=t?.space||("virtual"===e.binding?this._space:null),a.area=t?.area||null,a.room_id=t?.roomId||null),a}_markerPreviewDevice(e){const t=this._markerDraft(e);if(!t)return null;const i=`${this._haRegistry.revision}\n${Gd(this._markers)}\n${JSON.stringify(t)}`;if(this._markerPreviewMemo?.key===i)return this._markerPreviewMemo.device;const s=function(e){const{marker:t,siblingMarkers:i=[],...s}=e;return So({...s,markers:[...i.filter(e=>e.id!==t.id),t]}).find(e=>e.id===t.id)||null}({hass:this.hass,registry:this._haRegistry,areaToSpace:Object.fromEntries(Object.entries(this._areaToSpace).map(([e,t])=>[e,t.space])),marker:t,siblingMarkers:this._markers,settings:this._settings,excluded:this._excluded,showAll:this._showAll,firstSpaceId:this._model[0]?.id||this._space,loc:e=>this._t(e),iconRules:this._iconRules});return this._markerPreviewMemo={key:i,device:s},s}_markerPreviewDevices(e){const t=this._markerPreviewDevicesMemo;if(t?.base===this._devices&&t.preview===e)return t.devices;const i=[...this._devices.filter(t=>t.id!==e.id),e];return this._markerPreviewDevicesMemo={base:this._devices,preview:e,devices:i},i}_toggleIntent(e,t=this._devices){return Vp({hass:this._planHass,registryHass:this._fullRegistryHass,devices:t,device:e,virtualLights:this._virtualLights})}_toggleIntentForDialog(e){const t=this._markerPreviewDevice(e);if(!t)return null;const i=this._markerPreviewDevices(t);return this._toggleIntent(t,i)}_toggleStateText(e,t){const i=this._planHass?.states?.[e]||this.hass?.states?.[e];try{return i&&"function"==typeof this.hass?.formatEntityState?this.hass.formatEntityState(i):t}catch{return t}}_toggleConfirmationStateText(e){const t=String(e.state||"unknown"),i=e.entityId?this._toggleStateText(e.entityId,t):t;if(i.trim().toLocaleLowerCase()!==t.trim().toLocaleLowerCase())return i;const s={on:"confirm.state_on",off:"confirm.state_off",open:"confirm.state_open",closed:"confirm.state_closed",opening:"confirm.state_opening",closing:"confirm.state_closing",unknown:"confirm.state_unknown"}[t];return s?this._t(s):t.replaceAll("_"," ").replaceAll("-"," ")}_toggleConfirmationLines(e){const t={"turn-on":"confirm.state_on","turn-off":"confirm.state_off",open:"confirm.state_open",close:"confirm.state_closed",stop:"confirm.state_stopped"};return function(e,t){if(!Yp(e)||!e.nextEffect||!e.targets.length)return[];const i="group"===e.kind,s=i?e.targets.filter(e=>"on"===e.state).length:0,n=i?0===s?t.groupAllOff():t.groupCurrent(s,e.targets.length):t.state(e.targets[0]);let o;return o="toggle"===e.nextEffect?t.expectedByHa():i&&"turn-on"===e.nextEffect?t.groupAllOn():i&&"turn-off"===e.nextEffect?t.groupAllOff():t.effect(e.nextEffect),[t.current(n),t.expected(o),...e.skippedTargets.length?[t.unavailable(e.skippedTargets.length)]:[]]}(e,{state:e=>this._toggleConfirmationStateText(e),current:e=>this._t("confirm.current_state",{state:e}),expected:e=>this._t("confirm.expected_state",{state:e}),groupCurrent:(e,t)=>this._t("confirm.group_current",{on:e,total:t}),groupAllOn:()=>this._t("confirm.group_all_on"),groupAllOff:()=>this._t("confirm.group_all_off"),unavailable:e=>this._t("confirm.unavailable_targets",{count:e}),effect:e=>this._t(t[e]),expectedByHa:()=>this._t("confirm.expected_by_ha")})}_toggleHintLines(e){if(!e)return[];const t=e=>this._t(`marker.toggle_effect_${e.replace("-","_")}`),i=e=>this._t(`marker.toggle_skip_${e.replace("-","_")}`);return function(e,t){const i=e.targets[0]||e.skippedTargets[0],s=[];return"group"===e.kind?e.targets.length&&s.push(t.group(e.targets)):i&&s.push(t.single(i)),e.nextEffect&&e.targets.length&&s.push("group"===e.kind?t.groupCurrentNext(e.targets,e.nextEffect):t.currentNext(e.targets[0],e.nextEffect)),e.skippedTargets.length&&s.push(t.skipped(e.skippedTargets)),!e.command&&e.noneReason&&s.push(t.none(e.noneReason)),s}(e,{single:e=>{if("via"in e&&"virtual-light"===e.via)return this._t("marker.virtual_light_target",{name:e.name});const t=e.entityId||("ref"in e?e.ref:""),i=e.name||t;return this._t("marker.toggle_hint_single",{name:i,id:t})},group:e=>this._t("marker.toggle_hint_group",{count:e.length,names:e.map(e=>`${e.name} (${e.entityId})`).join(", ")}),currentNext:(e,i)=>"virtual-light"===e.via?this._t("marker.virtual_light_current",{state:this._t("on"===e.state?"marker.virtual_light_state_on":"marker.virtual_light_state_off"),effect:t(i)}):this._t("marker.toggle_hint_current",{state:this._toggleStateText(e.entityId,e.state),effect:t(i)}),groupCurrentNext:(e,i)=>this._t("marker.toggle_hint_group_current",{on:e.filter(e=>"on"===e.state).length,count:e.length,effect:t(i)}),skipped:e=>this._t("marker.toggle_hint_skipped",{count:e.length,targets:e.map(e=>{const t=e.entityId||e.ref;return`${e.name||t} (${t}: ${i(e.reason)})`}).join(", ")}),none:e=>this._t(`marker.toggle_none_${e.replaceAll("-","_")}`)})}_effectiveStoredTapAction(e,t){return e.tapActionTouched?e.tapAction:qp(e.originalHasTapAction?e.originalTapAction:null,t)}_effectiveMarkerTapAction(e,t=this._markerPreviewDevice(e)){return this._effectiveStoredTapAction(e,t?.primary?.split(".")[0])}_announceToggleDraft(e){const t=this._markerPreviewDevice(e),i=e.tapActionTouched?e:{...e,tapAction:this._effectiveMarkerTapAction(e,t)},s="toggle"===i.tapAction?this._toggleHintLines(this._toggleIntentForDialog(i)).join(" "):"";return{...i,tapHintAnnouncement:s}}_valueBadgeForBinding(e,t){const i={...e,binding:t,valueBadgeEnabled:!1,valueBadgeSource:null,valueBadgeTouched:!0},s=this._markerPreviewDevice(i);if(!s)return{valueBadgeEnabled:!1,valueBadgeSource:null,valueBadgeTouched:!0};const n=[...this._devices.filter(e=>e.id!==s.id),s],o=qo(this._planHass,s,n),a=Wo(this._planHass,s,o);return{valueBadgeEnabled:e.valueBadgeEnabled&&!!a,valueBadgeSource:a,valueBadgeTouched:!0}}_markerSpatialSource(e){const t=this._markerPreviewDevice(e);if(!t)return null;const i={...t,hidden:!1};return po(ho(this._planHass,[...this._devices.filter(e=>e.id!==i.id),i],null,this._virtualLights).filter(e=>e.device.id===i.id))}_markerAutoHasSpatialSource(e){const t={...e,lightRole:"auto",lightRoleTouched:!0},i=this._markerPreviewDevice(t);return!!i&&lo(this._planHass,{...i})}_setMarkerLightRole(e){const t=this._markerDialog;t&&(this._markerDialog={...t,lightRole:e,lightRoleTouched:!0})}_controlRefInfo(e){if(!e.startsWith("marker:"))return{label:this.hass.states[e]?.attributes?.friendly_name||e,sub:e,icon:e.startsWith("light.")?"mdi:lightbulb":"mdi:toggle-switch",warning:!this._planEntityAvailable(e)};const t=e.slice(7),i=this._markers.find(e=>e.id===t),s=this._devices.find(e=>e.id===t);if(!i||i.removed||!0!==i.is_light)return{label:this._t("marker.control_missing_label"),sub:`${this._t("marker.control_broken")} (${e})`,icon:"mdi:alert-outline",warning:!0};const n=this._serverCfg?.spaces.find(e=>e.id===(s?.space||i.space)),o=!!s&&eo(s).length>0;return{label:i.name||s?.name||t,sub:[n?.title||s?.space||i.space,i.room_id||s?.area,o?"":this._t("marker.control_passive")].filter(Boolean).join(" · "),icon:i.icon||s?.icon||"mdi:lightbulb-outline",warning:!0===i.hidden||!0===s?.hidden}}_valueBadgeCandidateLabel(e){const t=e.source;if("derived_lqi"===t.kind)return this._t("marker.value_badge_lqi");if("derived_marker_state"===t.kind)return this._t("marker.value_badge_marker_state",{name:e.label});if("entity_state"===t.kind)return this._t("marker.value_badge_state",{name:e.label});const i=this.hass.states[t.entity_id]?.attributes?.friendly_name||this._fullRegistryHass.entities[t.entity_id]?.name||t.entity_id;return this._t(`marker.value_badge_attr_${t.attribute}`,{name:i})}_controlCandidates(e){const t=this._markerDraft(e)?.id||e.devId||"",i=[],s=new Set;for(const e of this._markers){if(e.id===t||e.removed||e.hidden||!0!==e.is_light)continue;if("virtual"!==e.binding&&"active"!==this._bindingStatus(e.binding).kind)continue;const n=this._devices.find(t=>t.id===e.id);if(!n||n.hidden)continue;const o=this._controlRefInfo(`marker:${e.id}`);for(const e of eo(n))s.add(e);i.push({value:`marker:${e.id}`,label:o.label,sub:o.sub,icon:o.icon,search:`${o.label} ${o.sub} ${e.id} ${eo(n).join(" ")}`.toLowerCase()})}const n=Object.keys(this.hass.states||{}).filter(t=>Ms(t)&&!s.has(t)&&Xn(e.binding,[t],this._bindingEntities(e.binding)).length>0&&this._planEntityAvailable(t)).map(e=>{const t=this._controlRefInfo(e);return{value:e,label:t.label,sub:e,icon:t.icon,search:`${t.label} ${e}`.toLowerCase()}}),o=e.controlsFilter.trim().toLowerCase();return[...i,...n].filter(t=>!e.controls.includes(t.value)&&(!o||t.search.includes(o))).slice(0,12).map(({search:e,...t})=>t)}_addControlRef(e,t){if(t.startsWith("marker:")){const i=this._markerDraft(e)?.id||e.devId||"";if(!i)return void this._showToast(this._t("toast.marker_binding_required"));const s=t.slice(7),n=this._markerDraft(e);if(function(e,t,i){if(!t||t===i)return!0;const s=new Map;for(const t of e)s.set(t.id,(t.controls||[]).filter(e=>"string"==typeof e&&e.startsWith("marker:")).map(e=>e.slice(7)));const n=new Set,o=[i];for(;o.length;){const e=o.pop();if(e===t)return!0;n.has(e)||(n.add(e),o.push(...s.get(e)||[]))}return!1}(n?[...this._markers.filter(e=>e.id!==i),n]:this._markers,i,s))return void this._showToast(this._t("toast.marker_control_cycle"))}this._markerDialog=this._announceToggleDraft({...e,controls:[...e.controls,t],controlsFilter:""})}_setMarkerGlowMode(e){const t=this._markerDialog;if(!t)return;if("auto"===e)return void(this._markerDialog={...t,glowMode:e,glowTouched:!0});const i=this._markerSpatialSource(t),s=xs(i?this._planHass.states[i.eid]:void 0,null,this._fillColors.glow_light.c),n=!t.glowColorDrafted,o="fixed"===e&&!t.glowBrightnessDrafted;this._markerDialog={...t,glowMode:e,glowColor:n?s.c:t.glowColor,glowBrightness:o?Math.max(1,Math.round(100*s.bri)):t.glowBrightness,glowColorDrafted:!0,glowBrightnessDrafted:t.glowBrightnessDrafted||"fixed"===e,glowTouched:!0}}_renderMarkerDialog(){const e=this._markerDialog,t="virtual"===e.bindingMode,i=this._bindingCandidates();this._bindingEntities(e.binding);const s=t?null:this._bindingStatus(e.binding),n=!t&&this._bindingHasHaPage(e.binding),o=this._markerPreviewDevice(e),a=this._effectiveMarkerTapAction(e,o),r=o?cs(this._serverCfg?.spaces.find(e=>e.id===o.space)):null,l=o?this._markerPreviewDevices(o):this._devices,c="toggle"===a&&o?this._toggleIntent(o,l):null,h=this._toggleHintLines(c),d=o?R_(this._planHass,o,{liveStates:!1!==this._config?.live_states,showTemperature:!1!==this._config?.show_temperature,showSignal:r?.showLqi??!1!==this._config?.show_signal,designPreview:!0,activityRuntime:this._activityRt.get(o.id),lightDevices:l,registryHass:this._fullRegistryHass,reducedMotion:this._reducedMotion}):null,p=o?qo(this._planHass,o,l):[],u=o?Wo(this._planHass,o,p):null,_=e.valueBadgeTouched?e.valueBadgeEnabled:!!d?.valueBadge,m=e.valueBadgeTouched?e.valueBadgeSource:d?.valueBadge?.source||e.valueBadgeSource,g=e.valueBadgeTouched?e.valueBadgePosition:d?.valueBadge?.position||e.valueBadgePosition,f=Ao(m),v=!!m&&!p.some(e=>e.key===f),b=p.find(e=>e.key===f),y=d?.valueSource?d.valueSource.attribute?`attr:${d.valueSource.eid}:${d.valueSource.attribute}`:`state:${d.valueSource.eid}`:"",w=this._markerAutoHasSpatialSource(e),k=!!o&&function(e,t){return io(e,t).some(e=>!!e.eid)}(this._planHass,{...o}),x=function(e,t,i,s){const n="always"===e||"auto"===e&&t,o=n&&!i;return{sourceExists:n,fromSourceEnabled:n&&i,manualEnabled:n,radiusEnabled:n,passive:o,effectiveMode:o&&"auto"===s?"fixed":s}}(e.lightRole,w,k,e.glowMode),$=!x.sourceExists,S=!x.fromSourceEnabled,M=x.passive,C=x.effectiveMode,D="never"===e.lightRole?this._t("marker.glow_disabled_never"):"auto"!==e.lightRole||w?M?this._t("marker.glow_passive_hint"):this._t("marker.glow_disabled_no_entity"):this._t("marker.glow_disabled_auto"),P=o?eo(o):[],T=o&&to(o)||"",I=!!e.lightEntity&&!P.includes(e.lightEntity),R=o?Op(o):[],A=!!e.toggleEntity&&!R.includes(e.toggleEntity),z="toggle"===a?this._toggleIntentForDialog({...e,toggleEntity:"",toggleEntityTouched:!0}):null,F=z?[...z.targets,...z.skippedTargets].map(e=>e.entityId||("ref"in e?e.ref:"")).filter(Boolean).join(", "):"",N=(()=>{if(t)return null;const s=i.find(t=>t.value===e.binding);if(s)return s.label;const[n,o]=e.binding.split(":");return"device"===n?this._fullRegistryHass.devices[o]?.name_by_user||this._fullRegistryHass.devices[o]?.name||o:this._fullRegistryHass.entities[o]?.name||this.hass.states[o]?.attributes?.friendly_name||o})();return q`
@@ -7323,10 +7323,10 @@ globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="30d20d6f6822065e2d5226b18abbb05d8d26 -

${this._t(dv[e.display])}

+

${this._t(gv[e.display])}

${"static_icon"===e.display&&this._bindingHasAlarm(e.binding)?q`
${this._t("marker.static_alarm_warning")} @@ -7475,7 +7475,7 @@ globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="30d20d6f6822065e2d5226b18abbb05d8d26 ${"file"===e.source?q`
@@ -7495,23 +7495,23 @@ globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="30d20d6f6822065e2d5226b18abbb05d8d26 ${e.pickSaved?this._renderServerPlans(e):G}`:G}
{const i=t.target.value,s=mv(i),n=null==s?null:(o=s,this._imperial?o*wh:o);var o;this._spaceDialog={...e,cellCmInput:i,cellCmTouched:!0,cellCm:null!=n&&n>0?Math.max(.1,Math.min(uv,n)):e.cellCm}}} /> + min=${Th(.1,this._imperial)} + max=${Th(vv,this._imperial)} + step="0.1" .value=${e.cellCmInput??Th(e.cellCm,this._imperial)} + @input=${t=>{const i=t.target.value,s=yv(i),n=null==s?null:(o=s,this._imperial?o*Mh:o);var o;this._spaceDialog={...e,cellCmInput:i,cellCmTouched:!0,cellCm:null!=n&&n>0?Math.max(.1,Math.min(vv,n)):e.cellCm}}} /> ${this._t(this._imperial?"space.scale_unit_imperial":"space.scale_unit")}
@@ -7526,7 +7526,7 @@ globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="30d20d6f6822065e2d5226b18abbb05d8d26
${this._t("space.zero_wall_help")}
`:G} - `}}pm.properties={hass:{attribute:!1},_config:{state:!0},_snap:{state:!0},_continuityEpoch:{state:!0}},pm.styles=[Ke,o` + `}}fm.properties={hass:{attribute:!1},_config:{state:!0},_snap:{state:!0},_continuityEpoch:{state:!0}},fm.styles=[Ke,o` .hp-static-title { font-weight: 700; padding: 10px 14px 6px; @@ -4892,7 +4892,7 @@ globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="30d20d6f6822065e2d5226b18abbb05d8d26 text-align: center; color: var(--secondary-text-color, #9aa4ad); } - `],customElements.get("houseplan-space-card")||customElements.define("houseplan-space-card",pm),window.customCards=window.customCards||[],window.customCards.find(e=>"houseplan-space-card"===e.type)||window.customCards.push({type:"houseplan-space-card",name:"House Plan — Space (static)",description:"Read-only live schematic of a single houseplan space, with a deep-link button.",preview:!1,documentation:"https://github.com/Matysh/houseplan-card"});const um=o` + `],customElements.get("houseplan-space-card")||customElements.define("houseplan-space-card",fm),window.customCards=window.customCards||[],window.customCards.find(e=>"houseplan-space-card"===e.type)||window.customCards.push({type:"houseplan-space-card",name:"House Plan — Space (static)",description:"Read-only live schematic of a single houseplan space, with a deep-link button.",preview:!1,documentation:"https://github.com/Matysh/houseplan-card"});const vm=o` :host { --hp-editor-tray-bg-fallback: color-mix(in srgb, var(--card-background-color, var(--hp-bg)) 94%, var(--hp-line)); --hp-editor-tray-bg: color-mix(in srgb, var(--card-background-color, var(--hp-bg)) 86%, transparent); @@ -5063,7 +5063,7 @@ globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="30d20d6f6822065e2d5226b18abbb05d8d26 .editor-secondary { transition: none; } .editor-group-launcher .group-chevron { transition: none; } } -`,_m=(e,t)=>(e.composedPath?.()||[e.target]).some(e=>(e=>!!e&&"function"==typeof e.matches)(e)&&t(e));class mm{constructor(e){this.host=e,this._openGroupId=null,this._groupGeneration=0,this._renderedContext="",this._focusOwned=!1,this._currentModel=null,this._blocked=!1,this._dismissPointerTarget=null,this._globalDismissListening=!1,this._globalDismissGuard=e=>{this.handleOutsideDismiss(e)}}get hasOpenGroup(){return null!==this._openGroupId}get groupGeneration(){return this._groupGeneration}activeGroup(e){return this._openGroupId&&e.find(e=>e.id===this._openGroupId)||null}reset(){this._openGroupId=null,this._contentAnimation?.cancel(),this._contentAnimation=void 0,this._renderedContext="",this._focusOwned=!1,this._currentModel=null,this._blocked=!1,this._dismissPointerTarget=null,clearTimeout(this._dismissTimer),this._dismissTimer=void 0,this._syncGlobalDismissListener()}closeForNavigation(){const e="palette"===this._currentModel?.kind?this._currentModel.dismiss:void 0,t=!!this._openGroupId||!!e;this._openGroupId=null,e?.(),e&&(this._currentModel=null),this._clearDismissClick(),t&&this.host.requestUpdate(),this._syncGlobalDismissListener()}openPalette(){this._openGroupId&&this.closeGroup(!1)}toggleGroup(e,t){this._openGroupId!==t?e.some(e=>e.id===t)&&("palette"===this._currentModel?.kind&&this._currentModel.dismiss?.(),this._groupGeneration+=1,this._openGroupId=t,this.host.clearTip(),this.host.requestUpdate(),this._syncGlobalDismissListener()):this.closeGroup(!1)}closeGroup(e){const t=this._openGroupId;this._openGroupId=null,this.host.requestUpdate(),this._syncGlobalDismissListener(),e&&t&&this.host.updateComplete().then(()=>{const e=this.host.root(),i=[...e.querySelectorAll("[data-editor-group]")].find(e=>e.dataset.editorGroup===t&&null!==e.offsetParent);(i||e.querySelector(".editbar-tools"))?.focus?.()})}renderGroupLauncher(e,t,i){const s=this._openGroupId===e.id,n=e.items.find(t=>t.id===e.activeItemId&&!t.disabled);return q`
-
`}afterRender(){const e=this.host.root();this._blocked&&(this._openGroupId?this.closeGroup(!1):"palette"===this._currentModel?.kind&&this._currentModel.dismiss?.()),this._syncGlobalDismissListener();const t=e.querySelector(".editor-secondary"),i=this._renderedContext,s=t?.dataset.contextId||"";if(s&&i&&s!==i&&!window.matchMedia?.("(prefers-reduced-motion: reduce)")?.matches&&(this._contentAnimation?.cancel(),this._contentAnimation=t?.querySelector(".editor-secondary-content")?.animate([{opacity:.35,transform:"translateY(-4px)"},{opacity:1,transform:"translateY(0)"}],{duration:100,easing:"ease-out"})),this._renderedContext=s,i&&s!==i&&this._focusOwned){const i=s?t?.querySelector('[tabindex="0"], button:not([disabled]), input:not([disabled]), select:not([disabled]), textarea:not([disabled])'):e.querySelector(".editbar-tools");i?.focus?.(),this._focusOwned=!!s}if("palette"===this._currentModel?.kind&&this._currentModel.launcherId){const t=[...e.querySelectorAll("[data-editor-palette]")].find(e=>e.dataset.editorPalette===this._currentModel?.launcherId);t&&null!==t.offsetParent||this._currentModel.dismiss?.()}if(!this._openGroupId)return;const n=[...e.querySelectorAll("[data-editor-group]")].find(e=>e.dataset.editorGroup===this._openGroupId);n&&null!==n.offsetParent||this.closeGroup(!0)}handleOutsideDismiss(e){if(_m(e,e=>e.hasAttribute("data-editor-navigation")))return"pointerdown"===e.type?this.closeForNavigation():"click"===e.type&&this._dismissPointerTarget&&this._clearDismissClick(),!1;if("click"===e.type&&this._dismissPointerTarget){return!!(e.composedPath?.()||[e.target]).includes(this._dismissPointerTarget)&&(this._clearDismissClick(),e.preventDefault(),e.stopImmediatePropagation(),!0)}const t=this._openGroupId||this._blocked||"palette"!==this._currentModel?.kind?null:this._currentModel;if("pointerdown"===e.type&&(this._openGroupId||t)){const i=_m(e,e=>e.classList.contains("editor-secondary")),s=_m(e,e=>!!e.dataset.editorGroup),n=_m(e,e=>!!e.dataset.editorPalette),o=_m(e,e=>e.classList.contains("stage"));if(!(i||s||n||"stay-open-on-canvas"===t?.dismissPolicy&&o))return e.preventDefault(),e.stopImmediatePropagation(),this._dismissPointerTarget=e.target,clearTimeout(this._dismissTimer),this._dismissTimer=window.setTimeout(()=>{this._clearDismissClick()},800),this._openGroupId?this.closeGroup(!1):t?.dismiss?.(),this._syncGlobalDismissListener(),!0}return!1}_activateGroupItem(e,t,i){if(e.id!==this._openGroupId)return;const s=e.items.find(e=>e.id===t);if(!s||s.disabled)return;const n="toggle"===s.role&&"stay-open"===s.closePolicy,o=0===i.detail;n||(this._openGroupId=null,this.host.requestUpdate(),this._syncGlobalDismissListener()),s.invoke(),!n&&o&&this.host.updateComplete().then(()=>{const t=[...this.host.root().querySelectorAll("[data-editor-group]")].find(t=>t.dataset.editorGroup===e.id&&null!==t.offsetParent);t?.focus()})}_groupKeydown(e){if(!["ArrowLeft","ArrowRight","Home","End"].includes(e.key))return;const t=[...e.currentTarget.querySelectorAll(".editor-group-item:not([disabled])")];if(!t.length)return;e.preventDefault();const i=t.indexOf(this.host.root().activeElement),s="Home"===e.key?0:"End"===e.key?t.length-1:"ArrowLeft"===e.key?i<=0?t.length-1:i-1:(i+1)%t.length;t[s]?.focus()}_clearDismissClick(){this._dismissPointerTarget=null,clearTimeout(this._dismissTimer),this._dismissTimer=void 0,this._syncGlobalDismissListener()}_syncGlobalDismissListener(){const e=!this._blocked&&"palette"===this._currentModel?.kind,t=!!this._openGroupId||e||!!this._dismissPointerTarget;t!==this._globalDismissListening&&(this._globalDismissListening=t,t?(window.addEventListener("pointerdown",this._globalDismissGuard,!0),window.addEventListener("click",this._globalDismissGuard,!0)):(window.removeEventListener("pointerdown",this._globalDismissGuard,!0),window.removeEventListener("click",this._globalDismissGuard,!0)))}}const gm=e=>e.stopPropagation(),fm=4.166666666666667e-9;function vm(e){return Number.isFinite(e)?Math.round(e/Eh)*Eh:e}const bm=(e,t,i,s)=>Math.hypot(i-e,s-t),ym=(e,t,i,s,n,o,a,r)=>Math.hypot(Math.max(Math.abs(n-e),Math.abs(n+a-(e+i))),Math.max(Math.abs(o-t),Math.abs(o+r-(t+s)))),wm=(e,t,i,s,n,o,a)=>{const r=Math.max(Number(s)||0,0)/2,l=Math.PI/180,c=Math.cos(i*l)*r,h=Math.sin(i*l)*r,d=Math.cos(a*l)*r,p=Math.sin(a*l)*r,u=Math.max(bm(e+c,t+h,n+d,o+p),bm(e-c,t-h,n-d,o-p)),_=Math.max(bm(e+c,t+h,n-d,o-p),bm(e-c,t-h,n+d,o+p));return Math.min(u,_)},km=e=>{const t=Number(e?.cell_cm);return t>0?t:5};function xm(e,t){const i=JSON.parse(JSON.stringify(e||[])),s=JSON.parse(JSON.stringify(t||{}));let n=0,o=0,a=0,r=0,l="",c=0,h=0,d=0;const p=(e,t)=>{Number.isFinite(e)&&Number.isFinite(t)&&e!==t&&Math.abs(t-e)<=fm&&h++},u=(e,t)=>{p(e[0],t[0]),p(e[1],t[1])},_={};let m=5;for(const e of i){const t=km(e);null!=e?.id&&(_[String(e.id)]=t),t>m&&(m=t)}const g=(e,t,i,s=!1)=>{if(!(e>fm||s))return;n++,e>a&&(a=e);const o=e*Fh*t;o>r&&(r=o,l=i)};for(const e of i){const t=km(e),i=null!=e?.id?String(e.id):"";for(const s of e.rooms||[]){o++;let e=0;if(s.poly?.length)s.poly=s.poly.map(t=>{const i=[vm(t[0]),vm(t[1])];return e=Math.max(e,bm(t[0],t[1],i[0],i[1])),u(t,i),i});else if(null!=s.x&&null!=s.y){const t=s.x,i=s.y,n=s.w||0,o=s.h||0,a=vm(t+n),r=vm(i+o),l=vm(t),c=vm(i),h=Math.max(Eh,a-l),d=Math.max(Eh,r-c);e=ym(t,i,n,o,l,c,h,d),s.x=l,s.y=c,s.w=h,s.h=d,p(t,l),p(i,c),p(t+n,l+h),p(i+o,c+d)}g(e,t,i)}for(const s of e.room_drafts||[]){o++;let e=0;const n=s.points||[],a=n.map(t=>{const i=[vm(t[0]),vm(t[1])];return e=Math.max(e,bm(t[0],t[1],i[0],i[1])),i}),r=a.length?[a[0]]:[],l=a.length?[[n[0],a[0]]]:[],c=[];for(let e=0;e+1=2)for(const[e,t]of l)u(e,t);g(e,t,i)}if(Array.isArray(e.room_drafts)){const t=e.room_drafts.length;e.room_drafts=e.room_drafts.filter(e=>e.points?.length>=2),d+=t-e.room_drafts.length,e.room_drafts.length||delete e.room_drafts}for(const s of e.partitions||[]){o++;const n=[s.a[0],s.a[1]],a=[s.b[0],s.b[1]],r=[vm(n[0]),vm(n[1])],l=[vm(a[0]),vm(a[1])];let c=Math.max(bm(n[0],n[1],r[0],r[1]),bm(a[0],a[1],l[0],l[1]));const h=bm(r[0],r[1],l[0],l[1]),d=(e.openings||[]).filter(e=>"partition"===e.host?.kind&&e.host.id===s.id).every(e=>{const t=Number(e.length),i=Number(e.host.t),s=i*h;return Number.isFinite(t)&&t>0&&Number.isFinite(i)&&i>=0&&i<=1&&s-t/2>=-fm&&s+t/2<=h+fm});h>fm&&d?(s.a=r,s.b=l,u(n,r),u(a,l)):c=0,g(c,t,i)}for(const s of e.wall_columns||[]){o++;const e=[s.center[0],s.center[1]],n=[vm(e[0]),vm(e[1])],a=bm(e[0],e[1],n[0],n[1]);s.center=n,u(e,n),g(a,t,i)}for(const s of e.decor||[]){o++;let e=0;if("line"===s.kind){const t=[s.x1,s.y1],i=[s.x2,s.y2],n=[vm(t[0]),vm(t[1])],o=[vm(i[0]),vm(i[1])];e=Math.max(bm(t[0],t[1],n[0],n[1]),bm(i[0],i[1],o[0],o[1])),s.x1=n[0],s.y1=n[1],s.x2=o[0],s.y2=o[1],u(t,n),u(i,o)}else{const t=s.x,i=s.y,n=s.w,o=s.h,a=vm(t),r=vm(i);if(null!=s.w&&null!=s.h){const l=vm(t+n),c=vm(i+o),h=Math.max(Eh,l-a),d=Math.max(Eh,c-r);e=ym(t,i,n,o,a,r,h,d),s.w=h,s.h=d,p(t+n,a+h),p(i+o,r+d)}else e=bm(t,i,a,r);s.x=a,s.y=r,p(t,a),p(i,r)}g(e,t,i)}for(const s of e.openings||[]){if(o++,"partition"===s.host?.kind){const n=(e.partitions||[]).find(e=>e.id===s.host.id),o=Number(s.host.t);if(!n||!Number.isFinite(o)||o<0||o>1)continue;const a=n.b[0]-n.a[0],r=n.b[1]-n.a[1];if(Math.hypot(a,r)<=fm)continue;const l=n.a[0]+a*o,h=n.a[1]+r*o;let d=180*Math.atan2(r,a)/Math.PI;d>=90?d-=180:d<-90&&(d+=180);const p=Number(s.angle),u=!(Number.isFinite(p)&&p===d),_=wm(s.x,s.y,Number.isFinite(p)?p:d,Number(s.length)||0,l,h,d);s.x=l,s.y=h,s.angle=d,u&&c++,g(_,t,i,u);continue}const n=ui([s.x,s.y],e.rooms||[],.025,{step:Eh,length:Number(s.length)||0});if(!n)continue;const a=Number(s.angle),r=!(Number.isFinite(a)&&a===n.angle),l=wm(s.x,s.y,Number.isFinite(a)?a:n.angle,Number(s.length)||0,n.x,n.y,n.angle);s.x=n.x,s.y=n.y,s.angle=n.angle,r&&c++,g(l,t,i,r)}}for(const[e,t]of Object.entries(s)){if(!t||"object"!=typeof t)continue;const i=t;if("number"!=typeof i.x||"number"!=typeof i.y)continue;o++;const n=vm(i.x),a=vm(i.y),r=bm(i.x,i.y,n,a);s[e]={...i,x:n,y:a},p(i.x,n),p(i.y,a);const l="string"==typeof i.s?i.s:"";g(r,_[l]??m,l)}return{spaces:i,layout:s,report:{moved:n,coordsCanonicalized:h,total:o,maxShift:a,maxShiftCm:r,maxSpace:l,rotated:c,removedDrafts:d},changed:n>0||h>0}}function $m(e,t){const i=t.base+e*t.span;return Math.min(1,Math.max(0,i))}const Sm=e=>Array.isArray(e)&&e.length>=2&&Number.isFinite(e[0])&&Number.isFinite(e[1]),Mm=(e,t)=>Math.hypot(e[0]-t[0],e[1]-t[1]);function Cm(e,t,i){const s=i[0]-t[0],n=i[1]-t[1],o=s*s+n*n;if(o<=0)return Mm(e,t);let a=((e[0]-t[0])*s+(e[1]-t[1])*n)/o;return a=Math.max(0,Math.min(1,a)),Math.hypot(e[0]-(t[0]+s*a),e[1]-(t[1]+n*a))}function Dm(e,t,i,s,n){for(const s of t)if(s&&!i.has(s.id)&&Sm(s.a)&&Sm(s.b)&&(Mm(e,s.a)<=n||Mm(e,s.b)<=n))return!0;for(const t of s?.roomPolygons||[])for(let i=0;i0&&r>0))return null;if(Math.abs(n[0]/a*(o[1]/r)-n[1]/a*(o[0]/r))>i)return null;for(const[i,n]of[[e.a,t.a],[e.a,t.b],[e.b,t.a],[e.b,t.b]])if(Mm(i,n)<=s)return[(i[0]+n[0])/2,(i[1]+n[1])/2];return null}function Tm(e,t){const i=.05*(Number(t.pitch)>0?Number(t.pitch):1),s=new Map;let n=(e||[]).filter(e=>!!e&&"string"==typeof e.id&&Sm(e.a)&&Sm(e.b));if(n.length<2)return{partitions:[...e||[]],merged:0,openingMoves:[]};const o=t.seedIds&&t.seedIds.length?new Set(t.seedIds):null;let a=0;for(let e=0;eMm(t,e.at)>i);let h=c[0]??r.a,d=c[c.length-1]??l.b;if(c.length<2&&(h=r.a,d=l.b),d[0]0?(d[0]-h[0])/u:0,m=u>0?(d[1]-h[1])/u:0,g=e=>u>0?((e[0]-h[0])*_+(e[1]-h[1])*m)/u:0;for(const e of[r,l]){const t=g(e.a),i=g(e.b)-t;for(const[n,o]of s)o.toId===e.id&&s.set(n,{fromId:o.fromId,toId:p.id,base:t+o.base*i,span:o.span*i});s.set(e.id,{fromId:e.id,toId:p.id,base:t,span:i})}o&&o.add(p.id),n=n.filter((t,i)=>i!==e.i&&i!==e.j),n.splice(e.i,0,p),a++}return{partitions:n,merged:a,openingMoves:[...s.values()]}}function Im(e,t,i,s){if(!e?.length||!i.length)return 0;const n=new Map(i.map(e=>[e.fromId,e]));let o=0;for(const i of e){const e=i?.host;if(!e||"partition"!==e.kind)continue;const a=n.get(e.id);if(!a)continue;i.host={...e,id:a.toId,t:$m(e.t,a)},o++;const r=Jp(i,t,s.coordScale,s.cellCm,s.gridPitch).resolved;r&&Object.assign(i,su(i,r,s.coordScale))}return o}function Rm(e,t){const i=t?.excludeDraftId||null;return{roomPolygons:(e?.rooms||[]).map(e=>hi(e)).filter(e=>!!e),columns:e?.wall_columns||[],draftEnds:(e?.room_drafts||[]).flatMap(e=>{if(i&&e?.id===i)return[];const t=e?.points||[];return t.length?[t[0],t[t.length-1]]:[]})}}const Am=e=>!!e&&e.length>=2&&Number.isFinite(e[0])&&Number.isFinite(e[1]),zm=(e,t)=>e[0]-t[0]||e[1]-t[1],Fm=(e,t,i,s)=>[e[0]+t*s,e[1]+i*s],Nm=(e,t,i,s)=>(e[0]-t[0])*i+(e[1]-t[1])*s,Em=(e,t,i,s,n)=>{const o=t[0]-e[0],a=t[1]-e[1],r=Math.hypot(o,a);if(!(r>n))return null;const l=o/r,c=a/r,h=t=>Math.abs((t[0]-e[0])*c-(t[1]-e[1])*l);if(h(i)>n||h(s)>n)return null;const d=Nm(i,e,l,c),p=Nm(s,e,l,c),u=Math.max(0,Math.min(d,p)),_=Math.min(r,Math.max(d,p));return _-u>n?{lo:u,hi:_}:null},Om=(e,t,i)=>Math.min(e.hi,t.hi)-Math.max(e.lo,t.lo)>i,Hm=e=>{const t=new Set(["id","a","b","cm"]);return Object.keys(e||{}).every(e=>t.has(e))},Lm=(e,t,i,s)=>{const n=e.b[0]-e.a[0],o=e.b[1]-e.a[1],a=Math.hypot(n,o);if(!(a>s))return!0;const r=n/a,l=o/a,c=wl(e.cm,i.cellCm,i.gridPitch)/2;return t.some(t=>{const n=t?.center;if(!Am(n))return!0;const o=Nm(n,e.a,r,l),h=Math.abs((n[0]-e.a[0])*l-(n[1]-e.a[1])*r),d=wl(Number(t.cm),i.cellCm,i.gridPitch)*("square"===t.shape?Math.SQRT1_2:.5);return!(Number.isFinite(d)&&d>0)||o>=-d-s&&o<=a+d+s&&h<=c+d+s})},Bm=(e,t,i)=>{if(e.host){const s=Jp(e,t,i.coordScale,i.cellCm,i.gridPitch).resolved;return s?{center:s.center,angle:s.angle,length:s.length}:null}const s=Number(e.x)*i.coordScale,n=Number(e.y)*i.coordScale,o=Number(e.angle),a=Number(e.length)*i.coordScale;return[s,n,o,a].every(Number.isFinite)&&a>0?{center:[s,n],angle:o,length:a}:null},jm=(e,t,i)=>{const s=e.angle*Math.PI/180,n=Math.cos(s),o=Math.sin(s),a=t.angle*Math.PI/180,r=Math.cos(a),l=Math.sin(a);if(Math.abs(n*l-o*r)>1e-6)return!1;const c=t.center[0]-e.center[0],h=t.center[1]-e.center[1];if(Math.abs(c*o-h*n)>i)return!1;const d=c*n+h*o;return Math.max(-e.length/2,d-t.length/2)({...e,a:[e.a[0]*t,e.a[1]*t],b:[e.b[0]*t,e.b[1]*t]}),Wm=(e,t,i,s)=>{const n=`~r-${(e=>{let t=2166136261;for(let i=0;i>>0;return t.toString(36)})(`${e}|${t[0].toFixed(9)},${t[1].toFixed(9)}|${i[0].toFixed(9)},${i[1].toFixed(9)}`)}`,o=`${e.slice(0,Math.max(1,64-n.length))}${n}`;let a=o;for(let e=2;s.has(a);e++){const t=`-${e}`;a=`${o.slice(0,64-t.length)}${t}`}return s.add(a),a},Um=(e,t)=>{const i=[];for(const s of e){const e=i[i.length-1];!(e&&Math.abs(e.hi-s.lo)<=t&&e.safe===s.safe)||s.safe&&e.signature!==s.signature?i.push({lo:s.lo,hi:s.hi,a:s.a,b:s.b,safe:s.safe,signature:s.signature,roomIds:s.roomIds,finalCm:s.finalCm}):(e.hi=s.hi,e.b=s.b)}return i};function Gm(e,t,i,s,n){const o=i||[],a=Array.isArray(e?.partitions)?e.partitions:[],r=Array.isArray(e?.openings)?e.openings:[],l=Array.isArray(e?.room_drafts)?e.room_drafts:[],c={walls:o,partitions:a,openings:r,roomDrafts:l,partitionsReconciled:0,openingsRehosted:0,removedDrafts:0};if(!a.length&&!l.length)return c;const h=Math.max(2e-4*n.gridPitch,1e-9);let d=o,p=a,u=r;const _=gc(t.rooms,d,s,n.pitch,n.cellCm,n.gridPitch,n.coordScale),m=((e,t,i,s)=>{const n=new Map(e.map(e=>[e.id,e])),o=new Set;for(const e of t){if(!n.get(e.id)||!Array.isArray(e.points)||e.points.length<2||e.segments.length!==e.points.length-1)continue;let t=!0;for(let n=0;n+10)){t=!1;break}const l=Math.hypot(a[0]-o[0],a[1]-o[1]);if(!(l>s)){t=!1;break}const c=i.flatMap(e=>{const t=e.cm>0?e.cm:ul;if(e.open||"outer"!==e.kind&&"shared"!==e.kind||t+se.lo-t.lo||e.hi-t.hi);let h=0;for(const e of c){if(e.lo>h+s)break;if(h=Math.max(h,e.hi),h>=l-s)break}h!m.has(e.id));let f=0,v=0;const b=new Map(t.partitions.map(e=>[e.id,e]));for(const e of[...a].sort((e,t)=>e.id.localeCompare(t.id))){if(!p.some(t=>t.id===e.id))continue;if(!Hm(e))continue;const i=b.get(e.id);if(!(i&&Am(i.a)&&Am(i.b)&&Number.isFinite(i.cm)&&i.cm>0))continue;const[o,a]=zm(i.a,i.b)<=0?[[i.a[0],i.a[1]],[i.b[0],i.b[1]]]:[[i.b[0],i.b[1]],[i.a[0],i.a[1]]],r=a[0]-o[0],l=a[1]-o[1],c=Math.hypot(r,l);if(!(c>h))continue;const _=r/c,g=l/c,y=gc(t.rooms,d,s,n.pitch,n.cellCm,n.gridPitch,n.coordScale),w=y.flatMap(e=>{if(e.open||"outer"!==e.kind&&"shared"!==e.kind)return[];const t=Em(o,a,e.a,e.b,h);return t?[{interval:e,range:t}]:[]});if(!w.length)continue;const k=u.filter(e=>"partition"===e.host?.kind&&e.host.id===i.id).map(e=>({opening:e,resolved:Jp(e,t.partitions,n.coordScale,n.cellCm,n.gridPitch).resolved}));if(k.some(e=>!e.resolved))continue;const x=[0,c];for(const{range:e}of w)x.push(e.lo,e.hi);const $=x.slice(),S=new Map;for(const{opening:e,resolved:t}of k){const i=Nm(t.center,o,_,g),s={lo:i-t.length/2,hi:i+t.length/2};S.set(e.id,s),$.push(Math.max(0,s.lo),Math.min(c,s.hi))}const M=[...new Set($.filter(e=>Number.isFinite(e)&&e>=-h&&e<=c+h).map(e=>Math.max(0,Math.min(c,e)).toFixed(9)))].map(Number).sort((e,t)=>e-t),C=p.map(e=>qm(e,n.coordScale)).filter(e=>e.id!==i.id),D=t.room_drafts.filter(e=>!m.has(e.id)),P=[];for(let e=0;e+1h))continue;const r=Fm(o,_,g,s),l=Fm(o,_,g,a),c=w.filter(({range:e})=>e.lo<=s+h&&e.hi>=a-h).map(({interval:e})=>e),d=new Map;for(const e of c)d.set(e.roomId,e);const p=[...d.values()],u=new Set(p.map(e=>e.kind)),m=new Set(p.map(e=>e.cm>0?e.cm:ul)),f=p[0]?.kind,v=[...d.keys()].sort(),b=1===u.size&&1===m.size&&("outer"===f&&1===v.length||"shared"===f&&2===v.length),y={id:i.id,a:r,b:l,cm:i.cm},k=C.some(e=>!!Em(r,l,e.a,e.b,h)),x=D.some(e=>e.points.some((t,i)=>i+10?p[0].cm:ul:0,T=b?Math.max(S,i.cm):i.cm;P.push({lo:s,hi:a,a:r,b:l,safe:$,signature:$?`${f}|${v.join(",")}|${T}`:"",roomIds:v,roomCm:S,finalCm:T})}if(!P.some(e=>e.safe))continue;const T=new Map;for(const{opening:e,resolved:t}of k){const s=S.get(e.id),o=x.some(e=>e>s.lo+h&&eOm(e,s,h)),r=new Set(a.filter(e=>e.safe).map(e=>e.signature));if(!o&&a.length>0&&a.every(e=>e.safe)&&1===r.size&&iu(t,y,h)){T.set(e.id,{resolved:t,signature:[...r][0]});continue}const l=Kp(i,n.cellCm,n.gridPitch),c={lo:s.lo-l,hi:s.hi+l};for(const e of P)Om(e,c,h)&&(e.safe=!1,e.signature="")}let I=!0;for(;I;){I=!1;for(const[e,t]of[...T.entries()]){const s=S.get(e),o=P.filter(e=>Om(e,s,h));if(o.length>0&&o.every(e=>e.safe)&&o.every(e=>e.signature===t.signature))continue;T.delete(e);const a=Kp(i,n.cellCm,n.gridPitch),r={lo:s.lo-a,hi:s.hi+a};for(const e of P)Om(e,r,h)&&(e.safe=!1,e.signature="");I=!0}}const R=Um(P,h),A=R.filter(e=>e.safe),z=R.filter(e=>!e.safe);if(!A.length)continue;if(p.length-1+z.length>2e3)continue;let F=d;for(const e of A){const[t,s]=zm(i.a,i.b)<=0?[e.a,e.b]:[e.b,e.a];F=Ll(F,t,s,e.finalCm,n.pitch,n.coordScale)}if(F=vc(t.rooms,F,s,n.pitch,n.cellCm,n.gridPitch,n.coordScale),F.length>500)continue;const N=new Set(p.map(e=>e.id));N.delete(i.id);const E=z.map((e,t)=>{const s=[e.a[0]/n.coordScale,e.a[1]/n.coordScale],o=[e.b[0]/n.coordScale,e.b[1]/n.coordScale],a=0===t?i.id:Wm(i.id,s,o,N);return N.add(a),{id:a,a:s,b:o,cm:i.cm}}),O=p.findIndex(e=>e.id===i.id),H=p.slice();H.splice(O,1,...E);const L=H.map(e=>qm(e,n.coordScale)),B=new Map;let j=!0;for(const{opening:e,resolved:t}of k){const i=T.get(e.id);if(i){const t=su(e,i.resolved,n.coordScale),{host:s,...o}=t;B.set(e.id,o);continue}const s=S.get(e.id),o=E[z.findIndex(e=>e.lo<=s.lo+h&&e.hi>=s.hi-h)],a=o&&L.find(e=>e.id===o.id);if(!o||!a){j=!1;break}const r=a.b[0]-a.a[0],l=a.b[1]-a.a[1],c=Math.hypot(r,l),d=Nm(t.center,a.a,r/c,l/c),p={...su(e,t,n.coordScale),host:{kind:"partition",id:o.id,t:d/c}};if(!Xp(p,L,n.coordScale,n.cellCm,n.gridPitch).resolved){j=!1;break}B.set(e.id,p)}if(!j)continue;const q=u.map(e=>B.get(e.id)||e),W=[...T.keys()].map(e=>B.get(e)),U=W.map(e=>Bm(e,L,n));if(U.some(e=>!e))continue;let G=!1;for(let e=0;ee.id));for(const e of q){if(V.has(e.id))continue;const t=Bm(e,L,n);t&&U.some(e=>jm(e,t,h))&&(G=!0)}if(G)continue;const K=qc(t.rooms,F,s,n.pitch,n.cellCm,n.gridPitch,n.coordScale);[...T.entries()].every(([e,t])=>{const i=B.get(e),s=Gc(K,{x:i.x*n.coordScale,y:i.y*n.coordScale,angle:i.angle,length:i.length*n.coordScale},!0),o=[s.negative,s.positive].filter(e=>!!e?.full),a=t.signature.split("|")[1].split(","),r=new Set(o.map(e=>e.roomId));return o.length===a.length&&r.size===a.length&&a.every(e=>r.has(e))})&&(d=F,p=H,u=q,f+=A.length,v+=T.size)}return{walls:d,partitions:p,openings:u,roomDrafts:g,partitionsReconciled:f,openingsRehosted:v,removedDrafts:m.size}}const Vm=e=>JSON.parse(JSON.stringify(e)),Km=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),Ym=(e,t)=>t.length>0&&t.length<=35&&("space"===e?/^[a-z0-9_-]+$/.test(t):/^[A-Za-z0-9_-]+$/.test(t));function Jm(e,t){let i=String(t??"");const s=e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),n=new RegExp(`^${s}_(.+)_([0-9a-f]{8})$`);let o=0;for(;o<16;o++){const e=n.exec(i);if(!e)return{root:i,layers:o,bounded:!1};i=e[1]}return{root:i,layers:o,bounded:n.test(i)}}const Xm=(e,t,i)=>{const s=e.get(t)||[];s.push(i),e.set(t,s)};const Zm=1e-9;class Qm extends Error{constructor(e,t=""){super(t?`${e}: ${t}`:e),this.reason=e,this.name="WallSegmentModelError"}}const eg=e=>JSON.parse(JSON.stringify(e)),tg=e=>Array.isArray(e)&&e.length>=2&&Number.isFinite(Number(e[0]))&&Number.isFinite(Number(e[1])),ig=e=>[Number(e[0]),Number(e[1])],sg=e=>`${Number(e[0]).toFixed(12)},${Number(e[1]).toFixed(12)}`,ng=(e,t)=>{const i=sg(e),s=sg(t);return isg(e)<=sg(t)?[ig(e),ig(t)]:[ig(t),ig(e)],ag=(e,t)=>Math.hypot(t[0]-e[0],t[1]-e[1]),rg=e=>{const t=[[Number(e.points[0][0]),Number(e.points[0][1])]],i=[];for(let s=1;s{const i=new Set,s=e=>{const t=Number(e);if(!Number.isFinite(t))return;const s=t/Eh;Math.abs(s-Math.round(s))>=Jr&&i.add(t.toFixed(12))};for(const t of Array.isArray(e?.rooms)?e.rooms:[])for(const e of hi(t)||[])s(e[0]),s(e[1]);for(const t of[e?.wall_segments,e?.walls])for(const e of Array.isArray(t)?t:[])s(e?.a?.[0]),s(e?.a?.[1]),s(e?.b?.[0]),s(e?.b?.[1]);for(const e of t)s(e?.[0]),s(e?.[1]);return i.size},cg=(e,t,i)=>{const s=i[0]-t[0],n=i[1]-t[1],o=s*s+n*n;return o>1e-18?((e[0]-t[0])*s+(e[1]-t[1])*n)/o:0},hg=(e,t,i)=>{const s=Math.max(0,Math.min(1,cg(e,t,i)));return Math.hypot(e[0]-(t[0]+(i[0]-t[0])*s),e[1]-(t[1]+(i[1]-t[1])*s))},dg=(e,t,i,s,n=Zm)=>{const o=t[0]-e[0],a=t[1]-e[1],r=Math.hypot(o,a);if(r<=n)return 0;const l=t=>Math.abs((t[0]-e[0])*a-(t[1]-e[1])*o)/r;if(l(i)>n||l(s)>n)return 0;const c=cg(i,e,t),h=cg(s,e,t);return Math.max(0,Math.min(1,Math.max(c,h))-Math.max(0,Math.min(c,h)))*r},pg=e=>{const t=(new TextEncoder).encode(e),i=8*t.length,s=64*Math.ceil((t.length+9)/64),n=new Uint8Array(s);n.set(t),n[t.length]=128;const o=new DataView(n.buffer);o.setUint32(s-8,Math.floor(i/4294967296),!1),o.setUint32(s-4,i>>>0,!1);const a=new Uint32Array([1116352408,1899447441,3049323471,3921009573,961987163,1508970993,2453635748,2870763221,3624381080,310598401,607225278,1426881987,1925078388,2162078206,2614888103,3248222580,3835390401,4022224774,264347078,604807628,770255983,1249150122,1555081692,1996064986,2554220882,2821834349,2952996808,3210313671,3336571891,3584528711,113926993,338241895,666307205,773529912,1294757372,1396182291,1695183700,1986661051,2177026350,2456956037,2730485921,2820302411,3259730800,3345764771,3516065817,3600352804,4094571909,275423344,430227734,506948616,659060556,883997877,958139571,1322822218,1537002063,1747873779,1955562222,2024104815,2227730452,2361852424,2428436474,2756734187,3204031479,3329325298]),r=new Uint32Array([1779033703,3144134277,1013904242,2773480762,1359893119,2600822924,528734635,1541459225]),l=new Uint32Array(64),c=(e,t)=>e>>>t|e<<32-t;for(let e=0;e>>3,n=c(i,17)^c(i,19)^i>>>10;l[e]=l[e-16]+s+l[e-7]+n>>>0}let[t,i,s,n,h,d,p,u]=r;for(let e=0;e<64;e++){const o=u+(c(h,6)^c(h,11)^c(h,25))+(h&d^~h&p)+a[e]+l[e]>>>0,r=t&i^t&s^i&s;u=p,p=d,d=h,h=n+o>>>0,n=s,s=i,i=t,t=o+((c(t,2)^c(t,13)^c(t,22))+r>>>0)>>>0}r[0]=r[0]+t>>>0,r[1]=r[1]+i>>>0,r[2]=r[2]+s>>>0,r[3]=r[3]+n>>>0,r[4]=r[4]+h>>>0,r[5]=r[5]+d>>>0,r[6]=r[6]+p>>>0,r[7]=r[7]+u>>>0}const h=new Uint8Array(32),d=new DataView(h.buffer);for(let e=0;e{const t="abcdefghijklmnopqrstuvwxyz234567";let i=0,s=0,n="";for(const o of e)for(s=s<<8|o,i+=8;i>=5;)n+=t[s>>>i-5&31],i-=5;return i&&(n+=t[s<<5-i&31]),n},_g=(e,t,i,s,n="")=>{const[o,a]=og(t,i),r=`${e}|${sg(o)}|${sg(a)}|${[...s].sort().join(",")}${n}`;return`wall-${ug(pg(r)).slice(0,20)}`};let mg=0;const gg=e=>{for(let t=0;t<1e3;t++){const t=globalThis.crypto?.randomUUID?.(),i=`wall-${t||ug(pg(`${Date.now()}|${mg++}|${Math.random()}`)).slice(0,26)}`;if(!e.has(i))return i}throw new Qm("duplicate-id","id factory exhausted")},fg=e=>{const t=new Map;for(const i of Array.isArray(e?.wall_segments)?e.wall_segments:[])if(i&&"string"==typeof i.id&&tg(i.a)&&tg(i.b)){if(t.has(i.id))throw new Qm("duplicate-id",i.id);t.set(i.id,i)}return t},vg=(e,t,i)=>{const s=(i,s)=>{const n=e[0]-i[0],o=e[1]-i[1];return Math.abs(t[0]-s[0]-n)<=Zm&&Math.abs(t[1]-s[1]-o)<=Zm?[n,o]:null};return s(i.a,i.b)||s(i.b,i.a)},bg=(e,t)=>{const i=Array.isArray(e.rooms)?e.rooms:[],s=Ad(e.open_spans).map(e=>[e.a[0],e.a[1],e.b[0],e.b[1]]),n=s.length?s:zd(i,null,1,.04*Eh,!0),o=[];for(const e of i){const i=hi(e),s=Array.isArray(e?.wall_ids)?e.wall_ids:[];if(i&&s.length===i.length)for(let e=0;e"partition"!==e.host?.kind&&[Number(e.x),Number(e.y)].every(Number.isFinite)&&Number.isFinite(Number(e.angle))&&Number(e.length)>0&&n.some(t=>hg([Number(e.x),Number(e.y)],[t[0],t[1]],[t[2],t[3]])<=.04*Eh)):[],l=r.map(e=>{const t=Number(e.angle)*Math.PI/180,i=[Math.cos(t),Math.sin(t)],s=Number(e.length)/2,n=[Number(e.x),Number(e.y)];return{a:[n[0]-i[0]*s,n[1]-i[1]*s],b:[n[0]+i[0]*s,n[1]+i[1]*s]}}),c=(e,t)=>r.some(i=>{const s=[Number(i.x),Number(i.y)];if(!Nl(e,t,Number(i.angle)))return!1;if(hg(s,e,t)>.02*Eh)return!1;const n=ag(e,t),o=cg(s,e,t)*n,a=Number(i.length)/2;return o+a>=-Zm&&o-a<=n+Zm}),h=new Map,d=[];for(const s of i){const r=String(s?.id||""),p=hi(s);if(!r||!p||p.length<3)throw new Qm("invalid-room",r);const u=ac(i,r,a,Eh,1,[...e.walls||[],...l]);if(!u||u.poly.length<3)throw new Qm("invalid-room",r);const _=Array.isArray(s.wall_ids)?s.wall_ids:[],m=_.length===p.length;let g=null,f=m;if(f)for(let e=0;eZm||Math.abs(s[1]-g[1])>Zm)){f=!1;break}g=s}const v=[];for(let e=0;e2)throw new Qm("third-owner",a);const d=m?_[u.parent[e]]:void 0;if("string"==typeof d&&d){const n=t.get(d);f||!n||dg(i,s,n.a,n.b)>Zm?l.preferredIds.add(d):l.positionalIds.add(d),l.preferredCarriers.set(d,{a:ig(p[u.parent[e]]),b:ig(p[(u.parent[e]+1)%p.length])})}const g=u.parent[e];l.parentKeys.add(Ml(p[g],p[(g+1)%p.length],Eh));const b=[(i[0]+s[0])/2,(i[1]+s[1])/2],y=e=>e.some(e=>hg(b,[e[0],e[1]],[e[2],e[3]])<=.04*Eh);l.zeroWall||=y(o)||y(n)&&!c(i,s),v.push(a)}const b={...s};delete b.wall_ids,d.push({...b,poly:u.poly.map(e=>[e[0],e[1]]),wall_ids:v})}return{atoms:[...h.values()].sort((e,t)=>e.key.localeCompare(t.key)),rooms:d}},yg=(e,t,i,s,n)=>{const o=new Map([...i.values()].map(e=>[ng(e.a,e.b),e])),a=(e=>{const t=new Map;for(const i of e)"wall"===i.host?.kind&&t.set(i.host.id,(t.get(i.host.id)||0)+1);return t})(e.openings||[]),r=new Map;for(const e of t){const t=n?.get(e.key);if(t){const s=i.get(t);if(!s)throw new Qm("duplicate-id",t);r.set(e,s);continue}if(e.preferredIds.size>1)throw new Qm("duplicate-id",[...e.preferredIds].sort().join(","));const s=[...e.preferredIds][0],l=s?i.get(s):void 0;if(l){r.set(e,l);continue}const c=s?e.preferredCarriers.get(s):void 0;if(s&&c){r.set(e,{id:s,a:c.a,b:c.b,cm:0});continue}const h=o.get(e.key);if(h){r.set(e,h);continue}const d=[...i.values()].filter(t=>dg(e.a,e.b,t.a,t.b)>Zm),p=[...new Map(d.map(e=>[e.id,e])).values()];if(p.sort((e,t)=>(a.get(t.id)||0)-(a.get(e.id)||0)||ag(t.a,t.b)-ag(e.a,e.b)||e.id.localeCompare(t.id)),p[0])r.set(e,p[0]);else if(1===e.positionalIds.size){const t=i.get([...e.positionalIds][0]);t&&r.set(e,t)}}const l=new Map;for(const[e,t]of r){const i=l.get(t.id)||[];i.push(e),l.set(t.id,i)}for(const[e,t]of l){const s=i.get(e)||r.get(t[0]);if(!s)throw new Qm("duplicate-id",e);const n=[(s.a[0]+s.b[0])/2,(s.a[1]+s.b[1])/2];t.sort((e,t)=>{const i=hg(n,e.a,e.b)<=Zm?0:1,o=hg(n,t.a,t.b)<=Zm?0:1;if(i!==o)return i-o;return(hg(s.a,e.a,e.b)<=Zm?0:1)-(hg(s.a,t.a,t.b)<=Zm?0:1)||e.key.localeCompare(t.key)}),t[0].id=e}const c=(e=>{const t=new Set;for(const i of[e.rooms,e.openings,e.decor,e.room_drafts,e.partitions,e.wall_columns])for(const e of Array.isArray(i)?i:[])"string"==typeof e?.id&&e.id&&t.add(e.id);for(const i of Array.isArray(e.room_drafts)?e.room_drafts:[])for(const e of Array.isArray(i?.segments)?i.segments:[])"string"==typeof e?.id&&e.id&&t.add(e.id);return t})(e);for(const e of t)if(e.id){if(c.has(e.id))throw new Qm("duplicate-id",e.id);c.add(e.id)}const h=t.filter(e=>!e.id);if(s){const t=h.map(t=>{const[i,s]=og(t.a,t.b),n=`${String(e.id||"")}|${sg(i)}|${sg(s)}|${[...t.owners].sort().join(",")}`,o=ug(pg(n));return{atom:t,seed:n,digest:o,base:`wall-${o.slice(0,20)}`}}).sort((e,t)=>e.digest.localeCompare(t.digest)||e.atom.key.localeCompare(t.atom.key)),i=new Map;for(const e of t){const t=i.get(e.digest);if(t&&t!==e.seed)throw new Qm("duplicate-id",e.digest);i.set(e.digest,e.seed);let s=1,n=e.base;for(;c.has(n);)n=`${e.base}-${++s}`;e.atom.id=n,c.add(n)}}else for(const e of h)e.id=gg(c),c.add(e.id)},wg=(e,t)=>{if("partition"===e.host?.kind)return null;const i=[Number(e.x),Number(e.y)];if(!i.every(Number.isFinite))return null;const s=t=>{if(!(Number(t.cm)>0))return!1;const s=cg(i,t.a,t.b),n=ag(t.a,t.b),o=Number(e.length)/2;return s>=-Zm&&s<=1+Zm&&hg(i,t.a,t.b)<=.02*Eh&&Nl(t.a,t.b,Number(e.angle))&&Number.isFinite(o)&&o>=0&&s*n-o>=-Zm&&s*n+o<=n+Zm},n="wall"===e.host?.kind?t.find(t=>t.id===e.host.id):null,o=n&&s(n)?[n]:t.filter(s);if(1!==o.length)return null;const a=o[0];return{kind:"wall",id:a.id,t:Math.max(0,Math.min(1,cg(i,a.a,a.b)))}},kg=(e,t)=>{const i=[Number(e.x),Number(e.y)];if(!i.every(Number.isFinite))return null;const s=Number(e.length)/2,n=t.filter(t=>{if(!(Number(t.cm)>0))return!1;const n=cg(i,t.a,t.b),o=ag(t.a,t.b);return n>=-Zm&&n<=1+Zm&&hg(i,t.a,t.b)<=.02*Eh&&Nl(t.a,t.b,Number(e.angle))&&Number.isFinite(s)&&s>=0&&n*o-s>=-Zm&&n*o+s<=o+Zm}),o=(t=>{if(!t.length)return null;const s="wall"===e.host?.kind?t.find(t=>t.id===e.host.id):null;return s||[...t].sort((e,t)=>hg(i,e.a,e.b)-hg(i,t.a,t.b)||Number(t.cm)-Number(e.cm)||(e.idt.id?1:0))[0]})(n);return o?{kind:"wall",id:o.id,t:Math.max(0,Math.min(1,cg(i,o.a,o.b)))}:null},xg=(e,t,i)=>{const s=fg(e),{atoms:n,rooms:o}=bg(e,s);yg(e,n,s,t,i);const a=n.map(t=>{const i=t.id?s.get(t.id):void 0,n=((e,t,i)=>{if(t.zeroWall)return 0;const s=Array.isArray(e.walls)?e.walls:[],n=Ml(t.a,t.b,Eh),o=s.filter(e=>Number(e.cm)>0&&(!(e.key!==n&&!t.parentKeys.has(e.key))||!(!tg(e.a)||!tg(e.b))&&dg(t.a,t.b,e.a,e.b)>=ag(t.a,t.b)-Zm)).map(e=>Math.max(1,Math.min(100,Number(e.cm))));if(new Set(o.map(e=>e.toFixed(9))).size>1)throw new Qm("thickness-conflict",t.key);if(o.length)return o[0];const a=zl(s,t.a,t.b,Eh,1);return a>0?a:Number(i?.cm)>0?Number(i.cm):0})(e,t,i);return{...i||{},id:t.id,a:[...t.a],b:[...t.b],cm:n}}),r=new Map(n.map(e=>[e.key,e.id]));for(const e of o)e.wall_ids=e.wall_ids.map(e=>r.get(e));e.rooms=o,e.wall_segments=a,e.walls=a.filter(e=>e.cm>0).map(e=>({key:Ml(e.a,e.b,Eh),cm:e.cm,a:[...e.a],b:[...e.b]})),e.walls.length||delete e.walls,delete e.open_spans;for(const t of e.rooms)delete t.open_to;return((e,t)=>{const i=new Set;for(const t of[e.rooms,e.openings,e.decor,e.room_drafts,e.partitions,e.wall_columns,e.wall_segments])for(const e of Array.isArray(t)?t:[])"string"==typeof e?.id&&e.id&&i.add(e.id);for(const s of Array.isArray(e.room_drafts)?e.room_drafts:[]){const n=Array.isArray(s.segments)?s.segments:[];for(let o=0;o{const s=Array.isArray(e.openings)?e.openings:[];for(const e of s){if("partition"===e.host?.kind)continue;if(!e.host&&!i){const i=wg(e,t);i&&(e.host=i);continue}const s=wg(e,t)??(i?kg(e,t):null);if(s)e.host=s;else{if(!i)throw new Qm("opening-host",e.id);delete e.host}}})(e,a,t),a.reduce((e,t)=>e+(s.has(t.id)?0:1),0)};function $g(e,t={}){const i=JSON.stringify(e),s=eg(e);pl(s);let n=0;const o=Number(s?.model_version||0)<9;for(const e of Array.isArray(s?.spaces)?s.spaces:[]){const i=t.lineageSpaceId===String(e?.id||"")?t.lineageHints:void 0;n+=xg(e,o,i)}return s.model_version=9,pl(s),{config:s,changed:i!==JSON.stringify(s),migratedSegments:n}}const Sg=e=>!!e&&"object"==typeof e&&!Array.isArray(e);function Mg(e,t){const i=(e,t)=>{if(Array.isArray(e)&&Array.isArray(t)){const s=new Map;for(const t of e)Sg(t)&&"string"==typeof t.id&&t.id&&s.set(t.id,t);const n=t.map((t,n)=>{if(Sg(t)&&"string"==typeof t.id&&t.id){const e=s.get(t.id);return e?i(e,t):eg(t)}return n[t,t in e?i(e[t],s):eg(s)]);for(const t of Object.keys(e))delete e[t];for(const[t,i]of s)e[t]=i;return e}return eg(t)};return i(e,t)}const Cg=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),Dg=(e,t,i)=>Math.min(i,Math.max(t,e)),Pg=e=>Rh({spaces:[e]})[0],Tg=(e,t,i)=>{const s=i>0?i:1,n=e=>`${(e[0]/s).toFixed(12)},${(e[1]/s).toFixed(12)}`,o=n(e),a=n(t);return o0?a:1,l=Math.max(s*r*.02,1e-9),c=[];for(const t of e||[])for(const e of hi(t)||[])c.push([e[0],e[1]]);const h=[];for(const e of i||[])Array.isArray(e)&&e.length>=4&&e.slice(0,4).every(Number.isFinite)&&h.push([e[0],e[1]],[e[2],e[3]]);const d=(e,t)=>t.some(t=>Math.hypot(e[0]-t[0],e[1]-t[1])<=2*l),p=new Map;for(const a of e||[]){if(!a?.id)continue;const u=mc(e,a.id,t,i,s,n,o,r);if(u)for(let e=0;e0&&_>0&&a===m&&_!==a))continue;const g=u.poly[s],f=u.poly[(s+1)%u.poly.length],v=Math.hypot(f[0]-g[0],f[1]-g[1]);if(!(v>l&&v<.5*o-1e-9*o))continue;if(d(g,h)||d(f,h))continue;if(d(g,c)&&d(f,c))continue;const b=Tg(g,f,r),y=p.get(b);y?y.targets.add(a):p.set(b,{a:[g[0],g[1]],b:[f[0],f[1]],targets:new Set([a])})}}}let u=t.slice();const _=(e,t)=>Math.hypot(e[0]-t[0],e[1]-t[1])<=2*l,m=(e,t)=>{if(!Array.isArray(e.a)||!Array.isArray(e.b)||e.a.length<2||e.b.length<2)return!1;const i=[Number(e.a[0])*r,Number(e.a[1])*r],s=[Number(e.b[0])*r,Number(e.b[1])*r];return!![...i,...s].every(Number.isFinite)&&(_(i,t.a)&&_(s,t.b)||_(i,t.b)&&_(s,t.a))};for(const e of[...p.values()].filter(e=>1===e.targets.size).sort((e,t)=>Tg(e.a,e.b,r).localeCompare(Tg(t.a,t.b,r)))){const t=[...e.targets][0],i=u.filter(t=>m(t,e));if(new Set(i.map(e=>e.cm)).size>1)continue;let n=!1;u=u.map(i=>m(i,e)?(n=!0,i.cm===t?i:{...i,cm:t}):i),n||(u=Ll(u,e.a,e.b,t,s,r))}return u}const Rg=e=>{const t=[];for(const i of e||[]){const e=hi(i);if(e?.length)for(let i=0;i"string"==typeof e?.id?e.id:"").filter(Boolean),h=new Set(c),d=new Map;for(const e of c){const t=Jm("space",e);t.layers>0&&Ym("space",t.root)&&Xm(d,t.root,e)}const p=new Map,u=new Map,_=new Map,m=new Map;for(const e of r){const t="string"==typeof e?.id?e.id:"";if(!t)continue;const i=new Map;for(const s of Array.isArray(e.rooms)?e.rooms:[]){const e="string"==typeof s?.id?s.id:"";if(!e)continue;const n=Jm("room",e);n.layers>0&&Ym("room",n.root)&&Xm(i,n.root,e),u.has(e)||u.set(e,t),_.has(e)||_.set(e,String(s.name||""));const o="string"==typeof s.area?s.area:"";if(o){const i=m.get(o)||[];i.push({spaceId:t,roomId:e}),m.set(o,i)}}p.set(t,i)}const g=new Set(u.keys()),f=new Map,v=new Map;for(const e of l)"string"==typeof e?.id&&e.id&&(!0===e.removed?v.set(e.id,e):f.set(e.id,e));const b={spaceRefsRemapped:0,roomRefsRemapped:0,positionsRemapped:0,markersDetached:0,positionsUnresolved:0,nestedRefsUnresolved:0,deadSpaceIds:[],orphanRoomLabelsRemoved:0,orphanDevicePositionsRemoved:0,orphanGroupPositionsRemoved:0,liveMissingPositionsRemoved:0,removedPositions:[],liveMissingPositions:[],unverifiedPositions:[]},y=new Set,w=e=>h.has(e)?null:(()=>{const t=Jm("space",e).root;if(!Ym("space",t))return null;const i=d.get(t)||[];return 1===i.length?i[0]:null})(),k=(e,t)=>{const i=Jm("room",e).root;if(!Ym("room",i))return null;const s=p.get(t)?.get(i)||[];return 1===s.length?s[0]:null},x=e=>{const t=i.effectiveAreaByMarker?.[e]||"",s=t&&m.get(t)||[];return 1===s.length?s[0]:null},$=(e,t,i)=>{if("string"==typeof e.room_id&&e.room_id&&!g.has(e.room_id)){const s=t?k(e.room_id,t):null;s?(e.room_id=s,b.roomRefsRemapped++):i?(e.room_id=i.roomId,b.roomRefsRemapped++):!0!==e.removed&&delete e.room_id}const s=e.vacuum?.segment_map;if(s&&"object"==typeof s&&!Array.isArray(s))for(const e of Object.keys(s)){const i=s[e];if("string"!=typeof i||!i||g.has(i))continue;const n=t?k(i,t):null;n?(s[e]=n,b.roomRefsRemapped++):b.nestedRefsUnresolved++}};for(const e of l){const t="string"==typeof e?.id?e.id:"";if(!t)continue;const i="string"==typeof e.space?e.space:"",s=i&&!h.has(i),o=n[t],a="string"==typeof o?.s?o.s:"",r=a&&!h.has(a),l=!0===e.removed;let c=i&&h.has(i)?i:null,d=null,p=!1;if(s){const s=w(i);s?(e.space=s,c=s,p=!0,b.spaceRefsRemapped++):l||"virtual"===e.binding?l||(delete e.space,c=null,b.markersDetached++):(d=x(t),d?(e.space=d.spaceId,c=d.spaceId,b.spaceRefsRemapped++):(delete e.space,c=null,b.markersDetached++))}l&&!p||$(e,c,d),r&&p&&a===i&&c&&(n[t]={...o,s:c},b.positionsRemapped++,y.add(t))}for(const e of Object.keys(n)){if(y.has(e))continue;const t=n[e],i="string"==typeof t?.s?t.s:"";if(!i||h.has(i))continue;const s=w(i);if(s){if(e.startsWith("rl_")){const i=e.slice(3),o=k(i,s);if(o){const i=`rl_${o}`;Km(n,i)||(n[i]={...t,s:s}),delete n[e],b.roomRefsRemapped++,b.positionsRemapped++;continue}}n[e]={...t,s:s},b.positionsRemapped++}}const S=i.ownerRoster,M=!0===S?.authoritative,C=new Set(S?.deviceIds||[]),D=new Set(S?.entityIds||[]),P=new Set(Array.isArray(s.settings?.known_devices)?s.settings.known_devices.filter(e=>"string"==typeof e):[]),T=(e,t="")=>{const i=String(S?.names?.[e]||t||"").trim();return i&&i!==e?i:""},I=(e,t,i,s="",n)=>({id:e,spaceId:t,kind:i,name:T(e,s),...n?{reason:n}:{}}),R=e=>{"room_label"===e?b.orphanRoomLabelsRemoved++:"group"===e?b.orphanGroupPositionsRemoved++:b.orphanDevicePositionsRemoved++},A=new Set;for(const[e,t]of Object.entries(n)){const s="string"==typeof t?.s?t.s:"";if(!s||h.has(s))continue;let o,a;const r=f.get(e),l=v.get(e);if(r)o=I(e,s,"device",String(r.name||"")),a="live";else if(l)o=I(e,s,"device",String(l.name||"")),a="absent";else if(e.startsWith("rl_")){const t=e.slice(3);o=I(e,s,"room_label",_.get(t)||""),a=g.has(t)?"live":"absent"}else if(e.startsWith("lg_")){const t=e.slice(3);o=I(e,s,"group"),a=D.has(t)?"live":M?"absent":"unverified","unverified"===a&&(o.reason="registry_unavailable")}else C.has(e)?(o=I(e,s,"device"),a="live"):P.has(e)?(o=I(e,s,"device"),a=M?"absent":"unverified","unverified"===a&&(o.reason="registry_unavailable")):(o=I(e,s,"unknown","","unknown_owner"),a="unverified");if("absent"!==a){if("live"===a){if(b.liveMissingPositions.push(o),!0===i.removeLiveMissingPositions){delete n[e],b.liveMissingPositionsRemoved++,R(o.kind),b.removedPositions.push(o);continue}}else b.unverifiedPositions.push(o);b.positionsUnresolved++,A.add(s)}else delete n[e],R(o.kind),b.removedPositions.push(o)}return b.deadSpaceIds=[...A].sort((e,t)=>e.localeCompare(t)),{config:s,layout:n,report:b,changed:JSON.stringify(s)!==o||JSON.stringify(n)!==a}}(e,t,i),a=o.config,r=cl(a,o.layout);pl(a),dl(o.layout);const l=JSON.stringify(e||{}),c=JSON.stringify(t||{}),h=Number.isInteger(Number(a.model_version))?Number(a.model_version):0,d=(e=>{let t=0,i=0,s=0;for(const i of e.markers||[]){if("ripple"===i.display&&(i.display="icon_ripple",t++),Array.isArray(i.controls)){const e="string"==typeof i.binding&&i.binding.startsWith("entity:")?i.binding.slice(7):"",s=e?i.controls.filter(t=>t!==e):i.controls;JSON.stringify(s)!==JSON.stringify(i.controls)&&(i.controls=s.length?s:null,t++)}const e=i.vacuum;e&&Cg(e,"trail")&&(["never","cleaning","always"].includes(e.trail_mode)||(e.trail_mode=!1===e.trail?"never":"cleaning"),delete e.trail,t++)}for(const n of e.spaces||[]){const e=n.settings;"glow"===e?.fill_mode&&("boolean"!=typeof e.glow_enabled&&(e.glow_enabled=!0),e.fill_mode="none",t++,i++);for(const e of n.rooms||[]){const i=e.settings;"glow"===i?.fill_mode&&("boolean"!=typeof i.glow&&(i.glow=!0),delete i.fill_mode,t++,s++)}if(Cg(n,"segments")&&(delete n.segments,t++),Cg(n,"plan_scale")){const e=Number(n.plan_scale);Number.isFinite(e)&&e>=Dh&&e<=Ph&&(Cg(n,"plan_scale_x")||(n.plan_scale_x=e),Cg(n,"plan_scale_y")||(n.plan_scale_y=e),delete n.plan_scale,t++)}const o=Number(n.cell_cm);Cg(n,"cell_cm")&&(!Number.isFinite(o)||o<.1||o>1e3)&&(n.cell_cm=Number.isFinite(o)&&o>0?Dg(o,.1,1e3):5,t++);const a=Number(n.cell_cm),r=Number.isFinite(a)&&a>0?a:5;for(const e of n.wall_columns||[])if("circle"===e.shape)Cg(e,"angle")&&(delete e.angle,t++);else if("square"===e.shape&&Cg(e,"angle")){const i=((Number(e.angle)||0)%90+90)%90;e.angle!==i&&(e.angle=i,t++)}for(const e of n.decor||[]){if(Cg(e,"width")){const i=Number(e.width);(Cg(e,"width_cm")||Number.isFinite(i))&&(Cg(e,"width_cm")||(e.width_cm=Number(Dg(i/Nh*r,.1,100).toFixed(6))),delete e.width,t++)}if("rect"!==e?.kind&&"ellipse"!==e?.kind||!0!==e.fill||(Cg(e,"fill_color")||(e.fill_color=e.color||"#607d8b",t++),Cg(e,"fill_opacity")||(e.fill_opacity=.25,t++)),"text"!==e?.kind)continue;void 0===e.size_cm?(e.size_cm=Number(Dg(ts*is(e)/Nh*r,.1,2e3).toFixed(6)),delete e.scale,delete e.size,t++):(Cg(e,"scale")||Cg(e,"size"))&&(delete e.scale,delete e.size,t++);let i=String(e.text??"");const s=[...i.matchAll(/\{([^{}\r\n]+)\}/g)].some(e=>!!Yi(e[1]));if(!(Cg(e,"entity")||Cg(e,"attr")||Cg(e,"unit")))continue;const n=String(e.unit??"").trim(),o="state"===String(e.attr??"").trim().toLowerCase()?null:e.attr,a=s||n?"":Ji(e.entity,o);if(s||a){if(a){const t=i.indexOf("{}");i=t>=0?i.slice(0,t)+a+i.slice(t+2):`${i}${i?" ":""}${a}`,e.text=i}delete e.entity,delete e.attr,delete e.unit,t++}}}return{total:t,glowSpaces:i,glowRooms:s}})(a);let p=d.total;const u=(_=a.spaces||[],JSON.parse(JSON.stringify(_)));var _;const m=xm(a.spaces||[],o.layout);let g=0,f=0,v=0,b="";const y=m.spaces.map(e=>{const t=function(e){const t=JSON.parse(JSON.stringify(e||{}));let i=Array.isArray(t.rooms)?t.rooms:[];const s=new Map;for(const e of i){const t=hi(e);if(t)for(let e=0;ee.key.localeCompare(t.key))){let t=null;for(const s of $a(e,i)){const e=r.get(_a(s.from));if(e&&e!==_a(s.to))continue;const n=wa(i,s);if(ka(i,n,s)){t=s,i=n;break}}t?(r.set(_a(t.from),_a(t.to)),n++,a=Math.max(a,Math.hypot(t.to[0]-t.from[0],t.to[1]-t.from[1]))):o++}t.rooms=i;for(const e of t.room_drafts||[]){if(!Array.isArray(e?.points)||e.points.length<2)continue;const t=e.points.map(e=>[...e]),i=t.slice(0,-1).flatMap((i,s)=>{const n=t[s+1],o=pa(i,n);return o?[{key:`${String(e.id||"")}:${s}`,a:[...i],b:[...n],axis:o.axis}]:[]});let s=t;for(const e of i){let t=null;for(const i of $a(e,[{poly:s}])){const e=s.map(e=>ya(e,i)),n=e.length>=4&&ma(e[0],e[e.length-1]),o=n?e.slice(0,-1):e;if(n?va(o):ba(o)){t=i,s=e;break}}t?(n++,a=Math.max(a,Math.hypot(t.to[0]-t.from[0],t.to[1]-t.from[1]))):o++}e.points=s}for(const e of t.partitions||[]){if(!Array.isArray(e?.a)||!Array.isArray(e?.b))continue;const i=pa(e.a,e.b);if(!i)continue;const s={key:String(e.id||ga(e.a,e.b)),a:[...e.a],b:[...e.b],axis:i.axis};let r=null;for(const i of $a(s,[{poly:[e.a,e.b]}])){const s=ya(e.a,i),n=ya(e.b,i),o=Math.hypot(n[0]-s[0],n[1]-s[1]);if(!(o>0))continue;const a=(t.openings||[]).filter(t=>"partition"===t?.host?.kind&&t.host.id===e.id).every(e=>{const t=Number(e.host.t),i=Number(e.length);return Number.isFinite(t)&&t>=0&&t<=1&&Number.isFinite(i)&&i>0&&t*o-i/2>=-1e-12&&t*o+i/2<=o+1e-12});if(a){r=i,e.a=s,e.b=n;break}}r?(n++,a=Math.max(a,Math.hypot(r.to[0]-r.from[0],r.to[1]-r.from[1]))):o++}return{space:t,report:{wallsStraightened:n,wallsStraightenSkipped:o,maxStraightenShift:a},changed:n>0}}(e);g+=t.report.wallsStraightened,f+=t.report.wallsStraightenSkipped;const i=Number(e?.cell_cm)>0?Number(e.cell_cm):5,s=t.report.maxStraightenShift/Eh*i;return s>v&&(v=s,b=String(e?.id||"")),t.space}),w=g?xm(y,m.layout):{...m,spaces:y};a.spaces=w.spaces;const k=g?{...m.report,moved:m.report.moved+w.report.moved,coordsCanonicalized:m.report.coordsCanonicalized+w.report.coordsCanonicalized,maxShift:Math.max(m.report.maxShift,w.report.maxShift),maxShiftCm:Math.max(m.report.maxShiftCm,w.report.maxShiftCm),maxSpace:w.report.maxShiftCm>m.report.maxShiftCm?w.report.maxSpace:m.report.maxSpace,rotated:m.report.rotated+w.report.rotated,removedDrafts:m.report.removedDrafts+w.report.removedDrafts}:{...m.report};let x=0,$=0,S=0,M=0,C=0,D=0,P=0,T=0;for(let e=0;e0===Number(e.cm)),walls:t.walls||[]}),o=Pg(t),r=Pg(i);if(!o||!r)continue;const l=Rg(o.rooms),c=Rg(r.rooms),h=.02*Nh,d=(t.wall_segments||[]).filter(e=>0===Number(e.cm)).map(e=>({...e,key:Ml(e.a,e.b,Eh),cm:0})),p=new Set(d.map(e=>e.key)),_=B_(t,o.rooms,Mh,h);$+=_.length;for(const e of _){const t=[e[0]/Mh,e[1]/Mh],i=[e[2]/Mh,e[3]/Mh],s=Ml(t,i,Eh);p.has(s)||(p.add(s),d.push({key:s,a:t,b:i,cm:0}))}const m=d.length,g=Ol(d,l,c,Eh,Mh),f=(e,t,i)=>{const s=i[0]-t[0],n=i[1]-t[1],o=s*s+n*n;if(!(o>0))return Math.hypot(e[0]-t[0],e[1]-t[1]);const a=Math.max(0,Math.min(1,((e[0]-t[0])*s+(e[1]-t[1])*n)/o));return Math.hypot(e[0]-(t[0]+s*a),e[1]-(t[1]+n*a))},v=g.filter(e=>{if(!Array.isArray(e.a)||!Array.isArray(e.b))return!1;const t=e.a.map(e=>e*Mh),i=e.b.map(e=>e*Mh);return c.some(([e,s])=>f(t,e,s)<=4*h&&f(i,e,s)<=4*h)});S+=Math.max(0,m-v.length);const b=(i.wall_segments||[]).filter(e=>Number(e.cm)>0);i.wall_segments=[...b,...v.map(({key:e,...t})=>t)];const y=v.map(e=>[e.a[0]*Mh,e.a[1]*Mh,e.b[0]*Mh,e.b[1]*Mh]),w=Array.isArray(t.walls)?t.walls.length:0;let k=Ol(t.walls,l,c,Eh,Mh);k=Ig(r.rooms,k,y,Eh,Number(i.cell_cm)>0?Number(i.cell_cm):5,Nh,Mh),k=vc(r.rooms,k,y,Eh,Number(i.cell_cm)>0?Number(i.cell_cm):5,Nh,Mh),k=Fl(k,i.rooms||[],Eh,1,y.map(e=>[e[0]/Mh,e[1]/Mh,e[2]/Mh,e[3]/Mh])),x+=Math.max(0,w-k.length),k.length?i.walls=k:delete i.walls;const I=Tm(i.partitions||[],{pitch:Eh,geometry:Rm(i)});I.merged&&(M+=I.merged,i.partitions=I.partitions,Im(i.openings,i.partitions,I.openingMoves,{coordScale:Mh,cellCm:Number(i.cell_cm)>0?Number(i.cell_cm):5,gridPitch:Nh}));const R=Pg(i);if(R){const e=n(i,R,i.walls||[],y,{pitch:Eh,cellCm:Number(i.cell_cm)>0?Number(i.cell_cm):5,gridPitch:Nh,coordScale:Mh});e.partitionsReconciled&&(C+=e.partitionsReconciled,D+=e.openingsRehosted,e.partitions.length?i.partitions=e.partitions:delete i.partitions,e.openings.length?i.openings=e.openings:delete i.openings,e.walls.length?i.walls=e.walls:delete i.walls),e.removedDrafts&&(P+=e.removedDrafts,e.roomDrafts.length?i.room_drafts=e.roomDrafts:delete i.room_drafts)}JSON.stringify({zero:(i.wall_segments||[]).filter(e=>0===Number(e.cm)),walls:i.walls||[]})!==s&&T++}let I=0;h<=9&&(I=function(e){const t=$g(e);return Mg(e,t.config),{...t,config:e}}(a).migratedSegments);const R=pl(a),A=dl(w.layout),z=JSON.stringify(R)!==l||JSON.stringify(A)!==c;h<9&&z&&(R.model_version=9);const F=JSON.stringify(R)!==l||JSON.stringify(A)!==c,N=Number.isInteger(Number(R.model_version))?Number(R.model_version):h,E=F?k:{...k,moved:0,coordsCanonicalized:0,maxShift:0,maxShiftCm:0,maxSpace:"",rotated:0,removedDrafts:0},O=F?o.report:{...o.report,spaceRefsRemapped:0,roomRefsRemapped:0,positionsRemapped:0,markersDetached:0,orphanRoomLabelsRemoved:0,orphanDevicePositionsRemoved:0,orphanGroupPositionsRemoved:0,liveMissingPositionsRemoved:0};return{config:R,layout:A,report:{...E,modelFrom:h,modelTo:N,migrated:F?p:0,glowSpacesMigrated:F?d.glowSpaces:0,glowRoomsMigrated:F?d.glowRooms:0,canonicalized:F?T:0,wallSegmentsMigrated:F?I:0,legacyZeroWallsMigrated:F?$:0,wallsMerged:F?x:0,spansMerged:F?S:0,partitionsMerged:F?M:0,partitionsReconciled:F?C:0,openingsRehosted:F?D:0,redundantDraftsRemoved:F?P:0,wallsStraightened:F?g:0,wallsStraightenSkipped:f,maxStraightenShiftCm:F?v:0,maxStraightenSpace:F?b:"",latticeCoordinatesCanonicalized:F?r.canonicalized:0,latticeCoordinatesFar:F?r.far:0,latticeMaxShift:F?r.maxShift:0,latticeMaxShiftCm:F?r.maxShiftCm:0,latticeSpaces:F?r.spaces:[],...O},changed:F}}function zg(e,t,i){const s=(e?.spaces||[]).find(e=>e?.id===i),n=new Set((s?.rooms||[]).map(e=>String(e?.id||"")).filter(Boolean)),o=[...new Set((e?.markers||[]).filter(e=>!0!==e?.removed&&"string"==typeof e?.id).filter(e=>e.space===i||"string"==typeof e.room_id&&n.has(e.room_id)||t?.[e.id]?.s===i).map(e=>e.id))].sort((e,t)=>e.localeCompare(t));return{markerIds:o,count:o.length}}function Fg(e){return e instanceof Error?e.name||"Error":typeof e}function Ng(e){return Bd({id:e?.id??"",cell_cm:e?.cell_cm,rooms:e?.rooms||[],walls:e?.walls||[],wall_segments:e?.wall_segments||[],open_spans:e?.open_spans||[],openings:e?.openings||[],partitions:e?.partitions||[],room_drafts:e?.room_drafts||[],wall_columns:e?.wall_columns||[]})}function Eg(e,t,i,s=Nh,n=1e3){return(Array.isArray(e?.openings)?e.openings:[]).flatMap(e=>{const o={...e,rx:Number(e.x)*n,ry:Number(e.y)*n,rlen:Number(e.length)*n};if(!e.host||"wall"===e.host.kind)return[o];const a=Jp(e,t.partitions,n,i,s);return a.resolved?[{...e,rx:a.resolved.center[0],ry:a.resolved.center[1],rlen:a.resolved.length,angle:a.resolved.angle,partitionHost:a.resolved}]:[]})}function Og(e,t=()=>!0){return e.flatMap(e=>e.host&&e.partitionHost&&t(e)?[Qp(e.partitionHost)]:[])}function Hg(e,t,i,s,n,o,a=Nh,r=1e3){const l=gc(t.rooms,[...i],s,n,o,a,r);return e.flatMap(e=>{const t={x:e.rx,y:e.ry,angle:Number(e.angle)||0,length:e.rlen};return e.host&&"wall"!==e.host.kind?e.partitionHost&&iu(e.partitionHost,l,2e-4*a)?[t]:[]:[t]})}function Lg(e,t){const i=Eh,s=Nh,n=Mh,o=Number.isFinite(Number(t.cellCm))&&Number(t.cellCm)>0?Number(t.cellCm):5,a=Array.isArray(e?.walls)?e.walls:[],r=function(e,t,i=Nh,s=1e3){return zd(t.rooms,e?.open_spans,s,.02*i)}(e,t,s,n),l=function(e,t,i=Nh){if(!t.length)return[];const s=e.filter(e=>e?.id),n=.02*i,o=[];for(let e=0;e{const t=[(e[0]+e[2])/2,(e[1]+e[3])/2];return h.some(e=>Hs(t,e)<4*n)}).map(e=>[...e]);d.length&&o.push({a:a,b:r,segs:d})}return o}(t.rooms,r,s).flatMap(e=>e.segs),c=Eg(e,t,o,s,n),h=Og(c),d=ch(t,o,s,2e-4*s,h).all;return{space:t,walls:a,openCuts:l,openings:c,roomOpenings:Hg(c,t,a,l,i,o,s,n),partitionCuts:h,physicalBodies:d,wallKeyPitch:i,cellCm:o,gridPitch:s,coordScale:n}}function Bg(e,t,i){const s="string"==typeof e?.title?e.title.trim():"",n=null==e?.id?"":String(e.id).trim();return{spaceId:n,displayName:s||n||i(t+1)}}function jg(e,t={}){const i=(t.fingerprint||Bd)(e),s=Array.isArray(e?.spaces)?e.spaces:[],n=t.fallbackSpaceName||(e=>`Space ${e}`),o=t.prepareSpace||Lg,a=t.wallPass||Oc,r=t.floorPass||zc,l=[];for(let i=0;i0||d.physicalBodies.length>0;if(!d.space.rooms.length&&!p){l.push({...h,status:"not-applicable"});continue}let u=null;if(p){try{u=a(d.space.rooms,d.walls,d.openCuts,d.roomOpenings,d.wallKeyPitch,d.cellCm,d.gridPitch,d.coordScale,d.physicalBodies)}catch(e){l.push({...h,status:"failed",reason:"wall-exception",detail:Fg(e)});continue}if(null==u){l.push({...h,status:"failed",reason:"wall-null"});continue}if("degraded-extra"===u.status){l.push({...h,status:"failed",reason:"wall-degraded-extra"});continue}if("failed-core"===u.status){l.push({...h,status:"failed",reason:"wall-failed-core"});continue}t.captureWallGeometry?.(d,u)}if(d.space.rooms.length&&null==u?.paperGeom){let e;try{e=r(d.space.rooms,d.walls,d.openCuts,d.wallKeyPitch,d.cellCm,d.gridPitch,d.coordScale)}catch(e){l.push({...h,status:"failed",reason:"floor-exception",detail:Fg(e)});continue}if(null==e){l.push({...h,status:"failed",reason:"floor-null"});continue}}l.push({...h,status:"ok"})}const c=l.filter(e=>"failed"===e.status);return{fingerprint:i,spaces:l,failures:c,ok:0===c.length}}class qg{constructor(e=50){this._undo=[],this._redo=[],this._limit=Math.max(30,Math.floor(e))}get canUndo(){return this._undo.length>0}get canRedo(){return this._redo.length>0}get undoName(){return this._undo[this._undo.length-1]?.name??null}get redoName(){return this._redo[this._redo.length-1]?.name??null}get size(){return this._undo.length}push(e){this._undo.push(e),this._undo.length>this._limit&&this._undo.splice(0,this._undo.length-this._limit),this._redo=[]}undo(){const e=this._undo.pop()??null;return e&&this._redo.push(e),e}redo(){const e=this._redo.pop()??null;return e&&this._undo.push(e),e}clear(){this._undo=[],this._redo=[]}}const Wg=new WeakMap;const Ug=(e,t,i)=>255===e[i+3]&&t.every((t,s)=>Math.abs(e[i+s]-t)<=2);async function Gg(e){const t=e.defaultView;if(!t||!t.CSS?.supports?.("mix-blend-mode","screen"))return!1;const i=[128,32,16],s=[16,64,128],n=[9,19,29],o=`\n \n \n \n \n \n `,a=t.URL.createObjectURL(new Blob([o],{type:"image/svg+xml"}));try{const o=await new Promise((e,i)=>{const s=new t.Image,n=t.setTimeout(()=>i(new Error("SVG blend probe timeout")),1e3);s.onload=()=>{t.clearTimeout(n),e(s)},s.onerror=()=>{t.clearTimeout(n),i(new Error("SVG blend probe failed"))},s.src=a}),r=e.createElement("canvas");r.width=4,r.height=1;const l=r.getContext("2d",{willReadFrequently:!0});if(!l)return!1;l.drawImage(o,0,0,4,1);const c=l.getImageData(0,0,4,1).data;return Ug(c,i,0)&&Ug(c,function(e,t){return[0,1,2].map(i=>Math.round(255-(255-e[i])*(255-t[i])/255))}(i,s),4)&&Ug(c,s,8)&&Ug(c,n,12)}catch{return!1}finally{t.URL.revokeObjectURL(a)}}const Vg={now:()=>performance.now(),requestFrame:e=>requestAnimationFrame(e),cancelFrame:e=>cancelAnimationFrame(e)},Kg=e=>Math.max(0,Math.min(1,e)),Yg=(e,t,i)=>e+(t-e)*i,Jg=(e,t,i)=>{const s=1-e;return 3*s*s*e*t+3*s*e*e*i+e*e*e};function Xg(e,t){return{centerX:e.x+e.w/2,centerY:e.y+e.h/2,pixelsPerUnit:t>0&&e.w>0?t/e.w:1,viewBox:{...e}}}function Zg(e,t,i){const s=Math.max(1e-9,e.pixelsPerUnit),n=Math.max(1e-9,t/s),o=Math.max(1e-9,i/s);return{x:e.centerX-n/2,y:e.centerY-o/2,w:n,h:o}}function Qg(e){const t=e.trim(),i=/^rgba?\(\s*([\d.]+)[, ]+([\d.]+)[, ]+([\d.]+)(?:\s*[,/]\s*([\d.]+))?\s*\)$/i.exec(t);if(i)return[Number(i[1]),Number(i[2]),Number(i[3]),null==i[4]?1:Number(i[4])];const s=/^#([0-9a-f]{6}|[0-9a-f]{8})$/i.exec(t)?.[1];return s?[parseInt(s.slice(0,2),16),parseInt(s.slice(2,4),16),parseInt(s.slice(4,6),16),8===s.length?parseInt(s.slice(6,8),16)/255:1]:null}function ef(e,t,i){const s=Qg(e),n=Qg(t);if(!s||!n)return i<.5?e:t;const o=Kg(i);return`rgba(${Math.round(Yg(s[0],n[0],o))}, ${Math.round(Yg(s[1],n[1],o))}, ${Math.round(Yg(s[2],n[2],o))}, ${Yg(s[3],n[3],o).toFixed(3)})`}function tf(e,t,i){const s=(e=>{const t=Kg(e);if(0===t||1===t)return t;let i=0,s=1,n=t;for(let e=0;e<12;e++)n=(i+s)/2,Jg(n,.2,.2){const t=this._state;if(!t||t.token!==n)return;const i=Kg((e-t.startedAt)/t.duration);t.presented=i>=1?t.to:tf(t.from,t.to,i),t.phase=i>=1?"settling":"running",this._hooks.frame(t),i<1?this._raf=this._clock.requestFrame(a):(this._raf=0,this._hooks.settled(t),this._state?.token===n&&(this._state=null))};return this._raf=this._clock.requestFrame(a),n}cancel(e=!0){this._raf&&this._clock.cancelFrame(this._raf),this._raf=0;const t=this._state;this._state=null,this._token++,t&&e&&(t.phase="settling",t.presented=t.to,this._hooks.frame(t),this._hooks.settled(t))}dispose(){this.cancel(!1)}}const nf="houseplan_card_labs_v1",of=Object.freeze([Object.freeze({id:"iso",issue:89,since:"1.62.0",expires:"1.65.0",summary:"Volumetric plan renderer"})]);function af(e){const t=/^(\d+)\.(\d+)\.(\d+)(?:-[0-9A-Za-z.-]+)?$/.exec(String(e||"").trim());if(!t)return null;const i=t.slice(1).map(Number);return i.every(e=>Number.isSafeInteger(e))?i:null}function rf(e,t){for(let i=0;i<3;i++)if(e[i]!==t[i])return e[i]e.split(",")).map(e=>e.trim()).filter(Boolean)}function uf(e,t,i,s=of){const n=function(e,t=of){const i=af(e),s=new Map;if(!i||!cf(t))return s;for(const e of t){const t=af(e.since),n=af(e.expires);rf(i,t)>=0&&rf(i,n)<0&&s.set(e.id,e)}return s}(i,s),o=new Set(cf(s)?s.map(e=>e.id):[]),a=new Set(function(e){if(!e)return[];try{const t=JSON.parse(e);return Array.isArray(t)?t.filter(e=>"string"==typeof e):[]}catch{return[]}}(t).filter(e=>n.has(e)));let r=!1;const l=e=>{if("off"===e)return a.clear(),void(r=!0);const t=e.startsWith("-"),i=t?e.slice(1):e;o.has(i)&&(r=!0,t||!n.has(i)?a.delete(i):a.add(i))};for(const t of pf(new URLSearchParams(String(e.search||"").replace(/^\?/,""))))l(t);for(const t of pf(hf(e.hash)))l(t);const c=Object.freeze([...a].sort());return{active:c,space:df(e.hash),persist:r?JSON.stringify(c):void 0,knownUrlOperation:r}}let _f={active:Object.freeze([]),space:""},mf="",gf=!1,ff="";const vf=new Set;function bf(){if("undefined"==typeof window)return _f;const e=uf(window.location,function(){try{return window.localStorage.getItem(nf)}catch{return null}}(),mf);void 0!==e.persist&&function(e){try{window.localStorage.setItem(nf,e)}catch{}}(e.persist),_f={active:e.active,space:e.space},window.__hpLabs=e.active;for(const e of vf)e(_f);return _f}function yf(){bf()}function wf(e){return mf=e,"undefined"==typeof window?_f:(gf||(gf=!0,window.addEventListener("hashchange",yf),window.addEventListener("popstate",yf)),bf())}const kf=Object.freeze({rotDeg:0,tiltDeg:20,xyScale:1,zScale:1,origin:Object.freeze([500,500])});function xf(e){return[e.rotDeg,e.tiltDeg,e.xyScale,e.zScale,e.origin[0],e.origin[1]].every(Number.isFinite)&&Math.abs(e.xyScale)>1e-12&&Math.abs(Math.cos(e.tiltDeg*Math.PI/180))>1e-12}function $f(e,t,i=kf){if(!(xf(i)&&Number.isFinite(e[0])&&Number.isFinite(e[1])&&Number.isFinite(t)))throw new Error("invalid isometric projection input");const s=i.rotDeg*Math.PI/180,n=i.tiltDeg*Math.PI/180,o=e[0]-i.origin[0],a=e[1]-i.origin[1],r=(o*Math.cos(s)-a*Math.sin(s))*i.xyScale,l=(o*Math.sin(s)+a*Math.cos(s))*i.xyScale;return[i.origin[0]+r,i.origin[1]+l*Math.cos(n)-t*i.zScale*Math.sin(n)]}function Sf(e,t=kf){if(!xf(t)||!Number.isFinite(e[0])||!Number.isFinite(e[1]))throw new Error("invalid isometric projection input");const i=t.rotDeg*Math.PI/180,s=t.tiltDeg*Math.PI/180,n=(e[0]-t.origin[0])/t.xyScale,o=(e[1]-t.origin[1])/(t.xyScale*Math.cos(s));return[t.origin[0]+n*Math.cos(i)+o*Math.sin(i),t.origin[1]-n*Math.sin(i)+o*Math.cos(i)]}function Mf(e=kf){return`matrix(${function(e=kf){if(!xf(e))throw new Error("invalid isometric camera");const t=e.rotDeg*Math.PI/180,i=e.tiltDeg*Math.PI/180,s=e.xyScale*Math.cos(t),n=-e.xyScale*Math.sin(t),o=e.xyScale*Math.sin(t)*Math.cos(i),a=e.xyScale*Math.cos(t)*Math.cos(i);return[s,o,n,a,e.origin[0]-s*e.origin[0]-n*e.origin[1],e.origin[1]-o*e.origin[0]-a*e.origin[1]]}(e).map(e=>Number(e.toFixed(12))).join(" ")})`}function Cf(e,t=kf){const{rect:i,wallHeight:s}=e,n=e.openingHeight??s,o=e.floorDepth??0;if(!(i.w>=0)||!(i.h>=0)||!Number.isFinite(s)||!Number.isFinite(n)||!Number.isFinite(o)||s<0||n<0||o<0)throw new Error("invalid isometric frame");const a=[[i.x,i.y],[i.x+i.w,i.y],[i.x+i.w,i.y+i.h],[i.x,i.y+i.h]],r=Math.max(s,n),l=a.flatMap(e=>[$f(e,-o,t),$f(e,r,t)]),c=l.map(e=>e[0]),h=l.map(e=>e[1]),d=Math.min(...c),p=Math.min(...h);return{x:d,y:p,w:Math.max(...c)-d,h:Math.max(...h)-p}}const Df=e=>`${Number(e[0].toFixed(4))} ${Number(e[1].toFixed(4))}`;function Pf(e){let t=0;for(let i=0;iArray.isArray(e)&&Number.isFinite(e[0])&&Number.isFinite(e[1])).map(e=>[Number(e[0]),Number(e[1])]),i=t[t.length-1];return t.length>1&&t[0][0]===i[0]&&t[0][1]===i[1]&&t.pop(),t}(e);if(i.length<3)return[];const s=!t;return Pf(i)>0===s?i:[...i].reverse()}function If(e,t,i){return e.length?`M ${e.map(e=>Df($f(e,i,t))).join(" L ")} Z`:""}function Rf(e,t,i){const s=t[1]-e[1],n=-(t[0]-e[0]),o=i.rotDeg*Math.PI/180;return s*Math.sin(o)+n*Math.cos(o)}function Af(e,t,i=kf){if(!Number.isFinite(t)||t<0)throw new Error("invalid floor edge height");const s=(e||[]).map(e=>(e||[]).map((e,t)=>function(e,t){const i=Tf(e,t);if(!i.length)return i;let s=0;for(let e=1;e0)).filter(e=>e.length>=3&&Math.abs(Pf(e))>=1e-9)).filter(e=>e.length&&Pf(e[0])>0);s.sort((e,t)=>{const i=e[0][0],s=t[0][0];return i[0]-s[0]||i[1]-s[1]||Math.abs(Pf(t[0]))-Math.abs(Pf(e[0]))});const n=[],o=[];let a=0;for(let e=0;ee.depth-t.depth||e.component-t.component||e.edge-t.edge),{footprintPath:n.join(" "),sides:o,componentCount:s.length,edgeCount:a}}function zf(e,t){return e^=Math.round(64*(Number.isFinite(t)?t:0)),Math.imul(e,16777619)>>>0}const Ff=e=>e.every(Number.isFinite);function Nf(e,t,i,s){const n=e[0]*i,o=e[1]*s,a=t*Math.PI/180;return[n*Math.cos(a)-o*Math.sin(a),n*Math.sin(a)+o*Math.cos(a)]}function Ef(e,t,i,s,n,o,a){const r=e.flipH?-1:1,l="gate"===e.type?1:e.flipV?-1:1,c=(e.type,e.flipV,e.angle,e.face,{ox:0,oy:0}),h=function(e,t){return[e[0]+t[0],e[1]+t[1]]}([e.x+c.ox,e.y+c.oy],Nf(i,e.angle,r,l));return{leaf:t,hinge:h,closedVector:Nf(s,e.angle,r,l),quarterVector:Nf([-s[1],s[0]],e.angle,r,l),turnDeg:n,bottom:o,top:a}}const Of=e=>`${Number(e[0].toFixed(4))} ${Number(e[1].toFixed(4))}`;function Hf(e,t,i=kf){const s=Math.max(0,Math.min(1,Number.isFinite(t)?t:0));return e.leaves.map(t=>{const n=function(e,t){const i=e.turnDeg*t*Math.PI/180;return[e.hinge[0]+e.closedVector[0]*Math.cos(i)+e.quarterVector[0]*Math.sin(i),e.hinge[1]+e.closedVector[1]*Math.cos(i)+e.quarterVector[1]*Math.sin(i)]}(t,s),o=$f(t.hinge,t.bottom,i),a=$f(n,t.bottom,i),r=$f(n,t.top,i),l=$f(t.hinge,t.top,i);return{id:e.id,sourceIndex:e.sourceIndex,type:e.type,leaf:t.leaf,d:`M ${Of(o)} L ${Of(a)} L ${Of(r)} L ${Of(l)} Z`,shadowD:`M ${Of($f(t.hinge,0,i))} L ${Of($f(n,0,i))}`,depth:Math.max(o[1],a[1])}})}const Lf={window:120,door:90,passage:90,gate:300};function Bf(e){return Lf[e]}function jf(e,t){const i=[e[0],e[1]],s=[t[0],t[1]];return function(e,t){return e[0]-t[0]||e[1]-t[1]}(i,s)<=0?{a:i,b:s}:{a:s,b:i}}function qf(e){const t=new Map;return e.forEach((e,i)=>{if(!e.kind||e.open)return;const s=jf(e.a,e.b);if(Math.hypot(s.b[0]-s.a[0],s.b[1]-s.a[1])<=1e-9)return;const n=function(e,t){const i=e=>(Math.abs(e)<=5e-10?0:Math.round(1e6*e)/1e6).toFixed(6);return`${i(e[0])},${i(e[1])}>${i(t[0])},${i(t[1])}`}(s.a,s.b),o=t.get(n);if(o)return o.physicalHalfWidth=Math.max(o.physicalHalfWidth,e.half||0),o.sourceOrder=Math.min(o.sourceOrder,i),void(e.partitionHost&&(o.partitionHost&&o.partitionHost.id!==e.partitionHost.id?o.ambiguousPartitionHost=!0:o.partitionHost=e.partitionHost));t.set(n,{segmentKey:n,a:s.a,b:s.b,physicalHalfWidth:Math.max(0,e.half||0),sourceOrder:i,...e.partitionHost?{partitionHost:e.partitionHost}:{}})}),[...t.values()]}function Wf(e,t){if(Math.abs(e.distance-t.distance)>1e-9)return e.distance-t.distance;if(Math.abs(e.perpendicular-t.perpendicular)>1e-9)return e.perpendicular-t.perpendicular;return(e.target.segmentKeyt.target.segmentKey?1:0)||e.target.sourceOrder-t.target.sourceOrder}function Uf(e){const t=qf(e.intervals).map(t=>{const i=function(e,t){const i=t.b[0]-t.a[0],s=t.b[1]-t.a[1],n=Math.hypot(i,s),o=i/n,a=s/n,r=(e[0]-t.a[0])*o+(e[1]-t.a[1])*a,l=Math.max(0,Math.min(n,r)),c=t.a[0]+l*o,h=t.a[1]+l*a;return{along:l,length:n,x:c,y:h,distance:Math.hypot(e[0]-c,e[1]-h),perpendicular:Math.abs((e[0]-t.a[0])*a-(e[1]-t.a[1])*o)}}(e.pointer,t);return{target:t,...i,envelope:Math.max(e.baseTolerance,t.physicalHalfWidth+e.bodyPointerPadding)}}).filter(e=>e.distance<=e.envelope+1e-9).filter(t=>!function(e,t,i,s,n){const o=t.b[0]-t.a[0],a=t.b[1]-t.a[1],r=Math.hypot(o,a);if(!(r>1e-9))return!1;const l=o/r,c=a/r;for(const o of i){if(!o.open&&o.kind)continue;const i=jf(o.a,o.b),a=i.b[0]-i.a[0],r=i.b[1]-i.a[1],h=Math.hypot(a,r);if(!(h>1e-9))continue;const d=a/h,p=r/h;if(Math.abs(l*p-c*d)>1e-6)continue;if(Math.abs((i.a[0]-t.a[0])*c-(i.a[1]-t.a[1])*l)>n)continue;const u=(e[0]-i.a[0])*d+(e[1]-i.a[1])*p,_=1e-9;if(!(u<=_||u>=h-_)&&Math.abs((e[0]-i.a[0])*p-(e[1]-i.a[1])*d)<=s+1e-9)return!0}return!1}(e.pointer,t.target,e.intervals,t.envelope,Math.max(1e-9,Math.min(e.baseTolerance,.04*e.gridStep)))),i=t.filter(t=>!!t.target.partitionHost&&e.renderedLength+2*t.target.physicalHalfWidth>t.length+1e-9).sort(Wf),s=t.filter(t=>!t.target.partitionHost||e.renderedLength+2*t.target.physicalHalfWidth<=t.length+1e-9).sort(Wf);let n=s[0];if(!n)return{candidate:null,jambBlockedTarget:i[0]?.target||null};const o=s.filter(e=>Math.abs(e.distance-n.distance)<=1e-9&&Math.abs(e.perpendicular-n.perpendicular)<=1e-9),a=o.filter(e=>e.target.partitionHost);if(a.length){if(1!==new Set(a.map(e=>e.target.partitionHost.id)).size||a.some(e=>e.target.ambiguousPartitionHost))return{candidate:null,jambBlockedTarget:null};const e=a[0],t=e.target.b[0]-e.target.a[0],i=e.target.b[1]-e.target.a[1],s=Math.hypot(t,i),r=t/s,l=i/s,c=o.every(t=>{const i=t.target.b[0]-t.target.a[0],s=t.target.b[1]-t.target.a[1],n=Math.hypot(i,s),o=i/n,a=s/n,c=Math.abs(r*a-l*o)<=1e-6,h=Math.abs((t.target.a[0]-e.target.a[0])*l-(t.target.a[1]-e.target.a[1])*r);return c&&h<=1e-9});if(!c)return{candidate:null,jambBlockedTarget:null};n=e}if(n.target.ambiguousPartitionHost)return{candidate:null,jambBlockedTarget:null};const{target:r,length:l}=n,c=r.b[0]-r.a[0],h=r.b[1]-r.a[1],d=c/l,p=h/l,u=r.partitionHost?r.physicalHalfWidth:0,_=Math.min(Math.max(0,e.renderedLength)/2+u,l/2);let m=n.along;const g=Math.max(e.gridStep,1e-9),f=l/2;m=Math.abs(m-f)<=g/2?f:Math.round(m/g)*g,m=Math.max(_,Math.min(l-_,m));const v=r.a[0]+d*m,b=r.a[1]+p*m,y=Math.max(0,e.renderedLength)/2,w=m-y,k=m+y,x=Math.max(0,w),$=Math.max(0,l-k),S=[r.a[0]+d*(w-x/2),r.a[1]+p*(w-x/2)],M=[r.a[0]+d*(k+$/2),r.a[1]+p*(k+$/2)];let C=180*Math.atan2(h,c)/Math.PI;C>=90?C-=180:C<-90&&(C+=180);const D=Math.abs(m-f)<=1e-9;return{candidate:{presetRevision:e.preset.revision,geometryRevision:e.geometryRevision,pointer:[e.pointer[0],e.pointer[1]],type:e.preset.type,lengthCm:e.preset.lengthCm,flipH:e.preset.flipH,flipV:e.preset.flipV,x:v,y:b,angle:C,renderedLength:e.renderedLength,target:r,...r.partitionHost?{host:{...r.partitionHost,t:l>0?m/l:0}}:{},measure:{labels:[{distance:x,midpoint:S},{distance:$,midpoint:M}],guide:D?{x:v,y:b,angle:C}:null}},jambBlockedTarget:null}}function Gf(e,t,i,s,n=1e-6){return e.presetRevision===i&&e.geometryRevision===s&&Math.hypot(e.pointer[0]-t[0],e.pointer[1]-t[1])<=n}const Vf=(e,t)=>e[0]*t[1]-e[1]*t[0],Kf=(e,t)=>e[0]*t[0]+e[1]*t[1],Yf=(e,t)=>[e[0]-t[0],e[1]-t[1]],Jf=(e,t,i)=>[e[0]+t[0]*i,e[1]+t[1]*i];function Xf(e,t,i){return Math.abs(Vf(e,t))<=i}function Zf(e,t,i){return Math.abs(Vf(Yf(e,t),i))}function Qf(e,t,i,s,n){const o=t[0]-e[0],a=t[1]-e[1],r=Math.hypot(o,a);if(!(r>n&&i>0))return[];const l=[o/r,a/r];return function(e,t,i){const s=t.map(([t,i])=>[Math.max(0,Math.min(t,i)),Math.min(e,Math.max(t,i))]).filter(([e,t])=>t>e+i).sort((e,t)=>e[0]-t[0]||e[1]-t[1]),n=[];for(const e of s){const t=n[n.length-1];!t||e[0]>t[1]+i?n.push([...e]):t[1]=Math.max(t[1],e[1])}const o=[];let a=0;for(const[e,t]of n)e>a+i&&o.push([a,e]),a=Math.max(a,t);return e>a+i&&o.push([a,e]),o}(r,s.flatMap(t=>{const s=t.b[0]-t.a[0],o=t.b[1]-t.a[1],a=Math.hypot(s,o);if(!(a>n&&Xf(l,[s/a,o/a],1e-6)))return[];if(Zf(t.a,e,l)>1.1*Math.max(i,n)||Zf(t.b,e,l)>1.1*Math.max(i,n))return[];return[[Kf(Yf(t.a,e),l),Kf(Yf(t.b,e),l)]]}),n).flatMap(([t,s])=>{const n=ql({a:Jf(e,l,t),b:Jf(e,l,s),halfDepth:i});return n?[n]:[]})}function ev(e){const t=e.coordScale??1,i=Math.max(e.epsilon??2e-4*e.gridPitch,1e-9),s=[];for(const i of e.rooms||[]){if(!i?.id)continue;const n=mc(e.rooms,i.id,e.walls,e.openCuts,e.pitch,e.cellCm,e.gridPitch,t);if(!n||n.poly.length<3)continue;const o=sc(n.poly,n.offsets);!o||o.length<3||s.push({roomId:i.id,profile:n,inner:o})}s.sort((e,t)=>e.roomId.localeCompare(t.roomId));const n=(e.roomOpenings||[]).map(e=>{const t=e.angle*Math.PI/180,i=[Math.cos(t),Math.sin(t)],s=Math.max(0,e.length)/2;return{a:Jf([e.x,e.y],i,-s),b:Jf([e.x,e.y],i,s)}}),o=[];for(const s of Bc(e.rooms,e.walls,e.openCuts,e.pitch,e.cellCm,e.gridPitch,t))for(const e of Qf(s.a,s.b,s.depthUnits/2,n,i))o.push({body:e});const a=new Map;for(const t of e.partitionCuts||[]){const e=a.get(t.hostId)||[];e.push(t),a.set(t.hostId,e)}for(const t of e.partitions||[]){const s=wl(t.cm,e.cellCm,e.gridPitch)/2;for(const e of Qf(t.a,t.b,s,a.get(t.id)||[],i))o.push({body:e,partitionId:t.id})}return{rooms:s,boundaries:o,epsilon:i}}function tv(e,t,i,s){const n=e.profile.offsets[t];if(!(n>0))return null;const o=function(e,t){const i=e[t],s=e[(t+1)%e.length],n=s[0]-i[0],o=s[1]-i[1],a=Math.hypot(n,o)||1;return function(e){let t=0;for(let i=0;i=0?[-o/a,n/a]:[o/a,-n/a]}(e.profile.poly,t),a=Jf(i.center,o,n),r=[];for(let t=0;ts&&Xf(i.axis,[l[0]/c,l[1]/c],1e-6)))continue;if(Zf(n,a,i.axis)>s||Zf(o,a,i.axis)>s)continue;const h=Kf(Yf(n,a),i.axis),d=Kf(Yf(o,a),i.axis);r.push([Math.min(h,d),Math.max(h,d)])}const l=function(e,t){e.sort((e,t)=>e[0]-t[0]||e[1]-t[1]);const i=[];for(const s of e){const e=i[i.length-1];!e||s[0]>e[1]+t?i.push([...s]):e[1]=Math.max(e[1],s[1])}return i}(r,s).find(([e,t])=>e<=s&&t>=-s);if(!l)return null;const[c,h]=l,d=Jf(a,i.axis,-i.half),p=Jf(a,i.axis,i.half),u=Math.max(0,-i.half-c),_=Math.max(0,h-i.half),m=u>0?Jf(a,i.axis,c):d,g=_>0?Jf(a,i.axis,h):p,f=Kf(o,i.normal)>=0?1:-1,v=(t,s,n)=>({from:t,to:s,label:[(t[0]+s[0])/2,(t[1]+s[1])/2],axis:i.axis,labelNormal:o,distance:n,roomId:e.roomId,roomSide:f,source:"room-face"});return{left:v(d,m,u),right:v(p,g,_)}}function iv(e){const t=Jf(e.center,e.axis,-e.half),i=Jf(e.center,e.axis,e.half),s=Jf(e.center,e.axis,Math.min(-e.half,e.targetLo)),n=Jf(e.center,e.axis,Math.max(e.half,e.targetHi)),o=(t,i)=>({from:t,to:i,label:[(t[0]+i[0])/2,(t[1]+i[1])/2],axis:e.axis,labelNormal:e.normal,distance:Math.hypot(i[0]-t[0],i[1]-t[1]),source:"host-end"});return[o(t,s),o(i,n)]}function sv(e,t,i,s){const n=Yf(i,t),o=Kf(n,n);if(!(o>s*s))return Math.hypot(...Yf(e,t))<=s;const a=Kf(Yf(e,t),n)/o;if(a<-s||a>1+s)return!1;const r=Jf(t,n,Math.max(0,Math.min(1,a)));return Math.hypot(...Yf(e,r))<=s}function nv(e,t,i){let s=!1;for(let n=0,o=t.length-1;ne[1]!=c>e[1]&&e[0]<(l-a)*(e[1]-r)/(c-r)+a&&(s=!s)}return s}function ov(e,t,i,s,n,o){const a=Yf(s,i),r=Vf(t,a);if(Math.abs(r)<=o)return null;const l=Yf(i,e),c=Vf(l,a)/r,h=Vf(l,t)/r;return c<-o||c>n+o||h<-o||h>1+o?null:Math.max(0,Math.min(n,c))}function av(e,t,i){const s=iv(i),n="partition"===e.host?.kind?e.host.id:void 0;return[{base:s[0],direction:[-i.axis[0],-i.axis[1]]},{base:s[1],direction:i.axis}].map(({base:e,direction:i})=>{const s=e.distance,o=function(e,t,i,s,n,o){let a=null;for(const r of s)if(!n||r.partitionId!==n){if(nv(e,r.body,o))return 0;for(let s=0;sKf(Yf(e,n),i));return{center:n,axis:i,normal:s,half:Math.max(0,e.renderedLength)/2,targetLo:Math.min(...o),targetHi:Math.max(...o)}}(e),s=t.rooms.flatMap(e=>{const s=function(e,t,i){const{profile:s}=e;let n=null;for(let e=0;e0))continue;const o=s.poly[e],a=s.poly[(e+1)%s.poly.length],r=Yf(a,o),l=Math.hypot(r[0],r[1]);if(!(l>i&&Xf(t.axis,[r[0]/l,r[1]/l],1e-6)))continue;if(Zf(o,t.center,t.axis)>i||Zf(a,t.center,t.axis)>i)continue;const c=Kf(Yf(o,t.center),t.axis),h=Kf(Yf(a,t.center),t.axis),d=Math.min(c,h),p=Math.max(c,h);if(d>-t.half+i||p0?d:p<0?-p:0);(!n||u2)return iv(i);if(s.length){const e=s.map(({room:e,edge:s})=>tv(e,s,i,t.epsilon));if(e.some(e=>!e))return iv(i);const n=e;return[...n.map(e=>e.left),...n.map(e=>e.right)]}return av(e,t,i)}function lv(e){return!(!e.canEdit||e.kiosk||e.fixedFloor)&&("view"!==e.mode&&("mouse"===e.pointerType&&e.spaceCount>1))}const cv="1.68.1",hv={badge:"display.badge",icon_ripple:"display.icon_ripple",value:"display.value",static_icon:"display.static_icon"},dv={badge:"marker.display_hint_badge",icon_ripple:"marker.display_hint_icon_ripple",value:"marker.display_hint_value",static_icon:"marker.display_hint_static_icon"},pv=2e3,uv=1e3,_v=1500,mv=e=>{const t=String(e??"").trim().replace(",",".");if(!/^[+-]?(?:\d+(?:\.\d*)?|\.\d+)$/.test(t))return null;const i=Number(t);return Number.isFinite(i)?i:null},gv=(e,t)=>{if(!e.has(t))return{hit:!1};const i=e.get(t);return e.delete(t),e.set(t,i),{hit:!0,value:i}},fv=(e,t,i,s)=>{for(e.delete(t),e.set(t,i);e.size>s;){const t=e.keys().next().value;if(void 0===t)break;e.delete(t)}},vv=new Map;let bv=0;const yv=e=>`${window.innerWidth}x${window.innerHeight}|${location.pathname}|${JSON.stringify(e??{})}`;let wv=1e4;const kv="houseplan_card_layout_v1",xv="houseplan_card_cfg_v1",$v="houseplan_card_zoom_v1",Sv="houseplan_card_nav_v1",Mv="houseplan_card_kiosk_v1",Cv="houseplan_card_view_v1",Dv="hp-dialog, hp-help, hp-color-opacity, hp-device-preview",Pv=1e3,Tv=[[0,1],[45,.88],[70,.62],[86,.32],[100,0]],Iv=(e,t)=>{const i=Math.min(e.x,t.x),s=Math.min(e.y,t.y);return{x:i,y:s,w:Math.max(e.x+e.w,t.x+t.w)-i,h:Math.max(e.y+e.h,t.y+t.h)-s}},Rv=new Set(["select","draw","column","merge","split","resize","opening","wallthick","delroom"]),Av=2e3,zv=(e,t,i)=>{const s=new Event(t,{bubbles:!0,composed:!0});s.detail=i??{},e.dispatchEvent(s)},Fv=e=>{history.pushState(null,"",e),zv(window,"location-changed",{replace:!1})},Nv=(e,t)=>{let i,s=null;const n=(...n)=>{clearTimeout(i),s=n,i=window.setTimeout(()=>{i=void 0;const t=s;s=null,t&&e(...t)},t)};return n.flush=()=>{if(void 0===i)return;clearTimeout(i),i=void 0;const t=s;s=null,t&&e(...t)},n.cancel=()=>{clearTimeout(i),i=void 0,s=null},n.pending=()=>void 0!==i,n},Ev=e=>{try{e.target?.setPointerCapture?.(e.pointerId)}catch{}};class Ov extends he{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._cfgContentFingerprint="",this._unsubCfg=null,this._unsubLayout=null,this._unsubVirtual=null,this._liveSyncAttempt=null,this._liveSyncGeneration=0,this._liveSyncConnection=null,this._layoutRev=0,this._layoutContentFingerprint="",this._virtualLights=mn(null),this._canOptimizeUndo=!1,this._undoKind=null,this._devices=[],this._regSignature="",this._defPos={},this._newSyncKey="",this._tip=null,this._hoverRoom=null,this._pointerModality=new cm(this,()=>this._syncPointerHoverTargets()),this._devicePressAnimations=new Map,this._selId=null,this._toast="",this._mode="view",this._pendingNavMode=null,this._decorTool="select",this._decorStyle={...Nr},this._decorDraft=null,this._decorMove=null,this._decorSel=null,this._decorEraseConfirm=null,this._decorTextDialog=null,this._decorShapeDialog=null,this._backdropDialog=null,this._decorTextSelection={start:0,end:0},this._furnPalette=null,this._dtBox=null,this._dtDrag=null,this._bdDrag=null,this._slide="",this._reducedMotion=!1,this._onMotionChange=e=>{this._reducedMotion=e.matches,this._cancelDevicePressFeedback(),e.matches&&this._modeTransitionPreparing?this._modeTransitionForceAtomic=!0:e.matches&&this._modeTransition.active&&this._cancelModeTransition(!0),this.requestUpdate()},this._editorChromeMode="plan",this._modeTransitionVisual=null,this._modeTransitionPreparing=!1,this._modeTransitionForceAtomic=!1,this._modeTransitionRequest=0,this._modeTransitionTargetZoom=1,this._modeTransitionEditorCamera=null,this._modeTransition=new sf({frame:e=>this._applyModeTransitionFrame(e),settled:e=>this._settleModeTransition(e)}),this._editorSecondary=new mm({root:()=>this.renderRoot,requestUpdate:()=>this.requestUpdate(),updateComplete:()=>this.updateComplete,clearTip:()=>{this._tip=null}}),this._editorSecondaryCopy={groupActive:(e,t)=>this._t("editor.group_active",{group:e,item:t}),openGroup:e=>this._t("editor.open_group",{group:e}),disabledAction:(e,t)=>this._t("editor.disabled_action",{action:e,reason:t})},this._tool="draw",this._geometryHistory=new qg(50),this._wallDialog=null,this._drawWallField=null,this._activeDraftId=null,this._resumeDraftBySpace={},this._physicalSel=null,this._physicalDialog=null,this._partitionDeleteDialog=null,this._roomDeleteDialog=null,this._physicalDrag=null,this._physicalRotate=null,this._physicalLastTap=null,this._physicalPickCycle=null,this._wallUnionCacheValue=null,this._wallUnionPool=new Map,this._isoGeometryCache=new Map,this._isoFallback=new Set,this._openingTunnelCache=null,this._openingWallIndexCache=new Map,this._openingPlacementIntervalsCache=null,this._openingDimensionContextCache=null,this._planSnapGeometryCache=null,this._planStructuralGeometryCache=null,this._hiddenWallDiagnosticCache=null,this._physicalBodiesCache=null,this._lightPhysicalBodiesCache=null,this._cleanFloorCache=new Map,this._innerContourCache=new Map,this._glowClipCache=new Map,this._glowGeometryWarnings=new Set,this._lightBarrierCache=null,this._lightBarrierPool=new Map,this._glowFeatherUnits=null,this._glowRenderedSources=new Map,this._glowLastAppearance=new Map,this._glowEnteringSources=new Set,this._glowEnterRafs=new Map,this._glowFadeTimers=new Map,this._glowFeatherSuspendUntil=0,this._glowFeatherResumeTimer=0,this._glowSourceSeq=0,this._glowScreenBlend=!1,this._duplicateColumnId=null,this._duplicateColumnTimer=0,this._resize=new rr,this._rszLimitViolation=null,this._path=[],this._cursorPt=null,this._planSnapHover=null,this._mergeSel=null,this._openingPreset=null,this._openingRebindId=null,this._openingPresetRevision=0,this._openingHoverCandidate=null,this._openingJambBlockCm=null,this._openingDialog=null,this._openingInfo=null,this._opDrag=null,this._opMeasure=null,this._mergeDialog=null,this._splitSel=null,this._pendingSplit=null,this._wallFaceBatch=null,this._wallRepairDiagnostic=null,this._wallFaceGraphCache=[],this._areaSel="",this._nameSel="",this._roomDialog=!1,this._roomEditId=null,this._roomFill="",this._roomCustomFill=null,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._touchContacts=new Map,this._touchSequenceMultitouch=!1,this._touchClickBlockUntil=0,this._connectedPath="",this._routeDepartureHandled=!1,this._onLocationChanged=()=>{this._connectedPath&&location.pathname!==this._connectedPath?this._leaveCardRoute():location.pathname===this._connectedPath&&(this._routeDepartureHandled=!1)},this._touchGestureGuard={capture:!0,handleEvent:e=>this._guardTouchGesture(e)},this._hdrH=118,this._booting=!0,this._bootFading=!1,this._bootSettling=!1,this._bootSettleRaf=0,this._bootLastH=-1,this._bootStart=0,this._bootLastChange=0,this._bootSoft=!1,this._tapConfirm=null,this._onboardingShown=!1,this._rulesDialog=null,this._preflightClipboardFallback=null,this._haIntegrationVersion=null,this._alignDialog=null,this._settingsDialog=null,this._backupExportDialog=null,this._backupImportDialog=null,this._sunRaysCache=null,this._dayCycleTimer=0,this._dayCycleClockKey="",this._compassDrag=!1,this._importDialog=null,this._importQueue=[],this._importTotal=0,this._rulesCompiledSrc="",this._infoCard=null,this._nativeMoreInfoEntity=null,this._deviceInbox=null,this._deviceInboxReturn=null,this._deviceInboxMemo=null,this._markerDialog=null,this._spaceDialog=null,this._keyHandler=e=>this._onKey(e),this._warmVp=null,this._warmVpArmed=!1,this._warmLongReturn=!1,this._warmRevivePending=!1,this._warmGen=++bv,this._warmKey=null,this._warmSlot=null,this._hashApplied=!1,this._navApplied=!1,this._labs={active:Object.freeze([]),space:""},this._viewPreference={},this._renderProjection="flat",this._kioskScale={icon:1,font:1},this._kioskDialog=!1,this._activityRt=new Map,this._vacRt=new Map,this._vacViewKey="",this._vacLastView=null,this._vacRaf=0,this._vacSrvTrails={},this._vacJumpOnce=!1,this._continuity=this._newContinuityController(),this._continuityHistory=[],this._continuityEpoch=0,this._continuityDataReady=!0,this._continuityPaintToken=-1,this._continuityDisposed=!1,this._renderSnapshotAt=Date.now(),this._hassSequence=0,this._visibleDeviceSnapshot=null,this._candidateDeviceSnapshot=null,this._stagedDeviceSnapshotToken=-1,this._capturedSnapshotSequence=-1,this._capturedSnapshotDevices=null,this._capturedSnapshotLayout=null,this._capturedSnapshotActivity="",this._capturedSnapshotConfigEpoch=-1,this._capturedSnapshotVirtual="",this._lastValidStageSize=null,this._pendingRefitSize=null,this._refitRaf=0,this._pageVisibility=e=>{if(this._continuity.visibility(e),this._dayCycleVisibility(e),"hidden"===e.kind)return this._clearTransientHover(!0),this._cancelDevicePressFeedback(),void(this._modeTransitionPreparing?this._modeTransitionForceAtomic=!0:this._cancelModeTransition(!0));if(this._vacJumpOnce=!0,!e.long){const e=Date.now();let t=!1;for(const i of this._activityRt.values())!i.flashKind||(i.expiresAt||i.flashTs+nm)>e||(i.flashTs=0,i.flashKind=null,i.expiresAt=0,t=!0);return void(t&&this.requestUpdate())}Date.now()-this._renderSnapshotAt>1e3&&this._continuity.note("device-snapshot-stale"),this._continuityDataReady=!1,this._continuityPaintToken=-1,this._resumeSettling=!0,this._loading?this.requestUpdate():this._loadFromServer()},this._resumeSettling=!1,this._viewportInvalidAt=0,this._vacFit=null,this._vacAllCamerasFor=null,this._vacAllCameraCache=null,this._vacCalConfirm=null,this._kioskDots=!1,this._cyclePausedUntil=0,this._swipeStart=null,this._tabDrag=null,this._tabDragRelease=null,this._tabSuppressClick=!1,this._tabOrderWarned=!1,this._lastTap=0,this._onLabsSnapshot=e=>{const t=this._effectiveProjection();this._labs=e;const i=this._effectiveProjection();this._convertProjectionView(t,i),this.requestUpdate()},this._onHashChange=()=>{if(this._hasFixedFloor)return;const e=this._hashSpace();if(e&&this._model.find(t=>t.id===e)&&e!==this._space){if(this._wallFaceBatch&&this._roomDialogCancel(),"plan"===this._mode&&"draw"===this._tool&&!this._finishWallChain())return;this._activeDraftId&&(this._resumeDraftBySpace[this._space]=this._activeDraftId),this._commitSpace(e),this._selId=null,this._path=[],this._clearPlanSnapHover(),this._clearOpeningPlacement(!0),this._tool="draw",this._activeDraftId=null,this._draftSegmentCms=[],this._closingWallCm=null,"plan"===this._mode&&"draw"===this._tool&&this._resumeLastDraft(),this._restoreZoom(),this.requestUpdate()}},this._drag=null,this._rlResize=null,this._holdFired=!1,this._retryContinuity=()=>{this._continuityDataReady=!1,this._continuityPaintToken=-1,this._continuity.retry(this._continuity.recoveryReason||"plan"),this._loading||this._loadFromServer()},this._cfgEpoch=0,this._modelCache=null,this._emptySpaceStateActive=!1,this._decorSnapCache=null,this._markerPreviewMemo=null,this._markerPreviewDevicesMemo=null,this._showHidden=!1,this._connHooked=null,this._connectionWasLost=!1,this._haRegistryConnection=null,this._haRegistryRev=-1,this._haBindingCacheKey="",this._planHassMemo=null,this._onHaRegistryUpdate=()=>{const e=An(this.hass);e.revision===this._haRegistryRev&&this._devices.length||(this._haRegistryRev=e.revision,this._planHassMemo=null,this._regSignature="",this._maybeRebuildDevices(),this.requestUpdate())},this._onConnReady=()=>{if(this._loadTries=0,clearTimeout(this._loadRetryTimer),this._loadRetryTimer=void 0,function(e){const t=Cn(e);t&&(Tn(e,t),In(e,t))}(this.hass),this._saveConfigDebounced.pending()&&this._saveConfigDebounced.flush(),this._cfgWriting)return clearTimeout(this._reloadRetry),void(this._reloadRetry=window.setTimeout(this._onConnReady,400));!this._connectionWasLost&&this._continuity.hasCompleteFrame?this._beginContinuityCandidate("connection-ready",!1,"plan"):(this._continuityDataReady=!1,this._continuityPaintToken=-1),this._loading||this._loadFromServer()},this._onConnLost=()=>{this._booting&&!this._continuity.hasCompleteFrame||(this._connectionWasLost=!0,this._continuityDataReady=!1,this._continuityPaintToken=-1,this._continuity.connectionLost())},this._signer=new Wd(()=>this.requestUpdate()),this._dirtyPos=new Set,this._sentPos=new Map,this._persistLayout=Nv(()=>{if(this._serverStorage){const e=[...this._dirtyPos];this._dirtyPos.clear();for(const t of e){const e=hl(this._layout[t]);e&&(this._layout={...this._layout,[t]:e},this._sentPos.set(t,e),this.hass.callWS({type:"houseplan/layout/update",device_id:t,pos:e}).then(e=>this._noteLayoutRev(e)).catch(e=>this._showToast(this._t("toast.pos_save_failed",{err:this._errText(e)}))).finally(()=>{this._sentPos.get(t)===e&&this._sentPos.delete(t)}))}this._cacheSnapshot()}else this._layout=dl(Xr(this._layout)),localStorage.setItem(kv,JSON.stringify(this._layout))},600),this._frame=null,this._showFar=!1,this._writesPending=0,this._writeChain=Promise.resolve(),this._pendingPhysicalWrites=new Map,this._undoGeometry=()=>{if(this._physicalDrag||this._physicalRotate)return void this._cancelPhysicalGesture();if(this._decorDraft)return this._decorDraft=null,void this.requestUpdate();if(this._decorMove||this._dtDrag||this._bdDrag)return void this._cancelDecorGesture();if(this._resize.dragging)return void this._rszCancelDrag();const e=this._geometryHistory.undo();e&&(this._applyGeometryState(e.before,!0)?this._showToast(this._t("history.undone",{name:e.name})):this._geometryHistory.clear())},this._redoGeometry=()=>{if(this._physicalDrag||this._physicalRotate)return void this._cancelPhysicalGesture();if(this._decorDraft)return this._decorDraft=null,void this.requestUpdate();if(this._decorMove||this._dtDrag||this._bdDrag)return void this._cancelDecorGesture();if(this._resize.dragging)return void this._rszCancelDrag();const e=this._geometryHistory.redo();e&&(this._applyGeometryState(e.after,!0)?this._showToast(this._t("history.redone",{name:e.name})):this._geometryHistory.clear())},this._saveConfigDebounced=Nv(()=>{this._serverCfg&&this._writeConfig().catch(e=>{const t=!0===e?.physicalGeometryRolledBack;"geometry-unsafe"!==e?.code&&("wall_model_client_outdated"===e?.code?this._showToast(this._t("toast.wall_model_client_outdated")):"conflict"===e?.code?(this._showToast(this._t("toast.conflict")),t||(this._cancelPath(),this._reloadConfigOnly(!0))):this._showToast(this._t("toast.cfg_save_failed",{err:this._errText(e)})),t&&this._reloadRejectedPhysicalWrite())})},500),this._draftSegmentCms=[],this._closingWallCm=null,this._savePhysicalDialog=()=>{const e=this._physicalDialog,t=this._curSpaceCfg,i=this._spaceModel();if(!e||!t||!i)return;const s=mv(e.cm);if(null==s)return void this._showPhysicalRange("column"===e.kind?Xc:100,"column"===e.kind?1:0);const n=this._imperial?2.54*s:s,o="column"===e.kind?Xc:100,a="column"===e.kind?1:0;if(!Number.isFinite(n)||no)return void this._showPhysicalRange(o,a);if("column"===e.kind){const t=i.wall_columns.find(t=>t.id===e.id);if(!t)return;const s=mv(e.angle||"0");if("circle"!==e.shape&&(null==s||s<0||s>=90))return void this._showToast(this._t("toast.physical_angle"));const o="circle"===e.shape?{id:e.id,shape:"circle",center:t.center,cm:n}:{id:e.id,shape:"square",center:t.center,cm:n,angle:s};if(i.wall_columns.some(t=>t.id!==e.id&&yh(t,o,.02*this._gridPitch)))return void this._showToast(this._t("toast.column_duplicate"))}const r=this._geometrySnapshot();if("partition"===e.kind){const i=(t.partitions||[]).find(t=>t.id===e.id);if(i&&0===n&&q_(t.openings,{kind:"partition",id:e.id}))return void this._showToast(this._t("toast.zero_wall_opening_conflict"));i&&(i.cm=n)}else if("column"===e.kind){const i=(t.wall_columns||[]).find(t=>t.id===e.id);i&&(i.cm=Qc(n),i.shape="circle"===e.shape?"circle":"square","square"===i.shape?i.angle=mv(e.angle||"0"):delete i.angle)}else{const i=(t.room_drafts||[]).find(t=>t.id===e.id);i?.segments?.[e.segment||0]&&(i.segments[e.segment||0].cm=n)}const l=this._commitPhysicalGeometry(this._t("history.physical_edit"),r);this._physicalDialog=null,l||this.requestUpdate()},this._deletePhysicalSelection=()=>{const e=this._physicalSel,t=this._curSpaceCfg;if(!e||!t)return;if("draft"===e.kind)return void this._deleteDraftWhole();const i=this._geometrySnapshot();if("partition"===e.kind){const i=(t.openings||[]).filter(t=>"partition"===t.host?.kind&&t.host.id===e.id).sort((e,t)=>(e.host?.t||0)-(t.host?.t||0));if(i.length)return void(this._partitionDeleteDialog={id:e.id,openings:i.map(e=>JSON.parse(JSON.stringify(e)))})}const s="partition"===e.kind?"partitions":"column"===e.kind?"wall_columns":"room_drafts";t[s]=(t[s]||[]).filter(t=>t.id!==e.id),t[s].length||delete t[s],this._activeDraftId===e.id&&this._cancelPath(),this._physicalSel=null,this._physicalDialog=null,this._commitPhysicalGeometry(this._t("history.physical_delete"),i)},this._confirmPartitionDelete=()=>{const e=this._partitionDeleteDialog,t=this._curSpaceCfg;if(!e||!t)return;const i=this._geometrySnapshot();t.partitions=(t.partitions||[]).filter(t=>t.id!==e.id),t.partitions.length||delete t.partitions,t.openings=(t.openings||[]).filter(t=>"partition"!==t.host?.kind||t.host.id!==e.id),t.openings.length||delete t.openings,this._partitionDeleteDialog=null,this._physicalSel=null,this._physicalDialog=null,this._commitPhysicalGeometry(this._t("history.physical_delete"),i)},this._deleteDraftWhole=()=>{const e="draft"===this._physicalDialog?.kind?this._physicalDialog.id:"draft"===this._physicalSel?.kind?this._physicalSel.id:null,t=this._curSpaceCfg;if(!e||!t||!confirm(this._t("confirm.delete_draft")))return;const i=this._geometrySnapshot();t.room_drafts=(t.room_drafts||[]).filter(t=>t.id!==e),t.room_drafts.length||delete t.room_drafts,this._activeDraftId===e&&this._cancelPath(),this._physicalSel=null,this._physicalDialog=null,this._commitPhysicalGeometry(this._t("history.physical_delete"),i)},this._deleteDraftSegment=()=>{const e=this._physicalDialog,t=this._curSpaceCfg;if(!e||"draft"!==e.kind||!t)return;if(!confirm(this._t("confirm.delete_draft_segment")))return;const i=(t.room_drafts||[]).findIndex(t=>t.id===e.id);if(i<0)return;const s=t.room_drafts[i],n=Math.max(0,Math.min(s.segments.length-1,e.segment||0)),o=[],a=s.points.slice(0,n+1),r=s.points.slice(n+1);if(a.length>=2&&o.push({id:s.id,points:a,segments:s.segments.slice(0,n)}),r.length>=2&&o.push({id:o.length?`${s.id}-${Date.now().toString(36)}`:s.id,points:r,segments:s.segments.slice(n+1)}),2===o.length&&t.room_drafts.length>=200)return void this._showToast(this._t("toast.physical_limit"));const l=this._geometrySnapshot();t.room_drafts.splice(i,1,...o),t.room_drafts.length||delete t.room_drafts,this._activeDraftId===s.id&&this._cancelPath(),this._physicalDialog=null,this._physicalSel=o.length?{kind:"draft",id:o[0].id}:null,this._commitPhysicalGeometry(this._t("history.draft_segment_delete"),l)},this._confirmRoomDelete=e=>{const t=this._roomDeleteDialog,i=this._curSpaceCfg,s=this._spaceModel();if(!t||!i||!s)return;const n=s.rooms.find(e=>e.id===t.roomId);if(!n)return void(this._roomDeleteDialog=null);const o=this._openCuts(),a=Yu(gc(s.rooms,this._spaceWalls,o,this._wallKeyPitch,this._cellCm,this._gridPitch,Pv).filter(e=>e.roomId===n.id),s.partitions,this._openingsR.map(e=>({...e,x:e.rx,y:e.ry})),.02*this._gridPitch),r=new Set(a.materialize.filter(e=>!e.reusePartitionId).map(e=>e.interval.key)).size;if(e&&(i.partitions||[]).length+r>Av)return void this._showToast(this._t("toast.physical_limit"));const l=this._geometrySnapshot(),c=fc(s.rooms,this._spaceWalls,o,this._wallKeyPitch,this._cellCm,this._gridPitch,Pv);if(e){i.partitions||=[];const e=new Map,t=new Map,s=e=>{const t=(i.wall_segments||[]).find(t=>{const i=[Number(t.a?.[0])*Pv,Number(t.a?.[1])*Pv],s=[Number(t.b?.[0])*Pv,Number(t.b?.[1])*Pv];return this._samePt(e.a,i)&&this._samePt(e.b,s)||this._samePt(e.a,s)&&this._samePt(e.b,i)});return"string"==typeof t?.id&&t.id?t.id:null},n=Date.now().toString(36);for(const o of a.materialize){let a=o.reusePartitionId?i.partitions.find(e=>e.id===o.reusePartitionId):t.get(o.interval.key);a||(a={id:s(o.interval)||`partition-room-${n}-${t.size}`,a:[o.interval.a[0]/Pv,o.interval.a[1]/Pv],b:[o.interval.b[0]/Pv,o.interval.b[1]/Pv],cm:o.interval.cm},i.partitions.push(a),t.set(o.interval.key,a)),e.set(o.interval.key,a)}for(const t of i.openings||[]){const i=a.openingIntervals.get(t.id),s=i?e.get(i):null,n=this._openingsR.find(e=>e.id===t.id);if(!s||!n)continue;const o={a:[s.a[0]*Pv,s.a[1]*Pv],b:[s.b[0]*Pv,s.b[1]*Pv]};t.host={kind:"partition",id:s.id,t:Ju([n.rx,n.ry],o)}}}else if(a.removeOpeningIds.length){const e=new Set(a.removeOpeningIds);i.openings=(i.openings||[]).filter(t=>!e.has(t.id)),i.openings.length||delete i.openings}i.rooms=i.rooms.filter(e=>e.id!==n.id),this._cfgEpoch++;const h=this._normalizeWalls(c,this._openCuts());h.length?i.walls=h:delete i.walls,this._roomDeleteDialog=null,this._commitPhysicalGeometry(this._t(e?"history.delete_room_keep_walls":"history.delete_room_with_walls"),l),this._regSignature="",this._maybeRebuildDevices(),this.requestUpdate()},this._rebindPartitionOpening=()=>{const e=this._openingDialog;if(!e?.id)return;const t=e.id;this._activateMarkupTool("opening"),"opening"===this._tool&&(this._openingRebindId=t,this._openingPreset={type:e.type,lengthCm:e.lengthCm,flipH:e.flipH,flipV:e.flipV,revision:++this._openingPresetRevision},this._openingDialog=null,this._openingHoverCandidate=null)},this._keepClosedAsPartitions=()=>{if(this._wallFaceBatch)return void this._decideWallFace(!1);if(!this._contourClosed||this._pendingSplit||!this._curSpaceCfg)return;const e=this._curSpaceCfg,t=this._path.slice(0,-1);if((e.partitions||[]).length+t.length>Av)return void this._showToast(this._t("toast.physical_limit"));const i=this._geometrySnapshot(),s=ku(t.length,[...this._draftSegmentCms,this._closingWallCm??void 0],this._drawWallCm,ul);e.partitions||=[];const n=Date.now().toString(36),o=this._activeDraftId?(e.room_drafts||[]).find(e=>e.id===this._activeDraftId):null,a=this._draftSegmentsForPath(this._path,o,s);for(let i=0;ie.id!==this._activeDraftId),e.room_drafts.length||delete e.room_drafts),this._commitPhysicalGeometry(this._t("history.contour_to_partitions"),i),this._roomDialog=!1,this._path=[],delete this._resumeDraftBySpace[this._space],this._activeDraftId=null,this._draftSegmentCms=[],this._closingWallCm=null},this._toggleServerPlans=async()=>{const e=this._spaceDialog;if(e)if(e.pickSaved)this._spaceDialog={...e,pickSaved:!1};else{this._spaceDialog={...e,pickSaved:!0,savedBusy:!0};try{const e=await this.hass.callWS({type:"houseplan/plans/list"}),t=this._spaceDialog;t&&(this._spaceDialog={...t,saved:e?.plans||[],savedBusy:!1})}catch(e){const t=this._spaceDialog;t&&(this._spaceDialog={...t,saved:[],savedBusy:!1}),this._showToast(this._t("toast.plans_list_failed",{err:this._errText(e)}))}}},this._aspectJob=null,this._dayCycleTick=()=>{if(!this.isConnected||"hidden"===this.ownerDocument.visibilityState)return;const e=this._dayCycleState();if(!e)return this._dayCycleTimer&&(clearInterval(this._dayCycleTimer),this._dayCycleTimer=0),void(this._dayCycleClockKey="");const t=yr(e);t!==this._dayCycleClockKey&&(this._dayCycleClockKey=t,this.requestUpdate())},this._sunShown=!1,this._sunOut=!1,this._sunOutTimer=0,this._openSettingsDialog=()=>{if(!this._norm)return;const e=this._glowRadiusCm,t=this._imperial?Math.round(e/30.48*10)/10:Math.round(e)/100;this._settingsDialog={colors:JSON.parse(JSON.stringify(this._fillColors)),glowRadius:t,bgColor:hs(this._settings,{bgColor:null})||null,northDeg:Pr(this._settings,{}),bgMode:Tr(this._settings,{}),sunRays:Ir(this._settings,{}),busy:!1}},this._reportedPreflightFingerprint=null,this._openAlignDialog=()=>this._previewAlignDialog(!1),this._toggleOptimizeLivePositions=()=>{const e=this._alignDialog;e&&!e.busy&&e.report.liveMissingPositions.length&&this._previewAlignDialog(!e.removeLiveMissingPositions)},this._optimizeUndoBusy=!1,this._openBackupExport=()=>{this._settingsDialog=null,this._backupExportDialog={kind:"full",planOnly:!1,busy:!1,error:""}},this._openRulesDialog=()=>{if(!this._norm)return;const e=this._settings.icon_rules,t=(e&&e.length?e:Je).map(e=>({...e}));this._rulesDialog={rules:t,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)}get _modeTransitionBusy(){return this._modeTransitionPreparing||this._modeTransition.active}_cssColor(e,t){const i=String(e||"").trim();if(!i)return t;const s=document.createElement("span");s.style.cssText=`position:absolute;visibility:hidden;color:${i}`,this.renderRoot.append(s);const n=getComputedStyle(s).color||t;return s.remove(),n}_currentModeVisual(e=this._mode){const t=this._modeTransition.presented||this._modeTransitionVisual;if(t)return{...t,viewport:{...t.viewport,viewBox:{...t.viewport.viewBox}}};const i=this._stageEl;if(!i||i.clientWidth<=0||i.clientHeight<=0)return null;const s=this.renderRoot.querySelector(".editorchrome"),n=this._viewOr(this._baseVb()),o=this.renderRoot.querySelector(".hp-paper"),a=this.renderRoot.querySelector(".hp-backdrop"),r=this.renderRoot.querySelector(".zoomwrap"),l=r?getComputedStyle(r).filter:"",c=Number(/brightness\(([^)]+)\)/.exec(l)?.[1]);return{presentedMode:e,editorChromeHeight:"view"===e?0:s?.getBoundingClientRect().height||0,stageWidth:i.clientWidth,stageHeight:i.clientHeight,viewport:Xg(n,i.clientWidth),stageColor:getComputedStyle(i).backgroundColor||"rgb(255, 255, 255)",paperColor:o?getComputedStyle(o).fill:"rgb(255, 255, 255)",sceneBrightness:Number.isFinite(c)?c:1,architectureOpacity:"decor"===e?.35:1,backdropOpacity:a&&Number(getComputedStyle(a).opacity)||1,viewWeight:"view"===e?1:0,editorWeight:"view"===e?0:1,toolbarContentOpacity:"view"===e?0:1}}_viewForModeTarget(e,t,i,s,n){const o=Ei(this._baseVb(),s/Math.max(1,n)),a=Math.min(Ov.ZOOM_MAX,Math.max(Ov.ZOOM_MIN,e)),r=o.w/a,l=o.h/a,c=t??o.x+o.w/2,h=i??o.y+o.h/2;return this._clampView({x:c-r/2,y:h-l/2,w:r,h:l},o)}_targetStageColor(e){return"view"!==e?"rgb(255, 255, 255)":this._cssColor(this._stageBg(this._spaceDisplayForRender()),this._cssColor("var(--ha-card-background, var(--card-background-color, #111))","rgb(17, 17, 17)"))}_targetPaperColor(e){return"view"===e&&this._spaceModel()?.bg?this._cssColor("var(--ha-card-background, var(--card-background-color, #111))","rgb(17, 17, 17)"):"rgb(255, 255, 255)"}_targetBrightness(e){return 1}_applyModeTransitionFrame(e){e.targetMode===this._mode&&(this._modeTransitionVisual=e.presented,this._view={...e.presented.viewport.viewBox},this.requestUpdate())}_settleModeTransition(e){if(e.targetMode!==this._mode)return;const t=this._modeTransitionRequest;this._view={...e.to.viewport.viewBox},this._zoom=this._modeTransitionTargetZoom,this._modeTransitionVisual=null,this._modeTransitionPreparing=!1,this._lastValidStageSize=[e.to.stageWidth,e.to.stageHeight],"view"===this._mode&&(this._saveZoom(),this._viewModeSnap=null,this._modeTransitionEditorCamera=null),this.requestUpdate(),this.updateComplete.then(()=>{if(!this.isConnected||t!==this._modeTransitionRequest||this._modeTransitionBusy||e.targetMode!==this._mode)return;const i=this._stageEl;if(i&&i.clientWidth>0&&i.clientHeight>0&&(Math.abs(i.clientWidth-e.to.stageWidth)>.5||Math.abs(i.clientHeight-e.to.stageHeight)>.5)){const e=this._view;this._lastValidStageSize=[i.clientWidth,i.clientHeight],this._applyView(this._zoom,e?e.x+e.w/2:void 0,e?e.y+e.h/2:void 0),this.requestUpdate()}const s=this.renderRoot.activeElement;(!s||!s.isConnected||!!s.closest?.(".editorchrome, .stage"))&&this.renderRoot.querySelector(".modetab.active")?.focus?.({preventScroll:!0})})}_cancelModeTransition(e=!0){const t=!!this._modeTransition.state;this._modeTransitionRequest++,this._modeTransitionPreparing=!1,this._modeTransitionForceAtomic=!1,this._modeTransition.cancel(e),e&&t||(this._modeTransitionVisual=null)}_adoptMode(e){this._cancelModeTransition(!1),this._mode=e,"view"!==e&&(this._editorChromeMode=e)}_commitViewModeAtomic(e,t,i,s){if(this._modeTransitionPreparing=!1,this._modeTransitionVisual=null,this._modeTransitionForceAtomic=!1,this._zoom=t,e){const n=this._stageEl?.clientWidth||e.stageWidth,o=Math.max(1,e.stageHeight+e.editorChromeHeight);this._view=this._viewForModeTarget(t,i,s,n,o),this._lastValidStageSize=[n,o]}else this._view=null;this._viewModeSnap=null,this._modeTransitionEditorCamera=null,this._saveZoom(),this.requestUpdate()}_prepareModeTransition(e,t,i,s,n,o){this.updateComplete.then(()=>{if(!this.isConnected||e!==this._modeTransitionRequest||this._mode!==i)return void(e===this._modeTransitionRequest&&(this._modeTransitionPreparing=!1,this._modeTransitionVisual=null,this._modeTransitionForceAtomic=!1,this.requestUpdate()));const a=this.renderRoot.querySelector(".editorchrome"),r=a?.querySelector(".editorchrome-inner"),l="view"===i?0:r?.scrollHeight||r?.getBoundingClientRect().height||0,c=Math.max(1,t.stageHeight+t.editorChromeHeight),h=Math.max(1,c-l),d=this._stageEl?.clientWidth||t.stageWidth;if(d<=0||h<=0)return this._modeTransitionPreparing=!1,this._modeTransitionVisual=null,this._applyView(s,n,o),void this.requestUpdate();const p=this._viewForModeTarget(s,n,o,d,h),u={presentedMode:i,editorChromeHeight:l,stageWidth:d,stageHeight:h,viewport:Xg(p,d),stageColor:this._targetStageColor(i),paperColor:this._targetPaperColor(i),sceneBrightness:this._targetBrightness(i),architectureOpacity:"decor"===i?.35:1,backdropOpacity:"decor"===i&&"backdrop"!==this._decorTool?.5:1,viewWeight:"view"===i?1:0,editorWeight:"view"===i?0:1,toolbarContentOpacity:"view"===i?0:1};this._modeTransitionPreparing=!1;const _=this._modeTransitionForceAtomic;this._modeTransitionForceAtomic=!1,this._modeTransition.start(t,u,i,this._reducedMotion||_?0:220)})}get _hasFixedFloor(){return!!this._config&&Object.prototype.hasOwnProperty.call(this._config,"floor")}_fixedFloorState(e=this._model,t=this._loadOk){const i=this._config?.floor,s=function(e){if(!e.hasFloor)return{kind:"absent"};const t=e.floor;if("string"==typeof t)return t.length?e.spaceIds.includes(t)?{kind:"valid",id:t,source:"id"}:{kind:"invalid",reason:"unknown-id",value:t}:{kind:"invalid",reason:"empty-id",value:t};if("number"==typeof t){if(!Number.isFinite(t))return{kind:"invalid",reason:"non-finite-index",value:t};if(!Number.isInteger(t))return{kind:"invalid",reason:"fractional-index",value:t};if(t<0)return{kind:"invalid",reason:"negative-index",value:t};const i=e.spaceIds[t];return void 0===i?{kind:"invalid",reason:"out-of-range-index",value:t}:{kind:"valid",id:i,source:"index"}}return{kind:"invalid",reason:"invalid-type",value:t}}({spaceIds:e.map(e=>e.id),hasFloor:this._hasFixedFloor,floor:i});return!this._hasFixedFloor||t?s:"number"==typeof i?"valid"===s.kind||"invalid"===s.kind&&"out-of-range-index"===s.reason?{kind:"pending",value:i}:s:"valid"===s.kind||"invalid"===s.kind&&"unknown-id"!==s.reason?s:{kind:"pending",value:i}}_canCommitSpace(e,t=!1){if(t||!this._hasFixedFloor)return!0;const i=this._fixedFloorState();return"valid"===i.kind&&i.id===e}_commitSpace(e,t=!1){return!!this._canCommitSpace(e,t)&&(e!==this._space&&(this._clearTransientHover(!0),this._cancelDevicePressFeedback()),this._space=e,!0)}_slideTo(e,t){if(e===this._space)return!0;if(!this._canCommitSpace(e))return!1;if(this._wallFaceBatch&&this._roomDialogCancel(),"plan"===this._mode&&"draw"===this._tool&&!this._finishWallChain())return!1;this._cancelModeTransition(!0);const i=window.matchMedia?.("(prefers-reduced-motion: reduce)")?.matches;return this._activeDraftId&&(this._resumeDraftBySpace[this._space]=this._activeDraftId),this._commitSpace(e),this._path=[],this._clearPlanSnapHover(),this._clearOpeningPlacement(!0),this._tool="draw",this._activeDraftId=null,this._draftSegmentCms=[],this._closingWallCm=null,this._selId=null,this._physicalSel=null,this._editorSecondary.closeForNavigation(),this._physicalDialog=null,this._physicalDrag=null,"plan"===this._mode&&"draw"===this._tool&&this._resumeLastDraft(),this._restoreZoom(),i||(this._slide=t,clearTimeout(this._slideTimer),this._slideTimer=window.setTimeout(()=>{this._slideTimer=void 0,this._slide="",this.requestUpdate()},190),this.requestUpdate()),!0}get _canReorderTabs(){return lv({canEdit:this._canEdit,kiosk:this._kiosk,mode:this._mode,pointerType:"mouse",spaceCount:this._model.length,fixedFloor:this._hasFixedFloor})}_tabPointerDown(e,t){lv({canEdit:this._canEdit,kiosk:this._kiosk,mode:this._mode,pointerType:e.pointerType,spaceCount:this._model.length,fixedFloor:this._hasFixedFloor})&&(Ev(e),this._tabDragRelease=e=>this._tabPointerUp(e),window.addEventListener("pointerup",this._tabDragRelease),window.addEventListener("pointercancel",this._tabDragRelease),this._tabDrag={id:t,pointerId:e.pointerId,x:e.clientX,y:e.clientY,moved:!1,targetId:null,placement:null})}_tabDropTargetAt(e,t,i){const s=this._model.map(e=>e.id),n=s.indexOf(i);if(n<0)return null;const o=this.renderRoot.querySelectorAll('[data-hp="space-tab"]');for(const a of o){const o=a.dataset.id||"";if(!o||o===i)continue;const r=a.getBoundingClientRect();if(er.right||tr.bottom)continue;const l=s.indexOf(o);return l<0?null:{targetId:o,placement:l=4)))return;var i,s;const n=this._tabDropTargetAt(e.clientX,e.clientY,t.id);t.moved&&t.targetId===n?.targetId&&t.placement===n?.placement||(this._tabDrag={...t,moved:!0,targetId:n?.targetId||null,placement:n?.placement||null})}_tabPointerUp(e){const t=this._tabDrag;if(t&&t.pointerId!==e.pointerId)return;const i="pointerup"===e.type&&t?.moved?this._tabDropTargetAt(e.clientX,e.clientY,t.id):null;"pointerup"===e.type&&t?.moved&&this._suppressNextTabClick(),this._endTabDrag(),t?.moved&&i&&this._commitTabOrder(t.id,i.targetId)}_endTabDrag(){this._tabDrag=null,this._tabDragRelease&&(window.removeEventListener("pointerup",this._tabDragRelease),window.removeEventListener("pointercancel",this._tabDragRelease),this._tabDragRelease=null)}_tabClick(e){if(this._tabSuppressClick)return this._tabSuppressClick=!1,clearTimeout(this._tabSuppressClickTimer),void(this._tabSuppressClickTimer=void 0);this._pickSpace(e)}_suppressNextTabClick(){this._tabSuppressClick=!0,clearTimeout(this._tabSuppressClickTimer),this._tabSuppressClickTimer=window.setTimeout(()=>{this._tabSuppressClick=!1,this._tabSuppressClickTimer=void 0},0)}_commitTabOrder(e,t){const i=this._serverCfg;if(!i||!this._canReorderTabs)return;const s=this._model.map(e=>e.id),n=function(e,t,i){const s=e.indexOf(t),n=e.indexOf(i);if(s<0||n<0||s===n)return e;const o=e.slice();return o.splice(s,1),o.splice(n,0,t),o}(s,e,t);if(n===s)return;const o=new Map(this._devices.map(e=>[String(e.id),String(e.area||"")])),a=function(e,t,i,s=()=>""){if(!i)return[];const n=[];for(const o of e){if(!o||!0===o.removed)continue;const e="string"==typeof o.id?o.id:"";if(!e)continue;if("string"==typeof o.space&&o.space)continue;const a=("string"==typeof o.area?o.area:"")||s(e)||"";a&&t[a]||n.push({id:e,space:i})}return n}(i.markers||[],Object.fromEntries(Object.entries(this._areaToSpace).map(([e,t])=>[e,t.space])),s[0]||"",e=>o.get(e)||"");if(a.length){const e=new Map(a.map(e=>[e.id,e.space]));for(const t of i.markers||[]){const i=e.get(String(t.id));i&&(t.space=i)}}i.spaces=function(e,t){const i=new Map(t.map((e,t)=>[e,t]));return e.map((e,t)=>({space:e,index:t})).sort((e,t)=>(i.get(String(e.space?.id))??Number.MAX_SAFE_INTEGER)-(i.get(String(t.space?.id))??Number.MAX_SAFE_INTEGER)||e.index-t.index).map(e=>e.space)}(i.spaces||[],n),this._saveConfig(),this._tabOrderWarned||(this._tabOrderWarned=!0,this._showToast(this._t("toast.space_order_changed")))}_pickSpace(e){if(this._endTabDrag(),e===this._space)return;const t=this._model.map(e=>e.id),i=t.indexOf(this._space),s=t.indexOf(e);this._navApplied=!0,this._showFar=!1,this._frame=null,this._slideTo(e,i>=0&&s0&&Date.now()>=this._cyclePausedUntil&&this._model.length>1&&this._zoom<=1.001){const e=this._model.map(e=>e.id),t=e.indexOf(this._space);this._slideTo(e[(t+1)%e.length],"left"),this._showKioskDots()}}_syncCycleTimer(){clearInterval(this._cycleTimer),this._cycleTimer=void 0,this.isConnected&&!this._hasFixedFloor&&this._config?.kiosk&&Number(this._config.cycle)>0&&(this._cycleTimer=window.setInterval(()=>this._cycleTick(),1e3*Number(this._config.cycle)))}get _editing(){return"plan"===this._mode||"devices"===this._mode||"decor"===this._mode}get _markup(){return"plan"===this._mode}get _wallUnionCache(){return this._wallUnionCacheValue}set _wallUnionCache(e){this._wallUnionCacheValue=e,null===e&&this._wallUnionPool.clear()}_newContinuityController(){return new Ld(()=>{this._resumeSettling="steady"!==this._continuity.state,this._continuityEpoch++,this.isConnected&&this.requestUpdate()})}get _labsIso(){return this._labs.active.includes("iso")}get _desiredProjection(){return"view"===this._mode&&this._labsIso&&"iso"===this._viewPreference[this._space]?"iso":"flat"}_saveViewPreference(){try{localStorage.setItem(Cv,JSON.stringify(this._viewPreference))}catch{}}_logicalViewCenter(e){const t=this._view;if(!t)return null;const i=[t.x+t.w/2,t.y+t.h/2],s="iso"===e?Sf(i):i;return{x:s[0],y:s[1]}}_convertProjectionView(e,t){if(e===t)return;const i=this._logicalViewCenter(e);this._view=null;const s=i?"iso"===t?$f([i.x,i.y],0):[i.x,i.y]:null;this._applyView(this._zoom,s?.[0],s?.[1]),this._warmPatch({vp:this._warmViewportState()}),this.requestUpdate()}_setProjection(e){if(!this._labsIso||"view"!==this._mode)return;const t=this._effectiveProjection();if(this._viewPreference={...this._viewPreference,[this._space]:e},"iso"===e){const e=this._isoSceneKey();e&&this._isoFallback.delete(e)}this._saveViewPreference();const i=this._effectiveProjection();this._convertProjectionView(t,i)}_hashSpace(){return df(window.location.hash||"")}connectedCallback(){this._connectedPath=location.pathname,this._routeDepartureHandled=!1,window.addEventListener("location-changed",this._onLocationChanged),window.addEventListener("popstate",this._onLocationChanged),this._continuityDisposed&&(this._continuity=this._newContinuityController(),this._continuityDisposed=!1,this._continuityPaintToken=-1);const e=(t=this.ownerDocument,Wg.get(t)?.resolved);var t;void 0!==e&&(this._glowScreenBlend=e),this._continuityUnsub?.(),this._continuityUnsub=Od(this.ownerDocument,this._pageVisibility),super.connectedCallback(),this._pointerModality.connect(this.ownerDocument.defaultView);const i=this.ownerDocument.defaultView?.MutationObserver;i&&(this._pointerHoverObserver=new i(e=>{for(const t of e)for(const e of t.addedNodes)this._syncPointerHoverSubtree(e)}),this._pointerHoverObserver.observe(this.renderRoot,{childList:!0,subtree:!0})),this._motionMedia=window.matchMedia?.("(prefers-reduced-motion: reduce)"),this._reducedMotion=!!this._motionMedia?.matches,this._motionMedia?.addEventListener?.("change",this._onMotionChange),function(e){const t=Wg.get(e);if(t)return t.promise;const i={promise:Promise.resolve(!1)};return i.promise=Gg(e).catch(()=>!1).then(e=>(i.resolved=e,e)),Wg.set(e,i),i.promise}(this.ownerDocument).then(e=>{e!==this._glowScreenBlend&&(this._glowScreenBlend=e,this.isConnected&&this.requestUpdate())}),this.hass&&this._ensureHaRegistryAuthority(),window.addEventListener("keydown",this._keyHandler),this._signer.start(()=>this.hass,()=>Rs(this._serverCfg)),this._syncCycleTimer(),window.addEventListener("hashchange",this._onHashChange),this._labsUnsub?.(),this._labsUnsub=function(e,t){vf.add(t);const i=wf(e);return"undefined"==typeof window&&t(i),()=>{vf.delete(t)}}(cv,this._onLabsSnapshot),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},_v)),!this._loadOk&&this._serverCfg&&this.hass&&this._scheduleLoadRetry(),!this._warmSlot&&this._config&&this._warmAdopt(),this._loadOk&&this._ensureLiveSyncSubscriptions(),this._warmVp&&!this._warmRevivePending&&void 0===this._warmReviveTimer&&(this._warmRevivePending=!0,this._warmReviveTimer=window.setTimeout(()=>this._warmReviveDialog(),0)),this._warmLongReturn&&this._beginResumeSettle(),this._warmLongReturn=!1,this.requestUpdate()}disconnectedCallback(){this._connectedPath&&location.pathname!==this._connectedPath&&this._leaveCardRoute(),window.removeEventListener("location-changed",this._onLocationChanged),window.removeEventListener("popstate",this._onLocationChanged),this._continuityUnsub?.(),this._continuityUnsub=void 0,this._motionMedia?.removeEventListener?.("change",this._onMotionChange),this._motionMedia=void 0,this._vacRaf&&(cancelAnimationFrame(this._vacRaf),this._vacRaf=0),this._refitRaf&&(cancelAnimationFrame(this._refitRaf),this._refitRaf=0),this._dayCycleTimer&&(clearInterval(this._dayCycleTimer),this._dayCycleTimer=0),this._dayCycleClockKey="",this._bootSettleRaf&&(cancelAnimationFrame(this._bootSettleRaf),this._bootSettleRaf=0),this._bootSettling=!1;for(const e of this._activityRt.values())clearTimeout(e.timer);window.removeEventListener("keydown",this._keyHandler),this._endTabDrag(),clearTimeout(this._tabSuppressClickTimer),this._tabSuppressClickTimer=void 0,this._tabSuppressClick=!1,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?.removeEventListener?.("disconnected",this._onConnLost),this._connHooked?.removeEventListener?.("reconnect-error",this._onConnLost),this._connHooked=null,this._haRegistryRelease?.(),this._haRegistryRelease=void 0,this._haRegistryConnection=null,this._signer.dispose(),clearTimeout(this._toastTimer),clearTimeout(this._slideTimer),this._modeTransition.dispose(),this._modeTransitionVisual=null,this._modeTransitionPreparing=!1,this._modeTransitionForceAtomic=!1,this._modeTransitionRequest++,this._slideTimer=void 0,this._slide="",clearTimeout(this._bootTimer),this._bootTimer=void 0,clearTimeout(this._bootSoftTimer),this._saveConfigDebounced.flush(),window.removeEventListener("hashchange",this._onHashChange),this._labsUnsub?.(),this._labsUnsub=void 0,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),this._unsubVirtual&&(this._unsubVirtual(),this._unsubVirtual=null),this._unsubTrail&&(this._unsubTrail(),this._unsubTrail=void 0),this._liveSyncGeneration++,this._liveSyncAttempt=null,this._liveSyncConnection=null,clearTimeout(this._layoutSyncTimer),clearTimeout(this._duplicateColumnTimer);for(const e of this._glowFadeTimers.values())clearTimeout(e);for(const e of this._glowEnterRafs.values())cancelAnimationFrame(e);clearTimeout(this._glowFeatherResumeTimer),this._glowFeatherResumeTimer=0,this._glowFeatherSuspendUntil=0,this._glowFadeTimers.clear(),this._glowEnterRafs.clear(),this._glowEnteringSources.clear(),this._glowRenderedSources.clear(),this._glowLastAppearance.clear(),this._glowSourceSeq=0,this._warmSnapshot(),this._warmRevivePending=!1,clearTimeout(this._warmReviveTimer),this._warmReviveTimer=void 0,this._warmRelease(),this._clearPlanSnapHover(),this._clearOpeningPlacement(!0),this._touchContacts.clear(),this._touchSequenceMultitouch=!1,this._touchClickBlockUntil=0,this._clearTransientHover(!0),this._cancelDevicePressFeedback(),this._pointerHoverObserver?.disconnect(),this._pointerHoverObserver=void 0,this._pointerModality.disconnect(),this._editorSecondary.reset(),this._resumeSettling=!1,this._continuityHistory=[...this._continuityHistory,...this._continuity.trace].slice(-80),this._continuity.dispose(),this._continuityDisposed=!0,super.disconnectedCallback()}_onKey(e){if("Escape"===e.key&&this._vacFit)return this._vacFit=null,this._showToast(this._t("vac.cal_cancelled")),void e.stopPropagation();if("Escape"===e.key){if(this._tapConfirm)return void(this._tapConfirm=null);if(this._vacCalConfirm)return void(this._vacCalConfirm=null);if(this._decorEraseConfirm)return void(this._decorEraseConfirm=null);if(this._openingInfo)return void(this._openingInfo=null);if(this._infoCard)return void this._closeInfoCard();if(this._rulesDialog)return void(this._rulesDialog=null);if(this._alignDialog)return this._alignDialog=null,void(this._preflightClipboardFallback=null);if(this._backupImportDialog)return void(this._backupImportDialog=null);if(this._backupExportDialog)return void(this._backupExportDialog=null);if(this._settingsDialog)return void(this._settingsDialog=null);if(this._markerDialog)return void this._closeMarkerDialog();if(this._deviceInbox)return void(this._deviceInbox=null);if(this._openingDialog)return void(this._openingDialog=null);if(this._physicalDialog)return void(this._physicalDialog=null);if(this._backdropDialog)return void(this._backdropDialog=null);if(this._decorShapeDialog)return void(this._decorShapeDialog=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(this._editorSecondary.hasOpenGroup)return e.preventDefault(),void this._editorSecondary.closeGroup(!0)}const t=e.composedPath?.()||[e.target],i=t.some(e=>e?.matches?.('input, textarea, select, [contenteditable="true"]')),s=t.some(e=>e?.classList?.contains?.("editor-secondary")),n=e.ctrlKey||e.metaKey,o=e.key.toLowerCase(),a=/^[a-z]$/.test(o),r="z"===o||!a&&"KeyZ"===e.code,l="y"===o||!a&&"KeyY"===e.code,c=n&&(r&&e.shiftKey||l),h=n&&r&&!e.shiftKey;if("decor"===this._mode){if((h||c)&&i)return;return c?(e.preventDefault(),void this._redoGeometry()):h?(e.preventDefault(),this._decorDraft?void(this._decorDraft=null):this._decorMove||this._dtDrag||this._bdDrag?void this._cancelDecorGesture():void this._undoGeometry()):"Delete"!==e.key&&"Backspace"!==e.key||!this._decorSel||i||s?void("Escape"===e.key&&(e.preventDefault(),this._decorDraft?this._decorDraft=null:this._decorMove||this._dtDrag||this._bdDrag?this._cancelDecorGesture():"furniture"===this._decorTool?(this._furnPalette=null,this._decorTool="select"):this._decorSel?this._decorSel=null:"select"!==this._decorTool?this._decorTool="select":this._setMode("view"))):(e.preventDefault(),void this._decorDeleteSel())}if(this._markup&&(!h&&!c||!i)){if(("Delete"===e.key||"Backspace"===e.key)&&this._physicalSel&&!i&&!s)return e.preventDefault(),void this._deletePhysicalSelection();if(c)return e.preventDefault(),void this._redoGeometry();if(h)return e.preventDefault(),this._resize.dragging?void this._rszCancelDrag():this._wallFaceBatch?(this._roomDialogCancel(),void(this._activeDraftId&&this._path.length>1?this._undoActiveDraftPoint():this._undoPoint())):"draw"===this._tool&&this._path.length?void(this._activeDraftId&&this._path.length>1?this._undoActiveDraftPoint():this._undoPoint()):"split"===this._tool&&this._splitSel?.pts?.length?(this._splitSel={...this._splitSel,pts:this._splitSel.pts.slice(0,-1)},void(this._splitSel.pts.length||(this._cursorPt=null))):void this._undoGeometry();if("Escape"===e.key)return this._physicalDrag||this._physicalRotate?(e.preventDefault(),void this._cancelPhysicalGesture()):this._roomDialog?(e.preventDefault(),void this._roomDialogCancel()):"draw"===this._tool&&this._path.length?(e.preventDefault(),void this._finishWallChain()):this._physicalSel?(e.preventDefault(),void(this._physicalSel=null)):"resize"===this._tool?(e.preventDefault(),this._resize.dragging?void this._rszCancelDrag():("exit-tool"===this._resize.escapeIdle()&&(this._tool="draw"),void this.requestUpdate())):"split"===this._tool?(e.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?(e.preventDefault(),void(this._mergeSel?this._mergeSel=null:this._tool="draw")):this._wallDialog?(e.preventDefault(),void(this._wallDialog=null)):void("opening"!==this._tool&&"wallthick"!==this._tool&&"delroom"!==this._tool&&"column"!==this._tool||(e.preventDefault(),"opening"===this._tool&&this._clearOpeningPlacement(!0),this._tool="draw"))}}_undoPoint(){if(this._path.length){if(this._contourClosed)return this._path=this._path.slice(0,-1),void(this._closingWallCm=null);if(this._activeDraftId&&this._path.length>1&&this._curSpaceCfg){const e=this._geometrySnapshot();this._path=this._path.slice(0,-1),this._draftSegmentCms=this._draftSegmentCms.slice(0,-1);const t=this._curSpaceCfg,i=(t.room_drafts||[]).findIndex(e=>e.id===this._activeDraftId);if(i>=0){const s=Array.isArray(t.room_drafts[i]?.segments)?t.room_drafts[i].segments:[];this._path.length<2?(t.room_drafts.splice(i,1),t.room_drafts.length||delete t.room_drafts,this._activeDraftId=null):t.room_drafts[i]={id:this._activeDraftId,points:this._path.map(e=>[e[0]/Pv,e[1]/Pv]),segments:this._draftSegmentCms.map((e,t)=>({...s[t]||{},cm:e}))},this._commitPhysicalGeometry(this._t("history.draft_segment_delete"),e)}return}this._path=this._path.slice(0,-1)}}_undoActiveDraftPoint(){const e=this._activeDraftId,t=this._path[0]?[...this._path[0]]:null,i=this._geometryHistory.undo();if(!i)return void this._undoPoint();if(!this._applyGeometryState(i.before,!0))return void this._geometryHistory.clear();const s=e?this._spaceModel()?.room_drafts.find(t=>t.id===e):null;s?(this._activeDraftId=s.id,this._path=s.points.map(e=>[...e]),this._draftSegmentCms=this._adoptDraftCms(this._path,s.segments.map(e=>e.cm),s.id),this._resumeDraftBySpace[this._space]=s.id):(this._activeDraftId=null,this._path=t?[t]:[],this._draftSegmentCms=[],e&&this._resumeDraftBySpace[this._space]===e&&delete this._resumeDraftBySpace[this._space]),this._clearPlanSnapHover(),this._showToast(this._t("history.undone",{name:i.name}))}static getConfigElement(){return document.createElement("houseplan-card-editor")}static getStubConfig(){return{type:"custom:houseplan-card"}}static _warmBootReset(e){for(const e of vv.values())for(const t of e)clearTimeout(t.evict);vv.clear(),wv=e&&e>0?e:1e4}static _warmBootStats(){let e=0,t=0;const i=[];for(const s of vv.values())for(const n of s)e++,n.dlg&&(t++,i.push(n.dlg.kind));return{keys:vv.size,slots:e,dlgs:t,drafts:i}}setConfig(e){const t=this._config,i=!!t&&Object.prototype.hasOwnProperty.call(t,"floor");this._config={icon_size:2.5,show_temperature:!0,live_states:!0,show_signal:!0,...e};(i!==this._hasFixedFloor||t?.floor!==this._config.floor)&&(this._hashApplied=!1,this._navApplied=!1,this._warmVpArmed=!1),this._config.kiosk&&(this._booting=!1,this._bootFading=!1),!this._hasFixedFloor&&e.default_floor&&this._commitSpace(e.default_floor,!0);try{this._zoomBySpace=JSON.parse(localStorage.getItem($v)||"{}")||{}}catch{this._zoomBySpace={}}try{const e=JSON.parse(localStorage.getItem(Cv)||"{}")||{};this._viewPreference=Object.fromEntries(Object.entries(e).filter(e=>"flat"===e[1]||"iso"===e[1]))}catch{this._viewPreference={}}this._labs=wf(cv);try{const e=JSON.parse(localStorage.getItem(Mv)||"null");this._kioskScale={icon:Ns(e?.icon),font:Ns(e?.font)}}catch{}try{const e=JSON.parse(localStorage.getItem(xv)||"null");e&&e.config&&Array.isArray(e.config.spaces)&&(this._serverCfg=e.config,this._cfgEpoch++,this._cfgRev=e.rev||0,this._cfgContentFingerprint=e.config_fingerprint||Bd(e.config),this._layout=e.layout||{},this._layoutRev=e.layout_rev||0,this._layoutContentFingerprint=e.layout_fingerprint||Bd(this._layout),this._virtualLights=mn(e.virtual_lights,this._cfgRev),this._serverStorage=!0)}catch{}this._adoptInitialSpace(this._model,this._loadOk),"view"!==this._mode||this._view||(this._zoom=this._zoomBySpace[this._space]||1),this.isConnected&&(this._syncCycleTimer(),this._warmAdopt(),this._warmLongReturn&&this._beginResumeSettle(),this._warmLongReturn=!1)}_warmAdopt(){if(this._config?.kiosk)return;const e=yv(this._config);if(this._warmKey===e&&this._warmSlot)return;this._warmSlot&&this._warmRelease();const t=this.parentNode,i=this._warmIdx(t),s=vv.get(e);if(!s||!s.length)return;const n=s.find(e=>e.owner===this._warmGen);if(n)return this._warmLongReturn=!!n.freed&&Date.now()-n.freed>=Fd,clearTimeout(n.evict),n.evict=0,n.freed=0,n.live=!0,this._warmSlot=n,this._warmKey=e,n.frameFingerprint&&this._continuity.adoptCompleteFrame(n.frameFingerprint),void(!this._devices.length&&n.devices?.length&&(this._devices=[...n.devices]));const{slot:o,sure:a}=((e,t,i,s)=>{const n=e=>{const t=!!i&&e.place?.deref()===i;return t&&e.idx===s?4:e.live?0:t?3:2};let o=null,a=0,r=0,l=null;for(const i of e){if(i.owner===t)continue;l=i;const e=n(i);e<=0||(e>a?(o=i,a=e,r=1):e===a&&r++)}return!o||r>1?{slot:o||l,sure:!1}:{slot:o,sure:!0}})(s,this._warmGen,t,i);o&&(this._warmLongReturn=!!o.freed&&Date.now()-o.freed>=Fd,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},_v)),this._warmKey=e,a?(clearTimeout(o.evict),o.evict=0,o.owner=this._warmGen,o.place=t?new WeakRef(t):null,o.idx=i,o.live=!0,this._warmSlot=o,this._warmVp=o.vp,o.frameFingerprint&&this._continuity.adoptCompleteFrame(o.frameFingerprint),!this._devices.length&&o.devices?.length&&(this._devices=[...o.devices]),this._warmAdoptViewport(this._config)):(this._warmSlot={owner:this._warmGen,path:location.pathname,place:t?new WeakRef(t):null,idx:i,live:!0,hdrH:o.hdrH,stageH:o.stageH,vp:null,frameFingerprint:"",devices:null,dlg:null,freed:0,evict:0},s.push(this._warmSlot),this._warmTrim(s)))}_warmIdx(e){const t=e?.children;if(!t)return-1;for(let e=0;e4;){const t=e.findIndex(e=>!e.live);if(t<0)break;clearTimeout(e[t].evict),e.splice(t,1)}}_warmScheduleEvict(e,t){if(clearTimeout(e.evict),!(e.dlg||e.vp&&"view"!==e.vp.mode))return;const i=e.freed,s=e.owner;e.evict=window.setTimeout(()=>{if(e.evict=0,e.freed!==i||e.owner!==s)return;var n;e.dlg=null,e.vp=(n=e.vp)&&"view"!==n.mode?{...n,mode:"view",zoom:n.snap?.space===n.space?n.snap.zoom:n.zoom,view:null,snap:null,tool:"draw",decorTool:"select",showHidden:!1,selId:null,rszSel:null,decorSel:null}:n,e.frameFingerprint="";const o=vv.get(t);if(!e.live&&o&&o.length>1){const t=o.indexOf(e);t>=0&&o.splice(t,1)}},wv+250)}_warmAdoptViewport(e){const t=this._warmVp;if(!t||this._warmSlot?.path!==location.pathname)return void(this._warmVp=null);const i=this._fixedFloorState();if(this._hashApplied||!this._model.find(e=>e.id===t.space)||"valid"===i.kind&&i.id!==t.space||this._hasFixedFloor&&"valid"!==i.kind)return void(this._warmVp=null);this._commitSpace(t.space,!0),this._navApplied=!0,this._adoptMode("view"!==t.mode&&this._canEdit&&!e.kiosk?t.mode:"view"),this._pendingNavMode="view"===t.mode||this._canEdit||e.kiosk?null:t.mode,this._zoom=t.zoom;const s=this._effectiveProjection(),n=s===t.projection&&this._labsIso===t.activeLabsIso;if(this._view=n&&t.view?{...t.view}:null,this._viewModeSnap=n&&t.snap?{...t.snap}:null,!n&&t.logicalCenter){const e="iso"===s?$f([t.logicalCenter.x,t.logicalCenter.y],0):[t.logicalCenter.x,t.logicalCenter.y];this._applyView(t.zoom,e[0],e[1])}var o;this._tool="opening"===(o=function(e){return"partition"===e?"draw":e}(o=t.tool))?"draw":"string"==typeof o&&Rv.has(o)?o:"draw",this._decorTool=t.decorTool,this._showHidden=t.showHidden,this._showFar!==t.showFar&&(this._showFar=t.showFar,this._frame=null),this._selId=t.selId,this._resize.restoreSelection(t.rszSel),this._decorSel=t.decorSel,this._warmVpArmed=!0}_warmPatch(e,t=!1){if(this._config?.kiosk)return;const i=yv(this._config);if(!this._warmSlot||this._warmKey===i){if(!this._warmSlot){if(!t)return;const e=this.parentNode;this._warmKey=i,this._warmSlot={owner:this._warmGen,path:location.pathname,place:e?new WeakRef(e):null,idx:this._warmIdx(e),live:!0,hdrH:this._hdrH,stageH:0,vp:null,frameFingerprint:"",devices:null,dlg:null,freed:0,evict:0};const s=vv.get(i)||[];for(s.push(this._warmSlot),vv.set(i,s),this._warmTrim(s);vv.size>8;){const e=vv.keys().next().value;if(void 0===e||e===i)break;for(const t of vv.get(e)||[])clearTimeout(t.evict);vv.delete(e)}}Object.assign(this._warmSlot,e)}}_warmViewportState(){const e=this._effectiveProjection();return{space:this._space,mode:this._mode,projection:e,activeLabsIso:this._labsIso,logicalCenter:this._logicalViewCenter(e),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._resize.selectedRoomId,decorSel:this._decorSel}}_warmDialogState(){const e=(e,t)=>({kind:e,space:this._space,mode:this._mode,data:t});return this._tapConfirm||this._alignDialog||this._mergeDialog||this._importDialog||this._backupExportDialog||this._backupImportDialog?null:this._openingInfo?e("openingInfo",this._openingInfo.id):this._infoCard?e("info",this._infoCard.id):this._rulesDialog?this._rulesDialog.busy?null:e("rules",this._rulesDialog):this._settingsDialog?this._settingsDialog.busy?null:e("settings",this._settingsDialog):this._markerDialog?this._markerDialog.busy?null:e("marker",this._markerDialog):this._openingDialog?e("opening",this._openingDialog):this._backdropDialog?e("backdrop",this._backdropDialog):this._decorShapeDialog?e("decorShape",this._decorShapeDialog):this._decorTextDialog?e("decorText",this._decorTextDialog):this._roomDialog?e("room",{editId:this._roomEditId,fill:this._roomFill,customFill:this._roomCustomFill,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,wallFaceBatch:this._wallFaceBatch,path:this._path}):this._spaceDialog?this._spaceDialog.busy?null:e("space",this._spaceDialog):null}_warmSnapshot(){if(this._booting||this._config?.kiosk||"steady"!==this._continuity.state)return;const e={vp:this._warmViewportState(),frameFingerprint:this._continuity.frameFingerprint,devices:this._devices};if(this._warmRevivePending||(e.dlg=this._warmDialogState()),this.isConnected&&this._warmSlot?.owner===this._warmGen){const t=this.parentNode;e.place=t?new WeakRef(t):null,e.idx=this._warmIdx(t)}this._warmPatch(e)}_warmReviveDialog(){this._warmRevivePending=!1;const e=this._warmSlot;if(this._warmReviveTimer=void 0,!e||!e.dlg)return;const t=e.dlg,i=e.freed;if(e.dlg=null,e.freed=0,clearTimeout(e.evict),e.evict=0,i&&!(Date.now()-i>wv)&&t.space===this._space&&t.mode===this._mode){switch(t.kind){case"space":this._spaceDialog={...t.data,busy:!1,savedBusy:!1};break;case"marker":this._markerDialog={...t.data,busy:!1};break;case"settings":this._settingsDialog={...t.data,busy:!1};break;case"rules":this._rulesDialog={...t.data,busy:!1};break;case"opening":this._openingDialog={...t.data};break;case"backdrop":this._backdropDialog={...t.data};break;case"decorShape":this._decorShapeDialog={...t.data};break;case"decorText":{this._decorTextDialog={...t.data};const e=String(this._decorTextDialog?.text??"").length;this._decorTextSelection={start:e,end:e};break}case"room":{const e=t.data;this._roomEditId=e.editId,this._roomFill=e.fill,this._roomCustomFill=e.customFill||null,this._roomTempSrc=e.tempSrc,this._roomHumSrc=e.humSrc,this._roomSrcOpen=e.srcOpen,this._roomSrcFilter=e.srcFilter,this._roomNameScale=e.nameScale,this._roomLabelScale=e.labelScale,this._areaSel=e.areaSel,this._nameSel=e.nameSel,this._pendingSplit=e.pendingSplit,this._wallFaceBatch=e.wallFaceBatch||null,this._path=e.path,this._wallFaceBatch&&(this._activeDraftId=this._wallFaceBatch.activeDraftId,this._draftSegmentCms=[...this._wallFaceBatch.activeCms]),this._roomDialog=!0;break}case"info":{const e=this._devices.find(e=>e.id===t.data);e&&(this._infoCard=e);break}case"openingInfo":{const e=(this._curSpaceCfg?.openings||[]).find(e=>e.id===t.data);e&&(this._openingInfo=e);break}}this.requestUpdate()}}_cacheSnapshot(){if(this._serverCfg)try{this._cfgContentFingerprint=Bd(this._serverCfg),this._layoutContentFingerprint=Bd(this._layout),this._virtualLights=function(e,t,i){if(e.configRev===i)return e;const s=new Set((Array.isArray(t?.markers)?t.markers:[]).filter(bn).map(e=>e.id));return{...e,configRev:i,off:new Set([...e.off].filter(e=>s.has(e)))}}(this._virtualLights,this._serverCfg,this._cfgRev),localStorage.setItem(xv,JSON.stringify({config:this._serverCfg,rev:this._cfgRev,config_fingerprint:this._cfgContentFingerprint,layout:this._layout,layout_rev:this._layoutRev,layout_fingerprint:this._layoutContentFingerprint,virtual_lights:fn(this._virtualLights)}))}catch{}}_beginContinuityCandidate(e,t,i="plan"){return this._booting&&!this._continuity.hasCompleteFrame?this._continuity.token:(this._continuityDataReady=t,this._continuityPaintToken=-1,this._stagedDeviceSnapshotToken=-1,this._resumeSettling=!0,this._continuity.beginCandidate(e,i))}_continuityStageValid(){const e=this._stageEl;return!!e&&e.clientWidth>0&&e.clientHeight>0}_continuityAssetsReady(){if(!this._model.length)return!1;const e=this._model.length?this._spaceModel():null;return!e?.bg?.href||this._signer.isReady(this.hass,e.bg.href)}_initialSpaceSelection(e,t=this._loadOk){const i=this._fixedFloorState(e,t);return"valid"===i.kind?{id:i.id,source:"fixed"}:this._hasFixedFloor?{id:null,source:"none"}:function(e){const t=new Set(e.spaceIds.filter(e=>!!e));if(!t.size)return{id:null,source:"none"};const i=[["hash",!1===e.acceptHash?null:e.hashSpace],["current",e.preserveCurrent?e.currentSpace:null],["saved",e.savedSpace],["default",e.defaultSpace],["first",e.spaceIds[0]]];for(const[e,s]of i)if(s&&t.has(s))return{id:s,source:e};return{id:null,source:"none"}}({spaceIds:e.map(e=>e.id),hashSpace:this._hashSpace(),acceptHash:!this._hashApplied,currentSpace:this._space,preserveCurrent:this._hashApplied||this._navApplied||this._warmVpArmed,savedSpace:this._savedNav()?.space,defaultSpace:this._config?.default_floor})}_adoptInitialSpace(e,t=this._loadOk){const i=this._initialSpaceSelection(e,t);return i.id?(this._commitSpace(i.id,!0),"hash"===i.source&&(this._hashApplied=!0),"saved"===i.source&&(this._navApplied=!0),i):i}_candidateBackdrop(e,t=this._space){const i=Rh(e),s=this._fixedFloorState(i,!0);if(this._hasFixedFloor&&"valid"!==s.kind)return"";const n=this._initialSpaceSelection(i,!0).id||(i.some(e=>e.id===t)?t:i[0]?.id);return i.find(e=>e.id===n)?.bg?.href||""}_visualFrameFingerprint(){const e=this._stageEl,t=e?[e.clientWidth,e.clientHeight]:[0,0];return jd([this._cfgRev,this._cfgContentFingerprint||Bd(this._serverCfg),this._layoutRev,this._layoutContentFingerprint||Bd(this._layout),this._space,this._mode,this._view,t,this._glowScreenBlend?"screen":"normal",this.hass?.themes?.darkMode??this.hass?.themes?.default_theme??""])}_settleContinuityFrame(){if(this._booting||!this._continuityStageValid())return;if(!this._continuity.hasCompleteFrame&&"steady"===this._continuity.state)return void(this._continuityAssetsReady()&&(this._renderSnapshotAt=Date.now(),this._continuity.markCompleteFrame(this._visualFrameFingerprint())));if(!this._continuityDataReady)return;if(!["holding","offline-stale","overlay-pending","overlay-visible","candidate-ready"].includes(this._continuity.state))return;const e=this._continuity.token;if(this._candidateDeviceSnapshot&&this._candidateDeviceSnapshot!==this._visibleDeviceSnapshot&&this._stagedDeviceSnapshotToken!==e)return this._stagedDeviceSnapshotToken=e,void this.requestUpdate();this._continuityPaintToken!==e&&(this._continuityPaintToken=e,this._continuity.candidateReady(e)&&this._continuity.commitAfterPaint(e,{updateComplete:()=>this.updateComplete,stageValid:()=>this.isConnected&&this._continuityStageValid(),assetsReady:()=>this._continuityAssetsReady(),frameFingerprint:()=>this._visualFrameFingerprint()}).then(t=>{t&&e===this._continuity.token?(this._resumeSettling=!1,this._renderSnapshotAt=Date.now(),this._candidateDeviceSnapshot&&(this._visibleDeviceSnapshot=this._candidateDeviceSnapshot),this._candidateDeviceSnapshot=null,this._stagedDeviceSnapshotToken=-1,this._warmSnapshot()):e===this._continuity.token&&(this._continuityPaintToken=-1,this._stagedDeviceSnapshotToken=-1,this._candidateDeviceSnapshot=null,this.requestUpdate())}))}_onBackdropLoaded(e,t){this._signer.markLoaded(this.hass,e,t),this._continuity.note("asset-ready"),this._continuityPaintToken=-1,"steady"!==this._continuity.state&&this.requestUpdate()}_renderRecoveryOverlay(){if(!this._continuity.overlayVisible&&"recovery-error"!==this._continuity.state)return G;const e="connection"===this._continuity.recoveryReason;return q`
`}afterRender(){const e=this.host.root();this._blocked&&(this._openGroupId?this.closeGroup(!1):"palette"===this._currentModel?.kind&&this._currentModel.dismiss?.()),this._syncGlobalDismissListener();const t=e.querySelector(".editor-secondary"),i=this._renderedContext,s=t?.dataset.contextId||"";if(s&&i&&s!==i&&!window.matchMedia?.("(prefers-reduced-motion: reduce)")?.matches&&(this._contentAnimation?.cancel(),this._contentAnimation=t?.querySelector(".editor-secondary-content")?.animate([{opacity:.35,transform:"translateY(-4px)"},{opacity:1,transform:"translateY(0)"}],{duration:100,easing:"ease-out"})),this._renderedContext=s,i&&s!==i&&this._focusOwned){const i=s?t?.querySelector('[tabindex="0"], button:not([disabled]), input:not([disabled]), select:not([disabled]), textarea:not([disabled])'):e.querySelector(".editbar-tools");i?.focus?.(),this._focusOwned=!!s}if("palette"===this._currentModel?.kind&&this._currentModel.launcherId){const t=[...e.querySelectorAll("[data-editor-palette]")].find(e=>e.dataset.editorPalette===this._currentModel?.launcherId);t&&null!==t.offsetParent||this._currentModel.dismiss?.()}if(!this._openGroupId)return;const n=[...e.querySelectorAll("[data-editor-group]")].find(e=>e.dataset.editorGroup===this._openGroupId);n&&null!==n.offsetParent||this.closeGroup(!0)}handleOutsideDismiss(e){if(bm(e,e=>e.hasAttribute("data-editor-navigation")))return"pointerdown"===e.type?this.closeForNavigation():"click"===e.type&&this._dismissPointerTarget&&this._clearDismissClick(),!1;if("click"===e.type&&this._dismissPointerTarget){return!!(e.composedPath?.()||[e.target]).includes(this._dismissPointerTarget)&&(this._clearDismissClick(),e.preventDefault(),e.stopImmediatePropagation(),!0)}const t=this._openGroupId||this._blocked||"palette"!==this._currentModel?.kind?null:this._currentModel;if("pointerdown"===e.type&&(this._openGroupId||t)){const i=bm(e,e=>e.classList.contains("editor-secondary")),s=bm(e,e=>!!e.dataset.editorGroup),n=bm(e,e=>!!e.dataset.editorPalette),o=bm(e,e=>e.classList.contains("stage"));if(!(i||s||n||"stay-open-on-canvas"===t?.dismissPolicy&&o))return e.preventDefault(),e.stopImmediatePropagation(),this._dismissPointerTarget=e.target,clearTimeout(this._dismissTimer),this._dismissTimer=window.setTimeout(()=>{this._clearDismissClick()},800),this._openGroupId?this.closeGroup(!1):t?.dismiss?.(),this._syncGlobalDismissListener(),!0}return!1}_activateGroupItem(e,t,i){if(e.id!==this._openGroupId)return;const s=e.items.find(e=>e.id===t);if(!s||s.disabled)return;const n="toggle"===s.role&&"stay-open"===s.closePolicy,o=0===i.detail;n||(this._openGroupId=null,this.host.requestUpdate(),this._syncGlobalDismissListener()),s.invoke(),!n&&o&&this.host.updateComplete().then(()=>{const t=[...this.host.root().querySelectorAll("[data-editor-group]")].find(t=>t.dataset.editorGroup===e.id&&null!==t.offsetParent);t?.focus()})}_groupKeydown(e){if(!["ArrowLeft","ArrowRight","Home","End"].includes(e.key))return;const t=[...e.currentTarget.querySelectorAll(".editor-group-item:not([disabled])")];if(!t.length)return;e.preventDefault();const i=t.indexOf(this.host.root().activeElement),s="Home"===e.key?0:"End"===e.key?t.length-1:"ArrowLeft"===e.key?i<=0?t.length-1:i-1:(i+1)%t.length;t[s]?.focus()}_clearDismissClick(){this._dismissPointerTarget=null,clearTimeout(this._dismissTimer),this._dismissTimer=void 0,this._syncGlobalDismissListener()}_syncGlobalDismissListener(){const e=!this._blocked&&"palette"===this._currentModel?.kind,t=!!this._openGroupId||e||!!this._dismissPointerTarget;t!==this._globalDismissListening&&(this._globalDismissListening=t,t?(window.addEventListener("pointerdown",this._globalDismissGuard,!0),window.addEventListener("click",this._globalDismissGuard,!0)):(window.removeEventListener("pointerdown",this._globalDismissGuard,!0),window.removeEventListener("click",this._globalDismissGuard,!0)))}}const wm=e=>e.stopPropagation(),km=4.166666666666667e-9;function xm(e){return Number.isFinite(e)?Math.round(e/jh)*jh:e}const $m=(e,t,i,s)=>Math.hypot(i-e,s-t),Sm=(e,t,i,s,n,o,a,r)=>Math.hypot(Math.max(Math.abs(n-e),Math.abs(n+a-(e+i))),Math.max(Math.abs(o-t),Math.abs(o+r-(t+s)))),Mm=(e,t,i,s,n,o,a)=>{const r=Math.max(Number(s)||0,0)/2,l=Math.PI/180,c=Math.cos(i*l)*r,h=Math.sin(i*l)*r,d=Math.cos(a*l)*r,p=Math.sin(a*l)*r,u=Math.max($m(e+c,t+h,n+d,o+p),$m(e-c,t-h,n-d,o-p)),_=Math.max($m(e+c,t+h,n-d,o-p),$m(e-c,t-h,n+d,o+p));return Math.min(u,_)},Cm=e=>{const t=Number(e?.cell_cm);return t>0?t:5};function Dm(e,t){const i=JSON.parse(JSON.stringify(e||[])),s=JSON.parse(JSON.stringify(t||{}));let n=0,o=0,a=0,r=0,l="",c=0,h=0,d=0;const p=(e,t)=>{Number.isFinite(e)&&Number.isFinite(t)&&e!==t&&Math.abs(t-e)<=km&&h++},u=(e,t)=>{p(e[0],t[0]),p(e[1],t[1])},_={};let m=5;for(const e of i){const t=Cm(e);null!=e?.id&&(_[String(e.id)]=t),t>m&&(m=t)}const g=(e,t,i,s=!1)=>{if(!(e>km||s))return;n++,e>a&&(a=e);const o=e*Lh*t;o>r&&(r=o,l=i)};for(const e of i){const t=Cm(e),i=null!=e?.id?String(e.id):"";for(const s of e.rooms||[]){o++;let e=0;if(s.poly?.length)s.poly=s.poly.map(t=>{const i=[xm(t[0]),xm(t[1])];return e=Math.max(e,$m(t[0],t[1],i[0],i[1])),u(t,i),i});else if(null!=s.x&&null!=s.y){const t=s.x,i=s.y,n=s.w||0,o=s.h||0,a=xm(t+n),r=xm(i+o),l=xm(t),c=xm(i),h=Math.max(jh,a-l),d=Math.max(jh,r-c);e=Sm(t,i,n,o,l,c,h,d),s.x=l,s.y=c,s.w=h,s.h=d,p(t,l),p(i,c),p(t+n,l+h),p(i+o,c+d)}g(e,t,i)}for(const s of e.room_drafts||[]){o++;let e=0;const n=s.points||[],a=n.map(t=>{const i=[xm(t[0]),xm(t[1])];return e=Math.max(e,$m(t[0],t[1],i[0],i[1])),i}),r=a.length?[a[0]]:[],l=a.length?[[n[0],a[0]]]:[],c=[];for(let e=0;e+1=2)for(const[e,t]of l)u(e,t);g(e,t,i)}if(Array.isArray(e.room_drafts)){const t=e.room_drafts.length;e.room_drafts=e.room_drafts.filter(e=>e.points?.length>=2),d+=t-e.room_drafts.length,e.room_drafts.length||delete e.room_drafts}for(const s of e.partitions||[]){o++;const n=[s.a[0],s.a[1]],a=[s.b[0],s.b[1]],r=[xm(n[0]),xm(n[1])],l=[xm(a[0]),xm(a[1])];let c=Math.max($m(n[0],n[1],r[0],r[1]),$m(a[0],a[1],l[0],l[1]));const h=$m(r[0],r[1],l[0],l[1]),d=(e.openings||[]).filter(e=>"partition"===e.host?.kind&&e.host.id===s.id).every(e=>{const t=Number(e.length),i=Number(e.host.t),s=i*h;return Number.isFinite(t)&&t>0&&Number.isFinite(i)&&i>=0&&i<=1&&s-t/2>=-km&&s+t/2<=h+km});h>km&&d?(s.a=r,s.b=l,u(n,r),u(a,l)):c=0,g(c,t,i)}for(const s of e.wall_columns||[]){o++;const e=[s.center[0],s.center[1]],n=[xm(e[0]),xm(e[1])],a=$m(e[0],e[1],n[0],n[1]);s.center=n,u(e,n),g(a,t,i)}for(const s of e.decor||[]){o++;let e=0;if("line"===s.kind){const t=[s.x1,s.y1],i=[s.x2,s.y2],n=[xm(t[0]),xm(t[1])],o=[xm(i[0]),xm(i[1])];e=Math.max($m(t[0],t[1],n[0],n[1]),$m(i[0],i[1],o[0],o[1])),s.x1=n[0],s.y1=n[1],s.x2=o[0],s.y2=o[1],u(t,n),u(i,o)}else{const t=s.x,i=s.y,n=s.w,o=s.h,a=xm(t),r=xm(i);if(null!=s.w&&null!=s.h){const l=xm(t+n),c=xm(i+o),h=Math.max(jh,l-a),d=Math.max(jh,c-r);e=Sm(t,i,n,o,a,r,h,d),s.w=h,s.h=d,p(t+n,a+h),p(i+o,r+d)}else e=$m(t,i,a,r);s.x=a,s.y=r,p(t,a),p(i,r)}g(e,t,i)}for(const s of e.openings||[]){if(o++,"partition"===s.host?.kind){const n=(e.partitions||[]).find(e=>e.id===s.host.id),o=Number(s.host.t);if(!n||!Number.isFinite(o)||o<0||o>1)continue;const a=n.b[0]-n.a[0],r=n.b[1]-n.a[1];if(Math.hypot(a,r)<=km)continue;const l=n.a[0]+a*o,h=n.a[1]+r*o;let d=180*Math.atan2(r,a)/Math.PI;d>=90?d-=180:d<-90&&(d+=180);const p=Number(s.angle),u=!(Number.isFinite(p)&&p===d),_=Mm(s.x,s.y,Number.isFinite(p)?p:d,Number(s.length)||0,l,h,d);s.x=l,s.y=h,s.angle=d,u&&c++,g(_,t,i,u);continue}const n=ui([s.x,s.y],e.rooms||[],.025,{step:jh,length:Number(s.length)||0});if(!n)continue;const a=Number(s.angle),r=!(Number.isFinite(a)&&a===n.angle),l=Mm(s.x,s.y,Number.isFinite(a)?a:n.angle,Number(s.length)||0,n.x,n.y,n.angle);s.x=n.x,s.y=n.y,s.angle=n.angle,r&&c++,g(l,t,i,r)}}for(const[e,t]of Object.entries(s)){if(!t||"object"!=typeof t)continue;const i=t;if("number"!=typeof i.x||"number"!=typeof i.y)continue;o++;const n=xm(i.x),a=xm(i.y),r=$m(i.x,i.y,n,a);s[e]={...i,x:n,y:a},p(i.x,n),p(i.y,a);const l="string"==typeof i.s?i.s:"";g(r,_[l]??m,l)}return{spaces:i,layout:s,report:{moved:n,coordsCanonicalized:h,total:o,maxShift:a,maxShiftCm:r,maxSpace:l,rotated:c,removedDrafts:d},changed:n>0||h>0}}function Pm(e,t){const i=t.base+e*t.span;return Math.min(1,Math.max(0,i))}const Tm=e=>Array.isArray(e)&&e.length>=2&&Number.isFinite(e[0])&&Number.isFinite(e[1]),Im=(e,t)=>Math.hypot(e[0]-t[0],e[1]-t[1]);function Rm(e,t,i){const s=i[0]-t[0],n=i[1]-t[1],o=s*s+n*n;if(o<=0)return Im(e,t);let a=((e[0]-t[0])*s+(e[1]-t[1])*n)/o;return a=Math.max(0,Math.min(1,a)),Math.hypot(e[0]-(t[0]+s*a),e[1]-(t[1]+n*a))}function Am(e,t,i,s,n){for(const s of t)if(s&&!i.has(s.id)&&Tm(s.a)&&Tm(s.b)&&(Im(e,s.a)<=n||Im(e,s.b)<=n))return!0;for(const t of s?.roomPolygons||[])for(let i=0;i0&&r>0))return null;if(Math.abs(n[0]/a*(o[1]/r)-n[1]/a*(o[0]/r))>i)return null;for(const[i,n]of[[e.a,t.a],[e.a,t.b],[e.b,t.a],[e.b,t.b]])if(Im(i,n)<=s)return[(i[0]+n[0])/2,(i[1]+n[1])/2];return null}function Fm(e,t){const i=.05*(Number(t.pitch)>0?Number(t.pitch):1),s=new Map;let n=(e||[]).filter(e=>!!e&&"string"==typeof e.id&&Tm(e.a)&&Tm(e.b));if(n.length<2)return{partitions:[...e||[]],merged:0,openingMoves:[]};const o=t.seedIds&&t.seedIds.length?new Set(t.seedIds):null;let a=0;for(let e=0;eIm(t,e.at)>i);let h=c[0]??r.a,d=c[c.length-1]??l.b;if(c.length<2&&(h=r.a,d=l.b),d[0]0?(d[0]-h[0])/u:0,m=u>0?(d[1]-h[1])/u:0,g=e=>u>0?((e[0]-h[0])*_+(e[1]-h[1])*m)/u:0;for(const e of[r,l]){const t=g(e.a),i=g(e.b)-t;for(const[n,o]of s)o.toId===e.id&&s.set(n,{fromId:o.fromId,toId:p.id,base:t+o.base*i,span:o.span*i});s.set(e.id,{fromId:e.id,toId:p.id,base:t,span:i})}o&&o.add(p.id),n=n.filter((t,i)=>i!==e.i&&i!==e.j),n.splice(e.i,0,p),a++}return{partitions:n,merged:a,openingMoves:[...s.values()]}}function Nm(e,t,i,s){if(!e?.length||!i.length)return 0;const n=new Map(i.map(e=>[e.fromId,e]));let o=0;for(const i of e){const e=i?.host;if(!e||"partition"!==e.kind)continue;const a=n.get(e.id);if(!a)continue;i.host={...e,id:a.toId,t:Pm(e.t,a)},o++;const r=tu(i,t,s.coordScale,s.cellCm,s.gridPitch).resolved;r&&Object.assign(i,lu(i,r,s.coordScale))}return o}function Em(e,t){const i=t?.excludeDraftId||null;return{roomPolygons:(e?.rooms||[]).map(e=>hi(e)).filter(e=>!!e),columns:e?.wall_columns||[],draftEnds:(e?.room_drafts||[]).flatMap(e=>{if(i&&e?.id===i)return[];const t=e?.points||[];return t.length?[t[0],t[t.length-1]]:[]})}}const Om=e=>!!e&&e.length>=2&&Number.isFinite(e[0])&&Number.isFinite(e[1]),Hm=(e,t)=>e[0]-t[0]||e[1]-t[1],Lm=(e,t,i,s)=>[e[0]+t*s,e[1]+i*s],Bm=(e,t,i,s)=>(e[0]-t[0])*i+(e[1]-t[1])*s,jm=(e,t,i,s,n)=>{const o=t[0]-e[0],a=t[1]-e[1],r=Math.hypot(o,a);if(!(r>n))return null;const l=o/r,c=a/r,h=t=>Math.abs((t[0]-e[0])*c-(t[1]-e[1])*l);if(h(i)>n||h(s)>n)return null;const d=Bm(i,e,l,c),p=Bm(s,e,l,c),u=Math.max(0,Math.min(d,p)),_=Math.min(r,Math.max(d,p));return _-u>n?{lo:u,hi:_}:null},qm=(e,t,i)=>Math.min(e.hi,t.hi)-Math.max(e.lo,t.lo)>i,Wm=e=>{const t=new Set(["id","a","b","cm"]);return Object.keys(e||{}).every(e=>t.has(e))},Um=(e,t,i,s)=>{const n=e.b[0]-e.a[0],o=e.b[1]-e.a[1],a=Math.hypot(n,o);if(!(a>s))return!0;const r=n/a,l=o/a,c=Ml(e.cm,i.cellCm,i.gridPitch)/2;return t.some(t=>{const n=t?.center;if(!Om(n))return!0;const o=Bm(n,e.a,r,l),h=Math.abs((n[0]-e.a[0])*l-(n[1]-e.a[1])*r),d=Ml(Number(t.cm),i.cellCm,i.gridPitch)*("square"===t.shape?Math.SQRT1_2:.5);return!(Number.isFinite(d)&&d>0)||o>=-d-s&&o<=a+d+s&&h<=c+d+s})},Gm=(e,t,i)=>{if(e.host){const s=tu(e,t,i.coordScale,i.cellCm,i.gridPitch).resolved;return s?{center:s.center,angle:s.angle,length:s.length}:null}const s=Number(e.x)*i.coordScale,n=Number(e.y)*i.coordScale,o=Number(e.angle),a=Number(e.length)*i.coordScale;return[s,n,o,a].every(Number.isFinite)&&a>0?{center:[s,n],angle:o,length:a}:null},Vm=(e,t,i)=>{const s=e.angle*Math.PI/180,n=Math.cos(s),o=Math.sin(s),a=t.angle*Math.PI/180,r=Math.cos(a),l=Math.sin(a);if(Math.abs(n*l-o*r)>1e-6)return!1;const c=t.center[0]-e.center[0],h=t.center[1]-e.center[1];if(Math.abs(c*o-h*n)>i)return!1;const d=c*n+h*o;return Math.max(-e.length/2,d-t.length/2)({...e,a:[e.a[0]*t,e.a[1]*t],b:[e.b[0]*t,e.b[1]*t]}),Ym=(e,t,i,s)=>{const n=`~r-${(e=>{let t=2166136261;for(let i=0;i>>0;return t.toString(36)})(`${e}|${t[0].toFixed(9)},${t[1].toFixed(9)}|${i[0].toFixed(9)},${i[1].toFixed(9)}`)}`,o=`${e.slice(0,Math.max(1,64-n.length))}${n}`;let a=o;for(let e=2;s.has(a);e++){const t=`-${e}`;a=`${o.slice(0,64-t.length)}${t}`}return s.add(a),a},Jm=(e,t)=>{const i=[];for(const s of e){const e=i[i.length-1];!(e&&Math.abs(e.hi-s.lo)<=t&&e.safe===s.safe)||s.safe&&e.signature!==s.signature?i.push({lo:s.lo,hi:s.hi,a:s.a,b:s.b,safe:s.safe,signature:s.signature,roomIds:s.roomIds,finalCm:s.finalCm}):(e.hi=s.hi,e.b=s.b)}return i};function Xm(e,t,i,s,n){const o=i||[],a=Array.isArray(e?.partitions)?e.partitions:[],r=Array.isArray(e?.openings)?e.openings:[],l=Array.isArray(e?.room_drafts)?e.room_drafts:[],c={walls:o,partitions:a,openings:r,roomDrafts:l,partitionsReconciled:0,openingsRehosted:0,removedDrafts:0};if(!a.length&&!l.length)return c;const h=Math.max(2e-4*n.gridPitch,1e-9);let d=o,p=a,u=r;const _=wc(t.rooms,d,s,n.pitch,n.cellCm,n.gridPitch,n.coordScale),m=((e,t,i,s)=>{const n=new Map(e.map(e=>[e.id,e])),o=new Set;for(const e of t){if(!n.get(e.id)||!Array.isArray(e.points)||e.points.length<2||e.segments.length!==e.points.length-1)continue;let t=!0;for(let n=0;n+10)){t=!1;break}const l=Math.hypot(a[0]-o[0],a[1]-o[1]);if(!(l>s)){t=!1;break}const c=i.flatMap(e=>{const t=e.cm>0?e.cm:vl;if(e.open||"outer"!==e.kind&&"shared"!==e.kind||t+se.lo-t.lo||e.hi-t.hi);let h=0;for(const e of c){if(e.lo>h+s)break;if(h=Math.max(h,e.hi),h>=l-s)break}h!m.has(e.id));let f=0,v=0;const b=new Map(t.partitions.map(e=>[e.id,e]));for(const e of[...a].sort((e,t)=>e.id.localeCompare(t.id))){if(!p.some(t=>t.id===e.id))continue;if(!Wm(e))continue;const i=b.get(e.id);if(!(i&&Om(i.a)&&Om(i.b)&&Number.isFinite(i.cm)&&i.cm>0))continue;const[o,a]=Hm(i.a,i.b)<=0?[[i.a[0],i.a[1]],[i.b[0],i.b[1]]]:[[i.b[0],i.b[1]],[i.a[0],i.a[1]]],r=a[0]-o[0],l=a[1]-o[1],c=Math.hypot(r,l);if(!(c>h))continue;const _=r/c,g=l/c,y=wc(t.rooms,d,s,n.pitch,n.cellCm,n.gridPitch,n.coordScale),w=y.flatMap(e=>{if(e.open||"outer"!==e.kind&&"shared"!==e.kind)return[];const t=jm(o,a,e.a,e.b,h);return t?[{interval:e,range:t}]:[]});if(!w.length)continue;const k=u.filter(e=>"partition"===e.host?.kind&&e.host.id===i.id).map(e=>({opening:e,resolved:tu(e,t.partitions,n.coordScale,n.cellCm,n.gridPitch).resolved}));if(k.some(e=>!e.resolved))continue;const x=[0,c];for(const{range:e}of w)x.push(e.lo,e.hi);const $=x.slice(),S=new Map;for(const{opening:e,resolved:t}of k){const i=Bm(t.center,o,_,g),s={lo:i-t.length/2,hi:i+t.length/2};S.set(e.id,s),$.push(Math.max(0,s.lo),Math.min(c,s.hi))}const M=[...new Set($.filter(e=>Number.isFinite(e)&&e>=-h&&e<=c+h).map(e=>Math.max(0,Math.min(c,e)).toFixed(9)))].map(Number).sort((e,t)=>e-t),C=p.map(e=>Km(e,n.coordScale)).filter(e=>e.id!==i.id),D=t.room_drafts.filter(e=>!m.has(e.id)),P=[];for(let e=0;e+1h))continue;const r=Lm(o,_,g,s),l=Lm(o,_,g,a),c=w.filter(({range:e})=>e.lo<=s+h&&e.hi>=a-h).map(({interval:e})=>e),d=new Map;for(const e of c)d.set(e.roomId,e);const p=[...d.values()],u=new Set(p.map(e=>e.kind)),m=new Set(p.map(e=>e.cm>0?e.cm:vl)),f=p[0]?.kind,v=[...d.keys()].sort(),b=1===u.size&&1===m.size&&("outer"===f&&1===v.length||"shared"===f&&2===v.length),y={id:i.id,a:r,b:l,cm:i.cm},k=C.some(e=>!!jm(r,l,e.a,e.b,h)),x=D.some(e=>e.points.some((t,i)=>i+10?p[0].cm:vl:0,T=b?Math.max(S,i.cm):i.cm;P.push({lo:s,hi:a,a:r,b:l,safe:$,signature:$?`${f}|${v.join(",")}|${T}`:"",roomIds:v,roomCm:S,finalCm:T})}if(!P.some(e=>e.safe))continue;const T=new Map;for(const{opening:e,resolved:t}of k){const s=S.get(e.id),o=x.some(e=>e>s.lo+h&&eqm(e,s,h)),r=new Set(a.filter(e=>e.safe).map(e=>e.signature));if(!o&&a.length>0&&a.every(e=>e.safe)&&1===r.size&&ru(t,y,h)){T.set(e.id,{resolved:t,signature:[...r][0]});continue}const l=Qp(i,n.cellCm,n.gridPitch),c={lo:s.lo-l,hi:s.hi+l};for(const e of P)qm(e,c,h)&&(e.safe=!1,e.signature="")}let I=!0;for(;I;){I=!1;for(const[e,t]of[...T.entries()]){const s=S.get(e),o=P.filter(e=>qm(e,s,h));if(o.length>0&&o.every(e=>e.safe)&&o.every(e=>e.signature===t.signature))continue;T.delete(e);const a=Qp(i,n.cellCm,n.gridPitch),r={lo:s.lo-a,hi:s.hi+a};for(const e of P)qm(e,r,h)&&(e.safe=!1,e.signature="");I=!0}}const R=Jm(P,h),A=R.filter(e=>e.safe),z=R.filter(e=>!e.safe);if(!A.length)continue;if(p.length-1+z.length>2e3)continue;let F=d;for(const e of A){const[t,s]=Hm(i.a,i.b)<=0?[e.a,e.b]:[e.b,e.a];F=Ul(F,t,s,e.finalCm,n.pitch,n.coordScale)}if(F=xc(t.rooms,F,s,n.pitch,n.cellCm,n.gridPitch,n.coordScale),F.length>500)continue;const N=new Set(p.map(e=>e.id));N.delete(i.id);const E=z.map((e,t)=>{const s=[e.a[0]/n.coordScale,e.a[1]/n.coordScale],o=[e.b[0]/n.coordScale,e.b[1]/n.coordScale],a=0===t?i.id:Ym(i.id,s,o,N);return N.add(a),{id:a,a:s,b:o,cm:i.cm}}),O=p.findIndex(e=>e.id===i.id),H=p.slice();H.splice(O,1,...E);const L=H.map(e=>Km(e,n.coordScale)),B=new Map;let j=!0;for(const{opening:e,resolved:t}of k){const i=T.get(e.id);if(i){const t=lu(e,i.resolved,n.coordScale),{host:s,...o}=t;B.set(e.id,o);continue}const s=S.get(e.id),o=E[z.findIndex(e=>e.lo<=s.lo+h&&e.hi>=s.hi-h)],a=o&&L.find(e=>e.id===o.id);if(!o||!a){j=!1;break}const r=a.b[0]-a.a[0],l=a.b[1]-a.a[1],c=Math.hypot(r,l),d=Bm(t.center,a.a,r/c,l/c),p={...lu(e,t,n.coordScale),host:{kind:"partition",id:o.id,t:d/c}};if(!iu(p,L,n.coordScale,n.cellCm,n.gridPitch).resolved){j=!1;break}B.set(e.id,p)}if(!j)continue;const q=u.map(e=>B.get(e.id)||e),W=[...T.keys()].map(e=>B.get(e)),U=W.map(e=>Gm(e,L,n));if(U.some(e=>!e))continue;let G=!1;for(let e=0;ee.id));for(const e of q){if(V.has(e.id))continue;const t=Gm(e,L,n);t&&U.some(e=>Vm(e,t,h))&&(G=!0)}if(G)continue;const K=Kc(t.rooms,F,s,n.pitch,n.cellCm,n.gridPitch,n.coordScale);[...T.entries()].every(([e,t])=>{const i=B.get(e),s=Xc(K,{x:i.x*n.coordScale,y:i.y*n.coordScale,angle:i.angle,length:i.length*n.coordScale},!0),o=[s.negative,s.positive].filter(e=>!!e?.full),a=t.signature.split("|")[1].split(","),r=new Set(o.map(e=>e.roomId));return o.length===a.length&&r.size===a.length&&a.every(e=>r.has(e))})&&(d=F,p=H,u=q,f+=A.length,v+=T.size)}return{walls:d,partitions:p,openings:u,roomDrafts:g,partitionsReconciled:f,openingsRehosted:v,removedDrafts:m.size}}const Zm=e=>JSON.parse(JSON.stringify(e)),Qm=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),eg=(e,t)=>t.length>0&&t.length<=35&&("space"===e?/^[a-z0-9_-]+$/.test(t):/^[A-Za-z0-9_-]+$/.test(t));function tg(e,t){let i=String(t??"");const s=e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),n=new RegExp(`^${s}_(.+)_([0-9a-f]{8})$`);let o=0;for(;o<16;o++){const e=n.exec(i);if(!e)return{root:i,layers:o,bounded:!1};i=e[1]}return{root:i,layers:o,bounded:n.test(i)}}const ig=(e,t,i)=>{const s=e.get(t)||[];s.push(i),e.set(t,s)};const sg=1e-9;class ng extends Error{constructor(e,t=""){super(t?`${e}: ${t}`:e),this.reason=e,this.name="WallSegmentModelError"}}const og=e=>JSON.parse(JSON.stringify(e)),ag=e=>Array.isArray(e)&&e.length>=2&&Number.isFinite(Number(e[0]))&&Number.isFinite(Number(e[1])),rg=e=>[Number(e[0]),Number(e[1])],lg=e=>`${Number(e[0]).toFixed(12)},${Number(e[1]).toFixed(12)}`,cg=(e,t)=>{const i=lg(e),s=lg(t);return ilg(e)<=lg(t)?[rg(e),rg(t)]:[rg(t),rg(e)],dg=(e,t)=>Math.hypot(t[0]-e[0],t[1]-e[1]),pg=e=>{const t=[[Number(e.points[0][0]),Number(e.points[0][1])]],i=[];for(let s=1;s{const i=new Set,s=e=>{const t=Number(e);if(!Number.isFinite(t))return;const s=t/jh;Math.abs(s-Math.round(s))>=tl&&i.add(t.toFixed(12))};for(const t of Array.isArray(e?.rooms)?e.rooms:[])for(const e of hi(t)||[])s(e[0]),s(e[1]);for(const t of[e?.wall_segments,e?.walls])for(const e of Array.isArray(t)?t:[])s(e?.a?.[0]),s(e?.a?.[1]),s(e?.b?.[0]),s(e?.b?.[1]);for(const e of t)s(e?.[0]),s(e?.[1]);return i.size},_g=(e,t,i)=>{const s=i[0]-t[0],n=i[1]-t[1],o=s*s+n*n;return o>1e-18?((e[0]-t[0])*s+(e[1]-t[1])*n)/o:0},mg=(e,t,i)=>{const s=Math.max(0,Math.min(1,_g(e,t,i)));return Math.hypot(e[0]-(t[0]+(i[0]-t[0])*s),e[1]-(t[1]+(i[1]-t[1])*s))},gg=(e,t,i,s,n=sg)=>{const o=t[0]-e[0],a=t[1]-e[1],r=Math.hypot(o,a);if(r<=n)return 0;const l=t=>Math.abs((t[0]-e[0])*a-(t[1]-e[1])*o)/r;if(l(i)>n||l(s)>n)return 0;const c=_g(i,e,t),h=_g(s,e,t);return Math.max(0,Math.min(1,Math.max(c,h))-Math.max(0,Math.min(c,h)))*r},fg=e=>{const t=(new TextEncoder).encode(e),i=8*t.length,s=64*Math.ceil((t.length+9)/64),n=new Uint8Array(s);n.set(t),n[t.length]=128;const o=new DataView(n.buffer);o.setUint32(s-8,Math.floor(i/4294967296),!1),o.setUint32(s-4,i>>>0,!1);const a=new Uint32Array([1116352408,1899447441,3049323471,3921009573,961987163,1508970993,2453635748,2870763221,3624381080,310598401,607225278,1426881987,1925078388,2162078206,2614888103,3248222580,3835390401,4022224774,264347078,604807628,770255983,1249150122,1555081692,1996064986,2554220882,2821834349,2952996808,3210313671,3336571891,3584528711,113926993,338241895,666307205,773529912,1294757372,1396182291,1695183700,1986661051,2177026350,2456956037,2730485921,2820302411,3259730800,3345764771,3516065817,3600352804,4094571909,275423344,430227734,506948616,659060556,883997877,958139571,1322822218,1537002063,1747873779,1955562222,2024104815,2227730452,2361852424,2428436474,2756734187,3204031479,3329325298]),r=new Uint32Array([1779033703,3144134277,1013904242,2773480762,1359893119,2600822924,528734635,1541459225]),l=new Uint32Array(64),c=(e,t)=>e>>>t|e<<32-t;for(let e=0;e>>3,n=c(i,17)^c(i,19)^i>>>10;l[e]=l[e-16]+s+l[e-7]+n>>>0}let[t,i,s,n,h,d,p,u]=r;for(let e=0;e<64;e++){const o=u+(c(h,6)^c(h,11)^c(h,25))+(h&d^~h&p)+a[e]+l[e]>>>0,r=t&i^t&s^i&s;u=p,p=d,d=h,h=n+o>>>0,n=s,s=i,i=t,t=o+((c(t,2)^c(t,13)^c(t,22))+r>>>0)>>>0}r[0]=r[0]+t>>>0,r[1]=r[1]+i>>>0,r[2]=r[2]+s>>>0,r[3]=r[3]+n>>>0,r[4]=r[4]+h>>>0,r[5]=r[5]+d>>>0,r[6]=r[6]+p>>>0,r[7]=r[7]+u>>>0}const h=new Uint8Array(32),d=new DataView(h.buffer);for(let e=0;e{const t="abcdefghijklmnopqrstuvwxyz234567";let i=0,s=0,n="";for(const o of e)for(s=s<<8|o,i+=8;i>=5;)n+=t[s>>>i-5&31],i-=5;return i&&(n+=t[s<<5-i&31]),n},bg=(e,t,i,s,n="")=>{const[o,a]=hg(t,i),r=`${e}|${lg(o)}|${lg(a)}|${[...s].sort().join(",")}${n}`;return`wall-${vg(fg(r)).slice(0,20)}`};let yg=0;const wg=e=>{for(let t=0;t<1e3;t++){const t=globalThis.crypto?.randomUUID?.(),i=`wall-${t||vg(fg(`${Date.now()}|${yg++}|${Math.random()}`)).slice(0,26)}`;if(!e.has(i))return i}throw new ng("duplicate-id","id factory exhausted")},kg=e=>{const t=new Map;for(const i of Array.isArray(e?.wall_segments)?e.wall_segments:[])if(i&&"string"==typeof i.id&&ag(i.a)&&ag(i.b)){if(t.has(i.id))throw new ng("duplicate-id",i.id);t.set(i.id,i)}return t},xg=(e,t,i)=>{const s=(i,s)=>{const n=e[0]-i[0],o=e[1]-i[1];return Math.abs(t[0]-s[0]-n)<=sg&&Math.abs(t[1]-s[1]-o)<=sg?[n,o]:null};return s(i.a,i.b)||s(i.b,i.a)},$g=(e,t)=>{const i=Array.isArray(e.rooms)?e.rooms:[],s=Od(e.open_spans).map(e=>[e.a[0],e.a[1],e.b[0],e.b[1]]),n=s.length?s:Hd(i,null,1,.04*jh,!0),o=[];for(const e of i){const i=hi(e),s=Array.isArray(e?.wall_ids)?e.wall_ids:[];if(i&&s.length===i.length)for(let e=0;e"partition"!==e.host?.kind&&[Number(e.x),Number(e.y)].every(Number.isFinite)&&Number.isFinite(Number(e.angle))&&Number(e.length)>0&&n.some(t=>mg([Number(e.x),Number(e.y)],[t[0],t[1]],[t[2],t[3]])<=.04*jh)):[],l=r.map(e=>{const t=Number(e.angle)*Math.PI/180,i=[Math.cos(t),Math.sin(t)],s=Number(e.length)/2,n=[Number(e.x),Number(e.y)];return{a:[n[0]-i[0]*s,n[1]-i[1]*s],b:[n[0]+i[0]*s,n[1]+i[1]*s]}}),c=(e,t)=>r.some(i=>{const s=[Number(i.x),Number(i.y)];if(!Bl(e,t,Number(i.angle)))return!1;if(mg(s,e,t)>.02*jh)return!1;const n=dg(e,t),o=_g(s,e,t)*n,a=Number(i.length)/2;return o+a>=-sg&&o-a<=n+sg}),h=new Map,d=[];for(const s of i){const r=String(s?.id||""),p=hi(s);if(!r||!p||p.length<3)throw new ng("invalid-room",r);const u=dc(i,r,a,jh,1,[...e.walls||[],...l]);if(!u||u.poly.length<3)throw new ng("invalid-room",r);const _=Array.isArray(s.wall_ids)?s.wall_ids:[],m=_.length===p.length;let g=null,f=m;if(f)for(let e=0;esg||Math.abs(s[1]-g[1])>sg)){f=!1;break}g=s}const v=[];for(let e=0;e2)throw new ng("third-owner",a);const d=m?_[u.parent[e]]:void 0;if("string"==typeof d&&d){const n=t.get(d);f||!n||gg(i,s,n.a,n.b)>sg?l.preferredIds.add(d):l.positionalIds.add(d),l.preferredCarriers.set(d,{a:rg(p[u.parent[e]]),b:rg(p[(u.parent[e]+1)%p.length])})}const g=u.parent[e];l.parentKeys.add(Il(p[g],p[(g+1)%p.length],jh));const b=[(i[0]+s[0])/2,(i[1]+s[1])/2],y=e=>e.some(e=>mg(b,[e[0],e[1]],[e[2],e[3]])<=.04*jh);l.zeroWall||=y(o)||y(n)&&!c(i,s),v.push(a)}const b={...s};delete b.wall_ids,d.push({...b,poly:u.poly.map(e=>[e[0],e[1]]),wall_ids:v})}return{atoms:[...h.values()].sort((e,t)=>e.key.localeCompare(t.key)),rooms:d}},Sg=(e,t,i,s,n)=>{const o=new Map([...i.values()].map(e=>[cg(e.a,e.b),e])),a=(e=>{const t=new Map;for(const i of e)"wall"===i.host?.kind&&t.set(i.host.id,(t.get(i.host.id)||0)+1);return t})(e.openings||[]),r=new Map;for(const e of t){const t=n?.get(e.key);if(t){const s=i.get(t);if(!s)throw new ng("duplicate-id",t);r.set(e,s);continue}if(e.preferredIds.size>1)throw new ng("duplicate-id",[...e.preferredIds].sort().join(","));const s=[...e.preferredIds][0],l=s?i.get(s):void 0;if(l){r.set(e,l);continue}const c=s?e.preferredCarriers.get(s):void 0;if(s&&c){r.set(e,{id:s,a:c.a,b:c.b,cm:0});continue}const h=o.get(e.key);if(h){r.set(e,h);continue}const d=[...i.values()].filter(t=>gg(e.a,e.b,t.a,t.b)>sg),p=[...new Map(d.map(e=>[e.id,e])).values()];if(p.sort((e,t)=>(a.get(t.id)||0)-(a.get(e.id)||0)||dg(t.a,t.b)-dg(e.a,e.b)||e.id.localeCompare(t.id)),p[0])r.set(e,p[0]);else if(1===e.positionalIds.size){const t=i.get([...e.positionalIds][0]);t&&r.set(e,t)}}const l=new Map;for(const[e,t]of r){const i=l.get(t.id)||[];i.push(e),l.set(t.id,i)}for(const[e,t]of l){const s=i.get(e)||r.get(t[0]);if(!s)throw new ng("duplicate-id",e);const n=[(s.a[0]+s.b[0])/2,(s.a[1]+s.b[1])/2];t.sort((e,t)=>{const i=mg(n,e.a,e.b)<=sg?0:1,o=mg(n,t.a,t.b)<=sg?0:1;if(i!==o)return i-o;return(mg(s.a,e.a,e.b)<=sg?0:1)-(mg(s.a,t.a,t.b)<=sg?0:1)||e.key.localeCompare(t.key)}),t[0].id=e}const c=(e=>{const t=new Set;for(const i of[e.rooms,e.openings,e.decor,e.room_drafts,e.partitions,e.wall_columns])for(const e of Array.isArray(i)?i:[])"string"==typeof e?.id&&e.id&&t.add(e.id);for(const i of Array.isArray(e.room_drafts)?e.room_drafts:[])for(const e of Array.isArray(i?.segments)?i.segments:[])"string"==typeof e?.id&&e.id&&t.add(e.id);return t})(e);for(const e of t)if(e.id){if(c.has(e.id))throw new ng("duplicate-id",e.id);c.add(e.id)}const h=t.filter(e=>!e.id);if(s){const t=h.map(t=>{const[i,s]=hg(t.a,t.b),n=`${String(e.id||"")}|${lg(i)}|${lg(s)}|${[...t.owners].sort().join(",")}`,o=vg(fg(n));return{atom:t,seed:n,digest:o,base:`wall-${o.slice(0,20)}`}}).sort((e,t)=>e.digest.localeCompare(t.digest)||e.atom.key.localeCompare(t.atom.key)),i=new Map;for(const e of t){const t=i.get(e.digest);if(t&&t!==e.seed)throw new ng("duplicate-id",e.digest);i.set(e.digest,e.seed);let s=1,n=e.base;for(;c.has(n);)n=`${e.base}-${++s}`;e.atom.id=n,c.add(n)}}else for(const e of h)e.id=wg(c),c.add(e.id)},Mg=(e,t)=>{if("partition"===e.host?.kind)return null;const i=[Number(e.x),Number(e.y)];if(!i.every(Number.isFinite))return null;const s=t=>{if(!(Number(t.cm)>0))return!1;const s=_g(i,t.a,t.b),n=dg(t.a,t.b),o=Number(e.length)/2;return s>=-sg&&s<=1+sg&&mg(i,t.a,t.b)<=.02*jh&&Bl(t.a,t.b,Number(e.angle))&&Number.isFinite(o)&&o>=0&&s*n-o>=-sg&&s*n+o<=n+sg},n="wall"===e.host?.kind?t.find(t=>t.id===e.host.id):null,o=n&&s(n)?[n]:t.filter(s);if(1!==o.length)return null;const a=o[0];return{kind:"wall",id:a.id,t:Math.max(0,Math.min(1,_g(i,a.a,a.b)))}},Cg=(e,t)=>{const i=[Number(e.x),Number(e.y)];if(!i.every(Number.isFinite))return null;const s=Number(e.length)/2,n=t.filter(t=>{if(!(Number(t.cm)>0))return!1;const n=_g(i,t.a,t.b),o=dg(t.a,t.b);return n>=-sg&&n<=1+sg&&mg(i,t.a,t.b)<=.02*jh&&Bl(t.a,t.b,Number(e.angle))&&Number.isFinite(s)&&s>=0&&n*o-s>=-sg&&n*o+s<=o+sg}),o=(t=>{if(!t.length)return null;const s="wall"===e.host?.kind?t.find(t=>t.id===e.host.id):null;return s||[...t].sort((e,t)=>mg(i,e.a,e.b)-mg(i,t.a,t.b)||Number(t.cm)-Number(e.cm)||(e.idt.id?1:0))[0]})(n);return o?{kind:"wall",id:o.id,t:Math.max(0,Math.min(1,_g(i,o.a,o.b)))}:null},Dg=(e,t,i)=>{const s=kg(e),{atoms:n,rooms:o}=$g(e,s);Sg(e,n,s,t,i);const a=n.map(t=>{const i=t.id?s.get(t.id):void 0,n=((e,t,i)=>{if(t.zeroWall)return 0;const s=Array.isArray(e.walls)?e.walls:[],n=Il(t.a,t.b,jh),o=s.filter(e=>Number(e.cm)>0&&(!(e.key!==n&&!t.parentKeys.has(e.key))||!(!ag(e.a)||!ag(e.b))&&gg(t.a,t.b,e.a,e.b)>=dg(t.a,t.b)-sg)).map(e=>Math.max(1,Math.min(100,Number(e.cm))));if(new Set(o.map(e=>e.toFixed(9))).size>1)throw new ng("thickness-conflict",t.key);if(o.length)return o[0];const a=Hl(s,t.a,t.b,jh,1);return a>0?a:Number(i?.cm)>0?Number(i.cm):0})(e,t,i);return{...i||{},id:t.id,a:[...t.a],b:[...t.b],cm:n}}),r=new Map(n.map(e=>[e.key,e.id]));for(const e of o)e.wall_ids=e.wall_ids.map(e=>r.get(e));e.rooms=o,e.wall_segments=a,e.walls=a.filter(e=>e.cm>0).map(e=>({key:Il(e.a,e.b,jh),cm:e.cm,a:[...e.a],b:[...e.b]})),e.walls.length||delete e.walls,delete e.open_spans;for(const t of e.rooms)delete t.open_to;return((e,t)=>{const i=new Set;for(const t of[e.rooms,e.openings,e.decor,e.room_drafts,e.partitions,e.wall_columns,e.wall_segments])for(const e of Array.isArray(t)?t:[])"string"==typeof e?.id&&e.id&&i.add(e.id);for(const s of Array.isArray(e.room_drafts)?e.room_drafts:[]){const n=Array.isArray(s.segments)?s.segments:[];for(let o=0;o{const s=Array.isArray(e.openings)?e.openings:[];for(const e of s){if("partition"===e.host?.kind)continue;if(!e.host&&!i){const i=Mg(e,t);i&&(e.host=i);continue}const s=Mg(e,t)??(i?Cg(e,t):null);if(s)e.host=s;else{if(!i)throw new ng("opening-host",e.id);delete e.host}}})(e,a,t),a.reduce((e,t)=>e+(s.has(t.id)?0:1),0)};function Pg(e,t={}){const i=JSON.stringify(e),s=og(e);fl(s);let n=0;const o=Number(s?.model_version||0)<9;for(const e of Array.isArray(s?.spaces)?s.spaces:[]){const i=t.lineageSpaceId===String(e?.id||"")?t.lineageHints:void 0;n+=Dg(e,o,i)}return s.model_version=9,fl(s),{config:s,changed:i!==JSON.stringify(s),migratedSegments:n}}const Tg=e=>!!e&&"object"==typeof e&&!Array.isArray(e);function Ig(e,t){const i=(e,t)=>{if(Array.isArray(e)&&Array.isArray(t)){const s=new Map;for(const t of e)Tg(t)&&"string"==typeof t.id&&t.id&&s.set(t.id,t);const n=t.map((t,n)=>{if(Tg(t)&&"string"==typeof t.id&&t.id){const e=s.get(t.id);return e?i(e,t):og(t)}return n[t,t in e?i(e[t],s):og(s)]);for(const t of Object.keys(e))delete e[t];for(const[t,i]of s)e[t]=i;return e}return og(t)};return i(e,t)}const Rg=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),Ag=(e,t,i)=>Math.min(i,Math.max(t,e)),zg=e=>Eh({spaces:[e]})[0],Fg=(e,t,i)=>{const s=i>0?i:1,n=e=>`${(e[0]/s).toFixed(12)},${(e[1]/s).toFixed(12)}`,o=n(e),a=n(t);return o0?a:1,l=Math.max(s*r*.02,1e-9),c=[];for(const t of e||[])for(const e of hi(t)||[])c.push([e[0],e[1]]);const h=[];for(const e of i||[])Array.isArray(e)&&e.length>=4&&e.slice(0,4).every(Number.isFinite)&&h.push([e[0],e[1]],[e[2],e[3]]);const d=(e,t)=>t.some(t=>Math.hypot(e[0]-t[0],e[1]-t[1])<=2*l),p=new Map;for(const a of e||[]){if(!a?.id)continue;const u=yc(e,a.id,t,i,s,n,o,r);if(u)for(let e=0;e0&&_>0&&a===m&&_!==a))continue;const g=u.poly[s],f=u.poly[(s+1)%u.poly.length],v=Math.hypot(f[0]-g[0],f[1]-g[1]);if(!(v>l&&v<.5*o-1e-9*o))continue;if(d(g,h)||d(f,h))continue;if(d(g,c)&&d(f,c))continue;const b=Fg(g,f,r),y=p.get(b);y?y.targets.add(a):p.set(b,{a:[g[0],g[1]],b:[f[0],f[1]],targets:new Set([a])})}}}let u=t.slice();const _=(e,t)=>Math.hypot(e[0]-t[0],e[1]-t[1])<=2*l,m=(e,t)=>{if(!Array.isArray(e.a)||!Array.isArray(e.b)||e.a.length<2||e.b.length<2)return!1;const i=[Number(e.a[0])*r,Number(e.a[1])*r],s=[Number(e.b[0])*r,Number(e.b[1])*r];return!![...i,...s].every(Number.isFinite)&&(_(i,t.a)&&_(s,t.b)||_(i,t.b)&&_(s,t.a))};for(const e of[...p.values()].filter(e=>1===e.targets.size).sort((e,t)=>Fg(e.a,e.b,r).localeCompare(Fg(t.a,t.b,r)))){const t=[...e.targets][0],i=u.filter(t=>m(t,e));if(new Set(i.map(e=>e.cm)).size>1)continue;let n=!1;u=u.map(i=>m(i,e)?(n=!0,i.cm===t?i:{...i,cm:t}):i),n||(u=Ul(u,e.a,e.b,t,s,r))}return u}const Eg=e=>{const t=[];for(const i of e||[]){const e=hi(i);if(e?.length)for(let i=0;i"string"==typeof e?.id?e.id:"").filter(Boolean),h=new Set(c),d=new Map;for(const e of c){const t=tg("space",e);t.layers>0&&eg("space",t.root)&&ig(d,t.root,e)}const p=new Map,u=new Map,_=new Map,m=new Map;for(const e of r){const t="string"==typeof e?.id?e.id:"";if(!t)continue;const i=new Map;for(const s of Array.isArray(e.rooms)?e.rooms:[]){const e="string"==typeof s?.id?s.id:"";if(!e)continue;const n=tg("room",e);n.layers>0&&eg("room",n.root)&&ig(i,n.root,e),u.has(e)||u.set(e,t),_.has(e)||_.set(e,String(s.name||""));const o="string"==typeof s.area?s.area:"";if(o){const i=m.get(o)||[];i.push({spaceId:t,roomId:e}),m.set(o,i)}}p.set(t,i)}const g=new Set(u.keys()),f=new Map,v=new Map;for(const e of l)"string"==typeof e?.id&&e.id&&(!0===e.removed?v.set(e.id,e):f.set(e.id,e));const b={spaceRefsRemapped:0,roomRefsRemapped:0,positionsRemapped:0,markersDetached:0,positionsUnresolved:0,nestedRefsUnresolved:0,deadSpaceIds:[],orphanRoomLabelsRemoved:0,orphanDevicePositionsRemoved:0,orphanGroupPositionsRemoved:0,liveMissingPositionsRemoved:0,removedPositions:[],liveMissingPositions:[],unverifiedPositions:[]},y=new Set,w=e=>h.has(e)?null:(()=>{const t=tg("space",e).root;if(!eg("space",t))return null;const i=d.get(t)||[];return 1===i.length?i[0]:null})(),k=(e,t)=>{const i=tg("room",e).root;if(!eg("room",i))return null;const s=p.get(t)?.get(i)||[];return 1===s.length?s[0]:null},x=e=>{const t=i.effectiveAreaByMarker?.[e]||"",s=t&&m.get(t)||[];return 1===s.length?s[0]:null},$=(e,t,i)=>{if("string"==typeof e.room_id&&e.room_id&&!g.has(e.room_id)){const s=t?k(e.room_id,t):null;s?(e.room_id=s,b.roomRefsRemapped++):i?(e.room_id=i.roomId,b.roomRefsRemapped++):!0!==e.removed&&delete e.room_id}const s=e.vacuum?.segment_map;if(s&&"object"==typeof s&&!Array.isArray(s))for(const e of Object.keys(s)){const i=s[e];if("string"!=typeof i||!i||g.has(i))continue;const n=t?k(i,t):null;n?(s[e]=n,b.roomRefsRemapped++):b.nestedRefsUnresolved++}};for(const e of l){const t="string"==typeof e?.id?e.id:"";if(!t)continue;const i="string"==typeof e.space?e.space:"",s=i&&!h.has(i),o=n[t],a="string"==typeof o?.s?o.s:"",r=a&&!h.has(a),l=!0===e.removed;let c=i&&h.has(i)?i:null,d=null,p=!1;if(s){const s=w(i);s?(e.space=s,c=s,p=!0,b.spaceRefsRemapped++):l||"virtual"===e.binding?l||(delete e.space,c=null,b.markersDetached++):(d=x(t),d?(e.space=d.spaceId,c=d.spaceId,b.spaceRefsRemapped++):(delete e.space,c=null,b.markersDetached++))}l&&!p||$(e,c,d),r&&p&&a===i&&c&&(n[t]={...o,s:c},b.positionsRemapped++,y.add(t))}for(const e of Object.keys(n)){if(y.has(e))continue;const t=n[e],i="string"==typeof t?.s?t.s:"";if(!i||h.has(i))continue;const s=w(i);if(s){if(e.startsWith("rl_")){const i=e.slice(3),o=k(i,s);if(o){const i=`rl_${o}`;Qm(n,i)||(n[i]={...t,s:s}),delete n[e],b.roomRefsRemapped++,b.positionsRemapped++;continue}}n[e]={...t,s:s},b.positionsRemapped++}}const S=i.ownerRoster,M=!0===S?.authoritative,C=new Set(S?.deviceIds||[]),D=new Set(S?.entityIds||[]),P=new Set(Array.isArray(s.settings?.known_devices)?s.settings.known_devices.filter(e=>"string"==typeof e):[]),T=(e,t="")=>{const i=String(S?.names?.[e]||t||"").trim();return i&&i!==e?i:""},I=(e,t,i,s="",n)=>({id:e,spaceId:t,kind:i,name:T(e,s),...n?{reason:n}:{}}),R=e=>{"room_label"===e?b.orphanRoomLabelsRemoved++:"group"===e?b.orphanGroupPositionsRemoved++:b.orphanDevicePositionsRemoved++},A=new Set;for(const[e,t]of Object.entries(n)){const s="string"==typeof t?.s?t.s:"";if(!s||h.has(s))continue;let o,a;const r=f.get(e),l=v.get(e);if(r)o=I(e,s,"device",String(r.name||"")),a="live";else if(l)o=I(e,s,"device",String(l.name||"")),a="absent";else if(e.startsWith("rl_")){const t=e.slice(3);o=I(e,s,"room_label",_.get(t)||""),a=g.has(t)?"live":"absent"}else if(e.startsWith("lg_")){const t=e.slice(3);o=I(e,s,"group"),a=D.has(t)?"live":M?"absent":"unverified","unverified"===a&&(o.reason="registry_unavailable")}else C.has(e)?(o=I(e,s,"device"),a="live"):P.has(e)?(o=I(e,s,"device"),a=M?"absent":"unverified","unverified"===a&&(o.reason="registry_unavailable")):(o=I(e,s,"unknown","","unknown_owner"),a="unverified");if("absent"!==a){if("live"===a){if(b.liveMissingPositions.push(o),!0===i.removeLiveMissingPositions){delete n[e],b.liveMissingPositionsRemoved++,R(o.kind),b.removedPositions.push(o);continue}}else b.unverifiedPositions.push(o);b.positionsUnresolved++,A.add(s)}else delete n[e],R(o.kind),b.removedPositions.push(o)}return b.deadSpaceIds=[...A].sort((e,t)=>e.localeCompare(t)),{config:s,layout:n,report:b,changed:JSON.stringify(s)!==o||JSON.stringify(n)!==a}}(e,t,i),a=o.config,r=_l(a,o.layout);fl(a),gl(o.layout);const l=JSON.stringify(e||{}),c=JSON.stringify(t||{}),h=Number.isInteger(Number(a.model_version))?Number(a.model_version):0,d=(e=>{let t=0,i=0,s=0;for(const i of e.markers||[]){if("ripple"===i.display&&(i.display="icon_ripple",t++),Array.isArray(i.controls)){const e="string"==typeof i.binding&&i.binding.startsWith("entity:")?i.binding.slice(7):"",s=e?i.controls.filter(t=>t!==e):i.controls;JSON.stringify(s)!==JSON.stringify(i.controls)&&(i.controls=s.length?s:null,t++)}const e=i.vacuum;e&&Rg(e,"trail")&&(["never","cleaning","always"].includes(e.trail_mode)||(e.trail_mode=!1===e.trail?"never":"cleaning"),delete e.trail,t++)}for(const n of e.spaces||[]){const e=n.settings;"glow"===e?.fill_mode&&("boolean"!=typeof e.glow_enabled&&(e.glow_enabled=!0),e.fill_mode="none",t++,i++);for(const e of n.rooms||[]){const i=e.settings;"glow"===i?.fill_mode&&("boolean"!=typeof i.glow&&(i.glow=!0),delete i.fill_mode,t++,s++)}if(Rg(n,"segments")&&(delete n.segments,t++),Rg(n,"plan_scale")){const e=Number(n.plan_scale);Number.isFinite(e)&&e>=Ah&&e<=zh&&(Rg(n,"plan_scale_x")||(n.plan_scale_x=e),Rg(n,"plan_scale_y")||(n.plan_scale_y=e),delete n.plan_scale,t++)}const o=Number(n.cell_cm);Rg(n,"cell_cm")&&(!Number.isFinite(o)||o<.1||o>1e3)&&(n.cell_cm=Number.isFinite(o)&&o>0?Ag(o,.1,1e3):5,t++);const a=Number(n.cell_cm),r=Number.isFinite(a)&&a>0?a:5;for(const e of n.wall_columns||[])if("circle"===e.shape)Rg(e,"angle")&&(delete e.angle,t++);else if("square"===e.shape&&Rg(e,"angle")){const i=((Number(e.angle)||0)%90+90)%90;e.angle!==i&&(e.angle=i,t++)}for(const e of n.decor||[]){if(Rg(e,"width")){const i=Number(e.width);(Rg(e,"width_cm")||Number.isFinite(i))&&(Rg(e,"width_cm")||(e.width_cm=Number(Ag(i/Bh*r,.1,100).toFixed(6))),delete e.width,t++)}if("rect"!==e?.kind&&"ellipse"!==e?.kind||!0!==e.fill||(Rg(e,"fill_color")||(e.fill_color=e.color||"#607d8b",t++),Rg(e,"fill_opacity")||(e.fill_opacity=.25,t++)),"text"!==e?.kind)continue;void 0===e.size_cm?(e.size_cm=Number(Ag(ts*is(e)/Bh*r,.1,2e3).toFixed(6)),delete e.scale,delete e.size,t++):(Rg(e,"scale")||Rg(e,"size"))&&(delete e.scale,delete e.size,t++);let i=String(e.text??"");const s=[...i.matchAll(/\{([^{}\r\n]+)\}/g)].some(e=>!!Yi(e[1]));if(!(Rg(e,"entity")||Rg(e,"attr")||Rg(e,"unit")))continue;const n=String(e.unit??"").trim(),o="state"===String(e.attr??"").trim().toLowerCase()?null:e.attr,a=s||n?"":Ji(e.entity,o);if(s||a){if(a){const t=i.indexOf("{}");i=t>=0?i.slice(0,t)+a+i.slice(t+2):`${i}${i?" ":""}${a}`,e.text=i}delete e.entity,delete e.attr,delete e.unit,t++}}}return{total:t,glowSpaces:i,glowRooms:s}})(a);let p=d.total;const u=(_=a.spaces||[],JSON.parse(JSON.stringify(_)));var _;const m=Dm(a.spaces||[],o.layout);let g=0,f=0,v=0,b="";const y=m.spaces.map(e=>{const t=function(e){const t=JSON.parse(JSON.stringify(e||{}));let i=Array.isArray(t.rooms)?t.rooms:[];const s=new Map;for(const e of i){const t=hi(e);if(t)for(let e=0;ee.key.localeCompare(t.key))){let t=null;for(const s of Pa(e,i)){const e=r.get(ba(s.from));if(e&&e!==ba(s.to))continue;const n=Ma(i,s);if(Ca(i,n,s)){t=s,i=n;break}}t?(r.set(ba(t.from),ba(t.to)),n++,a=Math.max(a,Math.hypot(t.to[0]-t.from[0],t.to[1]-t.from[1]))):o++}t.rooms=i;for(const e of t.room_drafts||[]){if(!Array.isArray(e?.points)||e.points.length<2)continue;const t=e.points.map(e=>[...e]),i=t.slice(0,-1).flatMap((i,s)=>{const n=t[s+1],o=fa(i,n);return o?[{key:`${String(e.id||"")}:${s}`,a:[...i],b:[...n],axis:o.axis}]:[]});let s=t;for(const e of i){let t=null;for(const i of Pa(e,[{poly:s}])){const e=s.map(e=>Sa(e,i)),n=e.length>=4&&ya(e[0],e[e.length-1]),o=n?e.slice(0,-1):e;if(n?xa(o):$a(o)){t=i,s=e;break}}t?(n++,a=Math.max(a,Math.hypot(t.to[0]-t.from[0],t.to[1]-t.from[1]))):o++}e.points=s}for(const e of t.partitions||[]){if(!Array.isArray(e?.a)||!Array.isArray(e?.b))continue;const i=fa(e.a,e.b);if(!i)continue;const s={key:String(e.id||wa(e.a,e.b)),a:[...e.a],b:[...e.b],axis:i.axis};let r=null;for(const i of Pa(s,[{poly:[e.a,e.b]}])){const s=Sa(e.a,i),n=Sa(e.b,i),o=Math.hypot(n[0]-s[0],n[1]-s[1]);if(!(o>0))continue;const a=(t.openings||[]).filter(t=>"partition"===t?.host?.kind&&t.host.id===e.id).every(e=>{const t=Number(e.host.t),i=Number(e.length);return Number.isFinite(t)&&t>=0&&t<=1&&Number.isFinite(i)&&i>0&&t*o-i/2>=-1e-12&&t*o+i/2<=o+1e-12});if(a){r=i,e.a=s,e.b=n;break}}r?(n++,a=Math.max(a,Math.hypot(r.to[0]-r.from[0],r.to[1]-r.from[1]))):o++}return{space:t,report:{wallsStraightened:n,wallsStraightenSkipped:o,maxStraightenShift:a},changed:n>0}}(e);g+=t.report.wallsStraightened,f+=t.report.wallsStraightenSkipped;const i=Number(e?.cell_cm)>0?Number(e.cell_cm):5,s=t.report.maxStraightenShift/jh*i;return s>v&&(v=s,b=String(e?.id||"")),t.space}),w=g?Dm(y,m.layout):{...m,spaces:y};a.spaces=w.spaces;const k=g?{...m.report,moved:m.report.moved+w.report.moved,coordsCanonicalized:m.report.coordsCanonicalized+w.report.coordsCanonicalized,maxShift:Math.max(m.report.maxShift,w.report.maxShift),maxShiftCm:Math.max(m.report.maxShiftCm,w.report.maxShiftCm),maxSpace:w.report.maxShiftCm>m.report.maxShiftCm?w.report.maxSpace:m.report.maxSpace,rotated:m.report.rotated+w.report.rotated,removedDrafts:m.report.removedDrafts+w.report.removedDrafts}:{...m.report};let x=0,$=0,S=0,M=0,C=0,D=0,P=0,T=0;for(let e=0;e0===Number(e.cm)),walls:t.walls||[]}),o=zg(t),r=zg(i);if(!o||!r)continue;const l=Eg(o.rooms),c=Eg(r.rooms),h=.02*Bh,d=(t.wall_segments||[]).filter(e=>0===Number(e.cm)).map(e=>({...e,key:Il(e.a,e.b,jh),cm:0})),p=new Set(d.map(e=>e.key)),_=G_(t,o.rooms,Ih,h);$+=_.length;for(const e of _){const t=[e[0]/Ih,e[1]/Ih],i=[e[2]/Ih,e[3]/Ih],s=Il(t,i,jh);p.has(s)||(p.add(s),d.push({key:s,a:t,b:i,cm:0}))}const m=d.length,g=ql(d,l,c,jh,Ih),f=(e,t,i)=>{const s=i[0]-t[0],n=i[1]-t[1],o=s*s+n*n;if(!(o>0))return Math.hypot(e[0]-t[0],e[1]-t[1]);const a=Math.max(0,Math.min(1,((e[0]-t[0])*s+(e[1]-t[1])*n)/o));return Math.hypot(e[0]-(t[0]+s*a),e[1]-(t[1]+n*a))},v=g.filter(e=>{if(!Array.isArray(e.a)||!Array.isArray(e.b))return!1;const t=e.a.map(e=>e*Ih),i=e.b.map(e=>e*Ih);return c.some(([e,s])=>f(t,e,s)<=4*h&&f(i,e,s)<=4*h)});S+=Math.max(0,m-v.length);const b=(i.wall_segments||[]).filter(e=>Number(e.cm)>0);i.wall_segments=[...b,...v.map(({key:e,...t})=>t)];const y=v.map(e=>[e.a[0]*Ih,e.a[1]*Ih,e.b[0]*Ih,e.b[1]*Ih]),w=Array.isArray(t.walls)?t.walls.length:0;let k=ql(t.walls,l,c,jh,Ih);k=Ng(r.rooms,k,y,jh,Number(i.cell_cm)>0?Number(i.cell_cm):5,Bh,Ih),k=xc(r.rooms,k,y,jh,Number(i.cell_cm)>0?Number(i.cell_cm):5,Bh,Ih),k=Ll(k,i.rooms||[],jh,1,y.map(e=>[e[0]/Ih,e[1]/Ih,e[2]/Ih,e[3]/Ih])),x+=Math.max(0,w-k.length),k.length?i.walls=k:delete i.walls;const I=Fm(i.partitions||[],{pitch:jh,geometry:Em(i)});I.merged&&(M+=I.merged,i.partitions=I.partitions,Nm(i.openings,i.partitions,I.openingMoves,{coordScale:Ih,cellCm:Number(i.cell_cm)>0?Number(i.cell_cm):5,gridPitch:Bh}));const R=zg(i);if(R){const e=n(i,R,i.walls||[],y,{pitch:jh,cellCm:Number(i.cell_cm)>0?Number(i.cell_cm):5,gridPitch:Bh,coordScale:Ih});e.partitionsReconciled&&(C+=e.partitionsReconciled,D+=e.openingsRehosted,e.partitions.length?i.partitions=e.partitions:delete i.partitions,e.openings.length?i.openings=e.openings:delete i.openings,e.walls.length?i.walls=e.walls:delete i.walls),e.removedDrafts&&(P+=e.removedDrafts,e.roomDrafts.length?i.room_drafts=e.roomDrafts:delete i.room_drafts)}JSON.stringify({zero:(i.wall_segments||[]).filter(e=>0===Number(e.cm)),walls:i.walls||[]})!==s&&T++}let I=0;h<=9&&(I=function(e){const t=Pg(e);return Ig(e,t.config),{...t,config:e}}(a).migratedSegments);const R=fl(a),A=gl(w.layout),z=JSON.stringify(R)!==l||JSON.stringify(A)!==c;h<9&&z&&(R.model_version=9);const F=JSON.stringify(R)!==l||JSON.stringify(A)!==c,N=Number.isInteger(Number(R.model_version))?Number(R.model_version):h,E=F?k:{...k,moved:0,coordsCanonicalized:0,maxShift:0,maxShiftCm:0,maxSpace:"",rotated:0,removedDrafts:0},O=F?o.report:{...o.report,spaceRefsRemapped:0,roomRefsRemapped:0,positionsRemapped:0,markersDetached:0,orphanRoomLabelsRemoved:0,orphanDevicePositionsRemoved:0,orphanGroupPositionsRemoved:0,liveMissingPositionsRemoved:0};return{config:R,layout:A,report:{...E,modelFrom:h,modelTo:N,migrated:F?p:0,glowSpacesMigrated:F?d.glowSpaces:0,glowRoomsMigrated:F?d.glowRooms:0,canonicalized:F?T:0,wallSegmentsMigrated:F?I:0,legacyZeroWallsMigrated:F?$:0,wallsMerged:F?x:0,spansMerged:F?S:0,partitionsMerged:F?M:0,partitionsReconciled:F?C:0,openingsRehosted:F?D:0,redundantDraftsRemoved:F?P:0,wallsStraightened:F?g:0,wallsStraightenSkipped:f,maxStraightenShiftCm:F?v:0,maxStraightenSpace:F?b:"",latticeCoordinatesCanonicalized:F?r.canonicalized:0,latticeCoordinatesFar:F?r.far:0,latticeMaxShift:F?r.maxShift:0,latticeMaxShiftCm:F?r.maxShiftCm:0,latticeSpaces:F?r.spaces:[],...O},changed:F}}function Hg(e,t,i){const s=(e?.spaces||[]).find(e=>e?.id===i),n=new Set((s?.rooms||[]).map(e=>String(e?.id||"")).filter(Boolean)),o=[...new Set((e?.markers||[]).filter(e=>!0!==e?.removed&&"string"==typeof e?.id).filter(e=>e.space===i||"string"==typeof e.room_id&&n.has(e.room_id)||t?.[e.id]?.s===i).map(e=>e.id))].sort((e,t)=>e.localeCompare(t));return{markerIds:o,count:o.length}}function Lg(e){return e instanceof Error?e.name||"Error":typeof e}function Bg(e){return Gd({id:e?.id??"",cell_cm:e?.cell_cm,rooms:e?.rooms||[],walls:e?.walls||[],wall_segments:e?.wall_segments||[],open_spans:e?.open_spans||[],openings:e?.openings||[],partitions:e?.partitions||[],room_drafts:e?.room_drafts||[],wall_columns:e?.wall_columns||[]})}function jg(e,t,i,s=Bh,n=1e3){return(Array.isArray(e?.openings)?e.openings:[]).flatMap(e=>{const o={...e,rx:Number(e.x)*n,ry:Number(e.y)*n,rlen:Number(e.length)*n};if(!e.host||"wall"===e.host.kind)return[o];const a=tu(e,t.partitions,n,i,s);return a.resolved?[{...e,rx:a.resolved.center[0],ry:a.resolved.center[1],rlen:a.resolved.length,angle:a.resolved.angle,partitionHost:a.resolved}]:[]})}function qg(e,t=()=>!0){return e.flatMap(e=>e.host&&e.partitionHost&&t(e)?[nu(e.partitionHost)]:[])}function Wg(e,t,i,s,n,o,a=Bh,r=1e3){const l=wc(t.rooms,[...i],s,n,o,a,r);return e.flatMap(e=>{const t={x:e.rx,y:e.ry,angle:Number(e.angle)||0,length:e.rlen};return e.host&&"wall"!==e.host.kind?e.partitionHost&&ru(e.partitionHost,l,2e-4*a)?[t]:[]:[t]})}function Ug(e,t){const i=jh,s=Bh,n=Ih,o=Number.isFinite(Number(t.cellCm))&&Number(t.cellCm)>0?Number(t.cellCm):5,a=Array.isArray(e?.walls)?e.walls:[],r=function(e,t,i=Bh,s=1e3){return Hd(t.rooms,e?.open_spans,s,.02*i)}(e,t,s,n),l=function(e,t,i=Bh){if(!t.length)return[];const s=e.filter(e=>e?.id),n=.02*i,o=[];for(let e=0;e{const t=[(e[0]+e[2])/2,(e[1]+e[3])/2];return h.some(e=>Hs(t,e)<4*n)}).map(e=>[...e]);d.length&&o.push({a:a,b:r,segs:d})}return o}(t.rooms,r,s).flatMap(e=>e.segs),c=jg(e,t,o,s,n),h=qg(c),d=_h(t,o,s,2e-4*s,h).all;return{space:t,walls:a,openCuts:l,openings:c,roomOpenings:Wg(c,t,a,l,i,o,s,n),partitionCuts:h,physicalBodies:d,wallKeyPitch:i,cellCm:o,gridPitch:s,coordScale:n}}function Gg(e,t,i){const s="string"==typeof e?.title?e.title.trim():"",n=null==e?.id?"":String(e.id).trim();return{spaceId:n,displayName:s||n||i(t+1)}}function Vg(e,t={}){const i=(t.fingerprint||Gd)(e),s=Array.isArray(e?.spaces)?e.spaces:[],n=t.fallbackSpaceName||(e=>`Space ${e}`),o=t.prepareSpace||Ug,a=t.wallPass||qc,r=t.floorPass||Hc,l=[];for(let i=0;i0||d.physicalBodies.length>0;if(!d.space.rooms.length&&!p){l.push({...h,status:"not-applicable"});continue}let u=null;if(p){try{u=a(d.space.rooms,d.walls,d.openCuts,d.roomOpenings,d.wallKeyPitch,d.cellCm,d.gridPitch,d.coordScale,d.physicalBodies)}catch(e){l.push({...h,status:"failed",reason:"wall-exception",detail:Lg(e)});continue}if(null==u){l.push({...h,status:"failed",reason:"wall-null"});continue}if("degraded-extra"===u.status){l.push({...h,status:"failed",reason:"wall-degraded-extra"});continue}if("failed-core"===u.status){l.push({...h,status:"failed",reason:"wall-failed-core"});continue}t.captureWallGeometry?.(d,u)}if(d.space.rooms.length&&null==u?.paperGeom){let e;try{e=r(d.space.rooms,d.walls,d.openCuts,d.wallKeyPitch,d.cellCm,d.gridPitch,d.coordScale)}catch(e){l.push({...h,status:"failed",reason:"floor-exception",detail:Lg(e)});continue}if(null==e){l.push({...h,status:"failed",reason:"floor-null"});continue}}l.push({...h,status:"ok"})}const c=l.filter(e=>"failed"===e.status);return{fingerprint:i,spaces:l,failures:c,ok:0===c.length}}class Kg{constructor(e=50){this._undo=[],this._redo=[],this._limit=Math.max(30,Math.floor(e))}get canUndo(){return this._undo.length>0}get canRedo(){return this._redo.length>0}get undoName(){return this._undo[this._undo.length-1]?.name??null}get redoName(){return this._redo[this._redo.length-1]?.name??null}get size(){return this._undo.length}push(e){this._undo.push(e),this._undo.length>this._limit&&this._undo.splice(0,this._undo.length-this._limit),this._redo=[]}undo(){const e=this._undo.pop()??null;return e&&this._redo.push(e),e}redo(){const e=this._redo.pop()??null;return e&&this._undo.push(e),e}clear(){this._undo=[],this._redo=[]}}const Yg=new WeakMap;const Jg=(e,t,i)=>255===e[i+3]&&t.every((t,s)=>Math.abs(e[i+s]-t)<=2);async function Xg(e){const t=e.defaultView;if(!t||!t.CSS?.supports?.("mix-blend-mode","screen"))return!1;const i=[128,32,16],s=[16,64,128],n=[9,19,29],o=`\n \n \n \n \n \n `,a=t.URL.createObjectURL(new Blob([o],{type:"image/svg+xml"}));try{const o=await new Promise((e,i)=>{const s=new t.Image,n=t.setTimeout(()=>i(new Error("SVG blend probe timeout")),1e3);s.onload=()=>{t.clearTimeout(n),e(s)},s.onerror=()=>{t.clearTimeout(n),i(new Error("SVG blend probe failed"))},s.src=a}),r=e.createElement("canvas");r.width=4,r.height=1;const l=r.getContext("2d",{willReadFrequently:!0});if(!l)return!1;l.drawImage(o,0,0,4,1);const c=l.getImageData(0,0,4,1).data;return Jg(c,i,0)&&Jg(c,function(e,t){return[0,1,2].map(i=>Math.round(255-(255-e[i])*(255-t[i])/255))}(i,s),4)&&Jg(c,s,8)&&Jg(c,n,12)}catch{return!1}finally{t.URL.revokeObjectURL(a)}}const Zg={now:()=>performance.now(),requestFrame:e=>requestAnimationFrame(e),cancelFrame:e=>cancelAnimationFrame(e)},Qg=e=>Math.max(0,Math.min(1,e)),ef=(e,t,i)=>e+(t-e)*i,tf=(e,t,i)=>{const s=1-e;return 3*s*s*e*t+3*s*e*e*i+e*e*e};function sf(e,t){return{centerX:e.x+e.w/2,centerY:e.y+e.h/2,pixelsPerUnit:t>0&&e.w>0?t/e.w:1,viewBox:{...e}}}function nf(e,t,i){const s=Math.max(1e-9,e.pixelsPerUnit),n=Math.max(1e-9,t/s),o=Math.max(1e-9,i/s);return{x:e.centerX-n/2,y:e.centerY-o/2,w:n,h:o}}function of(e){const t=e.trim(),i=/^rgba?\(\s*([\d.]+)[, ]+([\d.]+)[, ]+([\d.]+)(?:\s*[,/]\s*([\d.]+))?\s*\)$/i.exec(t);if(i)return[Number(i[1]),Number(i[2]),Number(i[3]),null==i[4]?1:Number(i[4])];const s=/^#([0-9a-f]{6}|[0-9a-f]{8})$/i.exec(t)?.[1];return s?[parseInt(s.slice(0,2),16),parseInt(s.slice(2,4),16),parseInt(s.slice(4,6),16),8===s.length?parseInt(s.slice(6,8),16)/255:1]:null}function af(e,t,i){const s=of(e),n=of(t);if(!s||!n)return i<.5?e:t;const o=Qg(i);return`rgba(${Math.round(ef(s[0],n[0],o))}, ${Math.round(ef(s[1],n[1],o))}, ${Math.round(ef(s[2],n[2],o))}, ${ef(s[3],n[3],o).toFixed(3)})`}function rf(e,t,i){const s=(e=>{const t=Qg(e);if(0===t||1===t)return t;let i=0,s=1,n=t;for(let e=0;e<12;e++)n=(i+s)/2,tf(n,.2,.2){const t=this._state;if(!t||t.token!==n)return;const i=Qg((e-t.startedAt)/t.duration);t.presented=i>=1?t.to:rf(t.from,t.to,i),t.phase=i>=1?"settling":"running",this._hooks.frame(t),i<1?this._raf=this._clock.requestFrame(a):(this._raf=0,this._hooks.settled(t),this._state?.token===n&&(this._state=null))};return this._raf=this._clock.requestFrame(a),n}cancel(e=!0){this._raf&&this._clock.cancelFrame(this._raf),this._raf=0;const t=this._state;this._state=null,this._token++,t&&e&&(t.phase="settling",t.presented=t.to,this._hooks.frame(t),this._hooks.settled(t))}dispose(){this.cancel(!1)}}const cf="houseplan_card_labs_v1",hf=Object.freeze([Object.freeze({id:"iso",issue:89,since:"1.62.0",expires:"1.65.0",summary:"Volumetric plan renderer"})]);function df(e){const t=/^(\d+)\.(\d+)\.(\d+)(?:-[0-9A-Za-z.-]+)?$/.exec(String(e||"").trim());if(!t)return null;const i=t.slice(1).map(Number);return i.every(e=>Number.isSafeInteger(e))?i:null}function pf(e,t){for(let i=0;i<3;i++)if(e[i]!==t[i])return e[i]e.split(",")).map(e=>e.trim()).filter(Boolean)}function vf(e,t,i,s=hf){const n=function(e,t=hf){const i=df(e),s=new Map;if(!i||!_f(t))return s;for(const e of t){const t=df(e.since),n=df(e.expires);pf(i,t)>=0&&pf(i,n)<0&&s.set(e.id,e)}return s}(i,s),o=new Set(_f(s)?s.map(e=>e.id):[]),a=new Set(function(e){if(!e)return[];try{const t=JSON.parse(e);return Array.isArray(t)?t.filter(e=>"string"==typeof e):[]}catch{return[]}}(t).filter(e=>n.has(e)));let r=!1;const l=e=>{if("off"===e)return a.clear(),void(r=!0);const t=e.startsWith("-"),i=t?e.slice(1):e;o.has(i)&&(r=!0,t||!n.has(i)?a.delete(i):a.add(i))};for(const t of ff(new URLSearchParams(String(e.search||"").replace(/^\?/,""))))l(t);for(const t of ff(mf(e.hash)))l(t);const c=Object.freeze([...a].sort());return{active:c,space:gf(e.hash),persist:r?JSON.stringify(c):void 0,knownUrlOperation:r}}let bf={active:Object.freeze([]),space:""},yf="",wf=!1,kf="";const xf=new Set;function $f(){if("undefined"==typeof window)return bf;const e=vf(window.location,function(){try{return window.localStorage.getItem(cf)}catch{return null}}(),yf);void 0!==e.persist&&function(e){try{window.localStorage.setItem(cf,e)}catch{}}(e.persist),bf={active:e.active,space:e.space},window.__hpLabs=e.active;for(const e of xf)e(bf);return bf}function Sf(){$f()}function Mf(e){return yf=e,"undefined"==typeof window?bf:(wf||(wf=!0,window.addEventListener("hashchange",Sf),window.addEventListener("popstate",Sf)),$f())}const Cf=Object.freeze({rotDeg:0,tiltDeg:20,xyScale:1,zScale:1,origin:Object.freeze([500,500])});function Df(e){return[e.rotDeg,e.tiltDeg,e.xyScale,e.zScale,e.origin[0],e.origin[1]].every(Number.isFinite)&&Math.abs(e.xyScale)>1e-12&&Math.abs(Math.cos(e.tiltDeg*Math.PI/180))>1e-12}function Pf(e,t,i=Cf){if(!(Df(i)&&Number.isFinite(e[0])&&Number.isFinite(e[1])&&Number.isFinite(t)))throw new Error("invalid isometric projection input");const s=i.rotDeg*Math.PI/180,n=i.tiltDeg*Math.PI/180,o=e[0]-i.origin[0],a=e[1]-i.origin[1],r=(o*Math.cos(s)-a*Math.sin(s))*i.xyScale,l=(o*Math.sin(s)+a*Math.cos(s))*i.xyScale;return[i.origin[0]+r,i.origin[1]+l*Math.cos(n)-t*i.zScale*Math.sin(n)]}function Tf(e,t=Cf){if(!Df(t)||!Number.isFinite(e[0])||!Number.isFinite(e[1]))throw new Error("invalid isometric projection input");const i=t.rotDeg*Math.PI/180,s=t.tiltDeg*Math.PI/180,n=(e[0]-t.origin[0])/t.xyScale,o=(e[1]-t.origin[1])/(t.xyScale*Math.cos(s));return[t.origin[0]+n*Math.cos(i)+o*Math.sin(i),t.origin[1]-n*Math.sin(i)+o*Math.cos(i)]}function If(e=Cf){return`matrix(${function(e=Cf){if(!Df(e))throw new Error("invalid isometric camera");const t=e.rotDeg*Math.PI/180,i=e.tiltDeg*Math.PI/180,s=e.xyScale*Math.cos(t),n=-e.xyScale*Math.sin(t),o=e.xyScale*Math.sin(t)*Math.cos(i),a=e.xyScale*Math.cos(t)*Math.cos(i);return[s,o,n,a,e.origin[0]-s*e.origin[0]-n*e.origin[1],e.origin[1]-o*e.origin[0]-a*e.origin[1]]}(e).map(e=>Number(e.toFixed(12))).join(" ")})`}function Rf(e,t=Cf){const{rect:i,wallHeight:s}=e,n=e.openingHeight??s,o=e.floorDepth??0;if(!(i.w>=0)||!(i.h>=0)||!Number.isFinite(s)||!Number.isFinite(n)||!Number.isFinite(o)||s<0||n<0||o<0)throw new Error("invalid isometric frame");const a=[[i.x,i.y],[i.x+i.w,i.y],[i.x+i.w,i.y+i.h],[i.x,i.y+i.h]],r=Math.max(s,n),l=a.flatMap(e=>[Pf(e,-o,t),Pf(e,r,t)]),c=l.map(e=>e[0]),h=l.map(e=>e[1]),d=Math.min(...c),p=Math.min(...h);return{x:d,y:p,w:Math.max(...c)-d,h:Math.max(...h)-p}}const Af=e=>`${Number(e[0].toFixed(4))} ${Number(e[1].toFixed(4))}`;function zf(e){let t=0;for(let i=0;iArray.isArray(e)&&Number.isFinite(e[0])&&Number.isFinite(e[1])).map(e=>[Number(e[0]),Number(e[1])]),i=t[t.length-1];return t.length>1&&t[0][0]===i[0]&&t[0][1]===i[1]&&t.pop(),t}(e);if(i.length<3)return[];const s=!t;return zf(i)>0===s?i:[...i].reverse()}function Nf(e,t,i){return e.length?`M ${e.map(e=>Af(Pf(e,i,t))).join(" L ")} Z`:""}function Ef(e,t,i){const s=t[1]-e[1],n=-(t[0]-e[0]),o=i.rotDeg*Math.PI/180;return s*Math.sin(o)+n*Math.cos(o)}function Of(e,t,i=Cf){if(!Number.isFinite(t)||t<0)throw new Error("invalid floor edge height");const s=(e||[]).map(e=>(e||[]).map((e,t)=>function(e,t){const i=Ff(e,t);if(!i.length)return i;let s=0;for(let e=1;e0)).filter(e=>e.length>=3&&Math.abs(zf(e))>=1e-9)).filter(e=>e.length&&zf(e[0])>0);s.sort((e,t)=>{const i=e[0][0],s=t[0][0];return i[0]-s[0]||i[1]-s[1]||Math.abs(zf(t[0]))-Math.abs(zf(e[0]))});const n=[],o=[];let a=0;for(let e=0;ee.depth-t.depth||e.component-t.component||e.edge-t.edge),{footprintPath:n.join(" "),sides:o,componentCount:s.length,edgeCount:a}}function Hf(e,t){return e^=Math.round(64*(Number.isFinite(t)?t:0)),Math.imul(e,16777619)>>>0}const Lf=e=>e.every(Number.isFinite);function Bf(e,t,i,s){const n=e[0]*i,o=e[1]*s,a=t*Math.PI/180;return[n*Math.cos(a)-o*Math.sin(a),n*Math.sin(a)+o*Math.cos(a)]}function jf(e,t,i,s,n,o,a){const r=e.flipH?-1:1,l="gate"===e.type?1:e.flipV?-1:1,c=(e.type,e.flipV,e.angle,e.face,{ox:0,oy:0}),h=function(e,t){return[e[0]+t[0],e[1]+t[1]]}([e.x+c.ox,e.y+c.oy],Bf(i,e.angle,r,l));return{leaf:t,hinge:h,closedVector:Bf(s,e.angle,r,l),quarterVector:Bf([-s[1],s[0]],e.angle,r,l),turnDeg:n,bottom:o,top:a}}const qf=e=>`${Number(e[0].toFixed(4))} ${Number(e[1].toFixed(4))}`;function Wf(e,t,i=Cf){const s=Math.max(0,Math.min(1,Number.isFinite(t)?t:0));return e.leaves.map(t=>{const n=function(e,t){const i=e.turnDeg*t*Math.PI/180;return[e.hinge[0]+e.closedVector[0]*Math.cos(i)+e.quarterVector[0]*Math.sin(i),e.hinge[1]+e.closedVector[1]*Math.cos(i)+e.quarterVector[1]*Math.sin(i)]}(t,s),o=Pf(t.hinge,t.bottom,i),a=Pf(n,t.bottom,i),r=Pf(n,t.top,i),l=Pf(t.hinge,t.top,i);return{id:e.id,sourceIndex:e.sourceIndex,type:e.type,leaf:t.leaf,d:`M ${qf(o)} L ${qf(a)} L ${qf(r)} L ${qf(l)} Z`,shadowD:`M ${qf(Pf(t.hinge,0,i))} L ${qf(Pf(n,0,i))}`,depth:Math.max(o[1],a[1])}})}const Uf={window:120,door:90,passage:90,gate:300};function Gf(e){return Uf[e]}function Vf(e,t){const i=[e[0],e[1]],s=[t[0],t[1]];return function(e,t){return e[0]-t[0]||e[1]-t[1]}(i,s)<=0?{a:i,b:s}:{a:s,b:i}}function Kf(e){const t=new Map;return e.forEach((e,i)=>{if(!e.kind||e.open)return;const s=Vf(e.a,e.b);if(Math.hypot(s.b[0]-s.a[0],s.b[1]-s.a[1])<=1e-9)return;const n=function(e,t){const i=e=>(Math.abs(e)<=5e-10?0:Math.round(1e6*e)/1e6).toFixed(6);return`${i(e[0])},${i(e[1])}>${i(t[0])},${i(t[1])}`}(s.a,s.b),o=t.get(n);if(o)return o.physicalHalfWidth=Math.max(o.physicalHalfWidth,e.half||0),o.sourceOrder=Math.min(o.sourceOrder,i),void(e.partitionHost&&(o.partitionHost&&o.partitionHost.id!==e.partitionHost.id?o.ambiguousPartitionHost=!0:o.partitionHost=e.partitionHost));t.set(n,{segmentKey:n,a:s.a,b:s.b,physicalHalfWidth:Math.max(0,e.half||0),sourceOrder:i,...e.partitionHost?{partitionHost:e.partitionHost}:{}})}),[...t.values()]}function Yf(e,t){if(Math.abs(e.distance-t.distance)>1e-9)return e.distance-t.distance;if(Math.abs(e.perpendicular-t.perpendicular)>1e-9)return e.perpendicular-t.perpendicular;return(e.target.segmentKeyt.target.segmentKey?1:0)||e.target.sourceOrder-t.target.sourceOrder}function Jf(e){const t=Kf(e.intervals).map(t=>{const i=function(e,t){const i=t.b[0]-t.a[0],s=t.b[1]-t.a[1],n=Math.hypot(i,s),o=i/n,a=s/n,r=(e[0]-t.a[0])*o+(e[1]-t.a[1])*a,l=Math.max(0,Math.min(n,r)),c=t.a[0]+l*o,h=t.a[1]+l*a;return{along:l,length:n,x:c,y:h,distance:Math.hypot(e[0]-c,e[1]-h),perpendicular:Math.abs((e[0]-t.a[0])*a-(e[1]-t.a[1])*o)}}(e.pointer,t);return{target:t,...i,envelope:Math.max(e.baseTolerance,t.physicalHalfWidth+e.bodyPointerPadding)}}).filter(e=>e.distance<=e.envelope+1e-9).filter(t=>!function(e,t,i,s,n){const o=t.b[0]-t.a[0],a=t.b[1]-t.a[1],r=Math.hypot(o,a);if(!(r>1e-9))return!1;const l=o/r,c=a/r;for(const o of i){if(!o.open&&o.kind)continue;const i=Vf(o.a,o.b),a=i.b[0]-i.a[0],r=i.b[1]-i.a[1],h=Math.hypot(a,r);if(!(h>1e-9))continue;const d=a/h,p=r/h;if(Math.abs(l*p-c*d)>1e-6)continue;if(Math.abs((i.a[0]-t.a[0])*c-(i.a[1]-t.a[1])*l)>n)continue;const u=(e[0]-i.a[0])*d+(e[1]-i.a[1])*p,_=1e-9;if(!(u<=_||u>=h-_)&&Math.abs((e[0]-i.a[0])*p-(e[1]-i.a[1])*d)<=s+1e-9)return!0}return!1}(e.pointer,t.target,e.intervals,t.envelope,Math.max(1e-9,Math.min(e.baseTolerance,.04*e.gridStep)))),i=t.filter(t=>!!t.target.partitionHost&&e.renderedLength+2*t.target.physicalHalfWidth>t.length+1e-9).sort(Yf),s=t.filter(t=>!t.target.partitionHost||e.renderedLength+2*t.target.physicalHalfWidth<=t.length+1e-9).sort(Yf);let n=s[0];if(!n)return{candidate:null,jambBlockedTarget:i[0]?.target||null};const o=s.filter(e=>Math.abs(e.distance-n.distance)<=1e-9&&Math.abs(e.perpendicular-n.perpendicular)<=1e-9),a=o.filter(e=>e.target.partitionHost);if(a.length){if(1!==new Set(a.map(e=>e.target.partitionHost.id)).size||a.some(e=>e.target.ambiguousPartitionHost))return{candidate:null,jambBlockedTarget:null};const e=a[0],t=e.target.b[0]-e.target.a[0],i=e.target.b[1]-e.target.a[1],s=Math.hypot(t,i),r=t/s,l=i/s,c=o.every(t=>{const i=t.target.b[0]-t.target.a[0],s=t.target.b[1]-t.target.a[1],n=Math.hypot(i,s),o=i/n,a=s/n,c=Math.abs(r*a-l*o)<=1e-6,h=Math.abs((t.target.a[0]-e.target.a[0])*l-(t.target.a[1]-e.target.a[1])*r);return c&&h<=1e-9});if(!c)return{candidate:null,jambBlockedTarget:null};n=e}if(n.target.ambiguousPartitionHost)return{candidate:null,jambBlockedTarget:null};const{target:r,length:l}=n,c=r.b[0]-r.a[0],h=r.b[1]-r.a[1],d=c/l,p=h/l,u=r.partitionHost?r.physicalHalfWidth:0,_=Math.min(Math.max(0,e.renderedLength)/2+u,l/2);let m=n.along;const g=Math.max(e.gridStep,1e-9),f=l/2;m=Math.abs(m-f)<=g/2?f:Math.round(m/g)*g,m=Math.max(_,Math.min(l-_,m));const v=r.a[0]+d*m,b=r.a[1]+p*m,y=Math.max(0,e.renderedLength)/2,w=m-y,k=m+y,x=Math.max(0,w),$=Math.max(0,l-k),S=[r.a[0]+d*(w-x/2),r.a[1]+p*(w-x/2)],M=[r.a[0]+d*(k+$/2),r.a[1]+p*(k+$/2)];let C=180*Math.atan2(h,c)/Math.PI;C>=90?C-=180:C<-90&&(C+=180);const D=Math.abs(m-f)<=1e-9;return{candidate:{presetRevision:e.preset.revision,geometryRevision:e.geometryRevision,pointer:[e.pointer[0],e.pointer[1]],type:e.preset.type,lengthCm:e.preset.lengthCm,flipH:e.preset.flipH,flipV:e.preset.flipV,x:v,y:b,angle:C,renderedLength:e.renderedLength,target:r,...r.partitionHost?{host:{...r.partitionHost,t:l>0?m/l:0}}:{},measure:{labels:[{distance:x,midpoint:S},{distance:$,midpoint:M}],guide:D?{x:v,y:b,angle:C}:null}},jambBlockedTarget:null}}function Xf(e,t,i,s,n=1e-6){return e.presetRevision===i&&e.geometryRevision===s&&Math.hypot(e.pointer[0]-t[0],e.pointer[1]-t[1])<=n}const Zf=(e,t)=>e[0]*t[1]-e[1]*t[0],Qf=(e,t)=>e[0]*t[0]+e[1]*t[1],ev=(e,t)=>[e[0]-t[0],e[1]-t[1]],tv=(e,t,i)=>[e[0]+t[0]*i,e[1]+t[1]*i];function iv(e,t,i){return Math.abs(Zf(e,t))<=i}function sv(e,t,i){return Math.abs(Zf(ev(e,t),i))}function nv(e,t,i,s,n){const o=t[0]-e[0],a=t[1]-e[1],r=Math.hypot(o,a);if(!(r>n&&i>0))return[];const l=[o/r,a/r];return function(e,t,i){const s=t.map(([t,i])=>[Math.max(0,Math.min(t,i)),Math.min(e,Math.max(t,i))]).filter(([e,t])=>t>e+i).sort((e,t)=>e[0]-t[0]||e[1]-t[1]),n=[];for(const e of s){const t=n[n.length-1];!t||e[0]>t[1]+i?n.push([...e]):t[1]=Math.max(t[1],e[1])}const o=[];let a=0;for(const[e,t]of n)e>a+i&&o.push([a,e]),a=Math.max(a,t);return e>a+i&&o.push([a,e]),o}(r,s.flatMap(t=>{const s=t.b[0]-t.a[0],o=t.b[1]-t.a[1],a=Math.hypot(s,o);if(!(a>n&&iv(l,[s/a,o/a],1e-6)))return[];if(sv(t.a,e,l)>1.1*Math.max(i,n)||sv(t.b,e,l)>1.1*Math.max(i,n))return[];return[[Qf(ev(t.a,e),l),Qf(ev(t.b,e),l)]]}),n).flatMap(([t,s])=>{const n=Kl({a:tv(e,l,t),b:tv(e,l,s),halfDepth:i});return n?[n]:[]})}function ov(e){const t=e.coordScale??1,i=Math.max(e.epsilon??2e-4*e.gridPitch,1e-9),s=[];for(const i of e.rooms||[]){if(!i?.id)continue;const n=yc(e.rooms,i.id,e.walls,e.openCuts,e.pitch,e.cellCm,e.gridPitch,t);if(!n||n.poly.length<3)continue;const o=lc(n.poly,n.offsets);!o||o.length<3||s.push({roomId:i.id,profile:n,inner:o})}s.sort((e,t)=>e.roomId.localeCompare(t.roomId));const n=(e.roomOpenings||[]).map(e=>{const t=e.angle*Math.PI/180,i=[Math.cos(t),Math.sin(t)],s=Math.max(0,e.length)/2;return{a:tv([e.x,e.y],i,-s),b:tv([e.x,e.y],i,s)}}),o=[];for(const s of Gc(e.rooms,e.walls,e.openCuts,e.pitch,e.cellCm,e.gridPitch,t))for(const e of nv(s.a,s.b,s.depthUnits/2,n,i))o.push({body:e});const a=new Map;for(const t of e.partitionCuts||[]){const e=a.get(t.hostId)||[];e.push(t),a.set(t.hostId,e)}for(const t of e.partitions||[]){const s=Ml(t.cm,e.cellCm,e.gridPitch)/2;for(const e of nv(t.a,t.b,s,a.get(t.id)||[],i))o.push({body:e,partitionId:t.id})}return{rooms:s,boundaries:o,epsilon:i}}function av(e,t,i,s){const n=e.profile.offsets[t];if(!(n>0))return null;const o=function(e,t){const i=e[t],s=e[(t+1)%e.length],n=s[0]-i[0],o=s[1]-i[1],a=Math.hypot(n,o)||1;return function(e){let t=0;for(let i=0;i=0?[-o/a,n/a]:[o/a,-n/a]}(e.profile.poly,t),a=tv(i.center,o,n),r=[];for(let t=0;ts&&iv(i.axis,[l[0]/c,l[1]/c],1e-6)))continue;if(sv(n,a,i.axis)>s||sv(o,a,i.axis)>s)continue;const h=Qf(ev(n,a),i.axis),d=Qf(ev(o,a),i.axis);r.push([Math.min(h,d),Math.max(h,d)])}const l=function(e,t){e.sort((e,t)=>e[0]-t[0]||e[1]-t[1]);const i=[];for(const s of e){const e=i[i.length-1];!e||s[0]>e[1]+t?i.push([...s]):e[1]=Math.max(e[1],s[1])}return i}(r,s).find(([e,t])=>e<=s&&t>=-s);if(!l)return null;const[c,h]=l,d=tv(a,i.axis,-i.half),p=tv(a,i.axis,i.half),u=Math.max(0,-i.half-c),_=Math.max(0,h-i.half),m=u>0?tv(a,i.axis,c):d,g=_>0?tv(a,i.axis,h):p,f=Qf(o,i.normal)>=0?1:-1,v=(t,s,n)=>({from:t,to:s,label:[(t[0]+s[0])/2,(t[1]+s[1])/2],axis:i.axis,labelNormal:o,distance:n,roomId:e.roomId,roomSide:f,source:"room-face"});return{left:v(d,m,u),right:v(p,g,_)}}function rv(e){const t=tv(e.center,e.axis,-e.half),i=tv(e.center,e.axis,e.half),s=tv(e.center,e.axis,Math.min(-e.half,e.targetLo)),n=tv(e.center,e.axis,Math.max(e.half,e.targetHi)),o=(t,i)=>({from:t,to:i,label:[(t[0]+i[0])/2,(t[1]+i[1])/2],axis:e.axis,labelNormal:e.normal,distance:Math.hypot(i[0]-t[0],i[1]-t[1]),source:"host-end"});return[o(t,s),o(i,n)]}function lv(e,t,i,s){const n=ev(i,t),o=Qf(n,n);if(!(o>s*s))return Math.hypot(...ev(e,t))<=s;const a=Qf(ev(e,t),n)/o;if(a<-s||a>1+s)return!1;const r=tv(t,n,Math.max(0,Math.min(1,a)));return Math.hypot(...ev(e,r))<=s}function cv(e,t,i){let s=!1;for(let n=0,o=t.length-1;ne[1]!=c>e[1]&&e[0]<(l-a)*(e[1]-r)/(c-r)+a&&(s=!s)}return s}function hv(e,t,i,s,n,o){const a=ev(s,i),r=Zf(t,a);if(Math.abs(r)<=o)return null;const l=ev(i,e),c=Zf(l,a)/r,h=Zf(l,t)/r;return c<-o||c>n+o||h<-o||h>1+o?null:Math.max(0,Math.min(n,c))}function dv(e,t,i){const s=rv(i),n="partition"===e.host?.kind?e.host.id:void 0;return[{base:s[0],direction:[-i.axis[0],-i.axis[1]]},{base:s[1],direction:i.axis}].map(({base:e,direction:i})=>{const s=e.distance,o=function(e,t,i,s,n,o){let a=null;for(const r of s)if(!n||r.partitionId!==n){if(cv(e,r.body,o))return 0;for(let s=0;sQf(ev(e,n),i));return{center:n,axis:i,normal:s,half:Math.max(0,e.renderedLength)/2,targetLo:Math.min(...o),targetHi:Math.max(...o)}}(e),s=t.rooms.flatMap(e=>{const s=function(e,t,i){const{profile:s}=e;let n=null;for(let e=0;e0))continue;const o=s.poly[e],a=s.poly[(e+1)%s.poly.length],r=ev(a,o),l=Math.hypot(r[0],r[1]);if(!(l>i&&iv(t.axis,[r[0]/l,r[1]/l],1e-6)))continue;if(sv(o,t.center,t.axis)>i||sv(a,t.center,t.axis)>i)continue;const c=Qf(ev(o,t.center),t.axis),h=Qf(ev(a,t.center),t.axis),d=Math.min(c,h),p=Math.max(c,h);if(d>-t.half+i||p0?d:p<0?-p:0);(!n||u2)return rv(i);if(s.length){const e=s.map(({room:e,edge:s})=>av(e,s,i,t.epsilon));if(e.some(e=>!e))return rv(i);const n=e;return[...n.map(e=>e.left),...n.map(e=>e.right)]}return dv(e,t,i)}function uv(e){return!(!e.canEdit||e.kiosk||e.fixedFloor)&&("view"!==e.mode&&("mouse"===e.pointerType&&e.spaceCount>1))}const _v="1.68.1",mv={badge:"display.badge",icon_ripple:"display.icon_ripple",value:"display.value",static_icon:"display.static_icon"},gv={badge:"marker.display_hint_badge",icon_ripple:"marker.display_hint_icon_ripple",value:"marker.display_hint_value",static_icon:"marker.display_hint_static_icon"},fv=2e3,vv=1e3,bv=1500,yv=e=>{const t=String(e??"").trim().replace(",",".");if(!/^[+-]?(?:\d+(?:\.\d*)?|\.\d+)$/.test(t))return null;const i=Number(t);return Number.isFinite(i)?i:null},wv=(e,t)=>{if(!e.has(t))return{hit:!1};const i=e.get(t);return e.delete(t),e.set(t,i),{hit:!0,value:i}},kv=(e,t,i,s)=>{for(e.delete(t),e.set(t,i);e.size>s;){const t=e.keys().next().value;if(void 0===t)break;e.delete(t)}},xv=new Map;let $v=0;const Sv=e=>`${window.innerWidth}x${window.innerHeight}|${location.pathname}|${JSON.stringify(e??{})}`;let Mv=1e4;const Cv="houseplan_card_layout_v1",Dv="houseplan_card_cfg_v1",Pv="houseplan_card_zoom_v1",Tv="houseplan_card_nav_v1",Iv="houseplan_card_kiosk_v1",Rv="houseplan_card_view_v1",Av="hp-dialog, hp-help, hp-color-opacity, hp-device-preview",zv=1e3,Fv=[[0,1],[45,.88],[70,.62],[86,.32],[100,0]],Nv=(e,t)=>{const i=Math.min(e.x,t.x),s=Math.min(e.y,t.y);return{x:i,y:s,w:Math.max(e.x+e.w,t.x+t.w)-i,h:Math.max(e.y+e.h,t.y+t.h)-s}},Ev=new Set(["select","draw","column","merge","split","resize","opening","wallthick","delroom"]),Ov=2e3,Hv=(e,t,i)=>{const s=new Event(t,{bubbles:!0,composed:!0});s.detail=i??{},e.dispatchEvent(s)},Lv=e=>{history.pushState(null,"",e),Hv(window,"location-changed",{replace:!1})},Bv=(e,t)=>{let i,s=null;const n=(...n)=>{clearTimeout(i),s=n,i=window.setTimeout(()=>{i=void 0;const t=s;s=null,t&&e(...t)},t)};return n.flush=()=>{if(void 0===i)return;clearTimeout(i),i=void 0;const t=s;s=null,t&&e(...t)},n.cancel=()=>{clearTimeout(i),i=void 0,s=null},n.pending=()=>void 0!==i,n},jv=e=>{try{e.target?.setPointerCapture?.(e.pointerId)}catch{}};class qv extends he{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._cfgContentFingerprint="",this._unsubCfg=null,this._unsubLayout=null,this._unsubVirtual=null,this._liveSyncAttempt=null,this._liveSyncGeneration=0,this._liveSyncConnection=null,this._layoutRev=0,this._layoutContentFingerprint="",this._virtualLights=mn(null),this._canOptimizeUndo=!1,this._undoKind=null,this._devices=[],this._regSignature="",this._defPos={},this._newSyncKey="",this._tip=null,this._hoverRoom=null,this._pointerModality=new _m(this,()=>this._syncPointerHoverTargets()),this._devicePressAnimations=new Map,this._selId=null,this._toast="",this._mode="view",this._pendingNavMode=null,this._decorTool="select",this._decorStyle={...Br},this._decorDraft=null,this._decorMove=null,this._decorSel=null,this._decorEraseConfirm=null,this._decorTextDialog=null,this._decorShapeDialog=null,this._backdropDialog=null,this._decorTextSelection={start:0,end:0},this._furnPalette=null,this._dtBox=null,this._dtDrag=null,this._bdDrag=null,this._slide="",this._reducedMotion=!1,this._onMotionChange=e=>{this._reducedMotion=e.matches,this._cancelDevicePressFeedback(),e.matches&&this._modeTransitionPreparing?this._modeTransitionForceAtomic=!0:e.matches&&this._modeTransition.active&&this._cancelModeTransition(!0),this.requestUpdate()},this._editorChromeMode="plan",this._modeTransitionVisual=null,this._modeTransitionPreparing=!1,this._modeTransitionForceAtomic=!1,this._modeTransitionRequest=0,this._modeTransitionTargetZoom=1,this._modeTransitionEditorCamera=null,this._modeTransition=new lf({frame:e=>this._applyModeTransitionFrame(e),settled:e=>this._settleModeTransition(e)}),this._editorSecondary=new ym({root:()=>this.renderRoot,requestUpdate:()=>this.requestUpdate(),updateComplete:()=>this.updateComplete,clearTip:()=>{this._tip=null}}),this._editorSecondaryCopy={groupActive:(e,t)=>this._t("editor.group_active",{group:e,item:t}),openGroup:e=>this._t("editor.open_group",{group:e}),disabledAction:(e,t)=>this._t("editor.disabled_action",{action:e,reason:t})},this._tool="draw",this._geometryHistory=new Kg(50),this._wallDialog=null,this._drawWallField=null,this._activeDraftId=null,this._resumeDraftBySpace={},this._physicalSel=null,this._physicalDialog=null,this._partitionDeleteDialog=null,this._roomDeleteDialog=null,this._physicalDrag=null,this._physicalRotate=null,this._physicalLastTap=null,this._physicalPickCycle=null,this._wallUnionCacheValue=null,this._wallUnionPool=new Map,this._isoGeometryCache=new Map,this._isoFallback=new Set,this._openingTunnelCache=null,this._openingWallIndexCache=new Map,this._openingPlacementIntervalsCache=null,this._openingDimensionContextCache=null,this._planSnapGeometryCache=null,this._planStructuralGeometryCache=null,this._hiddenWallDiagnosticCache=null,this._physicalBodiesCache=null,this._lightPhysicalBodiesCache=null,this._cleanFloorCache=new Map,this._innerContourCache=new Map,this._glowClipCache=new Map,this._glowGeometryWarnings=new Set,this._lightBarrierCache=null,this._lightBarrierPool=new Map,this._glowFeatherUnits=null,this._glowRenderedSources=new Map,this._glowLastAppearance=new Map,this._glowEnteringSources=new Set,this._glowEnterRafs=new Map,this._glowFadeTimers=new Map,this._glowFeatherSuspendUntil=0,this._glowFeatherResumeTimer=0,this._glowSourceSeq=0,this._glowScreenBlend=!1,this._duplicateColumnId=null,this._duplicateColumnTimer=0,this._resize=new pr,this._rszLimitViolation=null,this._path=[],this._cursorPt=null,this._planSnapHover=null,this._mergeSel=null,this._openingPreset=null,this._openingRebindId=null,this._openingPresetRevision=0,this._openingHoverCandidate=null,this._openingJambBlockCm=null,this._openingDialog=null,this._openingInfo=null,this._opDrag=null,this._opMeasure=null,this._mergeDialog=null,this._splitSel=null,this._pendingSplit=null,this._wallFaceBatch=null,this._wallRepairDiagnostic=null,this._wallFaceGraphCache=[],this._areaSel="",this._nameSel="",this._roomDialog=!1,this._roomEditId=null,this._roomFill="",this._roomCustomFill=null,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._touchContacts=new Map,this._touchSequenceMultitouch=!1,this._touchClickBlockUntil=0,this._connectedPath="",this._routeDepartureHandled=!1,this._onLocationChanged=()=>{this._connectedPath&&location.pathname!==this._connectedPath?this._leaveCardRoute():location.pathname===this._connectedPath&&(this._routeDepartureHandled=!1)},this._touchGestureGuard={capture:!0,handleEvent:e=>this._guardTouchGesture(e)},this._hdrH=118,this._booting=!0,this._bootFading=!1,this._bootSettling=!1,this._bootSettleRaf=0,this._bootLastH=-1,this._bootStart=0,this._bootLastChange=0,this._bootSoft=!1,this._tapConfirm=null,this._onboardingShown=!1,this._rulesDialog=null,this._preflightClipboardFallback=null,this._haIntegrationVersion=null,this._alignDialog=null,this._settingsDialog=null,this._backupExportDialog=null,this._backupImportDialog=null,this._sunRaysCache=null,this._dayCycleTimer=0,this._dayCycleClockKey="",this._compassDrag=!1,this._importDialog=null,this._importQueue=[],this._importTotal=0,this._rulesCompiledSrc="",this._infoCard=null,this._nativeMoreInfoEntity=null,this._deviceInbox=null,this._deviceInboxReturn=null,this._deviceInboxMemo=null,this._markerDialog=null,this._spaceDialog=null,this._keyHandler=e=>this._onKey(e),this._warmVp=null,this._warmVpArmed=!1,this._warmLongReturn=!1,this._warmRevivePending=!1,this._warmGen=++$v,this._warmKey=null,this._warmSlot=null,this._hashApplied=!1,this._navApplied=!1,this._labs={active:Object.freeze([]),space:""},this._viewPreference={},this._renderProjection="flat",this._kioskScale={icon:1,font:1},this._kioskDialog=!1,this._activityRt=new Map,this._vacRt=new Map,this._vacViewKey="",this._vacLastView=null,this._vacRaf=0,this._vacSrvTrails={},this._vacJumpOnce=!1,this._continuity=this._newContinuityController(),this._continuityHistory=[],this._continuityEpoch=0,this._continuityDataReady=!0,this._continuityPaintToken=-1,this._continuityDisposed=!1,this._renderSnapshotAt=Date.now(),this._hassSequence=0,this._visibleDeviceSnapshot=null,this._candidateDeviceSnapshot=null,this._stagedDeviceSnapshotToken=-1,this._capturedSnapshotSequence=-1,this._capturedSnapshotDevices=null,this._capturedSnapshotLayout=null,this._capturedSnapshotActivity="",this._capturedSnapshotConfigEpoch=-1,this._capturedSnapshotVirtual="",this._lastValidStageSize=null,this._pendingRefitSize=null,this._refitRaf=0,this._pageVisibility=e=>{if(this._continuity.visibility(e),this._dayCycleVisibility(e),"hidden"===e.kind)return this._clearTransientHover(!0),this._cancelDevicePressFeedback(),void(this._modeTransitionPreparing?this._modeTransitionForceAtomic=!0:this._cancelModeTransition(!0));if(this._vacJumpOnce=!0,!e.long){const e=Date.now();let t=!1;for(const i of this._activityRt.values())!i.flashKind||(i.expiresAt||i.flashTs+cm)>e||(i.flashTs=0,i.flashKind=null,i.expiresAt=0,t=!0);return void(t&&this.requestUpdate())}Date.now()-this._renderSnapshotAt>1e3&&this._continuity.note("device-snapshot-stale"),this._continuityDataReady=!1,this._continuityPaintToken=-1,this._resumeSettling=!0,this._loading?this.requestUpdate():this._loadFromServer()},this._resumeSettling=!1,this._viewportInvalidAt=0,this._vacFit=null,this._vacAllCamerasFor=null,this._vacAllCameraCache=null,this._vacCalConfirm=null,this._kioskDots=!1,this._cyclePausedUntil=0,this._swipeStart=null,this._tabDrag=null,this._tabDragRelease=null,this._tabSuppressClick=!1,this._tabOrderWarned=!1,this._lastTap=0,this._onLabsSnapshot=e=>{const t=this._effectiveProjection();this._labs=e;const i=this._effectiveProjection();this._convertProjectionView(t,i),this.requestUpdate()},this._onHashChange=()=>{if(this._hasFixedFloor)return;const e=this._hashSpace();if(e&&this._model.find(t=>t.id===e)&&e!==this._space){if(this._wallFaceBatch&&this._roomDialogCancel(),"plan"===this._mode&&"draw"===this._tool&&!this._finishWallChain())return;this._activeDraftId&&(this._resumeDraftBySpace[this._space]=this._activeDraftId),this._commitSpace(e),this._selId=null,this._path=[],this._clearPlanSnapHover(),this._clearOpeningPlacement(!0),this._tool="draw",this._activeDraftId=null,this._draftSegmentCms=[],this._closingWallCm=null,"plan"===this._mode&&"draw"===this._tool&&this._resumeLastDraft(),this._restoreZoom(),this.requestUpdate()}},this._drag=null,this._rlResize=null,this._holdFired=!1,this._retryContinuity=()=>{this._continuityDataReady=!1,this._continuityPaintToken=-1,this._continuity.retry(this._continuity.recoveryReason||"plan"),this._loading||this._loadFromServer()},this._cfgEpoch=0,this._modelCache=null,this._emptySpaceStateActive=!1,this._decorSnapCache=null,this._markerPreviewMemo=null,this._markerPreviewDevicesMemo=null,this._showHidden=!1,this._connHooked=null,this._connectionWasLost=!1,this._haRegistryConnection=null,this._haRegistryRev=-1,this._haBindingCacheKey="",this._planHassMemo=null,this._onHaRegistryUpdate=()=>{const e=An(this.hass);e.revision===this._haRegistryRev&&this._devices.length||(this._haRegistryRev=e.revision,this._planHassMemo=null,this._regSignature="",this._maybeRebuildDevices(),this.requestUpdate())},this._onConnReady=()=>{if(this._loadTries=0,clearTimeout(this._loadRetryTimer),this._loadRetryTimer=void 0,function(e){const t=Cn(e);t&&(Tn(e,t),In(e,t))}(this.hass),this._saveConfigDebounced.pending()&&this._saveConfigDebounced.flush(),this._cfgWriting)return clearTimeout(this._reloadRetry),void(this._reloadRetry=window.setTimeout(this._onConnReady,400));!this._connectionWasLost&&this._continuity.hasCompleteFrame?this._beginContinuityCandidate("connection-ready",!1,"plan"):(this._continuityDataReady=!1,this._continuityPaintToken=-1),this._loading||this._loadFromServer()},this._onConnLost=()=>{this._booting&&!this._continuity.hasCompleteFrame||(this._connectionWasLost=!0,this._continuityDataReady=!1,this._continuityPaintToken=-1,this._continuity.connectionLost())},this._signer=new Yd(()=>this.requestUpdate()),this._dirtyPos=new Set,this._sentPos=new Map,this._persistLayout=Bv(()=>{if(this._serverStorage){const e=[...this._dirtyPos];this._dirtyPos.clear();for(const t of e){const e=ml(this._layout[t]);e&&(this._layout={...this._layout,[t]:e},this._sentPos.set(t,e),this.hass.callWS({type:"houseplan/layout/update",device_id:t,pos:e}).then(e=>this._noteLayoutRev(e)).catch(e=>this._showToast(this._t("toast.pos_save_failed",{err:this._errText(e)}))).finally(()=>{this._sentPos.get(t)===e&&this._sentPos.delete(t)}))}this._cacheSnapshot()}else this._layout=gl(il(this._layout)),localStorage.setItem(Cv,JSON.stringify(this._layout))},600),this._frame=null,this._showFar=!1,this._writesPending=0,this._writeChain=Promise.resolve(),this._pendingPhysicalWrites=new Map,this._undoGeometry=()=>{if(this._physicalDrag||this._physicalRotate)return void this._cancelPhysicalGesture();if(this._decorDraft)return this._decorDraft=null,void this.requestUpdate();if(this._decorMove||this._dtDrag||this._bdDrag)return void this._cancelDecorGesture();if(this._resize.dragging)return void this._rszCancelDrag();const e=this._geometryHistory.undo();e&&(this._applyGeometryState(e.before,!0)?this._showToast(this._t("history.undone",{name:e.name})):this._geometryHistory.clear())},this._redoGeometry=()=>{if(this._physicalDrag||this._physicalRotate)return void this._cancelPhysicalGesture();if(this._decorDraft)return this._decorDraft=null,void this.requestUpdate();if(this._decorMove||this._dtDrag||this._bdDrag)return void this._cancelDecorGesture();if(this._resize.dragging)return void this._rszCancelDrag();const e=this._geometryHistory.redo();e&&(this._applyGeometryState(e.after,!0)?this._showToast(this._t("history.redone",{name:e.name})):this._geometryHistory.clear())},this._saveConfigDebounced=Bv(()=>{this._serverCfg&&this._writeConfig().catch(e=>{const t=!0===e?.physicalGeometryRolledBack;"geometry-unsafe"!==e?.code&&("wall_model_client_outdated"===e?.code?this._showToast(this._t("toast.wall_model_client_outdated")):"conflict"===e?.code?(this._showToast(this._t("toast.conflict")),t||(this._cancelPath(),this._reloadConfigOnly(!0))):this._showToast(this._t("toast.cfg_save_failed",{err:this._errText(e)})),t&&this._reloadRejectedPhysicalWrite())})},500),this._draftSegmentCms=[],this._closingWallCm=null,this._savePhysicalDialog=()=>{const e=this._physicalDialog,t=this._curSpaceCfg,i=this._spaceModel();if(!e||!t||!i)return;const s=yv(e.cm);if(null==s)return void this._showPhysicalRange("column"===e.kind?ih:100,"column"===e.kind?1:0);const n=this._imperial?2.54*s:s,o="column"===e.kind?ih:100,a="column"===e.kind?1:0;if(!Number.isFinite(n)||no)return void this._showPhysicalRange(o,a);if("column"===e.kind){const t=i.wall_columns.find(t=>t.id===e.id);if(!t)return;const s=yv(e.angle||"0");if("circle"!==e.shape&&(null==s||s<0||s>=90))return void this._showToast(this._t("toast.physical_angle"));const o="circle"===e.shape?{id:e.id,shape:"circle",center:t.center,cm:n}:{id:e.id,shape:"square",center:t.center,cm:n,angle:s};if(i.wall_columns.some(t=>t.id!==e.id&&Sh(t,o,.02*this._gridPitch)))return void this._showToast(this._t("toast.column_duplicate"))}const r=this._geometrySnapshot();if("partition"===e.kind){const i=(t.partitions||[]).find(t=>t.id===e.id);if(i&&0===n&&K_(t.openings,{kind:"partition",id:e.id}))return void this._showToast(this._t("toast.zero_wall_opening_conflict"));i&&(i.cm=n)}else if("column"===e.kind){const i=(t.wall_columns||[]).find(t=>t.id===e.id);i&&(i.cm=nh(n),i.shape="circle"===e.shape?"circle":"square","square"===i.shape?i.angle=yv(e.angle||"0"):delete i.angle)}else{const i=(t.room_drafts||[]).find(t=>t.id===e.id);i?.segments?.[e.segment||0]&&(i.segments[e.segment||0].cm=n)}const l=this._commitPhysicalGeometry(this._t("history.physical_edit"),r);this._physicalDialog=null,l||this.requestUpdate()},this._deletePhysicalSelection=()=>{const e=this._physicalSel,t=this._curSpaceCfg;if(!e||!t)return;if("draft"===e.kind)return void this._deleteDraftWhole();const i=this._geometrySnapshot();if("partition"===e.kind){const i=(t.openings||[]).filter(t=>"partition"===t.host?.kind&&t.host.id===e.id).sort((e,t)=>(e.host?.t||0)-(t.host?.t||0));if(i.length)return void(this._partitionDeleteDialog={id:e.id,openings:i.map(e=>JSON.parse(JSON.stringify(e)))})}const s="partition"===e.kind?"partitions":"column"===e.kind?"wall_columns":"room_drafts";t[s]=(t[s]||[]).filter(t=>t.id!==e.id),t[s].length||delete t[s],this._activeDraftId===e.id&&this._cancelPath(),this._physicalSel=null,this._physicalDialog=null,this._commitPhysicalGeometry(this._t("history.physical_delete"),i)},this._confirmPartitionDelete=()=>{const e=this._partitionDeleteDialog,t=this._curSpaceCfg;if(!e||!t)return;const i=this._geometrySnapshot();t.partitions=(t.partitions||[]).filter(t=>t.id!==e.id),t.partitions.length||delete t.partitions,t.openings=(t.openings||[]).filter(t=>"partition"!==t.host?.kind||t.host.id!==e.id),t.openings.length||delete t.openings,this._partitionDeleteDialog=null,this._physicalSel=null,this._physicalDialog=null,this._commitPhysicalGeometry(this._t("history.physical_delete"),i)},this._deleteDraftWhole=()=>{const e="draft"===this._physicalDialog?.kind?this._physicalDialog.id:"draft"===this._physicalSel?.kind?this._physicalSel.id:null,t=this._curSpaceCfg;if(!e||!t||!confirm(this._t("confirm.delete_draft")))return;const i=this._geometrySnapshot();t.room_drafts=(t.room_drafts||[]).filter(t=>t.id!==e),t.room_drafts.length||delete t.room_drafts,this._activeDraftId===e&&this._cancelPath(),this._physicalSel=null,this._physicalDialog=null,this._commitPhysicalGeometry(this._t("history.physical_delete"),i)},this._deleteDraftSegment=()=>{const e=this._physicalDialog,t=this._curSpaceCfg;if(!e||"draft"!==e.kind||!t)return;if(!confirm(this._t("confirm.delete_draft_segment")))return;const i=(t.room_drafts||[]).findIndex(t=>t.id===e.id);if(i<0)return;const s=t.room_drafts[i],n=Math.max(0,Math.min(s.segments.length-1,e.segment||0)),o=[],a=s.points.slice(0,n+1),r=s.points.slice(n+1);if(a.length>=2&&o.push({id:s.id,points:a,segments:s.segments.slice(0,n)}),r.length>=2&&o.push({id:o.length?`${s.id}-${Date.now().toString(36)}`:s.id,points:r,segments:s.segments.slice(n+1)}),2===o.length&&t.room_drafts.length>=200)return void this._showToast(this._t("toast.physical_limit"));const l=this._geometrySnapshot();t.room_drafts.splice(i,1,...o),t.room_drafts.length||delete t.room_drafts,this._activeDraftId===s.id&&this._cancelPath(),this._physicalDialog=null,this._physicalSel=o.length?{kind:"draft",id:o[0].id}:null,this._commitPhysicalGeometry(this._t("history.draft_segment_delete"),l)},this._confirmRoomDelete=e=>{const t=this._roomDeleteDialog,i=this._curSpaceCfg,s=this._spaceModel();if(!t||!i||!s)return;const n=s.rooms.find(e=>e.id===t.roomId);if(!n)return void(this._roomDeleteDialog=null);const o=this._openCuts(),a=e_(wc(s.rooms,this._spaceWalls,o,this._wallKeyPitch,this._cellCm,this._gridPitch,zv).filter(e=>e.roomId===n.id),s.partitions,this._openingsR.map(e=>({...e,x:e.rx,y:e.ry})),.02*this._gridPitch),r=new Set(a.materialize.filter(e=>!e.reusePartitionId).map(e=>e.interval.key)).size;if(e&&(i.partitions||[]).length+r>Ov)return void this._showToast(this._t("toast.physical_limit"));const l=this._geometrySnapshot(),c=kc(s.rooms,this._spaceWalls,o,this._wallKeyPitch,this._cellCm,this._gridPitch,zv);if(e){i.partitions||=[];const e=new Map,t=new Map,s=e=>{const t=(i.wall_segments||[]).find(t=>{const i=[Number(t.a?.[0])*zv,Number(t.a?.[1])*zv],s=[Number(t.b?.[0])*zv,Number(t.b?.[1])*zv];return this._samePt(e.a,i)&&this._samePt(e.b,s)||this._samePt(e.a,s)&&this._samePt(e.b,i)});return"string"==typeof t?.id&&t.id?t.id:null},n=Date.now().toString(36);for(const o of a.materialize){let a=o.reusePartitionId?i.partitions.find(e=>e.id===o.reusePartitionId):t.get(o.interval.key);a||(a={id:s(o.interval)||`partition-room-${n}-${t.size}`,a:[o.interval.a[0]/zv,o.interval.a[1]/zv],b:[o.interval.b[0]/zv,o.interval.b[1]/zv],cm:o.interval.cm},i.partitions.push(a),t.set(o.interval.key,a)),e.set(o.interval.key,a)}for(const t of i.openings||[]){const i=a.openingIntervals.get(t.id),s=i?e.get(i):null,n=this._openingsR.find(e=>e.id===t.id);if(!s||!n)continue;const o={a:[s.a[0]*zv,s.a[1]*zv],b:[s.b[0]*zv,s.b[1]*zv]};t.host={kind:"partition",id:s.id,t:t_([n.rx,n.ry],o)}}}else if(a.removeOpeningIds.length){const e=new Set(a.removeOpeningIds);i.openings=(i.openings||[]).filter(t=>!e.has(t.id)),i.openings.length||delete i.openings}i.rooms=i.rooms.filter(e=>e.id!==n.id),this._cfgEpoch++;const h=this._normalizeWalls(c,this._openCuts());h.length?i.walls=h:delete i.walls,this._roomDeleteDialog=null,this._commitPhysicalGeometry(this._t(e?"history.delete_room_keep_walls":"history.delete_room_with_walls"),l),this._regSignature="",this._maybeRebuildDevices(),this.requestUpdate()},this._rebindPartitionOpening=()=>{const e=this._openingDialog;if(!e?.id)return;const t=e.id;this._activateMarkupTool("opening"),"opening"===this._tool&&(this._openingRebindId=t,this._openingPreset={type:e.type,lengthCm:e.lengthCm,flipH:e.flipH,flipV:e.flipV,revision:++this._openingPresetRevision},this._openingDialog=null,this._openingHoverCandidate=null)},this._keepClosedAsPartitions=()=>{if(this._wallFaceBatch)return void this._decideWallFace(!1);if(!this._contourClosed||this._pendingSplit||!this._curSpaceCfg)return;const e=this._curSpaceCfg,t=this._path.slice(0,-1);if((e.partitions||[]).length+t.length>Ov)return void this._showToast(this._t("toast.physical_limit"));const i=this._geometrySnapshot(),s=Cu(t.length,[...this._draftSegmentCms,this._closingWallCm??void 0],this._drawWallCm,vl);e.partitions||=[];const n=Date.now().toString(36),o=this._activeDraftId?(e.room_drafts||[]).find(e=>e.id===this._activeDraftId):null,a=this._draftSegmentsForPath(this._path,o,s);for(let i=0;ie.id!==this._activeDraftId),e.room_drafts.length||delete e.room_drafts),this._commitPhysicalGeometry(this._t("history.contour_to_partitions"),i),this._roomDialog=!1,this._path=[],delete this._resumeDraftBySpace[this._space],this._activeDraftId=null,this._draftSegmentCms=[],this._closingWallCm=null},this._toggleServerPlans=async()=>{const e=this._spaceDialog;if(e)if(e.pickSaved)this._spaceDialog={...e,pickSaved:!1};else{this._spaceDialog={...e,pickSaved:!0,savedBusy:!0};try{const e=await this.hass.callWS({type:"houseplan/plans/list"}),t=this._spaceDialog;t&&(this._spaceDialog={...t,saved:e?.plans||[],savedBusy:!1})}catch(e){const t=this._spaceDialog;t&&(this._spaceDialog={...t,saved:[],savedBusy:!1}),this._showToast(this._t("toast.plans_list_failed",{err:this._errText(e)}))}}},this._aspectJob=null,this._dayCycleTick=()=>{if(!this.isConnected||"hidden"===this.ownerDocument.visibilityState)return;const e=this._dayCycleState();if(!e)return this._dayCycleTimer&&(clearInterval(this._dayCycleTimer),this._dayCycleTimer=0),void(this._dayCycleClockKey="");const t=Sr(e);t!==this._dayCycleClockKey&&(this._dayCycleClockKey=t,this.requestUpdate())},this._sunShown=!1,this._sunOut=!1,this._sunOutTimer=0,this._openSettingsDialog=()=>{if(!this._norm)return;const e=this._glowRadiusCm,t=this._imperial?Math.round(e/30.48*10)/10:Math.round(e)/100;this._settingsDialog={colors:JSON.parse(JSON.stringify(this._fillColors)),glowRadius:t,bgColor:hs(this._settings,{bgColor:null})||null,northDeg:zr(this._settings,{}),bgMode:Fr(this._settings,{}),sunRays:Nr(this._settings,{}),busy:!1}},this._reportedPreflightFingerprint=null,this._openAlignDialog=()=>this._previewAlignDialog(!1),this._toggleOptimizeLivePositions=()=>{const e=this._alignDialog;e&&!e.busy&&e.report.liveMissingPositions.length&&this._previewAlignDialog(!e.removeLiveMissingPositions)},this._optimizeUndoBusy=!1,this._openBackupExport=()=>{this._settingsDialog=null,this._backupExportDialog={kind:"full",planOnly:!1,busy:!1,error:""}},this._openRulesDialog=()=>{if(!this._norm)return;const e=this._settings.icon_rules,t=(e&&e.length?e:Je).map(e=>({...e}));this._rulesDialog={rules:t,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)}get _modeTransitionBusy(){return this._modeTransitionPreparing||this._modeTransition.active}_cssColor(e,t){const i=String(e||"").trim();if(!i)return t;const s=document.createElement("span");s.style.cssText=`position:absolute;visibility:hidden;color:${i}`,this.renderRoot.append(s);const n=getComputedStyle(s).color||t;return s.remove(),n}_currentModeVisual(e=this._mode){const t=this._modeTransition.presented||this._modeTransitionVisual;if(t)return{...t,viewport:{...t.viewport,viewBox:{...t.viewport.viewBox}}};const i=this._stageEl;if(!i||i.clientWidth<=0||i.clientHeight<=0)return null;const s=this.renderRoot.querySelector(".editorchrome"),n=this._viewOr(this._baseVb()),o=this.renderRoot.querySelector(".hp-paper"),a=this.renderRoot.querySelector(".hp-backdrop"),r=this.renderRoot.querySelector(".zoomwrap"),l=r?getComputedStyle(r).filter:"",c=Number(/brightness\(([^)]+)\)/.exec(l)?.[1]);return{presentedMode:e,editorChromeHeight:"view"===e?0:s?.getBoundingClientRect().height||0,stageWidth:i.clientWidth,stageHeight:i.clientHeight,viewport:sf(n,i.clientWidth),stageColor:getComputedStyle(i).backgroundColor||"rgb(255, 255, 255)",paperColor:o?getComputedStyle(o).fill:"rgb(255, 255, 255)",sceneBrightness:Number.isFinite(c)?c:1,architectureOpacity:"decor"===e?.35:1,backdropOpacity:a&&Number(getComputedStyle(a).opacity)||1,viewWeight:"view"===e?1:0,editorWeight:"view"===e?0:1,toolbarContentOpacity:"view"===e?0:1}}_viewForModeTarget(e,t,i,s,n){const o=Ei(this._baseVb(),s/Math.max(1,n)),a=Math.min(qv.ZOOM_MAX,Math.max(qv.ZOOM_MIN,e)),r=o.w/a,l=o.h/a,c=t??o.x+o.w/2,h=i??o.y+o.h/2;return this._clampView({x:c-r/2,y:h-l/2,w:r,h:l},o)}_targetStageColor(e){return"view"!==e?"rgb(255, 255, 255)":this._cssColor(this._stageBg(this._spaceDisplayForRender()),this._cssColor("var(--ha-card-background, var(--card-background-color, #111))","rgb(17, 17, 17)"))}_targetPaperColor(e){return"view"===e&&this._spaceModel()?.bg?this._cssColor("var(--ha-card-background, var(--card-background-color, #111))","rgb(17, 17, 17)"):"rgb(255, 255, 255)"}_targetBrightness(e){return 1}_applyModeTransitionFrame(e){e.targetMode===this._mode&&(this._modeTransitionVisual=e.presented,this._view={...e.presented.viewport.viewBox},this.requestUpdate())}_settleModeTransition(e){if(e.targetMode!==this._mode)return;const t=this._modeTransitionRequest;this._view={...e.to.viewport.viewBox},this._zoom=this._modeTransitionTargetZoom,this._modeTransitionVisual=null,this._modeTransitionPreparing=!1,this._lastValidStageSize=[e.to.stageWidth,e.to.stageHeight],"view"===this._mode&&(this._saveZoom(),this._viewModeSnap=null,this._modeTransitionEditorCamera=null),this.requestUpdate(),this.updateComplete.then(()=>{if(!this.isConnected||t!==this._modeTransitionRequest||this._modeTransitionBusy||e.targetMode!==this._mode)return;const i=this._stageEl;if(i&&i.clientWidth>0&&i.clientHeight>0&&(Math.abs(i.clientWidth-e.to.stageWidth)>.5||Math.abs(i.clientHeight-e.to.stageHeight)>.5)){const e=this._view;this._lastValidStageSize=[i.clientWidth,i.clientHeight],this._applyView(this._zoom,e?e.x+e.w/2:void 0,e?e.y+e.h/2:void 0),this.requestUpdate()}const s=this.renderRoot.activeElement;(!s||!s.isConnected||!!s.closest?.(".editorchrome, .stage"))&&this.renderRoot.querySelector(".modetab.active")?.focus?.({preventScroll:!0})})}_cancelModeTransition(e=!0){const t=!!this._modeTransition.state;this._modeTransitionRequest++,this._modeTransitionPreparing=!1,this._modeTransitionForceAtomic=!1,this._modeTransition.cancel(e),e&&t||(this._modeTransitionVisual=null)}_adoptMode(e){this._cancelModeTransition(!1),this._mode=e,"view"!==e&&(this._editorChromeMode=e)}_commitViewModeAtomic(e,t,i,s){if(this._modeTransitionPreparing=!1,this._modeTransitionVisual=null,this._modeTransitionForceAtomic=!1,this._zoom=t,e){const n=this._stageEl?.clientWidth||e.stageWidth,o=Math.max(1,e.stageHeight+e.editorChromeHeight);this._view=this._viewForModeTarget(t,i,s,n,o),this._lastValidStageSize=[n,o]}else this._view=null;this._viewModeSnap=null,this._modeTransitionEditorCamera=null,this._saveZoom(),this.requestUpdate()}_prepareModeTransition(e,t,i,s,n,o){this.updateComplete.then(()=>{if(!this.isConnected||e!==this._modeTransitionRequest||this._mode!==i)return void(e===this._modeTransitionRequest&&(this._modeTransitionPreparing=!1,this._modeTransitionVisual=null,this._modeTransitionForceAtomic=!1,this.requestUpdate()));const a=this.renderRoot.querySelector(".editorchrome"),r=a?.querySelector(".editorchrome-inner"),l="view"===i?0:r?.scrollHeight||r?.getBoundingClientRect().height||0,c=Math.max(1,t.stageHeight+t.editorChromeHeight),h=Math.max(1,c-l),d=this._stageEl?.clientWidth||t.stageWidth;if(d<=0||h<=0)return this._modeTransitionPreparing=!1,this._modeTransitionVisual=null,this._applyView(s,n,o),void this.requestUpdate();const p=this._viewForModeTarget(s,n,o,d,h),u={presentedMode:i,editorChromeHeight:l,stageWidth:d,stageHeight:h,viewport:sf(p,d),stageColor:this._targetStageColor(i),paperColor:this._targetPaperColor(i),sceneBrightness:this._targetBrightness(i),architectureOpacity:"decor"===i?.35:1,backdropOpacity:"decor"===i&&"backdrop"!==this._decorTool?.5:1,viewWeight:"view"===i?1:0,editorWeight:"view"===i?0:1,toolbarContentOpacity:"view"===i?0:1};this._modeTransitionPreparing=!1;const _=this._modeTransitionForceAtomic;this._modeTransitionForceAtomic=!1,this._modeTransition.start(t,u,i,this._reducedMotion||_?0:220)})}get _hasFixedFloor(){return!!this._config&&Object.prototype.hasOwnProperty.call(this._config,"floor")}_fixedFloorState(e=this._model,t=this._loadOk){const i=this._config?.floor,s=function(e){if(!e.hasFloor)return{kind:"absent"};const t=e.floor;if("string"==typeof t)return t.length?e.spaceIds.includes(t)?{kind:"valid",id:t,source:"id"}:{kind:"invalid",reason:"unknown-id",value:t}:{kind:"invalid",reason:"empty-id",value:t};if("number"==typeof t){if(!Number.isFinite(t))return{kind:"invalid",reason:"non-finite-index",value:t};if(!Number.isInteger(t))return{kind:"invalid",reason:"fractional-index",value:t};if(t<0)return{kind:"invalid",reason:"negative-index",value:t};const i=e.spaceIds[t];return void 0===i?{kind:"invalid",reason:"out-of-range-index",value:t}:{kind:"valid",id:i,source:"index"}}return{kind:"invalid",reason:"invalid-type",value:t}}({spaceIds:e.map(e=>e.id),hasFloor:this._hasFixedFloor,floor:i});return!this._hasFixedFloor||t?s:"number"==typeof i?"valid"===s.kind||"invalid"===s.kind&&"out-of-range-index"===s.reason?{kind:"pending",value:i}:s:"valid"===s.kind||"invalid"===s.kind&&"unknown-id"!==s.reason?s:{kind:"pending",value:i}}_canCommitSpace(e,t=!1){if(t||!this._hasFixedFloor)return!0;const i=this._fixedFloorState();return"valid"===i.kind&&i.id===e}_commitSpace(e,t=!1){return!!this._canCommitSpace(e,t)&&(e!==this._space&&(this._clearTransientHover(!0),this._cancelDevicePressFeedback()),this._space=e,!0)}_slideTo(e,t){if(e===this._space)return!0;if(!this._canCommitSpace(e))return!1;if(this._wallFaceBatch&&this._roomDialogCancel(),"plan"===this._mode&&"draw"===this._tool&&!this._finishWallChain())return!1;this._cancelModeTransition(!0);const i=window.matchMedia?.("(prefers-reduced-motion: reduce)")?.matches;return this._activeDraftId&&(this._resumeDraftBySpace[this._space]=this._activeDraftId),this._commitSpace(e),this._path=[],this._clearPlanSnapHover(),this._clearOpeningPlacement(!0),this._tool="draw",this._activeDraftId=null,this._draftSegmentCms=[],this._closingWallCm=null,this._selId=null,this._physicalSel=null,this._editorSecondary.closeForNavigation(),this._physicalDialog=null,this._physicalDrag=null,"plan"===this._mode&&"draw"===this._tool&&this._resumeLastDraft(),this._restoreZoom(),i||(this._slide=t,clearTimeout(this._slideTimer),this._slideTimer=window.setTimeout(()=>{this._slideTimer=void 0,this._slide="",this.requestUpdate()},190),this.requestUpdate()),!0}get _canReorderTabs(){return uv({canEdit:this._canEdit,kiosk:this._kiosk,mode:this._mode,pointerType:"mouse",spaceCount:this._model.length,fixedFloor:this._hasFixedFloor})}_tabPointerDown(e,t){uv({canEdit:this._canEdit,kiosk:this._kiosk,mode:this._mode,pointerType:e.pointerType,spaceCount:this._model.length,fixedFloor:this._hasFixedFloor})&&(jv(e),this._tabDragRelease=e=>this._tabPointerUp(e),window.addEventListener("pointerup",this._tabDragRelease),window.addEventListener("pointercancel",this._tabDragRelease),this._tabDrag={id:t,pointerId:e.pointerId,x:e.clientX,y:e.clientY,moved:!1,targetId:null,placement:null})}_tabDropTargetAt(e,t,i){const s=this._model.map(e=>e.id),n=s.indexOf(i);if(n<0)return null;const o=this.renderRoot.querySelectorAll('[data-hp="space-tab"]');for(const a of o){const o=a.dataset.id||"";if(!o||o===i)continue;const r=a.getBoundingClientRect();if(er.right||tr.bottom)continue;const l=s.indexOf(o);return l<0?null:{targetId:o,placement:l=4)))return;var i,s;const n=this._tabDropTargetAt(e.clientX,e.clientY,t.id);t.moved&&t.targetId===n?.targetId&&t.placement===n?.placement||(this._tabDrag={...t,moved:!0,targetId:n?.targetId||null,placement:n?.placement||null})}_tabPointerUp(e){const t=this._tabDrag;if(t&&t.pointerId!==e.pointerId)return;const i="pointerup"===e.type&&t?.moved?this._tabDropTargetAt(e.clientX,e.clientY,t.id):null;"pointerup"===e.type&&t?.moved&&this._suppressNextTabClick(),this._endTabDrag(),t?.moved&&i&&this._commitTabOrder(t.id,i.targetId)}_endTabDrag(){this._tabDrag=null,this._tabDragRelease&&(window.removeEventListener("pointerup",this._tabDragRelease),window.removeEventListener("pointercancel",this._tabDragRelease),this._tabDragRelease=null)}_tabClick(e){if(this._tabSuppressClick)return this._tabSuppressClick=!1,clearTimeout(this._tabSuppressClickTimer),void(this._tabSuppressClickTimer=void 0);this._pickSpace(e)}_suppressNextTabClick(){this._tabSuppressClick=!0,clearTimeout(this._tabSuppressClickTimer),this._tabSuppressClickTimer=window.setTimeout(()=>{this._tabSuppressClick=!1,this._tabSuppressClickTimer=void 0},0)}_commitTabOrder(e,t){const i=this._serverCfg;if(!i||!this._canReorderTabs)return;const s=this._model.map(e=>e.id),n=function(e,t,i){const s=e.indexOf(t),n=e.indexOf(i);if(s<0||n<0||s===n)return e;const o=e.slice();return o.splice(s,1),o.splice(n,0,t),o}(s,e,t);if(n===s)return;const o=new Map(this._devices.map(e=>[String(e.id),String(e.area||"")])),a=function(e,t,i,s=()=>""){if(!i)return[];const n=[];for(const o of e){if(!o||!0===o.removed)continue;const e="string"==typeof o.id?o.id:"";if(!e)continue;if("string"==typeof o.space&&o.space)continue;const a=("string"==typeof o.area?o.area:"")||s(e)||"";a&&t[a]||n.push({id:e,space:i})}return n}(i.markers||[],Object.fromEntries(Object.entries(this._areaToSpace).map(([e,t])=>[e,t.space])),s[0]||"",e=>o.get(e)||"");if(a.length){const e=new Map(a.map(e=>[e.id,e.space]));for(const t of i.markers||[]){const i=e.get(String(t.id));i&&(t.space=i)}}i.spaces=function(e,t){const i=new Map(t.map((e,t)=>[e,t]));return e.map((e,t)=>({space:e,index:t})).sort((e,t)=>(i.get(String(e.space?.id))??Number.MAX_SAFE_INTEGER)-(i.get(String(t.space?.id))??Number.MAX_SAFE_INTEGER)||e.index-t.index).map(e=>e.space)}(i.spaces||[],n),this._saveConfig(),this._tabOrderWarned||(this._tabOrderWarned=!0,this._showToast(this._t("toast.space_order_changed")))}_pickSpace(e){if(this._endTabDrag(),e===this._space)return;const t=this._model.map(e=>e.id),i=t.indexOf(this._space),s=t.indexOf(e);this._navApplied=!0,this._showFar=!1,this._frame=null,this._slideTo(e,i>=0&&s0&&Date.now()>=this._cyclePausedUntil&&this._model.length>1&&this._zoom<=1.001){const e=this._model.map(e=>e.id),t=e.indexOf(this._space);this._slideTo(e[(t+1)%e.length],"left"),this._showKioskDots()}}_syncCycleTimer(){clearInterval(this._cycleTimer),this._cycleTimer=void 0,this.isConnected&&!this._hasFixedFloor&&this._config?.kiosk&&Number(this._config.cycle)>0&&(this._cycleTimer=window.setInterval(()=>this._cycleTick(),1e3*Number(this._config.cycle)))}get _editing(){return"plan"===this._mode||"devices"===this._mode||"decor"===this._mode}get _markup(){return"plan"===this._mode}get _wallUnionCache(){return this._wallUnionCacheValue}set _wallUnionCache(e){this._wallUnionCacheValue=e,null===e&&this._wallUnionPool.clear()}_newContinuityController(){return new Ud(()=>{this._resumeSettling="steady"!==this._continuity.state,this._continuityEpoch++,this.isConnected&&this.requestUpdate()})}get _labsIso(){return this._labs.active.includes("iso")}get _desiredProjection(){return"view"===this._mode&&this._labsIso&&"iso"===this._viewPreference[this._space]?"iso":"flat"}_saveViewPreference(){try{localStorage.setItem(Rv,JSON.stringify(this._viewPreference))}catch{}}_logicalViewCenter(e){const t=this._view;if(!t)return null;const i=[t.x+t.w/2,t.y+t.h/2],s="iso"===e?Tf(i):i;return{x:s[0],y:s[1]}}_convertProjectionView(e,t){if(e===t)return;const i=this._logicalViewCenter(e);this._view=null;const s=i?"iso"===t?Pf([i.x,i.y],0):[i.x,i.y]:null;this._applyView(this._zoom,s?.[0],s?.[1]),this._warmPatch({vp:this._warmViewportState()}),this.requestUpdate()}_setProjection(e){if(!this._labsIso||"view"!==this._mode)return;const t=this._effectiveProjection();if(this._viewPreference={...this._viewPreference,[this._space]:e},"iso"===e){const e=this._isoSceneKey();e&&this._isoFallback.delete(e)}this._saveViewPreference();const i=this._effectiveProjection();this._convertProjectionView(t,i)}_hashSpace(){return gf(window.location.hash||"")}connectedCallback(){this._connectedPath=location.pathname,this._routeDepartureHandled=!1,window.addEventListener("location-changed",this._onLocationChanged),window.addEventListener("popstate",this._onLocationChanged),this._continuityDisposed&&(this._continuity=this._newContinuityController(),this._continuityDisposed=!1,this._continuityPaintToken=-1);const e=(t=this.ownerDocument,Yg.get(t)?.resolved);var t;void 0!==e&&(this._glowScreenBlend=e),this._continuityUnsub?.(),this._continuityUnsub=qd(this.ownerDocument,this._pageVisibility),super.connectedCallback(),this._pointerModality.connect(this.ownerDocument.defaultView);const i=this.ownerDocument.defaultView?.MutationObserver;i&&(this._pointerHoverObserver=new i(e=>{for(const t of e)for(const e of t.addedNodes)this._syncPointerHoverSubtree(e)}),this._pointerHoverObserver.observe(this.renderRoot,{childList:!0,subtree:!0})),this._motionMedia=window.matchMedia?.("(prefers-reduced-motion: reduce)"),this._reducedMotion=!!this._motionMedia?.matches,this._motionMedia?.addEventListener?.("change",this._onMotionChange),function(e){const t=Yg.get(e);if(t)return t.promise;const i={promise:Promise.resolve(!1)};return i.promise=Xg(e).catch(()=>!1).then(e=>(i.resolved=e,e)),Yg.set(e,i),i.promise}(this.ownerDocument).then(e=>{e!==this._glowScreenBlend&&(this._glowScreenBlend=e,this.isConnected&&this.requestUpdate())}),this.hass&&this._ensureHaRegistryAuthority(),window.addEventListener("keydown",this._keyHandler),this._signer.start(()=>this.hass,()=>Rs(this._serverCfg)),this._syncCycleTimer(),window.addEventListener("hashchange",this._onHashChange),this._labsUnsub?.(),this._labsUnsub=function(e,t){xf.add(t);const i=Mf(e);return"undefined"==typeof window&&t(i),()=>{xf.delete(t)}}(_v,this._onLabsSnapshot),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},bv)),!this._loadOk&&this._serverCfg&&this.hass&&this._scheduleLoadRetry(),!this._warmSlot&&this._config&&this._warmAdopt(),this._loadOk&&this._ensureLiveSyncSubscriptions(),this._warmVp&&!this._warmRevivePending&&void 0===this._warmReviveTimer&&(this._warmRevivePending=!0,this._warmReviveTimer=window.setTimeout(()=>this._warmReviveDialog(),0)),this._warmLongReturn&&this._beginResumeSettle(),this._warmLongReturn=!1,this.requestUpdate()}disconnectedCallback(){this._connectedPath&&location.pathname!==this._connectedPath&&this._leaveCardRoute(),window.removeEventListener("location-changed",this._onLocationChanged),window.removeEventListener("popstate",this._onLocationChanged),this._continuityUnsub?.(),this._continuityUnsub=void 0,this._motionMedia?.removeEventListener?.("change",this._onMotionChange),this._motionMedia=void 0,this._vacRaf&&(cancelAnimationFrame(this._vacRaf),this._vacRaf=0),this._refitRaf&&(cancelAnimationFrame(this._refitRaf),this._refitRaf=0),this._dayCycleTimer&&(clearInterval(this._dayCycleTimer),this._dayCycleTimer=0),this._dayCycleClockKey="",this._bootSettleRaf&&(cancelAnimationFrame(this._bootSettleRaf),this._bootSettleRaf=0),this._bootSettling=!1;for(const e of this._activityRt.values())clearTimeout(e.timer);window.removeEventListener("keydown",this._keyHandler),this._endTabDrag(),clearTimeout(this._tabSuppressClickTimer),this._tabSuppressClickTimer=void 0,this._tabSuppressClick=!1,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?.removeEventListener?.("disconnected",this._onConnLost),this._connHooked?.removeEventListener?.("reconnect-error",this._onConnLost),this._connHooked=null,this._haRegistryRelease?.(),this._haRegistryRelease=void 0,this._haRegistryConnection=null,this._signer.dispose(),clearTimeout(this._toastTimer),clearTimeout(this._slideTimer),this._modeTransition.dispose(),this._modeTransitionVisual=null,this._modeTransitionPreparing=!1,this._modeTransitionForceAtomic=!1,this._modeTransitionRequest++,this._slideTimer=void 0,this._slide="",clearTimeout(this._bootTimer),this._bootTimer=void 0,clearTimeout(this._bootSoftTimer),this._saveConfigDebounced.flush(),window.removeEventListener("hashchange",this._onHashChange),this._labsUnsub?.(),this._labsUnsub=void 0,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),this._unsubVirtual&&(this._unsubVirtual(),this._unsubVirtual=null),this._unsubTrail&&(this._unsubTrail(),this._unsubTrail=void 0),this._liveSyncGeneration++,this._liveSyncAttempt=null,this._liveSyncConnection=null,clearTimeout(this._layoutSyncTimer),clearTimeout(this._duplicateColumnTimer);for(const e of this._glowFadeTimers.values())clearTimeout(e);for(const e of this._glowEnterRafs.values())cancelAnimationFrame(e);clearTimeout(this._glowFeatherResumeTimer),this._glowFeatherResumeTimer=0,this._glowFeatherSuspendUntil=0,this._glowFadeTimers.clear(),this._glowEnterRafs.clear(),this._glowEnteringSources.clear(),this._glowRenderedSources.clear(),this._glowLastAppearance.clear(),this._glowSourceSeq=0,this._warmSnapshot(),this._warmRevivePending=!1,clearTimeout(this._warmReviveTimer),this._warmReviveTimer=void 0,this._warmRelease(),this._clearPlanSnapHover(),this._clearOpeningPlacement(!0),this._touchContacts.clear(),this._touchSequenceMultitouch=!1,this._touchClickBlockUntil=0,this._clearTransientHover(!0),this._cancelDevicePressFeedback(),this._pointerHoverObserver?.disconnect(),this._pointerHoverObserver=void 0,this._pointerModality.disconnect(),this._editorSecondary.reset(),this._resumeSettling=!1,this._continuityHistory=[...this._continuityHistory,...this._continuity.trace].slice(-80),this._continuity.dispose(),this._continuityDisposed=!0,super.disconnectedCallback()}_onKey(e){if("Escape"===e.key&&this._vacFit)return this._vacFit=null,this._showToast(this._t("vac.cal_cancelled")),void e.stopPropagation();if("Escape"===e.key){if(this._tapConfirm)return void(this._tapConfirm=null);if(this._vacCalConfirm)return void(this._vacCalConfirm=null);if(this._decorEraseConfirm)return void(this._decorEraseConfirm=null);if(this._openingInfo)return void(this._openingInfo=null);if(this._infoCard)return void this._closeInfoCard();if(this._rulesDialog)return void(this._rulesDialog=null);if(this._alignDialog)return this._alignDialog=null,void(this._preflightClipboardFallback=null);if(this._backupImportDialog)return void(this._backupImportDialog=null);if(this._backupExportDialog)return void(this._backupExportDialog=null);if(this._settingsDialog)return void(this._settingsDialog=null);if(this._markerDialog)return void this._closeMarkerDialog();if(this._deviceInbox)return void(this._deviceInbox=null);if(this._openingDialog)return void(this._openingDialog=null);if(this._physicalDialog)return void(this._physicalDialog=null);if(this._backdropDialog)return void(this._backdropDialog=null);if(this._decorShapeDialog)return void(this._decorShapeDialog=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(this._editorSecondary.hasOpenGroup)return e.preventDefault(),void this._editorSecondary.closeGroup(!0)}const t=e.composedPath?.()||[e.target],i=t.some(e=>e?.matches?.('input, textarea, select, [contenteditable="true"]')),s=t.some(e=>e?.classList?.contains?.("editor-secondary")),n=e.ctrlKey||e.metaKey,o=e.key.toLowerCase(),a=/^[a-z]$/.test(o),r="z"===o||!a&&"KeyZ"===e.code,l="y"===o||!a&&"KeyY"===e.code,c=n&&(r&&e.shiftKey||l),h=n&&r&&!e.shiftKey;if("decor"===this._mode){if((h||c)&&i)return;return c?(e.preventDefault(),void this._redoGeometry()):h?(e.preventDefault(),this._decorDraft?void(this._decorDraft=null):this._decorMove||this._dtDrag||this._bdDrag?void this._cancelDecorGesture():void this._undoGeometry()):"Delete"!==e.key&&"Backspace"!==e.key||!this._decorSel||i||s?void("Escape"===e.key&&(e.preventDefault(),this._decorDraft?this._decorDraft=null:this._decorMove||this._dtDrag||this._bdDrag?this._cancelDecorGesture():"furniture"===this._decorTool?(this._furnPalette=null,this._decorTool="select"):this._decorSel?this._decorSel=null:"select"!==this._decorTool?this._decorTool="select":this._setMode("view"))):(e.preventDefault(),void this._decorDeleteSel())}if(this._markup&&(!h&&!c||!i)){if(("Delete"===e.key||"Backspace"===e.key)&&this._physicalSel&&!i&&!s)return e.preventDefault(),void this._deletePhysicalSelection();if(c)return e.preventDefault(),void this._redoGeometry();if(h)return e.preventDefault(),this._resize.dragging?void this._rszCancelDrag():this._wallFaceBatch?(this._roomDialogCancel(),void(this._activeDraftId&&this._path.length>1?this._undoActiveDraftPoint():this._undoPoint())):"draw"===this._tool&&this._path.length?void(this._activeDraftId&&this._path.length>1?this._undoActiveDraftPoint():this._undoPoint()):"split"===this._tool&&this._splitSel?.pts?.length?(this._splitSel={...this._splitSel,pts:this._splitSel.pts.slice(0,-1)},void(this._splitSel.pts.length||(this._cursorPt=null))):void this._undoGeometry();if("Escape"===e.key)return this._physicalDrag||this._physicalRotate?(e.preventDefault(),void this._cancelPhysicalGesture()):this._roomDialog?(e.preventDefault(),void this._roomDialogCancel()):"draw"===this._tool&&this._path.length?(e.preventDefault(),void this._finishWallChain()):this._physicalSel?(e.preventDefault(),void(this._physicalSel=null)):"resize"===this._tool?(e.preventDefault(),this._resize.dragging?void this._rszCancelDrag():("exit-tool"===this._resize.escapeIdle()&&(this._tool="draw"),void this.requestUpdate())):"split"===this._tool?(e.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?(e.preventDefault(),void(this._mergeSel?this._mergeSel=null:this._tool="draw")):this._wallDialog?(e.preventDefault(),void(this._wallDialog=null)):void("opening"!==this._tool&&"wallthick"!==this._tool&&"delroom"!==this._tool&&"column"!==this._tool||(e.preventDefault(),"opening"===this._tool&&this._clearOpeningPlacement(!0),this._tool="draw"))}}_undoPoint(){if(this._path.length){if(this._contourClosed)return this._path=this._path.slice(0,-1),void(this._closingWallCm=null);if(this._activeDraftId&&this._path.length>1&&this._curSpaceCfg){const e=this._geometrySnapshot();this._path=this._path.slice(0,-1),this._draftSegmentCms=this._draftSegmentCms.slice(0,-1);const t=this._curSpaceCfg,i=(t.room_drafts||[]).findIndex(e=>e.id===this._activeDraftId);if(i>=0){const s=Array.isArray(t.room_drafts[i]?.segments)?t.room_drafts[i].segments:[];this._path.length<2?(t.room_drafts.splice(i,1),t.room_drafts.length||delete t.room_drafts,this._activeDraftId=null):t.room_drafts[i]={id:this._activeDraftId,points:this._path.map(e=>[e[0]/zv,e[1]/zv]),segments:this._draftSegmentCms.map((e,t)=>({...s[t]||{},cm:e}))},this._commitPhysicalGeometry(this._t("history.draft_segment_delete"),e)}return}this._path=this._path.slice(0,-1)}}_undoActiveDraftPoint(){const e=this._activeDraftId,t=this._path[0]?[...this._path[0]]:null,i=this._geometryHistory.undo();if(!i)return void this._undoPoint();if(!this._applyGeometryState(i.before,!0))return void this._geometryHistory.clear();const s=e?this._spaceModel()?.room_drafts.find(t=>t.id===e):null;s?(this._activeDraftId=s.id,this._path=s.points.map(e=>[...e]),this._draftSegmentCms=this._adoptDraftCms(this._path,s.segments.map(e=>e.cm),s.id),this._resumeDraftBySpace[this._space]=s.id):(this._activeDraftId=null,this._path=t?[t]:[],this._draftSegmentCms=[],e&&this._resumeDraftBySpace[this._space]===e&&delete this._resumeDraftBySpace[this._space]),this._clearPlanSnapHover(),this._showToast(this._t("history.undone",{name:i.name}))}static getConfigElement(){return document.createElement("houseplan-card-editor")}static getStubConfig(){return{type:"custom:houseplan-card"}}static _warmBootReset(e){for(const e of xv.values())for(const t of e)clearTimeout(t.evict);xv.clear(),Mv=e&&e>0?e:1e4}static _warmBootStats(){let e=0,t=0;const i=[];for(const s of xv.values())for(const n of s)e++,n.dlg&&(t++,i.push(n.dlg.kind));return{keys:xv.size,slots:e,dlgs:t,drafts:i}}setConfig(e){const t=this._config,i=!!t&&Object.prototype.hasOwnProperty.call(t,"floor");this._config={icon_size:2.5,show_temperature:!0,live_states:!0,show_signal:!0,...e};(i!==this._hasFixedFloor||t?.floor!==this._config.floor)&&(this._hashApplied=!1,this._navApplied=!1,this._warmVpArmed=!1),this._config.kiosk&&(this._booting=!1,this._bootFading=!1),!this._hasFixedFloor&&e.default_floor&&this._commitSpace(e.default_floor,!0);try{this._zoomBySpace=JSON.parse(localStorage.getItem(Pv)||"{}")||{}}catch{this._zoomBySpace={}}try{const e=JSON.parse(localStorage.getItem(Rv)||"{}")||{};this._viewPreference=Object.fromEntries(Object.entries(e).filter(e=>"flat"===e[1]||"iso"===e[1]))}catch{this._viewPreference={}}this._labs=Mf(_v);try{const e=JSON.parse(localStorage.getItem(Iv)||"null");this._kioskScale={icon:Ns(e?.icon),font:Ns(e?.font)}}catch{}try{const e=JSON.parse(localStorage.getItem(Dv)||"null");e&&e.config&&Array.isArray(e.config.spaces)&&(this._serverCfg=e.config,this._cfgEpoch++,this._cfgRev=e.rev||0,this._cfgContentFingerprint=e.config_fingerprint||Gd(e.config),this._layout=e.layout||{},this._layoutRev=e.layout_rev||0,this._layoutContentFingerprint=e.layout_fingerprint||Gd(this._layout),this._virtualLights=mn(e.virtual_lights,this._cfgRev),this._serverStorage=!0)}catch{}this._adoptInitialSpace(this._model,this._loadOk),"view"!==this._mode||this._view||(this._zoom=this._zoomBySpace[this._space]||1),this.isConnected&&(this._syncCycleTimer(),this._warmAdopt(),this._warmLongReturn&&this._beginResumeSettle(),this._warmLongReturn=!1)}_warmAdopt(){if(this._config?.kiosk)return;const e=Sv(this._config);if(this._warmKey===e&&this._warmSlot)return;this._warmSlot&&this._warmRelease();const t=this.parentNode,i=this._warmIdx(t),s=xv.get(e);if(!s||!s.length)return;const n=s.find(e=>e.owner===this._warmGen);if(n)return this._warmLongReturn=!!n.freed&&Date.now()-n.freed>=Ld,clearTimeout(n.evict),n.evict=0,n.freed=0,n.live=!0,this._warmSlot=n,this._warmKey=e,n.frameFingerprint&&this._continuity.adoptCompleteFrame(n.frameFingerprint),void(!this._devices.length&&n.devices?.length&&(this._devices=[...n.devices]));const{slot:o,sure:a}=((e,t,i,s)=>{const n=e=>{const t=!!i&&e.place?.deref()===i;return t&&e.idx===s?4:e.live?0:t?3:2};let o=null,a=0,r=0,l=null;for(const i of e){if(i.owner===t)continue;l=i;const e=n(i);e<=0||(e>a?(o=i,a=e,r=1):e===a&&r++)}return!o||r>1?{slot:o||l,sure:!1}:{slot:o,sure:!0}})(s,this._warmGen,t,i);o&&(this._warmLongReturn=!!o.freed&&Date.now()-o.freed>=Ld,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},bv)),this._warmKey=e,a?(clearTimeout(o.evict),o.evict=0,o.owner=this._warmGen,o.place=t?new WeakRef(t):null,o.idx=i,o.live=!0,this._warmSlot=o,this._warmVp=o.vp,o.frameFingerprint&&this._continuity.adoptCompleteFrame(o.frameFingerprint),!this._devices.length&&o.devices?.length&&(this._devices=[...o.devices]),this._warmAdoptViewport(this._config)):(this._warmSlot={owner:this._warmGen,path:location.pathname,place:t?new WeakRef(t):null,idx:i,live:!0,hdrH:o.hdrH,stageH:o.stageH,vp:null,frameFingerprint:"",devices:null,dlg:null,freed:0,evict:0},s.push(this._warmSlot),this._warmTrim(s)))}_warmIdx(e){const t=e?.children;if(!t)return-1;for(let e=0;e4;){const t=e.findIndex(e=>!e.live);if(t<0)break;clearTimeout(e[t].evict),e.splice(t,1)}}_warmScheduleEvict(e,t){if(clearTimeout(e.evict),!(e.dlg||e.vp&&"view"!==e.vp.mode))return;const i=e.freed,s=e.owner;e.evict=window.setTimeout(()=>{if(e.evict=0,e.freed!==i||e.owner!==s)return;var n;e.dlg=null,e.vp=(n=e.vp)&&"view"!==n.mode?{...n,mode:"view",zoom:n.snap?.space===n.space?n.snap.zoom:n.zoom,view:null,snap:null,tool:"draw",decorTool:"select",showHidden:!1,selId:null,rszSel:null,decorSel:null}:n,e.frameFingerprint="";const o=xv.get(t);if(!e.live&&o&&o.length>1){const t=o.indexOf(e);t>=0&&o.splice(t,1)}},Mv+250)}_warmAdoptViewport(e){const t=this._warmVp;if(!t||this._warmSlot?.path!==location.pathname)return void(this._warmVp=null);const i=this._fixedFloorState();if(this._hashApplied||!this._model.find(e=>e.id===t.space)||"valid"===i.kind&&i.id!==t.space||this._hasFixedFloor&&"valid"!==i.kind)return void(this._warmVp=null);this._commitSpace(t.space,!0),this._navApplied=!0,this._adoptMode("view"!==t.mode&&this._canEdit&&!e.kiosk?t.mode:"view"),this._pendingNavMode="view"===t.mode||this._canEdit||e.kiosk?null:t.mode,this._zoom=t.zoom;const s=this._effectiveProjection(),n=s===t.projection&&this._labsIso===t.activeLabsIso;if(this._view=n&&t.view?{...t.view}:null,this._viewModeSnap=n&&t.snap?{...t.snap}:null,!n&&t.logicalCenter){const e="iso"===s?Pf([t.logicalCenter.x,t.logicalCenter.y],0):[t.logicalCenter.x,t.logicalCenter.y];this._applyView(t.zoom,e[0],e[1])}var o;this._tool="opening"===(o=function(e){return"partition"===e?"draw":e}(o=t.tool))?"draw":"string"==typeof o&&Ev.has(o)?o:"draw",this._decorTool=t.decorTool,this._showHidden=t.showHidden,this._showFar!==t.showFar&&(this._showFar=t.showFar,this._frame=null),this._selId=t.selId,this._resize.restoreSelection(t.rszSel),this._decorSel=t.decorSel,this._warmVpArmed=!0}_warmPatch(e,t=!1){if(this._config?.kiosk)return;const i=Sv(this._config);if(!this._warmSlot||this._warmKey===i){if(!this._warmSlot){if(!t)return;const e=this.parentNode;this._warmKey=i,this._warmSlot={owner:this._warmGen,path:location.pathname,place:e?new WeakRef(e):null,idx:this._warmIdx(e),live:!0,hdrH:this._hdrH,stageH:0,vp:null,frameFingerprint:"",devices:null,dlg:null,freed:0,evict:0};const s=xv.get(i)||[];for(s.push(this._warmSlot),xv.set(i,s),this._warmTrim(s);xv.size>8;){const e=xv.keys().next().value;if(void 0===e||e===i)break;for(const t of xv.get(e)||[])clearTimeout(t.evict);xv.delete(e)}}Object.assign(this._warmSlot,e)}}_warmViewportState(){const e=this._effectiveProjection();return{space:this._space,mode:this._mode,projection:e,activeLabsIso:this._labsIso,logicalCenter:this._logicalViewCenter(e),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._resize.selectedRoomId,decorSel:this._decorSel}}_warmDialogState(){const e=(e,t)=>({kind:e,space:this._space,mode:this._mode,data:t});return this._tapConfirm||this._alignDialog||this._mergeDialog||this._importDialog||this._backupExportDialog||this._backupImportDialog?null:this._openingInfo?e("openingInfo",this._openingInfo.id):this._infoCard?e("info",this._infoCard.id):this._rulesDialog?this._rulesDialog.busy?null:e("rules",this._rulesDialog):this._settingsDialog?this._settingsDialog.busy?null:e("settings",this._settingsDialog):this._markerDialog?this._markerDialog.busy?null:e("marker",this._markerDialog):this._openingDialog?e("opening",this._openingDialog):this._backdropDialog?e("backdrop",this._backdropDialog):this._decorShapeDialog?e("decorShape",this._decorShapeDialog):this._decorTextDialog?e("decorText",this._decorTextDialog):this._roomDialog?e("room",{editId:this._roomEditId,fill:this._roomFill,customFill:this._roomCustomFill,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,wallFaceBatch:this._wallFaceBatch,path:this._path}):this._spaceDialog?this._spaceDialog.busy?null:e("space",this._spaceDialog):null}_warmSnapshot(){if(this._booting||this._config?.kiosk||"steady"!==this._continuity.state)return;const e={vp:this._warmViewportState(),frameFingerprint:this._continuity.frameFingerprint,devices:this._devices};if(this._warmRevivePending||(e.dlg=this._warmDialogState()),this.isConnected&&this._warmSlot?.owner===this._warmGen){const t=this.parentNode;e.place=t?new WeakRef(t):null,e.idx=this._warmIdx(t)}this._warmPatch(e)}_warmReviveDialog(){this._warmRevivePending=!1;const e=this._warmSlot;if(this._warmReviveTimer=void 0,!e||!e.dlg)return;const t=e.dlg,i=e.freed;if(e.dlg=null,e.freed=0,clearTimeout(e.evict),e.evict=0,i&&!(Date.now()-i>Mv)&&t.space===this._space&&t.mode===this._mode){switch(t.kind){case"space":this._spaceDialog={...t.data,busy:!1,savedBusy:!1};break;case"marker":this._markerDialog={...t.data,busy:!1};break;case"settings":this._settingsDialog={...t.data,busy:!1};break;case"rules":this._rulesDialog={...t.data,busy:!1};break;case"opening":this._openingDialog={...t.data};break;case"backdrop":this._backdropDialog={...t.data};break;case"decorShape":this._decorShapeDialog={...t.data};break;case"decorText":{this._decorTextDialog={...t.data};const e=String(this._decorTextDialog?.text??"").length;this._decorTextSelection={start:e,end:e};break}case"room":{const e=t.data;this._roomEditId=e.editId,this._roomFill=e.fill,this._roomCustomFill=e.customFill||null,this._roomTempSrc=e.tempSrc,this._roomHumSrc=e.humSrc,this._roomSrcOpen=e.srcOpen,this._roomSrcFilter=e.srcFilter,this._roomNameScale=e.nameScale,this._roomLabelScale=e.labelScale,this._areaSel=e.areaSel,this._nameSel=e.nameSel,this._pendingSplit=e.pendingSplit,this._wallFaceBatch=e.wallFaceBatch||null,this._path=e.path,this._wallFaceBatch&&(this._activeDraftId=this._wallFaceBatch.activeDraftId,this._draftSegmentCms=[...this._wallFaceBatch.activeCms]),this._roomDialog=!0;break}case"info":{const e=this._devices.find(e=>e.id===t.data);e&&(this._infoCard=e);break}case"openingInfo":{const e=(this._curSpaceCfg?.openings||[]).find(e=>e.id===t.data);e&&(this._openingInfo=e);break}}this.requestUpdate()}}_cacheSnapshot(){if(this._serverCfg)try{this._cfgContentFingerprint=Gd(this._serverCfg),this._layoutContentFingerprint=Gd(this._layout),this._virtualLights=function(e,t,i){if(e.configRev===i)return e;const s=new Set((Array.isArray(t?.markers)?t.markers:[]).filter(bn).map(e=>e.id));return{...e,configRev:i,off:new Set([...e.off].filter(e=>s.has(e)))}}(this._virtualLights,this._serverCfg,this._cfgRev),localStorage.setItem(Dv,JSON.stringify({config:this._serverCfg,rev:this._cfgRev,config_fingerprint:this._cfgContentFingerprint,layout:this._layout,layout_rev:this._layoutRev,layout_fingerprint:this._layoutContentFingerprint,virtual_lights:fn(this._virtualLights)}))}catch{}}_beginContinuityCandidate(e,t,i="plan"){return this._booting&&!this._continuity.hasCompleteFrame?this._continuity.token:(this._continuityDataReady=t,this._continuityPaintToken=-1,this._stagedDeviceSnapshotToken=-1,this._resumeSettling=!0,this._continuity.beginCandidate(e,i))}_continuityStageValid(){const e=this._stageEl;return!!e&&e.clientWidth>0&&e.clientHeight>0}_continuityAssetsReady(){if(!this._model.length)return!1;const e=this._model.length?this._spaceModel():null;return!e?.bg?.href||this._signer.isReady(this.hass,e.bg.href)}_initialSpaceSelection(e,t=this._loadOk){const i=this._fixedFloorState(e,t);return"valid"===i.kind?{id:i.id,source:"fixed"}:this._hasFixedFloor?{id:null,source:"none"}:function(e){const t=new Set(e.spaceIds.filter(e=>!!e));if(!t.size)return{id:null,source:"none"};const i=[["hash",!1===e.acceptHash?null:e.hashSpace],["current",e.preserveCurrent?e.currentSpace:null],["saved",e.savedSpace],["default",e.defaultSpace],["first",e.spaceIds[0]]];for(const[e,s]of i)if(s&&t.has(s))return{id:s,source:e};return{id:null,source:"none"}}({spaceIds:e.map(e=>e.id),hashSpace:this._hashSpace(),acceptHash:!this._hashApplied,currentSpace:this._space,preserveCurrent:this._hashApplied||this._navApplied||this._warmVpArmed,savedSpace:this._savedNav()?.space,defaultSpace:this._config?.default_floor})}_adoptInitialSpace(e,t=this._loadOk){const i=this._initialSpaceSelection(e,t);return i.id?(this._commitSpace(i.id,!0),"hash"===i.source&&(this._hashApplied=!0),"saved"===i.source&&(this._navApplied=!0),i):i}_candidateBackdrop(e,t=this._space){const i=Eh(e),s=this._fixedFloorState(i,!0);if(this._hasFixedFloor&&"valid"!==s.kind)return"";const n=this._initialSpaceSelection(i,!0).id||(i.some(e=>e.id===t)?t:i[0]?.id);return i.find(e=>e.id===n)?.bg?.href||""}_visualFrameFingerprint(){const e=this._stageEl,t=e?[e.clientWidth,e.clientHeight]:[0,0];return Vd([this._cfgRev,this._cfgContentFingerprint||Gd(this._serverCfg),this._layoutRev,this._layoutContentFingerprint||Gd(this._layout),this._space,this._mode,this._view,t,this._glowScreenBlend?"screen":"normal",this.hass?.themes?.darkMode??this.hass?.themes?.default_theme??""])}_settleContinuityFrame(){if(this._booting||!this._continuityStageValid())return;if(!this._continuity.hasCompleteFrame&&"steady"===this._continuity.state)return void(this._continuityAssetsReady()&&(this._renderSnapshotAt=Date.now(),this._continuity.markCompleteFrame(this._visualFrameFingerprint())));if(!this._continuityDataReady)return;if(!["holding","offline-stale","overlay-pending","overlay-visible","candidate-ready"].includes(this._continuity.state))return;const e=this._continuity.token;if(this._candidateDeviceSnapshot&&this._candidateDeviceSnapshot!==this._visibleDeviceSnapshot&&this._stagedDeviceSnapshotToken!==e)return this._stagedDeviceSnapshotToken=e,void this.requestUpdate();this._continuityPaintToken!==e&&(this._continuityPaintToken=e,this._continuity.candidateReady(e)&&this._continuity.commitAfterPaint(e,{updateComplete:()=>this.updateComplete,stageValid:()=>this.isConnected&&this._continuityStageValid(),assetsReady:()=>this._continuityAssetsReady(),frameFingerprint:()=>this._visualFrameFingerprint()}).then(t=>{t&&e===this._continuity.token?(this._resumeSettling=!1,this._renderSnapshotAt=Date.now(),this._candidateDeviceSnapshot&&(this._visibleDeviceSnapshot=this._candidateDeviceSnapshot),this._candidateDeviceSnapshot=null,this._stagedDeviceSnapshotToken=-1,this._warmSnapshot()):e===this._continuity.token&&(this._continuityPaintToken=-1,this._stagedDeviceSnapshotToken=-1,this._candidateDeviceSnapshot=null,this.requestUpdate())}))}_onBackdropLoaded(e,t){this._signer.markLoaded(this.hass,e,t),this._continuity.note("asset-ready"),this._continuityPaintToken=-1,"steady"!==this._continuity.state&&this.requestUpdate()}_renderRecoveryOverlay(){if(!this._continuity.overlayVisible&&"recovery-error"!==this._continuity.state)return G;const e="connection"===this._continuity.recoveryReason;return q`
e.stopPropagation()} @click=${e=>e.stopPropagation()} @@ -5109,8 +5109,8 @@ globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="30d20d6f6822065e2d5226b18abbb05d8d26 ${this._t(e?"continuity.restore_connection":"continuity.restore_plan")} ${"recovery-error"===this._continuity.state?q``:G} -
`}houseplanContinuityTrace(){return[...this._continuityHistory,...this._continuity.trace].slice(-80).map(e=>({...e,...e.stage?{stage:[...e.stage]}:{}}))}getCardSize(){return 12}get _norm(){return!(!this._serverCfg||!this._serverCfg.spaces.length)}_cfgFingerprint(){const e=this._serverCfg?.spaces||[];let t=e.length+":";for(const i of e){t+=(i.id||"")+","+(i.plan_aspect||"")+","+(i.plan_url||"").length+","+(i.plan_x??"")+","+(i.plan_y??"")+","+(i.plan_scale??"")+","+(i.plan_scale_x??"")+","+(i.plan_scale_y??"")+","+(i.plan_angle??"")+","+(i.rooms?.length||0)+","+(i.openings?.length||0)+","+(i.decor?.length||0)+";";for(const e of i.rooms||[]){const i=e.poly?.[0],s=e.poly?.[e.poly.length-1];t+=(e.poly?.length||0)+"."+(e.id||"")+"."+(e.open_to||[]).join("+")+"."+(e.area||"")+"."+JSON.stringify(e.settings||0)+"."+(e.x??"")+","+(e.y??"")+","+(e.w??"")+","+(e.h??"")+","+(i?i[0]+"/"+i[1]:"")+","+(s?s[0]+"/"+s[1]:"")+";"}}return t}get _model(){if(!this._serverCfg)return[];const e=this._cfgEpoch+"|"+this._cfgFingerprint();if(this._modelCache&&this._modelCache.key===e)return this._modelCache.model;const t=this._buildModel();return this._modelCache={key:e,model:t},t}_buildModel(){if(!this._serverCfg)return[];const e=this._renderCfg;return Rh(e).map((t,i)=>{const s=e.spaces[i]?.plan_url;return t.bg&&s?{...t,bg:{...t.bg,href:s}}:t})}_spaceModel(){return this._hasFixedFloor?Ud(this._model,this._space):(e=this._model,t=this._space,e.find(e=>e.id===t)??e[0]);var e,t}_spaceModelById(e){return Ud(this._model,e)}_syncEmptySpaceState(){if(!!this._serverCfg&&0===this._serverCfg.spaces.length){if(!this._emptySpaceStateActive){this._emptySpaceStateActive=!0;for(const e of this._pointers.keys())for(const t of this.renderRoot.querySelectorAll("*"))try{t.hasPointerCapture?.(e)&&t.releasePointerCapture(e)}catch{}this._pointers.clear(),this._panStart=null,this._panLock=null,this._pinchStart=null,this._swipeStart=null,this._drag=null,this._rlResize=null,this._vacFit=null,this._compassDrag=!1,this._cancelModeTransition(!1),this._mode="view",this._clearGeometryGesture(),this._geometryHistory.clear(),this._resumeDraftBySpace={},this._tip=null,this._hoverRoom=null,this._openingInfo=null,this._closeInfoCard(),this._deviceInbox=null,this._deviceInboxReturn=null,this._markerDialog=null,this._physicalDialog=null,this._backdropDialog=null,this._decorShapeDialog=null,this._decorTextDialog=null,this._roomDialog=!1,"edit"===this._spaceDialog?.mode&&(this._spaceDialog=null),this._editorSecondary.closeForNavigation(),this._saveConfigDebounced.cancel(),this._frame=null,this._planSnapGeometryCache=null,this._hiddenWallDiagnosticCache=null,this._decorSnapCache=null,this._commitSpace("",!0)}}else this._emptySpaceStateActive=!1}get _areaToSpace(){const e={};for(const t of this._model)for(const i of t.rooms)i.area&&(e[i.area]={space:t.id,room:i});return e}get _settings(){return this._serverCfg?.settings||{}}get _showAll(){return this._showHidden||!this._settings.filter_seeded&&!!this._settings.show_all}_seedHiddenDevices(){if(!this._serverCfg||!this._norm||!this._canEdit)return;const e=this._serverCfg,t=function(e){const t=e.hass,i=e.registry||An(t),s=En(t,i),n=On(t,i),{areaToSpace:o,markers:a,settings:r,excluded:l,iconRules:c}=e,h=!1!==r.group_lights,d=wo(a),p=bo(s,h).filter(e=>!ko(s,e.eid,d)),u=new Set(p.map(e=>e.area)),_=jn(s),m=qn(a,n),g=new Set(a.map(e=>e.binding)),f=[];for(const e of Object.values(s.devices)){const n=e.area_id;if(!n||!o[n])continue;if("service"===e.entry_type)continue;if(g.has("device:"+e.id))continue;if("active"!==Bn(t,"device:"+e.id,i).kind)continue;const a=Wn(s,e.id,_[e.id]||[],m);if(a.partial&&!a.entityIds.length)continue;const r=a.entityIds,d=Un(s,e,r);let p=l.has(d)||"Group"===e.model||/scene/i.test(e.model||"")||/bridge/i.test((e.model||"")+(e.name||""))||"myheat"===d&&!!e.via_device_id;if(!p&&h&&u.has(n)){const t=(e.name_by_user||e.name||"").trim();"mdi:lightbulb"===yo(s,t,e.model,r,c)&&(p=!0)}p&&f.push("device:"+e.id)}return f}({hass:this.hass,registry:this._haRegistry,areaToSpace:Object.fromEntries(Object.entries(this._areaToSpace).map(([e,t])=>[e,t.space])),markers:this._markers,settings:this._settings,excluded:this._excluded,firstSpaceId:this._model[0]?.id||"",iconRules:this._iconRules});if(!t.length&&e.settings?.filter_seeded)return;e.markers=e.markers||[];const i=[];for(const s of t){const t="h"+s.slice(s.indexOf(":")+1);e.markers.push({id:t,binding:s,hidden:!0}),i.push(s.slice(s.indexOf(":")+1))}const s={...e.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(e=>!i.includes(e))),e.settings=s,this._regSignature="",this._maybeRebuildDevices(),this._saveConfig(),this.requestUpdate()}get _iconRules(){const e=this._settings.icon_rules;if(!e||!Array.isArray(e)||!e.length)return;const t=JSON.stringify(e);return t!==this._rulesCompiledSrc&&(this._rulesCompiledSrc=t,this._rulesCompiled=Xe(e)),this._rulesCompiled}get _fillColors(){return ps(this._settings)}get _excluded(){const e=this._settings.exclude_integrations;return e?new Set(e):Ye}willUpdate(e){e.has("_serverCfg")&&this._cfgEpoch++,this._syncEmptySpaceState(),e.has("hass")&&this.hass&&(this._hassSequence++,this._renderSnapshotAt=Date.now(),this._continuity.note("hass-snapshot"),this._ensureHaRegistryAuthority(),this._planHassMemo=null,this._hookConnection(),!this._loadOk&&!this._loading&&this._loadTries<8&&this._loadFromServer(),this._maybeRebuildDevices(),this._vacTick(),this._activityTick()),this._continuity.hasCompleteFrame&&"steady"===this._continuity.state&&this._continuity.refreshCompleteFrame(this._visualFrameFingerprint()),this._captureRenderDeviceSnapshot()}updated(){this._pruneDevicePressFeedback(),this._syncDayCycleClock(),this._warmSnapshot(),this._dtMeasure();const e=this._stageEl;e&&!this._roViewport&&(this._roViewport=new ResizeObserver(()=>this._refitView()),this._roViewport.observe(e)),e&&this._booting&&!this._bootTimer&&this._bootWatch();const t=this.renderRoot.querySelector(".hdr");if(t&&e&&!this._roHdr){const i=()=>{const t=this.renderRoot.querySelector("ha-card");if(!t)return;const i=e.getBoundingClientRect().top-t.getBoundingClientRect().top,s=Math.min(Math.max(t.getBoundingClientRect().top,0),120),n=Math.round(i+s);n>=0&&n!==this._hdrH&&(this._hdrH=n),n>=0&&!this._booting&&!this._config?.kiosk&&e.clientHeight>0&&this._warmPatch({hdrH:n,stageH:e.clientHeight})};this._roHdr=new ResizeObserver(()=>requestAnimationFrame(i)),this._roHdr.observe(t),this._onWinResize=()=>requestAnimationFrame(i),window.addEventListener("resize",this._onWinResize),i()}if(e&&!this._view&&this._refitView(),this._editorSecondary.afterRender(),this._settleContinuityFrame(),this._serverStorage&&this._loadOk&&0===this._model.length&&!this._spaceDialog&&!this._importDialog&&!this._onboardingShown){this._onboardingShown=!0;const e=function(e){const t=e?.floors;if(!t||"object"!=typeof t)return[];const i=[];for(const e of Object.values(t))e&&e.floor_id&&i.push({id:e.floor_id,name:e.name||e.floor_id,level:e.level??null});return i.sort((e,t)=>{const i=e.level??1e9,s=t.level??1e9;return i!==s?i-s:e.name.localeCompare(t.name)}),i}(this.hass);e.length?this._importDialog={floors:e.map(e=>({...e,checked:!0}))}:this._openSpaceDialog("create")}}_adoptStructuralResponses(e,t,i){const s=e?.config,n=s&&Array.isArray(s.spaces)?s:null,o=Bd(n),a=o!==(this._cfgContentFingerprint||Bd(this._serverCfg));if(a&&(this._geometryHistory.clear(),this._pendingPhysicalWrites.clear(),this._serverCfg&&this._clearGeometryGesture(),this._serverCfg=n,this._cfgContentFingerprint=o),this._cfgRev=e?.rev??this._cfgRev,e&&("virtual_lights"in e||"config"in e)){const t=gn(this._virtualLights,e.virtual_lights,this._cfgRev,"virtual_lights"in e);vn(t)!==vn(this._virtualLights)&&(this._virtualLights=t,this._capturedSnapshotVirtual="")}let r=!1;if(void 0!==t||void 0!==i){const e=i??t?.layout??{},s=Bd(e);r=s!==(this._layoutContentFingerprint||Bd(this._layout)),r&&(this._layout=e,this._layoutContentFingerprint=s),this._layoutRev=t?.rev??this._layoutRev}return this._canOptimizeUndo=!(!e?.can_optimize_undo&&!t?.can_optimize_undo),this._haIntegrationVersion="string"==typeof e?.integration_version?e.integration_version:this._haIntegrationVersion,this._undoKind=e?.undo_kind||t?.undo_kind||null,"boolean"==typeof e?.can_write&&(this._serverCanWrite=e.can_write),a&&this._continuity.note("config-candidate",{configRev:this._cfgRev}),r&&this._continuity.note("layout-candidate",{layoutRev:this._layoutRev}),{configChanged:a,layoutChanged:r}}_resumePendingNavMode(){if(!this._pendingNavMode||!this._canEdit||this._config?.kiosk)return!1;const e=this._pendingNavMode;return this._pendingNavMode=null,this._setMode(e,!1),!0}async _loadFromServer(){this._loading=!0,this._loadTries++;const e=this._space,t=!!this._view;try{const[i,s]=await Promise.all([this.hass.callWS({type:"houseplan/config/get"}),this.hass.callWS({type:"houseplan/layout/get"})]),n=i?.config&&Array.isArray(i.config.spaces)?i.config:null,o=Bd(n)!==(this._cfgContentFingerprint||Bd(this._serverCfg))||Bd(s?.layout??{})!==(this._layoutContentFingerprint||Bd(this._layout));if(o){if(!await this._signer.prepareImage(this.hass,this._candidateBackdrop(n)))return this._continuity.note("asset-failed"),void this._scheduleLoadRetry(!0)}o&&this._continuity.hasCompleteFrame&&"steady"===this._continuity.state&&this._beginContinuityCandidate("structural-response",!0),this._connectionWasLost=!1,this._serverStorage=!0,"boolean"==typeof i?.can_write&&(this._serverCanWrite=i.can_write),this._canOptimizeUndo=!(!i?.can_optimize_undo&&!s?.can_optimize_undo),this._haIntegrationVersion="string"==typeof i?.integration_version?i.integration_version:this._haIntegrationVersion,this._adoptStructuralResponses(i,s),this._adoptInitialSpace(this._model,!0),this._resumePendingNavMode(),this._cacheSnapshot(),this._warmVpArmed&&this._space===this._warmVp?.space?this._warmVpArmed=!1:t&&this._space===e||this._restoreZoom(),this._loadOk=!0,this.hass.callWS({type:"houseplan/trail/get"}).then(e=>{this._vacSrvTrails=e?.trails||{},this.requestUpdate()}).catch(()=>{}),this._ensureLiveSyncSubscriptions()}catch(e){if(this._serverCfg)this._scheduleLoadRetry(!0);else if(this._loadTries>=8){this._serverStorage=!1;try{this._layout=JSON.parse(localStorage.getItem(kv)||"{}")||{}}catch{this._layout={}}}}finally{this._loading=!1,this._continuityDataReady=!0,this._regSignature="",this._maybeRebuildDevices(),this.requestUpdate()}}_ensureLiveSyncSubscriptions(){const e=this.hass?.connection;if(!e)return;if(e!==this._liveSyncConnection&&(this._unsubCfg?.(),this._unsubCfg=null,this._unsubLayout?.(),this._unsubLayout=null,this._unsubTrail?.(),this._unsubTrail=void 0,this._unsubVirtual?.(),this._unsubVirtual=null,this._liveSyncGeneration++,this._liveSyncAttempt=null,this._liveSyncConnection=e),this._liveSyncAttempt)return;const t=this._liveSyncGeneration,i=[],s=(s,n,o,a)=>{s()||i.push(async()=>{const i=await e.subscribeEvents(a,o);t===this._liveSyncGeneration&&this.isConnected&&this.hass?.connection===e&&!s()?n(i):i?.()})};if(s(()=>this._unsubCfg,e=>{this._unsubCfg=e},"houseplan_config_updated",e=>{const t=Number(e?.data?.rev??-1);t!==this._cfgRev&&this._reloadConfigOnly(!1,t)}),s(()=>this._unsubTrail,e=>{this._unsubTrail=e},"houseplan_trail_updated",async()=>{try{const e=await this.hass.callWS({type:"houseplan/trail/get"});this._vacSrvTrails=e?.trails||{},this.requestUpdate()}catch{}}),s(()=>this._unsubLayout,e=>{this._unsubLayout=e},"houseplan_layout_updated",e=>this._onLayoutEvent(Number(e?.data?.rev??-1))),s(()=>this._unsubVirtual,e=>{this._unsubVirtual=e},"houseplan_virtual_light_updated",e=>{const t=wn(this._virtualLights,e?.data);t!==this._virtualLights&&(this._virtualLights=t,this._capturedSnapshotVirtual="",this._cacheSnapshot(),this.requestUpdate())}),!i.length)return;const n=function(e){return Promise.allSettled(e.map(e=>Promise.resolve().then(e)))}(i).then(()=>{});this._liveSyncAttempt=n,n.finally(()=>{this._liveSyncAttempt===n&&(this._liveSyncAttempt=null)})}async _reloadConfigOnly(e=!1,t){if(!e){if(void 0!==t&&t<=this._cfgRev)return;if(this._saveConfigDebounced.pending()&&this._saveConfigDebounced.flush(),this._cfgWriting)return clearTimeout(this._reloadRetry),void(this._reloadRetry=window.setTimeout(()=>this._reloadConfigOnly(!1,t),400))}this._beginContinuityCandidate("config-reload",!1);try{const e=await this.hass.callWS({type:"houseplan/config/get"}),t=e?.config&&Array.isArray(e.config.spaces)?e.config:null;if(Bd(t)!==(this._cfgContentFingerprint||Bd(this._serverCfg))&&!await this._signer.prepareImage(this.hass,this._candidateBackdrop(t)))return this._continuity.note("asset-failed"),void this._scheduleLoadRetry(!0);const i=this._space;this._adoptStructuralResponses(e),this._adoptInitialSpace(this._model,!0),this._resumePendingNavMode(),this._cacheSnapshot(),this._space!==i&&this._restoreZoom(),this._regSignature="",this._maybeRebuildDevices(),this.requestUpdate()}catch(e){this._showToast(this._t("toast.cfg_reload_failed",{err:this._errText(e)}))}finally{this._continuityDataReady=!0,this.requestUpdate()}}_scheduleLoadRetry(e=!1){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,!e&&this._loadOk||this._loading||!this.hass||this._loadFromServer()},t)}_ensureHaRegistryAuthority(){const e=this.hass?.connection||null;e&&e!==this._haRegistryConnection&&(this._haRegistryRelease?.(),this._haRegistryConnection=e,this._haRegistryRev=-1,this._haBindingCacheKey="",this._planHassMemo=null,this._haRegistryRelease=Rn(this.hass,this._onHaRegistryUpdate),this._onHaRegistryUpdate())}get _haRegistry(){return An(this.hass)}get _planHass(){const e=this._haRegistry,t=Fn(this.hass,e),i=this._planHassMemo;if(i&&i.hass===this.hass&&i.sig===t)return i.active;const s=En(this.hass,e),n=On(this.hass,e);return this._planHassMemo={hass:this.hass,sig:t,active:s,full:n},s}_captureRenderDeviceSnapshot(){if(!this.hass)return;const e=Date.now(),t=[...this._activityRt.entries()].map(([t,i])=>`${t}:${i.gen}:${i.flashTs}:`+(i.flashKind&&(i.expiresAt||i.flashTs+nm)>e?1:0)).join("|"),i=vn(this._virtualLights);if(this._capturedSnapshotSequence===this._hassSequence&&this._capturedSnapshotDevices===this._devices&&this._capturedSnapshotLayout===this._layout&&this._capturedSnapshotConfigEpoch===this._cfgEpoch&&this._capturedSnapshotVirtual===i&&this._capturedSnapshotActivity===t)return;const s=this._planHass,n=new Map,o=new Map,a=new Set(["sun.sun"]);this._vacFit?.source&&a.add(this._vacFit.source);const r=new Set,l=new Set,c=e=>{if(!e)return;const t=e.indexOf(":");if(t<0)return void a.add(e);const i=e.slice(0,t),s=e.slice(t+1);"device"===i?r.add(s):"entity"===i&&a.add(s)};for(const e of this._model)for(const t of e.rooms)t.area&&l.add(t.area),c(t.settings?.temp_source),c(t.settings?.hum_source);for(const e of this._serverCfg?.spaces||[])for(const t of e.openings||[])for(const e of gi(t))a.add(e);for(const e of this._serverCfg?.spaces||[])for(const t of e.decor||[])if("text"===t.kind){for(const e of String(t.text||"").matchAll(/\{([^{}\r\n]+)\}/g)){const t=Yi(e[1]);t?.entity&&a.add(t.entity)}t.entity&&a.add(t.entity),o.set(`decor:${e.id}:${t.id}`,es(t.text,t,s,e=>!!s.entities?.[e]&&!!s.states?.[e]&&!ko(s,e,wo(this._markers))))}const h=ho(s,this._devices,null,this._virtualLights);for(const e of this._devices){for(const t of[!1,!0])n.set(I_(e.id,t),C_(s,e,{liveStates:!1!==this._config?.live_states,showTemperature:!1!==this._config?.show_temperature,showSignal:t,activityRuntime:this._activityRt.get(e.id),sourceDetails:!1,lightDevices:this._devices,lightSources:h,registryHass:this._fullRegistryHass,reducedMotion:this._reducedMotion}));if(this._isVacDev(e)){const t=this._vacSource(e,s),i=t?np(s?.states?.[t]?.attributes):null,n=this._vacRt.get(e.id);o.set(`vacuum:${e.id}`,{source:t,telemetry:i,mapId:i?this._vacMapId(e,i,s):null,runtime:n?{trail:n.trail,lastTs:n.lastTs,moving:n.moving,jump:n.jump}:null,server:this._vacSrvTrails[e.id]||null})}}const d=T_({sourceSequence:this._hassSequence,hass:s,devices:this._devices,presentations:n,positions:(p=this._model.length>0,u=this._devices,_=e=>this._livePos(e),p?new Map(u.map(e=>[e.id,_(e)])):new Map),facts:o,entityIds:a,deviceIds:r,areaIds:l});var p,u,_;this._capturedSnapshotSequence=this._hassSequence,this._capturedSnapshotDevices=this._devices,this._capturedSnapshotLayout=this._layout,this._capturedSnapshotActivity=t,this._capturedSnapshotConfigEpoch=this._cfgEpoch,this._capturedSnapshotVirtual=i,this._visibleDeviceSnapshot&&"steady"!==this._continuity.state?this._candidateDeviceSnapshot=d:(this._visibleDeviceSnapshot=d,this._candidateDeviceSnapshot=null)}get _renderDeviceSnapshot(){return this._stagedDeviceSnapshotToken===this._continuity.token?this._candidateDeviceSnapshot||this._visibleDeviceSnapshot:this._visibleDeviceSnapshot||this._candidateDeviceSnapshot}get _renderPlanHass(){return this._renderDeviceSnapshot?.hass||this._planHass}get _renderDevices(){return this._renderDeviceSnapshot?.devices||this._devices}get _fullRegistryHass(){return this._planHass,this._planHassMemo?.full||this.hass}_bindingStatus(e){return Bn(this.hass,e,this._haRegistry)}houseplanDiagnostics(){const e=function(e){const t=An(e);return{access:t.access,authoritative:t.authoritative,revision:t.revision,lastSuccess:t.lastSuccess,error:t.error}}(this.hass),t={active:0,ha_disabled:0,orphaned:0,unverified:0};for(const e of this._markers)e.removed||"virtual"===e.binding||t[this._bindingStatus(e.binding).kind]++;return{registry:{...e,lastSuccessAgeMs:e.lastSuccess?Math.max(0,Date.now()-e.lastSuccess):null},bindings:t}}_openBindingInHa(e){const[t,i]=e.split(":");if(i)if("device"!==t){if("entity"===t){const e=this._fullRegistryHass.entities?.[i];e?.device_id&&Fv("/config/devices/device/"+encodeURIComponent(e.device_id))}}else Fv("/config/devices/device/"+encodeURIComponent(i))}_bindingHasHaPage(e){const[t,i]=e.split(":");return!!i&&("device"===t||"entity"===t&&!!this._fullRegistryHass.entities?.[i]?.device_id)}_toggleMarkerDialogVisibility(){const e=this._markerDialog;if(!e)return;const t="ha"===e.bindingMode?this._bindingStatus(e.binding):null,i=e.hideFromPlan||"ha_disabled"===t?.kind;i&&"ha_disabled"===t?.kind?this._showToast(this._t("entity"===t.reason?"toast.ha_disabled_show_entity":"toast.ha_disabled_show_device")):i&&"unverified"===t?.kind?this._showToast(this._t("toast.ha_binding_unverified")):this._markerDialog={...e,hideFromPlan:!i}}_hookConnection(){const e=this.hass?.connection;e&&e!==this._connHooked&&(this._connHooked?.removeEventListener?.("ready",this._onConnReady),this._connHooked?.removeEventListener?.("disconnected",this._onConnLost),this._connHooked?.removeEventListener?.("reconnect-error",this._onConnLost),e.addEventListener?.("ready",this._onConnReady),e.addEventListener?.("disconnected",this._onConnLost),e.addEventListener?.("reconnect-error",this._onConnLost),this._connHooked=e)}_display(e){return this._signer.display(this.hass,e)}_resign(){this._signer.resign(this.hass,Rs(this._serverCfg))}_onLayoutEvent(e){e<=this._layoutRev||(clearTimeout(this._layoutSyncTimer),this._layoutSyncTimer=window.setTimeout(()=>{e<=this._layoutRev||this._reloadLayoutOnly()},200))}_noteLayoutRev(e){const t=e?.rev;"number"==typeof t&&t>this._layoutRev&&(this._layoutRev=t)}async _reloadLayoutOnly(){if(!this._serverStorage||!this.hass?.callWS)return;this._beginContinuityCandidate("layout-reload",!1);const e=new Map;for(const t of this._dirtyPos)this._layout[t]&&e.set(t,this._layout[t]);this._persistLayout.pending()&&this._persistLayout.flush();for(const[t,i]of this._sentPos)e.set(t,i);try{const t=await this.hass.callWS({type:"houseplan/layout/get"}),i={...t?.layout||{}};for(const[t,s]of e)i[t]=s;const s=Bd(i);s!==(this._layoutContentFingerprint||Bd(this._layout))&&(this._layout=i,this._layoutContentFingerprint=s),this._layoutRev=t?.rev??this._layoutRev,this._canOptimizeUndo=!!t?.can_optimize_undo,this._haIntegrationVersion="string"==typeof t?.integration_version?t.integration_version:this._haIntegrationVersion,this._undoKind=t?.undo_kind||null,this._cacheSnapshot(),this.requestUpdate()}catch{}finally{this._continuityDataReady=!0,this.requestUpdate()}}_maybeRebuildDevices(){const e=this.hass;if(!e?.devices||!e?.entities||!e?.areas)return;const t=this._haRegistry,i=Fn(e,t)+":"+Object.keys(e.areas).length+":"+(this._norm?"n":"l")+":"+ra(e,this._config?.language);if(i===this._regSignature&&this._devices.length)return;this._regSignature=i;const s=new Map(this._devices.map(e=>[e.id,e.bindingStatus?.kind||"active"]));this._devices=So({hass:e,registry:t,areaToSpace:Object.fromEntries(Object.entries(this._areaToSpace).map(([e,t])=>[e,t.space])),markers:this._markers,settings:this._settings,excluded:this._excluded,showAll:this._showAll,firstSpaceId:this._model[0]?.id||"",loc:e=>this._t(e),iconRules:this._iconRules});const n=this._markers.filter(e=>!e.removed&&"virtual"!==e.binding).map(e=>e.binding).sort(),o=t.revision+":"+n.join("|");if(t.authoritative&&o!==this._haBindingCacheKey){const i=new Map;for(const s of n)i.set(s,Bn(e,s,t));!function(e){if("undefined"==typeof localStorage||!e.size)return;const t=Ln(),i=Date.now();for(const[s,n]of e)"active"===n.kind?t[s]={kind:"active",ts:i}:"ha_disabled"===n.kind&&(t[s]={kind:"ha_disabled",reason:n.reason,ts:i});const s=Object.fromEntries(Object.entries(t).sort((e,t)=>t[1].ts-e[1].ts).slice(0,1500));Mn=s;try{localStorage.setItem(Sn,JSON.stringify(s))}catch{}}(i),this._haBindingCacheKey=o}this._defPos=this._defaultPositions(),this._syncNewDevices(),this._seedHiddenDevices(),this._syncActivityRuntime();const a=new Set(this._devices.filter(e=>!e.hidden).map(e=>e.id));for(const e of this._vacRt.keys())a.has(e)||this._vacRt.delete(e);if(this._infoCard){const e=this._devices.find(e=>e.id===this._infoCard.id);this._infoCard=e&&"ha_disabled"!==e.bindingStatus?.kind?e:null}const r=this._devices.some(e=>"ha_disabled"===e.bindingStatus?.kind&&"ha_disabled"!==s.get(e.id));r&&("ha_disabled"!==this._infoCard?.bindingStatus?.kind&&"ha_disabled"!==this._devices.find(e=>e.id===this._infoCard?.id)?.bindingStatus?.kind||this._closeInfoCard(),this._drag&&"ha_disabled"===this._devices.find(e=>e.id===this._drag.id)?.bindingStatus?.kind&&(this._drag=null),clearTimeout(this._holdTimer),this._holdFired=!1,this._tip=null,this._tapConfirm=null),this._nativeMoreInfoEntity&&!this._planEntityAvailable(this._nativeMoreInfoEntity)&&(zv(this,"hass-more-info",{entityId:null}),this._nativeMoreInfoEntity=null)}_syncNewDevices(){if(!this._norm||!this._loadOk||!this._serverCfg)return;const e=this._devices.filter(e=>!e.marker&&!e.virtual).map(e=>e.id).sort(),t=e.join(",");if(t===this._newSyncKey)return;this._newSyncKey=t;const i=this._settings,{fresh:s,known:n}=function(e,t){if(!Array.isArray(t))return{fresh:[],known:[...e]};const i=new Set(t),s=e.filter(e=>!i.has(e));return{fresh:s,known:s.length?[...t,...s]:t}}(e,i.known_devices);if(!Array.isArray(i.known_devices)||s.length){const e=[...new Set([...i.new_device_ids||[],...s])];this._serverCfg={...this._serverCfg,settings:{...i,known_devices:n,new_device_ids:e}},this._saveConfig()}}get _newIds(){const e=this._settings.new_device_ids;return new Set(Array.isArray(e)?e:[])}_ackNewDevice(e){if(!this._newIds.has(e)||!this._serverCfg)return;const t=this._settings;this._serverCfg={...this._serverCfg,settings:{...t,new_device_ids:(t.new_device_ids||[]).filter(t=>t!==e)}},this._saveConfig(),this.requestUpdate()}get _markers(){return this._serverCfg?.markers||[]}_roomLqi(e){if(!e)return null;const t=[];for(const i of this._renderDevices){if(i.area!==e||i.virtual)continue;const s=_o(this._renderPlanHass,i.entities);null!=s&&t.push(s)}return Ni(t)}_roomBounds(e){if(e.poly&&e.poly.length){const t=e.poly.map(e=>e[0]),i=e.poly.map(e=>e[1]),s=Math.min(...t),n=Math.min(...i);return{x:s,y:n,w:Math.max(...t)-s,h:Math.max(...i)-n}}return{x:e.x??0,y:e.y??0,w:e.w??0,h:e.h??0}}_defaultPositions(){const e={},t=this._config?.icon_size??2.5;for(const i of this._model){const s=t/100*Qh(i)*1.3;for(const t of i.rooms){if(!t.area)continue;const n=this._devices.filter(e=>e.area===t.area&&e.space===i.id);if(!n.length)continue;const o=this._roomBounds(t),a=.1*Math.min(o.w,o.h),r=o.w-2*a,l=o.h-2*a,c=Math.max(1,Math.round(Math.sqrt(n.length*r/Math.max(l,1)))),h=Math.ceil(n.length/c),d=r/c,p=l/Math.max(h,1),u=n.map((e,t)=>({x:o.x+a+d*(t%c+.5),y:o.y+a+p*(Math.floor(t/c)+.5)}));Oi(u,o,s,.5*a),n.forEach((t,i)=>e[t.id]=Hh(u[i]))}}return e}_pos(e){const t=this._renderDeviceSnapshot?.positions.get(e.id);return t?{x:t.x,y:t.y}:this._livePos(e)}_livePos(e){const t=this._spaceModelById(e.space),i=this._layout[e.id];if(i)if(this._norm){if(i.s===e.space)return{x:i.x*Pv,y:i.y*Pv}}else if(void 0===i.s)return{x:i.x,y:i.y};return this._defPos[e.id]?this._defPos[e.id]:t?Hh(Zh(t)):{x:500,y:500}}_savePos(e,t,i){if(this._spaceModelById(e.space)){if(this._norm){const s=this._gridPitch,n=Math.round(t/s)*s,o=Math.round(i/s)*s,a=this._layout[e.id]?.k;this._layout={...this._layout,[e.id]:{s:e.space,x:Bh(n/Pv),y:Bh(o/Pv),...a?{k:a}:{}}}}else this._layout={...this._layout,[e.id]:{x:Math.round(t),y:Math.round(i)}};this._dirtyPos.add(e.id),this._persistLayout()}}_visualSamples(e){return k_(this._renderPlanHass,e,this._renderDevices,void 0,this._fullRegistryHass).samples}_devicePresentation(e,t=!1!==this._config?.show_signal,i=!1){const s=i?null:this._renderDeviceSnapshot?.presentations.get(I_(e.id,t));return s||C_(this._renderPlanHass,e,{liveStates:!1!==this._config?.live_states,showTemperature:!1!==this._config?.show_temperature,showSignal:t,designPreview:i,activityRuntime:this._activityRt.get(e.id),sourceDetails:!1,lightDevices:this._renderDevices,registryHass:this._fullRegistryHass,reducedMotion:this._reducedMotion})}_deviceVisual(e){return this._devicePresentation(e).visual}_stateClass(e,t=this._deviceVisual(e)){const i=this._devicePresentation(e);return i.effectiveHidden?"":("icon_ripple"!==i.display||!1===this._config?.live_states||"alarm"===t.status||t.activity,M_({...i,visual:t}).join(" "))}_liveTemp(e){if(!this._config?.show_temperature)return null;if(!0===e.marker?.use_climate_temp){const t=go(this._renderPlanHass,e.entities);if(null!=t)return t}return"mdi:thermometer"!==e.icon&&"mdi:air-filter"!==e.icon?null:mo(this._renderPlanHass,e.entities)}_bindingEntities(e){if("virtual"===e||!e)return[];const t=this._bindingStatus(e);return"active"===t.kind?t.enabledEntityIds:t.allEntityIds}_bindingHasClimate(e){return this._bindingEntities(e).some(e=>e.startsWith("climate."))}_bindingHasAlarm(e){return this._bindingEntities(e).some(e=>{const t=this._planHass?.states?.[e]||this.hass?.states?.[e],i=this._fullRegistryHass.entities[e]||this.hass?.entities?.[e];return Bs(e.split(".")[0],t?.attributes?.device_class||i?.device_class||i?.original_device_class)})}_liveHum(e){return this._config?.show_temperature&&e.primary&&fo(this.hass,e.primary)?vo(this.hass,e.entities):null}_deviceBindingActive(e,t=!0){if(e.virtual||"virtual"===e.bindingKind)return!0;if(!e.bindingKind||!e.bindingRef)return!1;const i=this._bindingStatus(`${e.bindingKind}:${e.bindingRef}`);return"active"===i.kind||(t&&this._showToast(this._t("ha_disabled"===i.kind?"toast.ha_disabled_action":"toast.ha_binding_unverified")),!1)}_openMoreInfo(e){e?this._planEntityAvailable(e)?(this._nativeMoreInfoEntity=e,zv(this,"hass-more-info",{entityId:e})):this._showToast(this._t("toast.ha_disabled_action")):this._showToast(this._t("toast.no_entity"))}_interruptViewGesture(e,t){if(clearTimeout(this._holdTimer),clearTimeout(this._kioskHoldTimer),void 0!==e)for(const i of[t,this._stageEl])try{i?.hasPointerCapture?.(e)&&i.releasePointerCapture(e)}catch{}this._pointers.clear(),this._panStart=null,this._panLock=null,this._pinchStart=null,this._swipeStart=null}_closeInfoCard(){this._interruptViewGesture(),this._holdFired=!1,this._infoCard=null}_ctxDevice(e,t){"view"===this._mode&&(e.preventDefault(),e.stopPropagation(),this._deviceBindingActive(t)&&(t.primary?this._openMoreInfo(t.primary):this._infoCard=t))}_clickDevice(e,t){if(e.stopPropagation(),this._drag?.moved||this._suppressClick||this._holdFired)return;if("plan"===this._mode)return;if("devices"===this._mode)return void this._openMarkerDialog(t);const i=this._devices.find(e=>e.id===t.id);if(!i)return;const s=Op(i.tapAction,i.primary?.split(".")[0]),n=(e,t)=>{i.marker?.tap_confirm?this._tapConfirm={kind:"run",text:e,exec:t}:t()};if("toggle"===s){const e=this._toggleIntent(i);if(!e)return;if(!Wp(e))return void this._showUnavailableToggleTargets(e);const t=e=>{const t=Wp(e);if(!t)return;if("virtual-light"===t.kind)return this._startDevicePressFeedback(i.id),void this.hass.callWS({type:"houseplan/virtual_light/toggle",marker_id:t.markerId}).then(e=>{const t=wn(this._virtualLights,e);t!==this._virtualLights&&(this._virtualLights=t,this._capturedSnapshotVirtual="",this._cacheSnapshot(),this.requestUpdate())}).catch(e=>this._showToast(this._t("toast.virtual_light_toggle_failed",{err:this._errText(e)})));const{command:s}=t;this._startDevicePressFeedback(i.id),this.hass.callService(s.domain,s.service,s.data).catch(e=>this._showToast(this._t("toast.error",{err:this._errText(e)})))},s=((o=e).targets.length?o.targets:o.skippedTargets).map(e=>e.name||e.entityId||e.ref).join(", ")||i.name;if(i.marker?.tap_confirm){const n=this._toggleConfirmationLines(e);if(!n.length)return;this._tapConfirm={kind:"toggle",text:this._t("confirm.tap_toggle",{name:s}),lines:n,initialIntent:e,deviceId:i.id,exec:()=>{const s=this._devices.find(e=>e.id===i.id),n=s?this._toggleIntent(s):null;n&&!Wp(n)&&this._showUnavailableToggleTargets(n)||(n&&Gp(e,n)?t(n):this._showToast(this._t("toast.tap_target_changed")))}}}else t(e);return}var o;if("info"===s)return this._interruptViewGesture(),void(this._infoCard=i);if(this._deviceBindingActive(i)){if("run"===s){const e=i.marker?.tap_target||"",t=function(e){const t=String(e||"").split(".")[0];return"automation"===t?{domain:"automation",service:"trigger"}:"script"===t?{domain:"script",service:"turn_on"}:"scene"===t?{domain:"scene",service:"turn_on"}:null}(e),s=this.hass.states[e];if(!t||!s)return void this._showToast(this._t("toast.run_target_missing"));const o=s.attributes?.friendly_name||e;return void n(this._t("confirm.tap_run",{name:o}),()=>{this._deviceBindingActive(i)&&this._planEntityAvailable(e)&&(this._startDevicePressFeedback(i.id),this.hass.callService(t.domain,t.service,{entity_id:e}).then(()=>{this._stampActivity(i.id,"event",this._activitySourceKey(i)),this.requestUpdate(),this._showToast(this._t("toast.run_started",{name:o}))}).catch(e=>this._showToast(this._t("toast.error",{err:this._errText(e)}))))})}"more-info"===s&&i.primary?this._openMoreInfo(i.primary):this._infoCard=i}}_showUnavailableToggleTargets(e){const t=function(e){if(!e||"group"!==e.kind||Wp(e)||"configured-targets-missing"!==e.noneReason)return[];if(!e.skippedTargets.length||e.skippedTargets.some(e=>!Up.has(e.reason)&&"secure"!==e.reason))return[];const t=[],i=new Set;for(const s of e.skippedTargets){if(!Up.has(s.reason))continue;const e=String(s.name||s.entityId||s.ref||"").trim();e&&!i.has(e)&&(i.add(e),t.push(e))}return t}(e);return!!t.length&&(this._showToast(1===t.length?this._t("toast.toggle_target_unavailable",{name:t[0]}):this._t("toast.toggle_targets_unavailable",{names:t.join(", ")})),!0)}_keyDevice(e,t){"Enter"!==e.key&&" "!==e.key||"view"!==this._mode&&"devices"!==this._mode||(e.preventDefault(),this._clickDevice(e,t))}_startDevicePressFeedback(e){const t=[...this.renderRoot.querySelectorAll(".dev[data-id]")].find(t=>t.dataset.id===e),i=t?.querySelector(".device-shell");if(!i||"function"!=typeof i.animate)return;const s=Number.parseFloat(this.ownerDocument.defaultView?.getComputedStyle(i).scale||""),n=Number.isFinite(s)?Math.max(.95,Math.min(1,s)):1;this._devicePressAnimations.get(e)?.cancel();const o=this._reducedMotion?[{outlineColor:"transparent",outlineStyle:"solid",outlineWidth:"0px"},{outlineColor:"var(--hp-accent, #3ea6ff)",outlineStyle:"solid",outlineWidth:"2px",outlineOffset:"2px",offset:.5},{outlineColor:"transparent",outlineStyle:"solid",outlineWidth:"0px"}]:[{scale:String(n)},{scale:"0.95",offset:.5},{scale:"1"}],a=i.animate(o,{duration:200,easing:"cubic-bezier(.22,.61,.36,1)"});this._devicePressAnimations.set(e,a);const r=()=>{this._devicePressAnimations.get(e)===a&&this._devicePressAnimations.delete(e)};a.addEventListener("finish",r,{once:!0}),a.addEventListener("cancel",r,{once:!0})}_cancelDevicePressFeedback(){for(const e of this._devicePressAnimations.values())e.cancel();this._devicePressAnimations.clear()}_pruneDevicePressFeedback(){if(!this._devicePressAnimations.size)return;const e=new Set([...this.renderRoot.querySelectorAll(".dev[data-id]")].map(e=>e.dataset.id||""));for(const[t,i]of this._devicePressAnimations)e.has(t)||(i.cancel(),this._devicePressAnimations.delete(t))}_t(e,t){return la(ra(this.hass,this._config?.language),e,t)}get _colorPickerLabels(){return{title:this._t("color_picker.title"),hue:this._t("color_picker.hue"),saturation:this._t("color_picker.saturation"),value:this._t("color_picker.value"),hex:this._t("color_picker.hex"),invalidHex:this._t("color_picker.invalid_hex")}}_help(e){const t=`${e}.aria`,i=ra(this.hass,this._config?.language);return ca(i,e)&&ca(i,t)?q``:G}get _stageEl(){return this.renderRoot.querySelector(".stage")}_contentItems(e){const t=[];for(const i of this._devices){if(i.space!==e.id||i.hidden)continue;const s=this._pos(i);t.push({minX:s.x,minY:s.y,maxX:s.x,maxY:s.y})}if(e.id===this._space){for(const e of this._openingsR){const i=Number(e.angle)*Math.PI/180,s=Math.cos(i)*e.rlen/2,n=Math.sin(i)*e.rlen/2,o=Wh([[e.rx-s,e.ry-n],[e.rx+s,e.ry+n]]);o&&t.push(o)}const i=this._decorH;for(const e of this._decorList){const s=Wh("line"===e.kind?[[e.x1*Pv,e.y1*i],[e.x2*Pv,e.y2*i]]:"text"===e.kind?[[e.x*Pv,e.y*i]]:Wr({x:e.x*Pv,y:e.y*i,w:e.w*Pv,h:e.h*i,angle:e.angle}));s&&t.push(s)}for(const i of this._physicalBodiesR(e)){const e=Wh(i);e&&t.push(e)}}return Gh(e,t)}_frameOf(){const e=this._spaceModel();if(!e){this._frame=null;const e={x:0,y:0,w:Pv,h:Pv};return{rect:e,all:e,outliers:0}}const t=this._frame,i="view"!==this._mode;if(t&&t.id===e.id&&this._bdDrag)return t;if(t&&t.id===e.id&&t.model===e&&t.layout===this._layout&&t.devs===this._devices&&t.far===this._showFar&&t.grow===i)return t;const s=Jh(this._contentItems(e));let n=s.all||Xh(e),o=this._showFar?n:s.core||Xh(e);return t&&t.id===e.id&&i&&t.grow&&(o=Iv(t.rect,o),n=Iv(t.all,n)),this._frame={id:e.id,model:e,layout:this._layout,devs:this._devices,far:this._showFar,grow:i,rect:o,all:n,outliers:s.outliers},this._frame}_isoSource(){const e=this._spaceModel();if(!e)return null;const t=this._spaceWalls,i=this._openCuts(),s=this._openingsR.map((e,t)=>({id:String(e.id||t),sourceIndex:t,type:e.type,x:e.rx,y:e.ry,angle:Number(e.angle)||0,length:e.rlen>0?e.rlen:900,flipH:!!e.flip_h,flipV:!!e.flip_v})),n=xh(64,this._cellCm),o=xh(10,this._cellCm),a=`${e.id}|${function(e){let t=2166136261;const i=e=>{if("number"!=typeof e)if("string"!=typeof e)if("boolean"!=typeof e)if(Array.isArray(e)){t=zf(t,e.length);for(const t of e)i(t)}else{if(e&&"object"==typeof e){const t=e;for(const e of Object.keys(t).sort())i(e),i(t[e]);return}t=zf(t,-1)}else t=zf(t,e?1:0);else for(const i of e)t=zf(t,i.codePointAt(0)||0);else t=zf(t,e)};return i(e),t.toString(36)}({rooms:e.rooms,walls:t,openCuts:i,openings:s,partitions:e.partitions,roomDrafts:e.room_drafts,columns:e.wall_columns,cellCm:this._cellCm,gridPitch:this._gridPitch,wallKeyPitch:this._wallKeyPitch,camera:kf,wallHeight:n,floorEdgeHeight:o,algorithm:3})}`;return{key:a,build:()=>{const o=ch(e,this._cellCm,this._gridPitch,2e-4*this._gridPitch,this._partitionOpeningCuts(e)).all,a=this._roomWallOpeningInputs(this._openingsR,e),r=t.length||o.length?Oc(e.rooms,t,i,a,this._wallKeyPitch,this._cellCm,this._gridPitch,Pv,o):null;if(r&&("failed-core"===r.status||"not-applicable"===r.status))throw new Error("wall boolean geometry failed");const l=r?.paperGeom??zc(e.rooms,t,i,this._wallKeyPitch,this._cellCm,this._gridPitch,Pv);if(!l)throw new Error("floor boolean geometry failed");const c=r?.openingIndex||qc(e.rooms,t,i,this._wallKeyPitch,this._cellCm,this._gridPitch,Pv),h=s.map(e=>{const i=this._openingsR[e.sourceIndex],s="gate"===e.type?!e.flipV:e.flipV,o=i?.partitionHost?eu(i.partitionHost,s):t.length||"gate"===e.type?Vc(c,{x:e.x,y:e.y,angle:e.angle,length:e.length,flip_v:s}):{ox:0,oy:0,cm:0,side:-1};return function(e,t=64){if(!(Ff([e.x,e.y,e.angle,e.length,e.face.ox,e.face.oy,t])&&e.length>0&&t>0))throw new Error("invalid isometric opening input");const i=e.length/2;let s;if("passage"===e.type)s=[];else if("gate"===e.type){const n=10*e.face.side;s=[Ef(e,0,[-i,0],[i,0],n,0,.88*t),Ef(e,1,[i,0],[-i,0],-n,0,.88*t)]}else s="window"===e.type?[Ef(e,0,[-i,0],[i,0],-90,.27*t,.78*t),Ef(e,1,[i,0],[-i,0],90,.27*t,.78*t)]:[Ef(e,0,[-i,0],[e.length,0],-90,0,.92*t)];return{id:e.id,sourceIndex:e.sourceIndex,type:e.type,leaves:Object.freeze(s.map(e=>Object.freeze(e)))}}({...e,face:o},n)});return{walls:r?.components.flatMap(e=>e.geom)||[],floor:l,openings:Object.freeze(h)}}}}_isoSceneKey(){if(!this._labsIso||"view"!==this._mode)return null;try{return this._isoSource()?.key??null}catch{return`${this._space}|invalid`}}_isoScene(){const e=this._isoSource();if(!e)return null;const t=this._isoGeometryCache.get(e.key);if(t)return{key:e.key,...t};const i=this._frameOf().rect,s=e.build(),n=xh(64,this._cellCm),o=xh(10,this._cellCm),a=function(e){let t=1/0,i=1/0,s=-1/0,n=-1/0;for(const o of e)for(const e of o.leaves){const o=Math.hypot(e.closedVector[0],e.closedVector[1]);t=Math.min(t,e.hinge[0]-o),i=Math.min(i,e.hinge[1]-o),s=Math.max(s,e.hinge[0]+o),n=Math.max(n,e.hinge[1]+o)}return Ff([t,i,s,n])?{x:t,y:i,w:s-t,h:n-i}:null}(s.openings),r=Cf({rect:a?Iv(i,a):i,wallHeight:n,openingHeight:n,floorDepth:o}),l=function(e,t=kf,i=64){if(!Number.isFinite(i)||i<0)throw new Error("invalid wall height");const s=[],n=[],o=[];let a=0;for(let r=0;r<(e||[]).length;r++){const l=e[r];for(let e=0;e<(l||[]).length;e++){const c=Tf(l[e],e>0);if(!(c.length<3||Math.abs(Pf(c))<1e-9)){s.push(If(c,t,i)),a+=c.length;for(let s=0;se.depth-t.depth||e.polygon-t.polygon||e.ring-t.ring||e.edge-t.edge),{topPath:s.join(" "),sides:n,contactPath:o.join(" "),edgeCount:a}}(s.walls,kf,n),c={geometry:l,floor:Af(s.floor,o),openings:s.openings,frame:r};return fv(this._isoGeometryCache,e.key,c,8),{key:e.key,...c}}_effectiveProjection(){if("iso"!==this._desiredProjection||!this._model.length)return"flat";const e=this._isoSceneKey()||`${this._space}|invalid`;if(this._isoFallback.has(e))return"flat";try{const e=this._isoScene();return e?(t="iso",i=e.key,s=this._isoFallback,"iso"===t&&i&&!s.has(i)?"iso":"flat"):"flat"}catch(t){if(!this._isoFallback.has(e)){this._isoFallback.add(e);const i=e.split("|");console.warn(`HOUSEPLAN ISO FALLBACK: #89, space ${this._space}, fingerprint ${i[i.length-1]}, ${t instanceof Error?t.message:"renderer error"}`)}return"flat"}var t,i,s}_scenePoint(e){return"iso"===this._renderProjection?$f(e,0):e}_floorView(e){if("iso"!==this._renderProjection)return e;const t=Sf([e.x,e.y]),i=Sf([e.x+e.w,e.y+e.h]);return{x:t[0],y:t[1],w:i[0]-t[0],h:i[1]-t[1]}}_baseVb(){if("iso"===this._effectiveProjection()){if(!this._spaceDisplayForRender().showBorders){const e=Cf({rect:this._frameOf().rect,wallHeight:xh(64,this._cellCm)});return[e.x,e.y,e.w,e.h]}const e=this._isoScene()?.frame??this._frameOf().rect;return[e.x,e.y,e.w,e.h]}const e=this._frameOf().rect;return[e.x,e.y,e.w,e.h]}get _outliers(){return this._showFar?0:this._frameOf().outliers}_fitFar(){this._showFar=!0,this._frame=null,this._resetZoom()}_fitAll(){this._showFar=!0,this._frame=null,this._resetZoom()}_renderFarHint(){return this._kiosk||"view"!==this._mode||this._booting||!this._outliers?G:q`
+
`}houseplanContinuityTrace(){return[...this._continuityHistory,...this._continuity.trace].slice(-80).map(e=>({...e,...e.stage?{stage:[...e.stage]}:{}}))}getCardSize(){return 12}get _norm(){return!(!this._serverCfg||!this._serverCfg.spaces.length)}_cfgFingerprint(){const e=this._serverCfg?.spaces||[];let t=e.length+":";for(const i of e){t+=(i.id||"")+","+(i.plan_aspect||"")+","+(i.plan_url||"").length+","+(i.plan_x??"")+","+(i.plan_y??"")+","+(i.plan_scale??"")+","+(i.plan_scale_x??"")+","+(i.plan_scale_y??"")+","+(i.plan_angle??"")+","+(i.rooms?.length||0)+","+(i.openings?.length||0)+","+(i.decor?.length||0)+";";for(const e of i.rooms||[]){const i=e.poly?.[0],s=e.poly?.[e.poly.length-1];t+=(e.poly?.length||0)+"."+(e.id||"")+"."+(e.open_to||[]).join("+")+"."+(e.area||"")+"."+JSON.stringify(e.settings||0)+"."+(e.x??"")+","+(e.y??"")+","+(e.w??"")+","+(e.h??"")+","+(i?i[0]+"/"+i[1]:"")+","+(s?s[0]+"/"+s[1]:"")+";"}}return t}get _model(){if(!this._serverCfg)return[];const e=this._cfgEpoch+"|"+this._cfgFingerprint();if(this._modelCache&&this._modelCache.key===e)return this._modelCache.model;const t=this._buildModel();return this._modelCache={key:e,model:t},t}_buildModel(){if(!this._serverCfg)return[];const e=this._renderCfg;return Eh(e).map((t,i)=>{const s=e.spaces[i]?.plan_url;return t.bg&&s?{...t,bg:{...t.bg,href:s}}:t})}_spaceModel(){return this._hasFixedFloor?Jd(this._model,this._space):(e=this._model,t=this._space,e.find(e=>e.id===t)??e[0]);var e,t}_spaceModelById(e){return Jd(this._model,e)}_syncEmptySpaceState(){if(!!this._serverCfg&&0===this._serverCfg.spaces.length){if(!this._emptySpaceStateActive){this._emptySpaceStateActive=!0;for(const e of this._pointers.keys())for(const t of this.renderRoot.querySelectorAll("*"))try{t.hasPointerCapture?.(e)&&t.releasePointerCapture(e)}catch{}this._pointers.clear(),this._panStart=null,this._panLock=null,this._pinchStart=null,this._swipeStart=null,this._drag=null,this._rlResize=null,this._vacFit=null,this._compassDrag=!1,this._cancelModeTransition(!1),this._mode="view",this._clearGeometryGesture(),this._geometryHistory.clear(),this._resumeDraftBySpace={},this._tip=null,this._hoverRoom=null,this._openingInfo=null,this._closeInfoCard(),this._deviceInbox=null,this._deviceInboxReturn=null,this._markerDialog=null,this._physicalDialog=null,this._backdropDialog=null,this._decorShapeDialog=null,this._decorTextDialog=null,this._roomDialog=!1,"edit"===this._spaceDialog?.mode&&(this._spaceDialog=null),this._editorSecondary.closeForNavigation(),this._saveConfigDebounced.cancel(),this._frame=null,this._planSnapGeometryCache=null,this._hiddenWallDiagnosticCache=null,this._decorSnapCache=null,this._commitSpace("",!0)}}else this._emptySpaceStateActive=!1}get _areaToSpace(){const e={};for(const t of this._model)for(const i of t.rooms)i.area&&(e[i.area]={space:t.id,room:i});return e}get _settings(){return this._serverCfg?.settings||{}}get _showAll(){return this._showHidden||!this._settings.filter_seeded&&!!this._settings.show_all}_seedHiddenDevices(){if(!this._serverCfg||!this._norm||!this._canEdit)return;const e=this._serverCfg,t=function(e){const t=e.hass,i=e.registry||An(t),s=En(t,i),n=On(t,i),{areaToSpace:o,markers:a,settings:r,excluded:l,iconRules:c}=e,h=!1!==r.group_lights,d=wo(a),p=bo(s,h).filter(e=>!ko(s,e.eid,d)),u=new Set(p.map(e=>e.area)),_=jn(s),m=qn(a,n),g=new Set(a.map(e=>e.binding)),f=[];for(const e of Object.values(s.devices)){const n=e.area_id;if(!n||!o[n])continue;if("service"===e.entry_type)continue;if(g.has("device:"+e.id))continue;if("active"!==Bn(t,"device:"+e.id,i).kind)continue;const a=Wn(s,e.id,_[e.id]||[],m);if(a.partial&&!a.entityIds.length)continue;const r=a.entityIds,d=Un(s,e,r);let p=l.has(d)||"Group"===e.model||/scene/i.test(e.model||"")||/bridge/i.test((e.model||"")+(e.name||""))||"myheat"===d&&!!e.via_device_id;if(!p&&h&&u.has(n)){const t=(e.name_by_user||e.name||"").trim();"mdi:lightbulb"===yo(s,t,e.model,r,c)&&(p=!0)}p&&f.push("device:"+e.id)}return f}({hass:this.hass,registry:this._haRegistry,areaToSpace:Object.fromEntries(Object.entries(this._areaToSpace).map(([e,t])=>[e,t.space])),markers:this._markers,settings:this._settings,excluded:this._excluded,firstSpaceId:this._model[0]?.id||"",iconRules:this._iconRules});if(!t.length&&e.settings?.filter_seeded)return;e.markers=e.markers||[];const i=[];for(const s of t){const t="h"+s.slice(s.indexOf(":")+1);e.markers.push({id:t,binding:s,hidden:!0}),i.push(s.slice(s.indexOf(":")+1))}const s={...e.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(e=>!i.includes(e))),e.settings=s,this._regSignature="",this._maybeRebuildDevices(),this._saveConfig(),this.requestUpdate()}get _iconRules(){const e=this._settings.icon_rules;if(!e||!Array.isArray(e)||!e.length)return;const t=JSON.stringify(e);return t!==this._rulesCompiledSrc&&(this._rulesCompiledSrc=t,this._rulesCompiled=Xe(e)),this._rulesCompiled}get _fillColors(){return ps(this._settings)}get _excluded(){const e=this._settings.exclude_integrations;return e?new Set(e):Ye}willUpdate(e){e.has("_serverCfg")&&this._cfgEpoch++,this._syncEmptySpaceState(),e.has("hass")&&this.hass&&(this._hassSequence++,this._renderSnapshotAt=Date.now(),this._continuity.note("hass-snapshot"),this._ensureHaRegistryAuthority(),this._planHassMemo=null,this._hookConnection(),!this._loadOk&&!this._loading&&this._loadTries<8&&this._loadFromServer(),this._maybeRebuildDevices(),this._vacTick(),this._activityTick()),this._continuity.hasCompleteFrame&&"steady"===this._continuity.state&&this._continuity.refreshCompleteFrame(this._visualFrameFingerprint()),this._captureRenderDeviceSnapshot()}updated(){this._pruneDevicePressFeedback(),this._syncDayCycleClock(),this._warmSnapshot(),this._dtMeasure();const e=this._stageEl;e&&!this._roViewport&&(this._roViewport=new ResizeObserver(()=>this._refitView()),this._roViewport.observe(e)),e&&this._booting&&!this._bootTimer&&this._bootWatch();const t=this.renderRoot.querySelector(".hdr");if(t&&e&&!this._roHdr){const i=()=>{const t=this.renderRoot.querySelector("ha-card");if(!t)return;const i=e.getBoundingClientRect().top-t.getBoundingClientRect().top,s=Math.min(Math.max(t.getBoundingClientRect().top,0),120),n=Math.round(i+s);n>=0&&n!==this._hdrH&&(this._hdrH=n),n>=0&&!this._booting&&!this._config?.kiosk&&e.clientHeight>0&&this._warmPatch({hdrH:n,stageH:e.clientHeight})};this._roHdr=new ResizeObserver(()=>requestAnimationFrame(i)),this._roHdr.observe(t),this._onWinResize=()=>requestAnimationFrame(i),window.addEventListener("resize",this._onWinResize),i()}if(e&&!this._view&&this._refitView(),this._editorSecondary.afterRender(),this._settleContinuityFrame(),this._serverStorage&&this._loadOk&&0===this._model.length&&!this._spaceDialog&&!this._importDialog&&!this._onboardingShown){this._onboardingShown=!0;const e=function(e){const t=e?.floors;if(!t||"object"!=typeof t)return[];const i=[];for(const e of Object.values(t))e&&e.floor_id&&i.push({id:e.floor_id,name:e.name||e.floor_id,level:e.level??null});return i.sort((e,t)=>{const i=e.level??1e9,s=t.level??1e9;return i!==s?i-s:e.name.localeCompare(t.name)}),i}(this.hass);e.length?this._importDialog={floors:e.map(e=>({...e,checked:!0}))}:this._openSpaceDialog("create")}}_adoptStructuralResponses(e,t,i){const s=e?.config,n=s&&Array.isArray(s.spaces)?s:null,o=Gd(n),a=o!==(this._cfgContentFingerprint||Gd(this._serverCfg));if(a&&(this._geometryHistory.clear(),this._pendingPhysicalWrites.clear(),this._serverCfg&&this._clearGeometryGesture(),this._serverCfg=n,this._cfgContentFingerprint=o),this._cfgRev=e?.rev??this._cfgRev,e&&("virtual_lights"in e||"config"in e)){const t=gn(this._virtualLights,e.virtual_lights,this._cfgRev,"virtual_lights"in e);vn(t)!==vn(this._virtualLights)&&(this._virtualLights=t,this._capturedSnapshotVirtual="")}let r=!1;if(void 0!==t||void 0!==i){const e=i??t?.layout??{},s=Gd(e);r=s!==(this._layoutContentFingerprint||Gd(this._layout)),r&&(this._layout=e,this._layoutContentFingerprint=s),this._layoutRev=t?.rev??this._layoutRev}return this._canOptimizeUndo=!(!e?.can_optimize_undo&&!t?.can_optimize_undo),this._haIntegrationVersion="string"==typeof e?.integration_version?e.integration_version:this._haIntegrationVersion,this._undoKind=e?.undo_kind||t?.undo_kind||null,"boolean"==typeof e?.can_write&&(this._serverCanWrite=e.can_write),a&&this._continuity.note("config-candidate",{configRev:this._cfgRev}),r&&this._continuity.note("layout-candidate",{layoutRev:this._layoutRev}),{configChanged:a,layoutChanged:r}}_resumePendingNavMode(){if(!this._pendingNavMode||!this._canEdit||this._config?.kiosk)return!1;const e=this._pendingNavMode;return this._pendingNavMode=null,this._setMode(e,!1),!0}async _loadFromServer(){this._loading=!0,this._loadTries++;const e=this._space,t=!!this._view;try{const[i,s]=await Promise.all([this.hass.callWS({type:"houseplan/config/get"}),this.hass.callWS({type:"houseplan/layout/get"})]),n=i?.config&&Array.isArray(i.config.spaces)?i.config:null,o=Gd(n)!==(this._cfgContentFingerprint||Gd(this._serverCfg))||Gd(s?.layout??{})!==(this._layoutContentFingerprint||Gd(this._layout));if(o){if(!await this._signer.prepareImage(this.hass,this._candidateBackdrop(n)))return this._continuity.note("asset-failed"),void this._scheduleLoadRetry(!0)}o&&this._continuity.hasCompleteFrame&&"steady"===this._continuity.state&&this._beginContinuityCandidate("structural-response",!0),this._connectionWasLost=!1,this._serverStorage=!0,"boolean"==typeof i?.can_write&&(this._serverCanWrite=i.can_write),this._canOptimizeUndo=!(!i?.can_optimize_undo&&!s?.can_optimize_undo),this._haIntegrationVersion="string"==typeof i?.integration_version?i.integration_version:this._haIntegrationVersion,this._adoptStructuralResponses(i,s),this._adoptInitialSpace(this._model,!0),this._resumePendingNavMode(),this._cacheSnapshot(),this._warmVpArmed&&this._space===this._warmVp?.space?this._warmVpArmed=!1:t&&this._space===e||this._restoreZoom(),this._loadOk=!0,this.hass.callWS({type:"houseplan/trail/get"}).then(e=>{this._vacSrvTrails=e?.trails||{},this.requestUpdate()}).catch(()=>{}),this._ensureLiveSyncSubscriptions()}catch(e){if(this._serverCfg)this._scheduleLoadRetry(!0);else if(this._loadTries>=8){this._serverStorage=!1;try{this._layout=JSON.parse(localStorage.getItem(Cv)||"{}")||{}}catch{this._layout={}}}}finally{this._loading=!1,this._continuityDataReady=!0,this._regSignature="",this._maybeRebuildDevices(),this.requestUpdate()}}_ensureLiveSyncSubscriptions(){const e=this.hass?.connection;if(!e)return;if(e!==this._liveSyncConnection&&(this._unsubCfg?.(),this._unsubCfg=null,this._unsubLayout?.(),this._unsubLayout=null,this._unsubTrail?.(),this._unsubTrail=void 0,this._unsubVirtual?.(),this._unsubVirtual=null,this._liveSyncGeneration++,this._liveSyncAttempt=null,this._liveSyncConnection=e),this._liveSyncAttempt)return;const t=this._liveSyncGeneration,i=[],s=(s,n,o,a)=>{s()||i.push(async()=>{const i=await e.subscribeEvents(a,o);t===this._liveSyncGeneration&&this.isConnected&&this.hass?.connection===e&&!s()?n(i):i?.()})};if(s(()=>this._unsubCfg,e=>{this._unsubCfg=e},"houseplan_config_updated",e=>{const t=Number(e?.data?.rev??-1);t!==this._cfgRev&&this._reloadConfigOnly(!1,t)}),s(()=>this._unsubTrail,e=>{this._unsubTrail=e},"houseplan_trail_updated",async()=>{try{const e=await this.hass.callWS({type:"houseplan/trail/get"});this._vacSrvTrails=e?.trails||{},this.requestUpdate()}catch{}}),s(()=>this._unsubLayout,e=>{this._unsubLayout=e},"houseplan_layout_updated",e=>this._onLayoutEvent(Number(e?.data?.rev??-1))),s(()=>this._unsubVirtual,e=>{this._unsubVirtual=e},"houseplan_virtual_light_updated",e=>{const t=wn(this._virtualLights,e?.data);t!==this._virtualLights&&(this._virtualLights=t,this._capturedSnapshotVirtual="",this._cacheSnapshot(),this.requestUpdate())}),!i.length)return;const n=function(e){return Promise.allSettled(e.map(e=>Promise.resolve().then(e)))}(i).then(()=>{});this._liveSyncAttempt=n,n.finally(()=>{this._liveSyncAttempt===n&&(this._liveSyncAttempt=null)})}async _reloadConfigOnly(e=!1,t){if(!e){if(void 0!==t&&t<=this._cfgRev)return;if(this._saveConfigDebounced.pending()&&this._saveConfigDebounced.flush(),this._cfgWriting)return clearTimeout(this._reloadRetry),void(this._reloadRetry=window.setTimeout(()=>this._reloadConfigOnly(!1,t),400))}this._beginContinuityCandidate("config-reload",!1);try{const e=await this.hass.callWS({type:"houseplan/config/get"}),t=e?.config&&Array.isArray(e.config.spaces)?e.config:null;if(Gd(t)!==(this._cfgContentFingerprint||Gd(this._serverCfg))&&!await this._signer.prepareImage(this.hass,this._candidateBackdrop(t)))return this._continuity.note("asset-failed"),void this._scheduleLoadRetry(!0);const i=this._space;this._adoptStructuralResponses(e),this._adoptInitialSpace(this._model,!0),this._resumePendingNavMode(),this._cacheSnapshot(),this._space!==i&&this._restoreZoom(),this._regSignature="",this._maybeRebuildDevices(),this.requestUpdate()}catch(e){this._showToast(this._t("toast.cfg_reload_failed",{err:this._errText(e)}))}finally{this._continuityDataReady=!0,this.requestUpdate()}}_scheduleLoadRetry(e=!1){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,!e&&this._loadOk||this._loading||!this.hass||this._loadFromServer()},t)}_ensureHaRegistryAuthority(){const e=this.hass?.connection||null;e&&e!==this._haRegistryConnection&&(this._haRegistryRelease?.(),this._haRegistryConnection=e,this._haRegistryRev=-1,this._haBindingCacheKey="",this._planHassMemo=null,this._haRegistryRelease=Rn(this.hass,this._onHaRegistryUpdate),this._onHaRegistryUpdate())}get _haRegistry(){return An(this.hass)}get _planHass(){const e=this._haRegistry,t=Fn(this.hass,e),i=this._planHassMemo;if(i&&i.hass===this.hass&&i.sig===t)return i.active;const s=En(this.hass,e),n=On(this.hass,e);return this._planHassMemo={hass:this.hass,sig:t,active:s,full:n},s}_captureRenderDeviceSnapshot(){if(!this.hass)return;const e=Date.now(),t=[...this._activityRt.entries()].map(([t,i])=>`${t}:${i.gen}:${i.flashTs}:`+(i.flashKind&&(i.expiresAt||i.flashTs+cm)>e?1:0)).join("|"),i=vn(this._virtualLights);if(this._capturedSnapshotSequence===this._hassSequence&&this._capturedSnapshotDevices===this._devices&&this._capturedSnapshotLayout===this._layout&&this._capturedSnapshotConfigEpoch===this._cfgEpoch&&this._capturedSnapshotVirtual===i&&this._capturedSnapshotActivity===t)return;const s=this._planHass,n=new Map,o=new Map,a=new Set(["sun.sun"]);this._vacFit?.source&&a.add(this._vacFit.source);const r=new Set,l=new Set,c=e=>{if(!e)return;const t=e.indexOf(":");if(t<0)return void a.add(e);const i=e.slice(0,t),s=e.slice(t+1);"device"===i?r.add(s):"entity"===i&&a.add(s)};for(const e of this._model)for(const t of e.rooms)t.area&&l.add(t.area),c(t.settings?.temp_source),c(t.settings?.hum_source);for(const e of this._serverCfg?.spaces||[])for(const t of e.openings||[])for(const e of gi(t))a.add(e);for(const e of this._serverCfg?.spaces||[])for(const t of e.decor||[])if("text"===t.kind){for(const e of String(t.text||"").matchAll(/\{([^{}\r\n]+)\}/g)){const t=Yi(e[1]);t?.entity&&a.add(t.entity)}t.entity&&a.add(t.entity),o.set(`decor:${e.id}:${t.id}`,es(t.text,t,s,e=>!!s.entities?.[e]&&!!s.states?.[e]&&!ko(s,e,wo(this._markers))))}const h=ho(s,this._devices,null,this._virtualLights);for(const e of this._devices){for(const t of[!1,!0])n.set(N_(e.id,t),R_(s,e,{liveStates:!1!==this._config?.live_states,showTemperature:!1!==this._config?.show_temperature,showSignal:t,activityRuntime:this._activityRt.get(e.id),sourceDetails:!1,lightDevices:this._devices,lightSources:h,registryHass:this._fullRegistryHass,reducedMotion:this._reducedMotion}));if(this._isVacDev(e)){const t=this._vacSource(e,s),i=t?cp(s?.states?.[t]?.attributes):null,n=this._vacRt.get(e.id);o.set(`vacuum:${e.id}`,{source:t,telemetry:i,mapId:i?this._vacMapId(e,i,s):null,runtime:n?{trail:n.trail,lastTs:n.lastTs,moving:n.moving,jump:n.jump}:null,server:this._vacSrvTrails[e.id]||null})}}const d=F_({sourceSequence:this._hassSequence,hass:s,devices:this._devices,presentations:n,positions:(p=this._model.length>0,u=this._devices,_=e=>this._livePos(e),p?new Map(u.map(e=>[e.id,_(e)])):new Map),facts:o,entityIds:a,deviceIds:r,areaIds:l});var p,u,_;this._capturedSnapshotSequence=this._hassSequence,this._capturedSnapshotDevices=this._devices,this._capturedSnapshotLayout=this._layout,this._capturedSnapshotActivity=t,this._capturedSnapshotConfigEpoch=this._cfgEpoch,this._capturedSnapshotVirtual=i,this._visibleDeviceSnapshot&&"steady"!==this._continuity.state?this._candidateDeviceSnapshot=d:(this._visibleDeviceSnapshot=d,this._candidateDeviceSnapshot=null)}get _renderDeviceSnapshot(){return this._stagedDeviceSnapshotToken===this._continuity.token?this._candidateDeviceSnapshot||this._visibleDeviceSnapshot:this._visibleDeviceSnapshot||this._candidateDeviceSnapshot}get _renderPlanHass(){return this._renderDeviceSnapshot?.hass||this._planHass}get _renderDevices(){return this._renderDeviceSnapshot?.devices||this._devices}get _fullRegistryHass(){return this._planHass,this._planHassMemo?.full||this.hass}_bindingStatus(e){return Bn(this.hass,e,this._haRegistry)}houseplanDiagnostics(){const e=function(e){const t=An(e);return{access:t.access,authoritative:t.authoritative,revision:t.revision,lastSuccess:t.lastSuccess,error:t.error}}(this.hass),t={active:0,ha_disabled:0,orphaned:0,unverified:0};for(const e of this._markers)e.removed||"virtual"===e.binding||t[this._bindingStatus(e.binding).kind]++;return{registry:{...e,lastSuccessAgeMs:e.lastSuccess?Math.max(0,Date.now()-e.lastSuccess):null},bindings:t}}_openBindingInHa(e){const[t,i]=e.split(":");if(i)if("device"!==t){if("entity"===t){const e=this._fullRegistryHass.entities?.[i];e?.device_id&&Lv("/config/devices/device/"+encodeURIComponent(e.device_id))}}else Lv("/config/devices/device/"+encodeURIComponent(i))}_bindingHasHaPage(e){const[t,i]=e.split(":");return!!i&&("device"===t||"entity"===t&&!!this._fullRegistryHass.entities?.[i]?.device_id)}_toggleMarkerDialogVisibility(){const e=this._markerDialog;if(!e)return;const t="ha"===e.bindingMode?this._bindingStatus(e.binding):null,i=e.hideFromPlan||"ha_disabled"===t?.kind;i&&"ha_disabled"===t?.kind?this._showToast(this._t("entity"===t.reason?"toast.ha_disabled_show_entity":"toast.ha_disabled_show_device")):i&&"unverified"===t?.kind?this._showToast(this._t("toast.ha_binding_unverified")):this._markerDialog={...e,hideFromPlan:!i}}_hookConnection(){const e=this.hass?.connection;e&&e!==this._connHooked&&(this._connHooked?.removeEventListener?.("ready",this._onConnReady),this._connHooked?.removeEventListener?.("disconnected",this._onConnLost),this._connHooked?.removeEventListener?.("reconnect-error",this._onConnLost),e.addEventListener?.("ready",this._onConnReady),e.addEventListener?.("disconnected",this._onConnLost),e.addEventListener?.("reconnect-error",this._onConnLost),this._connHooked=e)}_display(e){return this._signer.display(this.hass,e)}_resign(){this._signer.resign(this.hass,Rs(this._serverCfg))}_onLayoutEvent(e){e<=this._layoutRev||(clearTimeout(this._layoutSyncTimer),this._layoutSyncTimer=window.setTimeout(()=>{e<=this._layoutRev||this._reloadLayoutOnly()},200))}_noteLayoutRev(e){const t=e?.rev;"number"==typeof t&&t>this._layoutRev&&(this._layoutRev=t)}async _reloadLayoutOnly(){if(!this._serverStorage||!this.hass?.callWS)return;this._beginContinuityCandidate("layout-reload",!1);const e=new Map;for(const t of this._dirtyPos)this._layout[t]&&e.set(t,this._layout[t]);this._persistLayout.pending()&&this._persistLayout.flush();for(const[t,i]of this._sentPos)e.set(t,i);try{const t=await this.hass.callWS({type:"houseplan/layout/get"}),i={...t?.layout||{}};for(const[t,s]of e)i[t]=s;const s=Gd(i);s!==(this._layoutContentFingerprint||Gd(this._layout))&&(this._layout=i,this._layoutContentFingerprint=s),this._layoutRev=t?.rev??this._layoutRev,this._canOptimizeUndo=!!t?.can_optimize_undo,this._haIntegrationVersion="string"==typeof t?.integration_version?t.integration_version:this._haIntegrationVersion,this._undoKind=t?.undo_kind||null,this._cacheSnapshot(),this.requestUpdate()}catch{}finally{this._continuityDataReady=!0,this.requestUpdate()}}_maybeRebuildDevices(){const e=this.hass;if(!e?.devices||!e?.entities||!e?.areas)return;const t=this._haRegistry,i=Fn(e,t)+":"+Object.keys(e.areas).length+":"+(this._norm?"n":"l")+":"+pa(e,this._config?.language);if(i===this._regSignature&&this._devices.length)return;this._regSignature=i;const s=new Map(this._devices.map(e=>[e.id,e.bindingStatus?.kind||"active"]));this._devices=So({hass:e,registry:t,areaToSpace:Object.fromEntries(Object.entries(this._areaToSpace).map(([e,t])=>[e,t.space])),markers:this._markers,settings:this._settings,excluded:this._excluded,showAll:this._showAll,firstSpaceId:this._model[0]?.id||"",loc:e=>this._t(e),iconRules:this._iconRules});const n=this._markers.filter(e=>!e.removed&&"virtual"!==e.binding).map(e=>e.binding).sort(),o=t.revision+":"+n.join("|");if(t.authoritative&&o!==this._haBindingCacheKey){const i=new Map;for(const s of n)i.set(s,Bn(e,s,t));!function(e){if("undefined"==typeof localStorage||!e.size)return;const t=Ln(),i=Date.now();for(const[s,n]of e)"active"===n.kind?t[s]={kind:"active",ts:i}:"ha_disabled"===n.kind&&(t[s]={kind:"ha_disabled",reason:n.reason,ts:i});const s=Object.fromEntries(Object.entries(t).sort((e,t)=>t[1].ts-e[1].ts).slice(0,1500));Mn=s;try{localStorage.setItem(Sn,JSON.stringify(s))}catch{}}(i),this._haBindingCacheKey=o}this._defPos=this._defaultPositions(),this._syncNewDevices(),this._seedHiddenDevices(),this._syncActivityRuntime();const a=new Set(this._devices.filter(e=>!e.hidden).map(e=>e.id));for(const e of this._vacRt.keys())a.has(e)||this._vacRt.delete(e);if(this._infoCard){const e=this._devices.find(e=>e.id===this._infoCard.id);this._infoCard=e&&"ha_disabled"!==e.bindingStatus?.kind?e:null}const r=this._devices.some(e=>"ha_disabled"===e.bindingStatus?.kind&&"ha_disabled"!==s.get(e.id));r&&("ha_disabled"!==this._infoCard?.bindingStatus?.kind&&"ha_disabled"!==this._devices.find(e=>e.id===this._infoCard?.id)?.bindingStatus?.kind||this._closeInfoCard(),this._drag&&"ha_disabled"===this._devices.find(e=>e.id===this._drag.id)?.bindingStatus?.kind&&(this._drag=null),clearTimeout(this._holdTimer),this._holdFired=!1,this._tip=null,this._tapConfirm=null),this._nativeMoreInfoEntity&&!this._planEntityAvailable(this._nativeMoreInfoEntity)&&(Hv(this,"hass-more-info",{entityId:null}),this._nativeMoreInfoEntity=null)}_syncNewDevices(){if(!this._norm||!this._loadOk||!this._serverCfg)return;const e=this._devices.filter(e=>!e.marker&&!e.virtual).map(e=>e.id).sort(),t=e.join(",");if(t===this._newSyncKey)return;this._newSyncKey=t;const i=this._settings,{fresh:s,known:n}=function(e,t){if(!Array.isArray(t))return{fresh:[],known:[...e]};const i=new Set(t),s=e.filter(e=>!i.has(e));return{fresh:s,known:s.length?[...t,...s]:t}}(e,i.known_devices);if(!Array.isArray(i.known_devices)||s.length){const e=[...new Set([...i.new_device_ids||[],...s])];this._serverCfg={...this._serverCfg,settings:{...i,known_devices:n,new_device_ids:e}},this._saveConfig()}}get _newIds(){const e=this._settings.new_device_ids;return new Set(Array.isArray(e)?e:[])}_ackNewDevice(e){if(!this._newIds.has(e)||!this._serverCfg)return;const t=this._settings;this._serverCfg={...this._serverCfg,settings:{...t,new_device_ids:(t.new_device_ids||[]).filter(t=>t!==e)}},this._saveConfig(),this.requestUpdate()}get _markers(){return this._serverCfg?.markers||[]}_roomLqi(e){if(!e)return null;const t=[];for(const i of this._renderDevices){if(i.area!==e||i.virtual)continue;const s=_o(this._renderPlanHass,i.entities);null!=s&&t.push(s)}return Ni(t)}_roomBounds(e){if(e.poly&&e.poly.length){const t=e.poly.map(e=>e[0]),i=e.poly.map(e=>e[1]),s=Math.min(...t),n=Math.min(...i);return{x:s,y:n,w:Math.max(...t)-s,h:Math.max(...i)-n}}return{x:e.x??0,y:e.y??0,w:e.w??0,h:e.h??0}}_defaultPositions(){const e={},t=this._config?.icon_size??2.5;for(const i of this._model){const s=t/100*nd(i)*1.3;for(const t of i.rooms){if(!t.area)continue;const n=this._devices.filter(e=>e.area===t.area&&e.space===i.id);if(!n.length)continue;const o=this._roomBounds(t),a=.1*Math.min(o.w,o.h),r=o.w-2*a,l=o.h-2*a,c=Math.max(1,Math.round(Math.sqrt(n.length*r/Math.max(l,1)))),h=Math.ceil(n.length/c),d=r/c,p=l/Math.max(h,1),u=n.map((e,t)=>({x:o.x+a+d*(t%c+.5),y:o.y+a+p*(Math.floor(t/c)+.5)}));Oi(u,o,s,.5*a),n.forEach((t,i)=>e[t.id]=Wh(u[i]))}}return e}_pos(e){const t=this._renderDeviceSnapshot?.positions.get(e.id);return t?{x:t.x,y:t.y}:this._livePos(e)}_livePos(e){const t=this._spaceModelById(e.space),i=this._layout[e.id];if(i)if(this._norm){if(i.s===e.space)return{x:i.x*zv,y:i.y*zv}}else if(void 0===i.s)return{x:i.x,y:i.y};return this._defPos[e.id]?this._defPos[e.id]:t?Wh(sd(t)):{x:500,y:500}}_savePos(e,t,i){if(this._spaceModelById(e.space)){if(this._norm){const s=this._gridPitch,n=Math.round(t/s)*s,o=Math.round(i/s)*s,a=this._layout[e.id]?.k;this._layout={...this._layout,[e.id]:{s:e.space,x:Gh(n/zv),y:Gh(o/zv),...a?{k:a}:{}}}}else this._layout={...this._layout,[e.id]:{x:Math.round(t),y:Math.round(i)}};this._dirtyPos.add(e.id),this._persistLayout()}}_visualSamples(e){return C_(this._renderPlanHass,e,this._renderDevices,void 0,this._fullRegistryHass).samples}_devicePresentation(e,t=!1!==this._config?.show_signal,i=!1){const s=i?null:this._renderDeviceSnapshot?.presentations.get(N_(e.id,t));return s||R_(this._renderPlanHass,e,{liveStates:!1!==this._config?.live_states,showTemperature:!1!==this._config?.show_temperature,showSignal:t,designPreview:i,activityRuntime:this._activityRt.get(e.id),sourceDetails:!1,lightDevices:this._renderDevices,registryHass:this._fullRegistryHass,reducedMotion:this._reducedMotion})}_deviceVisual(e){return this._devicePresentation(e).visual}_stateClass(e,t=this._deviceVisual(e)){const i=this._devicePresentation(e);return i.effectiveHidden?"":("icon_ripple"!==i.display||!1===this._config?.live_states||"alarm"===t.status||t.activity,I_({...i,visual:t}).join(" "))}_liveTemp(e){if(!this._config?.show_temperature)return null;if(!0===e.marker?.use_climate_temp){const t=go(this._renderPlanHass,e.entities);if(null!=t)return t}return"mdi:thermometer"!==e.icon&&"mdi:air-filter"!==e.icon?null:mo(this._renderPlanHass,e.entities)}_bindingEntities(e){if("virtual"===e||!e)return[];const t=this._bindingStatus(e);return"active"===t.kind?t.enabledEntityIds:t.allEntityIds}_bindingHasClimate(e){return this._bindingEntities(e).some(e=>e.startsWith("climate."))}_bindingHasAlarm(e){return this._bindingEntities(e).some(e=>{const t=this._planHass?.states?.[e]||this.hass?.states?.[e],i=this._fullRegistryHass.entities[e]||this.hass?.entities?.[e];return Bs(e.split(".")[0],t?.attributes?.device_class||i?.device_class||i?.original_device_class)})}_liveHum(e){return this._config?.show_temperature&&e.primary&&fo(this.hass,e.primary)?vo(this.hass,e.entities):null}_deviceBindingActive(e,t=!0){if(e.virtual||"virtual"===e.bindingKind)return!0;if(!e.bindingKind||!e.bindingRef)return!1;const i=this._bindingStatus(`${e.bindingKind}:${e.bindingRef}`);return"active"===i.kind||(t&&this._showToast(this._t("ha_disabled"===i.kind?"toast.ha_disabled_action":"toast.ha_binding_unverified")),!1)}_openMoreInfo(e){e?this._planEntityAvailable(e)?(this._nativeMoreInfoEntity=e,Hv(this,"hass-more-info",{entityId:e})):this._showToast(this._t("toast.ha_disabled_action")):this._showToast(this._t("toast.no_entity"))}_interruptViewGesture(e,t){if(clearTimeout(this._holdTimer),clearTimeout(this._kioskHoldTimer),void 0!==e)for(const i of[t,this._stageEl])try{i?.hasPointerCapture?.(e)&&i.releasePointerCapture(e)}catch{}this._pointers.clear(),this._panStart=null,this._panLock=null,this._pinchStart=null,this._swipeStart=null}_closeInfoCard(){this._interruptViewGesture(),this._holdFired=!1,this._infoCard=null}_ctxDevice(e,t){"view"===this._mode&&(e.preventDefault(),e.stopPropagation(),this._deviceBindingActive(t)&&(t.primary?this._openMoreInfo(t.primary):this._infoCard=t))}_clickDevice(e,t){if(e.stopPropagation(),this._drag?.moved||this._suppressClick||this._holdFired)return;if("plan"===this._mode)return;if("devices"===this._mode)return void this._openMarkerDialog(t);const i=this._devices.find(e=>e.id===t.id);if(!i)return;const s=qp(i.tapAction,i.primary?.split(".")[0]),n=(e,t)=>{i.marker?.tap_confirm?this._tapConfirm={kind:"run",text:e,exec:t}:t()};if("toggle"===s){const e=this._toggleIntent(i);if(!e)return;if(!Yp(e))return void this._showUnavailableToggleTargets(e);const t=e=>{const t=Yp(e);if(!t)return;if("virtual-light"===t.kind)return this._startDevicePressFeedback(i.id),void this.hass.callWS({type:"houseplan/virtual_light/toggle",marker_id:t.markerId}).then(e=>{const t=wn(this._virtualLights,e);t!==this._virtualLights&&(this._virtualLights=t,this._capturedSnapshotVirtual="",this._cacheSnapshot(),this.requestUpdate())}).catch(e=>this._showToast(this._t("toast.virtual_light_toggle_failed",{err:this._errText(e)})));const{command:s}=t;this._startDevicePressFeedback(i.id),this.hass.callService(s.domain,s.service,s.data).catch(e=>this._showToast(this._t("toast.error",{err:this._errText(e)})))},s=((o=e).targets.length?o.targets:o.skippedTargets).map(e=>e.name||e.entityId||e.ref).join(", ")||i.name;if(i.marker?.tap_confirm){const n=this._toggleConfirmationLines(e);if(!n.length)return;this._tapConfirm={kind:"toggle",text:this._t("confirm.tap_toggle",{name:s}),lines:n,initialIntent:e,deviceId:i.id,exec:()=>{const s=this._devices.find(e=>e.id===i.id),n=s?this._toggleIntent(s):null;n&&!Yp(n)&&this._showUnavailableToggleTargets(n)||(n&&Xp(e,n)?t(n):this._showToast(this._t("toast.tap_target_changed")))}}}else t(e);return}var o;if("info"===s)return this._interruptViewGesture(),void(this._infoCard=i);if(this._deviceBindingActive(i)){if("run"===s){const e=i.marker?.tap_target||"",t=function(e){const t=String(e||"").split(".")[0];return"automation"===t?{domain:"automation",service:"trigger"}:"script"===t?{domain:"script",service:"turn_on"}:"scene"===t?{domain:"scene",service:"turn_on"}:null}(e),s=this.hass.states[e];if(!t||!s)return void this._showToast(this._t("toast.run_target_missing"));const o=s.attributes?.friendly_name||e;return void n(this._t("confirm.tap_run",{name:o}),()=>{this._deviceBindingActive(i)&&this._planEntityAvailable(e)&&(this._startDevicePressFeedback(i.id),this.hass.callService(t.domain,t.service,{entity_id:e}).then(()=>{this._stampActivity(i.id,"event",this._activitySourceKey(i)),this.requestUpdate(),this._showToast(this._t("toast.run_started",{name:o}))}).catch(e=>this._showToast(this._t("toast.error",{err:this._errText(e)}))))})}"more-info"===s&&i.primary?this._openMoreInfo(i.primary):this._infoCard=i}}_showUnavailableToggleTargets(e){const t=function(e){if(!e||"group"!==e.kind||Yp(e)||"configured-targets-missing"!==e.noneReason)return[];if(!e.skippedTargets.length||e.skippedTargets.some(e=>!Jp.has(e.reason)&&"secure"!==e.reason))return[];const t=[],i=new Set;for(const s of e.skippedTargets){if(!Jp.has(s.reason))continue;const e=String(s.name||s.entityId||s.ref||"").trim();e&&!i.has(e)&&(i.add(e),t.push(e))}return t}(e);return!!t.length&&(this._showToast(1===t.length?this._t("toast.toggle_target_unavailable",{name:t[0]}):this._t("toast.toggle_targets_unavailable",{names:t.join(", ")})),!0)}_keyDevice(e,t){"Enter"!==e.key&&" "!==e.key||"view"!==this._mode&&"devices"!==this._mode||(e.preventDefault(),this._clickDevice(e,t))}_startDevicePressFeedback(e){const t=[...this.renderRoot.querySelectorAll(".dev[data-id]")].find(t=>t.dataset.id===e),i=t?.querySelector(".device-shell");if(!i||"function"!=typeof i.animate)return;const s=Number.parseFloat(this.ownerDocument.defaultView?.getComputedStyle(i).scale||""),n=Number.isFinite(s)?Math.max(.95,Math.min(1,s)):1;this._devicePressAnimations.get(e)?.cancel();const o=this._reducedMotion?[{outlineColor:"transparent",outlineStyle:"solid",outlineWidth:"0px"},{outlineColor:"var(--hp-accent, #3ea6ff)",outlineStyle:"solid",outlineWidth:"2px",outlineOffset:"2px",offset:.5},{outlineColor:"transparent",outlineStyle:"solid",outlineWidth:"0px"}]:[{scale:String(n)},{scale:"0.95",offset:.5},{scale:"1"}],a=i.animate(o,{duration:200,easing:"cubic-bezier(.22,.61,.36,1)"});this._devicePressAnimations.set(e,a);const r=()=>{this._devicePressAnimations.get(e)===a&&this._devicePressAnimations.delete(e)};a.addEventListener("finish",r,{once:!0}),a.addEventListener("cancel",r,{once:!0})}_cancelDevicePressFeedback(){for(const e of this._devicePressAnimations.values())e.cancel();this._devicePressAnimations.clear()}_pruneDevicePressFeedback(){if(!this._devicePressAnimations.size)return;const e=new Set([...this.renderRoot.querySelectorAll(".dev[data-id]")].map(e=>e.dataset.id||""));for(const[t,i]of this._devicePressAnimations)e.has(t)||(i.cancel(),this._devicePressAnimations.delete(t))}_t(e,t){return ua(pa(this.hass,this._config?.language),e,t)}get _colorPickerLabels(){return{title:this._t("color_picker.title"),hue:this._t("color_picker.hue"),saturation:this._t("color_picker.saturation"),value:this._t("color_picker.value"),hex:this._t("color_picker.hex"),invalidHex:this._t("color_picker.invalid_hex")}}_help(e){const t=`${e}.aria`,i=pa(this.hass,this._config?.language);return _a(i,e)&&_a(i,t)?q``:G}get _stageEl(){return this.renderRoot.querySelector(".stage")}_contentItems(e){const t=[];for(const i of this._devices){if(i.space!==e.id||i.hidden)continue;const s=this._pos(i);t.push({minX:s.x,minY:s.y,maxX:s.x,maxY:s.y})}if(e.id===this._space){for(const e of this._openingsR){const i=Number(e.angle)*Math.PI/180,s=Math.cos(i)*e.rlen/2,n=Math.sin(i)*e.rlen/2,o=Yh([[e.rx-s,e.ry-n],[e.rx+s,e.ry+n]]);o&&t.push(o)}const i=this._decorH;for(const e of this._decorList){const s=Yh("line"===e.kind?[[e.x1*zv,e.y1*i],[e.x2*zv,e.y2*i]]:"text"===e.kind?[[e.x*zv,e.y*i]]:Yr({x:e.x*zv,y:e.y*i,w:e.w*zv,h:e.h*i,angle:e.angle}));s&&t.push(s)}for(const i of this._physicalBodiesR(e)){const e=Yh(i);e&&t.push(e)}}return Xh(e,t)}_frameOf(){const e=this._spaceModel();if(!e){this._frame=null;const e={x:0,y:0,w:zv,h:zv};return{rect:e,all:e,outliers:0}}const t=this._frame,i="view"!==this._mode;if(t&&t.id===e.id&&this._bdDrag)return t;if(t&&t.id===e.id&&t.model===e&&t.layout===this._layout&&t.devs===this._devices&&t.far===this._showFar&&t.grow===i)return t;const s=td(this._contentItems(e));let n=s.all||id(e),o=this._showFar?n:s.core||id(e);return t&&t.id===e.id&&i&&t.grow&&(o=Nv(t.rect,o),n=Nv(t.all,n)),this._frame={id:e.id,model:e,layout:this._layout,devs:this._devices,far:this._showFar,grow:i,rect:o,all:n,outliers:s.outliers},this._frame}_isoSource(){const e=this._spaceModel();if(!e)return null;const t=this._spaceWalls,i=this._openCuts(),s=this._openingsR.map((e,t)=>({id:String(e.id||t),sourceIndex:t,type:e.type,x:e.rx,y:e.ry,angle:Number(e.angle)||0,length:e.rlen>0?e.rlen:900,flipH:!!e.flip_h,flipV:!!e.flip_v})),n=Dh(64,this._cellCm),o=Dh(10,this._cellCm),a=`${e.id}|${function(e){let t=2166136261;const i=e=>{if("number"!=typeof e)if("string"!=typeof e)if("boolean"!=typeof e)if(Array.isArray(e)){t=Hf(t,e.length);for(const t of e)i(t)}else{if(e&&"object"==typeof e){const t=e;for(const e of Object.keys(t).sort())i(e),i(t[e]);return}t=Hf(t,-1)}else t=Hf(t,e?1:0);else for(const i of e)t=Hf(t,i.codePointAt(0)||0);else t=Hf(t,e)};return i(e),t.toString(36)}({rooms:e.rooms,walls:t,openCuts:i,openings:s,partitions:e.partitions,roomDrafts:e.room_drafts,columns:e.wall_columns,cellCm:this._cellCm,gridPitch:this._gridPitch,wallKeyPitch:this._wallKeyPitch,camera:Cf,wallHeight:n,floorEdgeHeight:o,algorithm:3})}`;return{key:a,build:()=>{const o=_h(e,this._cellCm,this._gridPitch,2e-4*this._gridPitch,this._partitionOpeningCuts(e)).all,a=this._roomWallOpeningInputs(this._openingsR,e),r=t.length||o.length?qc(e.rooms,t,i,a,this._wallKeyPitch,this._cellCm,this._gridPitch,zv,o):null;if(r&&("failed-core"===r.status||"not-applicable"===r.status))throw new Error("wall boolean geometry failed");const l=r?.paperGeom??Hc(e.rooms,t,i,this._wallKeyPitch,this._cellCm,this._gridPitch,zv);if(!l)throw new Error("floor boolean geometry failed");const c=r?.openingIndex||Kc(e.rooms,t,i,this._wallKeyPitch,this._cellCm,this._gridPitch,zv),h=s.map(e=>{const i=this._openingsR[e.sourceIndex],s="gate"===e.type?!e.flipV:e.flipV,o=i?.partitionHost?ou(i.partitionHost,s):t.length||"gate"===e.type?Zc(c,{x:e.x,y:e.y,angle:e.angle,length:e.length,flip_v:s}):{ox:0,oy:0,cm:0,side:-1};return function(e,t=64){if(!(Lf([e.x,e.y,e.angle,e.length,e.face.ox,e.face.oy,t])&&e.length>0&&t>0))throw new Error("invalid isometric opening input");const i=e.length/2;let s;if("passage"===e.type)s=[];else if("gate"===e.type){const n=10*e.face.side;s=[jf(e,0,[-i,0],[i,0],n,0,.88*t),jf(e,1,[i,0],[-i,0],-n,0,.88*t)]}else s="window"===e.type?[jf(e,0,[-i,0],[i,0],-90,.27*t,.78*t),jf(e,1,[i,0],[-i,0],90,.27*t,.78*t)]:[jf(e,0,[-i,0],[e.length,0],-90,0,.92*t)];return{id:e.id,sourceIndex:e.sourceIndex,type:e.type,leaves:Object.freeze(s.map(e=>Object.freeze(e)))}}({...e,face:o},n)});return{walls:r?.components.flatMap(e=>e.geom)||[],floor:l,openings:Object.freeze(h)}}}}_isoSceneKey(){if(!this._labsIso||"view"!==this._mode)return null;try{return this._isoSource()?.key??null}catch{return`${this._space}|invalid`}}_isoScene(){const e=this._isoSource();if(!e)return null;const t=this._isoGeometryCache.get(e.key);if(t)return{key:e.key,...t};const i=this._frameOf().rect,s=e.build(),n=Dh(64,this._cellCm),o=Dh(10,this._cellCm),a=function(e){let t=1/0,i=1/0,s=-1/0,n=-1/0;for(const o of e)for(const e of o.leaves){const o=Math.hypot(e.closedVector[0],e.closedVector[1]);t=Math.min(t,e.hinge[0]-o),i=Math.min(i,e.hinge[1]-o),s=Math.max(s,e.hinge[0]+o),n=Math.max(n,e.hinge[1]+o)}return Lf([t,i,s,n])?{x:t,y:i,w:s-t,h:n-i}:null}(s.openings),r=Rf({rect:a?Nv(i,a):i,wallHeight:n,openingHeight:n,floorDepth:o}),l=function(e,t=Cf,i=64){if(!Number.isFinite(i)||i<0)throw new Error("invalid wall height");const s=[],n=[],o=[];let a=0;for(let r=0;r<(e||[]).length;r++){const l=e[r];for(let e=0;e<(l||[]).length;e++){const c=Ff(l[e],e>0);if(!(c.length<3||Math.abs(zf(c))<1e-9)){s.push(Nf(c,t,i)),a+=c.length;for(let s=0;se.depth-t.depth||e.polygon-t.polygon||e.ring-t.ring||e.edge-t.edge),{topPath:s.join(" "),sides:n,contactPath:o.join(" "),edgeCount:a}}(s.walls,Cf,n),c={geometry:l,floor:Of(s.floor,o),openings:s.openings,frame:r};return kv(this._isoGeometryCache,e.key,c,8),{key:e.key,...c}}_effectiveProjection(){if("iso"!==this._desiredProjection||!this._model.length)return"flat";const e=this._isoSceneKey()||`${this._space}|invalid`;if(this._isoFallback.has(e))return"flat";try{const e=this._isoScene();return e?(t="iso",i=e.key,s=this._isoFallback,"iso"===t&&i&&!s.has(i)?"iso":"flat"):"flat"}catch(t){if(!this._isoFallback.has(e)){this._isoFallback.add(e);const i=e.split("|");console.warn(`HOUSEPLAN ISO FALLBACK: #89, space ${this._space}, fingerprint ${i[i.length-1]}, ${t instanceof Error?t.message:"renderer error"}`)}return"flat"}var t,i,s}_scenePoint(e){return"iso"===this._renderProjection?Pf(e,0):e}_floorView(e){if("iso"!==this._renderProjection)return e;const t=Tf([e.x,e.y]),i=Tf([e.x+e.w,e.y+e.h]);return{x:t[0],y:t[1],w:i[0]-t[0],h:i[1]-t[1]}}_baseVb(){if("iso"===this._effectiveProjection()){if(!this._spaceDisplayForRender().showBorders){const e=Rf({rect:this._frameOf().rect,wallHeight:Dh(64,this._cellCm)});return[e.x,e.y,e.w,e.h]}const e=this._isoScene()?.frame??this._frameOf().rect;return[e.x,e.y,e.w,e.h]}const e=this._frameOf().rect;return[e.x,e.y,e.w,e.h]}get _outliers(){return this._showFar?0:this._frameOf().outliers}_fitFar(){this._showFar=!0,this._frame=null,this._resetZoom()}_fitAll(){this._showFar=!0,this._frame=null,this._resetZoom()}_renderFarHint(){return this._kiosk||"view"!==this._mode||this._booting||!this._outliers?G:q`
${this._t("canvas.far_objects",{n:this._outliers})} @@ -5118,7 +5118,7 @@ globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="30d20d6f6822065e2d5226b18abbb05d8d26 style="left:${r.toFixed(1)}%;top:${l.toFixed(1)}%" @click=${e=>{e.stopPropagation(),this._fitAll()}}> - `}_stageAspect(){const e=this._stageEl,t=this._baseVb();return e&&e.clientHeight?e.clientWidth/e.clientHeight:t[2]/t[3]}_viewOr(e){return this._view&&this._view.w?this._view:Ei(e,this._stageAspect())}_roomLabelReferenceViewWidth(e){if(!this._markup)return e.w;const t=this._stageEl,i=this.renderRoot.querySelector(".editorchrome");if(!t||t.clientWidth<=0||t.clientHeight<=0)return e.w;const s=t.clientHeight+(i?.getBoundingClientRect().height||0);return s<=0?e.w:this._viewForModeTarget(this._zoom,void 0,void 0,t.clientWidth,s).w}_screenToVb(e,t){const i=this._stageEl,s=this._viewOr(this._baseVb()),n=i?.clientWidth||1,o=i?.clientHeight||1;return[s.x+e/n*s.w,s.y+t/o*s.h]}_clampView(e,t){const i=(e,t,i,s)=>{const n=1*Math.max(t,s),o=i-n,a=i+s-t+n;return Math.max(Math.min(o,a),Math.min(Math.max(o,a),e))};return{w:e.w,h:e.h,x:i(e.x,e.w,t.x,t.w),y:i(e.y,e.h,t.y,t.h)}}_applyView(e,t,i){const s=this._baseVb(),n=Ei(s,this._stageAspect()),o=Math.min(Ov.ZOOM_MAX,Math.max(Ov.ZOOM_MIN,e)),a=n.w/o,r=n.h/o,l=this._viewOr(s),c=t??l.x+l.w/2,h=i??l.y+l.h/2,d=this._clampView({x:c-a/2,y:h-r/2,w:a,h:r},n);return!(this._view&&Math.abs(this._zoom-o)<1e-9&&Math.abs(this._view.x-d.x)<1e-6&&Math.abs(this._view.y-d.y)<1e-6&&Math.abs(this._view.w-d.w)<1e-6&&Math.abs(this._view.h-d.h)<1e-6)&&("opening"===this._tool&&(this._cursorPt=null,this._clearOpeningPlacement(!1)),this._zoom=o,this._view=d,!0)}_bootWatch(){clearTimeout(this._bootTimer),this._bootStart=Date.now(),this._bootLastH=-1,this._bootLastChange=this._bootStart;const e=()=>{if(!this._booting)return;const t=Date.now(),i=this._stageEl?this._stageEl.clientHeight:0;i!==this._bootLastH&&(this._bootLastH=i,this._bootLastChange=t);const s=t-this._bootStart;s>=1200||s>=700&&i>0&&t-this._bootLastChange>=250?this._bootSettled():this._bootTimer=window.setTimeout(e,100)};this._bootTimer=window.setTimeout(e,100)}_bootSettled(){this._booting&&!this._bootSettling&&(this._bootSettling=!0,this._refitView(),this._bootSettleRaf=requestAnimationFrame(()=>{this._bootSettleRaf=0,this._finishBootSettled()}))}_finishBootSettled(){if(!this._booting)return;this._refitView(),this._booting=!1,this._bootSettling=!1;const e=this._stageEl?.clientHeight??0;!this._config?.kiosk&&e>0&&this._warmPatch({hdrH:this._hdrH,stageH:e,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},_v)}_bootSoftCancel(){this._bootSoft&&(clearTimeout(this._bootSoftTimer),this._bootSoft=!1)}_beginResumeSettle(){this._booting||this._resumeSettling||(this._modeTransitionPreparing?this._modeTransitionForceAtomic=!0:this._cancelModeTransition(!0),this._viewportInvalidAt=0,this._beginContinuityCandidate("warm-resume",!1),this._loading?this.requestUpdate():this._loadFromServer())}_refitView(){if(this._modeTransitionBusy)return;const e=this._stageEl;if(!e||"visible"!==document.visibilityState||e.clientWidth<=0||e.clientHeight<=0)return void(this._viewportInvalidAt||(this._viewportInvalidAt=Date.now()));const t=[e.clientWidth,e.clientHeight],i=this._lastValidStageSize,s=!!i&&Math.abs(i[0]-t[0])<=.5&&Math.abs(i[1]-t[1])<=.5,n=this._viewportInvalidAt?Date.now()-this._viewportInvalidAt:0;if(this._viewportInvalidAt=0,!i)return this._lastValidStageSize=t,void(this._view||this._applyView(this._zoom));s?this._pendingRefitSize=null:(this._pendingRefitSize=t,this._refitRaf||(this._refitRaf=requestAnimationFrame(()=>{this._refitRaf=0;const e=this._pendingRefitSize;this._pendingRefitSize=null;const t=this._stageEl;if(!e||!t||t.clientWidth<=0||t.clientHeight<=0)return;if(Math.abs(t.clientWidth-e[0])>.5||Math.abs(t.clientHeight-e[1])>.5)return void this._refitView();const i=this._lastValidStageSize;if(i&&Math.abs(i[0]-e[0])<=.5&&Math.abs(i[1]-e[1])<=.5)return;this._lastValidStageSize=e;const s=this._view;n>=Fd?this._beginContinuityCandidate("stage-size-restored",!0,"stage-size"):this._continuity.hasCompleteFrame&&this._beginContinuityCandidate("stage-resize",!0,"stage-size"),this._applyView(this._zoom,s?s.x+s.w/2:void 0,s?s.y+s.h/2:void 0)})))}_zoomAt(e,t,i){const s=this._stageEl;if(!s)return;const n=Ei(this._baseVb(),this._stageAspect()),o=Math.min(Ov.ZOOM_MAX,Math.max(Ov.ZOOM_MIN,i));"opening"===this._tool&&(this._cursorPt=null,this._clearOpeningPlacement(!1));const a=s.clientWidth,r=s.clientHeight,l=this._screenToVb(e,t),c=n.w/o,h=n.h/o;this._zoom=o,this._view=this._clampView({x:l[0]-e/a*c,y:l[1]-t/r*h,w:c,h:h},n)}_onWheel(e){const t=this._stageEl;if(!t)return;e.preventDefault();const i=t.getBoundingClientRect(),s=e.deltaY<0?1.15:1/1.15;this._zoomAt(e.clientX-i.left,e.clientY-i.top,this._zoom*s),this._saveZoom()}_stepZoom(e){const t=this._stageEl;t&&(this._zoomAt(t.clientWidth/2,t.clientHeight/2,this._zoom*(e>0?1.4:1/1.4)),this._saveZoom())}_resetZoom(){const e=this._baseVb();"opening"===this._tool&&(this._cursorPt=null,this._clearOpeningPlacement(!1)),this._zoom=1,this._view=Ei(e,this._stageAspect()),this._saveZoom()}_saveZoom(){if("view"===this._mode){this._zoomBySpace={...this._zoomBySpace,[this._space]:this._zoom};try{localStorage.setItem($v,JSON.stringify(this._zoomBySpace))}catch{}}}_restoreZoom(){const e=this._zoomBySpace[this._space]||1;this._zoom=e;const t=this._stageEl;if(t&&t.clientHeight){const t=this._baseVb();return this._applyView(e,t[0]+t[2]/2,t[1]+t[3]/2),void this.requestUpdate()}this._view=null,requestAnimationFrame(()=>{if(!this._stageEl)return;const t=this._baseVb();this._applyView(e,t[0]+t[2]/2,t[1]+t[3]/2),this.requestUpdate()})}_stagePointerDown(e){if(this._vacFit)return;if(this._kiosk&&(this._cyclePausedUntil=Date.now()+6e4,0===this._pointers.size?(this._swipeStart={x:e.clientX,y:e.clientY,id:e.pointerId},e.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&&e.target.closest?.(".roomlabel, .rlhandle, .rszhandle, .dev, .oplock, .op-hit, button"))return;if("devices"===this._mode&&e.target.closest(".dev"))return;if("decor"===this._mode&&this._decorPointerDown(e))return;this._pointers.set(e.pointerId,{x:e.clientX,y:e.clientY});const t=this._viewOr(this._baseVb());if(1===this._pointers.size)this._panStart={sx:e.clientX,sy:e.clientY,vx:t.x,vy:t.y},this._panLock=null,this._suppressClick=!1;else if(2===this._pointers.size){"opening"===this._tool?(this._cursorPt=null,this._clearOpeningPlacement(!1)):"draw"===this._tool&&this._clearPlanSnapHover();const e=[...this._pointers.values()],t=Math.hypot(e[0].x-e[1].x,e[0].y-e[1].y);this._pinchStart={dist:t,zoom:this._zoom},this._panStart=null,this._panLock=null}}get _swipeZone(){return!this._hasFixedFloor&&this._kiosk&&this._zoom<=1.001&&this._model.length>1}_stagePointerMove(e){if(this._physicalRotate?.pid!==e.pointerId)if(this._physicalDrag?.pid!==e.pointerId)if(this._dtDrag?.pid!==e.pointerId)if(this._bdDrag?.pid!==e.pointerId){if(this._decorDraft?.pid===e.pointerId){const t=this._decorDraft;let i=this._decorSnap(this._svgPoint(e),e.pointerType);if(e.shiftKey&&("rect"===t.kind||"ellipse"===t.kind)){const e=i[0]-t.a[0],s=i[1]-t.a[1],n=Math.max(Math.abs(e),Math.abs(s));i=this._snap([t.a[0]+(e<0?-n:n),t.a[1]+(s<0?-n:n)])}return void(this._decorDraft={...t,b:i})}if(this._decorMove?.pid!==e.pointerId)if(this._pointers.has(e.pointerId)){if(this._pointers.set(e.pointerId,{x:e.clientX,y:e.clientY}),this._markup&&1===this._pointers.size&&this._markupMove(e),this._pinchStart&&this._pointers.size>=2){"opening"===this._tool?(this._cursorPt=null,this._clearOpeningPlacement(!1)):"draw"===this._tool&&this._clearPlanSnapHover();const e=[...this._pointers.values()],t=Math.hypot(e[0].x-e[1].x,e[0].y-e[1].y)/(this._pinchStart.dist||1),i=this._stageEl.getBoundingClientRect(),s=(e[0].x+e[1].x)/2-i.left,n=(e[0].y+e[1].y)/2-i.top;this._zoomAt(s,n,this._pinchStart.zoom*t),this._suppressClick=!0,this._saveZoom()}else if(this._panStart){const t=e.clientX-this._panStart.sx,i=e.clientY-this._panStart.sy;Math.abs(t)+Math.abs(i)>4&&(this._suppressClick=!0,clearTimeout(this._holdTimer),"opening"===this._tool?(this._cursorPt=null,this._clearOpeningPlacement(!1)):"draw"===this._tool&&this._clearPlanSnapHover()),null===this._panLock&&Math.abs(t)+Math.abs(i)>8&&(this._panLock=this._swipeZone&&Math.abs(t)>1.5*Math.abs(i)?"swipe":"pan");const s=this._stageEl;if("pan"===this._panLock&&s){const e=this._baseVb(),n=this._viewOr(e),o=Ei(e,this._stageAspect());this._view=this._clampView({x:this._panStart.vx-t/(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(e);else this._decorMoveUpdate(e)}else this._bdMove(e);else this._dtMove(e);else this._physicalMove(e);else this._physicalRotateMove(e)}_stagePointerLeave(e){this._markup&&("opening"===this._tool?(this._cursorPt=null,this._clearOpeningPlacement(!1)):"draw"===this._tool&&this._clearPlanSnapHover())}_stagePointerUp(e){if(this._kiosk){clearTimeout(this._kioskHoldTimer);const t=this._swipeStart;if(this._swipeStart=null,t&&t.id===e.pointerId){const i=e.clientX-t.x,s=e.clientY-t.y;if(Math.abs(i)+Math.abs(s)<8){const e=Date.now();e-this._lastTap<350&&this._resetZoom(),this._lastTap=e}const n="pan"===this._panLock?null:function(e,t,i,s,n,o=60){if(i>1.001||s.length<2)return null;if(Math.abs(e)e.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._physicalDrag?.pid===e.pointerId)return void this._physicalUp(e);if(this._physicalRotate?.pid===e.pointerId)return void this._physicalRotateUp(e);if(this._dtDrag?.pid===e.pointerId)return void this._dtUp();if(this._bdDrag?.pid===e.pointerId)return void this._bdUp();if(this._decorDraft?.pid===e.pointerId)return void this._decorCommitDraft();if(this._decorMove?.pid===e.pointerId)return this._decorMove.moved&&(this._recordGeometry(this._t("history.decor_move"),this._decorMove.before),this._saveConfig()),void(this._decorMove=null);const t=!!this._pinchStart||!!this._panStart;this._pointers.delete(e.pointerId),this._pointers.size<2&&(this._pinchStart=null),0===this._pointers.size&&(this._panStart=null,this._panLock=null,setTimeout(()=>this._suppressClick=!1,0)),t&&0===this._pointers.size&&this.requestUpdate()}_clickRoom(e){!this._suppressClick&&e.area&&Fv("/config/areas/area/"+e.area)}_pointerDown(e,t){if("plan"===this._mode)return;if("view"===this._mode){this._holdFired=!1,clearTimeout(this._holdTimer);const i=e.pointerId,s=e.currentTarget;return void(this._holdTimer=window.setTimeout(()=>{this._holdFired=!0,this._interruptViewGesture(i,s),this._infoCard=t},600))}if("ha_disabled"===t.bindingStatus?.kind)return;e.preventDefault();const i=this._pos(t);this._drag={id:t.id,sx:e.clientX,sy:e.clientY,ox:i.x,oy:i.y,moved:!1},Ev(e),this._tip=null}_pointerMove(e,t){if(!this._drag||this._drag.id!==t.id)return;const i=this.renderRoot.querySelector(".stage");if(!i)return;const s=this._baseVb(),n=i.getBoundingClientRect(),o=this._viewOr(s),a=(e.clientX-this._drag.sx)/n.width*o.w,r=(e.clientY-this._drag.sy)/n.height*o.h;Math.abs(e.clientX-this._drag.sx)+Math.abs(e.clientY-this._drag.sy)>3&&(this._drag.moved=!0,clearTimeout(this._holdTimer));const l=Lh(this._drag.ox+a),c=Lh(this._drag.oy+r);this._savePos(t,l,c)}_pointerUp(e,t){if(clearTimeout(this._holdTimer),!this._drag||this._drag.id!==t.id)return;const i=this._drag.moved;this._drag=i?this._drag:null,i&&(this._selId=t.id,window.setTimeout(()=>this._drag=null,0))}_showToast(e){for(const e of this.renderRoot.querySelectorAll("hp-dialog"))e.closeTransientOverlays("toast");this._toast=e,clearTimeout(this._toastTimer),this._toastTimer=window.setTimeout(()=>{this._toast=""},3500)}_syncPointerHoverTargets(){const e=this._pointerModality.hoverEnabled;for(const t of this.renderRoot.querySelectorAll(Dv))t.toggleAttribute("data-pointer-hover",e)}_syncPointerHoverSubtree(e){if(e.nodeType!==Node.ELEMENT_NODE)return;const t=e,i=this._pointerModality.hoverEnabled;t.matches(Dv)&&t.toggleAttribute("data-pointer-hover",i);for(const e of t.querySelectorAll(Dv))e.toggleAttribute("data-pointer-hover",i)}_clearTransientHover(e=!1){e&&this._pointerModality.suspend(),this._tip&&(this._tip=null),this._hoverRoom&&(this._hoverRoom=null)}_notePointer(e){const t=this._pointerModality.modality,i=this._pointerModality.note(e);"touch"!==i&&"pen"!==i||t===i&&!this._tip&&!this._hoverRoom||this._clearTransientHover()}_guardTouchGesture(e){if(this._editorSecondary.handleOutsideDismiss(e))return;if("click"===e.type){if(!this._suppressClick&&!this._touchSequenceMultitouch&&Date.now()>this._touchClickBlockUntil)return;return e.preventDefault(),void e.stopImmediatePropagation()}const t=e;if(this._notePointer(t),"touch"===t.pointerType)if("pointerdown"!==e.type){if("pointermove"===e.type){const e=this._touchContacts.get(t.pointerId);if(!e)return;const i={...e,x:t.clientX,y:t.clientY};if(this._touchContacts.set(t.pointerId,i),this._touchSequenceMultitouch&&"view"===this._mode&&!this._vacFit&&this._pinchStart&&[...this._touchContacts.values()].every(e=>e.inStage)){this._pointers.set(t.pointerId,{x:t.clientX,y:t.clientY});const e=[...this._touchContacts.values()];if(e.length>=2&&this._stageEl){const[t,i]=e,s=Math.hypot(t.x-i.x,t.y-i.y)/(this._pinchStart.dist||1),n=this._stageEl.getBoundingClientRect();this._zoomAt((t.x+i.x)/2-n.left,(t.y+i.y)/2-n.top,this._pinchStart.zoom*s),this._saveZoom()}}return}if("pointerup"===e.type||"pointercancel"===e.type||"lostpointercapture"===e.type){if(this._clearTransientHover(),this._touchContacts.delete(t.pointerId),this._touchSequenceMultitouch){if(this._touchClickBlockUntil=Date.now()+500,this._pointers.delete(t.pointerId),!this._vacFit&&this._pointers.size>=2){const[e,t]=[...this._pointers.values()];this._pinchStart={dist:Math.hypot(e.x-t.x,e.y-t.y),zoom:this._zoom}}else this._pinchStart=null;0===this._pointers.size&&(this._panStart=null,this._panLock=null)}0===this._touchContacts.size&&(this._touchSequenceMultitouch=!1)}}else if(this._touchContacts.set(t.pointerId,{x:t.clientX,y:t.clientY,inStage:!!t.target?.closest?.(".stage")}),this._touchContacts.size>=2){this._clearTransientHover(),this._touchSequenceMultitouch=!0,this._touchClickBlockUntil=Number.POSITIVE_INFINITY,clearTimeout(this._holdTimer),clearTimeout(this._kioskHoldTimer),this._swipeStart=null;const e=[...this._touchContacts.values()];if("view"===this._mode&&!this._vacFit&&e.every(e=>e.inStage)){this._pointers=new Map([...this._touchContacts].map(([e,t])=>[e,{x:t.x,y:t.y}]));const[t,i]=e;this._pinchStart={dist:Math.hypot(t.x-i.x,t.y-i.y),zoom:this._zoom},this._panStart=null,this._panLock=null}else this._vacFit&&(this._pointers.clear(),this._pinchStart=null,this._panStart=null,this._panLock=null)}}_showTip(e,t,i,s,n,o){this._notePointer(e),this._pointerModality.hoverEnabled&&(this._drag||(this._tip={x:e.clientX,y:e.clientY,title:t,meta:i,lqi:s,temp:n,hum:o}))}get _gridPitch(){return Nh}get _cellCm(){const e=Number(this._curSpaceCfg?.cell_cm);return Number.isFinite(e)&&e>0?e:5}_fmtLen(e,t){const i=function(e,t,i,s){return Math.hypot(t[0]-e[0],t[1]-e[1])/i*s}(e,t,this._gridPitch,this._cellCm);return li(i,"mi"===this.hass?.config?.unit_system?.length)}get _curSpaceCfg(){const e=this._resize.preview;return e&&e.space===this._space?e.sp:this._serverCfg?.spaces.find(e=>e.id===this._space)}get _renderCfg(){const e=this._resize.preview;return e&&this._serverCfg?{...this._serverCfg,spaces:this._serverCfg.spaces.map(t=>t.id===e.space?e.sp:t)}:this._serverCfg}get _spaceH(){return this._curSpaceCfg,Pv}get _segments(){const e=this._curSpaceCfg,t=this._spaceH;return pi(e?.rooms||[]).map(e=>[e[0]*Pv,e[1]*t,e[2]*Pv,e[3]*t])}_savedNav(){if(this._hasFixedFloor)return null;try{return JSON.parse(localStorage.getItem(Sv)||"null")}catch{return null}}_saveNav(){if(!this._hasFixedFloor)try{localStorage.setItem(Sv,JSON.stringify({space:this._space}))}catch{}}_leaveCardRoute(){if(this._routeDepartureHandled)return;this._routeDepartureHandled=!0,"view"!==this._mode&&this._setMode("view",!1),this._pendingNavMode=null,this._geometryHistory.clear(),this._activeDraftId=null,this._resumeDraftBySpace={},this._draftSegmentCms=[],this._closingWallCm=null,this._drawWallField=null,this._showHidden=!1,this._tapConfirm=null,this._vacCalConfirm=null,this._decorEraseConfirm=null,this._openingInfo=null,this._closeInfoCard(),this._rulesDialog=null,this._alignDialog=null,this._preflightClipboardFallback=null,this._backupImportDialog=null,this._backupExportDialog=null,this._settingsDialog=null,this._deviceInbox=null,this._deviceInboxReturn=null,this._markerDialog=null,this._openingDialog=null,this._physicalDialog=null,this._wallDialog=null,this._backdropDialog=null,this._decorShapeDialog=null,this._decorTextDialog=null,this._mergeDialog=null,this._roomDialog=!1,this._spaceDialog=null,this._importDialog=null;const e=this._warmSlot;e?.owner===this._warmGen&&(e.vp=this._warmViewportState(),e.dlg=null,e.frameFingerprint="",clearTimeout(e.evict),e.evict=0),this._saveNav()}_setMode(e,t=!0){this._endTabDrag(),this._pendingNavMode=null;const i=this._spaceModel();if(!i)return this._cancelModeTransition(!1),void(this._mode="view");if(this._kiosk&&"view"!==e)return;if(this._mode===e){if(!t&&"view"===e&&this._modeTransitionBusy){const t=this._currentModeVisual(e),i=this._modeTransitionTargetZoom,s=this._modeTransitionTargetCenterX,n=this._modeTransitionTargetCenterY;this._cancelModeTransition(!1),this._commitViewModeAtomic(t,i,s,n)}return}if(this._bootSoftCancel(),("plan"===e||"decor"===e)&&!this._norm)return void this._showToast(this._t("toast.markup_needs_server"));if(this._wallFaceBatch&&this._roomDialogCancel(),"plan"===this._mode&&"draw"===this._tool&&!this._finishWallChain())return;this._clearTransientHover(!0),this._cancelDevicePressFeedback();const s=this._mode,n=this._effectiveProjection(),o=this._currentModeVisual(s),a=this._modeTransitionBusy,r=o&&"view"!==s&&"view"!==e?{...o,toolbarContentOpacity:this._reducedMotion?1:.35}:o;this._cancelModeTransition(!1),this._editorSecondary.closeForNavigation(),(this._decorMove||this._dtDrag||this._bdDrag)&&this._cancelDecorGesture();const l=!i.bg&&"view"===e!=("view"===s),c=a&&"view"===s&&"view"!==e?this._modeTransitionEditorCamera:null;let h=c?.zoom??(a?this._modeTransitionTargetZoom:this._zoom),d=c?c.centerX:a?this._modeTransitionTargetCenterX:r?.viewport.centerX,p=c?c.centerY:a?this._modeTransitionTargetCenterY:r?.viewport.centerY;if("view"===s&&"view"!==e&&!a){const t=this._view;if(this._viewModeSnap={space:this._space,zoom:this._zoom,cx:t?this._logicalViewCenter(n)?.x:void 0,cy:t?this._logicalViewCenter(n)?.y:void 0},"iso"===n){const t=this._logicalViewCenter("iso");d=t?.x,p=t?.y,this._view=null,this._mode=e,this._applyView(this._zoom,t?.x,t?.y)}l&&(h=1,d=void 0,p=void 0)}if("plan"===s&&this._activeDraftId&&(this._resumeDraftBySpace[this._space]=this._activeDraftId),this._mode=e,"devices"===s&&"devices"!==e&&(this._showHidden=!1,this._deviceInbox=null,this._deviceInboxReturn=null,this._deviceInboxMemo=null),this._editorChromeMode="view"===e?s:e,"view"===e){"view"===s||a||(this._modeTransitionEditorCamera={zoom:this._zoom,centerX:r?.viewport.centerX,centerY:r?.viewport.centerY});const e=this._viewModeSnap;if(e&&e.space===this._space){h=e.zoom;const t=this._labsIso&&"iso"===this._viewPreference[this._space]?"iso":"flat",i=null!=e.cx&&null!=e.cy&&"iso"===t?$f([e.cx,e.cy],0):null;d=i?.[0]??e.cx,p=i?.[1]??e.cy}else e&&(h=this._zoomBySpace[this._space]||1,d=void 0,p=void 0)}else this._modeTransitionEditorCamera={zoom:h,centerX:d,centerY:p};this._modeTransitionTargetZoom=h,this._modeTransitionTargetCenterX=d,this._modeTransitionTargetCenterY=p,("iso"===n||"view"===e&&this._labsIso&&"iso"===this._viewPreference[this._space])&&(this._modeTransitionForceAtomic=!0);const u=++this._modeTransitionRequest;t?r?(this._modeTransitionPreparing=!0,this._modeTransitionVisual=r,this._prepareModeTransition(u,r,e,h,d,p)):(this._modeTransitionPreparing=!1,this._modeTransitionVisual=null,this._zoom=h,this._view=null,requestAnimationFrame(()=>{this.isConnected&&u===this._modeTransitionRequest&&this._mode===e&&(this._applyView(h,d,p),"view"===e&&(this._viewModeSnap=null,this._modeTransitionEditorCamera=null),this.requestUpdate())})):"view"===e&&this._commitViewModeAtomic(r,h,d,p),this._path=[],this._clearPlanSnapHover(),this._clearOpeningPlacement(!0),this._tool="draw",this._mergeSel=null,this._mergeDialog=null,this._splitSel=null,this._pendingSplit=null,this._selId=null,this._physicalSel=null,this._physicalDialog=null,this._physicalDrag=null,this._rszResetController(),this._tip=null,this._hoverRoom=null,this._decorDraft=null,this._decorSel=null,this._decorMove=null,this._backdropDialog=null,this._decorTool="select",this._bdDrag=null,this._dtDrag=null,this._dtBox=null,"plan"===e&&(this._primeDrawWallField(),this._resumeLastDraft()),this._saveNav()}_primeDrawWallField(){null===this._drawWallField&&(this._drawWallField=yl(ul,this._imperial))}get _drawWallFieldValue(){return null===this._drawWallField?yl(ul,this._imperial):this._drawWallField}get _drawWallCm(){const e=mv(this._drawWallFieldValue);if(null==e||e<0)return null;const t=this._imperial?2.54*e:e,i="column"===this._tool?Xc:100;return t>=("column"===this._tool?1:0)&&t<=i?t:null}get _drawWallMaxCm(){return"column"===this._tool?Xc:100}_showPhysicalRange(e=this._drawWallMaxCm,t=0){this._showToast(this._t("toast.physical_range",{min:yl(t,this._imperial),max:yl(e,this._imperial),unit:this._t(this._imperial?"wallthick.unit_in":"wallthick.unit_cm")}))}_draftSegmentCount(e=this._curSpaceCfg){return(e?.room_drafts||[]).reduce((e,t)=>e+(Array.isArray(t.segments)?t.segments.length:0),0)}_mergeSpacePartitions(e,t){const i=e?.partitions||[];if(i.length<2)return 0;const s=Tm(i,{pitch:Eh,seedIds:t,geometry:Rm(e,{excludeDraftId:this._activeDraftId})});return s.merged?(e.partitions=s.partitions,Im(e.openings,e.partitions,s.openingMoves,{coordScale:Pv,cellCm:this._cellCm,gridPitch:this._gridPitch}),s.merged):0}_finishWallChain(){if("draw"!==this._tool||this._wallFaceBatch||this._roomDialog)return!0;const e=this._curSpaceCfg;if(!e||this._path.length<2)return this._path=[],this._activeDraftId=null,this._draftSegmentCms=[],this._closingWallCm=null,this._clearPlanSnapHover(),!0;const t=xu(this._path,ku(this._path.length-1,this._draftSegmentCms,this._drawWallCm,ul)),i=t.length;if((e.partitions||[]).length+i>Av)return this._showToast(this._t("toast.physical_limit")),!1;const s=this._geometrySnapshot();e.partitions||=[];const n=Date.now().toString(36),o=[],a=this._activeDraftId?(e.room_drafts||[]).find(e=>e.id===this._activeDraftId):null,r=this._draftSegmentsForPath(this._path,a,t.map(e=>e.cm));for(let s=0;se.id!==this._activeDraftId),e.room_drafts.length||delete e.room_drafts),this._commitPhysicalGeometry(this._t("history.wall_chain_finish"),s),delete this._resumeDraftBySpace[this._space],this._path=[],this._activeDraftId=null,this._draftSegmentCms=[],this._closingWallCm=null,this._clearPlanSnapHover(),!0}_activateMarkupTool(e){e!==this._tool&&(this._wallFaceBatch&&this._roomDialogCancel(),("draw"!==this._tool||this._finishWallChain())&&(this._cancelPath(),"resize"===this._tool&&(this._resize.dragging?this._rszCancelDrag():this._resize.reset()),this._tool=e,"draw"===e&&this._resumeLastDraft(),"resize"===e&&this._resize.selectRoom(null),"wallthick"===e&&(this._wallDialog=null)))}_limitReached(e){const t=this._curSpaceCfg;if(!t)return!0;const i="draft"===e?(t.room_drafts||[]).length>=200:"partition"===e?(t.partitions||[]).length>=Av:(t.wall_columns||[]).length>=500;return i&&this._showToast(this._t("toast.physical_limit")),i}_svgPoint(e){const t=this.renderRoot.querySelector(".stage").getBoundingClientRect();return this._screenToVb(e.clientX-t.left,e.clientY-t.top)}_snap(e){const t=this._gridPitch;return[Lh(ri(e[0],t)),Lh(ri(e[1],t))]}_snapDrawPoint(e,t=!1){const i=this._path[this._path.length-1],s=t&&i?function(e,t,i,s=1/0){if(!(i>0&&e?.every(Number.isFinite)&&t?.every(Number.isFinite)))return[t[0],t[1]];const n=t[0]-e[0],o=t[1]-e[1];if(Math.abs(n)+Math.abs(o)<=1e-12)return[e[0],e[1]];const a=Math.PI/4;let r=Math.atan2(o,n);r<0&&(r+=2*Math.PI);const l=Math.floor(r/a+.5)%8,[c,h]=[[1,0],[1,1],[0,1],[-1,1],[-1,0],[-1,-1],[0,-1],[1,-1]][l],d=c*c+h*h;let p=Math.max(0,Math.round((n*c+o*h)/(i*d)));if(Number.isFinite(s)&&s>=0){const t=(e,t)=>{if(!t)return 1/0;const n=t>0?s-e:e+s;return Math.max(0,Math.floor((n+1e-9*i)/i))};p=Math.min(p,t(e[0],c),t(e[1],h))}return[e[0]+c*p*i,e[1]+h*p*i]}(i,e,this._gridPitch,zh):e;return this._snap(s)}_planSnapOpeningCuts(e,t){if(!this._openingsR.length)return[];const i=this._openingWallIndexFor(e,t).value,s=[];for(const t of this._roomWallOpeningInputs(this._openingsR,e)){const e=Gc(i,t);if(!e.negative&&!e.positive)continue;const n=t.angle*Math.PI/180,o=Math.cos(n)*t.length/2,a=Math.sin(n)*t.length/2;s.push([t.x-o,t.y-a,t.x+o,t.y+a])}return s}_planSnapGeometrySnapshot(){const e=this._spaceModel();if(!e)return{key:`${this._space}|empty`,value:{segments:[],endpoints:[]}};const t=[this._space,this._cfgEpoch,this._activeDraftId||"",e.rooms.length,e.room_drafts.length,e.partitions.length].join("|");if(this._planSnapGeometryCache?.key===t)return this._planSnapGeometryCache;const i=this._openCuts(),s=_u({space:e,activeDraftId:this._activeDraftId,roomCuts:this._planSnapOpeningCuts(e,i),partitionCuts:this._partitionOpeningCuts(e),epsilon:2e-4*this._gridPitch});return this._planSnapGeometryCache={key:t,value:s},this._planSnapGeometryCache}_hiddenWallDiagnosticSnapshot(){const e=this._spaceModel();if(!e)return{key:`${this._space}|hidden-empty`,value:{segments:[],endpoints:[]}};const t=["hidden",this._space,this._cfgEpoch,this._activeDraftId||"",e.rooms.length,e.room_drafts.length,e.partitions.length].join("|");if(this._hiddenWallDiagnosticCache?.key===t)return this._hiddenWallDiagnosticCache;const i=uu({space:e,activeDraftId:this._activeDraftId,epsilon:2e-4*this._gridPitch});return this._hiddenWallDiagnosticCache={key:t,value:i},this._hiddenWallDiagnosticCache}_planStructuralGeometrySnapshot(){const e=this._spaceModel();if(!e)return{key:`${this._space}|structural-empty`,value:{segments:[],endpoints:[]}};const t=["structural",this._space,this._cfgEpoch,this._activeDraftId||"",e.rooms.length,e.room_drafts.length,e.partitions.length].join("|");if(this._planStructuralGeometryCache?.key===t)return this._planStructuralGeometryCache;const i=_u({space:e,activeDraftId:this._activeDraftId,epsilon:2e-4*this._gridPitch});return this._planStructuralGeometryCache={key:t,value:i},this._planStructuralGeometryCache}_planSnapContextKey(e){const t=this._path[0],i=this._path[this._path.length-1];return[e,this._tool,this._path.length,t?`${t[0]},${t[1]}`:"",i?`${i[0]},${i[1]}`:""].join("|")}_resolvePlanDrawPoint(e,t){const i=this._planSnapGeometrySnapshot(),s=this._path[this._path.length-1],n="draw"===this._tool&&this._path.length>=3?[{point:this._path[0],key:"closure:first-point"}]:[],o={tolerance:this._cssPxToRender(12),distinguishTolerance:this._cssPxToRender(8),gridStep:this._gridPitch,excludePoints:s?[s]:[],extraEndpoints:n,epsilon:2e-4*this._gridPitch},a=t&&s?yu(i.value,e,{...o,anchor:s}):function(e,t,i){if(!(ou(t)&&i.tolerance>=0))return{kind:"none",candidate:null,conflicts:[]};const s=i.epsilon??nu,n=i.excludePoints||[],o=vu(fu(e,t,i),i.distinguishTolerance||0);if(o)return o;let a=null;for(const o of e.segments){const e=[o.a[0],o.a[1],o.b[0],o.b[1]],r=Hs([t[0],t[1]],e);if(r>i.tolerance)continue;const l=bu(o,t,i.gridStep);!mu(l,n,s)&&gu(r,o.key,a)&&(a={kind:"line",point:l,key:o.key,distance:r,segment:o})}return a?{kind:"resolved",candidate:a,conflicts:[]}:{kind:"none",candidate:null,conflicts:[]}}(i.value,e,o),r="resolved"===a.kind?a.candidate:null,l=r?[...r.point]:this._snapDrawPoint(e,t),c=s?ua(s,l):l;return{point:c,candidate:r&&fi(c,r.point)?r:null,conflicts:"ambiguous"===a.kind?a.conflicts:[],ambiguous:"ambiguous"===a.kind,contextKey:this._planSnapContextKey(i.key)}}get _activePlanSnapCandidate(){if(!this._markup||"draw"!==this._tool)return null;const e=this._planSnapHover;if(!e)return null;const t=this._planSnapGeometrySnapshot();return e.contextKey===this._planSnapContextKey(t.key)?e.candidate:null}get _activePlanSnapConflicts(){if(!this._markup||"draw"!==this._tool)return[];const e=this._planSnapHover;if(!e)return[];const t=this._planSnapGeometrySnapshot();return e.contextKey===this._planSnapContextKey(t.key)?e.conflicts:[]}_clearPlanSnapHover(e=!0){this._planSnapHover=null,this._syncPlanSnapActiveMarker(null),this._syncPlanSnapConflictMarkers([]),e&&(this._cursorPt=null)}_samePt(e,t){return fi(e,t)}_dropLegacySegments(){for(const e of this._serverCfg?.markers||[])"ripple"===e.display&&(e.display="icon_ripple");for(const e of this._serverCfg?.spaces||[]){delete e.segments;const t=new Set,i=e=>"string"==typeof e&&e.length>=1&&e.length<=64&&!t.has(e),s=e=>(t.add(e),!0),n=e=>Array.isArray(e)&&2===e.length&&e.every(e=>Number.isFinite(Number(e))&&Math.abs(Number(e))<=Ah);if(Array.isArray(e.partitions)&&(e.partitions=e.partitions.filter(e=>e&&i(e.id)&&n(e.a)&&n(e.b)&&Math.hypot(e.a[0]-e.b[0],e.a[1]-e.b[1])>1e-9&&s(e.id)).map(e=>({...e,cm:Number.isFinite(Number(e.cm))?Math.max(0,Math.min(100,Number(e.cm))):15})),e.partitions.length||delete e.partitions),Array.isArray(e.wall_columns)&&(e.wall_columns=e.wall_columns.filter(e=>e&&i(e.id)&&n(e.center)&&s(e.id)).map(e=>({id:e.id,shape:"circle"===e.shape?"circle":"square",center:[Number(e.center[0]),Number(e.center[1])],cm:Qc(Number(e.cm)||15),..."circle"===e.shape?{}:{angle:eh(e.angle)}})),e.wall_columns.length||delete e.wall_columns),Array.isArray(e.room_drafts)&&(e.room_drafts=e.room_drafts.filter(e=>e&&i(e.id)&&Array.isArray(e.points)&&e.points.length>=2&&e.points.every(n)&&s(e.id)).map(e=>{const t=rg(e);return{id:e.id,...t}}).filter(e=>e.points.length>=2),e.room_drafts.length||delete e.room_drafts),Array.isArray(e.walls)){const t=Ud(Rh({spaces:[e]}),e.id),i=t?j_(e,t,Pv,.02*Nh).contour.map(e=>e.map(e=>e/Pv)):Ad(e.open_spans).map(e=>[e.a[0],e.a[1],e.b[0],e.b[1]]);e.walls=Fl(e.walls,e.rooms||[],Eh,1,i),e.walls.length||delete e.walls}}}_rollbackRejectedPhysicalWrites(e){if(!this._serverCfg||!e.length)return!1;let t=!1;for(const[i]of e){const e=this._pendingPhysicalWrites.get(i);e&&(t=this._restoreGeometryStateInConfig(this._serverCfg,e.before)||t,this._pendingPhysicalWrites.delete(i))}return!!t&&(this._clearGeometryGesture(),this._geometryHistory.clear(),this._cfgEpoch++,this._modelCache=null,this._wallUnionCache=null,this._physicalBodiesCache=null,this._frame=null,this._regSignature="",this._cfgContentFingerprint=Bd(this._serverCfg),this._maybeRebuildDevices(),this.requestUpdate(),!0)}async _reloadRejectedPhysicalWrite(){const e=this._writeChain;await e.catch(()=>{}),await this._reloadConfigOnly(!0)}get _cfgWriting(){return this._writesPending>0}_writeConfig(){var e,t;this._writesPending++,this._writeChain=(e=this._writeChain,t=async()=>{if(!this._serverCfg)return;this._dropLegacySegments();const e=pl(Xr(this._serverCfg)),t=Bd(e),i=[...this._pendingPhysicalWrites.entries()];for(const[t,s]of i){const i=Ng(e.spaces.find(e=>e.id===t));if(i===s.fingerprint)continue;let n=!1;try{n=this._checkSpacePhysicalGeometry(e,t).ok}catch{n=!1}if(!n)throw this._restoreGeometryStateLocal(s.before),this._pendingPhysicalWrites.delete(t),this._geometryHistory.clear(),this._showToast(this._t("toast.geometry_unsafe")),Object.assign(new Error("unsafe wall geometry"),{code:"geometry-unsafe"});s.fingerprint=i}let s;t!==Bd(this._serverCfg)&&(this._serverCfg=e),this._cfgContentFingerprint=t;try{s=await this.hass.callWS({type:"houseplan/config/set",config:e,expected_rev:this._cfgRev})}catch(e){if(!this._rollbackRejectedPhysicalWrites(i))throw e;const t=e&&"object"==typeof e?e:Object.assign(new Error(String(e)),{cause:e});throw t.physicalGeometryRolledBack=!0,t}this._cfgRev=s?.rev??this._cfgRev+1;for(const[e,t]of i)this._pendingPhysicalWrites.get(e)?.fingerprint===t.fingerprint&&this._pendingPhysicalWrites.delete(e)},e.catch(()=>{}).then(t));return this._writeChain.finally(()=>{this._writesPending--})}_saveConfig(){this._cfgEpoch++,this._saveConfigDebounced()}_geometrySnapshotFromConfig(e,t){const i=e?.spaces?.find(e=>e.id===t);if(!i)return null;const s=e=>JSON.parse(JSON.stringify(e)),n={};for(const e of["plan_x","plan_y","plan_scale","plan_scale_x","plan_scale_y","plan_angle"])void 0!==i[e]&&(n[e]=i[e]);return{spaceId:t,rooms:s(i.rooms||[]),...Array.isArray(i.openings)?{openings:s(i.openings)}:{},...Array.isArray(i.walls)?{walls:s(i.walls)}:{},...Array.isArray(i.wall_segments)?{wall_segments:s(i.wall_segments)}:{},...Array.isArray(i.open_spans)?{open_spans:s(i.open_spans)}:{},...Array.isArray(i.room_drafts)?{room_drafts:s(i.room_drafts)}:{},...Array.isArray(i.partitions)?{partitions:s(i.partitions)}:{},...Array.isArray(i.wall_columns)?{wall_columns:s(i.wall_columns)}:{},...Array.isArray(i.decor)?{decor:s(i.decor)}:{},plan_transform:n}}_geometrySnapshot(e=this._space){return this._geometrySnapshotFromConfig(this._serverCfg,e)}_recordGeometry(e,t){if(!t)return;const i=this._geometrySnapshot(t.spaceId);i&&JSON.stringify(t)!==JSON.stringify(i)&&(this._geometryHistory.push({name:e,before:t,after:i}),this.requestUpdate())}_restoreGeometryStateInConfig(e,t,i=!1){const s=e?.spaces?.find(e=>e.id===t.spaceId);if(!s)return!1;const n=e=>JSON.parse(JSON.stringify(e)),o=new Map((s.rooms||[]).map(e=>[e.id,e]));if(s.rooms=n(t.rooms),i)for(const e of s.rooms){const t=o.get(e.id);!Array.isArray(e.wall_ids)&&Array.isArray(t?.wall_ids)&&t.wall_ids.length===e.poly?.length&&(e.wall_ids=n(t.wall_ids))}const a=(e,t)=>{void 0!==t?s[e]=n(t):i&&"wall_segments"===e||delete s[e]},r=new Map((s.openings||[]).map(e=>[e.id,e])),l=new Map((s.room_drafts||[]).map(e=>[e.id,e]));if(a("openings",t.openings),a("walls",t.walls),a("wall_segments",t.wall_segments),a("open_spans",t.open_spans),a("room_drafts",t.room_drafts),a("partitions",t.partitions),a("wall_columns",t.wall_columns),a("decor",t.decor),i){for(const e of s.openings||[]){const t=r.get(e.id);e.host||"wall"!==t?.host?.kind||(e.host=n(t.host))}for(const e of s.room_drafts||[]){const t=l.get(e.id);for(let i=0;i<(e.segments||[]).length;i++)!e.segments[i]?.id&&t?.segments?.[i]?.id&&(e.segments[i].id=t.segments[i].id)}}for(const e of["plan_x","plan_y","plan_scale","plan_scale_x","plan_scale_y","plan_angle"])delete s[e];return Object.assign(s,n(t.plan_transform||{})),!0}_restoreGeometryStateLocal(e){return!!this._restoreGeometryStateInConfig(this._serverCfg,e)&&(this._cfgEpoch++,this._modelCache=null,this._wallUnionCache=null,this._physicalBodiesCache=null,this._frame=null,this.requestUpdate(),!0)}_wallModelBlockerLabel(e){const t=e instanceof Qm?e.reason:"invalid-room";return this._t(`wall_model.reason.${t}`)}_hasLegacyZeroWallFields(e=this._serverCfg){return(e?.spaces||[]).some(e=>Array.isArray(e?.open_spans)&&e.open_spans.length>0||(e?.rooms||[]).some(e=>Array.isArray(e?.open_to)&&e.open_to.length>0))}_showWallModelMigrationBlocked(e){const t=this._hasLegacyZeroWallFields()?"toast.zero_wall_migration_blocked":"toast.wall_model_migration_blocked";this._showToast(this._t(t,{reason:this._wallModelBlockerLabel(e)}))}_limitSegmentsOf(e){const t=[];for(const i of e?.wall_segments||[])i?.a&&i?.b&&t.push({id:String(i.id||""),a:i.a,b:i.b,cm:Number(i.cm)});for(const i of e?.partitions||[])i?.a&&i?.b&&t.push({id:String(i.id||""),a:i.a,b:i.b,cm:Number(i.cm)});for(const i of e?.room_drafts||[]){const e=Array.isArray(i?.points)?i.points:[],s=Array.isArray(i?.segments)?i.segments:[];for(let n=0;n+1e?.id===t);if(!i)return[];const s=Number(i.cell_cm)>0?Number(i.cell_cm):5,n=this._limitSegmentsOf(i),o=[...xd(n),...Md(n,s,Eh),...Dd(n,s,Eh)];for(const e of i.rooms||[]){const t=String(e?.id||"");if(!t)continue;let n=null;try{n=kc(i.rooms||[],t,i.walls||[],[],Eh,s,Eh,1)}catch{n=null}o.push(...Pd(t,n,s,Eh))}return o}_junctionLimitLabel(e){const t=e=>String(Math.round(10*e)/10);return this._t(`junction.limit_${e.rule}`,{actual:t(e.actual),limit:t(e.limit)})}_junctionLimitsIntroduced(e,t,i){let s=[];try{const e=$g(t).config;s=this._junctionLimitViolations(e,i)}catch{return[]}let n=[];try{n=this._junctionLimitViolations(e,i)}catch{return[]}return function(e,t){const i=new Map;for(const e of t||[])i.set(e.rule,(i.get(e.rule)||0)+1);const s=new Map;for(const t of e||[])s.set(t.rule,[...s.get(t.rule)||[],t]);const n=[];for(const[e,t]of s){const s=t.length-(i.get(e)||0);s>0&&n.push(...t.slice(0,s))}return n}(n,s)}_commitPhysicalGeometry(e,t,i=[]){if(!t||!this._serverCfg)return!1;const s=this._serverCfg,n=this._geometrySnapshotFromConfig(s,t.spaceId),o=s.spaces.find(e=>e.id===t.spaceId);if(!o||Ng(t)===Ng(o))return!1;let a,r=!1;try{r=this._checkSpacePhysicalGeometry(s,t.spaceId).ok}catch{r=!1}if(!r)return this._clearGeometryGesture(),this._restoreGeometryStateLocal(t),this._showToast(this._t("toast.geometry_unsafe")),!1;let l=t;try{if(Number(s.model_version||0)<9){const e=JSON.parse(JSON.stringify(s));if(!this._restoreGeometryStateInConfig(e,t))throw new Qm("invalid-room",t.spaceId);const i=$g(e).config;l=this._geometrySnapshotFromConfig(i,t.spaceId)||t;const o=JSON.parse(JSON.stringify(i));if(!n||!this._restoreGeometryStateInConfig(o,n,!0))throw new Qm("invalid-room",t.spaceId);const r=i.spaces.find(e=>e.id===t.spaceId),c=o.spaces.find(e=>e.id===t.spaceId);if(!Array.isArray(n.wall_segments)&&JSON.stringify(t.rooms)===JSON.stringify(n.rooms))for(const e of c?.wall_segments||[])e.cm=zl(n.walls,e.a,e.b,Eh,1);const h=((e,t,i)=>{const s=new Map,n=new Map((e?.rooms||[]).map(e=>[e.id,e])),o=new Map((t||[]).map(e=>[e.id,e])),{rooms:a}=bg(i,fg(e));for(const e of a){const t=o.get(e.id),a=n.get(e.id),r=hi(t),l=hi((i.rooms||[]).find(t=>t.id===e.id)),c=hi(a);if(r&&l&&c&&r.length===l.length&&c.length===a?.wall_ids?.length&&e.poly.length===e.wall_ids.length)for(let t=0;t{const n=[];for(let o=0;oZm||hg(r,i,s)>Zm)continue;const l=cg(a,i,s),c=cg(r,i,s);l<-Zm||c>1+Zm||c<=l+Zm||n.push({start:l,id:t[o]})}return n.sort((e,t)=>e.start-t.start)},n=i(c,a.wall_ids,r[t],r[(t+1)%r.length]),o=i(e.poly,e.wall_ids,l[t],l[(t+1)%l.length]);if(n.length&&n.length===o.length)for(let e=0;ee.id===t.spaceId),s=this._path.length>=2?this._path.map(e=>[e[0]/Pv,e[1]/Pv]):[];s.push(...i.map(e=>[e[0],e[1]])),c=lg(e)<=lg(l,s)&&this._checkSpacePhysicalGeometry(a,t.spaceId).ok}catch{c=!1}if(!c)return this._clearGeometryGesture(),this._restoreGeometryStateLocal(t),this._showToast(this._t("toast.geometry_unsafe")),!1;const h=JSON.parse(JSON.stringify(s));this._restoreGeometryStateInConfig(h,t);const d=this._junctionLimitsIntroduced(a,h,t.spaceId);if(d.length)return this._clearGeometryGesture(),this._restoreGeometryStateLocal(t),this._showToast(this._junctionLimitLabel(d[0])),!1;Mg(s,a),this._recordGeometry(e,l);const p=s.spaces.find(e=>e.id===t.spaceId),u=this._pendingPhysicalWrites.get(t.spaceId);return this._pendingPhysicalWrites.set(t.spaceId,{before:u?.before||l,fingerprint:Ng(p)}),this._saveConfig(),!0}_clearGeometryGesture(){this._path=[],this._clearPlanSnapHover(),this._clearOpeningPlacement(!1),this._mergeSel=null,this._mergeDialog=null,this._splitSel=null,this._pendingSplit=null,this._wallFaceBatch=null,this._wallRepairDiagnostic=null,this._roomDeleteDialog=null,this._wallDialog=null,this._physicalDialog=null,this._physicalSel=null,this._physicalDrag=null,this._physicalRotate=null,this._activeDraftId=null,this._draftSegmentCms=[],this._closingWallCm=null,this._openingDialog=null,this._rszResetController(),this._decorDraft=null,this._decorMove=null,this._dtDrag=null,this._bdDrag=null}_stagePointerCancel(e){if(clearTimeout(this._kioskHoldTimer),this._swipeStart?.id===e.pointerId&&(this._swipeStart=null),this._physicalDrag?.pid===e.pointerId||this._physicalRotate?.pid===e.pointerId)return void this._cancelPhysicalGesture();if(this._decorDraft?.pid===e.pointerId)return this._decorDraft=null,void this.requestUpdate();if(this._decorMove?.pid===e.pointerId||this._dtDrag?.pid===e.pointerId||this._bdDrag?.pid===e.pointerId)return void this._cancelDecorGesture();"opening"===this._tool?(this._cursorPt=null,this._clearOpeningPlacement(!1)):"draw"===this._tool&&this._clearPlanSnapHover();const t=!!this._pinchStart||!!this._panStart;this._pointers.delete(e.pointerId),this._pointers.size<2&&(this._pinchStart=null),0===this._pointers.size&&(this._panStart=null,this._panLock=null),t&&0===this._pointers.size&&this.requestUpdate()}_applyGeometryState(e,t=!1){if(!this._canCommitSpace(e.spaceId))return!1;const i=this._geometrySnapshot(e.spaceId);if(!i||!this._restoreGeometryStateLocal(e))return!1;const s=this._serverCfg,n=Ng(i)!==Ng(e);if(n){let n=!1;try{const i=s?this._checkSpacePhysicalGeometry(s,e.spaceId):null;n=!!i?.ok||!(!t||"wall-degraded-extra"!==i?.reason)}catch{n=!1}if(!n)return this._restoreGeometryStateLocal(i),this._showToast(this._t("toast.geometry_unsafe")),!1}let o;try{o=$g(s).config}catch(e){return this._restoreGeometryStateLocal(i),this._showWallModelMigrationBlocked(e),!1}if(n){let n=!1;try{const i=o?this._checkSpacePhysicalGeometry(o,e.spaceId):null;n=!!i?.ok||!(!t||"wall-degraded-extra"!==i?.reason)}catch{n=!1}if(!n)return this._restoreGeometryStateLocal(i),this._showToast(this._t("toast.geometry_unsafe")),!1;Mg(s,o);const a=s?.spaces.find(t=>t.id===e.spaceId),r=this._pendingPhysicalWrites.get(e.spaceId);this._pendingPhysicalWrites.set(e.spaceId,{before:r?.before||i,fingerprint:Ng(a)})}else Mg(s,o);return this._clearGeometryGesture(),this._space!==e.spaceId&&(this._commitSpace(e.spaceId),this._saveNav(),this._restoreZoom()),this._modelCache=null,this._frame=null,this._regSignature="",this._maybeRebuildDevices(),this._saveConfig(),this.requestUpdate(),!0}_roomAt(e){return this._spaceModel()?.rooms.find(t=>{const i=hi(t);return!!i&&wi(e,i)})}_overlapRoom(e){return this._spaceModel()?.rooms.find(t=>{const i=hi(t);return!!i&&Di(e,i)})}_pointInRoom(e,t){return t.poly?vi(e,t.poly):null!=t.x&&e[0]>=t.x&&e[0]<=t.x+t.w&&e[1]>=t.y&&e[1]<=t.y+t.h}_contourSelfIntersects(e){if(!Ra(e))return!0;const t=e.length,i=.001;for(let s=0;s=500)return this._showToast(this._t("toast.physical_limit")),!1;const e=this._curSpaceCfg;return!(!this._activeDraftId&&(e?.room_drafts||[]).length>=200||this._draftSegmentCount(e)>=2e3||(e?.partitions||[]).length+this._path.length>Av)||(this._showToast(this._t("toast.physical_limit")),!1)}_markupClick(e){if(this._vacFit)return;if(!this._markup)return;const t=this._spaceModel();if(!t)return void this._clearGeometryGesture();if(this._suppressClick)return;if(this._drag||this._rlResize)return;const i=e.composedPath?.()||[];if(i.some(e=>e?.classList?.contains?.("roomlabel")||e?.classList?.contains?.("rlhandle")))return;if(i.some(e=>e?.classList?.contains?.("physical-hit")))return;const s=this._svgPoint(e);if("select"===this._tool)return void(this._physicalSel=null);if("resize"===this._tool){if(this._resize.dragging||i.some(e=>e?.classList?.contains?.("rszhandle")))return;const e=[...t.rooms].reverse().find(e=>this._pointInRoom(s,e));return this._resize.selectRoom(e?.id||null),void this.requestUpdate()}if("delroom"===this._tool)return void this._deleteRoomClick(s);if("opening"===this._tool)return void this._openingClick(s);if("merge"===this._tool)return void this._mergeClick(s);if("wallthick"===this._tool)return void this._wallThickClick(s);if("split"===this._tool)return void this._splitClick(s);if("column"===this._tool)return void this._columnClick(s);this._wallRepairDiagnostic=null;const n=this._resolvePlanDrawPoint(s,e.shiftKey);if(n.ambiguous)return this._planSnapHover={contextKey:n.contextKey,candidate:null,conflicts:n.conflicts},this._syncPlanSnapActiveMarker(null),this._syncPlanSnapConflictMarkers(n.conflicts),void this._showToast(this._t("toast.plan_snap_ambiguous"));let o=n.point;if(e.ctrlKey||e.metaKey){if(e.preventDefault(),this._path.length<3)return;o=ua(this._path[this._path.length-1],this._path[0])}if(!this._path.length){if(!e.shiftKey&&!n.candidate&&this._offerExistingWallFace(s))return;const t=this._draftEndAt(o);return t?(this._activeDraftId=t.draft.id,this._resumeDraftBySpace[this._space]=t.draft.id,this._path=t.reverse?[...t.draft.points].reverse().map(e=>[...e]):t.draft.points.map(e=>[...e]),void(this._draftSegmentCms=this._adoptDraftCms(this._path,t.reverse?[...t.draft.segments].reverse().map(e=>e.cm):t.draft.segments.map(e=>e.cm),t.draft.id))):(this._activeDraftId=null,this._draftSegmentCms=[],void(this._path=[o]))}const a=this._path[this._path.length-1];if(this._samePt(o,a))return;const r=this._draftEndAt(o,this._activeDraftId||void 0);if(r)return void this._mergeDraftEndpoint(r);if(!this._canAppendRoomDraftPoint())return;const l=this._drawWallCm;if(null==l)return void this._showPhysicalRange(100);const c=this._path.map(e=>[...e]);this._path=[...this._path,o],this._draftSegmentCms=[...this._draftSegmentCms,l],this._persistActiveDraftSegment(),this._offerWallFaces(c)}_draftEndAt(e,t){const i=this._spaceModel();if(!i)return null;const s=this._viewOr(this._baseVb()),n=Math.max(.15*this._gridPitch,this._stageEl?.clientWidth?s.w/this._stageEl.clientWidth*12:0);for(const s of i.room_drafts||[]){if(s.id===t)continue;if(s.points.length<2)continue;const i=s.points[0],o=s.points[s.points.length-1];if(Math.hypot(e[0]-o[0],e[1]-o[1])<=n)return{draft:s,reverse:!1};if(Math.hypot(e[0]-i[0],e[1]-i[1])<=n)return{draft:s,reverse:!0}}return null}_mergeDraftEndpoint(e){const t=this._curSpaceCfg;if(!t||!this._path.length)return;const i=this._path.map(e=>[...e]),s=this._wallGraphSources(i),n=Array.isArray(t.room_drafts)?t.room_drafts:[],o=this._activeDraftId?n.find(e=>e.id===this._activeDraftId):null,a=n.find(t=>t.id===e.draft.id);if(!a)return;const r=e.reverse?e.draft.points.map(e=>[...e]):[...e.draft.points].reverse().map(e=>[...e]),l=e.reverse?(a.segments||[]).map(e=>({...e})):[...a.segments||[]].reverse().map(e=>({...e})),c=this._path[this._path.length-1],h=this._samePt(c,r[0]),d=h?null:this._drawWallCm;if(!h&&null==d)return void this._showPhysicalRange(100);const p=this._draftSegmentsForPath(this._path,o,this._draftSegmentCms),u=[...this._path.map(e=>[...e]),...h?r.slice(1):r],_=[...p,...null==d?[]:[{cm:d}],...l],m=u.length>=4&&this._samePt(u[0],u[u.length-1]),g=u,f=_;if(g.length>500)return void this._showToast(this._t("toast.physical_limit"));const v=(o?.segments?.length||0)+(a.segments?.length||0);if(this._draftSegmentCount(t)-v+f.length>2e3)return void this._showToast(this._t("toast.physical_limit"));if(m){const e=g.slice(0,-1);if(this._contourSelfIntersects(e)||Ti(e)<=1e-6)return void this._showToast(this._t("toast.contour_cannot_close"));const t=this._overlapRoom(e);if(t)return void this._showToast(this._t("toast.room_overlap",{name:t.name||""}))}const b=this._geometrySnapshot(),y=this._activeDraftId||e.draft.id,w={...o||a,id:y,points:g.map(e=>[e[0]/Pv,e[1]/Pv]),segments:f};t.room_drafts=n.filter(t=>t.id!==e.draft.id&&(!this._activeDraftId||t.id!==this._activeDraftId)),t.room_drafts.push(w),this._activeDraftId=y,this._resumeDraftBySpace[this._space]=y,this._path=g,this._draftSegmentCms=this._adoptDraftCms(g,f.map(e=>Number(e.cm)),y),this._physicalSel=null,this._commitPhysicalGeometry(this._t("history.draft_merge"),b),null!=d&&this._offerWallFaces(i,i.length-1,s)}_adoptDraftCms(e,t,i){const s=Math.max(0,e.length-1),n=ku(s,t,this._drawWallCm,ul);return t.length!==s&&console.debug(`[houseplan] draft ${i??"?"}: восстановлено толщин ${s-t.length} (#234)`),n}_draftSegmentsForPath(e,t,i){const s=Array.isArray(t?.points)?t.points.map(e=>[Number(e?.[0])*Pv,Number(e?.[1])*Pv]):[],n=Array.isArray(t?.segments)?t.segments:[];return ku(Math.max(0,e.length-1),i,this._drawWallCm,ul).map((t,i)=>{const o=e[i],a=e[i+1],r=s.findIndex((e,t)=>{if(t+1>=s.length)return!1;const i=s[t+1];return this._samePt(o,e)&&this._samePt(a,i)||this._samePt(o,i)&&this._samePt(a,e)});return{...r>=0?n[r]:{},cm:t}})}_persistActiveDraftSegment(){if(this._path.length<2||!this._curSpaceCfg)return;const e=this._geometrySnapshot(),t=this._curSpaceCfg;t.room_drafts||=[],this._activeDraftId||(this._activeDraftId="draft-"+Date.now().toString(36)),this._resumeDraftBySpace[this._space]=this._activeDraftId;const i=t.room_drafts.findIndex(e=>e.id===this._activeDraftId),s={...i>=0?t.room_drafts[i]:{},id:this._activeDraftId,points:this._path.map(e=>[e[0]/Pv,e[1]/Pv]),segments:this._draftSegmentsForPath(this._path,i>=0?t.room_drafts[i]:null,this._draftSegmentCms)};i>=0?t.room_drafts[i]=s:t.room_drafts.push(s),this._commitPhysicalGeometry(this._t("history.draft_segment"),e)}_activeWallSourceKey(e){return`active:${this._activeDraftId||"session"}:${e}`}_wallGraphSources(e){const t=this._planStructuralGeometrySnapshot().value.segments.map(e=>({a:e.a,b:e.b,key:`static:${e.key}`}));for(let i=0;i+1e.key===i);if(s>=0){const[e]=this._wallFaceGraphCache.splice(s,1);return this._wallFaceGraphCache.push(e),e.value}const n=Uu(e,t);return this._wallFaceGraphCache.push({key:i,value:n}),this._wallFaceGraphCache.length>4&&this._wallFaceGraphCache.shift(),n}_offerWallFaces(e,t=this._path.length-2,i){if(this._path.length<2||this._wallFaceBatch||this._roomDialog)return;const s=this._spaceModel();if(!s)return;const n=this._activeWallSourceKey(t),o=2e-4*this._gridPitch;let a,r;try{const t=i||this._wallGraphSources(e);r=this._wallGraphSources(this._path),a=function(e,t,i){const s=new Set(e.faces.map(e=>e.key));return t.faces.filter(e=>!s.has(e.key)&&e.sourceKeys.includes(i))}(this._wallFaceGraph(t,o),this._wallFaceGraph(r,o),n)}catch{return}if(!a.length){const e=s_(r,{requiredSourceKey:n,maxDistance:wl(2,this._cellCm,this._gridPitch),gridStep:this._gridPitch,epsilon:o});return"ambiguous"===e.kind?(this._wallRepairDiagnostic=e.proposals[0]||null,void this._showToast(this._t(0===this._drawWallCm?"toast.zero_wall_ambiguous":"toast.wall_repair_ambiguous"))):void("repair"!==e.kind||this._overlapRoom(e.face.ring)||this._beginWallFaceBatch([{...e.face,repair:e.proposal}]))}for(const e of s.rooms){const t=hi(e);if(!e.id||!t)continue;const i=zi(t,this._path,.02*this._gridPitch);if(!i)continue;const[s,n]=i,o=Ti(s)>=Ti(n)?s:n,r=o===s?n:s,l=[...a].sort((e,t)=>Math.abs(e.area-Ti(r))-Math.abs(t.area-Ti(r))||e.key.localeCompare(t.key))[0];if(!l)return;return void this._beginWallFaceBatch([{...l,ring:r.map(e=>[e[0],e[1]]),split:{roomId:e.id,mainPoly:o,newPoly:r},consumeAllActive:!0}])}const l=a.filter(e=>!(e.ring.length<3||this._contourSelfIntersects(e.ring))&&!this._overlapRoom(e.ring));l.length&&this._beginWallFaceBatch(l)}_beginWallFaceBatch(e){this._wallRepairDiagnostic=null,this._wallFaceBatch={candidates:[...e].sort((e,t)=>e.area-t.area||e.key.localeCompare(t.key)),index:0,decisions:[],activePath:this._path.map(e=>[...e]),activeCms:[...this._draftSegmentCms],activeDraftId:this._activeDraftId},this._clearPlanSnapHover(),this._nameSel="",this._areaSel="",this._resetRoomDialogFields(),this._roomDialog=!0}_offerExistingWallFace(e){if(this._path.length||this._wallFaceBatch||this._roomDialog)return!1;const t=2e-4*this._gridPitch;try{let i,s=Gu(this._wallFaceGraph(this._wallGraphSources([]),t),e,t);if(!s){const n=s_(this._wallGraphSources([]),{point:e,maxDistance:wl(2,this._cellCm,this._gridPitch),gridStep:this._gridPitch,epsilon:t});if("ambiguous"===n.kind)return this._wallRepairDiagnostic=n.proposals[0]||null,this._showToast(this._t(0===this._drawWallCm?"toast.zero_wall_ambiguous":"toast.wall_repair_ambiguous")),!0;if("repair"===n.kind)s=n.face,i=n.proposal;else if("none"===n.kind){const i=s_(this._wallGraphSources([]),{point:e,maxDistance:this._cssPxToRender(12),gridStep:this._gridPitch,epsilon:t});if("repair"===i.kind)return this._wallRepairDiagnostic=i.proposal,this._showToast(this._t("toast.wall_repair_too_large")),!0}}return!(!s||s.ring.length<3||this._contourSelfIntersects(s.ring)||this._overlapRoom(s.ring))&&(this._beginWallFaceBatch([{...s,existing:!i,repair:i}]),!0)}catch{return!1}}_columnClick(e){const t=this._snap(e),i=this._drawWallCm;if(null==i)return void this._showPhysicalRange(Xc,1);if(!this._curSpaceCfg||this._limitReached("column"))return;const s=this._spaceModel();if(!s)return;const n={id:"column-"+Date.now().toString(36),shape:"square",center:t,cm:Qc(i),angle:0},o=(s.wall_columns||[]).find(e=>yh(e,n,.02*this._gridPitch));if(o)return clearTimeout(this._duplicateColumnTimer),this._duplicateColumnId=o.id,this._duplicateColumnTimer=window.setTimeout(()=>{this._duplicateColumnId=null},900),void this._showToast(this._t("toast.column_duplicate"));const a=this._geometrySnapshot(),r=this._curSpaceCfg;r.wall_columns||=[],r.wall_columns.push({...n,center:[t[0]/Pv,t[1]/Pv]}),this._commitPhysicalGeometry(this._t("history.column_add"),a)}_openPhysicalDialog(e,t,i){const s=this._spaceModel();if(s)if("partition"===e){const i=s.partitions.find(e=>e.id===t);i&&(this._physicalDialog={kind:e,id:t,cm:yl(i.cm,this._imperial),length:this._fmtLen(i.a,i.b)})}else if("column"===e){const i=s.wall_columns.find(e=>e.id===t);i&&(this._physicalDialog={kind:e,id:t,cm:yl(i.cm,this._imperial),shape:i.shape,angle:this._angleField("square"===i.shape?eh(i.angle):0)})}else{const n=s.room_drafts.find(e=>e.id===t),o=Math.max(0,Math.min(n?.segments.length?n.segments.length-1:0,i||0));n?.segments[o]&&(this._physicalDialog={kind:e,id:t,segment:o,cm:yl(n.segments[o].cm,this._imperial),length:this._fmtLen(n.points[o],n.points[o+1])})}}_physicalDown(e,t,i){const s=this._spaceModel();if(!s)return;e.stopPropagation(),Ev(e);const n=this._svgPoint(e),o=[];for(const e of[...s.wall_columns].reverse())vh(n,ah(e,this._cellCm,this._gridPitch))&&o.push({kind:"column",id:e.id});for(const e of[...s.partitions].reverse()){const t=oh(e.a,e.b,e.cm,this._cellCm,this._gridPitch);t&&vh(n,t)&&o.push({kind:"partition",id:e.id})}o.some(e=>e.kind===t&&e.id===i)||o.unshift({kind:t,id:i});const a=o.map(e=>`${e.kind}:${e.id}`).sort().join("|"),r=performance.now(),l=this._physicalPickCycle,c=o.length>1&&l?.signature===a&&r-l.at>380&&r-l.at<=1200&&Math.hypot(e.clientX-l.x,e.clientY-l.y)<=10?(l.index+1)%o.length:Math.max(0,o.findIndex(e=>e.kind===t&&e.id===i));this._physicalPickCycle={signature:a,index:c,x:e.clientX,y:e.clientY,at:r},t=o[c].kind,i=o[c].id;const h="partition"===t?s.partitions.find(e=>e.id===i):s.wall_columns.find(e=>e.id===i);h&&(this._physicalSel={kind:t,id:i},this._physicalDrag={pid:e.pointerId,kind:t,id:i,start:this._svgPoint(e),startClient:[e.clientX,e.clientY],before:this._geometrySnapshot(),moved:!1,base:JSON.parse(JSON.stringify(h)),delta:[0,0]})}_clampPhysicalDelta(e,t,i){const s="partition"===e?[t.a,t.b]:[t.center],n=s.map(e=>e[0]),o=s.map(e=>e[1]);return[Math.max(-Ah*Pv-Math.min(...n),Math.min(Ah*Pv-Math.max(...n),i[0])),Math.max(-Ah*Pv-Math.min(...o),Math.min(Ah*Pv-Math.max(...o),i[1]))]}_physicalMove(e){const t=this._physicalDrag;if(!t||t.pid!==e.pointerId)return;e.stopPropagation();const i=this._svgPoint(e),s="partition"===t.kind?t.base.a:t.base.center,n=this._snap([s[0]+i[0]-t.start[0],s[1]+i[1]-t.start[1]]),o=this._clampPhysicalDelta(t.kind,t.base,[n[0]-s[0],n[1]-s[1]]);this._physicalDrag={...t,delta:o,moved:t.moved||Math.hypot(e.clientX-t.startClient[0],e.clientY-t.startClient[1])>=5}}_physicalUp(e){const t=this._physicalDrag;if(!t||t.pid!==e.pointerId)return;if(e.stopPropagation(),this._physicalDrag=null,!t.moved)return void this._registerPhysicalTap(t.kind,t.id);const i=this._spaceModel();if(!this._curSpaceCfg||!i)return;const s=this._curSpaceCfg;if("partition"===t.kind){const e=(s.partitions||[]).find(e=>e.id===t.id),i=t.base;if(e){const n={...i,a:[i.a[0]+t.delta[0],i.a[1]+t.delta[1]],b:[i.b[0]+t.delta[0],i.b[1]+t.delta[1]]};e.a=[n.a[0]/Pv,n.a[1]/Pv],e.b=[n.b[0]/Pv,n.b[1]/Pv];for(const e of s.openings||[]){if("partition"!==e.host?.kind||e.host.id!==t.id)continue;const i=Jp(e,[n],Pv,this._cellCm,this._gridPitch).resolved;i&&Object.assign(e,su(e,i,Pv))}}}else{const e=(s.wall_columns||[]).find(e=>e.id===t.id),n=t.base,o={...n,center:[n.center[0]+t.delta[0],n.center[1]+t.delta[1]]};if(i.wall_columns.some(e=>e.id!==t.id&&yh(e,o,.02*this._gridPitch)))return void this._showToast(this._t("toast.column_duplicate"));e&&(e.center=[(n.center[0]+t.delta[0])/Pv,(n.center[1]+t.delta[1])/Pv])}this._commitPhysicalGeometry(this._t("history.physical_move"),t.before)}_registerPhysicalTap(e,t,i){const s=performance.now(),n=this._physicalLastTap?.kind===e&&this._physicalLastTap.id===t&&this._physicalLastTap.segment===i&&s-this._physicalLastTap.at<=360;this._physicalLastTap={kind:e,id:t,segment:i,at:s},n&&(this._physicalLastTap=null,this._openPhysicalDialog(e,t,i))}_cancelPhysicalGesture(){this._physicalDrag=null,this._physicalRotate=null,this.requestUpdate()}_physicalRotateDown(e,t){if("square"!==t.shape||!this._spaceModel())return;e.preventDefault(),e.stopPropagation(),Ev(e);const i=this._svgPoint(e);this._physicalSel={kind:"column",id:t.id},this._physicalRotate={pid:e.pointerId,id:t.id,center:[...t.center],startAngle:180*Math.atan2(i[1]-t.center[1],i[0]-t.center[0])/Math.PI,baseAngle:eh(t.angle),angle:eh(t.angle),before:this._geometrySnapshot(),moved:!1}}_physicalRotateMove(e){const t=this._physicalRotate;if(!t||t.pid!==e.pointerId)return;e.preventDefault(),e.stopPropagation();const i=this._svgPoint(e),s=180*Math.atan2(i[1]-t.center[1],i[0]-t.center[0])/Math.PI,n=t.baseAngle+s-t.startAngle,o=eh(e.shiftKey?n:5*Math.round(n/5));this._physicalRotate={...t,angle:o,moved:t.moved||Math.abs(n-t.baseAngle)>=.5}}_physicalRotateUp(e){const t=this._physicalRotate;if(!t||t.pid!==e.pointerId)return;e.preventDefault(),e.stopPropagation(),this._physicalRotate=null;const i=this._spaceModel();if(!t.moved||!this._curSpaceCfg||!i)return;const s=i.wall_columns.find(e=>e.id===t.id);if(!s||"square"!==s.shape)return;const n={...s,angle:t.angle};if(i.wall_columns.some(e=>e.id!==t.id&&yh(e,n,.02*this._gridPitch)))return void this._showToast(this._t("toast.column_duplicate"));const o=this._curSpaceCfg.wall_columns?.find(e=>e.id===t.id);o&&(o.angle=t.angle,this._commitPhysicalGeometry(this._t("history.physical_edit"),t.before))}_rszRooms(){const e=[],t=this._spaceModel();if(!t)return e;for(const i of t.rooms){const t=i.id?hi(i):null;t&&e.push({id:i.id,poly:t,wall_ids:Array.isArray(i.wall_ids)?[...i.wall_ids]:void 0})}return i=e,s=Math.max(1e-12,1e-12*this._gridPitch),i.map(e=>{if(!Array.isArray(e.wall_ids)||e.wall_ids.length!==e.poly.length)return{...e,poly:e.poly.map(e=>[...e])};const t=e.poly.map(e=>[...e]);let i=!0;for(;i&&t.length>3;){i=!1;for(let e=0;e0){t.splice(e,1),i=!0;break}}}return{...e,poly:t}});var i,s}_rszOpenings(){return this._openingsR.map(e=>({id:e.id,x:e.rx,y:e.ry,length:e.rlen,hosted:!!e.host,angle:e.angle,type:e.type}))}_rszObstacles(){const e=this._spaceModel();if(!e)return[];const t=[];for(const i of e.partitions||[])t.push({kind:"segment",a:[...i.a],b:[...i.b],half:wl(i.cm,this._cellCm,this._gridPitch)/2});for(const i of e.room_drafts||[])for(let e=0;e+1Array.isArray(e.a)&&Array.isArray(e.b)&&e.a.length>=2&&e.b.length>=2).map(e=>({wall:e,a:[e.a[0]*Pv,e.a[1]*this._spaceH],b:[e.b[0]*Pv,e.b[1]*this._spaceH]})),n=Math.abs(e[0]-t[0])<=.05*this._gridPitch?"v":Math.abs(e[1]-t[1])<=.05*this._gridPitch?"h":null,o=s.filter(i=>!!n&&("h"===n?!(Math.abs(i.a[1]-e[1])>.05*this._gridPitch||Math.abs(i.b[1]-e[1])>.05*this._gridPitch)&&Math.min(Math.max(e[0],t[0]),Math.max(i.a[0],i.b[0]))-Math.max(Math.min(e[0],t[0]),Math.min(i.a[0],i.b[0]))>.05*this._gridPitch:!(Math.abs(i.a[0]-e[0])>.05*this._gridPitch||Math.abs(i.b[0]-e[0])>.05*this._gridPitch)&&Math.min(Math.max(e[1],t[1]),Math.max(i.a[1],i.b[1]))-Math.max(Math.min(e[1],t[1]),Math.min(i.a[1],i.b[1]))>.05*this._gridPitch)),a=new Set(o.map(e=>Number(e.wall.cm)).filter(e=>e>0));return{minDim:this._cmToUnits(30),eps:.05*this._gridPitch,step:this._gridPitch,movingHalf:i>0?wl(i,this._cellCm,this._gridPitch)/2:0,obstacles:this._rszObstacles(),thicknessConflict:a.size>1}}_rszResolution(e,t,i){const s=this._resize.snapshotIdentity||i||this._rszSnapshot(),n=`${this._space}|${this._cellCm}|${this._gridPitch}|${s}`,o=`${e}:${t}`;return this._resize.resolve(n,o,()=>{const i=[...this._resize.rooms||this._rszRooms()],s=i.find(t=>t.id===e),n=s?.poly?.[t]||[0,0],o=s?.poly?.[(t+1)%(s?.poly?.length||1)]||[0,0];return function(e,t,i,s,n){const{eps:o}=n,a=e.find(e=>e.id===i);if(!a||s<0||s>=(a.poly?.length||0)||a.poly.length<4||!Ra(a.poly))return{enabled:!1,reason:"invalid-geometry"};const r=a.poly[s],l=a.poly[(s+1)%a.poly.length],c=Na(r,l,o);if(!c)return{enabled:!1,reason:"diagonal"};if(!La(a.poly,s,c,o))return{enabled:!1,reason:"side-angle"};if(n.thicknessConflict)return{enabled:!1,reason:"thickness-conflict"};for(const e of n.obstacles||[])if(qa(e,r,l,n))return{enabled:!1,reason:"duplicate-physical-wall"};const h=Da(Sa(l,r)),d=[],p=new Set;let u=!1,_=!1;for(const t of e)if(t.id!==i)for(let e=0;e1||d.length>1)return{enabled:!1,reason:"multiple-rooms"};const m={[i]:s},g=[i];if(1===d.length){const e=d[0];if(!Ra(e.room.poly))return{enabled:!1,reason:"invalid-geometry"};if(!La(e.room.poly,e.edge,c,o))return{enabled:!1,reason:"side-angle"};g.push(e.room.id),m[e.room.id]=e.edge}const f=[];for(const e of t)if(!(Ta([e.x,e.y],r,l)>2*o)){if(e.hosted||e.length>h+2*o)return{enabled:!1,reason:"opening-conflict"};f.push(e.id)}const v=Object.fromEntries(g.map(t=>[t,e.find(e=>e.id===t).poly.length])),b=[];for(const t of g){const i=e.find(e=>e.id===t),s=m[t],n=(s-1+i.poly.length)%i.poly.length,a=(s+1)%i.poly.length,r=Ga(e,t,n,1,o),l=Ga(e,t,a,0,o);if(!r||!l)return{enabled:!1,reason:"partial-shared"};b.push(r,l)}const y={roomId:i,edge:s,a:[...r],b:[...l],n:Ia(a.poly,s),roomIds:g,edgeByRoom:m,topology:v,movingOpeningIds:f,sideOwnership:b};if(!Qa(e,t,y,0,n))return{enabled:!1,reason:"invalid-geometry"};const w=Math.abs(Number(n.step));if(Number.isFinite(w)&&w>o){const i=[-w,w];if(!i.some(i=>Qa(e,t,y,i,n))){if(!i.some(i=>Ya(Ja(e,t,y,i),y,o)))return{enabled:!1,reason:"partial-shared"};const s={...n,obstacles:[]};return i.some(i=>Qa(e,t,y,i,s))?{enabled:!1,reason:"duplicate-physical-wall"}:t.length&&i.some(t=>Qa(e,[],y,t,n))?{enabled:!1,reason:"opening-conflict"}:{enabled:!1,reason:"invalid-geometry"}}}return{enabled:!0,plan:y}}(i,[...this._resize.openings||this._rszOpenings()],e,t,this._rszOptsFor(n,o))})}_rszSnapshot(){return JSON.stringify(this._geometrySnapshot()||{spaceId:this._space,rooms:[],openings:[],walls:[],open_spans:[]})}_rszResetController(){const e=null!==this._resize.preview;this._resize.reset(),e&&this._cfgEpoch++}_rszProjectPreview(e,t,i,s,n){this._rszLimitViolation=null;const o=this._serverCfg?.spaces.find(e=>e.id===this._space);if(!o||!this._serverCfg)return{ok:!1,reason:"missing-context"};const a=JSON.parse(e),r={...o,rooms:a.rooms,openings:a.openings||[]};for(const e of["walls","wall_segments","open_spans","room_drafts","partitions","wall_columns","decor"])void 0!==a[e]?r[e]=a[e]:delete r[e];for(const e of["plan_x","plan_y","plan_scale","plan_scale_x","plan_scale_y","plan_angle"])void 0!==a.plan_transform?.[e]?r[e]=a.plan_transform[e]:delete r[e];const l=this._spaceH;for(const[e,i]of Object.entries(t)){const t=r.rooms.find(t=>t.id===e);t&&(t.poly=i.map(e=>[e[0]/Pv,e[1]/l]),delete t.x,delete t.y,delete t.w,delete t.h)}for(const[e,t]of Object.entries(i)){const i=(r.openings||[]).find(t=>t.id===e);i&&(i.x=t[0]/Pv,i.y=t[1]/l)}const c=[],h=[];for(const e of s){const t=n.find(t=>t.id===e),i=r.rooms.find(t=>t.id===e);if(!t||!i?.poly)continue;const s=i.poly.map(e=>[e[0]*Pv,e[1]*l]);if(t.poly.length!==s.length)continue;const o=Array.isArray(t.wall_ids)?t.wall_ids:[];for(let e=0;ee.id===i):null;n&&(n.a=[s[e][0]/Pv,s[e][1]/Pv],n.b=[s[(e+1)%s.length][0]/Pv,s[(e+1)%s.length][1]/Pv])}}if(c.length&&Array.isArray(r.walls)&&r.walls.length){const e=function(e,t,i,s,n=1,o="fixed-topology"){let a=!1;const r=El(e,t,i,s,n,o,()=>{a=!0});return{walls:a?(e||[]).map(e=>({...e})):r,rejected:a}}(r.walls,c,h,this._wallKeyPitch,Pv,"fixed-topology");if(e.rejected)return{ok:!1,reason:"wall-metadata"};r.walls=e.walls}const d=[];for(const e of r.rooms||[]){const t=hi(e);if(t&&!(t.length<2))for(let e=0;eJSON.stringify([e?.key,e?.cm,e?.a,e?.b]),u=new Map;for(const e of a.walls||[]){const t=p(e);u.set(t,(u.get(t)||0)+1)}const _=[];for(const e of r.walls||[]){const t=p(e),i=u.get(t)||0;i?u.set(t,i-1):_.push(e)}if(Hl(_,d,this._wallKeyPitch,Pv,a.walls||[]).length)return{ok:!1,reason:"wall-metadata"};const m=this._rszSpaceCandidateGeometry(this._space,r);if(!m.ok)return{ok:!1,reason:"physical-geometry"};const g={...this._serverCfg,spaces:(this._serverCfg?.spaces||[]).map(e=>e?.id===this._space?r:e)},f=this._junctionLimitsIntroduced(g,this._serverCfg,this._space);return f.length?(this._rszLimitViolation=f[0],{ok:!1,reason:"junction-limit"}):{ok:!0,value:{preview:{space:this._space,sp:r},beforeWalls:a.walls||[],afterWalls:r.walls||[],artifact:m.wallGeometry}}}_rszAcceptPreview(e,t){if(this._cfgEpoch++,!e||!t)return;const i=Lc(t);if(!i)return;const s=`${this._space}|${this._cfgEpoch}|${e.sp.rooms.length}`;Object.defineProperty(i,"sourceFingerprint",{value:Bd([e.sp,this._cellCm,this._gridPitch]),enumerable:!1});const n={key:s,value:i};fv(this._wallUnionPool,s,n,8),this._wallUnionCache=n}_rszSpaceCandidateGeometry(e,t){if(!this._serverCfg)return{ok:!1,wallGeometry:null};const i={...this._serverCfg,spaces:this._serverCfg.spaces.map(i=>i.id===e?t:i)};let s=null;try{return{ok:this._checkSpacePhysicalGeometry(i,e,e=>{s=e}).ok,wallGeometry:s}}catch{return{ok:!1,wallGeometry:null}}}_rszSpaceCandidateRenderable(e,t){if(!this._serverCfg)return!1;try{const i={...this._serverCfg,spaces:this._serverCfg.spaces.map(i=>i.id===e?t:i)};return this._checkSpacePhysicalGeometry(i,e).ok}catch{return!1}}_rszCandidateRenderable(e){return!!e&&e.space===this._space&&this._rszSpaceCandidateRenderable(e.space,e.sp)}_rszEdgeDown(e,t,i){if("resize"!==this._tool||this._resize.dragging)return;e.stopPropagation(),e.preventDefault();const s=this._rszRooms(),n=this._rszResolution(t,i);if(!n.enabled)return void this._showToast(this._rszReasonText(n.reason));Ev(e);const o=n.plan,a=this._svgPoint(e),r=`${this._space}|${this._cfgEpoch}|${s.length}`,l=this._wallUnionCache?.key===r?this._wallUnionCache.value:null,c=this._rszSnapshot();this._resize.begin({pointerId:e.pointerId,start:[a[0],a[1]],roomId:t,plan:o,options:this._rszOptsFor(o.a,o.b),rooms:s,openings:this._rszOpenings(),snapshotIdentity:c,before:JSON.parse(c),wallUnionBefore:l})}_rszReasonText(e){return this._t(`resize.disabled.${e}`)}_rszDisabledActivate(e,t){e.stopPropagation(),e.preventDefault(),this._showToast(this._rszReasonText(t))}_rszDisabledKey(e,t){"Enter"!==e.key&&" "!==e.key||this._rszDisabledActivate(e,t)}_rszMove(e){if(!this._resize.ownsPointer(e.pointerId))return;e.stopPropagation();const t=this._svgPoint(e),i=this._resize.move({pointerId:e.pointerId,point:[t[0],t[1]],step:this._gridPitch,snap:e=>{const t=this._snap(e);return[t[0],t[1]]},project:(e,t,i,s,n)=>this._rszProjectPreview(e,t,i,s,n),publish:(e,t)=>this._rszAcceptPreview(e,t),measure:(e,t)=>this._rszEdgeLabels(e,t)});if("rejected"===i.kind)return i.notify&&this._showToast(this._rszLimitViolation?`${this._t("resize.limit_stopped")} — `+this._junctionLimitLabel(this._rszLimitViolation):this._t("resize.preview_failed")),void this.requestUpdate();"accepted"===i.kind&&this.requestUpdate()}_rszUp(e){if(!this._resize.ownsPointer(e.pointerId))return;e.stopPropagation();const t=this._resize.finish({pointerId:e.pointerId,currentSnapshotIdentity:this._rszSnapshot(),validatePreview:e=>this._rszCandidateRenderable(e)});if("no-op"===t.kind)return this._cfgEpoch++,void this.requestUpdate();if("rejected"===t.kind)return this._cfgEpoch++,this._showToast(this._t("resize.commit_failed")),void this.requestUpdate();const i=t.preview,s=this._serverCfg?.spaces.find(e=>e.id===i.space);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.wall_segments)&&(s.wall_segments=i.sp.wall_segments)),this._suppressClick=!0,setTimeout(()=>this._suppressClick=!1,0),this._commitPhysicalGeometry(this._t("history.resize_room"),t.before),this.requestUpdate()}_rszCancelDrag(e){const t=this._resize.cancel(this._rszSnapshot(),e);if("no-op"!==t.kind){if(this._cfgEpoch++,t.restoreWallUnion){const e=this._spaceModel();if(e){const i=`${this._space}|${this._cfgEpoch}|${e.rooms.length}`,s={key:i,value:t.restoreWallUnion};fv(this._wallUnionPool,i,s,8),this._wallUnionCache=s}}this.requestUpdate()}}_rszPointerCancel(e){this._resize.ownsPointer(e.pointerId)&&(e.stopPropagation(),this._rszCancelDrag(e.pointerId))}_rszEdgeLabels(e,t,i=this._resize.rooms){const s=i,n=[],o=e.polys[t.roomId]||s?.find(e=>e.id===t.roomId).poly;if(!o||!s)return n;const a=o.length,r=this._rszInnerSpanCms(t.roomId,o,e.polys);for(const e of function(e,t){const i=e.length;return[(t-1+i)%i,(t+1)%i]}(o,t.edge)){const t=o[e],i=o[(e+1)%a],s=r?.[e];n.push({kind:"length",x:(t[0]+i[0])/2,y:(t[1]+i[1])/2,text:null==s?this._fmtLen(t,i):li(s,"mi"===this.hass?.config?.unit_system?.length),edge:{a:[t[0],t[1]],b:[i[0],i[1]]}})}const l="mi"===this.hass?.config?.unit_system?.length,c=t.roomIds,h=this._spaceWalls,d=this._physicalBodiesR(),p=this._baseVb(),u=this._view&&this._view.w>0&&this._view.h>0?this._view:{x:p[0],y:p[1],w:p[2],h:p[3]},[_,m]=this._lastValidStageSize||[u.w,u.h],g={...u,stageWidth:Math.max(1,_),stageHeight:Math.max(1,m)},f=this._spaceModel(),v=this._config?.icon_size??2.5,b=f?ed(v>8?2.5:v,f,u.w,this._kiosk?this._kioskScale.icon:1)*g.stageWidth/100:24,y=Math.max(10,.77*b),w=this._t("room.settings_short"),k=y*(1.457+.66*Math.max(1,w.length)*.42);for(const i of c){const o=e.polys[i]||s.find(e=>e.id===i).poly,a=h.length&&f&&this._innerRoomContour(f,i)||o,r=ir(d.length?mh(_h(a,d))*Math.pow(this._cellCm/this._gridPitch,2)/1e4:tr(a,this._gridPitch,this._cellCm),l),c=cr({poly:o,edge:t.edgeByRoom[i],text:r,view:g,gearCenter:$i(o),gearWidthPx:k,gearHeightPx:y});n.push({kind:"area",roomId:i,x:c.anchor[0],y:c.anchor[1],text:r,placement:c})}return n}_rszInnerSpanCms(e,t,i){const s=Object.keys(i).length?Object.entries(i).map(([e,t])=>({id:e,poly:t})):this._spaceModel()?.rooms;if(!s?.length)return null;const n=this._spaceWalls;if(!n.length)return null;const o=function(e,t,i,s,n,o,a,r=1){const l=(e||[]).find(e=>e?.id===t),c=hi(l);if(!c||c.length<3)return null;const h=mc(e,t,i,s,n,o,a,r);if(!h)return c.map(()=>0);const d=4*Zl(n,r);return c.map((e,t)=>{const i=c[(t+1)%c.length],s=[(e[0]+i[0])/2,(e[1]+i[1])/2];for(let e=0;efunction(e,t,i){const s=e?.length||0;if(s<3||!Array.isArray(i)||i.length!==s)return 0;const n=(Math.trunc(t)%s+s)%s,o=e[n],a=e[(n+1)%s],r=a[0]-o[0],l=a[1]-o[1],c=Math.hypot(r,l);if(!(c>0))return 0;const h=Math.max(0,Number(i[n])||0);if(!(h>0))return c;const d=[r/c,l/c],p=ec(e,n),u=[o[0]+p[0]*h,o[1]+p[1]*h],_=t=>{const n=Math.max(0,Number(i[t])||0);if(!(n>0))return null;const a=e[t],r=e[(t+1)%s],l=r[0]-a[0],c=r[1]-a[1],h=Math.hypot(l,c);if(!(h>0))return null;const p=ec(e,t),_=ic(u,d,[a[0]+p[0]*n,a[1]+p[1]*n],[l/h,c/h]);return _?(_[0]-o[0])*d[0]+(_[1]-o[1])*d[1]:null},m=_((n-1+s)%s)??0,g=(_((n+1)%s)??c)-m;return g>0?g:0}(t,i,o)*a)}_renderResizeMeasurements(){const e=this._resize.liveLabels;if(!e?.length)return G;const t=e.filter(e=>"length"===e.kind),i=e.filter(e=>"area"===e.kind);return W`
@@ -5887,7 +5887,7 @@ globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="30d20d6f6822065e2d5226b18abbb05d8d26 ${this._settingsDialog.bgColor?q``:q`${this._t("gs.bg_theme")}`}
`:q`
${this._t("gs.bg_daynight_hint")}
`} - ${Rr(this.hass)?G:q`
${this._t("gs.sun_missing")}
`} + ${Er(this.hass)?G:q`
${this._t("gs.sun_missing")}
`}
- `}_saveKioskScale(e){this._kioskScale={...this._kioskScale,...e};try{localStorage.setItem(Mv,JSON.stringify(this._kioskScale))}catch{}this.requestUpdate()}_renderKioskDialog(){const e=this._kioskScale,t=(t,i)=>q` + `}_saveKioskScale(e){this._kioskScale={...this._kioskScale,...e};try{localStorage.setItem(Iv,JSON.stringify(this._kioskScale))}catch{}this.requestUpdate()}_renderKioskDialog(){const e=this._kioskScale,t=(t,i)=>q`
${this._rangeInput(50,300,5,Math.round(100*e[t]),e=>this._saveKioskScale({[t]:e/100}))} ${Math.round(100*e[t])}% @@ -6053,7 +6053,7 @@ globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="30d20d6f6822065e2d5226b18abbb05d8d26 ${this._spaceDialog?this._renderSpaceDialog():G} ${this._importDialog?this._renderImportDialog():G} ${this._toast?q``:G} - `;const s=this._spaceModel();if(!s)return G;const n="valid"===i.kind?[s]:e,o=s.vb,a=this._effectiveProjection();this._renderProjection=a,this._labs.active.length&&function(e){mf||wf(e);const t=_f,i=t.active.join(",");if(!i||i===ff)return;ff=i;const s=new Map(of.map(e=>[e.id,e])),n=t.active.map(e=>{const t=s.get(e);return`${e} (#${t.issue}, expires ${t.expires})`}).join(", ");console.info(`HOUSEPLAN LABS: ${n}`)}(cv);const r="iso"===a,l="devices"===this._mode&&this._showAll,c=this._renderDevices.filter(e=>e.space===s.id&&(!e.hidden||l)),h=this._renderDeviceSnapshot,d=this._spaceDisplayForRender(),p=r?this._isoDecorationLayers(d):null,u=p?this._isoOpeningPanels(p):[],_=this._resolvedRoomFills(s,d),m=this._resolvedGlowBase(s,d,_),g=d.showLqi??this._config.show_signal??!0,f=this._config.icon_size??2.5,v=f>8?2.5:f,b=R_(v),y=this._viewOr(this._baseVb()),w=this._floorView(y),k=this._editing?"":this._stageBg(d),x=this._opMeasureView,$=this._decorMeasure,S=this._bdLive,M=this._furnLive,C="view"===this._mode?this._editorChromeMode:this._mode,D=this._roomHoverPaths(s),P=s.bg?this._display(s.bg.href):"",T=this._continuity.overlayVisible||"recovery-error"===this._continuity.state?this._continuity.recoveryReason:null,I=this._modeTransitionVisual,R=this._dayCycleState(),A=I?.viewWeight??("view"===this._mode?1:0),z=this._modeTransition.state?.from.presentedMode,F=!this._markup||!!I&&("view"===I.presentedMode||"devices"===I.presentedMode||"view"===z||"devices"===z),N=I?.stageColor||k,E=I?.sceneBrightness??1;return q` + `;const s=this._spaceModel();if(!s)return G;const n="valid"===i.kind?[s]:e,o=s.vb,a=this._effectiveProjection();this._renderProjection=a,this._labs.active.length&&function(e){yf||Mf(e);const t=bf,i=t.active.join(",");if(!i||i===kf)return;kf=i;const s=new Map(hf.map(e=>[e.id,e])),n=t.active.map(e=>{const t=s.get(e);return`${e} (#${t.issue}, expires ${t.expires})`}).join(", ");console.info(`HOUSEPLAN LABS: ${n}`)}(_v);const r="iso"===a,l="devices"===this._mode&&this._showAll,c=this._renderDevices.filter(e=>e.space===s.id&&(!e.hidden||l)),h=this._renderDeviceSnapshot,d=this._spaceDisplayForRender(),p=r?this._isoDecorationLayers(d):null,u=p?this._isoOpeningPanels(p):[],_=this._resolvedRoomFills(s,d),m=this._resolvedGlowBase(s,d,_),g=d.showLqi??this._config.show_signal??!0,f=this._config.icon_size??2.5,v=f>8?2.5:f,b=E_(v),y=this._viewOr(this._baseVb()),w=this._floorView(y),k=this._editing?"":this._stageBg(d),x=this._opMeasureView,$=this._decorMeasure,S=this._bdLive,M=this._furnLive,C="view"===this._mode?this._editorChromeMode:this._mode,D=this._roomHoverPaths(s),P=s.bg?this._display(s.bg.href):"",T=this._continuity.overlayVisible||"recovery-error"===this._continuity.state?this._continuity.recoveryReason:null,I=this._modeTransitionVisual,R=this._dayCycleState(),A=I?.viewWeight??("view"===this._mode?1:0),z=this._modeTransition.state?.from.presentedMode,F=!this._markup||!!I&&("view"===I.presentedMode||"devices"===I.presentedMode||"view"===z||"devices"===z),N=I?.stageColor||k,E=I?.sceneBrightness??1;return q` this._markupClick(e)} @wheel=${e=>this._onWheel(e)} @pointerdown=${e=>{this._notePointer(e),this._stagePointerDown(e)}} @@ -6148,7 +6148,7 @@ globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="30d20d6f6822065e2d5226b18abbb05d8d26 @pointerleave=${e=>this._stagePointerLeave(e)} @pointerup=${e=>this._stagePointerUp(e)} @pointercancel=${e=>this._stagePointerCancel(e)}> - ${Fr(R,A)} + ${Lr(R,A)} ${this._renderEditorSecondary()}
+ transform=${p?.structural?If():G}> ${""} ${this._wallHatchDefs(d.color)}${W`${this._paperShapes(s.rooms).map(e=>"path"in e?W``:"poly"in e?W``:W``)}`} ${this._editing?this._renderMarkupDefs(o):G} @@ -6250,7 +6250,7 @@ globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="30d20d6f6822065e2d5226b18abbb05d8d26 ${this._renderIsoWalls(p,u)} `:G} ${""} -
+
${c.map(e=>this._renderDevice(e,y,g))} ${this._renderVacuums(c,y)} ${this._renderVacFit(y)} @@ -6362,7 +6362,7 @@ globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="30d20d6f6822065e2d5226b18abbb05d8d26 `:G} ${this._toast?q``:G} - `}_vacCandidateStatus(e,t,i=this._planHass){const s=this._bindingStatus("entity:"+e);if("ha_disabled"===s.kind)return"disabled";if("orphaned"===s.kind)return"missing";if("unverified"===s.kind)return"unverified";const n=i?.states?.[e];return"unavailable"===n?.state?"unavailable":t?.hasPosition?"ok":"unsupported"}_vacOpenAllCameras(e){const t=this._haRegistry.entities||{},i=[];for(const[e,s]of Object.entries(this.hass?.states||{})){if(!e.startsWith("camera."))continue;const n=op(e,s,t[e]);n&&i.push(n)}this._vacAllCameraCache={devId:e.id,candidates:i},this._vacAllCamerasFor=e.id}_vacSourceResolution(e,t=!1,i=this._planHass){const s=e.marker?.vacuum,n="string"==typeof s?.source&&!!s.source,o=new Set(e.entities||[]),a=new Set(o);n&&a.add(s.source);const r=i?.entities||{},l=[];for(const e of a){const t=i?.states?.[e],o=op(e,t,r[e]);o?l.push(o):n&&e===s.source&&l.push({entityId:e,name:String(t?.attributes?.friendly_name||e),platform:r[e]?.platform?String(r[e].platform):null,category:e.startsWith("camera.")?"camera":"partial",hasPosition:!1,hasRooms:!1,hasPath:!1,hasMapId:!1,score:0})}if(t&&this._vacAllCameraCache?.devId===e.id){const e=new Set(l.map(e=>e.entityId));for(const t of this._vacAllCameraCache.candidates)e.has(t.entityId)||l.push(t)}const c={};for(const e of l)c[e.entityId]=this._vacCandidateStatus(e.entityId,e,i);return function(e,t,i,s){const n="string"==typeof e&&e.length>0,o=new Set(t),a=Array.from(i).sort((t,i)=>n&&t.entityId===e?-1:n&&i.entityId===e?1:i.score-t.score||t.entityId.localeCompare(i.entityId));if(n){const t=a.find(t=>t.entityId===e);return{entityId:e,status:s[e]||(t?.hasPosition?"ok":"unverified"),pinned:!0,candidates:a}}const r=a.find(e=>o.has(e.entityId)&&e.hasPosition&&"ok"===s[e.entityId]);return r?{entityId:r.entityId,status:"ok",pinned:!1,candidates:a}:{entityId:null,status:"none",pinned:!1,candidates:a}}(s?.source,o,l,c)}_vacSource(e,t=this._planHass){if(!1===e.marker?.vacuum?.live)return null;const i=this._vacSourceResolution(e,!1,t);return"ok"===i.status||"unsupported"===i.status?i.entityId:null}_vacEntity(e){return e.primary?.startsWith("vacuum.")?e.primary:(e.entities||[]).find(e=>e.startsWith("vacuum."))||null}_isVacDev(e){return!!this._vacEntity(e)}_activitySourceKey(e){return this._activitySnapshot(e).sourceKey}_activitySnapshot(e,t=ho(this._planHass,this._devices,null,this._virtualLights)){const i=k_(this._planHass,e,this._devices,t,this._fullRegistryHass);return{samples:i.samples,sourceKey:S_(this._planHass,e,i)}}_stampActivity(e,t,i){let s=this._activityRt.get(e);s||(s=om(i||"",[]),this._activityRt.set(e,s)),null!=i&&(s.sources=i),rm(s,t,Date.now(),window.clearTimeout.bind(window),e=>window.setTimeout(()=>this.requestUpdate(),e))}_syncActivityRuntime(){const e=new Map;if(!this.hass)return e;if(!1===this._config?.live_states){for(const e of this._activityRt.values())clearTimeout(e.timer);return this._activityRt.clear(),e}const t=new Set,i=ho(this._planHass,this._devices,null,this._virtualLights);for(const s of this._devices){if(s.hidden)continue;if("icon_ripple"!==Bi(s.marker?.display))continue;t.add(s.id);const n=this._activitySnapshot(s,i);e.set(s.id,n);const{samples:o,sourceKey:a}=n;let r=this._activityRt.get(s.id);r?r.sources!==a&&am(r,a,o,window.clearTimeout.bind(window)):(r=om(a,o),this._activityRt.set(s.id,r))}for(const[e,i]of this._activityRt)t.has(e)||(clearTimeout(i.timer),this._activityRt.delete(e));return e}_activityTick(){if(!this.hass)return;const e=this._syncActivityRuntime();for(const t of this._devices){if(t.hidden)continue;if("icon_ripple"!==Bi(t.marker?.display))continue;const i=e.get(t.id)||this._activitySnapshot(t),{samples:s,sourceKey:n}=i,o=this._activityRt.get(t.id);if(!o||o.sources!==n)continue;const a=lm(o,s,window.clearTimeout.bind(window));a&&this._stampActivity(t.id,a,n)}}_vacTick(){if(this.hass)for(const e of this._devices){if(e.hidden||!this._isVacDev(e))continue;if("static_icon"===Bi(e.marker?.display)){this._vacRt.delete(e.id);continue}const t=this._vacSource(e);if(!t)continue;const i=this._vacEntity(e),s=cp(this.hass.states[i||""]?.state),n=np(this.hass.states[t]?.attributes);let o=this._vacRt.get(e.id);o||(o={trail:[],lastKey:"",lastTs:0,moving:!1,jump:!1,endedTs:0,lastPos:null},this._vacRt.set(e.id,o)),s&&!o.moving&&(o.trail=[],o.lastPos=null);const a="never"!==_p(e.marker?.vacuum)&&!n?.path.length;!s&&o.moving&&(o.endedTs=Date.now(),a&&o.lastPos&&(o.trail=lp(o.trail,o.lastPos,40)),o.lastPos=null),o.moving=s;const r=n?.pos;if(s&&r){const e=r.x+":"+r.y;if(e!==o.lastKey){const t=Date.now();o.jump=o.lastTs>0&&t-o.lastTs>1e4,o.lastKey=e,o.lastTs=t,a&&o.lastPos&&(o.trail=lp(o.trail,o.lastPos,40)),o.lastPos=[r.x,r.y]}}}}_vacEnsureMarker(e){const t=this._serverCfg;if(!t)return null;t.markers=t.markers||[];const i=t.markers.find(t=>t.id===e.id);if(i)return i;if("device"!==e.bindingKind&&"entity"!==e.bindingKind||!e.bindingRef)return null;const s={id:e.id,binding:e.bindingKind+":"+e.bindingRef,space:e.space||null,area:e.area||null,hidden:!!e.hidden};return t.markers.push(s),s}_renderVacSection(e){const t=this._devices.find(t=>t.id===e.devId);if(!t||!this._isVacDev(t))return G;const i=t.marker?.vacuum||{},s=this._vacAllCamerasFor===t.id,n=this._vacSourceResolution(t,s),o=n.entityId,a=n.candidates.find(e=>e.entityId===o)||null,r=o?np(this.hass?.states[o]?.attributes):null,l=!1!==i.live&&("ok"===n.status||"unsupported"===n.status),c=this._vacPlanRoomAnchors(t.space),h=r?function(e,t){const i=new Set(t.map(ap).filter(Boolean)),s=new Set;for(const t of e){const e=ap(t.name||"");e&&i.has(e)&&s.add(e)}return s.size}(r.rooms,c.map(e=>e.name)):0,d=!!(l&&r&&h>=3),p=Object.keys(i.calibration||{}),u=e=>{const i=this._vacEnsureMarker(t);i&&(i.vacuum={...i.vacuum||{},...e},this._regSignature="",this._maybeRebuildDevices(),this._saveConfig(),this.requestUpdate())},_=new Set(t.entities||[]),m=n.candidates.filter(e=>_.has(e.entityId)||e.entityId===i.source),g=s?n.candidates.filter(e=>e.entityId.startsWith("camera.")&&!m.some(t=>t.entityId===e.entityId)):[],f=e=>[e.hasPosition?this._t("vac.cap_position"):"",e.hasRooms?this._t("vac.cap_rooms_short"):"",e.hasPath?this._t("vac.cap_path"):"",e.hasMapId?this._t("vac.cap_map"):""].filter(Boolean).join(" · ")||this._t("vac.cap_none"),v=e=>q` + `}_vacCandidateStatus(e,t,i=this._planHass){const s=this._bindingStatus("entity:"+e);if("ha_disabled"===s.kind)return"disabled";if("orphaned"===s.kind)return"missing";if("unverified"===s.kind)return"unverified";const n=i?.states?.[e];return"unavailable"===n?.state?"unavailable":t?.hasPosition?"ok":"unsupported"}_vacOpenAllCameras(e){const t=this._haRegistry.entities||{},i=[];for(const[e,s]of Object.entries(this.hass?.states||{})){if(!e.startsWith("camera."))continue;const n=hp(e,s,t[e]);n&&i.push(n)}this._vacAllCameraCache={devId:e.id,candidates:i},this._vacAllCamerasFor=e.id}_vacSourceResolution(e,t=!1,i=this._planHass){const s=e.marker?.vacuum,n="string"==typeof s?.source&&!!s.source,o=new Set(e.entities||[]),a=new Set(o);n&&a.add(s.source);const r=i?.entities||{},l=[];for(const e of a){const t=i?.states?.[e],o=hp(e,t,r[e]);o?l.push(o):n&&e===s.source&&l.push({entityId:e,name:String(t?.attributes?.friendly_name||e),platform:r[e]?.platform?String(r[e].platform):null,category:e.startsWith("camera.")?"camera":"partial",hasPosition:!1,hasRooms:!1,hasPath:!1,hasMapId:!1,score:0})}if(t&&this._vacAllCameraCache?.devId===e.id){const e=new Set(l.map(e=>e.entityId));for(const t of this._vacAllCameraCache.candidates)e.has(t.entityId)||l.push(t)}const c={};for(const e of l)c[e.entityId]=this._vacCandidateStatus(e.entityId,e,i);return function(e,t,i,s){const n="string"==typeof e&&e.length>0,o=new Set(t),a=Array.from(i).sort((t,i)=>n&&t.entityId===e?-1:n&&i.entityId===e?1:i.score-t.score||t.entityId.localeCompare(i.entityId));if(n){const t=a.find(t=>t.entityId===e);return{entityId:e,status:s[e]||(t?.hasPosition?"ok":"unverified"),pinned:!0,candidates:a}}const r=a.find(e=>o.has(e.entityId)&&e.hasPosition&&"ok"===s[e.entityId]);return r?{entityId:r.entityId,status:"ok",pinned:!1,candidates:a}:{entityId:null,status:"none",pinned:!1,candidates:a}}(s?.source,o,l,c)}_vacSource(e,t=this._planHass){if(!1===e.marker?.vacuum?.live)return null;const i=this._vacSourceResolution(e,!1,t);return"ok"===i.status||"unsupported"===i.status?i.entityId:null}_vacEntity(e){return e.primary?.startsWith("vacuum.")?e.primary:(e.entities||[]).find(e=>e.startsWith("vacuum."))||null}_isVacDev(e){return!!this._vacEntity(e)}_activitySourceKey(e){return this._activitySnapshot(e).sourceKey}_activitySnapshot(e,t=ho(this._planHass,this._devices,null,this._virtualLights)){const i=C_(this._planHass,e,this._devices,t,this._fullRegistryHass);return{samples:i.samples,sourceKey:T_(this._planHass,e,i)}}_stampActivity(e,t,i){let s=this._activityRt.get(e);s||(s=hm(i||"",[]),this._activityRt.set(e,s)),null!=i&&(s.sources=i),pm(s,t,Date.now(),window.clearTimeout.bind(window),e=>window.setTimeout(()=>this.requestUpdate(),e))}_syncActivityRuntime(){const e=new Map;if(!this.hass)return e;if(!1===this._config?.live_states){for(const e of this._activityRt.values())clearTimeout(e.timer);return this._activityRt.clear(),e}const t=new Set,i=ho(this._planHass,this._devices,null,this._virtualLights);for(const s of this._devices){if(s.hidden)continue;if("icon_ripple"!==Bi(s.marker?.display))continue;t.add(s.id);const n=this._activitySnapshot(s,i);e.set(s.id,n);const{samples:o,sourceKey:a}=n;let r=this._activityRt.get(s.id);r?r.sources!==a&&dm(r,a,o,window.clearTimeout.bind(window)):(r=hm(a,o),this._activityRt.set(s.id,r))}for(const[e,i]of this._activityRt)t.has(e)||(clearTimeout(i.timer),this._activityRt.delete(e));return e}_activityTick(){if(!this.hass)return;const e=this._syncActivityRuntime();for(const t of this._devices){if(t.hidden)continue;if("icon_ripple"!==Bi(t.marker?.display))continue;const i=e.get(t.id)||this._activitySnapshot(t),{samples:s,sourceKey:n}=i,o=this._activityRt.get(t.id);if(!o||o.sources!==n)continue;const a=um(o,s,window.clearTimeout.bind(window));a&&this._stampActivity(t.id,a,n)}}_vacTick(){if(this.hass)for(const e of this._devices){if(e.hidden||!this._isVacDev(e))continue;if("static_icon"===Bi(e.marker?.display)){this._vacRt.delete(e.id);continue}const t=this._vacSource(e);if(!t)continue;const i=this._vacEntity(e),s=_p(this.hass.states[i||""]?.state),n=cp(this.hass.states[t]?.attributes);let o=this._vacRt.get(e.id);o||(o={trail:[],lastKey:"",lastTs:0,moving:!1,jump:!1,endedTs:0,lastPos:null},this._vacRt.set(e.id,o)),s&&!o.moving&&(o.trail=[],o.lastPos=null);const a="never"!==bp(e.marker?.vacuum)&&!n?.path.length;!s&&o.moving&&(o.endedTs=Date.now(),a&&o.lastPos&&(o.trail=up(o.trail,o.lastPos,40)),o.lastPos=null),o.moving=s;const r=n?.pos;if(s&&r){const e=r.x+":"+r.y;if(e!==o.lastKey){const t=Date.now();o.jump=o.lastTs>0&&t-o.lastTs>1e4,o.lastKey=e,o.lastTs=t,a&&o.lastPos&&(o.trail=up(o.trail,o.lastPos,40)),o.lastPos=[r.x,r.y]}}}}_vacEnsureMarker(e){const t=this._serverCfg;if(!t)return null;t.markers=t.markers||[];const i=t.markers.find(t=>t.id===e.id);if(i)return i;if("device"!==e.bindingKind&&"entity"!==e.bindingKind||!e.bindingRef)return null;const s={id:e.id,binding:e.bindingKind+":"+e.bindingRef,space:e.space||null,area:e.area||null,hidden:!!e.hidden};return t.markers.push(s),s}_renderVacSection(e){const t=this._devices.find(t=>t.id===e.devId);if(!t||!this._isVacDev(t))return G;const i=t.marker?.vacuum||{},s=this._vacAllCamerasFor===t.id,n=this._vacSourceResolution(t,s),o=n.entityId,a=n.candidates.find(e=>e.entityId===o)||null,r=o?cp(this.hass?.states[o]?.attributes):null,l=!1!==i.live&&("ok"===n.status||"unsupported"===n.status),c=this._vacPlanRoomAnchors(t.space),h=r?function(e,t){const i=new Set(t.map(dp).filter(Boolean)),s=new Set;for(const t of e){const e=dp(t.name||"");e&&i.has(e)&&s.add(e)}return s.size}(r.rooms,c.map(e=>e.name)):0,d=!!(l&&r&&h>=3),p=Object.keys(i.calibration||{}),u=e=>{const i=this._vacEnsureMarker(t);i&&(i.vacuum={...i.vacuum||{},...e},this._regSignature="",this._maybeRebuildDevices(),this._saveConfig(),this.requestUpdate())},_=new Set(t.entities||[]),m=n.candidates.filter(e=>_.has(e.entityId)||e.entityId===i.source),g=s?n.candidates.filter(e=>e.entityId.startsWith("camera.")&&!m.some(t=>t.entityId===e.entityId)):[],f=e=>[e.hasPosition?this._t("vac.cap_position"):"",e.hasRooms?this._t("vac.cap_rooms_short"):"",e.hasPath?this._t("vac.cap_path"):"",e.hasMapId?this._t("vac.cap_map"):""].filter(Boolean).join(" · ")||this._t("vac.cap_none"),v=e=>q`
`}_vacMapId(e,t,i=this._planHass){const s=this._vacEntity(e),n=s?i?.states?.[s]?.attributes?.selected_map:null;return o=t.mapId,a=n,"default"!==o?o:null!=a?String(a):"default";var o,a}_vacSaveMatrix(e,t,i,s){const n=this._devices.find(t=>t.id===e),o=n?this._vacEnsureMarker(n):this._serverCfg?.markers?.find(t=>t.id===e);if(!o)return!1;const a={...o.vacuum||{}};return a.source=t,a.calibration={...a.calibration||{},[i]:s.map(e=>Number(e.toFixed(6)))},o.vacuum=a,this._regSignature="",this._maybeRebuildDevices(),this._saveConfig(),this.requestUpdate(),!0}_vacPlanRoomAnchors(e){return(this._spaceModelById(e)?.rooms||[]).map(e=>({room:e,poly:hi(e)})).filter(({room:e,poly:t})=>e.name&&t).map(({room:e,poly:t})=>{const i=Qd(t);return i?{name:String(e.name),cx:i[0],cy:i[1]}:null}).filter(Boolean)}_vacAutoCalibrate(e){const t=this._vacSource(e),i=t?np(this.hass?.states[t]?.attributes):null;if(!t||!i||i.rooms.length<3)return void this._showToast(this._t("vac.autocal_no_rooms"));const s=this._vacPlanRoomAnchors(e.space),n=rp(i.rooms,s);if(!n)return void this._showToast(this._t("vac.autocal_no_match"));const o=this._serverCfg?.spaces?.find(t=>t.id===e.space),a=Number(o?.cell_cm),r=Number.isFinite(a)&&a>0?a:5,l=function(e,t,i){return![e,t,i].every(Number.isFinite)||e<0||t<=0||i<=0?Number.POSITIVE_INFINITY:e/t*i}(n.residual,this._gridPitch,r),c=this._vacMapId(e,i);l>40?this._vacCalConfirm={markerId:e.id,source:t,mapId:c,matrix:n.matrix,rooms:n.matched.length,error:li(l,"mi"===this.hass?.config?.unit_system?.length)}:this._vacSaveMatrix(e.id,t,c,n.matrix)&&this._showToast(ss(this._t("vac.autocal_done"),{rooms:String(n.matched.length)}))}_vacApplyCalibrationProposal(e){const t=this._vacCalConfirm;if(t){if(this._vacCalConfirm=null,e){const e=this._devices.find(e=>e.id===t.markerId),i=pp(t.matrix);if(!e||!i)return;if(this._markerDialog=null,e.space!==this._space&&!this._commitSpace(e.space))return;return void(this._vacFit={markerId:t.markerId,source:t.source,mapId:t.mapId,p:i,drag:null})}this._vacSaveMatrix(t.markerId,t.source,t.mapId,t.matrix)&&this._showToast(ss(this._t("vac.autocal_done"),{rooms:String(t.rooms)}))}}_vacStartFit(e){const t=this._vacSource(e),i=t?np(this.hass?.states[t]?.attributes):null;if(!t||!i)return void this._showToast(this._t("vac.cal_need_pos"));const s=this._vacMapId(e,i),n=e.marker?.vacuum?.calibration?.[s],o=this._spaceModelById(e.space);if(!o)return;const a=o.vb,r=n&&6===n.length&&pp(n)||function(e,t){const i=[],s=[];for(const t of e)null!=t.x0?(i.push(t.x0,t.x1),s.push(t.y0,t.y1)):(i.push(t.cx),s.push(t.cy));if(!i.length)return{ox:t[0]+t[2]/2,oy:t[1]+t[3]/2,s:t[2]/1e4,rot:0,mir:!0};const n=Math.min(...i),o=Math.max(...i),a=Math.min(...s),r=Math.max(...s),l=Math.max(o-n,r-a)||1,c={ox:0,oy:0,s:.6*Math.min(t[2],t[3])/l,rot:0,mir:!0},h=dp(c),[d,p]=Yd(h,(n+o)/2,(a+r)/2);return c.ox=t[0]+t[2]/2-d,c.oy=t[1]+t[3]/2-p,c}(i.rooms,a);this._markerDialog=null,(e.space===this._space||this._commitSpace(e.space))&&(this._vacFit={markerId:e.id,source:t,mapId:s,p:r,drag:null})}_vacFitSave(){const e=this._vacFit;if(!e)return;const t=this._vacSaveMatrix(e.markerId,e.source,e.mapId,dp(e.p));this._vacFit=null,t&&this._showToast(this._t("vac.cal_done"))}_vacFitTurn(e){const t=this._vacFit;if(!t)return;const i=np(this.hass?.states[t.source]?.attributes),s=this._vacGhostCentre(i?.rooms||[]),n={...t.p,...e};this._vacFit={...t,p:up(n,t.p,s[0],s[1])}}_vacGhostCentre(e){const t=[],i=[];for(const s of e)t.push(s.x0??s.cx,s.x1??s.cx),i.push(s.y0??s.cy,s.y1??s.cy);return t.length?[(Math.min(...t)+Math.max(...t))/2,(Math.min(...i)+Math.max(...i))/2]:[0,0]}_vacDelta(e,t,i){const s=this._stageEl,n=s?.clientWidth||1,o=s?.clientHeight||1;return[t/n*e.w,i/o*e.h]}_vacFitPointer(e,t){const i=this._vacFit;if(!i)return;if(e.stopPropagation(),"pointerdown"===e.type){const t=e.target,s=t.getAttribute?.("data-corner");try{e.currentTarget.setPointerCapture?.(e.pointerId)}catch{}return void(this._vacFit={...i,drag:s?{kind:"scale",sx:e.clientX,sy:e.clientY,p0:{...i.p},fx:Number(s.split(",")[0]),fy:Number(s.split(",")[1])}:{kind:"move",sx:e.clientX,sy:e.clientY,p0:{...i.p},fx:0,fy:0}})}const s=i.drag;if(s){if("pointermove"===e.type){const[n,o]=this._vacDelta(t,e.clientX-s.sx,e.clientY-s.sy);if("move"===s.kind)this._vacFit={...i,p:{...s.p0,ox:s.p0.ox+n,oy:s.p0.oy+o}};else{const e=np(this.hass?.states[i.source]?.attributes),t=this._vacGhostCentre(e?.rooms||[]),a=dp(s.p0),[r,l]=Yd(a,t[0],t[1]),[c,h]=Yd(a,s.fx,s.fy),d=Math.hypot(r-c,l-h)||1,[p,u]=[2*r-c,2*l-h],_=Math.hypot(p+2*n-c,u+2*o-h)/2,m=Math.max(.05,_/d),g={...s.p0,s:s.p0.s*m};this._vacFit={...i,p:up(g,s.p0,s.fx,s.fy)}}return}"pointerup"!==e.type&&"pointercancel"!==e.type||(this._vacFit={...i,drag:null})}}_renderVacFit(e){const t=this._vacFit;if(!t)return G;const i=np(this._renderPlanHass?.states?.[t.source]?.attributes);if(!i)return G;const s=dp(t.p),n=[],o=[],a=[];for(const e of i.rooms){if(null==e.x0)continue;const t=[[e.x0,e.y0],[e.x1,e.y0],[e.x1,e.y1],[e.x0,e.y1]].map(([e,t])=>Yd(s,e,t));t.forEach(([e,t])=>{o.push(e),a.push(t)});const[i,r]=Yd(s,e.cx,e.cy);n.push(W` - ${e.name}`)}let r=G;if(i.pos){const[t,n]=Yd(s,i.pos.x,i.pos.y);r=W``}const l=[];if(o.length){const t=(()=>{const e=s[0]*s[4]-s[1]*s[3];return(t,i)=>[(s[4]*(t-s[2])-s[1]*(i-s[5]))/e,(-s[3]*(t-s[2])+s[0]*(i-s[5]))/e]})(),i=Math.min(...o),n=Math.max(...o),r=Math.min(...a),c=Math.max(...a),h=.022*e.w,d=h/4;for(const[e,s,o,a]of[[i,r,n,c],[n,r,i,c],[n,c,i,r],[i,c,n,r]]){const i=t(o,a);l.push(W``}_vacMapId(e,t,i=this._planHass){const s=this._vacEntity(e),n=s?i?.states?.[s]?.attributes?.selected_map:null;return o=t.mapId,a=n,"default"!==o?o:null!=a?String(a):"default";var o,a}_vacSaveMatrix(e,t,i,s){const n=this._devices.find(t=>t.id===e),o=n?this._vacEnsureMarker(n):this._serverCfg?.markers?.find(t=>t.id===e);if(!o)return!1;const a={...o.vacuum||{}};return a.source=t,a.calibration={...a.calibration||{},[i]:s.map(e=>Number(e.toFixed(6)))},o.vacuum=a,this._regSignature="",this._maybeRebuildDevices(),this._saveConfig(),this.requestUpdate(),!0}_vacPlanRoomAnchors(e){return(this._spaceModelById(e)?.rooms||[]).map(e=>({room:e,poly:hi(e)})).filter(({room:e,poly:t})=>e.name&&t).map(({room:e,poly:t})=>{const i=np(t);return i?{name:String(e.name),cx:i[0],cy:i[1]}:null}).filter(Boolean)}_vacAutoCalibrate(e){const t=this._vacSource(e),i=t?cp(this.hass?.states[t]?.attributes):null;if(!t||!i||i.rooms.length<3)return void this._showToast(this._t("vac.autocal_no_rooms"));const s=this._vacPlanRoomAnchors(e.space),n=pp(i.rooms,s);if(!n)return void this._showToast(this._t("vac.autocal_no_match"));const o=this._serverCfg?.spaces?.find(t=>t.id===e.space),a=Number(o?.cell_cm),r=Number.isFinite(a)&&a>0?a:5,l=function(e,t,i){return![e,t,i].every(Number.isFinite)||e<0||t<=0||i<=0?Number.POSITIVE_INFINITY:e/t*i}(n.residual,this._gridPitch,r),c=this._vacMapId(e,i);l>40?this._vacCalConfirm={markerId:e.id,source:t,mapId:c,matrix:n.matrix,rooms:n.matched.length,error:li(l,"mi"===this.hass?.config?.unit_system?.length)}:this._vacSaveMatrix(e.id,t,c,n.matrix)&&this._showToast(ss(this._t("vac.autocal_done"),{rooms:String(n.matched.length)}))}_vacApplyCalibrationProposal(e){const t=this._vacCalConfirm;if(t){if(this._vacCalConfirm=null,e){const e=this._devices.find(e=>e.id===t.markerId),i=fp(t.matrix);if(!e||!i)return;if(this._markerDialog=null,e.space!==this._space&&!this._commitSpace(e.space))return;return void(this._vacFit={markerId:t.markerId,source:t.source,mapId:t.mapId,p:i,drag:null})}this._vacSaveMatrix(t.markerId,t.source,t.mapId,t.matrix)&&this._showToast(ss(this._t("vac.autocal_done"),{rooms:String(t.rooms)}))}}_vacStartFit(e){const t=this._vacSource(e),i=t?cp(this.hass?.states[t]?.attributes):null;if(!t||!i)return void this._showToast(this._t("vac.cal_need_pos"));const s=this._vacMapId(e,i),n=e.marker?.vacuum?.calibration?.[s],o=this._spaceModelById(e.space);if(!o)return;const a=o.vb,r=n&&6===n.length&&fp(n)||function(e,t){const i=[],s=[];for(const t of e)null!=t.x0?(i.push(t.x0,t.x1),s.push(t.y0,t.y1)):(i.push(t.cx),s.push(t.cy));if(!i.length)return{ox:t[0]+t[2]/2,oy:t[1]+t[3]/2,s:t[2]/1e4,rot:0,mir:!0};const n=Math.min(...i),o=Math.max(...i),a=Math.min(...s),r=Math.max(...s),l=Math.max(o-n,r-a)||1,c={ox:0,oy:0,s:.6*Math.min(t[2],t[3])/l,rot:0,mir:!0},h=gp(c),[d,p]=ep(h,(n+o)/2,(a+r)/2);return c.ox=t[0]+t[2]/2-d,c.oy=t[1]+t[3]/2-p,c}(i.rooms,a);this._markerDialog=null,(e.space===this._space||this._commitSpace(e.space))&&(this._vacFit={markerId:e.id,source:t,mapId:s,p:r,drag:null})}_vacFitSave(){const e=this._vacFit;if(!e)return;const t=this._vacSaveMatrix(e.markerId,e.source,e.mapId,gp(e.p));this._vacFit=null,t&&this._showToast(this._t("vac.cal_done"))}_vacFitTurn(e){const t=this._vacFit;if(!t)return;const i=cp(this.hass?.states[t.source]?.attributes),s=this._vacGhostCentre(i?.rooms||[]),n={...t.p,...e};this._vacFit={...t,p:vp(n,t.p,s[0],s[1])}}_vacGhostCentre(e){const t=[],i=[];for(const s of e)t.push(s.x0??s.cx,s.x1??s.cx),i.push(s.y0??s.cy,s.y1??s.cy);return t.length?[(Math.min(...t)+Math.max(...t))/2,(Math.min(...i)+Math.max(...i))/2]:[0,0]}_vacDelta(e,t,i){const s=this._stageEl,n=s?.clientWidth||1,o=s?.clientHeight||1;return[t/n*e.w,i/o*e.h]}_vacFitPointer(e,t){const i=this._vacFit;if(!i)return;if(e.stopPropagation(),"pointerdown"===e.type){const t=e.target,s=t.getAttribute?.("data-corner");try{e.currentTarget.setPointerCapture?.(e.pointerId)}catch{}return void(this._vacFit={...i,drag:s?{kind:"scale",sx:e.clientX,sy:e.clientY,p0:{...i.p},fx:Number(s.split(",")[0]),fy:Number(s.split(",")[1])}:{kind:"move",sx:e.clientX,sy:e.clientY,p0:{...i.p},fx:0,fy:0}})}const s=i.drag;if(s){if("pointermove"===e.type){const[n,o]=this._vacDelta(t,e.clientX-s.sx,e.clientY-s.sy);if("move"===s.kind)this._vacFit={...i,p:{...s.p0,ox:s.p0.ox+n,oy:s.p0.oy+o}};else{const e=cp(this.hass?.states[i.source]?.attributes),t=this._vacGhostCentre(e?.rooms||[]),a=gp(s.p0),[r,l]=ep(a,t[0],t[1]),[c,h]=ep(a,s.fx,s.fy),d=Math.hypot(r-c,l-h)||1,[p,u]=[2*r-c,2*l-h],_=Math.hypot(p+2*n-c,u+2*o-h)/2,m=Math.max(.05,_/d),g={...s.p0,s:s.p0.s*m};this._vacFit={...i,p:vp(g,s.p0,s.fx,s.fy)}}return}"pointerup"!==e.type&&"pointercancel"!==e.type||(this._vacFit={...i,drag:null})}}_renderVacFit(e){const t=this._vacFit;if(!t)return G;const i=cp(this._renderPlanHass?.states?.[t.source]?.attributes);if(!i)return G;const s=gp(t.p),n=[],o=[],a=[];for(const e of i.rooms){if(null==e.x0)continue;const t=[[e.x0,e.y0],[e.x1,e.y0],[e.x1,e.y1],[e.x0,e.y1]].map(([e,t])=>ep(s,e,t));t.forEach(([e,t])=>{o.push(e),a.push(t)});const[i,r]=ep(s,e.cx,e.cy);n.push(W` + ${e.name}`)}let r=G;if(i.pos){const[t,n]=ep(s,i.pos.x,i.pos.y);r=W``}const l=[];if(o.length){const t=(()=>{const e=s[0]*s[4]-s[1]*s[3];return(t,i)=>[(s[4]*(t-s[2])-s[1]*(i-s[5]))/e,(-s[3]*(t-s[2])+s[0]*(i-s[5]))/e]})(),i=Math.min(...o),n=Math.max(...o),r=Math.min(...a),c=Math.max(...a),h=.022*e.w,d=h/4;for(const[e,s,o,a]of[[i,r,n,c],[n,r,i,c],[n,c,i,r],[i,c,n,r]]){const i=t(o,a);l.push(W` `)}}return q`this._vacFitPointer(t,e)} @pointermove=${t=>this._vacFitPointer(t,e)} @pointerup=${t=>this._vacFitPointer(t,e)} - @pointercancel=${t=>this._vacFitPointer(t,e)}>${n}${r}${l}`}_vacRafLoop(){this._vacRaf=requestAnimationFrame(()=>{const e=this.renderRoot,t=this._stageEl,i=this._vacLastView,s=e?.querySelectorAll?.(".vacpuck")||[];if(!t||!i||!s.length)return void(this._vacRaf=0);const n=t.getBoundingClientRect();for(const t of s){const s=t.getAttribute("data-mid"),o=t.getBoundingClientRect(),a=i.x+(o.left+o.width/2-n.left)/n.width*i.w,r=i.y+(o.top+o.height/2-n.top)/n.height*i.h;for(const t of e.querySelectorAll(`line.tip[data-mid="${s}"]`))t.setAttribute("x2",a.toFixed(1)),t.setAttribute("y2",r.toFixed(1))}this._vacRafLoop()})}_renderVacuums(e,t){if(this._markup||"decor"===this._mode)return G;const i=this._space+"|"+t.x+"|"+t.y+"|"+t.w+"|"+t.h,s=this._vacJumpOnce||i!==this._vacViewKey;this._vacViewKey=i,this._vacJumpOnce=!1;const n=[],o=[];for(const i of e){if(i.hidden||!this._isVacDev(i))continue;if("static_icon"===Bi(i.marker?.display))continue;const e=this._renderDeviceSnapshot?.facts.get(`vacuum:${i.id}`),a=e?.source??this._vacSource(i,this._renderPlanHass);if(!a)continue;const r=e?.telemetry??np(this._renderPlanHass?.states[a]?.attributes);if(!r)continue;const l=String(e?.mapId??this._vacMapId(i,r,this._renderPlanHass)),c=i.marker?.vacuum?.calibration?.[l];if(!c||6!==c.length)continue;const h=e?.runtime??this._vacRt.get(i.id),d=h?.moving??!1,p=_p(i.marker?.vacuum),u="always"===p||"cleaning"===p&&d,_=e?.server??this._vacSrvTrails[i.id],m=_?.current?.map_id===l&&Array.isArray(_.current.points)?_.current:null,g=_?.previous?.map_id===l&&Array.isArray(_.previous.points)?_.previous:null;if("always"===p&&g&&g.points.length>1){const e=g.points.map(([e,t])=>{const[i,s]=Yd(c,e,t),n=this._scenePoint([i,s]);return n[0].toFixed(1)+","+n[1].toFixed(1)}).join(" ");o.push(W``)}if(u){const e=ip(r,m,h?.trail||[]),t=!d||"integration"!==e.source&&"server"!==e.source?e.path:sp(e.path);if(t.length){const e=t.map(e=>e.map(([e,t],i)=>{const[s,n]=Yd(c,e,t),o=this._scenePoint([s,n]);return`${i?"L":"M"} ${o[0].toFixed(1)} ${o[1].toFixed(1)}`}).join(" ")).join(" ");o.push(W``);const s=t[t.length-1];if(d&&s?.length>=2){const e=s[s.length-1],[t,n]=Yd(c,e[0],e[1]),a=this._scenePoint([t,n]),r=a[0].toFixed(1),l=a[1].toFixed(1);o.push(W``)}}}if(!d||!r.pos)continue;const[f,v]=Yd(c,r.pos.x,r.pos.y),b=this._scenePoint([f,v]),y=(b[0]-t.x)/t.w*100,w=(b[1]-t.y)/t.h*100,k=h&&h.lastTs>0&&Date.now()-h.lastTs>6e4,x=i.marker?.icon||i.icon||"mdi:robot-vacuum";n.push(q`
this._vacFitPointer(t,e)}>${n}${r}${l}`}_vacRafLoop(){this._vacRaf=requestAnimationFrame(()=>{const e=this.renderRoot,t=this._stageEl,i=this._vacLastView,s=e?.querySelectorAll?.(".vacpuck")||[];if(!t||!i||!s.length)return void(this._vacRaf=0);const n=t.getBoundingClientRect();for(const t of s){const s=t.getAttribute("data-mid"),o=t.getBoundingClientRect(),a=i.x+(o.left+o.width/2-n.left)/n.width*i.w,r=i.y+(o.top+o.height/2-n.top)/n.height*i.h;for(const t of e.querySelectorAll(`line.tip[data-mid="${s}"]`))t.setAttribute("x2",a.toFixed(1)),t.setAttribute("y2",r.toFixed(1))}this._vacRafLoop()})}_renderVacuums(e,t){if(this._markup||"decor"===this._mode)return G;const i=this._space+"|"+t.x+"|"+t.y+"|"+t.w+"|"+t.h,s=this._vacJumpOnce||i!==this._vacViewKey;this._vacViewKey=i,this._vacJumpOnce=!1;const n=[],o=[];for(const i of e){if(i.hidden||!this._isVacDev(i))continue;if("static_icon"===Bi(i.marker?.display))continue;const e=this._renderDeviceSnapshot?.facts.get(`vacuum:${i.id}`),a=e?.source??this._vacSource(i,this._renderPlanHass);if(!a)continue;const r=e?.telemetry??cp(this._renderPlanHass?.states[a]?.attributes);if(!r)continue;const l=String(e?.mapId??this._vacMapId(i,r,this._renderPlanHass)),c=i.marker?.vacuum?.calibration?.[l];if(!c||6!==c.length)continue;const h=e?.runtime??this._vacRt.get(i.id),d=h?.moving??!1,p=bp(i.marker?.vacuum),u="always"===p||"cleaning"===p&&d,_=e?.server??this._vacSrvTrails[i.id],m=_?.current?.map_id===l&&Array.isArray(_.current.points)?_.current:null,g=_?.previous?.map_id===l&&Array.isArray(_.previous.points)?_.previous:null;if("always"===p&&g&&g.points.length>1){const e=g.points.map(([e,t])=>{const[i,s]=ep(c,e,t),n=this._scenePoint([i,s]);return n[0].toFixed(1)+","+n[1].toFixed(1)}).join(" ");o.push(W``)}if(u){const e=rp(r,m,h?.trail||[]),t=!d||"integration"!==e.source&&"server"!==e.source?e.path:lp(e.path);if(t.length){const e=t.map(e=>e.map(([e,t],i)=>{const[s,n]=ep(c,e,t),o=this._scenePoint([s,n]);return`${i?"L":"M"} ${o[0].toFixed(1)} ${o[1].toFixed(1)}`}).join(" ")).join(" ");o.push(W``);const s=t[t.length-1];if(d&&s?.length>=2){const e=s[s.length-1],[t,n]=ep(c,e[0],e[1]),a=this._scenePoint([t,n]),r=a[0].toFixed(1),l=a[1].toFixed(1);o.push(W``)}}}if(!d||!r.pos)continue;const[f,v]=ep(c,r.pos.x,r.pos.y),b=this._scenePoint([f,v]),y=(b[0]-t.x)/t.w*100,w=(b[1]-t.y)/t.h*100,k=h&&h.lastTs>0&&Date.now()-h.lastTs>6e4,x=i.marker?.icon||i.icon||"mdi:robot-vacuum";n.push(q`
${o}`:G} - ${n}`:G}_renderDevice(e,t,i=!0){const s=this._pos(e),n=this._scenePoint([s.x,s.y]),o=(n[0]-t.x)/t.w*100,a=(n[1]-t.y)/t.h*100,r=this._devicePresentation(e,i),l=[`left:${o}%`,`top:${a}%`,...Go(r)],c=r.disabledReason,h=r.haDisabled?this._t(`marker.ha_disabled_${c}`):e.userHidden?this._t("marker.hidden_ghost"):e.name,d=g_(r),p="view"===this._mode||"devices"===this._mode,u=[h,r.haDisabled?"":this._t(`marker.state_a11y_${d}`),"none"!==r.pulse.kind?this._t(`marker.pulse_a11y_${r.pulse.reason}`):"",r.valueFullText||r.valueText||"",Io(r.valueBadge),null!=r.lqiText&&r.lqiBand?this._t(`marker.lqi_a11y_${r.lqiBand}`,{value:r.lqiText}):""].filter(Boolean).join(", "),_=[e.model,r.valueBadge?.fullText||"",null!=r.lqiText?"LQI "+r.lqiText:""].filter(Boolean).join(" · ");return q`
`}_roomArea(e){const t=hi(e);if(!t)return null;const i=this._spaceModel();if(!i)return null;const s=this._spaceWalls.length&&e.id&&this._innerRoomContour(i,e.id)||t,n=this._cleanFloor(e,s),o=this._cellCm/this._gridPitch;return ir(n.area*o*o/1e4,"mi"===this._renderPlanHass?.config?.unit_system?.length)}_roomTemp(e){const t=e.settings?.temp_source;return t?Mo(this._renderPlanHass,t,"temp",this._markers):e.area?this._climate().get(e.area)?.temp??null:null}_roomHum(e){const t=e.settings?.hum_source;return t?Mo(this._renderPlanHass,t,"hum",this._markers):e.area?this._climate().get(e.area)?.hum??null:null}_climate(){const e=this._serverCfg?.markers,t=this._renderPlanHass,i=this._climateCache;if(i&&i.h===t&&i.r===this._iconRules&&i.mk===e)return i.m;const s=function(e,t,i){const s=new Map;if(!e?.entities)return s;const n=wo(i),o=new Set;for(const e of i||[]){if(e?.removed||!0!==e?.use_climate_temp)continue;const t=(e.binding||"").indexOf(":");t>0&&o.add(e.binding.slice(t+1))}const a=new Map;for(const[t,i]of Object.entries(e.entities)){if(i.device_id&&n.devices.has(i.device_id)&&!n.liveEntities.has(t)||!i.device_id&&n.entities.has(t)&&!n.liveEntities.has(t))continue;const s=i.device_id?e.devices?.[i.device_id]:null,r=i.area_id||s?.area_id||null;if(!r)continue;if(i.entity_category)continue;if(!(o.size>0&&t.startsWith("climate.")&&(o.has(t)||i.device_id&&o.has(i.device_id)))){if(Ye.has(i.platform))continue;if(Co.test(t))continue}let l=a.get(r);l||(l=new Map,a.set(r,l));const c=i.device_id||t;let h=l.get(c);if(!h){const n=e.states?.[t];h={name:(s?s.name_by_user||s.name:i.name||n?.attributes?.friendly_name||t)||t,model:s?.model,ents:[]},l.set(c,h)}h.ents.push(t)}for(const[i,n]of a){const a=[],r=[];for(const[i,s]of n){const n=yo(e,s.name,s.model,s.ents,t),l="mdi:thermometer"===n||"mdi:air-filter"===n;if(l){const t=mo(e,s.ents);null!=t&&a.push(t)}if(o.size>0&&(o.has(i)||s.ents.some(e=>o.has(e)))){const t=go(e,s.ents);null!=t&&a.push(t)}if(l||"mdi:water-percent"===n){const t=vo(e,s.ents);null!=t&&r.push(t)}}(a.length||r.length)&&s.set(i,{temp:a.length?Math.round(a.reduce((e,t)=>e+t,0)/a.length*10)/10:null,hum:r.length?Math.round(r.reduce((e,t)=>e+t,0)/r.length):null})}return s}(t,this._iconRules,e);return this._climateCache={h:t,r:this._iconRules,mk:e,m:s},s}_resetRoomDialogFields(){this._roomEditId=null,this._roomFill="",this._roomCustomFill=null,this._roomTempSrc="",this._roomHumSrc="",this._roomSrcOpen=null,this._roomSrcFilter="",this._roomNameScale=1,this._roomLabelScale=1}_openRoomEdit(e){if(!e.id)return;this._roomEditId=e.id,this._nameSel=e.name||"",this._areaSel=e.area||"",this._roomFill="glow"===e.settings?.fill_mode?"":e.settings?.fill_mode||"";const t=e.settings?.custom_fill;this._roomCustomFill=t&&"object"==typeof t?rs(t,cs(this._curSpaceCfg).customFill):null,this._roomTempSrc=e.settings?.temp_source||"",this._roomHumSrc=e.settings?.hum_source||"",this._roomNameScale=Ns(e.settings?.name_scale),this._roomLabelScale=Ns(e.settings?.label_scale),this._roomSrcOpen=null,this._roomSrcFilter="",this._roomDialog=!0}_roomSettingsFromDialog(){const e={};return this._roomFill&&(e.fill_mode=this._roomFill),this._roomCustomFill&&(e.custom_fill=this._roomCustomFill),this._roomTempSrc&&(e.temp_source=this._roomTempSrc),this._roomHumSrc&&(e.hum_source=this._roomHumSrc),1!==this._roomNameScale&&(e.name_scale=this._roomNameScale),1!==this._roomLabelScale&&(e.label_scale=this._roomLabelScale),Object.keys(e).length?e:null}_saveRoomEdit(){const e=this._curSpaceCfg,t=e?.rooms.find(e=>e.id===this._roomEditId);if(!t)return this._roomDialog=!1,void(this._roomEditId=null);t.name=this._nameSel.trim()||t.name,t.area=this._areaSel||null;const i=t.settings||{},s={...i};this._roomFill?s.fill_mode=this._roomFill:delete s.fill_mode,this._roomCustomFill?s.custom_fill=this._roomCustomFill:delete s.custom_fill,"glow"===i.fill_mode&&"boolean"!=typeof i.glow&&(s.glow=!0),this._roomTempSrc?s.temp_source=this._roomTempSrc:delete s.temp_source,this._roomHumSrc?s.hum_source=this._roomHumSrc:delete s.hum_source,1!==this._roomNameScale?s.name_scale=this._roomNameScale:delete s.name_scale,1!==this._roomLabelScale?s.label_scale=this._roomLabelScale:delete s.label_scale,Object.keys(s).length?t.settings=s:delete t.settings,this._saveConfig(),this._roomDialog=!1,this._roomEditId=null,this._nameSel="",this._areaSel="",this._regSignature="",this._maybeRebuildDevices(),this.requestUpdate(),this._showToast(this._t("toast.room_updated"))}_roomSrcCandidates(){const e=this._planHass,t=wo(this._markers),i=this._roomSrcFilter.trim().toLowerCase(),s=[];for(const n of Object.values(e.devices)){if("service"===n.entry_type)continue;if(t.devices.has(n.id))continue;const e=(n.name_by_user||n.name||n.id).trim();i&&!e.toLowerCase().includes(i)||s.push({value:"device:"+n.id,label:e,sub:n.model||this._t("marker.sub_device")})}for(const[n,o]of Object.entries(e.entities)){if(!n.startsWith("sensor.")||o.hidden)continue;if(ko(e,n,t))continue;const a=o.name||e.states[n]?.attributes?.friendly_name||n;i&&!(a+" "+n).toLowerCase().includes(i)||s.push({value:"entity:"+n,label:a,sub:n})}return s.sort((e,t)=>e.label.localeCompare(t.label)),s.slice(0,200)}_roomSrcLabel(e){const t=e.indexOf(":"),i=e.slice(0,t),s=e.slice(t+1);return"device"===i?this._fullRegistryHass.devices[s]?.name_by_user||this._fullRegistryHass.devices[s]?.name||s:this._fullRegistryHass.entities[s]?.name||this.hass.states[s]?.attributes?.friendly_name||s}_labelPos(e,t){const i=this._layout["rl_"+(e.id||"")];if(i&&i.s===t)return{x:i.x*Pv,y:i.y*Pv};const s=this._snap(this._roomCenter(e));return{x:s[0],y:s[1]}}_labelDown(e,t,i){if("plan"!==this._mode)return;e.preventDefault(),e.stopPropagation();const s=this._labelPos(t,i);this._drag={id:"rl_"+(t.id||""),sx:e.clientX,sy:e.clientY,ox:s.x,oy:s.y,moved:!1},Ev(e),this._tip=null}_labelMove(e,t,i){const s="rl_"+(t.id||"");if(!this._drag||this._drag.id!==s)return;const n=this._stageEl;if(!n)return;const o=this._spaceModelById(i);if(!o)return;const a=o.vb,r=n.getBoundingClientRect(),l=this._viewOr(a),c=(e.clientX-this._drag.sx)/r.width*l.w,h=(e.clientY-this._drag.sy)/r.height*l.h;Math.abs(e.clientX-this._drag.sx)+Math.abs(e.clientY-this._drag.sy)>3&&(this._drag.moved=!0);const d=Lh(this._drag.ox+c),p=Lh(this._drag.oy+h);this._savePos({id:s,space:i},d,p)}_labelUp(e){const t="rl_"+(e.id||"");if(!this._drag||this._drag.id!==t)return;const i=this._drag.moved;this._drag=i?this._drag:null,i&&window.setTimeout(()=>this._drag=null,0)}_labelScale(e){const t=this._layout["rl_"+(e.id||"")]?.k;return"number"==typeof t&&Number.isFinite(t)?Math.min(3,Math.max(.5,t)):1}_rlResizeDown(e,t,i){if("plan"!==this._mode)return;e.preventDefault(),e.stopPropagation();const s=e.target.closest(".roomlabel");if(!s)return;const n=s.getBoundingClientRect(),o=n.left+n.width/2,a=n.top+n.height/2,r=Math.max(8,Math.hypot(e.clientX-o,e.clientY-a));this._rlResize={id:"rl_"+(t.id||""),space:i,k0:this._labelScale(t),cx:o,cy:a,d0:r},Ev(e)}_rlResizeMove(e){const t=this._rlResize;if(!t)return;e.stopPropagation();const i=Math.max(8,Math.hypot(e.clientX-t.cx,e.clientY-t.cy)),s=Math.min(3,Math.max(.5,t.k0*(i/t.d0))),n=this._layout[t.id];if(n)this._layout={...this._layout,[t.id]:{...n,k:s}};else{const e=t.id.slice(3),i=this._spaceModelById(t.space);if(!i)return;const n=i.rooms.find(t=>t.id===e);if(!n)return;const o=this._labelPos(n,t.space);this._layout={...this._layout,[t.id]:{s:t.space,x:o.x/Pv,y:o.y/Pv,k:s}}}this._dirtyPos.add(t.id)}_rlResizeUp(){this._rlResize&&(this._rlResize=null,this._persistLayout())}_renderRoomGear(e,t,i){if(!e.id)return G;let s=null;if(e.poly?(s=this._gearPtCache.get(e.poly)||null,s||(s=$i(e.poly),this._gearPtCache.set(e.poly,s))):null!=e.x&&null!=e.y&&(s=[e.x+(e.w||0)/2,e.y+(e.h||0)/2]),!s)return G;const n=(s[0]-i.x)/i.w*100,o=(s[1]-i.y)/i.h*100;return q`
`}get _measureAnchor(){return this._markup&&this._cursorPt?"draw"===this._tool&&this._path.length&&!this._contourClosed?this._path[this._path.length-1]:"split"===this._tool&&this._splitSel?.pts?.length?this._splitSel.pts[this._splitSel.pts.length-1]:null:null}_renderMeasureLabel(e){const t=this._measureAnchor,i=this._cursorPt,s=(i[0]-e.x)/e.w*100,n=(i[1]-e.y)/e.h*100,o=Es(t,i),a=Math.round(10*o)/10,r=function(e,t,i=.001){if(e.length<2||t.length<2)return!1;const s=Math.abs(t[0]-e[0]),n=Math.abs(t[1]-e[1]);if(!Number.isFinite(s)||!Number.isFinite(n)||Math.hypot(s,n)<=i)return!1;const o=Math.max(s,n,1);return s<=i*o||n<=i*o||Math.abs(s-n)<=i*o}(t,i,2e-4*this._gridPitch);return q`
- ${this._fmtLen(t,i)} · ${a}°
`}get _decorMeasure(){const e=this._decorDraft;if(!e||"decor"!==this._mode)return null;const[t,i]=e.a,[s,n]=e.b;if(Math.abs(t-s)<1e-6&&Math.abs(i-n)<1e-6)return null;const o=(t+s)/2,a=(i+n)/2;if("line"===e.kind){const t=Es(e.a,e.b);return{x:o,y:a,on45:Os(t),text:`${this._fmtLen(e.a,e.b)} · ${Math.round(10*t)/10}°`}}const r=this._fmtLen([t,i],[s,i]),l=this._fmtLen([s,i],[s,n]);if("ellipse"===e.kind){const e=this._fmtLen([0,0],[Math.abs(s-t)/2,0]),r=this._fmtLen([0,0],[0,Math.abs(n-i)/2]);return{x:o,y:a,on45:!1,text:Math.abs(Math.abs(s-t)-Math.abs(n-i))<1e-6?`R ${e}`:`Rx ${e} × Ry ${r}`}}return{x:o,y:a,on45:!1,text:`${r} × ${l} · ${ir(Br(Math.abs(s-t),this._cellCm,this._gridPitch)*Br(Math.abs(n-i),this._cellCm,this._gridPitch)/1e4,this._imperial)}`}}get _alignPoint(){if(this._markup){if("draw"===this._tool&&this._path.length&&!this._contourClosed&&this._cursorPt)return this._cursorPt;if("split"===this._tool&&this._splitSel?.pts?.length&&this._cursorPt)return this._cursorPt;if(this._drag?.id.startsWith("rl_")&&this._drag.moved){const e=this._drag.id.slice(3),t=this._spaceModel()?.rooms.find(t=>t.id===e);return t?(()=>{const e=this._labelPos(t,this._space);return[e.x,e.y]})():null}return null}if("devices"===this._mode&&this._drag?.moved){const e=this._devices.find(e=>e.id===this._drag.id);return e?(()=>{const t=this._pos(e);return[t.x,t.y]})():null}if("decor"===this._mode){if(this._decorDraft)return this._decorDraft.b;if(this._decorMove){const e=this._decorList.find(e=>e.id===this._decorMove.id);if(!e)return null;const t=Pv,i=this._decorH;return"line"===e.kind?[e.x1*t,e.y1*i]:[e.x*t,e.y*i]}return null}return null}_alignCandidates(){const e=[],t=this._spaceModel();if(this._markup){if(!t)return e;if(this._drag?.id.startsWith("rl_")){const i=this._drag.id.slice(3);for(const s of t.rooms){if(!s.name||s.id===i)continue;const t=this._labelPos(s,this._space);e.push([t.x,t.y])}return e}for(const i of t.rooms){const t=hi(i);if(t)for(const i of t)e.push(i)}if("draw"===this._tool)for(const t of this._path)e.push(t);if("split"===this._tool&&this._splitSel?.pts)for(const t of this._splitSel.pts)e.push(t);return e}if("devices"===this._mode){for(const t of this._devices){if(t.space!==this._space||t.id===this._drag?.id||"ha_disabled"===t.bindingStatus?.kind)continue;const i=this._pos(t);e.push([i.x,i.y])}return e}if("decor"===this._mode){const t=this._decorMove?.id;return e.push(...this._decorSnapGeometry(t).points),this._decorDraft&&e.push(this._decorDraft.a),e}return e}_renderAlignGuides(){const e=this._alignPoint;if(!e)return W``;const t=this._drag?.id.startsWith("rl_")?.5*this._gridPitch:.05*this._gridPitch,i=function(e,t,i){let s=null,n=null;for(const o of t)if(!(Math.abs(o[0]-e[0])<1e-6&&Math.abs(o[1]-e[1])<1e-6)){if(Math.abs(o[0]-e[0])<=i){const t=Math.abs(o[1]-e[1]);t>1e-6&&(!s||t1e-6&&(!n||t + ${this._fmtLen(t,i)} · ${a}°
`}get _decorMeasure(){const e=this._decorDraft;if(!e||"decor"!==this._mode)return null;const[t,i]=e.a,[s,n]=e.b;if(Math.abs(t-s)<1e-6&&Math.abs(i-n)<1e-6)return null;const o=(t+s)/2,a=(i+n)/2;if("line"===e.kind){const t=Es(e.a,e.b);return{x:o,y:a,on45:Os(t),text:`${this._fmtLen(e.a,e.b)} · ${Math.round(10*t)/10}°`}}const r=this._fmtLen([t,i],[s,i]),l=this._fmtLen([s,i],[s,n]);if("ellipse"===e.kind){const e=this._fmtLen([0,0],[Math.abs(s-t)/2,0]),r=this._fmtLen([0,0],[0,Math.abs(n-i)/2]);return{x:o,y:a,on45:!1,text:Math.abs(Math.abs(s-t)-Math.abs(n-i))<1e-6?`R ${e}`:`Rx ${e} × Ry ${r}`}}return{x:o,y:a,on45:!1,text:`${r} × ${l} · ${rr(Gr(Math.abs(s-t),this._cellCm,this._gridPitch)*Gr(Math.abs(n-i),this._cellCm,this._gridPitch)/1e4,this._imperial)}`}}get _alignPoint(){if(this._markup){if("draw"===this._tool&&this._path.length&&!this._contourClosed&&this._cursorPt)return this._cursorPt;if("split"===this._tool&&this._splitSel?.pts?.length&&this._cursorPt)return this._cursorPt;if(this._drag?.id.startsWith("rl_")&&this._drag.moved){const e=this._drag.id.slice(3),t=this._spaceModel()?.rooms.find(t=>t.id===e);return t?(()=>{const e=this._labelPos(t,this._space);return[e.x,e.y]})():null}return null}if("devices"===this._mode&&this._drag?.moved){const e=this._devices.find(e=>e.id===this._drag.id);return e?(()=>{const t=this._pos(e);return[t.x,t.y]})():null}if("decor"===this._mode){if(this._decorDraft)return this._decorDraft.b;if(this._decorMove){const e=this._decorList.find(e=>e.id===this._decorMove.id);if(!e)return null;const t=zv,i=this._decorH;return"line"===e.kind?[e.x1*t,e.y1*i]:[e.x*t,e.y*i]}return null}return null}_alignCandidates(){const e=[],t=this._spaceModel();if(this._markup){if(!t)return e;if(this._drag?.id.startsWith("rl_")){const i=this._drag.id.slice(3);for(const s of t.rooms){if(!s.name||s.id===i)continue;const t=this._labelPos(s,this._space);e.push([t.x,t.y])}return e}for(const i of t.rooms){const t=hi(i);if(t)for(const i of t)e.push(i)}if("draw"===this._tool)for(const t of this._path)e.push(t);if("split"===this._tool&&this._splitSel?.pts)for(const t of this._splitSel.pts)e.push(t);return e}if("devices"===this._mode){for(const t of this._devices){if(t.space!==this._space||t.id===this._drag?.id||"ha_disabled"===t.bindingStatus?.kind)continue;const i=this._pos(t);e.push([i.x,i.y])}return e}if("decor"===this._mode){const t=this._decorMove?.id;return e.push(...this._decorSnapGeometry(t).points),this._decorDraft&&e.push(this._decorDraft.a),e}return e}_renderAlignGuides(){const e=this._alignPoint;if(!e)return W``;const t=this._drag?.id.startsWith("rl_")?.5*this._gridPitch:.05*this._gridPitch,i=function(e,t,i){let s=null,n=null;for(const o of t)if(!(Math.abs(o[0]-e[0])<1e-6&&Math.abs(o[1]-e[1])<1e-6)){if(Math.abs(o[0]-e[0])<=i){const t=Math.abs(o[1]-e[1]);t>1e-6&&(!s||t1e-6&&(!n||t ${i.map(t=>{const[i,o,a,r]="x"===t.axis?[t.at,t.from[1],t.at,e[1]+Math.sign(e[1]-t.from[1])*n]:[t.from[0],t.at,e[0]+Math.sign(e[0]-t.from[0])*n,t.at];return W` `})} - `}_renderOpeningCenterTick(e){const t=(e.angle+90)*Math.PI/180,i=xh(15,this._cellCm);return W``})} + `}_renderOpeningCenterTick(e){const t=(e.angle+90)*Math.PI/180,i=Dh(15,this._cellCm);return W``}_renderOpeningDimensionGuides(e){const t=e.labels.flatMap(e=>e.dimension?[e.dimension]:[]);if(!t.length)return W``;const i=this._cssPxToRender(4);return W``}_roomCenter(e){if(e.poly){const t=e.poly.length;return[e.poly.reduce((e,t)=>e+t[0],0)/t,e.poly.reduce((e,t)=>e+t[1],0)/t]}return[e.x+e.w/2,e.y+.1*Math.min(e.w,e.h)]}_openingAmt(e){const t=e.contact&&this._renderOpeningEntityAvailable(e.contact)?this._renderPlanHass.states[e.contact]?.state:null;return mi(e.type,t,!!e.invert)}_planEntityAvailable(e){return!!e&&(!ko(this._fullRegistryHass,e,wo(this._markers))&&"active"===this._bindingStatus("entity:"+e).kind)}_renderEntityAvailable(e){return!!e&&(!ko(this._renderPlanHass,e,wo(this._markers))&&(!!this._renderPlanHass.entities?.[e]&&!!this._renderPlanHass.states?.[e]))}_openingEntityAvailable(e){return function(e,t,i=An(e)){return!!t&&"active"===Bn(e,`entity:${t}`,i).kind}(this.hass,e,this._haRegistry)}_renderOpeningEntityAvailable(e){return t=this._renderPlanHass,!!(i=e)&&!!t?.states?.[i];var t,i}_renderOpeningPlacementPreview(){const e=this._openingPreview;if(!e)return W``;const t={type:e.type,length:e.renderedLength,angle:e.angle,amount:mi(e.type,null),flipH:e.flipH,flipV:e.flipV,base:"var(--hp-open)",tone:"var(--hp-open)",cellCm:this._cellCm,gridPitch:this._gridPitch,face:e.face},i="passage"===e.type?function(e,t){const i=Math.max(0,e.renderedLength)/2,s=Math.max(0,e.target.physicalHalfWidth),n=s+.18*Math.max(0,t),o=e=>({x1:e,y1:-n,x2:e,y2:n});return{rect:{x:-i,y:s?-s:0,width:2*i,height:2*s},boundaries:[o(-i),o(i)]}}(e,xh(this._gridPitch,this._cellCm)):null;return W``}_roomCenter(e){if(e.poly){const t=e.poly.length;return[e.poly.reduce((e,t)=>e+t[0],0)/t,e.poly.reduce((e,t)=>e+t[1],0)/t]}return[e.x+e.w/2,e.y+.1*Math.min(e.w,e.h)]}_openingAmt(e){const t=e.contact&&this._renderOpeningEntityAvailable(e.contact)?this._renderPlanHass.states[e.contact]?.state:null;return mi(e.type,t,!!e.invert)}_planEntityAvailable(e){return!!e&&(!ko(this._fullRegistryHass,e,wo(this._markers))&&"active"===this._bindingStatus("entity:"+e).kind)}_renderEntityAvailable(e){return!!e&&(!ko(this._renderPlanHass,e,wo(this._markers))&&(!!this._renderPlanHass.entities?.[e]&&!!this._renderPlanHass.states?.[e]))}_openingEntityAvailable(e){return function(e,t,i=An(e)){return!!t&&"active"===Bn(e,`entity:${t}`,i).kind}(this.hass,e,this._haRegistry)}_renderOpeningEntityAvailable(e){return t=this._renderPlanHass,!!(i=e)&&!!t?.states?.[i];var t,i}_renderOpeningPlacementPreview(){const e=this._openingPreview;if(!e)return W``;const t={type:e.type,length:e.renderedLength,angle:e.angle,amount:mi(e.type,null),flipH:e.flipH,flipV:e.flipV,base:"var(--hp-open)",tone:"var(--hp-open)",cellCm:this._cellCm,gridPitch:this._gridPitch,face:e.face},i="passage"===e.type?function(e,t){const i=Math.max(0,e.renderedLength)/2,s=Math.max(0,e.target.physicalHalfWidth),n=s+.18*Math.max(0,t),o=e=>({x1:e,y1:-n,x2:e,y2:n});return{rect:{x:-i,y:s?-s:0,width:2*i,height:2*s},boundaries:[o(-i),o(i)]}}(e,Dh(this._gridPitch,this._cellCm)):null;return W` `}_renderOpenings(e){const t=this._openingsR;if(!t.length)return W``;const i=this._spaceModel();if(!i)return W``;const s=e.color,n=this._spaceWalls,o=this._openCuts(),a=this._openingWallIndexFor(i,o).value;return W`${t.map(e=>{if(e.orphanReason)return W``}_renderOpenings(e){const t=this._openingsR;if(!t.length)return W``;const i=this._spaceModel();if(!i)return W``;const s=e.color,n=this._spaceWalls,o=this._openCuts(),a=this._openingWallIndexFor(i,o).value;return W`${t.map(e=>{if(e.orphanReason)return W`{t.stopPropagation(),this._editOpening(e)}}> - + ! - `;const t=this._openingAmt(e),i=t>0&&!!e.contact&&this._renderOpeningEntityAvailable(e.contact)?"var(--hp-open)":s,o="gate"===e.type?!e.flip_v:e.flip_v,r=e.partitionHost||n.length||"gate"===e.type?this._openingFace(e,a,!!o):{ox:0,oy:0,cm:0,side:-1},l={type:e.type,length:e.rlen,angle:e.angle,amount:t,flipH:!!e.flip_h,flipV:!!e.flip_v,base:s,tone:i,cellCm:this._cellCm,gridPitch:this._gridPitch,face:r},{half:c,outlineHalf:h,hitHalf:d}=d_(l),p=xh(10,this._cellCm),u=xh(12,this._cellCm);return W``;const t=this._openingAmt(e),i=t>0&&!!e.contact&&this._renderOpeningEntityAvailable(e.contact)?"var(--hp-open)":s,o="gate"===e.type?!e.flip_v:e.flip_v,r=e.partitionHost||n.length||"gate"===e.type?this._openingFace(e,a,!!o):{ox:0,oy:0,cm:0,side:-1},l={type:e.type,length:e.rlen,angle:e.angle,amount:t,flipH:!!e.flip_h,flipV:!!e.flip_v,base:s,tone:i,cellCm:this._cellCm,gridPitch:this._gridPitch,face:r},{half:c,outlineHalf:h,hitHalf:d}=g_(l),p=Dh(10,this._cellCm),u=Dh(12,this._cellCm);return W` - ${p_(l)} + ${f_(l)} + rx="${Dh(6,this._cellCm)}"> this._opClick(t,e)} @@ -6546,7 +6546,7 @@ globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="30d20d6f6822065e2d5226b18abbb05d8d26 @pointermove=${t=>this._opPointerMove(t,e)} @pointerup=${t=>this._opPointerUp(t,e)} @pointercancel=${t=>this._opPointerUp(t,e)}> - `})}`}_renderOpeningLocks(e){const t=this._openingsR.filter(e=>!e.orphanReason&&("door"===e.type||"gate"===e.type)&&e.lock&&this._renderOpeningEntityAvailable(e.lock));if(!t.length)return q``;const i=this._spaceModel();if(!i)return q``;const s=this._openCuts(),n=this._openingWallIndexFor(i,s).value;return q`${t.map(t=>{const i=this._renderPlanHass.states[t.lock]?.state,s="locked"===i,o=s||["unlocked","open","opening","unlocking","locking"].includes(String(i)),a=(t.angle+90)*Math.PI/180,r="gate"===t.type?this._openingFace(t,n,!t.flip_v):null,l=xh(16,this._cellCm),c=r?-l*r.side:l*(t.flip_v?-1:1),h=t.rx+Math.cos(a)*c,d=t.ry+Math.sin(a)*c,p=this._scenePoint([h,d]),u=(p[0]-e.x)/e.w*100,_=(p[1]-e.y)/e.h*100;return q`
`})}`}_renderOpeningLocks(e){const t=this._openingsR.filter(e=>!e.orphanReason&&("door"===e.type||"gate"===e.type)&&e.lock&&this._renderOpeningEntityAvailable(e.lock));if(!t.length)return q``;const i=this._spaceModel();if(!i)return q``;const s=this._openCuts(),n=this._openingWallIndexFor(i,s).value;return q`${t.map(t=>{const i=this._renderPlanHass.states[t.lock]?.state,s="locked"===i,o=s||["unlocked","open","opening","unlocking","locking"].includes(String(i)),a=(t.angle+90)*Math.PI/180,r="gate"===t.type?this._openingFace(t,n,!t.flip_v):null,l=Dh(16,this._cellCm),c=r?-l*r.side:l*(t.flip_v?-1:1),h=t.rx+Math.cos(a)*c,d=t.ry+Math.sin(a)*c,p=this._scenePoint([h,d]),u=(p[0]-e.x)/e.w*100,_=(p[1]-e.y)/e.h*100;return q`
{e.stopPropagation(),"view"===this._mode&&(this._openingInfo=t)}}>
- `}_renderOpeningDialog(){const e=this._openingDialog,t=this._spaceModel()?.partitions||[],i=e.id?this._curSpaceCfg?.openings?.find(t=>t.id===e.id):null,s={id:e.id||"preview",type:e.type,x:e.x/Pv,y:e.y/this._spaceH,angle:e.angle,length:i&&!e.lengthTouched?i.length:this._cmToUnits(Math.max(20,e.lengthCm))/Pv,...e.host?{host:e.host}:{}},n=Zp(i,s),o=e.host?n?Xp(s,t,Pv,this._cellCm,this._gridPitch):Jp(s,t,Pv,this._cellCm,this._gridPitch):null,a="does-not-fit-jamb"===o?.reason,r=e.host?t.find(t=>t.id===e.host.id):null,l=r?li(r.cm/2,this._imperial):"",c=!!e.host&&!o?.resolved&&!a,h="gate"===e.type?"mdi:gate":"window"===e.type?"mdi:window-closed-variant":"passage"===e.type?"mdi:arch":"mdi:door",d=(t,i)=>{const s="contact"===t?e.contact:e.lock,n="contact"===t?!!e.contactOpen:!!e.lockOpen,o="contact"===t?e.contactFilter||"":e.lockFilter||"",a=i.find(e=>e.value===s),r=a?.label||this.hass.states[s]?.attributes?.friendly_name||this._fullRegistryHass.entities[s]?.name||s,l=function(e,t,i=200){const s=t.trim().toLowerCase();return(s?e.filter(e=>e.label.toLowerCase().includes(s)||e.value.toLowerCase().includes(s)):e).slice(0,Math.max(0,i))}(i,o);return q` + `}_renderOpeningDialog(){const e=this._openingDialog,t=this._spaceModel()?.partitions||[],i=e.id?this._curSpaceCfg?.openings?.find(t=>t.id===e.id):null,s={id:e.id||"preview",type:e.type,x:e.x/zv,y:e.y/this._spaceH,angle:e.angle,length:i&&!e.lengthTouched?i.length:this._cmToUnits(Math.max(20,e.lengthCm))/zv,...e.host?{host:e.host}:{}},n=su(i,s),o=e.host?n?iu(s,t,zv,this._cellCm,this._gridPitch):tu(s,t,zv,this._cellCm,this._gridPitch):null,a="does-not-fit-jamb"===o?.reason,r=e.host?t.find(t=>t.id===e.host.id):null,l=r?li(r.cm/2,this._imperial):"",c=!!e.host&&!o?.resolved&&!a,h="gate"===e.type?"mdi:gate":"window"===e.type?"mdi:window-closed-variant":"passage"===e.type?"mdi:arch":"mdi:door",d=(t,i)=>{const s="contact"===t?e.contact:e.lock,n="contact"===t?!!e.contactOpen:!!e.lockOpen,o="contact"===t?e.contactFilter||"":e.lockFilter||"",a=i.find(e=>e.value===s),r=a?.label||this.hass.states[s]?.attributes?.friendly_name||this._fullRegistryHass.entities[s]?.name||s,l=function(e,t,i=200){const s=t.trim().toLowerCase();return(s?e.filter(e=>e.label.toLowerCase().includes(s)||e.value.toLowerCase().includes(s)):e).slice(0,Math.max(0,i))}(i,o);return q`
`:G} {const i=mv(t.target.value);null!=i&&(this._openingDialog={...e,lengthCm:i,lengthTouched:!0})}} /> + @input=${t=>{const i=yv(t.target.value);null!=i&&(this._openingDialog={...e,lengthCm:i,lengthTouched:!0})}} /> ${"passage"===e.type&&(e.contact||e.lock)?q`
@@ -6662,7 +6662,7 @@ globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="30d20d6f6822065e2d5226b18abbb05d8d26
- `}_gridLevels(){const e=this._stageEl,t=this._viewOr(this._baseVb()),i=e&&e.clientWidth&&t.w?e.clientWidth/t.w:1;return function(e,t,i=7){if(!(e>0&&t>0&&Number.isFinite(t)))return null;const s=td.find(s=>e*s*t>=i);if(void 0===s)return null;const n=td.find(e=>e>=5*s)??5*s;return{fine:s,coarse:n}}(this._gridPitch,i)}_renderMarkupDefs(e){const t=this._gridLevels();if(!t)return W``;const i=this._gridPitch*t.fine,s=this._gridPitch*t.coarse,n=this._gridPitch*t.fine*.14;return W` + `}_gridLevels(){const e=this._stageEl,t=this._viewOr(this._baseVb()),i=e&&e.clientWidth&&t.w?e.clientWidth/t.w:1;return function(e,t,i=7){if(!(e>0&&t>0&&Number.isFinite(t)))return null;const s=ad.find(s=>e*s*t>=i);if(void 0===s)return null;const n=ad.find(e=>e>=5*s)??5*s;return{fine:s,coarse:n}}(this._gridPitch,i)}_renderMarkupDefs(e){const t=this._gridLevels();if(!t)return W``;const i=this._gridPitch*t.fine,s=this._gridPitch*t.coarse,n=this._gridPitch*t.fine*.14;return W` @@ -6676,12 +6676,12 @@ globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="30d20d6f6822065e2d5226b18abbb05d8d26 - `}_renderPhysicalEditorLayer(){const e=this._spaceModel();if(!e)return W``;const t=this._gridPitch,i=this._viewOr(this._baseVb()),s=this._stageEl,n=s?.clientWidth?i.w/s.clientWidth:t/8,o=Math.max(.22*t,8*n),a=Math.max(o,12*n),r=e=>`M ${e.map(e=>`${e[0]} ${e[1]}`).join(" L ")} Z`,l=(e,t)=>this._physicalSel?.kind===e&&this._physicalSel.id===t||"column"===e&&this._duplicateColumnId===t,c=(e.room_drafts||[]).flatMap(e=>e.points.slice(0,-1).map((t,i)=>{const s=e.points[i+1],o=Number(e.segments[i]?.cm),a=wl(Number.isFinite(o)?o:15,this._cellCm,this._gridPitch);return W``}_renderPhysicalEditorLayer(){const e=this._spaceModel();if(!e)return W``;const t=this._gridPitch,i=this._viewOr(this._baseVb()),s=this._stageEl,n=s?.clientWidth?i.w/s.clientWidth:t/8,o=Math.max(.22*t,8*n),a=Math.max(o,12*n),r=e=>`M ${e.map(e=>`${e[0]} ${e[1]}`).join(" L ")} Z`,l=(e,t)=>this._physicalSel?.kind===e&&this._physicalSel.id===t||"column"===e&&this._duplicateColumnId===t,c=(e.room_drafts||[]).flatMap(e=>e.points.slice(0,-1).map((t,i)=>{const s=e.points[i+1],o=Number(e.segments[i]?.cm),a=Ml(Number.isFinite(o)?o:15,this._cellCm,this._gridPitch);return W`{this._physicalSel={kind:"draft",id:e.id,segment:i},this._registerPhysicalTap("draft",e.id,i)}}>`})),h=(e.partitions||[]).map(e=>{const t=oh(e.a,e.b,e.cm,this._cellCm,this._gridPitch);return t?W`{this._physicalSel={kind:"draft",id:e.id,segment:i},this._registerPhysicalTap("draft",e.id,i)}}>`})),h=(e.partitions||[]).map(e=>{const t=hh(e.a,e.b,e.cm,this._cellCm,this._gridPitch);return t?W`this._physicalDown(t,"partition",e.id)} @@ -6692,7 +6692,7 @@ globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="30d20d6f6822065e2d5226b18abbb05d8d26 stroke-width=${24} vector-effect="non-scaling-stroke" @pointerdown=${t=>this._physicalDown(t,"partition",e.id)} @pointermove=${e=>this._physicalMove(e)} - @pointerup=${e=>this._physicalUp(e)}>`}),d=(e.wall_columns||[]).map(e=>{const t=ah(this._physicalRotate?.id===e.id?{...e,angle:this._physicalRotate.angle}:e,this._cellCm,this._gridPitch);return W`this._physicalUp(e)}>`}),d=(e.wall_columns||[]).map(e=>{const t=dh(this._physicalRotate?.id===e.id?{...e,angle:this._physicalRotate.angle}:e,this._cellCm,this._gridPitch);return W`this._physicalDown(t,"column",e.id)} @@ -6700,20 +6700,20 @@ globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="30d20d6f6822065e2d5226b18abbb05d8d26 @pointerup=${e=>this._physicalUp(e)}>`}),p=this._physicalDrag,u=(()=>{if(!p?.moved)return G;if("partition"===p.kind&&0===Number(p.base.cm)){const e=p.base;return W``}const e="partition"===p.kind?oh(p.base.a,p.base.b,p.base.cm,this._cellCm,this._gridPitch):ah(p.base,this._cellCm,this._gridPitch);return e?W``}const e="partition"===p.kind?hh(p.base.a,p.base.b,p.base.cm,this._cellCm,this._gridPitch):dh(p.base,this._cellCm,this._gridPitch);return e?W``:G})(),_=(()=>{const i=this._physicalSel;if(!i)return G;if("draft"===i.kind){const t=e.room_drafts.find(e=>e.id===i.id);return t?W` e.join(",")).join(" ")}> ${t.points.map(e=>W``)} - `:G}if("partition"===i.kind){const t=e.partitions.find(e=>e.id===i.id);if(!t)return G;const s=oh(t.a,t.b,t.cm,this._cellCm,this._gridPitch),n=(t.a[0]+t.b[0])/2,a=(t.a[1]+t.b[1])/2;return W` + `:G}if("partition"===i.kind){const t=e.partitions.find(e=>e.id===i.id);if(!t)return G;const s=hh(t.a,t.b,t.cm,this._cellCm,this._gridPitch),n=(t.a[0]+t.b[0])/2,a=(t.a[1]+t.b[1])/2;return W` ${s?W``:W``} - `}const s=e.wall_columns.find(e=>e.id===i.id);if(!s)return G;const l=this._physicalRotate?.id===s.id?{...s,angle:this._physicalRotate.angle}:s,c=ah(l,this._cellCm,this._gridPitch);if("square"!==l.shape)return W` + `}const s=e.wall_columns.find(e=>e.id===i.id);if(!s)return G;const l=this._physicalRotate?.id===s.id?{...s,angle:this._physicalRotate.angle}:s,c=dh(l,this._cellCm,this._gridPitch);if("square"!==l.shape)return W` - `;const h=wl(l.cm,this._cellCm,this._gridPitch),d=eh(l.angle)*Math.PI/180,p=Math.sin(d),u=-Math.cos(d),_=[l.center[0]+p*h/2,l.center[1]+u*h/2],m=[_[0]+p*Math.max(t,24*n),_[1]+u*Math.max(t,24*n)];return W` + `;const h=Ml(l.cm,this._cellCm,this._gridPitch),d=oh(l.angle)*Math.PI/180,p=Math.sin(d),u=-Math.cos(d),_=[l.center[0]+p*h/2,l.center[1]+u*h/2],m=[_[0]+p*Math.max(t,24*n),_[1]+u*Math.max(t,24*n)];return W` @@ -6721,7 +6721,7 @@ globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="30d20d6f6822065e2d5226b18abbb05d8d26 data-kind="rotate" @pointerdown=${e=>this._physicalRotateDown(e,s)} @pointermove=${e=>this._physicalRotateMove(e)} @pointerup=${e=>this._physicalRotateUp(e)}>
- `})();return W`${c}${h}${d}${u}${_}`}_renderHiddenWallDiagnosticOverlay(){if(!this._markup)return W``;const e=this._hiddenWallDiagnosticSnapshot().value;if(!e.segments.length)return W``;const t=wl(5,this._cellCm,this._gridPitch);return W``})();return W`${c}${h}${d}${u}${_}`}_renderHiddenWallDiagnosticOverlay(){if(!this._markup)return W``;const e=this._hiddenWallDiagnosticSnapshot().value;if(!e.segments.length)return W``;const t=Ml(5,this._cellCm,this._gridPitch);return W``}_renderPlanSnapOverlay(){if(!this._markup)return W``;const e=this._planSnapGeometrySnapshot().value,t=this._activePlanSnapCandidate,i=new Set(this._activePlanSnapConflicts.map(e=>e.key)),s=wl(5,this._cellCm,this._gridPitch),n=wl(10,this._cellCm,this._gridPitch);return W``}_renderPlanSnapOverlay(){if(!this._markup)return W``;const e=this._planSnapGeometrySnapshot().value,t=this._activePlanSnapCandidate,i=new Set(this._activePlanSnapConflicts.map(e=>e.key)),s=Ml(5,this._cellCm,this._gridPitch),n=Ml(10,this._cellCm,this._gridPitch);return W``}_syncPlanSnapActiveMarker(e){const t=this.renderRoot?.querySelector('[data-hp="plan-snap-active-marker"]');if(t){if(t.setAttribute("class",`plan-snap-node${e?" active":""}${"line"===e?.kind?" dynamic":""}`),t.setAttribute("data-active",e?"true":"false"),t.setAttribute("visibility",e?"visible":"hidden"),!e)return t.removeAttribute("data-kind"),void t.removeAttribute("data-key");t.setAttribute("data-kind",e.kind),t.setAttribute("data-key",e.key),t.setAttribute("cx",String(e.point[0])),t.setAttribute("cy",String(e.point[1])),t.setAttribute("r",String(wl(10,this._cellCm,this._gridPitch)))}}_syncPlanSnapConflictMarkers(e){const t=new Set(e.map(e=>e.key));for(const e of this.renderRoot?.querySelectorAll('.plan-snap-node[data-kind="endpoint"]')||[])e.setAttribute("class","plan-snap-node"+(t.has(e.dataset.key||"")?" conflict":""))}_planSnapPhysicalSegment(e){let t=0;const i=this._spaceModel();if(!i)return null;if("partition"===e.sourceKind)t=Number(i.partitions.find(t=>t.id===e.sourceId)?.cm)||0;else if("draft"===e.sourceKind){const s=/^(.*):(\d+)$/.exec(e.sourceId),n=s?i.room_drafts.find(e=>e.id===s[1]):null;t=n&&s&&Number(n.segments[Number(s[2])]?.cm)||0}else t=bc(i.rooms,this._spaceWalls,this._openCuts(),[e.a[0],e.a[1],e.b[0],e.b[1]],this._wallKeyPitch,this._cellCm,this._gridPitch,Pv);return t>0?{a:[...e.a],b:[...e.b],halfDepth:wl(t,this._cellCm,this._gridPitch)/2}:null}_drawPreviewJoinPatchD(e,t){if(e.length<2)return"";const i=[];for(let s=0;s+10&&i.push({a:e[s],b:e[s+1],halfDepth:t[s]});if(!i.length)return"";const s=2e-4*this._gridPitch,n=this._planSnapGeometrySnapshot().value.segments.filter(t=>e.some(e=>Hs(e,[t.a[0],t.a[1],t.b[0],t.b[1]])<=s)).map(e=>this._planSnapPhysicalSegment(e)).filter(e=>!!e);return Yl([...i,...n],s).map(e=>`M ${e.map(e=>`${e[0]} ${e[1]}`).join(" L ")} Z`).join(" ")}_renderMarkupLayer(e){const t=this._openCuts(),i=this._thickWallCuts(),s=t.concat(i),n=s.length?Ds(this._segments,s,.02*this._gridPitch):this._segments,o=this._path,a=this._gridPitch,r=this._viewOr(this._baseVb()),l="draw"===this._tool?this._drawWallCm:null,c=(()=>"draw"===this._tool&&o.length&&null!=l?this._contourClosed?o:this._cursorPt?[...o,this._cursorPt]:o.length>=2?o:null:null)(),h=c?ku(c.length-1,this._contourClosed?[...this._draftSegmentCms,this._closingWallCm??void 0]:this._draftSegmentCms,l,ul).map(e=>wl(e,this._cellCm,this._gridPitch)/2):[],d=c?Jl(c,wl(l,this._cellCm,this._gridPitch)/2,this._contourClosed,h):"",p=c?this._drawPreviewJoinPatchD(c,h):"",u=this._wallFaceBatch?.candidates[this._wallFaceBatch.index]?.repair||this._wallRepairDiagnostic;return W` + `}_syncPlanSnapActiveMarker(e){const t=this.renderRoot?.querySelector('[data-hp="plan-snap-active-marker"]');if(t){if(t.setAttribute("class",`plan-snap-node${e?" active":""}${"line"===e?.kind?" dynamic":""}`),t.setAttribute("data-active",e?"true":"false"),t.setAttribute("visibility",e?"visible":"hidden"),!e)return t.removeAttribute("data-kind"),void t.removeAttribute("data-key");t.setAttribute("data-kind",e.kind),t.setAttribute("data-key",e.key),t.setAttribute("cx",String(e.point[0])),t.setAttribute("cy",String(e.point[1])),t.setAttribute("r",String(Ml(10,this._cellCm,this._gridPitch)))}}_syncPlanSnapConflictMarkers(e){const t=new Set(e.map(e=>e.key));for(const e of this.renderRoot?.querySelectorAll('.plan-snap-node[data-kind="endpoint"]')||[])e.setAttribute("class","plan-snap-node"+(t.has(e.dataset.key||"")?" conflict":""))}_planSnapPhysicalSegment(e){let t=0;const i=this._spaceModel();if(!i)return null;if("partition"===e.sourceKind)t=Number(i.partitions.find(t=>t.id===e.sourceId)?.cm)||0;else if("draft"===e.sourceKind){const s=/^(.*):(\d+)$/.exec(e.sourceId),n=s?i.room_drafts.find(e=>e.id===s[1]):null;t=n&&s&&Number(n.segments[Number(s[2])]?.cm)||0}else t=$c(i.rooms,this._spaceWalls,this._openCuts(),[e.a[0],e.a[1],e.b[0],e.b[1]],this._wallKeyPitch,this._cellCm,this._gridPitch,zv);return t>0?{a:[...e.a],b:[...e.b],halfDepth:Ml(t,this._cellCm,this._gridPitch)/2}:null}_drawPreviewJoinPatchD(e,t){if(e.length<2)return"";const i=[];for(let s=0;s+10&&i.push({a:e[s],b:e[s+1],halfDepth:t[s]});if(!i.length)return"";const s=2e-4*this._gridPitch,n=this._planSnapGeometrySnapshot().value.segments.filter(t=>e.some(e=>Hs(e,[t.a[0],t.a[1],t.b[0],t.b[1]])<=s)).map(e=>this._planSnapPhysicalSegment(e)).filter(e=>!!e);return ec([...i,...n],s).map(e=>`M ${e.map(e=>`${e[0]} ${e[1]}`).join(" L ")} Z`).join(" ")}_renderMarkupLayer(e){const t=this._openCuts(),i=this._thickWallCuts(),s=t.concat(i),n=s.length?Ds(this._segments,s,.02*this._gridPitch):this._segments,o=this._path,a=this._gridPitch,r=this._viewOr(this._baseVb()),l="draw"===this._tool?this._drawWallCm:null,c=(()=>"draw"===this._tool&&o.length&&null!=l?this._contourClosed?o:this._cursorPt?[...o,this._cursorPt]:o.length>=2?o:null:null)(),h=c?Cu(c.length-1,this._contourClosed?[...this._draftSegmentCms,this._closingWallCm??void 0]:this._draftSegmentCms,l,vl).map(e=>Ml(e,this._cellCm,this._gridPitch)/2):[],d=c?tc(c,Ml(l,this._cellCm,this._gridPitch)/2,this._contourClosed,h):"",p=c?this._drawPreviewJoinPatchD(c,h):"",u=this._wallFaceBatch?.candidates[this._wallFaceBatch.index]?.repair||this._wallRepairDiagnostic;return W` ${this._gridLevels()?W``:G} ${n.map(e=>W``)} ${this._renderPhysicalEditorLayer()} - ${"column"===this._tool&&this._cursorPt&&this._drawWallCm?W``M ${ah({shape:"square",center:this._cursorPt,cm:this._drawWallCm},this._cellCm,this._gridPitch).map(e=>`${e[0]} ${e[1]}`).join(" L ")} Z`)()}>`:G} + ${"column"===this._tool&&this._cursorPt&&this._drawWallCm?W``M ${dh({shape:"square",center:this._cursorPt,cm:this._drawWallCm},this._cellCm,this._gridPitch).map(e=>`${e[0]} ${e[1]}`).join(" L ")} Z`)()}>`:G} ${d?W` `:G} - ${c&&0===l?W`e.join(",")).join(" ")}>`:G} ${p?W` `:G} @@ -6772,7 +6772,7 @@ globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="30d20d6f6822065e2d5226b18abbb05d8d26 aria-hidden="true" pointer-events="none">`:G} ${"split"===this._tool&&this._splitSel?.pts?.length?W`${this._splitSel.pts.length>1?W``:G} ${this._splitSel.pts.map((e,t)=>W``)} + cx="${e[0]}" cy="${e[1]}" r="${Dh(.22*a,this._cellCm)}">`)} ${this._cursorPt?W``:G}`:G} `}_renderActiveChainInk(){const e=this._path,t=this._gridPitch;return W` @@ -6780,9 +6780,9 @@ globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="30d20d6f6822065e2d5226b18abbb05d8d26 ${e.length&&this._cursorPt&&"draw"===this._tool&&!this._contourClosed?W` ${this._activePlanSnapCandidate||this._activePlanSnapConflicts.length?G:W``}`:G} + r="${Dh(.22*t,this._cellCm)}" aria-hidden="true">`}`:G} ${e.map((e,i)=>W``)} + cx="${e[0]}" cy="${e[1]}" r="${Dh(.22*t,this._cellCm)}">`)} `}_renderPartitionDeleteDialog(){const e=this._partitionDeleteDialog,t="mi"===this.hass?.config?.unit_system?.length;return q`

${this._t("confirm.delete_partition_openings_body",{count:e.openings.length})}

    - ${e.openings.map(e=>q`
  • ${this._t("confirm.delete_partition_openings_item",{type:this._t(`opening.${e.type}`),length:li(e.length*Pv/this._gridPitch*this._cellCm,t)})}
  • `)} + ${e.openings.map(e=>q`
  • ${this._t("confirm.delete_partition_openings_item",{type:this._t(`opening.${e.type}`),length:li(e.length*zv/this._gridPitch*this._cellCm,t)})}
  • `)}
@@ -6833,8 +6833,8 @@ globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="30d20d6f6822065e2d5226b18abbb05d8d26 `:G}
this._physicalDialog={...e,cm:t.target.value}} /> ${this._t(this._imperial?"wallthick.unit_in":"wallthick.unit_cm")}
${t&&"square"===e.shape?q` @@ -7077,7 +7077,7 @@ globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="30d20d6f6822065e2d5226b18abbb05d8d26 `:G}
- `}_markerValueBadgeFields(e){return(t={touched:e.valueBadgeTouched,originalHas:e.originalHasValueBadge,original:e.originalValueBadge,enabled:e.valueBadgeEnabled,source:e.valueBadgeSource,position:e.valueBadgePosition}).touched?{value_badge:{enabled:t.enabled,source:t.source,position:t.position}}:t.originalHas?{value_badge:t.original}:{};var t}_markerDraft(e){if("ha"===e.bindingMode&&(!e.binding||"virtual"===e.binding))return null;const t=js(e.room),i=Fi(e.binding,e.devId,()=>"__hp_device_preview__"),s=this._markers.find(t=>t.id===i||t.id===e.devId),n=Zn(e.binding,e.controls,this._bindingEntities(e.binding)),o=this._effectiveStoredTapAction(e),a={id:i,binding:e.binding,name:e.name.trim()||null,icon:e.icon||null,display:"badge"!==e.display?e.display:null,ripple_color:"icon_ripple"===e.display&&e.rippleColor?e.rippleColor:null,ripple_size:"icon_ripple"===e.display&&1.5!==e.rippleSize?e.rippleSize:null,size:1!==e.size?e.size:null,angle:e.angle||null,...this._markerTapActionFields(e),...this._markerToggleEntityFields(e),tap_target:"run"===o&&e.tapTarget||null,tap_confirm:!!e.tapConfirm||null,controls:n.length?n:null,...this._markerLightFields(e),...this._markerValueBadgeFields(e),use_climate_temp:!!e.useClimateTemp||null,glow_radius_cm:(()=>{const t=mv(e.glowRadius);return null==t||t<=0?null:Math.round(this._imperial?30.48*t:100*t)})(),model:e.model.trim()||null,link:e.link.trim()||null,description:e.description.trim()||null,pdfs:e.pdfs,hidden:e.hideFromPlan,vacuum:s?.vacuum||null};return("virtual"===e.binding||e.room)&&(a.space=t?.space||("virtual"===e.binding?this._space:null),a.area=t?.area||null,a.room_id=t?.roomId||null),a}_markerPreviewDevice(e){const t=this._markerDraft(e);if(!t)return null;const i=`${this._haRegistry.revision}\n${Bd(this._markers)}\n${JSON.stringify(t)}`;if(this._markerPreviewMemo?.key===i)return this._markerPreviewMemo.device;const s=function(e){const{marker:t,siblingMarkers:i=[],...s}=e;return So({...s,markers:[...i.filter(e=>e.id!==t.id),t]}).find(e=>e.id===t.id)||null}({hass:this.hass,registry:this._haRegistry,areaToSpace:Object.fromEntries(Object.entries(this._areaToSpace).map(([e,t])=>[e,t.space])),marker:t,siblingMarkers:this._markers,settings:this._settings,excluded:this._excluded,showAll:this._showAll,firstSpaceId:this._model[0]?.id||this._space,loc:e=>this._t(e),iconRules:this._iconRules});return this._markerPreviewMemo={key:i,device:s},s}_markerPreviewDevices(e){const t=this._markerPreviewDevicesMemo;if(t?.base===this._devices&&t.preview===e)return t.devices;const i=[...this._devices.filter(t=>t.id!==e.id),e];return this._markerPreviewDevicesMemo={base:this._devices,preview:e,devices:i},i}_toggleIntent(e,t=this._devices){return jp({hass:this._planHass,registryHass:this._fullRegistryHass,devices:t,device:e,virtualLights:this._virtualLights})}_toggleIntentForDialog(e){const t=this._markerPreviewDevice(e);if(!t)return null;const i=this._markerPreviewDevices(t);return this._toggleIntent(t,i)}_toggleStateText(e,t){const i=this._planHass?.states?.[e]||this.hass?.states?.[e];try{return i&&"function"==typeof this.hass?.formatEntityState?this.hass.formatEntityState(i):t}catch{return t}}_toggleConfirmationStateText(e){const t=String(e.state||"unknown"),i=e.entityId?this._toggleStateText(e.entityId,t):t;if(i.trim().toLocaleLowerCase()!==t.trim().toLocaleLowerCase())return i;const s={on:"confirm.state_on",off:"confirm.state_off",open:"confirm.state_open",closed:"confirm.state_closed",opening:"confirm.state_opening",closing:"confirm.state_closing",unknown:"confirm.state_unknown"}[t];return s?this._t(s):t.replaceAll("_"," ").replaceAll("-"," ")}_toggleConfirmationLines(e){const t={"turn-on":"confirm.state_on","turn-off":"confirm.state_off",open:"confirm.state_open",close:"confirm.state_closed",stop:"confirm.state_stopped"};return function(e,t){if(!Wp(e)||!e.nextEffect||!e.targets.length)return[];const i="group"===e.kind,s=i?e.targets.filter(e=>"on"===e.state).length:0,n=i?0===s?t.groupAllOff():t.groupCurrent(s,e.targets.length):t.state(e.targets[0]);let o;return o="toggle"===e.nextEffect?t.expectedByHa():i&&"turn-on"===e.nextEffect?t.groupAllOn():i&&"turn-off"===e.nextEffect?t.groupAllOff():t.effect(e.nextEffect),[t.current(n),t.expected(o),...e.skippedTargets.length?[t.unavailable(e.skippedTargets.length)]:[]]}(e,{state:e=>this._toggleConfirmationStateText(e),current:e=>this._t("confirm.current_state",{state:e}),expected:e=>this._t("confirm.expected_state",{state:e}),groupCurrent:(e,t)=>this._t("confirm.group_current",{on:e,total:t}),groupAllOn:()=>this._t("confirm.group_all_on"),groupAllOff:()=>this._t("confirm.group_all_off"),unavailable:e=>this._t("confirm.unavailable_targets",{count:e}),effect:e=>this._t(t[e]),expectedByHa:()=>this._t("confirm.expected_by_ha")})}_toggleHintLines(e){if(!e)return[];const t=e=>this._t(`marker.toggle_effect_${e.replace("-","_")}`),i=e=>this._t(`marker.toggle_skip_${e.replace("-","_")}`);return function(e,t){const i=e.targets[0]||e.skippedTargets[0],s=[];return"group"===e.kind?e.targets.length&&s.push(t.group(e.targets)):i&&s.push(t.single(i)),e.nextEffect&&e.targets.length&&s.push("group"===e.kind?t.groupCurrentNext(e.targets,e.nextEffect):t.currentNext(e.targets[0],e.nextEffect)),e.skippedTargets.length&&s.push(t.skipped(e.skippedTargets)),!e.command&&e.noneReason&&s.push(t.none(e.noneReason)),s}(e,{single:e=>{if("via"in e&&"virtual-light"===e.via)return this._t("marker.virtual_light_target",{name:e.name});const t=e.entityId||("ref"in e?e.ref:""),i=e.name||t;return this._t("marker.toggle_hint_single",{name:i,id:t})},group:e=>this._t("marker.toggle_hint_group",{count:e.length,names:e.map(e=>`${e.name} (${e.entityId})`).join(", ")}),currentNext:(e,i)=>"virtual-light"===e.via?this._t("marker.virtual_light_current",{state:this._t("on"===e.state?"marker.virtual_light_state_on":"marker.virtual_light_state_off"),effect:t(i)}):this._t("marker.toggle_hint_current",{state:this._toggleStateText(e.entityId,e.state),effect:t(i)}),groupCurrentNext:(e,i)=>this._t("marker.toggle_hint_group_current",{on:e.filter(e=>"on"===e.state).length,count:e.length,effect:t(i)}),skipped:e=>this._t("marker.toggle_hint_skipped",{count:e.length,targets:e.map(e=>{const t=e.entityId||e.ref;return`${e.name||t} (${t}: ${i(e.reason)})`}).join(", ")}),none:e=>this._t(`marker.toggle_none_${e.replaceAll("-","_")}`)})}_effectiveStoredTapAction(e,t){return e.tapActionTouched?e.tapAction:Op(e.originalHasTapAction?e.originalTapAction:null,t)}_effectiveMarkerTapAction(e,t=this._markerPreviewDevice(e)){return this._effectiveStoredTapAction(e,t?.primary?.split(".")[0])}_announceToggleDraft(e){const t=this._markerPreviewDevice(e),i=e.tapActionTouched?e:{...e,tapAction:this._effectiveMarkerTapAction(e,t)},s="toggle"===i.tapAction?this._toggleHintLines(this._toggleIntentForDialog(i)).join(" "):"";return{...i,tapHintAnnouncement:s}}_valueBadgeForBinding(e,t){const i={...e,binding:t,valueBadgeEnabled:!1,valueBadgeSource:null,valueBadgeTouched:!0},s=this._markerPreviewDevice(i);if(!s)return{valueBadgeEnabled:!1,valueBadgeSource:null,valueBadgeTouched:!0};const n=[...this._devices.filter(e=>e.id!==s.id),s],o=qo(this._planHass,s,n),a=Wo(this._planHass,s,o);return{valueBadgeEnabled:e.valueBadgeEnabled&&!!a,valueBadgeSource:a,valueBadgeTouched:!0}}_markerSpatialSource(e){const t=this._markerPreviewDevice(e);if(!t)return null;const i={...t,hidden:!1};return po(ho(this._planHass,[...this._devices.filter(e=>e.id!==i.id),i],null,this._virtualLights).filter(e=>e.device.id===i.id))}_markerAutoHasSpatialSource(e){const t={...e,lightRole:"auto",lightRoleTouched:!0},i=this._markerPreviewDevice(t);return!!i&&lo(this._planHass,{...i})}_setMarkerLightRole(e){const t=this._markerDialog;t&&(this._markerDialog={...t,lightRole:e,lightRoleTouched:!0})}_controlRefInfo(e){if(!e.startsWith("marker:"))return{label:this.hass.states[e]?.attributes?.friendly_name||e,sub:e,icon:e.startsWith("light.")?"mdi:lightbulb":"mdi:toggle-switch",warning:!this._planEntityAvailable(e)};const t=e.slice(7),i=this._markers.find(e=>e.id===t),s=this._devices.find(e=>e.id===t);if(!i||i.removed||!0!==i.is_light)return{label:this._t("marker.control_missing_label"),sub:`${this._t("marker.control_broken")} (${e})`,icon:"mdi:alert-outline",warning:!0};const n=this._serverCfg?.spaces.find(e=>e.id===(s?.space||i.space)),o=!!s&&eo(s).length>0;return{label:i.name||s?.name||t,sub:[n?.title||s?.space||i.space,i.room_id||s?.area,o?"":this._t("marker.control_passive")].filter(Boolean).join(" · "),icon:i.icon||s?.icon||"mdi:lightbulb-outline",warning:!0===i.hidden||!0===s?.hidden}}_valueBadgeCandidateLabel(e){const t=e.source;if("derived_lqi"===t.kind)return this._t("marker.value_badge_lqi");if("derived_marker_state"===t.kind)return this._t("marker.value_badge_marker_state",{name:e.label});if("entity_state"===t.kind)return this._t("marker.value_badge_state",{name:e.label});const i=this.hass.states[t.entity_id]?.attributes?.friendly_name||this._fullRegistryHass.entities[t.entity_id]?.name||t.entity_id;return this._t(`marker.value_badge_attr_${t.attribute}`,{name:i})}_controlCandidates(e){const t=this._markerDraft(e)?.id||e.devId||"",i=[],s=new Set;for(const e of this._markers){if(e.id===t||e.removed||e.hidden||!0!==e.is_light)continue;if("virtual"!==e.binding&&"active"!==this._bindingStatus(e.binding).kind)continue;const n=this._devices.find(t=>t.id===e.id);if(!n||n.hidden)continue;const o=this._controlRefInfo(`marker:${e.id}`);for(const e of eo(n))s.add(e);i.push({value:`marker:${e.id}`,label:o.label,sub:o.sub,icon:o.icon,search:`${o.label} ${o.sub} ${e.id} ${eo(n).join(" ")}`.toLowerCase()})}const n=Object.keys(this.hass.states||{}).filter(t=>Ms(t)&&!s.has(t)&&Xn(e.binding,[t],this._bindingEntities(e.binding)).length>0&&this._planEntityAvailable(t)).map(e=>{const t=this._controlRefInfo(e);return{value:e,label:t.label,sub:e,icon:t.icon,search:`${t.label} ${e}`.toLowerCase()}}),o=e.controlsFilter.trim().toLowerCase();return[...i,...n].filter(t=>!e.controls.includes(t.value)&&(!o||t.search.includes(o))).slice(0,12).map(({search:e,...t})=>t)}_addControlRef(e,t){if(t.startsWith("marker:")){const i=this._markerDraft(e)?.id||e.devId||"";if(!i)return void this._showToast(this._t("toast.marker_binding_required"));const s=t.slice(7),n=this._markerDraft(e);if(function(e,t,i){if(!t||t===i)return!0;const s=new Map;for(const t of e)s.set(t.id,(t.controls||[]).filter(e=>"string"==typeof e&&e.startsWith("marker:")).map(e=>e.slice(7)));const n=new Set,o=[i];for(;o.length;){const e=o.pop();if(e===t)return!0;n.has(e)||(n.add(e),o.push(...s.get(e)||[]))}return!1}(n?[...this._markers.filter(e=>e.id!==i),n]:this._markers,i,s))return void this._showToast(this._t("toast.marker_control_cycle"))}this._markerDialog=this._announceToggleDraft({...e,controls:[...e.controls,t],controlsFilter:""})}_setMarkerGlowMode(e){const t=this._markerDialog;if(!t)return;if("auto"===e)return void(this._markerDialog={...t,glowMode:e,glowTouched:!0});const i=this._markerSpatialSource(t),s=xs(i?this._planHass.states[i.eid]:void 0,null,this._fillColors.glow_light.c),n=!t.glowColorDrafted,o="fixed"===e&&!t.glowBrightnessDrafted;this._markerDialog={...t,glowMode:e,glowColor:n?s.c:t.glowColor,glowBrightness:o?Math.max(1,Math.round(100*s.bri)):t.glowBrightness,glowColorDrafted:!0,glowBrightnessDrafted:t.glowBrightnessDrafted||"fixed"===e,glowTouched:!0}}_renderMarkerDialog(){const e=this._markerDialog,t="virtual"===e.bindingMode,i=this._bindingCandidates();this._bindingEntities(e.binding);const s=t?null:this._bindingStatus(e.binding),n=!t&&this._bindingHasHaPage(e.binding),o=this._markerPreviewDevice(e),a=this._effectiveMarkerTapAction(e,o),r=o?cs(this._serverCfg?.spaces.find(e=>e.id===o.space)):null,l=o?this._markerPreviewDevices(o):this._devices,c="toggle"===a&&o?this._toggleIntent(o,l):null,h=this._toggleHintLines(c),d=o?C_(this._planHass,o,{liveStates:!1!==this._config?.live_states,showTemperature:!1!==this._config?.show_temperature,showSignal:r?.showLqi??!1!==this._config?.show_signal,designPreview:!0,activityRuntime:this._activityRt.get(o.id),lightDevices:l,registryHass:this._fullRegistryHass,reducedMotion:this._reducedMotion}):null,p=o?qo(this._planHass,o,l):[],u=o?Wo(this._planHass,o,p):null,_=e.valueBadgeTouched?e.valueBadgeEnabled:!!d?.valueBadge,m=e.valueBadgeTouched?e.valueBadgeSource:d?.valueBadge?.source||e.valueBadgeSource,g=e.valueBadgeTouched?e.valueBadgePosition:d?.valueBadge?.position||e.valueBadgePosition,f=Ao(m),v=!!m&&!p.some(e=>e.key===f),b=p.find(e=>e.key===f),y=d?.valueSource?d.valueSource.attribute?`attr:${d.valueSource.eid}:${d.valueSource.attribute}`:`state:${d.valueSource.eid}`:"",w=this._markerAutoHasSpatialSource(e),k=!!o&&function(e,t){return io(e,t).some(e=>!!e.eid)}(this._planHass,{...o}),x=function(e,t,i,s){const n="always"===e||"auto"===e&&t,o=n&&!i;return{sourceExists:n,fromSourceEnabled:n&&i,manualEnabled:n,radiusEnabled:n,passive:o,effectiveMode:o&&"auto"===s?"fixed":s}}(e.lightRole,w,k,e.glowMode),$=!x.sourceExists,S=!x.fromSourceEnabled,M=x.passive,C=x.effectiveMode,D="never"===e.lightRole?this._t("marker.glow_disabled_never"):"auto"!==e.lightRole||w?M?this._t("marker.glow_passive_hint"):this._t("marker.glow_disabled_no_entity"):this._t("marker.glow_disabled_auto"),P=o?eo(o):[],T=o&&to(o)||"",I=!!e.lightEntity&&!P.includes(e.lightEntity),R=o?Ap(o):[],A=!!e.toggleEntity&&!R.includes(e.toggleEntity),z="toggle"===a?this._toggleIntentForDialog({...e,toggleEntity:"",toggleEntityTouched:!0}):null,F=z?[...z.targets,...z.skippedTargets].map(e=>e.entityId||("ref"in e?e.ref:"")).filter(Boolean).join(", "):"",N=(()=>{if(t)return null;const s=i.find(t=>t.value===e.binding);if(s)return s.label;const[n,o]=e.binding.split(":");return"device"===n?this._fullRegistryHass.devices[o]?.name_by_user||this._fullRegistryHass.devices[o]?.name||o:this._fullRegistryHass.entities[o]?.name||this.hass.states[o]?.attributes?.friendly_name||o})();return q``}_markerValueBadgeFields(e){return(t={touched:e.valueBadgeTouched,originalHas:e.originalHasValueBadge,original:e.originalValueBadge,enabled:e.valueBadgeEnabled,source:e.valueBadgeSource,position:e.valueBadgePosition}).touched?{value_badge:{enabled:t.enabled,source:t.source,position:t.position}}:t.originalHas?{value_badge:t.original}:{};var t}_markerDraft(e){if("ha"===e.bindingMode&&(!e.binding||"virtual"===e.binding))return null;const t=js(e.room),i=Fi(e.binding,e.devId,()=>"__hp_device_preview__"),s=this._markers.find(t=>t.id===i||t.id===e.devId),n=Zn(e.binding,e.controls,this._bindingEntities(e.binding)),o=this._effectiveStoredTapAction(e),a={id:i,binding:e.binding,name:e.name.trim()||null,icon:e.icon||null,display:"badge"!==e.display?e.display:null,ripple_color:"icon_ripple"===e.display&&e.rippleColor?e.rippleColor:null,ripple_size:"icon_ripple"===e.display&&1.5!==e.rippleSize?e.rippleSize:null,size:1!==e.size?e.size:null,angle:e.angle||null,...this._markerTapActionFields(e),...this._markerToggleEntityFields(e),tap_target:"run"===o&&e.tapTarget||null,tap_confirm:!!e.tapConfirm||null,controls:n.length?n:null,...this._markerLightFields(e),...this._markerValueBadgeFields(e),use_climate_temp:!!e.useClimateTemp||null,glow_radius_cm:(()=>{const t=yv(e.glowRadius);return null==t||t<=0?null:Math.round(this._imperial?30.48*t:100*t)})(),model:e.model.trim()||null,link:e.link.trim()||null,description:e.description.trim()||null,pdfs:e.pdfs,hidden:e.hideFromPlan,vacuum:s?.vacuum||null};return("virtual"===e.binding||e.room)&&(a.space=t?.space||("virtual"===e.binding?this._space:null),a.area=t?.area||null,a.room_id=t?.roomId||null),a}_markerPreviewDevice(e){const t=this._markerDraft(e);if(!t)return null;const i=`${this._haRegistry.revision}\n${Gd(this._markers)}\n${JSON.stringify(t)}`;if(this._markerPreviewMemo?.key===i)return this._markerPreviewMemo.device;const s=function(e){const{marker:t,siblingMarkers:i=[],...s}=e;return So({...s,markers:[...i.filter(e=>e.id!==t.id),t]}).find(e=>e.id===t.id)||null}({hass:this.hass,registry:this._haRegistry,areaToSpace:Object.fromEntries(Object.entries(this._areaToSpace).map(([e,t])=>[e,t.space])),marker:t,siblingMarkers:this._markers,settings:this._settings,excluded:this._excluded,showAll:this._showAll,firstSpaceId:this._model[0]?.id||this._space,loc:e=>this._t(e),iconRules:this._iconRules});return this._markerPreviewMemo={key:i,device:s},s}_markerPreviewDevices(e){const t=this._markerPreviewDevicesMemo;if(t?.base===this._devices&&t.preview===e)return t.devices;const i=[...this._devices.filter(t=>t.id!==e.id),e];return this._markerPreviewDevicesMemo={base:this._devices,preview:e,devices:i},i}_toggleIntent(e,t=this._devices){return Vp({hass:this._planHass,registryHass:this._fullRegistryHass,devices:t,device:e,virtualLights:this._virtualLights})}_toggleIntentForDialog(e){const t=this._markerPreviewDevice(e);if(!t)return null;const i=this._markerPreviewDevices(t);return this._toggleIntent(t,i)}_toggleStateText(e,t){const i=this._planHass?.states?.[e]||this.hass?.states?.[e];try{return i&&"function"==typeof this.hass?.formatEntityState?this.hass.formatEntityState(i):t}catch{return t}}_toggleConfirmationStateText(e){const t=String(e.state||"unknown"),i=e.entityId?this._toggleStateText(e.entityId,t):t;if(i.trim().toLocaleLowerCase()!==t.trim().toLocaleLowerCase())return i;const s={on:"confirm.state_on",off:"confirm.state_off",open:"confirm.state_open",closed:"confirm.state_closed",opening:"confirm.state_opening",closing:"confirm.state_closing",unknown:"confirm.state_unknown"}[t];return s?this._t(s):t.replaceAll("_"," ").replaceAll("-"," ")}_toggleConfirmationLines(e){const t={"turn-on":"confirm.state_on","turn-off":"confirm.state_off",open:"confirm.state_open",close:"confirm.state_closed",stop:"confirm.state_stopped"};return function(e,t){if(!Yp(e)||!e.nextEffect||!e.targets.length)return[];const i="group"===e.kind,s=i?e.targets.filter(e=>"on"===e.state).length:0,n=i?0===s?t.groupAllOff():t.groupCurrent(s,e.targets.length):t.state(e.targets[0]);let o;return o="toggle"===e.nextEffect?t.expectedByHa():i&&"turn-on"===e.nextEffect?t.groupAllOn():i&&"turn-off"===e.nextEffect?t.groupAllOff():t.effect(e.nextEffect),[t.current(n),t.expected(o),...e.skippedTargets.length?[t.unavailable(e.skippedTargets.length)]:[]]}(e,{state:e=>this._toggleConfirmationStateText(e),current:e=>this._t("confirm.current_state",{state:e}),expected:e=>this._t("confirm.expected_state",{state:e}),groupCurrent:(e,t)=>this._t("confirm.group_current",{on:e,total:t}),groupAllOn:()=>this._t("confirm.group_all_on"),groupAllOff:()=>this._t("confirm.group_all_off"),unavailable:e=>this._t("confirm.unavailable_targets",{count:e}),effect:e=>this._t(t[e]),expectedByHa:()=>this._t("confirm.expected_by_ha")})}_toggleHintLines(e){if(!e)return[];const t=e=>this._t(`marker.toggle_effect_${e.replace("-","_")}`),i=e=>this._t(`marker.toggle_skip_${e.replace("-","_")}`);return function(e,t){const i=e.targets[0]||e.skippedTargets[0],s=[];return"group"===e.kind?e.targets.length&&s.push(t.group(e.targets)):i&&s.push(t.single(i)),e.nextEffect&&e.targets.length&&s.push("group"===e.kind?t.groupCurrentNext(e.targets,e.nextEffect):t.currentNext(e.targets[0],e.nextEffect)),e.skippedTargets.length&&s.push(t.skipped(e.skippedTargets)),!e.command&&e.noneReason&&s.push(t.none(e.noneReason)),s}(e,{single:e=>{if("via"in e&&"virtual-light"===e.via)return this._t("marker.virtual_light_target",{name:e.name});const t=e.entityId||("ref"in e?e.ref:""),i=e.name||t;return this._t("marker.toggle_hint_single",{name:i,id:t})},group:e=>this._t("marker.toggle_hint_group",{count:e.length,names:e.map(e=>`${e.name} (${e.entityId})`).join(", ")}),currentNext:(e,i)=>"virtual-light"===e.via?this._t("marker.virtual_light_current",{state:this._t("on"===e.state?"marker.virtual_light_state_on":"marker.virtual_light_state_off"),effect:t(i)}):this._t("marker.toggle_hint_current",{state:this._toggleStateText(e.entityId,e.state),effect:t(i)}),groupCurrentNext:(e,i)=>this._t("marker.toggle_hint_group_current",{on:e.filter(e=>"on"===e.state).length,count:e.length,effect:t(i)}),skipped:e=>this._t("marker.toggle_hint_skipped",{count:e.length,targets:e.map(e=>{const t=e.entityId||e.ref;return`${e.name||t} (${t}: ${i(e.reason)})`}).join(", ")}),none:e=>this._t(`marker.toggle_none_${e.replaceAll("-","_")}`)})}_effectiveStoredTapAction(e,t){return e.tapActionTouched?e.tapAction:qp(e.originalHasTapAction?e.originalTapAction:null,t)}_effectiveMarkerTapAction(e,t=this._markerPreviewDevice(e)){return this._effectiveStoredTapAction(e,t?.primary?.split(".")[0])}_announceToggleDraft(e){const t=this._markerPreviewDevice(e),i=e.tapActionTouched?e:{...e,tapAction:this._effectiveMarkerTapAction(e,t)},s="toggle"===i.tapAction?this._toggleHintLines(this._toggleIntentForDialog(i)).join(" "):"";return{...i,tapHintAnnouncement:s}}_valueBadgeForBinding(e,t){const i={...e,binding:t,valueBadgeEnabled:!1,valueBadgeSource:null,valueBadgeTouched:!0},s=this._markerPreviewDevice(i);if(!s)return{valueBadgeEnabled:!1,valueBadgeSource:null,valueBadgeTouched:!0};const n=[...this._devices.filter(e=>e.id!==s.id),s],o=qo(this._planHass,s,n),a=Wo(this._planHass,s,o);return{valueBadgeEnabled:e.valueBadgeEnabled&&!!a,valueBadgeSource:a,valueBadgeTouched:!0}}_markerSpatialSource(e){const t=this._markerPreviewDevice(e);if(!t)return null;const i={...t,hidden:!1};return po(ho(this._planHass,[...this._devices.filter(e=>e.id!==i.id),i],null,this._virtualLights).filter(e=>e.device.id===i.id))}_markerAutoHasSpatialSource(e){const t={...e,lightRole:"auto",lightRoleTouched:!0},i=this._markerPreviewDevice(t);return!!i&&lo(this._planHass,{...i})}_setMarkerLightRole(e){const t=this._markerDialog;t&&(this._markerDialog={...t,lightRole:e,lightRoleTouched:!0})}_controlRefInfo(e){if(!e.startsWith("marker:"))return{label:this.hass.states[e]?.attributes?.friendly_name||e,sub:e,icon:e.startsWith("light.")?"mdi:lightbulb":"mdi:toggle-switch",warning:!this._planEntityAvailable(e)};const t=e.slice(7),i=this._markers.find(e=>e.id===t),s=this._devices.find(e=>e.id===t);if(!i||i.removed||!0!==i.is_light)return{label:this._t("marker.control_missing_label"),sub:`${this._t("marker.control_broken")} (${e})`,icon:"mdi:alert-outline",warning:!0};const n=this._serverCfg?.spaces.find(e=>e.id===(s?.space||i.space)),o=!!s&&eo(s).length>0;return{label:i.name||s?.name||t,sub:[n?.title||s?.space||i.space,i.room_id||s?.area,o?"":this._t("marker.control_passive")].filter(Boolean).join(" · "),icon:i.icon||s?.icon||"mdi:lightbulb-outline",warning:!0===i.hidden||!0===s?.hidden}}_valueBadgeCandidateLabel(e){const t=e.source;if("derived_lqi"===t.kind)return this._t("marker.value_badge_lqi");if("derived_marker_state"===t.kind)return this._t("marker.value_badge_marker_state",{name:e.label});if("entity_state"===t.kind)return this._t("marker.value_badge_state",{name:e.label});const i=this.hass.states[t.entity_id]?.attributes?.friendly_name||this._fullRegistryHass.entities[t.entity_id]?.name||t.entity_id;return this._t(`marker.value_badge_attr_${t.attribute}`,{name:i})}_controlCandidates(e){const t=this._markerDraft(e)?.id||e.devId||"",i=[],s=new Set;for(const e of this._markers){if(e.id===t||e.removed||e.hidden||!0!==e.is_light)continue;if("virtual"!==e.binding&&"active"!==this._bindingStatus(e.binding).kind)continue;const n=this._devices.find(t=>t.id===e.id);if(!n||n.hidden)continue;const o=this._controlRefInfo(`marker:${e.id}`);for(const e of eo(n))s.add(e);i.push({value:`marker:${e.id}`,label:o.label,sub:o.sub,icon:o.icon,search:`${o.label} ${o.sub} ${e.id} ${eo(n).join(" ")}`.toLowerCase()})}const n=Object.keys(this.hass.states||{}).filter(t=>Ms(t)&&!s.has(t)&&Xn(e.binding,[t],this._bindingEntities(e.binding)).length>0&&this._planEntityAvailable(t)).map(e=>{const t=this._controlRefInfo(e);return{value:e,label:t.label,sub:e,icon:t.icon,search:`${t.label} ${e}`.toLowerCase()}}),o=e.controlsFilter.trim().toLowerCase();return[...i,...n].filter(t=>!e.controls.includes(t.value)&&(!o||t.search.includes(o))).slice(0,12).map(({search:e,...t})=>t)}_addControlRef(e,t){if(t.startsWith("marker:")){const i=this._markerDraft(e)?.id||e.devId||"";if(!i)return void this._showToast(this._t("toast.marker_binding_required"));const s=t.slice(7),n=this._markerDraft(e);if(function(e,t,i){if(!t||t===i)return!0;const s=new Map;for(const t of e)s.set(t.id,(t.controls||[]).filter(e=>"string"==typeof e&&e.startsWith("marker:")).map(e=>e.slice(7)));const n=new Set,o=[i];for(;o.length;){const e=o.pop();if(e===t)return!0;n.has(e)||(n.add(e),o.push(...s.get(e)||[]))}return!1}(n?[...this._markers.filter(e=>e.id!==i),n]:this._markers,i,s))return void this._showToast(this._t("toast.marker_control_cycle"))}this._markerDialog=this._announceToggleDraft({...e,controls:[...e.controls,t],controlsFilter:""})}_setMarkerGlowMode(e){const t=this._markerDialog;if(!t)return;if("auto"===e)return void(this._markerDialog={...t,glowMode:e,glowTouched:!0});const i=this._markerSpatialSource(t),s=xs(i?this._planHass.states[i.eid]:void 0,null,this._fillColors.glow_light.c),n=!t.glowColorDrafted,o="fixed"===e&&!t.glowBrightnessDrafted;this._markerDialog={...t,glowMode:e,glowColor:n?s.c:t.glowColor,glowBrightness:o?Math.max(1,Math.round(100*s.bri)):t.glowBrightness,glowColorDrafted:!0,glowBrightnessDrafted:t.glowBrightnessDrafted||"fixed"===e,glowTouched:!0}}_renderMarkerDialog(){const e=this._markerDialog,t="virtual"===e.bindingMode,i=this._bindingCandidates();this._bindingEntities(e.binding);const s=t?null:this._bindingStatus(e.binding),n=!t&&this._bindingHasHaPage(e.binding),o=this._markerPreviewDevice(e),a=this._effectiveMarkerTapAction(e,o),r=o?cs(this._serverCfg?.spaces.find(e=>e.id===o.space)):null,l=o?this._markerPreviewDevices(o):this._devices,c="toggle"===a&&o?this._toggleIntent(o,l):null,h=this._toggleHintLines(c),d=o?R_(this._planHass,o,{liveStates:!1!==this._config?.live_states,showTemperature:!1!==this._config?.show_temperature,showSignal:r?.showLqi??!1!==this._config?.show_signal,designPreview:!0,activityRuntime:this._activityRt.get(o.id),lightDevices:l,registryHass:this._fullRegistryHass,reducedMotion:this._reducedMotion}):null,p=o?qo(this._planHass,o,l):[],u=o?Wo(this._planHass,o,p):null,_=e.valueBadgeTouched?e.valueBadgeEnabled:!!d?.valueBadge,m=e.valueBadgeTouched?e.valueBadgeSource:d?.valueBadge?.source||e.valueBadgeSource,g=e.valueBadgeTouched?e.valueBadgePosition:d?.valueBadge?.position||e.valueBadgePosition,f=Ao(m),v=!!m&&!p.some(e=>e.key===f),b=p.find(e=>e.key===f),y=d?.valueSource?d.valueSource.attribute?`attr:${d.valueSource.eid}:${d.valueSource.attribute}`:`state:${d.valueSource.eid}`:"",w=this._markerAutoHasSpatialSource(e),k=!!o&&function(e,t){return io(e,t).some(e=>!!e.eid)}(this._planHass,{...o}),x=function(e,t,i,s){const n="always"===e||"auto"===e&&t,o=n&&!i;return{sourceExists:n,fromSourceEnabled:n&&i,manualEnabled:n,radiusEnabled:n,passive:o,effectiveMode:o&&"auto"===s?"fixed":s}}(e.lightRole,w,k,e.glowMode),$=!x.sourceExists,S=!x.fromSourceEnabled,M=x.passive,C=x.effectiveMode,D="never"===e.lightRole?this._t("marker.glow_disabled_never"):"auto"!==e.lightRole||w?M?this._t("marker.glow_passive_hint"):this._t("marker.glow_disabled_no_entity"):this._t("marker.glow_disabled_auto"),P=o?eo(o):[],T=o&&to(o)||"",I=!!e.lightEntity&&!P.includes(e.lightEntity),R=o?Op(o):[],A=!!e.toggleEntity&&!R.includes(e.toggleEntity),z="toggle"===a?this._toggleIntentForDialog({...e,toggleEntity:"",toggleEntityTouched:!0}):null,F=z?[...z.targets,...z.skippedTargets].map(e=>e.entityId||("ref"in e?e.ref:"")).filter(Boolean).join(", "):"",N=(()=>{if(t)return null;const s=i.find(t=>t.value===e.binding);if(s)return s.label;const[n,o]=e.binding.split(":");return"device"===n?this._fullRegistryHass.devices[o]?.name_by_user||this._fullRegistryHass.devices[o]?.name||o:this._fullRegistryHass.entities[o]?.name||this.hass.states[o]?.attributes?.friendly_name||o})();return q`
@@ -7323,10 +7323,10 @@ globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="30d20d6f6822065e2d5226b18abbb05d8d26 -

${this._t(dv[e.display])}

+

${this._t(gv[e.display])}

${"static_icon"===e.display&&this._bindingHasAlarm(e.binding)?q`
${this._t("marker.static_alarm_warning")} @@ -7475,7 +7475,7 @@ globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="30d20d6f6822065e2d5226b18abbb05d8d26 ${"file"===e.source?q`
@@ -7495,23 +7495,23 @@ globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="30d20d6f6822065e2d5226b18abbb05d8d26 ${e.pickSaved?this._renderServerPlans(e):G}`:G}
{const i=t.target.value,s=mv(i),n=null==s?null:(o=s,this._imperial?o*wh:o);var o;this._spaceDialog={...e,cellCmInput:i,cellCmTouched:!0,cellCm:null!=n&&n>0?Math.max(.1,Math.min(uv,n)):e.cellCm}}} /> + min=${Th(.1,this._imperial)} + max=${Th(vv,this._imperial)} + step="0.1" .value=${e.cellCmInput??Th(e.cellCm,this._imperial)} + @input=${t=>{const i=t.target.value,s=yv(i),n=null==s?null:(o=s,this._imperial?o*Mh:o);var o;this._spaceDialog={...e,cellCmInput:i,cellCmTouched:!0,cellCm:null!=n&&n>0?Math.max(.1,Math.min(vv,n)):e.cellCm}}} /> ${this._t(this._imperial?"space.scale_unit_imperial":"space.scale_unit")}
@@ -7526,7 +7526,7 @@ globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="30d20d6f6822065e2d5226b18abbb05d8d26
${this._t("space.zero_wall_help")}

R4=7=5BtlaNuuT0 zk>N|q{6gr}*M+>oz={O3P{De6S^C=dOgn)gv(I+}EF$YUbdSoXEmZvSOu%mrQ? zE%U{gzB^D4rp1Y)PB02pKpkMs52(~e!-OKg=Y3jaPUX_jbYpGK;PxO}5|{Z8x|!Cq!_lK|^XA^2!hucJLAAAHU^^=XM^;g#@hh~WOVMDtw0|6%PrDV<0mOpi zoHRC?>4~sG#4|W8Y-VLitaJU3_x{>jMWbUKaF7rzbyebl%m%Sqcp)I%*G2G$E!x@y zzNFLqhxsbe4jWWHJe@=$*8-632G=fQ+PopiwGr?F6r_h76~p`_$e8z ztnT+`tB;e1La|1i6rKmt8z&ngg8RcJ^5dGiXpTxwPBb(cF>Jg*v4dHI^Qx=u+m-=c zo^1XxNGUwva_E{dI{>)cc+<~Ht$uU6d)uNe4-XF>`rMCEJnRID$F%f*c!_d9m3hym zW7;nA`|R=I>5t41`y_Xnk0&YpZdc$)k+;SUW?B^ej_T2zeZCP&`z4AIt*G zYar03O7`cD^f0@zhO-`R(oST>ZRNV+SH|crdN`gB*#Uu;|LdmE5|X5w5~9TX%`=a*%9Lv1A`5TqKavxn65J(~mF_u_gJZ!a zg*AaW_t)+*5?ta(u*tt(S1M)8g!B@odlm=iB-u!iF3G@L>&-|NIr}a}F)SYIQT@;J z1$3{_K4u){0qT1B%FXc*2KBs4>}WK18}n@STWFF!nxo_4?6XU42ZbCdzFRZnH6cSV_rC%NL+h*m zPS1s#^DUBXx(EvG>IsNoc%z?NDyW!v?6VefOJ8HK>X__1S)72dk2s0XH~jTf$OgSE`GZap>=EJajQhg zeS@*mz}U;zbp1;ti>9GT#fZjCYxBhMhp)u@yp%sXHL>Jp{UZ)0`gLrLW!9;BmdIU zLN7y`kn)%R%Ibw10s=g*9D(ahEYYT7%PHpDvup#><4lw6zsQi8hf56XFN;4r(=bqr zF-6$W`7*&r#^d_6kC*vnAjM<)Zwq1C1c1aET`NWPprwv=EQX(xR!8ytwlC1p|T$fK79khFrAll-R+%yCY>! zWlB8pDr9hVEDE~Wt}t3SCYt9xk+oP@U6JEehF?v(2mRiV5FNr{ULc|X&0@6mfJ`a` zx-9k4$OV2K8(aGl@t#U-3$Frt(VQ0;a=p)E!@Y3KXSB+7g z!6pA7M&g73x?tY-K6E_`r=q@8UwYCe2L`TaOp-yv4mgEsr;pw zq3AF}sOoO%?s~}VEF1|Ym=0r5mkUL*Gk<_fv=PH}vGe=3f01Vw6@xLVf-+V0&DEsy zR^-ECn0QzofIw`()gH1xS1V3ue1O!8Jw7_vgAC9{D~}QH=I>Q>RKDQEl?W=0(lSV- z&qT)J$JiK9*w|ow8OS#6ik!(K@Cnt$?UWE{8V^sRMbmhf(|J=uT3clPY?JTszghw6 z_}hxDAfZu-XUz>}cNTEmv(E#sZ z^S?1EBliKj0KMOYFqodB4_-otye<+pBEi4QN55-Ar2IHs8|LZ{5AcA>*5eI@pDKlj zDba6hZ6aOP-7XksH742TzRbt9p7_*dhYW&4;Mo@w>^p38__zdeX0aAlgA6O)mI;(BVEh4wRB$(=IUc=cX8@44|Vm0&E3Q5NL#lkYIC97_$=?mBsp1XAVz3a*Y};Vfg! z=H5!-2PY&^U|Rx5RN|!R-_tZ7$&=_)X93(ho(%t9>^9k(3nM=drw-DQzxOvX=86RD z3#Wg6e^dTFt;I_wL~ciFI#_I=nXqaaHDAWDWcO*9DJ@@W;P#d-JE8IG>2+)~yzGyF zYqTfrugQDkVUA9!?_zV0fU*{Y!?85o>_0Bt;4g`o&@%fdS#SBWBz?_Q0!^3v`|(p9 zDEz(DnximUA{aZ+73G9r@L}jiBkhUM;C-!YFPSj*%TqG*5%?wO3HAXQF<4l3Bq#hY_|b&7p!UW>UX})oD7)EN=V#!6);x{x^sc(NE;#AHY)+7Iw-!=%hV@T675L zks<0)2EU}S1jx#FUgXGg-17VMV6vIstqY{Q@Gh7Luw6rhzUap*BDBHjvTa&YY5Hx~ zq8lb!Hu6A=^*1(}UwF^3m)7@LX9MD95o~CCdcL(I*nWnhIR%~-+H#Gc3VxYOA=w2M zDJ1I(%Z(AxX>4Z83TC9K=}nYoDRcvxrCPUPYbJ*PW7lmosRXQ0eB-aA!#`nlLUvA?9?IP_?r>o3<_;@hba6#gSvC@d3J2OELy z0BcUGqzEjlmudxs>Szj0b_1D5MEce2fPaS;Tx;=u(@%=K(b0<1@{gkc?==6*=^+al zw=ILTM{1IS7dH`>f2Ym%8j|@JO!Gf{nn<6alQB4#7Mx2i4gES;^_{ccgQ09U1PN() zsWO_0t&3IVJwvbNw(g0|ckA9f)BQopJRs>Mr-W4QvLPpglgZT)A6EHA9E2$|urF94 zM6XAbeGt}jAj2Ma_$l)x(basyW>PaI1cyMYO`HI^^Mkynd+!7*l>jjf@7kG69(GfX5gKxXS@x`b@y&{k%H+?A{8WQq>^y&w! zCu`;M!6Y}M+}_FhI(hld-xuSYAmo~Mrp`9v?Qr+tWL8GsV0-tX<^o7 zuC^~iF=26^WtGhe=PwI{!}05Yzy|-q!6Ad`p{}>0W%b*-Y59dYUYLu&rN$_?0wTz{ zJB27+9}$WAG923*iZgX97WAuDgWzv|k@GTu@6jA0y{D8wck6ik(;lm(^~~#fu}kH_ z8kKAx_&D=3ywZ>icXyipK}t1YL4JuEhEM*4@07Tt8cEv7jus{HeyK(P$JuDZfn%I! zr`odI&$32J40S|VjzHaErFdbX5~TrL_Hh+snfGCQXt?~e!BYfjPfuNT_r%T#4;(x< zG1~e$Lm{KFvFB6rab>9%EUBsLg@8X*5&ORpOOrC-) zi{=lDIMtyQmN5E{iFFIcW8c5+^EGp~wQ&21@xQMiVCewej0dhcV+WOb zfRDe6_c?ydqlnJK_Q|9F_Fm4vhwjixH*vpSlui!1@1NB3HA~h;jfPa1W~mQf?NR>3 z5KXx!MrT_qWTUc#7qqq3qust+@q??*^M1sL*$v4IPZ7iMMa8uJyhuJA-x(KAaLL)r z>f5{zhOUrzoOr`vxj{cnxU3Opsz1|w0p`_*ip#O%zP9XsmHV9QJFh&b{6&fEdLzf1 zRs3-^6p-?x`vdzfrc;=yj+o(})J~Gk-Xl|sid|#TN7y-}J^fqU{jLAH zxc{$7D+GxwAJ{h;jmwfug4K^Yb^hr4K}1#O%w818H6^??tI*>cwK$;#EdClH;Q2Wt z>?gCvG?iHtxabt$>T>V)(|I#E;fE*5n%<9am#=sR3|Pr2K1DS&(-g^=!~6#5b*I(i za`9gyqIRtLYK?;voE*l!5a6dDts!S95!}XM5ujL@f}HykF^VdQ<{CB#coeKC5L1x&{*V$HNYx+2c^&U6o(Bh2M(;*~rkhS0$TdV+34R z>9OD4ki=pNcObj?)ipnAa-`#ab$kxi#QGlMiI-Uvtb9h^LOMscdf1x)&#hp_XxV#) z@BOE_EnAR{Pc|A@?9{?1&zPQ()_h#xxI4G**?Qwxw{*50tA7y=uLKCD$dI>VPjD}& zg?dl2w%t-ppB5?IWBLBTtSdxhSS6;i2$&EFfay|w>%|=T)$wrRb&!6lBqWdAdR9~3 zapu2TC+MUt4a5i%LNksXD-Xe1X6%@8O&iM8Wg_B=^8L6hBDZ&$*zX}j() zS-9urZpsS3NBu^*RtA8N9DNZS#b)qm)7f()PN(yT(1`ERj`!B}eZ2W{KAVwl0O=vt zD>h0qrc|r!YA&~>z^5}f|Mk1qfZN9h$r_>I;$V5EGJhEc*lHyBS%}e_T#Pw(>v^xogG__Rk0Y6x;{Hu5;B~q4AAmS~KX?&z(^}>J<*2|6 z1HOzaptU|X$nAc+Uem&M4e#cO&I697C~Q)lKSE1&fQ~YQ_={caOb>H*G%k)DTK9{- zx5Je%8p44$^YzViE_>NhSIBpT+}YCoV_hi$=Cc35kswffV}mVkZ!~O)B*lbG49=Se z*uOLSj09_t2b^B4m@{IS73F2YR*LAp=h%6QS`S-Ww$v}v5ut9d_uta9U`1!VTTpHC z|Cc}Zul6gp0l9r*w(~NN6-bR@S#UoqQY)D1mTvT~EFuiet^nbb2H6`6EdZx@U|bZw5l-?*^daUl)Zw!=P^vrrFt7-ylhZMAEX%jGv}& zA3sbQ11=g|Y?kY`r*HpcBv_rzY8kzeSWJxCoZm7XLo3dR$vIb@#~o2Vg&f5E%A?4z zE+mi85;1+zwNc0_eA26HTc~l$!>f~1&%+>LK%PE4Dx7V$& zj`GdJ-jBQBr*d++1h2-Kg)s45;=q)Zlk5V10J1Uz`M!lTzp}tSMtTsE9M*63;F|WX z3L*?MdM*s~Et@Rl#z0Adip#a}QC1K99Zg7W+(tdGDVyuxh-9M{`-3DWbWbc zVw{}7hV`q?bol}))aO8iB@ye7y$(avAr%q0FnWw#yM>ZyCpY{SMO(9_M735~2g1Jx zh?xb$?)?Tr#p&O5((NtdLe2GVR7YdzEOOUS`Zhj{e_mNnHgW}z{)1|npaIqRY2vXU zqv1w_t9M?S55(4l{IYK>lj%nK-r8Yaf|s7g9!ki&7Oo>WgTt5*g;52WkPGgS2rGB| zdL_n@PNVK+%K5|Q+ZDWTr?KZJ`IuH<^VgbuY7A%Z?QeBGY+jpJHMG%lm^xM%XXSzz zT6hP)GBH@j4_DWc8?vwW64+<8M)o1`ay8Dbxk;I@TLNUcVo;F=n^JPC*)GQv8 z90oS}voR-qW`W;fTF<=TyoW)*Nm0QxASEP#AHiQe&9XV7v?QZy5fU!-LK!fv=nI!1 zo6>q8Ue4a%&Fh-3L;x-Ik-@{#_p_2el`-RFV)W~+A@52|v?6Ngy8X7~Wtsgh+SSdL zPb>M)TtkD@Kk&FmmOdQxy{st)d+gy!KJTMK)jf35EsR&}#=$%R+xCqTGkRpTMg)@k zsBwR-AbIvf!S7KL7K*C6EmXh;EGhq|6LdY+6O0sxq`PIU9ra5suka?0#umd_E*R=e zJQD1!14=ZNajGwcPt?&dT5fJkn*iV&zEaJLTAn_HoqFGnA07N zoFpVY(kJ-p(laWX(NZ`S2a;~ZC@;!H@ue2m=hBycEkH3zyy~iZe(*oFh~|VBDUE%x zMvxWb=@0IOb(@!Ri?pGUsx-gf5=Uhn;YdkHn5Dmcay#MN-{Vfp4a!&0$J5<~kG_D9 z4{BbJ`<9Y%CI)z`mxR*(>B^*Y7TukHA0{Gu-yB3cXhtsE-P2>Wz0DF->8c@-JTi&H zaRz<&$n7CgCp4}S6Z)|}djp^>c@-x&krnl9lUmu6 zj2vcaxy1@pQn0&=*HT-3La{s1ou|RqeU&2}qAh5GvLHrZt<5I{*-QLqWvw6lpt~iEo>;hN?m09ZHvhEWc=$+&X z!~0q>iUlUk`?{0*xHX~Qf8jIB_uGMxnGTJwA(Jf8vnc=A=DLx z1m6|6Xave2SZwuQPlSstJ4UA}wI2U0KZ)c2ANk-4Z_t1&mQn%<9B$ft*$&`}%gG%OjkR|B=&%Ux z7y)k=0G?d7FWR`AvtWru~H_(@f2SDM=Hm(Bd{1)+1=ix8fLjA z=b&yg$we|XG4$OTxC*tTC9az?8B3k}(R69;A7SZ@%no+Q-u)HgU}v||iv_>tOWVKy z=>+{}(w9slqi6yHK0&D+6jeNzlp^0z&O}GAQM*6qZfmYzL$bh?k|l7_hhq7GMp-S6 z&ga13%)7-I^kw$7|3B%pQ{tBFKMi4qU8RYwmDe&+J_LhYBSwo`kq zEY68hv}y%h{Zpd!ePy(%r|d&SQ{pBkV@@IUIH(SJxcJa4rZR-Lrx%tHt~w=KY~ldgO0<8^>_v9$625~#xf@;HVdsZ4 zwv3+^^rGXrg?3QkDM9Us3v~=_9rX4&P=(BGd1c20jP;vD|Y&av9MfZ-k?(T_n%~P~w`yXdkdXTVdnd zymVZMy2f#gUL)d-?E#KWJX4#gR9?duNl0~Vr4%}QcwWgUp2oZlPY!u!!$BbPoJf)1)p{fb!=BZWPI?C2BBCB1;CiMYn<5(jNs~4hNcmB zbIH&FW5+78yV_!tddjk#rQSk$1g=83}0_LWUk?J`jmX+FT_j?1*meq9o8F?>;6f7OX-YiL> zC1>X@>~*8^05!FL$n)f(h25i)oxK$!(6q;;+U2Z7^xr-cyWk8Ji_!W0-;9wllTh_6 zoCdi>C`BDW*P*t6<3em@#zu-^*DDXMbumLfQYpi|y>MPXe^WP3=>b7_5FF}xGt|Qj zzQ(Dk4c|hp133KqT|DLVh_eN(H$^x53Nl;nE%=szh-2g?isSd>w0E^QqqCCy1~y#g zr*BSv#9GCmi|K=Za5HeZuE{C7uRH5ytw4|<)haohp=U@NDwM>QvWUdRbAVMcapV+F zVe&_>!?nzIAus1Uz2(2#d?&Z(0-0J=(&j+Zc$gY^11#icWFKK>)RB=^}7xebiwYPK^j~Xu$R{cZ5Hir~r_1 zRqNWfz`(Zi&qzB23mt=8QJp^gWZdlyD5+_V!Uy$t(P>#<45W}|v%rnB@zC0k)Q|1r z@XHunv%*87@Qi~80^O2Gy~c$GYRNd7>4y1xY$~tk5+L6&%5u}b_N5LpAEgd z-yYzW)1zUtt5zwYoUB)XEB)FDa5#uAxWfrnVH8#$dt%A?PAC0G-N8zZi}hu{9oVPk z{JZ(s((NHa_B=WBz~~^3*>=;^27sxF5Z;9&Lctkis>GVW`TZ+N%a;Yu?^p_^Z6C>) z*Qm_Ygxg#k=fQ_p=4D&ZM7;?K)2}y?1&ZUeu7A`L$LrM@aFH8~f!8yk{4%x73wc#W z5sGZ)lU`=?5`j9hMcDLs*=NKvqJfvzB@hg=kBJkMXMUb?VVYLj0U@vHK}?I!Bda;Z zts)2~o|=}6m7J=*Rmd?79*{EoxCAnWj+uSh(BG0Y#T-qlZ;T zvP|y%S&ZCCmX?1H6gRW)gzx^-7^z-(7F58|oIvKd;8eNonGUqs7o3J}eQ*BxpS{)( zJHOoAe69w449X?Tzdk)d_CKH*y@X%6&CdvfACw0o3pSq9D3qJVN_2=8&+3Zs)pKf= zvjrTGF)?eJ(v%VM^~dtEq%C}YbxC3_#e{A?xm)6xygFMfgZiVhaD;x#KkT#dMm8G? z;p@Apoiqb(w7&>4Jd;GS!m@pCQv$)}UHdMW=1)thNN;J(w%h(ly3u5o|0RJJ5Un1` z^B&K#SfF-$T>kxuw@=NpFuQRk@A&Vfn3w+6T*X`8)%Q7Xc;3)%iN`5m zTP9nK;rTBK@oRd7^h9>oMTr4kOTE$-5?li87rPsGZ{=gHe7q8n%w`N+r@AUPz;TU8 zso10D)BA!<0dD6@x-)QR39hK}pseNgC-X+i(Wn2T6K&=ND4h@jnNQ~@@m}3Bz9v)U zMsl!w!*Q6-5mnAo}lSv5%o1ka(jtnqV5Nfow@(gyvpr+;z zt9lF9K`A{vYFzDerK!V5ppgaT)c@+h&kX?V^vQHQC@T7Vd@a3in)kyx_(vnpu0@)Z z=kE%UXRcJKgX|V<_G7W#IwR%wh~!6Yt|aZ*A}~W{R1&TRBdNvo1i&|1(7>&Kz%7o(FZ&m9Q!dw=G48061#3A`Ze}F9tM+);RmW~C`I{A6G}gqU1b07PRhk>Dq|w?H>~Dh7qhHdQ(1-i0n{gI z-17LLZ#(;=lKQ>uN&I2S`U5a^seNd35-ky1Wh7Zaf9S7Qp=4Y_?!N72LrhtNS9pquVI!SI@C9Q*iA^ECX&*y?+tp zm7tS&3l^~|!9SD-2NE+&1vc3r8MWvERokvqGhMUj>Z>x~mAUJ87lF?)XnTbI#@4neGR3(3LVQ02h&1Lg8F zh(fTXu5T@T+ecXap91H@pzMwm&W}OLS*=pQ`4?(yVU!rs`To&%?0Xb0PzL|n{gc(Y zHy+EPP^`-$sr+-t`Tx8#M_+nuQCavB-db*^nU@b*KjmYn6}=s!V^ewuqkUa&_TxQy zc4cDeG)k=9MkQ1pD?Bc>Z0pjUrD#cQ0R&PU7r`Tg==U|)j?pMq#NYFi{9?TifQsx# z+zIEEq_IPc6L95xGASC#wb4J-?pLz*vKrTa#R6(Y2)Hh(*Q*Ij4XIkl2gjUK(uACd zq75Z?;veGZsq*mC4J)`Y_CM^s?VoQFr=JR)1m{13-;13(&`asvY~ZR`1?QGS!&-b~ zf|pkBV4!s2O6@Y3#(3pdVt_ zi?BQ}lu|0X52YyQv6(e!8$#CzuFixG#!O*`5ZGWdxWvA(QHI=klA5T2JZ-&;*FC%# zwx|ssy8t{R7h9~YK0Ur-YK%~`nn;sqouk9#Zy~>Y7=wy+d^{PMI!BM>41fDBiil+$ z_R}dZJOhbEelXfGA(Kh6b)8dj@=AvUBbkW^LMg>Kk`k?=N=d1g!EO2sN`Kqo{ z+-Nw!;#ZZEaQbVD5j;eGGcNnrLT;yX>*VX!M2ydg`P-_p*xOun$2M^DkLh|2Fz}d~ zdbVS{1+Kn5^u~H>?Y7UwkeQBv?Uw>v{$fUawqUvN$_=aRXs z?(@4T^^z}b=`e0mU3E-FLssDRyU2KMf`SiL;g~tx-Q!2SGKc1)3c_QDzlbQ8Rfj*R z1L0SDOjGjXqRD-#5e`d@@eRPujXYG46_1R{^eeK2=nd@aG+9kJf^JbqKlCFTSEv6( z#kmukz9FQ0q7$}T!A$z?@t7n#HsiEX5wy!D%+`NxU4-p6=NJ3-A8vZQ5lnBfiA_K@^L`{Fs z(8J+6k@@ar93JbJHn0)YjDTow5x~p;0Tp-x@y(j|Ztn2VcB6+rif{fo9iHN)8VfAU z)%c!YDilYx%o9xz{S($xlFn@!weu~?Io{-l7cQp1#o=Ka+T2{iUHWpHyH!8I zRrPjWTXSqnY8E8!0>OIE@V7Cq{q|p0_T-+7jRLVpTYD>>vOi}s@?MR}=G~I$B3&9y z{$ASEGXxl$+ZQpLKl4rZyo)h(I#Y~8c2c8oc^P+;lA3xhjcEN-BDe-)LhoDE{#sKN7f0TJ$eFO_bQyK-_|HC7fOtdxR$h zQ{11P6uL@U?EgJ{G?-weai(hV&%R!i?A@1zBJDL zCa3?+H$DV{H-n~M;Hsqi_JIz^Ec*rDXCtLq|7XlV34T@vzt;KJ-b~1SX*(}@+F4io z5BqlnGMSD}hW3liuO7EYY&Y-092dCJ`1X2o6`}rLB!ERavRt{r1^oLr1-vSHV%oG* zv%>rsaOC$Lf-P6X-9xZ5XRQ_JZY6&H^ZPm&Ej-NMt5&GzlxR-*`qQ_w=i228kI^dd zoY6P_62u(UJO_xl-+^WOw~~?}J`9bD#2q(E{7J-qe~l5-ohF9r+OM~jo=!JT3A^9d z`%PRYJ(uCX9I=WAo)H4#pgtjDv?fTIE%-QwC5GQ`d0gHpj2v>us_VUbw?ew&O&FDJ zOcV7~fkG>0%#VDxS!aB9#%%RFix5`<+uL?UFd>*#S<~z%*d0cQ5Wf81Jz*w9=9glt z@HtAv8DDAx&O9Z>Unmj(5F6T;rb5--0=J*Zr42p)XsiG?+ih!Jem$RdmO=Mcgb@^= zLI?v$qwc{tTJ&on4|H|B!_1w`ataThDduuNFr5~(v|4Uj0tfF&33mst7uDfK1PSJa zWf&wI#aJGonAz|D`b;e*CPsAJj1ZE_+SMh(IT<4G4XiSc<`oJ@?ZA;yfMiav*I~XV@bSwy>orzpAWX9oT2G3;WrCIlm$HHQP@eg^n1?B> zAc$Auq9qy*_R>Wnowd6vYnKwWk1KJzzZ%W+MHa3xrd5{zVeN(f*&vYkf&WSgRZigY z;bc9j?V&`80>nDt=E9vXNp~e%S1cC-os!&BYx13r?{_o9X;{`%uvYL}aKVIB zC^qYhEt*zwEdz{98n>6e`Ji;S$0znKGlL)TWg_h-mFq~B2q(<~x_i2*{j+H1o@B%q zWT%H;-v2Qh^sP_r?paI4d_d1!>KY>o|J#I2VCg@1ULz7JTqlerEF|n0CrDY6H|Zt? z)ClB^HS#i*{!EaaV4O6vYcgAp{#wn)v(xb4>dG>~v0EMy>)sFp^Ln0$C>7zgeBa)X_RC6e}9d8O5EvKL1L86re8r}C>XpRA{Zf*W6bb8R$B*UXWKWx=K{fT|K6 z>7UoInJGI+0(ZD$AXqB`;O3ZnabDP8wa_3MA9gDiz!z{ee^w*k@A^j8TgXmvp4Uhh z{J>Th5-Pl@h3+lm=lLPJgNRVjGi%;~rP*nh=USIwCyhtK*=&SGZd%7EUTMhKU*fY zVmK0>=IgV|?=mePKVEX1z4%vTPnEX|845{u8~D6G!E#mfwf^#D^COpvT zPE4^d#X4DoJcjsi%cAq~r!3MlX7p6!-rz`?Rmt4=72G$@#ZT)z|o+M!HoWgA*r&{t6AIP=OFL+7^$3l`L6!$3!?zO{Wy^+l#Z;=;_dYUQNDvU0w(?l7O&9riLy1{ zkvSj@=@uuT2cxB1yJbyF|3ewg&_RKf#{Ulj0C)a}ql7CV?2R@0wzV{us~A0y zJNAX;m($q61&Aiuy;-3gvUcmi18sx?+~pWBgsS^gZb9mzu02-c#ss5F>cM{CLizYbh* zm8GK;Nl<5^G;Y{?HYOMKqC+pFke9&yYb3~tMqRVVNlt8WLGQUcBv>5j#ud(b^TPPn zL2`E9g^UPu+I?zA8^C>+)fk(c`%8&LU=A;m-cIasPz!diMK2UOim|IF{oy%h_h-j& zz7a?9BX`Rh*@V(LRf|e>*SSATjO}`5{AR1iPifg8b~IDO6_~ zAq0*pHrc^!kBKxYoDcTBU&l(6?i`;h25NjADJS}lpSzLO?CvKcuLb?(NxsgEW1&6R z!TZ6;a!`;h7xl|-(pWGC;9RdsL#%yWm6)A`T^EcC2>};k(Zsd_9I72-Y&Jz(7S;vk z`>jhsT&BZzEowjrn>jr}!-5OQeGR(droropQ5qQp>5^K8t#(;+zQ@5d9lndR7Y-pF z5KX%iTKrtG|3}n0a90{^-MW)>C+XNm$F^-79ox3GJGMKvZQHhO+t%HE&UeQB0U0Bs z-r7~Q)|zuZr8I)Iw~VL8ytKwvjVM+7CE5Yt0TwM$VdnIB@*05ZicMx>_>!{-;I`v@ zZ1kA515%EGsK22V74@LTA_3h0WelWRGqE>&AS^H|VWOUP+ZT8r@z=>f={lg@6tfCH zC_-Nx--D)HbSF*@=Cp1;UC;+W6|M2}ltc77^UoXycqu-|)zOOy1ssyVPMb-Fol%V-4a-UCUPqA5qXHRh=iK;$_Kt?!Jwmu#JyV8B8QdZrjhS#yg z(^mi5&sFe33-=se(0h0okpH^f;wpc@`yww~pc{{xwk?}uzkqK2nA8JfZ08<0bZv*9 z6ky^g-Dap+@xF_IgQYKQUMvX1-7jGDlNg}>=Du(uEyst23oaToi!1*Ykjn5Yr$!{Yo|CIhdxz!h(kqv~LkAT#`{jXQ> z&J|_{+`-%3N^if_e>0hZdwoK=&RKpVy==4^`a$GO4jKwXrRX2?@0l9y1Je0)KDu)p zQQX;?pP+C)C@ljnxXC&?B?mxYT+>}`Zd#H!?`?o1*kqo$t^t3czUvPXMzH8R_zmgn zJtiNX99w}Oz!LIz_Vm15fX7bI&AOwPdc^Tna2desdT%<(^wexLyAs;IEMaGtgu8>U zvMj@66}CuBF&F#u)(O)OKtdlP3r&xOJ5F=Hy`pGM?L z(YETvhRFhsqX*Ai#||Al2btBPx+p~^3X*y9IRlod@&}=;fxZ+J1!kBcQ9=LKVe}$k z6u~M!mIsAqVE=Mthv1-)%D%))BWY0~G;rvFy|`pF*#iuLGw%m%p+Limdj4g^uPyLw zTPt~Si#%d=p3bg}pKw_%CLEV1Xqe4@6uLysEfD&vfbMQW_uDtImn^@0(ygMSE{u*Xl9- zCX6^wypsr)d?_hF=md&jK7iBGAUGo0{Fl`nNo2b*2R(|;k(bD_x)Af{(KJ7?bE87U>OS#*BzaGVfGTGw<;Qm~eND-j42+}V(ZmgFI2 zx`%)%5G_-rQ9KSWjI0tcQ25Uwu<9upwk?P4k&m>|`UF1OhiV)&U*3K>%DLcHm`2yhX4 zc-bR13AmZ9h5^mfhIV736+Y@vr+qxv`|&_ck3&bQ4s8`Lc>l0#YXA!Wdu#H)5%jrLCbR+}%y)fA-Bde`{K}l#DG|##7G>3c67EiIRv-D}|mIb#2np16N z?Cre;sGf4c_F$1Zc*mqzyGLUt0Ck=Iu#WFSWU$6WIzd5WUh5+MJAa22fhj;O<3ktB zwZ}QfyYS&ru;6_;F{bL+H-91}zAjU%L!~}Sg-T$-sI7#rJ+ml&Cl!biiI*4`=?Mj% zL5$c51=TCwy2Uq2GY1&Ago^$eu0za@z2grq-&p>Ii3p7D-uo@4`|-o)8qnm57+uh# z=th+_^T+=5pR_YV*E!=`hcKF{`l7DqWfCJA1u;&7a^vP8Jo@ETyKtvi@BOYRFioCW z6YA)*XHyAaXYTN$Fy(6(SGBZIagYHi*r0&lutH?_LTe7#>mEE&bNDrJUBV;mDr?Hv zgWP0y;ofFr%$^0+U`mY#Fbw~GFtk1RoOnY;yTQWE{TCj1n-!7DeH}&P>98?6oi8&0 zGxpu+T`qpBW_DPYF(fNERU4bQJkAU~;qqu4>-)e*|Nb$$?7XDoy_o107bP^q^Vt8H zrt1v$e~}9Rk%1L+kQ28|U>Q;{Z(-{3UePtY8L<1q77;IkIs*%M=6u+ zwWa_#{SaB|;B_sdakeuzxUm}wPIhZMW}O0@@U^50PU@dLQfY~3aOq7>!>C$;VV5(* z*VmgLax(0ZqQLl1PzUrStp;mLmjvy!+`AOcXeM+@r6r{qU<3s)N8;bGPFdhpz47uP zk1C-!N7{mDig>BGlc!?OA-emgqn}eo3Sd2(7co9={g&E@A*mhM6g+!A3{(lHX1LGO z?crL^1Xm}(y2Qb~B5hNJDcct!c+I!1jk{(R*T)iZaJmcsOo?=Rr>m|isE3hf#t^YY zsP)+XKXSUT=BmyQW|D<_W-Q*?!ff~xp-{zcQ=9~dqnS@D&{(z3Ym~F*d z1BQfOB)hdVF327hw}tMP#<9M(z}(-erO4dL8I=_T^hEDoX}_@p9E({r`EVhVW(g4&%M0vf?fE9G2X_8CmgFqrphz z=0f=huLkWuoKOjF!!Sl!W-OQ!3eN)UCWvPBw15P<)F6NzQ_@n0Tc~VBakUNFqE!3e zqDH|VBBtxXPYbKqywEGygv1rA1Kq`@B?Hs+Sf+jK&Yg^~!40kwOSah{9f+jN+qM}G zv_RwivsO4ZTm&O_c45HOw>JT;mM#XYJL_qMUxE5g(N(O;CJ%{se%T7XM(vqac` z<{b2X!3Ga)0<{k-a7=&UBoZ zsvZJVB#YNAme)j#`avCO&U&>co>D#I91%xKYXb5uqwzpGazxpf$;@%2%=m+?*k-mB zB5P3*oT&`+w}G<3otpfRYhA|n{SnwD1SQdp2Filmc#{J{%7P5gXb2DkPx6kjwh?x9 z#pKx_dvzY9-R}wF&GF$me{8_WLhSQ>!R&wI!m)Gi;zzPi;lNxOyXLNz z81&ALgq4p4JByCRZ9-@kfQF^-4ooUY2b95uditkH2EJqonQG!ng`nj3C{gM4oB37sv;!lhwVHCwU4bxj z9}C|JY9~fh1F{I&DKRn)D-VMCE-GAnW}&3Q88~2|h95W}okd0W zu^`~T$3?k-{G6jx{oAz5qlXY?5kaJDl8(b^Tz)Ci3VWi)yy7~M39+%0>_gD*s}t!n zYaze03%5_JY`sBpOYUiYp*zioqEjh>ky&AEKrzGLEmRiQuz^Eqnacs4KwB4woo*o`k} z5G_4~fz=5FXNYaWO?r>mE~8ew-LSO*!NM>oME;Y@P#6o03ktFR7McKFqbwfDY=(+O z%)t?%>!?7`q+*r>l7cNu&76GmCXxZf6zsJKRBVmX!p6}V|2!}UOe>>IT8l+pRx3LR z`GdXU^$sY%IxRW4*hqw!QWorjut-8Xh6FWA<5bkYXU76=s8YGC=<%+ zLWk=x%%H0wwaoO9D+RGWg;5OpkIOMC)kY-$I|&2Y9}$dGN8dGQf3>1xW;}J(d{|U!+OA%NCUceb&Yu09T!sk1<5w;VMg@ef;jMmLH(F~(;bfK9 zJg3dlVYNrRG{4Fx7qAKAgCB5DQzb`-Cy;G>g#@$?XJOM~X#~EYpnPJCGOnCU@F!4S z2Ic#N0Mih+q~9aYS;6@jsDJs!i_-2pV6eT$F{S^icmSWM7ZI^-j+~TXwu0L;3EIsu z6Y&S^%PPc6i{OYmIAtH-XBkscq6BRdnONGwi2RxYy%=RsBQgY2<~~8?D}+Vix5aazgdDLPyY2XMo9tJIcA9_d zW!^&G^mY{lbK?9ocs|eHR&t`&B1|=amLH@UJ zpck`gDOK~{Qc6rrZEFYLr7JJS_P%0;JAXzdl}Gl<)S(pQ!|ax}y0%adXeqf8ClpFO zl0#sOU$j2=egg5FLJ=ye$Bc5b%*jOpiRptm=sMKJ$CI0#4I2QP@U&l49sRy)(`KmD zb@DMmUe`d3F*;|3O3?`0G1^)faLXtONv z2jH_L=R_pIWA~5J%x~~@7z?;KR0#2PnX*4Yi2s{}8{u=$2%}u6N5lhZO}ex9P)Y1B z(QBn6?Er@Jp}p4KoXh~xBGFF zlakp@T0P@mWJ)II)Hs(FuZ&6zrl^C}J5Q|+!b2#g9G9ZHs}j=?+^Mc>LW+PS;Erkd zJ}H&XDutfg+c3qgK2dnw{4qGl7_XZ_kp7PAvRcQa6zSWu6YHEph#37#ffTPKTu|O; zSHFpWyf1)@1z?~a!)Q&zt85F$n(7aI$MoysS0rR8m)E*Yg^v!@fT^~_3w3?mH z@UtugC#g}K5=N;~q>fG@I*ChWR$oyvJ=>BYtznJKRzswgP&nYld z{yBha3|j#StLzl>sgaz8jkiYLLDQ1Uz{kbJ$G4W6MS{i*9>j0J0v`M}Lhtf1SxJ?f zz-m)Xi4^MdG6>$APsfn}n2O&QL=r*ucYF3t3#g zrA5+B&Pd7RM1AnUY9t}SPvc}^XJjQl5;`>~Mpzb+NPcdg zVwW>v%KkJEx!~Lsw5+plzQqb-$2>4SG9%RrQY#Gs1X<=n8Qt6#7L|^>QN-w2R)sXQ zktvP6#NY7+>P)g3)(Bn{3FpCC$h*YX!+{z^pj^=Bm-C5?m!Sg3&xZuuA^3F7#yab_XWsCklUFt4!to=FM`PAg5BxK`Rr2sObnIjOdYeK&yG{KvR;TLONW5Dg2C$E?o%@17W;tX&Z z;5e0mN7&jrMN+{DgKiBi$>dMH7KK$fahQ$1Pve|LnL=s3v0PM&&@WC=P=98Y42s>F<5aNg~!Fq#kExt2^nlJFWj(h zB>^=UgMvN7m{3)MW zatnU+@CQpUf(_K*1>mmc@V_L#9;6ABvw9<<2CX#vT1c4z17t8sgR~8HnIayUq21)s z?E*@aGQG0>kVdmGX7$07q|uus7pZ|1u2fSq=oZ{EZ2}5P^^``B>0clDh}hD|f>N^~ zs7*D>ELdp%Cz&wX`!qcG?B?{?k8dQzu5vTmbO9^ zgPyNiM^ZnTEKi{rOf?tGp`$U5FYx_Y8bleE6(EiyWaK zh$wSp8!>i10dVBb?h zawpgC=a&cV*WuDk3du}mvvR{RX#KIco!`m#&w@k;p%|^2&`eBafjc#vLShvM2M2(q zqbgTb$i>;XGas6lcgBWv;+B=RsCO{)b?F>fI?aBSUI&zPl+m_1?e>S-SQD=N_>zWg z@ftA)y98he1u#>qcqqFyGf8Qp1gKYV1B;m*gQ4$zr>4ib)lkx~|5%#buW&ZYLH-5L z4UNzR!swRDWdfQHAlm)rvEc5sfI^yzxE0^3e8~x=JZVr2c-Rs_UtDW^}xYr0!{~< zj0+PY*>1h4gw5F+Dx0L|Dq4ME<-YFN{i|DpB7osM@PJ$KJO$Hv_`%uj_Kj5Z%HEDh_`;FA#cG5RqnkNy@R*hb%Oeu6#0PhqI=Ww(DfJ|@)r}eu zduy#`U$1ci%)G9}Im&Wul$)m@uB7TM)3b9Ew$4iBp4oaZ&uKiFBMS}eyWbyC8j7N> z9UzC2!{vjjD9-Bc$%zeIN!b@&*7$V439}LTzv2v#D&itZJY_R3UTOm+E6MM@NPJaz z-P$%tK|{kOmRcTzDh4wa{v(exLyiAAz>D-w+NFy1T~%u_+{ zK*07F1l&J*wTq6MPlwJEzA+`rP2fw5sN**z=Vp>~{!N>xd+ZqLGpAK|EbHN_iS)}c zZaF})k;`lS@Z`uI>LhriiKTw#-8pv<)6?B3@Vo6buiJzq2B@dzDPI}*_1O_t9t z8kqe(sqpD7GyS)IEFt2r#?BCJ&G+9>U4;Jj>quZo8lfjOj=avAYQF>pfkarGWfI>p z^Z~=gCtBCy;&8lA&G_3ANP6X)zx{mD0i^Y@4;Z7$5QNjU^og{Jhitb7=1Z}#t{Eq9 z@3-2iabg7tCFaf=57;>IH)5Nr7V3YryPbRWyb9+Poi#BC=dWR(>*Xmdc%?62G{U0h zzC0Jgo&je(qIsJ?xk6u>OMoUZ$~GT}N+t_)^KEb9=MA$4G+-p%!edH_gyOd)fR^LL z!;B+e9^evOu-D)qfuI2s2@IlnlrjddE&rsPr$CT5ZeIOwR=Y*FQhF=mRzOC!C{G_PX zOC0=C9l<6GK6>K8{Gv+a$({HHfO%Tqt2&khpR{wIJJ$eY+&K7utq@`1F?teYx;%2c z=fNhXwzItKX{4`R7K*k43bfE>NezYH-w)KuhaQ-{eWR;;L&Qc1lO&mP795Jr@+Ixn z!_a%$1Cf~K?U+FUqPls&dW`X+ zB%-BljB$P}w1hXdfCX(aOPnV^p}iQ?_FEPs44_sKxIk?!$Lsr}jH=J^<(l1HLK^>$_ig-_M@+gW@+Bo4C5&ki*^N@ro?p9R zsl-cs2pNATvNdi&@U3{KuKSF!?U+m-mShK2?lF7xz?5?Mc!T?2-m+-~FALxCBSAZZ z@y2I!>H)_bR=$qzqqUWI<>ip3yg6ujO4QxZzGrhQDu9wc60klpt4GFanU+qIqY*!I zl}*I|Uxk8U3deAO8gWW4N}LuH zms9{_@us2(=U;P?x#uvoJ%l7n6aFhXhAw zA0^bIZpEC=Y)nt_jIDPwSoop+MA)cbadZagB{Oyjf)dHf%hO)E;vCa~6eiD}z?$M> zlU%aZC!&Svk)Z7#{&NjArP$wyRoe?=AI3axJ-~b_dS`!PVq>(dmyd~XMt1^0GOU@S z+i}~xe$@nrfB>5Q?`A?nLt9#2s=Pna(yIat9)Q(@TZy0f9<@wfPXng$&&Z~sucdQ` zl22xB?k&db{4=AmHgpF{nRt87BFTju8=)=@B(6PYj%^Dn-*vr*OwxeFpA<{Bbv?|E zzsY6NnHUJ}Kt=8A7qlUiM|l8lxWof@%;G@voe_l!1U}N=mpre^QjH{NPL|r1!k>dkaUGEDWr*Mza zBAVjgT=3UlS{)&RntI2k-p`i5Zd&2Jk0nc<=cQ#Ns86ZKS-^t=Ry6WfY?`nm16tM| zuzBe;r<8gn0pwAQ>jY)S9J$Y<@MC7>z9hVEbfP<-ueUK2nep4`f)ChZGa# zBM$=?L#)bT=@Ni=j&Z;QyMp9waf%tgS#?ywI6>K}jsdmGyl*b>n&5lx!6Tat;s0N= zU=1!w$AjYB@oTA5AZ!O1r(|kpc6^uhF@8V)*FJcxvh@`hHoBL@`_)1etUD}b>-8}4 z&%6dCa&2|!`T)I|F(lyC8$gX1nOw*kGvDWq(AFE^v1ynv8_s&}xp@!c-)qH#&{;sj zC>epImB_7~=aX+L3f{~CKgEdkPFbiv?f5iI_=dA{`=$~~+CgXC#$JjtK%4~Ke08C= z25y0w0@phT z&)ug*#5S6}%n9E8hKc8|ydebd4McnynVaeRxairbIT$J|hZYqKkwtdoor~>4{eG91 z^wIeV)Thh44kM1xKATQwY#@vPq=XAA@c{CU6k;Kv5$O!dhKFrF8pE=EIDUZk=aVH} z;Aaqsn#?)=CdYl#FZVGo7i;kCH&_^)PP%7L-~#c=^K&8)TlPlvbuChR4>Sx^EMfn% z+INh@PCU=tkthSdo zB;56q)9V9;iSxf!xWIPpdg!KQA}9J@Dj(2WYZd<8|#-xZ12Z zECRtD0H8&JR4$_(s2)RSarguhKkPQ-w*F5F9`q&+?{${O_C78HRKlE+DZA3xjuKc#AqjiI3cdnh^{~i{747{wAN> zXf+bYUzL>>d9rJ)a0vftSvyR!e;uN6bo*>yYd-hwbm}jglk42!r!{@6F0RKmMt<{<jd8i=hOEX^r7Gp zLc|s5H|ctf=TkvuArOEt=bY!LJ^~6eKn;FE2_6F@8Uo+aGr1pbqJ7j#dC7+n)zPZvlWXD-`=3pLIm7*s>Om)WDbgX2?<((dP0bHBAi4Hi*FF2`* z>+YW{9iImd`1N(I8>Wmxs(u5yK?~_1y5 z)8!NTW_}1ZR3f?qfT34hs2e!st+=LH2Ws$(dAe#Mxo}2E?>uhX=Hha`Kt9G1i3iHx zHDI8s-0xSoeDqk#NtLzbSJ+=MK<@zoN&wC(Q0+C;l>TE)0K()kAPDd)9{i%$Qr=&_ zsDj!EQGe_!tAh`u@t}D$U`9*5;feRI#lJG2N?R(id?b!W6Yu)ZdEz+O4{Jl5!xWe0 zDtEo!=pB~pU#+2yzCH*x=TUH=c+4_i%pf-qH`oy%O_=L8DZv+87;C-$5u}=RP8Bbc zeJPKXrSGbTqvNBcqvZgebnhTfTUy+VHo1z?@v7QVmjhKxV;>AfO-)$YwTaqsMaK6C zoCGWpo#1T-JGNu^WXbCH3V1*W+|h6>`XEo3LX2=Y+JzwN)bpYhMX64nlKhS>{Vrrn zEvRIJ^E8FLUyJ9lFcG4O;My)IQ;(obUv7zGL_$iQ-uw(zdlZ0_NHUn7fNO{gB;u}T zzy$=xSpu~!pG^xp5U8WrSIR}0yKrxeJPMbY61hseC3GG6jie(v-yjqW*YLh#VDr&l zN%NTc^bSyFzg+G>6%9`N;z?a(Xci$gsjT9jT9q-;E`|RA4q-fL`g`%0yv2~*=yW3* z`k|(w(-UDHmlI&6r?oo+i4_54;VQcfp--}=hSJJ6CxA^D(WY!*z-8Da_W7A*NhjLA zDC=VYew79&JkA1xpe>Aasl^fPp0~xEfTkhwD>yebQuh}S%}RqA-Eds5l@Xc@8n1Y1 zF=ws#TQV=%*pe55Mx(*Jln+&>4keFak-LzBnOD#$ECEpeBYc!RO)KPx!bSAKiQHkp zic<7B0<{9u-#8m@E3{x&{K|!^T6=;kupb)%!vBaT`L|DC4v=K|CcPT-A3prvGO zds45}61-vK83l>H_>H|z7k=Y_i&Q?`$%<5E8_=5IdK3&e0DHa*?t0QqOnj0zAVA_+ zzXfo8z4SrA<9hU^+4j+3WWJu8@bjz`V_7z^00khL zPdw=hl49+t%dIY$l}&=J!?ta&X}JMbZze<-a&3WKG#%vyQ=N}wUwkBTMbf7WA3a6O z^irJKoJKIhao5<^=zfuQMb#!tnyP)Pk}~AHc;zwf6DHcMm>Kf$DElHse}B2rR3;n@ zF35l2p$x2avM-pH!B$*TvsL=&^Z`OpGdE&TbH^&=$a5SmEE{y;s}8_-ER^s%$W>l< zjkc7a^vhwsC-yQSoTkt;YzQKeuiVxIKX4@^)R}_&^A28K2dnVtJM3gL)*)V0(s|!# zUwt4F`)mdh+D{c693*Yso_bz=z5-vOr^_>WVmfYQTG369ADva1uty+xEpkW2?B+PFHJPO=})DZK53spJoR zfpgL1=vI+Y(|M`r<8>)*P_N{Yif%-ErHUcw9tujEKol$H91d`sr~(`h7a z$=cbIF252K1qgnbNal!R0-E;XCOwue{#;w&(ZmN?IKH*hUgOr9(V$v{H#l7-(|1!G zIJ?L8(O*k5Ln$8G5wttYLV~U84aegY$Iw=gb=}?fzP|&1zz1xbF~;idGEp#K)G*h5 z*R=ftsFb*D0E(S9tP|EF5Y=iycYjESKuO=L?l|UHx-jX$jg*uI0BYA@LPKC+AR-%U z#avngeQU?cLj&rbc`TV8ONW0f*6F0Y+$g)OBBqbw78=624%#ufP1g#xiIhN|C<5qv zEA}_)ZHvGeX123hjs!TIo14FE#s?9!EpjTAeIk>_B^rI}&73+nH{WBLRsAh$y?XP# z{1ln0whA?Bxo^l%01BEsmjdFn)B|eIT;5dHO);&ORb3#M;S&Yio`*2tyYwzkBhgy6J2*X^mAJTcyzn&_a^ zLY}RgO4q$;?GK0kT4e0ldi<}GEP+dpDYj1g3s|}gT{UhOz&_;QuGzzweKes4@WX4B z?e9YxSW)H*ocFgfvQIy4lW!gVpo8Aq?b4qDt?J6@MyBY zBy^j=4BFqQnA;ACD0+dC&mjp*-krL+4->!WnJi8-Y2qd$meirt7$x^JSIbUv{&42O zhR-pe+}sog2sy0jqqEJMo<|u72weZv<1b5n`Hpq0;f2G!D=*!lAg(Wn!5itDz21lw z2(H{EqiLQRHGJ%`A*-+-9}+Ehz#TnV1#|8276w*B!r)l&(T#Db8TiKGNq@auBvT*gqQs0(f zo+OULp`nYWGHIIRkxD0_ITbikvOxX=3wmn@M+6)-wTa?ul(Xb zS(%QLlEv%pbtRIdb~Um`cfYij7vi` z>}%>cd3cn|7`yVksKHEnVi^rUjq@bL__|1&y}Kv#NjO0VTvG8{Yub;paTVEkdv8ec zc))fv!-oT3A@yc!X7UBNxw|)b96s@!+78Qzkv7t39%kWYrsX*GFv$GxOSpCHq;Q3~QnBWZI%bwBpENFxR$}es2Hk z6%g0(2`?FkAQF+97tLL?aBhc7d9G2NKfM87ivS*j#MV1mfE#oG1K{t>NNUp4LgV-( zogMG2M_OJQ%-qD8*0ey^)`?5X+u@N{&13mkYKg7hmrN}tdYVC?)hK;q4{MswOG?+< z`jhw7MV0r3We3!rSQJi=W5iqaf45GB$^qp=*LklcYlvt|upaN<0%8Aw-=rHSUQ&HN zqZtot()gCEHbelwfd$40k}>AdbCVSeJ)82OPgsx4jA|cAccg77PK*+8u7RkOA1W@N z*L2^747Pu!TBo3{=#_uW5qG>4Vy~BvK_|{IFlo`IqbA-bMGR9AM&;W~Z&i;a5}TXa z_?SB%I7ww-oW56mJ#<}eb@55WA@*genZ|b!boA4&hUNk2r0tD5i+3IFF@;87n9ju~fe4wIfpb@AKd$vJvpfqWrC*j;86#?NFS=d6qn6ljJ;&=__y|;_01?66 z$T)Z@!E>&^`c~ds*aOuT3>^&T0(oJ&! zAvBhRs9q;hn!@}>VQ^)3S@=yEwJ9`oJl;REG`TyzMA?}X`(a`N+>k0yuRw3}`^?WZSC5P9^i2@5P}*5Nd#ng6!as=JvxLDEI;lno%AobDdV zWKu&nE*Qn+1KuV{qGn#qEYhR{L!AXXzJCZgV*&DVze5_9L`Y*W;zwW|W=Tr4=ID_@ zVeh<5JF^vYQt7GS^LAeo;u)yL*6~&EZB>FrM#3__{}_l@bFC7QMz6v2HLTsD7)t54#j< z#PeBk;y2&>w3PWTen~w*cw51U<=#esEQ`}D{3(JVlGg*Z|GOg*46{)1BQ}`$w81xG z2Mu(Ofet4Dx%H8nu2AB2nwXMjl2l7+Ncz5yNKXB50D+0|_h>U>Jnpzz3rz=n z%t2X2?{mh&r6!SUGIS7Frvk7P3KE;MI245pv4e#0PpOl3fh|(~LUU6e_p8y89j1ez z)!EID62c~e1>5?|^LIjkoQho5@Q`%Ff*Dr^@B+|A&O^3f#bsTR;+%$@M3v;7gzif> zmgBEF0G+NJ?57jRS>o3e(s$F2=KkCduWD}3nDO4reA8yIu`=t>EjN9!B1?%K{e}vo zh~OnZ?&2n+uSITt6-k|SRlpKx@077I{H9(*AMawBRH8@q;pGj80UEd~ygno`{0%y? zrd-bG1N?joP}WMT>N4tsxlFhu zBuO@P#l>D~U2}kL+!!KPNeVircH9a8+I?P;tz}vSBQi8n-cz3i;QT#0gkdiCbUbu> z<}}NpKY|)PEEl7OEqO+BDvThQJ9Mmw5Z6IwF;P>$ZeGs|!>>2vVWL$K=k!Fef5K=~ zUltXvHeDIrYLzCkFJ{fC#fqwr=jJ;sxJHru!Y|^3u?K)m{&Kd-$7w!_%(^m{qF9g0 z($ZTTs6DX*bM$2)cBK>&VA^AAlgCNbWI|dz^VoAP;1-xld9fkY5x}OWlOPI?%GoD$ zx(8C`*)mN-iB-~xb8J8trYN16T%8U&)aoM{430;I5awdXK1UnH?b zu_-57ps(7HqZ56Kh3ng4WqB@od{3qP{I`1x3X6KVlazJxN@Vg;m4r5fSkQ6BNO>@L zYOi6dVS?yO17dob_dEk_s6l`Ig&G1az>cz>n+!RLaYTV#AsKz@zUXL{(NCtbwc|0Z z=HrKz7^Q_#vxpIm089$zBSJ$UYrE4wfuW<`AA}F*Fhg5?fToU#NsjMrJ*AF{uIna< zcqfN@|KS1FOG1zK!a_B2|8>3tdtI({_w)tLu zI*&6B5nvhPD4{LTWG5)Uql66#u+!CY{}eP;l+W(XRxUPIK;3U0)Y3$Q53^oxd$pMp zaoJj?8v(-8rXb;2XVW_yuwZ;pf7-O3leqBbNgn-*F6)%d#fzI-GLX*~`{-|RHOGo@|mN2bbE|{-Xeq;glkq5^&8gjW$PNg6; zRgnTYP-LE@XXDu))V2d`Md6gK+E7o8Pj4dRZ0hxL73M`D?LEC4(d)J8C7+AO!h-9e z-N}3L52`5P&HjbD6{1dYIJ7RS_>0Bh87K66UvgItY2Vz<-1`3Q3>#ZRpF2B)=NLXy zmj^gFA{&azoMEnk)BB9N#jo9=+(x~KTWVnHny2_7ahyF-@jVwH!F3RcbV?Oo{X+XK zVv}=8ss#lNT<06Ho&5fA+^lR>aDw9$c%ucgUR=khonBDgb*6pL?g zJcSxJ2&F^|3hAtQAguMr#xWOZqA0IWS-vNT)a~V#I&H~%L7#f6`X$P#fEOct z1JtsT;JjE7T06pmEUz;uwNykA{a*ocl!Ga1nk!C<@B?r#<{W&vFdCxqTe|BRb&^!b z&w{CNG#d>J&!;%>2!tVdcp*JqBs|aVNT$6&DX0STH-wO+Leo5fI~@I z`fmp3B18$JaT!IV`6?|Y(VgOWp>JLXF$CwS*(msV@UFNp+7+*n49Ej#`+pQCUB(=?IB4XivkhQ)O_>Ulm3bvmH-38(~eL{W9t2RdYqoFU1Pd}2HNm-q0`ro zo>$SYQFLve)BBUg$*Ok{T1>MmN;6R9!1c!QGAs`e{oUtf2A2lu52^0riss5+g7owO zVIICKx{m}MRE&bN=0)Lu&(BYgp`|=8Py@ZWx~c)(Y+dy=jjf%XtGc?d`rYhnFrVWS za(}81QsJLOH-d*f>m1!6nT2NYC>?3@Sux@X(#v~8wFt`SIg7OievK&ZT8q!pcR{;5 zL*;}TZqPRgR|fKRLiJfU^d1j~XhDMG?{Ha_QOC9ZtBSaECnVTV#z|wR=@Y@T{d`uC zHUatU3ZH1Q6~?Qmc5Kx{tKhS1hMW)N=KCr?$IM~XUZm!zhlJLpA*aGrx{HC3Kc#jGs~qc#}hu8R{y3Iwn3ZN!>wLaO5cF z&z}-el0+5Zt_#Q@W2*>t$3XgqeLTE*8v#NSXWU(Vc7|&j8Xj6!QdUwnPv$C6k&raV zNhHWR^@>^TEa#}K6UPi^m;BbUOcpR%CpZMBZV7ChYKXQHk8Pss4rG@HB*pR zus%^7LK9&J3LLqm>K{oTy;d)7a3uo_9Vj*IU;7mTigF#pP#Zcv(a|~UM254MVTpCS-%~>xl09F z%x3TEiz3?WLW}-ZDL$Z;u^xpY`xTmHelgnrn-^oyWJrt<;D6P90tez4T2`nC-f>2hw?+{TDAN`FZ$ZFm z(LV}EXS>*bCm2l^B3IQX$HaB?Q%YDJV-`|aX^?(Ku@duhaTr9P>8LQ(_XVK9Y|}HX z?!GI05;?V!vPUd!1gi`%Tk5si^sHNPWDJ&&t*88qpp{#PTWh&v^v2MLYnv|n(gZdb zmWl)A_`pvE{`Cp~62bz?qf~6F1nfmG4i!>$Id<-2*I1yW^Xn}sDJkBbkM;De!Fb;9 zt4Zzb0^Rk(;>~Qz*VWYtQp#z^Ec;f!JybYodt*3gN<~F@e~S*yi)?9uH{Sbcr7Ri+ zFd7IuFsl7Op3X9?%3%Ha64ITUmhSGBZiG#DN_Y1|hjf>qq;z*T2vXAB(nxpwx92_Q z{mLh<=bAlp&sx8=CTU`Vbx+E9d+~~B%WuqjX(0XJ@o_Y&U~&g);upZGE3Kt0M4UXG zwA|_3FdM=wui+uxcQ?mThSU6Bv-ga?ly2aG zhLG?8kPEx>gAR)sCr1oLIsE9gz`ggx<&X`51clRc&(9bse>>SNuoiY zKd|vkD|G{L7`pK6^|<2}DyH6JbmSKX23h7B7ISNb3ekUL6|;(^E#(S+^7Q4*aj5RD zZE9*u@(@^aK!2OP7V*1@JLdS!YI9S7$ucdD6Y>i8x*H-Q?YW@SH3c1`fO)J_HY*V`4h;UOYg1Uu&EmDUV$ z!^NZqh1TXqJ)oVS_hj7O9hBh7{ddMp8{50xWx$dqnxlGe`ca%E5YkG+T0d?+Ai=z~ z=+%bE{JU~q64N5t#M67Ls;4*tR+f~<1z_$-L(E82u+?Pv`cYcH;V4N#)m^?-9oe-U z_hGke=0)E&Y=_PrPTMr!z9}7+6RXpLgPabNxrl=0myI# z4@BL~3FX=`Bq!q$Kw#(-ie8jTRB=~LM%fWB^x{Zk{&yjIi&L5Al#Hf(uX=GrN??Yq zCCiGB9fg1WM{=z-NHI5s-53GWO-^H=$7%kvn>84%Ct>>*xp(gPUAlPSS5O*)jGw;D zw>hSk4qUjavH+rUZrnq010wlI@Zx%j+d^R{x!;#La{OEz?;kjil^9(qNsI?sh~+Jg znj;ECj*IKR^nXMfB-k7Oa@dO@tOjTWlp3cW!n~vB%qb1=n}k#dQ?K3AXi}?LA$pTi ze9C-3S*de^n}GGQoWK_o26o>@2l}-+hPY~Uf}x{W#T*>EkA*HTFGt)bf4%YMk!V4K zd{qK5lJb~d)qkf6NIcTjL6b<-rv_$9rj?(nzTDp*1q%D8k?5tS`$z1gz60R#sj&2H zK1(36@eB@6H!i1hY$K!obU~zKz~o1;+BOj(etG&Z7eaXJi2AeWu%ENh;|CI zUL@8#Skv2IK{+vG77W7DpEgzfllUmS!lr5^Cs4b=G9R~hbZ1%59 z3~94}7YK_Df6mC!@sTLuM-M}rw2o~TKT16=(oFh-5Ozo>WPT3ZggejqNMxKHC*Y&}`x>`kndP9fnAm?MR+KzDqxU*Z%q}ubOn+!&T{;rA{&^ zJJLHt6jst6Iz^K2Baw^KyVk|vD}wqJ$5BtGXArtd00j!@(@`ArxaDIP*cIP~qzAK1 zjBrU>N6cGAb7gk0awN6!vBun~j9YhADd;ufh()!*5$t!IM5f%ys((6Nao_0}el=vB zkk?w5>j?-!BnZH7aCuChcQ!+x`B=VL@LD^<0;f;8{`=Zc+iigA8Vqb zHspz}1=%pkh{OLOn_Al^Zoe$qB!gF~R}xeK_{|aS;Jkc7`0tOU${4-kz&4Uv2!&+i zl_9;)?$CU59DrWT;b)%FQl0PFS1G1#-9zEz&un&jui!2U=9ntORqh~@P?1Z#bcOOm zfZ&u#*ZBSsGT|SQ`U-Q#FZf+*SOK5#!_mHT`o~Y>xoag6O67@r9i;}L#L11OXIKFp z+)A>cX_}rnVLp>md7@|MMKK2j+qG25YjW~QjG5VJiK?WqHJ8WY*rbN4EFYc=kzv*i zq2KKDJ0BH(E<|j0O7^y76{%B%oEt(CUoauutmrr1IMU5cwI-s+hI6`M+&CPGdHqt{ zB}21#*AcAC2*Ig_E1`M%;PM*85G|8H^zb)5 z<74LkPOj*&4K9iah}Sj261x6twgjO#XdJ9*VVuIsbcD%A2G<{c$Gyzf6Z|?aZ@}58 za~1xqC>&M3xC~pIdhJvouE(%@RH%FQRq&Gz8g2?_7&9}Y}Gsa`^kscxGY7Ax-6Imon14v#&+Q^jaEs4 zc7M@OdynGek5wZZ{fi4cEfC!F=UM_#ak|v_`vP}$Y&b>OfSIcqPB{et!wiK?$E69GBZVN|iyvHH>(3=X;-ggZuGt z{0KP;?-$qV?^3SB=6dpO4PwNC=ioL*)x+(NKTAGhw)%ugz9(Sp7R@v%RFrvDj19*r zy6&7li4BAkVBU&0LesD9{nJS9D{^ry#HYK3sukVW;$BM_)9@b742Tzg$QcX^^N@~M z0CEZTBz~qBez^D33O^)7+Mz(nIW zypt2`*RhXHhTiLBPzqy4W1_&xrowhkP`k=l5JotJ!sH=|Ll*xZ*Ga9OYx*w-sx4<` zSkepur<-I8CAly#U2fW=bTWa1{rMjG7Z`4j6D4~n!l;-|Ue~`!eh3C#h}DuvSH3s^ zN~y$buUw7)D5;*rCGWw~RJIgR@o}RVx|}qo#u-}48WpPCN#qMc8Vn3ublsR79b0l) z7#>;1hXoB8y3PYw1_R#h69 z8`LV_m2KfziJsj2()hp{*2Iz~(ym_72og;05|jq2+swC&18&bWcs<@5%I zhn>h{Layw(IAMpBA&=!H&i+@-FZH*!iuvLqHmaLo+Yswjj`lp;*m`->MMcfK*{7Eo1_-Z_yPB_DsG(B>R z=D}mfJ)xpG=8S*&ms0FEAQcFA0(^J>v3+Iq0Aq;Xq z9d-nfVidbcgCuM=9tx*Z*+06s~@QSsW5@0W4A{|+Ve_@SLk-YbMX(#Mjvnj z$1eU%({1HxO_BD$QSKYfYJ-@`e1hvLZn5}EnR@>g?`=KWOl{K0lnu0?g-sGn5^pAn zdfYT(6B}m3k@4i`qHCzHFz=sMq7G}p+9XWWvtQnef67$r+;1wj&O+kIz&6$-pW{5! zH~f*GC$2zpf<|z+W}{z8_#4P~Zz8h8k@h^g&h#bovT_b+M#J(<4nkdGzq>(UgfV_M zQ{Y~p^AJ4ztmABm!Rwe+EJ0v^u0s~xw1+o1T<}j1@8C+$t2wf@tBI+yP$sSd>&_Aw z)KBDa6qy^lutsI;OcX!w$t-ZWy55>N=y>wdaVo8KDlvX;V|Z7N23)ws)UPI&WGkTC zhNxlJh1C5d`Mb4d{DEiqH=_TjclNyXM-8Uv`RYY560|3Evkn;(SQ+x$ zpMUzv>)2zW8iva+6D9YI4X_PP`S&RIdq=hetLZvPDo{DV(Eg|%ra=4 zc-4Z&Vu$NSUlwSn|zEL3GMUJgx|m?>)diLlOID7V7%pB3}vK9{E>kXq8{q z3JAghOeF<9)Pv$$vXidL2Fj;udg5|H?2TW(8=i?_+U7l~6zrwl1XXcp#k%N9Cy90P z4q=j!?G;8^N5?xNqBO=>Zz+~w$8BocXMMHO8g{U@Em`$2(?N9EO1)e~mNB}hO9ZVI z;Tr+7WGE?rGBQx4WtX#KDMbve%WGf57eo8*so26>u?$=BXYK9fYn{SoJg8%DxOlzw z_e;vHCCuEYMAjz<>>}<2QU#_P%k=*p182I2_%Hgu=+k{Ollu7D{!jl-o@iPf@W zxEh=@#`vyqR2jl!n3IGMg=jj&aK)q@ZvkKGO}viCMDFfDsQvdu z(*1U@e;21IK^^I~#4!H@3;NJyALcc+&<&ia0|JiDlfT_B%CH|bHgr7Cdv>@&`YjtB zz07{h42p{0d3vt<-Yq!qzu=Sf2w!~SWs;sv)F1EpFtk_0Q(SMs+3WPh+<*1+8O{ z=ttFSg6rcjZlJ1?>ZtR}e_B5-d`Wo^(EG$4ePy$+MA_A{udG~c z!3#T}&i_)QohZIvp#xzLAt>oh5sQcMT#{VmF0Ph=Ft6y_NIwJwmQ4=0<9)@(!YZT# z^-6%R|AC|}FFAh$SWg3Y;hQ%-3Wc?wlgZu|57mAo7ztljK27^R&i+Jy8--6`oqlbg zoeybTq5%?8$vFqsUeE7d$9g3q5mbCPj_lZD_iSQ!KJwZFPAoj6XoDBC4rU5Xc z)FM&O{BLMO9*dL+d>P3IAPtFI$s8950)z1DdubJ1VnXP?1cd9br~|%^G4T4z{#~cc zMe^z9QdG2qsj@I2jd0!Z+k~;+NJ@+Eox0`nykd&!yrc>9e^7$>Y4`HPzSF|2=o~*l<9VQ#vmwAh)3yx`KC>WG z%3)1sDB%Y~6|_D#_9jR;5DvydO6+CK-S806dyKc@Y+AcpT1m2SkHApr%@b+sATYVD zE#oc)t1XvSpH(HsPz01(aPK=iy;$%&z)qGPv|q@!b7>IyIjoBThD}$$l1-n;nlwj% z62y5-Lt$^OkaTO!t7@`U#+aCute9@v2>xAUK9J|FUWb#O=+um1g(z}BMPWVi667KW zLha>W(#$u$*T0uNI{SKmA3EJD1~{FJB>uVG6ZTD%H|aqwPy{V31JhFQEL}K2v*^>T zTFYK-1eva$fo+f@?aw_U%%ri%n2V^%HkC!ttMvwt9PNwak=z3XQ6bUEUl@qAtQ;=nUL4T}Q zp~vH9HDsP6H2dR}wuy|&aZ<;xKkNhqos#lCZ9@Od~ft!K{SW+X4RN7IMJ}wb~ zNmUqNU5r2X$ol-GZk(R`AZ=@pnW%Y=LAB39i(8Do=e1XKxcKau5?rNMj#DyRPymOOP1t;DRdT4`C~&$>fU0UV3JIffptz zJlmsmvs2qB8@yxt?LwvNOrS?Fi}nF@b-S^3_}^i$u%Rb4u>t;gUU@F1BCfnvbATQe zN`+G|yqR3D_KB&Ukb2n}nC*6QtNDSST4epuBO!q+ofL3Bgbg1_sGZuUlrgj_jqQ*v zuizpFWA3t@iGcDR6Yt)3;YF`8=SO}?(kvYwz=)Mah1P3!rw5zbomv7HA=d=-1i#zz z_-x@12swmN;F|D0M-oJ<6{Jw{HeaQuI#zSm&z8<3_}blSNDdTR3ojc$XN>S(Wk7I1bTH zO3{_F^pW|fG9!|BvDKFwpuxN#_VlZ=x>JkR$N-ix^bf3YCskY!X zvh*j*$59c^Y#E^$TRPkJh>b>q&qR;esC!BoJfwRJ?y^;5ZS`ZpBD+gJD(?Lu!MhjK z#8x(>!@+|>EkYWY7}zb2TmWH8CuqpsL476?f8!tcO0Tek*=~yeE zU`$(@ol2@ae8jsHxrpQUXyypW{+PvA67r#4Q~ubrCNg`+SGB_P1(CP*k!6wHLndq< zoQGWhCmX#ixAY2r^qP511!e1hyqQeMA2)dNvg>f3HnJGKNS9WEMG^Qru6i#a*Clre7&^Q$DCE!#mqV8JS=XF zeD{IlUEmK$-q7-i&?-oAsw0kjV(Y#6y^UXT){dYla}313a$S=)aeL_vlv**(rg}-@ zK(FpTq{%7`Yk(pk;Xp-MC0EeVH4J!Qt}Y%_k0TNG*$vy5uEt~R1#9Ek0zE#f*1n)( z-zW4JHh)r-M~7WhQA%IGH6q8s$!hO4BD(6jPUZ>%Ih?KGEMR*-Am}%1#IhN>Xy}%t zZ=fBq#PcGa{{$Sttp)-==@aC9jJdc+|v zvcJ|J<2+wq-X0s;N$!Sgu&7Z@4-jqZ8U0otnt_*GGXHN%-EN$s7gsso9*HVWL#m$< zD#@ds6Yi4?Ug|7Dlh4%>^L{2bF;`&3pUtm00MCgLckp%WnO_b&Pg0v(%8deUIlm1R z6iBrE&Gu9S3TvZ?pKh0r9X}XP3SZfA`pIOL@H8e(gslbd_rV?5*#Em>26LE{!bZsR zP59OEhq5e9m3sw_iAgr@qGjoaQ^}ze6tLxtyBE%pzb`-Ml#!_NfZde7wX?9~E*@rh z@&dEFQx~VoGgW0p=+K*HzeDwX_9D>_yb$0vzupB5&nzHOD}zW_;pGQYM#l2$*1f&c zn6njh(KcX%6oL$*u0PXmpR*cF=EpkXAVu3iK`uTk_W!`_`;#|FJ#1jU=H7=8x)wt&MSN1k2^YZ$#+Oh1$%xPei8(PyOMO~8(swhVPrl@^=r;!*OESS< zXZU0K=&2iIab3mJzJJj+aACvMwUJ?QdZ*%;R@CFbqNPr5a2dKH`#p}{1{91pR55TI zic4nM&=%{G;Zj^FP>n4}E`nwco}LNHn-DOU&vnpcAY%pMJg8I8mao_V+sZg>#3DCd~HEe9^!#BTF7^FE7VoR%si;P&mGH`Tf1kM?WE67QavMe(CiwJ4g!2 z?JX9g>-*8d{*$gYi~bxs1ur-oK8tbA`DjTpNzJ0(NCEU-^^*W}W6T%QoN{VhZu1X3 z+Exs7Px(W~4a+XFj9&rmZS}$7%&a}SGX1f%V0M!PbMG0c*7O%9E!$m1=mL)+$@adM zsiZw}R5yfcxL8NXm}%7cv<^`kW*E!8dzTA4=cvGN5BD0}4zR!F4U$ zk>~Wl_Kq00D;yLQdir#c^^tlp|DrBU_h_4jwWHsB#cgT>uPstAJ|j$_$>n=p-aSMv zgZtUBcI(ekie*lp0~ezWbv1uK?q?y7 zIyA}T$1kdgMf5Vz8)dmJH#jCuhcGY&@RsHSK})ls@2Xv|+QY?2*-b)E7`XK82QFNA zV2VTWYIoBs=Z`WgT*%Z1P2^Jr9)EJVz=>1u8719ifyrznf~!`qdnVh%tw6>_1MFS| z1G}%T=3;CFC_FUcR<0N4VM?71O-&*c1uOL(ZU>hN%pdW^t~9QC@XY1ss* zY5MVTMm%PM6sI(R*BvuRHLg=Domk+K9s`f;llHQgkP{Y}R*?;=SUH@JP1uBg6$XmN zm)L1FwMNkY$h8VPkDDMwL`1_CnYf4a8P}DLhvxT@K~&T^rA-vyOmKuD{fb45+F#xq z$jwkkutJk9ewn6Ebg)dt-%AIaIZ1xk4HtD>+E;~}*kDsfDKUNK{u+1xjVW)RL~|>% zDZ|IpaA$N`swlKlxjC)?)u4O|3=bO`k~es*P@Rx}a||ZTEG?7ten%yPHvgFrrns>~ za_qrWq?2{+YLj)aANR6W`7J&Am9f(VD9FMhdI-;&6`gA{RcNi>&$1GW+T=(gndjV0 zs1J_Z**5>sbBp#{x}XCnOxzngoYwEcZOV6CnHd(mP`rHprvpb6kH92yT&+^m?D)ni z(u1#;Ra;hYXfITG><7@vH*=HjTZnUuzf5oa<(Sw!U=RFbm!+7hH@AUk74@#22?_f% zUtDXgoL=Mr77Dv-E0HA?lA%@)HZ{sjnjDmd;diP}d3k{CJH>q<&DP^cie)Y@@SQ7# zj=Qj8-cSJ?VG8ZomU}>U5BHykWpzDr{B!l3sJ_2zETB^sRG7`pL3n9%w@wFqIg)Hy zzmE6P3Z8ah6n-P{Cd6#^q1ceighv$46JC#1YYuIYYQ2Z_52D{?8@c%GqtwY9S!`lu z0h~Oukp5o<4FnN8O8c37dh)KIji-@Qci>XAM=Wrk+`g%2IpPg=I&Bo)W7Q z*NZ^18iP$s2kk2{FTeD5KA&X@N?IBoW zdyNIn|K~5*x?j?ip;?OOkc%k7XR3P?EINmO{}WsIVRjj$LAnPng{v&P5a86PjG0K? z{d7M(>uw02dWvgE8-69=i4XtLJ|M@HOXZu9Wp)HZ?0cdD*exz^LxNAc`2^lTZmsJ; z(m*%pd-^m)PYqZ+h+$dA)1h+zkG$HIjg43qu~C*HowCL9XlW^d5X@QVnlxQxG1usW zGXb|vD9cEUuJ~(=jVm3Mr{6i1u&2Oev_Y7i$Bzv?I4igPMV3q-xGd_ZHn zsL++;0&984Cif^5JC?CD;Y*+nV#wt;8@{-?V5O4m7u^YNjUt{b+k>NTtN6PiQv&+!2=;-mb&7%E7BkAT?HfQHOiXto}yxPQ{=$jNV-^ zFD=(B>*erNp5@c1#LxGl)@3A#PK_L2?8n+SH!l$o%Hz&w4%LHqO5UWX3>-1aPy_bRXYFU7<`%f+C?Hz5K&jp}e)2`w6Ia2yU zWrJGwgepT7zps-#CMf2m3HN+yS!xKjMTKx}IAr_e4_(ZSa4fCuMi zz;9=~+Urh4D_6M;8Ry^?futXaOPj z|3`XWoS75`#>O1&EdNc0xe#PAW3({fZYiLar-!vEKiNr3pJlAb7S|x31tG4stKPqs z#_ZPp;(}>`<@pjg`=!A)+Qd_M&-Za%ZnU_@mxEfQi((~7eBWBbk64GI4NpqVucHS^ ziyDP|?kGtBrBs1sX7B~uws{t!Z15FQW(75MSURSChG%KTk>TMB?Gx3~(j4Z$PY2Z?1}Ms8g*qRez6&b*AkJswUZ@iMnwTdFK08_*P_PukoMv)J ziw+$+5da$PD5RDn6DBI6$6rRc?{u`=u1eeO$j`r`MJ|jv`>7xnta?Gbagl z7<=U6m{LN%!dEpl_!XESX~22=*n%mGo~Ke2+THxYtx4KRtQ=X|L#(AQEBY#qm~78m zC-1y@aIQV-wn>Pkc+wgh4t^t*2O7n5C-Uk5$sF?g``d$oVkK;Tc!^tpg#3s9C`|(H zeB6peH}AJEm6ihid?3{Kjh&AOL)ybdT~J6?jC<~l{hK@eDt8rsSqkEiD9xEv%AUom zvxQlVQlUW1Rhl5Ju7gWRa$*^hoFL0^RRL{}V*N?Ir4fU?aqbLB#j{xIEU*rhm79L0 zzW|)~T#jJ|4O8LT{C3m?xe~l73Ka~|U)A)qO`rop4M-pVEV^We&I(_ihuohLBNBB9 z4Pmas+^xDo66~GZW#x&B#C%TdaKujEzTLMP^_;KW@UAs9bi@SZbiWyW8;a%o{pk6& zwZJywy21O`W8>QFd20$+Ya2aa==6Sn%n6$!FMvx)Smwi2x+U$j} z=wsJXtM~Ks>=v!{wKZ>5WtHFM4iFy1EzZHosh}!JT(kTg`%L0*Ut&qeW4mGeptGgT z+GpDXOO+zZ;E+w;>cuOQWSM$5^?$Oxhin_GsamWB@a$!X7AKR@qD5u}|>)sFuve!qse zIx2l_3j%7$(;;rk2d#7s1VD^r`xbqEqr;^m9ZD^aIbXT~)A!H)v{|F8(tsLS67>6t5=zsFo5L#_>Hhz<@gDq&n`rJ@&(w_6-yMu%ywXfuQHf}9}4NRq5dh{Cw=9)GA^eLz2T&P8=c!`GK1U7%bQ)IOgya=e0 zri*x9c6L(M=B6d~A!+S}yYcLkH+{uf&mUN0pd@v1mhd-TMea!fb6oA&34mzgC-g9y z`atFCW6sV>Yd7B@J|G0+HpRMd27}1{*swL%WVkEH&;ua3#leVHW4DD}HX$*KJ)4=? z+$K1IlBS^u_Fy<4YW*!B z%|Pw`bH;+6X6{$xJzsS{LOWh8T$`4kUsXYU=Tg%O6>`ysu|Cz2R~UFFtKfb#b3Vvw z9C(NJ3V5GSZ zJ5gOH9alZ|Z#=P*y{4iYOCE4n`@)=F`>*c4nc$HU;lHn7RQPo3Q(I7)1+tA@gU8BR^1`fgyQ^nuKwd7cm%0P&^ zPoA2^&JNl}%Q2(Zw{7VT1Z&=BgLc*|tv-l^J@BLS5pe&XSTGwF zA$lED+QQ|roQR)mc6pg*@I~spBpY7)DVXp@-gf>ZfV*~FJ7hX@5t>f=2X8q^qg!KE z+_pci;Obr&hKpFX0@`v)fNiE%sR51VJ8BODI8ZqX-}l|1kCXu=4TcoEk45ccU#!rT zN%mmS_2Kul_vW~30h~V*Q{}he0mF_u8QWjyz$*N7#Swoh3d_XFx+jn|xC7tYE7NNr zXr4}pabEi=c|i5>;l?3IFeg&TgPT9I6(2xfT?R->du}w75~9G#B`MC&!&X)D?XCr4 z_$3E4M%z=O@L;0woaTPxiAifp8u&!5FTGGX$`g!p_=l5Z9q2eC!FOzHL;TH|OSP(J zlP1spt(?)I0`dx2iJ1gg3Ob{4a zJeb8X-~$>NJP>kH#rl)4XW{Jea`jn=1g-07I9QuGj97-3`&BTkdcBsZD`fcMQG>M= zuN5|6h`EKN6+>+mCZgVhw;Ar_Lt~Y zud&?j3}YN8a>ZcjTIHip9H9|Eety;;7$`Ad3VYhw+5w25PI!rDbr-#=AY;=xj5|IW zU=16O1Km7jop0F3h*2%U%C_QjMI6QvdZ8Vu%=I)Jy^1%0eWyqEiZLDV6kIURVm}a= z+F5p?&ne}GiAD1Me+#&gF>SrltD2%ssH3vR8Ko4bZzx%ueMpsoN@%g@U~mjZw7QfZ zm|1^XI0ZQFY*20h9*{ArVUJh*Y!@tKg?>fCHQl=(KmVn+0g=LLXxF04UXIIe-*Z2v z&R4YF&V_zkqEX^w63<}%?2%{TMv7MlLvvuyUK!t)%>kEI`EV7;5L#&-(j`1L`JEtT zOIF#Ss>-0g5Lk(A8bT4j(2~nJ8GQmAk2Q5Bzy_PM<3e%hYt0RX6w|AGeRlMAVWWk zHL!LaQ7^1{VFy&|I4r&1Xk5hw6mgHmUEXl#5_oJCKV(n#yNRJO)2u%TCLLqgwSIbtJG(maW-*K`lYq)( zyfLq4++u)SklFdCG)QXhwpYyLNBhzknv4bf_$3M#Q@{2=S$(LjD{pnI;4uBH870sD zDPs)i-^Doq;wEli-|4t{?tRO;KQyOiU7q)S2I*nD@4%24Wfb}?bn)Yt8)Q= z{qO~`Lzfm>1WOl#F!HjxUCn5d;JBu?j_J?s#Q^x+5VL*O%Es8a3MmfqUMZy9scp?6 zz(Ja_K$QgP%2orT|P3T=Sbk+0A9r~AT^sB>s2Ofh3s zn~y_)$Se}t(?O9)*UqpiPLVbFdJ8LH* zE3*KJSJkNyV+HEg+&!Y9?>z%lG?yzYkX^|;iFxs{t*r*z0%jpSNTA4~3wu&7gvOhoakdk?qvI%0vIKW|nVT)~bp!{q@Nob5YHXP5Zuz3{&=n zhvfK-#fA|d?F5Y(!7<$)e*I)exu|pp<>DFo34I~Pt^fxos@zR&jLTbt4BJ^EAXPQ?i5rJRQ%*Vbn0$An#e@iQx72!9Z2OlIguecHN-U!7apY z-k5ydhF{RsB5k=_$M4>yPH~7Z;~4GjPk(gy_%1>|UgR31DBvGnW-Wq#=CuFg6>g<5 zQ%i|TJK^?WlTlRs$qqb+L^N28h$xNquNQ4wI)<&|AJ4iwDf+|&eBL%`H+mRm-44#aVrGn*;HN0+4wr3bNR;XQtPY#$2uRby4;_)e(Jr&rLIprK7PAS zLs<%}uWq`v4yPkr&;-+1LVtw&67pc=PN$D^fUMO(TMuWL^*H&F;*G0*9&F|J<+=&O??mxYuw4FT+@m6(i6?s9eBr9tjUXl_h z4KCt@w>y8TxGkkcSA(p1d=!(ee-?T}rB2gYmX>NPBClTNN3^QWK1^hvzeb)sIqkFt zv0kXWPv5jXU4gq%=g#$Z-001_UxYK{M!fn$vvDNez}Am|*9}w5r}x}vsTQc!=fM5y z#*Eesgiz)RbB-@keE-PEnuHvuM$tKw5k&NiY?9B>&g4 zdKjz{kVCiQ9;1)TZ_I{k<1Se5BgSkfbL26!2jM=v)$N_fSL}8_9Va1+{azQKSBsz| z*ZLALBqb)geg2zzciZb#jlN0JZLC^6|dERuBR{lbMyxOL7(-ssN-z;zjZQ6S<#iZS2tpD zRSq}Sq4p*cwjq8^$y_VqpkqSmy=mHpEdD-OA8YKqQ1Wx@CT!cHp6oYC;@6^MV2P!P zdG2A(7^lYqr?Lo* zx#Fm&lg7A0UgH-((lpjlRk~;)!W6~j>|G|iX?#0yVau9HGP;QnZi8c}tT=Z4Jo;Jw z=YWD=;VqUQ7DFDDlq|%2rinrUenuW&l&Ed=t*#!X;+EBv(yN0&HhZ`=&k6LG9|;d+ zozwC5C#zDP34EjO4fBmt=!o~O2XxfcuxrE*D} zq>G2ZM}CLc;)z=3_Ap@UeVaW%bpke}2uEq)B3!_TDpJ|Lw(Ia=xwH_7!y->lDpF1s zsGW>8b)V5l+jd7%Z5q^3f;8ly~`p!!9rU->UjyX--t4`J8&1ruR0f$IJ&sqcV-=EF0-0Vir2olNMDycs??>R7aHjee zhx92ap1p~?^js|`j;zw;EQ{b8X@fz9os-+@dO2Z(g@xIHL+M(G^JMD<-#|UOA5uLW z`)l_;wU(7G{S=D_W+OcHL(O8rpKvHhryTPvnMo{Cjwr;uIlw4SbZ&G}CYkAFEZ$N7 z66(Tf62nKBFa@--WhTu1VW?}}RF8<=`|O84ii9doGFv`yHyg^+TP7n-+IZh$ToEu^ z#-oEG%Rj0UE!A#!P^EtgOGk|>%OiiZWKDwP8z>(I)e=FR}cxujxBwkF=M$A zMGsGEqBVY;EB|+|_k)w_bksS2TaG#$%9nhC{#x2;qddT)?m|AQ=RHcQO}U7x)jD{c zqEaXQ-D~#yuaOQ2CJK&$&3zu}=jw~lFuxwcYK=cKqO`|1r<}X1gW&k&SJ%NEjl98| zFD&lazJGBT-6n)^(GvafD_Oox_JMvdKiqJ$pe%FA$4tEFY9j5}Ji1Bbva4?I>{e2H zJGGK-Z z5J&zea-`c(i$duR>C+VeL#xG;eE4F#7;1s1o4E4Kdi}1X?{~=uOyi0=m1g?rLyf~mU@mtkj z{wO&M#f;>Yr}Ly9nM<;aeR24~0%*|IZ%0$8A?@5W>6#cPR?rEcriWd~-2I$g_#t{x z9`oM{C8?FKspv+@J~A;9s_!O`&oC@)J=wDm@y;*j!LZ6zUYR3>l1c0zcJqVY;rJK= zGi7hg-?Gf}DHJyQFdTA%Gf!r8ZOc4Qkc~Js##y2eHIbCnN3ndHR)NV&fihaC&W#z9(G{0&OJtEs%-Cc;HDMOJ8rrK4XC)EqAna6vvJqT1Zefdd*j4-;OXjdgsZaYQ8p3S$R7n;{>ORK8>VA5Ui)7G=0@Vd?G~T0pu+ zx|NXblo&##JBEg#k(BO`?q=xjM!LIGT0p=v?6c4LIe+JRzc-$>*1bUa>h_zc-G5Lb ztI3-zEwLG`j$~+hez=nVDue2qY?o8D2abqAbL)TXH};&{{~Q~t}X`|2;itGwf@>+L_~bJ)A(1o za>CBe`6J-fiu&B?3)w%o;N8(s5yOLZ@Je#Z3mx^z{JEok+*(+BEQGuaEZ9Kq{`&BV z_F8S+X8jw4={B{WM1S-CKBBs$h_YJ*H~MT)+WlDK=BiILg8@y?;3({;=nvY1`0N{W z^jjL+4`f6*(>sG1JKpel?0w$VG4#3p@zSTVaR+Io8@>K@1gSQ{3-tXr=zI0g=k7F> zZt}yVYbZNpax&xP>30$h8`)}^2eH*h`()V~U3b-&FXc(Tf;Sa(ijR8uVFo&;pwfOp z7tk@an&q521$CHugw;2;u9KhV#azuOWyNZ6f-R+gU#)NvO`ic??qmGMe;}x*FlO!GbM9)9JJVF-gA7FpO{< z)~ixcUS3&I0rM+N@b=oLkQjONukX=UEpWAzRk}|N#}^rT?=9xG9u)iB3O@WDYZRL- zHClqg3YBbOeZrkj!IM8aT=!rJxN8oBHAg*HUusZ2WX;CW|5uKg{bX5H`#DVOvi)6C zXFl=tV*igpgVSa4oEx1$OTtNrrOt=WJzn9^t+Y=;RHuXD9KDeTFT;vRN?hu#d2O2U zQ3z|Q{lBXp%f!FMqC^zalFS7Y{t0A?D3);+{UPx$9PduCblFtICrrYc*M2e&$(^#| zvfD0Tf(XOg*z#yN72O+LFUtya9FeS06k4}S@ms_4m9KQ?x=HHPBUe|+8*c@#uPzb5 zMM0$A^t_?c$jXIui4 ztiY-=A4>g$!eeV+-!QnU#!?~875Ld&3;hDJ_Xr#0t<;LO3W#;=Lw^5VS4ms@<8ysp zXtCnud*cHetq}Jj78^oN(x-VueU1synqDc()$^a2Yb4yLDdu9g;R7(yRHool7NyP( z9cCA&g-U8nBERqcy|}<*_bEK@!GVoIX2>^O$V*U-?f+kk(ITwwKU#Ez)Q6kaK<+^G z)R2`Bn@&;i{V>Ce*@qQnV=Flo5yx>~s^z3a?AD!%4}OVX2{fB+-F!_hU!SCh5}G^> zc3DQ8%7uMP#i-(+WCwpxVPxW&ed9iq&!f9avbADt@+8;(bn(iEu3Fho{A#j7b-z3K z53|w0_wZNeU!2a6P(et&4VK_JWFfi3A`uhs3>LvTlxK)pFog6D?+jk5cwrbnpYuwO z^LnjA3l~AL1-^`a^pme5zz zM-J#&`4Xc*UFIC!L3KaHvoWyfwhH-I6+f$4eqTS(__Y6tFRA$59?G!gC!M9ZC&juODLj3^2(rdS~hz)kl&q~ z7qdQ;(d=JZ1!$#y=i!LD46dvz7d!az60_`T4t=};znas1UWJqx!asemu9iPu>Fy3) zkWik}c*x6pH|obIeTQF)bg~N$giWuS#E0lQ^8+($!^T^)ae2EqCfoH7@<(L$Zxg?@R^MW4*KH^l!)e$Rz8`L=zudd0T!Z9{XjV9U$p8p@jR z_p?`trlP3%!%7C06MNyi6bPslfe+(9 zD;K+^P{x{+KENS0m)<637w}aEfA;y5hB4_#6DeM4@co@RZ_0i0*exqdgs$Gcf;u?2 zA)J3Gkp<&e^3NL70hcf9*!`ZonSyAG^hmhf1Y3`;+@EoRVb?*P2jWgr3|`s&5%qG^ z@{t3dCD|n}+R2H_(VPP3_OfTF-xFKixS9;0^~KY_j!neeqiNL5c4%D{xC@OPmHbE{ zBDd=?dCl&><-CVJ@DWsS(p=7>9VWzVktJ)Kp1+ZvODQQd2*PtBDy=A-fh3hShxFpMQo`(Ak+2>Idy{WpyNr8{zli~C)B#zZA@7CSWag0{ zO6F|Z{cB^U*B|6uuvj(@Wec*zdOMt3+|O-Zc9}1q(9ytYJ8|1P{lkgkosMhq+V^PL z82_XJr4?$RGE%R{@{r3uxyw^@*9er5#T?z*_!yxtcs$ZikY$k3KsRm_+2tCyU0*C| z^kj(kmqAx0zG#Lh3{#lSy1O-63sa`p%x#2LYS7$MgV)jWU1W^ zLitC^Gh}B7fy78}g*49_mO%rA=J+@W$VL)=*dbs_ZU@J zSbxLabN|{s(`9_|>-^~K;I83R@QTbe`MBP^8sYL#LWh!+z6Vcjkc0AO?__;h5GxZ; zB+R{~T9BueO0*WML81G-+IY36om7#q68= z+ZH~bmGhF7W{}wbUdps?kNUf_)GgU{9o;JWbY>5YDNx0dysYcGHO6Xx4b$zctB$kJ zAI9}YL{-jBY0+Mq<>eO%&G)t} z7zvP|T0r)8<7W0AEle+X@cIho?1J?3=kG6d}~o z`++n(aSictp`25=k>YPcNNCnd$&d*=)DU#3u9|?gN?oc(bwu{#(qU6HYC=#$iVeRy z@=u1Myr6LjR-KCPfw9g`b+Oc9VGCVl5jBian-`**iH zAD+2yNCQ6!IP~EN;F9`)5Glypx8@=KJNXRcHPWd%)K9-;KGRiT$OL67Bek{mQw~7$ zY7KLxzX1r!9LcT!atdA4b>53VM)Dy4>vKEK8F8!+-_c1{4c4=tk4&g-XM>Pp2iK5S zb?h&j)z6IYe_?5j6q`M^x!YB(Dl4}0C~wTxU$(-Au8eYRXz4^KF6XP>)E*1c_vUyM z>(rF9ud@jxc~q?|KYV(Zvn!O$5)VzVZTOVj2j*X&J-W&AJ!akw8e2$Z^Y&>l0_WXO zt&88A*x9XDP=9zU*{dO4(+43jx{X8W^!b2{Q00E91;8k1BtJtf35jVm8$W>)MyXL# zQ3q5v7wF=^OUp<00se?wJvrwUNiEx$G_pkE>YcWS3aIe_Cw^NFjk_6&Dd~= zSHHf=`-7#oI6lw5+Kc!2IVC-`M4bxmcy&y5Og>MUra&IETu?YL0Zl6SG?hZ}w8>yp z<0BDGS(a+Nk)?X1)Dkmakahak7ekl45;&6jL@SEVsoZI@!*_^*F0M@T2F7Ly4FE)O zWQC*nv6KzcAQLZ&HV%k!GRSjyD3arH_EZ}=3V4PJyeYvZZ8(8|bq`(>d z->e{6P(uRoql79h#oKqfl|%!nRfH%;gcJVVX~{CM{&~EEDaXXT*Z{qoCRZ$35|@wf zv_icdm@b_3{5=_mtbY)d#-Q{KigQ+<(xM>r76D<*OP<@(v{0eHF@8*bLUrn@4M?=? zMFcjDO0vgkba7^B+N~zK6g2JINee+voWqB6yyMzEvAI5p>${+HVv2LO7D~S8E!ni% zh0m;$C6IBh9uw11VX(*mGT`c_%fITfGir~Ggl~;%z2Jc1`}?*_(K~Y8ZIfBr-WDUX zJdI`(re$*bUbyBhRQJ3J6R`VsXGKQCO7Q24B=3XP4Qmx^i+|&Q6hVlsA@3hEsgnnw%9AW4^ z#+8#P8NLV^QomBEBGdvG?JBeO^4lhw8FY@5kFdBYTw3Mq_PajQxeRF1BQ2W53wJ8J zvYTtpQu5QIhjGBOm8kPnzNlmnaYBM;ba=#maWL*_U^Czs$QBI%`B-F7HOM?2S&-f- zM8oCe$7G|Ks25;JPSzTCj1D-8_nNjeZp#&0?xY=+-l~n+v<#d4dIVMge`5D$nHGg@##I;ez;(PoY?A?XKVWhcr*|Oit%O)Q&Fj1Mb%OGCOXn`u| zk~%5w#(rexC?@v?#K`;$(iNIA&^`Zd&0s^o@yY;Bo{JWz1TPZF5(3I3y_LyF)<^~- z#aXv<5@g>`7bZZf{NZO2+B^--@ZXuH7@4{8^GMxO(7~ov`p;(S4Zjc)0RfzdCe5K6 z$fhOA0Yt;QDszFuV_PwQjf%1nNXhds63CUvbviv%OWV{$P>gp*CFdJ~Xx37Uv-Z~Vv6*3o z2EJb7VIrtF8u59!-uP#lkhd0GIK+d>chhFu0}Jgpg{t-OC2$;HP(5mrtL<$&=N4`1 zvc1-*nv3%m1*D--?$I$qv`*=3{Eu3pw=>@a_4|UCMd%2Hb3Oc;E;pV-je0BZlCVhk z5Wgs5Qtytrt$9KwImySDNBLHI6yPO)@~?YyJL#>o=lD|Xk(KG5wYhsuR&1Qvw#Z)^ zw%*iA%JRm#ie294-8b(Y-_8SxeZ54DWlY?r25e$zBKL_ok=p<;WfzzsFs~EN`*++g z^uqq-tg~^!mTBPdnIW|+h8Il6y*&4pxar>-N9@Oc&K3{@9f>jaZWOAq&&}|Hiufh) z^NEqlY7FD0BaI_%6n3b{iFn8W9cN8AiYDf7mU!JUqcu!hK_lrP%4!z!vi80`?bX&P zVjbPQB#ZYl2X7QhM!u&i0A#=H`7^2cuGy7GHb3Q2Hqk(bDDhDGbN^R+)%HG zMtp}G@{|b~N*;#>+6j*4M`L|$X`0+KB!_uQuG)v3`9D^-1K;6O6!R`zr2>%O1cf-~ z05V&Eg_vL2NQ$g`kFZkEG5N$I>tRKS?Pia_MF+t6t)6k2@kdH&E{cIgk}fHr86oB) z{&f^j=5og89A04vljx`aNy%Dy$4&hr!@@D6?dUT-2z|1?yn%;2u)6;r`{ z{E@_HQoF9V3S1O7MvilH;}!=Xqet31D&j$O>i8-g35f87{HH272EnqujJP^f5`;= z75)JQ+aU5H=3%C0Hfizpe3H)`?K^VwqP9XQ4Ray)w{O)2dGoz41e{?7sJ9G@7s9|Y zQEhD}9+}>pCZ>=#j)H^? znabXKXxp`N7{W+axr)?K_JC-tmI$}B#P?cN=p#!B@-TcNWgFivP>r|JFer?6a#1-Y zxJGn74jk4ybN=r4Vv!}(yCIWn0q*G+RZ za;yibVA(3`(5u<93`cHGbiXU<#hlmZ#-VzrOi|;~4952$$XyRdoh>jvDL zPg+%N4;LDf*rqN<|Mq=0{NXAF?mP?;vW)n=rtp~hlz6pv?Zy6`~I5Vvo{qM@Ax(?XT zqqQQ2p2r%5dvHY~vmgkINR_!1mlgED2nTS?IPYgx=K=N1V;Mz3+Ov$w}h>(-(yB)b;2k`3$y^?Su2&KcPa6P)T|f* zmSs%vq2&dsDf(j&vD|Bk2;RAEFuu%$mDT>;kQ4q=U0J+vaD;@y*Z2GGQN@(aegpdZ zZxFSZX5mxl?W&3P3zc)`JMsm=67n%9rmz%lGHTXdgEgHhi?}oj5P+Gs7c^y&g*bp% zIWI|tEE#0rItr5y`i3+b37EU6*3E&I4 ziQ*b~*#B9QbWLf&=;Vr;S!|tCx$1yC@R6k2wc-K9`n)}>*Rk$`R>Kuj>AN$m!vt%+ zv;CH(Ze2PXQq=?P5MW;^g?Makv`82+JC%?tR@*kp{e{f>6lCM$2m{5;*Oq}E<0fMJ6REKa4h-lhmo?4z~y|!oCti=E2>&8 z9O#X+QuQ;Gpt4(chnLwW7~5jm|-nJ zl`J|Dr<$utJ%tteu*nXCk{fa-U#{r`Dh(i+d$gM)1@3Wg4u-xw2DYIZ@^v@p z8OMy`(D}t+d*B0*t}kfusrex=%3d_(2S=FI7uckK7bO7KK4iQh#J zE@B{(N&Qh=sEX+nvZT97eFLw*LbvhwS3aX^aX@fr(9%hD0l!E=0C4P2ThZ*dNQ3E$_rtSXG;$^XJ4}e+jrjh{TdV0SkRbO{dJD811mD5l2PtbS=*m|OAqxN^SLTCSGx7(HV(Gd{i6jeR@k7?w zEI3ULQW6V(&JvhMdvdyW*U4{3)v0|z8htDq)Qad&N9d$wM}7dHzyLz0!gTgcWK45pG^Dl6ymTkAbR++_dWGgmoHa>VOTJ5vhu~*cdhk;MM%o+G zEYxIHaC5L99_Hb@tb8S4B@Hl*<85r9L#IuFt(7t;gXBM*9<4L^J#0MG_Trb0M_e~~ z=jg?<+<8-{nR*}9r|!R>6>?pwa|ty^M3buF7uxUk=6|pDF-!J^(4cf6b^lC!B=S+~ z6d&F%Epc!0-I`5t=!XCLEQQ9HkRhM2X?sT(BkY8Uc+t^f$^cxzBXpqsjUBQd*HWsFEQ9_Jnajuay>HF3gULo>**in*QTq<6i<$k3bKt z&I;D2y|;iMtxkjjeAF($zI+c6!{$FT?w%#v$|D#d$~ZFj@yt<<)Df_4Wob|OL_XuqECp`wj*GWa00ng93*@a8;uXS@UfH$RV%t2(4GJua z^bQ1uDc*5D?n})?HlZ@R{WWbx>B{fu;}(224jTz85#SAgszy`1gKG*@9quR};!6NOtK7 zB@1yhcEnLl`RfuR5hYp7Ui_4(gE5Mhkw#ZFqtvZ4PY~+<>R(BhSEl-x;H-)2?d+|V zNX(USvF9)qEqP2}*o!9aw1gOvCqh2V5dPt~^3Ok;37HD`+G4Awf$O^Uk5M_pb8pn1 zB6tesoV3r|u*a**0>C!(io>Y0K)eq4WrJ440V&iK1C7vbX^l#?`JO`;+c%(+Z^zcM zVL#lSIJ`dro{&FI%qzi)fs(0_@#`k)O=PWjos5(g3b~8UqZ`|wVX_nT3nURo1O{NM zbJmN;`B0uA8b}Vy-7dXO4(=ad3e7kS-bb4U`^WU^uh%sb;>pfeLLS=2^zK z!zjkZiazQArTL1|h-=F6J?Lf&nEvSbF&;N7rQUVoqPn6@`)i?d>6Y`Bj_6zB#f|mK zlRpVZB^dPK$EEOJ7Iz`aY2HQS8iG*ZzH zm-k87goH~dC_bOE8DDbVoW$?8rG4ly7vx7wx;C*)=n1Pg{VTkt?ELrV2Labz)c^cD z79>e{c?2wf)T`WwZTjRiumJ-n@RvgE`}xHKkAA6OE>i0fjYO<{lHeDM6>~yE9h`UQ zD$j<7kb`~iX=-ThY$g%{{wE-7%^8=p3>h+JK1-%CNr2<|2c+1kPr^UgxmqY2nZ1iL z1UxYx{+Bsx(Yk&bR9WHdZ*Ze->=zB7L=par$p$63<78s&^jPtqJ}~2fPasVSpGF(6 zv8X^-J7;krhl(g>^E7)&F}xhuF!SrYs6xsb67<6o=jOFzg_~G^V2p2^W>3t1jEbp0 z3TN2hE_*Y_(<+F?n@Z`A!MWUF}=G;3hl$p0tYc@3K{|W zw!#{lh}mpU3Z(BQ(*(du)w3-9I)Rq$&EOWPVCwqh+g4@Q@OVO zM6^s|=X3P-B-HjgWo%P@!=Vy5=Ecld3C2&v3a5#4d&n3Gs`Y5VQa}= zDr>VKI>+N635Y|wC62Dq8OS)5gXzw&#!O-)f`>GX<$$5u$LcVAVFtoX0Snjm=IKuZ z)$c;hh;sn}CSQ0}4P2yR{jGHRy*q>)bKfx-c3q+sTQ5~Ow~c_d zq9T(cAZt`Q_75rmsOId6kFnOYABan~S@kqKKLJ8eZ$ci!-vY)P7zn9xlD?>jKEvSh zZui0}_BVeExtPT|0un4G%dw89*PC6!xaD!%N*>#DU4|FPC}4r}Z(lsHOlVB|64N|7 z;f-)nFd$v3V@f@rue*Rmp2jiOgMEXHa-H6rS&#whr;De$$r$CeC2n)y6S{w~%&~#5 z>hUfXs2<08_w>}RHqPr`>g#c$S6}fSl^)^;Q74^ZF&5X+msBQucR;Ij^T;$-q5)LV zF4+0Cl#t77-p@oXkjONF#H%NHo8*bK7tRdnI?hKAD*6QciCFecq|`HU(cgk18i?8+ z@mX7gO9>FYG^S>M5O_qA{sD&0%#aR^45`kF&oimsbbP?-p+e0fD{KCBGvU(uCdTxc zEYQLqt^$~^Y4RonES@K^LQbXgQ_%0K>B%2Yf8?D+6cx4zw{M`O#UE5rlL+=MYI>w|xe5?8}x-uV`$JEB@j|Lp_R% zPz^RoZa?kz`sUvt?YAYm`(k`inr?4p?xG@cJC?OqP|Fv0ryZ~f!__|A%Zj$_s;5=O ze-B!~S!w#5_VKz{Gnn@FD2@?bdRY^aNQdP@l^`PnC_zDP24MJx+Eyr;D6jQwZ+mV0 zd3i+_Prj2QA;Ngw;%&{@(JVb^4T@8N*B5GkNe3ri86g;j>JgbJ8o!__$0AS_I)2r)^>zh-7TJ@HHgO3{;hCK z;^Tf>iu4W2W*!(LBe$^prqKP{}j6;>;ND|uJ768YId_(Kx`L>pRon@aJXGF zMcPU3r|vOR6NI!mJONW?Aml)&lDh^5zpWNyiUld4#kofHEQjAz>7%WDR4{P$+BA5l z8#Urbs7W=fckM`3I<&ECW>Vxg4RFuZi6Q&MEso>_4&v4aNS*4>Vh3|)t~@%B|C)|&kukf7&XsjEYXe(1$q-l#+YpTf;)=iZah z{;v+9CShL2xS{Ni%p5z%${F+wLy1uJL~vR)RI7{CJr!-rShNICKc zP#8mM;k<*y?fXfmjIbNKlrb!7nqZ5_WQ5Acis{aG@WpT;sSCyxy7YSYznk|oBBTR) z`sSnn_BbeVoK9o%eNofD1@VXp;q(KmuI>Iz$*JwxY;J+S2z1s$coxb-_ZgX3D^HJR z-<)T4{3@+>i6%BPRy?&68k|j$K8mcvkTPGjhM{6$lr|JjL5HIPlHZE}AZ&lCag`>q zjrea5UPJ@)Ojt4+ymPZDwi7l~C~o zb87*Ww9StNUUIM-Zlb81wQW@+pNBgZSqP*9{!ffr#)8{WWtvnyI;TGY^Cf>e|aKx=f* z1Jv(8LS6=$C4MD6T|TS6eh`_VAwP)MWzUiW-*~S()YX5T(<&xvY%h?F8a#;mx3wbv z#RUzu6+>2+Pib1Qx{MIMnrJ>0UE-uu@EU)%O&~s^Sl)w)NDj@BalX(!(_r7Au|I5K zYC91Tr14`}$n=ditIFUxi`0+&F=$NKSJQOUFUYZf89=|uBnK{&nlnEIJ5vkoI~oJ+`*5+;I=hBTAHdyD*4J0#4uP2&9n zX>*q`OvIv9^5ZX66@@!Z#|lQ6wkH{WTeb?t>Nzmh+eH}e6|9?rj)DYP!^%EKeI{6~ z4uVITsR^JagmLThy$dx`6B)HSrxJ58JTpg3Kb3AArp2GA&nr~i6#b5xRFJ6l)!HOHvlhtfg;GC9mc*7n=4a>GFdTzKecZof`Eqdhoye z6l6a_UpYektCkF8UD}dFE=D8}FM}jUITuluI;p?CA^9$T`Hu4u1ics5;{oc^-Sshf zmkI(X1xcD*5CeK}0&zpU@;GQ^ws(%hQ8gF0(J4q;1UlAGG0oc}qe)8+EqhcwLzv5q zY#VwKxTg-I?i#}9qk9^x+U)9pZA93?-9EM@ze5w|R&wp%ct_4v)rjZ|EW>D+4(=;^4AUGj^ zhe*fKRkGad9#4V3k`|OiV*Yms8Bc#IwamD0f&NgBa#n%Hp~SyqE0jhd$NCKhXsV)n z2pk;1+eHqj{nL-Vn>lbZ`a1d%#;G_1v$*r&B3*JG5J6mF8E}T!9v2YDFnLNbh2}97 z`m0k23;$<8A2D1b`}jRY#-?%&_exI26Y}}`Zje*x$dgbJVc8wJdDa|rw=Fi?l1n!_ z0=^C0idP{`5gpjbUsOKTo_X=30*N2l7~Hio1rG>r>;TKweD1u01ie*{HRI?O$fdTc z8%wgT4gqpu!V*}%1|1DQ*ZR{W_0MX}ZEqSR9zE9N<1B^N2-eT?xb4;AxE-}GV zkVf16->l$PALf>$tYzN=J2G+hx3FRchMIhA>IpM`gJ=x=%()31=PqR1*Jp>PX;SnrXB8ml-tSph$Px$FFj8qndgJ^lja9qtA zN`JG?71HG*k1ddpFp$^mr`S(Wo1xvDpOr3kOWyOiwmM{cUCp{kd=C<3=9<9Rb@tFM zi@^$fPkiqRh;J^$hV*(ZRclKRTBHm~x|vqvkdkx!Sl{$2aNvvd9V*p?O~ZA)+X}oG zgWl)VyS3imyO_KKzC4f>(skNy@7VB2C+{`S#FPOIw@lQf+Xl^jDqW;59jnUdKvC+E z^*uAyk?v{Ax&9Lqpv%kG#TU`A!gkRyCuv;D@tfS_-{xD0Rz%)dzPfdyHMVr&0}*o! zMrfKE2kv+DvXX9MJ+=%MmKio80g&=_hkJnP>dpNH@1PTPISYx}P4I_iDS|P~r*oI?({RQpWlV+08QZhYs=mBRR+; z4Yy`Z6rW=t{789Qw&pI87N37AcYp@LRIP8l9Z&HA8ZwLX+V_T*j?jAW&0^RNqY9L} zWrtC@vb>TD#W14Yt?ZcpcV&2#H&s_hj7#JHAc2{TVUdGkz z)78D>HPy?_yDS_ku!w727E7cY@m#Lh^*)ydLWlyfZW32@?!#4UT2L}J?&9rlla8^Y z#(Dg4H;%C*@iWr`5x2r!lP}*TMq)E({+RkiM?P}6*zD8+%SSI^$o#;9NlGvv>ryJI z8=b}V>BjLFNduczb$xi)^89bz@YDcTx44CLQPK4K(4(eF?o4(xhL19kqs~!y2$kUh z@}YbQLh)FY^PN@P`-{2L3!wlL#(P059&1~%Jee)MW(QRt)fU$9$iTO*^Api(hAwexc5^Y+Gm1Y^~4Z{4$iQ=k?rrXs_EpAm=I-mom zz+k_5^ssM&nOy0MNK~X<6YLo8xc!v}djUJon|X4xzi+8xmUi3B_3=K~)**?u4d*0#Lt#Bxh~&p}Y-$Bl8EmO7IKI`pO{|o_gPhn8FJL5`LMm zR>Pxew&@ZdXP^8{AXL#Lb9zdA0FTw%_#Z!jc}H|Jjdbkumpx6-GbD*l3O>5w78sbl zlh(=j3MW*!KLuwBl9ncEfL#LlfBX0$9Efz7{BW%#!$Ga3;G^utGc1}pyEXG#OVub+t_~}=u<&><8fMMCy~DLM&0sj) z;;k*PlA2M-95?0c+-RM&gB~DU_Qi@wSbO3likY_FRL`mvr2?aeMkDJA{O?n-p~Nl+ z<~=ER_qX&1PFTHsT2zumA?yB#=jeK6{lONlLvjf1-69avT2tkgNeOI^Rh+t(*ZhgDs0Nx?+D#iL|f>&@jZyP|wW42a-PQJDQ*tqzVAO<#7p3 zR0+6T+V@C_&%%O&{RSTz_% zYO0`g{^9~rk`9I1Vus&}zhBvcIbr1J6OR9QhE(P!U!^I?c^$w!3(2!E&8aP$2!q>F zi^V`pK>P2*z}xI>xmL?yKRp1qy7VfFWGjo2y=G3(lu|n?KbHtMa~F17Nove2JLm85 zh^N!k`2QW2D9v5)E)5`e92yyYHZas%_wuBL7|Q4kw29?w2rUTigvoe|uJMU3YC*u zTXxSK(F$2-y^`B1fka7GUHdwfgae-hNtDk%&c=4>7$1I>8ZiO!X!FW2gMxp_cSB<# zI4zGzbIi}Mv14wq+O{%z+(9zGM`~aC+kKyyK65 z(Dg}WGYkc@{V)>@3sWn#gIN-*g+d`Vme%pWI9Q{5dk-dluLr5$NiwlVP&uaBf4StT=~qg~FWuux}hKcy_Ox zl@;A)0!(AB!OL^ ze(K6T#P??eQC?#wjHUHjjLOUzz&;Uml6-V5x47}s)n)KF<$)~ z2hi-hqM;P32n6=5IK-?Fq5Yp)qoj4*dmjsh1Lo*C({l&lHtNE;inY_cV@PJ17T1*8 zl#k+sYeedg1Rg5SZKm8*H6mb=nB8agcAky-=T%MuO*n zv;{kx_bX5k6rXwi`l)z8G>| z3^(rd9oG6^jAtLL!1o6DUxHRJ1Bd^hcF*mcR}LK7l&Csu{EjMd)701Big0-Z>Mf@Y zK^2S@-IE&eLZCZzKp}ndt77GCu$CS*&3Ebg`kC9(8!bZEnGaj5I^%hdd|?Uf=quj zY2iQ`T0E~bB9`GN*^G885!|00pJ;g4^-_h3+or)UHAGs^s%xS18pG)GjOsGX$+?E( z9Q>OZ01)3{1dL=+?=v%a`1^c3Zy7!%x?)!iUmVbSeqIVB*4 zx4&wu3R@M^VN<&~UAG<$-8}eq-7brAIn57zl1@Dm zjR2Jk9|@En*rb^d(IAVR&)g@l>)&;6bX3=2_&sIq?SFB_pD@xhOzj9bb1I9pkefz` zn0XuV$J2r?>c}8DbVe+Oj9pLNOjU93Rl4O7?5NCiNmE+VEi*iW6&U*%J`^X(U3|=Y zZ<%B_Hx~|jqA?*Ij-@f_eSR{a7?bsItlaId6N?C}QCeB6c;B+vJv9Lm_HwZOWPW(LHEoAW@^?NJPWql>kbvs5#mXxyp{M(|cA4!@rkw5f+XzPY zp`2LAr0GK;cU_-bVaxgKi8~SxEU=UAvpIC+Y?O9rYv*CRi;ridp7jbn~7W7 zT$0GJs02bwFYWoA)OrW}2q_5o+1HV(XD{lnr(2|~v~wCS)OSL*|C1@fz>wixW^cAg zXwT4E>}-?4=MS-?C1(jys9($W`ayun!rz+6}THEX=)QN4T%w?jh+8YH~E~ims~j zo!A$)*(mpZCtjEE8=3r^3`2TAxx6k)v1d`3)%kOmPWV}nQtB*Tp1!{R-|NnM_!mKb z{=Z2p8HX5RQ+Y;4lmnFT=UgL(Ip; zjF?v{jPs*{sa9mP z%T_@#NcG-?u#`X&*f$^X#ff&GwCJ=mLHPfOaB-azuq_b z?pN=oU~jXlD2FW%0BKXVHo}P4^}H0)U`uQgWSz2pWjth_pgKv8ApbEMa%$vsNa=AS z2ErJ$rWc5gTjEXIL|-N1vIG-!U>2kka-T*TcCqye)<_chTd%wvg$^NOl}wYtdGt0q zA++Bl4i1J_Fus(!x507Tq@D}U=QDX8;vi{m@iIg z#gaJrOhi#&bI2O%G|WLJ3+~-x`KI+6dJ9*-70sk(X8If-nIEY{`iVa5Zb>Fne-r*D zJN9y?;b!Oj){Y#Ld3D40m^*gp^#uJEOt)(r)i>x&@WH8pE-Eg3PToYj^&`EZYm?qN zzKd~$$XI1OEq$9-(1?<{CiG-u)(R_xR-_|X647MBHYIF57Pw5l|emS}mt>OlsC1;T-#81v^IU`rA@D=?f7kgMM3QuP=U_OT>)UAvW) zp97DBzO+5Z7!`sc$@9bdsUec8zM)md*hR(n;3${r6#AYBpvi*s)~4lfdFXae&4{1~ z;Hr)cGv)LayZt5ZVJfw4EKL>-7y2*3zQmouWhkOU*BaLSQ&_%c?bFl}3AUMrIK7KqcFdsrwP-~ZpE*_l z!uuf*;GqNy4I#U}{L;1=i*HYM%^27Pq^uPn-*5TTVXw;>l4$pQzCd@`yVi04!-z)t z3;*^3q$t~WU%}|56zdPj_rbJ&Z;#XK2#en!RG8v}?>5H23;NQtPcU1;a|8d9x}k_& zz#jR=gz3c1ymlUUO9wVA zC5=So*?0Nd?$v}s!p{4r{Up>53QOghB6kFg5M{m`J$IK#6dXg(GhQ8y@WS-Uuxt_% z5-QJoHJiP2`*p8TR(t9CMgQ6CJhy}u^7<)JJpEXn*K^F45A|Jx$3iio*+2P|=sHrU zRCog4bk(e-obQMlPiov860Ipc3l%ChXBjWb7$v{v3w)i7ZmVMg5g*PF-&%^_g1a!p z=yo0sUceUau$NaZCBayalvFi*_9KT2TA)Px+o}fi3epf`h6n$J{s7(VbG3!`j$3K} zV3W<}^PBtz0qH|zpYv9UkS1_jG-!iHjXkm5Ol-5U(bze08r!zj z7>(7~wr%sB-}Bt}^UnYCnRCwUv)9^dUF-V7`q#_>u;+hUkv4hecTtdhmjd3uqvHkBK6qRB*Ns2>OdSm5wCrwOr%vzyk8Yz>_hVHBJ2}Za=f9dzT~S#BlO{v?KZ{I z$#qcy8LCl9l5A0e5{a}p5k7?(tdok%??Hr21}PKrsdke!@_!*%}s^;60w*G_6$ zn%C>G?sG)zxln_THoO37g>cYyXxdLOehBL3xl&R7A1?3<|D#$~H=^A>ZB^Tr()%^b zj}hJHRITW#eDhGFz47<0s^6g-{HJ6vE`r~I-~_!e@yZkDaw9Jd|qZLPkQ;vv3vt-Qi)W1$=SXX<5mvm{q=)K|^H=L&I%a7q8jEpOI?{uG%x-RQ(2k zK;V0tlU%Q*?&}aF+-Crv$IK=fzDYHC?=;PQ=dZkJo&CfXN_J_?mB4_lL%wK{m0;mo zB)Vc|YQ~#^We(np!nEG2qOD}y1M;2l4VhcBt{OfyZ#DolKviij6FZ}0i9z3=FEn<>@ z%XurvvahH^HXTD<5}5A7+z5f$HM0_J;Q9sd|1MPKH_f73r%QYb?j27vyBg1#V6 zI1}4M2}gi$42&M@vIXWLp#*e>n;uAlBsIxwm_(#ZwP}Vt7!(fIvvU-tj75SoVrd;N zE75tHVHl<{DRGRrP0grNd30|z^u^uN$2J4z*k1j}H?5dXrNcC=ukyfYs_@}qO`~Cg z-Xvb#wVpQLvR%n>x}}>l7x@0~s_rN?1|+zbhd3#Ovl=>*!OH;af0;2^n)W74J;(rA zOz&|eyMiE#00FGK=7ZeVK_k#zpE3+`k9-qssc0H8Af{iPX3tAY+)OnPQ{nPj4Ri@CfIaw=v7Khm(%XDS zR>AnNRG6~|CceFJd2l2=km-2^>buky*$bNFIzh)@?BT1CtH#LxT_l&)HC{(>_~q)~ zouSns6_kI5;A$Arg*NZi!S(~Lz(z@zfBgV9WQ%f`;kM9;-qTDV8U6UHpX%oA&wz0_ z#I9%2b);;ZyE~^Jkj{Q%NJ&eVtD;Px_A9bvxHdpmQo^@9m+P84uk935T z+#|5z#5zD3V-%*_s8Lsv#E-8+W^=LT+lhp;zv97boQtu5B=w^ z-$5HG)b2-KQNuk^@6;`+pa5-5(MtOeu_RN)5C()9E*%`;FZ}_EPqyt5yhw4f5DKX(Tg**Ju}VD5Q%yj9iB8*|*n6 z@A98qPGt!1of?i&Ww+3Ggo6}_8`lH#&nCWWom@l+SIYmHsgU*)UHQu{^lMG#)tW?K zY9PSw5h@noTNu=5FqZl|M5Zp^vcp5g-yRqXhm+Ssliau- z6#B=|e7?${AgD0F@wauia-Bu2B-My`bC}Igai2*Xi(D4hv?7`e8?Te*xj&Ibek7Dn z)pMnq5;Ntb9*k8HDIt$Hlz_nPP3_=WbS9g`>Hz^Ds%NDo&7{?a-f@BUv%4n;^T%Qu zCga$D_#J{qEDG;Rc=wET70j*WB<)%f9%F3Hf~NGPqLBiq{(z2D<{}B!2DL4xa0De8 z7A54=KJxHFfciN*Eq zqsa`aBX0$}?}~EwNO&?_l|LMTmVC0teSAET%C?z^tE|d1|;KWnwqZQi7VU5D$j~<6+Z8AJ(%93QF~~ ziK!_=`%dT45zSl3XZ91K6EOP;j)tY!XB-&m(an!rnNm_=wjRd>j^N+78tjCSRf9BW z1o4~ukfv~~OJTzuNnx{QSBg%aaCHi86J1X3cc4?(J)<4V_UjID-`B|E*y4;x58dlEl_4A-}8_HaXdd%vcNf*ZFX=^epU zG>^dby{-2&zIhJTUU`CFCFIaLtJU#*8-E+TOsyCI>-Gmo?TS8_{0 z&&Hr=<7XvJN#rM6bQ2Fti9Jn(z(T?u`s_x_tmS{nZCgPHBL>*#x@EfR@CDamth2Cz z3Z3?UPu||P9NqFQMxU+1GWhfsYO@FQx$rzV^up4)>IC6rm>EGwEzB{v)U4WR(}M~l zfBk6~GsiL72AH|0dbiunJ^Mi9e-jnsn)Qrk+dtDPH$XEEZ;S%pQQxO-4HKGACKASZ zZ^?K}=`mve(@8*Lu-X}R$J@qsha-WSl-J>o1UMb}KqJ1m!ld<$DC>vL*q0Woc3QO= z@fpMfnylElTT>GWESZ~PdI(w}Y0CsD&g2 z+G6uemVT14SBx{WkRyg1YojTt)ei9&i7`c0X&bFU$<6FPnm7XBU1l61a~ZR6d7_@_ z*Ym*IRj7ZGwzd--?&{Fd5g!`w!^<_JG(;i6VQBrjTycT|7xDEQc%K^{+S6|%&G#cI zZ8)0KVFTX18xOK#{?2qz*T6}!wZAXr8(U+W!FlHH|L-FymsQhH?|Wd{Cp~1!oxot@ zfNkI;f8)S3zxlUL*Fq&UD(sOEu%!vFx($nv9&zF;nEPZv`XR56e0iwPsxxrC3b?Xv z?p~PAdSELgsn|j$@(oWMdJlZ{z|H7 zaZFz(?tEwMT3&);nj4}$6f)RlWi09U31?Fxu2Q|+VkVY}&ph;`V*rgDJ6mbBz^z(8 zYbjMa#gLzH9ES^-D484S^AQSt?eQs9{T+e?N!bUT{yFTtxR@4g*Mz3}y{Ze9;&{JT zP`KhRsS=3h6AFYV(+*3i>e@tw4yW$bsZ?-|t83*fOZ zyZ>VsNsDH*(_pGI1(0)Jk_2lTjI0fEOkcxVwlL?|e){}l&=1rdyX#HuoI`ul17DYb z5=heT)1|ECRxG?ZFKDWt1l^-X1LJRwlc`7tL05lA?v6fI4adl1u^okoc1gx;u!`nz zW9#tV=ood_bevZ1M}jz;$5fwg%SeaAY7dss%kbHRJRaFk0qLLV5a*t-d;J;H|1B11 zHFdIu$F(=u`=c)pA^p@kzLE6a!F_qS5hs=d$aQce}BLcRq5?mvvde8FDm_fxZ_lMZa~K)`y}AU#Fm z03_Uk0*R?Qmxj0xtfVMDVOkWJQG&lQGb%BV6p;`UYUQ|z zq!;Q;nGRliXYTG@EUJTuk$V{M@s6VPN`8I*oM>+2J2};199$i<pVmacM+)m~2rNhhh8(OOpgj>J zAE5Jg26a8VlR$({C?Tgcbo>YOQb6oFSH155e;W+1t)Txkz*b!^ir4#LqDyKCcU7Pj z>AZwOkvzQzUyUqyN(Bv364#E4Q4j$|xuZUT*tImD6aRy8AobU_NdmI2q^BjQT_6_Z z+EWmKsC1?vyDu5fX8tU^uGuOtzIt@D1Sz!0{vXG~uR$fj2G^H+Ux_GD{8O+@c(|q2 znDOzRn({c@mrLHFkF}A;v*QRYLMq$JLsJkXSO*IM#A(86#nLj#F9DFwgw$dll=}z| zz6_)!`=cNjH-;-Lp?BafDK;M9yL+X=z}W&DFWIk%cf!`$%T&L%5j0ib<6{!IO&TE6S!_*cY>d^$&f{qTf+&==xJyqB z3`H0eKA)iwPBjM+ceCRRdTZ`9Ko|TtpW{yb=MdBcSt8^e;S1 zuvddwxb;|A__WA&t2uj29ZH@ul+D$1b#mjNs*YoOu8@BYimJ6hSdzQfZcNi9MR^qI zjHA_yvXfG@#y(3&my0ubzLio1-Z+p!8QGrVL`kEPN7;|Om!B``8zsbb5_es3L|Nwk z3(*kXp~Zu7+J4+lDDY{mamuir3lVGe$582A><}`FUZNP=(8LN-UutKOQ73B#v{FLx zB{#)T6VX9EeVT2*=;K|2ln`g=Hwsm!EDaUPrpWDTY(DDi@{%Pw6e7ZX)7&@rz*gFy<5;&O)3a285mu1*< zx;2`hKRANL>hIawrU!|8rbh%vGlk^ntUA$J$8tGo%$+-KX%_q+^~r9~&jx?*EbE+q zE`N0roE9a38IPYCe9Ec&##JWr-8Kq_8o(?4t&b7{Xgp13HeR4dX`cAVi6gA34Fylj z@>AKK$Kb?D&>X$bh`wX%`UPaBkbmH+3!I7KY-AzE%8r-karQ_W#rsAkm)jsz=P=u5 zVPupzDX|FtVm)k)q1fntCv9ueSXv_XUjxp~hy|##^&Qx|dH%8i zaq}i**nBsgsQFH0+)yw5{ypJ~W)3jT zpe`YaMM88Nzp{4w`dt6yW|%@Gp^*y#Kr9@DM6}VFbboSuYhp1C^ItoRe#r#6L;14I z$!%QMh{#kn%See$!5+U$$dT%v`7=(HLyu#RVi zhdcK_`R0GL+4_1`(w&cWD~5bNb9FYYz#V?sVTNY;Dnv-VP-*9@oE7(&s6B)Y=s8vn z!a*uff&0Qd4$j6uz>O|$)CytIz5L;or*<{;#nmPdG-$~erQh92G820=KN5p=0?~aD zYrC_WKwdbdGn{|fWYRourFNYDrYt@NLb8f{bLme}|2@+~^~7CH?w?#9&W45&G8PYJ zn-K#g#Ah(>ADiQ)!1Gd~!E?Z{63+zG*hV#{ilmpHWLubLpuXlR8#%P${-0eNFiX zUl6uravcbM$>?}~JJilq6^YTwxW8`mQ9y4f^{y=mi;{y8k*4EcQ$Gas&8SHVk)f-K zAoB8GKfuAC=OVnbAZ$uV2Bj90*a+92OjKJz@B4XzJPRl29@1a0U)(8OFE44dk#viM zbWLGO*IPe?gjVRuEj5l&eBIKmtnM!;YHy%D zs$UaNmsEHgR%%cq3^53>C{soJ9&PU_5^SHbtp@WCP`=+-R%IWw`-IN5J{U6T zdrGAd%JC$RY==VsP+JU*IYmqciput(hyhj2aV;mI-%l=#&nmqC#k_{) zFmOaCNNOBs4j#DD9?L%7x91&2!ok8uMA#&>vSYd+U6C%C@)tqMcQ`@;fpI=95;I=? zXb%r&f(SCgNO`sWzf}C%hROcsd9-9AkE6TLHqP|PVw z|4B*F13u=LjJ_1Abo?#w!LHzlX{?w4U?-rUHDw*8sNvVCC+rC%TNDJdh1~;{;#Bm< zV4>d{Zh}9APrxFh7f)QrmMJ0%6Toir2ate-U9!;N>i%nP8C%b|IhG=Xr~I4$-i9jL z98c^@3MDbMR;o-8I+Ok*DR#%4J-7<{!fk(+eBc!m78-9IwQWYQs@`~JgbxIe38)Ce zSMb#v|3Bz6r0mLot0NqebhVfw_?Y|^RiqXy5!)40V9P12|A7$a@gf#>>Oy^n2Frx? z`zPT@I9EdP|=5e#{I3WIT1ou4AKc4nDhTn~rk^DJ&2P*18+?Dn@ zT^>Ec@*!!EWx*I8oy>-IsNMKYt!&H*9xe?T;<@jM6OXHIhj6>DSIu;Q7V1gdV~_KD z|0(0Q^i1#5#oUqO)ERQwpFZktoZV=SL%dHxFZ{?5O|^w@4q$zgpzvFA^xicp|8Lo| zs*bz^{mp~4*o`LxHL0$+S_I-&(oQ$>`R)*`ynhY41yVTeC2>AtEB{4)`dI34q;=T; zXdL%*VAmQ;bMWB~nhxydcFCkoIn&&d=vJVP(8jcL$zQek$L?%E?0eQQ-dShrl89f9fUvqhJM6y3;d&(qk@*-hk#_7K z5g`jPf*!rFNix(6q^xWBsX*K{jC4D$XXy2MatPFg8RgFlIe&T@jyw0`UqSpDFfJJu z)_7H?fV0{{+7wz}0^8!l#(+VkbDJti6JE>kSJbMhWvCD5x(OpZ)AwE!EY{ox($sG0 z2Dwh4WuG?ukJmys6E0Z3)Y0B6zBdK@GsHGz<9cvc(MH!O0{JN86pP1)q6%83JsVI> zD{^JiH63o?W1}Z`%*M9h4?&$M!O_tLku2D-a-B2n?s8M%GIKZZLj1UYR@igNYb1SV zWibhsF5WCmPhi|eAoh27{Lq77=je8}Bo7|&%sDaJ#$#%ktu4CnPRRhY#CcXHhqu0h z8+rT%#Np>v$L-ts8>`6#f9P_=qJ&M7@#5u z2@CV5)v~31%OAD2oK%!}RFW2?WU`hddMF?bd<_FKS{xs>wq)F?{L)Hy=A|2 z*u2)IXJ}}R4Q=<}_hT?%Sa?@|NR2XM4U$kcY@b9a|FUx;+SFR zxQWdPN45Qkd{ASiW%WOg8CGA>;+vsk3F`=ef6o6SfJfO(8Yy=UV{yyTuO zH)9r2s0>#et*zVSx1Sfrv)0HhT@$XHw!We-@bT51Ts|8p97@%sxoK5SB_9lI<*KOG z{q3uf3Dk=B`!J2LX=rJE6p@~-#|D*0bRUdWmajZ_id@(7*=64KtM(9slT7^+YKs!@ zbb*~xfBg~b+mRC9af<{j#h^cf#+iF?XVGMbD_hKP_a~?sHn!&DqNcKhX+Je(V`W*4 z8Z-XZJnOhxL(FGb{_64-2_JlQ9?ex{s5-2*chmiffXQ!LmC(QCo`>0|Id6R z^?`FjaoB=>59V7ERY@}TZ|GwZ;7`$)TCjaVViz4((gX_A(3TZ1hD_koxMGt8j;`st zuZYH=+4pL9*67TH8!9IhX=n1&y_C`)|641tj7o7#fNNI9ULO=K^mC%wRm2H8DovTM zwyjxdn1Pcet5Xi51>s~S89c1iV-8gLHkpL$4|${f`Q1a z^vZ{(3AN^*OKJ6p(sH<9b$!ok5M7?gTSN8!_ndXXkcipY1QyCP$1zAP^NPdBIw?eLljGUlX7atYCf z&$jQk(nl`$iu}_+36ftG+92!@tWC+R5Yu46k&BL}c8NDy{DUipIaT<5LHL7q)IEl3 z8M=OSx2qD^(~Fq>Pj{JAdm$DC#4G(F$o=Ka=gIYdfc1o$GM?Xv`Ylu#Vy31g4zTIF zCRm3Ht-j|oAl!5-dehaC%@Q5tn4358DTw&~fg7(-Nj}&*1jj zJ2cG#hyo{dUbnu|Gcpp!& zbHTqABiSalZ|2M=oz?vDphr>Uq4j4o3Q4wywN27Z8?HH5MA(p9Z_H)&h#i zt7!WML`AS=(2;p}xU142*OToF;fP;yBkKeDuDt^s1-@f=l@nGIU%-@o14wqxc@V^m z0@j0`tNEEu_OQ8VO_nR@A?Shc=^OQ(MtBhKGN@;n#bJ>YZvsa@wV3%PWU8SK4HphqF3q865V$)zab===GnRx*J$IDDbVZVA0`^)jMdb@bM zx9rJvUz;1;NIo2FWaT*sXEg>axJD2VmqYuar&R|8ph&RmBc#1>LE-B`pV(j|l3J<5 zlfb}>b-Qyx!x(n@bS*$>CDK1eSM+d;IkZ1J&A+RutiC=Km(IWL{pHA0@FI*_yQwNW zIzIAVy>%k^S#~%T;_yQVI#@0`0E|abqb#nWZG!h_EB?l49$9g!QxXq2QdSohY0z;` zOu+4ya~Ey2>)~Gh^F;)j+)NMak~n0#XKM&;2;(bRPM3%QUe~{FKV`Vssm`k~itMgW z$erhp&4-gAY`h{{4g0c0=R%XPK6TSYkzK8cKK+9asY55oU!&KkV6%dv^GR9-^aNr~ zR6|5bL^af%hLFix?Xgw>Ca^@oegbw=0)>bK6;?(P{$Az!ptyDk9E%29^D1iOWu64@ z@D)|^BPXyLM;Fn4QVR;@3O8g7@Cv>(qN!oza=|f$)HlS&PbOoG#pBO5ay*V$AswX^C+^re=Z*yc~Vah5Ti5d&+-GpFCCEWhMqF?`^N>r_=We zW}RoSBkAOI*=5Lfm~!LsEm+esv$`WX75VNu{bot37sumtqA>&!9#lW3kK!xQw4_@% zYSKd^J(+tH0=`(4>qDWji3O}g97+p$+czZr6Ux&Y0H&f=vVSHUe-tWdBezHCszq+! zNBiUy?i!0zxVTj=Us-b_WJJI9x7Vt#w9em{VaDb0bN*oENVCEj@e^i;G?j&Rm&saBopS6s-aSa~e0%&zir#Ej=`^njeqciMu%Cz$AS5W~h^6oNrFT{{v) zcZwC``uibWm_&|r3YB}x`IrCm7tWQ&PLEf*Y!Zvndz{<^3lK?gk8os_r|?%}J!siy zrMd6IfSGZtw<&UtZ%R~>R9}4Pm{jtrr)P3-+lp}ccz9iQ-m;T_J?&SM!Y@?^oWxnp zDN5UA6pvZX3}}3=*?+B<_ZnkaT2O0Vw&Vk5_O?H^(6nR|L+*OWGhNFANl9Z692*^C z9S1Mc-s9R3ZOhMqR!~;iE`ruEGchrtUXpzdsODHk(s0M!u1efp8)4n?Q$7v-@+9*6 ze!ZVdgB~2aWh7yRc}cM4O3FF5OoSUMDm*B69A#=yoBP0u7c`;1n7ual9Uhxt>Z{n72WUoxJXMrL zpxlbxBEnrIyct=H;-sA(T8apmk;LdmS#_Ls0z)W_8wCX=A^|}fKWWBdh5gY8I+h0Iouho* z03mK^JWDwkmP?dXw;CaD?1h`oL`e7<=${S}S|Dpll-eKj%{8>t$!*xzng|ZI6!S`@ z7-XORQxZD7OW&%O%4H$`Vc`4^xm8N3CzX1*Lh=pRA<;Ydr$ zv<{|@$7y}`N@d5J`&-dAgp-8d@i7b_;O3N4>u#Bx zA&p!tX$Lv3r)64H1g7HP$q&d*tDH64K_qXlQK-nbV{F>b^iZwR^_tglfz^`D;D%jw zMB}@e2-CgEl>?rp$!HdcK$I|3Q=E?=X-0^lA` z8M^=)de+sU=ipJ3P14yegg;`%i}v(@y==6=rt?oLHrqXcjidV;JU&6%7Jg{mUDmYS z8iczT^I5BH+hsohVUv4yA?aQ`&3C+6 z{(N5YN8`tlMdI3*0*t+R>KqFD?Z_!t}KWv1OM@MQB$WcZ-j&B>GXpmhlg0kh<$Lq#r$W>C#1ycz1zK-vLv z*`Bf8ra5~}dJT@%yVGT%iVDs8(D!EJ;lzFZ`{u@VZ;$GpwZ9$^N6PM`j+fn^uSaSf zkE6B}04&1JN!@ay=r|sh>0+}gQs|gcu-i^*(4>g9UJTHto2-S#gCP-$4WqfGO9E%1I_kfb{_FXr|%o#p-hdM}csQ$7Cv47{VUzunosJJ)NzHUiI$ z5J7(*bIJVi?&q}W>T9>6RX>K;hT(aBjP&@1aI)ryA8|OPA53@_BEM&fBV0XH{-N>^)_rrS+*H*}7A(cMxL5pa;y5N^$YqdX6A(m%=OpyE zr-xO#C#6hj_=+i3Zz1Rpd^8|d>7Ur`sr`R9Zfy958wb5cNxxkg&?RLJxeq1~^n4u9 zxe2Sl{l(dH2mt{}kPgpd@#C~pj92ca9t?$SzJKC+q71%Z@+olB39-9S=Vqv zs`qw2f33c5aA5a^M{W=q_HcGqb=6k)9#qHa+fo+iGD9Lg{6+x4qF~|S(Ec8xc&%Ox z=Ojf5h;huw=sXriN2qN50e{{8Q{P+is*8WoJe$yL!;1Bnv*;%o-SFP^p|QTgHqLz3 zAGqJcTUI{qu=bLi&{L4Tat|u$8*6O&7h-A>^Z?Wa4NM;-?gmMtRvf2gE*^VBFn8^7 zpLR`5Og6@eUJt~8D1kRl1Aox@-}|+inwpEjkq@V;&?L4h(ypR&_IR7i=COQ9BHg7v z;C51kz)xbm!haa)E=nkz?d`BS+6YxtudaEqZ}I z#Zf3%^iz(yMjf$%zMqjx`bUxf`EP#viK$IK#Hm^R zJlMJ*dh|rq%|32oH@e5lAF_&C!$--Z#4FB1-46ZJ67WR~`aUeDjV|Cp zE3Pi|>}>TOI}BF2Y`O4=&a}XH@u=*d2&$U$(^BV4qNJ0es&(3}>@KQOGJ;F3|Zh)LvMM@rFSO!^Y&d^&~xHd56yxgz}jkd;!|gA*(%NrB*g{bEAI zR_yRxcJQ*@ry&A=yGX4*Esm=RP_VY4_eX%Qb6%qg6dZRI&9|Ta1rzZR57%2A0tvy*vB}hBPBc1Q6l*B z@?9msz5FqA=qMrxomq4r`^VpICXX0jG7=FSDE&mtLSZUO1QI-EBV3vxAUAOrY=Y;; z6+t5SJY#NVW>zkkoDl*Y2D|rOOH@TZ{W0WZAk!$r&Yk3)8)H$FH~dphHMN^Pnjeh0 z-LM@audNmlc1BSDce{-c5o&A*1>L6p);+moQ-bF}Ro{!#5ixmt&^a?L&Ex7HWux_S z|GVcNOV*-@ipX0RmAz^u;H-CyTAz!Q?H-ZL7x0|1Ni6Ii^u_7FSVW5+tb}(tk9I8K&$wQzgI2t3Z3_q)r!qr3JQTppEGfpPUGK6`K~Gt5VOxoR{h#wY@l=EzW*|8wKWxjDZ@ zh#(9IdU%TGDTDU1Zv@I&qs88xl=+~xbhkNG*10@C481*(pkQ^p_W)!^8FQ&vW| z99xa1vSsfQdfiM`dG69)?6YKEhI{fy{UJ^luzS?zXHI@Tmh8;NCb$F=zYGU}G5+@# zFMzgXT0E9YU?>4}F_R9JH+%9C8}J)By#W52P0U9E-3 zVIWRkqphy>xLn}w3-{M|~; zG6RFUGFi&^!PIeC-mzlbM&w3VS0FO4j?u@IYL!dxF{*d z913{Sv`dbE_*)X8Ba|gcZNIkya;(gOP4Nb{e&YDsyjuL9(ZblqEoVtgx>c^zH%6Pjt?CB>E4TQ)cX|+-ITuu>kE}^xk&?E;muf=ZT=z{ zr?_be_e4I#s-;w?mv%SK2Cm?dx^DmWfg_odWFhJ}DlJ=kyKAh{;&@D81a|+Pd;Bb{ z%X%Csx?kz|q__$Rh_>#)blT8vEC|zyRmpC-(N^HsMrTE1JK}9X-+uLjJ+SZ8aZRK8 zR3vbH7zLbchbo&N(R0EcNJCeBay9DSH>sViXEy*LUq5oJ-Q1Y+^LRGeG-?VwoVj@0 zov+SHVnY@L!bJei^S41(h@#?o)&R|MYx(zf0DY9HMq~)?)hIwA9s4<{fmbi>5X`)@ z6wYCzGe-x?RbV)R8osKo+$O0!ez|J1OJca>$CD(@mJYSq58SWUJatvMG2&lC5FIT~ zkzm~%JNzXd8Af00Q7S8LLmFu$yAt^uPCuv*1MkOKugug0sCR9eN`FdbJ_CNz4AZKQ zd54v3Y;3R*VjUjzI~6=L!Y$E*tfTl5C8x_#Dqdecv7EXH$4TPr3-Ox-)6~?#*;7Sz zXJkqG6X?F3*3W|?4uzbe)zA~70hULXcF zA<5*a^!lbk5x|yMSog3Hp>;6%%8%;!pxdh^{QC7NPxnqxBprEpxmNNqLh$U}k1iy;iKJ zYS*$Ca1&&y-~L%|ayo6fy?@!M%z8Wc#4CP3VR_(kmdga>mP6sGtvL649bwv8bFP*(;gzcVYw)f32YIRVXuF=2vwp-hsjAcxyDmQ0ey;-`JS-fxwXYT}7U zi1DXfEvScepF)Plx$TclJp-$&y`5xNL*4a3HRP2TVkrVy44B7l*oeXg)BTfEyzj0h ziUI~oN}`h83pJYEoqSV@^oGY$5_f+GO-akjenAZU>v5l}>npQdXLTL~ZP30-mngQl z0d2Q>RYjKQl~m(e$kab2&+9OmwPi7`o5+gQ&MB+~1+hLM;IG|B+CD%nVHD~U! z(d$~p5T*!4G70#bXnfi8iXAcKy`-Rk$Ay&1_6%hm z*ya7;bTQcWH%AD)AFGhfaPAp$@A(c9ixf7OKu zwe<^uu2`O;^W=WC3jnd;RK&M3x0A+vKgF8&>fQ|dtplM+1g(WINOTB1FwDfWa@&SB z?0K2O@hdampkpm3nW{Eot=?|{tS0UfIcJH@HmFdZ#@32H<6AGVplAk%AeENovQ+=1 z=Y&R~3L7+!rmOElm>~Qm954@#VkJY}W)3P>kk#5x2cIl$tV{C4qt|JdEe`G?R{!N? zX5w%_BnPpx-}Pe3@!l;MzQ~;^&0Dc6Sg04&_<+ka8c)BeK}kEoOE)qB0!BF!9IB78 z)6ux++}o6a5A~n5Ce-bs{H(0#a=IeMYPhiqy4vYZz$Y2;R49%I6LCpDpRnq4TRrYy z4f9BaFqV7EB=^LZM>T?Q8}HaDLe0p&y1X)|7pJqNRwAv2M0?T&_dqA)P+F^W5sbz_ zk%bZBq6h^wC=K?F4&;;rD&)Q9WZ(M#qLax@bXxJ!e8hu9kcg06o>+g6(Aiz%H9e5B z!hqJoi^IeT>Nz?xQo#7cI+XRLEpV(Q6pzLhfYwDdumkGW%et_UfXPtsY*c5JCf)eg z>eF4Fmmf^TO*c1si zu21EK1#Z;<>^PC5Yn(y?{tI>Nz(pt`U8)~$n%=@aMjPne(%s+uYCDdHbTBb7M@^2) zem>I_IlgB;LjcG2%MFd`wXjY-wZLJ^Ek1|WRUQBxdKNoe^^lO%o?ex)(Q>BNe$)2} z!d?X)i^f+V{ulFn&r6no>wrs4Q2!O2*A3pKTF@Gj$>XuJIlR=mwBb80(G@u*#qt;h zotv%EX9Rbt1(+f;3NlSqoB*y^!%9(d+Ze8=f`hj0Sb^AxaFSwQzmTO9BXv&x;hJD% zkHQ#^n4X|Y26_}te4|72olka!~W8E6&8^D`}$8){V^4XU!_p;gTQ|Lj8 zlOU9&CTIS6i<#zP+W4W_z(wa)?BP>|ppEgAl$3GryILwXX&yD2DA1*xIcpjUZIW2# zUe}dYK`DS`DghguRePYtQXJs}b_~vx4fPA6>NQVx{71_aQL%4zR(jBoQQM4>`d4_i zD#Usk9bhWb-Q=Prq|q=N#=#rKB`zLf#~T-;=$iWH-9W9ipqxx{wNpTnM}my)+fOC_ zW5TJa*KC0aFEQmOo{$(*o4MzvD(43n>_HlIHR?G3PWXH%PoI_8=YU<9b(97&7bIHl zb}dfq-w-1Br%nLKF`~IbUR6`rLSBF{q(<=H zCa;7+4!Y{aSzazajG5(Zw!j_+-w8Bcv$0?gr=?lGf@2iFH#)aPqKY*g$!FY%gI`uK zd`^+uby~WOT5g_DxA=L6n1cTI8Nx!nb^!e{s*RI^q(9V3kDIl+l!xNN78Nrd>8>K= z81J_2Za8_b<%(O^9^Md{!zOA(zqQEHn3^B9!hA#MuGLYsnf!u0=UdlMTD#tUm!`(t;Bj(BtN-nbE}w+`(`uF?OSM&Y$ll4axiAPNb(A13e-!34bL+A1cg(f(uyNn}UMO|N*(RjWFqCuV8 zMSAo&Zx4HKzHfhiyQOU;;PQm`zT3#BjtOj z7B9a>JUN_qPaXuz^4sroN2+>g&~iuAVwz*E`actus2=+}&!}@oR#?0<0R9iVCv>Q3&V+o+iHzpbc(ooFpCLW;Cd21&gqwbheFMT9!=C_R~^ z+n2=55}+~6nAZv;Dy6yxl$}-cIxZ<${Yi|iZ!!OdwHTDdGh#*Yxl!%D5o`L5ec{)q!PX6C}x#<&y$5E3d~C<m^8Sy%Hh7Vn`fG zjfwoI8$_%HZ5=C4^-cQma{%3|Yi&%)3ygdRoem-e130mQhx*~&wCfH!`@8$*q9c1D z)+^OEF`;7-&hIgO3)ZHWxup57*iJKqGhW{=tFM*!*D7w&R-nyARC zu93sEX`hi{((M~nOuA*LK4wZAW9#gNRSx*gfa6B)omsGOSw0ta%8)R|^<`xajv`Hq zdl)N0qaLo6#^-cqW$PCDU@U9%;&>K&gy2ifY3l|FCfgmEZ%AyK`6Sd~!B>R})!QVg zIRS8JpAG2#xkeKP+W{g(I_>hQTwXN0Z=QabH%Aw+^frHQRXj10awoIuJB|y}Y@Y5K zJ5WU1c1LZ48u;rT9(${e_$iBIg@{n+J*Ze=QJFMcw|ea!e%-RoYxkiSMl2A6#arF3 zO`1L<4d^0XclduaO5na;sJZ@_-c{W%{hI*(s%XJ@h)lyN^csLy`G^gb^pZbp3X8X%CLF+64Ko)5=#gIk}KU^A|>6@A>Fak-O}A4jdV(P zgLHRy*L(Xs|L5h?e&INF?`!v(nR9+~juaiCx9F)^gZsK;mowM(I=54nf97?mDJ?BL zz3s*v>m9*~`@&QgN&9R1>C@)wbEeP)3{&%g`S?*_I*`x(fZ=!QF)UVR%*haf&&AW= z{qZUq`{?ohx37whNcS~utHCss6@Ih$9nOTYb`bXJIEOT5z+mSDtodRuYRuUt4hR~$ z&JVoA)5=Nm=VF=YCz%CMA%V;$?YSAOlpc2fcb;>q7xc z7A)%a#C`IVw}z|L%+_6s^w8knHP(+Fp4Zfl59hyo&4>b1CtB}9XQxy%}9OdkHOb;|vL-Z#|F)EP%g-+Xx&E|uZmy@kP-#M6)_;dR% z`&YEYRBjBK9cbE9`wX6p%l)XBBvU=TEefNG;{gbDhibYP3|0F^C?1w`xc=ihF3SOv zFe#_wdho?}e`MPfxkT8K4)Ism-(-3qq^ygQKTxc~k_rI(7dfGKrh6$K=V7|Tw3f(y zx`P*p=Usg;^lX@a9v?cJuYb(>2nnxW>rej3^gTn8xOVf0`4{`n+}L)k6x1N-@IRY%k0kj^m0Wj z(EGaNIQln?8QS`ELjFANMEI#mRFsOQ;7jIGrMYF9GnO$T0s70Ii*)XW($Lc&aS|Ht zz}p_|bE5l_%OF~K=`%%>&amXij|6y(Uf>jo3I3bA4rS%3y7YVVq;dhJ9u}nxk`S;f zRxB&FORXd{=6*6Q(NlBg2v^v?`Km)^teM85{fLouYjYH(em5;C& z)NG#Y&;*nrU=8&uUjAnfTLaVzxA5(HW=3XN5h|etH^)*W6Dc~PXM;PizynnZRw@E^ zlgAXhShKD8j*o7jn0mrKuPHUTyU8CG4TAUY2|QEHp!BHV?Oc7^z5GH9p2A&|0!0a- zp^OT+fsR=zxkwTC`Lme{uTLdUYpy^&_=hkQy7hzO`Elh|VEyN>tT1HO8Ejo*oEt=9 zT&!SZzbru+jvKaq!C`6^Q)N@KH@|44FrJ;r@BScmeMk8KW9&6GM$C4{4&+*{T^ zL3b>m?kiq^x=sFa@0(8eykPURQ;gepdRK2li5_8K;Qig*$mpFhVnTQ<>rO{713;+5((v+go6U?kR&Kkv5?Fyyg7!v=eT@7O0+$X1Szi_ z%8fLHtmu{PQ=UAvia(lh{|y>hUNOM`X{gJ?-HLQ6O;&p38w8^jJj!+<#mDCvIOk^5 zF))ZKOLuiohA9{Asb^fIAc9OdK!GhBm27!UZ-~&9?fadf=KU6M=gJ{&U8Ei${}<~N zRdb^j0qBCcQ%g@+e$1ys&We;J1rRZS#!gkcrgz!gS?y-we)lvy4g}&)4<1zK_k2=j zdY~D`bfdX`Me$OjmttUne|B1nOMi&^Y;+k?v3W3_{Hbw>DA{C1xNmVSCm92gC7?3c zBu(V&eJ0Qx5vlrWU=0^Vc(#B8`s`29b)HjI=Pzl0zFrh9`1xyh?tQR1l8JEyEP8(> z))@)IjmXT=&u=u*vMAf7%1S741zLt6HB@e9EV;g3hvCyj)EpX13JV>4^Pw zym*6ax#Ho3Ge7)QclWJeNTA3fj$h=QzzWufX?y7smd02Iq3(NuZ|w%?sp5jx_+Y=p8ie` z@9rlvbI&$$bI-yCg|#JG(b{Vq8ddjnf_pFE$xo2b)6XV>wPEjOL*;$ullQ-PUqSU; zx+2D0ZyYktOLyTH7t8*VzTT8Qo;+(98^8eR683n1r32JUeS?m_^0gTg7gn9A!<8Ck z!y2PU(KN2z{(a;w_B~18i#$bK4gAVlG?GYWs4(oa1v4_&-Zc@H_P(zM%s8n*7La%m$4=D*hi zA$=T%Q>$S+hn;XvFOlZLchaStiZsZN;^$A#2C7>TVtvN6gT${B$ps-02m*519zsB5 zx!)@qY!e1x z6<9xfUwBp<<+Bc3zH|<}`qo~@_Lu_|&r-C+#6ID+#=6sAFy3)R?)z&0hAa7RJHt8Y z4A2Cf!sYK(#wa0h*YARPex2W0wRj5X<+L@-WtPbjE+b)b_oa)(NWjKf&N_Z|>=E%{ z?6HV8C8;Tz0tmkGETpEM=vRX(OoP=zrdUFW>|UbKBJK={Zm{(G#{BkBCRGxiJkbxL z>&HMAGqFi~UwzVq!5(1P6zMm_*2YAQ2_-2wMt9c#x-{V9bkp3gW!9bOkdcJ?{>m^W z=P-f~2jk-&!GQ;9j`x&0KkLfZ37twW634xO`rDn5zA`ktV)sj6sLA2jffs|Unumb#~#lc<(}_~I+;Hy zO4jVId=-cNFvH>-7R0}8Yv0`8iPVmt(?Q_Pj}Ugh@A+V+v7Es1j@DonJv(<_sXK|@ zZNGYLTa^hXm*)bVKw=9~9Yv^iNxw+J;GVX{W8`m-tRXY?gezST9goE#(E^z>(U?XI zpGNS5%kIbAXh$NOd{*)(-tgI!?|uOn$a?njaCN)Z$moi}yy1jaFrpy)#(OT1z!j3( ze;`Dp0e!-a{mQMA6--Ls=rHP?&EY{+9Lfx4H$$KzNsf|q6BD6>%27+v*DxX;d2Cg^ zL^e@>81DNWxF8n)YuQqxd`Y~C5M<;^w#Pp!L2k~~Izgc`+^1+EemjR7bn!;S@_$+Z zQ_~vX1OGvXr?#+P=5}{IcUq_seTf>V6ho11CqMxKB!$=M>B*VRN$Jddp=NAYz%=~) z2KNLm=speFgi%yTq@(xNjUb$hdVlRkocYbElWJ^BQntM0^-3+$F!YHz7iKYvj2C946%u+<9p>UrnAh#G5Jy4@ z#R$!KGe1krz>G#+;rs!8uj!n3B>=5w{+IGVxm)8~jtb{a%NQLkZx_<@fIGL}fZN&thI9;$US*-R~K- zoQLEQh`c+SRqAUG=>Y2N+K=Ur^*a&*#Z6D(bCHJ&YoReF+mq-v#qW!&RFQrA@&6!h z|DDa2eai1;4;anW1VjlC9&}|8+dWZ{nFChPAd03g-=EY}1j~Bj5a$mkH47VaZO3Wi z^i6XN))tY&kA!c_gueE(b%RYzMoj&Tq-J>0-y1&2!D0FZRuO^bMSm^qL2DW3mdrR@ zbljyu;+z~jN;VL*yfP^8(G~kG&r29kOp)Ij ze-P0ya}?nc4QA^$1i=>JK}i#p5Xe3dy$zZpkarE(jA>D<47TnyPBLDbXi=<@mj4+V zbfNlW2XFr!Z_u#Vu*(MgmD^^kwR(e?UgRg(C`q5lAD$i95&ypjW_xqYdW|pb8zaVA zys~0=k18ujO*FE}AJ@wLp8Cl*$$>(#)igz7w2m-$uRwkbD&(T)?^l%Fo`i){i-D-} zm-zFyB(#YiX8J8|n}I(=BlY4`2Ba<^2_4{EZ#6s+OT;KFJ)aT01=BfB2UbyqobkQ_ znuR#wRsy?X6PhDUk=AStLb(_sft$$QoE)vC$L&msmefIKmq!imr zjsn0pUVXfHndaK^FbyN(5$3n4RUAQnaC#C@ni0%Nb;u;3j>7zxo<@&Q`SZM|6fDaT zPRVb>)drTJc!C*n`CPHb)M~VQcSkolPQ+4^Go{`!9{QbI=s$26dc?ZV*r(u9(jf6i zv25LB_CTOfKJp8>q~fC$n$=oLlRpfs6bbh^-;W>(=DQ))g{uD-0cYe3@&!u03krPs@R+N= zF@*apW1dS`wx}0q_<@T07C|BmW{>QLOFz(6N6v>z_ZU&dwMbf`fuQnxVNWm6FN;-d z*5<2*DI+=#8#(59Z4@+;ljl*^uad^-8_+i=J8a}=LEDC~#H#C4wQU$`f`Z*kKbX@I zGr555XKgeS%zhK@d0Pwai$?(!%1Nl3f-hsZ1Zo!8Pk6{Y)r=>MUyj; z;J-Ge%{2RU0@$yC7bY&qP9a2)aw13SgX55UvX5~|lW9=CD&KkS(I(xZqDW@lr=y>p zchAMnV_FP~QSnclaeS(#gd`brn@Yt3cN?@cwA<6Oz$fXx;Ys)t%l`q__C5iJq59_; z7kqfc-@dX9pultSePF5+JTQ}_l%Zm-(hDtDMjItlqCWWW)letdEO4HCBV)iN*GGKb z;Ql%{$HyZNEE_x$4h_zWWlOX}T<&O>HA=!C8@sLP^*K#48W&Hj?S!^O1R3F!i;R>rn>9Y`wyfTJ^BjDSa$ti#QVa# z$++emJ`!?;=VmcdkzKs&?STULohIe~$bYPXAexI5NAb^Th$&KNy17+t=?NHTeP~f*{Y$B z*$vl<2r@$+?z1~kf%_Gq?*QEJ{Jb8keviEpgNB!OG+nyG(7t&5o*_2s!q}vFvn&|b ztdilrsyq&NhiCb9pYL=-GX72K9=9`|Eu0|wKzmR>M_G9&6Xq}GpVS8|WYUZ0G++D~ z*{uX34U6-3Hu*%uSk{w~ScA^BPj@yqqSfDHko}J|(;pz`GLD^d9>7JRnu$XldPFs} zk>lNfjuZ+*e|IEjSao$zISKG|ahM<84@|K;cpc`VPTRbSNTo&<=CaBKngPEMy4sw_ z`IARxAj(Zon_CN%i<+8A-E1K-G$mP6oiup&RbV^yyF8B)8FFk46wbUc@3*wf8vhS5 zDf(^y$7Z@y2S+%z3~P9g(=s5|sA)S(L)-EG(Sxk~{2muqjv(>dpXr3*KV_Ab3xQ$- z#a9FvF=;&0D9#28jTQgPxVdfopM{>VDi{6}pD7zY2Yo!aNgkqQoRwJGfn=wXDy5nhBTIo7&U zwJg>B!x%>k(9QAFt*Ou>@PPr11gxf}Pyd%+BG|(JRPjpNTU{Uu z5?3ppxj9-6a@rKlh0@`nXik`?1pqg*c{cC!fB#dvlOU5?5gkw6gBFr$iWAh0n%Mxp zJXfbrPUVh(vTc%g*nh|%PT3tj2;s!>-(zn3YiwjfYVfjYrNbI4Qd^+pII}S3yb4Ul zJu;kT-aY|3Gj+NA^v?{R<>c0CNqs+&bPlS z)9t+G0`f)oT&VLB0sv6;>vQ3DLr>ZVTcX19RbaGWVIq|=?^o?Rx^gry0}d=`guuLJ zxh3Knqu&~EXQY0vueRp8+h`fx#VlkO;>ifwOURw{pN%LEu8^iYD`v1 zO(-xymm}C6A0S2T|BSWIf;Lv_;H76@&N3rau~+wfzQx=AGvn5vSGi99+qz-#1>@`l z%J?a@)BOzds{@nr0^wLln)rm2UP9vFfCSa{J?$sTI5{b`d5Cr%FGSl-yzyee zRy=5UKvo0=bo?F6iY_VMg&puNGm!FUG8BQAIoa%N!M1vQ&t3^grOL@;S$|F_=#g}) zJRvYtVXLwIH0_Vkolv~A3mX2kH1+9V^;qn;)qQq=`x3CNgUbP(?Q5T}!eYR+2AY;5=&j z<&1?fp3iplpk=fU{Nm^|gxD#pKmuvFA<+#-^(N9=TY9e`%(Nzo>!P8p0Mf$jJi0va zkb<2)8%Uj0Y3k1}6?Ht3Sj#M6|6mD9=l+mVLo%Xy09fN%CNeS6IE#r^Rx#mDCT{Z2 zBq|B+et?fBvjSMuJn%{lBtC0a+evIMYRkwLw%fK9_$M)KVM;@4JU=8ks39aIxgVQ- z(axeeNa|vN#jYU+oG?g8zV@Xi5D(e$q#!% z6WdnJ^H%SP=+Qgk|E^R=Tf6(cF)j{gG`^Pa+6$4Wkl3{VB`Y~)gU_ciOpB0=DQ)rr zG;Z99j8uEBZk`i_aMK25*$|aiRIEa?<79AVr;4zpPs?YN(cSYIU8?%L6aY>rR2u)o zKY^7%^ZTZb(x zu=y)2C`g(k1Q_7_4bG|0Ja6|`SmbOT6=i80>au^*4( zqCp9!NJG#HMRBwHsiK(!H66QR%?W<{wU8Oy&2?WZ)D;J0l?I-lzlYy>DMzD$$#9C@ zf3l-n2r%J1@lUdhq_f6lN`lyZDMLGe$8j3SKFrG5k}N8J1xy+a&SKu zj)0+x$g!*^Ei5Db1Q}JaTCOfG$!R{?NSAPg@~bn>M*qS(!4c6A70qLX|8EA8UDfh~ zCYJ#>YH-xs{BiGOCRF~LlvLr~!mYAo1dZie3o}NXI%B7=j+@`8G;Pp;+TU9Pq<7h( z_xMH2S$n2*Y!@Xrh^*=H@%3qa;R!Mrtk!;V-J`V6o_ROd`P5>S8OGfFbkBUZ4Q2M; zQSOTpnExnv6`R-!>n(V3CXlh!g6g7OcPL}<(rLvW{|QMbfUo5=n;iOzkq0FCF$l68 z0lfGdM{Afojp-y5mBc*$*7}Q8%m)SXUrwP{=RHwP)8l)DK!32=WtEeaH2{v_^Z&F0 z-C~vKz}{r!d4`b69QMyp{zXe7qCoq$yA%@WZadWNq<^Kk?QZ4N^GdMmwDH^H%ch?9 zbB?KY=Euw-CPZ;W^1APWnAdR8>st@#_0U6-4gv*9^5;K#40xONU7YO?#tPYooZm(M z0rcSUPq)TZ*`+l{)iYJ=w94iyX-!h5q{4=zGEct!ZIT#_mx|CtjDIvamu%&*lfT3_ z?g_IB1<+Ub)_f&LOVx^n7CWGK_Fs@jrc1{i^j)Y+#}G8a9@k5Or&Ak&F_tT7I)09F zt)@;ty|CBsE1BCk-1`|*n@8_rIF+gWCja%KJXLnnayApXy%SbmJe_&Y-OEn28B3y+>%%Cres`O_%oP&(V?6I|_UG&E-uy z++zU}14~DYPsj`Laflc#mn{9 zqk~w$h#6dIN)y(+rtF^Ixu-Kw&9**281JK^8(33>ghA9CBM)aJGG+h-O?Ra4_dlL} zOWhhRKw_%^36diBM*&2%tB@vvS-uJ_HWMrShVC196x{`W_lewPURrTnDyJkTw|v#Q ze!?D=o87dhwexUzf!8M0VD?ldjJ~Ou{?pIjjJfM;=*BQ<;lUut1q6}o&Txrek60z`Tnx~cA$Rcs_9h~q!mwJGNHKl)njYj zOYnXoeO!l(iebZEL*nX`Q(K3ckxcI(YO-_4n~ zfdFUQ9ZfVmj;|4YLZ~N|XA$Etw5xYhGD_gK>2TdaK{acSVzDH{Zp2#e>D|%I-peyZ zz5b@Go*To{%i60eCSB96wg)L4&wwJO+0P%^{wpF1@mUXR>|4qus_X1|umgzPq5{Gh z!4aeZDahn0z&tyGC5pt+7ioQglfmJ>7S%s=p zj#Am;y^F?ohO6;wd3lA<*=D zc=XdD%F>7gJylhZ1<5%uX(~NV5nHW*Y22t3WS8hz9MS)c=3HU#*B%9OOJ`DfW8r~o z`3aBwQoBciyeRAJsRYSat?y-@>8;W1EwiON)19(%DP~lblY;o6Irx(nyb6B@npoAs zrV($2GK;wt{#t#M&lNYXAr>tnK#t(Z$37{|g@CqHmW3E5J)atxAD^3T9`zb0=RPq% z;xZ&+)@e0%&M-fJAlbQCe;#jN-Tlb zBU(YG_@Q;XR4nUy=mN!XEHdq^H4#bX59%}G*x6s7+DN~5XJxH*bv=@ae0bApdIo2Y zI=u<>C<7vEA6-`AD6yK}8A~se5jei-MC20M!}Q+_7|VQ^TNM$A{-s&`hoB$P-jA;_ z+VA<}A}n_Bzx-}1xLu1T`;B}eOCt%k*8Ik}&|n7k@kneHG)wuA(LphniQIK>{S4Kf zk&dPlMe;VB8c)?^_Mm5@6>nxPKd|a4kFI#_J9R!pNmnGKy(&B~k4rj*C3U)ZdIsE% z;fq#9y*{@mK2-QpN8?o{^c%D7n6he}M)+^Cd)>G(?;lK~qeKi$&D zGM2AbqSS%;(BjH)gam(T7g{ioWOfHP`-GLY`YBNA-)*sKx#LI_i|=ff&Z32d zkD?#N2S;2{2KZo0G6 z$J~rlN`)p%R~ycwUarbI63R>b!oQSOTc5rWzOPAvmZ?uy_XM@0=vHpS*MIBxVPJYI z`o0OHnUFb9yEm|4#<^5N#Oxv$2Ga6@@P@a3 zUFyM5PJ1E|s*hBdvn&qM9#qEU%lz$gaYNfF5fVQI`Nn$ifc{4vi^Zj}Zp+q&ibQWU zUdDn5Xxe_@Pr+flF%v1eCJz}Ix9bdbca`tFtaN=$HBax+(bw1@#Q`yx|DeJ zGy>Hdv^xr+4(Tc&n`|8qCT0F+sLvDni3%MmuEEjb$u@%)hmtKyRaZ@=x{zC9)=%2& z6{uqYSD5Fcu2ImySUkaPDn~&4{}&?h@Fm9$i#^c5oUXHgE3Hp7u<0&jR+Z z%M>j|CI%!$+=*ew`vit`b#bE-&@W1~9`mG0kOlS0Dqp;HnRbpbplpF(_+FV)K2szo zc;6psy381!pl0oQWV&khsYK^equp-mp4a(o-t1{CarNO~j-odYB_%yMFoWj>n71|L zLC>)k1a(~%7bn3E`?uac`+m9i7#Pxpo=>W+Jmimg6&#>)uUK+AJV2D#5YzbF3^x-# zRz(D13c$2FOZ}@LN#u@NPvt}&*hr|TiCKKNZ7iz#J(se^WCaYQ&kAs})nlbPbc4m< zhJ#z;=pjN@otFLmM7|C%pM5y8OPoY%lU%EaZ{(p}V%FaP zE<6ztU6&;96hf^iPM&V9Z^nBQgD|>Bd7O^NLmu7c%lftzw<}Lr@{LhGfCX5ZDL}S3 z@eSy|-9f~_eh=q<4rIS4cUB7p&YK{B#G$CxWN=lx6GZ=*Zv;q!$hab!^Id*AbH##V$I&^h|HR-` z)l90(T%*#g=biqL{tL;KajoWOf#522dJ(*CB_&wl3eeT`xrX(Z=7(g@BSS8Fl3Le` z?yAOlVky{6up3Ju6S|PaOX2Iqj{YF|9_I?L%X~S5&lZsAfJn%pyWhC*hq0&9I$S6I z<;Z7n#X>3eA5ft$CnPUPnC&XzR5O6;VhJ-=oPYgxqiK|FvZVrVk8P};Vx$~7@14^C z{&K)>x+SJJzubZx#0+;tJ13~MAO_yL3?nSieLBB3&7x~i08e2`eI24e2r|dhS=2c4 zjX$%n5+$}K5rtZY^=mfuk+h(pn9U6hd)ZVvMjo}BT3w{==SFcH+F>R>}^^}Jm!ov$NTduaJ0WwvwI z#`~Com$`AP?9}@-rPk8sv2(Z64}Zqtvh99`SrkVK=@*naNjXsri2NH_Q5bofHm@(_ zBAN=8p7U~hrGBf>t3sQ%zg$+%byngNjmQv=Y-iI28}7F&{5`WAFzu0SkjXKE7vuV( z_U)2@gwQU}>TR@HERD4W!d@jsjP?34R~@aWOwc({soHbsk_DAkDNPuY0fJX@_*9`O zU>1`MZETdOeQe;15Qh~!{k^re=xieM+kB{w7E>_BWbEQDW%Zt1?|Ijy&FC?nlkald z2IH@cIVXwW(~=(FdDx=f`Dn%SF^QgnR+6wR%-*&8j)V99K<=ZZ`wccH* zAYnS`UH|uo$Nt2ZcLC&?6SJ{?u8CZ8+)nZHzzU7!#R{(xkCVGCtti1JkLP=}1lqrL znN0^r#g@=Re!bVd*LsyujH(ruy&d-#RBvvR3xc}%%>>6GRkr23jl`w;N8PeLAOLs& zkzpm!ilTle6sGdctDmAqO6JWG?=dp;{TmZf;7d#jBH+?ujJin-WfcAVZ9JPr>1Kl4 zO5>qp0w7F*7Jes|_9CD$ixXyWvXkr!tP^l|40ZnmpKynWDZ`(o{m? zZ_eI4$tAzDbbK#VkqWeu!2V&;wxe7If)W?Wq9Vsu9hZ|@@|p@*sM+1xsGVr%M!#Yg z$E#k1JDj5=DVCr9!n+V(5J}MJ*myZsFH7l-^zmjNVQiXyh-gcV!i+(s2*3}Aw6milAN?IHYow;KOZ0Ziq%tNHw$g-){yJ(geOQnf?e0_i$i! zE2|%8MjsSZDWt_?wR+||K4&_bFhxBO-(zw80EfxH)F;sNCzWIh|DcM+Kb#Bq`SWZ5~2wPQII*XmUc>tZ5P;H4o?aB|!Ys?R z|LYXR6$V1F9F=g!G7nuucl>caTetBCvonR#Qu)AO)L&2q|NEh4rX@^d`M)iMp^L~3 zy|Pp6{}T(m#gj`J?MUBa61zd<>I_wn>MM%qlGfK)zJ?C5e?esLT@LI_)}a ztG1TbkQ4`Nxa4dAtyMsc*wPtdDILEMw(c`7uH0Hh`VQa2Y$@+*B5^_rU6fGVsRSvGaHR4&uo+p1D0{ISb3RmVr zu-)KInMxRN(_#W4%uZs-22qJ=OS4+;(Cxe|pWl;0$>wJaLw0FDL(7l3cGH`$vn9#m ze&&i{(xMI=s>bJBYGL&R)8W2X-k`uwpcaPBKml>x;TXX1i>d4?-pzDLx!Z}Ya15|_ zQwB=yoP6%i{t?K9uezc{%?T5pH~U87f|tXD8NSCHKKcU>Gv@G{B6I z&8oTOS|2Gx3CZsA{H}SCBHjSWl+}^1&n^5^h^H8fvbx%q5&w%c`&RRvd*tq4`=!q$ ze{a<$4D#D;L8wPYMI~W1G5MuXV==!^+;Ou%Vtfru01@jsKPEXl4dJTj&kh_Srl=N2 zM2^Q`z;69Jiv`ovU%!{&(9NxlD(K|>q|7Qu9qdRcr8UyBKOkS*js&rX2VprhCC*u= zs>}OD(qI)THFzTuqlg9$Uu&Jnmgo4iMkfVwZD}MK`k1J)qOr+^W>Tv_LnCRb(D+n= zC6xohYJ`!E-kayXiq$%cY;sg5vI2^Zix{%_sKl;0KeRCD=gv>m`;A(pWH?a8&69ox zY8V;!utE3(neZ%9qyrm{V*1V%uoD+ra-ETD(*I}T!1WEuWeEKitMeCHeuaN73D4I@sBMeOCfQAze&^vM8d#iOT!Vj7KYO}%#*~qL zkq-cY&?CIzT&AqNK6AWT>(6406guh{Qd-pfnZtY5Z6E@j&XxKEVbec8`1%1q-6wIt zMNTvqQz~~4f`Is6qyZwLUUwiN6z*~-o!SFXTy2tMT16_Kr+|?sFJEJ6W?CS=sM6Qu zXxaZ)y0lY$vzgKB&*%izF+DOijk661-~#Smz`F?;xe0@)G9l@i3jCRDtse(8&3vc` zL(}#f{=$E*BAZ9B#0he!3E~=_0vhbn{~G>xIjSWzjCj(6GuhkZIYZsNWvajTxvV!} z-`z#bO@FdVnq!fhs&;Vesxi6@b}s-otKx@7_T%12z+LlpZGVCLz>tX+2IhG*%W?!J zD4zF;SCMz1O>MRHOH5xil$ufgaJk)n>8{8D z5qinYZu*`=Wp+zDaJ%|FweiUO^4w=KD=}ab z0;+ZXjX@Zi&aidy)*V@i_rn3LIDhXuF8uPT?`ni5>v3;A@MNF`#OJFA$>2jIJniHI z0iNodkv==aSjq*-$8X4|egQJe0ZuY~?$6u6d0 zQ+4ybW~spMf*>I&D%UsSvVaBeE;d&xcs@AMtUovaHt0MJpBo}5W>3HrOxmj`++X=k zATkj1zo!fIA1HS=*N=mv1Y{u$F|YJ9Qtz{|{p!7Nvj2GUCFc&sCWW}Pm*#hd;*13O zAyW4COR*UxY!lg`e=y^8F#75!vbzM?+0+oVE>Oz{aJZoh2-#lM;HgO0F~Dh(?NzJj zm|f}jVCdL&ThB7cH*3%(pl+53^=1EQOV)8Z`U-8`PCt7$NH{d&+`MeXH2hh#LZ=GS z`8TT@8zd449Mm}MqLg;3j-*c0bR>84eM1_8DIMPj6g_(l4Kq7n(s$w&m&o@v1Ysj% z!5%d1$#>6IvMHOvH-b@*O{kH82z0yD^n1wYWreA*Q3ge%N0_g*PRFqVw4JFwiI*c> zK%;kMzZ3fs`bP0NpKYY?mf(|KZN63P)NW^(mPiX%0Gf$t_b$9l8u}a?RNPjn>quLo zqSqY!h0b6CdpG(bY@iLju~%J9AA)6I{51svNy+8d2qgY2E^02aG@tnua3SU9_>LAO zt`+{r-xQrnnS7-Z#ne=Rw-#76I=fBr6GHYoA!aFVjx~g8J7gi($9ynsO#UXC@w{Ok3bJ)~%u@BzkOH=d3@GP^T7qvjbzTwEk`}2f zY$|8@>90N2&*Al&$F}m*3#poJ-M^3hamK($%|5i2Np0mY_a9k<{8Zle2JZc+G_9o{ zj$@U^E6g%rArbl=WMh(<1z27}|9M{egEa^O_@DBm{nw7+(k49L8B~mYxv3PBN&`dB zKUfL8XA7?(dMw)G8`Gn<6H@ixGWly#kuWG_z>=Ph;1YAf9`QYJZQs0zxOea(fe&1y zn#}&Wq{c+&PRXhk6rou=W7UAs5)<^Q?FS;ABD`>Ji)O~N<|Y3b&-@d*R;XK|LSO<+ zJ=FxwpP?MfP!XWm$mi~1@VlWIr5j6qLDA@zmhLqId$$Ffr6|mi@)Dzzw#GrS^dt>T zmf6v%P|?MLRAtPiL`!qf+%#gNT{b^Gh*PN~Q2xvaq)qPL*%YS3MTf8o{QWwS-t064 ztZu@l_Ic@w@r`kj8V!f?LM9bf`n7zc0pN^}NuBzOPP-x_B!OK9t9nxshy|O}m#Wmf zFJ}ibT?v6po}Hd)K`0#9Q6j{A|6^UT1eER`rK;vopKpYCv{(n8Ow{fu+26&#HEMhd zJ|%T?9bE8%8*ayNS>r7GdBrazI?-X|Bwgvl`0Hwximf6&D2c3FL@@2(>J((U~tE&{CTt@nbV*G3J(QReE)aV?}R@l_0)TQ&f zU(Jo3%rBck6eU_7oGO?TWHRr&`v`V+*T??X;rqV^Uq}KhRc>y5+l|xhahr>?iDobL z+-~10w4G|M!F#jdpJuh#ejNcQQ?UQuJsN6Wrq1`}A(2>L0-Ed`28R@cI)}gip#zm2 z>%L|R{R|5KO-(F-K5g?JE?ZctRkgPCU8W?WujkFxfHQ+b7$rhK%tf;L?+iUz;C!64 z>57DAyM|R6NM`U=%x9 zC`1WqbMhI`Wt;h7hPDmE@P|cg`R%Sv`%X%s;N6;^$IX%;@W;cW$&{#fexdig9(CeA ztcOO6F4XChAqUVe_Y|&gf-<{3xn0$auq2;WDQ7vdbD=*Flkd4c z@48>GY9vgLq`49}b5&)9-Ih{^xSjb1Eb#&3^pcTe(2X?%GhImyv)R*{Y$m43=ll*P zjE$xUO((+33tin=lN7w^!&UE z#VEg#NY(UU53(x;H*|ZZ;aQ2A39OjxY&uUHq_K#enWW-5NHE2O@`f{*ZOP^8(+(P9 zY`z6|B`n?y_a$Z_davc2bfS(n@8zJjKQ5mlXzdV3lJeGB&N4Opf|7Y1o&VI(v0Wd{ z4Z`dSD%5!%uJqOX?aT&yG<^hpaK`jpNb2bxGw`@#i;Q^=D?PL{^BVghhK2EEgBX&C3A`QB9vV1uH&^LT-5L{`*4C1jQ`)YxWV zP$E~e;#%Nz7dc%LZ|DY5htPQTvt8QFU%LtA?J1yK+8Kx!TXjEL z2tYF?;dI2|dg9(XFIJ@r*+7~ak{L*QfmF&{V`CF1H45?lGHiwI2XsMd+voSBLFej$ z)JQZ8^jY9)##_=}jawB+{In+@9fN^@{1YYsg)I0pLY6^*6H9jY=yP&%RP(TB8pt4kIS@~@|QDMh$ zU!NJBNS8sjd#d0MWxo7}h>nAPr79#Z$J-T;3YI31+Y?j4#}pB8l+qjcF`yqG1yBOC zf=##&heBiUUh=#N9r+xs_IEbKw_k!Y+8t<*?u(;E~~a*Z(Y-Id4aAypFZ2f2e?sq&SIYWd;Z`E=I`I_C43%Cckv{wlLH)x6}jmC zQ4i~Ih}EdFF40=(dHo!?_|vi)ta)mViF)=EQjJMv4J%}S2M_)v!|Bp7d=7Un1dn1- zIoa`#V+GD}nEmEHR%OtmJC8v9&0e%xG&~Bg7vxz5zx<^u204 z4X+tv1r`lDW1-K_!U9xu!Z;`oyW?Tpx&;C+JZGNpqf9}#xhrO`h65Es5y_4RX zX*^w^3B7wPxUAO)6k~@Lu`&F+kzjb>9SvExI+bmve=S?Ma$V~Uaj3@6EtB9(? z)z`5G1Shz6AZ9!a+#2$Cgn0ogjg}eDX#-9q{?ZG_H%G&e3cB%p1uR4U=-}(?^W4By z!N-9pVV=&aOX(0miDtl;*werx^D(dFz(}A$h6xg+8}3_osu;JJWtM$&qd>b6h>}hf zgrx*E3XY+!iUM$PE2}(Ro9>}l5>prC>n)aYlJpQ3BBXkA(V z^W1FhbI9pG7>nhY7=a&7N%HXngq&G3kAjVye1v4FnonZ&H#TR8we-7QH#*IvnE?e0 zjY!qJ`@4th!<(b|+_`L}Vyi`GCK(tkSpbT8$`$motfXl5i|JEP@dTeuGbPZ7LgG5oOxttXjftl5V%6@?w~D_@o;+BC)${oaB1% zAquBzKQTUXTvO2xC~8gV7YV6VET=;NVb+c@PM=Iigol~9BNQQf}W^!^VX_C^?7zx6@xD6^hA1}}>t^e_X6MQ+3BJJb0 z-;!cG-~zmgI6gl3e?o5}@)dopv32IXV9I5>hl!;jsmRZ+k_w0Zl-0r4`3+o@lwpbn zjnldSYOG)BaKJbO`YOK)A|dhfQs5M-09_zr!3s4ByWpNiZoX-R)%i-O=S*Bgf#vG? z?aXKMz?8pG{o=j6km|S1Zwc1tUb+|6YC?p>n6+9fT)ott-2HF70zFqq33KRBf57QA zysdhH?76|c|F#L;Ogw2qncgvOE(Z+S4z@zRVZEIRRX;VZzM;T36V&|{y?ENT9u-B( ztwbMxhowAs(Odtd;VO~yPk$x$?>C&7NT^hGWFR{>=^AzW++~tmK6iOP27UQhzeK6* z_~Ur7z6*odV}8hp*Z;Eqm=ABcD=el@iLR-5UqiB7{u30E!2P#OXBn6*Y}thU_MvBV z-nTB-HC!jpL`lU%K!*yR0zVIr2L*l)XJ`Mo12JafbR-b(We#ip1!Z0 zW4VvF|HfUFapx+TJx%pf90Z& zBw6uS%c?Z+z(43`4ki}fQU^gRYrJClhKBz}2`Ft~b+MNn-&Mm+gq~Qvam?CAStnwGiT28Jm0K1CA)LX|BPEkerCX2M&}woLT8@Q0!2iHn3_>3oCDVrpce(nq^GgP)C= zzXMyEhkRT9-0VO58}WD19)fb`$2@kEP9g2Jb4C;ZpN|52$(L=cxf{w~BVU%fB5!G& zMRBg!f4PVM*#hah;lBRC*(eBS>I@|KnD|ChC5~+0<G3eI$F`XzXZy6TJpg7Nkll+$aHv4K0+7f-EFe8y3QhA@^kz5%QU^e%$=_#oHsK_+&`{p|FSlNGH~sLyEh)U1@*KI zT60wG;$s{K@2)!)E(Vu&roTx%DEpEa^nE<}$4_g&xLvt+*@~sE&+n?H_W;h)^RD|zJ*mHY%popN3Rq5&p(O-DCv)w~2EbhU0 z9*@U3*a=?Bn7k8%OC>w-%_zf+bIs5qk@JC*4ApgalV-h2Gmr0IgAa=L+n0qm2XBAi z=T%nyncN+`Y;W)KhC75qyXr-!f`@$`3IA*a0q%f=Z_oZ-1MpJ)gW7zg(T9+eFb1-t zd)E@5nM6$m(^|TkV+vHN1Q?!)`Me7GoT7j>^*xo3fd1J%B~2KB2hs8XDI1;hYRN6@ z=0!bgfIb*e?n?mbe5Udb!evmX?<0<_ua*K5wO{e*PQAKriY}1fqMpjWsL#WAk{G z*ev4(aCWy+UTeF^P6>J-Xp?-hCSPFPt>e?1>VEE_R=E2p|Er`IzskaQfft?|!7)-( z0h~BFk4*bv1I?T<5wv|%QM_QnMP!Xtatv?N+p=!gMY#HUuS>Lcqg0&=K48CI_8qTY z5YlTqlZW8I%o&r%VvQ6$vcqgif)!zIQ=t!e_#;s!M9y_@^vUMVZNsPwr@Ls6M<>oQW03r<_UTJ3=Ct zx+CmirOd}%L;D6cNYn&Z9!=;A@S`t2g~&8SbT2UN+_KA3lBa7928+6~Xp}ICf!0Z$ zIm#=J_R|S0x;wf^?zL^oJ4e)qA9p)1S2mrRP=({V2lyTBsrP4p5Ipyg9muyrtPyyy zt0aF_S*Vr(bRBj?Zog3g?Pc(94OC!(kG5Dx;gPF^T_^r;TrbIHmWRT$AQ3>Rh8Yw9~dri)H06wrVLQ*%J) zIWd0)e{pa~;=5e0;-hq+sVBg{X~gvj#Y@E7TJ7%c2DDGIm5~)aI0~zldgy|JPxs3*XjTiWbOf={dR;HrF;^OdmYUfu6}B>iRMeuq7bM%XcuwEcPR63H2U?2 zFeL8IDhEM4nD0sZ<@fku(yW}!#8U0aX&>fjO`8AIw#1hp-W}> zWq46;e(vh|+Gn)q6C=H+X6pz6Ogay3yKkS3GW?KC{2$@M84{p9_Ir;PN@!KFY%YrKCKcWr%&@Pd0)wA-X=3& z)B`GYOS0hE6{RSC@Du{WvNB8@c6YMM&P&@?hXL{&ZqmENg!?a?+yw1#SM+O%eiI|+ z;P@iIAU&M_Y>33cR^IUK{X;Vcd^--=|1!|+t02HJQsSwon|BE~PC;IeGNb^L(hFdK z=5b;{I}bA`Kr&Am8wQsFc>?%9so`!_Kf4$y*%hubUbKHlI}XVplo=5FKw4X576zuf?%x_B;E8xNF`&g)uHZag&d^gXbVTw$3O-h~Piial=F(IO#kn~- zDe0K4Ua?-i`1@})ZACn)8iRp8`k5I zH_W?IspqX&ASo;?977RlM58{d1z(nB5jN75xgr5Y9ieJba`(5@8iMY$k2~oDvl-{3 zm8y^+Ogxj0+VMZ$RtXd zv#ok;EDp)Y+OX*QBG&lnl&1$eh9kRV+4mK=n`nc6G@1w~fMo(dHLLUYgrLOppJ^^*_%+LvDzlz_8b|(^?Vx)5H zk<+_4JMz>PD5yz;oW)^j$YPXw{vMMl{_fuOw5*O}){Q)VU`T`?jB;$IRAi6HPK9>1 zk;m#B$L!@14(FcginozVxlZlI&L+-uF2U9#I6F*_+!(YVwR7kk)CXB;gfI zqFyA4eLpE?^}}45$$5s!y)V!J{(~4ng#5F~%>G-~Ta%E7lHYCBUrTa|WSacP6r#|8 zb0I%bG+&i-{5<$BP?V(Gv3Qmy8T|D*+)EXc*kGg z@ifn{rwdm%FI}@s;pOYNU~A`B(RkG=Hb7;*tIsZxLdeAI6?*ck#s9g{F`$Bt!lhb~ zj?okL3ic4X`=BlHP`kOc|F+f{Vph$K<&3vPhNpC{Vc~uClny!5VNf)^Qlqhh6a19r zUcrkj`VNZ;b#In>CHjl1bWq&Xcb$VG65lziX}LoG8j*bZXv!@vPW`0*-sr38p>4IB ziH^zrcnR;`&PoyAe&)~ehLOgbu9al1m;1vB=~rf9Eu~6d{D$br7RlKz>lSn=ne@t1 z(49(qQ%GCpd8Vq}x!rB041=>4co(wJ;4Nv2L53B2BQ?usqTcN(aY{e4vHpSawFR0R zVP5>YFXiVXKnMDl$OD#s-7YEs5v5EfT^|?M>(K-mB53CvYVj%cHZc2ur6; zY--yxHo{!*^78e0ZMzbS3pE&-rC?e`W*z+Xcl%oLhU9h2e%>_TbaVaSGIso%Dxkf6 zXnTEwIl$AOp|lRMeUHaN`o4QqEu^dXpwU9v5d*ru(23S@(7-kGjv7nv&N82Fl-+gB zetK^rLgBz);)Qzz1YU(ind83E#i4Pxr<$m@gw)n^=gvpr(e?e-30>d=sYQPMxDb_+ zHYuYGZr~nxZYk|*HO8j`6i}|YBb0E`i+ZNGf_%`ljmw{03~Wa%mJCdx#V(KSsMkHx z0!Y)HiwW}mc;B$H1hfpxzaU>m=NXTDZ3npwo0xhkEV!Z*;P@lf5Jqxv9g1DBU1tt<_ zxCDcn-|0RcgjLTb>&cYwQa)wD>T0@HxLZ&=BB{4%Hk7koGdJ57FB6OZMn8iYbDQE- z5qcG#q!^~@P!Nw*cxWZ#HT_UtzeW$YRG=u|=l$ZL-uro(ScJv$43|ZohSC01;V;a)IOx4PjX2vN!6m zkQd1lwLfVc@;o~zB8u>EhYU}wqM$f{`_%?c<3a~37AszVT?Hk*9)LcXx?B`KZ}LZz zpqx)wxbYyl`9RnTYOH|9*=-Y!QftzTiR#nF5y$->QG|@Ei8vf_(u+LyixlW&Fw0EH zP>t2{J~^88poJ)*`cMJ}tS;2(0nbO4Z3={^&n7Ox2SG?PV|!uzUEMGQeCp@kAfPq2 z#Y#jYED~xADIrd|@kWadVHKOB=2O&x^WWSE0pFbJ6sBAb)&!&t!*#25O60scrrNG^ z_-#Ck{os9wFt`3`$+!Qwzw#`iKw7CnbQ2unNnSsWmlIC~?8O}_-gLbD^sP$sZ80xh zq!IWvz46Boug?b14)_D{-!sm0_}3@T@_l2kFe!#acgtX~0Lmhy2fLMfj0Ownzc48S zfweb6>43u!NDV#{7Pq9jacHS}(}M@ARnB|cpu)15-b!7)Z{G9s-QcNEs$SnEpZYK& z;d5Pdqb%{;T~54@Nn$U#?^{^8FM9(MU@RjvkJyEk8XPz?!mLV}I*M|s7#2S{U`&Xz ztohAQdzZ2A*U(U7n9e#+`AZf){b1JY;B6W2;LE`H@K4Sw!{HLTxIe^q z{79iV8!m8t6QAoEFzQsUk$*GQ|0lyO01(#r>t6Ysd~@d$5P!Ar^wMwjDA3NXtnhE> z%Rd`-(muDlsrA7jx4$Jq<2(OuH-EmlatpRP4*v2lcNZ4vzCkPL^wW}q6}{QX09y(W z&L&U(@<3-U%B!8x0};Y`Upe|(lxanr*ZUG^7)(@Vmv0VU%+PzEZq3m^%n(umNR8<# z7-N!x94wMh{agNuZA%a9DyQ}uHK+L9wQj&+H0nYms2cT) z%(z-D;5 zit|sM0-^0i-c3hDnA90?Wc;LgnE7GUGW923Y$vmcuZd(@707TPeO6)Z(%C}UFh$&2 zm3_#eR!13}zzU-e#f8_^m2m4TW29!C?4tNKkOUyDiVqba4GfK#yB^_dN_J5mpg3lH}+p zaTJ7sNuKSV4>)k8twm>n`9cmyi*KD5su!OuJs29ij3~nrFax4@Uxn$p!TSI~ei2 z!;HLt>c{pxy{bkseYeGZ&-nuFI>bMwR{_+pAet;1&DMpv*QG?e|nzy zB6RsKNUKDT7ld>3JM>6;j>?wcuV;6oV*~@v|0iaP{zBC#;wmtehh3=J)ms~+VLc6{ zITlW41G=7(pC7!plA}K4=a7Cpp<;#^|CzKlr)%tz0)9h|lMJ4OJ_LRcI$1TU zUdT;0JjK7XyVA|10q9mUVDcpR_NneCD~y{ndyv-UaQvd^w6`_?^Hk8DSCLAF*u?OY zKIG~Sh+W` zeP2l~+;D=3U7JF7mM&p3)kG84Z7zYW`jzd(cntA4%CGL)KP75#%D@=W#%d07ah@Kabd^j-ijqqT#YaTV?#(!^N8O zc$HGGCcdR{rFmRlWYzb%!R@hO7PB=6tm%HobEOSF4XI23`0x<9^}1rkp6ZD`)w~0a zAin*;o~EuAJB=^}3EU_PR2hEQNWIVy#Fx5QV z(|R>x&@i5b#{d}u)%vdzg!ju9^YH5Z$vS-hD)TCyqU2CwZ499;}jypz&ds^;;`!12imoJ3 z<0Lgqs4CA(ZZAR%x0Hge6)p3c+1_6YQPmPw)KiEuB&;K1tLCdfdxKYJN5lIf<96HW z@87fCWdnvsj4cT~UwWF{vvDYnV=CczF9MFy$-CRF#&pHBUGC2w&VN*_gOzH}HyxU! zfuH^PLq`b*JOY3|`1q5@=)&N$o5|+0@kYmo{OS*HIJy1r0kJg}hWRK1Li#9Xlr!U? zr937EBQa^DQnbw1ukL4Cj{xzl%j|dC?3c^sWBET(n&#wkPdfCBGlb0v_NJOP9|JMK zzgNe9na&9B-_Ts*sNG$)xa)|ag2=0<>lLc;Oz@tMEZ^D^;s>`d9wT$(TX>6TaD>&k z?3la9gkDxARKqt2E6;LGZy83~(|R~Hitf@<-F&R6{oOHR^%?I?e++e-J5h_L?W70G z{S$+S9_$9Uoqm0qotq6J)A!t2WFb5bqkresR3ITDf$<9K)t(Gv@Of+@USbGY!uxQz z6cQe%$}JrUdcyB@)1Wq6dcS-W?*TcsHc=Zz07vDFOzwQEzm@#|tNS87gzx3-|9IAN zT!c418*@|zRh+H+Qu}zx08VRK(!WjW#kkfMgpumw-N``rLRrb~&?D|U4j0@aBOzfj zMgvwXVlUs!N_CJYE}C3C^ayThWo2dfTo~u0;*Ue)FCHv^NiU4~&OzdzLwOf6>JONKM8bzhI^=L zc7^+gdJZ~H!_iQ8daCMY`Y_TR$W;P+TmVQwC5QAPsY4bFwuS1z-~JwJPoe;|cC9l= zc$VmJo@PhZZpXV_3$7vljcqxM5&~Cdyc&um@Q5>BI)6}kx4PynLKCm>Va9$cU-))g z{Lr_UprU)mw)lIKageobF+rfN2Lu}%X>_)bey}k7tJ#W>Bu9?fz&BsIA z^+g{Ewy+Pv1UBHn)|q7&{U9DY-$>-kZTd+MW#E>Sjv^rgVkE2%D6?9!a}7S+|7p-K z^=x%i{|gzB^vxC^=bpdG`Na@q?&?b+pwIVaLe}ZD2*d8YKi2(C)LGFE3po z2Swxvw^F8JR<}aiTmqqp_NoGyMTw4gK`K3k+9z5AB|e)Z<71o`PoSp5mP#*-gRw$Z z>;}7<4@c5$fv%P3^dZcn1z#=KXU(pT-M;+xohO)m3IF}=%L#lvA1vO}_4|>G^4YY? z-RF1{anZbV&-kxp;c2GCPnP}@JG|4cjB{sjLT{GDdY2$Ql8sn3nt@gFhtJvEBEF+2 z7)Byhnnt`|ou8iEaGQ?yhc%j+t4_*Z-Y(EdJmt+)<#>}8!TIjkoVmD!%X0$DcuX49wSViR8HQ!$sY$M2+auBCK4YlKhg?bC>&#b2nNS?M1+ZyERa zj#BcX&-J#h(T@zXK3G#f;*a#usrAsHg%=TQ`gU7{GoT0=AzNLCBx00H6NE#eU06hmal>=?ze|Ht1%{MyD0^6TdG*`{1Gi<*< zyK#En>$aT|Ks-78 z8dfpk{hnyZqMfRVEwYBo&_3xEO+2wBc{r01iyl9e;phP#sClA@&drxY&e8_`(1WFt z69ne`R%-*+OJib5R4}!qWZ7DT!1mr~a1HaJQT!*!>Lp{^S6f#{%f^*DJ3BjleSJgQ zXKa}!XTKS4PdeX(?ZVai62HK)ZyE2RSmcCxLZMnE*sf?Bo580YMNY!T-`rMjZ~}EM zO-zies{!;V#n4S#Ci@;2C=Nzqnx>L&*O#=HSK9~XfOuAz&L5N2h=g5oVbrecuydME zxE9w(@1ahLKKp4zycNp&Z0<)l!+VzN5ZqB;$4X6b3gpA!5CN~Ga_vkuiS(B8*xG(P zSeID?GYuUg817%v&A0P3v|8fT!OzL+wv8pP zahFD;CYM6EsK?p)%b(gEA$@mPDBzr3z-P@v#qA_W-gz)-VzB)fP0X$T2WW@)*zA8LWsw&-C zmdI_DJ~*Ffj6{3-QwmlW$*h~QA;&`y%#$;EfSX>caDN2i&OuI*!8Vd)WUdNhKO82R zuhfzVuvD_AYQWP`>ya}Mrz_J3 z&gw?yEPgAXFtNrIJEtdUo$U`vj1?X<_Mmy_$WkB}LqSJET})^r`z|!%42XIhWTt=I z)f_i4%(Garh7?8A)ic7BY*=612gV+V9DEFzQCgYNhv2{1&lK(;OkmiXgN_=vf%GWz z;}7l&RnSLulB`z90kYv$+wuSvTV1$!t4Z}Cs~jCk(@RQn0ia?!TNMM4I!BY{W2|Ui zZRW9GnNh>M@K;z;$J-BQo4m%yw+oJipNrYMK%Ofj`iPu*2I$3$9WL}J_C#RbS7<6Z zd)LnZCJp8&kKG|Uts<0XyaE;bGZ!5#PG677r1qf$#QaW;0@^!F^cBkZ0PaOWlJRiS zMcGh{biPa!vnJ7#1RRh{mwCe^!nd2Q@Q?pD#z!=W@ey18vDetNXxJJ^yLj0XB{oYO zmnDYU#*^P<$T_6w^az<8K?=7~N{lNAn<#l7Jz33M`-Nn=xBp%i#zIOTxPc;HCR<)^ zKaTxi6R{2UD@7n)ciq7MGqtp@K-Uan8=><@JG-p&PJo8Mp*~>q4LKLvSoWBt{MZLd-FU~O>|W^0Hv_fgdA&XgK>wQjl$gdMUjz8=R;Cht zyV|9UPhi5Tr&KKT?qOrmCUsDWn@pH>D~J0~o>txMh)N!Xn$zCSMZNV`;b2MRxpv-wW+tR}Bo4S^TEeyOaD|?vlwexK5aMi`| zFSU^*Jd0LghHzL9EqvSnwi4Q}Y-MJZP#>wuJkTEFV+o<|`E)>T;{bjF>*02~p4^SM zAf%p{M#uqBQ)>}A5ft$U5wdVhepmV^;J#|wve00&jPwA1H2`YL!z;l79xN$pT)pw-6*y?j5P9|Px~}FV=HvhpHqu%`gvU7 z&@zGNt!4IV{envyd!b8it9HVC0!`TaczRCUQz4AV?>8Nx4y;CNNKMJI0V0o7S2&W? zk8{>7x<_>5y`F7JGCvTw-rCvRs}I-YYOAxgcsQts!~t z(ak-)S()Q<1B)Lcg+P)1oVL4f3uw}7mPP-<qxN1%0jbHY)1&Es=L^*~MQt8uXan~*LvDYoNRh`iisn`CA zklT7|AQCTt8zrb|UxmeoY#Kw2eN<~=lwec-oyE^@IydcJ;g|11Eev;=$aWT{KSJ%+ zT({I0Rg^bn&j*?0tXq!sZ$qYbHi6m#{4P@487Z`ksY`FA0r5{i)!@NaL&;*MYFP5M zs20jR_DmESc}fIIDd`#(*dUkJ+1X^}V|dQ-{0WFzghAh0De0c+uib@$eG%{=@nSFk zxyN{>WF*hR{>q~WfbeSy45LR^1XwPZdIB6-68efWwgC<^j(z7FKkKahh^%Y>G_2>k zPQ_ZY@r%X3K5tE6pS(tI?qvdvbsvm6C_-3(y9yNFWo|jT@V)Yd|4AYicYtue-w*{8 z#^W*E*NWdV)M+RxcTFZb9#F)tyn}hT8gMvOQ(d}BCzKNF!j1Cs5nxVmkVd`(R^D5{ z2T>e{LOi8mM|4=-e}wHA79;H_`L&%Vw24tKE$!@AijeNr!miPIH>;@z=~0SF9bN1Y z^WKtxDTG6JTD#)iga6G6HhWjI{AU$}!JY(Wh-`a~rvaA%OdY0?qCe9Go)y`qoQc2S z5-&)E`*ryre^U~5(s&(dIWGN_Y?&dVo&?dYl{W&yQ;6{P?cBgU_3E)aBLTx?5{s(M zfHLS0`~U7GOil002$c>kn3Sx8G%qT8#g=;%q{=)GXwLDY;{NdAQv<^XaN%3F9hTOlHe(?Y-ZWw$FnQb9I z(y=V7R}FOZjv-mtZKws~o!{rmL`g*m-YyT95ej>?ii(~p-c9QJG@-wz^ z8J08)W-?hn`Ti9DnHA<)H(Q*9a|#No&==<(#rEeq$&$h69^$Op*3ufooCc>X@Gwm= zyDc^Tc+WM}0zL)?3xZAP@R=ZhbT)h6$yE!=Z5kU@Z#Mqm`~JHEL(IP=E!*6@XK0&e z5zO%NVX(Ipmv}fUVcNjLYcvl0RH?*paK-NNYB>T%LXlskw5QYcYgvPYWQAJ>peOet zS^72dqI@ot(~gUvx2K7}GU4mg>KHepQF&O@%&>V?pG|I{*+_MgiUT$^dfA=`Y0HSH zpTq%p_77VJ0Zw75e#^2mB+s_S@Wujx z7#YNzyNlE;+y;vABpW}qq%66fTixmu3Ft94T0m8UXZ&Iy4k3TIKsorq4Py@lrx#Ah zzbDI0I9m{B75=}>$r+hvnX=K{w_-c23W(9mpy)ULT{$~?GI4I8E+;dl49O62_oEK@ z+iAyAAa|JK+e|NdkqRW?V4KceMK^yl)W0Eflx*ega{jF`#g8RD*UW*X?$_szS3d`d z-r9BD1p%vMa2_}M(e|+c{To>^ezC--Mo&DwBr2cN$#M>RW?%cSxklnwR_|vPZBle7 zLHwX}dwaRg;LruCoP81P1rb8{sH?GT58h=Xce5S%_s2z`O~w0k>S)^4crprs=_COP zN8})P$ChZ~0q!b5tG3A&Zt8C3cXDepumS9)E3cC_C$_aWm~`C4)PZ_ImhXIKPOUtV zX`Tr3j=_2zUTdWnhNqgvhbj)DCG#W*N$^80PCbesyY(lHn9H_p`u z`urT8eiq(YTV9fCi;UdoR)D zwi1#8@=9b%rHQR{fe<;N*qM%`90`+RH{V+(Dcp)Lh;M~7O7f1PEGSF@!#A{*v2(T9g;Jgm%{j6;yBPh)|Fz&Vtt z*Z78pXG9)!tbv-K|Ju;1)G+H29CmNJim_9VuD#{7McZ9tYb@sXR)%y;2Tz_`%=9q$ zM6=Pf)5$JWO&ll1KhoQo#0Z>{Mm9oHm%?# zw-h|rAcX|GU`Y z4kVX#Mhg(t2ozrgVDo$yt}T%nPgDe_{MyW5i} zMNnf7#LC^j(Dfk~cs>>aJhWnw+2fGOS~eSMDdW0dfZWeyrECb4-zb@Up;Yb}Q0f8Z z+X4sih;EGKG~>ElY6o-qip_+4BzM8k!46JhL}V2oaO~b(Y@Z-94)hy>{zk&l9#rEL z^|j$xDa=K?P}cQgo3*-7EpMfg?gw=8Hbdw)^#}yn9v*bQFy{l%&uR*FaI5d}2u40n#F))PY;N#37H3 ziOD*K7qFVp_N6|?{xg=%(SI~CsJSA1rj+;2oCY)cvh~=OmwR|1+tgvr8WDgu2yLi} zo1T99Uu3aI-)m`3QZHFvQTU>zzJg)QHR0U@2+l?5DBq7vl9Gyaf6fHq2E$(e7mdQ8 z`ZJ4~aZW3ny~!nzKgQM8cg(}&E^3FY69w#rK$6;wL;i023yWq8?7X%@ zzC88)yA+|cbIy%J#oenpfPrTNO3LT%-*FM4&N0OweiWJ|du8JuMsN)$S;_iPVtMh? z{WUNbSrMg&j8$2}9s%c~ebH;r z;qSq3{|A2|IQ<02?*5=F>=E}zr8=YQQrnrDWMkZ7b5G@G7C~N14~^+jO78?s6`FR& z2Xk<=UzsEPAyX*P(H$Q;CI2gwiG2@eul!mxFZR_UUZaUgL(yaT6x>q2EQOROvL3WNo(UAc|J$o;l)a`ZZy`dtW}>w8%}10>aN{BtSREdT7ox&4Zog*mE>3#Zju(`f zpY~c|tmMWb8KTMQbUZNBtE#}#R-_b;)h9+)-j%G3mLKW=idX}DdOb5M)57ACk!6m( z9?>ovqs9Kgt;PF{x*xtb(3Yn)0~=W!AtR0A?`gPt&aEoY8WGB(25xFlY{V@UM;pue zuJv?r9oz%cjiWekURfRp3Y>gstQBUM1&&StA3Eh|1v6k~rS6fn$vtsi+;MI^=X51t zGL#}uq-f1@^b>0%+&^R^dBeapflHXd&%Qv;*^pPff>q#2+n~^UD``~|o5n5IVc95F z=+p}di@araGx@p#q6yy@rMN?mKV)EAtB3v&I8OO`lzjuM^ej&+lfUYb*D}exc3|l* z$O7P@pZ>gMIcZmjpeZM=j`y94ZH4vdrccAcu14VMPgSoGQzJ%lJ*N&WMNU2KbJh^D zqd66D9nt>EW7isp(eL8*l(iiN6MZ8+fDEkFGZ-dA02nRM32E9FP?RA9+uU8TNc+2FEcKxU?Kn#g`ddK^%Gf zkl7`&udya}Ht)U$;9zWxkgGxfFa+OOqqoA4^OdJ$sGAVvj=z(4 z@_8xbTML=PN4xazErBIXQ7n5r4uq9h-VSX1dD>BDcG6a5_c2%^mMPeB!Xv?vfXt8EvsdACD(O+|rvyNmc#TjRx^pHq*e}cjlzhK4? zd|%JJdskd!-W6)y^^qNeczqE+UHCs|G6f7r8gjxedbbkVMESwkz62{78@+krZ4m** zc=V-M0*@4m_%pb-=pyiA^}VIx&Rp>yiAjF3FEU4ZOv)gJv776`g1wa~u+rK*tfMzr z3NEgyK=*E&@ExcWu>==`zqO#=&_UE!{Xv=2kJ88QPG_ZHnRyRbhs@uPp9^Q}@pBOQ z^&F$p;cW;ChkNJ6#A}*|WU@hE1e1~wEf`@}t`Xjd^mQ0l!SI8k{oEgcMd?6Qys?HE z<>kp$@$M?Vf+7IOuyRsxTl@;7^XuRCK02-Os<4@FCL&+|Tkj@*VlA z_rvi@ISSx@rZBmB*cURoGcHaioM^DYJx(g_sj@bWPwbJ&9aR<+yKXo`JluldZgLfb zVvigT#xRA7AqjX;NbD6C-f)c;HOL+UqsigM1HTP9aR)X##NZ-wl^cT$W^3=_I)|RN z>KFpoRuqzwm%~o$uLm(UXOE}eEtXjmdWIj80~g#Q0N0`4L9LNw1AK*o=So3~sVNc8$Uq;t{>c@MpkYxW3oH&w|4frcW*f_SW zsbi}vZv8%qbkC6F|9sm5cVg3n-_C$-2r%Azp^|e}eriP~$Q^hA# zt?)|xx>6G|CbW{~&ZUz3PQ4CO0HR=$(+GFBKlh&pJlwsH)-S$CAt?Bx`CkoA+UNj6 zZ424kM;Sp)*T}5H7IE^Fti(-57|C-R8il$R4xoafiMC(X<7`9sV2VlKk|lu^v9_mE zk~@AWfJ_!@xCKZ!1+5TGpe2O&XbzsEkchN_vY0Blf7CCzD_TDv>8AsbxfYQg;X$)* z9#K=q0HbiKUXu7-<5CkWMvP^hPveCUlQoU+l0_b*4Lx9}AdLs2XYNJ)_u2CMjVg&N zDoBF)!LjX1R$2AuP}cD4aT5JnBi!|!Pu)dPnHB=3Lf<=HqpU*p8c*7BV zD34;SbZC(V{lG7kO|!8nN0)LdDzh|Vzj~LHgBXZjOh)09@5M8zO*&&9jWA=3kjVRs?*>4#2FKs@hh}5{`Lg;u#NK{RF0+|4>SK#;=oQ-GOA--+5}D z6#p|g`o0*n#yy9+i&;55yGN8lD#9Z62}k7QRY4|tz0geh`%74vzBkS6^J+68{%6k^ zY&b4k`&59n*rxS+{7V&Ej`LOxWsJu|+JdYkt6Mfum@Qw2KUh=(WLWV9QuTTAZBJUH zeAuhSXosw*ECH|zLJl%P=vOSO=7AFcNn(Wee4gl}0}lprU;0u`t}y|v)b1wK_OFY4Q% z<;Dn#Psa(>jw9$QvR1_-x!p@TZT|Y*R@Yl>Q6mP>_<(ahMD*3Ibuk(U!4&sDp91@o z@SCHsSIT%6fiew4{BrdKsem-N*+*ZD36w!Jqnr>7_U^|`$?mJMGB}KTi16dKvE{BT zn(5!)GOMfAY~70~e@DK&5}a6N`VrRwpXws}$JYAe|8Ol;x@LMabb`G(wl!c6kLr=d z6u@8`xQbK)P5B>NfvxFnN;$1W015DGuP#;Z-X3|v+{DnJhMjDcMtXE~k>^c6I$o;~N(v6Pt8m~ZkN=$MbA^x_ z?#CY;l~jt5cPeZ#!=b69p7_niWf?(kdeDUb&yAY$DZ&d~`oh!}XT?)#tovH7Vxej`3O9(QP&g6FX&dXI+@ z{%B6*bx+naFei=nXyVkZxg+iUE|+aXCC$5VQC+F^=pv%>0C1*;EjS?*Avr|@dMp7d zvE~pIR|I@IK;@Pl&~T6uPG&P0H%9zp%C{7sE_q)BfVqVj4gzF8C1`aCcRGMJWGRTi zQkD%%>Mcf+0!>Og96V{)H=^k!1aO4Dr3^S8BZ%k ztoAXH=!l4(2r|#FLFwO>7G1mPZ{+|O8IIL@9MaOrG zO~d*479-K?2jFm#5ZpnpA0*3uIy`hM5WRBS2@k%1#9tP-G4kXUwt`%(i+^V_9ARL& zlST9djEecFT+j9$ih(D{ieuAUMPTNd%w0*OJ*i1iHo`|o7Q<_jQv38hDKm$H@}>GA zJ}WUTJYtsT$*YcCHieY=MQ+v?cJ+s%X+M&X|C1i1W`uB7E@j*qO&T_#vVT&(QC2v zaj{PuQN>-i+?0lhW9p{3%4^w%Xg-+h#8kCcf+6?FQ$%_pyB`2nl#+=SLR6R5l$_3X zW`!jnuUT`fyY7YU5G*5F@w~-6^^;960Z71_NvC#`mZ=9#YpsN<$4Y!P1Q$4)3Nn!? z&J*$ECi9|dHb6X#1-i0Y?y7?ShmhNq%qo^Lo%jLxCH_StZ58%=^nsZM2w~%*xTzJc>n2t-$g6qyT`GV zCZUSY{lcfqoZFw>$Oqj6P;TSLt9Z{Xdr+ywcbm0WiYoH`Z?-o)f%Wd*Z>oPAFazJW z<6qqw7#_Jie*@sMww79roA2ayP`p{PG92xIkMrLaKuscDYlj_=at!65sEXFzJzM4M zOl9<8i+Q^*)7_zTm)e0Wf3r==suN{-*O<5I{PlHY^hFho#Im<&3Nc+E^$IUkPd;;e z8^~aSaR<(*_TM=$s$t2MO`&L?VW^`fGxRds71m`NWAehGXo?07@hkXcfma1)?2uPDJYHa& zfWA0Yr@Z)A_3%zTeQ&PS4>5++@R?#D-5!^P5wg_%X-Xco`>RS6QaRats} z#fnAJIwpmIei)yZsOxnTJLGM5`dS>cJ>$spYm^H3tVJbjN49hW-R~`K#CVq7{yVH< z85(=fC5~5X*FIC%M9mBJwg~e6(`fy z;fjtFM!w?_Na@k*s)h2n?C>4UEZWDl=yl;YcP&;^=Ey*L_=1nf&0Ns?c2%e+F+U05 zn?yyB7-Fz%7J?YLUR(eAmV@a5SiO11QrCf7Huja4K$QV!;`6G4-26)JkuWvS!EAoB znNCFdaMxwC$N3E4z1nMZ914H_bW^`t_>1IbkXr(+Yf&pXzoh?&%>P5yTSm3nMO&k7 zDemr2T#CE9L-9bNxI>G(lm~Y&Qrz8I+}*9XySuw2H}5&$`E`FLBO@8f-dQr|T63m5 zdrV6}Zb(jMiZi^YwV)-ala%$s_;=qs);Qx4qLWb)AVQ+q z7(a&kvZ6}3hf|~8p)zrvxwscpEGZbUKJCgEk%S9;t58Zx@@&>TEj#3~`>O4E>nMK} zZ+cS&&}4WhyXHypB}fuQNCgv8QY%FE_i64-?zQz!k zdAD7=RKiPKqO0?@-iG;yeEvxlORi$X;g?X7x|(;>E>+58Qim_d6BiZ!ygR#gP_Ax5 zDN5u*G)DNs^$~@T;}eX~m=!A#k9Paxzo_eDAebC1e2iF=OAd!8YS+}&jRh4f)RMI- zig@};DxP&J_Q*0U)%J;r0om0g=wgCS@zHMIM|9e{j5}?-{XukERyx$X9+UUQPNYgM z*vs*)0dMQMvdF*Ij1S@FifpVRR6&w#n=85VsVM>O7#THj#D|1JEySeN*6U>3ZDsfZ z@Zr62)F4$bOBsQt0ZF`VSE#$n-#-;mT#sjIYl@B>y)64XCPYJA{pjgXG4+jPcBq4C zIOzZ?Ymhbl{_|OC?2Ogvq!L*T_5O}$zEQKM;B^CjZ4Fdbm^#{tj4vmHkeA%joNx?= zv>M~a@h~4o8fs#KBhbq({L^OcxIPCc`(B@B!h4wCTHq(*$hb3l%!x{#P1(t5-83}! z=1OEqqR{G#i<7BCBKaBCfoW&q&7adf&keGm>PGFVRUE5){U?5yBW{3If+py&R5A}jO~B2-9aJ)kSb0?&c<9n2 zJzPQ8$*Cxw`#VY}h$A(RW5UKd^eP`q*^0&Eb~`v6Zuz3^eN66cQO#p#Wg`~)cR*%d!s!8hcr}&ME@lM5p>#BW%)z z&O$ODPTi4-x9+qG1vXReN)+KLD#~*mr@5Xb@-I+ADq`t zOUS5{hL96&3o`{6NUaSWE}o8|=!*Z&78d59v_)HIi|G`qotDvOyaeW~4>qD%$M>KD zrNlDXFXY49$+$WV4(WGO2VfRmk|7hiW^*PQ+&^3?a&dB4@tcMo<1NO$yOg+@iW3nF zZvVk{Fwk+PV)jqBl*dlZZ6_5a_ZsDAP*rOk7pS~bGe>%)3CZ{TGk$0`o1n&-=v*F3 znN$eUp~q)!g1dtSMqj?4F~eb`1;?~h4~|+;67pFxD?l01SL&&OrvKhOG7t);L>fqC zW{%dUeW?qWwBtF=xZPe!=nd7L-E!;RqUEQnmd+eV4O$J!wA!O=yrP`_tl4f!=so`& z?XmRra(E;5@pH6ix&xnZa`_yT4UZor6BQQzp5`^%{GY&jp+=#sv1mJ;x`y0 z31yZd*sp_Et(VKH?Tf!tz5jI0R0*SD%b4S>86|iekDNg`Y!Y;dc7}1`8Mj zEU3;W7FMF&Ud!^pYqmNFb7>QLm1{p**=eD+MZvnt93M+pb>wJ}#2K8ih){7+@kg+V zwz(#;N(pAmoo=vg8<@D3+-A^+wY4;@>e12u0`CI5@N%+uTA~LY87J>yW(8Hin zm`maOM$44MkQ={b_e}>6y&uoaeU6Ko?67M3KzGZ6#hCydT9d{N9W0+6_c04p^-q2x zv~Gg3uX0w8xgs-Nj6@PQj@mMT9)ts96@uo3*Ks{5LPs%QpmG8caRG3M!6uPw?rlA= zr9zSp*fW}ZX$nN@GnbJHJ`7ZivJnsk*f?I(05;b#}P0YbP|<9srZ|(N^rs9Gjko1I zAH9H`$hoqVwL^$dVgdUg)99d{ahPhp^Fp^}##7UWf4=v%>(|MRuiy&+0`3kB&3c|K zHgN36J@~OyW4t3X!{vMZD|_AZAQK*qMD@U7<_mB8(HHxcH^B|hiJkUvRn%sg;l)W(xT^*q zSA*{iA-Je;J*;;eeTJgs`t|ECua8X6=!UYRq7DqMd6bWDnK!W;b`+)=TQ zpiCGR<)X2?xEDoE+vfMX0Vn|BqUI8$SvF@S;D~B+0XRwz51XD6S}62H1zWWy%BWaI z%+F#~Rx7d7tGQpax1y5@-Nwhhj-MDpysJ*y4ue@=*B?4~U7v5CQBS~Yovq*p-;2A4 zHTR8d$dh0!sUQ%dh0)>UaNNOQeL#IXOF>h{{P1w@v+FHuxpi|t)q`IRj1*U|luo+Z zw4Iby{`<;%KXM_&HS>cCHTv{1bKz~G-0tTbtM64LZ`&4XSUcBye|U1Z;*(?&`wpTt zcdVap>_=!hhgmgnZ~d`Tjbz0DxEJ~8-}S6(mbS<37bd{nAG=Z7XOwgcx^rRQSI*^J ztgD7Vwc$g8Ji?(f^I?!|eRX72WgXKSY{zBhlFAbYno12Z;vqes^U=fQ0F}xCqw0&i zQ0!tL$I6I5`YS@iB36hD6bjIB|B`NVr!XVlb+lCbzxsKSn{dj>+@S@Ern}qk2~eQ6R46 zQ8tE9!XyUyf!FL_5bB5&PeGjkuPGW1)_9KxvY-zFqzM^E5<;A4!|DvInS%2q1F>BXvH`H*`jw^o`crTG z^-!qj>z3$aps2_7FrDFjP0E@(Wj<2X zSG627T3J46zzb3&)X^Y&^JXFSBKq!!tC{Sl+d7TkI?p?;cI(bw2r99HecB z)c(NPyT{|M+z_=Ba)}N({0Y6%eSM4_SIqXlH~sjAuT}2tFFOCc+zM+h2Z2`^E+(-T zlMTHy0662v0xyYbQ!Uk|+106V>k1AYjeNdnu{l`|Xg@JL4<>(n2ZTH*$%r?+?SM^R zEXr~YjY1)B8OR;JRyHr9Z@1j;r`|gnypk8>)03(uqx|1CABIacdgy&FHq&7@SRao; zjJSs#J1cawv?7q;f4y#p+um1^1}MwueOuL?!1hAtQ#AyMc#GF3g!ys;c9*>1e?Bvh zMp{7{{_z&3WLm=BoA!C#J_qPXRp3T@yzIG|YDCL1e5Sia_nvIw0NIIJvZ_>lJ$PeT zvHB;^h+ya&-$?fw^6$@Hg|uvL|%Exg zH5DD#d(~p!;vjxBhMCWeV)Mc3!k>BR#gi9EgT)T>RX4v1{52`9-JFvv5!6 zzUGP!ZSm>eWZh+$ z`gN1c=TYr{f7fJ0lL$Nc*6ImL6thQ~l8WpLaQ}DTlSc5F;6`e8w&B+jpLE$`_a(_12JlM#a z&b)r+U||ee*G+GH7@vO%h1}mdZ-qifKPtr<5cB`A4_PYmcbXSCyhO4}5)qX;K291x z3O8F+vLR(|O-9BnrXc4GS@sS@PbR@juq^g;HpFEd_$|Iu1{TBMVvFs?08i5A$@atS zx2w^dLjw;ouML$+Ub4|-Tyl?Lcy;g*XGsQ(t2>MLH+9v(W+jl2-t84+Z zk(#J*e$0V>iUPlu*(1gX2_|Nen#TP7zO?dc9y7O*5aazTqRIrQD6AMTw)v`zx6P{# za~PMEjK0C?0utn^U#Mhyuab8bxDH7JS5SUO4X9&IacRAae$UXNOFTZSHdEMZuvu8f zUGg_XUlpDRb=HAC`l{^#%{|pf)%jTDb_@M&ZR6)_FL0A9`os!2ZTAh^zn<_S_4n9! z9D~Tgm!ZJLgD+4vHFSUsdF$-7H!;~3g&eF8%19^zn9GrqHoL$z`pd&bXiRtOg)imT z%`KGv+WFX|A3F|(-Gjy*z`yuQy(Y0)#C&5hv{3xx>JC$g|C2AvO6A|0_oQo`PwCYG z$`_Y1A}M#(kmomTL+5d5l0fM&@o~zeB=?wey6VRd6*c-(QGUqZQyjRLU`eacf%a)JH$^H$xT%tuBSuiCzWKLJ;4xNAH zj9OjMgDiiFg41s_<>Sgb@o9Q3n0#seErVi>Ly9x&Bv-q)Z`<2I8B1k{u>NC4Rpi$E zoisf9YAI1$KNUZ+JxTY;D5*H?e{!aKO@$feGTO!gR5o=aj|_X2iyAta@Vmrg0E(ueA_@l9|WhVevD~#iUrjIuEs?s7*(~6vV9^2K|a222J`EPa% zDT2zX-wd~dH^J_kMLPMun>yMC4C!)e9rXG6$IHn|DuhxV;3?{j|xaVw5>XfF1l zr`_l{01Nw2nS3ttd0E*I*$FYUBWG^ADowu-uD@*0ujL%SS5X;z+Ydfz0^(k7T?HX` zDcM9Qoj5YRy{rH`sI+cvWBG548w?r|;LVf;oa^CKQtG9jw^AmKgsjDyNi!t>tt$aH^&lflkM@U) z#df6Kjm|fLvqR#KO>*H1xMe9h!J7$-ZqHrN3H3f#)8m2BK5+v}3Cn!ezX84>a^iip zm=7X-94MFN7jL6dkE^Tg;U8hR^e8B`qoV*M62(c&lDu}t>Xw#8=-1`g@ZIjTlCgV zI#!SMn2+Iu>aMw4BcDf-42i1};Gq8E{rF-Wy=;7<=^; z#qk|X+^FuDT%V``mPnUE{{*g{4ID~_&oY6xQh^_H7o~^n+w8(*9>vABQ=zUgaUXHk z{u}F(baq_`pJ%1dOHFew3)w%h6U6zz4YF=YqSdj=wfQy1D~9K$&VZm;^M6`?&okNJP{<|u`dyX#TQ~3w^XT8O*84&p(z4!imw^sJJ*$Qaxr6tgo;>UL z#0=kaA#GftEo(b$cKJJ{#+U_=y*sQAjE3%1uL@G(8Hf5ds~EI$KHiW&kRwO+Z^4w* zuK}#BSbwLISRoUEwc``6iBSR5FB89NJKffIJKHbSA8-C^#v&I)gR4WIdQEGWtM#Z* zMZkY!$wgcqzu0?WlMm~aYHmDqJX}>ztDLt)vYNQ~`6CNa7(tj1et6DRR&NI~cR~w= zkL8BGhmzz{;O$h&Z`pX4{@xfaXl<8m0Lo97_u$@zQqbB;mOSw8Qps!Op8CAxk)^mqr?;4)&O???rxnIt_RrA;crDl$6km;`Wa*YQnoSAuR^3%(4m1FvO!tj93#=}k{>sun)2 zY;43%V3-M*p+?gT&UY@Ra1Z02w2?J%e$cs?R;8E#HjItTQWwprrr99lvfR_%ac~lu z(d*Ei`l*=cj03{ZW=Bsp9{Sg|Je7sM9NvX9C4i}KYAeOyCSF=_M*{&Z2!`0_039Rx z4z&gYE#nl!PM`qvd-d-P!*G2(RQe14Uf5^L^MEW^B{wx2BI*s`m5Mn+CY^&|Dca411J~r>@~Hb1^bfd!+)N z2USGCi>qPhXYQhp-yyT2cI=mosf(sMNidM^U*9NCj+FlRqK`Dd$sSzxQ(UGIyT_I> zWi9v6@vcE(6WRx1h+OJ9NA58B5SuW!I5`eUrOx%c-I`?m|o{04XhGH|zx z0bo42Z$QrN-*#BRqrh#Q_f_bx8_1pgOaEU3uV$HR3~85g`C&)RTXE7R3O(w>S5gD_ z!=6AwIVJXRX9V6jZwAbsKy_dig`Vz8rD3+Y%=#a-1Zr=0ju3|2@HQst1}A|g$ttz0E#s0pz_zh+SH7^a-<=S{2yl)FyLO)=6cxX%eRkXs}ZBHEIgQvl#r>N4Uk2? zhM)_gxXmEL!u0+_HlC|tgOs>*ZB7&SoS?uY>*UuGn2~^rG`r&0>D2*Sw5=!7MKT;A z#2R5gVr=_o$+1zCa>t^kshnL=LIOUe%%&c;kbo2+OJUY%r6M`L{KU{1h zj$ZdW9J?F=Enm;c$-pY$J;+hD?~~%=@G$Uv1~z;Hz_7Q|imdH=r4C;~bzrw`)Ieu+ zc15zt4~p-HkUT|?Ai$kWGLK!aCo$^`@mg}kq21|uMpkAwEV7`?9(Rt~p|Kb`6_wBp zM+>D2ju$~(Fnb%A4FNCwP+6JW<#(p$k1^QGCO2EMb!UEnAqeBta}g~z6({=~lt z@asPaNmZzknp2_Ea$uTU)l7IHKC|A^+vevZ=n1V)XNVjw0L=?pee%?F<+Et`Z4FUO zWK-k#N`^TlVoty?jhoq0SXEh-g;Q;cf!EO<-6wM2>m}%g%zO|*LCZhhqclr0GWYT| zKn=ab#yStvE6uo%_=oNUp21HZ|fl zV4KTsvUmYcj(D>UBw)T$mlvgpQirBQP>64Ftrby}V(Zue z`ins}bDj?D4FXXwQfTy+Ae)<(IDPlm*l~ftrG1sV{pKB}FDlvVAV8dqkL2W7RlK2| z)7-<5KeCiU^fS>sbR^^ZQh+r{4V9})#9N5+pT$%s7=mao!y?8%>tV{t(qE4EgtS4H zfWc9MeS}e}CO*7rsb&fy%zpP*JPIKcwlrivHAse0SAFOewid{on>P)6WD{YZfxI4=&{+#?C`&PE^vF%*7(CVSEpR6LqS1 z6=2?P-+#XTbTu$8yG2Lg9V_JZa34zw(9Mk@K&nOOA%U_0-p1S;a_n~Ji=-sJ)2t2j z-u|AQS%Jg?uJ!i+s%p84Wg8*(5TvSGFSeVo@L@H1@$(YZP}^t|#D{F4Qr-Bgp29EM zk134PWVOF?mpw{{2ESkb{D^yM?PPNWBS7$ugy#lfz|zpSew|xjl#;ZS-5CV9D$MN? z4&XDC>&VZ&r~0PVE`XxT2l`cvX+MvepITm)BFP62r%#E}!o$Wg)!)62azO; zr>aseQTnB(q89^Ip@NQD*~Wzd~}koXsvBaBBA^M0|t+ug_A-Ca721xH+E z^jKw;*jD?O(80?Ty7A7-MHQi{ov?FW+1r(0pAW;@Z?FBFUhyI8-M~F?@tVkEtgdkZ z83bM)-2rqhET@>5zGPb2s}BT@6OBsB_3D?s)24yCK`@H5X+zmL=~q1ZwDm~7DjUtM zfOsp5wLEU65%r*y&e`g2>E}_(T=>Z|61zRcI4ommjX&)W@ zDa-w?uQijn0^b(2I}(A{zh7V#YrIV#n7Iy~&Fkc8JN2aKq`s-zqRMLq+*ZY#?OP@E zO|_;46cFU5x}vPXJo)Cy9Q^j1DtHKv%M($l)T2~8cXcPMdB%q=rjtb&|D_`A4nQVc zwEj)-3;6P_GB7Eeo0;pJov-b3x6IW3l2(6P!cb>Rb}7+2eD_KyRRIGbHIsGdmekhYFHa^*1*OMLm^gloy-W?)+xBci&J zs+BtKXyRU(10g}6I=2FmP$jNRV=fCh95~3R1m%EI4@qWD9}n@kVb5r2xbVD2OJmPC zs5g)Aq+>yl1pAc|*BsASc}}gG8|Xch`aRBeS9BI}xGQIX+a$=s zV?(4ReYC+w?_jU@gE8qJt_Xc(yJPLrq};SWd>QeMMS0Qi9~9jRtWv9dn}ObuIV*x+ zCLB3x!S7K@8R-IPktGXEzPt;39 zXHWX(=7Q0kr9d+NCC}?>`C_ljZk~d-*DqKIsHF0SBT3-q;?V_cQY7L=O;o=@E=2U_T8?2yaqqeT z123KG*_k)UrQt>>KuTtzvocfC%lrp3z2j8nD_qU=JJ}l}4^d33GRFuG3OS}3SmN{{ zWJ>k}0Vb>|QZmx^yZaa7H^&ud`ch;?r;U_yY1hlZnR&a2sLY1i1OCs`?U!-uB;ZfL z7;{^50BNUi3AO0&u!Xa+%uOj5V0{gIVOF%xUN2;2-W_)S5ByqbnbiW)n;V11UuaHL zk$4U}A1UN}x_;>WW-s>NbBe5@h+7ny9o{SF$rA4RRc|z;eR1ARBQRn3*7e53A;pAJ zg+?5qn^~|Q{`6C|q!@VIUk#G^LsNKRih)*=NM0+NI?2zg)~(8gT;RXVUYL>{gp%!5 z`v@kz`sLkJ_{xkBf(PM-K$o^|=M^{{^}K8Gr_^w|)I2CMpH{v9D^rA@9&=hyXw`Kq z41`f0pSt}(#uXuPENZS_jBd-2LCjcFnO}+x>>{Sve>RzE(Rh4HZ;No!+hPQ%!+!3{ z5kg5ic7l)9is%JYe7^}V!MpzN*TN(eezSP$U6FFjMf>3)d%SA-u!~hMi7kzjEYP7t zmwz8;t-VXRgkXl;AKtQ-0HmX)rr`VIA zc;=(_dZD}{Bp(6Cwn>6HI9XRlRwKFi`*5BVJ|iABgd2B__NHJmK(pnhaXZu;tmgFjQdYjyvsL$mB|c@*WNP{ql@zLB$$k5lPp_@rvB8sXCtvJ zP10+r15&n@GL+0U+7yc2r+Go6p{;V|{YZd~`TxLzU$Mv_d{$5RM>GOLP)7xv11iewR=V*k&)??1w8w2)fcaIy+#TzormDp;{<&dKY@fk#bH_5l z!3^WGvLOaVha6txvV0B19VRA4GY=NyjABp*QdNYHkJmxDp#7VyH>46k1^(w!dU+1* z?TbF}!ezhF^~a0Q!|L;VI5-h-|5gOq_sp?Bk}|<=D6GF>F*gh>O={lkX`yUE#?ck8 zbxMAE(PsWp?^0K1QduY@H!>

Ps(Be`uo9^JK=@~gtrr_WgWq^3tmtT|ujI_fsZ zt74|hl+=%j9zK1KdnzghP77mRlk2aX|E)qR&#OOriG|~`+6e5TWr`q1dTzH{O)FHD z)HLG&>LD)sXDN0L!cfmNcM?~wqv_avFR8Zsju)tg@Dy+-O49zQ{ZHhH6lWX!I6yYJU=as6|DNPu+tb7f}U+g7M;+vfX@6E6cKg z)>|?Un?HK(Nnj2i)mCd_vxQElT2!cF*SiWfco>DCywjlg$FLT~q+%v`GW!D=mz8hn(%%@w z&)S9i9BBv!0z+7kSBbVt0*r&-FZ~2<-y_iBM#C91YMmkAM!_2w^7q=tQ@}FLn&V1N zumz~e5lDupnWP4=EB8#^VI8r$Dhz#y19k)DtPy^-m=h(ye@5vpAA*G5a7F zp@qR5D()n_6T0Fq@_c*4T{UGql5Qw9*Ue^NWV92kUP&s$(3#yvLh#7e+x7h&j9Ftd zNf46((HG0v(;%=mpQ68p`>HU=GhZTK={3C8avY`={a|K9+Oo&>F6IDwtU{?40!IJMYs zd1@3N)3|w@`;p$$>T?}r(|mNznov380Mc(H%jf*Fh^KUn45SX;elIIa-EPrk>!0YS zs9!1=Tr(UQH#xl->(Ta*4Fs6qv9%OZ<;^rxMC=V}ialbhzBd?enpW;ozWDiq4oTAH zg_HtU1HcP__&)))U5MIgC;Nq%7rYGl^DGMawRfcdu3cmv&e39GvQHyy3EH79K7B8a zYm~v?m$;{M02HKM;=&FwToD;oYg;_el2WQXr565+W!IeX&CoUtpE`+?CSrWJ`vTGk z87~Ge0Y?MC!v=k>2xLF=rg~$)GrgDm|NR9{DEjB~p-BsxT7E$i1C8&F01jwRN_%X- zr-@R$)9jWy@d_yKkG8;vZ%R-AxOOo-ZLv8Tr-_#P9c4^zjg4e%dF3ZW|1UzY9Z|J> zPTXXsUw<@&$U^30A(tB~zI)^=o=4=VuXB*~=wg6-@#lyCeR(t4^eUtSe4e?#;togt z+J3yUu|0)uK_}-;tMEq&zC^^c7BfNTb1xv}(-;)@RPwHtx1es;vHGEPAbtO5%{!;6 z-T=(CZx?N`+I8QG{bt!3 z;B;neydB?Xzv+W#*5%ekNfY?8H1#Fuf;1e)o3b*Xs|-PN z+e;b5%QZ*nHIPE0z*VUOtDZD;*=>CJcF_iznrU>=e0{<HhuAgasQAdLSR<>(tt)m_>%SUs>zY@H01sCf<8oU-Hv;1JzkU_{-7jEfr}7Kctda?^O~ znR1T^gZ&0Od6#e2(k`ec0E#)D?dYB)H<$Rn=yhU%efvIQgc8CIw{iVEnfQubZzT0# z+4;6M;Nj!tg=E}5yXhA`Sgs)*$5$33<}8D&2$hl7LqvHuj?!QdG-~mP?e|v(1Rphr zQI)(UiE2uLOKp-Aqp1bp#UAoC-lSf3h2o+q{yVt^kzw_-O|ZPlm3&As_~Tm(FG6JG zKufbDlF6O1#it%#W0N+4#U_^!TWh1bRe~%-Kt)f`qkSe|e45u+G0V?tdb>WlX~>;r zVZc^wM;C@kERYrMVf|@B{Emq`lbepyxLb_Iw08doEgC`P2p=w>gDY?*kst^DYI&F$ zqfi5Csu1rM*Z;kxR76ySF<~)YstGF9)GAzMTKjYTXW?JRW5h-0-7a=uSp+HO(^MhK z(k?vfh%uEoJd>|oD{9(>@z?_m0s6`p!B#(CWQ zQ=dPTzz`O3Gma<#QFa!LFt&1e=sQ%25Jg~on{8ed6Xc`G#CU6GWxOVhP5q&PrIbZg z)IF;_!Zu`@lcfSua$>emFO~06s!AbcYvV9eDmLj}WQ&W!S&J5kdX;2=1!AR6{-u1RDS4p$OIXm zx0(~i(}I>X3-X^yB>Y?$LFTU4wZ$o!S#lk$Yh-?mNj_vqg72(w>)l~7Nfm;wgC$Do zB(_-@VTi1=w?1w0&IsYz0Rnt2)rVm_7RF+H+Y z0EJGc=kKzSpfbGPL^)i`MLE!i++cqk66NaUNGm`G3hKRwlhI2iS>h=B(OzdGPmpP@ zgZnX*u8~c>G?A%Zrg&&j#o`ZlflU+(Sf<>{*>A3iepIW_s*ite;ww{jQ>jJ5-HQuS zD>aA9*20%wLNdjHCW0a!oz6G5kVf3eGil7lWp}ztEoO1*Zgo+>Sr$e9{+1nz#-zfq)>#ULA zvi_VzZ^~YQ1TI0YYotCxOEUO6zaF-%*Nq*MLnkQQOYQrl!!7L3GOsv_1JKHeBc}rG zmna{TMx&3syBchtj8S2GlkHTZ?J;4VvHWeCQ#1C_^&{VZCoeFm0!lR(WAcAQa&cX)nO$l1K40?8nAf)Zt#i?7 zjOhKv4*1?RXJJwd&D36htpAo)45vXNjAiFhncrKLnLADNRT zt+6IW6npRI8AdfN8XntZ_Q!ZFoy+M`34{EduJfaBDw-ry=47{TfiK4vydjK1qO`uO z70mM9j=_%Dk(8&J!5!H-r&@iR(5+hrjM~XG}J7?6!y=24_23HrRMWnDt9V7lKsa+(BV>5Oe-t&8@ zsk(}#&6uvu`?R*nsCSNWpQ3ZJ>!^e2`PH=E4QT45qW<7kWjTXmTUEl8AOJQSoEX)N zhsLoGI2k9Zq{gCum=_h~Tm-YJL-!A$5>tAh0R?AG!pbE&LOKpnBQy8&o84k3J4TRL z^r5Un^BAu92G%PEZ02#U+$k8IOll8;vP;h@kUsU+ma(MHo|J%0O88YCy%6q?}~ z%41ExsZq&sErO`-?_agM(EtX5VncyEVl?;}9fH{{q4|r9RQKum}*0wA4`DFg^~S#}M*JR|xkM>631)(aKoiGp_h&d*E| z5L(FnGr@9ah9Tz8@P{j=REGM)T-Top<5a6)qLM$%WtoUIrIUD=q5jW?mfdMl<#1Wf zgy?_8hTm34R40OPOja1a4DD~*RukCsrP8Q=_z;BWFkRw@1yJ#7v@FAxR9`7^w|nK9 zs$2%Tu!;n29!Ly2ANILUucO&0Vdv1Kux4&P8L)q}<&^h5J-Y|KwAO z(ms4QSf=UDx~wKuEavj=_qp+QUxU zkBmlM(4bou2J|^MNl2v-Y3j}}mou{c7=hQ^QYiRWo-{Y!*B($t)jJyGkIsyu%655d zjFW-@(|XhZD6_ffoM`Av>1;qeUaDW8Q`Ruo?0sKa2g!c+jem)AIU!{yz~Pbwd8Xg! z&ozw{5glt97s{w7DRFCq%rvRaPU$LL|0W2)5Ct}&0XbB4fe3B{J8BM8Bf~4%!|cT- z(Is7$*&W;^aLxB``zsd@7vv&Wi}~5~QDbiZhZX#M3cm7CC4F!7E9X9-t4Ym5dJZfZ z{}6jddZ?$8WkDv^YxS39vZaht%XOE;&?$0yZTvyJb}9cw<9fp7a*rn1t<}=SvZlWd zxHt`|CT$ihb%Di3bk4QsxH(L-jj?LCi>_H;^$Mq9_cs;%b>r(0Sm!oA9)37^7H~G+ z-6mdiDV@fD+;t??AQUn1`JlT%bN}pn!nWR&6@7=fKIU2=Le)3eNbXUZ#Cih|x@kA{ zQoY{Zc(E4(EKM~^fWG*Z&~kVeu_Z#p zbyIOeQ>DbW#+c`~jiemh{9!A{j*FmXm+0xlzH=umW-T&5AN$CQKb>I;ePB#lu)h*4 z;T}D}OjL1jU_EKQdh5!2Jn9j!*4eO`pgRUGvOI8AE!Q;gNI(iN=|{2SlKdSEsMvXK zR<_k6kNAdDC@f(lmPM9HwqX)yk}xR9-oU@V`Q1>tL%lG5TD71**5!oh32uYcfE=oh zx35ps(PtjDotdN=)JqEg4LM(SebGB1GvR!AQMZ%u`|&TN;d2P@V!c4Rc%95akz%Ln zE&aPI!9hgWwJ>GF4z&N}+#k|ye| zbHs>RRIPm8JwWXKS1P0QSQPg@uBBURMc~hJf8=*!nw#>V;k9o98bB?>*naYo{~itU zO?MN*g0pfJ2Z1dC2Hwq%z=}!B;BfE1Qa_-nt`J!G(YT|5L9Z`TtRk zG>Y;3`%}?}K;MIGyIxz+?vAra=&ux|6X~0h_>WUTp6!u-V9UBUtQqk&?Ts+*7HtEs zEPV{j$6UMvHYpA=Z9#rC39TdMIb~Vy&Un1 z#i|``Gq2{25J{%fG;c7Jm}9Crf(L|inu_xN)ABgVOyXh0l2;`zS_3RnJ!Pa-42|akc^M^&c#?(??)My+~IY(jF4eVpb4fHKgjxPU|x+ zf4tV__N)~B@}Br~iO_WpMOr{p!yvUbk2(^Vlo{h9iRE^}Z}HlhyaxUj05 zR+C76B9m@KT$)MBPUi8_s1xcSqUW;RVr2`ngGdn7e!PgM++M?2eEBsv)gwny+TbTX z!1_J9>~?zw#;hrhF{&btWHcW@f9me!6!JS0zDCJn%d3UXETLG=H_zs4=7ghVs!6*` z&JrwJ)}K{|Q&1Iu@EbT%vs)<0c}T#YYW5cTCMf@DxW>ZuZEU7-o_K25OP*kAt-Mr> zO%@SEXsyYp8!j!Nt;LBxpuRiwAKME|@mAvxj4(}WqnUCCeP{j75;e+DuC1TTnB0s> zDnD=URx1l)uZSp!s2(JHJgQ6O9=B3Od8J~YIpHn0;-FUq;`TI8kDWt)8LI`C`eokh z>5!Ijc3ZG?$>v6cP@q?|QeHa-@l^$0>Vj+X1L=7c*3>cPLT5}gBLc(H3Y5h zol?H;kXG@da%D>gj?V)hSEw!t4oK#bHI2)$cF*!J zfF%4bqcA7>hJ{wBn5YN_u?F@LJ|p&C&U&hJr*P!G^pCd5@YeAU-I%HZ6q3s^(IU*! z1AG&3j4||SGMeJq7qMCW(mwzuM4S9rx(3kqBd z8Iv_?aYOvZc=Zq(62)l*{R2(xz?`ZyWGOTfN;Tr6fGYv{Wa)QcbvVd+9C2=Nnalt> z8h*eOf5vhLd<8SQkwz|R$B;ggDynHOr@G#}ZHQSmap-a@vl6pBpCz!JV`o4$po-D2 z8+{7XVxXKkD_VbqPvFrNu+fiE@S;+Q-aA?cl4i>&3No7R^M0mEiYD1c=|*PJ!(BQx z!EJ7UI+FXPv15%^4}>ld!~=2OE<>JWK`w z1##hunk%v{-3j@y8lWwUVx-I*ig$fDAm(@a+L_PTsJCSc3g$|9hp#)LFejl`?MzX=?9~G>e2T;fyFrfr|!~|-YKNs0&!Sp7&TC+`; zL0!_ad{)2IyAe?QbItPc;U<`^9I-&q+5VA-mc&v%beZ4|h4o7{<3itOvT5o_r!ew4 zcM{9w>q{|mvL%!Wp&*#~O2M<)9&T!0y4$0sul4MpY=&7uppRZEi2IQtLOld`>8n za4B_=G|h2(gD=GjIxuFOE~5zIAwtVo}|0ug6iWybf-WmtK4o$Vu{DgZ_2j%Bsx|+Jm2+y zyvY4V28@mn=H`kfgEpnV?KQ}Os(UK&ZPKdYR%v^?hB_FQPm%>$R59zcB&u6zCBss< zFvqUS;uW~-O0_=*{?Jh?8{jrgL{evj2P%%#jSULzzowT(lba?T*~gEN#0E}iN+Yjn zy?;X

!y$sV8<+*UzaQ`!zi`^({Kq@g2WhM z+ML>%v-(~4D z=5i|sK!7P9kb_=f8Jyn zFxLmoVSLY;sg5T)o8>Q19Irs$zM8SGII%Aqfp9bZ*xAc{#W@F*ULWUmxw4%9z!&KcSvjKNcqJY+qXzpgl6b`D?;x}T38(M;0bP{mF zd%>E!)E$$WtgD2i*x~*{RnH;;up`KqsG7JJj!6j3_xoOnqf`evlfno~-S$b8{^SKs zx}vd6Co9L)Z88>hYZ15JKuo>TOp8!OhUBIuLhuldRJ!C69ARgXQFt;G9m(+{KgjAl zj(k)&;V9#u^y5Qe2!U!}IK4yPHk)DrpA3$?DpN-ubsDGegERyy<{cdi!QLda?~!8J z;9ZQeF9ih#@;=zMN(nw-t@ivx+rv(K@K$BgJq1jORBMGn$n+bJ!T`v$zu{Z&l%-VV zj(gz)Q@J)YzlEl=!|`S!?B@yCb;4&(ldeovtr>9;__XK>%t0-zibk8LIl4>1=2pO& z#BVR{LCz9galFy3E7sF1ht8Y@_w6mX#g=TKep6Zr;DoPn?lQDV1M%2@S)}WKT0vVr z8$ig)XbifoZu-ev4~UF2^wBNy?EoBVzxmg5FS}DlyVPHh9zg35YN~@LlF+9W^fjDZ zr2ZxlCiKI=4*Y8^wKF*0-|Ic~nt4eNboA{JzP{WflBRx2vX%d2>V10vbXXLw6yw;r z5`u_|?Ai}Umy}Nrd&MruDuwYHlORK={(r%<%GhX_Ee~}8zZfs|(XZU%Eo#xjP9=v~ zpSQH$AV@M7vJiF|izRcSjKfBDQw7$pjjRRP*zL^)_&rB{%71Gfr zcJ=z5@xv^q3UyKdCJkBL4KzhFki;R{SSz`eQQ{~CLzk2i_1B5YyoDaN(qWG^X6R8W znHwWhf}H1@tWOM9g0&tBqWrPP{1G=@9m$Y=3%ze_7hM6GR=Gr@2Uj(^RHVq3tQV&s zdQTN{aMWF+MQwcIEGRkpY|NaJi_e&%XW&k8%L(}MS*H@FhBw~(Dcz}}T1wiV`&?cg z4a%E8U-K%wV|mppmW z2zhy3+dKajAE9%b!DeuEbicOAI{)C`0SRywpxEX6+=!G;(XjyjOZkgyKO z4gDSQ`5D~cQfxrur$1U_)}e2NsJ){0B+acrS#c^x6G95fvvlypCVar2!OEe`M=G!@ zy6g~S>JT{l?R{QQS0YrzN8*0_Hyx-f@mp=}MbEEo2YcvY!`l(Hdv5w%=n0~2fP zZbJKW-38ZYJZJU|M|h)84V)`0n3%uOWJf+cTL0HE=xRDz7 zCkwQeo7Kx(-iSl07oH?`iz`90NrTX@8vQPKKFB7a@v8OS1~H!YP8`H0DT=cE?QSwZ zqE{H>vDxaUWMB_vvPL2^cYlmx;WFUbxNEmqGlf$#li`0G%m|$^5qMwAjnL;}W&3M? zK*=cfSzRNi?{G36QiX9W48MCo@ zT722Vek8D&`kSf_=RhzLu!*yU){QV%gxxTU^MfhQs~(`*e{chuM-%7_fnoL zMi}dik7sv+T>@R#pWslY{DX!lPK|jfaIJ)0VD)~7LY&HNY<&J49Bij}@%6caqN9&8 zcwlan|9logQ8eAElE*Pdo{)P*qaNtQ3NYQ z?6yKID$rr2%^ztBi~YTf5T%sqlf=rZk&wBsCU*vL6}jC(qq5dsxn}N%n^H+)=?}vr z{0LHqfP3>{O*Us0a^$8Di&|k4bw0q&w^QtcbwABNQ(Jqi4}3+3k(!Kz_lFO`+40zp z5Fi0G{6p(dVBXjlMaG5m8%z@gjy>Ltl-nuT%mPOx%yaS=XCbutRi)h?5hw{Y?wVrX;={C(1{scfCRqtvDwD&&A5mM)M=NpB6V&rIG1+4$;FhHv?>`z_y>9 zsx8OH1gxOhzTR)`-Ob&1f26_PiOuo;!Sdx^b)G-oCf)n#j+TGc3lbTp<4xv1#Lx1! z$LDA{_9bTb+_vW$Qg7n4p(q&+PJJg(%uB_~TLj?PtC&C!#vxI&6TL7k%#j96>2-rqrS-@p zD<^|dJebZcL_VpT2;r4z4Kdf`tzCSXj^V2L~$}r=!YJ-+0Uvf=mQwB8( zRi4=>)E<>F9>thMR%)U%V%AQnYsKPzzM+Ajm&R}VLMsF2NaxM21)n3J9W0r6>ZDr_ zUzcNqm-OTWK((1Iys^Q{zZU5&Xkm@+0g-H=-we-r^q7FCCHO#2mNO_@^Ij$Ht(9a1@B*+Le)yg*C?e!yVO0jMm7x-P1H`~DJQP6R zc@Yt(^Zxn3HMpq)gg0TG*2nL@Yn!6qO6KPF^i!P97yLh|H+^}TyZmB#J}1lit^U2Y z!?g-aW`Vj2oS}P*qi#2h0xVG*^HsCg0m+dEC0&1+dPaIHks)Hlgo(}}8u{;oca)pZ zHB=uU$U_3=stb_QWO7L?iYOwK_?d>h_VuGg9fH^G`!~l@rHyQ0%EiR$EiCQPK|o3z zlH%5kn~#kwOZ?JeCn8wR;F&c7ggCT$_b3TyZTE7`kZ1 zH!hkj(zztq4dl*g6hn92>XZcNYM1QcfN6>Eqswah8ZO=N%@~>?fmVg z1>Euw`90yL0d~!Yy|ll)^P4N>$u6DugB>UcWbD1C1h0 zq8k~rX`Z|Rxt_zc9(3=bgEm7^EKfNFv#5 zE6eJ&d)zMB~4H7zb0IG6d+= zAva$ovZh#S01<|~6Dh@G2+hjr+PPJ$tW|DbjoUTPO|FEbCLP{Igp8lepD)Ia=-4Es zhl)%>RmHR3`0Xm3|Q}Y2AnnnGt?Nqy5HE4cY~#xQ@imS|e=b zh)=g6MIj;VbhQ#Ae>ukss~%Z1Ntj*MEZi?!C)GNyXl)%NI{IVL+{~Non9-kk!Rktb z={O>1?$ye-tC2ShO__%=6WgLoJMHnQ*$@q#sCNBMgoSjZH zM3)_X_D^L=v;W>a`o>TXetlyZ{(rZDqL$1Q5;ew4&5|>)6+U_3TS=|1^!Hz_%~X7| z`0OJGs+-Ot${S^o0-8R~>VK&Saf;fFXv-q0uh!9ZQGZAe&jpfyZfyqwATFHwn@R6_oA2xZ*fMKEd%-dQ(XgwQ5YaG!{(<7rJa- zv@Kg+u%ukCcDL%shj0y3I?Md9G~`v0iAFAvH~*Z#4SI%Zj7o?)+n3EyS<7FnYgN?% zP7OhI^qDMPjplFn9RiujSKG!v<7|ToQ7m&>yNoQo8p4b7x_oX=j*HdETx`8aU;d6A zGedIGzL3DjpKcoA1(dY21fEjlh*d(pe)0DmffJr?PfNwmAIs}0#hwXrs!Y6Qdzbpo zc+EPXj&ey9cV}+j0nsiY4=M#Ot3>RbcH+VMCMJ%{lh8Gxz=v_ufXnYFy%#uUB$!-$ z$yleM4L<*L+6P-8&9U1L{-^%rxr1L^myO;RmHv5&yVknps+Evri3fF?nyDz}ZdEO? zjAHyBT<*mm&_Az=ND{HZ+%4+?@GXt1dD%af8N6ebcqb$@7(2R^<%Ocf{jnpHyJ#xi zJHCZbXJ|o~Nb!E?j>mO@Qu0Uvd&kP07U_MKM%GeI?07!{TK7OJ308oJ-)x|H<}kb; zb)kh3b{D0lnRx% z(p$V8krJ>fUmr!BC;>>)wMv46R`o3Cx9oeo(WGiW7_uOdb>>k}7-?Afr-wq)Gf@jK zh8VROqReAzi72OU6q1+HA_ka2`duOcjz-Phl`R^L>?j7a9JKKiU&8k%hj8E6pQo?? z9?eQ2O9ge-i21nUQM%eY3dA4(B4fv_(~Zlc#Z^EYKcn_*#qTverx};V-cL;@1@g+P8Q1T zst4(>l0v`mWnW5AI~Wyxk-OeaKSo-3u>o|=37kRFr7=gQH&ky!HD!8gee_(6sf`u2 z1EmIV!GuwE6ifHc#G-c2zDfOu`Oi~xG8(@fEtx?T+7$19d(E~aL&uAI=~X#TN-$wV zInf&Dw`>s_+7J&V00r>Y25tSDKVCceAP89uDAP|z280cp;Pm6Z9l$N_SAQUKDZTf% zw|8eO?%JNQPUl9W6ASV9PlAc>bBWGl1|oQ%ROz@pmEG#e(IAxLgD&^)(NAf;LBTdE zRU!3pJJ4s=5DYz>fX@fzi=T=~pCal7$xv)f;!F74R90wK@CM1QxGv>|b@v4kgQ*T&Lrzg5I>{@$$? zeX7$w*A1~%`KMK{9W0KJOThgWWFzDdf+O}EwbbY1C>I^XC#vD+-La2{JY7$#3t_uu?CctA1^?R-z zDLA{w&tN^S`bJ`g;$5I~NLF-H*@f8-irdQS0R=GaqPL)CIYy*mcqd%ftpi0m zKc3!!G0rYp8*XegMq?)p+OV;0JDJ!{8c#Se8{0M;H8v+`Y};(`&GVjfzWD<)_r3S* zz1F&<#YP0BKqE{^M;m|-VqZ7@XMa+}^6${+Ld@Z+=Hnm6_kPzAPHyghFN<9d#6LHK z?V#E){UvonQ4evsyQ8_VNcuKQ6=lp_qo4e4Y6U}acc!!qy#`C)4=uyfx*j-N$%|#? za7HI`KL(9Hhy&4?dhrtUm(R6FUtW0s2J>~Eq-5s$T|Bb__ba&|st>H< zL@b)h<{&9Ih~dh=wZjjnWt{q9DKa0?2kQ(ICQdtUeIRrDRd_rn;7!{eEl0qRUviDG zvTrOkHMNdA9=RktNsy|;=P6;hY<_5HNbBOILZSOhSK-y~vL98jaX^$0ajw&x@WsxT zWXN^T_d%HjE->Ipae5nZu9ooCKmJ*XVS^*HGw#A@z}PO^upr2^aHSaa8$31R$u?Km zIwM9{rZ7}UXXKt$j1Z&Qkd;$(@yhEPD@xu5Th-H4BX`St7SdO>+?PK3nGf}iT!~85UYoeij0NBK+9^hcSD9%8jvbn-0jLzw#p1+%@EO$#R0Zm-8jocgG4#)6k zDwuK_ewjSIiJ5>9WEW&hFq-5IvpZ@+00CK{sQT;v^ESsQ?*2hk$meo4fVQab_d%sp zL8un5hyl`C;hR_S-eID9N3r(H5|ED+xc*Q5BbZ8*)Hnd_+bZk}@E|a?$y0MggrP#} zv1(bMofSxg=e_MQP88)}1*eFCG^?G;<>u6H>SZ!EEig>3m-L$nd*-g&N#%p{nr)zBje+bZX;)#`B0k z`ZHIs#J_}5y*e6R7#EmQP47H#HUS{DGEh zFGL%Ir&ns1hQ@7MY8(yR(BJYQft zzR*^i=N@?Yn%%!gEf~QzjtO!^9hSMzx06pcGm2%vY(=Xay_v_26J+aOH(aM_<+_K6 z#Q@WV-weKU|Hw5|VpM}wTGT%nBq%B2`n!=ERK00{pw=NjZVtg$vWYLSZP=&}VaKTD zf2`N2>Wk6mc4(}W)7SWkD0-#ZL|2Gqh#q)kaH_=5kM3*leG$Ei*}N7v?qOHEoBv0e z8b z4$Uj!=iW&Jn*o7oo4lhma5mc74j=W81e^8@eh^qehjNaj6$LcC-$x#VP}s_8KoC)! zN>yz)-*mqsXl1OSCL)6Nl>Oo0aRO!$$q~u@Bnn%zRlD?MsP8+P#6J2Kv+` z^y`nMcqhx$<++XiRQB~np+RGl3=@(*j~Ai95LpTC+$Rxw((HiwOp%EYo>VJS86RjY zk93T=8d7exK%K0dmf(WFo}>~rNo$!S=vq=tnqlL4(zJmfG%rm8_sQtdpti(Jv7i@m zNl}X5;}zE5|K!**VVy$2HnAPd2aN1lYDqI`@ucwICi@c-CPo+Dz)feE#SU3KJ_iQ* zSN+d-yxo2**l-S1@!;ZiGU|Y!_=11x6nGsn@=pD0P1TrthbbZt4 zH-z|pPENQjE^@0D6E!q?Y~&`@PavIL7G+1Vfxfp#pdoz>-r5Z-^re}0%$3NW)coFw z&qk8e)2E#)LMD(ERTU?UPV(2O#QZ7Q(E9s#4;Nqrm#!wHj6rSh7IHjK48{d=nn@*H zNFS%>%UV_B#~ic)1Z+okfZ;1TM6YMA)24@Ko2~e5U*02%E-LViuAi{OU=*UgqhW_S zI_V^+tly@IA$0g`3_{4@1Z61@Ee*T0vhkp$)ZU0cWxt9^=}n16gJj7KGDnBBA0fbW-uo6fNDCa!j;htu9Id{ z*q2)>6uC?{P^O0)6lWHEp4SqPVR8r^B#8KSuq75OK|EOU3je7M;U;VG&jH>GcE8lf zH9cLtzH~_1j?3j!FEBzpyqt}Q2G8*4xt!|e%MWSm_-7S6WTffG&izU2?+>YY)gk0D z+Q<=K-e(TkEvG2)ffaDIvmAuQieE#&H8It826;Ff7|uH9M=?B95)m1fPEJkf`;G=K zENHx9Q`s#EEydU^eQWp|OUZ_qmeCJ0Ads4ZxB2jw?u_OTTp8dI+{zGhJL{wQ6y>+^mib6CJvoNMDkqqmjy2kkQJpVO9*>v)1wYtw%< zvu?@}0zBB(cD2J1ctC@|NAx-VFNAxooR`F#b;9LwNry6xmx_?n(XXInVLKPb#M?pS zj0qM*KyT_g5bKgzC}3-e@Oh<#Bcep+r7~(Y5rK+7|WkdeJ(sb zbzeC3X`oo|K+*pcq0nZB7@-$i9Nwmt9l4>vB%2C+hxIrisze{ zny9I%{!u(u(i5_ncGz3Ba4y~T)4{{S-G2RVIZn~OifXxNwM+WGDpPqa7Awjoqep=T zM#f$dEqFdh7}C~KD5=)WayN+3MpkJ$tQxbq+J`$iB7VLoJBH{oD$yjPo_G#xfnEE! z2&`?tPf)+NCoe4cka}J{9~z}W7!nRcD=)2j%fzTetUS?E?wIgTu)W+cFp`=CWGA!s zoENtq1Vz%LrD(x%%POnzFiNks4qk&B0^<;U(f|5L<_MbF+rogSBh!1n6lveg&^lAj>rqn6~T#$X0~NUz+$=|Y`JOeretK*gRn-bJ_JsclN~5!7jAkEnEgGv+^3_)%PoRZ1 zb(22-ZQ;eMtZ^hXK`f2jQcj=to_{_i=%U^$u3~DDN9Ca_nFZ9yv9nPJ08eV8t<_a{ z6q4XVX&o=31=-y3DCdcFEf!Z*Y|gP0MKz(?qpO)D>8RY>t{9zdCyll%l^Njv0SJn> zQdA+FPgrA|3||y!&y{0}ax z7cJ6}5&P-(BA}exju?8|Kw4LVW62@PUpI5nO?1lecsM`^&G?(@nW)xL*k>yyVq~#s zsNnLJ8|Bcx+Q6wk76eeOIwJfW8-MYC(bWPC8yOJNu4vXey<#;xwKeCf zj$yk^`^oRibTns|?CQHyEvXcIOK>xVCbvz{!;Sq4F#Qh?#JLB*H9^F``~QXoPJy-r zbbj{x@Dwe{_zhCxi8X)EO4rJPsj>Qm1CUm_}yZ--hiSt)Z zfu}-B@odOaLI zj_O`I$ISec>oK#;g{$R2bYo#-25KHVi|8@i}AX(Bu1+`c7^r^vTi1980!tm-LkDzF+XQRqmbjOGKslNNO}G zStGwre_w))rbeYAgf_M5>P0KI4TG9Q9+pDP3{Y9+9~-0hwD)+LH-<2jTiw)G2ZuoV z1(a*V{6(&4A|du{@o!Bd_6V}uJbbW)>&d9DF)(6&bW!#}fqP-V6(R&l;=ZkCRi<_f zOSc{i3-1=`F@Q5@`at!buY9&nyhEH0&Tx??Y@hH?d{m7aBujGq@YbY6O-V|D$0!5P zm|c*nIrgb}VYjhd3dSH+_KhvY;wcNH!kj#!dYcXHxkI(1=KzU)`#OHj7HLr>@ZSq9 zP*}Jc=bEM)#RXz?Iu;N6y5i8cM#ss zau%Ag)#KWXj=Jgcd&XNHSjqCtrpT%y%%2HDebJ8AVqDxf!^%X8iCP&vdLZE2N8`~EMaGaF z>|6hKzhPx<`+d<1g~~TUkxWuf?^jzNBF5P!UlP~=IJpof=)Y8rMyMi;nWaB*dNP`) zH?x339~}ls-ZPGW;vvSMFvSw{oKsM(aY} z@wDL=u_yDc@)uom z@-aTY4Xs-5Q+ofANB4H6DZ5|nesByw@!80Htd$*ymS+Yt+(#i5pFi!uk+{8u;z)4ab@&gDA9wT-lE z_nE6+*>TN*HHELMAH3R0K8su__CdzXm(>P_S}rP&WF>AWW(~y!uBVaU{hOz)HDfnV zM!t3NsXS8&!4Y`kNgAaB`%DN6^8$DU_;LfCg@O-J4D4!$f(My=_3W@zTmSq4O%DS@ zi_QN>z|t~-mzokqxv6brsb`TT$3nL#1+}$N?)+!^#c}3C)5`#b>2|SDl{`CqmEfAU zG1zI$M!i5MB5X0eNU52nEbr5LhVGH7g#j|B-jP0Atm8P}&6gdxU-#UR{BfpbBu)6S zUm(1VZNc%VsB1F`zG(<0l%yUBNP`ARBI*rfyAot!U0lKg+rHCk@AH(C7af3u#0{E8c?E@UXm`sMZwf?A}af z&aBNQGOX>#`QI+xWGE_^0OvNeS>_RQcng*we$_gIUFdQ_x?AS9Bqm_bk$wW22Yw&Q zbg0L{*;shA!{v=?0Ukw!AA!N@u8E#9U=rd)smfe}8OoZOH>nZ+6{7>00vgvMRLB|d z!lqvC>}{LD^?Z^#a_Y_Ac#8t5DrDx;&`BZ7Yc*H@b==wQkITc^&=67P{1v#5I8IGu z4e1Wrg&{S%CN&bh8kkz@kq4L63vjMTdVx*$#D7NaZ_3h8nop#aefyj8oingndB#@4 z=|N@dYdZ9%$hVFQBc0McuF#yvl7rh!4K1rT`BL?L#E^o$#}8r?c-j_XM`Um&O{l6v<~ zjOdJ*fg|L4F8ZtXTp7<=wQ{wHI5}&_TDizLTf*zHYQvMnLZ)&KTlZ0oau7>fg%fS4 zVc6n|E}1lN^d_AH(X^%Cl2?O3GF2ZZ2E|#=PAw6h_|%s8^jF-E|Iv2g>98Cp1iZj# z+l-7^a^drDLkQE}uQ)+ZY06me1%0Ozg~Sy$2q`%<%7^Zu<#q6Zk$VHbGx|*!bXXKl z@ihibLLmkL^P1H-;^g~JAo5K2Z^!X)6t#$n!19aU)@r->U37AnKMB}{FsmvJIF5Ju z1Up!&*R0yeg@wJUCQU7$5~<-N2&gm1zpstQ7`OC~s7t{C5dQ{}qYg=6c`QiBh9Eyb0f;?t8Z`^g26%%F__srd&kl^uWOj&{nm_o!3H$DC{6J41>PH!66 zPV`_xf(SY-kv3$B=}r<2SmXFgT*+HLk1@6iNS6JtC>5moS=PVbY1<{Zw~J$Ayq}vJ zC`J}!n8caJqml)&7`=Q+I(zlCC^Whkf$-rhms6TsRGa;(OfYNeZgaB|tSg$_kqh!3 z(saF+Cdo7vssxq&E&BLFM_*AHMn5UwN5owQSgnN?sQo`(Abyfarjp>1^T4J;UM8|P zm}xAHuo3*dOcP;hf+KY$a9Qe_LLr~Xt)@yQ?b&hWN@SVmn|xTuXZY>f#=j}R1)TuN zG1|H4*!{LFk;UnK&kTGvdPW?qK7pkjlP#&=>8iyDVR+Jq^Tfu{Z0HRlhI(jvqGi6j~o<}t|O(RUOo^d4-UR5>nKGP^N(8IK5vp+VSsSx9dapcWnUHw{Hy&j z1{6U)3IVxt{vnN4F-{0Ca-Scfm~qI3AQ`IFf8f^mO4;p^IyM3OuUZLDl1LW@kt<2q z#G)>Za$cPB9}z4xqjPrXMoe3`Q0mV04(%CkLA2piUrgDCpLQax*e>O?p|Zl88Vz_VbDGs=JY+^=k&6O z`|aw50&ph^Y`WIpgx0RK`c^vAR9)K=^QfORyKaAQ0fB@f<|Vjhn`Yez&H*TZj1=0`SXD#`Mf%oyP!=uI=lpYax}TK=j`SpI5TD(YM2c^Q7niWJ)t z=3u&+fLCcn8}fJ<@}M-+gY7@G2e?IBY3C^lo-;){rrMSoTd^!|9z8B15EExZjG!~O z*I9;pkd>_Ly995Ob69@E!N93)$M; zrJQhW)ll4^Z1t&?+fO(H)d?&OyrY(!+>@ie9XQhv2*6xMMaQ~$0h)fhg#xbf$b?tz z|JQ3F)bx9Fp8E0L3w;E8%pa^xtlqsBrsreovo%HPf0?0$;Ia80ZblB_0xH=nJ<4;w^) ze)e#qdac}i-M`QLx@gKt78^-@x^%vRs4&UIW|C_UoG8mxQsUBrm(%C?OBoKZ^{p3=du%b78Vi~rm zG5YyPHcba1kkq}PUMqgFyc*YVnBSau7m(d{JYOQDI!1%l_D6T$C9i=+!pdR-Jzcq9 z;Rln^5VkP<;SCfBd*|q8tvNqB_E~fpJj7|@R%xlU{q~&?*c$KAUYI(_3Q@7Z1LHAk zs&n>z{Tu)?0pXnv)Wmp&Vv>)238pBww_jKA^!|s+>XA=y$at-)P$sv}k2J(DFH>48 zoDQvX+d6PsQQ}d-(unW}&%ki;YGr2&5L=*smM337FT&d|w*dWP*0*^>MY<|9G}_nYQiyMlX% zhE^Eicdplr}|7|l8`;K@+L2_a1@O9U{LI-RHD$pk^ z&akxZ_uH!pFJ0Z!lZArmDrjAgQ%L4)RzLb#&LJ0%^3zop(1i)p$p2xH z5DjITX4}xx0u4&5uw^pVCJqH>8|bt>28JD2`t0zZ$5ewvqFJWlnJkr<&%1yl8VLPq zt0(DdUO5Yl3`MBs3FG{eXloQQvu%Uss29s5yz3jYIZ;zt{9N5lS=8AUBMy8%rjH$0 zD-iP;3-2y(#n2hnvkZx9eZx7+{hLmf5>gxp3rv=f00La}EtUUt{{PKKIIo@aic=PJ zCy;npR8+q)VIuq$1DYu@Tg2?iG6(Cpu;de)Bn>WmQfDCF=N3EtV(Xmx0~6K|4;DAR zw;~r{I#xL$N;{KXSv-7ZdHKIt0V(@2BbrM&ip1$aND=_?-wG!0NRpaul9gx3DNFAEaJ*aCQC)GGPKt z#l9s#HGEhjvUrpvlr`1LV3T;ch0FG*->Pq<^w-x8v&saQa)j4yq?a@h)j%J4=ygf- z(~Gd3S*TX3uL1)kh&TNc>iyF?)cy7U2G;X8Wjyf+MlV$8Qx=#0nqkrn%C}BYSQeKy zz&Z*oe$}>+sSuhGo11m=DF8v6!%6xAvp#Ra%mole<5sM%j0BG4SPq~@ml0?jc>&~i zb|-9>L@8ROkAL{G)smNwyT#Y(N}EOg^!RNx&#ezpJrCG3!RE^CYmMDMa-^!M9W?Nh z(fi#gnyUEJ<5p~*6CHI(`gXF{KY1d8u6~<2HjUYrR`2ZQw1lYN@w&fE%uNddg^&w7 zUItlp4GsAzWk@oWVb*>0b$#`pio4RK9DH1^AsIl0FX!02bRoMvWf5_wRpb2q1nWCF zQQzv4n%c;?-P6QISxNo2F;&s}on-%d-cPCo zO14BtZ(j_a@=N4$_8a;Zp!5n>;^# zkq)~c_ZD+z5WMV65B-h^R%zH^GFcK0i?nEP*Z@b+uTZ#hRO;fueS8JsU<`tQ&0E*G zLTp=4(187Pw%|r^0m>)qQYDh$pUhA(3D=y-%Y-cCT`I_eXcRJH9>5-d%H?XTDACA< zx|1YAX^(yS-$2voMA>O3CMPBZP@*zDFDv(iL3cvJZ&fsl1{;?Sk}tbbzdTd+RoHHw z-`nYQi2Rl<0XVJ%!-k0e(051GO^jSF*rqm)2jX&;3#rEA>DPP39_OvCtgNbpVGnlG z1OoXbEKSCbnn*hlus)*2&aGcYGX=w59|8|ANFcHiq6jm7ifPGWo5108qCRBIKLfb^k;z@6?)GEVp;;Fm z?{4lv9tgvr-<^z0!z^bl=ulE8HGC`q|-^>EQmL-mxGa1+&M- z?ryTMf=1in3Y|SWLVyF?{r1m@Rr8F;3^6C4OVpe}G~Ehy#Ft+fUt$<#hieBp%vojR zrn>7^bn&uNr3qr_{Z&H*i%5ki``^KC0jj{QGf-rNn+*SW9ZD>U7Yz+91~+``SYkCQ z?+A6phGRLPe$SO)g+bEN%IqqSR>W|_R`)$8LtIlf;U0;66QJKSNrpWTqT`DX;hoY` zUSnSW2o=qdEFy6$I^TkSWOn-P82I?2BP=$barsT0X~9?&JuLK#(Q^pPSPy*GLur*n z2ykZ1<86vS6o#FQH8qj}H#?QBcV+JD1Q}M5^@^-d2lcLY~?|zk%3eC8 zrEnv3u21THCG4}>GU-TT=|*DmJeZGIJ~<5Irr{XP(vvypo3a7-|aaRoc%W z->_>ticMdAQdunnzc5n&^8Eb#dR384V72Jt7Y#Ss(~e(fhokgoeu{U=+fRb95(m=~ z8sz9SgQJN{v^#tQ*OE?ItwP^%qC(5X|w^f zQ>+ia@EnGO;pYquJa;0 zSHn#m*YoJ*aGj6;6uW6Im!nLf^>ZaBeva8ahRrNek%~Ppvqpy-^%r0CT)I1ZX$Nil z!-}m)n*s3c{#9w%*?*VYA4Z(y6~yuz|Ibw@pT`;EC59LL3mS6JBj=Wp)jnrUf3W47*-xIxdh~vUuH*+mA`T zkMi-mjwEv5?@DFV>qK(mU3)K4C-zY$y_tt!|4REZj5U&2;}}$Cj{!tYzs(dViiwGt z!UgHXm}W-svhQZu*Y=8r2JCQc+`QK+T4_YD6zH7A( ziSACX{i4Y46(OV$JMA2G*YaFD{7qJS{M+Sk#fO|LDiOqb+yyKyClaHZJfnF0$#q8= z%j=1$9!0E-@jfm2Z4?(8Pt?5Fv^{cDYh zUgynAC>Z2EQ?8%2n2rg>6u6d?5GH_+mhV^NS5+-}&64^KbtS}_P)#v7%G5GYv|{D5 zK-uHY)%#7l4G!(+tF6Jhdd)VtAFksm%+r1su8!Sr55{3#K93Mb%1~C|^LY2mLaqO8 z=B7Ll8Ea(Ox|KO9hm(G)!L=F>C%Y8=c7zkHFl?oV^24E3ugr*!MnOlGD5w{)(e)M* zG^E~K&;h*sGs;=n-^QuS()`de*@?>#1G%AW5EV&=cJpoK>|54VH==(;BjmgEHWjw` z33sfxNXIPw6W2@p`)(V1{uGbAsPFCd%=a{3{6#IR zrBkfCVO3BOxd;hKWM{0{-V-BuJj&ce=is4Q&!tVjT9eOnZ)xb>c6>k4Iy@6Ub{F`C z*9FHzTj1Le^X{h@3s-ONlJ+{xvx67fb(!2#Cu!rCv$}W&=>?N=7wt2-SZcvVWFlk~ zJ616@c~aHohKBZKdrOxcbgKbT18b*S=W>eQ3@nxSM6qcg;u&dPzA)d>Q1j5AO3PA< zc6?4=)Z@rj#&9tq)9%V)qw$%PNfAI0Wq$yCGf9+eAbIlW_av~inRIr!LD1@?CX3Nk zMGeLI$MSDy({lBfL*VxZ>B&(V&D7u$phF*t!YD4 z2X?i_Ukb<8p%)L9pemnfapn4{;WiWZb7x*XzGy#wxn0kG_uFFVVyxzfr{ZTD-V3|_ z>gGDJwFncAc@So~3i0(rMIwm@ztxWm{r>7Ewm@~7t;=G{iKDErA(w&g>xgJV94A5E zVPV#3Aa3eFWyv=imQ(aAVpXANDvT!;WVf?_;hZ`+D}2gpGw4pw02n08?^G`A@vR7g0V-8iBc+Ig=}ZZS~_Q@ISi?2bUOT9fd#3 zHg9Je{{V;fhj!4P3GBjB9?#CIu720OLKtz8gXQrqGkB7-KX`%2MD!eNnwZH7FMviu zXGtPNs$*Whz{OBYi#`eG8 zjZaQY^yCV?fa8Fqz*px1c)*6wWtXX`>2^Xo)JiqH=tf1_Rb%(+ z3*9__=@edcHgdu7{tYl{ynawH`$~81PEvv~xJQ)`LpX?s#RYqPw)XmlaREG0YiDX7 z1vXcjMk*q%{o-p`Ss~_COc=RfkWOAE?cyeqRN_z;A{oLpcSmB5g}=ZT^U^`QZl$%x zU0?6GWWqx!(`;2((3z5jXh*f;dgm&4AMU z{$zoQ%B>#zD3s6bXy$LV-m}M12FgPqI`H-Q*c#xn(*#4RTz0CuVES!WQN*6y4lwGh z0)u0M>5Pb;J|ddtVHL?9vRZr906=Y=Gj8E7lG7Pg2NlUNRvq=V#GLW()CcL9ysy`9 zDE8b;I8Jd`l&~C$*Vw`Zv(}{mxpl#*ck!MxazPG ziJCTOsADl&Vvb~m6Qi05W~1T=c=i08%HTz%^Vc&l$-d=^!w}k_R3aM$0u3RH|Cv+3 zhr)LkrOy#ric6F}BuUk!E`Z@{M_)nUNizy7YzuwA7GgID`-YyJB#(7>@H{DKqkQvg66G)(`L3P>lwcl@nc%o_ArcFC zD4&~|nb8hpPTO1qU$#iE~TD*Pgd(1*59bWlSnL!{(GWXM>o~%Ub__Ev*EWg-xJNieTDz;3a z9N)v5>vX7=1o>6u;Ld`UQOx(gJgNt$GW{Bge^(85#gxUsf;j@%rn3KeZ~}3$&tZa) z37g+|X~T3geW{JVtDzNF?NJiwisHeWNg$Hn9T5hmW9kFU%rNHNs^_l;XX zlu3+&W04^FemOnbzyDm0g1~oDOK^A#?$=>dNN(9yXaRZBMdGp&|0RQpIvZ?0vSQf> zouI#2vs#Pw=x}imjYmrYBS!FG#IYn6T@Xa6uz8!eS$-1vI%Iz6(40IijYG-~QeL+s zNJSa+ujlEBXAIg-7YdCx6@$26-3{2pwbTsOo&B{_QkWnEPI&4(W}#S8w$AUrJpx<1 zbp~ZjnXsRUH_loWQVGUL;z72_1;N4$Cb`i_?P{H~%R0Q(If;GlrOCoE|+e}*x z^y`i&R}9pcBS9m72(36)Cd9QRgHd~Y`4jT{Z3@Nu_iT|sKaao=8z0eN!{zTp-xnPV zIMOtmj?Mhsm=TD|lO#99J%G7ZX2{MAgB!33Tti+hzLcZ{Xw=TbvEYEqYLepKD!2$h z2FtbXoQL41jcoNvi^Dqdw8MqqV-F05zUw3>J<|k#Go~3wp0b0(aRNSbtVC(!l)M`H4233Im24sCzo4Pj^>*%P)ar1nVz($w6z~FCOEit>^wf6_VsvjSa)dlzgoY1-P!1< zOlE{^2<$DSZx27>ts#tx$I3y{qk-1X!$^9h(+yv++4nMm3Tf0-EcRYKTyrsIBh7@4 zYwcA!#^Qzg^KdEq0E1yM{l({fuU!^{9Y2mFN#S&y^(mBT+vb()ilb5APVC4G9rj;V zec5x{d0+7LEFRUftQ~Y+4$nqre`pcxK7`%S32M8oV z3#~=ln-c~QxnSH~c&xgFU2BiT%m&2PJK5i$k}#%MX%;3-ry85)D_2ZO$*plJ&i)fqoS zvN9Zo6OI>Ibzuc$DM;#X3Z0+P@rh!uig9}jU9#&ezbZq|S}p8)ffBi8etP*lY9RCm#;_@0k_#-aTNbg^BFKkTGAaPAgejR?K~hS|&+-{?DFtFJ`4GKqT)LV*HtF z0RUM~DP*Xhd77`=7+78H?IZ=+TOWb}kiSHdr6OQHc8<1pJrWsRCo#9^BGgid6d0$b zM)vJqzR~6W1e#r`Hzk{$dHge4ae7wPR~%%Y#|w!r=*$-D(-%&`wdzrj}Dia2|RINoYlVTRn^Tp5Ze>pxE&pil&SCG!+ z{CUx+``@9^rFS_2=(@7|oj7mj{lZa@$Ngllg44Ff_l4c~U*It5+lu|i%^Z;I<0@sb z^Fa&vmZIc;M}_F#@z2KUDRapoj$who|uTu->x54)%-* zHr}(mqmarC_XWOF$8g}jYTYh5%D@$yd;lW&_6NYh1=uZh_}1qnDBxj!&ZV0ngdxy# z@i$nlxgH%WZLuQ2sFm@wJ#abioY}cTWTr=j=q|fUiHd8b&XTAJ9UEU=OTyB)Th|Gm zNEt6-j$Fqk7&}j3D+IANhSXa6%aA#$PGMHd)Q^~@=HBjPUrchVHqFL_aa>~`FEbN| z0~}dnJG-+8x*X55`r)VCwbGhpyMp;TSyQMO%|?gSA2qOPCzxptra=D@(O(W#H#DUb z>>KVwO32r?R4sY+JEU;SOWLBr#M!3q^s>QzI!iH2d<-f?M>F|!tlf7EHWEJ{Fa8Zn zN(E83L}(>XB(!8UqOv=j+sosCrCBas4C<7BSaKNPw_{U0YomuDFp4RyR0Q#5P{B## z34A9CLbWfAkIIY_(*ah>hR;d!MEg)k=i~)0d#XcoNZvXVVN3j^MtH=j93SuOH7+ZN zZLNDg%v&bepdi3Q%+2qHTiMxs|JxcwPiBKi7Nin83JB>H++I&aoloG*G#N_KaBW#-PdbD6#HR>W~z{^3qLJY>2MZ!}?LO8p_noZ9Cq{aXq}U9iYW%+ zgFKZZWf+=)fi6)K*U0SL2u6V9&AwEIATLZpR%qjF5Adz=;lVbzWu5u!MYgbCF$HRI z0f30b`P{c=q0Ci9i$1v$rSaT@DP^?~wKtcYojv#M%u>ZB&7(%06tI&!YsE#Z$r8su z8NA;rtMNfUm57WkWC?DyP$q_oIYJl6#(_gq37=y-PSi3X(wkmh(*WD^S-R42_=Hv% zVXu}@08JFT`dl^n)f;9~zHwx*3o9qvbL7Oy2NnN%vr}uSD`yki8V3_VI7gp8JzFJ2}rIQcc2qnRjphrjP~)uDq~p7;SL2b$1RSJ|AdRB`YGSumhy z*B!UgkOz6{OVL>~sz}_v`=TL=6x!usAFn3#YqX`n&&PEk0slMt*Xyc7gAO*K4-B$5 zMBr;rn5DpDs`2i2uo9$b@Tu{CxQz!5HG~1AFE3qm7O8l}&O{5MYU50Z^Zog;Oal}9 zy%GmRDXO;Cr6jl!XZ}`*04Hd?mk>By#sfgke`ll%k4XJq$=&9^R<3A^Qhp}_Z!aNw zpL`j%ZtZkvy?KH?;g%ex4S>Jo3k?e21?sktteq4j!NdIyyIrYEc_^wIR59a_94m&j z@wY?wLj{+uSKqDt2<=J4Y$Hc>+Xw&M3dS@KJ~c?n#cqRjIy}%!47jJg|27I;KLRn( z9)-!_0{jWAhQ$ssOx9Vs*PQzO9yh1O>aH<9uHwj`>Iff$pl9rZ36~8|0-`730g}~>^}TLGu8#Jd1!8q{)=(`+p31tu5W}$=Q&zgg z>T&#=#|=OH57$e-$G1~02R@f4%-1uYt3Z{H!0X%Gw0e!-DwV0}4?f33 zmlA6MuP3Bshf+la5foxxZU4JMvLNaJ5Z_o(?wUJ3nKH!k`r;E<7Vgi+uNg-eA$?_} zMre(p1?WXneW5G<;CJpRAiH#5GOF8HuYW z|I*_fU;=p|KlSehOgAuNkLOB{r&e1O6|&DV4ojF<<3W;mby|?pyRfZ}EeaIm&#Cxi zlIGhSH^YcPJ!96XKx~j26jy#$B^kIsr}0cKKmUyy$vumT&EhZdHMF>ihC$;5*msavc4Jvy~Mh6ziFNOWNwtq+Y2~ZpET^>kK(oFP>ZSJw8v#DX-ox z(DneZgSJSWX6z{91=X*8F@YUNjf#0xnzCD?!wLQ=QCe2k$QH7vg>!OjqSwpuDUOVv zUyv(B5-f1fz^7|}(yIv4ATHa)4FyT}D}|=ZMC#F};2)F>)BYuLgG1$S@pgIHQ~CKB z9{y85$FNpy|9cPg4sUX3TS7gOTREZg#&;i7WiX;A^|?_VdlPAb&1UxP(`Kvse2*l8phX_Jg#fE9KOd@r zAk|PSZ?W}|+5OCD?7y#}6~vp7p1$mNd9f!r`l@C@8W1rwYCOHf(X#Q0M8^XtWS9ck zvf%=MzExTO!p+1Y|ICyu%a+fA)U1D)U7W|ICSQEZ&aXJVk}>K&94AO<=R4KB80i16 zRLQ>+d}a7vZPX0~R(qwMogw(NwV++7B88@2{k2LL?UKQ%OH)K35VMytb>N>67BY3> zd}>x$xK#qK1z=#YxG1U+&d&iD($VE*%2sdWJrj5cl8yUD9XQ)h5UTa(uzhNLdM+|; z5_|PGV4V^-oA~^lDyn{UYDZ46tiiiP1T+#~B~LVyimGKQD}nHjhlMi%bW6!3ckr?< z#q_|DPdYigjL+3#@{2b)8h&rDfxxIG$KoV$cI4@G0%zoh|3KxUy>1#X{RDzU=BtyE z7zL-#ahF1+r%DYSSJP^@z(txXu8pk-*LOH#_8~1gx{p-GglNjRs(w!nr9Rj-5c^i7 z?sku7&Fj$neW`(x$GmLCO%I)6WmcKNat{lAx4C51?w85NNG1=SO_Q{kDjvqZLZR`n z7>5`V8Y$&~cH%X;0QxQvB-rko&*A!_KKAwuOLw%ejiS5eeOmcM%_31KWD8tW;9kEw zcLWkgdX8sqqT2geUEf9kMtv0(vx5Y`)I2I%A%8JxxEhGqz1lvpt!ay-kSDGeiH`TU zJ(zT&!i(*~IRGNSj4-+%)SDi{@B{;5(lPlk_mt|#lVloBa1Mc=E1(%+1^+AFoJQ!? z>$jWDg3<$R1mBHU(1Doo$}F#-4Y1RF-!bUi>7?KFL>NivRA*XI5m9|>px*R~dF{Tb zG>qH-gKzVBxci?_U;&K2$HH9RG8!KhS_~A7_etcSYQ46&Kp>(dLxabsk1*=TM|lgl z^7fGMQzh^IGN38q|3}kV#zhrvZCs?gyF)-)80j9mMI@x8L8Uu~96BWgK^RiHq`OmK z0O`)5QyO`X_rCYrd|>8x&e?~()_T@|J-h#{2utorBOY@*%sz<@D0B62qog~82=_augrXU7kOBH^g@!3v8={UO)vpr*n+>+kHIQMsyL3G zzEGu9t;HiL+(tRJ*$Rzf#LZ{Xn+&(|6*bU8e%b=!D4|W%tpF5}yJIYZs|WcSMQvHz zpsi*mjY>A0cOg*pSaUj8GIaL(OKM7am&N<5n|)=(<)%&S)Yoi@EZ$gc0i?>e(D1bw zf_28coE>8pVV;xx982{fSs8ob+{yw^`^I2uS3_OhU31msFdfi?qY6LCtw3yUUd1Yp zfo-F}Yn_6S2POj)n97v9IU{5s%Q0b36t}Me4}%*tq?V;atr5d)`J7Qn9t_h7O?l1x za^wvBjxn}Sk(qJ>^y9X14O86da_+5=WVNV2J*~O@B@pUnD_ghp%%_G(u4by(Fkmgm z&DaIVpjB80hW1%dnqQt%s3qSlXRFOK$!i=?Pq^fzOgpNmA8`JnBjj{^;`Q|gdD~ab z8KSthx41;7Z~XOk`D0o!Y9Z4&u@AZ%>EoNw+NN3Hl~3K&)SYW?vGmn+4nuk|k_%iLaQ>jr6Pz? z5SPjAy3i)VV?AmVxeX_>ifhVqOiA)`G|;SuOHGaIMiBm2hfH=@v1@HYRg>0DWBiv| zUQA%BgeiJbNM+(znlOx-^-|OOkGi*AXFxp|#7hDhLbAWRZaeYse)&#@oY=gCxs{*g z5TBowfq)oI29o^w&?*7)Rr$kM;h6X{9n}Pyy93G7AbjXDiT3m1yTWV%%k#R*fY(;C ze_m>3Dhd+-cc{loBmZHET#{YsPl(uwPPWw=ei1L9Af{#lcD5vmdygSb`+d1%rlkA% ztivrZO!oJ(_1GsjgqDyp9Dho#HGL1Ex+pnPF*gBvFI zeEgO?I>TU+z|~1G4;(B!!NetT2EFVm9mt6U{DSx98roZy`}7i)Kq1n9fv^+^3ASQdI%`huG64|9GuEM zhYH{~y1LN9Bxqy-d65>pT73I8K4|na2*=z0gO!py5+7CJR>INW$%Nl%8%0DHP_Ziz z#^WNWd~(ps|L@PKeXnS8Rpw7KjwY|0U?6_$?ejvbGtuzX)A=zOwxyfi1zaHhM7@MG zTi3pl62pbl{BWJ>GZgrkwMdY-&&87ez$k~tg@xRn; z0`g!mxPZ%T_u$~%UNLdHw*6zYf4}K*=SnpAI6UT6wna}--i@lVIi%8R>v69DU((yr zz9oWvZwrZaruBNCr6#?!bqqUz2sf<$1sZL&e=DQ*kL@H~Gnav}qTa%_LOr)MW0%B( zX8dDcVf`azu*Dm`n9_>I&zpDd)xY@V(aYD->6RcHa`h)S^Ei%vv}aPp_@{bpx-TlQ zUGU_nhvPg-4NAEJ#~_2`s$E9{6kdBz?}PjAYEaqtOFfJwMYWGh5Lc3yr*-3PXj!y3 z7zdXk=LJ%V>jP{G>*OgRjWIry0d~7CjnRg4XYr{dR{9qmHmKt zYCncjXP+JJifW7anqmW%y8GQ3{CuO04w4x~#=If-Vwkh`khH$ESpJn30cs*Hlq zlt_9PX`=GRSRvbLG~>+YLUE5-(ya1&Tw9;qALFzw02o3vmaY?B#HWG$X0#lQFKa-T zJ(;$_xRhriCG-Ln5vQ8hB~4JD;f}~bmifv_rrvYD>S8B9OB<_j0Sl);SWs-xDrbyE z$|HY+zP$7ia{WAZ`bQ$)Sw@!-3Vf>x?!oPV-a|P6i?QC&~-otUR zXpPaIC{f&KS)F>gk`-vsE#H@mN?{v&V!?>XBn<9YVgUJxOMKeD2nA3N+YZ|lg#>mFLB6;H~9vcBpQgcy-kQ$c>x+#Tg zL%SEJ*qiePG|#P;-D$0{`rK&I)2#fAmFOUXYKzo|oh6N5kPi+$6B{NXcz4BLk*gv4 znB-@vy;*49PjF9Pi^@F~R{NN@mgcs6xEDlBU^|}tB91qtWY_+)0}M6oF6?^Hh+Ddg zOaJ$>s-Gjp%DtUl?8_EX_-N`v0~{Er(tDt*T0s`;$JYD-sXor-;@1E!N%|*p2;Z*N zt-6pDMGbv-q>jIyTZq#mtI{!(gxrNQX)I%N!1Y?OzrsXkz&D@~A?CKl{y=i>jZo(I z<)crVI5qBgVLc=9yPv@p!+&UM3gbX@!^dIA@7XhA8?}}%qtxUAfgRXOJI) zu;M=uB4JV&Pw$l3&~h8S910`3^5{T%N;!+1xaoN>P>~4G$Dc=pYC*m#CFs~1;LTkR zT0GLaD{Fs^x52H8e$U4d$nru}L_o^9x zy+>kQLdUxhfwmeYs97hOS+j3+ zATb#l1G_0y&u5gySCR!sMdV^Hr$#zTN*Wfa#IP83aH{hgD!xwa5ypM3RZi+@bS>*% zQfy9RY%Td6hp>`MCBz!h|Mnea>_?_)j|fF@XF|$5X2|pVTbT5Jk!9OZMLtYfCCOwI z&YH{F;;r+{yD7W{npitPup_gq4I z$LY{sKLGu3=6H>}M2stgyfm(!jHUQjIn*iblZgUyJ-vj-^9)}*l4UFMlS>|@$m^eM zLUIrq5(%W5N&#IH3MG>xZK?_PP0v*8zVYllvQAs8t|TyUwZ$C*29XMkIT-Dst{y({z?nJ!+@7U`m@z5P)G=O#zBDSNPEeyuCLmE zQ6yT&ty*tknkN047wdgcNrF`bcyu&l9Bn9}#FI*`_c9%g4h`4h6{sd$rw$JJWKh)v z|9sqhnFNY*`0SRyVoSmA=(*3Ne*Yb1wmu0O6tTYerk@{ForV>Sm;NC=z3wX-wUjar zCKxrA;aw7RNL%@#rOyhU5Hvcm+I97ThJ`a)E_$OuaN4fn9<%9QT!w=xH(_=|Pmg4b z2y0k7v}OVk>I5aQis%EOXuX7p@)Y2RYx7~@RdZ*aVhu2R=Y1etj2Yn@>CE%av;C6E zPKv)>ezS?OwZxv>r`-o#l`U~u8T7U46VM4|2M_Xf@nK+E3*(^v?}4oyE?Vq!CZRA# znrpYU^_`Qa1}O1m4EVD8x~eJNpuXCb&h;4w#b(;`D!|pVzC(hJ+cD7JfFZ9KSw7O@ z{U{U2=;x!%MS^#FUG(F=B&F?OElx_@vf~N?D?C=PgFaAYq3U=IVoV!tya;C0GEET1P4m4qx2dG=Hg;M9-C*v?WUlwuw;l;Jbm){JS z@4iX{_{J0Ry@yeizcPI<6(?@Zi1H5v2o1eG2BMNdpI>d8ujfXE{QvYcRdL`wynrC> zGljg*ijyBWM*0Rh^(4atZtOEOc6RnAANJ~lt$a~+FpPBBCGfv+7*!8)_9p@ZF}&!j zNZB@i8yuifp7D-Y*VJ%MuDvZhp|D!q&eH0Ku3JbBe072!1_O@>BrCvwQ$b>t974UV zqxi$h9R_>Ea2kBs4WTMjKWwOMBXf5D|DS*ld8t=ns~jWS?~rIq>Zg4BmJCNG1@m4x zGw-C?_uEFsHL@*A4xGHsX}mDqi7T6#CM4>zjLkFyxB*#Iy`UE(5LB$|;2k*VG8PdP zt0gsK`cy2Il5{zr=pnR@ZdYk&W~zhz<}fYs8CQER%3-??EY+O~etmsEK?HyF-%e`r z8y$nTDpr4T!F9M5$0puQ4LV5jU?b5d~RM1IE!8yX*<5HJZ-h=)D$KZ zLU9yv7z1H>Y;oWkb+n|%EAq39*0j#=z`RP(1n6z7`s{8PGa(JQ%&%jq^14O`(sCBn z{x`b;FnxRYiLKR^l@u>d_%W02l2m^UJmR1loDr~;;ClBFV$jRGsA zkEPuuKnfgo+EE1)^O^jM)~$1brmqkc;($VgF>K3#id%5du)!r3U~ne)gLqg=H$g=% zj~lZqyUD1cG#5BugPkloz*;(x3$&ar`uxR?!txaDj;dsjQAbwj!L{EPui{+sg}9bZ zS>+37Yqv4&*G$D2yrp|LR`RxdBQ9eJEWq9dF(8e+y-`Dcb>Vy)^6|s}1J~Qnv1duU zHYB#a+4=iRER#qvoV>J+K0~JAadOEDCgvR^#zhpF68TEgZ%cZc`QbRVuDudpP85)% zYkJNP6y=exmB6W3suboV?KQcJiOG!pcBK-rz$F_x!HB`i$eea8dC=hRb8ieG?t@)_ zWuY~OGHl6Q*dt&i=OZ7z%0RR$JZ{Q&$zddnQbID$`hQ;Vvw*z9<9>4W2`L2}aqM$o zMDCkp{BZSF8YZH zC?h4Ds&?P=I8i9d7$}HuiNr)h?7SF%%KeZ0XGp?V-Fm%ORdze5h>DqwSn@NPljhSm z=(bLcY{MU_iOKOE6MNR?kKsD~M{rGgrdktC1@so7FLYu7A*B^ES5T^oF-z0x_%+~L z+esIJ?t>4SAo?1=IbDpVL*2Cl?C?GwSMBK6v9Za3pN8+O|NCyYdE$rVLlN!_Mn6fKRn~5jYZ>oOB zFtDEUqv_LD238YFX4Wl0XpXnpwDN19kFi>fM*M%IS!a@z(=bc*Q4$-8LJ1pr>NR=q z%2$tG$T!W9zt$lF67$f=q60rSsQu*3#g`(Rox2%D@*k^z!x9APH5Dzs;=nsc2i|;? zzph=rHm&ksEH0i}@G}Y@n@BhuBGh$zwWzS<{1|7-yq|D#m-VXmbMF_;Ql!a**%@ir ze~3wF|0L3Y*g>#81#_}FMf5>4Al6hi9wtEoUjCy8&3$~Xw)XZwQO7UEcqv|{6&7j$ z#Re%#7%*buvR-u)q*SciQ9HOyEGP8C6p*H&nY(5oDxyvOI5TC8+Ct^n%K+t%$$O{l3 z|0sAh+5f{BGu5dlIYbu~fGHMWK!cmn&HdAVrn$J*F%rr!?A*Pr-ZSAoq1B$^X|XjYz*a=RL-Shue#E(l^kcmizJtH z2JdWE>+lP?QbDZxrGmG$#RWj)S-*)LSuo(He&r*BqoUmp1M|)1EMXtj3lJrB*+=b; zo6tYCwY6`8{jZu7Mu{=2x8Yh+{6;LXfA5WK3SK>%J&~N0HpVSX+1Z3Lwu@UujTLxU z=ATH;c7r{(8QtxrCl0%In^!?T^^0T`XnQ4;c!6kSU1_6YB>6RqwuOj5tS&yj|ndFzx_G3x4Ja87RH`B%){|Q)AJm>5j!n>-lpq_Mb*ZuPNspD$9~MR9HPWYznlM z(5TlardI^Jg;G~=cKZ$4P>=12zPC-#hjL^5rp-Yr-e4R^FMmsQ@f>O z?a%%&E;Ng3D6Gh{K(PmKxr>SLG&lysmSHM=$Iyv;QV-2wO}8to#Pp zkzpI1mY^!p{KBAj#Z~N~EVI%!5N2J{(5bWnCjtCPEO5A~L&cwt5iOkmZ zo70x~iCcAM8*yUvQMzG6IKNOGc0RXgG85(M?w|?Lr|Fyp!op2I0yhpRlcrE;C^Xp^ z8p!_Gt;4jq&al-GOY!`1Fgpz+a#5R=jR=b{o6eDN0>;@p68?9*_Z#6)p6wH9fj{t| z+>v>Y+IclT9jai?@-{2R#Y;4#VQor-;r%QqoH*7bcI-EZzhGY$yirU$rbRd`x1s`| zaXAO#qK#GdwT>X1Lw|@_Z+K>It~up~gYKcV0@b>Xu&P0F>jZLElf}12Y%rH*K~9iw zE+dz!^^v{VenSP1>Q@!n5M@>Y0bF;bBt}t}%f`({00+7mvWQifl45Ue{;l7|wcs$u zZ*GxdFvu=iVNYod5?bsfMqL^s%-|UA5sZy|exxzFcvk&0VF==dl)}~UOe`$PY#L_9 zX8Sc0EmW-s6id-_#>BIWp&n+j1>@4LzeV-}VBr4^0tnxw|5euEO(N88d!Nh}#ola* z0s9Gyo5aEDVJRb&ca++MT<0J{??14-sU9Yv%Jr`WQ1j3`^*pg2ThOmz_OfiG>u4w* z_c%c+#56Bz;=Jfh>F>(s4eh#I->pvKQnvmc)OoVjU7{aO?(8<{B6o!hl(OP1+JD$> zsHXjlSZ;jt%`!yZ%7%oUYO{;x|92%bU!1xb`@MZqHPERTmT?QlYo1s!P&D4TTnM2; zR-lrfbr91q6#HnKSv=Ql^;S>bbG}b376I|8(yw5A$GG$&v<3=QvcULn1_HM5Mp9MK zW2H;UdYrt1FPD;L^(Q1~!0S$m;;2+-u%;*USw4^KmmvBF6n?Hy02|Ij4XAy`yW=Xm z{;;vcAbXrt0bj!H`ugd%r|#A+nXoco`5?Mr(nj*EI_%baUXt9@08Us@#~$!Eq*{fyh3a4P&vh-okVmC}>um5S!8T?!_=TFVG+KJZX0{H*eKw?1%qPE6^@x zz>O6kuF)ehlefu$_|(tx@!@RyoxK+NI|g|=UrKEA^gnA`y+uHvtF8lAj{_YKck<(n zl7^CL#&}V9lAo6Y==RYWdWQZ`J3P$@1#{=bN!|r@=(6{3LmdH@AV+rAaVhj4Krfr~ z>3GB(Y+yHURcg_rSvc7$;+{Ar8r&_{YKa5*1nZ4WE^m$`m}82PhfuQfr=Y#B9&u-PSL@|eu*U|gzJJy1AOK?1*YAEu@8(9-%J)y z+*!CFchO_a`ew=HhXnb=;J3?>Nph<01!*F3y9xx&Y-y}`DS)80WyIV3d0g`)Hz!d}PhQcuW6>dRo6N;} zEXp@*HoeYsMX;x0HHGY*+uL^^*=-CIdb+5G*=;Su;)JDJWmYP zp)n)me%@Q{7;wbN5GAeNmCew6C2`v6yYe@+_-&CxKp!XLmk*kQNax;%>yO=j4t{5< z445n^Lpoffw+c5}245lJu>SdKJ-az&(r}r2J&DbX#r7MKxg+@Fy^KRwe_H#w z?#*M@(;1zX+j!HJsFqt&p45!+us9*L7}jfI zNf0p4jyppVGnbvz>9>@U9xt#sFE@%iIuOZ_((^E2A>tx-9tZ)KnGUMTTeffY<`Iqv z@X^P!2C*I7+#mqrVbg7;F{vu8x;ORxdU4iI!f*wSy3Q-V-;tY9+AoJ)dSR*E&kd8! zzTJ+L+6^Ao8yefOb5-Txv`zX`*)ze`hwTQ{va@hBmLzeBCK%Ff2mLEx=0f)RY1;5@ zSCQU!&MswTO-NqpLBnWubCy%0N9(5$FM1-mjrJ(wg$rYO}5B=u` zm#|XPy8(}Ow`=g@<2Dgla$Y8DB%+BKt7_^eC}u zKV6@+qsuY4i3}(GG~`A+3&nQ|oS?@Tz|NNXQ{55f$MCLBJBT|0e+$jqg%SPUupX6( z;GY}BAR(kdMHVTO$IL~DslKKU7L+W(yzuRX1w^K3#$YE`!C3NiqGz3aOJ7SRlr-*` zQklJMwBmPkpYO|(YE@i|Tje*}UCT-;cKNNLL=X!~TxI7ZkeOid+u~Ai04)loxpH?k zJn=G0BiWsUDoSquNXcuDBYOY+yS)+Z@aKvV0h5FJzKx67!p7Z}`aW8XhVRWv5aCKV zs*ty4l(<}&%EubA`84j4gr3Oc2EOPpxz5uei~38JxTM|3Ns8#v0fS0PGRiFKIZi@G zXAb7X;Z8;>c76=hd)*z?ur9m~z+`+F+;KBg61%$?rp={8k*?onwR;!|7R$aE1{nn9 z8+15t(m(DQhHx9}p;Kn-TP?021)tl!h8R}=u!_cqkhXpp!E_i%K-M$D3fyUZG+gz9 z|Ke@C-LBjUVUcl2QCV3Jp+lB0Q8FplZ5qqWGy?n^4a6v?rOV$3Wsc|UK>*3WC-gcr zPGZIH$st54AN(HkKAwqdc$h$(^CjW~85283jZ3u3%Azt4B8}_wgd$Z}CkyfvvzT%h|tC!++VIZIt z8KgeTIbtMA_0vsUoT{6kNCr5d>r3#xT!_i3_2=nY^z_`2Pm8-#^i&B^mc_UV&nQl1 z0)xMp|H~#}gkmQBy`63(pA@JdQ8k~vZY@hFSxIHX6+T-jmi<)JgC~f^+~c%NqiHB3 zSJ$XH8))ab$_cPw+Syd`V#6AIvK4gtQItv%e07AT??8$!4lDdz0y}&TWgJWx+qtmd zNEMMhyev=FprbsI&)*VtN~4eU$GEr3=C;kg?d&HBOnO8&{kRqWBQ2y0NzrPe<;8wQ zeHO{Yfs9KW9_~uUrBfg4v*<1yD~=bRR=9%j7oLY}weXv4-i|-N0R~B#6eK2qE8+eia5>WFMkTix0D|tl zeftXaE2i(sJ!msWxbO8g&CMpmcI6K@-3veW#!lh)MPWUE;cgWCuq(Y_LTv%Rwo zOh|C?kw>>bP^X@ect8YEFow-0B)&q~eV*~$URLiQ^y8~DV6ZI<0*zeg2e@!ve5zJK zrByqnT%dGZ?40m8WX8>e%P)w%bdzN8N43E6VS_4%#625S0kD9Xi5%NOM~-ft{!_aM zS+qZY6rh|1U5R#9B-YG$Qc!l3KFT4jA%)$TTzDqjNm>^c>1RpAWvR5gHouYfayo5^ zKg=o!r}h^PC<;QhAdY4}p7-h>^NnlE6_%4nad@gKW@=Km7d*eIiIJDGXHhD2Qsr7u zaeLa8+VvoW82MP2;YVOm4G8cN1^Fn!Ca)32o3#tyJ^l#X&hzcq(Y1p> z+uCG*AC`q4UeN~>Qz(`Is>{st?{8HPuzTIJtn$50Urtzkca+I6CRP&JPvUIG9v7RX zd+_=CGu?KAHKR!m-&dU(bKyNL8SbASs-HxDLsR_Oa|)}w?Q(cP0L)ciJBP}-{(BC} zzaR*O%#bD4xy1{4QIbqlrKR7meAuIzhm6l{iA*Wd+s|y$as3HPp9;T@typ%kTpe%T zaa|vaF4V}vB4b8Mce^|_L$n~9)t>~RSG276uljC6(nY<46`N99wqI9mIIuDt#jwgiXDwfVk>t;(UC-0Cr&fI#17{uvf#1!*ZdY5jCV1-DMhM<8ho_=bR5AaXe zP@2bLfU~GB)Zk2*$uKQ;FFJqLgeK!{0+s6a=T>n%1B-&(5ph895}+*790$x|1R$=i zDIc$$y{V#60#x*Co~ldY#x?KSBFn0|fVK6~A9A=Q32e&RQD#p&p^GqOrkmNMxe z7;w|n;RU#+cWh*t-Y*KZ=hX9sq&}ZG_%piuFuD75c0wA3NFQ&x%CM1QvkR|MduD#V zqt{A=vT~jesA$z*`5oJ6b9dzTqmYiJu0n+mjv7r;k>U?*ScTuH|B|>ubX(b6ootd? zWp6(eaHvc*6e^8c$9iRNE)u$He%xW>UAj$nNyobz1np1ixp~2~z1O-P*;>@o0sJ1d zr*S`OM6lwTRTsFyiMg}FJsgO@5kV>DT=jIy z!hvMP{dWm6wu#Bl<~$dOA!^S?MS+)C6vX9JuTOWxOKJek=+6P0XjX9b}+|gQa(!ZPAB{(heC3wk|D7p}bL$>#Nbwo!u4ZzAYEclYj#n2oi z|E_61;l>@2o;>U?H?%>nZZ^@6A7}P|iOtw|JnW~n?|p*Y7u`bwu8e=?6Zm+52bLA3 zPG=EnfhI!#T1gn>jO&@s-2pLM0^y+x^TE3X4Vgc47|3KJo5(^bH->axG{7t#LxPX! z;-#B!%Q27nw_e4lG_TwtEL#%WGvYmE=V|-LwW<7t=;@ho5AWX==(yd}iFAt34?2Bh zE>*ohhXs+@^+CSd265W55349L2Pm@8CI;drGOP=UfLVx?o@n~PAQr1)y9k!I#rlX6 z#EfP|);B|p-5J}&La<)Ps9~ab9&At~M5}zS-bnjrY-VH_EJ>YQGSW)FNN^)Rd9zrH z-uCBGDj4gWfU!U6YdpTuG-Js@yT9#I+qmx@z0u{89z>8j#i-rS@<{@6-%nj~p*o}Z zPv)(zS#ML`il=^p^?XN++A%QRh~p}RPqA!Ku5)vDiKd2%u(ou&&qdhCjHPw5!gcWQ z&4TLP=Gxa$Vb$ZA+(pVsoYBAc|DeKru4{5#K8?lbF3-S zal1ZQ-j!8`B4PT%kQm>RFmbVnSbkSAdUL)I=$O4sjSG}sSvpXLEx7bqLTRB4f)+s#H_{VjmU;7%G!Q#IzL}6_`JY%2 z#cyD+A*x2le{TErb6?q9mWHlwgc%db#D`fw5Q-v)F0Yw9xk*e^b3lt_`})j+EogTE zjUNo4wJD+l)?>F4vZCp!;4B}vjD?C+**kPqRu{B9i7$8 z)>>9*XrKG$JsDODRh5oIT_2ctu2x@pI3okeJYrcw%*YyYU-BSl?|7WVPzR)n}Q(zsWrXSP2rcM#*5BlVx9-!cyZR3ijj00WJ$B- z9P+yj3{iw{Sk(%9WjMH$gHgmuK~ASHx}W<*{20qSEe%h++=ytkPqK-S$4MMr{uTj7 z0yu=S)&eDm=M>77NHJTUpGQqFqNXqy-nyAMTuLyUL7msU0)$T?!>X2e4Gz^ULTyFF zU=SaQuXmCqbaZ3s%bhTgl%IV1j}*bklOq!~39%K)irp zV`uZsvq6TVhhWSc;T3m5u^Qy2%_wJSwXVkYH^H)#%G@3m$U2B@ zZb(ay+>Tk*05TGR_Q{2{5{VhLXA}^z?o^otz#_PaH$lJ9@#vuSpQ+@pld;DgMW%m_ z3%;{yLZ_Ns7&Lj4iIzC=A!~O-R4%DT82pxKe?0@=h60~)$BnmoQLs7_jaHRGqrmAA zkDmmJlYY>!lx8H4?92EH*Lkp(ukZP(>bw7Dy0 zGDtDPXf_u9<)|2gah-2kJ`@ydrIaTIj!_)mPLAS98y9&U-gYzKUzqqR1rJv=blXOr z@cmzqxfW-04udrY5B8AXkn;-vMUu|wA43Y+D4nPppZqS_;!maH`quT{|3DzBN3`R@ z`MZqI&pH!j3}}MpLedKA>)7Qz*CKmDAwLuoKiXP$F8nUl<`6~Z{c`dZsz9Hh0Jp=z z`!CX98(Q`GcWfZV$>|rtXn^AKj~B1kD$XbbMxO3aMv_c4fcR3TV=LdV^=Yxe?&-bS!LVKnVoAn}CrUa=S7kg7z`Lzye=K7@%pYK*Dt0Mv#0o{^Ke# zkIK)LPR12obK_TIo%FBae|U6iz<9dU0wWXj<4G6 zYoXQdIn-`whwzUY*rS|-gf@}wFcxj!6FQQOrmZVUNd|Vif=lm_WKrKw3A7WBKDqgS za%?jG4ocx?xq+1MLZM8(e3=8EQT~T;0L)8Bq=np1I!tthNOZ9?A}s0-e$(^L8@#ZX zq$<+{uAZt}FM>We&MUlK764968=s#z)=WC-SQd1hpW4|(E|B5H9?s0nOz{1yPu5VAM&|MqvYl>ZjL*~?Eo z600yt;1_9&A?q+6aG(M;up@|!3DT<5UA$NesLTB%cBE23^)Q6frL1axv~1g?j=s&! z^@?5*m3mj*jQ#Y5Vj@8;Aul|E5E~V5Q-ssSHXve)%ZNZMCNDU_Y`~8Om;S$Z3-ll4 zMhAKp3F-Y)ZFQNR-jyV($ugrk-m}OC-FopWroDJYd=g-w8bI@7P_ETsRH0|soQqq6Ba3}VbDdfSUT|utK#MfL{}7T^G3vC zggRAxm{?vOe8ZX6bD!+ z7;1fDqhL#1vs*E(tH*`22=17cmo`cJR!z;s1~BQH`^3hFazc#TD^a%%`g-eiZlybr zChna<>%h!Y!-WrYyDB=PBy>`P6_`kp!;&&g_ZwDVj95*F3Lm44aJL|g<3Krr!iz%h zeYn;qHm=7hiWtDo4Q&e0`w=Tl2?Lsml;E14ayF;&cU-ek!;?Cr#Jgs=t)t1srW^4BdNQdA0b z^8|(bv8EYpTgKcu^MbZUiQ%9Nge`Bys02}DhvJW-5iMs(om_{}hUIf8mYA13r1`uX zp#nx>QXQZiuIW=EC0dAJZnA1hgE56BgXEAZxlqB%N^guC8$?r41Raf5-@(f>C>-k+ z)-!+93DuoP*eqhc_zs@)MAn?)^EXC5H#EmXFIJ1eg(I1be|-0q%_50iL#F40V4yYr z>Zqg)V0j7o=Xr?%uHnM+y;1&x(Y1&!oOdhSZIYdRXcn0u4F0?EcFs@DlEUuQ)f>3? z_YS3vz%q=XUuC~cxKk3lKZuIq9y2Z5P%YzhO-*SD#H4IAVxI7c>4-6WVLhLf)+-KSopb1rJGfPE&SBmu8!8G1q9SV!s`J?K*#|#DI0#lH=D|;*@5^Q<-4WM4+H6AwSi(f$l_yUo zK=tJ*&uds1Px?PyMl1Z_l4qB|)#Q%^_7W{tDqC~EveH~2uBQS=H!&$ae+*|vWj;yB zq=b0d=EGVO8&DYk0cS>4O5d9U^7L)FY?2u)2jXL_lm?V{%9T7G)_ygLMh%vuACZp@>HAzQaE>mDE|@-FH9XiG)NLeAv}^b%yn zf#`z759o;EPl6vW1l}?em*UQkgjIweDgvPZS(8T8*@eT=ux14KNwxwZ=#Nz^J1SKQ ze)Y39P#MC!J~qK{Oir)`VevaSg;DZWou=ju-kFY4CWrHLG8yFUxd@1w^WY*E+g1vcuYP%XU!RDVuWclbg%XTI~6*WRg%QFGouD?-< z;c}a6H=l4cc=J&-SCucEofPn4VvEmeM08)QAx}=|%K*N%cwDoMoUcJB2=s6NNC*SW z%x!fhyhj{J!-X< zhgr$yJT-Vq6zV+UHBc@S{zEbTHTkp#r5^2CW-3irKfbmX^Snebz-@D5y#5@R zm~y2^UPQ)okB;|b|F6UM{|!DOZd3&YMMwXmgX2a2lf%)UG0Iir@f{F|VwLk_zxqGT zssVC9{ZE;i1TLO}Oi8L`sW~l-1(jPxR$gxhg!_57>_2p15#n>HWDq+(rHwMbAJval zH8k0f1fTMc1|pL2cqq4rdtZ)pcgW;%5|Fn9s;wnDQi1h3Xw=dQst8Xn*A=WVopqls zs6-%|cjdfsAqi$#$udCJQ_D!g(3Wcfjhj|ty5&9t2OC5z)oGFv`5!$0(q>tL1g98A z)(td^XvQ8}4fyq16LQ*xetp;k2?z*qbNgw;)3LGLao0n?{O4;2g$7k%D6%{{eZ7N} zW0M`@THba#u;%A7r_b=DB5z$zD+U?jZaU;E>}3@pNcj90&KYBWwk&G6ioc1RaUD9D z%aETKC=*?*p<*|A1LO2@G!lP%yLu*C<7y@F;~rStkPHmwTkNMn|!NbywDSo7!Nf z$Xnr;bI=LD)?cFoM?ZRm&7f<)1YhpN7%`E0Qs_+#rYm%5B=^zuW6MIh8;;WBd1de) z(wrQSDIrepB<|)mU)DCSb!RE!(?jt!Tkg`$Q0uIZECJyJ&?3z@Q@JNn&=Ndp_bC^4m|m0KGX1Es6~ruvHZbTCsI=7SI!oQ8n&(tmz$i zAxMv}){JVhu1yu7w05U1inm#fqfDTpt0N7zG&mNEsXZ>XPj8b;s_JW7AP|wxIw-1oM1n-5)>bGz2F^Tt-;tJN*OwNf5o3WR+&)k|iG2cLE8> zuEyNOTl#y%+>L&f|F5m)r^mk?562B1O&3Y3Qh>Yh|8#+zqO*ElKL-bot4|I7FUvG! z$Yx63u_I0-&lx{p3}7@#>@FNIkP?K@n%oT=T5WgxcC|o`AG+>W?^ijnFQjiO=vOdr zpV<@mCXC1O-ld40-0*x(2i%5powWWD4n632mgK3&3=LFDiT11$YocP?KBRXmz|v&%$iS zyEVsbMuHd*VET4iSfLIF54}mNPS#I0M9|wA>{Tk3Nir*aPuqIl=|Uy^Ydch)aB17T zI|}Cus482dmu`eto~sD{xKEm?UdEy7F`;k5s6wT$f&5Zaot%ou@|)rSjUq1G38(iS zGjYxz-SOjJrfrHmf(hP(nP82YMrK6_YVjp2N7jnxV4lB*oWv4DGK2cha45R z?3auHYg;;pl&jhDaW+e;726#dgYm}ywDaGgBRPI!El!G!EtozlJWJm2$CeYjIx0;% zNt8)!5Z$528a!MIU@vy=)w0CrKi01yUoIQhAE;>gS5c2&Od9K*`7>N}+z+DnY%%~JaImR}+X1=yLLcH5YO(u;2vD7MIbwi=U&WtKeXytDQYCth z2hsW(-*aFB`(0t0`s@&<(Thtes)z?+%pW9RRyL;x(D1oArM8ubv=>5S$3*)>W=5p@ zLb$c7pwUB6vri5iIP^6vXAx#lN;=m`*{dsr6c&CL3wT2Oc<0(jRMhqB0IPuT5I*=p zl5XvlGCeK2(fLTX-_j`*56d?2$7@upe>9p9y&}Lwlf&1J=knt#Rv7`OcP@_7Z@k{Y zp_2(@us93V#Oik88@Jy+Z9PHvo{P_C9Whc~Fd}%UIVt1?-)q}Sn*3Cfv6Pg| z5NfpYj%l}Hb|6|z5{|jh`pH-N1vXtnQ?7Jz_UB;sXuejl8eE_~Uw>qj{G1_m#&PLJ z5pp;4LDg%SaAEN(({#c44DzBrOUmVj?=a@;Bp9|H9Y{v)fu9sP(mgcf4k-A@-pB@B zHs8JZj$cXhqoY12CGQ#f!los3`X)g zqB?z!r>m1E#&dk6=`y;YVnDlOBzyb!K$C0U^zKggQl*YKDL)BU3i77y@|`$V$n5@b z9Y!sOXf#juR|5B3>q{o^NSB{q`h;|wFNnElnJcCEM@Z=hvj8eww3OR)zvA9-YQrWY zi~3-{`19lN%m_Ly4$m`o%Z8S70D!E2OZh}n25aoAgS*sxuFwbbVt>T-% z_$R)IjUp2?`VaK&s3@clrv~;p8_)aLM`X~nlK73&(EPgTcp(^gDEVtZSI>*Rct-l$ zyogw8h}QkttyiT&PoR>zgdDT3&<-HEpf;EAv>)KvmS>Y9LbhjZI1#v}KJ>=}By6Sn!I-NXf&8U*-r-eq^vAHPOCj78jmAWuBN zfK@_Ty)t5XB*QTg(Av+?uv&sx8YA~lYZbsq?90vLHY-Qy ziZA?vW?f`Je<>JO?_Oj-Js3JP$rmD?EjBoY)0$k>qz!ps>^d%bvp0v6GshQbxxJmL zjWdE|0lsdoWri)yz!ag^0BXN>R8}o&h<`qhL9d1ZPhFNNFB21*dbx1nZ*^ZTl4|wWj~Qr6jfUnrvTC_C8EL3CGd`0#soh#z^srW`wHv8t!^j;Y2zZc0-&p!yL-S4K}cb4&d zw65)i?5@tQMXtWxwA=8wMtQs&)-sr;KwrO|>Rps>zEut6d`$aU14(;5lgoH=I($q% z9pM?Q)f)Up&#-bHc~O|##q9yyBZm)?UzlD8OCTZsih~*}_dY8+ViRw@#e?vY`U=`pPBvKk}Y2xEj?I&Uw7rkpm0s#erdanI^G)3pVgiY?$p3N4g zYMsulnW)<(rA4oH$ANd(ClsR34S$zTzx(Fp75w$j3`S@W+@XTmi#vbjn1c4BtthO} zyXkFKBvrz-=*yyS&1HKgK10J!&DBEyX%Oq#cOD23u#}Ctgjw;|Y@iOfm!=SOt-aot zfS5;b8Of7wRIdn*HTn=^+{2l5li0l0K^J1j9o7~Q1vua4ezqrxR2^uL>dYHy7Jg50 zEphCJexMFWn{IuJVp0%vP({234DQtwFA9*?qL-v$G_3%RSDz!fwY9ajw$`=Pf0#Md z|L;>7$=6@#z~Zu_pqk+0!HrLh9bBdN`}D*vkFSEv*Jw5)44d6ilEWe8hvBT7K(UPU zG?93e&z@yc!z{dHr|*{7uk2hGA41d?8y4@ZM~p2NT~1&Ep=pAe4Kk3JILK*)BG;NS zdm>f{i|za@lgRh@W)cycN@B#jU!!`QW$!tU!KfuHIOay^=eFlafS`{-^5yJ! zbv`pz(CF3Pc2K;;AWk>+mUyV_P=u*On^BTk3kK)-Y3g~6vS*RNUt&loBj9<3_vomxShrNat zJTt=9)Z`cTB!_5ZG-N}cLPJ9V?USt|y|X$GWGgw6=oF0>uGdn#9M{@p+LXnY?8m8(IX{W5RMK3_V+q_^2Ca5ky_yyI z{4Ood?>Dl6$;XlWA(0$L=GN#yp#@VRm$l_*FXu1hGwP>yjlX`=-jUy1cZGB zPc*UU-bcJGYPHzhjtNt+a{b^O!4gdokk6E!zxhU40CK&D2u@D&A-+{KG4ZC6>qH)EY2(P{1)kG*powgVFn&Dy95Yu=njVu><}Oj3^-6k? z$Hm}0$uI6PG!9=?tDytEWn-Hv^Su^uZQ4lZ^z&j`X+ z-qs)#d-E@0zaO%xp=lCL>B%s*%z(FODX;}kmNin;KX@UY=2L3Rq6t6PZ$%=xG(Vi3Cpr~Js9gLfw{DBGP}WFQJ{ zgk#C3o;48l^UkDWg&oAjrEbUaP0H6JAuj8fK?XJMb@rQMzJQ6NjA--444ZA@EaqdfI z2o%mh9Zl-y!hnDn`)DQ#kmrc$^k}Icmn^K?Ob~axH>ba0#Hpol0_Nx#Ry)XK=9#g` zI@!m|oipSUT0#G1piddt0$WQ@)7R?<%3>^skQCN0*{y1l^kMni4;rog&KlK49G37M z?iWl=jw>Z4C9*?}D~<<+65d)ul^Yn`K;#s>N66)um+w*n4A8c}^orJneUOAImNnPi zsQ=$Q!S)z3Wan$T%Cw_FbJMi0SdJ|h?b~>_m)w1KgWvr>&L`c({k?hr*Vo}{ce&C2 z{Q3?6y62Tn)K#gGb0m)d#3XtPTu&Zaf0R53+MEi3^Z{Swg`+3NlnDF%-M=0KEx*`5 zVTpI>sTn{oZgTv#FhKE8biXOP@&#FBxNi^{7P9#8uF7Fw%I_DIn5#8_=L&4_n{dl{ z{Asb;Xz;J3%U0i?-?v8Gwq|D1W;oK#FJt6w-I@Je0F^N&I4tgEO1Zu}pa?sSe6k1s z{$I}$K5hhWR!ovBk6W;i!sUD6kRiZGvK@dk8iv{yO*QFw4z%}3`Zzc^5Od=; z3TM<5wgtl+8YochV7E^S!-WaMHh=bFysWxz!GELcZjzl%0hLomG_RGAHk+31 zZWWMd3#hbzzkr0$_eo_C(E|mrPzaX3vAig>Snl~NWI^DP2mB=v7~xaN*i9~;k- zcO4VVJ7SB8ehSIUjKz|q%73_1zkr(hNMTpFNoP|g$2W(Hs5;nP+byz|G-J2jp#WtC zp{wrRWCy}#H-pU7t+Z=4IKTt&Q;~ThsKh?h>GuZj)s$0x|vuraz=ibO^q2t8~S>Wi6-WhyXHOmngYkm6wZT# zLW(+C1{`|%--C+kHV!?HssjF zMbj(<;Mj1OnnG|<{$?a1oZPoqkfm-p58|)(Hm^~`K!c&(;JyA;ihMZ^81E+~l5W$r zUq`l3yL$PW;n#-T4>HmoD9ayuiGt-HHEbfLluix8$`HLO;VpP;y6q3$*en!hhp;h! z4BgH}FiMSAlO$&00pf!$n_Ta09UDT_5K)AcAPN#u4OSLVD1g$?fe3l9+ZwBDB5RB} zwzLSfq-KTotwEFXYiUYsWmR91ZGIK8``{X)m+PeKQF=yB)fya*#?Gzh8os3B<;%E5 z;)Wu7=5dJ7w=*_HKYO{rMUGOlO1G_<_k-PqPJLS@`ZAa-K z9mUpX!=}w^_4mQ-w7Ca@v9~|ggiUX+ z`k|TWcR@;@?RyjF&_j9}0}IP%vWPnl@UuBX`MWFZgQwO6%pMeB$1I(CmVCjoHGt-K z6F;iNM+$$L;wyspBh2B3!u14X;?cL|XpI)&G~B3HjRef>rGZ5dgkgMcpa1GWmPHae zP(ZnflYq~m7*_t`>aak}uH9$l!&q8xOKn>SY(;ZIpl6%yoQ2~vj9UD}_>l_i>~(5X z2}fI@SaVvG7v*wFYuiqA!&(6~McObzmIGpmgc{laAj-PP&?9mXcCuR%%1Qt%mK8N) zpy#gS%F`HNhUN0Vc9{_ROoO;u`h-^)jGH~Ihf43XFy#qSRGu1GE<7SdC|8Z}Jumy- zBEc*9=@Vxm#>SN=h(1E`{S!Uwd||&!w#*H zDNQU$hDI*T)i!>8q~~nZ>v|SJN!RmQ9~@a%hr-bezQ{z~l`s@roQlne?)q|LDUuN< z)qfep55))EuOq_C;wYFKtQYyvFqGviAylXATeIVy<7okN-sdk$2BZjK2_S40+7w+t zFy-NhpYD)POb}Cy?@s(bI|`e=10x1#GXlDCf(w5u)4@Z{ol07G@MZ1&wkRS#FD4)U zL3vrAAYqrV&pn1_3t99{Xz5zMvuVnKe5w*1RDL@DuJjp=2a?Q-5Y$U$R?mZ25T|7JKm`ZFjo;04%WsUx>3|;QuJu`L)(vkL@`Char#}L^`u=Y>-*2rn(cCqOJ=8(1FIrq@h3^2 z(J&O?CzKv?L+}Am2w#y!eyIGPug_K*1AgD=SK6+$7AnR4KFV2(feFITeo~68on;^w zHM7NkmdE|(-Z;A#+bn+`ewo}fw|2i+Sp0bWaqV(qLS5$XlTUa3lm3TS)2#5@yQ^C- zG|Irgqt0)Be&4tmSicPjywBaC<8Ahdc`y9v*HSJR43t5&oI40`G9aIneIVHPl-t7j zt@|jE@Z3ed!^8OCFm;6HoqD9xZ4;8aTAy=R3&ALTrv*rjoXO}}J~mn~?~s}+E3MJ~ zts#TLmw`kX+ff-GNVqmj=j|Yejrzf27IM&0k9--@-oGf@ee7%b>8A5l5^lCiQxin< zN<4iDC#~ghrx2#M6clbW-l_g1o>P_BPUQ+IX(^4a%eWm1cWm%C>TBuPA*4b%0K+#(V#4 zfiAwCL{XX`fR!y;ccsK9EViUM03ya``jUEuM3Gs701K$ki9>D5Q5Z+ttNVK8ee2#= zJn5@1IZ~IClaq0=u_>d--4`8qFOXM-?KFNz5f|40qw{oYl*bIW4MP;+Qv$3PvL05O z)Yp^#5yLAp%nF`S@ZHl2$c#- z5{<;tO2x1y5uF9ezd4<6(Fdgl7ibx2Q)Z!O5i`1c{?HzohRRianZgi)1|Jp(8Baoe zGwBo^o`Pcsz)ouA3|S<2_^+8j#33y;QFM6(?Sf(C1G&@+ijT8JJ$#*KK^GB8RzPgOd(EIG>)_6a1i9Icy0c{=ZQk)RgnVE@5SOTg1oiBj%z*k4x*nbYr+ts z6(Q!Oc^VoR)rQS0dQuR@a|aZFP&%Z)67@V?W5vHKTu;xW^gL&azb8UegA|oPRv@44x92448N&a~(0#Bk7)3Z76}+ z{^oLJBg6?Z6(;iWiWwqB4^TGt2mGEyIppsEBR_mkbou4HQrsJyT;G14gFwkQc31(( zuWq@4)WXi6&sa~qSua$8Ij|GJhP)&53~E5vGxW_9 z{lRd7Wh*Uz&7$NE4DcJJy%_{A_vspGYYaI;Xz?wnXANTMNvUCGrnDiFEv4M5Wx6vI zngwWCRYDwee@C_}y$8`RcBjDwhpCj!E)`#gEOS^W=k^tnx!j6UpGQMK>G_2V6Ma55 z5hO{M9=-fdkOnfscY49}H8CF{a`ZPCZu{ZNh^j4t#ggYx_3`kTZV|ClQtoK^*YrxB zc7^JL zP>lptDQjyUDx}*JHziW>ps@XN-7j={t=&uJ_VXe!mQNCH`^h!?9r`%wI>w{DjD5+= zCfS=1)(E*W7A4adqV8 z>Z;oRD+fRN{8%0vZ3&R7dvoIVGlo?@mg4;X2+<*RK$ZrRuk|~2Zf0gS&>v%lb$JrV zwUhMcn2~n51&)mn9s;$PhzS6 zBQtMv1&>9?f|nzsx0eKQC<*r&bFfAQiKU47Mf3*>2DvWhNpL=FUogSb-G{P|^4Fg! z4o1JR-O#M#QykJlIXw2wjqkI_^5p@54_NZU54Ag|`E;iE>Spn6$fx4x^D7F}g&nw< z8u%!6FjpLBkwD2VU{7dYs~H2hxLFl?WXt2?t}j_!4r&_6!Yf*A>P;)hc*iv7IR%G` zx4GRy8KlsD$vBJkwEIK>mq&zOyPD$Wabw_f+Bz=|I6YUf1qb5G7~}^7VoHkvb*s@k zI;DW3H!sV}w?ueTSW)DED$H{m5 zR|#SgFszvJ>2Zk_#SepS10w~%8`q?q4F3`lqyqKnRliD%BLhN;*r$xa?`1&AKM)Q> zEZ>(zSRx@1opADUbA3|lMpPXufmP|e1OFQq0N$8+)ljbuIpUiG{O=3)J)TP#mYBjp6NdGk+-$TM zYoBgumR|W=&I83xtCyQzEf_;Pg|t`pe|!#ihV|=D?J`IFZ@ z$^jzP;5j6Sj@>7J-=yVn11;aq;3FmRR!zw_GUm9E1jJnLrT}Mz$BZ;q=_gOZvKN167mVpH~fiN&KYIA3p z2oU6gJ8wMRBfqt8MBNeOcX5R4_*OS@Id)Oal{*eTv#izq^L^tlbcgoQg~%a6+Wk=@ zKgUj%!uxL4qn!$dqFyOYcu-TmLk>UHloz3NF;Nh~cSzHpPzcGk|ENQ4^0$vxXIG^C zN+!*VJxni4;XW-DVxi0u7fO;1=YG+CoE+M{AmGk6&UqXDPasZuGIi^|9c3mUB1p+r zvoqGLM6>=>N_XEu%FD?U{Q~D=E>QMnk4%P)<~JMF3rs)xzvQU~{vz zSTmChjRUuc&Yk;AOQ$+exZdq_AoBle!O(4o2av@R88d zY8x0BsLOG{N7}?4uQUg2!~U=yG@I{Hy8Hh=ru^d#tUtd54$7XHc>ELsbZm^;)0n*D z`zR&BtSj;?*6WNv(oPm>UaPBnLX?Etb96^7p+)*&CAH&-$!fJav^|%cS zcN54}0&83VNWdR1zt3a|m3rs#q+Iqk+l!tX?1~KTmGRtBF4x@>#IqQs+&FvH1^PF( z)oP%+?5N&HD0-1HaD7^OnXLP%`>T^MIOb*bbeV+X)u_kvcNn!+X!SU3*0K3&XbeXE zt75Jq*|&4St{Fi_J09F8xHvU6^r-qE1uMAv+xFnIq*1uyE9xPo+j_TEW&*_gs~H~#+36Hnw@rtX)i-K1<6fMrP~u5)f`O8N0-fumg6CvIa! zLqiLSfefKapwZKKQDagoEQKS4FtuQxdeC>(xG9Bs(fJB5!6&2TuMSGO#inrKPj!=C z-fc5p!mmZ_rsP7uj~|?Jp(5g?Ci}T+{g$7bu64*nIb$IC^m7A=d6jz$J*oS!Y5xVAef)bsOwv_((lBOG+yN=1kVCR)|_Hm$VB}ej3Aww#v zzvq4D(Z)u=?e{wBnooaj09og6kA#prD)^S@ZQ@R4^1W~c$ymXq-s54Cs{kbyrn1VOiyURMH#cuqAU z_Kg~URjD2mlIGeKOr~zCI(HN#7;QuTj(EI>xGtt&#Rq@PvNu_rK$=9a_<>`HY)-F9 zr4`OLXgG-@Qxrqj=p*nmAzE_$R$w_k~z@(Im>XzhVA8?gx5Ni|ne&tq!F z^4^xD{HcRgzMQ6SXP|E^*JfCX&6oLM@828?$;r)GtTKxc?N<+-7ZTO+84U{%0u;J3 z^X)8A1?qwCA-&$6NX3j;qa^Zd5$Z=&Xpm(tCQF0TUk6OiqvVOtWR$=C8A@G`=wM}E zVZA}44%wr0cxFE7QQg`*~L4)o2IBf=&7urlD-N7Duuw{QM5af z!q*b2X>p8yYc&)z5b1)?w3x>S6JAL>VI^f=_9SAM2Hq6lBAJsYb<*R`H(mHi>nvP> zW1I8zvN@xA>Cmz0#rY}E$DOf{hG~(?T%+wN%!0HhyfL04pFGk5rZ2trRJ>1~-=YNr z)P{7`PGX!)-z}5BLgIUn?R0lq!zJ!}xeuYTxodA=+XA{-?wR8y?dwG;{Tl^p?aeu% zXYU$PCz+r0AQy}S%{r&dd1k7Fvb+7W*nnzf5)#qqSB3PK%&F6|cBs{532YFtDl-PW zG_a+#DI8YHmDN$nX8ZcD6BkC~@Ax#-P-JIs{B?PRt-1UToS8Ud^_Ns$!Us#GBlK_K z2z(jqt(}a49NyN@aC)<+f^b^u;{C+X5+nPB1W6ADB<6XTR`FMT`lMb@eg`#Nvln$! zbU%f`jC~v!&<0qQWr+0Z6H>5Kv7*HKkyd!$NCEa1Oh*q4(Vegug;cRYVKgyqeLS$C zW?R(U<81vDi-LTsFHn=#X3>kG?`!SNI^|>I<1sNY$)me!JgqyoGFO{`MQ1uanilyN z_e$=b&;Z=fMeWfFmGM>!Mn@9Od=(cRnkF_r{v`NScG%j|Fk~F23g$}s>A|Zp_X12F z#?;1^%rO~FKQCqxBcz4c(Q2>TU^jI}|MmjiytiCkx2tFk1}B=&-&A~al7%H_&-bSL zSiH()M`ZTK7jC5@K()n-J&ds4qkC4&qXzfnaCt^%5l4m!>O2cEpS~?rR!)pmc2XGo zMWbS?EZ-8w_&mAzhG#T3RWON(LD^(*WH!r#h8kx1^vTD5+TU`PCPo6jqWA@A7=@@J zE~=!^P@g)C1m#B|%taMG%%C9VnvKLdEi5oiiAW?U}^{j^L|raXIpZ=f+M4gx}l`C)!st_rwAG{$He9>VXQfr&&`}L+8jUY+|KJ5g z-w%Eus7Igu%r@dV3A)#fHX95>2`zn;2jmmjQ$CGro+ph}9Jsa`uc(A0#hDyF@o-rG zlIRsoMF(Wf4ElPKLE(!5F^!{60n{FOhZ0M!*UEdx{hZuUsSU>**QsShP9jbW{Q@dM z${jX)P|Y>xj5;_f+?feO)S&?L?b9LS64_iHJNTtuf`(Uiwig=%#ap zgs0L+hRUMtaWQdWH?1HO>s(ptG+Z!DX?K|*XTlOZKcP%8WWQF_f_FYLj)X|;SGbhHOCH`Rb`A6RFOQ_O= zg%`mn7>neuzI@I$_O^Df4KkxqtWlw3RS@W5@X!AYD5sEGg=X*Y8VV#b1A~V}^CulN zXg*rv9Y~F$g^E0KRJUAWsi4#4%QM0=Px=fS?L)OPoh%ALCXBQECQ5+XyV-%CViDh> zfv&ZvGPkTI3xrS^a4Pe^mi-j`j-0ARxhfuJuZwM`SSr_Ds_9b^dnhsJDCA`F8ri&H z2gw>WX-B?Y9psXD!53Fw%;x;syiiYeC&|{Ri9+-(@bQa!4~CQh{M*D{4C?p^tt3#S z@Yzn-QDPA>m+)^^NoTQp22>2Ff$GMJ%%h{fwT+rhyAZVP%(nn$$8KX?clM``+g8<| zHYPmO(7+boA47gv`Lt5^N3g-0Pb|8MHl-R_;J9upG+?*z+)Yv0Gb7E6_j7TU1?)}$ z<@1?yWCo&xLK!Zcl}=Ok(g+k)f+Fzs-G`mTo$?r8Ib+Xa!{PR!`5HD@jL&CO6YHY3Zx@(@|yY?#$F5@*G z)Uo?yR*&0#i4(HGYxB>AFZWX!$@U9;f;Xo&D+e zWLCMM3!3k(o{6%xI-7_jq`Ga2}4CukWsX?h;7fLK~Tt z+O^y+>)01cuiM}<=AY%gw;f`bGWc9*!bSs0VBrS&HiY z^yR4R zBtLhl2Yjj)hJi$0Ea#^*wpZ|BApQ;~#($MJWdJglcg)VuewFSZ=c$@_!*6BT_Mvi9 z>qLA-z+t&a@Uw&DDl&iC?A!&esQt`Qu>QIQ(%YXFH)>lpJ_uA4Pz14#RrwVJwk?N0 zuVwggl5&&iR__gi8iz5QyA7Rd)esAeFt!7fuG>+zKq7% z=cPZs(1Hxk9AZzBxaH9`vq&DqO>k!lbLmXC7WqBlBJI=*+gkmgwP4JDxaLo###qrH zDghGGg&?o8#Ak6tRR@mXw3g}F;kmqT zJFd$QPI!RAIMc32iN3oe?Mcw-`eeduX&_dC4O44YouSakD zNw)S;{X5JM)LR-wlTM)c`Q_sM$%KQEcW{WE>|2QP4Vv*c&Lip^H^`t&F-RGOF2y%L zCk2Wh_HE4j+w6e;fP_NU@NcjYaCC1AgMu}^J4aG*Zixi%cBM*MNK5xn4TPrbzN)zP?$i%_VNNORn4OvF)co?h z{%njiG2q>YKm@wGP|2f4O+wNiv2G50_1!U4XxI`O9~Kh)*-B8ZPwbr3{P+wM#>6FV z2xz-Om+je1OdW=A0a9`V(2ABVO7QLA9ovRt=+!puC2y}_2Kq%N0a6Skpn$4NJsdCu zT8vUk__a`FncuuigFl7Lul^X<y{!e3uXXOm@J0+BI9mq8F~2gYa!x{d$^i;4y#+%RKc3kqm2BLzS$!w$Il z5}(Er1Fk8Ab|Hu2*4@LuyT7mi*nPDtT?2~$WKP(3)ZaDS|5uDYH3TB_Z}X)3{vEjq zNj7%_pc;pVL<1^=b^j}0xypG}AYzCV`tBt4`hXQky`cs^2Pyvi%bhs^6-pS3oPhkh z$H1O>?{swox4O$Wem{S_qnDiwx{oXx1mbJjorp%O0bLt>BqyYdTa7w9d!9PE;z7D8 zy8`E@U2C`$Iwp&}ii6y~35eqm@ws`C&k(dme#oM8QG+v0##&PlitG?5b#R)5+`MWA zno|z8%GWB_no0;jm4 zK4{sxYX(py2%E9!Sa1bO1$S{cec!>$jfdh(>bCM>E6FpjmFt;td?0`_RK;~Q(evC6 zvu)h{**}T^RtWN&r~6B52_d6cCF7cLVg2(*4b4f{ z)D`_%@CMGc9*50A8A7z?j*Hcn&UTzAq@#}T(%_hnr$|m0GLD@eDwZ)QxU1GUYL+v0t3be}H06+QNtPtec^M3hbDs1k#?4@Lk^fBR8_7sbj8Vqi1 z9kEghB#1Sm0tB&xKzQ>WQq8~iwlGEk0F~IK$_Joa2KUN4r_bXbS(g zWqeQ|4hOTD>WZkC3ZwO-GVKN;|t(Pc4p-NQ0EpwFvQQW@E zFw3<92S!Y-*0it{i38ZXqf18-nr4(j))Lb~|AC;Cez63y1^1!AvL)uDA`4nJ!*cw; z=7_7`1@Ff{SR+3_$KV7u(f@3YxB!#OYTCHF>08_Q0ur8TJU1vU&Sf{w%My~d_UrYC zI3t4mGqjgWZPvhFc~(?SUVez!1hAEeMYBG`y~`HVj$JE$m*3&IlOU?sEsR0<&23}c z*dQfAuzjX$80VZcF%)4)QCVsBUp(=4^uss0EPFx5um3dl*F@J5pVQu7%=Kvi`!SRr z>F0~PnIn%dfS?}y7lR_5@`GPc_Cuk7hQrD)OX9V$qpamSai?j5#I)KEB$2vY##LLkJ@D7jjc5-D7n7njsF5 zXN;hFvlz2)d8-uku?jjS&zBbQ_8p+I|-c% zyjyPv)T!sGb(^LY9`2^h-pc+D^g^}egBM~{>99qP{GDvf9sI3$Nr0&@w|8JZ`3FC> zs7shg+bVNJv4}yTSk*U-#LT#NS{T^!X!NW1ENEtls8D(JIfA)o=PsgTKby$xT3Zl` z&mx&fR4w>on4XJLk$^J52;!=i5c1f`pJ(~gc`3%ypm(OlYHE*P^uFpmWL!s+L@nLrk4{ z6l@Izz@*sM{95ixd(*=eN>sm0edgQxEASkeDWN+apT?1^L02VaUS|{dNRi_ov zP|E{%W8xe`(j|@rAZyDMMHf2+TRjE!VV>UgG4|K4QoV4HKAw_{SgJF2*HW?8aers8 zKj@#*GGaHpmJ*Dw5>i&`*(2Jn(Gh7WMPKy2M3p3I{x}dd^l9Z3fv?$1FpW?_`qvn_ zLVu*J?zb`575`Gbv~2)9^p$Uh`%5OJK_Z%r#+2X7$lStEl^m6SA*&4#V;{qZpz`#_ zaMbqfYsE#BSM4x@4KUQl;lgtefM!GZ4n#$gkT%U>emXlI@Bvg2su=8 z<@E|bSfhCWG57LVUQi|Y0jOwv@ZU<{1~=>ONXDM@?^w6g0DAZlGLlEyviQ~3Oh{3w zZp3-AKr$C5#hBRUo7UeGF6=WllN_@ym&%R=N^?dtG&-Pz8C6TsV*K6Qhc}AooN8Zr z`3`$BiV(OV*B=7y((q}u+N)LhK`Mo2H#y(xK^yh`1rQp@;q7EX4sXbgQA-G3W z9o+p9Vjk|;=P)u!Rgg7dw1O3v;gAFt1?l?(|36Fm;8%=HzciW@akonXaZ>S|;6gUx z&zZwiEyO^pk3rGPt104)AP+}207{C}`qx#qSD>#P2aYuSo!>2)AqAeUVx9Ot;nTxJp=D3k6x($EFc&M2i0G#6 znhhUp5~O3Hf};v16UFf6kF2&V+bZ@Jt9x7A`w$$(Djsphrsrdd=r#giR5S`sUa5*G z`rc=oMiV1hs6DZnMZs+5uH?oez%}QHb4Zu>uRUY{D?}v|fhp8adwwTWUPi<_E&k(g z|DU9GG=l(9ZSi??<3&s|Rc*dK52?sp#XRaff9xol0syEf7zVEM=?MY zIFl}FxfF*EU{+a|%nfRyKKLK|Iu3c;<|P?hw`tucyKWB(+*F2#8YXX^s9>DuGS`?l68DVzgens7_F6}aMGta2 zNzf~Ve5{sC?(#=w)zonZq!eqr|AcJ^KD`{&e}?Dp{Z47Yi0w5wS&3^Bg*XD^A7$VF(EUX8ud5SyOd%JDM+Shhn7fmTM%;O6gU5 zHKq_PlD*d9vr~K9|IU)%Plg*>a}{w|B(i)NRjUsInr{Cz+UrxUnaLg#F3S9GRxpU1 z9%MAL)@Pda+|4K(eL5Pc&T`S^Z;P^nqYcyOQ$>#r|_|Bi0LK-DHx=fh#?r}!sUzAOZr?3xAeOdZ(*-Yr~k|+l=}Mv z;hJ3IPCLth0O=8}L${b@;9flHI!pN}X-sR+EjtliGpX1{nd#&3Xb5V|-1ijn+7n!- zg|szzQz{q6ju(agvx#VykANQzNy3Rh6ww~Tg44F}&k%HSs5ixd5|BjXrNQBMo|0}T z&_MmAMPSOD0&EG+c^8(5-a`>P3cX3z=A#yj8;pXLYq-uWOYGf%=VHObB>A(Uo6o~`dBqiVi0L)o${2mk)SEZ@tPX5X zxHB`xZR!+0Td>P3&vhMw538#_&K^iW8{};-2JmgcQ4@d;`wFA@x%;@j#1#%13;^vF z_z7Zn$4%i=kvR~3-qH=tGL-EBVuQwtP^Y+>B8$u?eky24>QJDnx-*lSYf%o zyHZ?knb4uKRaYKfhlWuTJrJ}Z*UY5yJ7fFXVe=imD8H6aF5C`<(mna9GW|14Bg`O) z)@HOB**68a!~VTir=>-{>paObJN07Qj-J4EVd z;&GL~--kyw)SK&`ZG48LPHJ}dM* zLaS2|`ot*yo-JC2uvm%yumcyOZjS$fbtyH~4`-L>f>MBHN|K8W%noNsfyNfskt41mn_1?(FOGzoIHM zUvr+)9y`;Td|{~m(8WTy?Vwj-Iu20vZk`3Z=hN4(=<^+=qbhL-!~jTU))<893CO2R z1gz-^Rvy-}agPN&IY7PEgeK6A$3Busfy`z+F8{7dAJkA8UwnwMiXjJp zF@#BCgA#+#=_8b&tUznhm^RQdRtQuF+O`P_H7`fM!bH9R%dsWCTA|0ruOPBOe3YZp ztKJ=m#qrE`ZY#Af0)q%hUw(lzOHMK7vq8h)2eaW}q#4KVF*#~UO%*qo+=s~f%^3te zxWBXfXhs&HgdqX7REaEA0Ku80@{WvLWemv@wQx`)JilouWVe`2}utxcSPD zw~T*rYWv3c>2)A^B(L6CtIdR>liDcbk2o1pcdRlP>d+UJGw3pqG$yo~_Ez3g7~D9s z&?d}>`)I{`XGNTl#46&cNt-JXZb5mU@cA$;8`P>>&G#+c*H9?5@wzKyZYv`=`5r2|^XpqpXOY3wszU`UDhcNHID^ z4hBW^w!CVNDaJ80v}|`|2T?#nxR1nKMs4%ZJ_KT>OvR(*=Q)|2!)>RG;3tsymI54? z3Q?fDZLF$O=}go)KP%L#bSx>1izsf-rJKcPG@Kf2JtSXdJ}4%SDij-vC$3UvI7)`^ zlwY^Jg(1b9cMRA7Abu?lHYw1H<#JyO{2!Bj?W1WQJ|(}l4}Xd9Tx(hVezG-lkyR?l zgfJOeMq7&w2)}zxIP5uUoK)aZ(fo<&)vG&WkdlXB`C6@YVOM2+QoXny9FqKF$ibej(1O{2 z--WB3?lV%}7PPpWV~k3T&z{JOsH+D6wk>z#6Io6lDxa0{-xxGDDKhr)X#eiLx_86> zZvj?&B%2$xDJ@O7obw1kV-2;sH9N`u=TgV;u3(lNA1M4o-VccK=_-b1#i9=3x)3G%or(?aZ+YELLg9go#w-@$iDAnI+Fs$6=( zK6(2@d)pmVDX*kIqFK@3(jCHJgKn)^*`w)u>GTBDrE7MNz}V+*Y>W;HPUJ|DrrpyN zDjLC5SokHG8?M+K-BZfr<~^0nsu0E*(b2%~Jxd-)EzuJ@zcc?rzMu)VmY<;u5lZ$? z0|dNopK7;59f9CaPkF<|mML6XMeBW1UDE!13tz?p-9;N^{>|_!d9;RY|k%Odrf=$mggx@5Q z1UuRzW#>#EvA8rK05M7Nc#?T|v*qNI3Ao%bo0M`f=Fk@{drs`tL>}L{HTOK_#k62q z12r$e7{x3}UZ=_6=^0rwg;fVxguYxJvskTeo+fvx4x(@hZZ_eC1R_utH>;c-%LR** z2Kmp4PpJp!6>NzaA;?ue5Tksr1^nT)wmi^I=v3WbF=G%!`m?~=pjMYA*FZ`{;<;hk z)AXH0L933cKoDnY@Hgk}y=uT`HE%zkgqdqP@ZQ)lz-Qokol0y~!Hv_>`$t-!@cxgY z&_DZP3#HG*E{m#hKry@FGc}oucZX(ly-7j~sbaFBdlRjz;>i8F)BQic=00^4-<a_s4lS`lv#uBc$_z(#`e^$(oX)h%DE;N>@GzM&gYr&O6j2(cXo8D>ewa zE(Y#zQ*g-tA?q)r+WelkZ@575;O^dH1&S1RcMVd!xVy`VyOsi_xO*v9+}#~o+_kt% z$dm8yf8DR1m&po?m2>ax*>lXy=QzWaCp{+9wOl?rlhdnDZ8y3aNm1g*_4uuu!OU{) zTK)$-D#{-wHYC}E`#+8 zvNvqUF~wgx)r9VLY1~WT`mO5Koj$2G*8Q?w`26Rq%#xv@L^}RVCMLhN1zgdQLAFrT z^gU75h8}{`;K&-RR+p7Q9Iy_M`>mf`kZ_udA$fnFG2*uW>3f+=vbTUP`r;Aror6OeU~s~!glQ#$>so;jp})ZwhF_z-#dS3ZkNZ(JvQ^VA*2W(Li{`ZKxHJ9E zfuh71%zIlp$GbIugJiVZ?I(v1y|?7J0Y7(bVz$mA&JcVq!0n*E(=S>za)VF{CagqiQte8qyDIC#mHXTWh9koA&>3)t2g zOkc1f6%mmRw3>BJu6#b>p5*)H31MawsOO8&M%&aKta(PTI+Hqmt;zo9{c<-)(@D+w7F%>-{MoCY5=|!V%*PqJAAbTvrbJ4gE^*U@mwp0X z6zSRCU11-yNGcbyb3cs%)8EXai2FL{hJS2*vA+4ptppp@^F@czx ztgDlM=C{*J!8lQrG2g;%Q1(7>kz9=rWh~--v$)Lg>#bAELD4W(38fwhu-H6wA>DZB zKPJdKDm`Y|vGVAk`s z-Vs3YGCEkB6S1_@>g(jpDT zu^l5)W5Km+UjvSTJ_ zp00}@9(@rb(#!(sSp+qw|GT!q+L=_$#15tB_gsCJ^wdvFwO2;=(CZF=x4XDnd?Fg) zTa;OGgGI9}dB!ZDF_}F-6{TK{&Bz(!7(MNNX;~jc4RE7Vco-+9Pe^e(Pk#OeD~UeH z7sR{#CkhfG!^9NAjwk`abUU6*YsCCD`#=0g15FH(ST$vRry+gHt|~^c0`Xj^Ef|6` zqtcE$(q%ejzEhlcRkvi9b+wx*T~wDkq}QLeoPAk!Dq+=dxQ+A%Gq#PAaGm+kQaV23)qw6pz6FIEk`VfnT4BZYGJbA3JUyi4txh0^8Fb-( z7{chWpdmuVb+x0@ld#bn_hEV=rpd=L8eVed`x8vGE0Yjy!gTO0=4^NV2IjRZ8L~sW z>cp!#oL{259lB5RjR8Exz3Rx#nS36P1RO_4&=MRmg-yOCgu3A(za5EUBQ#x^11D=rOc5c~xqV`mYOBU>sq=@WY(k%1RL1BtT52J-2K)3oew&z(0ary{8l*_^xLiC5G zZo0!#mpnt>5!}1_B*=zN^uyS53^#%&)uw4N9)HElPM(KvV$SLm*<7<8s*YftC3wkZ zJVGxkRoLT7VVWfhl9Kztld>+erUYI6+V476%9szsXB9SbLeqxDQ;oe72KyY8B{U$K z^`#;nR5Tt zx)3pN(FO?H&b`CYHGCpA-<6a*bEk3_m29P_7UjcIv$2qK)=@w#G}VH11RIhqGm{LP zgqL*l*x$%@GyAy#v!QKfZxJ*Ka$9Tp8)}m2kn|ZnzU{0T&irjY>JkaNbQ*_?f!EJ1 z?a$T(MaJJR`(Y66O^E+!n{(u;0aq^?--!kcn_w7^dl2HSW zNW0a2Pol89Qrcbmrv&Kvfq@$6gV1B2S$)mZnaJN)JbvKBZOQm%4$tkp`G9(Mni%wu z{?nkuiIF+=*ch^43_0m~Wg!KH86R6jbp?vF+IHMOUh3UYbta?bH98wHN3(&X1La|i2M%bpNfR}^+p@z+TDLShDjh;hFK>goN}J^7=e zn^xi184Dnuk-nRSmBQ$ye)W9~xsed_=~+6ChY1iz1&1i*T9q^I+ob*L(CwJ7DMNp_ z#=nJ;pwDR&ciN=S3ypeMm?3n7P#TdT+4gGlOpY&~YB%bbNDk zOSTAU1H2&TkoA-Ew)0L==(QK6peLxB+JA3z9thB!os>T;msHTwKRaK09KKJO>^(Rw z3}-ijep5AW(#$`Z_g(_)=hiy@OWp9XF8K>DcV6G!|gXbUyMCezT}6K}-;CZ%J**ZKu0?S+gEKGEd-X8#(OZ$oL(gj4)f)^@27IX<@Fbe8QzU4?*v!k8 zv;O|=L9v8P^y5SMRmuP1%DI&WIckcM(<75iExku(L_rGk3$~5G)9S(ceJ5}qxC>ji zj*Vx?M)O{p^9_@#&nVgYg>3H2?nc*9;>Jz)dIzIm+QG?7;liS^vD+)p3E~-w7e(%K z{0fysxr<5XYe}xqosLc}vaq+ozKu1AWXaI)G?^~4r2xVISToo6d1d2utm|cr1w7wz zOL`M>YJHEoAYzAhC^ewz4g{T3Nbnj*896&zja>yxw9_oKDP4N9`XIzCkdV%jOC#_@ zlAxc7Bb&I0Ur)427CIRPb}5L?oQD5-!Q78%CFSU`S|cW{Njp-*pCbTW61GjptS*{#B+~oi zNm1yFSNqP?S^IS)-Ci;l@X!ZbAOjb>DXN|SEZE!5U!N)0p%$csIsHkv9bKNz+g_MqPc1l+;7c zcS=RCj}n1@JHzLfV|)KDWd8U(-<@7;!9Yo4TND^Nfctp|dcbv%ZBx0xX*s&q>ie@& zQSzD&{598)bs2G6eVou6lEYSqLx|U0c8x*e`je8oGbZHnG+S7o?djjT3MN9BZ^QOB zr%dcrW2&=`8t*fn@K`#b=--FPZWK95cR)GQT1D%dk{H)jO{AZVsY|Y(Z_#$ z8C4A2lNEiUf%*&yu1_A^gesXFT(3yY12eoI}e=%N>J zub}gcxDfm2A;{3(gqHYB4<_`PpU59FJ%0y09oe1zxgRWbj93?i(XIQ_++}H9 z-^@lI7M1(o|CCaU`4)qDafGZ^9KL?1bkngR2KDDkwI#pU3O^`xq7du4Q9Y!(%k!|P zSPh&s$}y;&d^Y?&lar!_-T6Z6r22r7YdWSEo4|O&C_s)8`!y=$f39NIAgZlYiCz?z zRs$75au5Onj>pPxhc@6}-B{-hyRn2l`99gkgN!va;K516`|u)P)VGf;=e42o!7<+Q z+Aa6_g=a~~?PSr-TrXg6%sBWrH54uxDFA+pk((sH>V1wk{1bLwp-GMC*X#0h5dx8G z@h=-4I|*RC$~=nbNnNGgDyu58=b=c|aqg811gg!c%dGOK-a&x+anEklV(j4=(h&UE zQCN>Pp#$O?Z7)ZDkSY?iiY>S=(o7iWc&P zULR$(nmj`vm;gxo@59?AapbjVv{v&Eke7M+ClZ0Zpf|(4fLRUe7O%gG#_{{%I^Eym zNPo#D#QqJmAAOa7=n;OnDEzy;d8J(o{Xtk(o~vj;F#Rj z9g%SaY{+)!BERp#&voLnDZW5oJ`qJNJCRuOR75;kJ_}Zu!LM+@frftyt`;uq7Y+uc z>P8UodL?j^?>8g*ypt|I({Ukm)0vy+B$W1nMdacuR?*9xl^Q?t@tMKh@1o_B9cKOz zc`w+>4YzpGV)|B@u$&b1Mjr_--Thso8GZ&AM^-6|O9ld5rl(WcyuLU8C)ONgSplew z#Iy!=zl%X%|CqsyIJhCB`!}c|OeF7zOk4!8^I@pQW?B%biG+hBzL>Vars@qTf`&Vc z$5mcfq8QoHtq8VLGs9@h!{jC{+fpOl@j0hBC*pcT00HAc){--`EVJ28gdKG$^a|9}Mv690jRT>)v4i;BJNSawXiPp^#_ZK=*; zF4o=6&%~{#rZqRJSsQKv)hu&of6R33ei)Muy^d#F@FJCKX8?QZ69pZ<9^u@%yEzN4OzDEDJ8-u6Ay&)% zqrTy`le|ijS{OE0y-YL#X8s6fI{EbmodXe3mG_F_ciWHL&1BwyO;Q|)fIClkx0w>d z8^MObrWtW7+88UO?2E4&X4l>_ii8KiD7ClW7%Gk<=DhZgo8At z>?(FUtfcRMIQAw6ld@Tp$2(Tmm2jOeWGP)R1nobZ>6nWm|5)75-nX*z*8CTmqx!Yd zY^cKAO+D7TxZFXKp)r{CZxDKg^&)yxL*8 z`4KPop})FmRf8@4^&AT6s)3wt{M4?5tus(>d3zk2>pD}ME^^!Tx+E&vFYwm4PxyWn zp(AA4yd4&cAJmjO1EwH;4>JAQN{@F*m_U8^FWy>~QuH~eh3{A8`Hew^m!e1D!m zUviRBQ*r=fC1mAL%9;z+i9 zF?J6H1=xr_rC8-bJpv+NsKgCla^)qu`b|fH#MgaW3?PTiF7~F6J$ue)Hpo?wFEXbi z<8|MzvU~Ev_k5$)k6^e9c=lMH;YD#y#!Y3`Vi!m6VW>U52_7)$iar^fk57*dZJ!LA zlrjE-2mvLBL|M_D1w>gK)?q&@7t|k-@0Q~J!cMm!m6`laRCs6-c`<4q)x>X5@n=oS zBTSMW2MCEUS&1&St#9=ZDmB~4704RJDLPgt{7^cBJLB9s>pZ~SjNrPG8qqpS{gKoW zM($HcR8;CypLMREzObXaz)LJXmgq~>`Nq=q$$$X^<|Q7(9%LS28lhrK$_BB-;ngCu zX5=P^!!V*5wUbn#3(&JAJ)^Z2lQSSZQb1s^0m8bNq%^eSkdC5}P$g<(lQz89u;VX6 zgZjCSDh{bp8C(C?*0q296R+A>O^S=>Knr7HY0Z=It!>4uJBxDNw8X-@45uL0e?_)G zL@b2=Kds<*_K^U;USECVr)X_CbP1k&^NH`3(rg+seJqM%eI8cFfs8lqLHAz(bmb=I z!Yw|oI3!n!Z~osfDMOFT5ngUeMIl(wEz$N9!}F(5=ne7(fXmHS z_#U=FC$6urtzCjT;jQsIcPJWaHeuJgJx+>|x596x?U2b}^V7{;d3F3w%`ATsVhe1kybEz$j|Kl%5n zLf?1*Sw9eVQ9#x1dYO(CiFz5}iu^6|VH4q=`jFgv%ZKFY5dI~y2GFc*Z4yp-eY2Ty z^ZVQ{z%g&n$Xx{TxP`N9H-t!OG9}+?vQG)TFv+!jD0H8G_YbxCpqUr12C9bPO_MQX zVyT)x$$Hs*qLe|m1uyTdFO;IPEzQ_!Hl!-zyBVFVfpd#Ue>*s^7roGed--X#nwmDA zaZJA-?yi1I@|#nIAJ7(&THfC?;IH?zjHxsg5*BzL)LC~XTpu_?Ju3Q~R)bZAc1QA3 z!u%oDy={RxIdGog&U5NYm}Uz&;=re+4x)FjJ&A|^n35IF-5x`0D{xb(@}*ph8wvCO zZ#w%4QUe1*!(znoL?-XGXd;ZQIU@}a{Y`^B!?KLIxjAbeF&8zeWlP8wo(-f;^s=2o zf3&5jxF=uXx~Z#+Dw}55eHbPTB~$~o>~>#S7JY>6t=`tH7w1c4K|A}phdFCUWQt5* zGZSr#LTNC<1jssI^YaB1Wc*WHm~J~)CiZF%KGL~Aqs5(mu4L#&751@r>;rVMo`a>> zScy^j=R2qvc9)iH<<0)^i7r z>+J2mOcQ53des}-HQC*-{axd~U-cVvZ4v*(V1Ef;$Et-zeHrzU6BlVjNEZnl?EQv7 z0x4ZtFOYK^RSGp0o@52=Xbzz6_#Nl?O^I0D2W(VZPVziMr^qR1EE^tqPjV-g1&56M zs`=f_rTjnAa=OMv4L?wtY?xL3h{lkvW^S3o(oj+pMJFD?h$NwHvmB`t(6Zz@<_R(- zguJ!WCJ8KXGv#Q{4zwgHQ%PMv@^Uc2Kl$a)3u-}kmnP;YP+~ySK5~7u!>T9k0XQzXOSk3$)CY9 z*p|47J}w!#Fk|r+3hZU0)jk}bzbe1Ep5+n!ORJspc$9>0P+os^5A6}%6g^8lt*-96 z?SjG*JtrvHQi|k@`0hpkw5{tlvFm{yIx}}RK&3JXUFtd|8uC5bBOQ^%pQ(PwFr+?% z?6Dc)oSb*<<-L}Vj%7*xae#i3W>xI0SPBJ8L7givt6%glpm9)9BAkN4140hH5~F5_ zm38-@GEs9;Bl?!gr5TCFiQhpkXgXk&T((N>K|HvJtz;}o{7)8)-ltm=Qz_c{jzi)5 zR%6h|4@u)bA0A9dME-I7QD(;nfkfHEz+=5Hg|l#>icTmsTp(S`_{lFxE?OBHaI(II za*h092VN$AfZ7H9@ZB3nrS>DNkL+AkgBja0p6eo+fs> zS>quAb-HLsi#KI+=}yFZ;H68;dsUZ7F#9x zH;twG?O-eqeo?{aYf-3MGbOBRD0S2Z%XYa%<$an_gR{kbXibsd(VnlO+f$zLfssDW z`{XR3N<+}#VwtnfTZ-41BOtf{egwjh{wLXjuC=1|$H;_{?@@7jZjk@Oh!t!@daXZm z@WoZ6$0mV8QjZ>ec*uKI<(lbSi(Qx5Cl8NKIKZxYSN~8t`67*ceWJ{tAdwfE1iQ-t zZ?I^w1bmNfPNEOx0s|6Gr*hB;L3eetvhF~~&8#AOI@8XjwWE}myDMi#Tz)!w8aSl& z`slCfKWW{xg}*+YhA<(*xBc@0=$0paNa5k8Dp&1j&-80bA{6~8dJ-OYW+W0S+H9-0 zgCh6HGVh{UIf7IkAhqo(c0acsr_=BasS z7n>$t=kH#^!Ycbj4D+?8t7W|-cuDqw$NPc` z>Y!`HI6Tmj6Q~%xk5(GTY-MbFqn<{=?Do?Fy~JfWVSa|`j!dBEi`6KG3HNb8Mn$(T zoq!%8PkH*a0XW;ISh15S!~)PTB#$fBFnkC4j%=nEcEQnY&GtqH;uZq8L^-Ic3r<~F zjZ%>c2z0cn-@mBhPt?7W`VviJU8s0@YUhkil}Fn78l)1*DIh4#iE4h`Rm-X z3&lXsurLgV)hl89)>K2)2`c)!u+S;oHaVL`x%S!xVQHQ{=^3Yc_fD1pv87Og;x|tW z!z%FFs1R=I!le8I+n_?uZ(Jq9cBhz@s%GRKN9$MVNcjNPp~)NPKjU=7xdD$0zDtL! zvF`r{$H5Cs;1nxjW1y(Yk^zhyXRmjA%wfHyrJN(vuE!f^`Ln_ZbBmnVJ(}ZixqG-1ej@D}q@0p?V5){}!Ef&M z(1v5Ej<4bv!nVCx)#4^0Yo)B|r>By+zxfT^U9rg}lrVay3S_Pfb{@Xn_#N z!4>z6dFBV`2GC7__qgzVpPuAElO0hN>Jq)2LvaOhwnIFksw`G`y zO*l4>IcqbD*A|9Sxfuv%BN94?_J+of8dpP~2v|qXfcUkh>8z9VnRgj4t~lA)4&seG z^y;XyZ8Bdo3gvNS&u!7ZehIT&{OFFg`y5T0Z3ZusvQ8us^CZ;h8ZFhbv}Q4UY>c0k zLr%l3DssCDfe6m&2@4(^K5RLc{$gxNNwsKf^GaDdRGCsCl)tr-6|$Ipp~|U#U0?g# z#PxEO1z-l^uJ5SOsL1$K!E$5E9y|9g!(n3B4y4$71@4@do{dGXmY`lQNju<~exdJC zUTO6iVy!|ycor_)>TCXz1&Cfe0eadW?E&hg$YPufzjroL7R9jqSc@H0WTz;xfa%v80gFE?r^Cs*Amfr$YZ@5oUoLnlSig3bBxQZ{_(Dl)4Eon zs35+A1dBzd&{QdABuIt;iKD0@3-p5(lpMnY2SQ2&8P)Y01>;?bxYS=rf{ zakP(^;tGLaVdCiV@$ci`CF8)(Zxet|#~FKq74#q5>l~iHr`Er3I@2b0=@7l^0e*ka z#g{3O+}k!bKc7E)uvl+A)CIlwf|5aZE)}8uo0mE7SV`IB0OBnl^_(*B!L$ z*&TdRLBy&vkL-73(V?Mw4?z2X0IF9H@9!24s)d+M-7@x1b)u#u!wLxG6QNrWsl4(* zrqM9!S|uWTds_CW{;ZQ6P?#dkB5`*mSXv=J|4$_w~hu)~JcgD+F)G$LqN(CBqjOn!n0RMWkyLeZFqW z@j2FZ0dv95U)W!Zq8`z;vZQbCj%{E$b-?}ay^a_9ut@i(Glw>Pv^9^GyL5MK$+InH zENY{og$M`Y982ufkP-3_KSGpl!o))(->ttxRDN&&3*kn-df=z1GXXi5n}PF)CL>sY z{_ovD0GHGMcw+n6t6%kOEA6U@n)vg}(#rue>Wn_iNWaVJgpri2`WxA;aQA(;b3NEK z<#u-`^qBLzoK3CoEyv~oGJDx?F7RuMqTDTa zEk$u2QyE`f_xQmwJ8oIB#4tIxTY7irbd;PVRj-h)u)@OSjZqHcRF>z+;V}CI`Dcef z`H?!DHRq&<&1@6t)>B`G*E3(R?YX7=@4d093o8^e#0AM2I7(Y$lJr0V0>dvAkrKDS z-qHr_a?ts3by8pN#@ke%L0vA01xwArQCs#3kp~%Cn&KL~@y(A9lXDqzJPsNplRxM| zueVi%9FrOr+54thDtHDy>F)+0iLX!$qd|HL*s{aEQabg5iIg#<1v9n)Yu;U|bc64- zmO)A&FD9J++WUup7M~E^7`}3_0&w}2*Mv@>Eu@sT>1{Rj(I1WNe(Z?OoB*?*3UTBz5<>Jde<>9;kMail;S#`*G%{&P1EXIpg{*$&i z+4d~}qeOc@1pOrDkWI}Rabi?&|J=Co*TU?~Y)oU?6*Uw4^-Y$_qU+}?Us;j)>=+ZK zz0fK-caOMYmiC}8;OE&8-ZlY+N>2H5yVcMt@%_x4x^#gn{l!6GO4!ZLQEI5qRXyz! zl_5?4OBoxuJa7KbjAlNMkcDjo>R0Ny_9MK3VRQ0*n{}7@nIc8eA164M%g<-$&}>=g z0@V3t+gSK{w=3-beo~YwBpolRaa4YtFH=w*Yn8}vA;+RPUHPUCuJ@J|R5QgD*HXx# zBw!MkM7%>-iEmVdd&bTEj&4@HK?6htBuZGkq(hbp&7du%wn>cWK?RV&*BZ_NF%p#RE`^uhjUX)%`%ZpPJuXJH#X+w+?T#I$=LX#g;w{i*1Sj?vmn>FWR)^c2eQf05@ZX*eD@gPA+pLHmxOFRE#!UT`;0x@7$s z{E~R8G?w?zW(PId66*k|;dk`Ex!n*Zf*Enz0?B!XBIl{&{YD+5)_okq|IV_pDXD!K z_YQ+3t;uhUpWY*PK{sA`bDylB#bnSmpfK#|CDUuND=-u4hzb0^pTN&ZeEmdBr;d;Q z$I7pom=O!5(2)yKXl7Ygs^-V6go9-Zfos7G_7h6_5CA>=1>DTPd?6B|QmdJh@mx{& zXKmfLJL>08yZ?7Y^b{o?{!|NT%Jbd89B>p5Z>h)uEc&J06)H- zG^;Vxv3^eK^y7X6ez*k_UB=z1<66XM#xdi6dowqVm2!s3l~gGp*-8sFn>OM^qd3Af z+cXlEK~mbMxqFnm&zz!bzPJY7SFQkeUXQANbUsjbxovL^kC7}?-|L!JkIoxaQDwyK zyc^ap)*5Bwl@;)nv}(~O`~Y}uTFdH?#MqT_rooax4ousJ9NBZ|tM8F^eVvxhwAJ#`O zUAR%2)ESQ#MsSr+ht{?qRlqi-ulxu<1remT%prvztF;^_ICEC;ANnb;tayIxETjrMPn?X`A1&6j|^XCXGp15$Wq$sd}h8~RNwzE2E1@t0NY4foP*Uaho$l>?# zwcXI=qZ#=2JWWtOSO@iFe2aT_Uv!Sxkz*LGun|z~rj{3(tPl?`WFt0>%QHbSZafLA zjm53kIB1WX@na7K7QBD>^klVWQ_I*NdcWH)4(3B%sGoOV%o-0vL`aRB_)(w1XVSpD zqh$_0Y(ST%1s=_^^SuO^N3^%Z6__q|l9$HR6S$9T$+(+{hYg%M^9GZt|{(Z5Gk>z7+MmeZ~28b4kOH_Mhhw#Mq=}Jm#U8>iX zO}FKTdk`rnq5NqrY88X5`ut@6O`{Oh&wXG%sPcKmj+L^yV1d5>}_y!b}OZ!pLB zxC-cqSWgu>_=JS0j?qm>xFJyJ2fgwIn4qC0*`_QEZI*fA+Z)teN~H+tqS)|C(A zzc+c{`E>#*cSf91BDCThl;|!-h^{II=2bMtWWDx|%<_Hl@0I>ilh9p4tA7lCrXHqc z+~fVz?3?mGB~v=1S$(6u0wehhwOLp?|KgnEf~l_}ad31pDAn z3r%@R@K^;Kg^ZqB#t61X#phYWT@!QgW1a0^GChJDjZE8k4lTW3%yD5AWJtB?b(F-L zMKNGBnN*um`nUv8c_FJVYJ@pt-?V}mui`UElNOw1N(V*_BSg}0=IgL!FR*}VdPu~? zfQz21`B+)q?Q8{use76Q7@It2wO6iKqi&uwo0dv6qh~Rx;$!OrS#`k#oc2xutA1($ z&ViPoS*`ze$q)I(^Esw}Ux%l|jd?Mwyjj75g?Aqm>#FF=m*Y(4KNp*7!Npzgo1+QR zsqDeqo1&O`uv!~@=UZW)`GjeU#f^PJ3OuMl>O!{TX(TD+W43Dbx#OdPboEX0a2=V^ zjDIJ2c~{7k{|PG6s%~3Nnn$^3ky}8ik(D;kBWC7A*P=EZrk79krz0#2QKXnRy*xTF zzQR&n!^JUlE$(?sRFqwH_lD1&E_iW^i;W^9Gn>_dJLE7Do0;yi|Co53Y565_7vQ_; z!C3aWF{64@N9W(J77AzU1xCj(PD?=pn}jWX@T58X{4|!hNLYrsG9Wc~$% zhUljJSUe(2$Dw9uf-!^p<5l!p2+nGfYEMuY4?al0RhXw!8gxh}&cQ2}Yivnu%FR1q z(WqCdCD+2-L^8-czk|qDd$KeY0&3O0*6W->?sbn&mz(NS#58tS@H$u8q?24^OktX2U@k8ljF36+GraMN>a!S6uFg;t z>8uK1LN6>d*3_O0H%*RmBn)U$DvwZ~j@CG55z=+ZvYTxL4O3CirlmeTIgInXZW0BMD{zBa|}} zX}i1?PHV_PCD`^JR?i4i59b&J)hJa;>81W@&>P&8{cO>rSc>KopMcO->Ljf0B9-nl zeUEiknYl(>f&KdZq2t$Y`qKe|L1osMUz!9@fgzs+*WklngtMZTpq0Smxzuh%Nu%Vy zAEsOy1yK-!C4*9TGVE6~ACtN)L`$)57A@uLZG| z2C{BvE@>3gpq0^bsc;&ASCM+WjIRy%BX3=5#@CQeqFy-~o%{5bFgGv>%Y?c`gJrIH z*6>SE@>$PuIc>xfCOdCt-^(O+7!6BV767Z zjf6edy>^N;#^FZ8GK0*}6+Vv}zyJ!NQ(nbd~bwe+AvEen#tYYu9x z!pf>NmUeWRR;F0)#(RS+7o~OqLK><>Ele7|U9F^~-ew<{2>!6v)G>N?{ul4(v+TC} zR=QTf`@6&hRV7CtpanWThMl=;ca!I zf-Y-fR)mJaA}o~SjMq!(W$;+^W z>~RIwq|48ra_0&8`3nV-`Lc3iW({=>l#Y9k-d}HCGG7q6c+13-==^M#*ZaH7^WAWX zguWCx(lL;YXvg`J)O*rGs2`r;-i<|)A5SC7p_H2@Gq$PYOZ%32niwhy_UCT-LU@I^ zRiz_aqCB8;kZa-QI6OhP2Wz(D0XrlYonk5Ek-r54VTEK;Mb&5L)B zR*?W=$3qfn;1KKSu8dSSpauOaS$XB}nYO4_^}w+RfbN`jU7Z+v%DQ(wo}N?s-Qe)@ ziqBSi^_!?olY{phCcVHr%$c@jn&GLW@?g#d18}l>d_#S1!{UI#F~}OUEfAD2jY<2* z6o`}UiD!K81iTx{is31M&kcB5%p=`hzRz^(+UNov`ppsp?`Y^;K>uH3!5-1zj=0C$ zAmxx{bod>a3w;{Cm1B(2FpPSMC{s*#UzlP=7ENb`_($D(a^ zBw$@+O;=m=1q;U^rgTqX$<+8ZYfXth-@qh|^qMZ;`}NLrGE3PFOmHv?Fjm>GuybWm zO)Zo)*{s%AgCH_ZAWgAX5)1YAq`upqU+`c2sXGQ$_;+&pG9K$a?LJ()4 zA^D`vlf&IztaJZq+5h|6>8#TG-(`6V@HVJ!T`zHguZdHSL9wHER*b}uglI}C$6=`h=4CDQUsjxNgRFVE#wBrU zeuX=|+A=nUcHC}mbK(%L%pKmli?dNgDjth`O&`yz&M&C3pFtJYVwZTry* zMoD>Z=TCMIR~*z->E)A+6$nUgb9$->H(`0qd~e=arBi1|697#m%C)*LU{v5ZBWeuH z$a7MY{q;rekEJJtyjQt3-mvk)ZsRLAqWv!`t9dXN{*jupkHuunS5^rs#1m3f3V=7E z*R6Xz-33?nP`GiW89PhZB;maD@6Kx7zxAJkly~89_5LgrQ6JLdQk)e|pZ+_nob9whhO^W!O za%SlrXe4R`zY}nmAy~suH?z)N_}%m_A}$N<4QZ)ti(yL0x}uTP!P%w#DSa^g*pG!< zF4c|CPEzkr7)+(SYD(aH$QiUOiqy-k83>OI^d^Le6_e?VVbxyQjdmkqmU=+Wm_Kd- z`)5a03kO?im61nyg)U5Pq1WsBJ3$E^_{IE{xs%dwvvkgKk-Jd*<3(c8x2lb*f{{E{ zh_5-kk!!B0;O_#``gWMzB>)}-o)0iB}0ghaKqe99s>rRu=!*A-o9ewjn! zBEqUbHA2t8jY0h^1p}5D12>5=8FAW!FunQLbZ1t1I`?c%Wl%_~EgLq!bCi@r5&GZ> zy&fUlgCfa`pQK|LVFf9PD4zj}%z?A*Gv%+}LP5&mpB`wvYQ=csFs9^O^qNS%1~`)2 zp8w`(q~FSl4sG>`Czb@n@$Go(unv9sJv5;6CB`P3aOivP>tn&Y%bvBM;1DrOabiPeNRRnw*T*@OYP7Ya9PTNGKl>U} z$uH{4c>L9L8prFE(HNhliVhhOZ-0#r`n|E^e@`=dVSwIJTij5NFqO zpx{c4|E~Jp>4OP?G#86|31QEOt(q%n`Kj~38st)lHy zT!+c}MH=FiNbbFA76gVBo8u5i;&@M-^6_rD3fLKu^oT>z-H;!u*|X8XWABNc$Q49a z0D--lsBmSq235uElp#oq81c5@v8QU`RNnpYwbE!c1cD%*lNa7-e)InlW?CzXntN3< z3z_V(GHr2_5_uIEu#q^-Bfk1)nf_`q2HTYqnah0&S+a7b8A+^p>hf0XrwMT&@!47Ig2EEDt9i#)pN3)|uQ( zN9E=C3|yT!@fG;p?h!@w<&)tR;94~FPCtbld@K~fn`>QSW`;i{CpBwQT4ZkPz098= zB^H=0yu%ltgQt!-^CJTz)qacHn;%F@kqqV{X+`Ac@e~s{LRr>YtW4>wz!Dk8z|9Xw z!g4^_>T}|6^l&lH|NE!PqxO`}lr5;3PD>|K0>BF)a!6gF1$UsqoSAJpNu4u62z1XS z);0QP&0^BipHVxGe}HI=W~DfWDrJ}#rb~=)Ky?<<<)lk-Fr;2N`AcnyVz^Igr>R55 zr@%OHNtZOUn-HdeCcy`HeZ(7fVnu#S5OfJ2@ss{axSa5VgH+^kp&>_ND=IS$xUcsS z@cF4$I=P0Rw9kGY)2QtSk0$VW*ktZLX6Cn<-xMv*+E8wwc!QjDjgs~o*%qyI{h7ve z8ATTD(bHaBqlD=_x}ttLcoJeh_62ea`aG0_z#Om?FTz{q~_^XJ(g%2qI>b%jSwH)JN})=cy3O^a)j z9$5W~%+G25;_1)y2HS|JQ-ZY`+Cm=l3q?RPOXxo1LE}V952KvESl*(QwID%*URT13LS5cw(zSosfqgg( zevm-A)Uc?H1g~O*{}ag5@)%@sO3ziICl^E*VL10TXi-wjMJJ!PK+FyWLYMl^^7lIT z4=u(eZirSw%Z20B|wpVn}h|CStq zbTp$2v_sU7%O)ZFs4Ky9s+dAFceU!^5Pw%AOBR{wQIB2l`fG{a3X}yRr!4c*L zNs*?7HH1Mg9(L*ZIxqy~TXlBN*>n_A-%sYC7dEpJzqR2!L52fxI5-gKCVw@{VY-iN z@uL=2jwUg{=;yU>dbvSA5P<(5O=rOtRk*fox;v!1hZ;Z{>Fyf3Te^{uMR#{g$AGjn zNOyND-5?++Ao|VT`+I-FtYaPXJnOp8>%1AXxW{z@?JbBfQHJz$5dtazWO zqksWF+A5~MoGD(I28bMY3a)I%UF?V64^5BA_g7i4Y!o3ngC=%@G9W9G zD>xe&XLb3wFJd6j8t;b1sL0Y2>*-{|Y+9-XKO~jwT|SDOzzYomkrE#@DrX@Nl~QJ? z3>hd#8bxH^9qF4-#axf1J|)d+aG?tF&r!4 z74o9y_s(wXN!psBt!<-(p~Z&w15X=hxr!4~*Sq>rN;`3<<)a>aBgHR&rL%YYJL(T@ z4&}%C_%K|tC$vh`qCtIFFRq~?VaPuvr-;fS^+IMMOrxd{d}l%TQCoazSM#; z-s>f4uY)dUUo^urP21M>$FHh!M-VvEaK`#Cb(mqH!VnQuSr*QUfSQkHz|2z3zjlh2 z#5XQUyEaHdABhT`EAXOzg^XB#&HD1nw_kQ&M8wBvpmoxVf?ufbax(DcX_H?hZ;jn@ zFXsC6^pJ$R_s8DYr!ey|lQdVzMvd~|wfckRP(Q@-P&XR|u^u~NpTP1v)O(AHjH@;* zC{xrz5;Sbo$YFpz`n-9;3s_EbVrE5`*wmzJVT^n$<5 zh8^nYj5dG>Q7{~=XpoG+RT%`^&U}6g8k;2zqHEZRV^Pd90lv`=7oP=m1HFF`n^d%;U?{{)QcVEt|m?24j zPIWOvdaJT;Qtg6iK8tHGh&P1tugD}_k4a}7Z$sHM#n!#ciZ4~GMx=jbK_|&eN61TE z1-*!(gy(sc@9T^>z^Po|>U5(u`^hW$dY34X_}CtcxA|Vy;;VB+F>S(R^5UkWEDX;4 zRV!%r?vwhS_Fhk+jM!2m=8LK-jYo%pp0;of8J9Au(|oQ-rqP<|Jr zCXsUwU^0emPhm-$q&1K-ny*I)C~Kc()2k>78UL`U+N_jd?BkJGQ>+P#vyBR` z8=>TenTHDSO%8bXEj+DX|6f+X!TZ;p!YJ*NMCIwYOS6qhG@V$3v$rPFcd5^7$eqI# z?Kx_IdS6~xV1sOZ8d3EPOeG2v)oR$%HATD#E?~N6z8u>@KRp zK}_n#Ll(U2`l*OEwS1H=UD>f;)8}OWn|e0)G`>9F((GO(oqpKAJpGLX`>54g{q=F? z5wi0arO?B;YUqtfh9kFC)Azh78LoZjRp9LBkJHl!eRFc#)l-Auj*ll>H^GfX2}xrZ zgc0L8qv-vmGCy?|!9#`W?+p5w%EQEu(c98c#peR3h> zL;;%IS(t+Rvtd6Qp;Y6R7H36OS3c>V!uR05{cqQ;Rt$3@+>$f{1Q?Y94kN!lum-8M ze{FaJg1L>Vqyo#MIlvgItdra1QHzb<;(vXbB?97oqS`|+oZfkIp1CCX0G`h87Ru4L zx(P0PNbA;8#mtm;42s9_ZyI8%;yl!AfgfrJ+w^}I3ZF!&(44ZPrU~AkuZO4*V#*j= z6VrMcGcbM1pp^`F7OG;!mMkm}GsUO+O;s?6N?(w6ADq`NzZSF9G;%a}LxEYpFi^nX z^^?wiO`!B(Acz@WAMI$x2Usxrsuw`Ih9=MOGWsP<%Va;u97jG@^ATK+4jXBmSctv+ z{M?DZQy{m^U|LmL`E_E?YFWIezd48OsYR9+a~a!1||S(7|PSFUtmk zX8O1NzyqTW`-}&9WiQy}s&NL-)E;udF=ph+TcT94$WwS^?XK(WB^NbBBCOZ|Hfd^P zM-T4uHH0sVBmu9^f5Pgb5YzH1?iSLub&7^yVz#8jb0#360PfVfU)0vhwF?tezs1OT zMqB>SVi5f3GBCxUeGnjZ{mzDV6wc*CmL`AfX%iilTIl=JK>!T7+7Cz#2ZvG~(_Tht zJqtmg2#etDl=hE*y(PT+k`RAfYlchhnWj_9p6i(K+|qVzVK~GynVOWaPED9)z1BBD zMtxrsTd^mK06X++L1><+dd+r>>t^x0`DV~Gvug`ibqs#l6$*3`2`~5<^mkA|<|K3J zZ|i7Gk`ZYPW-YDE!W6T}XDQyj1uPGf$i5f3A0{l8jSSl6e57HxkDG&d8p>UDw)npN zLfK%&0ah7(ei$gnySxt$yA84>Rf2FqtjQw}wQQY$(55iuA=-}|VU8K>p#zD$eBh`s z0e>>mT85vyfnJuE*Uoc^r)D1>Yj7q0PMfV^9q1@An8`(aU(BYCBUIRo4ka<_>%wi< zsCJF{cv;o%?J(3Q>lhA;>H)ahV zE)#7G82|n)-;HEznNkeyp})IT6w9XTIW{*lxcU8a(8uArkeF})te&-*-#c_rQ;Z|l z&;+s+i)=v|VsHU|KE_tx1g)c-oiprzh4_=&DXgx#YTep02jFfI$Xw$fmZ{*MlMk_0kwDr`V@)+H8n2U#}dPzT!?_O=R z9pT~2Wo^#0#!m3zEeaU|Y<1V~FyBjOH zM_}zaO51Rhk$_jjBem%6@2bA~4K+!$#-5PVkE@uGd-ol7-9I_fsC$_OF? z@}0t+gT1v)KY8mN{uNlmw@U5!n|>3uU8DMyx3MdKlmy?iJ!nfc6W3eW*%Uf^3`j8) zMebFbkoKtheUMksG5a0rp@eGhZk-@doxl3Y47puqVO zd+=QilN(8~%rxhAWEeLfxSFjHy>0xgfnCF9_0!-hMOoTk4a3&HIPYG~S%w$e8k;+3 z6J2p<%rZT*&qnx~Eq`4^$SSJW9VXY-6(b7rPz1>5&?0O5u}(A zrTy1-i}e^)G}=v$TtCVxYi83&WkS-M(!?EHa)3~JCyI`3Sb=gtblkBZqRy!BeqWxd z*AUp(qc_$S-A9Xnl+!0QYi?cHNDl|g1R{f8jvd%r#6#W-RIqr$}hp=_pRyE=CWtP}GrF0r{H?vpe-1CPx~{h7MKWlYp;`+1aFRxZhg z?^uuwAIDUv27`F@WFb#dZGZtJ6bkb2<0aK=vD5-kusr2rMYSR5q?`n%UIh%H~fVIHyy#A1lj$_NKVG`$;LD8|79=?j6;6})dg7Snf8eMw?LQ1K z&AYpH$_i-+-3eO49)`p?zRBZZ=Q$?S`3Iq*7PH=puBd?AOJ*^qi~}E8DaBuT#W;0h zD>NC?n=m@Qax}5=KDAMDc==ZYVi%b&B1*Jmtt7B(u*|G+@jVKkVQlEkbylmXiX8wc zJ(IXDzNzQhELxI|Am|CG5#&BG&qoG+;WI4BsibeqRTa%@3+C9P>xf2---!u}d)KpM}Mq7BJCR1IbgVuqn08{ONu0c9^UM#Ol6RE{Las>pSE{oHeAaB z7Ua;A#?=&X!HtSRu!g2}tH>(?Xh~Bp1)4DUv6lOc@qHI4u`X@8VDJ83yg2_pY$9C{ z@p?-^adccq2C+Tb(ywM7vD-m9Jm?`8sE<=xNr(}eIL6ya-Vn;`;Hhs1P-komEG5y* zGV3-em#yq8%N#9ZuCnnH5Pk{7B^nM1>%%8V@$6kBh78;e7JCoyCD=LjJ4q1Rn8}lX zFj0K;tYYF(%S1l^)PW@il%hME1RgsJoiSyuNh8E#YoquI=7@^qFj83w4X0VSmT^eP zZ#zSIfRut%a1O$Pl zHfh-4h3TPpyvX4%pbNVCnSoej-fM-@A2g-grsPr(vO8EXsbdYPNUbN$nUtKm#NsiO zb!33|n;H$$hEy80TB}}=U#Gopp1lc;kuQ0is)u{ewXz9;V4ytJ@bV+NaSi_Cv4vo1 zcj9LM2%MfZxGx7tD{?vM+-LP1=|mLD*69Yt8fPa&c5`l4ryxXkFI)1!e)1^!6;d4q z(z8l3kr+;;Zdk%?=j7bG*JVU`?*ZWgw3MmOGRQTgaECu4Gk=fc9qQ=pmy(%LCP2|7 z=%y;VXh~b-f7Y-^415OrT4ca_yV!gCV6b|micLrMPfMWq|H6X2xGAbk`ePO!GnIuQ zyxFw%IsXUnaD5@c(9JU!nLOL*{o4e|m{=Li0MVCpOeP&)S#7b)AyC|uE2=uBwT0MFofbSnFWr_Dw&SJp^qAou-Y zJdhb)Jw~=*Ctz-ZKGs~s)IcV#1^*cxrBrYdRt-wN>HBxfZ4Nv{5iW#czw<_UmQ=a@ zF+Rlk+5EWfbR7ZWjQIJ&uD1?hWz0tp<0J`;;>qg)LAz2RxpGNrBPJB~7Cxd={}<(L zQpug^>FkqIYG%P3neRaS3VITE%Vf&|JnJW5bDvOGs}*_p*4r2+klUrA1$y*!kZLj?QMn4^AMpJ%v+}D z*$W~c=I(nwj&Jx{m~ir&=6|%m z_qaCxj-#gbfUaY>Ve~g&xkCYpKcevhFajUjoITEpSo{?|Z5Z)o4 z;vnzF&a4fpz&U(vxGbPRZ@6Lgo#k&g2jv=`8<#!9W8H_7{{d)5M-y~DwqAR_ytv4A_F1)8xy!+xj zhlSP<&iAF;9r~pu*yYeoqv@#U2h*Tw^3- zc%T)UxB3A|yK$7c)p!im9+cIPYi7;0jpRW|P>)c&boMe|3Q3CLx>RPrLTSmCNf;9^ zaY*?H_U80WO<{T)>%o2+4Z~(w>1A2zL{TqDqCTFTvQ4#sydX~7nU^F#KU+UyiyrN} zTSn%;O^7hz-&`4KpC~&ew?6idXVO#K3AwGE7uf)F$2`R3hn@GE(@mko>C0qMOZZ*3 z>_>I|@u$_WKNsj83|-SjQ}z5JKNLcB12E)MGGJwZ*XNlvuEemO|8f>pEbOx0n*;rI z72R;g^lZzq|@}#W(S}|HbAJCgv-QOZVaNMsR)aB27JW1w#$m&^T9i`RigE$~xM z1#FU1M8jRkUHaIl+~O%W$?3L?pE~N_LX(_!gzAOSLblfYGKybiV4ALwL9`qtFY)k+(@cQn9De39;JaOVA`;Q_zPH^gPw56fH}8=*lFZ%^{I9 zC>cy^O)Hc&XN!h265}H1U!J18a^3#+w%C$Mz*fiuawk_o-#Yr!!@E8ZeCco?ww9=q z#hnA0;F;W^!3mDNuKJPj!774-c;U*~t+1d-o|RVN+jdD<+a!AC;kWSLn9nPduyZIw zgy)9dqON~od#EGoKZStD=3@XFKpI~oxzNX*>8K|N%hAVX!L{RK84!!6+EMEO+u=7}b`Pp#c5P zW8}!kbbO54BqmR^N{9@NS95LHXGyW%eVbI%(A`=T+9fPrHN@sD0I2bEnPRq_D^|Og zmF)0zX&LOy-@^KJlJGTSV&L58@&SBY42L*UkbTPkM3xozB$9T>tp}dugtZNTTHKD$^?>?nn=Bhs{@rmjbM1;%4)f zAr}vCli{H8O)G_GC{Qi=kr!hFEXhcO1Q#qOx8EVAt-5Vvh3Skfoft>s;!qB!9CaP_ zR-=#~h3p_bp=9{!!L_lRm7jQ^B6L9@7Zkr7`=e5sxitMxR9K8@;Y}>_n7q7&+SIqi zD-oTt->b&Yc93Fk)K0LjigqM$9mjZ@A>~{`W&SpcXH~Oi8(^XOJo$-H^F|Kk&&?2WM8xfNlih{t0V#nvsSg^k_C4G4-l0 zg_@VWwCI)L*IOlyU65u-V>x{$U2Hf{i)|)Z(M35Fn6MY3K^Z7E!I%I3gWo^RbqY+K zy)qpx<-ZCmKo85FaM?b29v+mVlyZ^2U%>z$V$!3^)NqkUG0m#eXJFm<Gs#!w1x*%zx?Ckp z_JjF1zP=1~Um=wm2$j4p!I}bFGMk+9BN9$|uj$7&qfoo5@1TyJ!-sbzgF9L+qEc(W z>qLag4%n^|FLsp9d?}NJJL}5WE)&`0n8-jSlR%rpt@r$Ol6 zJ@=I>e6u9AHs`k{E>w-AO1FQK|v0IaPr4IAwzZx z`pX!gb-1Qe7tz7ly%3NH-@PTn-9iC%G8xRc_ez zUvTYSVwflf!cuEbFo-HtN@#QL?~PStVL~0bixm#l^;DPr00o|Va6h?aT?XK&PN2+y zG?~{}{C}QCq_9@@;F5rieAtUi;lyKf&yt{WpYB6V1Q&4BajJ)YdtMMVY(`J~P zqjM~jfW|Jx|7RAjI1CH=LZlJcwZQ78Yr zIY+KE`1;`6y2?t>srkNvjRR0CoR*XVX?m>=c55xYh1s4)= zXDstJ3S#!0icU@7Hj+3NCen7){rGvkkiBk_{qwcacTaTKo^{E@finvZXn$eg!J=Zux zJgN>OLThb+dOcFWyLm&el~uULcstjGoo6Yg(~hud+m>WvKm{8OK`NqEIm?thB3G9z zbJoJ2xZd~+LPCexdE8}m?1}6s2XvxQtL_6=6%`@5F{tc@K&$!&^2W)&g z>a(&})JjHK|2V#&^5)92)AtZ;iu5tcL$ox7%mwa`tw@WcNuE)Mbihe+HVCezJ_bkE z5O>sz%HBXp8u&q8QgW+ zHe~YKjktvx{@vN zeCVZv*YI@@Cf6WEySr^hn;82Qp?sOfE@O6Q<+km-0)(-P85HP3XSz0GPF>a~zUAX( z^Hb~Aj}GSOVt?g9AeEPs&J1hHjc(Es42$RUwc;|X-~Xwymy{t&F)<|Vu8W3oqYEO% zoxG*}I6U4_J&I@`Ad_^DvLa%c5XY-Nl4=*62s6M)i2a*hYA*`5H%}q(1+hprCYZcOcm-KJH;VLGfRVmblBugW7xD`Ob_b z9z`=h$UgRYHP{V%_`9#eP|Ks03Ny9x7WzAp=W%Q>qIzI*(y1Wd&no zq{=?T-5S-Kb4y}QonBO(j)6a>Zp1Cn?Jw*FD#a>QH|?1$4727-0JbUsn6go&gX&N(d+ zAZ4J{IA>mEuu&3{Q`nAimSJP1(FxB_=Jco^!R)lt{yEPGmA@}G4X_?0L)4G9T}Pxb7j7ynZxz>mbAHu_<3$4)Uk?dnMFqmn;)0g zIo75prClS&3a@$$#sXr`OweH~-**&aaZ|u?$VV(zpi?x7&kEdjb@+>YV8t&>b3?1?uJ zoY|O|`1I#|M*M$2wi5@Y2-By3Ro<~xoG)4N^QK(b;1>zB7W-OckmM!ifZ=z&F~W<{ z>(~+#MVb{o`(Tq3E`_9v#I7C}IIz`omK8c%0o#vgo|=Rt{h21=H}Zv-=C~^c1cGke z(dewB7A%2I&> z7iGC1rT5-;AIQM_F-dEuMF4ZsX+e;UJDt82>vo8}72ktxA$pZG>3S5ag~sW8eaFpC z=Ng@!RBaqjM>`#yCbNUrn+sNqr+)Jb9TE(M{OQFRCGLz8lGZ1>c#PU@Q0c=yxCv1k zXecIT8yES`WGv93Qqt$PlgC1~R)U;w*er7sF?9$+5oZ6gPTdpfp%?p!XOc@mB#$E= z9Lf)0@~N!dJsVV$Ef-n(4eTdFRI(AmVHwmQnkydnog^nu5iDn6-)cuMGI?ZkY+b5i zDpVLh%gTuJ!i6$)E=AuJ{u2E~1pgmBz(nm(uUs7s+ozT=CA&U!YFP(2^dBD%WXJi6 zsG{c;XT_0c@Elz4sM%SXDWZg=pD9!?mQG47NuD9340R;W65>G2EJs@gVd*Y)2^T6s zjy|zVhDGgrZz7k0+{F}!@X+|cC)2VD_v@(|^z&4e`iNYtW|Mx7gM#b7WsblBnaYkG zpNEABHIyNT4<87z%WHQ32=D>78NaL065;cP28vzXT=F*yboK=j#WM{GH^apF!zvnox$vggB$7eaHvn*x+T>n0bT*Q~kFh;toqfh$rJ@tio2Kq?`aY;yf&u2p4*) z1sl2fe(jnL73q*LzEL*JMcNAf?GNe_rDkKUsPy3FAy;{n9@W@W%4)}lzskk=dZBKx zdFl`3dg_Ipoo~R!)i1wx!Pim?WV;jBOgpsc^3ony5#Iw0^I?f5tV|k-4%&b|z(w8K zTGr{UhW8s-8}>qF-T(=w{{w7^Ai08SE!2eQy4CM^AE?Id;e zWj}8XiHGv@>(CGHy+2zrpAPbyH^!UQG?-ELCv~<8RSS;_Qt3F7_ zs=}Qn34LFU$08y|NT=gU=5t1~dM5EsdrR%klBvVp9kk})s9)ujk_-l^Sgt&j$`(2m zGtc}h?KmS8LC=4YG=fY;vwn7LCUYb%pPH<MkQWrWj zE*vL{hQyo>FP)1uIt=RYzn7kHmFYr!OYOMxutNJiCRZX=!)a#$7hQGwDi)r`Ouy%l zAn0vth0Q?Bwcyu}7n#{bn16877(&Wl6B9o0Kt-xb`LiJnQ7OmO`_V^fmdp1RZ`s!y zi*!~!!LV(PZs??7T=`x`EO%{AdsgKkxTk(DOqt$?^PZALu;h>fFF38H*hiR)66MG; zC30aH41<0eElK`kK5A)&BFeMJ*Dok#|NWsWbaJVMTH#ZB-SRD1dTdFPKOHK{3;7=A zVSDq5-!It^k}eTiJ(&i5i={_Z$TBG+mJUt>&?2EcyHB=L#8h2u=TITk@TtwJgl($| zB>!1+WtmAT`X4Qfa#m>L==i@GuYW<*E~Zr9Vr=SDe3rJ!-ve{CVB}od;naLsUVlqzw^by8 za9UAQE-5R6_n3U+i8mC6yoDc)N!*+1t3LdyvT^k#WO^d&#MAz`I{`nzU+|ZLs=IZ! z`?Qp+vxufvp}!F8b?YY$#>Z$Q>oWZJ3^b1ZrdrNbBmnfNebcQw}LC707HTn zSn`%zdIyflf?{pVs$PAl&PNQl-6+-quD+c@b)|n!hWvQ1!2hoJBn`o~9x>toy5wYx zqYz)kzz%mJDx#QF8cfc9b>JM8&SlI^z0iBR$)3F30iVs#+GA&yY}7F({EIsurT9Xt zP_UK21O+P(74h!3ek0uxgla-BN=jw$biAro&O&`e8<)dpsQ7xDwW5R=q&n~wK#xF* zA99EG=1hZP#{CTNGw2YRzQPohW({Pxs-!%BQGL!r}uFGFi!m|2eh~8@TR_}V!oL}K;9rr z8j@KQ2kcPZ1~`?SqV?)VDngn7C=ql}XW+O4Q~?@K8QQ=$8{pIi$60yRSt3D|>Fc0& znh|7^&C0c&mK@{@Pdji-E=1%f>>W)Ru7*=JSC>{CSb^wy+}G3Q#lBTm=aM2?xza8i zI8yHyr|}|-zO7v>k{0yq&q|oA?{ZheioqXs!xAR9%1f3S`r846P3%29QM=zlhITjhGSJUJT?Dxj4VD#x< zN%comk`{dp4B;u4tD?>PIwwcvAL>`!2T^#=UI(fjOn;vg0~8XQ?cWqkpsjN>xfKYK%04k`tUXep+S9H#uu$mD*oy2M9n<#dYxV6zYbK zZdhM|p|+C`JMww_+gp3oZe{4h))B~AmDp&WwiOr1m4>E_ZER)b5qW33;g<54J96o^ zmVs|ljguni1atCSwl>y|VS^IFWN}a5VCo@Fn{E$d-`Yu6UuPqL2_pC(LY$}&G;L#G z!k-|F_THajlC7px=ZhJsoMY=*h?XPqcV4uU{$f|sln5;tGh_zw9-Q~ys-ZK+vv0sc zg!8f`&S|sE1x@YUL`6)a@+?M)$;U-vf)Z_H@MIdy*F)M9I`CQ<(MrapSASegRDbr^G3?NBXs$qvHATQv z2ED7{g<7JA(--a)AEFqDtQ0htVqH`k!Uk_JT@?_{KFN}9-C(5CnnYDIu80#+Oe==1?rlZ(!%h)e?N8* zUevaYr`NK`aJ4T1}FIU zZXXay(2;V&Ks0HZJCpZNL;Fsx9G5}%meT4u1RHm!xd(+m_n9o00t4x**;TYxK*lc_ zWN!_3IJw0|7h94N|M${JfOV&~peS^EOZGo&-&^rK1-?+i}+r0~R@uMWa&M%^i8UH!C7z;$OVL*&j(0NeKyjjO5%`vnNcvTRUoA6YGNPqY^!AWxduGAk zjRyLsLSQ1iICWB|x4H_3M#xh&^%7Wcta@R$8zkn*QQ_Ay*9S1CrMkVVD`ifi_6MK~ zLfJB*1LlQF(Gx?l_-f?Ct%MY_M|idxjc`yzz`UGZP1+^GhI`s0l%1)IHZR6zd>UVj zqMX7!yuHN)OJ8Qpd-%z*hPGA3Qt~|f2D2X3F|OeT1Kb_4DKY23=tLIJi%x3)QI3`Xn z<9ycxQs2xQV^aAfh<>4_!BuDv#AA*`7t%qm8ow9)6d!irv=Uu;jp*6EM9#Av1;G0{wy?L zxf1?gRv>Iq-6Ub@4s?OCIg#GCrVe&~(D?z2$)(*1!~(w&Vu%tU84JZb;7KpE$j|O{(p^JLdpMmH65nJHvf0`h4Mm` z+bN?p)&oA&>`nTBI~bNe!HU?mQl9J_MhfGqzeUY*1J7eU{P%6C6i2K(FD4Po9z{gf zbbh@6{%O6kmRguf1p=T1I2hQ;Ik5dbLjJiMB1jj-G?E+gE=b|u{x(r}gSv@*Z{XaK z>adUDkWi+qY;nTZ?c+4TM#6PA;2Rq~#JMuT8UC+Y1Rb}4Zv$3?ewb8C$#KWI($n&bqXP}s6YD^e z^YRNEIEg9qvdT@E>ULPS?axD?Lh~pV)R+&%ojZ^WU-P>%4@5FkR#hLf z=QNpBs}`X)hE!;oj#{L5(;2Owg-W*yRE1#dC2FM4CVk2s!THDLt8AY;(0B_P@blz& z-`;PnrI&E!iS&xa!0zVLpPd~HV}p+u&B6m%ZBJccau*e~TUOF;g6PlLgWKDH$Tg2^ zl~n8_iPwN3gC>cXo)}W`vclKpUEJ?MVW{6PbIUWx3N(NMj?HjMFtI#{^!-BZ?_)wy z7JF{YbX-jZz3+f6iS2?vU5|7P5V-lGy2N-Bn@|+)Tzf>)qdD0+Z`Ho1EQnWm11?eW z<8pA5!ni>{aqMwO*`6v~#jrDyMhJFME|NlegdHy>A592E-$?5bo zb6SBX6Ju3%Py(!j6Q45Oa9$hIPXaR=y0)bA_!#xEOYhUe=vb%b77q`aIflSRI>_KO ztF=?1(kZ!*uv6c5dnK63PWP^s)59w54%jsG;#H`T4UG_q`qCI}Af%j5N3?FXcHw1L z-^W3)TP$+_g|&ctY8i0tLLsvC={a=O$+gDqxo%KeVIcXUMU2)5C-Cd7h`9by`(Cx> z5MRwaCvLu~E^g)OXa3f}#LX>i+@u8~eC`stVrrL`yPCzPK)aPj&2+}_q&c>QKq*_l zINTK%PD%B*J8cCtXelnrWD1j9nUi>hd>~HcE!+XEnmY0)jXgkbT+!O~ai41C9WSb) z$VD7pG+RKUchVxfN;@aycC1S;vc}qi+T;j@+LsgbH*C6=BqFmpYwY)vHpnxQym|Zv!LsE!kLqCbo+bt+XSk;ybCCVu@_iHdB};+g4Bue;L~(> z7RUl7Iy7iLt(mO8wva|~#KW{>h>j1;Xm| z7Gf?OWc>C1 zocQdkA|F7jlcw=Hxy%i z2q~GiPn;*i$WGmJ$|Rn5IDeL9!6tbpHq||}>iapi0XL`dagKQBuo8E<9I>xw$|A(z8eE=NU;iSWKj zQ~;t!zq_HnyQeA)!>5y_<}m|~Dqz5SYALlkT{$K#5`edQW6M{!HWO-QUdn%tJU-_2 zJ>O@@ASJ^V&-pV_9S8LB54@Kc3b?>JMZ|$6=;Qq2lY&(CVNG(oa~847Xpv>!gxZ$zrLqi zkxCHm$>ar@ROgkAZ?$6`@Dej>7vlX9n;5fhNKc3-G>~~Jb4)->OI4Pe*pvUDj~y+U zfh6_(Cvw=J{56vjt26_3*T%A=c^po$ohS$7Jq4;UlOjNWq>|M zk_Z?UP;Bsn1#!JyJ&pQ1$KJEY`P!pM3$qI|bx(acWug137$WOSWa=v;I$5kOqP)+D zJt8P3tiqAxG2>_JA@z5*%R8__We(Vha}kTYl@lZ#iiA)}Ptedg<11L5`??5Kafo7Q zL0cbNGqEb&Gc=C^Xd9_?JSC-)L9=cPF=r?5m08-C#(pV~x9WgkZ@6hBdX4h-_WFmE z7*~N>Ls~9Y`>nbe(a0`>#YGG^A`^^}N${P_@Z#!uRH_^guDlTph&u-P089p7Uc0@@ zDqi3|FF!B4NKUe-u+_8>&fcg`WD{{>4+XH{;jUyfkRPF*E*F$#TPoP6)qtyJi|3BA z`4yv~KAW`ZPHk)UcNfZUU}o|YOWO9G%?nQgL>=l5k6DI0k1}QCrDD7HP45@87LhCH z;Y+teeI-*6+&*5ir?Jz~04EZ#Z3*1(m?fni+j%%9=}Y!~7G~(Up#nYR6q-m`BE)Q& zwbp>GwXOw-_#ZDmd$-k#EpfjjHiKSGGbplAv628h`G>$qU-sn1p0&3O>h7zR<{d*^ z)z%%;kaMcY-Irl>arAkgM=moek}$t!=z(~lsw-*N=k2m_9D3n6utgG`Hdv1am2?az z^8a(djBhA#KiKK`_ecVg+8D)wc~mql(5#C~L>}b|5$4u;(%86`&BQHviiH1RqiiXr zH20+7#FdHU%uu|ed5*-@_MagJJ=ta<MCI=8z`8kVVt5w!% zzgA1oJ6ALwVp%)`@k;bY!+8rNa?~;3dpX&p9U97-Ec0V}E`^j12zl274^KWN*_QB= z8Tekpl`5ScoxX|LEyTfdIBVmB+C*`}T#Hmp=QFiA;U&{asjGGdLI#(GT`d(3!wdeT zMs%N7{QQZX19jk$MO%wHT9D08b_I0Gdp?^VwPh7+9{WBOaa-2v_zYr() zrdWOBQHR9+Pa$io$Jbs7Jbs;!VA+!z6Tta+%ppzf#I>8t-`>=SXqG=8yhIH%00WO( z->$B%DXFNCL*kZ6ABsUHeo@)TW%&sCT$m_kyjUhIu&g4G^nNnTpYk*trR+4S$u~k} zFelmlGq{eULmoBip*tK;tSS!+vlFeUKshy;B=u9V?hurncy#m-gWO<_YY=4GD+r4hBN2vv!CBaX^_@=(#~#u9BiLzmXySB zvV3D&U*jJ5Ik6+USNIc~*>}`x#In{9nhc++9M!vWyUG)p?wmiEu-}_MR1e4uUN1K3 z%M^c%F6S%?RzbHq~#a5_bUupcV(2z`@BujN9lua`HQ^oKoT17&x*<6iq-3U z!x1ObIDskz$3@!vv$N0XLRDaY!WROooWRarXK$habr!T&6mZ1z!3TYeA;F}3g}F@4 z?PxZxc&VAyc5GkX!CYgPJI?kQ_{45c&E$F%#;4Sp-uF=t1y%q*@+K=5hA=R02xdye zei9J^F+HyJb@#YNXO2lu^@XQ={d?)ugzIs^b4rRso`c+#{w-jceSl~E0q2K6?Vvy5 z&WS^i9F;t3uXG$4^pExK?pxszM4gInF_oLI`!*zGbab@W zj%sgp!R_V9ZN2!arI)mo8&BKp%B!%KI!ck{xyajygD-ETu8qF0E_fj;r-gZ?p#D$} zI6nRnu#Frd`SEw&3NANY(OJOKT^ie)MQ#>1&WCBXzDr`}Jd{7YxUx1EP@^Y&Bhh_CuyR^;ipho)$~Pf+{oCj{Yt3dhJ^PKu^I;2@X=g?{vgv9v}V>xAlRR z`B#i)QkcPm6UqMeU+L9(d31LsW&e~tX_D2LcN|l^Wt@W^k1HiV#SVl$dYb zJkuTM8k&N*ZH$A4i}d&Jkdmh3 zG=pvaS+-B1#7>Rgm+jwh6%6^`_0ZH4|J$?u(;}gQ`={ZhVdl~w<1ZAuH9R()J^#rr zJ~u(JDk`b_@RT9(NQ$wA*Xd7FM(>H^^f;m(4kwF$xeW{1GQotEB_ofpo{c(Ox^rs)B=1=^>HSACL{)3y?d(i@$XqjUoEVp;Ac(SmY2>T96X|(_G zlUK3cz*ll9rXP1s))v$LlZ3_gzMP>A_8xbPp7A-_=$(ii0qX>06;wf=hi)#A%d_{2 z*owb0Q!}0}rh-dtmM2?@7_@fv2`XLA$kFM_AFp9) zne#Vgzdw+Ztb>WxD(cIQtMqYOzh$dS_h_c0tjC<-OjBuL^w&}HhmWT7A|+u-=n>hy z8Y4$KMozH*7`oe`i$6kanI7{yI6D8`{Go2lw@-{VW|T3b-sQ16uOhKWtcKk+=*V(x zEMC0rjoqds#4-q(a;>h)7hYdDADY!}JXyVQGxzX%86yKblW%*xwstMd)6~sWuw+8n zhnRmLfqzq2b2JCtd6W7@0`sQmR&INAfq&yL zK69bWIkv^Dd7FV}3-KReL$E~CQvJhzq5Pn!{l^?%YYOKeg61-iWa8M|xKE4{Yt$~( zK%4#R*l-Wb?y%lJ@j~qO>+;KZQrC)@dZnlJZChLe%=72{mPWx?(~)vRLPKiU`~j*TRgI^m~==3#@eoBc}-ABZAERePdaQi7U0N=awVP%89XJAewGyVD+tN= z(~KTZyjko2YH5I}>=&S>&3F4ghAnv<$-sX8TAhgVI~ap4v1z|nNr(jx5l4G+lM|u* zl~W+-*q&(2|Hpcpo+ttSfU;8Q7n#UuM^bkZqE`MX&l_W-+qy6=Gr&gh^IT;U^5a#l zQPX+OybUXz$R>=`c4I&v5SV?OiIZKf0EPuF5#*a+nqxQClO)fb3i`Q`&Hie^-e%$k z5k);}!u9mQ4dF4TYIxa+8u}~YRAFBDD>R*m_dI3K&}0yI4ZpWG+_WGJ5`K_qyS)TJv7W*38H2)&TKhve<>+1`>Af1QJ4(_n-B3Gdl?S8M|Q$#)H(Fy17Cy_XT~*34Yb(f0@C zIh#%s7Z>oJ^=^!5n*UI)V4r=n&4>94QwmcvA0d^ZLs0;FjpnVTu~nar2Ge#w_}2SD z+s44!Vb7ah`+1>-ii1tuyN{UltV(li@5#Sl?^F<=?>x)+XgWx+1SU{rE~un~B&ENv zGkmL`;!S^K`#EDd&aUz<-=n*+FcEr-7caX|v5co%M($Bsb{jNC9zErHG6DpjePj~d zFZrO2wYqJY4&rz=)F|Koks20-(#g>O5;sUEaC!owGTxKs)?bzyst#nf$m(&#p4OYF zl`6DQl3loK)~U{8GiZ{yUU;Y`x-O~cV-Q=IxF)#rwbl!ofV-~V_Su8oQlP%SUCaMa zB0R}aYh#6gj&gg*XhSL3`O?j}Wzo@BsS z*FeA>$|zo;%fyd%g^e^yB~j$pD^0Iq!K5jl%b*z(4E0w@N`5mYSZ^mNVaCZ(uvJzg zw_=t}PV)klPx@8Q0!-tjOfzA#5bmRDe21ilo6TP*2baXbSiu0Oq=&s)9iD)`SGuNF zSt3JI@yjSF37myMkdwv-WE5sjznnjm$LW9V7`Es!dX@K+;BdY|{^4(Q#WhNkq+g8g z5B4K|w=th+rU&~`7|I>I58BiA%r`7qi&F_t8cU$R)Gdo595q+DWTn5?{0NZR!kJK#NP6g%o=P`Ofs`|HV$_)dP#tQSbm ztIOMD3YO5JYj>>Hu^6TIHs+-1solDES5v)@{f7;Q2`0q(+D%E_DvC^>5$J8)MQ?Uk z2bpSS>g6e!Ui-pCTA)tgUlEQnHm={C;dkUv*QGGQhGMUB!Fm-?zF~7|rJXU>;_lSW zoRezT+O|o{jMfE~8^?s**PV<86x4}h?ooS4m4F)EsE~dDO{xqDDwmRW3*@ z;M1no3lk6ig~1Y1w1m1hPVu~RLZhxHADZs|s4(4vZIVB#GdfL@lG=7BvK@Uw`mRV?-?u zO8$`1{UJB+886l+@pM!>ow3%EKE7--{L$_(cYwdjSHIBNv|tK(sg-pF)cxjR7sn?y zEY5s>-u$lV<+MdU8epZ@6}Qj|OszOZdfD94um}qJ#A;>~{87=ovTtCUWLKLvSBW(m z;%&O*t^O=j2RZn+v{d3NMG?gG{^vKxK9V~`B^NWV^-wL+NvSHV1d{W=rVh^HNSFE8 zY{2$d@5x!oour%l2pW7fl%UXj?;_Ve-ME^a=2icb2|oY2p>UiUY=kH2io4P5;GG{7 z0_4pN?)2{KAn(}8tyuK7nQV`-wn4@JNm5W>WNG|2QIyc!5&p28dQr2FG5h_?9kxBx+dSrOzjuo)eGLB<%u`@;i zi1>W`7=p|F_k&Ozb9R^fe^(m%QX$S0oW1`RvjRHG2`WLcTC`3>Qepn`6TpR$E^U2dJIr z+~RUw1s(N$p5@1p2U=JaEI)QN2RYNe(oUe@s!MDnu0MqDyV}mc$d0jPcDKPxW2~9A zR!hs-j+1HXFfMW>CBb#O!lr_*z9zewQ0v_dkCdpT$T3L_U~UsgHwAjI;m-cqQN{z63D9ClF3yB6}O+3?AB>?V4U!HXfx3a+W6<$lNF7HMz`*Wpcq zg6&pX4?Vr+SJp8%!PB}IaH-(_!jo2$%4U#UeYwfsdB%!cua2IgfeLi>ro8bbV+ULSYZSGJkxI(k4-)10wy2L z>H!wMQk^F^T|wvfd2u0lJHJ0kaN>T@*&%6+ldj8}P)JQ)^M0M4OzzxYn^DIW_F0D+LOGGg*F1UI2gul6cYiiN!R;fc`a4z^gsE&Mu z*reyh!XGZ^Wrfj|i)JeqU%^c4*KI}8v}pErvLTL%rSA9VXE~+tdW-UK`<%SCSn{+*`Wzr3Wj!d{D zWvi!sZHdmhKI(jQ&~2k;GTP9I%3@2<(Szw*dC!L$MaqbSmBKlL;!gIkyvWfWl9{JG zDj&0RwWvymf;a8vsTel4l$InGR6gQ5WmnfLANz~0=HZPdZz>TUufgadBQ~FUr#+|R zY!_koul%rsyu^m#E*BTfZ`!*u&?8+4)I?u|9(<7SX+7TD=uVrQy%zxoU5Z?HJ^Lat zWpfoo(gg^;UNOX|%o} z5T-b`<4xxGy9eNZeK*nSgUdbmX+v-(*VCXxwL(S|Q5Fn>TwxW3w;2svc^VERIS-Vs zj8exQjzwF1R4E4*bc7e>77Q?-pfT^?AKlw4PE+TzvNHuawopweJIGWZxXsA6TxoB= zo7Ox?j13Y>6{p(Cgj&i%kuI21Hq<~;+Cz|#v(F196J>!+(oKfYsg#E@t4|+=g7_%P#4&pp zrRHVX7I^DP{&iU=+A-SR9*-{!v_?G*l*mTJ+OL0A1`8ogG4|g=1|g!^JXKWMGT*gE zVg}E=M99%iC7Kx$fFzxo)~Y&`AO=C?t+>e-AW!r6!c9B9{IFDuVyN8MIW&^m&t94j ztko_gWI-qGH}sy(n#ya$hzqJ2c(uEZ8Ll#&o35{u;SBRula$Ah0wBOVh zG8pRfUY%t!;+e0pW}t(bU^3iiTFQD011BGH!hr z%)hmr8>wg_Zsu(q4{snFtJP!i0<6rlK1{PlQrh|ps&YJ_ zAT`h>0k6kjNe96u-b?2#G@VI&#_OI$i3K^uHuIA0&+kw^I1Z4?9QU&be~5^WzIdfc zNC0zJJ&$_*Dh4)Cgx&l8r+|#$BFk8UZ82*Gavjb3@1Z8X0gL#KcW3owqWe}Qt#5*x z20zbSBab$xoa z&}d7w$oDd0$;z*XM)#w)ELqfT7G8spEU@j-=^l1jf5f1idD7!DmD1l843_ANi~L~oR*k~9yw+FRG(xG>5zDW2ocX0o3L^j^t5vpI7ehBVT!XwLr3uT!lK z3FwL_=_6#_o<1;zaAYGM4{V2;3>gb5vtP+1{8~LyVMeq!jWIvpBSGBZ!L!h1cc3B7 z-%ih>d8@ayN@p_Gq!XbZO*H)P8&|;!!@V~qA#2rrVXW9eoKciuN)7&xx}@|xw8hdJ@3Py` zOB2eh>HJ{zh#B_GM5m3ubyz)4DP*Jm<+^*zdphC0h0eu9^w&``bNex>s-+Eg#i_YV z%gZCv{HtQZ50648-IosyM^)xDnQgm1{Gz^hbA+vlD0=_EnPihd&XYhF^G)ZT?warY zBW|-XP~>qYttQEM((2>zH~U6x)93p7TO}9v!O_tJEw~*fLyNM+3ZvAqpq>nrxCmKfJ*@ENCUeYwBhJ(>Fi8y*q%P){BY1(n(KWzo!MIB z)Drgav~t78_i}2rZ7|Nc65zw1BN_#K5XF08&)nObx)JdEnl1z!h;&>|Q*w@LF@kyC z1nC-iKkY`ZWWkt9XI`zjm^s{(Gt->ZZr{`ReeXOP+{-!mxXjUgw>vE4v6xUe4ViE8 zfUo|$?Hl>+3}$D4r7TLEnGx%_c>2mr0~3Z_(~d8l_(3SKb9{CWpsNYF{!crj)6zqDr2hHp(-Y0={qu*1hno}s(**`Tpr)=4NAAS$ zloRLd#aWs;ogcva_Bf#mA2#P7k+?g%&W;s*%z~b5(*QZ`gx|KgRYeeBK70S&WSYe2 z(Ono2*YM}#a;(_>!}j)NGN~~*e6h)OtDda;;m-%S!^4jqTB>DIGur0xL&4KDF|ybr z5rDqhKOJX$>Ckm|UWGHI5O21gJ#XX%eM{{o{1P}QPO+8t_C?Oq%cCghn)kyrGxZ@k z%9{V*{xiqh2W~^N^-^PBH{+Oqpcu~6Vc1fx?={m0XCE7GA=GoTb2!?R$i=V1Sl6h4 ziIX*iiH(h-@XLPoqkk3KM-LA>q(Z|z4&8t6+D}@$?M}@S0xy@=9ye~cqYA%YxVT3K zGYp-q^&qqxe-$l{byT1;{ArBbyPvYrAmlvyIjP|Er|D4G00;DDr)ti13S{}l(ttp=fE`0> zQlV5UI$UE66lF>V&RR6#PoJ3l_Kml-xxFG*?D1jy@@Q5?cLPA_0=dc#A(e47C^si- zd#Uqm93mcx!#!D*kjyh5FJ#>fSYmw=bKKn}n_u=(~u%-%V!?c7 z6A&iagT9L}@kMW3{zgbKEXL(PK3 z9%nO;MD}vFeeThYesm*#!`P_o11>FBO>vJx_I5qFmn&h9yNCT7kYRGfC=jQY_)rSF zv>aaV^QRlGgguPU)A%tSid?Wcn@m&^so+xo~@YBf7o5G0IFcF0l!_w&*?`f=?<=iOnNN zTtK@|V_{da@3#CWgDyS9YMF#6*{`u$onTi(m9b(eS2vz*1ONsb)ERgzk3;i@CG3TGGi_E{~I#;a~=(oP6^IDyNZSA&)ixlR~kl*~3^7XKpKbVAtZ? z?_Zg7{C3N66weC>c+IUk3!Mb;L|R}2(L&T#YrV@bI?o-N*g#kxwH*namwceC=`*V|qeO`7Nh?xco8l&IYThb85SRyz#hOg60+lG3?{;tq? z{@jDjP7Vi;3yO+9&4}s5%99gh#-oUR+lH&SgSHoLafMO49ySwI&45K#D4*)U`&~uXgytZ@)T^g0Yg^fGw$drHWU8(S`cDIqLuDUFp z8}EtRX;TEpr6ik}i@l3+&crILlu>FTfPu>iWs_bDM5|&g=LW}XZ-ZKpDqak(j-ELA zZ!H}PKXc5xV$QDaBRxX*zY)RZH>~dKd~7ClA_l~%2p~BM8dG`thGVny>24f&$|`rQ z)2C;3yvPM)zz9&52YApMC%rcPt;vQuzjzyeehBIGaQI#uye>V>AUh;r<#zyM6+Z#e zQ}psR5me$|T>>%m&;waNdS6<2PYCWPj0}7IEb;c0vh8*yUG}86HtVT84!mklV#i}Z zqnd)lV;nUinVJGlOwPzJV{XsCQfu$@tRW30va}~!t9>sTJB;s`>*}x2=m85t_~E(` zOboN5e!Qx1vz%UQRMSc;@*$X71v|*7_x`FQ9A2m@x`$UORA8pM6Rm5ULot1}4LF}; zPJFj!b%Dsdny#mml|^`XOebFG%719v-CI2UKu5I)_A2+uIDZfq;K8A%{fYT@2Epr(tthU*bB+Mk{wDw|cJQ#Wm-g@%-4RFv zjO`aSU6vl-fECjTIM?RW!^+2A^lvPhlvV-S;cYRo_nT z0>ahr+^S*%K*JS)7Q$DTtmFV|WX8wCnEeHX2RY#F+&#VlFmq-rt8U+8(iQxbQe*## zSn+q#9`|sOoEh~PaPvr>78{H)pUROM!C&;PAOeJ~%kMouXunC|R>AdaOiMoSAQ?R5 z0vSV+jaNtxRIkD;9P7aYZK29K$v_x!`G3BLZjS+#Mj&j50`&@EPGXA)&LSn{9hb$ikI84xE{kP$c?)e1=8nDM%II7A(OMOF?azB}$? zsbH zLQQ}nGllkZsYX9mDXIf6)@zKr@aow8|7;R&F7a1*qV`4gKS+E0e&-4_lp3Yg>0ROU z;$mxCf(_~Oo*nI05Su$0Yuaejv#WG9dSWAfkUQBBOcZ1QLaj0{!vPm+_~!fhnLt9V zfwW{bP7tDej}`LlfI*OW8i4&J()eGNcdqXI{1OWuS1wEXf0>CBo4+>6g|yoM8QNB%_OEQV5}K3qaC@w21%H<3%ni&e{SH;2Rrw2}nB*@b|b zFjHI(Xr2!-jWn6urg)vf4?r^w>38e_rLdt338*dGK@@ZsuARs6&1y(*f5Ub7~Xjs zadd*Gxp5;|CH<1q{hbkm0}|>q(_c9O?i&6Qd7$m+u&?B$H+fW@~)O7NjN%9Fqnz0L4W1nDfK`&%Scd7!#2uI9;p$` za+v3lB?7sT4NQsu?C1USXrG8jUD!GIYi2T3N;jp)7!mxH1Q14=l|`)|=P^JH^+%moo}c}RI#=*NAdd*l&hNr$sc7k?zhD=?_8X|901`>CRbLY7D?F+wn!M+N z6A8gngM6;GytxHz_L`c1JwcJa%Z2z38TZT+y#jVH5MaW#n%EGqlO+m}eUXXsJKIsQ zIkbub@LZha)>X8&ZWNmmDe#c}P^Lk>c?z1@U9Z9lwE%nc(y*R8VK8{zD*wNi&sF=I zd&ATN9>Ic(iv}{}`(N6FJ4AmHi(9drev+aM>l6i(p54wGC{UK>Sn(X$0kg`3I}qBwzDnD^m0Tm^Fu*Q%L`K#JBPRF+RXv1)B%6kv$8@Q2Ut zFx8x35W{0KXlGq@PI7;a!ji6st|kW<_%bngFLpgKv#cEguV1UyvtM7w5`%JBSpC2n zO*<}mLHX~*ayBPfOjUAuFi~-Z^$dCg#B`e;>&wgKG(5kQYMdr$eqSD*GJpN_mMHrq zK{J1oFNus7Kf9<_kXZS75IcvLl796*`d}`)&?m5IJs##hLz~=PIPAY&*qveOWA!-P zF!d;7>T_+iM2FH2FOJDwlb%D6= z!l=_TRT8aDSo;(&;Zr&CO>;2NbKqeF)5slUvEgvCjRIdrq#fF%gDR9|3Zp&efaBuDqjC4Z*7@0(&QBgECZN~5L0)sB~?{|Noa4aH9o+f@8&%zE4GRYlwU5Qy!+TI6sSB<=}Hjm#NxG{_%4f zqqKHi>;=bG9hU5u9*6*7JTDa>TELj4O@v|rc}kPC9PRv8L?p?9K_tVVgdG^e@^yR#%o5y&mc^xnGS|0f|(E*Oq`7gE&x9 zVrDu)05j0;`=@K0ZqN9l_VkXu$rV4GPk_&#$^ZA%By0+y>N|C?h&Tb}4#0r6)5*+% zl_{NguU~bKyE(^Pu0as{erBrs_geRq&L&01%uBDS8?n`mh1)CRj*&uHoSz$KXCHtW z`NNFr@sa%w?b+$~8(Vvo|B)qV{LdE;4iFqhf9e^9LX3Scs6Irje92-up<4d?xODP& za|cGs%f~laJaD5_%Iz-Y^~3jan!;fD?M%x*A)(t8P-*l7+Ek=WPY}S+4LE2E>K`s~ zzyxDhog_?lYnsJsG%=Ao)b(&~i|^W9ko@N6#J6Xa`rQ>($^*dd#Kn!}*V*`x5yb?Y zfp>6}W#ro?CwF&$R1CQr+}M^4el6J2>ZI69xBj_ZiX6{}`0C;9Le*B;nvR9p7D{vf zixpfD#(6A8`?@W1mz5dUsQ&qp?cKe{>Q>yz?gRx@%Jw3ryA+`1=)BuOWYkK%>S?=bmH{I_RK8dlfjz+y5r+xXOkb(Ex`N{L$#>;vd?AnFf{SI zSzp~WptAiPR1_vRr%7zTr>x;RI^(}jJH_j*br5-4i0-WBJjFfnhm@gC2`>VlagNYM zLvscZ#mZZP9yW09q023>tPj8^ZgQS>lIHkjFu!w-o#M!CsoKWM9RI)|Lpt%m|iKhVDjBuQ)h0m`u0(!?^OX$I>2t@ zAA3?W04-^<(*xlDU;TTD<^iklXmy|cFxd0&{>YQT#{_ue+G>6VXdHvR@>veRJ4$_{ zsF7l&;RFlKhNS$Zb`c3ooS@Qc4n8dQ{$y06Df+mE$b7izzAQcEj`vu--=FOCVQ3|a zqgY?S-eHbB!B50Z_X*x}@}A@ap=u9{kH%82y?R-D!KWPZfpe=|f8c0+v=FI#yqyl< z(Yt%==m4>OLbOh^o)2c--6#YcX^xj{bQUKY`LGBZzFn^ydff6)p1vD#HDgi)#`QTl zPP2$_ttpf^?X-1FizznN2H(s_TiR)}v$=28o0&@cqzF^Ke-$B9oU}6t9q_DZjsD`o zJ{mm^+wTC5mQch=i7)GSF@8#dj2%+)Pz1K!Cnqa^dsxixC7|lg;u`_JFw7>DFhi+mR?8@Ws%NEAnC+9PnsF%7|$}3ZHtDeUe`~O*t z1vb@MfZBWSbAtni(<~>#+86>76E&auMceL@SI)AJk12eFeAGhdAbIP548RLzmG{ZT?^4)K6gZaJd8U zBQI#KxH-Hjsj1WXp}A%qLHF;d6up$CScw{SJ)5LaF(_G&R^#H0hTr9Mva=Kz#>6a6 zdYl}y1)b1PzG)g5>*LJCgsp1PHaB!8-%~cG8u=?YTS#O-ycMY9V#oD>l4d}FNd@MIIiiz09@2X5%eVl`M8ug751DVb)z0~+kAZd zb>i!URZds2R+Aon0%s10nSXUFS#V_BRdCBqxIGEYc^DAP?PAVs`8TLVIp@h+z12(e z1vQ{yJSny{UxJ+6{oQZiU529B?SbUuANd!y@KmIomVlG&06*4wIzavN&`sf6Y=6j6tg*pZ%2*! z+`X1Dg)FmGpH!^m!GTg+wry`gy;^AjoHqMO&;hcs=wHm-6_}J(Cg`)YTv}3lSrtmZ z6!BUVDb920Lpg0)#`;+)vtNMJNuvBBMeNGFAPeL&=t0`iFfAsNtU6YV!u-UGm%us< zBtlJFV6v7%_VrgfjpPkZohrc;h^%N+ku8T{I&X2Xx^(E~>W49E;_~NFT(T_O!pRlt zsDLDF#**WkwQUkU<(nEtH+lbxBpAB%#UU3Y1#Ysn(1|8MM+lf|SBy2O@Kp7=6hDtD zXJ-qXmJ7y!fw_odk$hjWEpZTko!+;85d1kzMNAyB?UUY)T;k- z=P)DtkAwOIbxGRiElqf>sMjAxCkjr{GA`toLXm>GPJ=_g1DvQHeo?|bAQa%2xHN$* zS?_v$vb&cY0p&w->9FU@i_gu;)=O>N?L*BV^@!AQn77$+dsUG_k&rvM8Gj zSL|DVLr(FB@kPH*x?7;Pr!vIz)*2L5&qCc=HwkW*A(g|f5hbJ!;#p`zK^jtbpeJFIQ(s2fpr<_ev@Vz$r+5~MC9 zv))r#EZHj!RaB)1Ain}1q2bWmlxg)RMZ&NLS*L-r{xcTA#L$XJY5gqLPe%4h`q^(P zrHW0W(7-?JgwX5GRU@<@B|phIqsm=PU#xsv`+hW?ZDA7bfH2oDl)%idIxp(0S8@zd zeL;8Y44D+dn+#^f=+_cBx_B14j!C*TM7z#(GuGG9oExBSfyc|L(h)egQAtnZ0EbbJ z$LNKpd?P=*7IA>*Vm!gc2XPrIW1e%g@&~+?8>|WI=l%_@uW)7lDA)1s@R9rXcKu5u zR$hV9-(tkEV-w(^^v|3TCj0f1GB+!k(&Z%tq2eqhdq2XQRLef2QSuRwfKIX_C)Mpd z-(pzjt%>cBa=%l~|0AcPFD#R&=Ee@QWzlLU^jFSD+v-Ts4y6$0N;SIKnSPjz@TFED zzh(Wz;$B1m(b6~j6ixpO_O}W;8>2c1_*rXO$0!Hj$_mt?S@oZ_L1syTbeaK|{G-an zV}ksp>U1WzWD4NDi87)UOEqsu5)YsaiHGJxlN>b%!~*jFv@`cOnP{VvV8d{Sv>fML zbc9Z(j{hqb@R@=oXHR?Tz6?S>a}ragX64t0o^UFH4N@X?rEDNk5*R2nKv{50l?1Yn zj6kHxGAZjc-!m{X0jgC?82=@6o=WMnp}eAZ4B%1%)KoDRGw{Syy2*JfU4g;Lv{3S# zS{Qk37AxON;-EEc81o_m0;k5ZUz7kz@nWKFXfH;Yf=ekk6T)?~6RW_e_iHz*GU4rC zBDcY>qh?%?gN&1o*3L4KD8Ubc-7ep!0zVS1b>x{i_Hc%qI3}OSgG0g(g~3NZ8hBbN zKxRihYUMa8GPbQkBsgtCh+zmkr_9^w5`MMnf>rpjgH;h`91P7{KSREG3kmIYFs|m( zP0l6qxRdQ&nCe+aI$FihjU2;x&heca17%R4KiZ=M9KmV>PJAAP;&l6!Uqvv~iMF5n zMZbuDjOI!**=kmBq9`V6cz=lq`23iy2QVKB_GJG~1^#v2hbIO`)ru2X7sxPbaQtkJ z#z77vwTrM2I`SPYR|0#YnlY~M9j)cVF?7`SS2rp)1k=_H8~s3j8~^5SY7E__AkJAx z%S}C|Fu3phsO936=gj1^EzwisR{KLZ|FR87XdP^f9ExxT_n0J`gqqseKG#kW?w}M~ zM*75JYypjWv@g`CvqJ2LqDf64;JIg)3`fqkN3i}hR+beWn4_bkv+Lid$Lj0=fW$1kDV7UEM7PoF#eZw| zdKEE$W}o(1x`%(O{wHKX&A`cjfcIVUyiqiG4{;LAV-3Z=ZfJftI2ZQ-QfB2%624q} z4LcN18hk8XO-h^#;F)~!NaCbL-p5Zov*=^Cz-|C8sCrCX>>nUQ3b0b|&tZ6M!o1^|Xi)=aYQiwxzD9+chcO$&!QyZ?R?b5R& zY&I_|zh4z_+K-c_X>xFyVo5ssLx#U%k7}il|0ds@To7XasT+cB(P< zyb%+|+HZzYhzae<*RqRlsiGe_Jyj~>4bzi>z;oqyFY%9yv;+S>Yp|L%%rlt1R-D); zjl09wCwB@*JQeAjCEU;Na5iFptag0H7d3qp;AXwhG!Uq+FZ~)6iBE2Hjt*teYAWKt zYQ=3RM`vfFAJ9J+Qms#C)~cuqg%R*~)Q>pz$XTQ*THMYBu~OLIysSs%k4_ke4F9bD zjYSK+V+48qXbi<~8077vT_7SVd+wR%>N5(mYd!<*yk`*nKKni>!LU(cHVqlH*hLbm zoA#CKV~}TsV82s&mHGf~d=9S!Dgj^dCysEzFf&9C$yXjhs5DybcuwNyd|1?1?(M(h zpr~N4h{xyx`5UPXLPAw6DM z`v-T(0n+F4=^-M5=CnTrNpF*W(U;KBzbFg8n@ezS1JF@$GI_|L>8u}^A(i*iAa+qSbLY5EMY2DG7U~~=lkf&W+kic#VQ6E zswwa51o7UDs&k zuA|*)F`*;p6auINkdZD~6sd?kMNxLL)220_MXKfB%Vn}#qpMpTM6fYx?x_vxWwBqz zI}v`FXv55gR-TS>W8;1g!$xE{Xn-B8Kl*rd*ZpzidM0*_=-v9=oLmzr*@bC^St7hA zNv=eLsUv=d9yOf!^*H+L@vyz^nz!r8 zP_&35tvhd}1I?F@tguBNyJUuF>M4rHO1^%U_BWQO^fP>tF8i|iN~{~YZ{s(z`92A2 z3G#x5MUIL2;>aCo4~Y3#i3h4VMoW?)8H`blm~TtJ!6_sr!lTT{M3aYhKGGAFup63* zC7(DyhX;hlH$t=PLy=?8J~9ZQ%8TJStFSYfwD_ASFd1Jt62qLCwzrUEyj2>H} zeD;xpesy{AY7tbVfvLg^HG}H);YC;tScB?k(V6rTg<8mw*mXs$DOiE^{J3>I#duic z+5?JR0>2=EAS^8*!eCaw9e$tZNjzHS3udv}C5oc|u2w?MsFkJAv!1+$-jUW=saEk| zLGwatj!o%B0_?*UDvLJ$ydoWCkx5dO0+7~+rIw zWVoe{Op4Tmk^{rR-e-cJ1L(?B7{Ec2mGod!`y40{2H4EWnSZLMTxR?m*;5POA!Epg>teuC}nU3BJcNtv6aj5>{>>TBy-QEKoMb_Qa2K(M+DWZ+q9+7Pug z#M8~5l)s-b%2c&a&VmIh{v72k$jHxi9xU;}r~^su7Z%|hp3*p1GHww5Dj17k7fO6> zWP}cDli-Q8i^K;R_0S|Po9PEbTEgR5%!zu}lY0yUYQfqYXjmXK2YSh@>AY~QWxMB5 zJ>;}<@4j?8y}s7NA%J`=0!uL1KyKp)2zyPWj>jDS$g2Bbw=OAJUj@ZV_Trr&&Vbk1 zvYdrdzk|pUpvs$}a@X~d|KtH9L==)IwP7zms}l^B(KWrKEK}f&RyJ+OT0>?8mG?Of zDD*_P3(@Oyfc6_@QHS`0=`=9FM14r|%VSthjP7?K9Lf2iz*v%tIC#85gURHr!cHkU z`e`3i3`Gb&9Gy5MTUj(}=~;(H2pK%eEfl&|Hn!rFt&{8pF8)k+EfSgS|AM3a3`X`W(_L`F};ot}1WVCdMD8>!L6vpHW0Hjzrr(e5|ZBf#y$2W4;Y2dI^S^A}hN*IS5M z>2m}N{!ZtHyJH(avkZMz8TdAPhm!cK)?8Bna@s>ocUT<`I2)bYVzetO47t`)s(4(Z zLAA0k9IG7(e7A8T9?l5^acdC)z50QQ;d77@`JarQI5Bf5(tuWo%Xgmx$mWxKI;4kM z4ZnY%#fIrL6$3>OceUji7$aIsom%$KYe!`h@zoA_@LiO0o%0~&0@OGLrb>S;qk{kwikXQq}uk(cxM<_*}RuuWOqbB>6w2J_o_Rf1A(nYp}O5Xu4VG z*HhI`#o9V~2$8#P*eKt6wMJhm-x*ScsiU#crv0P;w!8;G*9K<6HK0h_?zYAh;Lo+f zlKXER{E688Lm?(!U^a_e%@E{tT1OTAd1~2rq4VgdyVT)TK(jtGVK+53jly#L?o#fw zYpbc29XxC&v0%{)Qp;j3Q!u114P92Fy|)thHTEklbwbq9&%ji>dOye;ajcQs|FGz8 zxO82(CUSeI=r5_`lM~<NVmrC0W2JwYr<~uaI+pyUcZPYpTc$1EyjZ;HC=@kQ|Me_`R^_Dl zDEqsScdPJ0Zu9??L;s_0RmN|aoDP`9p3?a2?C(pTygS9%atZ0HP0? z&tSbnrFMOqUwgGpx>vhN3yC%IKV7I=gk_ zT&Hos8Y}%RU~smGHFeb67<;fI^7fYezp}Jwh^@Z-3MM44KlF#8h1d9<$+m_FI%rH6 zA!$-X!}&0oFcY+ibHqFWC4dLZue%MPd&1qz{^r8|0@@IDZ$f=T(<`Zg6$-xR z6E~CB-@c~S%VwFso(tD*m8J9A{PluIK{EMOWmp|;l(z3d*z+OnU5G+*u~vn;B)9=|cmsO|86ul=!0xAM_y9hq zbJk8^ecwV-Nc8%uuH4zSEHMh(M$y%Xcn1?w5sqh&B7-UWN56y!;du-&Mxc%{kqx4s zop_VW=bjf%Kwg-!rneAUG(nz^d*y8+rxfi}GDe|#)*bJz!v9ZKUl|uw@U{&u%_1Rj zD3MNamu^8qS~?`$WeF+i2A5oFK{^G6r9`AVBo>yI1`%9=MNq&%QUrbW|32~I{dRsc zU(TE}bI;6mU-xyT?py@Q^#p|cqx3u2{(JR@mRng*2-`h~JX!_sj5|xo*(rr|9?#)e zVVM>8*|(2T z^FpuwXJ;;w2)d8{^CJ;1+P`i`ZMwg%g60xiWF1Fj&nrhdLqRzA$ z5pH9n;2ndySBBQaq`o zu;60J*mm~u#?{+o>M9o1i)krWp!(0QOdiC)HvN6V{}BsHqE9%9Bx>g?*1R)?S;3F( z@w~w6L^XtLb+<4hUSy+Pgoa*j8PFGZA7eAtmMQpsDYOB=$FhrCrc#(SvV|nUr;3zEo#vex27XE#`o4T&o=|Q| z!-Iltskv;oCTdT`yjx~?V1gutw#j2_$XN7;FK+)%P{eXFg2yjz120xN_{n_XhO+4B zd@h;&j-=Mt)M%P#Z*6~Nr4}fn{DcZiXe&5v&=l|pKa8)a@~toJCGs(bf{bFhv;_Nk zZ#I<0NAHG!Rgr{S|9--vs~FkHB8kYvy?9Cv)JroeSR)Pjen_-Q3sRT=vDpa`XWX2M z)D->u#Lw`t;`PE#!QY)?lW}nK!yn3s!8OJK26hiX8zw>?*E8LjWYa%0?Ch274lv|? zt{oQL7M1eMNX^KGC;hA!Alp?_xK0c~;J=$f;qerU8@T)w&NcuGqvfi)$1x`#e6LPey~pIeR=tq5Fi_*OJnV#iU8xGjLFW<^De( z^BevzCoP_DzN>i;rXFPZ-5G6q@yfM`;rUIC_kl1Am$ncBk^&v#qe9)|_1n}hJUslY zRBdtlU0+<>pEFQwXK{owD-O5(?(0|j`e2jXo*u3)?+5MeKB~$q}Q|bm^2&2D?mjGy1(0r#Uc3L9-yUF=a{bSkSRdTwmH?S9nPkpl#Y0 z4gGz76)<=ag}7&zaKGL}emaU6uI-G)q!#hQ((gHtW&<(xmPIE$V^DOyc5LLOm)PyQ zr(B|_G5{B%_mfTlHr9NN!|!Q$y1?(wpKGI~iV}Bzp8_FS8*W*f^)?qh%ar-z{5&B* zM#<|GR_Qlc=%+=vob_BIVU`g=_HJ+8S7iB6Z5Qg$q7TYWr7Q{Va!a=|$Ey62tW?oO z{LRM53bS+Q^sA5RMaP8#4D}B+pu5s51~o+rcV)kpZrgRpq>??AlG-4?Pbeq5vj#OM z2MgKGY;U&c0p&Yt~Q%soruRja=6KQ4hIUayy1?_r4czvf}*pSbOel`^hR3qh8Zzs%FzN{ z>2Te6_j|ra3>w)98q`_l<6Y|1j=yw{va0KNZ7Z@Ni`lWFo`7Z6ZjlUm@M2!YY7>7; zu^&C}-pg8vdN0PipE)RG;Ft_|7c$+L73{q&z0B4{^4i_8N53;q#7qQ_)IB`6Z7PtY zOq!+UpHaj*q&CC#qtW zuDN*C=w@f5m^1~QSM##%H@kSX_0lngVC_35{`PWQ)2}S(KEu_oQLtNWk%5icuWOC_ zIhy5-j&o>BK9{mUOzH<-Kcb12IY%z0I`YR~r#Z0bfU=7zeMuXS|EChQPu*tad*fHmM6iuV!Rk32u>?8Lh0`+|--vBTc&d#diZmo}f z-2F#q%hJb;R8ZPbMN}y_nz8>05niFwIMR}z18u4~`Sp#->7Spo1Id(zJxK2y;N8bv z@lb5aM}{oMo8`_QIH0;|8IY5SC#vx^P7aU?Srcfp@Vb}wJon&O*oHIyTF~Wk%W{(Y zaOG}xAfq>C(X>`4$aKJ-Qa6zEDC>y@m~1@2UJenCY7Xh zF#gi>^6YN7K}PrWD^bh8nMh%lFm{caT9c7~hxaHS6kS)c{Ofun=SHj3^lc$V$Kb z7DOxehKnBa<^2i{qGy+dE$~_fT{~8zF6+X`1k?9)-m{cKi)gxNA#GXH1M;k0v}>7K zAQrU+f0<~h5hiHD6D+$JFn)T^yN0i9FCMBpu<^(eqqW{yb>9;3(pg$oZz3y+gX&w@ zx+b{;Nw$DZbej$%yS@#7g30Y-bdFd%s)C$Hhx0wn;W3fdX?*PHo#xk?U@1ExQknHC zM|N1soe3vGj*&q^Qha?kga~4ZYj-r{TtsibP#=@qZk}KUzuGEXZhAkvUunL)@t57F ze+p~zMxwoD#LmVvJrS#AD`fdvdLD>K|l==^|*j{iz8TE_K%VNFbb1*P-?mv=c zy#yJ{)X^qV2#uSK$f-8%LQAjaoTg%QXvr4vC6QROyBs~k7 zQ3;H8*hSh=mBSa08w9`^4I~TlDb5jP>%Q+@MGRQD?RX_p$-r~oC~acy0#Y6o_=_bY zmN$UGCE16JCWI1$GW~+*98jm#^wu$I%|9sD=*V0KYM*4sLdAGVH7m1b{8{ow9@t!` zcnFwAAYXwsH5FZ6(Up^eGkra!!VfY(x|K!}D}Y`^5!$R3{99a9e-9IUdN1ZviJs5H zgl9zTmo5=hT-F@fs9~{bG)O|LdB9D_NuDEHL39X(8CO1)hD7E*H)XQi`CP{rc&!Hx z)^FOrIY{D(B?Hewm^L(QF~?u)26HOS!XN|4CY{EvxuGP>gjXxh1<^6h5-8KW!HAq2 zDYu!jc`qP2_l3;_;jm0p*@PL2#DHNC&$6H+|Nk$RhU2nk+QDUr3 zRI6$hlnzMkGzKm;ySTu_+r(JA^-YSgk8JyinHCPW(2W5q%#g)<_F3|ZwEQpjG~mNm zLiC^tI_jZkXE&LE-}s(jVB*=!6C_r|>|+%t#W?w%3R;)Q`LkZ$gWN*YMAo*~xiId) z0$W!=Lt~Jkkb$v0*+)S}ut2~giv6@!_SN5S{o6c9wQYjG+3hzO0kFPW>q-j~KDAzm zZ$h(_@r-QjTr$HERRbkDmtkiz_9kv=aDZ4cXzm~cjy8UGv45Sv;h{1ZX}ez`e%y!^ zS-uXEs*M!0p{AG;Ozp=(l+310Ra+t9ODwgL8Z`e$F8FT;;IE&{a@A`7+mGshX$Rq9 zNtN__|I`1!jW?aTQWoxfI`>pR#u@o#xT~-0Wi@Iy`J%-1I^NWn5`G}9X58Fa^!7F} zM@2{)TM3qy7U%Y4OKEEUGAW2tJS#=z-Ux)~qpP5qA;B~17W5wvNDEYaa_on-9F`|r zyZ*-JVjzs(P>mh2Jkp2*=T3oZ6{-}=f>b4k+X6xS#`nSI|IWzlmIAW%h^ zGK{N9R?8MHJwx;#(dyG87KT{3h*~nf7HI2`@v&h=C{GR4^uT8021Lvt=~@_P_|z}R zo<*M$Or-os36X|5ssf?5sMC6kB(a4Doa?LIFc=3;A`wE4>2Z`E=NW@-HShK6OPSSE z@fS|y3DU3IS;(?c(BGdNQkcXl6w~rcF^`|>4>1_7?;?jxEW6}@^`>gkTwX#mk_-SWh}yDzZTSzP=9%PkbI#Xpt^w>*K#^c=V~xG>W;$hCX= z@l@y&{6@kG9@GaLfTCpT&WYu--tskVhBz0FRsgVCs;3=2wHcLAAz~t`17h zAqv8(f>HimRY_y#{p9>Sk9rk;$w%eE)@^^1I@Hmuw0Lsb=YZ zHGh8JL4W^uN%z&?uz2iQC#KhS&%jEmWLQYtDYUKp?0(s+6hnamT_H`6IrxiBr0~k* zUw=KUJ5jRbEL(vDD>`#(Lb&#)LRX-}>)ud%ayZ9+w{3TKx57&FT(&|~ zieHb;jq%1RA&ieIF8~Bd{Z-;#Q{3O5ckn(HO(Qq=fa=oYB@U1yw zxdDW=LaE?bDxFd#=EWUYYDpFXnSq(gQyPiC^Pr>H%ftG`(88*hQFpy6BL2Qwgh`h` zsE4(b)LcBkS!*z2Bxk7Wq?U~`mVzT0aVhCE)TnkmEXF1kJi~JKd)}+DqZF_HY({|(FHBM?x89#^k z81nWYQUnH~wFV%@@ixwY1)Bj35hL3VRvn@;9Jh+l8#;FO5PK}Wu-fP7MUG~P06`zt zy-uc%axg+Qt*82RZCrc37#~z}+qb%0C^vbZ@5az4pIg#%$Q@4Zw)NSdav|Kn8$~Ax zsq8nC?XSm;DySX=wXuZpqa9QII)oMka5ih*?MygSML8p8Ld9qEM@xMmV8bTYW!w;L z({#>9p+|3CJq!%QJ5TKMt)3-})?{^urw-!BAbFjUFfRchua~O`OY3X6 zrC4ZlcimSjxiGM{xO;4jLs*N@?Q%V?K2}07xz#TJaAWyiLF%I%o|VcHdKS-{7JB6& z^zi@X6=aLDIljz<w4eDvr!!h#u1Q`BybeLs z?_26WE|?A1j47-DVqV3(H(jjXm+kXW932?neE17B(rIg&T@BTlDLN^jl|thYBrha} z=#G}#Qe_URpuBj7p>fjviyr~q?}CT`A5Eg_BKQ8GfwV40=S8@!M@b<`-L?o7QY`b5 z2EGiH>1ux2v{x>)Lf?9Uy0zrOg%Vd5o&Q?C!}Z~7d{L|1-?ufE9-sX8+5Lw!)aHjH zmrdW+lQ~9ww#v4`IW2Ev4f|H%kM$HHOq!-F&4Wbt#8|$ZEE~mZaAY!-tw`muJWOrc zl(k7PCapG*3}jOv*AvZ$Y9_Hlk?}%txtX%D=jRM^?z8lzGooBNcjyvJHFCdDG;5OZZOM6qbJ6BY6x7Yb}KM|FRGFwct4IQ-NXMGwhIrDcFFcqq+vh zNJ%1;wb^J7wBxw1-@^4$%LE*Ci(nY~Ot>0dg@MR~dADt?4D@?oc_t9+a~F2qL4%Eeac;Q)T#|QqbI;@?l{^D^w#jeQWjY`$uNk ziI(a$o^0>g$raG|cl@ut{T2QB=X-*qxjpx`z3LdFi<>gkt5f$`=AFnmjFhm)?O_!a z$drN73NBo;Zt{Azf6{m9lOd!{@Qq%Xwazg6)Y?xP^^4o~Wfg5>qmgjI+#Q>qXHwn0 zkDOlQ&{&kqUy5bi#*BPS@=L9=$e$F{&!b$MTd$zS!W(zQ(^rkm&76PiU~`^!bi4el z>O?Eudo!{LOM(9Apu87&zGU?Hu#~RgTSGj)Z6ygx-{a2y>nEKP|FcKPwPOEjD&UD) zPRIuC`_0c`_z@JTd&yR}da2VR74BcgCCWKj=bdKAt7>C;MU@9f+?IJ%%tk3~%z}r0 zml1Z!TZBlK7QT@w`;#>f589x^>E(7w27iYmE>LilUb^X=<@;5EmBp$xM#00wBI?~Y zbuoB-kDZiH{%aFk1Y;efiZwv_)M?OZyXb>j{>uvoYe!I@=;th`1pGU`$g+Qz9e4fh zs-_6M5o4p)jGjv}n_J)3Bc4V94|4vy*jL&P&3ZDd*igspNRZ!g*5283Bg^k1BjoL|r>!Gj9%DIOlSN-E!9672f+a$vY3)c=bONOiF0 zd3%K5}izLEuPa-^KWJ?5-)MO-}N|!|oab zs8?H$M|7GXTsRf4ach*9qC3l4xh; zDdllfmAsOJ2#b7V=rH|mwjT>PgD9siD4P}8)X!w$1hKif4Kz&J>o-gfuwzmk+ zCqwiF5rOO|r)0L>8s<-)3A9^d6S&P}2{q#xf&kz#fXo;k6>s>I#$TDloBV7o*pI79 zt-|1&8FJr#veh=vSRx6<9X!|)(p->30vahZoc3D5nU#k0*3Y{4l z?FvoJOnPR$0mdj^U>@JzF980$w5tbFO$$4v_&!k0j%p4ma5+3|PTntPu=IAQ6l#nQ z;)ib>ZpIIfg3vYNVKLW1)j4{u{y}!;=rnyM?{G&4^XXlDL13A2bW%!M2uL>1ge6hy_(B%8`baqA#g z1<2cPLbt9>^UKci42UpyN~=;32D?ksd3Ao6L#K#ZD$|;rJ8^K8P3J@1!^2GzwkX?z z*nUOgux7l>?mD4&*;<~`;M4}U{&fHz!{=7$sJTB%5Ovi%yefK6{&Yb}PN_F;8b)3w z1C7>^kv7Sjp42Z;q<<{?&tS}kB=;WV`aJy%aDj*@){I^!J;p0M7_Ca44$QH^IQ`Ii*rMQC{HZ<4~17{*OtvQn(`MEa!9+Bpmkz{tmCeimOe0 z?Sl&~i&h$2yJPwD5i5^8?s9}Oyes6qmMd^}H{u-mF^zYemZ`+NMb4k~6=nTbqcZaG zUpEDk)nD_`U83q|lX3f5#Wv=gl=N`>Vp=Qw7e-7N7b-Jn!2lTea4W>1_5QDEyKlXI zO^_AOh5c(frive(wEC|$*xoQve4coEvA_m-E3wgm_G^)|Gb)*<0NTf6Rl=i9^?-7G zI5h_O3@Z014Q@0^*B9BD@?zsUgcueSQ8CiPov!FyTNl7i9NLg@&Gtz#OOmF41d7R%~vP~_79 z(4+5E1XnEn@w|OGQ^)A6HaOXLK-VJKPaDf{<<*x7FX)Tika+$^aho4=gQ&_cVRNcF zdj4(tIsylHBx-P=A7E|RASnB?uX)g?ogpQ$Y&3@x?g~w}a313B%RdHTOM|)ba0=+Y z4L2wBX$SV@N}+K8+UQf&kLlnbW>||#6>B`5$U%cSFHAxsu($cEV81hqVx3{U{y*k?VC25zs-&Kow)<>$5 zx)IQeUTfe1^oh-B z$zs#~F%aD1j3%y9<=9@oer$p4p1?q((l1V718%2`=s$uhxk;Nq-++++(-^YB9=|Q{Z+c0ZyJsKK6v~eH2H_x$ zt9;+lgjWg!y$uClDu*LFZ52rmu++N>~O8@$^lrlQ*Lf5X$oE zi5XqsYlBjR#DvrG*-cDZz|}xWtig{IWpXH<9I)9?+}99(h|_a;HZN9z*$lzjp2<=<9_9N zDIw8dnUCJz46yv**Hp-UbtUH$p-);gBn? zT9k>k_7vVr3;7B5)!BO=5A`N%Iw!(F5F=!jf!t@OWt&@{A66sSBT{BMSmPvT`ij3h zerhSNAC^R*<(Abu08hra;O7;uN~jG9?6{p;C+dS#2GGF`C?k#?AtQ=1ckiFpdO`QP z^-*(chZv#;010mobNW>E4GxnQy2j@}f9b-6ny+zTL}g6gY9QMsqa&{=v`P-2&> z&n=xBFnfp&U1pVB6}B##Bi|O;FWDH zP?UlB#EHHhe%3nm<|c3UscQn#Pfo+x2^^Qo>~xHdX@Y8z(k{>%QQ%*dfAz0Chz05z zE!gCKdkDfBheDtIq^7{V-~B^H2rNg5S6fwbN1fbtjC}sgKT&y+`+Vo~EKP$8mrAue zdWlo^L%;L~GJ3z}>$kXXqHnE_U7(8OQiUv^RE+raEJ&dmwfMiv1rJ?+9 zrVmtJuj!Cgh%*Nu>`a3LWB%xmG8h;mGyXTEERZ zIRvMdGiGX2aC#pL{fvqxrAGPqYuqd;>SeJrB=y>U|5NkM*BmN-$tmEgPb4Fvxn$=$QlEY^rwQQHpRyWRCuQr}bQ2(Bk;;-;LQyAzxwB$O}o zv@|T*WSLOU9Q|s4bjerBj$k#_U}f=xCHL4Cn{^4nUA7kL+s2uE6X%V|8m*7!ei=jY zoPGAU5^GrVSR(9tkohugF?R$$XP4T|p(?F*f0BdyKW7LvHkuoHG{3f6p9yAf6*y(t z)ANqkcr>f1^JqN{*rzL*;SyS>7{fDkWJxJeuCWUC)in@bG6aZcQp!?1|0)!?%S=RZcRJpIyUDjQG zP293XilRfjI}{UH4I>B{T|{n-*Im8(un5&*fx%3_g6Bf&B#9|=yqOf zC5g2DfcN!izRB+e`$<@uwGtp8n^uP z%|^w-_PeshMUY_Aq(_Qy9}>g{&ki+32dzP=K46g_uOT+@@=&=XdhT-A%To+;5hIG1 z_^j@PemEWXhz3qwu}j|UwrTSxE4w(E-lUZB|yumDXTSx2kf~_WAZtUbz})G zR0yr3>G-Jko@v>>u}~NAlzcu!4MOqeBa}jthUdId)f)j0mtwb;8G1~M1VVpY%da2< z(Oy25DRM1TQG!o>$$T!FV3cy0dAh1ZeUM%{@}@h_n3NS`1yu>htO$!z{ATEbLoLuT zo0o8_Wa3}@k!&Ii*92|{rMRNAxvc`FIEp_*~i z&}_Gf@O|uVg~YR_ISM48q4wlgblLnhM$Af!drHjY2<6Z~_Z}F_qz`;adsAwImOIrk z@7oXeTIr3S+iuc$z|i|+FYL8nfTYtDBPJOlw9H8dmuXEk@jgg9TliZ6m8K>{Rl6D8 ztuBe$OFL`1rjsDFzBF6LANkkQEK|Na?FoCF<>W&5P8tqje2V1%sQLW6qgEuBdZ#== zO=`zYKlmXZ$c%_|><7Uky&W`kND(f&Pe~Tw=yh<-WOFq9FWAJflU9?Q1q^>E%=z??{7q6Pay_wU;nsqgZkG( z03xZKl6WWOp-;#xU?8MG!y!BX=BWT~W#t5d%esCS`J-Cqg|JVV0)RUy>Wz^f|McK- zqs&Yaua5;;cGUioqH2r}-e|F!0AH{7!}|iEi-T!BN(!h$yp88k@IBrX&NB>b{RtIf zsaXE@2u^D#G?MFH81_;ha_dvgMq&uM>44601!qi+Or?Erb}5e_yBo{Bcd?7Ce)jgy z=er8XV*h{F^{7gAb?*cbeWJg&ai0BqaW(yk@bBOEhHZ(+xZDvw(nVU?i!vD}G!T*X z)Cd@OX7UW+*C{|FEj)(-sG}k(7So6K9S&^+DAxJ@=tC9{7c1_gc|>t{uQ;#HdLI2n z{H!Hrcps%-!tM}7tpD`=e0zsGppbn&iLnaF$gj7Q#8|<|Z`eQvx<8RgW&#_IW+aHu zCz0|~Fhd=&DoRcRNu;09yd_^8Ww`a`#$Py%{(pFeyWyuS$DiNw#r|ys+2d~h56ba> zfCrml;)QI9(LYKOl7Ii4rRa`HNJuFDvvY$;u5Kh!#0H#yD<(FP=xG~k)!&1~{ug(4 BEo=Y) diff --git a/docs/images/screenshots.json b/docs/images/screenshots.json index 201c831e..ae16ab78 100644 --- a/docs/images/screenshots.json +++ b/docs/images/screenshots.json @@ -2,7 +2,7 @@ "version": 1, "fixture": "synthetic-only", "chromium": "151.0.7922.34", - "sourceFingerprint": "6d094396ebd90fad934bace295f8eee0e6dafda27d8f38dd31beac954ff93880", + "sourceFingerprint": "63fd6b17b9c24cb2f35753e6632c7be08208a5c279978306f7c6d101a0c779d1", "captureScriptSha256": "ce2e9542fed9dade3085be87d16f69adb2ac8262893ad78ad966b1b9673f2983", "command": "npm run build && node demo/docs/capture.mjs", "scenarios": { @@ -14,7 +14,7 @@ }, "theme": "dark", "language": "en", - "sourceSha256": "6d094396ebd90fad934bace295f8eee0e6dafda27d8f38dd31beac954ff93880", + "sourceSha256": "63fd6b17b9c24cb2f35753e6632c7be08208a5c279978306f7c6d101a0c779d1", "imageSha256": "36223106c073f07d8cc3ecf8eaab37192ebb2687daba65c5c21047d0b7890de0" }, "view-touch": { @@ -25,7 +25,7 @@ }, "theme": "dark", "language": "en", - "sourceSha256": "6d094396ebd90fad934bace295f8eee0e6dafda27d8f38dd31beac954ff93880", + "sourceSha256": "63fd6b17b9c24cb2f35753e6632c7be08208a5c279978306f7c6d101a0c779d1", "imageSha256": "41e3ba67f8db0e98f26f484293af83ef937c369ca5ca6a59a3350d8954c906f4" }, "space-create": { @@ -36,7 +36,7 @@ }, "theme": "dark", "language": "en", - "sourceSha256": "6d094396ebd90fad934bace295f8eee0e6dafda27d8f38dd31beac954ff93880", + "sourceSha256": "63fd6b17b9c24cb2f35753e6632c7be08208a5c279978306f7c6d101a0c779d1", "imageSha256": "0dc024726327f60f4a9ceaf3044381691f81f1090af81d1812e870f22d9343ba" }, "room-contour-close": { @@ -47,7 +47,7 @@ }, "theme": "dark", "language": "en", - "sourceSha256": "6d094396ebd90fad934bace295f8eee0e6dafda27d8f38dd31beac954ff93880", + "sourceSha256": "63fd6b17b9c24cb2f35753e6632c7be08208a5c279978306f7c6d101a0c779d1", "imageSha256": "44cfaa95bd51e2cd628400e28db0ad8b2f0cd904385845bd402494f3f5c0d93c" }, "plan-context-tray": { @@ -58,7 +58,7 @@ }, "theme": "dark", "language": "en", - "sourceSha256": "6d094396ebd90fad934bace295f8eee0e6dafda27d8f38dd31beac954ff93880", + "sourceSha256": "63fd6b17b9c24cb2f35753e6632c7be08208a5c279978306f7c6d101a0c779d1", "imageSha256": "e0662429b423fb74151b583dcc2c8635b001b637d03bbf7a6b16aec46399c3f8" }, "device-editor": { @@ -69,8 +69,8 @@ }, "theme": "dark", "language": "en", - "sourceSha256": "6d094396ebd90fad934bace295f8eee0e6dafda27d8f38dd31beac954ff93880", - "imageSha256": "827a5f0cd6f1c122a63a51d83569a2dbd87b70b3753266a3eb0a9f2986b1b911" + "sourceSha256": "63fd6b17b9c24cb2f35753e6632c7be08208a5c279978306f7c6d101a0c779d1", + "imageSha256": "d0ffd31ce80bfde21ab75da356a5fc1af38246f2b301030880320620c228d89d" }, "device-display-preview": { "file": "06-device-display-preview.png", @@ -80,7 +80,7 @@ }, "theme": "dark", "language": "en", - "sourceSha256": "6d094396ebd90fad934bace295f8eee0e6dafda27d8f38dd31beac954ff93880", + "sourceSha256": "63fd6b17b9c24cb2f35753e6632c7be08208a5c279978306f7c6d101a0c779d1", "imageSha256": "2cdabae1f89c3286e4fac0ce30f757ee1690b707ab8a5488748b7cd420626160" }, "background-editor": { @@ -91,7 +91,7 @@ }, "theme": "dark", "language": "en", - "sourceSha256": "6d094396ebd90fad934bace295f8eee0e6dafda27d8f38dd31beac954ff93880", + "sourceSha256": "63fd6b17b9c24cb2f35753e6632c7be08208a5c279978306f7c6d101a0c779d1", "imageSha256": "30147bb00a90eea7136b4cee30995f6e6a9217b5132f3e8d3ad7471413b1af8a" }, "room-card": { @@ -102,7 +102,7 @@ }, "theme": "dark", "language": "en", - "sourceSha256": "6d094396ebd90fad934bace295f8eee0e6dafda27d8f38dd31beac954ff93880", + "sourceSha256": "63fd6b17b9c24cb2f35753e6632c7be08208a5c279978306f7c6d101a0c779d1", "imageSha256": "029a3e69ec647a8a370d99e6bb7f9225833c526739076022f6b52ba54bff30ea" }, "device-info": { @@ -113,7 +113,7 @@ }, "theme": "dark", "language": "en", - "sourceSha256": "6d094396ebd90fad934bace295f8eee0e6dafda27d8f38dd31beac954ff93880", + "sourceSha256": "63fd6b17b9c24cb2f35753e6632c7be08208a5c279978306f7c6d101a0c779d1", "imageSha256": "dd492f53150b7149085daada5cce9eeae9bde9e7ea1d86679a54b3041f72f517" } } diff --git a/docs/specs/062-i18n-registry.md b/docs/specs/062-i18n-registry.md index 28142d8e..b333bb05 100644 --- a/docs/specs/062-i18n-registry.md +++ b/docs/specs/062-i18n-registry.md @@ -140,7 +140,10 @@ option с этим кодом и не меняет config при редакти Gate проверяет: -- коды уникальны, lowercase и нормализованы; +- коды являются BCP 47 tags и уникальны после case-insensitive нормализации + (`_` считается эквивалентом `-`); canonical spelling registry сохраняется в + selector и точных именах frontend/backend файлов (`pt-BR`, а не принудительно + `pt-br`); - `en` существует и является fallback; - у каждой записи есть непустые `nativeLabel` и dictionary; - каждый `src/i18n/.json` зарегистрирован и у каждой записи есть ровно @@ -230,7 +233,8 @@ Schema и persisted config не меняются. Миграции нет. ### Unit -- registry uniqueness, code format, English presence/fallback; +- registry uniqueness после нормализации, BCP 47 code format, English + presence/fallback; - exact/primary/fallback locale matrix, case and `_` normalization; - invalid explicit config; - registry-driven dictionary/file/backend parity; diff --git a/src/editor.ts b/src/editor.ts index 0c7f8b19..a5a33719 100755 --- a/src/editor.ts +++ b/src/editor.ts @@ -1,6 +1,7 @@ /** Card configuration editor (Lovelace GUI). */ import { LitElement, html, nothing } from 'lit'; import { langOf, t, type Lang } from './i18n'; +import { languageOptions } from './i18n/registry'; import { invalidDefaultFloor } from './card-editor-validation'; class HouseplanCardEditor extends LitElement { @@ -97,11 +98,7 @@ class HouseplanCardEditor extends LitElement { selector: { select: { mode: 'dropdown', - options: [ - { value: '', label: t(L, 'editor.lang_auto') }, - { value: 'en', label: t(L, 'editor.lang_en') }, - { value: 'ru', label: t(L, 'editor.lang_ru') }, - ], + options: languageOptions(t(L, 'editor.lang_auto'), this._config?.language), }, }, }, diff --git a/src/i18n.ts b/src/i18n.ts index 3ab4f924..8907594a 100644 --- a/src/i18n.ts +++ b/src/i18n.ts @@ -1,34 +1,42 @@ /** - * Card UI localization. Dictionaries live in src/i18n/.json so that new - * languages can be contributed without touching TypeScript. The language is - * resolved from the card config (`language: en|ru`) or, by default, from the - * HA user profile (hass.locale.language); anything that is not a known - * language falls back to English. + * Card UI localization. Shipped languages live in the typed registry; see the + * translation contribution flow in CONTRIBUTING.md. The language is resolved + * from the card config or, by default, from the HA user profile. Unknown + * languages fall back to English synchronously. */ import { subst } from './logic'; -import en from './i18n/en.json'; -import ru from './i18n/ru.json'; +import { + FALLBACK_DICTIONARY, + FALLBACK_LANGUAGE_CODE, + LANGUAGE_REGISTRY, + languageEntry, + resolveLanguageCode, + type Lang, +} from './i18n/registry'; -export type Lang = 'en' | 'ru'; -type Key = keyof typeof en; +type Key = keyof typeof FALLBACK_DICTIONARY; -const DICTS: Record> = { en, ru }; +export type { Lang } from './i18n/registry'; /** Resolve the UI language: explicit config option wins, then the HA profile. */ export function langOf(hass: any, configLang?: string | null): Lang { - if (configLang && configLang in DICTS) return configLang as Lang; - const l = (hass?.locale?.language || hass?.language || 'en').toLowerCase(); - return l.startsWith('ru') ? 'ru' : 'en'; + return resolveLanguageCode( + configLang, + hass?.locale?.language || hass?.language, + LANGUAGE_REGISTRY.map(({ code }) => code), + FALLBACK_LANGUAGE_CODE, + ); } /** Translate a key with optional {placeholder} substitution. */ export function t(lang: Lang, key: Key, vars?: Record): string { - return subst(DICTS[lang][key] ?? en[key] ?? key, vars); + const dictionary = languageEntry(lang)?.dictionary; + return subst(dictionary?.[key] ?? FALLBACK_DICTIONARY[key] ?? key, vars); } /** Whether a localized value exists and contains useful text after fallback. */ export function hasTranslation(lang: Lang, key: string): boolean { - const value = DICTS[lang][key] ?? DICTS.en[key]; + const value = languageEntry(lang)?.dictionary[key] ?? FALLBACK_DICTIONARY[key]; return typeof value === 'string' && value.trim().length > 0; } diff --git a/src/i18n/registry.ts b/src/i18n/registry.ts new file mode 100644 index 00000000..813b3d23 --- /dev/null +++ b/src/i18n/registry.ts @@ -0,0 +1,88 @@ +import en from './en.json' with { type: 'json' }; +import ru from './ru.json' with { type: 'json' }; + +export interface LanguageEntry { + code: string; + nativeLabel: string; + dictionary: Record; +} + +/** + * The single runtime registry of shipped UI languages. + * + * Keep English first: it is the synchronous fallback. Adding a locale means + * adding its frontend/backend JSON files and one static entry in this module. + */ +export const LANGUAGE_REGISTRY = [ + { code: 'en', nativeLabel: 'English', dictionary: en }, + { code: 'ru', nativeLabel: 'Русский', dictionary: ru }, +] as const satisfies readonly LanguageEntry[]; + +export type Lang = (typeof LANGUAGE_REGISTRY)[number]['code']; + +export const FALLBACK_LANGUAGE_CODE: Lang = 'en'; +export const FALLBACK_DICTIONARY = en; + +const LANGUAGE_BY_CODE = new Map( + LANGUAGE_REGISTRY.map((entry) => [entry.code, entry]), +); + +/** Normalize HA locale tags for registry lookup. */ +export function normalizeLanguageTag(value: unknown): string { + return typeof value === 'string' + ? value.trim().replaceAll('_', '-').toLowerCase() + : ''; +} + +/** Return the canonical registry entry for a locale code, if it is shipped. */ +export function languageEntry(value: unknown): LanguageEntry | undefined { + return LANGUAGE_BY_CODE.get(normalizeLanguageTag(value)); +} + +/** + * Resolve an explicit setting and HA locale against any registry-shaped code + * list. The generic form keeps the fallback rules testable with future-locale + * fixtures without registering a fake production dictionary. + */ +export function resolveLanguageCode( + explicitLanguage: unknown, + haLanguage: unknown, + supportedCodes: readonly T[], + fallback: T, +): T { + const supported = new Map( + supportedCodes.map((code) => [normalizeLanguageTag(code), code]), + ); + const explicit = supported.get(normalizeLanguageTag(explicitLanguage)); + if (explicit) return explicit; + + const locale = normalizeLanguageTag(haLanguage); + const exact = supported.get(locale); + if (exact) return exact; + const primary = supported.get(locale.split('-')[0] || ''); + return primary ?? fallback; +} + +export interface LanguageOption { + value: string; + label: string; +} + +/** Build visual-editor options and preserve an unknown persisted raw value. */ +export function languageOptions( + autoLabel: string, + currentLanguage?: unknown, +): LanguageOption[] { + const options: LanguageOption[] = [ + { value: '', label: autoLabel }, + ...LANGUAGE_REGISTRY.map(({ code, nativeLabel }) => ({ + value: code, + label: nativeLabel, + })), + ]; + const raw = typeof currentLanguage === 'string' ? currentLanguage : ''; + if (raw && !options.some((option) => option.value === raw)) { + options.push({ value: raw, label: languageEntry(raw)?.nativeLabel ?? raw }); + } + return options; +} diff --git a/src/types.ts b/src/types.ts index bf5f007b..88924883 100644 --- a/src/types.ts +++ b/src/types.ts @@ -273,7 +273,8 @@ export interface CardConfig { show_temperature?: boolean; live_states?: boolean; show_signal?: boolean; - language?: string; // 'en' | 'ru' | '' (auto — HA profile) + /** Registry language code, or empty/absent for the Home Assistant profile. */ + language?: string; /** @deprecated Ignored since v1.38.1 — per-marker `tap_action` only. * Kept so old YAML does not break; no runtime action reads this field. */ tap_action?: string; diff --git a/test/i18n.test.mjs b/test/i18n.test.mjs index ac8bc0da..6cc31854 100644 --- a/test/i18n.test.mjs +++ b/test/i18n.test.mjs @@ -1,21 +1,72 @@ import test from 'node:test'; import assert from 'node:assert/strict'; -import { readFileSync } from 'node:fs'; +import { readdirSync, readFileSync } from 'node:fs'; -const en = JSON.parse(readFileSync(new URL('../src/i18n/en.json', import.meta.url))); -const ru = JSON.parse(readFileSync(new URL('../src/i18n/ru.json', import.meta.url))); +import { + FALLBACK_LANGUAGE_CODE, + LANGUAGE_REGISTRY, + languageOptions, + normalizeLanguageTag, + resolveLanguageCode, +} from '../test-build/i18n/registry.js'; +import { langOf } from '../test-build/i18n.js'; + +const dictionaries = new Map( + LANGUAGE_REGISTRY.map(({ code, dictionary }) => [code, dictionary]), +); +const en = dictionaries.get('en'); +const ru = dictionaries.get('ru'); const cardSource = readFileSync(new URL('../src/houseplan-card.ts', import.meta.url), 'utf8'); -test('i18n: en and ru dictionaries carry the same key set', () => { +test('i18n: registry codes and English fallback are valid', () => { + const codes = LANGUAGE_REGISTRY.map(({ code }) => code); + const normalizedCodes = codes.map(normalizeLanguageTag); + assert.equal(FALLBACK_LANGUAGE_CODE, 'en'); + assert.ok(dictionaries.has(FALLBACK_LANGUAGE_CODE)); + assert.equal(new Set(codes).size, codes.length, 'registry codes must be unique'); + assert.equal( + new Set(normalizedCodes).size, + normalizedCodes.length, + 'registry codes must be unique after locale normalization', + ); + for (const { code, nativeLabel, dictionary } of LANGUAGE_REGISTRY) { + assert.equal(code, code.trim(), `${code} has surrounding whitespace`); + assert.doesNotMatch(code, /_/u, `${code} must use BCP 47 hyphens`); + assert.match(code, /^[A-Za-z]{2,3}(?:-[A-Za-z0-9]{2,8})*$/u); + assert.ok(nativeLabel.trim(), `${code} has no native label`); + assert.ok(dictionary && typeof dictionary === 'object', `${code} has no dictionary`); + } +}); + +test('i18n: registry matches frontend and backend locale files', () => { + const registryCodes = LANGUAGE_REGISTRY.map(({ code }) => code).sort(); + const localeCodes = (url) => readdirSync(url) + .filter((name) => name.endsWith('.json')) + .map((name) => name.slice(0, -'.json'.length)) + .sort(); + assert.deepEqual( + localeCodes(new URL('../src/i18n/', import.meta.url)), + registryCodes, + 'frontend locale files and registry differ', + ); + assert.deepEqual( + localeCodes(new URL('../custom_components/houseplan/translations/', import.meta.url)), + registryCodes, + 'backend locale files and registry differ', + ); +}); + +test('i18n: every registered dictionary carries the English key set', () => { const enKeys = Object.keys(en).sort(); - const ruKeys = Object.keys(ru).sort(); - assert.deepEqual(enKeys, ruKeys); + for (const { code, dictionary } of LANGUAGE_REGISTRY) { + assert.deepEqual(Object.keys(dictionary).sort(), enKeys, `${code} key set differs`); + } }); test('i18n: no empty values', () => { - for (const [lang, d] of [['en', en], ['ru', ru]]) { - for (const [k, v] of Object.entries(d)) { - assert.ok(typeof v === 'string' && v.length > 0, `${lang}:${k} is empty`); + for (const { code, dictionary } of LANGUAGE_REGISTRY) { + for (const [k, v] of Object.entries(dictionary)) { + assert.ok(typeof v === 'string' && v.length > 0, `${code}:${k} is empty`); } } }); @@ -23,10 +74,49 @@ test('i18n: no empty values', () => { test('i18n: placeholders match between languages', () => { const ph = (s) => (s.match(/\{\w+\}/g) || []).sort().join(','); for (const k of Object.keys(en)) { - assert.equal(ph(en[k]), ph(ru[k]), `placeholder mismatch in ${k}`); + for (const { code, dictionary } of LANGUAGE_REGISTRY) { + assert.equal(ph(en[k]), ph(dictionary[k]), `placeholder mismatch in ${code}:${k}`); + } } }); +test('i18n: resolver supports exact, primary, explicit and fallback paths', () => { + const supported = ['en', 'ru', 'pt-BR']; + const cases = [ + { explicit: 'RU', ha: 'en-US', expected: 'ru' }, + { explicit: 'pt_BR', ha: 'ru-RU', expected: 'pt-BR' }, + { explicit: 'unknown', ha: 'ru_RU', expected: 'ru' }, + { explicit: '', ha: 'pt-br', expected: 'pt-BR' }, + { explicit: null, ha: 'ru-RU', expected: 'ru' }, + { explicit: 'ru-RU', ha: 'en-GB', expected: 'en' }, + { explicit: undefined, ha: 'pt-PT', expected: 'en' }, + { explicit: undefined, ha: 'de-DE', expected: 'en' }, + ]; + for (const { explicit, ha, expected } of cases) { + assert.equal(resolveLanguageCode(explicit, ha, supported, 'en'), expected); + } +}); + +test('i18n: langOf wires card config and both HA locale shapes to the registry', () => { + assert.equal(langOf({ locale: { language: 'ru_RU' }, language: 'en' }), 'ru'); + assert.equal(langOf({ locale: { language: 'en-GB' }, language: 'ru' }, 'RU'), 'ru'); + assert.equal(langOf({ language: 'ru-RU' }, 'unknown'), 'ru'); + assert.equal(langOf({ locale: { language: 'de-DE' } }, 'unknown'), 'en'); +}); + +test('i18n: editor options follow registry order and preserve unknown raw values', () => { + assert.deepEqual(languageOptions('Auto'), [ + { value: '', label: 'Auto' }, + ...LANGUAGE_REGISTRY.map(({ code, nativeLabel }) => ({ value: code, label: nativeLabel })), + ]); + assert.deepEqual(languageOptions('Auto', 'ru'), languageOptions('Auto')); + assert.deepEqual(languageOptions('Auto', 'de').at(-1), { value: 'de', label: 'de' }); + assert.deepEqual( + languageOptions('Auto', ' RU ').at(-1), + { value: ' RU ', label: 'Русский' }, + ); +}); + test('issue 251 unavailable controls toast has exact singular and plural copy', () => { assert.equal( en['toast.toggle_target_unavailable'], @@ -139,9 +229,9 @@ test('i18n: every literal help call has body and full aria keys in both language assert.equal(helpKeys.length, allCalls.length, 'every _help call must use one string literal ending in .help'); assert.ok(helpKeys.length > 0, 'the help affordance pilot disappeared'); for (const key of helpKeys) { - for (const [lang, dictionary] of [['en', en], ['ru', ru]]) { - assert.ok(dictionary[key]?.trim(), `${lang}:${key} is missing or empty`); - assert.ok(dictionary[`${key}.aria`]?.trim(), `${lang}:${key}.aria is missing or empty`); + for (const { code, dictionary } of LANGUAGE_REGISTRY) { + assert.ok(dictionary[key]?.trim(), `${code}:${key} is missing or empty`); + assert.ok(dictionary[`${key}.aria`]?.trim(), `${code}:${key}.aria is missing or empty`); } } }); @@ -171,7 +261,7 @@ test('help hosts do not duplicate their explanation in a title attribute', () => }); test('vac toasts never mention the removed point calibration (HP-1540-06)', () => { - for (const [lang, d] of [['en', en], ['ru', ru]]) { + for (const { code: lang, dictionary: d } of LANGUAGE_REGISTRY) { for (const k of ['vac.autocal_no_rooms', 'vac.autocal_no_match', 'vac.residual_message']) { assert.ok(!/point|точк/i.test(d[k]), `${lang}:${k} still points at point calibration`); } diff --git a/tsconfig.test.json b/tsconfig.test.json index be8d0f20..1809a5af 100644 --- a/tsconfig.test.json +++ b/tsconfig.test.json @@ -10,7 +10,7 @@ "tsBuildInfoFile": "test-build/.tsbuildinfo" }, "include": [ - "src/color.ts", "src/styles.ts", "src/styles/*.styles.ts", "src/logic.ts", "src/glow-blend.ts", "src/grid-scale.ts", "src/device-visual.ts", "src/device-pulse.ts", "src/device-presentation.ts", "src/device-marker-geometry.ts", + "src/color.ts", "src/styles.ts", "src/styles/*.styles.ts", "src/logic.ts", "src/i18n.ts", "src/i18n/registry.ts", "src/glow-blend.ts", "src/grid-scale.ts", "src/device-visual.ts", "src/device-pulse.ts", "src/device-presentation.ts", "src/device-marker-geometry.ts", "src/device-face.ts", "src/device-toggle.ts", "src/marker-toggle-entity.ts", "src/activity-runtime.ts", "src/ha-binding-status.ts", "src/integration-provider.ts", "src/vacuum.ts",

&((g>XyzkI%bNsH6K5Pvt&a;g99p0RakfbAKFsvp&z3IzPPo^)%XUQaP99 z7Z8KTv3T2VQg^nvUMnZ{a8+!G!K^;@`4?`N8q3_Cmdjb;)O19WQ|q6g6e^b|1P1m5 zF*vvhMQ+(Se~S3y4@~0w7yXzlY(07-Fs;*avfZ6JI#vrb{+SQi+D0C!%Sa#RWh>AA zm;ialUL$Ev@-?1E9m#bTGpWxKg*I!S9e_HMx5Y&2pH-{2TA;+&fpuc;HW8lNM#bxY z=~P6C65J(7fGoKkf{lH1^IxSxjxr z0pe=lX^z*OKhJv)_OFcg^LvWrJ>rx3TtL_MbK6?NwG=82vSW||!6z7He%TVsaYTJ| zwYQ=2{8<4tElEasYxPu?$dY^<#NSKRnTEH{UnhDM6NJAwURfQ7I%dEizsgCo@T%QIgms% z7!)>B>#Elt_f>Gd0kx#g!Ww%SL-E01OriN}==>k6?@ZuQ&2{N-8C9fmc-BfnZ6jUs zxF2UkeQP3gK`VVVALP}g3VRY2^cfJb7eIUkUmAlH8mt9+=QQ(5l8h1s%5HSTcJsx+ zN)eVUKTLTJ;xRgtCqrt^K;uFz1;8bhz@$DGrrU_j7B@BNm*GLuuAu*qrnk_Ft81Hf zad&Opoj~JGaCd0j8h4i{{{9UYPYtOeqZbxe*9yXD+bhAgALw~$Xi9Gjo9a>AC@)~yOI zQ1kl^xg_VJMeLx0}x`gUl zvQ3()m}#do=%&F)QSA;}8pm3QCMPRYmtsBC#Eg8r1kBJXCfY9#d|h4VE(vhA`da#! zIx{q@a&j3PQ??atR%b{qaM&ZN24xkp?qTxBLAc<6%5Ot9jXa%%8rj6de2~r%YAFk9 zw;+BgMlFw|-j{T+Rwu1+wfnXT*V)&Bg>nI41Dg;@_hR#HT&R(>hmPHHaSZ3kSEHf? zb6BwjZbbWZwuDTzXm>pj!WL$pyFqx;R;F`rPQJBN<6GOpb{9u3g_N$a4#|g(cg|D` zKSGIh>S)Igm!an7YUy*Zix5TSYEy?oy+^N$f7jzqrLwuD0wl0%RI*G)EaCfN=Jy+o z*3SRpex3C(jbWhbuJ|=d%0T5dKR4&EKJf`BPfGfNB_hJYuVc!bfxqr6_tv>G%Zxxi zH7QNK+F~m}HxNK*wR|Yp5x%rb2GGU2<0Bt2Q$uZbj0H$SYbIhxhvha~j_&>Y7)?kt(4xcafY>bP^Xcx8V`Cq)k4Xk!oirOA!?0sn+d& zGygPI7jn-W7U$JUBNc6fao$3wG5(hBHgHz(sIMUc8CmVp7domNJ(m4Z+sb2sg&5S4 z0|_1|oO%r<-!7RS$Dad@+D(wJwZR1}wl`zq9DCx9)lpbWiIBYC)h3Wu^;o>ht<8Y6 z$J6c7UIAIlFRvtFaaW?a8=Pb`%qXP~rEMLg$$)RiAU?9}GL(|h5Vi@W|s1`L_#y>ck-FB1Ku_;n znLyV5?pW`~E~MM{-;`Q;o| z&n8^EgNMA?7LU&5m{1{T_y*opp@O4h8{^&y>M`zE9T}1pdwNB)aUQ^Yx<5-_{!c65 zjE(!a9g%T#n#dyTk;_i94n~=0BcmXI{iJc}4Uyzgx678y#{Sz7ov~5q zK5lDfF~H&^!V~5^3TvcfR@Q?UId$+4$PAt9qTEHk@-7sa{S`I5_maEVdATBlgK+U) ztkoasf37Dx=hfGsKasw@bixIKBEsS!&_`|B(`U2R&!El$N!#tU^QJFY<(skk>|KzP zhoo4+TyJ49QDOi0)l9i;KH&^1mmjasy;OBfrH9SK2sGRk?r=?KIAWlT7=g(Xn1V{{ zP-Z4KZY~A+OOi-#x2GjZ>J!jC;nol{$@+IzutvBKo4eX`(gxwCrY6SYh_T6#XY5F> zcCt+xf3Ase{q2ObY2cgow(-fL%PnMR4r84)Q+Gj{eM&qM3{mFjd*#ai@9w`Ts5Z;w z)wuY54MDw5K zK$}*>#>Hd09&D(8UTvfv^!L@)MpLDschb^!^)>mz(uL^={=N2BdGMLGXp}S`etPoZ zKisau#$TNx^&69|bLb25P2r){n1=UalxSwl*SED_l=!7{Y0%@~@ME|;BZ_(1 z^AjQYSBbk8`THM=h7BQ!#>)P=migpH>b&;D&kdvg6iAoe^oe>}0z_x-qi<{n)fRcn z7gT|%Fr85lFWbLr$itiEG_5i@!u)$nqr)0&`iN26YYJ0L3@8iKWOFP^@ET0j=6W*7 zLCBSNAt;qceT66Wi+l%OPVU`zZ{wkkUO?M;j?a_d+vCqZ0Sh6DgM?Ck-X?8pjp>x* ze4&ezU)}4?2{HwLWQJ+drisNl!buB{3jyZEKRdd}yqwVq%+Js74;^_Sz0B?PMa;rp zB^33PoC`)YLy&CwoD=|Im%MC%wvZ>lJ37u+)5C<-eRlbmDC(oLK1u>+EOD+*50M@5 zFH{Nky67=+%Se#Ijo@T>jimS49LaC+lZ!>vM0LoZ>;p7cwfRe$S|ssPYV0$!*q?My!TV;qD-Ot7bLz-qK*TIj{-_lZ)BtC|lg7mN3+w&XM=ilRwjVhJx z0C_U*Zq$S{drY60yf;-a?T4qtB9_D0`s>x2+=90ZCK*WkEZED2ksRN&^u)6@^9XyG zIQg`d|Dj73c7%MS1kI+C676FH(2&f#i@|_UD)ZmyG)O$Rj4C{P;%ezN!Mqp(N6v*Gcd+vt4`KR5R?Ia% ztxa(yPEFx(Gzg~v&M{zU0jC#0vqQn@80~^_=AvdKP(@aG z6_O=Kt}i7!D#X`c<)O_TR1{mn>SV3<<7>AeAzaaPegL@16YeeE-7da#i0QAfljZuN3c=OgM zjjx%+Ya-(PZWK8Iwqr8DxYY7zo7=ljtX1&yj&(`^_5He`X2r4Q?~4Qp^RbHX0r)iw zmhU#J&=#Ua2|loN2j|q?3;NTRhKQ#d_ z4w=Lh@e|O6QW&zf&wx@GDpP#Gh0vKtl z)@Dx%W04HuV2(xBwjE`RE0tT28jfkPO3D?JfD*DOI_MQ*{6)Qr%5B*?(H{yg*wl|f zsYi`zuO#B|KL!X^c8jFg|Jl(CL6UdR7G{3A%gw}$3&r45{8TON9#(cbq*`*?lM%L6 zjMx*;j%NgM#;#HENq8AsaeL_;CE=g7v?;p~7sWh_G9Q1*p@#M9I>Ul*??J~@?zM~` zPwGg=8Mb5A$lhM{$ZO``e6*05_?i9UBit1)S`Cr-Ump%?O6VKp8r|9va0A5S@;x`jIIsm(pLg z&$!+)m0iQi)&!@?eAq>f5N4<|ZkhY-nk+_cd$*=1AN4{-x0qL4+;)E_nnN`(>-!RsWfp~sRm@~-|!gA{|cqJ2C z+UBeV&T%FF)1etN#*9A2aM1#ERQjF{yfLcWDD95bWZkg?&FaYvB$@<_$^yW_Q|Tp% z*j}C)(Fk8@&&DTOWA4+59aMPql@9&ZvrI~gRBrB8W1|R&r#a_{Wsj36w>fk0YmqPR zIkNyVr|t&=Skhex;7jdANvpbn2)RNsya#1|Qe`1FPa{IE9Pwc zS;RGe;nK9$5VY6XANJ|^%u48 z-V^;c9i5upmN1;1ZU*wL7LE2UPDQP+W(!faU_n-5B+g}ug2lx&;vjS5r6H1SKq=-$ zg?B$hX@cju?Skz)-^%BUs?$_@j$SDs6Ino*o4Ui)7UCHM#}nPRcyA{D>3EUmCF8HQ zv_lL)Z0&Zus_dUOQGFw=31`~lWRL-CwkR2KI`-CZRk~iSF2YJ3Bv(z2h4q;>&YWPw z&KK42!F|fI;OzcCOXwZ@W6-7@|{2Cb!cwiD0w`+ILo@#XGe=0hXR?H zT;;4QxayCZl(cU3kl+^~m$n4_Db1WNO?g+SMey?5+Q6~MbcwfJ=Y8xX8YZYKv<6X= zVl}}kCqB=7gxk`iE`WE^nX{YJ$lP0d$DE zuCT@Jin(?DXQ!vNK%Mg-Ks7KGjit^NW@JrZ|3VTYLoI&zpZ4cpUq9XSl%?w^Qg}0*O(*AlkNkpv42Gfp79wdd zJ53bgXUzdimuj96bM?{lqEIm|`!em7-S0J&`F`1BiV7#f-&oIOTyf6C3M-s!w`{r{Z+p)v-V*z8vV{bVMyT-#d?y!bZ7gSWEv<=C} zh*)*fPlF9J);vhi0l~@5C^+; z#s4C3314anUU_7QY;&1OjCB(ee1hcJJ+H9=zx;vzB3;rz1AK!e=gRaQAYfv@$Rlf+Flq2A2ompTyrM>A-JnrXR^|v241-p zPphh{!FyJ-fv4@gcL}R?T3wUN4#|_=HnOZ4XQQR+ox;e_rMUtvEsAXv`u>q?3`(;= zgUyp$<`Bs7*s>rL=tm=eQcb8{S;D99z)0)+^Fh8^12icFXW2E3?SYUf=GX8$l$Goc zf>v5Ih;KDPbuozHY#3)#CE_e%05_#X`wL)LW4+gW5`zT}yTvuNSuR-fqps|hM!g!I z0@C#t?#}U~N20U7Ar)Njo>hhm$uqr{q&OO6WAKN1uX2LKK^N) z6&Eyp6r=_ic(BbkvJvJ7U=zL^6t5~zQP)5(9cD1sxeTNEh}rU)5)#JwMTd2o$DL{B zA_AG;} zIw?%}_FLU>6JBI^k?b2P9Jya5>hWDWxD-ra$e(e!ZXriGkiqLSVU1$5fdK5QU}Hpl zt%VjJ9j#i6kj#rEgg=4NCGPTCl7~bWfD@|6P|J_pzL9-iWeBi%vqmT#?2oswTyvWP z!B}dj{PL$Wck2T(o7`cPekZ-#R7cFtT>LT}Dw&@SI5-%pQe%5hLwFUOQ0wfFG4}Q1 zIH=0CbRWBKcOP9`he?q;cvip*4Re}fodV8L2$X99$C1V%@mz6KI7kujn=c>#{<=Y? zdQYM2*`es=!B3agJL{7E$$!i^ZFY_9eTL|oFuxJA;Fy_)_d&NU@~G4QI=ZGmLnCVI)V#mR!dW~7I zz#rV{&RS$lMV-LPhZTL0eHj~41@{8Ch_nh(@}|PzP77C|PI@)bHDI|XqStD`r$?5$ zM6>F>g-s$yx!nhp9x54BqcS^~8+!*)F(3@nxfx-A{Gn{+SrcWEv$s)3$!kqFjG9|y z_K5;w*Lk)i2%Pjjc@Td2^S5KM@Kf{%z=j7;^^Z@%xF&8` zOmIgYml~3+NH9WyUdDN?7{<_vrV0bJ2vnLcVX?Cm}z3cs|9HAL=FN#T* z)a~e16nI{vv$Bf{n$FxMANK5R;$v5{{nHtRyFEgn$&Lt0`~9haGcNKtYWirV4P8#D zoh$g%$K10B>=p-n03S{FkQ?w<#act$_jYGQUoDQQFWlwYvS*3)hMVhbryL{HbtD`^ zL(bwKe*C*T?7fBjnOQgM-}6@741zRVP26Yh{8+>*HLG2pC~cyiBA zAMU1$3&~S4CX{+xk`2f$bsm$!GEwu3S{|UG$UIjrCpV%ft0K-)*=IDA9Z-UNohLiK zq+812zgv}9tYb%g>A-j##PFl2DYIEOEWLgN%SqhP~4ZvBtB24S3AW8`0wf@&Ex3<7kPr#D z zUOekE6Ip;&k+mBS!G}>x{Y`nvB1Z z^CDpCOw{xF>JJsWV;jG|9$dOI9SZ%G|6kglqD4ohGshSod2jPKjULWQ^}493QEHvh zg44iJ)XmPz$KR`DjSRHH)19r#Q$E! zu0wML(A7u$KfuLQH$^$>%s-n=uUYFf5G5t>!xj(x@a3M$HAkMqb&WN6vI}wG?Oy&F zxY6I$+-X$)OjLx=+T|!}B^JcZBta{5AJIEp3Xvk0Iwii&FYTn2XJj2kaUe%_Nbf~m z@qR7^CZTc8l`JqkVH_b^5&38^+$Gzc@n@Pxs~}R_yNB^V1~{CSeVFd*I+}>;C}MuA zvTLzzoKCzvK#Tl*22u#|hNWY)95 z4H2+pbiVmrj>_RhNZdz~kJ!VnM#uAZsHPw6J6+ztOz82oo%)}@)OHj{>uHN)Jk}pg z>hyw8TzUp53@{M%*sfekefwX|;`MwA4L9Eh2&@h5L*7k>et}hU<8*^;Lg4_CZAbc1 zI!tqRBe%6+Gg3~IiT5{-8b%4-OLN*+T6+S#kj-N|b$2%^Q$H(?uE0IkuMf2<9XQtO z5hY>j8rBgRL+lvc3U5nMS#g&VOHHKYjAw9TvpP$QyVK0`jrGCZCo7VW(O{tRVPi_)o4>Y_54GVgN-ppH)j&E`GMkaA zF&DM+A+ZZ8XdU3pVZ3&QbEyp4RXhaFNs^4C*oFogyZf0CKis1emz>P8s3C=7tnj(- z@TRbl3n1wbZEqyhxIhx-&)v{+Rkh=l*N5wb@mRO*?0n-~2y_L!0-=1}L_I9AOuD*w z5Iu+tUQ%3~-DJG`WMDe$E+My??0|)#Kn||dhVY&12qUo#@2PHSe1>-fT^P8O z`6h(MAzUlfI;D>f!U*tZ`tmxsCB<7z@SWS8eT6OirTo*I_r6{#>Te)U*L67)`xSl} zWywNBnN2vxdFuqQ0f#iD5Dv%V^9V&b3Y-Cd37fVN6F~r{Lg;zXn@?4aOS%&wd$oeK z!h!iWCy0S{#Hnz#!vo1&q$H48FC14eP_>|Ji#u+@n(xtEqu>b&Kyxj2D;s>`3U;TTb`rCC0ON}hi~V37p3arklv@!Luh{V_V1mGNC-2Ln%%!PC@Juq zYKc8dsuS_Vrx#l}d7a9kr-)HqIH{X>jwFN%$TCBOVPf7uY{=Qm06p@x{9G7-z z0d&t>i`)`P%&}N%xt6e{-(}gAvB!rLJ=qhwtUwBhUpdbgeF5Vedb9enOxoayqwIZR z$OkR*&4;LE0&3t+&Xnuk;sk#+#<|i%* zWtpqq1?M)JmA8|I!`Z9^?AlN6L&@C^>01=NyN;2>>Rq>YcZnPi=_uA5co1K5e!mjh zt4N~k8*s}w@^wuBy0~w;~(T}?)gSqPmu?&1KGyd zp|xskt`?QF6WEI2Bu^JPw}*?uXVuBlkgRE(1%c%d{Rn+(%ni~>9#WpPdZ1g3EtW@H zB6Zf+lb{oafTSCtegBLfq(g5)4d|P=^L`b>)8|HEj@Mz|#Vw}fn#_+by5VHcwU|*( z{`^_PTSTO2vgX=PQO_3xk>SwUbVO6u zX5!IELR-mezjImn`8ClvHC>(+zI4$HExbWVI*T;#X@a*Jeo$d{Pxtt8y>+c$`t~^R=N+0D zHUS+Io7ul8KjEic0^s|3PXn|M+#o|L@#Z`3Y&rzf?z}^I=eb9}h4b-0BuPn#3;6o*FXzEj}Gm*fIAh~iLebX>?b{IwD^G{HWkmUw{+8I+wR5<60Ma|SRX2npDD5d`VAC9 zD#Vh7;OzuvD>*V4NcJ2%PG$vBL(=Z+VL94h9a{-JXe|tKZ#+Swn}XA)VExJ6YbzG2 zRd{V-!-Y{xj|N5qg?|-^0LFX4-(lq69yz_X8OR74agBqC&`j1SH+MP# zJFUd;9mM5l#b(wDzH4>S9nZ-KVadXt%!(_}R9rj7Ks{u+& z;y4k@{%L8t}Iof8DPHUZAbmZy{r$XOBO` z6=Ett^`nen`*6F&LQH^e>7zxOy3vnc7ovn-9LHW5DeETbpTdM$zZt=Ebx~~I)%9ooTll};wap=9zIie!jI4tB>=j0>p-9mE6QPs&N__T+!!KL2^pqXiOAfCTjkh8 zemRoNAX>o0Or8T=HUO+EkRUU!$|ogoo8H7tuBF#pa-jOr^T$OTHF0B>7dpxNRIrlz_p|Qxwx`{~zoBbDKl_KX zEP~DIxRrB8QzrY~ihjh_ms6s%P>k)`zi=k3yRC?N%7=MR0XVMZq zvmnTQh`OBOddYu;d3k1eS>joPQp4TP8D3Qq&B*Bj-el$UGtqn!Q=~Y-l0&|p)52&v zVJ0dPXYn!sN6hRSCH+u>>)qz)Ri4SeA?wwnOo8}BI4LX8E+jWY^N8tP`=m~f1g z_}%*Nl`q4KjICatOX${Th|WQiCBv+pF%Y|cL6xiE6*fCrv=*#SQyG{yT2;43ohORp z-gZMa8CMG;``q0zl5t94)hZHce<4;d;;GVC`2RY)Z$%$2S*SNxpAL?{s6W?H)tP@3rN67M3%*MK)T&9u1PqqmQ<&~u3Qao z2*i-UHcuacoP@-XkW!Nq!GJX*!N3C7jt0Nl=Ave+1$sS2ODZZB%=a0pLLmM+aB&4HSBK zUw&b>NMcCtWRw@%HL6nZ*!Q!LMJtL6%iPxbnq(Xm;wZ-4^@=p9C;xT&#zXf*BdiRf zi5Mo7oAQm*Kh@##p<3HrlUC=7ka074>m%Qc>0J_wi?7LNFOSqAASvap3$$im%cxuW`hUL_z6-KTx>>t28s{rk7#h)PshSbV?`M$jT@PB*XxmF!u z)(`pKZB$MI$5YMR2nF%U<8E5kuq@kK))Ii(Xq3U=Km$N+`V%z}vZk-wc#(ui*CUsl zSZU%f>YK@R1M5_Ct%SUNW_>i*vU4=k^DD4y;ry#e3L# zHNG$gWW2V+3&rXnSe3Kv!89|Q^MiuPHI}F&tHo)hsrXM6JIm@~)ja{!rlcm0S*Sg3 zv&2^=dNmb`;%x1t`|fjAcpq_VYMN^*))IOD0u($HlWW`$Bpj2ni{76+W$LwLpu&iN zeSu>Q%g|uSe6@DFXUQxn=<^)hc%*>b`C297_=jbISVWW8npN@J#<)IPqgr|Uk0tBW)3mP zLbLuN=F`U`Zz~?J%y9hR%h_B#Cq1Hzo7U3z?q}9KC9P6?9AI|&9j-QfBA%qX`aq*p zo8uH=h8R#t zv}`5az{E!y`hMm^5wti_KUy~Q{V5HH?-^h*7`aZ!*^NMj>C9pPEP0!C{o#LHehT+5 z>llwE1Y99SS8a zPM0`(EtP*1C7crqSdp~fsd>BVEL^zf)tN23NKhf{GB^JIW;?rMsk?flPF>Sd#)=sR zl0St+w_wfF$I(j_JH+`0efN-!bcyL*VNkV+BL zP~8PcJ!+Ivu*8(GpyFvK#Pm>+U7CsvJ9=FSmwhdriN0Uh%v%TvzR6&HfIM!0ER;9W zn-HMQX0zJi?UdX6@yMzo$%x{9bfO=!=?Wd?I>3zbg110Dsg|jn1kl|a#_%|Nlgm)C z{jr9aS2xMB`_7V`yCb6*B*zi1Q|Rj<;elECPi}&v{)MBbO1a^5;sV!=N%|lEdt_+9 zmPk}yn_Bdl@k@QMGhX@!Vbm=r+$Eu-@CN}~kp$C>(K@K|R#7F2QBuw--NB z88kQGx6^rpj;T+_>F1^n+|*RXKI<-%$i9Tx@4EQ8nK80>a6XAP_?m!~Qd(6wuJk6D zyI(f52Gu`Z`<|!i1Y8D>Q9d+gua^?txX-=MRKTA3>zrcNBV@vcoeTww{v~u$@B_)W zq=OeyfWi;w4!Bv`%`5QAJHRRt0VRmN-4`_NJ6AZGp#$LN0W)8kBooH8KI^}~7ZMxb zq`=hVOi``+EHhhW&U=b{AHis?mEGU@%MU3ctV?r#`13@$FFGE(X#|{p(&sHOsm{{Q zRVmCfDjkeqb6?JG!S0e}&R7Rm_SarESC%&R*m&HGat%;<<$;-ieBbUSvoJ)86GWp0 zs$>09bEnfJ)Sy(2#(m`G6Q<`DOAuGGLGB0$sYyYptsx-*N3_%})ffX}<-CFfBoxWM zjK89}u$LRHc{qsl0?k?kSJB}CPRz@vxmC{bU`V_s13~y0VwdvKw3U9<7d0mNb~UDrKWJ}@6dmKhU+6|= zv4bmhD?iVOX!K*cTi(g%{1&Gc3?b{5KGK^+A5`ET`%4}Dka4nZFDI$#d!G`VW>@@# zSPC5Z@|q-7{2@SALt@b*Fh-w{YgQjpLac0Nh#R%<;O|p^OA5GUnrk%+)m@htE6I*t0 z_W*E6xjlTSvB9~2h`laxwDUAGOR-JQi+R?fl<%UI!A61XQ3f4&60^c)%jdbhTSw+) zv@|g z*gVY;u?u5Z2v|jiL=Prl0VL@W<^y?md>kf;M!&O-zziB2AXYf*S4?~S>ILt&7~Un> zH%fiB!_NTiivp@!(9)>NBxpzKltMVQ#FYN_E6DgdL>R0=T5bFJSmmG$L2=0U)?HGf z(wK1N+x2*p%m48AQMqYq5VYY+AyAo*B>Z_#MV}9^TIpwUZA%2hRANiN*B6;89oV=Q ztMo}AlB>Df01J(CL~MGk5c3zu9x)CsQjXVkO~jEFnQv7!fi-as`ol#Ewt~#vuo-H6 zm37P`J@yc2m+yalReLcHQ%4)MYXtR{@~qq`@KiNMTb|lw*!4Fn)Ze_nv;cp8MQ~AJ zpgJru!F2$YZGT3HOG$Fy&@j^y$O24LIXXp`nIlkq6}uVzUE}P|7~~cz=7Dv!(wqT5 z`iHt3Yx@LftLZS0w*!|qxN%~02=+Q4Wg_YM$_3eE9*iI8>%uzJS;!fN(Yx~O(KN<~ z>xxXFwMN2>%n~;rk?v$~lvJ$h+s~sse%FBA!8b+;Jx6Ow5Eo()0!qw= z6nkp^)jpD&O0zBHL+Nhz=7Sb5PtM{W_=#1sYN1j)aoQD%l&|Ow^NFE+%=xf6ZnwqE z{sE$Y&^mUWMd8gO_gEC=uJsw4sK*s29NXxv%O4dN@2_L5{^xb&=Q3LCx(sW&o+0xj zlnZD%lVWF07`Sin8}AU}U5Xh5z(9Kp#wi1Rf<2S%rl<|K5o3Z{)yFOz-$DEvkVm|&X=#khp9%%$9 zfR9~fvz^~m-k%yOBEdk<2^;#RZX78?GBl6s?pc`u$Eos#a$L48+QV7qWK<%#0}|HV z5Wk$afhJb@-I%+x1b_X@h#^^VI~Uue#`JDv&{e1@>qpKRts==(Z?E^>Hq?cq?CB}~ z_F2}|m?1tUhsU5vC76(u&wOTOm~brV&7Mpj;7$x zr|?P&wZF7?d-XBqG12y+Y6~&&K>fd;Kx~nkPh3t5T)I(bdo4#fUVE31K+2ec**NE6RLA_5In63+-b1GkTb4 z)7muSen7P&{M#1emfP^NDa!YN_=qdSm~9b<)@NGbhfrxw)HWBfkXtvQ7sy6%bYB`6 zu$fM@gdLrVFVsFrE&ek$Wa zk$7Vwvs+#U1#j>vm#HrHf>i@I?FD!t=l{#R%uwmL7 zU6Rzf%C72&E2vfRwTpt5;FE$h0xW+`O8;(UPDQo(cLT@`Z>$Bf<9P*xBV39(_B zpB6dWU*H7`_h1DB7+I{5PM4{eVxOsTRK6sm$r=7+{rWmOH}!pH_y~R_nedm{cUg#m zmnll4#zn!i_%iQQ0Bz|h^_IgcB4--+hqevpt|iRya}gE0rF`^Fqom=0;cik+Qu-H< z%J$Ig3=PS>YyRxc4^*Dz2qYcEOOGh8SjwhjJGW;CQ8!z+LBAfhZhuEL{P(gyPGKO% z?7}q>W#`;eW&%-!z#zId14pn{TOi3}eHzw&FIHk6d`E|6lM|jRyM7P%EVVTVBftE1 zm{*H1NX9EwJ^4W-NM7Ngjt5?wW#%Z;53RhfUF#KJlrwl%EIwf#^y)0=uyLot>NPXMh`$8Gj2_xuBCZzJ?1eAUhmr^s+t zxmx4NEz0HGGN*A$u}ja=ZV(;TTDia4U4-0AS-Jh6KW!KTdh(2jy*DB1H%y#|+@ zl|g@+8$jR-Ko+uIcSxiObaSA7yg&q(*Bx^OeNBrYFD0`t!_9A%6$?KKTlevpcDUsy z;q7pg$Ibe|V94CS_s0kqW60}346SFN__GSR$v2?Od=D>hpkV;!qf*2^MWtamonRm`r2;tB?2( z?zs9WE?-9;lQwf95E1dr8iMwh?EU26R;*>Ab`yYD* z&5Q*I4oruug|~m-2J#c6Rh0KCcBNycMr3imjL!b779LMs3*tQx-qa`{{Kq&o!4T4T zA9^Gq#r-L%8X=(3d%lf~rPSE1nq=yaiS&$(nzKO*17T|`WJgc-H|G+@WZIE-y=*`8 zl+reHi}z|meFi;46yteEc|bKYT%)sW%BtRi>}7Wl88SbZ)fzY5&%_AHD$%P9R(AWl zoUwBNB6PJG@%trlH7cwiRWR}bP^UBtnE%Zg!?NN$cW4bnC>NoVU$U*>E>J68#*MIJ z9&Zh(?2v=FNKf=#*!eZ=v?x5T2oXH)%KNT7lP|2^lg-hcGd2}|*DSTKE{0tn(xWLU z-@^L%%@efuuef6xy;{o}5jS7A9c4?zp|E_%u)vVqj2zR-kC^CA>-eLzkzIYR3 zk!a%~#c1ZTK%#6W=6BT*B6odsMMJS)zMN(l-uVy&mX>BG;Bc{+>(`d#e4u=#xeQ9O zeB8R3pFK42URD*UjdBi$GDH>r6!0D6(%Z9WJ<~4UANJv%{FluRFoS{WmKtGz7tjO~ zht+ePX1k17+6{QPNAQV+7Yp4$w8UL=)t5pvc=Q=Mqedu{7cXEEp3ju^6kNy*Oa3p# zCJM2m%CC6sC9A)nrgHT-I?UUj^7}OhJ}rC?#6nP;6Z=&L7@wE(6!kWh4DpI;ot1>N3k1pI@&Rbe#(W$i zU;t=fZ;?Aax*&3SZt%w{__MB-pZff%{v)K4=)tMpi<$Pa;nuO;kmYYtYFKnr)F0Ot zoWU2(EeKgEm+aG7gY`zw1*caKQjfX5sU5^N8GT z+&5!NcCte>=9JW?ZahBxR-EL-qfVxf&D>c?;I2wbND)+&zQ>8j{Aet+}7R$w$l6-mJC_bGEMJRGC|dK{&%x&cP=i$)-LW%mh>>CrF3x> z{@APiz#ywU(qxJ@D$RFXEB6X3%y)Wby|I{W#rmz9=gjlf8gr@GA)kNpDChbq`%g~_ zBD9&@4>0N6`P`E?I+%v+lJ^)DxLu_+#9L)x=#2R5X|gbM1fN_Xau2pi#bx7 zoOo4-PD@ZuM1_)I&KR*R3RRy>ygVmkYcLzfkqAP{)nt{9FE-4+0|>K}#s*YIryDkc z3=n}DBT=B5IwczRlxl=H?g5z{!o}CWBuckcta&DB^b{6j)z=&cY>dK7v7F^={(iNe zR5Z)M`=d4&Zl7g;RyUOTQa~`DGAyK+9-haF%bM6iS(7%YWhwu4DavHb_PI6WKwi~B z^mQ~dQr%3g@$9ScUm}W)Kyx!Xf3-VAG>@h2g1|7M*;)YgCC|T$Im!&MTPSt{X~H3~ zANuSLQP74QnaIN~id#NxB;{{YmjP|ul@_VS&M9)$q*GaHbv|AsqCkvT*oEM;{#v9& z5jETVlubsa{p6|~gR^;Q=d{5{%PFF^^eY_Wnez3u($c_A6)A&4B-jqmU#JJM#J3V2 z!La8#jx`&M4((c$kM@6LJuzo)wJd8VA;KaGsJwAvA$9knjL=nZd@?ab+@efZu<|E} z@FeS*-zu<8nT#eHJc79BukOTjFd44&G?grTPky1GP;zX0F9%6zW}Kr=kJ0vgzy0C& z5isAJ8sN_d0x7lDagJa)+_tAC`YuLEGi5)OCns{k&_NZb`1UEji68FY6uV>9s?sTvJ*?n%}5v4o{T8z7$PxW<*~ABJ~@$!;%s05 zSlo-miUUMF9H#(VP%vKwE9Pk2tdpbEe#H-$6PvNdv#O*fW&-Pgj8s2J`47>w>V6pV zsU;`6#=Ge+TJ1f_q)E!7)6r6$7D-ogA3;lRbP*NJE)I@kCMVE0NYeqhPbFo~lxYSa zWKJP@16ipth~g)DRa-%Jn#vq>_!ic1QS1i~M=zER`FCrIYR=J;Lyi>-Q(V#1qhN%I zSDFW^$zd6k8*jp~bPfy=TjoK>zkcc#;z8-QMZ)!% zPc1|n$wKA!^T|XMqUb8j-;4;G6ql4Z^p@rvXfkc~D~(iWvq(m)((ZU)K_rJTp*e56 z-eSwlLI{ee7X4U>b6>e~td_gC8kBbpGKs!;&N6;$n}9X|7rsCH2K0)^%ge(S(elZO zRiUlt?^_R@RSZ_lgob2dz^|iPVnM5!`&!H?k$;!}e`LLNR8()+{tMDLG|14M5(7vh zNT>7=l0ys9EwPmtLOKMbl#oWcyIT<{Vd$0y38}Nc@9+1nbJjZl>@_g8`H5dS&eh;bJ0Nu%;0# z3xeQkP6RJIFp1IOk#aI#BVmK)VN~@W%kP58XVe{K;ft!Cg(9)ZoC|m;dZ9kHx;r2)Pr8bz*oCzNubTxV~9n)KyNBg^}1O zrMG-)7AGL`2rehHcpZ`W3J`AYEY7W}x6wwMznP9*;txh3JUl$yOa_}peX{WcJ9rWr zjp-+i&0<}=eMi1TQ6yXK*`xUf|6?9cXs4_d^)Y`zwuQ(kMEBCO43P9<^ndY%_>+jk zWv>SA>%f%;>8)t>3y7K-1UQd|1@+_YylWW`o%|hGI?QR*pt&tB1LRHNE|7!m5@VkH zV6H+AaIw3(Qo1D?@LyH~{aa&j7@M&BF^Z-Bz}^Z0{{nGaM^A?E>etCPnJ9rQEQxEG z#7l3|5Hr=}+)eSs@W%DY(OLpWjT1AVvE*FqpW&V8*LK62NzRb7Zy3F^EnBdsgsWfQ z<2J=2v-yXa)qzi`qS0&Sj$iUzKZw8u)q_Ig*1ZT@n!D(a*D77v$*^a=xvh0tZPIq2 zGbRR;Qd?>Jwf)dZ9 zn^?By|0RfTZniQ6OG!xW#_e=GoLrm?bDev1|NQpLtcjNXKiOsJZY4i?imj!!P#|Fq zDd?mA^`SP+0E>0zG0Q`XCzm(s1mw=Lt{RD}Ke{lqzj*E~WMlSn?^i>&88d}a+K=Bv z=YZD6GU*G~4=PSSBGdj?EFh=x&rLrI&8F#+-KL8swG#efBK^6_c9%^uB#UfmDZ`lB z!K3VO3Skvo}?t!~F@ga*H=*`d?UA%AZg?*H=m~WBda3BRRW=zm4%; z3}a<)SsU(hC72}uRQ$*IombX6l0d&4c<{p}gYsy;5l{YKdVJYPd%z{=mIAJCd`12z z32QUjU@!78cP6w37q45kCRi&oOid_8G_(|#^O5m{{kXqcKh?zEmcC77eknxX`z41S zRZB?~&oEQ1(+N zP9m{}Hg|7|gVxI+fNtI_C(2qUFv+E}of^ft^K1HRlJPK_1cZt@Ib68Iv}Wqi{rqK> zxqvWLUc-A&jC$jeVvB=S=XLeSK<8g=8&OT)ueM$Ciy02w`-UA71Lci{Gx#X!UBV@_ zD3!Di8hB*>Ip|iW(|qE{{f%7w+{eou`lF!c?`aN8GJd{46fmSvFFO@*TWBd?-nbT>S5(M6M{d3GKoZO;6fD|S|9K3SP#ZgpUZI})|7vNgps5T@ z^t$=W4_G{`UeE<3KCAZ?vax76UA|C*e@Nb7LAoolEX82=cgZ9rVe?lbA?M~*A4@M(k@w@j{EWpKR-H(F_i=_(V4=Z8Z;q@z|ssNd5&tG^5vK6 zr-;;jw=qZ6IEXluJUI|o4eYkp6!24hzL+4ZWjQ*PvKc!V^tI>lc;ix%mZWX7#vy{Z*VW*?wGj~sd*Rk}N>1gK z%&lJk_&QcDx+kGW-{C%?a2m-eKl&b^PyN;OW=l5Jti}1*V46DZ_d;`y3Pra=#?%7! z2Fa(8a{T1K(H{q_6G8S(MeR7^LTtYpyrF#gu`mZ$lIAnJsLeuY z@D7UqV8;e3tx!PHz%ANGQ96L);=cb}qqHuBlB@xP&t63lwd@*9hln;Cv-f@g-U&GW zgnhzUe{nQaHQf6-)zV8SW=aqS7MFX4h+kl43(3qVOB)aLR|zSf@<1C(e}BrmcPIr5 zb&Hx}MK$Od$SG1mvsqCuE6WL?NZ04FRWwT3w$NM=vr-AL-bAABuTRA8&^K2bijjSx z4MI`6h|p$7{94-2r&l4mJqD!CFXow+4NE3Iz4MAgUEK*KmHvp`)F8BB>?$$k|444z zJa!E0hArVv3#gu+3@FdhX6=2>k0SPH>gFc&B>ndDL)udo2E#ZrC|<%I9B)E42;+r^ zGVyB*SYo8U@v#2S?V%JFM0zfnZQ+NSxHp-aKa9pc?1=3>)x9(-8c+t_cN6H~!x~al zClC4#CgdOVSidFcqkaR63yU@<`I?sLKeB1`c@#7a%(uuX_BK?UOYqjU6EGSW<+FYn zbakm}Gp8^Z@-1rNYMe#yZLQO7tc~UsXRyCSQ#LkWty_%iY4wRve=Ihnk}?7^<%!mM1wwP&;UV)BuwIP~z@^sO99-P6RW zd29cjtmlo!DKbx`wFwNngQsTFB*X=9g|d)g5!VaFle6i1et!K_gsKzeKF6h*`dXDy z2tzZ4&uQMkI1Mlb!<2NEQa0A%NQ6`oHMvz{U8GTGYIK_HXhI;Zh;pDzY{7`~`^><4 zhf+aV>4_4^wO?YGK%^iK>tr*gMdb6$9Ro2Yb5IXsxq}Pqm(MGPu*t(Ko-KA@uJ8?W znV-s`6f6n3Nkqv#wwYVV*thz~-7B62@DEG=!o+ea1vC{Wa`^ON#7y3g)R=Y~y01^M zWnF9adE6X~zM6IFK6Ak^a;SlO)P-*rx&#^4lc-;CIp`4A-#hCx-J(xqu%EW2$Wgs8 zXSKKBFlqQ@@*IPlSw4s31;m#rWR=aAq~TBqU(NOzqiS;_cIVd73`g<1aXD)3udFM(|%h0~)iD385Z9v@fU251Z(h5d7|@7F>8^~T1Vi)W182Raq1UdB718cC;Q`b|1t3KM7!_fH+?NLFKs$(d^~PkHwRj`l@l@`ufc zu2%3fiO=dcIojgkySHACKgt?!DMsuWYuY;ev2_RPF-Z27UR^bhbReUZXeTSG`gn55 z^^A;)>AA9xDK?z0D;k#r&SEXf1@d~G4AX( zzcjF)(X$Q>hO5D1($JMAY?O&Zo}Rilc0{MOL5FKXAdm5^!RyT-EFbfEi-CJO2Gyu( zF?gbh^;{H(c1n)IIzk+cJRsOysVl(KZ_&?U5O|?h{$Xs84}w&oSV@sPx*?}iHDUJb zcK}7RrMha-9n0p%m$=Ornsa~hNw6ApmsQc7vtvl%ZuuTH6OzBbrLh%ZN$klnA`7;Lg+ zLcaxvisEl>&I@&4KKWl|v#mGe)o4HJ#Hh0z62f@M82^-J@irLLD$}p`-c;@}?=&#! zJ@H{K@b3M*Nm7YzEu44eB42@vVfel}q;yP3@)Bms#Yci&IrgvJ#+a@I*h;IHmal-Y ze2j~n*b+(mEm`sjGHoTR*5A>gxtSVX_EDJB-ri=EdRs`J+vwM;KPlkdo*z6>j3agt z2F*2=V1+v7G$u&ywWHd@X6qNtha1k zjyQDxH2Hd}iaueT!@+YZJRiSxU9FC5zvOhMe8@Y>XEIxCCdy%WDdnla$aqOAfJ%+a zdctYLq|og1N_(vLBfJ@lmsN+yzV@fBZNnI*ox=7ow#*}q4>IZAz+$}JM<#fY&nxBU z&iC@GTj=Jm@27oyy&Q?xRYiR0zzCwp(y>OyZm7~!th6@5Gs|*p4=kt~dIQL;YcDmt zThy-v=lQ%`o?idNvSS%_L7u3eU3~i(*tT8L`o@?$FO#D<(3R|o9}{iKyqi7^(wnjH z`j3~DKQVJlb<{s}U^38ZYd~?M$;KwF4w7POx{W2qUg?Q?p@JP>vMF|ac=%+sk5M!`J+yOvP4$RsD4`4uebSQsnDYq|8j z`eyO=Hfpr;8+*uF7G{dpd&ED3ALcHtepmcoJ^uz14KN19w}0!hN^qwGdqP1nkKU^W z#s8^Q-=2VW&C0aLNlR;K+)lAODRu6Ot%W6Usz&wjV8@r5?qJ5ikEJ;0F@#}F!BW)n z@6KwoUuSE8#9cCFhtWe>EFKEqPdYa_G~YY_iRc_2v-~mTFAXmz(mad-vyM6^{U^-t z0~EhS+WF9nP4NG7;&zYRMJlJ9h4)T{W(DF&T`mrzOXguS^Y5`7F=P;7vr!Y{PPRw= zM1?7!q*kNUWm)%^Z6E0v8T~c~5H%Wy!SBdLczLn_<2u?1cUgak&8S+PH@86I<*zNQ zg;%W9OLoh$EISt(V~eXs(LE88l_{y9NwIM$_?ydK&Aze8|7^5D8W^VN(QK}iD^dku zgIu-LDoIknf+8kVNX!n3wI4T&Z9N|uH}++Zvtw&ttoT=EIEM@l-LUoz9qsPb%Lv=I zfbmdYpyT||(&w5Skx!^f?%Pda`|Yn2qfPIjIIc*tvEBoI>D_+Z(@-8g?e$kIR2Eo? z7ImCo`IwsjxQ(FM@Ss;y{t4#5`D}z4mIAHFeG$f3>{?}xPE318$`*M)?eYe#cPaG) z;K5Yzi>+Ii6rSF>mv_4EDmPg0;jzyk3y^KzI^KH``zYUg+!mcp){n{--RVB6L8m8D zBKcYuZTMOerB-jZ>wuV>U>Kv?2x)Oqc|CR^rk-Cieloci5JYjUbFTkyV|`_UO8U>7&b>LNvz`0Cgfg%&nzY0>>_I$)UGUfF82$ zL0;o(Y7b2#p3I(5h;du$+CuX|YMV_eEWRedDRP_XQo@pCftnUwca`Doi48OXx{n=? zWN*5!{Rx&CdK;CWfi1FY`80k`WCMg#xSxsWaFAy!5cMH>-X#nne+bY|7r!IUq6b?eIbd^`e-W^Q29uTr>ew>nBzRf zXU2rLgTjZV@H306ov`p}pkxY>C$aYMx^3pyuQfa&y`e*5343Dza=v_vMosVXUG=MB z4Ol>AF9N^F++oc`B(k`6<4ZAj1eaV8KYK$GHPJ`ReKox<7OuAyZiwpD90T%b&pfo{ z*_0KUl(-UH3JugVwzQ=kZX&GBtI{X;s%$vHXWrIx+#^Yl1+HPST1`&rOyL?w=l%+U z1HrX7N`gGoUv?lszq?8JGKKw5>(V@o35^8S`!cM_$MZtDbtA6iCst)N-q>#z&11h- zlE&~YvPIbHXYr|js(kX&B|h2%Za^-BcpW#Q`qx~wepVa)pqG&xqdjaK)%hb+ zvx1;~@#=l5CuY?1V;f?TpGkZfT;eN}T~BCF6m@Q3_}>kz0Gsu|kzZk9sAMT?_2_j5 zf!Fd?AH6gaHASLpSWQZz?OyETG&Q&%5V#w&9_h64loI{RcwPAz;ViIH7o>1XmslUj zHW5RyFPJK}q%0f_IlUFgPvrU3q6mAoJZm6B&Lsb#D8 z!Cmm}dJ~n}FKVC17%z-NY2!-PuFnwXIdqnZDjG1umTCt|InPCkZH$S`e}%2YPSLw^?N#o5NdZE#s%^2L&D_2P zrG>)e5ZxIg28gDYC zW9s(7fJCOdGbLC7+p8tA){C}IsouL(oZ@viD|SeSNpghf_#3TO@CF9v$NmwU-mTjb zowR{cr>87SSBN5ix*tC`T5T*l{-V}v31Iom3wTRDBQ9>HMLtFyt}zAA}Z?fEbfws2+X#= z;eYA4$6tlR4YZFSIMWMR3+6n<9SsK^fw<}A;D_D=u*t(+iX?@2 zIN)$;0ocBazshNEKPc6Zmyncv=mlDjWbSuZw50AGa0)=wotqeKHQ7Kug7BxkMPNPP z_AqT|PVHf0$9M;V9S3uRPkxW`ySTb;^7wlNjv2f?+%2LHI=4G?qCI5l1TOE!V~1-S zT?7gi9VZ8K1ErlO%!7BYzr4$KS#<5Vxi53=2slWk6lG7QWv!fL0M*k}AT6iU-&)ju zc-L#>a&c}UXm5B>lIQwfnZc7k;H24Jg8Fh4a&8|UXlM{U5L;X#J)xzC4AF9H}K%Awmi{%_M8H;Qrre-E$oJ#~IUh4rtz*C3h9 zgTZpn zHtU!LmJ#Fmv8}Q5A;MQC@NX(*(}BlFDH)lEyH*CNi=kK!2A~|{X8=QBjC`Q16uYrX zF39^v1>md+P!W101h)lk=WEH>&q;#ce6mxnGs5UJ;q)^m;Yz`gJXHc+V%a}r(X(?*1B5VthWaeL}?hI>f&X9FiNO5{i9g4WtB@6H6)DjaHwRf zCn4;2k3YfJLN8=N;GGH^SAPx6hTBj$8D@u#t)=-P880m?kyE`Vq4p;ioFy+s5F_6R z8{1w4s%ckSTT$`y@St*UT}wtr{CPnA6#NQA>4JQHlU44G!LGZT%j?a*BkJE#8v?Lx z?lHjb*4(@cepSG;+rKSo77k|1oLrzl`$csx+)~uiMPbl2IX~a}Z!Lb|VfHT$p~cEf zlt9x4qQY@*->PiQVeeSuYL0d%j#@%2v|Zp8L)Ln6Kv7@G#i#itq-gM|=`|{O%OP6y z(_7b{6VFHI*>q+|(u5r@*y$lTmMEE$c)-3%*kME!E%Y!q8L5K@4edb(W@xqg17S8h zH+=e)jyG)6VX zJa_H5P>V2OY|m(%!w6Vy7GHu~?pbtR|8o-?t5ym=1>^KsA9fkq=LMRoEQU_@7#>dl zDl-hf{Vo-K*Kgt~b92tSduEG68Jw>*U`>xXuh!hXc^5AY5{>VlcHVDBZuejQLXWzYFtOd^T->zG7-|p7f4$;Kt zZhe|tf#agid$!gdah2t}V;1H6&U^SQEXXVHbRvME<9M+a1VFOC@}fiLBf_WToNpX*=Rn{>-r zO)zhK!LT-33k7-%sVwZz2dkxJ4b6742Rc_PwU0l!3 zwUyUT1INz;2efPltxx+6mjmw(E`d{JS1-&Au{=O8#SJi4MUGjgSE8>-`T4 zzK3_a-$m!&s#0+|DkOk`Hj1QH!5*Z2M{|&sDSf%{4}R4pbe-x)!cve8f1ABz3^m_ z@R<$1{>R_KB4Pf{>c1Dsf0ERA0Jgr1n|6wWpO0<}@}&~0rO>g($hgpInYU+u!DpYpIz;>LxkV6b|4cM*VF8svGnt*M;+tGySAVA)Pk!? zI16sFvNFeFJBUvw6!g#92X}><>v8!EmV#F`jGkU=PL0O1Jww#uC}t;2^lWTO3!GqR z(gmj$TQ4uDbU|w*`)_b78%Sl6!2hALD?n%X@ccZ##f_q`!sTw7#Tm;Fl1WrYK>W5> z3cxbJE66#Guj+u4r7TTYQsKZX-%Am<x<-sTYJNS-xdMp3ue!zSAktEwm&r z>nRq5VfHq?*D)o53}eLA8Gy>?RyUe_Z>B>EHxULn`W^0UY#4s){7p9*BsdFi8nj+H z0{6X?;cBDn$>|Na7jjQ#EwafbgKhxcR{U=jYXezQ6542)^)L5W!fW5jEu}^xUGyb|di+e(HT&?BM{A2WoYH zY^lduCyoEgHmD;y2;)Mrij|Kb;C&XaKEIhjWZdJ1zHAes>a!64q7R0eu;2_RQFIeK z=Z?tZhI3;1I8M2xPgEAETDOD-PKry+6g9QUL=F2Ob7z%xeeDGc~ ze$0!1k(!EL;5~aIf+5K9n{V^^8q0tOd5H+l@jl@j!Vk3>SJzv8H@HvwsWpV@iP`M} z-&u?J(Ccy264t=#xWT*zKfBD?;AfB%Is@E%+9D9Y*Ias#7Nrbi0}N@$8()pZV(F>$ z4U?Ox{)X6k_d>xruC!EriV4G`_h4ij!{p!pvp{)&*y%7gQMhcC&da2kbaw~Nx182` zr9P`KRkKRhwB*S*e2GAp34#VG*t4|wb?tiW>T!282@nfV6vjE5Fv(YhY?}VVdGC(r zaggp${Pzp6VQ80B-#Y{Z|5o-2Qkea}i&@9n%~_`f?|EgfGhegP$hZhGc#wP6uA4p~ z(w0r@S$p36q4`^5{SB%%MPrKTcQ?+$+8iQL^HJb&h}IqH7GjsE$ZQ6bZ9$e%dY+!VHL-i1JPRNmi= zEo1JB${GWt4o@zE$oh5aqI!wJ>WjPf0^(Y+im6nDt1uNhN zi#W~6*bi25%ctFIB*ae{Wm!kP-wR}S=o?Jhks`?NYbq~cV$eEG(%QVv3T1|1l0!b1 z%|8zYZT7!@$^LGi(6mQ|K6vW?d-{NfA$ZpIZEW1m z?d=<-E@^MLyLk9No7abOS?B%T)f8N-ic-PCvq_&z0d7wAT@lE7%GMEkS5iohJntXh z^k~)$;Yb!TE-mRC9q%5MGV*%gL<2MK81{-%HhaT*?wC#DiSYLuZ&wNkd!EMNj(eDk zap_vuJ1iFa=_SO6t~B*X=Y_@;|INIc+Ool4koQTSB>2Jl$JbL3WQg$*T6y~q{|S%_ zZ_Q^{0fe)sZ;HGG3)|h>g-(XX?Lx-e#B&}M{m%RxG@8uwq5aMpE0iNzjRC3ed`-J! zxibj@vxTD5r|e@xx-p2J7`m-|hdXz^apX=SUs@|6Z`&Xjx;zmw{vbo3xZS#;UwlPi zi+riT!BwuQNY>3bs!p%>@u`H|2}h46H8Pzi40!Y}k}v81y(Ylj21Z;2%(As^2{D#C z5%cT$V}%{@S~O!txNhFUwD=k$P5RE59Ql`aPs^mPLtN8NPZhR5?TZ=8#eM&DZiT=x z^h-)JJ)^LuR;nx?4FzM$(2{6(4q9GgV^`2%Zz4WNqsZydE8TY5K5-H=_y8VRUCCIf zSBJIZVSr=T9WPUm0*At*RUBQ3?GX&uYSmMhveTa>c5gNa$i3-yGxAL<`JbP>1bM~RZ-c)VX12c$v`=FrqL5#cU=__Yr zEYSW}E%Y^Ug^eHQzAO`%2k6i4q5~J>FSQfm4Q;6hCYor~reWHt{S7uyt%P{Wa^_)m zbAv>j$^ZZ91rD^sgTpMuWM{Q&G33PNPX^!GHD-0?UyhEO*pWE-v(FcAX?2hK z?T1Vu1S(hHnFu=q(rPX1ARTQ9>uGnd)(NNGY2X>o%F%v(>V9jS81D%c0aV*) zv^@zws+WFdp%7iGqGs2F+de^Rr0Sxlu}RmN&|+(C2cGZR=K?1L0jsv~8dn@H@h0GW zM)Iirwx`y_B=ffKH1{g!?ab|Aw(q5n4?VEIrJ*KRb}4fk)}8^1F~JgKQ>w!OUy{?jaA;UATIQG4cjPqys&*604_e}2#^yDrXUs;S!bUms6h zk5zC`{Vdn)y+1$uc5!)Bn|g)Zs#9G$yNmY)tEf9l{?p>bP%pp0+nI$UnTK;d$yO6_ z6)CB+=b4$w|3{XH$PM&)`}Y1rS_{vx<|^fK;GlukCA0l-0L~=QkH>m) zojjk~jX`PCKVt|w$EFk=e|Gqvknk-%EeA08Tsf667jVCNkquVI893*(1z>^Up3?ti z((l=b@#)4!3=^v5?^SGjcHF?-og_n5_BfItRQO85#4Vo`n zuya;+cCPHBpTJ!&i;EcHbVK7=yeg`y{u;?a4;1_nxZcsLoP5gfBg}`Bu^f1bAs=#U z-NPql^6qFpT?15JBs1^tvoFOqTK&(IBG~*JLQo0YInC3PO|&*k&AwfCu>!d{UzzTX z*Xa&h7Mt?BVK`B}-VGaI+1K3Kib9W)M3cFv{owNqI8@FJ4h{_bw>Qe~^_+eAt_zif zI1@{t!yqCAE++yOnN4ofZK%`KEmZ;nT4|wP&kh3^f_unz`P+}Pu3A=E&(huAocA7p z#UW`t_Wa<+q4Z!GBtU9Hnq5i(wr>(I<755J33A)p$^a?t7Si&0&Yl~1Ki&PF7Ng%f zi3$S%ntFqwqI}yQ=`iB`Ac05W_PJZbiL|VQiC3|;_07Yckuml@SyUJ@_c1uvhXTic zTst22OvJIRf+35Y-xHuB-_&a%`|gIi7bxo*l^;(x#=7Z`$VWR45J zT0`1Ak5C~0|L(uH=(pf&)s$5&2w*SCNYuzsekzbWX!I>+@AY^zTKaBVX0W#q7)?sq z%+Sw5aKvnO4w}ZV*m&a1@UFfsG5<9CCq?VQ_n!UXj{lD9R%0XkQo6L(s&^H=y|MsQcs==6_;}Zc%zf;bxqf-|ZDdMc` zoK(1Q@d%-csWAP++|kjyzQ^pez@3`Pe1M6tM{0Ttv5m6Rgub-$B70Ns z4(Cd?h+aOGH>wSrpQzJ#jRg<+RP47Q!M~h`OOAhpv3WXa4J3Keq%jHPIJ&H_(W-l_ zd$dBfh5436sJ)GoQ0HU_)xUIJ6G@LqwVHWP)5n|_Gv1i;NYE$u)A$}*10EACtG5Fc z%Im^X>{98GMFliJL*iBC&!~L|hGs9)Q#P{(%=QHQR|FE6;2&b%KbB&D9REJQa?qw) zAOS(?M2%sLBwB2ujXdqW0mFe@_FZ}Ma!3^h{Anby|Y* z?km&&Ujh8p$Dv(hfe|&vz~=H`plu25)h>*;wIq0j1AB%^s;B|*)2G1tjw$>2YLynl z{_pPf?|~QQ34ZJKhAZ1l4>PX)%NBR2PCUM-=1$WUinlVzf4f`-@f%* z<-4&D^brxt?3#1i(4&=mok3mmsRVqi0}6BAMA=6X_^qNg1+yoK_WX~d9n$ix8_rMx zHzO-II1%aqZ*`5^*w+wIilKuyuA9<02Zd?5Nv6iy95OF8%ORtoIR*x7Gr_I8!>job zlf5d3R6{ zwC-zdyM!gH7Sf0c+nX9+aQU$gA+`;#3?+8S(ZC8|g?MrEx}U9k$hL_Ga_<}v;N%%1S0`_8xdezDr$+Bef$ibk_3LTjvEsnYz{>*6^5 zIYcbm!k;xu5N&{JZ*@)6+OGUOAV^JkAr?lavv?7ULS+WDrUEVRB_7-qop_v!oB5Q9 z){6k5bt@6WiL^3i2G_WW*V-$^ry4z9(`UTcuUoCB{dwz>eoJbj)YAA5HI2;`%8*> z_!D_s6p0w4t~{;6SGGr&PrAW!_#bosGHS&8!{T7gcAe5iR#41E{n zqBpA4O&+5p&4q#u=mb<#dV38}^$c)^O%B-`cO6U8s5U?k^KO-B3oWzoQup)j7wQs0 z%uOgTN6XeSUScy!I&+MOBto(Q)3cltKe~v`o*|jQh)7ac-1olgSOJJIF<8bc!TfC2 zX$QHW5zgMgt2u>6y7=&YTepYr9x{-u%-_K zND0;MD!5(tXL@ro2z>`NMm|rpvdjJn!{hZ7jJWk1oSRGUA$M1x1?Y+!|JHdYd&j*t zFdqB7Ii<0+wY|Ezy}6$4Q_X$|iBV|x>`OJae@yOWvFmT6>@()rd-0!kW-AWnMC<2q zSwq*(>;<9+kb5CaqiQoBXxQF$qtlq2PPE@GT>AN^7%Cra69$f`8b1LOq}qs!43y^^ zXp*bBo$M@M;A7vs4+Vy(xu;=;R`S(q=e@<|QqdCyUrL#Eo)oElN~5tgC>q_<=7O%H zV|y(S%9Y>hF;m2p)G0x%xwDOA8xKT<0=(?0plc@5#xo8Ha-3ySB~?6RrmK3gxE-`H zXM|xwU(|YFaKf9mcT7z^{Y?V6e#7lGu%iQeOMR-a*l4nEmVoCj+i>tGGblf1$T zrM95&nK$+!os!xo7{jG3-RgXrj0CzTe^!rUM3Cj&C_HM?qsg}qF(S?7QEAaHCrU1~ z`tv=6kYJ0v1~as!+;cMMl3k~?B#enTdRP1$u}H?ff?H9C)HN$*NEHmS($W zObC3&=v97X*RqV0QT@7J^@o}Xr%FMb>VV{=2%;h$ONw4-q2-W1<8w_9y^EJJO5O=@?oQ$kl!SF}5{*EWY6152K$l3)*?@D+Lg8Ou23U%K zkyzFK72j!9AL*FZ!4MN4;@*VV9$7!QNIrCcE24>Y4Zh9#6xn@$d8bFRc9_R3uJm~Q z+_Yj)vVp=&$&1u^M+Ao2{9!~0SBR?q-P)@(VuIB_Xh~tH{vN8B3M}KyQ z4(vh*CWhAP+mo8-@u>UpnMThG_X)RkI)0_R5$XX}^z|3C!B69o;}En%#~R&k@ww~z zzP3nFj@5$r5cIXG*F?y`8~kI_;w(b9qKiWC(nYxoxeMx-6yW3VbOAZ98PmArGE@!c2Ji`vYP>w?@gRgBBZR#FqYLj+#a`m5qphkVy0e^@yP{ z)Vgz_SbyJGx@EOn+q2`w9+0}jZKb8TfqlitCNZ&|;&*biTY= zX}a0?(56kT2H_glEPQsCIqDmjjWGx5fX}K){ulYOQ<55jc~7zIZay91(~(cZ+@9?Y zF$37_l;?lOKh^F-~BgaNP z#d1(LPPhpRUm32TloVO%IFkWM%#D4Lc#wkR>(rIbu6<)~N>0Q2J6)lFSOvifAC+jW zI%G=VZ5#LA{t#!3PfxSD2&|t4SY}iE@K#&uKhb#{Y88e|laiamh4XT01|9ak;eIq4 zjqCpLb|M*gvxS$+UG@c&@EeZ@ElihcOP8wS@8=QZLVHv>x@P`{;8=BC*~KH3bZIQ?Lh6ZqeO9&g7WDi<)AgU zN^$4{keY9kUD|8cNkr<{fd`l7J~)jcqNTv3U(KZ$e|XK{m}e8tB}g^)w_4unK2e>e zqNhzd^mDc$w59LO6-dI^l1lXPTnhwT zv@lNI6)UGId~-D;Ofcoz^K5E8brp#-S}{>#Uq7*N3b1y%sis+Iq(`;7TYo2w%m&8y z76zF=sa=?xY^vlBo+&--jl)JNKV-ZgI*N z0XD75+x}QJtm;4NHC${l?075{kH$+XZj`iznAeSvT7~Z7pK!yu)Mw|kHd|@m2Yg1b zIvW+0Bf6}meh7MXEqEMQ z^{ocOSJ;RyoZM4*n0I^j<=piH*T1U#;Do=klIJOj-VFK7Ga>)xC0AdF62(c9E1_@< zWACHs3Cu6}LxcU&oaTyx+zi+w8RA&^xI!r<*mx90q%glt(MSC32iz&#z`Qcho$wc5 z@BPM16S^9_@2@T{4i}WIOczY+>(jL-=}F&#^wt!pb*Yp<5$-Gm@?*qlKX5xDm%R&EiG|Nr*H>8|0u;prf1qi6(0>4WzkLuxj9bO@Wud+dWuEZLNS>oHBAe+ zPVeS;#bc=Z$6<2CmSK_vR~&%(@?5VHV+;Z^LX-S8#u7~eR{BHR>dt43Y>Wxg43D1< z!B#8qK;Zs_5?C9B!~B#U*rO;a5WhslC|FWj*+x~u0~itdB#`PZwy)JVBoOoL1*{1e zUjAG%crmL%iM!DVLJb*E!b(3rQu3pb|LqAA#+<6r*zC0o6CDT%1N@D`+tVmRT(o1Y zGOaK}DUSzPFO8lsLHMj#@u?JHer#@rj66#4tL{g=bD5FE_Rlz(DSTe=#_C>|U_WYei&|Gg zgh|RNBJ7ii)*H~i=_8Pm*4cT-*-Vk|x@e;NN> zEPXY+B=qJIUL~6SHKQ*jD_0A+IuSv8cu%yMIvyJ(wjm#!)Y#fy`#k4IRk{MK3Efwz z*wXTI(u{VgWxeI+t`7%+tM?}J&W?w)-T!LU`e)KrQv-q|GMCz0AJ*wk@YWV0F8z7q z$}mP%0_Vnn&(yTJp2l?oxEA9OfBU&HY$ixb%ygTVP+}_^hSPCv(>QjDq-H3$C$dMI zV%QZk(6Xj>9Q#?+KP5PK>Zwha;cMtRYYa)F^&_NaAtLOfeHa;DKJF+fENsLAY`)KG z7a|8~#4&ods$fl~!AK4ppn_r}sJv*9-G8a!?m+%djS&TKsPm+P+pSj7xYy2fk`>R~ zQ2f{hjwD4M73JwW$6o#A#-968Xg^&A{n!`khAD3^rpZXot;E?df+@zQSQ%Lqw*#DW zMxd3?YwynHw;AAG8VP!L(!V)7G|-r8F}J~CB`!uus-B6 zL5%1J)Tr+D5ii(rv-D=_BPJ79g+tyq<1m+jn`Nmg@9gY+nroliQ5Z~7?gZdmF3@G3 z$+27zUlJXjF}(ZsD>Zsn{H1nZnF*-o#3|>aDMg4ssl%=aebrSdF#>Nwq56xl44hKx zJFm7$V*%_2$d( zPcF>vt-paW2qeN8g;KyhS=Mf6WL8c#mEA>2g-NZr5^xz=s3V{k#0)30763aM%<3?Z`j;?1 zY$f~nPdF^G`83$3XxDzE|FxyDKuipD8y`V-s+hbCjhAYqq0RarrT-M(K@8nh){s$b zB80+Kt2(kO+0DYuGp@tS+4{Cr19US- z2`-snIFIGs1=k}s#i+b4b9|+bh&HkTjh`923<`Q%o|3{}6z>f`%0l79b(ANWdLj7@cCEzqj$`{?2;_zsCv*dUd zLL5Bk>lxSN(k|BPros!&n5A@#m^=~k`@e(kVvye@u3R|I8@_J)P2^qJ` z31J%U(9V)h3lU)P&$4@jTscA}h%GQ<{y$xPbyQT*+pg3gICOYm=x%0^7EpK zyXv}u^~Ido;Esn5nK5DUwizV}%(a6;8oJ>gm28lGJ_p<~eZHkeJ26&-hcwIS<+GO| znZg<>_IEcow1K?huhle&JbkB1nLd|0dVSeC0^iiF#ld|~ILd<}`CTtXD2j>fJ>Ivs z{w``)$)EVP^7-Ebw!7`C)X52o({0#_2Z;X z>>WIR{l2$#j~^6ea3ltnidoYJOs(g+iq5^1RF9>xY?AE?;Q51Yz7h1$<5W>4uPp-U z-hlq}&JvTg()b|`%6IuI=tced!wbnyvA|KSSU1QCBgeP6__dt$egsr|KE#gRAh`-LB@ zCMv#Z$H?iNh_yTA6a1_&#*9(>>QenF(pXvhEpSSi47ye7OOK%VcNH`xhVaL+m$p); z(S;AdyIL6yN3FU5BpB}DA!VSSm4``(p4j_3!*M=OXUZ*fr(d_@=&ou;q;I9dl(2`+ z-rXNR%`=KFI=~zB7_Gtf1{q>%e^X{K3TWD%Y{-^oA%$Lp8Q6Ar%nDu7`{TH?+YDJ0 zj*xU{zk(*20S2@CdPfsbkq5E#4H3E#$jM_ksaj*iE&Stm_?twwfGHL48bA5Ol{n9l z8*y=ev3F+YCXaJ6GEduihjN0senrT3l=^0e=Z-#?sdkLcR=<3f|EE}P^T1CB zwz4|h!}pYc0@ndDqDS0cJ80LVFx=&g#6UG#weO0ZYffzDX0Dksrq5FT&KIME9ve1> zhskOJUfL?PqdyRfX4k(bt&X3PLe(*>a5_MzZ_VqD1ke2UJ1`a-6e~#Gsa?dEGB{zJ zb(3e)5#Z?*C8WaBB$Ld0Q$(ZNo^x=^3%Py2L-+8oyzvIfal`1tXeT)V&Md-{+;Bjv zOtPx$G7pXOrNcBPme zx7`tuRa5oRP?12SM^xqrkd|rE%A(l;bL*qeZA2TNA%^`DHW6lduV1frmC?ww`+Z+q z`}-%7>)ZBfa%@9Gi(kl9bQQbV);9@FuTN<;M>Z*kDPUFro7cSBDiYV{4UehEbi0-D`Fy`}9NR=Q|JI)MZH*2Ov4b3UDvJj7 zs`!fEl*0G}oo2N)e6=xN5EGF;Cp}|p;@73;$=Q!Jkh%IYT6~SJY(;2un&R#FYK98N z2t7YHxfcTA0u(V-7DnTj<7f1h0+WXN9fFth;uAbkZ?NDX!u71eLDok77&uv!g7kOC z(I1WRxrEs0csXwhHA`cnHP6wz(DJADq{<1LvS)@D84FQGFV_OH{CnU+y#QkqvwC3z zr)doe(S&961AtKu{T5SrK^^q)EwPR=3S3+gL#J&zuEy|En!ypVOUj2Orb7@zU z)TbPgM$b0Qo=6xy%j%r&+!S`#V&3BepOqj+S>YL*?E?By>@EDRPY;I=ombT270X2u zMQsKQ+c8A?i$abMS%^&5&gx$Tned4RMC~j5u#9l*qBI*pE4^4|RbY0F9C)!~)?Qeh zz~i^;l}13)14%PN+oyaCtu1g6h>wc@&iI^eL$l!U%a0p++CO}kMv)&}TJEzzL}oTi z3I~iRtlw?%Sq6D&8K-Wz2&hfpN@vTW()1HCR|^JSL_WY|$P=lh)sPrJ$;(RL@@<5_ zyj2GNxY$UK&c}5Ub5W_B6)oH>j3&PO(NhnTKpo;BwSLd=ONeR>(~5G=5ht5W*@a;W z&BYc)rkwYobqv8Or0M7EtFJ~3;qOMb@ta}G*FpU+ffY8Kj}<1?csYY0>F}-lWzff0 zX7@+H42B5?{D^@%2!UQvn^KzAKfT|UVr47Ym_)CFjsU^G63u!+_%VJLmz1mZD7hHN zm^h)FcW|%?FP~mlqYVvrrPXb)E0r1ckV4MprN1Wh35R@6>wWf~vuYU>tMA?=pPl+A zp@8&CV>?FZ0ulXZe5d09Bd*QEY5mejdalY|yu)SEDCWhkX%_buLjKuUM!wuX)_;Fe zR_RO7wQ6Xc4D_b9hCQ6NQpD^8-8t2lRvK-P(X&LlMOtI!m#7_c>$Q89|2R>a@F@Ey zaP$Jbrm?lE`AwZ6T5kEu7us`MI@LW`pfd85S?7@o-q^Xm2r!Vk=TPB1fdW-lZ6n6QOqD_ zM2)dJhJId)+iXmL_iaKAw`*VAH0YhGQh1R!mZ8hi#(~WfX`UpdQ{gD$MAe{&&W(ZT z^a)X6dDz(6M%qT#&vjquTkDJo(l%1HS4)wpRR)y?h{>LY?4`@Jq4A$2e?rYf6UE(5 zm@U#b)}h9k+U6q1u0ZvVK6fAu{9l>HmK4Xyg<&KRrVGz@cKn@g+lEbZ8SoQFBYI>T zi+KQ~q0w^xbLwlEyhfBeBM6NIt5paz6jEASFnRTu?P*j>t!h_|v6faNkpuJ4vwoQ2 zwcxTS1<9sp?`aaxlD&`|+dGy~6OAE@n`1mgYW}Z~bP!4=EI~#xjI0DP%%*Pr6%y6| zxvw0_*l_`ZPW2nTGG;j9fA2EoSt5g}{8WO#>S*;ERctod#yXuapb7HU%N0wM@-2p9@d5`C%+(d-KSp(p3f)0iU}5*xb5sq;%|ERT~AiCVcWU|@YMzzX8z z-!k`Xt$-$I4oK$h*KiI-hX2d|XZE>nN0n~n=F|b<{HdZmoa9%x|5^2D^f$Xb?6S1W z5E(?BMmk;6j7Im;rok4-;AMrWP8AgSTZm!ds#{S+g|(vQ~Ub zKO+fpT)7Ff@hBsX=*h+46_U^V_D$YHHX1T;3vJe>{$&4fS%?wf+cSc@;i~rRc%v(h z6yAM-u4Tvk;C1-}O)zWS!#sErrAWhT63{=K(V_?*21MReio09KC;;q7XOU1T>@hpE z(P_fcjsalDJbZ-da?`Iw|CYQQdP8&BmS?6by2)l$w{I@Ylpaqb3AQb)#?JaBA^dp; zl==^d9Qb1{8w=um1E4-+z@=Fh1xZ0#(_eH4Zn$cmT5Vo&k5c&%n$Uua#EQJ3w0K73 zH}bU(hD|o}Goum5+6Tl|>b@ZUf5`>^t^aHv672GpX8(V6a-jC2|3@GC|L#Qi@Qkyn z{dzhk_m`En%h#06k(D+umCwUiEU!=pJ>x0rHuvlO$Dh^@HBv)Q{T-Z2D-gODc4q z87^R+hVjjfg4JkOB=BKfiwLXW=lEGVoLOVnukZ0Hsh&az>9O7$uB+65rUw<;*kW+=cLuf zZs%TPVUX&ESK645z;96CI|(2g0~_Pk>)Wke(EC9ymEBgYSeJ@T7wy+7ZFCwTxnMS* zi0#8oH$o?WKqt5RKDZ@oO)Xcn=3KV$gs`C~(p4%oy)=h$!rg6xP^Obl{ z0EF^1Y9+b+2%*U|l;?=Z`sivc<5C_TcE-_MtR~ z#Ii&l#80Q)(UDB|AvBREGoGKr_d-8Z1P{abR_shlK$i0rism^1doMn(=bfgXj%?-f z@N5Xqwjwq+66JQn#gSmaM7Co8U7zEi#uu>oW6L+LL%~1a{3DJFHy(vi2i*G?JN@TP z54T;iE5jvSV7i=c_=rwv+M=TdxX$AAuaLC)%jcvFBWOo0amB+s*P9_rk0e~>^T4~^8XG#;$>~~J-riw_hR~N8!n_t-cv$A= z98YV8vX3Eoyx>$ZK~vp2fiHtaH3z8&^sq^GxLE-U6dUO~6yTW%@Z~Pd)8n6+k*C?? zPa*}6(Lc#N8cd&npQJCDlw}`p?LAG?KiW49QhZgTz0mR)dp!J@MkI^W@JI(PkW1^J z7EsYPf}zkJe>^j#EpRB=Z#8Yq-8VH45t9@}&?>bg>QArGA@0v?hT^T7I$9esK6&Zgn_U8wSf>D0 zU{Y7?RLz3(It9*h_l zh=bS?BoQ3FkD~AptKZHl)C8i0m)s<^vtR4!lX*HTzF$bJiEKc5bHNh>WMGALRU^>M zP?*GRTSP`~eQgujH?z4CDPKEBwCb1}%mg$1@ zDRkl2ht`XF&zEROKQCTDtvhbwTE+Umb0 zO^;874m0-np*bb}9NxD{q#-CQ_Cp%KYu&`*_W&~;3SLXoXhW`cJbj7zEG;kq zQI%If*!>GPSZMe9d+=zzKCZ(-Il>j>I=5>osau1-!w{LlM)rU|^%3{DB1XWHS=z#G zZu2V2;tOp_2Nvh!B&eZiHN%!VQFX*)A%o%cUMi zG>|P9l_J4m|`hRJZqFKVrRo%(m5QVzcAOF~Qn9%U0g;0ZT}< z3H5Y%sXZ{}^(@O7BA4QBe0Fy@BR5Ypy_xwkTe7-jhRyxL7@l>ZdzfYtrE`jTMAqok z+y;Spz0BBu(yl)8193O^l|ND*JRdd)d+(}~KuA@{p80Ok3SMQ*GS)0_k!RC`ZT~sH zA5Y!WK_R}{MAY;rW9t1mD{LDnC$5I(=zid_dEy>w`i+qYHxc)PdS&r*vC@b4i%_l_ zQ`_6ariY1TYO57~aVGSfmiu-82o8&JJFeZuqx4Zl+6|dSd@9LkZ&Bm0ygHOcNp?x>``h1H@63>yveBNfJ+VQ1*;t3I zjKuFyZuA<8Sz&EWKkd+)^&E`47s$P}mBR3kf3|7bzfi(0_Q{3b2nz5)I^+nECHShFyCw(7{dBItQ@YZYGZE4qHZDEFWRNFD*MEVW+!`GhAUEiR0Xg05nG6-n#pP0ZxWr{ z8MD4tGZ2R2A;j4SVR^7pVm#MP34~eDoq4x{+ps58{s&36VR?R+1{IE237nDG$yc_F zuc0+Q57?}iTW9ZmOBi8%C%&H~l5ul!bHXz8^AwoI04C|F zxWDw$Q(ZIR60LR_14E)!dDMclq_~6wMj65;orA{QvryP}`!D(1-Z1);6G}F?N!Fl{ zY_QSG*Xdm^Ux^4tuS~fc1tJt6Smn(9o{|bGPNQpdu;L&Om_n z@~88xn8MC0CD(#7*oW0#_FvLCqjTyeF%^4RUpvO4%9^S<(#(1z zA}HZ~&73%unMQK8Oca_0>y}bMk9pli^V0>~lyZz#fQ^>c;e=k5^v?6bZ3}`+KvyI{ zEOB7z5JJgnVHP&98!m!TNY`o&cEN=~v4VMG9KtFpZ2Lu$w@i=a%8bLVbM*H$u_xE4 zdBeU%L96S3%xX!%mxKn%kVoX8@*Vyd!4c1Ua-d!nqLt|9Dfj3|&J$8-L}6j#>$6Zq z4|@NC1N)3(t>VW-9b2@+nlP}hKyiUg*Z+{*P}WPg5e$XT>gK+FCl^YAy)pvGwTesn zvhmWTuq0PK2iDpDZvKg%4JwEHPy7FObNYt79FqKK`sjD#v`^Qw!ORGztEZ~>ZYb+4 z^Wa%`CnjY&Uv*QWv8|@N$%OU24TU8v^!}P5sMg2cE9~qzqj(-T4rt;dO?9 z;&hN5`U!)(+r}C<*4?jf6rzlhPQgJ_pM+45SV1Z3W=22 zV0T+NuZzt43v8DR(O1OyEV63?WSDoZsxV!?fs?gxbh7}@0j8Gba`e1+sY=aa5EV}b=qg#x)#ym}<%*_YN8^7G$h-=lg_(S~_^yg`J z%okf<4=#A!F)%wX46oJg=2Wu*+YK!4YZ+6*Br=Z=MBA)hbT2iQ(dLKogIo=71z2Or zc0{xrytOq#EV-Q9t@^xc*YmdAGi`prhjsXPz4)kn6zrR$x6Am)beITX)*@J;sl;_kAUvKu&Lt>dyei^0^xUN& z3kF>*?_D%*Bl&eEllM8TbV@v=IGhxu9ol5(&!0QWy32$2_F5ZbN3M7*LiBTW&Ay%k z9r4_B)WCBQSgi|C^rl8m3XE>Dq|J+Ml8Fm*^#8g+h9w*8-T`{LmXPCs+7VPM`otAD zAjZECmHsS+r@5##JyzwmSD+GP9{SlD`0r1FQ^i@=T%;cpHM`IlgAAy30$-P*Z^P=1tCQLP=uv-Y z?dgg7{vA7*?FbCl+g|9u8^|>ZRm36mJx!`73Eq0O12L8jX!ICh5tX$1z2mOEN=)CA zPh{Znx1$LkDL}7x^W-uaA@MNxZtCbW4sEZyIA|zr9!vBB6&834eGHtwvmsJjXc>jM zlyxl6n>YUZ+A)g0`aH?#u-5nE{oP-5@^_O6*xILx-_w_IkwtawiQReyRB<-m;(ab@$!$cN!(6) z1KDK2LUq(?6DTAZmMsM~0fvsWvi1Y-_Ny=}KCrNrDM8!Z=tYn+>w zICpOOgKqQzqFr&oV{F3+G(?a&g-q3?fGP2UazhwTHP)S`_%xpb=aq@2b9Zyld?EKO z5NLwulL8i+5gU#bYG8Vwp3M$=nES@Z9TpOGFg+&?6pHF;U9~cmaDoZE@A&3nSK`b; z@yup+Faqp3SY4ds-MjmY*!MaD{RWli4Dg|6?3{oV;RC&K)(@+J*uGLTjjK$DXhwWA zv2XX^zptMjwPKB<_K3j~w@oFOr3*~*-6feN9je*kyoh?n-?H;Ig5JHiQ=-tC-rzvh zW`@KvYlDHd0$i{_D^>N)4^KX|XEvC}2>$U({j?fOg$nED1>2VmL%d75L5cplfCc(( zcm~DePqy(5>1HM0=Q(&~|M(a_2Ko_$u$9X0Gr+mGzVeHHWt3OIh#ywNdi-kDq1m^V zv(40J&(61u3;+HG$t|VF%Dd`g@)ZZhz~WeN?T1_Ec+f(qQM17yuuH{E`T>?1+o5VI z;hbbc+4-$$c&?!byt-&I7=IEGM}%hH;DDJ#x$>;+1!_LT^9?4KzOM;)4T?cBt$$yr zkgG2{R*%c_YUsfZ0YBD3C)koA0;ppCzWL4p>r@VX?Qkru(XaYZ1sg~NdQCK`#r_If zn#9G7ZXF>j9q}J2wH;@@RbqSKFXmu)aygHh+G-D+{d^E=F_*FEgq_B-qIa1c#8Fep zY0@osqFf0u)7D%pDx3}#8O|fnFYkaA81xZ2YR%bgLS~%nW}aI(fteiEV)BAECj2iN z6V8|&NF@DsR=G@xqR-}U^WB_OT$px$agzHwgU+%c`|M+`^K=za@v~OKIsa&hz4otN zg6KCpHVr5}x8Bf^_Tt|MlL05gKHR!@2)qo2z_7=XJdu9&bTxh^8 zw+$Q+;h^yPM<|vPj!+hMjr_0ra;p&ew_I@3L7;l(TW+39fw!wpyS?xT+H^bGXr|2lezd@&8d9(Y@SRSjuNU|o z#)-@`nDg11t86Z=`#Y4F^3(X6Ph1Ddmrk~a>n+&m9qFWokYf1nK=`XQZi9KE5?nN0 z48;12(X8`y$!JpZFVDb-c-l-CzI^wx5qZS@%nwuBDwdi40!R9;5={YLvF%@@(=-j; z8c_qQkP4F$W;DNi-*eaVqH$PgG2fsU#qaU&^Y>OEFK#hhgmFrxvA0|l=p;YMPj!$F zKCSMPefV^B%GdXO2kC>Pnv(`P%ea8{#Yi!3%w+Rt2Je!Vocx_x9_`EK+Z)hb$>Ezd z#aG~l3+~DXyXkGcSfj+4-~D*1MLmLcx=E)W>KC`{%nbU)IC9gZV2zzjRaS0%Ho`yu z>tEp*mxsCRAy{s$C5)*K9`xzV2B4zxFu!%Ygrz|Y~T=e0pFg~<6>((ai$Nol?xBEqEsqArV zN!W~^=yLtsK3jL>dMn!uDf80=ZT+VKiNBX5qBGG0-KxqJNzmO}ibK1J@97-63V-I{ zVm{qif*AD{EJ79E`rL|3tZmav>5CP(3|W1WE&r*$-tC@l%%#WTv5L_#W}C|DjRD)? zUC)6NnIK&D@c0QEGFv(;|AU{fms}H*n%Sa)kA(OkNy``iBWPp(4f6X$#q~t9?`yoj zVv!DL3fk`pyxxv4J@cU9tHLqs@4D&n7Fmje%mDgOZc{BDZc1+X#m4)lugeZqezJBl z)jbogGtdXw@I#^Ze$c^3}r}ymyI$57BfI1#-ynQd*9hEF6w>l$<{t_ZJSTqpyF5;7neoMY=0OTGP`z7>_ znrVu)05@pwm1t&^GuR}N`k;So^;dY3^|In%ujp5Xf%2MeWXwrvRfB}UI8^caidph9 z&XT|3P$9I~WD>IOy??Wq7n^yY15=EfP5?%8NwFeB<-Iy@c;SPqyD0CxnGE`VEy`x} zs!ypvzY*5BSgz7771c{!oYd8qUj&dyPERbC+m-o$){--`G()_tG{vty)wu1Q{+-cd zr9}G;jZ#j_J@Z$J_;O;f80BaBzX{-b%KWkV67}LJzK%`sqmQFoI$WNZ|x~^#FQd>KNYG)21rMgF+g+QWP9q9!S6u_U%h41!WvfvAM0|9MV*Ef zw*Fyqs2>466-8B&uK|;-v>~ntv=-7w;|F2u+E|mEl+Dg>JmEfwb5vE zKT?I;d+owHA^hUfbpv|*;WSP=IVy(F`ZWQYZ^#%Bk@!s?!-I$%WGns+oCep<%J$zx zYv9Q&o=)gO>rYuGz6aUp^Xsgf)=!lDRWIcMO$G9R_tQHRU0I524K@t=B+*66vQ8<` zIqKrXt!dE%HT&rfS-R@dZFE?!X>G8c{A2I&q@Va#ZKfUCXDN`Vq_0oQzkvg8ambd>rdXQJ{L#B)8F{AC@AinUO<^!l1~JdmBpD{^cSy;|-Z#*DfSNtzLY;=l>cf26f87VHEc208suUz$4Idd2r}5}jm&!o9l%w1%Xs(j%F2%D8 zJ7sSfuSpH80!o?=KM+#Pjm12rt4!)TiCBIk?JR)o{C--!x6|BYNa(TXEuV^c&#LGj z^8u|d@&n#FE$&e77W{Cbb2?~zB%&lVe)e->dR*lyj>q%n zhABKNUT8f_(L5HzuU`y*r*)g;Jid-SR2JxS?!2T0OzeI`e?6G`Nw(r~%&dUSD+RWm zc1d9CYD9;H5FTx&wF{sHrva^qxd<(6BEM}774bcas8VHxO$d(cM3pFmV-8ohM?z+m7?>LqmxVS*0lK z#q6m*$+i(7Z!*b|a?&Y~7`57a4}It(=O>LFW1?bKdJqxf1)e_V0)=dB6hi44P_{5Q z%{Ga{T*|<&s}2sl)y(?NpY-jYo8pY*xHkJVxnqIL-xO4t+bponqy$8xcb8(B;PC|d z{qrk-CG01eNeDGbiej6uCHW9^72@u>Y9OTUyAi>N{X~VV4*6O7b}?HENJ&u>^3Hxl z0osHxT^}dIGQ0W?mKTNBy?xjBUjK8(u4&e*+5NlzemWi4b4~u(^xGG1io&04dvB=& zZY*^@-T3>jspm5E`rns78F{hZ^^I11=*W;l_`P&Emd?R&rjCN-7u`Oc!@$k7lN7fk zfEO=1WaQJl07(Ywm~oLdj*loXim!7|<4<@8f0dz&|3zGkp~3b{?Z3Z{z2rRH`m*TN zb9?pTt%JlJHC9-^G>Wf+74}RT6|AV>;`l$1yaNOwq$ZUKRf7~LaB z?H&62{@-(UcFvydzV0hOSKRjoQb_w#NGtF#fF+7~nLmrtT7RVOuW~nwL^2%VP4I`! zVc+mFL1@Ae`O&7s)L8QqMilcSMz;2g4RH*RtGxTN;dqhWaCcr8%`N@{g?Joxk!1lg zw@qT(EV&{oAx(R7bqbrOMf6fOnmKMK`?Jbr5vuo~IQO}< zukgaG!WT{cA{z}bSId^fI7cvp3YFSxDS)nX{TL7XP0uv!p=C{oZpNn1?^lDonE^lE z?%W^0F~#jsV<|~7rII=`y`L50kvuCUkZ`JZ6t@)oBx#7`P;&pt+nekQgR8ytL&d~u zN-%)}alQsOMIIK^kDEBAtOGuT5|^pJTZqgw|9U;t`fzRe5FK|$tv-;qLBxsAjNgS*?`{oS!1kZio5gJx9KrO(>t6X^8$H+~9wZWvLk^1xC4PCdJzNwQi~B03cDi*3 z{nMTRwJqytgARZM4<0L}O^hjL{{UnE#o7~l2S8S?jPQUaLwPYOiebnui^XfxX+O&7 zS@LAd$u&J}UR#Ms>U7nu2_}7h6K4t2MmS_$SC#LvRt4*?7Un7!_yzskm2UHe^}`3f zgC;aC=`RrzCqD%0sB1gejGSs^-nx`u8s1!$QJ!igmZa`I-kWO`76%^}NwcY9a2q!c z0{ogKwja%;wC(SFoDxnu_)P%MauxJXySnCpoe?>+rt89Ys1R++!cK&VmPV?H;)wIR zq;e*U;reX^n%6v;MdQ_)Ax>){>CGUO2>nA5;DM=p52?7qEBCcgY?yROb50InC`x(2xL+cfok}a)nFj}sI0R8K> z9U-fs-%U+%b=QBMRNyz(fP;{Rq z4TDEeHdO6&ml34mq4MR48%Za_yQB~h5fn%@MQ2~bYCsYRd;G8B_xR2^<+UYmQ4!-PDu*qi;eeF zr~`*>>+D|TdPZ+%ZQ0UX|3n|B{!3teV^@jV@xNZ%6$nkZ7sG7?+7 zkwTyc+L5*K$cVxLl~Xeo>}faVCQ5q)Hc%hJL3IV9#FVFH*`B`7r*n-BeQ$-pN9nX^pF9(Lee$9eY%_$ zn{*9tTd#jhjL>LlU=fNA1VFdX%E|1c52h-kcsgIfQ0$@i8bmEC7{zcT`CFrE1u66#Uy`r#2i5 z8Fzc<*MYFyoV(+vO`;=35|Xma7>+k$?dooc^DT)|UcvPGZsrOAcTZgP!0Z>b5C#8T zgUZ}=sb^b~n|}fl4T_IY27@%dlZaXo_~kmJz&)BrD`_q@2_*)NZ6*Zwl*1}_$06N8 z-CoV=;sK7%3T~FgPIrdyyC-|t?Gt6qa>**0S(y(1X>v8!8g9M#7?O%5x&X{An6g>S z2=(@)4U(;S>N)`4e48^D%s=VCE6GOS7V!$!rhQn|B`W001N(=zx`twNq4~p-)PlfT zgY4xN@5r?4)_q#dvoe*n5gD$_FYxSDre>Q9_`&ci$Aldj@aAbUS7Kjm_tNLKTts{~ z;!e+ctQT}U((U5CE?czwTP%tGA0^J^g~{`B$;y)Z9wxxEr>S%8eGkt9uU1S6rD{dZ z!s_m~r0)b+8dm^Ey|S%@A2Mf_>A{;XO$#{8r1zlsZf>vIlE#D_Bnh8eoDfY$EEGmpqAnQ#)XNIkRZY2xr_uuYYl{*=7d$ez6uC1rC@7&OO^mq1S2Q7y0bYDW9jFj zT|5zDqHi5mY{Tjkym~EPDkZE!UVkXG8o9juZR_e?t74FUo{dy>FY4szn$~vizf=>x`P_1S?KwQyD=i>E82GNwQzCmP_Tx*e9C=wf$9q}X zgmtDPRGD62u^NrgdxajayZhZ@FYUnR@+=CRL~Q}mRpVzu_w0(ndHn;aBgbh(q)k37 z#?XgX2TT@FbH28ND{dbe0yeo%;BT25>eX=4WN2J>jl*5LJ z7l;G(`f&g9ihw44p3&o@7vmEPay_y1&6xDcgjtUQ-wyTD2`+C(n}Vi89xsUv#l<#Q z9v*8$*<d!!BLWsRn#??e@dqtLzx5$kj5a_J}Ae zMk{44fPSd9Cc3*JrGY%A`Q-ZMLn4>k89C0XVb`UCP)jT^*TbIn=4Pxx3Cg*=ljRy-VE&nI$%T_CsjetyT+#T1yfhGvw$<hydS)9^Z| zyk!>)9KB@0nH91h7kg3$04iWU&(oxpgKI0ut3>tkU9pvbJ#%22xaexR^FtFa95fB9 zvl?4v<~z85KDC_IziZA%wG`G?4~S_e1`c%pxS>vXA8UbghNb^Qzd4ARi=}1S)qIHl zfS#m=aNoZ_kn&g2q>s7y&-IN*ZGt}*Dy@Xf;t`$LlOaulX^s$Jm9&psYI}EQtCG8< zswABnD*yxLAVeita#cO(=bhNwdmflfltdG;KN2s+nEv#L@5Ulv%?B*`G7hC@>mFBi zg^Qed9Y6nPmm3w3@S2V5y+7Zf-Qp*0@1$6Pbq~~?{nYoDhG{t+sn{L?LG+KGpg=^H z&p3VDFeN_(P+1NG-XF^Et->ng*ndK}zKl7=6SLan3k^5zEP_e)$Qcua2yO_D>tddk zcUnR3MwwY!wq2DM7M9hKVm&QAhE7W0@3Nyj50V7LtNqkh7k)w~kMWk-!m^E>f(wcO z57+mP?GDqc;*L+kgfRi7TyWl`gMY}gS}f(fvo=5qLc{~qYq!>BAG7tz(tKym^Vn38 zq@tC|ig)Pxkeqv|CFN<TWXQ_P2wOws&&iB_h4{!>PRZJ z$u%Kq%=|UbG2-B(tu008g9=rCXX*yMOSJ$$p9zu{k&;=BBcf|GyuzMUzxmbbu2mqh zBTXqIMy-nc?rjw4@aT&8&K=@As)};@TqChPM5)>4{k@Sozc`?~+vOt3bJ$^@gd`ds znN8!swceVSd~0ye*)iuB=|$+!5_@xqWwV{?`F1Wog!y)hvbDO!S9bF0KQ;D zBR9Nf;w{rqkk2Z1PSkqd7u!ER2fVGDdmpdk8>Fv)ETmOe4RP(&yF5Q#oPb^QOhhPM zine-9Si7J8di~~3rQE9uNlhg_GcPLIv?^(@1)sq7^kF|$e3w{)(zJk0^-*PPT2CQb zFmmxDzyz?L%|PbA0<`l((+69rZP^i3*Dc%6V^=)sqnfUgMO%}1bP34e4ITEDe$2`W z$^O_>5+TBpEen2HvI&E1S2^}yH(W1Hkz+&G*Vh9KNq%3Ny;Pj{E8H#v0{#1j=11w2t*Kyag6UhWChAa)r0knz0^)|HXdd~7%Xc@oF)4vD0HM{P%z$D1a z_GChS!RYssD;nvZCT+WPuj6OSHFLA?l7IPeH&_pt_U*Z6@hGh3o4eXH;6Ms|TtFj@ zH?JOW)k&#%PfNt9WBAewd|>lS8lddRUSYnv3r+SgL=1#0f@`XYD$|d8S3O#jdczF? zD0gdWpO*I*%Q;q|cxjeiC9TG6zf#cm>{OpkOq92;aGPhEDAd;d3Y-jH5w zkVaurrVc&(G|05P#+OYZ3KT+STM-xlNL9<$mH7#VkJr1(Wc|kzk4)&w`bNj|mc2bj zNZdO$|1`Vm&X3q}XBk4#WermhQNLv+6znl+9PI*Bs6B^=U3 zy&#QC7~`huL&!A7KBE69p3?LIT684nk0hlj87Mc-%*^7YK!}w0W_J*YXFsF`TszC9 zMFs&~x<=7}!i}qZjWtN6ZSiAolhu5SeAEylV$xd)l*o=H-1b82Pm#<-I_5E7;0il3 z$LU-LT29YmNFAtq@c#3O0^M%>fZWK;_{%F{Dq4nX+N)+$Zi;&1&o8?{m2vTH@l=xx z#?A)A^Xdw=&m;CVU|Z5*y~rdWp}QrZuYltw5?;@43$uNzmCA7QE#wVbMbNrd>?}$R)N7xL1`6EHx#PW$Vtw60Uu@ez!-Qs9$~! z(aLw}CCWDUcnpLJqzwTq*eQIhWVWl%+>g87xjz(CPLeQJViO>BWL~{8n0k7pD{@)z z%2XSBiK>ezW8V49Fz!$;u&;Z&HtBo5>-1Q{oIxph$b)_6tR2^P5j2dx(#P<6yn*T< zeMWcP9-X?hrj&{2r@K~Jj#JHFK0Lcwi@`BBhIXmx|DKZVYO2owz>S61=rVe=&?gW8 z^pjUve6;QNJi-$o((?2E_oou4cHKp@7PubUOeX;p0&o#v^K*SXu{q z9|i^4(`xVMD2%IaWptg4R~z-ckP*y;nekdzOwiJrs7~3nDu3yP>!)yQrdVRVFI>>3 zJtX=8Z&#?nE(3T_cMXGGTfKrnvfwac%K8A;VztcCpwrQo?FB?*2|M>XSb^iY+j|Ai zg5mE(HxQlJ-6vjx0asTdxtLzN_k1_fwR|+RHB;0IpsnCeVcnwG!=GbDQqbAiS2YvgJv z7OQdptB;)&EU|g7wrNlEn{JkDCY2hZVIJMc#tuFmZR2J`B;*OG{^;aOW@h6OQ>a~> zy~2AUW%}yjWSjUDVA{U{&Qlp;8H^N4f^%K=X)HP(?B#J~@=10@amO9igyb{7 z9G;L;1TuFxU}Q-LFNq~K=Et(04C~2(S-5{+tQD6^JW~!9ZXefzPBoweXX_(n104M= z9H_s&a5rRZY5AZwD1M7L&+{ zc#-FD*BkYO^isjuI5Y0|#5$By;al~Hucq$C05VRv4*9+DIoK8t6LX8 zC9vUhh)houe~@l_W{7h3VR7Va<2<#~B@!9>v9C3cnz8vn!y_9QRgIfQos6yUf!hg) z-U&{crG6qsl(;yfo>TO@5LClAt071x1dO?Of5MX*siI$7!QV;8m=UMCgCN9dpD{zoVEReDmZ139Qsq9c>#7&MnYK+}r z))?a8c@W5$tFAXqUuKeumO4>#{5n;uu+F=tz=on|LmBuZr(EZ}nnkBZk|K0KtuGaK?K@E$w@N ziA%O5Tl)v6GLGcZva&Ld!pDMPk@7N&snHAb33{H7_1K7<=T@?V$oKc>G#R`;Sh6+YsePvDuQe)X)X;H@huo`m|qz98}dM zAwLE(e73%39}Ta8=V0eYx$CmOo2^PA(1gadFokI7k zgH`dE>L8wBnnKaKg?TF*X>KD3FI&=--A}R;udV{(rH+h{US`gu-9I& z7pt?DXl&@-f48t@vAy|C&)l9IlIn+`w2;kg^i$Zc91_jYyCBij)WVmKvrf#0j$#Ns z^)Dy~66R!uem@iZqbQ|Nds>Q!Ytd(lFi12>@JYL7;+ks=I!*$5meQ6OjJN%8hk6}; zS1iXxfy~4`6xsslwNLUfUF*wt**581J%wK`N^^2GsTu~uVmn3GO+2P$#h2hmmDq#3 z#OYqcSuzA_DTF)`BV>7orHK=1`1D$IvTHZ9VoU_gqNT-o>AYK_g>G*}sAM=Sm+)4u zsTxX=ADMn^Jl+6Q6MZbz3C)%!%v&!d5NDT2pg#6ZP-l8W1 zZOUiH;VrYy3Mg90tPfJ+qQEGc2Cv8w)<0bhx*xiivw&&K7OS~a+B%rud3$R#Z6@K}kGU(02yJ7vK)ZS@MX8d?e*mUwL+XUP*9ew@(Jr>Sv6tTyY&T*{vsSm?ek#F{MN7|=0r zUT>F?8XM7JT*0UB^PPV8Dxzsx4p&B_SIzBMfhq=x6;cH^Sj}Bj3?Hc|a1?WjcJUZi z;Y+(m4sqw(nKHKS*rU2?ni1ped7?eE=zt(I zG31f-)wLa6%Q~yOc5FsX@wyknelHIYJ-mc$MIGb#6{Ny&ej(n<_OHt@daX2*W1BJ- z3UT;c_x0V8LlU5;!~DP6UA{LzT&rt#Y%Smlhx{gaekR|yw!a1EkrD6j0gpdqlYZd7 zfeTdeI@bOkc{QvHS&wFkbrGK&mqL}w*N>+H7&1+v-SiYvK3`Dclh0+|+PqCGuCnykhN}6@ zavcqZw`+pF!(#7aflH;00DuB**@lFh=AmA`P1cmj1l zO7XN=d}l z7OKV5hcvV%9rf29C#dvKWSAMypWfin??!3GW9ll-+TQu(;nWLw&uxnWGEnWo_u+c28Chz+C&VbANVoJ(K8&Gw7QnNTtdus0|LYGlax? zp7`)x(BFh!=`_2)*#a&BHrc|b^UN;z?^O@&UhS-Ih{`_ZZF<~@`kV;;|?7Ypk24teX@Lx7IqP>GAei zTUfY0Zpi&sZP#f&s@JC4N`|wv2dhZNmV%&0#$0L6VqTb`j2gK)i&Qg2ub#o|2JCe4j3BJDpil2#m%ejXHnal#Zj0WQr6_6fqQNNbX1Z&Wq1c5`&4dOCn=I zvKnNWwrihgzjG?-4rw+TymVeZjcknUVRf}?2XH6S)^9#lQ}y5`c;j1QiH4J=|Lg*>Vv}Ch-^MqmoTiDm>4a^5s#EgO_~tzyso&~O3;DC6 zDe4VRGYo&QobxAcNxtA(b)h+%{eBuP4Oe7ixEK?zk(1WWY~D^K1J<*|5_~83Cr?LX z@_{lbDP76)H{lsf*pf&|+2IN<$RkQuCFL$Kqf5lkH+YjCdz42=bRlEnMdd!Fw<3NX zVkPtZL-)C`6vX+(bX3}aJ<%=@GAPbVFa8!hc51gOo_o~U#Gi+!d(unnNZ}z|6hbJ0 z?D$f@0d{ogUD!7kSU1OaWZs*BT+KR|0+K9{sXLypChkw^t=Ds#W%Ac6QyD3I>BwTv zFCfaz7XMnwVfnSfSanM!`Egp~aA5kZ&=;!Z;+#{Dw-;}A#6O!3_D9VIJ@ z9Oqu!I8euIP~*oJq9~DQU=)=7y4iY6OaB#XZ&Vz!3U_uNNVDrz0dXXAOOBIKjR4mM z@7EUttZKD1@~`!;1d8Iy*)858;)@`XwN5v5)HL&aUR$;Bh>xHT z!?XNr4thkFz6GPbu3zfJy`Q8T?({)YB9r-xR*GMQEUrCZVmSU&xoDk@P{>KnoqkU9-CXI zsDQ7*?XUPhFU2tml2sHE%B@ip=tk+jiA3coHm}Ex?337*b(}xGA5&)C(J1G*;m@Mdxvwfox_kVlKne@zSZsF578_SMbkGfKnI9fqA ztPjuOU5^|&&(thmGr-2L6CG|VFU*P^dmilh5t2>r)Z zxccnBSs!9fKL3xpBLO<{gn)`TS1f%OX|>m!3u9X`TKD|S8}pL>Cjrhl_1YU}`85uU=?}SOle4UAv|=T^;nNO^mEJO2r|?zp}zM34Q|ofjHUHWHX?hsqWztgPJ; zeQeoR4cV9N7X;gJ*}_5 z+n&%is%{6Ed3OQtn^oH?Yuan1zsR9)JcEKf8qAcHdzU&RmIk6Jl^9Y%uuHH+vfAVD zgaLaPIgI&#%nNcYrfZ3`bME&O@LDuGuCSipLH%0qXS(U8xFaCseP-^HEfeTJU1nZj zy$QS7g=P6&q_L={NS*8!wjO>&>2ZJZ-Ua6U){ZyPdp~BA`ybEo#+ab3t*?cJ4)F1U z^(@e-^nT!e)rd4+_ELJ(gB$PJU+JYDv!gnOKGTqb1Vc-|)i6qn`juEo7_w7#(81{E zF8$Raw&lef9}8Ju1oTwLNBgX@Kz$@jQu#mMOCwnG(Vb4v^6>(^Hgom#^wOLsxNAk- zpv_jD;nNnNU9<&&i$dVdqaMWSfX~j%JNQ8Y1~!p!NfO~xY|`h*hVpWv8(O1gF^aeW zH-@0lk4!F0gJ~0%frt_!*{g#&*v%=WrT^w{Q#ZdQF@*p5pM3%{bJ85N;N>&_E`s+0F~GMEZAljn33`rkw%|h_@LqAx?dHPG9cd<* z7BJleWoc{hJ+!X!-+EeV2{ZxGwk?VKZC8jgR+kq%8R8&&Yip_00WTk)&g|Z}Y<60p*WM#$ky+PKC8_`2>-9F#??XHl`b1=stSy@h?hvu-@fZ17qd zdcL)BG+*m7_tCWW+3WRfN#$Op?3+_PSwxvn%X-VcAHp(A3be=le*y8dJxX`$4x+9* zni2-$1L%qTU@d2X`?LEZqIv0h_(Vhsyx3H0vFSdg=5-Vj_(W}fGr|M|m68$?G6z9K zG_u|_{s+26lVNz2{}Uycp$gN4dh&hm`@Qi3b!;NqP@)6AfHH3RFZ+6;O`l4~@%Wl6 zT(28>OzXO=*W#`qan1|1Cxf$9bG2@lz>?1mKl((k99D7DO=OJhe zE37pzmCsTJxCuD6M&BwBy54dsm-C@YVLC;`R0|ajThNJ-q9X zOk4WoljE28$($px|AEvX@8`*vj3evd9lz-&u(1Enva&sAUS;4*|FP#(lrc|2A!FtXby3%=#ONHU-z^I+Ag`T z9nTtCE>W$`3LOAqJh=bu`tWsQRfOq?P~WJvj=AG;aDygEY?&2^61Ww-k+sXD<2gowJED&f?lEJJWBD ziQad;j8p!9KDqmOlIK}5n^!@iRW)BxNF#R!Bia9~ZlbWVKl$92aIBNhNp;3~;2Yim zpoqvps%sC}JuDF^Lq+FGz$97gNS7o^`R;Oug{;-$w!_1<)eMGcp^ zZsc{MLB*c-it$!0@!o=x(q0}E5NwTDxr5kz&Vb2+A#97^6Z)f;hBSOnk~S5YfcpfR zA6YdrI_q)2hVG9sLTEa6`#X2g$b>0J@x)^;AOq2N<^r|D-o#oxWA;^Ej)0X2Y-F$O zL*Bs}!oL){2z_I~5o~(p9dVnp@e&&{Cm%2v{(NNXb8ARPT*0Q!$$!MKju?t=j7SXc*}rQ7(5c~8 zGTa%vzZ)JA?))Vh{3`YDvO#A4zn{rpS^WF{zQ*nEiA6q7|6SjFCrJYRQ4#MS5DA_E zX<<>iji8I$up4LBKjb)97Aomf)w^AkPbWC*k>4^XuPZA4F6@>)nKjSl(7(0L_)~v> zO3fIXRvr2(E64XXe&_|k#-t^IW2c>uI-CEByvAJ>KWU|fW+eBDBY&&S_*fTB11H#Q z^(zt`mJqWb#~a|ZO>y14IPd|T_wTp@?LMLWEdfVD_Wn={=nZ&r-B8GY(&6@+Rc@iof(8^-%I>5UP?9SYrI+S zp({CfyG4A-J+;?NX@WKa6Z}P1@%HV`bCos9Tk=SQyg;wd^=NvS-!~&( zaKi_BwlWSA**r?a%)Q0#-G*YCUe`*Lej{`C00lyPpz=|bsu1vXl3#Oz|Nm;wc=4F@ z$(P#eZ$>8g^KJ!wFo=ri8Gog_H6HSm9&A0I|tkCMblwr;Iqa+Fb%F&X7Kyn{YcQAfS96cauj z8X>*4v&`t(FpM92njW+q=dWM9Vief>z&8hX%|p3U>dbYS7j=#pG6Y4FPHR6EI|P6L4qZp ze|~lmb>ip^Bi<~S_yZ=4^cs9Pdu8sosg^MJ0u(PF%) z)A>3DB!^xwB-r63VfMQ+0^Ha5miTf5ZM-!Rqz$Z&H`C}UMY+pz?0@YB9yasSipu?q z%buH&eX?8aWC@+RW$!iIbQr3YD=zLWWTT`d> zvAPS8`;2~oQ(3{^I1M#>By-y|#NU^Dcm8U6YnQ}rbcsRZmVoiAN3>jSp^|rQTli@+!t7uR^Qni_)Cd+ zMlW@_MSXRhGlc&o>@WU7g5h71rzcOYudHJwcy8%wGHwwxrm=X&Sjk7CKMxXNVPnIt zvwUEFy_rG#`>mI*=XANYSs|*o#taUfI?y~m6PXP9s~17~M^sdPd$a4V4JRp0d!=x% z1LRt|TlhYs+M4*Sb%VKIGaTk#p`5Pi#U*W;Oyo6kb42oi;zZMG=*9TF4|z9%ue^yS`h6 zd#h7N%B-_hDO5-v-{1WnL6-NLw}+=K0#CYAEgH9nC6Sk21*ENdh4!-%C;@?LRd9GS zFL)Z8w8Rx?JqSZ-+#3C9h%wEra&Q>(no2UpIO!YbWL{VPJeQKKz~t!H`bvaKiSdGpapX8d%Hwt0N)HoYzw*08z+ zIe|z*4`U0n{I|L(Epe{S`m_Ur2Z5OKfYkvV!YlPPx@k+y>?!?uf>`-^(h z@O)mGdM#w2^IHtZNT2JCruk}zpu2rjKk9fh>V!xzUm&7T>q(N{JHE?6R4*lu33)6b zx5;rAB^?YrQEQ1h(N3gj$6_N^6Nk4Uf$mA4)xj>$Az-jf6zs7|Jlu1OPdk*O*!hMt@Y%G8;L+E zi9`qdUfV?p%4_#eO+0<0UuI1INO?12tNg0Jyj}#5->2fnr^gLjPHjW1%A%IDxx)IW z$)dypva*KjPx|+lI@^G4QzEJJuai{YgAb;KeIUERBVXZ7uZNX-O?sFat@3EO5gd2gXdSd&p&Q)whm1 zPX%O72RhdymM%Lwy5nST!~*p#;{z|+D{9(;ZwPO_RAXqS3SQ&)WC=lRJul%eI7da=?+9m=5lsK{!1O&6K!m4 z4z4xl>c|pG+7SnLe}|FYv%|uY{^cOv43Pc4_%q$gDkO2oy^!eUYJ>~65yHp#B#GB$K7$MRRTPo_nv8{)S(Qor>Dz2H8s=aw8$uW~+oPt4Dux0Ob7` z*?5B~d4?8{*w$h^;OG!f`wHHr4wyC%Vi!{IWm5xte7rJ;EBP;miHMrA_kjUZhNkzi zd_HekZMo6Sc18N-LVcJIDb({wGcYi4RN-XE4XX*8@xazbMasiC=FpNTG}x$YyFR^;{lstX+vvzOuG9~xUqwU5+qP6c2vqdcb*`3x;(fl; zz(-St0SVBlhVS6gV!Jht9P1Iiw)B1A=Egx557jpcAo&8|jJ9fV(x<(9h|J8)ASx}! zpFzi1x;1UrfT=?}+^6-@T!q~3l%*|53b!?sh~dr$FA(a@UE2XnH#mZYy|+mJ$ty*T z$1A5RcL&15KZVsl#(6Hsihu8(aRGkchp$AVO?^x9-g|#m30a;K=UaVk+he9jZmi3q z*!FaS;{xC|D=Rj)K#exBy>MG$S;Gc`B6WC}cLM^rE5CyJt!E;_H$S$x3G0}=_myfz zd`Vu~FDxuvNYft4kkR9&=yN9CF!D&t%5v|`v}p7+Ziv}tTpA)J!F1$^5m3vtG#{u` zQMVEa{97m=k=xJhy{wUb<~8VgxZ3pM7EmS<{P3j4W!^1^Uaf7TF1+eMLwMX6*UqDW zCH8{TXcE@7`jTC9hVu%O_aCXiwvZx4Wk8;R~P( zxkxmQ0mmp*-pi6QaRB_NvdL@vci<9UHmbn#!j~(;vY10VI(Q=QHkThg8mQHn;7)cP z=l$B4BAev$si$hLmA-7bxOz(nh**>r#E>~_7?JySH>wwHR`9kdtkL)I9!J|c>$*r# zEUS-eoE!Kk9esJu0=og1yC`G-MXaMIOzCoznf{{ejtnHL1q~727 z;OR3)I3*&|!K2zZEn)d!Pu0|N-7%sEHP6huCi=dm1KmwQ2-;t7+X{eE!`Rc%d#j@c z=+3NbadCM>_U7~8hRo?$ob1Jh@^F@Pll{<_5#UDq(~Z{<259{jh{B>?a#Dq>{=w0A zFlG^CbF3&Vvl$>do4@u5n`jaOp@98_gm8Gb)%-dGn zU67O(9ddU&plS;~&`-XiIt}mw_0(zHWbG$I3c zT*NPAa(loMSt%K)G83e^=HB=-HSw%v{~Db-iZ2T#p`@gR+Q7v`JgS~?K}>s;*&*4} zF5t8(+oip8*9~<#;O;tTa)$-lHFC0{$BREE4LViidtl1w(EKEq1WwVHW{>uaAq+u4 z!c|hHnx=7WK8ElwP=d)@&3;^7#`b3>5v%1ah3L6i@AE((UZnky^SXnzhF%a7l_z zyK6bh+5ST{DP%*fJ7717*}k$FrDNvU%`y%Qxpcp*+RKv2t7^N9pz}h7jvNr&a;<+A zHv*>cAEpmH&g*~hg4eR)Ud}?3H?Sturu~JmRr}Tq+@2r0<$)rjjm=%{C%Qk4nxl@a zdvCt!2I+(q{dQt0m)rs+H<`8s^^i4g|MNrS%?V#Bmq#*qYo_ zroUF{x`zfBG~(P2Z_s)rxa(*Bt~p-g8{=Ie%_QofzU|L057azPr6u@ISiF9AoGjF# zJQvl^?GXh)8_!1?7KrmoD-elpE(x^)ZYh|(gdZ8ZKh(2innQJFf8PfE126P@e!=9l zo+v^zZnBl1uvrn^TG+h8{(BI>{p`yrCnI{bAX^7g_b=83{jJY&nA&&#&g0kEKL6j~ zKX}mQ@1z1~*lL#%za?+1@=6!2mdXPwOrd`dDkfcIVsHI5P@<{vK~BIo^{uM`6bWh_ zY>2d6HqOUCxdMb;InV;*jFY3s5eY~QR#0p;<-dBJp=Zs9bRs`owMgz9pjrForxf#r z6=i|R@Xm&K1?5KE`M#$A0RzB2yy*0cTc$EZKJtTLzj20(+-HE13(@Wz9Vw!~*yB9+ z;DycxQO6na>f=|TzpZuH6E3XGjlg_22(O72ogtwG|kpM4a}sL>Z(d|N3Zc$@>d=VEP`OoA_BuB2!VBnV0^Bdy2` zUPm{23I;pXJPXGc;Z@L|)}@M}Zy!p{Ij?clS7Mper|MUz7NE+iq5ectj7Rv2m73F+ z<|$_gsxYCWYrkRnbNO?uhhuAf47nn$7jyY7i|9jEbR&n`#_D%K*zsxh1^*LXEyOVN z@iLy?VISdS`@B2cYk@KesF}F1RssuA%~eE}^5e zU5!N0=o9`L2V+In4~u9;$lHM&MygV#5OzEMGa{6~cR~BJL3=u?pm0R^C&BNzA~YYDXj@b%_<+bm7LvOsy!3pdsGi@ms&;G5zizGCl%@#7ph?i^Oa7mTH;kW+i=^+vGLJ7 z2HsX6?LL!nCHMP^*`J${MYsM;u14Xaw|1w_Ts_L)MM zyq39i(OZQM#y1anbRY^~Dom3+hFY$N@m5C)`fM1~#YVaVp9hWa59|e9KXhhS2-g?< z9&gpjNR56ge;xF2(yK%J1DRTcyq+JIWo1*6{VN{!x4NN<3isuk{f<%=R#WACox}ja z@#02?PZ2uvDr|~up5J*hWA25@Uk=!tDV4FK1!Q>Z3~7`gl{=hR)iFYISJqX>MQf%m z{K-100e^;LHrI@+g3Gb?nFlph8dIbL2MKOJyHSOCrhIr#;-PlLAhm_rYnkKLHk(4Q z4fAbgpujDW@pyeyMIV*+?L{~dKt_T=-Tg|PT8Im#-sNvCjJ{Lo+2h!MZ>ek{ent2i zCM3YF`>D*ge3+DIL6ceRiK5iQWM+Mp#XzY#+3?>~m42)$TS<&r)wPOPFPrVZC&|Hm zRa;`P$ZNH+-qG1k`2T*Rqttc7Y3LyQB!vFJt8a8_svf_!I7cGDK_Ps(9vJIe%&{LJ z_Nq}(O1?M8k@w-(x4zd>H zo6Wyys5%BH~%>BwUGhTEY2Ge@r9@Jb!rUf{aQVxhhdsYW4`S2N)y|~q+f`V#$GZe zy?TNPK<|fh{s;rlL$QV5$Pa+yJA^YrQ0FS&4 z7QsNg-WRTIQZn&Kq?AHVqAz;z(9aOsqaX-$?Jd{gd@JTv*GPJ`W!EJyr?;ja z6S*18{+o$&MlTn8$s$^_Vjh13zypbztawsk@6$IwZ{j_47EE?PlC~8H4H$BsQ@Zx! zvVfS}*43|a+1-9EY#Vh{_Eu7aE(5Fac=I)u!$#I>uVK$g%6$ByKiawAuxKn39X8bV zdNlJ+9BX#m%V~bRY-ns*c3)6QPAS1b?^{lM0?(hm_?Y1Co~oyzq^tz}6*G#%!(m&A zf}a?Tr$4jv_juS)<80cJKX-Z-x&Qx|I?Jf2y8rDfNH-D=-O@22APqxzHzF~FASEd= zATXpdbW5j{G)RXGLnBhs-5{VeJm%vlQeb zdQ4?OY{DRC&0~>_ND4@p(nNm=HXfN+4a`qP^8o;c8Uj9w}K@|Y|*5+@5N=pJelvdTs zF_V4JfTKTZWjk2-fBqAVBdfYUW_|l2fHB(U=(|M-QfnC8u4zohR0Q?%JL4K)1 zmhw1H1z~k*dqNxvnaaTZxrs!+14XxTkD0>rUobrR(-+DpYQ@7Y$ZI&U^r>Kk*oE4 zt^nzWfPLBdG~fO7?iR=uo1OKP<$`ds8Z%Px|)pU7Sya(mU zlT4Qj>8tBdh7p>>lRjzE-O@Q8AEb)j0tyk^$GSD8&?^|XW&cO1c& zSLb*cGCCpfgDFO4bu!QIpXjf?AdaEYNfD~DM00Y38N8F~Q533=LHHEBl+ThL`)o6y z%Pll(OSSEm}~k2S}(4jlWp|Ek7|c-D8DfmGxXAn zOg^L~UpEiNT%e8Lsti#?;c-vq=jZuan6%^5)rNwz;GC!5@liDg_|-$$&S0TH9hCMF zpNUb_bJ7sBRfj>-+ZqnkXYevx?^nitL8x*)e2gaj3hHYbnoZ*e?iDnf; z#4-M+vI>KyKeQiMM)~js<1fK$OSq@BJ$N>)dLgV7Z(gcYypRcTnUOM5%h# z66T!Iq_{KtTKNeY{Lk3+f?{W70y4pT(BwriZMrVbfZ{oDRQW1@|yVp%>>^X0{E zr_b)uExtSHs zD~gy;8y^jSXlKKz`>8fFLuhq!&8FcK+b$6cceYd=)Cy6cO-Mvqz-pCfCmR;*wi-%a zW5Gn0A}hWwK^BLBwUmTc7?nn%i-dN)b!Fo2-Ef-ALj>S+@2iG+;|A#ATycdOhQqC6 z<&55H!*RfuD~+!$rW^@kYHXF^dX$Oa09jEMF`L_a);wo|SCj-1Yi%!_)lj+jt$n6$ zO39HCro9{fAl#l!a zx>j(=<@1s@1|&1;}z&axG!CG{A$|a z^e=4#XrFrc55uxKuxDO0{-67`F*K?~t7p+OS%RqWl z22$^tZJ)uf31FqgD0VZ2FVIp*U*NtL2QzpI7i4#b3xrHd4VPuCaynqSW3xtWAPTE3 z#rw&$KIX0W@6F0)ggSDL43yoZScsCXs?iCOFDpeva=v4)E<&Dj;=UN2tF3wu0b-&0 zC|sPVQZ7?WomY36e9XFe4g??Z=hZ=l7-04JG!Ye}{8)P7+?m=9=?z);ViJO3rD`39c?ia>r#hW?mZSoe z_#gLu!tfoXsyv>hYA(Dv-em{%Y@0q0RcHy~+Artro%;1w38k&+HyIg=op@A>uK-Ez zlNW-iqWc7f5TMw_W1VarlJjTdY1vwNGL zg7*YRQ#2R;pb%BdI$(z%G~XM3ky}a89jYw_$JS>01=8)jm@Syu4AC^7afM8rl6bk# z9KW}i{{xtkm}_}O3i-vV*+NeS)9hE<#e`u04LW^6`t3T8f!n+f3dOh;+N63UzIL5S zOYVsa0a*?s13WL2+m01ue!bP=8W{-x=sQiiwJzi=B^Cef<7nXMD8|emGpMH&3XcVs z$Wt5@K+|Xc2kZfSABg&P5JHzEU>HwQ-_-$r3zbn+=PIB(a~H84=%L%`=>WlS@gr2B zAXz6@Cdu(i^$>-$I4&sm8Q`Xu8nwHYeb@F%OBGZSBSGr3o? z|a<_#}hlkSis+$eKDHg18WZ<2<5LxvA3o=<64CO>**vim&H6)GX7(NKwgqg zRm={wYg=9!Q^a753yLJpi2Fx6GXk-f`kcD8&UmquKQa>kE=7p`LbP7h=YVO@6!+|R zz7Rd%8*^Bvn(CSR?tyx^(mQ4N{yW-pneF1SN&nWuQyHJ(fnK^Dh1F{da5UqLtE0(h zJr3?UD5wY#n_y%$`!!>TJuJZ250V^q<*UL2c`LJ*-Q@Mg}Y*e#_O!fUIk*XVKgHL|*o!w!xhH>1tfJzMrqv;2iUr)x$-d(ZKRf zZlE6BIlh8PZCsFveM#8xz!3P9aqPXC5ra)tiLk@WAUm8a<>P2eN#j-|ZhF6(lk4sz zo#>-5z7`w)w_nVd*PDYPY?CTyfy>dK6~Q8;X5*=;TSd!8?7utY8@G?E(q%Verl~Ew zf;Dd%F{?e zp|O92L_>h*|^>Pe0JU$At(bLUmF z=d-c$%Gsg38s@fzAvwk7ywj8)RON7wVc0-BMy;xH^B9(GO*CIi5kGw@7|5}`D`r=H zJ`7|2UznK?jrE+Mq(`_3k`WiN;Qw?%BwaKv`p!w^*s&Z;pZa&?cDK3A?d~W+c#Z1J zT?#B{E5&=*h=Vh|iBx8nD?GT?2#c%JReZVeMPpuf2#SUq9wTJQMUv3{3#QG9@0Y7~ zW7nfBXR|yk=M`UDCT8;nlr12@0_J80))n*D62<)VK9C^tQPau!U-TT}v0TFgKqOsi zsJJj!<)(a@kXUoo%-qX{le{ld-{$#@XlUj0yg4I|bDbwE#Tr48+>oOm6`?E}xiEby zhN-u2VwoqaAqug^QzY36+eK<;#)aZ1J{cKMh`=FB(?;<-ifKOWLARKr3i#IZ>EzQ@ z^V&}Med#A)d6#oa!v*0`H1%K@N{sg&ooPc%n}fLIBzz5kXx3wDH!~WYH6A zReWaA7j+y;Z>PieMN;$l>9?IocKPXav9TU`dez$QoHFcvNMP6yp{HbYAh_fO3DcLf zy?D)|T?(du-o~o{qdpbvU-7Q#_Mx9g|M$J+7BURn8ZSN$d{XtU*s*+M;Ob6_ATv%+ zszdXwl&0kI)Rm%$Nn;+EJ_4)tWH?E86VDE6wl{9!9A@LCuZ+yiXoxm^Nv=;`THobj z3}5QZ9JF7^mxNZ)YNbkMTvDAxjkk4d(g@o@ zfP8SVvA9YZB;V0yQ*P1Ou(kd+C66%bw+9MgmU_L(o{evkJE9af!vWc6S`5Z#YF%6r zkvRirS}4F#+pQSjDKCW~H(a55+!x?WP+q`3UoG$U$A(th9pRQ%{I?bowqdWbz9@Xp zIhH+h|3_qBsM4p-91vAhb>-{eH=lOZEciHzQ{FLm?78-9L5L3F`rBj@D`vVGif0Xm zH@1kEjG^^Liq3>chL2`nsf!gAf$1j`h&_4&7Aoqh*g>^21&=|dl)K-lRQVvw+J`A5 z(3Pr-DPhkB1(dd}{EMlgS6rrww(Pp_2{aI_5;^CYVClHg(+0WA=yZ;FVeB zk#c+og3KrzW??ht z#!Pm?YVfRcX>J?e4E2pGGAafeKgv#lasx%bS5E;X7ZJ@s~ zqY@ZF0i)C(W0Be>aF`*wavh&~;_up6M#j)lV?~wGwtSd}nIQ^^2eN^JhQw6t7gDv! z`wk9QU)~iO&|*hLuyJ@m`|!iN>$7GgfwC>7pe^^%O4=S7xOFeVs?K*<`+c|>708;$ zDsVSdAc3*qrIZHy!6#^TJ=f|tpHwiZJH#<=6q*J{xwcDz!fRu7+rfPmj5Rq=-++J_ zhP5{vw!zG>uA5^17(@ZXMF+Q{gZtndP~#K}(n>2%Xru{5h*5mY63^CrG+_t|QWJA< z)n#S2W8c;e$tm+yXNCB>PVu6H#dw+VW(buOwI+ecN3JIB%3C{HKxE{1_OkQCc$0p{!s$WPFl&wX;+n>6^d2yj~=}z z5a0B3v@8^{ZIvl~+;qd;Pk>)ajY`d3jw|`Fs1kbd#kb1fDgi^}gB#DW+Kq0(1Wk+R zTl?r+UeM8JaqB4!8(#|r;gsz}gC5hRmU%x51x&B*Z915RCi~b&Vi`qFZsvifNZ3-+ zYPLWCH4-TWq>WcONVlVv#`09cXf~T)*F6U) zS(%|roqzDva^TidES~cWdG0kwx*rLGkb`b9-MI&j>ux3uIgge(=Prcb6f;qvb( zQo1EG(h;i!A46mDGdWMfp4b-Jz!c|`bzb2a?rWKp$*;_=5Uz8A76Jk|2aeMi)zq(C zdGos5br=rFj!mEDzhEnh%}0=YS$M!k_hCoysFD=no1~__U3deI5w54XIgOR8dxi-GQC`RoM^JCp91RFE<;Sdq(A1pBPx8Y9=JccuJxX?Puv1 zi-){XDPv|8TF8^77PC#_4eF)CggNGV#k{_EcCHqM&i$Wf28mmswU6S^S2$uV6&tyG zk58?lLJ5NUnqv#K;O8=9I3NouP&Upl>JLgb4C|^Uim|8J3Fk;yT9Q{$0M9W+8aY_3 z9jsi4Z%Ekx)_7>7p%$pTl_i3kMIf;m0uP!TztMBKK#1;JJRl`(R_xl6&|K(L7T=Wa^WD+U;YlN}g2Dk}A zYU|fL@N3xRg8pV8HNBdNZBcF|m!%q&dg|@gx|{u@%`Pa>eJJ%_8#(v5`+(v5T*?;7 z_sD>(Wpek>T_&8N6^iyxd@Wj-&Qc4z;$ZHSCUhs9W!r(5iatJE>q5RwG@n+rnl_W{s=3L&Sr&GM&f+$sH=glfu zsZjI@A6Fa+aw5b<(hP?fJW5I{+S5m{bUF8!?z7h<74u%GZbHbYo`MCA-_W7^&`6j!uFunf_pIBT^qoh83k>h_6%J?-zFy@;HzyIXqtvebZ-tHucR=*VzBeaR=i4i+E3SmJRCu!#+3@d?hiXLfyJvibIbE z?lWaMxaL{#_!e#?>T~>OFn4k%ON^1eR;C%jc3ah_5^A*XxXw#qIPS{l$33e(Jnw1Q-psC{{jpSs@+1 zN*kp*wAKp_Gm)6;zi|T=!Th|^k;BGNFiLT|?Sg~7H&?}_eAJ8?qz9`oSOb&M?bPUT zTOHE65FCZL;Hg1j+Vcg!tV?{!zlX<$aX^FVj#sx1$Pn?kEkSA*SA{$Br$+q|DiEh6 z?gso>%alR1>7`eo@td^M9BTnaW-CW1OS6GzF6W#!f;>@Q!Xc80=KED%TJ(*WLGEQU z!YbM-`tk8Wnwb%k159dE#3XF;F(_bM^q5dJayplBU~lwE=%MO$1fd70*a-9YF*xW^ zm#O2!YyCZ;ByyrAOs}kF8_sV4Pa%=I`7C=a(MsQxnJ$6RjCoY#rGpeNZoNjY=JNnB zd$P-x(3UX*YkG}wU_SF2n&uWQ0KuQfZ?i%|S#pz~d9Gpx!BQ+hWxnG9Sxt&)e=*e} zocmUV!tcmaNY+yYm#8p17u-O0%5cXgKDZpzAM~tC)`6=_C19qW@}$@eoU7hnhXmvQvUF6#jraVU^2LcuP8UXEv!zf6%X& zAg~_hpEOw9w=NBPSVj^g`S?a}oDuTe19QRooXyda)A)7Hvl{Di+cXXkE^@`_d`Xp^ zy?{@nhp|+I2z(k)S%cq9x%XBXZc-AvL}p?);oiIio=*f0ZNhFC%p8NPHv`pu7R1QBNiBn+B3E6?^%_G_A>=&>^S~0BP7YSLuMFmUi42BK2aD?? z9$(asQ{7Yhbfoa78KQETq=`_$+D0buJVYM0SO1loYSc4NxElz)tn1@9E@p((No%W~ zggv40Fkbk0O|dEb@$(N%QyjKkRzzSiQd!V7;B)-v?(;ciBQ1WDaI-5R` z+F9Wli)c$oE3d)^S>OoLQUbN7tf^!OBWQd>_xl>*p2lH+x1tzn-xM;KMfjkRb6<5A zS||rziKj`ml7X>lL``d>R>(1OBpcEHPygb!jIZVW^xg$?4+bREydw1iXYS?RFC+Xn z^E4-OHb|QF)YGETqM{WcZ_v$^6r-z?GZa8<2ZX$#QG@3hti2U_mEv z*<+E;-m=1=AcP+4eqvr3(BM>HXEZG^L-CXAB`9XZIY~57Cwvvv@TIIr#A9oSvaE32oES7)6M3^9gM#Xul zdH5mtzNeEq2H&|^JhK#+%FM*-Z#x0b>B9kY9ISQub_aHibDT4>d0qJ{Xtkho;pZal zC0)nWN%ies_C!V#^7|peFqxZ$4KRq2RjQ)Aq*iTO?-To1xQihJNM$P+uA!t#Z)evzn*<4uAic3f=?=K97Xf#Ij`?%XkH z{QQ6VHy~fDBBY`TGT}~P`~Li>{h?cLAP!@aXXkUP`;CTmdXGrQUl#6@4k9TJzm2td zf|>8@Q6k=l2WIsSo8>>}hR>Jp{=h6>J(I$6q~_+Y@g+9A8r6H?{Xv?_BXSt*@%MO6 zL%z!60pc1#Kb$#D19>w3wVnA z_$`FXC}@+f6Wda*2$ zmVI7&RcaCRW9}z`MaJ$Y&8CfD;n@H{*?YPfAKySNj4Vzxqc!xnn#6YQDR0ie0CwjWR z?jqIbd+KP>rv`3cVa1OceYz{Wx7fn@HnrnzL+rFLxGDjBWQ_7yCvnz zc-8Z%H2i5W$XgEv-N@ub@0dXnJCRez$5Xx!bMRNKMV^AxnIYsJ`;!se zMfmM<6jICGk6O&47&tvZ3b9VKz`-LRpOS7e%{RI8p{V|G=U3qEYnDHVw%Ra!F%;WQM z=cPmdoGd(2|LyDF*6EG1+obYH4gXIu__8&*2ixH|vwB(O|h z%;SM^RQz z#PYKdE;`8WsHS|hTNMV>M!{yd#tK#BxL?20G(9s!1shBO>DXCX%^CrcJ*gT0l5gcL zs~(3jh9UQp!_(#n($vQo6cDiLryd#QDTAddT~XVQXBUIKq}JO!C@SIL)aA zmRBRE>wRY!k^2HHj6`DDijM9QuX$lWja@7lK@^$9xbGM{Id<*nUa5s$TA_nI7+t@h zNfTaa;ta7zx8`B397s1q11I`dlH^09rO1tuKK&M%Qrq;~TQwy>Ux;unQIHL*Bf zQ|rpdjTPW>x5?_pa2qLJyz?Q3s@MwHD@9E{W;1PMF#5fRAuHsWx}{D%{3(^eAkf}H zO|LxH8I30~SF8UHB{>~*!<#|^x~@<7;@qJT;MHk%AS;stFNRgf8f-*Jl4Z)>=kL{(GF*F?XP~}O*SzV=;;Td|ltF7GF#tdVwNvZio zIAgHH``q>hs(j{-5U5OGlndY)GHhs5&2ve_5$RYb@G|)cPjP!@)QEZelGS_D^A(p3 zXCaUVe2#clXU|%lIdPDR=#j16@XjE4V3%dW6haX(GgC67S|0M6hTN08R#r$a{E>bP zl?geF;_tVlJFZ53IxiNb?_qi#w|TX;%64n+_659gv1E7(mygoN{+aZ>W|oQLo&z>= z=68Z3+f$CA^Wvz6Zzk-IpmKwSm~D=gEQ=FYc=UJ8dYWG!?H2hwv6CM>YSuVTZQufY zXm3KrW8a3(j83#&Xd0Y!p?*@-5^n)TDHwWBg=;w;)o*29 z>X|B_(*gn4OBz3zQ_`h;jHE1Rp~J*hz7X%UA{bvMbp(1Mjm|^F$j*;JK#pKE?*!#= z4?O>zbU_*LE4xN71YHIh3?O;!I3BF@IJusHR66l@B}brr&wl$?s0_R@6VjiQ-VHa$ z+goc4ssO9uJay{UB>%A4JZ+0TBjbrRYn7^RBT}MKtep_ z+|RdU6=B1FZy5L;n=EP^CST(R8AxdG&8#t68SN0v>0-LR5+A{TAlaPy*`M?D>eH(^ zDs#AFUD&EC!4Z8nm(GzjrOkc&Fg5P<8UeXBI~8t_LSC2W0`{S5hheL&7fXOrweyv8 z6r0AkURMKqK_$fnTgR`$RCP<7w4*xrpthqsi z9Mk6wXtHV?TbQgVO^eD~=>z5-DoR@wc|t3^rapKwT_g7N^J!W@EW7aB>qbks2n(;` z<8T%|7M$M3^(pKKnLG~L%ZpTQ{>{|xtWj8?1?weAu0SZpD3g)mLXFA743(TjNDPSx zeF?0NUvEyGhalH}_fYz@;Hk|zBEKt#sO`{-={uJk#d*QQ?(=I3o^n$(&x*Sn>4(sZ zI|0g_WDh-#M=9|!vV+HWWfziHM3y+!Xp8T)b8qoE^d!2g5#vVQLx(2A>NsAxEzr7lhBvG5XN({x~O3>0g&g~i3v!%AM@O)gBgcmycPvydLC zIl;{fhX~h!&Yz3U&*ayL6AX#mQqN~`W=X$RboX-D_(3A?NmH!cunxP-y%2)uY&>7z z15MLGkfh3zUK0MGvfG(E(9};@4P$R&Aw(+UfULb5@EKo-`UIg(*K)^Gf*8Z|VO5Al zVe+2Vt4+)IZ*I&&{c|A}`pq_2a(1q0wa-$b2R;CqJ_9o#;~id0u3DZ{qC-6;T*n11 zpi6?lSi!`|8il$`15u}L4Hea|ouz5OE#Lunq(jBAHek2q^F(O|1DT8eh~nxTY#Dpzk|TOQg? z3^1E^dM#-K6IH;1ThbvoUmnwmN&dnDgaN^61M1- z%4ZS%ik37j>bC&0IhSS*^yk*6b6rz%jaG$yo8)S{I)DQv(f9-J++0?R){{=|9=+eL zxMWkGcf8E&Zn~0B`XNjGMEPp54%_y4VLH=g3BVcxp*i3R2|Nr)tK6p+>!MUjx|n7FBnq4W=oH7uI%p)X$9Tp)m+OH~ zqMCM1LHl?#_i;?5ef(E!+!rCZW^KeftTeO4gnbXyAW0;r8H3>ss zDma$ubCN|57B-We&1Z*jB5Vr#MqczwGn~xe9oE zug-SK3}x?6UgaU6dmvXUvSs4EyF$~OA2P_DfwAX|^%keo@kt%e(sAOBZJmBi8#E(* z|BM#YU5wm3lTe5q(86$y=3J9acxw_>=sU_yd8*Hbk)&#vryZ;zC;_(!fv@qT5A{}s zKlD(1s73xT*M0ocul?=+Y6bOuiz(+#c~AB}c(UtAJ?ilyxi9_2NfE>0vkh;Ifg$bx zzI0G&c~{2O`%C-e<7|uFu)9K`{7>zgcdPzB+t-cd6~v~seLgO7qPTiSa3eZf;TAbr zI@eW*5yhbRt5b}iguY=^>*vD+%bwA2Q_`qriH}JH7(9bFMNgw@7@N5|SxmvZt|}lg zJr{xtp(sC(_1v5ixg{+s&`~v3xi` z?%f8GR{Y^0zsqsi9pg|wXgTu$@B0XVhEB7)-1*x}nGhCub36oMgEq}Ztt+MS(0`~` zy?^PkDiKh+_rTWBy+th0UN|hloDwlAiIiKMSq!;;Of)RGO{0zjS3r8*+bFeEB7u*1UNhFCP?{W z_SI4Op=&IPQ(sv)*JRO!SMI>gW)mE&$V(Eo2>$k zj3OM%b1XGAH4Y_Vp01-FlYX_-ykuRD*_JnRMpdzN zV!+J2yT3ot0ApDYJC<~Fa~MoeXqN>3r$DUbu)ijOBe=XOKN1GCK7Y>2SZcOrgxsg$mW1OjY7VR*|tfbX-+y(dg!pxFQ-Qjk0 z+pjTGxj&x6X0!g(&A0b)O=**sPevEP*yli3Lc((*Mc8LHtYrz@Z=Q#HPWf7iLj^Y4 z+3JDGL*}gk7(q{RS^fR%OK@mr-Eb?6JDhX*-fVY#ebDAiHuoAijr=BgV>AjYgCr3@KpjahLJ)cO<}o+#a)R zV+le}yoN1zeGQF>>jsl_h9Dv!YP=S;&oq}xm%AVldD6=ods+6v85PfOlPXCkse2W| zOItx%SXcze(sDNnQZb#wK-hrh-FHQ>QApeV^M|3a&hy)gq;)|`(vT`7{Ax~#E?iv{ zLCuWqVeoZNFv9Tm*A0}O47SJT@$z>kri31B9oCiUCW5Y#?OU%N*zUV|;IjSs&P}8) zXoT~gVfpOYugt0LKS95r==1U9 z<^*iUyYuTITq6eS+N+F20uM`ND3vD!pEIvBbFRflddg$*`bBL+@(|5S@3qNf9R!Q1 zE|2475Aq%YRFCL4o>8eFUbeNqBii^58A{n<>8?97@;*8|ItcCuW@63B5QtK7-5j-u z1=i4x_t9?M_NQzK^jiOOKWy7_?L~sjDxhiKjD1a*JS1~L#*MB)P^Qy2x>)zX;5mV$ zexH3{^IR)iS{f~Z!D2?`Lz3$SHP-9&$TpG0ksg5-kAC6>Nu`5@8K2I_O7ji-)AIEj zdCUWhXLIj+6(=-GTn6j5`MTbvREjts9sc~x_B2t?t<9pzWu&$!wDm_{s6a4hAFsTeC%feL*NJc#|VO#aLq}5Hgs_xf~+Qp z8ngG&mv4W)3w3XQBZ9W+Bmz7=Jl+q%{!lZUo({KI`AXIPxz;$LE=?p*!mgj(+Mnk8 z`G6@`O;!Il|GwkJmwe5q%3og(j>LC{3}|JC6cT!yD^0nsB+pzNpw9t=cU%@rT9gZ( z(vwd5hq~FGKIzfh%dSA5gfF23KBurTsVlQSak>yv*T$LXHdl&Q>tFD8DnG;?!AAXq zO5apd$)Ot8(x`SJ7`xf!-Jkutu6eB>i zcAiFoidd5Ap2BeES8s)^E}>uCx0Ot0g`k3r+5eEfh*{^H36HjO<35#WeT{TFxfdGS zsRFoyf?~rvk(k3f`~VNE>TfJev%@{QKEn_3ul-bzC3EPI5|rKSHGVO1DETPR)9nX+ zoXvkHeDlvw2nAcO!L2J#I0ODZB#c;N5)9L@WHZ{b^Glc1OMG=E6@0+g zmISp(DT(P&G=1W5{@tV67_Tp1 zvY1UuSp;Y9|JD7$Oa)ayad(f(2WHxBzmK?c}j zLgYq_x#`qc5*!y7AqE~T66ck&a!t1Go{ByQd(SUbQ5^=^Sy^o)H#_{Wf5#LsCix3~ zXxk_%Ffbrdb*B0HTMme^sJ z4$N!D{F2(OlbSXG`@gp-ZQ=!20mM{^S;Zm`F{G~51|VVrZ+{O6qyhpRN2Zg4>);i1 z`pd3@IH~LQ z2ewS>LU+9aFf4y_9?oC@)Y87yCdM;8m=I}?+mB{`6aMgt@jmYph^R>EQ?@G0Q#A@c zRPSM<0co##-#6^j58U?`eYfXKcKf~p^YgKD!yD)BgkkDqng=Q-rGFaBgR+1_M zQHYtk@=viJj?EKc4?RQ1DR)(Og&iBh9?^yPm9NuwvSPXCaKLWyn{L06fBC^&Y0ryJLq$4 zw)j;uJ(KX5VNgOm;4zENgcJ(;{dvh>T2cJX!XJa?ygAIcD*e_tEV8XY2uJ_*-Lk~{ z4|9Jr3}%AuvRP*9YK|FTye27{lgShAJFhwn7cBQoNgHWdc+6^>t4mo=nG>{qcnUGCm2A&L?_K+0e%0SA@dsn2YBKR}2lemeH{5l2EH)cg*IRaKgz z+_G_+lkw{%GRN01bi^+fuHw%qc|WlDKFM`bK|*9mxzV*?o;)TiC4;N|G1rX!C`yJ- zy(X58b~m!hR}J7bp_i~gyGzvUWyAhV*JE_Ea`UapWC33(w1l7@PMizR;ZUfhdJX>{ z4 z;tJ<(ub)5UDA8T50Ps_n_CJQrgDOR0PL@7D?Fm2LbsuV?ZMQ}9KIC*_KWZ99Y^K9i zI9q5KvhQr^aiN&R z8Cm}mIo=evdx6W$6RDL(|FiD|yZX^W857XDxjR=n9>1d(=}M#qZ&UTLTi9I<#cv=q@uVRjg5F0v$&g_htFua+ctf*C=VMV0wj9ISs+ZbrQ zcsPk&avwOu>}5;J;am%4_!(O%K~ur6blzCs)Q*ZEue$pY>|@ zH5Ca~@V9r&gpUlRG?>`55Lm$+p8J3z=SP?W6^f#+g4%BCahF_eFGg)G%Ur^IU2Q;{ z0^Or%*!oCzRQJmzi3CrtZqlM!mcz%yVj4YO@u%r{YT=M%jUTrw#K(_Uq%|T>ADv{e zwYDzMXPvBW8SEUHmzTx(vT$fU)x9@?Q$zv?E*XmudKwEzw~Z`PzsY&&S@whlh&Hr@ zoM_3X#EirlH|vaT8BdmgsV{dax1p(qyXjdBEXqE)W(4|R2bJ|!H;fXnZ(M~ zCnr#46n~$3+8-4E=K7?z1@YY)-M!1o+;iBFqd-g21D4F9v0%Z`=T_^olXub=0KKUF zd~)cYI0oS0EZ^KceDymk_CIRbFA3T!xxcRNl;7Jx?UZJ@v}BF{*1DDJzl2!|ToHVsDFciKMGywkNkHGT!PdkqZ*O|MX0ebT7 zOc+(uKk+58`wT0P9bq@33}>4%2O$y_#_CuF#V!XWy-(|JSoMXHn`#xN)A=`?Q&zQ= zdUkNb!an*|^|dBq%D2BT?WvWpw3b{Yu1Ie3!1xAK*(wU_6+u5>eq6oK@v5-0q{pXX ziMSx*4_IVLqaU97E*i)^?7nSU#H7F9IQwVYa{vH)dzJIRdh364*pw>N>&!%~m2PtB z|2s+Gne`~tjLo&X!8h{vgE4zwB7J7{vnrJhg*TwJBiV|gq}3^fH>t827jzaTm|tWS z`B8#2X3ieIJoo1?^TswNmYLdQ!0C?gpZkQ66#_dq;ET(_-#ucN^9}==5xQ`Tlx|PP z=}3Gph(M*Bc)m<~Y-B@4q)n(JWCEO&NkN;z1x9%(ge8G1BGIUm^DMY(UmS?VK}6(* zfCpK#Z$1PVwfiJT_Bn{};mecdAPX?4`rJ9aRD^ZH z@mpXN22-q%uql%K&#kfVZBKlZc`aO26)6#UOSYya!%a+HjcSY?H2K%s7MbQT_)v?J zitJtTH;~gBov_@QBu8ixkudNczS*$)j$hk8Gk~)1eUNf1 zjwjJctxL%>a+u=logRAqXJ|ZvlSgackpPB0(F(Z3AT#iK4RBU#KIG3}a2UkTtCZ~( zh^gEg;VUS1EWWyC6zSb}6&#~4A?i899WnWJ#bGdQ5K`Q&yGM*3U#6YPcwXzp((GH+ z13=^@G-7N8%^6bTiNU$wWh_3)CF9dsuaW%_QjKx6{X3MG$Jn!c)0eITj44wj3}9Wa zE+=yV+X4$12+K$~{b+OQtv+2_D@W3!s%zMfcl-Na`9;Xs=s3l{-=7R$A=$r*VgA)* zzMK?WRUV7|dwgZyIeI*eq@6ljJS-5P8WHX>uJY zbNV2~0x;7am?Aee^6qCT{Ah$kXhQL%H&0myK1$#|_#|!wQhl+j(qIOO(Du4XL2h|lf5ELu)8tz%( zR{mwIj3f8~#t=!UXM<~A(0fUZMW};b4F`sI0T!yGM4Ob(-P{Vn{cs zKV@3k5`G@P*B=6(+DvXezy-lI~XRA&Hy za?L{enzv^g|5?bapqBLAP0pQj?#b?MS%cFIopcZl>S|$I$_Jp&AvdM(cC{e+tY7>e zZkBSC`xX<5f(w)Yl6fmRh3{sv(W+$&Q^0+)ip}JOVM$A-3be# z)o(GoF5(MRsoHd53xE^Z*c5OXRs@gfmVbc_Cdd*CgFOW3w3;*8n>T|`-9lr{JD$Ln zYHbFvVE5aLJ+l1uI3#yocpUE(iEY`CIBB~d@Gwdx3(Pv42lG2R+;p3?sc|9C-n>%= zRZ_`;-f3e_JlswvPkgOyXaZ%x3t`2Gyhf7kjt#LhcY{a;(byT{XzkL^FPr|FD_JO~%raeuKwn(d%Na&OT@(TN(|Ai2JrHlt>Qs#8R%7 zMX;0~K@fDi-icoZ?CdyW3A;PK9W7bay1X}n{plqAT}*E)|8QUFD$DrI2X+h}(}hUT z9UmRR`SJqNYr5@`JGoC+|U1czPkU>XIlvxgMd?N0+~E{EaHCA zMvY1o1VU_?M`ZHxdr-|= zIM-nJ{IAdW?}I3UQUDtI=T$4^cFZS3)!#!#0Qt}F(UV3tfQGk}mNCSv6#Pq$)O{_1 z;?>)xW1y6KavOMR@f6J5$x*Az?zh#r6!dIl{4v83;)D4sUomkJO3o#Ygiux4%cJ~M zC&kXSO6UkkOR10^8MkpsVfho7KyK*$6~=iUL4%%Drr%sE!aoTPrR!MX zTP>=|)hNy5rmibWjV!j<9_TUJ9o$|{6ls#ky%Gp}e^U$8wp!gSoxHEhq=VfIrW*YW zqF*4k-y1SXV>A4%;q&`5Ilmznor0~l`IADHYDKHzMC512&ZgY}QE zfkn*ti!qY3lVj0lXIHI7SJdX3j60C6RT(9CAIG5fYw6+gDeznF=9FQqwJBoSZ&zMcpy?`FmYHN44CBxZAa&K{jgJVCQ|94MARagVjU0(NFW z=Bj`>8VFKhM&Z%&s`rKRQS%q|X1e#$48~_&Fz}x{)L*BNXz`!`tyk!1C!8w~$klS( zK?wdp8eYOzLqUeEJ~1*)R94Ksy+nXTd{rYbz3nl!9U6wH(UjX_aW|^wG0in&-+#x1 z9Qv%0Nl+H{zH`SuIkL`&a4Y@$5j$~M-O~F;N;cgOSEr#Wm(RVg+yE0+z~NHT&mDlZ zqPb)JrQ{vb1N+QAZ!`S`3lWp75a|muHg{1Hy@>J-re2(5TTK~{V{Go`P=#4;H^Wes(8MdK!86D{>?YD+s_T4y4hk=rox=Qbk!Iy}7QI~Sk#J2y9Cu@WPl9(|Pu*Oh)(Yt)ES zJ7c4Q2#1mBI?oe{gIF!jOH5$g>as%m*a?9^7~jRrPU{13Zl=3Ga##2|5sz?uS?|7{ z0n_~5cZn~LzYz*4yz^B1`C<7J;t3ww`4-%8?P^;aQM-++4%qNSCTMe9Ec1L1>RtUyzwBz5fr!p*@h z+Hxv^({2;ekr@cx~`3!VD7<>iA6_+-2Es zg2LD6Emv4%t;5tPv8a>4v@1i(2i5d{6c6KxZPTaeNYMfZ0qaWPeaw>_9gaaDyE1e^ z%JgK+s3a9b>V{G+iO{MST0KyrV}o6gw@npU!9xUcDf&^w&_DE?!vGO~An7ltC66L6 zu)wcrkBNHc9n&u$+QxX=cGKR~G0Ya`n5#W1|M0`fY8PP8qyqQC{I6EP{#FE5V^GM# zZhvGiKekIH^4W3~+a;c>-jn;U&r17ab@6$osZAat?`56>FRaCc5fLZvd^7UfP#~=ETm*2DcP;s-aJ1}_US^jG!6m8^cN1x+&HmO(7(IVN zvilIvnSAx^$)?wxy@ei(vChD{m1T4CcCPwiO0d`qn?~7vAfNP7m%kWB7OajXh zMetv_sKVbm48%g^&32}Dq6Bgy?HV&K1U{=F#EunxpFxl>rD{{b%mEHJ$iCIum);5*{Aw<|Mr zd%>_V{#e`z-t;<%tS$qyw0EX-Uiv#+yN2;RxKh+ag_4vUB^*EI%cz@Pu*JKxlO~2& zAF4(iv_0ZS)O{{oVh>ePXKz&RjRCZ}&ZnJ%5y1I#ap8xO-I$!=#_~QH_n#Iw&T9Q> zryf%g!xU^5+;zm+EETwv`TYm*8T8tFb46wbYT$dujFkao3=_YL7R??YB; z8(c~ijV7g5EH(RS)F8kRG;OEZr1Xlp1h`UmAf7;k56U^v@{q)clwff@zUCpo{p^Dz zA)GjRUNk?LKC*tY&kETe(dUUWoi2f~@1RXq%yTf$-Zj#Kvn)Mqoq~|Fb1=@GK5VM& zNs*EBw=3Gb;M=1O#6Wx-)ICTE389{@#w=99e3CYtFai8u7;1CRmx@xLW|Azdp`xP zQ%xl=2w?|Pu`5VTWW@yq+Qv(YK%}bX>g{%Xd*dNZwE70}suU&yAJAFm()4cw3p8l7 z0+BAEyVKeJQ#4{=O_rP?lqGWj`OA57xtvt{i4xcg!gzCf_5kf@Q|L?j`TbM$#EWci z@cn{+IOyv89J}dBcrPMUE0*Br+pDi^0m1OV>6i*;aIlaJbW2A9Q!8yaZFVVVOm2~|5CMc4mFN66^Dh-*yOeR8gYvCJFZ1aoGk*YpB9V%Khd!QYop^x; z6OJ4-=PjK|vjP{s=o9X!=- zesriR_BFgNkdV_y3j7VVQnE{yjDmswYQ9%hFMPMSxG{ zv(pC%9BSY9>gu&h(V>F`U^(4jvWmjOeqa-4EODMGAP|7poXA<=-{^OKeG_kxNf!_Z zkHUnlfrOSq`P|gcaq;Mx&EH|QYLW&byKFM1y)4`qt{_zwVs9_P zr64o!b|(s718C)bL5g=`7m#FJc*0 zW4AK=3~~8008+1%8=0d`6j;nsG8pafmHFjTmsHl6DAkj4w@mgSPlV#o|; z0{6nkAtX#_%UFrlT{lkXaZ`0X0NvmQpga1{1Cx)8f} z$c)Md^p38`5BuhT-(KAcQ=NYXYNoM707kgaWd8^c?pDn)tYMYMi)haTy<+Zo(s%p` z(j?O_;B)x*H^=mAE4T0a^K(mcN|u=G2}U@Oy#WHSB6;!+BwD_W(+{xib!t4|tKa(h z|Ls8ft~@bLN=n+^-dA}UgHh-&n0haYvukP_Rb|`C)tL_NelBGBRGoyt6n(J5NdJNY zy}@(0hPb_B7jq8!x1}No;~@>}AruvTG?BFDnC*%I6!RF8vu~_kqkuQCpIM$5wE^Cs zJA83Pn?C*U-cANRA5gd$!{ox~qs6x-mYlOY_KS7}ol~MTgy8_wpVn7%w~@M%GF@8i z08W1EC7a>QaD=j+r=}fXSsKSjBVCwl3dV<$M-!wOW)*>U-pwZgxQ=KDG~|N}@K^Rw zP6KUDG%Ns;^t1oGFI4x5l&cJ8X=Bzb3w?GL`K$89s6wy!!PL>mehGPdbzPSjG5!}* zbW$>xqw!>66mrfS1eNwNTmgVT*u`_*e#>{`u!$~&k+dcxQ03uYtfd~?ga^bypc8Y! zC(rOG-u!FkB^Wjsn;%tE$0hvf=<1C)o?%DeE5W-K?P;fMe(FTpLmefBG-jy;E@9g* zR|0Wo-Tu;S39szTeeht<+548x_LlWAQxT`=vOp@s{z@j< z0%3(mn`^ZW(*84af&1lGmzs-1BqZ)QK>lIEc$~rt2B5gFUheiKc2<>mnf@Qy+f92^ zc}ITF&{|8Zc2bHUVv=v%+m?UScfPWu&EJ1B0#%|WCqQmW&nc}~loZM1aK>uE)vP06 ztgDk~m^WmkmxFXhPxY7Yif7Anlr7<*M?5p9?JSKrh}CEcyL_AUASKw~5(El>r@3Fp z6c4W2#f<`08M6!>@vK8)mct^j3z9GJFV9n8}t85a7_vxBo*+?h3$$Qxv^YaY~-E+y%|T2ndvv?a!9WyFrt91)gQ&-G(j&-T0rTmAZu4H z4=#e)!C~n{9=u?gR{`4=BL(=SJTe8pf0~Szjsh?{j+`t63VAJ^tM9J}4la|Bjz}mm z2+n$@c5@5Sy@Ak?$n^toB0Ko;^IFqb_szBQerz2WLyqf^@b+!?NKaA(1#W-^ErorCK-D<@IvAER#GcbspN?o>Cf=e$zKmC;!L-n zKw;fTX*{Zbm~%E!1=lwV$)Wt@1;rI3X^AU&wsK7VUxbJ(?40g~Ar}nOKnJS6mj~*A z<_cflK;u7MgFJW=OrFs8WTK=ieLURDTnzCqMgGx5qKQ<_v^BE~g?_OO?G0`X+zpr~ zsE3HX;2%s;>cS5ODtgf4LhhWkyw7b^!JD|Ucc%mm~i>xcTEZ~sN%>qWtm2aGIcD8H2y zMg~lmI|C<8<3-F>CDh{0u?0Zc1161@wOFN}+xmm148h^7_Qjy7iKs!{o7WRsOl#XG zv4Fk-Xzbjgt<}l`c*KgeB&-t@xX-mJ_nTNd`?8K#9vH_3s(hjY?qhzs02>QnOXhaM zp5y0#(96+s71^z-mzge-v0jVyi*SB@p&edcO`Yo#gAkI&f_{LD(aZd~v9>;|?#C1w z|8WdeFq@p1)^JWl=ZpmTjdV{7!|*9zt!SJZnRSaMpX*#|=oJjUO`p8P4R4mHCOfJzYi5hGQ;c5v4>ExSr5Uf1A0Kwq6#+3Lgk-| zOwhuUzCBY_z?EkM2D3F z3cpU~vTc1P$DS6wb9_xZ3xild*+Z5Sjx`}8G~=`C=4$Cnn;iztotv)&hA&ENTh`e% z6SW34=B8LQ8~u2c?8Jtg&VglV>8zK^J-mnw;X1$KDO z8MRWxm}wNGEug&JCZ(7I~dz3ts7Q!*ubCU}E@hwafcsP0*jl*tf=fH{3_d z!v&0$fYtlbs15-H+)add_a=684My`HY@dp>SgVKkcIP9JMQMPA@ouTTx(Sy7z`BKN zxm91)+n^r?&;|hQ(6%qEPuE^5$_bbQ`R;Z0V2=W@PZF2xu3Rs_2MYUK=EZwv-iT`> z4cT?Ond)gM=>mK+MU00FWdo_3e12put<3rG4ZFKNi~QBvU{^{J)XXPJ2oayMG_ z?FT&Pn`?denw>_ic*0cs^8Ty;)e89CTh;+++AKK4h;b@=G2CSr66d%X#}y-W7YyC@P!zX_I)z8d&qwo9QjpyGOnJf;(Z(F{80G1AM zJ}nfDQ&Am0tRW^;2|xG28R!K6qE*WXh#VnsTN!2P{@M{8w>?Ly7;LH)r~?DJp0Q8%7O3kyeomgygbVZAaY z$BFyLW~EQ7ct!jYl)Tgox*lNJ2K`e^NU4rgfu5S|OGlb;H z0Ws~Odkx3KAiEBjVa;VhHw}Jm?0qw&gDlr;JcXw67Hbcl|n}S1jHNYc34B*^tb2k?1Hhoht~L$)4xmYh?P`PVPlUFM@1U?PjKZ;`KZSW zX9<6@C=mDwZqqLQNb4K->6@;#$eYD)VqT`6x(Of&Ckpmwb{tgXp9tk0Br*i+-M}yN zmJlai%%(ddE>06#r$OS^0lM?OezbXU?jH`m-kGl9@qf(d2zmOn)DTCu4T1kje1R}i z0)0qxhEWsszTJxXEW+n7$UWWwfboyX{Qcl|`Ub%b4eh(|D6njg_6jy7`|Rn<2wp(v zsrA?XJJa}xD<{>6{HQSCka1=$ZczDd!T8RC2G{rnV9Y(S{_}jp&v^S@wEr_AdfAV- zJD6S&&)QP)`&cG>`TY9Y#7G{M88Diff*JSGayvZmugcWp1@9be zOQxxbGc4hs$5KWxG2eunkSHQxZ_6UQQrSA0WxqrkKX(UawW_4`kv%R@H8Uk&R$WPs z-`8|~`*W-jl?~7b{{+RoZ%-2~79s)`zkR*BGQPY({LyiO#`Y?|(Q+Y?4-x7tw$t*5 z_TGqy@#(WCG^u%jzWpV-zE}^5jt(QR@WvAA`>eixG17xA>a*xOEbI}c^EnaNK6}}N zP^6I#5W#~;=)V1}i&99h#Bd76DSTB8x~IZGsT)Oz15kHgu3jah&kK|<5x&ojHuXe) z%s&ePPB(Li?c?rqyW#ZK5n?b|J8yM2yu@!2K+r?L@XHEiYQLuLXnCO=dS6?cX;etGh1!Km>akuSit znTUrS8Ql9};+eEDga{s`_UmlZgsna2BH+DZ&`63&G;X>-JXmuoO>fPDf^t7pncL$l z5`>Y)R_S1II+mH&6k<=VUaN%LCic(rpd9$^S0C*I2C&XH2oJ`o?>*4I*C~)M~)`3IVz~2*F2-idOcg8K#ru;E0&95 zK(n_@V(w%j;{*8pP1f&zd@+W>=r)JWb6O)KNBJZFGJ&T!g^iJ_`aWBVCG?IM_MIPS zTWk2C2Qou_h(ukTvE?c~@2Q7gkcn967|>p8is$&bz{1lsRo&w|uk$<*m#-v#6Bt95 z2rhqZmEOKB!c6b95q37?>kB*?snXL4z*ICnrhTKq29C2U?`wkmUA(=0Ou@Q@39Y_6 zF=J#B`EWR9Nn^ryKVV<*^o_i5Sl7c}3k^>Ij`(wg5rYfZgH7TG;$|HY(isz4XqMUI z1TYlppdJSE(aHCj<(Qfs=f?B2RQ&R+qxG~H28=jk*zna-n)Wt{y06X-^m(O08Mc-* zc5>KCn>!YV2xx7-6<1f*utlI&9wu9`NeyV|!|?U^=oe*vwUzIEr&O+-=6n0 z;^_2!&@>_K%3}WnZT#!1!RpPm-ve;wo6HUUQOGCv&*l>5VlRL-?ENB0C@b-ftHY#& z*wC-CrP*}#Nyo-sNK$PUko!wfgFVIl1=GIsw#st3@7`B~43Dc2zwyzT%ql+5|5<3V6e&vX9Wxu3XwxRj}0bdKSAu(Xubn3H?>u=oB`!C zUJ8vkM-v32UJM_0=@Jn4tNs9h<+LAo&H!noflGukG{UHXt_OO1pRC;wBfagWy-as2 zY>QnjcdKXjc|TC9GI{65=b}unwWX@KEf@QGstKHKBslMbpd5_+<44W6wjy7HK2 z2;g^0g=?NjFtMJU=(G11?qcwq=kEqD`u+tK#8#H~W3w8lUkUzi3hOa~Mf&Cs*P|1_&g)s>iyE@-N{fESc{d|Bxx~Ru z!rsn+3qg&k{^_x0ah_lLWnQIHf)zuy+@RFnlNqYLFbvpGzvT8czYzmj+R zHAzC=@zB91o@ZY_w3$R@TgVs}>vyv^bpzS`Q}u)0tLdAfza=9(-SjShEv`0%2))hC zT1EgfKj6nH3`zn6D;Fmvh)5a^tnaq>HFM%=&h+uz0o^)s*wl9-FAWrns_^RU9k*i2 z&;Qr(+=f4;KZrkv2edD3i}mxqS^9+db~f$L=oy1MmZ{K!>xNjf*Nm~%oV}YbCC`14 zE%*>fvk%|S0mU*YO-Wi>L!yTMQ-K*nE{`0uMa#|JQ(&Q-VDQn5-ZSnwV9W3Z#3RIK z{-4CB$(xHDVgaACf;4z@%yaj-%3Q|6uxH3APD1hDDgRCar%dOn>lgvBc{KjSPyIoR z*ng{fY(xFaz>(XP!~xQ>B{Np54k|mA=OzP$ucpCS)AX#HYgxq%M4V&ozJ?@~o<`g` zh=_;uAA0*~Td`0!DGGjjBc5{n>AkZF8$`pDPTA$7g2ineg%CT;p+F&7g-2T$2F)NPxyR3MgIu)~Q#Xb8wl|NPe0e(i~TzMo8!I zcYRFPF|w)`;0LxlIcrmkUcv^I!fU|(E85o=wakri5fa!@zYq_a4QxNw3L8|%zu1n4p%Z<-7$g*1U>mzwe~2YN8~+z&m~6+DH(bM2S}RK@Igj;O zQzV|)aw-aku$wjAd*hD9=N9uxbx>G!9*&;=**ieE^e}97$g>dC@X6dmI8xd6-b>+2 z0>_ri5ABJjeGRLO0P?@>n!Uj|xl4}yB;%gwNHN+3_*R28u0!6}+9i2aW*32UaBB)h z`i?IEyoN*<$kBZ!1Q7dXq|ji`ft&@@L~OBK$)_4L6@|nc=*da1r-wsVxyp3N7~V1j zK=r4U;Xlv&$|v0s(Jlp?!he1&0g4YW_ETB1L+3#T481%DQ0m>YJ}7I6saz;^2&~rR zF>paT>Z`QTz>v@g+Jv2r*b<<_*K#}=V70&wa(wP*OqX(5s`p(>3%YozrvsVQ^kxvYY4wF5HQ7*^Kb&2XvN)BA-nKMU#Zg`kDDg>vc4A7MaN)Ny>}e;DQkXvh zC*nXKoC}BnM*JZivjGNIV~S(YPxdYM zRTT`mi3=_$qobLo2R2l7ox_u>^Ysq_1*u20MGC9F6B&U1P*wEpn{dp_FE)H$hy9`I*1HzgQr=*#U0VrE#PCH5E4_E= zW}mZEZVNE!^CL1G!Ker{s zxBH4IQB6V8+~eD-F#t0X&PoR9qaDx8Vy^(UOFF@cvK{VVMQ}cS2WFuq7yQ@D&+-2R z$ysyc2%CDGHVqXVC<6MsWn6IH7}W;}O?|)riUl{1h}Lp~3VY2eOhQ6f?q|7qA0>u* zikNnrNwaB(zio)?x0KJR=jV?%90Y6Ysa6&659Iv4?wp_Oe*{hb4z-X)G3Tk-@$#?d zl_4FiX9&?bTJ8kdb7jF@=#RPzIpAwgN%w z26BLZ3tQgFkWdG7f<*RbXpgc3ij08pb8;D{bX`VN)}b?x`vaZe+CqJ$H3cJ~g=l5> zG;xoV`=501pBLd9XM!pw z@V2-Ph6Ti@C5<;fVtXr2pI4oXdE7vwM*r;_so`FkO(GA0U1O>pVo81F00krCyMN}L zfgAv=5Fp=zcLHuv!R4V=Nm@snUz_;&`T%7YHFYQ@6Q>WE>wm*Ks(L^w_wJI~c?J`Fa zs#xm2e|`LTW!AX*lK7|0zG>}5M{ zAk8MNoKDRUFzlmf#~uZJ`KX1xS~*z#vnt?6*c)#eRZeTl2FF-bHrq&V-$a6>)5=Z3 zNba0wNG9(93eJ`9i-^|In{Edr5PK*ieKjeOjj}>t=4#;ik^N;eAnv()xO*p>v{!dm z>Rp}-GR`ly)8ab|DwVC1{Y}VUgDYSis9r{l#dI}etuo>rB@(_GiAZhxtey)B?S?|y zX#sz>*JW_MHo8JG@P4MK!jfM!B<-`~oGP$pNEe-yk@E7ssFM$4iT`3`BntmB@#LtG zsCGGcYnAT1>EAE*kQ`qM#vbkVc7_V1!uoo|VUiMSX?SQ~vkoc`r%Hc`0aWJeJZPT% zeZ-QObL$;_Jt>Xl5Qvod>jzd~R$q?OSkQY_lZXcpk$?P7kU{6RP>5MKXIE#fy=iPn zZMYznMJfQ<)-6E-;?4gKNQ>e?HKbpx-ZG3Gw3N);S9sjDM{wmj4z zoB9ay`n5~hy`dnZ1$juDDmbGV0Ff!+1gnN(AS{TDz-HPdxjP0*{Im(c=|*(HO+CYz zj42(5y!JQg?Lr$YUtX?qUlEg#BL@G?rx-?+c*H)3Qc|QriEwXo`v48jOn~ zqDx9-6wNGog`B6NRBs@OvaA`n$TN%)e2;Qee!tmU!9P$YvU)yAH(2tBeg`gCtHJ&R zsTOTFL+fE*sKn3p=J}_wNJ{aUd9_5|KI}cfE@}?DHius`)ArwC7)h|QQD!|`F&bO< zS6@wukOh8wHk|7<=2<@tLFtMRO$fq{)d$Lxk1gwC8^RIab+RAZ)(+XNn~QkA3Ji4t zwy#CJMGS%Md$mTkfWZimmojAQ^_zF0L!FOAueTZer-1P! zWrhyzbXLa#VC$L)7j5E?r*p%M|3QvPhhS>a9wk%1SJx`$h+T#of2l!+iP*95w@PAv zRduL1G4$^2UCJv=!0yLXPfRPjA^STkknV($#egv>9XtpgCj!g{OJSN;@tD*`X9$fW zvwR)^pI(ZO)N|eJ5MEss$%Fk?ete-yFh9Xrkd?wPo8V~ zn(kn@-OXrzN~AQA!+d!eqTy(Cl9|55xY;QCn-rNuH0)c@T+^435>+G3R{=$EAm0aQ z!UL(lkK6v<4oAa+3PKwo$XSc}$79a&b`kqV{S+}`5dfJvlNKx_eQe$65Dq$&Lj%L9 zm^gL8gMcNlX&n`90Ba;3`6PL@W5_#q`CCUAH(%3dh%GnuGc{LQ5U^-dGm>W;mxDTH(!^t}L zLTP+^lk1&_q!7SbGtjyQ3NOesSHrLXj$udVT}9slcByi}!|6;iYMWkh*o;C?8f{X3 zQ$x(%k=sW6lY3V7GNEm|D~y#V;UfWzH{_j^W*siD!q5TrZfvxS89jMjn~)dNwyR!H zMG!LeF_26@;PX@{n733b6)9xcdSw(%w#H<<^ko#0GR4X^F`?CZ<+%nSznIW2u{eH| z0TWgXE=*8caBTbySi1rT>WTA4PVhS&%vJ-3e2}^;I_|su%!FeRQh%VwN+)>ie9pP3 z42?Z)Q3TAdKFQ?;ie;o{IqxSKD>v0-i;xrD!OgWDGQIgW9)s-?r7pBYO1G#*s%6}j zCxV}!nrQ_VINFfKP5q{)cNLmQyHrTAow+!=R`%+u=|4VUn~Z;DpWOaNdDMUQ^hT$F zkb+AmA-^`nP^T8#cNRx)miGmAT}|tY8i&PFq2vd(>;{$V3zf9BZSO%C_MA!shn+tX zkAo>V`G2GyGZ@qO``{R3w>Ig$U1pR?G<5M#G%4fu7qG19ef$Vh+Ma$c#=@=we$YQ4 zpR$pbT;(?X=X=qiShMEj&Y_@{CA6q#EhppFLrc_XYhcIw+Suq>m1=`A7G6_AK#J6V z&oEV}A9v624hNnjWB)JIJpzQTNqB~p{udfs20|0Rp0YUoFSK|JghF!uE~Wf8RI~d4 z2)V1)xBTxL>we?k$E2`M3uAUw?sbme=)Il4}M}HEV-sH?kX={jkr*5G;kSei6(xS zoN`b~U|-_szjWNkNF|FH95fa56g-yxyGBVGb@_}|LTpH(@?&7h`Wl9=p5DrOw}M|w z6uauO$MTaCx|7!+9DL^=7y&;{Rbm`wD(&@VQ4R-x2Hd9aw3`=rCl|DM7n-e%tBszS z`Q$H^A&S1)dFSu#)S)s|`DI?Gu*-)qZe=$_A^FhqJm}!foQ9{=c4I4+nI71b6NL@V zWztiUh5nk@iYkL)xM$Ez;@sQJ30Qi>rcG#V33O9cFz!o(|Kw^XnEWqdZh+G`E{@qs@ zfLrS|-YvVioz2`=V?oAo4w_sku-Q@P^(e$8fw%^>pUGJr_{M+Ap$pe&2q}FGccp= zM1EMC5F#fglXpP**LuQyCgD0noF(ds*?iN`26(}#8Qx1MvPjVa{5t~K9@ zn2h}Ig`9gFH2d}D&D1g9z_+%^H6)P(*N2`#hu(cE{t%Z^4=|w}%K@Ga0>ir5vL%5; z)9sDejs0x{aSu68S=5cxkafKJd!604pi-ufH5HT60U4uEW`HryZmY>Om3W#hXU>i}MBpbp40$>*bn?_~K~%biaiZxKF=%nQ+R zdtpcNcC-{zbLT>p368YLkT|}7Z3{2=@PUMLMJC7>7}RYy3lWJMzqbjO$wO|d-@09> ze>prg5}rHY(=$7Ur<0+wr*ty9amSpQg$#d9BA7F}!HPMd*#=EM21%E1Fo?f0GO&G; z7lPB^U8T|Li54*K>Ysa?o0?{L-oMxxmV0U!Y@<&)9?K#;Z&K7>F5mx+??qlsLbNMf>t zW<=yyz7M^Os};Gz{p@DNTgOml*RDIJrO2LAG`b9Tq0Q%JwgIJD%cn+@z zx|*QFgq}SEu6_59<>P??VwPtspE1@ZLboHm*LamneA=sYC>tv4JZa%3j4u;kZv}20 zg|D*yM3|`!{!+&<^?ju=K}I+m6*kQ#^EuwjkAwFRySFyfCU4MjaD#-(9MhkoF31m* z5JiSX%=Y-}W8^=pi_6(@ixjf6xGu%--E7u%cI)E$Mn1|nzr;(}^W_W?n^&OMz_qUK zxYXcO>KN62KwgNSmR%Ys_gd&Z)CF39nX5RCzl11*dJmyw?2c41JZ?2kE0yT$RArx$ zyO`)T<-{!FH;#mkkz_xho{$R088tJQ*FK=ms+!#Vz;Xu}=FHiFU(($gB#=Eq!1 znpZI5w~14rivbiX8LTuOl9l;FeFI(n?AD`ZZwq9ejZdxSx)Xbs@+yibwI4T*ezu zQz)NXjN7?TO3-C|F*#LU6biqyD3(HSRr?~w_98cus~O)UwsV|_XaDWgAW>v{n~@cA zHnJ|B@r~fiDAQJg;ah4FDxs<%Msn7;Eq~Hx(>M;2Q%&mNCRm}PLHlSw`D&o9O)kCZ zbq-P)Dioc!wN?wtiU^QXS9~U$>*4g%y3-+9b(9O|#EkYYDGgrC&v^^$P%)(EOf3Y# z@I~Y`lLpagD*>$>xy3U<7K^=b^gM-#AAz0{7yxTHXl1wgjBCZ&{p{itq)t5V@=?+23<2m$$Jxm6mU#W}4 zi5UevrLefZ(QSD(EU2Y{$b`+0(hAkYZr`NrQA~0N$$;a(PQP6;vm-=Ay$BE0B1)Hj z+CL?G^##aeFJ4UkBVKeoE>!FH2)nFs{F}T5tRwhmR&Tv%1o@Xb9^>Ot5>g{L$;(5G$|U> zuMbGc2Ug}@)=AP(K_+JIJKu_RV?FW#)eii=(aeO}Q(o;%$$e;nY5=^Ibx%&tn-%5y z-u`H_EtlJzCo|x|%bUtrd|k@b@M`XVh_sU{w&1Jn)8Xw2mf;A{glA5|O*&y#eY>Vc z<)bX(01*Qo8o@W`xtbi4_)7XmVk{bPE)pi+}8Jx zoZHNC9N~kY;C&N<8jd>~hW&HFtKKpcr2>uHD4!@!8cA$wZvVXz%NK8J*=Q z@WP}`nbhc;?!_pFlhdq+(1%2LjupRwS;yH>3aNUO1akqIcfe|c={JI(HW+F6!g#Cs zZC}RlrxsPoZCwdu>y8So7@5A=O2UZVoJS3W#sU5-PY`%3SPuDFWQ0{=)wIMHAEzkv z$U#h-$u?Z{c!J${0INh_ORXvQVEfb8_&%)L%|O$us}q2aSX>K{2iARm_#gLY*c! zgh^|5x7+{DxBH%Rhupt<2(v6(^Bfu{&}yPJfuZ!BAR(BD2SJ~pS5o(iO}yN}bHGNM zdCpq@=S<(em+w+H-rk?QZ4{I>P`QV}I|m`>%$dA_+1kk87g98qd6Q>~yVBsFTp0hY zZJlM-ikwaxHkvNrWjj6eW#%`-w!Yli5r_Tyy}0$GpqjYKIkG4zIM0=3dKMV`b4 z9?P3GWd4e_Tl^^gIB)NlN07k1R0Q0;UHs|R3h*-RQ4~2a!i^iHnj6y3%?`UP5?77n z!Q$=4Wkp$59XA z77-!!FE!wMuI=Wh@G!FG(f4g_QorlG`(GD%pu-hMwGdYXUl-5cPIZLAX<%waJNhkc zg-!w4SatPUC+m6rN&SAzci`QAH*7s?^&}3SzN!t)dG-Mv!cN<#z)=vd?lylDB-$a} zZ9N?Itpe8ue~YSi^-Ba3;Nv+vYw(O)F<`zU-LzAB$gV+MhBNbFo-HHAJ2l0!CbM5k zfVlaQ1h2uy#5!-F=K~^t2>73vfq$`aVP^Omf3?>{?JG|Mqkcx?JgJQgdjJKez@8+Y_CmbGqMCGrLF@ zv=WU|s6R0Ux4Phn#R#rn)-!J;gDmXxIBLKAY23jz4{=P`W6@%5tqoW07#dNfM<;%< zSx+RLKvPIPwuTQ=GU2@#$F5x1%cpgi=OCH2kx^iIB#ltWaV(B901H|FbW9MoH0n#m z4xF*!!U|7Qg8LdmIty2%--RSqw7<;~8~gD`W&q5(p#8FvEG|X$AIGPr1{1n{QUL;N z)uY>bMdWzclc1sS(|ROypB4*G(>;%vDzOe*l6|l?=&^iNck*wokSB_ibiOoHyE5hJ z!|#_Hqc{*GA+yftQ3+A^W}G0AH6HxzQIlq$9eh-}G=Zx@v?wtnG>HWYOm&JJS4 zQV559hHY8$w&j9DHaEAbKtxl)iz8AKWR>T%2qL1h5)%EVeR2T;HW*OhYAtA|ZnA+? zg8EO=S4sh#pMsmW21#r|g*WxqU~+$`J~XIPlwj|jp3uk*B~_V-UNk1}__FqqjUx_& zgPJg&{+Hk!j_2W*$jUgn_vF!~9QX_+Sa@bxZG9s@{#ZnpYD#tJ_NfFUd^2U2&E03P zL=f>3tPadJC)CO}F0f>8TW)Ti2iRh^*XI+gJ8W1}_RaOFVShFd3n%A|C%nKRmrS6) zj**^)tSNCKn06%a=K8eJC|WsJ2L+#ZJmGSg;s)jO$Jzh6r`oNZWNp}M3^&(aiXN$u z3qJ1cAIKF*y%MOkFvv4{i~Ua5egxt3Ae_iuj}BVPkQnqC&w|7VA44t}sMO5A+L?!r z2=NLd=af;;rRmGZ3%J8{>P2&B=`6`R@gd*Tuj?i9qWo5xz}FQ2Wg_ zt$VS;LCtE%;Aua9jFJSE@rsE z&Ih__GFdVpoNoq}KIQU|aF@)n(jOHMpn68oA{tnU@uQ4jNX#4S5guUIQOg9MgT}}LLW>|@P@4+`LhDnhcg;t*c&9e#4MYYG$R(yCUUuZ)3O85Dm zH>=Pk?~4L=l92jX5?Ibd0*^tcgJ^ezu)tRpL1~RYws0jtmO&4P+2p8FvV@z zml5rIRp@|kgH&H5hrk@{J<#Y1+<&7CKi;dsQ6T{OT27oaE_+A1)>YL>edjZT_{!J` zFZ%BP>${R5p5vgWE>*+vj@%1vJG$IG^iI#q5;&w3VIsjX?HTL2I(%o>uj;O&QoZu6 zW?%5#{wq?Uvo-KZ)&`CHv|0ZBjC?T~LEplU&-|41Tc>H+f%xU0zOxsYdtq@~+a;{_ z|KFajKk6##B_osKFQ$gYX)j~NcH`ac`_#|T2tAjo0%X4v!g?%oW)U0a3?(fL;(9}T zi?xt{qD#|6kB&Em)A2d2%^i&Ypjx@v#14ssPG(Xl3pN;L!d&$1rR^o8>liI~o>#SsYhTQjGg9(lZdFh|B8#pu5)SzuiCXx62xJ#Gok& zEd>*jbR4XDkO{dKZ#+lvssa@y20S-mM2^8X;X5Omq%i?_@fl^j$G4I5<~4ex2!vddb5drBV>&xh zX?(=MV-^pn(C=#|gEUbUv+U4(Cdtc{C_JQ{?sBR%^<2x%9IZzZLribu`N!s&P7iwWr!1^iRSm7GQ;mWzTyN+5aD zESP%gJoCYrM5RTy!1yFzv4Fzm{a|N^xvAwKW_Y3QH^i7g5d0^1bu2e>w~doIyXE!g zF%RKeG7R67<#kGV49fx?@$8cQtNsqd*1t6&P_cXX!>{kf{!m>3ov3nX=;RG@LYj8A zfxgss8Aps8h`YE15cs23okA6mM+bh*PAH@N`Q#yZ?D}qM;Iz{*+5B8ls1J2?-rWXA$t>lKFId(Cflyh_Gdt^ScRSXw_0Lt))`5fnlYi{{ zWT*Xle%&TJ&cbtYBKKb(=6fRC+uYVW45cOuroJc--QK?QjB=o*i8g*lF%aLfncj7p zoiNkVe@f+U$6}b|HpWSQA8_Q+el=EeMRa}mZ1nT6LfE5iApz?03p1IDoxBcuf^)is z|9sGPnWvn>_v?D1+u}kFBd>^-cJ`g+aU=g48YNCyYDy-o5XQ+f7MsdjLAU(a5;gtH z!59ydT&0HM##hX1XR>3WsH#-`S=gl^3<>H?klcyvQMENQgV}ILL%VC%^gpxRqD7LYgrGkV~P8o23|0yGM+ z7Ug*ThJ2>7e=){qda{78G4bT3XHXdURxAMnBZLWUm2@v1Q|_okbhIdH)JULE^azqp zp+l*@>btV~j**N(9@`P9CyZk5LI-&O=WJntB)1yry)2Hr^ zmY6%3xPea^2X7`Mv!kQQ(nQ``FrjvqVhEjPDEVzc=|!@b*l(m5B4fsySr-& zdt%_!{|_rb;R)={p;$nF5h*gVLve&MrExg~!#(!T|3tYA9kE;UUQQ#uo#U<%KlTLn zBVk#dthmv)6OdvN{-V7(nLSuJV z0&8D~pfcx4jXSe1p(yVJMJpklJqa zoX>(F9+Cr%ksnt$Bu0SEK+U8nhhH|cPlcLtaA!30f>rUXkb8|8qq?Nv?4lJRds~*u zJ`QZCAQJ~_JXLG61!=G+DW9eGGRjUK^LhO|L zp>AYh@69sXAXxV%-C%7k=@3bYFig3UEe_AcDDC{{1nNPxkOjo~QSV z5FG;SNHbjE^Zhh5HD#>@$ZbW}M*-qrjaZO!6nkVV-`vD#e*E88?3CR{PNAyz3E=X}Qv0T&6~qOTNRn)G zQd}Tr-L7OS>hxc8Yp*A4ZXbDGorbVES&B?hDHUVvHFmQ2rJI7GV9NQ1) zQWQ3G+Ohoj?12U6BROJBW_jHVlb>n8U-KvHkP?yo()>%RGGSBLePK!}Qmihl$*hg3 ze+JbP(4_+-8Mpc-CaRZ^>PJ@&nSR#n%l39)GNdRZURlo^>U3k9^38CY%3p6&UdyB>SXz15?LMx|`o=mj8e@;PXK_KSAs))}Zsmow-xLuskv^L`9 z-=shNTI-Q&Ac~^En5j*7OcnBvBE^vv>rmyYq9yN9qBWTv1sPvwv~wNubaR{>Gq^#< zh8RVj#q4>*#&Qt(&ITEZI*;QOQx*%@jX-Myz#I2#87oIdI^Y}o!I!j%uTVweTQ2&> z1-S-z{VZ$Nvb{d!%V^coswshYL9 zUy-M@D6n6yfm`UYuja%JgsPLC4=~>%=e}Y|Sb`Aj4=1e>pW5u}a|gCA-~==x43LcLLP+qh7$BU=lkpPM7aW% zXBxgTSkPWXdyG?*fH_AS`jEiuYXc*M^KVNq>)}=uZkp{6sOK z1^r6)c%*Ooc0;lL^_pnH|9$RW`=?~^yZ9#?w7^$%G9dy5|HEA@H<+*s%A3F<8IORQ zWRmzNzwHhFyQX-WvVIf0^o^H3JS;7*t|uq(ds_Vqrz=lyfwh7j6j?nC`T@KFV|iw; zAz)qz{VcT+F*bXRTv2M-TPU|3xbtyJf8b+!dHG(Ug*mC8FR+ru@q@==C~eNlci0s( zsJVW&m>Mz?dNgJo(Kr6bwz5gbR)4Lt_lB_G{BPrK8sOc=4fv;$B*PB7gG9=3du#9e z2Vrkd%g-BoeG-e)g`wkaL2Hg)**9^)g6cy|KVKl;nJWD!^XJoh7P^1L18WW{zt;Hy zm?-XQmx#&9&msr^Sx_@cMaQI(fCW`FU>NMNAF~x&3zJG^+Gay9D14WzNei|^9QEEW zB1{%9xpODxXhdi*vy$=Pr%Nb;DJV3vZ0<%>%n5S8{N?B9WHJuDy9xX0sd_KlUXWb3 zW$_>RS1y{3Hf+F^|CPyJX>>aFyWG-un|J(rc$E8NCgyC+CuS%s)SnXPKF7qet(lPbJJNy`8Uhnc4-qz589l#pFAW=7_x@V@~ z2&z|b=%N^o9Ren}aMaJ%Oz%-cnxle;YFbUKhDG6oSt*YiL3ZzhH~KN1Zbg?Z`+_&F zW21r#D#oxUs|gf1?^+Fi4qR7d3=>}Vra zbUoGVjIH!ahE3s9n?~s0@(z9@$PevAZdik9F+1e9z~scBD4pMBl~5cM6{G@KtbIOE z9|Ty)Fg`6K*Uf52GZPID+LZqoMIkEg$}ao^m<4gW*3|hY>GD5n3rqVj&g8&IA@<){ zCHxGRvArU_NGZ}5e~fx*yk3bX$SJc#Ij&B}hqk2m@Je}dP*$Uv7X@z5rn0@byN^OSKQ*Z?dr_YYSTKc*Xir!tR=>qYQRr3BkXiq#4Oel+kO|NzPz9 z0cpaxTj%agq#QMm<%_r^VGoIbdnLVs*a}hA?2p*gm9AdvNbrVZRfzPc9v9*2NM5=Y zPl0xL4_>~JrF6rtmv&m#(%&seD8tR#}<`gNo~D9ga(s! z{J@%e3256;+YUk=58=m%bNdnpo7>w2!*liV4HwoE zRK9;ILo{L%UvbyNm6oJl52+v9Dhb$CO;>gqRP0^R92KSNvQke})v&@;%@xB3Q3{#G z#W0JDkI^+wV4BYfR8JI7PC-m{so6@%@?p|2$e{G4dt-by?W^`k?u_nEV=neCR@~E} ze+68m9b(VzYUCiWKWN+%_a`+a!7Gl4dj-V>%sSChO%)svZ#LKI>|uE-Lk5hHTygj* zOyA;e8zvhvBrz-3FQBk;^3gzR7$PFfiwhfL`#cH=b~gs<@DOLC{TFm;6=wWzHwR3R zKxpsn8$#P;t8yapUYcN-U`nrmK%L8D)t>)DRX!juUs30UdX^$L%uBUAv(OLxcmf)Vla_H-)T34-r-L-pU_pz2XrcML8!Tw_m= zYm&-~1pqXe?RJiaM8J}jviI2HG76NTRjLC$HyZF7SmA;DW>v1m3x}n9HA-I~#YHvh z5RSc)y=tsjsShrpbFkJpw2i7xbk#xGV_h;-)ylYN^kp^S5KXa(x8(}{6R!Z*HrkhF zj= zlsTW0RzPjB0wr12J$iQrr1@sN)hWe~*QeTuK*F#1C=DIn{#yZ3+Gl1k^**oiC_aI_ zW0y5&*N!hHA|L>RNlUoFjkGiWQ8d3P(R$s>KJfE@5ayOHrQ~29>u?r*JOUhL5^9dmRHC!$+34W3ZV@2}8H;P~WVa6IDwPP4+-O6u+o(=m zTx+#RNsA_YPPaE(d|pmat=%Y-1ggkSLbOx@mio=k4|;gsDJuFi6-3K#1V3>4wXWJr zsz|&-iURjA{n{OCmgs07z@yVYie%mgrbDMz!skx&nElH)S%>9>HY=zS@FKNZ%Or;< ztpW>nmdQI@{qj7GtOR%(dkEVKE!>aBI>^1tN{ zpLBh&IZ0i;YNIi8F%R9S#cB%iPL8=C%|VMI<=Xmq;bhNfX2m$=J9MFW=%gEH0S~Pv zN2ZnBu=UHy#Mk!7hQd7otwyZU@5<`G-E zwdAxNa?ll6rOX-tn-}L4bn9moruTxI^Hru9Be8>3sKoPd6q^QZ)8eYdzu_et>#NK} zMcEF>Y`z_Vfrm5&`QYmMw~CmA;>gur{nn>D8waJViJ{b+L0wVtwPl z<<4kfBbg;a-&f54dWX`uBM>s`mf~hXl(Gwl7$FvY>9V1hl9O>eo{Y&c5zGmCos#tS z%w`bh?B7ev+C@Q#HPc2BJW+#RcC4(DZdleCf?c zc;EYc^>RXUacxb+@KI>6CkH>UoNfSC^!_-5O4DNA6PIC1{s&eV%iKodTHcs z3hk6aJQ3y{${IZI<{kDq;0=Yq6J1_^ZBI(}$YVTAw~`rPwLpNuR+fsK*XD$02Erd1 zVMT&ib^3+NMo+GATVJA#Wm#|>MqI~zSs_2aFI$we-nCprfm*G~W0%Q!G z_nobpCY94r8CnHnjsj}3XMIN`#`1$t!pOvDQd>ub}}a?8Ov%}n@txdMwbIw*>|Q;kM) zM0%<~$KNx*CskMASz>#TfyJ*;dGj>nm^nc@QBpy%c@>RRcDnkVE-W~@v2^0|2=N4-{;oxeYMB;~+frzNZ+Q~Nr)B5q z&p-^Y&}F39gD>4d3ed>|=IWwcysDMFyJGA*CduXDj?vY&xvW{nDu`Oz+%i`OnfZxs zXp;{-eI1~986gA4Y@OB0%9ByiXjyfB%W@zXL4ctL8t@v|V#@3|eaKCi!&-gcK5qxtNHVk*{8Sricw5Mr zoNxw74CzlCO#{G49$J1Qq@;o?G89=JM$NoueK1qD18W~&aQ8#PXUxhrC*kCEo z|4(E>VYD*7d?%-4$K60EAQ?@}EiC==hNXO*pd^K~)e$mK@`=@XTB?O|I2U&n=OK%$ z{{0L1Z6c_<-+hXR4ZWDN7d>CeE&~g~=Zx^uAQ#|V>u+11o!g6)po8^kuiVigu$H^| z5L9C=|5eo{C0P5!fW_%88OkV&>z!&og&oBgs7MBud8Y!<38eSY@JVgA4dTM07vT?v z@uC|h=J2gDX|l_{EmdwkL>M_WEiPu`2xOS}!u&(TB(q73Lp?7I5dqX8o-0%7Kcppf z^gnhMOX}9PO^;k?k*=eypx4v+kLK_2f$y@dQUCC%QWSr2SvnC;tKzzvtRoG+oi<9G80F7&BslDMz2cQ!g0nv@e`8<2Jd#)RI(N|0wj?FPv=X$OS5@&Y)^EyoTp=^F&v*5be3< zir70(K5D^ZwT_$%*1dbXLoai};nyxmiI<>WT$@}M6sv84W-^}L5zc6#=d^#J86Il`Lf189&!-{%B$^l+udzo` zY`5E)sD!sc(#c-QnR#9cW6E1T;m_ihzNGYr1iUg{IOA#FAC%%f3U!0SKl0mePz(!j zR{<%^g1tvAgaKftKZ^Qm^5TD<~3Cr2c$b=%ZQzk0X*XHkJ~1DAWXKnRX9P))e~DG)5m+p zbNZ!P@L|;B2_p0Ex}t20YTVg0ZCD2d`{RsyE=6=1F=$pYaji>J+Y8*M(2Mq znNK|zPzYKEOC3k3OH2msxBLOl4$=zsmlt=8RRu;oHgrgtgmm@I*AN9UgW|ZiugLiW z2<N{%`?5BR9bxtyFP&g;VdJ)Sd%S!nlUZzJ} zaBoN*1XrCJq!}GN>B9##5vrU}n?x|Kmy1IjjiuGZaFt2Z0yZpUE|pYu5|m=+ULlUg zmu`GD=;Gm5%1bO1y%))=FLD@B@(?BuStv1Dl|f7zq94SFhT8K zX`!$c%M$kOt9S+8%*`ztf&&k3Fp-&MGXCgwPIl^ozj?IzS3^I}VNA&EPKeldA9(91 zMu9kh(anG!ZXkH$su;bh)^5@b&K8(ucs4T-NxCP_3x@k3DlTM7Fg;OZH$TDK;SaXfHb{}B61aEyVlSz+BVYyGnN_vQHIe&j{+zxF01>jhZr)rGY7av=;I@L7Mb8HgbZ z0WN{v{bkY1R=UerN?O(nFwS1=9Si|X^-91MGW4LJFwI{6DA$6wIS*6zEnD+UkY|&& zIT5lFUcV8XQbjGc%?HA%-6(5$3z~w~_Z%1UjC6d~Etjef?-$J|Z5iG>$Zx~R-x5dX z#8=b^O~u}1IxQJ_0YwnQL~+=sHlUZ6pgsoa02grRYvR zZAkmf#YDLi++~n#$kTW1Lhb2MdPb~-#=@H)=}*+%Y*O>bUdcx<%#S|)5}q(U#yJRb?W@jcY%wHhIgFf zLJv&)^#_%0$A9e~TCyH@Xsgfo*YC#eK?hgfa*D?H0F;N5-U>G`I44)Aq92RTw!e8#IUhZMuD!YpO!(Y2bg*L-I z2F+Ioy)sXi80*hBP+{L&gjh%N9dc2m7r+B@v*Pk{)&*zkRILbifbTsQb>sSrnsEA8 zeA;(AUc2PQH8?+YS3jgm@LvNSdoRlwO*qiGYL1G;6G#&jg-0zW7}WzA zYjFYvKNB{`(|5S5z*a4x^zcP|$0nKFenG3sd~Y?& zJu6$tQ?kKHMil$~2{PwSu;+_8TG<~vUt4F}bx$nO4YH7JP%oiBmS zv#dM+a-qd=;VhhtIUJt$zuFfP$UhyhhM4-{X09by#TM;T|F%dV;-OPkP^@V+}k} z`3z3)eagYImmI+Par|X!Wb1u2W?V2*oGZcjU+B|HPV9va%Z@$c_kwJh&v`}`&8oZG z!+tJ%ae^@$@$!R99b3Ufjtn%vnbX&A`?-H&WtA*H<*mm4?3GP$@O(O;a44LIo78Lr z@#Eadtj%{myD8h>qn}={`J4o4hN@fMDSYlQ7%<&n=3Y=`-{^7=^!u-^o(yavq9`!&OZq+F^+H`)3lJ*G{PKlO2!tXnm*xTEhxUnuRr+wCRv zsYPUeKFIA^K=hjKi~b*0z@RA0XY9n3fEBQi$WWk_7U;P<(Zfc(USD$({_#8aNccgp zXMyT_aTQ!B%eC^l)#>vTTcR_xzJUk)M{G!XQ5d|{w~Lf1sIEMz@Bi;3!B>fP6me;K ztzs>Q1+k3hsSORwW}h{Ztyk&`(NGF}jdHP3C;xR^-Q7Zes;n*sR&&Z%C z&)+H^`a7SN)9j(sz^XX111agV6h4`_rwhLq->X@z-u@)RoAVKEq+IA-67=nzV5pcK zIXb7(Xt(YliWp;cZw0VGOc@V%@nSIZ>R=vv{v%7^awX?)mT(|*PnmmL6f6ehF9N>a z8*5D54PgA?Ne=lT^z_)HXnaOSVX9{(9d5RcQ!yY z96JS}>hcM0=+a{ipi~YOfKSu7d&b_*ss6 zo)L!R+bC5uA5v%2BCN&b@ZW$dhXE2SV+M}P2rj^-SdFRmlzHj7R(BJ`%XobHTlb2! z?easn&U2(i@fXE1=u+)2rW=(bl$afJR;EV7P$=LFmP)b&Kej@4mw3V9Mncrfe0EGh z5S?>|2H4c-|M8jyziro@)=)z--^;_vwE1m3oxGfPycFvqi}W1j0Ugi{nePN6BXF`w zV1~z?%m*YNCFuE-NbAs)C!S+C^dMcnMgs1iC?nUY=b4L>A$yPV;T#jKf~vYf9IiHQ zlHPoN2C;wGTLz|%z(!)7vyXJ{*yh!ik|JAYArq3#xq@mbe7v0T1M@yL?v3?FQz4dH znoe{EY*O1p>FSO^1baMBI_jY(^#V}sn4?wb{>;u>JEv5hI09DpEQTN`g_xt;$)zdj z7(WMYvX~t&TNS%_P_dMCVk0r6xqulTL~nl%smA?l9z1Iq*oc`<6xYJ6HE56%fw*Z@ zuK=lL{=G0<)#^KNZTAb8BrPT5X(-RfP{6sK7?i$e#%H$@5?MQ~$xwS4EEsq(T24Wl zMwvQ<6g+`F_4!|nL{S_RRl|YtyRdh(c%?|Mj?uc+pei~z1@n>E5PCFg@&3m@;_%}d z+UxblQlhQk9!qNqSUawjY^tbuKVm)Q!d-Df<5Q)q`-Qi8(-)JzgVN^(J(kWwI(w&X zihL^yi;2CWieo`88J7A#L_-V2C+3LjHHxT4)q@xy>K0Urj8U6VsaO=r$$z{~dN0jn zEaBZ3FSieY)bnFI2}@q|<`$LV7B0}cW5Z|YaT|sp+!_!7=ZHXq`Q5q;p;8F{g}>fl zrNvi}(DM?WD)?8CO2VI2^!$l{8alqhspGk3ZQHC0VWF-cC^nH`GLu-uW_6Tm+t8s# z*nouZ3vUXb6QR5%MY=}Jm|V?HGN=p65|e^%8;dx!v;pLUY-ssp0degF41W++2Y*U| zdjIhBq4lx?J5|aZ&RX23*@CwknIQW!3caIjv3Q9EMvU+E^O+%`35XT1a`I~bsjkMr z3a<*l!?M|*E#@%jL+Qo{di7xyr2APG8PQ9|LV>qYp=;Nd6pq+1o&DZ&!y*2vnK-94 zLuynm&seuIHURNJl*&*pXX7{B!i41yJ7UFknt$ESA%!C=u~ zD!xbuFbaA6Kg?n{_+_c$>J&TF>-wNAlqg7G312+|es#iGsV>aLnE*Mx$M7ikwrb)Y z^fGEV>r0orgki?hx< z=W?iAh^rKv(m+YwU=nZB(`I1s71i40Y4_V_7bpJh1Wvnyp(!R_%sEi_zu3@gA zIS6+mm6uw-leu7j>p7P`zS*D1h?_47^4l}}hOS^q2S${(nn8jjPSg1=DrI2jwFwY- zhmc+?bG{V1?|@wsza*0|H+92=7(Ol3vi2?pUwsI0kgFQoyp{Br{nOUNMhPV)l}Aeh zbS6C0o2#grZ#5%|Uu%R@ZL3qB&A4*aT*a<@nvU7kh1DNAZiKAuami^B7yg1Oa+4rP zn#;unKy?9YcQXcbem(Z|Z2M&GmjLaSMc4p#-fvderxd_U3UR*eE1E#4Fd7 zMn_=Ye7Wf}Xf9Ik(Gp5Je%u?TLhS4l^!7JH>&Ub#DXHIo_GJPkA;0RP|M)k!U8q$O zu?B}*#>X-P2PURl-LzLUM;`UI#;!>xAG#sSRoNz~7`n40PWF#CHASPY;fhs%icxN^ zVMe4yQ#DAHkY{Z*9$G!tk?l@~mtnjK)GG`U(|=8|ppy8%6DIx0e&UJ&W}XS_!WuVU zH6=-I0SK;SoIx6-CytRe?XgX=I5LU{=rCPK+oZwxmw*W-bl<@qzf%%bfGw}O#yO*JQX?(IB~n}H zAD~&6I36`xJW4@3hac;`hh-$OL_M0(Pf)}vC-)?#X304WSsu#vyi;BI1sg63JPVX1 z4bOi~Zd?Po%5f?0LN&)4g5nx4*e5?dLB#N%=)E3CDuRuS_F6e%P5aO8cE)?hEtVs; zZBc(Jro$@6kpdakp(2b11Bwo-HxsiG^+yA;=JSs#G&p;NomQ@0R@>#?M@4Q zcanZZn$;RS{vo-ql?aVFxWH-SydE-KN9d}%dRXwZZ#!`m9oIjugi>1}gG?!h3n#!> z0$Q{zezkCRi?a%N+#;Kax?MQQ-vqDx={s_M;%aE{9vNV4(irt^k4NI85R4wS78;ZP z?}vGu5=uV{eT1g(ZZ~u>ypPWfsCsjxndnY1zDJqF>J`5bO0+}R>Q6K>(8jf8wC3yk zkvH~(UiSTMF0}S>WIziR@2`7Sroh`z1AwYHZ4^dW^wngM7xRToY{h871(_FhCl_!RCms zTP^!|otQ7W0txMik3y`OB4+{j1;^)3GbU(!faB8!P^*J0SX$pYbM)?Ia}h+?HDsA! z8DNU?hpA$-e>QdnC_{zX?#+!}M+MUn4iD@Ca9WXyvO ziqCN-ro{5a>&aLfMNsh2HpU(Tx0<^`MEstnh#0OxS#jS)^D82EIv3OPUIpZwOq;lN zG8QcgVj84Jniv%PC$?-l`;X;k-Rip_{1~w$pw7|K_oqMnvb$Y~QZOpm6if^$4>>#p zNtI1hhgjl)Bl#IjcU5OCUB&B7gP`u<%Gi#I<{6HO&yF8;mz)EM@xVqJuCjJiid+-1 zMSg2nZQY30n7O<}PFx%!!ITC+Vg?H2*trVYTu> zPX-wc`b>JtXEy68^K({{l=n;}40KhMJnQev){31q*oalPDzeXDUcqjF`x!AMjR>A? zO3gzLaZ0-5Y3R3n4?d@29IZwIS)*bhftDP=Gok^N@4ywB4@-=!jJbPK(!qc6-&tw^ z&o+tyaT>sP)*%d<&}KQyOTl_M%LT8U4P{_vhNBWg_Sb)zfynF>hl&)c7Uofm4!9i6 zPUbB+H1#Ph6SMCHms7djdddbIbct?T4~`$mtJ7lDfe=%r06hG z+{tE@c(B>q&m2UkxDG^Tp;4U(A5U_pci7p8O8zDJATS3d0BlNu2P_IVLdKn9W#9Ta zy8h3OS~I6|ik)}V-?seSmWW%zXI|lA|KrNWPKs}quTi3-6iG3v@{$h6<_P>Tn1Gz!^`pbvQREB=P=|7jncA&o_^@_$yi-bli z&=!j`pmYGlDMtV+C;WW6M`c^|<3GtNFusGQ{l9FiUAJNWHc6t5)dl>K)fm?k0Ydl} zJq5q&#Yov^MxFbYs-`g^u9hoXk3o}tAOV36#w6f5x@CTg5R$8l0xrwv*5n1%N?FC4 z<$t9s+spTZ{aeTwIEoXqp#K0>AN2fHb9aJ;{lF;kR4A&6{C{$lm=B?$r;pQ1d&&d9 ze*07V>qYmm_Lut0YibIoi;ug@xxLY>Ny!$Kuk9 z%@|Ppg*GY6+NQ~$i1LfEu!7#G-7`_um1sU@l$FUeSI;2rEenzs4Ky&xr3T(O@h1we zT*~s+F=jz91_I-VqJlmjIMQ4*W?FplN~Ux=7LF5OO%(%Ntie+)F0MSj<#N4_db47) zAJcwLJNg<7d0F22SG)nKNnd64mtw>jhuho#eBeYan$}|ks`0OUB-Z)B{L=iORWaQ_ zM4}SIPxaRZdlJ1MD3|tlVyeAl1v;5ktvT~AtmJVfiHjr4d_uGt*`F16Tx25+2nFW4 zl!0iUDw(s{sjW=qC_toU^MCb7|Hols1;uYpu;(>UQjAdc!yTyx)-uEoCn!(Ne#8Bs ze^@kf#;`d3JPYp7kMdv*Bx(Zt8=dN<4Ps7wrumu}~6M>!7TTXP)YnEWdA+Np`ags&NRdplU zLQxL?`GjTXpdC#*$+vo`QoIqbL#URUJ;tCi+Sb@8ITl1Y*`Em_;mO4B!y%@F& zGV6Q$fnt`U^}x`1*ekc)a~)19@!-bq%JHb8x|p!%B6)Fc8TQ&Z49|$wpF3`divb>i#X|7E#j4DW9X6ly6cE#2Ls6P5;Dh&FINO$3%EZX_v%5nAjeu2Q9W7dr&$Aj#>lxgxo2d1`2V|k06rZ z)WSyayWlBO68le5j90F@j%&L94(CKrgVGWHWB+kG;g>|M4(P7i{`wX7iswcNtwmwc z;8wNU^0i0D-+5p|Jxw%m&5_HZhF0f=)|$`7fqjs>gXe6SQig!lGU4@O(93DccuPP0rh5phEJufF5v+5nk`uD$QosDs}FtL6cv8?IKzW9#y#HAya2$cJ{_3%8~;DD;>+n2GC`VSm@_mzfz>x=wjlMn4o)!(J+yvDr#E=Nlq zx$G@k$kdpW_~tvl14TvdfxJ9%2NrDB*Y9FFW5c+@)dF`KkPJ5nUQ7s%yGdxch7^oGmVX$|XsxVHT87oRf;wmRFGuaz-<W_$w0OVClK#+&7(AyD|zZG-xW|a9kCnfM1{4UhgS2{-6-%Uc*dOhjeN?gX59{uc)~CV8jVbIWV4zQ$XFoA`q| zNW|yP?hSC{>itcbS2r&Y4r3h~Vk@=Y&CH}_JKD!Df2&r`8u_!LtXX zS~e*x9daN3us~{*^XeHZIkNwyb>G{cNAtJho1O=smCI*VeE+fFwIYVSc%d$TTgl4X zI^(oh)l!Ms5WFHZKZhxc2tOxajF=^+FyH&U zK+a(Ll|q7|k71%ZQI+Cge0eI@VVYINe$xh5zxq#bngIg-*z}JdSuckc1{cBH22P_5 zNA3rGHQT57@f16P$KE%qXt&UTjLEVV4FnDL3Q?Uv?K_G-rzr9*U_PE#A;xiv|pM5>`0|GzwaKV>xb*EB%zlU z#qI4uUwd~cJgqM=yEW3JbFwU%Y0qKBwYNDu$s+SdJU0R>>(@1~O@MO`(GwLZ8lKeW zmbMRlpr-2%k#%gXW}6#&bMqBDJ^a;z(r+T#6@`K4_uL{57XatDbO7}bSJ%}t@X_Bb z|5Cak?)8h&VX70Bl(ZnOv);5Q{>)T+Z1%x^)ATrxAzxUzXpO+U#0d`TV8x76FS7|RYRE! zElVb|WV6`L5ue;olAy3p;?>gXbsUGhzY)3+z;5iK5bTH>Z+ca1?p(j0*W@D3gEh_zFC~I8OE+$A@02 zU!q4CaQ7WCLMRP?_!;ViFW+9G*&=PiZ2N4%BU1~g#u8Qw+r#g2PODAK0oF-Fw_%&j ztEZbM9M{51NOqe#hVX5MLvP|{oXTwo>&D5#JqVCocBB4!ysa_GhU0vC6M{jQ|Ln|} zIQzghzH{9KZMU1=9ewp;KD=5W6)_(MP#Q!tlsO?N;qkZuXWDPl`kT7K;IB>qo1=2) z>-T$y=eM)Dnhp0=7}u(a|6nc*WniEQ_}H|KXH4JJNH}uuDSSMc5YywOJQB@3h-Mq~ z+J}tAy0$Ysn}k|oB`d%6G;SA`nc<#o(<*sE0p*(a8(LFQNhI;LD5ANl4Y~;cQUW9a zUQ7u0)05fVLRV)oMzE&FTg6LjR!tPlaI7qAEvN=v=xif?)>#v9Yz84%ch4P4m?@3{ zUs>tGGeHfyPC?3#0c6h^F}{a5rx=JgY^MkXXQ#(xU+ue>fRS)=)(Nr;=qd|Hjge3X z-r)uBqG{2|PzsV*jP#6*S;nDxG&fjww9N$)4&KxIoD(R9fr;?Q*a)$}DdZR<-Dwa# z9Kjp0@j#ZAO2p4@xkj9Xp4xq@vXPS;mh9|X0Bj~Jv3KRF!5bQW4}FwhoFk&Z==MZU zy$tt(+rS0mX3>MYT6>xUZu>x&xA#!ROs$Zxr~GeBWW~zGgt)l$h|4u^vauJC@c@xw zT+f$_cS80X81dJ_XFSBLk8q=if+qYC*~lvaA{|GYDp)IxpFmVr9^CdzjAdQU;Ul+m zKU-!%YTHaB5I9oF$pU=CW*JE>(KBz)1;@wRp>N^#!?%UrqiwN1<@BDCO{&nnWsrP2 za!A!IGJ!f~^s~{U9h2MefrG{mE(#l?;TO6YA~%A)ULMkCzkQq+xaIfG$U^a^wx>Kz*)QtkaKdoo&ezJtIu%529t=#RM>4R@Mp}vf(*g8 zrDyX9RqG=fyvkNn_Y}_ua z)V`*Ddw#obx0u}ZoE^vU6g=o#?&!KNz=XbB6MJbFvGs-XU2V3b#Kf#mmZvM=zWbXA zg}J0APV$GNbb06H$%GO{tva4fxNG3tLMb$l>S&y<@(FF_G~6A>397!H?BhHZf3|%c zmgZdG4ZFQ-UROgP$<5DA7DRD&x`*SQ-ceDVTgJRvYX{8djM)kwb4uWy7H1544s9he z^yB;(7!b!OL=(RVgShUcj}$Qf(CHfU{N;z73n5GxlZ;C@GS7AX~{WpqMs*}h%MK8+EkgZPbb)dojW9ps5`idL>|FyQv zEgNeYt9M+st!3NxJKJ2gZQEFG*>2hHce?M-{k?ww^-s7ubedjTe)incu+Z$SDoF|UPun74)y(cl<`GLcVlFH0 z=E>kEnOhVwYuaEgPXeK8pr;q$2?d=}yrx?A;Ihs?XTsLjlhotkp)?sC7;40Gu$#|E zdOCz_jD~N85D-CJ33eIs1bu3(6Ed*AK6*IT!v;QMiHbj0J7cM&d>Y|NI#;EL2GR7Z zSp`E)5FW?@2x?AFrd8b{LF0Doa5?6S2TdbwPYZiw<0ApZ0gK|p0H8b|3~e6a5cRvtX%7=8}L9Qu`@))D=zgSV)VJC?tEPz;r{Vi4~o&^NYqvc z9Bt-}H`Q{Z-vzBDs;B-vvJHj{*4n3BFY-$02H2|b3EK=z?v?z-`gKy&hOQf%Y@*aM zZ(7Vyfbi)T#CT$D!eJZ?bB7lInjBcrp} zu`~oR_)Dxh^%6+m&?1rbmKwy{vmuTtu!A}Tojt?pVc#Es>q3qWM}E;KnP%=7+7Ns{ zPn$p_xwLf{Z5jNYuBdaLSX^#6%Kebhpy5WN+ z4>;?B!YyruNE!V(Ry1^p0sm82F+_NW&7fyA9_~pBlHEXAT7`j%gJd?oy&U`zP}0iU zQ8PdEU1Y2B82*fiPRd19GbyqbR}BI3;Zz`(C|NA_j#08Ds%hK-S*&E!rsX4=99o5d z)p@{@MKcY0zUFr@^Z8SkwKv-@5Ky4LB^^Xy=9n`aa9{w>FIRvz)Li`8uB5+U?`JYo zHGZH10IgDN`Vc^pE-X?%2OgjHowKZ?Y>dWV!40vS$`a&t?Voa z;^FJ!%9S^K<{hKtnA|>~s^82dYg z)f+Y@rJs9bIJJ7S25M0vIKNV7A@M$Gta_)32L}(vGsu9ke$zohn8vbLY0_PjK8(8M zYJ%N;bWdu)Pd>vlnL_`^*A#fUf|#-RoWIcrS|XH2R-+gsI1wI0!hRGu1;4430^Y5} z1d|0SkRx|}Qs@MQnHE$#2jZwDRB8?>5>DN6P#}sL|IgN>J#jKHU05?*+(ekF_%9QR zWnqviu^#|M#@mE?j?hI`3Ldcl>#xb4$rc=>UY&^bhX@>U z>X-t^|N8e}pqSk3O+CK-@o^{ob7YnKc#ejdH%80NzE$U2X6KexE|_wu{i5LQ^8I}Z zFVx}3itowV0|>qwSNoo-UO(T1s&Royj^d)z(IFHrx$O<-X*D ztHs@N#YG#GQULG$8tx_`FgQH~#Cy@T=yf@3AS2Z1KB3>(v8QBfNpeH}#ny3?Xpj-F zhrxFTtEkvQbX*=uikO7a4%HurIdLM+xeT2@W9EyviMK}CE`dswQjy8?4XK{m-j((% z*B2gg6m69ockRSfp0FN9uJ+v41$++h{c&>9LA)-G*jV2X9G`aFUaEE{_#pwg4n{0* zzHKw&VZ!#uO5#b=bs*YhgMa@0!K(|Lki~_?2kZynK(smT>1EG!^j9>@ba%#{&&Jx78;3&&*&WUIv3R zB$1+$Ri{j@dhJlqF=1FKEji**PD}(lTDlqFSZSpTKgdf=;$DyCSCH z*f!?41DQy8_|?o`RORgvqaE^x>y}7za3ob$zi1i=7}SB71eXE5P#SR_UlM;cdY9dQ zseGJ?IMKzauREiC)RN#~-ImBf%2tC7v2ENSG@zW=f)u7rmJ%v&`B@^?Q(ES$b@k(y zMV6cI7>*z@!Xe>ZeBGR%vs2#`=F2(6CJ)uC#A!j?++O|pwgnZwIbYR{j4pw`V^pa3 zNEyy9%Ad zI!7~$uWnJ_-CcSJn_hQmMB9qB^Na*l-&K{m{f>rJm+Zd^sU?)acgPoz5fa(S`J+4d z)66BUnC>z_IvhTph|Pj_EIOhe_?eR2xv7cx3=$Bx5vx9WxL=QQ$(n>|5cbO$Ho8E zwie80Dr7*6_Rr=r;U8+&l-6fZ_<5x2`_F8SV)KtjN000W;*y_T6N@+%X`yDi$zCTT zUh7}SyIhd7SQw^2OsP;<(2`IHZ_C1z1(<~1n0p-d56T~@8_AE0Ba!KB%|LeUvGkzj zqr(*OLa=!Nq?zP%Zdj?!1!!ZXsFET=w#>D*2V|3Q+cDF10yIMec$R8Sdmpz8jrV?1 zuj1+j+$o)Bn}9Y_doWb8323DRkQP-?BUao}JqvXa4ne%FbM_z$kz3rwL7dsN`l*5!6XjdFyGcr>8XI^_6p;F>uI)LPoPq!6a=%6-Fw+4$M&=?~Oh zfMaUW9IQx6y%9LwNb&C&KM1J2q}Ka5z*OJ^!7%RZ7;ZB@0skX}92yZ)G|+~ zX`Q!lU#^ajB%<%t+NFEk`u&x>;hOE8`*`a{PkR)P_)bdn*>l33)mocS`%Ay}<69ku zTH{;i+Fuiv`G|;@9Xd!puj+5Wz(S&&%=~}>JGE@{V$IbBd>oGtFI;V zZAh<{3r%852|;ViR?41&uQPn(#%FAUd~*<-p;=nJSKULL;5-1~1)g{JvUGDZ+Zsak zlxYX|QbSU`^=r300l=;G%eRiwsFlzzmz*BH)#pHU%&Q1l&P*PM$qS(&!Z1tyZWGGu z-CDnO?7^V?Ns%REyaBDJ*JSXU{dW~HzD@rmM!L37ypnRJM`Vo>a?rYz$qX|X^o+%H zHmHvYS1xntpVoT(&41&;OpnEaE&rUTD2sw2m)f22`lbIC!-QSwS>eP*pMFghioEM5R8=d2Vt~7q_zSTvm->9L$eWO z@%mkuVeYYMUa&4C;%SagKFPMpgtS1w@0fQMxY)kcgWUJbnq;7?$`H`w?*WU$2^JDy zZL*uOsY4%O(l>H?y_9gqkaO5iuhpdS^x9cCJj9;D$gby}s!GSrKCBzQ4)lR?o`SKo zWCz+=jHK~tISyo|{vqitZR!d6#7aj?Nx4;0L4IWk?9z&I)TvNChB zJdT4+@YkG?swG69e4NKR$O766{N-WC12l)xQ%D)UQI}a9o!NsT6;MFT!vY-}LL;cx z;Kh{nFQo?!iP&R!pFJMVge_V*}TLwBt@Q3t@q>14R=jAozU) z&0s9{6#EP33X9;H;=rTi%cT3OmslKyfXPQ&WyKRDR{=`lU+b0N%E7;2>jMXlZS@IX z+oS7Qw6^s0j7{gB}_oX}!`Zayte!kl;Pj4@*_ZU#cDjER10@CBD z-5PAZUm?MVwrEkwhwv^_b9)^x4Dvkc-u$h8Q|keMHUEBdvLXb5OBAeOscfebl>d#4o%anzOjNb_U<~3{#xb%G`zh(PNUGdE6gsj3ubEQI0 zB{jT#!lut;>LWjTO%xhYfE;F{tgru17&AE+zE{>9TIAv4A6}SM@RC6B$;DBwMmw#1 zXy5ecUu;G}L{M-9l-Se|W^UqAaC#tt-DFnthk6;gFBl7)%M#$?2FYv}Qf9>>@k3%9 z%%kZc!QyLEnq`c&wT0?;mwMg=w3II0Gw5KYYBH%6gog?|RD*}jh$Ny?*kyXvh?i{k zTN*_v^*FU$?NBnXKipMBlcDc*cy2Y}<&%6x4F95UJ-L%Ap8@qFsm9+V1&UJKPxgvE z(=2R9;upUw4!D^<7RfmhDJ-j(4QA;1=#2)+*7T&j_Uo`y6Z_Dvhu37In=j5a*3O@l zoSx%ZU0K`cb6lO8p4rV2*{-FS1Yr>%NO^MUq?+~(c{)xm;DK#hmpAxf&~8{xXqKxP zd}h9OE-XvRKm-MGwb1(?iFsekhB!O~&4++|D)(m*NR$XSmivTrglAL#2BJ(W` ze9CegsCL?Z7{ED#9xJ>OdGynW5?-h6*CL-Ac|I9c%7^Re-^LF%%l%xxC& zYWt~Q3@z!+<01UAEBqxUlk%UAZzj=c=AnH(kC&N!ZEX`OOw%shX;k{;m8uT>F(kA8 zuIm{e`fA&5nOklF2X@C{RqYY$J-1PZxLcAD;34puu!3)KCS=+!Aix&7toO4UU*`|m zA2IlCpy61Iyg0N-PQfmw|D>zq4E zwy_bXpr4BRtB{H?J76N=TXtmm_D!k)^~s5-CH_8!g0Be4-MQGNLq4fla=8KGHwApn za;CZ>7aEi%tkb3p_LR7Y=0nncDJHxsvjB8I6>7I7P9zbEEH}6JGrA^!;0U>n>7J_u zG~&ga{j`p7sR^(HfR5UUb>0o*9_JuTL1&oDw*^7R`~$%P1g-<}z7NR#e55+I>dnzb zGr|H1Ba=n!CMb(RFL}C1yQY%}h(;`gXF>wck!mJb{Ou-rlj>9bh}G2)jCeR>gGxn- zNQi%j9wDe^0`YeKK7OCumzc-G$IZ$`DKRA9?+Lu|GiX8$L6LZaVQ8`PMx3j)43X{n zix^Fumz^Ai3>L-7&iOGZHKQA#4{7l&6h>_w|p#|W~R_gpLilnY=m)?i+v$%(U>b1enNlwXD=PlLICe{J- zcA8%8b-rF_c8lV)D4x7^HFhK~5}NsOWE){c`kj(Vf4B;BI{6sb^>v{H=02!z z_2B+qf9iM7Y6utfm*YlQ=Zo;TrGG_`;UrOld+o&2M$>5EzskIl}2H7LHG1h{4to+k`c)RgjV)T6;Hxc|_$HGYbL)VJ0FiX{8=+j9?u+qD7yNrJrEjI-FIwc8`)&Hhn}1Sf0cZPuDV-ADDTdt*=mv4eVl3lNSIP8|;7 zw4d1^v zmHI%%w984DRC&+=UqYU0791DIk1B-83WSWIaeOM07_-$lKA9br>DrxQtyV{-vkJ2! z7ZAWg{moj0!l@6p5a3nvlRrVX2pg(k2+V?R;4qyvmn{)i;h%~z%Rvh4u^A-{?9WmU zo@IEtit&Dq{rYdorqc z>OQ(gdHfOR?Ogz?1mEDY_OM}@`9VAahT4Cak;KD=2u}j*Tl+|!@VMDVl5;H(W5iKZ z|Ik9j>sJR>poV(8LZAodtmxZp4%pc+vY@H(sfHPXRQ_Bg5m@zqLC1}eOXtbU z*AU(X9kZT><7UV08|{n!xGv2^by*TX7T^)E7RVHs0QYWovBGF|9TrN{7Gb0~%_s6K z(>IwIzdrj{e(+G5bNx%x!9JS7>^oyb!4(+!ylG5CyE+Vh=>Sjt@^mX^n!JBG!&!D$LiN+7^b2n z`e&2*#KE+mEkYwj+uJQb7OHz|6#V+1L(0D3C>k|Pz~J-Ha@Y#1>5c9mpRy1GtZ=~wmDEBR>+ zZ2`jfEdb8#8JwQ|>cA_8iOzuHzeyCnf6b>GgTcpRP-D-LRUXN;^p%Y!@cJXTf;ujw zhZmdwo+EdQ5l1F_e_M$o3v6VcYuUax_5tUXHFErlbo;rkajb+QSZ=>|Cm_UKs;7c zGWKEMXm;d475D#sgW$0hlOfW#b4!Bc%*dpTk5oo-iL2sQYN7kS-)LV<3VICe?~++l zGN^`U-gfg2UW_wH$N%h(0@SeFwNpUjsrLU5j%)iqL;;{I0({T7xHzT&a%@*c;r>42 z@O_D`@xh%s~kz~1YZ+2%&u43Qk=&!<&3QJe`6wGI@FS>3mZunw z^MbDRh)NbFl%>O)Nzgbl&H|mtY&4cOFtxhOFXTw_xi93|sCWV;oF>1T1aMrl28Jz>z`0QEGN}F!Zzm++- z*j-m;)+cNG&pfWyty;JL5H|09h0XwbFvf9s6BpPv6e8Ue>3ZGplx-?x-V@$~@U7(F z6}x`$k9;ij`zTP)|2+mj!#Ln+{o?P>%}lS~NFLkf+5y`yUDlpELz}(#V_(jj-#WlO zDOU+u0+0?r{gJrbW!DMkE!xi3=zB5ZNBVs-zfXHz1oSpMINCVzeSJXx&ex*}25vb` zz9eZbz|kf!>MBIG<{8!j2#=FX?rD$=w@K-D)O}=KApD}oJD|!kA!urS&;tFo4e{J} z$Mt%!@EBnRPE&$UR@HckRpjs1Cze0j_$ItfYV3wK{>IK2RtQ>Ylifn>6c@#I7bw0n|2p+C%a_?3JhCzfa3DgE&wc)*n4>#b6Kb|Jas~%=VC9 zzR4Yb5SB+RE_Oky%uAHx<^1t!o}e;HT@aUyBoQMVGFB>0UqFN=QKHV)Rc>cmDC!9L zR?b#1CO$WW335386c`Bt#5X4H(DYC}ppW(@s}K&K^>J;n zM{v_6kR8NGS1}ktfr?;tzuRaH0f)~Sjk%StA9?PVTZfi>Z9ySX6|}D*I7N8ZUF&aW zoz-)YxspQzWp?ZAY@zDlQztCC$})CbI^C$S?YLc`i6~RRmpN|=SGDwT>v8ewQNcRJ zYj@y;#qhI#(>V*_X;S?C0E0iUMfLy_0Yk;A!Nc{dU-H?os2jXfVx>3MH@6`b%0)S` zRbAO39@<2WJzPK9pM$B$g)g$3Uq_aay}|q!-&lf&b4vCnTBUE_$KXLZUGKG+`dQi1 z4SR420!JBw!iBQrQ5Hc{$9R>X+Uyr6*t7BP{)w;0acCq$PXxF%LOSR*sM$PUmEZaRm( z`PsV16yxO}3*tdr$3DHiV|4mXH-L5sNYKdO%c0|yk9j|-rggs6mT5P#n%w^N)1o2_ zU9M5YS_CZj#D*1Oi&0dn`NT9Sl&Uf}m3)ir8j#C0IA{P);Nd9|IYeGMP;R=N%w(wH zGCvDnZbY;fHFnT252CZ5zH<*a`X?810|u1iRl$o4m;F_#Rdjuf6Iyy2qVckWW?VQT zgJ;07GC2pkF%qpq&(~Uy3Q}bXY+M88f+V=8Fcj_eZ~ubKI7Euh`z$~+-~U112X>!c z{>JkJ4;%L;v*24s-}n_b5IIbLF%!e7#jhF1+0ypJ;V8I$=6U7rhNrpA7VJb76ML&( zVCK>C?ZSN{!im_{Ph)H`Lr-VCAra#UDEky|ja5yqnutS$^^T5@-WsLw@3&EJ*q+9f zAL7yZl^EsaMuFyPQm#Fenb{JTH-hjr>SGqTPbcnc7+XoD#ushl_z1^6j!Y^OwY%8w z1Wk|Qzc=CrEL4>rqs@N?Q&UgS*@fJYw_c11%HZrD%sN%jh1J^IN1b}s(6e)-!~W28 z#wX5sdP^2xOfh&cEjmPT47^+&q9C3X&rrj{FfBzxJj&{hxAf!?e3J3YX42v|upUJR zPXi@ooA*x8d2SRuA`xQU2mr@5E)^PNWXlesW1UXd&1d{HUg)xj)W>g#;JxH$**iBuE26rcfcUXjFb5C`TR+`q#!EFqOKZx&Jz z$At24e^u^JmSndF5Ar>b=`i{DF%E|idrj&X#YppNb`!y{Si;lrdRF(k}< zVP7c*EWTyZ$k5OM4yo6}HOtu^K$W!7j1+F zp&7zEw)ZM@6^yFr`D4^Y+S(Oes6!TzAz5>HJm~oH|)@)h(RKwpzXu2YD2!4&eYZG~+rr zuBu>rhY}X?fJjEJ0Fiv+CbDle#*X@;W4lIZK)Mb1&+oJ}; z`6E4K{1I_A^#jbZ3N-m|O(||UC(-UKQCLe`oC@}=s71^||LTP(TM9Eh$D4rbBEoF3 z($ozM2_+G=<*5H^%VTnEdKOq?TkZwMmm++e^HKhcB&`%p7g;lw6sG>z1|K2+5oNF{ z?ag7WWp+NCdPe(mjbsFL$YhSeW=2Ni4FrwA`0woTe>*|w@139$PK82TD2hyPKvX$x z$;6Q1t-!_Y6*_v)-I`r+fp}AsGg^Q}AD*@+k*oqDx!b?3YZnofp6EHU%NHRb@N^xj z^e}TyOX=my4Z7f8CKB4v$SOO%juW5Br7_V?}JcEFZFWd>NbdDR|rj zbKe(&?=OH1}inTVU#EG z#r|)g1R-JhT|j%~f61D$YI(p&GyPRMN8qvXGxM=;@OAU;&Uuo~jDNx2$_Znngv)2F zys;hjC@8{hhUiUH5A*b$y=X+F?EDux>9XD-ZToRspYzwKynmjU+`Nf*i6=lZC?45@ z%YT!9^kFkq9Rve>Knl|$M|yp;t&t$iPAi3lG7bB1eTvMxUbqweJ-Sfp7HazC1VUdM zJk{SzM}d+Pumd|%@4S2p^cy%K&s@GoX;LJmJl&FLef2(qnwgE=r4q?rr$7!n2UT6L zsj9o*9h)Vd=g@=QFb7o(*#V|oTV0(ca5AxNBn1qei1vc!7%lG( zEOCgs;&VGte0?0@@tE3-nLBhK(ubn&cw2=giVOS#Z|2u1_vy?sW0@1GSg;Mv9H^Y=XerA({f31;ZV8qilN{o6uuW| zr5p;;8uXm0W`z9Yuu_^pH=b8z@u_ZZS8yg-ogOm#k8tZ)+1H%a-1y1r0hCZBWA#MY zJd6@bEh@VPr4ZqRyiF5oyMW+ikGoIIfixhJSncvc5p^X~tfUp&iI(s*5C;-YOf73u zG3(aXE|k!%$eI}86J@gzNIeP}h>?&;yGNfOoaVU*1 zLx_o_FQAAtxnhIKHlVn`Wg27B8x9eq7MmR-tPb={^OBz7OjyC*HpS?bY6(s#n5ay_ufLcKQ{ocUXBqG0%L98{%#;h$bbK+UK|k*p7x~4! zLeTOCmAwDWc(Ey%7n#h)KyJ4e*2Swh?4_oTt)WP?L}Abgi8andpxc4XEW>_^C!5Gd zWJd(X=w_O-y|h}k^HF2_-W5!}&ro&jJe+W4=Jp~L^OD*nQJHdEy~+9)HjwTxj1TCs z;QWnF2G+XNOcwaFK1l9u_w7npz#0CaI z_sOAvp*R^H_lHrZ7BFylb>dmkZ0e%;C6KQr{$YQ$*$`{IPi5Km~!fFqb!ELJAn|(5(3cyFxU50j;ee&8C0FMsdFrV9V*b-DST*jW#j<{NuiS z&pLQ98QWvr5~#wYbiG6o{&djHHnDA#~nQ|_&;z|k+YltoX8h#nl7&WD8 zEC}oSc7-XEo+q{!T1b^|TdepE$*vpBS%K^tYoXpCVc3b5t~XS4F;Eu zq6QXP0LIX&>wa1}c)i~;-J97Q1XF`ag{mhOY$TAC3w1;TV?y^$qZ9fl{s&kfAX@%w zzGU_q=ywQ|ek>HzBnq+ZX>g7HtQy5~nX)Tumsuhr`3~)u06!F?Pv|&2{AG zzam+O&>c5YT&U2$lff7=gYRh+zM<|6S-6okKwa@UdQZ(-xV;a^3^ysmR&a=fZLVL)`8p>u(Jdq zuRpKpe)CIxfNA;a|IvwtBp@@_XkWSCcGpQS!sG6HO0+u@`5)TztdX)$nt($2dpeEM z)Nmzw#QnnIm-8S0g72pC0$`~+XRd)1P28pn4lJjf?t+Oa*D{h|?1X-__rcvI3l`<$ zfewI=)|H-nrOHwE>>F+N10A2JE|JfiR)+dL^frndv#d8<8jisjM*4-`vY6KFi?vvB zQ(oY)pPimcMq-2pC+gtM&o~Y9v{7gPd@wEOw%3=ISWns3Uvw~t`U(y05HI%b2v_E2G^q*OWAyMMwK%H0f0;&X6b8%LV4O0nG%zM z0-2IR1p?3Tluc;rv2gZej~it3N*|FsM>_vA`ynXkf?_E3!JjWWExX&~?x?)RiK>Lx z)S~Izs*BAl*hrpE&JHD~$;rtrM#5zdHNZ6sbNj;2DZB1Y4!PoAz97te)66U(@j)PF z(lq_=teK;TB|S8Jgvwlsf616afemhf=S{w^0h7*4LZqz0o5R0JbxM$vVgnI|mB?s7 zc8~@AlioP^!~l@PjnxV0uJ>tHBb{nv&Q9gYG+d3i9WHMF?LW)#B2si~C7fM0k zkS!kx^$y$QoA&Kz7w0|#9f+a(7d2@dj(5KH^8V5ke-QHD!>nsM*=$j@1wNB3VQAdq zOgtE=#vJ7!WY)eO@>w*T|JB*+aspT|OMm?h$u4IhESkv{Zs9*vFwXr!Dj*Pn=L$A4 z=ks^zqfm#?+!y-4os|7*Ru!rr-w9pdcL#Va`{PsUlF(m;zG;!Bl26QKM>Itn)3~D0 zHzx`dN6wnM(2CLN>0z=CmZval?g;MVp1KJ>2=m{ZB$m7#Wpn5@x1h!dg#*Tg z<=e;ycmPyS3*_AGt6OR(VFD}T>C!2y%GJbup5>@x##Lvtj zwkWkKlYPaYMMktJHKIiS#WA9peeO0IAW9#|Wm0uKpSB>8J>_bUtE)StiSDG0F)`!1fGz+SKK3i*>IR)-d-93=DTI9D4li6N? z6$)UoT!6{u^^5}Vd={GYM!{pPOUU*izDKpnGj;eD@k@6ynv`%vHYj+MMjIkv_rF(W z>2uT^nwArV)YuUFuvYTas}yd5yi|^yUWPQk7^l`CNRvZQpIW^fm0*5A-}E=Z7h+b; z(ZhdQ@~wppsDMhR0F4Bo-+KfmI8i3Mq(6@r6?=yHBmM8ig@(aA0*cJKxrPJ8$`=@YR6zc?jFyN)f+ ztl_j&e7$psdf zh9}qcX>GBJ5F-n0j}cn!l<e5{tpy@B_1dbB0MZE3qq)4S2)=YUW2@88MX#EOXF#vw#E;N>LA(1qM6pr>k1M zQn5?mOnFRy_juF*+R z2nT7<46_%fc4?8G9MSkr8Ahr0_EcFlFnc+v&G(_nFOYXJK`yJ|9Z2j8Qu(Wj#1^g> zyenYg5RCwjIN*ZtrtnB^kgnFmkxfx1MFBrqe2Q_M&Y9vdI2y z$XD%$AbN~4xX8P5=k{$}?I$xYzNDm&S*=cK?rRtNU#)^dI?^CVjSM%vIk-kL$l+WD ztd=;v4mN80fA&q$Dc=K$`5Qw`!W*&TH7{WEPZa=^wjP(1S_5{>joT6VQw-r*#iT^= zNcu|cIAGigRmQ_RYi+R=XR!jOxv5G8Y3#Z&Nts=qnqBVp;#*&5)VGLfR?cqr6}C=3Ai;D&&nobxKzDajuc-|bUKk`WrK`^J z{pBn|9KXH{RPy7P2T>%z6B*bZR^r#iLYH%>U79FsdO@A^#_pir+T-Un-;1`vB5y#6 z-z-28P516j|9GW|^%Kz@hMERbjUWvoxrG{B*^cyz1Vq%DrrVEK&Z*UJKNFGbd;$ZF zAXiwprIC-0E(U0?uQ!EnW%q|iP$u4;k8wQTUxWkBg4IeJwAD-~Pe19VXH^bS^};<< z^fS@!&Nx&{j%t~UOMaDW{wYObr9t>lvUnv)=Y!&HZG&{^cyI@Q?rs_f#^jPC;B zToxsR*S@ipPK3Nsz`gT{=!%K;=T$)G3r)D2k{aag^WOZ~1hSjcX$zW_OYgc$+vWGR z+)B)D8a}VE7D}WPln0$KS=c(HHytqiF_iucbwx9VR^xK{)9K44FwUv3jNauw#M4je_V z#+(Nb?Q3{@kM=FiT1_$$EnQg1*)U9qRC~REYHx_qG*}x5++c5gj!V7Te%HzuLZ=n| z797dUX;}L%Mu5wG>b&woeH1PjpWGwzC~gTjQi9nefSwqIl`G&|HnKBh#Y!{@prXdITh2Of{$IZF5gK?ia54sZ ztw&??wPsbud(Iy^Gpb(RF#{@;yj-poJ7h6D%=hX(jvQ>;AwJB@(p0hB>l8TKT~FS1vUc3iUi`HjlZ{-EU>zt( zay-vOA$D40g6XGp+U3AO5jG{g$${${lRRHVwECC`J1E`AfP@qhvChX45s#3H794Jo zgHQL8^AY7U&Vkb0T&{4RsKhRF&M~#oHp`^t?&V76wsF-X>ES=JZ7hD)3?2OaV8a>_ z)ysqbRq&7PKnHxX}SOU_7pguk-?3IxJ@-p-|YJ_P<^DDd(47_PjT$c_-ptK98`RnV0T3#%pqOgzVcJe1h``b0)-#5# zms#>x=u-rF1xt|z29C7UbW#kBHv9SGF@&lf(g0Kj1c4vz=i}NB%vjA-pJD7!wFIcM zsC4@fNIRWcA=7#LTprzlz}X`oy@PVgWf;HS^28a?_UqYS@vSI5}wIK0| zTWObVizA{*eUU(3!Zo=@a#HM(Dm*q6MMJ&WeDwosbXpBFR*(XE&C({B)-Di*9J3+h?9p<@+&dDEa&S-jR*1+xLzP(9 zv5%()I05uD9;dwZt6DCbllJHJRO9USp<4qP+KFR9dQUcvY+hoF^?WM4K}7`i&zJFj zo?bBY4aS&M&PhcyDPJ_&)Fr6o<~Omk#R(A1`*6+C)Ix~KIG>63~6pKd#KT9Khg z6y*Sjv|LymrtywtPIdJTAn#O%W=>tO7bD(*Gg=$m*EaL-%Mvd&^TA5|dbCQ_)s?f%0I{+|SxZn>q9Q0GecS z-}p!e1(F@Zqr4OoT4xg6X^4-6Mbo1yQaZVIFH!TzHrMq0mb7oJ@e@@(OpqJZVQ~4> zfnFg7+hi{asRb-oi3nONwQ@aK6CqTRiP`-Jf(t>o-2X5+wBLQb8eUbu%SMM+_OE23 z`t_SMuOlJ7m~kefTMape!r#E>og-=5f{j}*dqL)o z0OKY?Iog9Q0~Ph>$;@~1(8Wdh0c~Z zU!D1XB-D=k%kEHG;hA=wVM z4R#G@M?Ew~7Az>Wh80?25Mk!*@X=>F);NP zSzBI%U@7Crf%bol0noCMjm-^FiD>~N)vV99_|v$LQ7T%;4$YRFW$;lx#?sW`XU1h8 z+Vltk$M&;jT^RKLkEnMHuPfTxzuP2DW1EeQ#IzOGzztu^NuW8U}gmiy!9p@A59=9>?MelENw`(+p%3^gf@lRKSSE37~?V@*77 z2q22_&DMhvQl-0 z0;%~Zz^gvTYChS$SP+H=K0)ZGXn^_NiEIYD@Vlie9>F(0d8qHv-&2orYCioVT>I)u zDV*l@jH=BWbdPBb~Uiu=lZnF{%D|V^?fg%e!31|F~(LB5oHb1b>2KuDK3200Llppl>D zUa1)-tPa;RC^DpSB;nRZR!$Zq1j%5ltQpM=072kpLjm1X7&wuCDNXrIq#s@XDBs=S zOxv913hGj1Tr?_*rsfG*771R2tkZ}{hfo&K-%jY2gTb$b2%$y2VJ4lg{B*kX2xCG+*X=JFhg(HVJ^O>{k{@xLoE6 z{oS~KjoJ>OoPMBRmR1nrQ)%GZ$>`iw%d5KmHy)n0*Q-~G(hHI$FEH4?uZPe5-7@dB z2O*!&xm`i`U{j0z{Y$SH+|0_jeEJZCc+LoTq`^ax$_4YQSTGo&=U% zmnC*Rs3Z-`76dbtP(p9#dR{yBKCXaW=I_~DR>42hZHNJwc zd-MO1c6Og~ef0>VovN?w{=3d#N~N;&!Zf=x>Ad0)3Z1%@AA#aDR$?aeiJ9bH(k^IMe?|Ku`gbSa(+4`BF)DLy8}g?|B~f&fa|r`Cp{M ze`H{aP6`r^8LUG}=3UG^UhBs20-U~aq$PQPnrcN-yS+L%fyZVq1p9BJ+h<21{);MCe{}%Y}#=l5mr*2js#w?N!qy&7E6tb(d~B6`}_z%+=IanAWv!|$^t&Fd__!oQ+sfBapy zmB;zopLFAqa=Ma?48r#|lQ32U`{Q&1ih0kUfA0LN}ywb2ke;9*LdEbWN9fHZqQbyxKYX51i^$) zwIE(qG_iYO)U%67Xf;LnDNZXz#34nW$$e8zRah>UcjQ7{A z80>ghrffJTK)qlPo)?~lP@VD?PnUb&#_$>I5%S`Dl#=V3fO}qmYhs6T7-Yf9x8n*R zz&yz9HQ+aK3$BWv7_fN?4JRuQvIZLWOFE6}qTPlWpI)Na54GndX)zv9w1uAA&2bwL zx#^pa<>4Cg8?I$-WIu;}D*ECk&>-NXdaJ?awvUCMj|T7V^y|F9pQu=~89LSmB#O!oa_#$2b5&LC0$679 z+4<<;N|_d=xr_1K|#Ava4uIgqu^*%`+^gkH7)9|Y8ZfCq3`Rd$_AL;v4) zp%IWYejB`cbxj#=PsY+JwK-*MW)FM71F?O7J3P1R8B6Dpc<9B-Q z_U4>rKFH`Kx*#cgr}a{FtRg%zBSQkMXiV9iRZPG&0q0{~6dnSnNCN-Xah?!RT4WcN z1=-6?OqD@l@zDWb!BM-NUrmk^-yPk7NsC^V3E;9=rjbb##8d=^8hE3!SR9KPY8DAcN38C{ zd?DMa86j{c_Dl_P#=XY~E(-(gA*TSX?j&6tQvETMu{l6)8D-{LG~R|`*>N!B_j}&J zh_d^W>Vxz3c%*3+sX=h-zGuexFp-^R@du?wjB7E{%w36QAqzfwp_5|D^s@TkiB@cL zh(=^n3j>@6X_9vteB-|JI-)9rQK|p!gi!7mL}M&T6vFueG0Cqks>+umc9m$^tqpTaZseKwV?N?O#cQKg#M z7Os=yr^E3x=4<|On~mg#87m=!u^B$;2EG1p)=C4~$-$QH)#)Axks~1G_QP!AZwO?Q zwr4>aYtvk8RC4Z)d4v{Elg;6t{gYz47{CKUGYe7;6uQRS__|}W){Mu=r)hk{UZl_B zhJEMokjE%(7s>}W=ANt0NQg-z-}8(F?Gne&uEWv@b4Nw__A}A6ekH+|T6G;>@*N38 zL+nm_!doManbv~paj8@ zpGF?Ryz;Z;r$(qpL-8pr?iGL&F0cOGJf+HBMwy$<&JNYGzk_keaA7!Kp-qKP^~jgB zOjsUR@E0=SO5e52;ch|+y)J{Ss#_}c!>531)3G{LPXy%^!zsUQiG5v~O&50t7wR1Wh%u>@7rk=SX#oxix#VRLe)nbIQTFY;sW zKtZ4o*|#Q-x0S~x_ERCQ)EZ`aKj5FY zK{3V*&RSJ+?dT9LaW{ENMh_>9{(9V@M{`{G1Wmp$9i{9z4`K~!c8nM^eDJ60pt58x zg8E_LYe{|uTnqL*9w`k%Y)gjPS9p^D-Gq_=1C*M=>NZ20idjk!EDJZ(OKC$sWDRxm)~`FV17b|kBOTdB;1;|*=l|WdzbI$ z*Z!8LvxzViGO#BjR?;c(!gyDW2>NfSOOHdv4MVZxkU_0hFrtUOxk*cFb|tw$dNn;j zSPRx^E`eg_q31d@ljs>G-c_DKHhQYy$NyGkdqWifblWuL@$sjpD|Wk`!9OXU*=4sd zrKC_XJ7poesDI|t{b`0b-gNZX;vqVLZYFdg_iIae8i_j_up_Dj#Q=I^te`VfIBb&X zMS`qy-0Rb2fex=xQKsbGT*4gB+~AZyhyrdUQ!}L}qx;QVRIKGJVRyf5k!pzksJEaY*Vd@X3wjaLwP>vK*12 zPHA2guSSU_DTm}ZHj&40OV#XpOOCXeIT?`TattQ2Z)6pS^bXCR{iL(^fLY>@pTB=_ z(Y#iLadYkaRkrghML;i@cAGNxM%_m9RY!a;i>xM_{Vz_BR@M&v!aK#qo}cutC^2aGb_I|tvMW=-+(0?!efHr`Ae3rx(LHJcMyN? z_se|U;kJFj&z>S(ksNMImq4TwIFh# zZW#NU*M7nom1WqnhEAn}1)?IszC5mG)=xAs4Z~#c;8Y8Nvuqb^NoFft0Q`QIW?Vf* zlu0ym-jLD+QeX3c)Xj6V+xdi9ks%eCkD3N2&azq-a<(~F-4CgDUZ!T`s=5PR(k@1B zW?mQS(+3u7X(>K77fX8+5DzhAV(!N*9o;l2!6Mk#%QbCg-Jwdm8(TuDm8Y0z#k`9y z-Z?QqY*K^TFm*gvlO_=xz;x5DOTV8_^nsSu^6Tj z$_}25Aj(X~xAYZEu^<`fiRGUWZ&;9AZv`#PHy6z1=RQBLb2NZ2Nzbw@qpgF(Y!f62 z#piD}DPY_zd|M<^3U8_46W4<2@=q;D@GfvVoAET1?}&0r!z~ApG{KXd1W!2YESM!p zEgI*M6;GU_pGNQwy&alllIC#MR*P$4yF=C#s#TO}3*W`il!NJGG`02V8iFIjYY{eo zUp_vWoAZGBW@1o2gM2!oFo_kP4wNlW(Y{1t2l{@MYNv*`<)oMSgar8;5kNk~#74$h zqyRbCC@o!{DG`9vp0>;Cvd}zBStRwVnUR3CnGN*8pGU9gXe}5na|LerbkKFGu}A3Y zDpOMaF{55H9sT4Ni&mv&3`w+&zBlWVIUMYbA3nwdHQ((frzhp)gR@XzCwdqLCQeZA z8k9-S7TLcC$2SK)rcZ+Em@_S|a4bM{Jj{arb`>B$3z&HvCDrleR%rxFuKWuoS?C?CL2oqc5u z#Il1JxCPwR?*EVE=TDYSwP-OaX4%TNXM&s_K1dFkIKbBKkS^z$9zFOosaIN+Qmt2Q z6xjxdW>FtG$B?wgaFHC&{F`NZ2E&nCtzAe-rJl*=Ay@E4l7ualJTSQsna0+*%#wu` za*h|fZA9CH&wkc`4d*7zCQnd$7AaY00bp)oXN;zaO_rMqP9+#%xwsju6#01HI+cQA zwm6S&G}T-V%vHl79R)VodrQO7IUj;}_V#*YH3(eS_oI8pxE8|nQSuSk{(Be>6#1P< zE?jwT*78$O3+Vn&valLeP?`EThR zm!~xA;g=LKJYA-D2tsz34C zdmBh&U@|v(#nK%oZFd-9N-=;kvo<1cPIOfU`M~cKZTB)7+SNhPNI%OG2Lsih;a3tl zLA^dy)3-9#U6_ZgV5so@0hl=nGvZ;&mPN9{bel=lVns5QlL8$WoF`^v(X7^!vbw0f z7JRlz8TqM9K2gk{I*_bxr%#F_OQ6gYbdzOUx{0Yw+sSE6<@iQU4h{fIM|HNI>~Cl5 z{xVc?@g+Ob*&9Cgs@}1J&y6z})jWqy&R-x&hq|uo$v_zD#;Qm?>_-}o<8%BRxg$DvW-y zR4t(S6ud2Tju`${2Oy)ZMb-eWUk95zj04tGC13AIS$a(1?)4eIKCj;tn&L$4U|=Vxb)~OW5P@45nG%a!K8{F0a!M{s zOe{6hYrBBsW`7(xKpMKhV}qit2|xDZ#0sWL2_uVo-P>6ic%UsEmY}^|b}3H? z<#I;CtKl#(4&|gc)dj_bkSX09cL%@OXijNW31SCy=%4<1n)q&f_yI)EnrsFZbYFLq z{M!uy4A94AaOKl^^NrY}CfBoE2q~@emgi(%@h|SK4fGJ|(;AtW%e!?rajk2$yCACs zhTndtjcDY+@T6C!^#5`k~Ga1%PEN`Ja)}?e%1a$8wA|4N@ zk-F%(e)H(Oj%77gKZA24#XTFKFnWG( z5to%POp^(ZGr8EubF|_P_v`W~36xYn?9jS_LCXUe4+ax>`O}E{`!-HcjEb>Yo8V7^m;u$V~ z$jCTf=7GMhG}3{2_FqvhI{|DV4&md}=|UL#jv*1waY(%`u#zd3*3ILLy`wHWwazSX zA+(}J6toKX0s8qj)}epb`nwPJm_ z(r~o4_2C*vtZ;X|Or8aK1Uyk5Zql`Fe-&0AI%At6d|Uc_4hp$li@AE<|8+TTz3|BE zeY-qF_si*dZum56aoyV3;7g49vs3oT;U0{rqjUOm3nK)BDc|PhbzWvv%PkpU^)KNL zD?WPK@v^EaoVla8Hh@KL|C0fUG@p#usJqA@Sn4>!|3)F9p~;3)9FiLI%b~^^6r#^8Ucd+qgOFq5Md_2wgendcfD%c&^=Ng$96vWA zT!M+6f=-lpMrXtLbv(Amgmj9|QL1oK!e69G>Qfw>0ZH8y>jD3AmysBx`#06ZgY%VG z_VpdAS1hjA6J)~0_VWeLL#)l9azbeAcy1hO;Uu0Cj&20SHIiz9t>wDd&_4#B`3dI0yq54eOM*omI7Jc z*NbA6OA7HI&a3-2e|$4JBbYVOLtO;uKoF5rhLL7pU_Y!5EFM$&V;_1? zom7AsDi>hM77Q3_)*!=a zq=wfD4sLt31zkMC+1Q+b238Wc=oOk6;H2cD;uBkmEp%t%l6!MQ7)f6UJ_u^9WA~g6FjH5FLI- ztD!-8OL1X5?Yj40P>QJox`Dr^NEYMS8ur_cOr!<2xPEk|F%u6-s%(6 z!SYYg361-@gPvU!YQt(0guRPqk-8RcF&}lfH#@mLQrj!R{9{pn7C<&+RHEN^)3NjL z2Mz%NWcoiUKt)A$a=O!hePQR+haNlybq_a6-{yui)5QX;n8#3X>|#D^Rt}WjE!y0= zOa&yDMw5Rt?5m`c?>WmQl?!hK`!tcd4xKsnEU1CC_MY;}LeZfrRd1OESR9rsq;vc- z5<2`Axock0j!>HD3ApBx2tTrj1)1+gl`54eDdhvmtGC8Q`a!84!Q;nxzkB5Aas5$a znU$*P(p!Aigcf1S`XBl$k0rj|IXI1+yiB@F-gY9apg2D1C}Z#1-lnBKHHC6T`4xvZ z9>Nrz>~68l032NscI5|xsyNwL0zDaMCr;C9H0JO(D2f&N0F772vPaq6Gjv#X6pt5t zEq5+Q2yk{mDLKzeb)S1KgfBBmN;hR`>G2x#nyFTBaL^4+VhtO%>^RU)f6myw^qR9v z0+T)z@N8Oz)y5q~Zjuyh^LDfO^tPu=fm+1O21fr^u&pKYu#HO4QuP~tIZ z4cdLu;Hnw6kiLk;kS(C-uO|XUZz36CDVJZ21mB_;Atx|mHd1j_Iy_GdUl0P8Q8enf zr|^^^jx2)>XU?PR3`N9Yz=twZ3ux$1xh|4dT?}p25H}vv#aChm(956l65l#dKum$W z%UF_l-RtRG?slU1&*V@UU0y)$p;9ywDmJHa>CnXQ_r}<)U`~inx0|_|ZqQ>0z{?T_ ze$95<4a<2c%OM{8QVxlR-@)-FEKI_Tx^dg~9D z?SjEoxVWz%F+51O{e%3U0uiZ?H;>JDrFBJfaDV*KivZAU4RS~fYhSI`A5?;ZJ3c@b z3E6BecaVCF-g5s9l=!jTmeciLDLC9?8o|>dyWLY-24qO^f?_H8m!6~lYP)Ou*S4N* zX(Q6wvSpaOcR`yLGD*#`J#*B8Zbt&a;$;yzIGxRw2w8EDvdjJ{@KJe9y&sC)2at$R z)63CJ%rP7}d}Yt>Umi^z6%m6ryN}JYJG@U5t;$F4O2dVSuS4%9tofKHVzUxY=BLNc zjypFvo<9L9NlfCTM|O~#rVeiQOy-Ke&cc>Ea&YO)|FX%1ndb34PN&g3RCDHEe!m_W zVZ6~Ws>}~k`fz!b9*xnm~y~B<%f#fr}rm> zMJFihPJ#ce9i-py)eZ$a0zrj2&!M?9voqiNwtO(gjBG?xkN>l@JO1$&D?Hl2Pf6u3 zBqX(t9dyr-`p>HK$IG~@mHcU9s`JmLl9dZCo(#Fl;oID7^?5pMrRI#u{KB$S)5<_{ zwZ5)Z%bZap{R)8ZHyM2dpEA>0weC@yj*8=tl8@NT8JEz{R!^~xoHVacjy&p+0@y%H zU6R`m5cJBGx{Xu8nR|+FypEt!yt_7B1b>9|$@98rE;btsl#ekbeNRdG=O0kD{2pI| zfmk)Osu`3{F7N~7JrJgZ;%o$|y<+S*VVeUGCeESZ0fOZ4t3gY-ka=?2nj^%07!qag zpDVAZ2HMdTGFX#Is-9QOIo!umZL>`#qv^CO^#@-OM{GxV6lU0l46`jl-qXL6gFLw4 zi1``jxX0gjhAxkPYzxla%cCLzkh*)Z>@#{VlHHd-qUz{)M$GG3rI*sLcrq=n%Ethv z)f1JKfbxme{*_-XkB76s*4O#+i8tyBOLd!Z7GogRHY}s#cU#I>kzI`?d@QkR46GC0d^4D(6Bt zJ~i$*rYoUy^OCQ?MN)O3PHfPd~O(Ae{t8S&9{R6CgOHiFCILXLZbs0<;+AfrMT`eNwBKCs#=EkbJlVDGd|22ZJQ5z&Y z=KqeMBZGTk!WrpXw#Af=sU-y=y)r#g4;c{2$Bv!Ye$--`5u6F1rhVr$XRSr0T$W_* zB#um{)o5NViEh?_mdiLVQo+nDChZ*-52*hVHuW=4H~5g!RqVxu++)z1Qtmwgy&l{4 z=sY5R3vRzhrj%@0BRd1M(!S$*4#FnjSJmr+pxYL5y777UwZIV?Bw!o>UzwBdxF>^8_YGyoyH zaGN65MnDXY>)&%2`|5#V3O{6}cQYckc992g%yD?r%54gdWF4Y!mzSWMT~jYmU$RR+~;0dY6u$;|uZ06C&s4WD|}R zY1T`tNCXl@^S9YSMloPACS-&S1pu8CeOe#f!Qq4fLc;t?X(Q(*Mtn)n$D&5|oGNI4 zSh|Z1t5P4#LdHu}!eJ#E+*#JGz0OAeIBFe2C@mG#a`b9Wn7t;Lr9=~VhM<*d!XfJ= zWvRZ{-MtPUe(Q*fWC{G)h7_IO8%H0PQ;45q->;7l0ax9$bXR!;LZpr@2Y}xncOi%b zT=&83Tfy3lJP#|=UN{A+9$*>MI;#OU)p8X0rqd4Na@KA?uw4852ZZ|z%t#E@h)IF@ zqTCEs)y=e0O8I)oxU*(DPb_1p7*lF%y5 z5pz8qkT^4|Y0M@>rMuypC_x&68ctI57iyUgq92g_Vp8Ob*iWj+mxJP=1I>%{-%{TW znzap0MArrnFWhN1d5H_SU0xE=S^`e zi5f~5WzplBv2VH=JMDqGw+S)EY*$!-wuh#4j`xN92S6%YE^WTzH9)@3Fxk1yc?2tz zbccPF9s+kq&Tz8&PjzrpQo4c{j|S0Q`ed6m6IUJqt^A3&ApLS2D)OviQRAB%M-Tc7O3wSi-7Tfj5uM+9}}hc<=|$Qe-X z;{4&}phxQjZ@z#i4I-seTplYOFW@!7Wq7#IrZ&)aFn;5lC)`Y*PK4?6UyfoVbcslu zE=?f-wx+Z}JTWS3`;qJxYsFytE32%-P%WDaIl-;tNps$l*H;9=niNL=Y!}G75TGvd z7ZR9A6pCX4*bb9rJyfrK-C5w#B8Oi%{Ohi}&20kIqMpaFI@$bb=&L+-c1s*$xSeK> zRyeUE@vtE^u(m^XbVCEERk&x_FprF}fJs?&`BfReV_lw%9Es@KT9sryPBSYH#?*um7fZ_RN0^w)FmFF6w*R?RA zA@w_odx|b5#P5$6e(wX>KY;0-VM43$)tzjt)wXxftDYQV@ffdNV?uaVS3w}_A6R`e}ZRfSOimS)fUF&uZ7(tF41fHhs5r{T|9(=3X=qU2QvWiH+ za+r$+mr)ubM@`HmedZ0=JQ|aIzq1fcWCf6pUF+LDhw_O`(ML?aN3$gswcjLG}GUC;S+>HFc zDl(_@<+{Tm&^J(T7|c37HKBpkxuOa1;lh>{F%;S3AsVH(wydqAht>-d91V?GQ9La) z_#Jj5KL!D_XBsrA#A-F#)=1ve_v=X~+B*F1)T$#K_O!YPn=j^mLOGmalF``(cX#ht zE7Q=4ugd-{n|*ih0Y0-88;roP(LN8?2V9SY*lst9kZ4SOyU$jODMBAsL@*2< zw3JK3hDJ(KN>k)1rTRC`vm5&VF8osKVn?5nj3Jl9$K4mr@>qj?nJ|Ni3HqB? z+cu9>T=RzxcImFT<;@wD~%3gF+=z^yUsTxmV%La?K`)>uapG>-#*jZ5CxYL1uQpB&+Lq)LjZExtzoRd9N=*>^$erE^@e1 zwjNiFndz^r5}|2GA4M2H*4T@VPUPRH=NLZL)qPi+cN6VglJ=H$|Ynew+;efjF~^Irb*K2mbEkNH2 zvDBIy;L|;K!Spye{cLohnZl~P)$@^I!c5OL2(yxCXdPg~_I}F@cx=6T-CWauU0w1( zABw@_^gqISH2m+YQ#Gb~3RnqRvPOz>MC|pVln#T8sE}!!drl61Pvk!Plg78$xFH6B zh^R2dl1{crT$!x@*|V+@^NxGZ!)^GUcuU%Y?#!qJ?;4KJ3|o2rwxbUfJkW#6vc^PH z->dOjBI$7_%if}yf=OFoY}TT~K|_1OfE}kSf+x9=+ijRaCpkN{{x*9$c9P8XbN*TX z^9-=j4FJTGk_7YCO_2kHJ;DqdQN;oJskaL$xK z_!U9ckeFfzD%WBS{Ggq{A0KDeJlZ<8MRLl847Y7m89LsLQl;^7H8|X=fM7wwvaBLa z&&xdn3G^{1{e98w7(HRS_xiLb_m_zkJKlRJAGZ^iC0aUq6ZgLdH9k(p-g~ps2uKA5 z__z6PK-2H)ON*$o2DN#W$>NrGatC!sn(-qpE4;oHudqc*VBuVC+~W_@O5BHkS%%Bg zsr~F2o&Gh$OnH=}fp&73{?L;@3Nm6agmAPq#J*RLYjk3NoYj(EG;O?SgnblM z{I{8B9jOtPb7BXWrDy7b2ewvDo$KXDiRWzC<8df*+WR}nrP`JNLTD|i@q5bR#0;I-MP&xpaje8t_R|UD;e6k@Pn@Y= zS(|@w?nL|EUgKDjpTY`&Vsv1j*Ul#<)-!c5K6k`(u;3t>8#+bkM-{L=c%QRM8saM` z$xm1ckBMt?ap(d8q%}etv9+sKZjlHD1&3T6<(F9;bf;q8!_mBuY!gMkt?i@D+9Lhn z;sU(NBj}%b?A+bW9*cgxDUZ55ohc-~O+m%x`IB_CMA*g|%|)GA$G!<5~s~Fnzy#INf?q+U<=+{JZHUJ!oddKJ!nN3}!h*T3VgzNMP zMrAQGIFlYf>n+*H!(u47Dv;MlJ=1Wcf*T{TVPSqTD=`!PNt_;(2`bBQvsgB#S6v9o z1d>d|uH)&(NplT9D8&nfT$?b8N!L-ZFfvydq5M+DCtJ#?tMHqhWqtxw$4{b6b#4zr z;FGNm31IOoyZ?M9tA(}+b29;|iO8Lp+cA4>x*Pm`CKt$G??!xv+e<1vVAghQ*XDMNy`1d#^9TZI$xDVZH3FX%r{n^ zMFH8B*?e&^X_gg0S1!;2&`vH!F>lRfU7g~bi=0W5=#_~X%sHOzt2h2FS2rq5-(RT4 zuQ|Byx{bj7Z4^`A!JWI{b%^(|-DrJz#-m$f`gTQ*i6rSOHCEw|r`*(w>-4@Bh1pG9 zO};H@E111wuJ*Xc1|viAi$!|nUbUC!7r+mF5p}KSmn25WK@a|%i$z1IZ{X5Yf$&(~ zBB|5QQdQRbxNfEqjR#4+i<*)1phKB%)!m#lXHvt|OxsW-aG_x>76He2=ZR{mZ;S0l zX=Yh5ypbAslus}@4y#MbVC<|y7)wLb!$5M0>WyKjt~pl1i%(CMXj@-c8Kl`Y3+N(E zA#qh=W^isJZTQ5vEiJNj%!^>eLB-Ac+h_T43PpfyTr9efhT2=Oz<&^mtx1n2`qRjc zvEWZOx-fz}N{YNF*M52>-Jd?Qvfd{~h#>B>43{8|`MILdjM2pYOlmw6&NBMtMs1uB zqCcaKD{8@>yU;jrjdFSAf)ZmXXMhZeI>E`81xc#(mNM7EX#c9}nn$v4yAu261fXbO zofOiK+=s4C&*SQe^t4zW;A1iL0fx#!(*X>M@dI*ndfBosm#e02A$?5aNbPJP8TpLVMNuP1b`9L&Fiu; zJH(vg;EZ)F@+Y zp4&|0$5?gIa}@DuL79d0*z>EFeu7(dvg*~k*%=b;T9;$?+Is4x1+{(=e=o4dj=8d? zWNLmzz&Sct7I4%}O-sFB0>&l-tLM&+{h7VvR1x7vXGf!UpCI`=vzMfZpm~~lXI#wa zD)8@rOxN}8oxM$XT>89^(ZCy4j>Akp8Dz#YKAph-9HBucc9}0?3)d?9$mQtlm9w^g zj@o%IUp0z|Yx~ztaU)jY6w-YD0oQIQAph~h*f~8SQSw)CL+n@O!kQm$X7k==*5t2 z<@#kpS5uUMJU} zPvV1ZXp!Ih%Z-Iw0DWaW*XasUV_4EVGV%s2qfv?cqbO!-e}E~i_Q10SqLT6?AXY*X z6tj}~l;{vBYuo!fjj@NtcW@t$3GVj#aBZ_+X4yV}TbX~U>-p@#OZEx7kDQ(1KE?Ow ztS(eDy0jaDJuZ@9U>s8`w$Gm9;@P(?c?p+7mFOC8;lDCv0g`n1zsUMdZtURponB=g zq91sU>Yh=5!#P9@fMBZd~R0S3f=- zLd6_i^}ExN>#su(W+$TG=QiQ=D(WsC=VzVlRvh3O_gjf zNJ6J(`yB_nkp2ufFN4FEjq>ZbRM^pSpg(MBdu~axW4`kH{$4CRCPYm;7cJ$>I<$o7 zD~(DhDm^MgEB@C8CWJIBDu;wAvpVTA)3S3bh__rgzLDsQqR>^9te)*Is!^F=BW@tl;01{lsaLMM?F%0i?zhHH`RHryn(ZY3n zk=V{1i6bk@(nG`s_TBPXmwx=kDOu z0n*wwyL*OMw6XyS6m$h=uH4PJTo1Ls*m_G%DS`^gNwTkb8>|J(d?-}8ilhu%S_BT& zXcl^vn2E3I^|a*0Wy|{HfEOz9TcCFLK$ERzt-N0&+wczmM9P~Hqy5{Wj_|T#5k?!< zf}EH)1FLF8A^pDwWJ;Jha!Mpl<_8P_vR3srcm8bgL&}7O6LoArdBni?%^1La) zPJz4Wy3d6@)J*~l z=j1S{R#xUHFp~eS(!jjB`WOP-ZG9|^ZCt#)o4UJj`g|RlvER}%a=sXjvl3oLwIRkm znjKvunFkm0svPP_*f5d{b7%&kwhE~kIxDn?3&s}>ti=`@`e5Fkq6wi6w;9@o>A(WK z(1X`3gMe|!tw?ZueZQC0G)Z0lbw#dS=?S)!sj|d*hP3bk-`?xVIslRm`EPWYTH}p0 z+qMQVP4I<(hMi9pXGf|~lIL)0Z&QjjqeEKKkPMzvupL&@11Bd~_T-tlr4y>Na4wIw*;h< zvsDKB5+Q@3zn(q5jsQ^T3hpl7`r?eOtj?Som>ZZo=Ss9`NJ$$Nq~hhgdKGN87mL+b zX;X#^Yrg&ApDbs#PIn5-Jz!{%R3O#uisZk{3Nfqp|dybJ5d;Er@7#!2n3={-;$aQ5zMVkGRzq zgH#Q2peP@v_M-ykT0B7MuY?;YsCNukW4TwA!B zvCEuhPc>|B+~NGp6&ztq{QkmG;17uE_f3^c9ylr zs%b~83b$D7ao+H6U2)`!QkHLFM#a+2ZozMMIx>A>Y$W}ir~df|G+?M!gw09hT{MXS z%?bctBt-;O)NQMU?B(tbv{KB3cW#q+SRrIeTb-DhnP2~&TNpYc^1eJZF}OSU`&xv> z+S`?G8yeE2l(GS>Mpnx2D;;$LiJY`lqQbq(BcsbAx?16^PrkJ>RgFTK4utNT)RJap z>5oP14%8j7_dO@i)rTT0Wm4PD{_Ux4A%~)|lC5dX{3d(;` zyABwNvY<$#a|6@=A5Z5P9|yE`{l>N?Zfvt*8#|2~+qN^Y?S_p#aT?ocY&N#-ywm&K z`+m)r$(-MrbM{&5zxI|dSrAuM)Gtv&N7Kv^H~m-DrSV<2bg}X ziO-asU%{gZQm#`(=ns(EJOc)*0+t4J|FV#M4Mkl#@O0!1Gsf{tnOG9aV5o)}cpZ@Ruu#MRYwWMjoR`i~BOI zG+7Z@aA7flQG=Z+;Qbn-)JVc$?*N8o&;&nH;Urk(NB(o>GASDUnbXrsaW%{Hrw!0vc= z4L4r_mMJc0^mcFcWWBGOPqyu@Q6AKb*|MA~6DH;#=)Yp3Duz+k$N&Z?1Y<$08{#EW zf3~xWX(gt_|JImHX=7(2YLwC3<1RS(xs%b0YC4pTK+@i#kJuHW%mQ@R3Us&HWIl9M8dF?Y>W+Ua?SQUUnM7R|r679@3p1(Nhk4_ln>Gk!&dQ&C|T~(N{^3LZYmzjnn z7wkS&qkF4$<<<%{B7IW!=y}4Qe01OarS_g*=B=0h-Y{0;D6mF4>bL?TlF2Xi{uXfX zoidlP=HSSzv<+tTYvtI z@dy(4FeTJ&Zljj%bPsj<0N5P5LMP1&>2gZ)E^4H&n zes?B8B+i*7a1WVdSd^`z#KAzERq`0#1fHPml;4H2u4^--FyNnD7s5*s7R`P7y^#vv zN2{B$r>+}V>I7q`)WKbcjy&QNWJ{F=`T1)^U||#EilM457hsN%l>pfa$;UR2fio3} zjjz~_>#kGeX#UH9!GQM(Brv!>J@xF=(a2>ur2iL{;NhM3w~kE zRySK>O_^~)qBmL^|0yS!{;qCs+%GCulnS?kZ*291c5b`wS1GuisXcn;mao-);#b;Q z*rb+kMRVaGbSYsGEx4ek6KIEW)AuI8 z?3himO8r-!1G)hhU<``rqv2B1Ymtw*7C^V7*&4DB-glRYIZb``gMCG_q5JXMA zBLW?{WXr^0w>qRmnc-lq^+=9yXrt|Hjr;r-I?5Xnt!YijMZ==3zQ>fg>nVS0_#V&? zP2U<@Xuq7WoJRt@ax}5dZpWBWlO%J?A)4eb?Y8w&c z7>>3iLYh>E=cOChzPRVq5y?P~St=0!aH1Ag-p<6i zp;lN6B-58vvJd}i|MdlhA0Ih4Dl@5fo*@pKz8&@B!~v1|gu#C%a~=#E1)EiG(}|B=NrHk3vE^i$<;f5a1XMOJtG$cKHNC zp5?+Glt$NS$@0sUUp7)yR2WPn8spg9mo@%-{xf7iM=IoMrH^*Y+r046W0FRQByg)$ z8E#OnH`UDGm%%27QHzEI5?3_-kJE5kA(H>NPQ_-H`F~9b7R=a@s7g4@4#OQJMZAFd z8Uy~BOWAbPqnCK;MaZM(0PYyHE;*&-hG&_SXgCrNy$SAyWVtuUjPFCE8YND1RObA< zA~%!$;IRqmw_Wlu>Vg2n9q5c10!Z~OA8ZUpI9LN*)3l`T2GnXuMZ>j$yL0)JX&H-0 z8!)4e4Ax-|?hVcD#Nr*_Xo~Qs3~Yc-S62}R!}*y3hBR|rx=ck@tWGIDJmVV%cLslG z+4u^x*G)!QMTG3>+WA}QWFwCrB+x@A#aW%8g3{PnB`_&&b&bzS47-|sommIPoaA4` zuf^ByCyGpE<-koisvQv-Q}qzG@nAmnmXzLxA{ko={zWaII52}V+*A`xp3VmHdRp1p zfo!BI{9a&sI<&SPalDoxwNFKa;iNBHQ(BroyN)EGmmC$gCpCq~#chcI;0~63%;BT6 z!Nc;%%l<3oE5FPv*_BW6n@%kCWyVvai@uIdHZ`Ced8*qbQzV{w)+lu*X)#QixhoRFJ0}z0GBkCK@ zb#$wpNxe;gP(-vgh6_blRyx;Wsj2Pqp zN;zTqX3L=7O0t7y2Dy+XwX)DY`%`n`Vq>a=ym@H1KXa6Dl=kfWr9=f-HiqOD^F29Z zGDlFnaESN6v1W~nYWRN0l;R)-=dhP}P1?%Oa^je<(sWmfl$)=$v@3{5woAS z%{Oat6#~UiYxP1gLZ=q4*Nh4W+Eul7nGfm>(=xdw4 zRb{C4<~J9Uc$jayXgMAgts(4XI|%>QQWO5(=Cs;(|IP`)iIH=GE5qf2Pwc*67t`d* z?OAw^V&8dof6);n^!H&L8~|Vu7V=t_Mb*0pJ-iQ_3*Q{Uoj)Di3);6o;n+WQUVPjD zhI$-spwESZ+Avu0DVru2^`J|)+!P$#RFP~#vU zKd83`BhE^P@SGbL;I>FRRI*Y|9RndJHlx2J9q7;>4Bn1P1*ixnpH>VGcBiUr@BBG0 zR|rL%Oo?=pQ%uUEzk6+sXMS36zc_c5-ix$Kw|n^9kL7l~dvp*>L>w}$3ml)1in8B-TxJr||}AM+Zs__G!q_ zmBcMBh_MbA+1zeqWXMY$#}BS~t)At+-o%kHX#ddh0o%-RL}rY7?sm(g%N$)Ft6d}i z0EIImwxaKFUY=M}0w}@iSvxU{6%tb8)9ryXrecv*G-H3bpuHAGVedD%x(2nmf!W6a``{>21X z;m`K|{7ysEQ@g_XWf~N_KC|$>O*>&9_!-F#}%%>y0xk&n@XH%n$5TA&xHN?w-{dDD=8PM#i7_TQ@ZT4^5^z9jKp& z`H-PHH6wNMH*2t_fe+GB#C5#La)KToZ`kI2mvh2C=ND`Qp;tW7q08_aU}lTeBjn^~ z#pD0L0@C>Fswxmk>$c46>)aNN@KtS`(VVrV=Tp^%#{sy%rS;#-L4}eipx^n$dHch8 z_0Gf#3!lIDcCOuz=u(Q7jDT;^V}`arCRdI}b6+ojz+mljj}x>%6XRV6l7AmkfUo55 z5tpFW{fwSpA7zSufd<}=T9l39Yp;Pe+2pQGpGn3}*N9TYUo<|RhnT;3#DCK9J#%I8 z-eYRMlHB-6va3P;Xn6a&YCT*AWxF;R`cktwb4}7OF%-L6=C_K|w7-wLstztXnTZNC z@*?MfM<(O zS+S!1IxzC6+}M;+RL%@xCNKNSC9P>nLHpme<}yYIo~N-L7`VzPxtE=FS!)sYd6PIiS$ppT#n0gouv~`o+^Vs&H*4CIwYX-Ez$fJ!xb(3;p!DF?G{HS#A#VE9K%}jkO|Ft zFngG=y>l$9d)i%2m4rUR0BZHJ^LtMS1B1Zv)NkkZuQZgDQcA3WVTFhPKvKsS{=aW} zD-a`Sc0FfO-ZhUj!tb@SB?@F+UWeKb1rN7nNu=*7XrJ}--z*g?;jHWBfu9*f&BEK> zwl3b%g2GVA0vecKqp?w?slDQe1tX&|psd~fj_qp@3Z+XFa?-Oi2bd0h-d%`#wX>$|sa^4eDQBmREes=Z)DzSnfQ>01a z&0lzU8(kFZixCo6Of)tUInc1rs|N0p!wtrbdLf7?&T5dN^}RULAfNZGVi%asY%lORgv^6zEytwQt6Uzw!u$N|FCf>H_y}mahQHO@%F$%%>B;X_7D691lF;&~^aqccAz!(0(0vwb#G2V0@Y!h-s+xZZ*VD0o_n zEE)}}7&-`IsfnQI6L2YBnRPZufK^eU>`1uiO{obTGsTu2*%YSFl(g7P{0r1xA}c|lb6u5K&t=PH z!rc0ot1EEw^0OGDk1I&row%2C&z@P|-w^xP;beg*# z?j2b93}5NDylyEfMc>mz$`TCT(^8Vy?T<6He(82vB2OL5bSEvTJ5PUQ%9D}0%QVjJ zMj3%DQ4P~MXVvH#+P;o2lI1b`NwOGK?az<=3k|44k0G1qMwsDW$5SZqOBH^%d(=PS zHc{59pyFHf!U{Qg)h3zLgsuX;9O>vyudGqIr>?BzbT|1PgvPIfux3ac$R+DO6?#iL zuJ^_~IJvUuoJjJU&%vxB8~fMY2H!NiAC%Y9oj>9yz*c#gt~UlfAbTo%#t92wBWUP2 zX$H7`-76)+`U3!K9fIN3n3b#x8Ke+dT>$K;l7R?bsNWAbJNCUa(+Lcv_WD#6H}ZvOJ70aKhX`vaGJRh{`A&OI zn+@Yj4RA5`r?%&%6WlrnCo6g}ax$iyvSW`bInmehp>e;&eFSee>^+8}VY*D*=s>TU zf*;KXG;SdiY;5vN5&(gOmNaoaV9hjoQ(N&W;VvS|zDRVe%oUqGc`@iJzJ8qRZX+Fe zumQu4CYpP3&QLDYp|?q^(=RW(FuHM}$Y-%w&*@2rQs|szUOq@M%x)CQ)=)L3-oyqV z<0J5i0sk(4qoU3+VOcO3hiqWU1u~0NKvN{VNT&oaD{D4doB2KKi|Z8 z#H{H|Vo+6;nl4`b(<5AMCjUycsw!`k z^btt0`f1|Ai9B2PH*kh1-ob;oDms58o3^8s#5`uopRXmMhND7TgvzR1>?C|~U!KI)S$#;um-CO*Ttn{tUOb7tYqN#Na?XTC`dh$_aMEqX2!$^}cdQ9qpMKz2IK>xeu*?U&GhkMdz!)F1& z?fNjGpTzxRE6+w`uKrCc&v!jjZ|xr(iL||OTp#_DZ;(a$sEtD;e(-$}_n($|Lmz9I zp0iNcPb<)!1n$B2Bf-(hdla+PLXZw#1QldAvEMsXSF}Nn?=jsm&q^Q)*Xn=vV9lS2 zj3D;wg(aZ)*I$&gm4<0-d=fW`n5Cgd(I650D2~(d7dQMhV^#?16Z)ToymNrlY8gRO zF$H%QgdSJ)ph{&n99*s&0@u6NsujyTiyTx0bwk}B#kXspc3e)g>V^;Vvxn~gII|#| zx-?Hd55oRi8^dR+5Z{d}koyjrbG{xxu&yLF`Jy)RM|*vFq0uDQ}Zj4VB!kKv{xAcHN_$8$;266 zw=PfP>Qh=!xYY#N93h&Z%^)h zIvFVqx=9Bf-?OgTT%r!CG}bpE04RIYYGl^&vY3uSZKMx zAYaILUu#A;4zKB$9#TS-~m`i)0jUfY%k^<9M*XCXb0*5=Q|@nVAL3~#+u zR|L&5$2XN*W=7rXhE*)_1oI%>sPDSLuk*jxd@eDcCfu#!s0rSccm)`X<;x zV3(v&Zq9puHT&DOLWxncZZi(cuG?4ftt@T^h9RPWwts}vs%@&V*w_s6%`I(k&L9LR$@EDY=sw_>lUj6SPThRVVXrdvp6Q>^5#X&7M-gv{Gay7o z#v*}!KbY|wPHpS10e!<oOQ1xvU5Aqe)*B3Lz{lWbo#ki&YpcNIh4&`e>B_IiW<@)2 zPdxt(zRVv!0&5G7K|iy6s%ghs}KcA#bD^?dS?5Eg{X10>hV!d5;1VG zutRiv$0M#1wtuKfHX=?#M+70z-eiVL#T6qOg(X@YZ0q+?`0IDoFQioGS(liWEwHC5Z4xp~1t%CJAM`y~ z(a|_j$%sp36NZ)vng@+jqkLzsK7z93k6BkLD`I|*3$ztJjv$|gEWOq6SDTtC)$jM> zF^iUsd-3YLz}o(@$T$wJF(uWOR3;eX-p?b~#ZgWyFPfl*;h)eFXVDREA&z-eW1<9y z=!Yl-f5ByDr`JOVSZOHHP`?Rml=iNWF7yL@=Qq-b6kH?JOS7=9um~XIn(}20))a#G zVHL~#>>;JPj?}002AV9GFaIk9uz}VEf5;aQA2Kd5xTk*?96bcU`fwZ?8_r$iM+^)F zS?wc3LXt2S$j;7{$vM|F%K4?ZR?KWXR%)IxSlTaOL$j#EO7-m`HQ0?}S+ri3rMb_J zV*XU!8vRs@*U?a^;CrQ&cLR$oJy~e-1Zf=^#}Le}`?a?;vDHW|Dh`R-&42FfYZ7?d zM&SZ&E5?guwIEflR$>-xP1l0g^#Py)l3jF*Qe-(U9lty6v+Gnypmt)Sv~4LgUrqpa z0j7*fEOe)u;NCG^ugxqRtOVM`a5z+b8Qa$apSRjrc^qzA&wDa@WuvJ*3&ujRnGn5` z{{0>Q*d|L{nJHV*Uy^5k1T726^N`fTkK=(kJUHz8&R3V33p0HX8Z~Xyff%hzya&U9 z2J8SEx!|e&?JcBCFH2inUonZ_=AK7Wdudwn#(f6w=X(<{`%HVTjSsM-^*jbx+dDhG z2C>J#4Uhh~|4%C@QSBa(5QQICMsJk~V!b^hqQ!A(?17g_;oFuDh3pX z0I~&XmEY`+$sr4fysMeNxa_KYW)#Y)X}I#(q!a?l%o7BvqukCRX20l=0m`un3rdQu z*#1YZX)d20Lt$ZJwl~EQ-LRA#G+WEa+s!*`Ef*YJC zn`%}ZyEA}&h%(W83gk2^`-*j(%6KH4I!O4mz@zS|D4G})ic_nj(i+*~P$#y27~|%Z zmF*r;yRbYckE9-pR4XmQ0uBJKmroP=W7QAuwh~=pr*G?A6tb>KeCXQcN4+vr^Ct$~ z<0@8up_98LK)?^H&LQ)ePssD?LkC)_pew-TE#v>X|nFG``IFlm2&k7uFOegqtQd^{4}pvvE=r zdIS}~Xy1uvLJGSbO+i@xi!wIv1r=E(!s$FIIQ#l`aw^ ziNZ;%nA&&p${k?+=cci&NrZW`j1Md1Z<{XbiY@_ccTW^r^zfnAI&&f)cfz9wQgrJ1 z5~BEHJX$ZW!3sQ0Foqj=^4vX>|FjdoB4mNtS+oLAp<0(9i&3&HwJE1zpz52MP3hPy zFtr@rhZz}g{Rz2+d~u1jlnKz%R&34o#{M5pP7o(OtiGN`m3swpoC5kKuJpn{+Nr8(&>^qRU3X{F!}52A-lhdOS6rex z=isUM`o+#Ex?kLJf)<~Vi3$AwTL5<^HjJn9<;TDg0h3QXc!8gKG(s|+YR`gt+=l<> zFDxAI%BvDj1oMgdq@%Kzol4a1Ab%Stl>S!Q$W|^eTBMAkrMBa0R<4Dg%`lRC8CQ1F zj!M7E(5`@d;CjxC>c8^JcVO{LsB3~7O^pDFTLPii^17WpXIPx$8Yp0V5Ka{VWc$ie z0M=7qYo_sa8<^^(j{hUC`tZE2FGgrY;6OC3-a$c~p=-_d5F^mBoa zaFX=&G(!t!LYvSXdMJ|Se@0XQ6FxjSR z7@8NDN1!3lP$t8HsKvC^1?&aP-80v%^>u$X~FE2v}WEV(hi>m=p$_fs_Ec>hihN zhEQAHDh0QcuOOr5s2DXX+GrzkfK3=<;?aMJYT97jDTo6@Mj1`3%paxFLCKjakh6)O z!wCwkF-RrxY+@cg@)w$@l_lGL9x!}Tl>j(7sL-;}*!_$%{i>xZST;>Xy?2KVM6N%_ zPl3#KrI-9{MrPkL>Oo9_;$CmjY--oQ9+|4YW6H3gUHUHn=~t@}lFG502$SFt=gaJB zicU^)SR#_&j4D6*mX#^?YN~4jCv1?9q-`}R+IChIRXX=s|vQ<0mu0? zF7!-vQu_di7_#*#05J;m@2?nsK+LlvgxiIZ$^aobLmz%axdo*S<-+tKcedye^c-Ht z<7K?q29DNQu+>xvS`j9`x@wJXR(rcYPOOIRAF7=jm0%kl@QHJ;5LA}RZUrmNx*fkB zd2?-h0mI5(kL!;LKC9bzS>qv@vWquABs5wey`OZ*E^5Er@>79s|EM= zo1T}8-@uKlrr#gAA0J)bXM`Iblk0yyPPf7~?lwrDz(u?7a(@*( z*+gw)+x{bubfey$)XxL>*kiBg-%?cN-ucq8AvBcqn0oQ@F8pywD*SQEF~03G$e(>) zfF|5-evy;vmG6n7c-SKvw&vVX(;U9ITdyd{)qs|1stwALCs^=#dDu`|eQfD!yIDE0 zUz(U*_v7-iJ$df8c6p|Lk-@j}V66T)*Z$ZAeiTfj{nY|Vyl(<8IlNf$A~_3(nSx z*Sn+EsaavC`XQs{FYl;=(}GBq$slUsgzrU2qXHLA^d}jT<{ai%(b7-N^)|V{LS;?~ z&Ph+gah1_wCwOL{;n#?OqqNRziUTh;M~YBJw%vYXq|fVCXS2JKYRd7r^_rhl2Go(5 z0_1(aVZvj(;Ixp1kR_ZSMaCsn3_ex)IIm3M*0Z)dt%5%D(&1wd7!)?m-O5ftvL-%@ z@Skn(*tYIgv3j@)t0~@@nb-H&zeufp)7K@PSxt1nyc9~Gy zC##|N3tEd)h+1}9v z=|1iO*MC+RB-`3bT{-%qZ}V+6p+ls;>GWin-UqHPd*EC z0hA%uYkDjv!p_Vp1f<$G4>#Q?23i>ssXXX63Q=I;+I($9+C(6EzUCSu9zx8rE6{3L zEV2P3r5t-pghirvEhoPz%OT1kJ(I|K!Mtm^$%Q5p-=(#3uqU{_Jfd(d_0H1dS0?U0 zOMZWAIs{ontJ&$DBSk!kNS+J=(Ei(@P0VJXI$rc?phE~3-U0C!q0yTee5A1xcm}wT5?s)s%`qn$&JU*56 zDb5_u+UaQPKJ5;DAVXOPo0yrU=7;kdG=8I53)={xQ1ZNU?;wfVnV4%GTiD0L1$Asm z2rOL?`Sp%%+c@+|oE~|uC5`qGJq$85oC1Y>#`GcQ6u7a+AX&R)v}&$ zt@d3(7Px6lK~KUW1qRtFiN80!7|I?!7M@Xa`lNZ>HA zOjlf$335=O&nn@bQyYIB{8fSfhw!x*JbeT*?x-fukC`^i}nn93VR9(h*k7^-}sMyK5{a0$m1Ab+-|6N|6a z*c%oZck{LE7ehics3Pa#S*^qDo7PI^uws>}NUKxmu!RWBtxa*WRtN1t(=mI3a+^gK zkcu9<@4B@=+99CD%C+3S>akhkSH+%;kB&WeG>S{NBAOVdGsm-Qz5uiD`L4IOq>&&K zMFSd`r+ZnAV z!eAc|jB)oc>YNNptUd+uzc-GT%}|3gX}3P&cQb!-$6+z`HR5g6I`^vzaFf zmfpX%+1~Ov1jiUN5-Av-qW(S=cDMq*RQ>H{BTW<}YFt8eOb#-}BS7AgI;2|EeF*D% z&=-1TAngvHvetWmT{#ff=zNU(*nALvIw18Pxm#>AtyLl#6@H!)Z5H;z!11!AK!tOp zXx+F?y(l9yjJ#XFS|I&u7We`LYme9uL&|c~UkdfQZgPdAUse}J9NJwE{=Uy&ybl7e z+4*c97FO+s3i|3E5B}MUuQ3!NuQA#+3Y9-seE&IqZCmh->IgF&YvIfSxTjR7D2VB= zd%5qVd9M}UJu7-nnuQ3l`aH5cP$1ReegdWeB7Oqb^j z4UDsh2fBr5n%ZSV!Xf64)6dFul|(-&)r1;Eyf1cE;o3{#&rUWxDjwclUq}(S=MAbQ z+PT}`;>0ichKM^I7d0-024XxgX6zo@-1IrCgTWGZc-f5?5EJKrVgV8w@DNJH(eku` zf<<6xcaNzJJ8Dyj2d(BFhU+p}n$|$oIwt%A+=6ke)y*j_ukrfy5zze-w^B5A@ zZXkCWQ3KuE0{fM6n_T55nbTHeR&{)buOm zE3A!xbbqq*G|o`oV*l2$4txP~RZidK(8e{T)k1{)vhm8TJ|V4SDVL*Hu4D(99X@58 zLi#(>6JdmEk&7o6+Km~=O~dT(y@f}gciIbb0+16ae^yo@=x93*w?U9SQomW@tx5oF zzz>HNL19|}lPy(5u1s?@NIS(Anr>#?oUa||xz5kL;o^!_Xf7b#{Ckcu#Yjj)qxA=P z3Yd0TbrrV;12WgNo%upuR-qcv_KwtZhIRGO!=9XD`#-}mcEA!KW=v7N6;C|2jcQ$C zo#*S&A3^bjAY%tGVK-z*YA41WQv2Cv1tzGE*NZC_^iAJvgMzgXIv84a=oz<&5qCWVEqV8m;ZX??hJI z42NodW@m@86woYuhe<-m&Kd24YRfZcY_dd@!zdsrmoT%hTKZid<^zw6W$&ry5kb33tp)^gaVmLI-V^H!Ic= ztnpbdOwXX{ZvP9SDf~_?dbY)V99|1kIL-NQp;xl}w|f}LD&3WE2nKJpoffmmLvl(! z#Q$wzD-FgD?JGTT7f%mu!ySM!U2qIdh*5Nbs+32K>~vHboS&YGGqAYhp?dYheYOILF)zLH0C=E{xio!U3?OS*78)CyLXNb(o4pPT9 z5|dcGKm&n6v}}(OQl=GLEu;bpC@++Qw(GFAB{AmorYIO)n=qT+d6tNQt?s?yo5|@P zC}HYp`i|nn}}^rl12O#AzeY$qCZ7}_Nqz}=}e-?eE@SW~mnXxg>V&j4JbaSoN6rCL2Zo5qgbs%ff?g^~4if{i4IDLnFZ( zD`qv)8mpV+Ms?Uldb$qjki+Yth;+SB7HO_assr%%YFHg+Iq&dd&L z9ao%Mo?zx>&`Hmu*l4b(;}|Ut^z2Kki_PiSkD$p%?Y+C`L043VS)$3Qx@iF6-@-=w z7&B?TMbanlH^uihCoyDQ($BLfUE@gKC&XXw!Tz9K`+LSWw~6p_$tdnf6jPV!reSI# zzD?jEe%Lxs=jlG&d0SYS!8-Uh3x$GXCW}2VD~Pe?*2g%hMG|J`km}8_7B$Qq4;OXQ z+D?pNjVwP43hGsGuTLY6{ezmZhi~yCv^HGL9ARKIRkCGePFqJ#}t^5*?6o=Q#q%yy;3l&3tc2hY}N2x zJh5s?+gQjv7+%MZP)`c>ekn06QYoZOR+Yx;u*y46!PVIt)IT@7)tgd_S$Eq6!MXGpqgxQZxM3 z%LudMfD3;?cWPeZOg}pfJ?m>I{+gb1Fi0RUg~>W~f|c5?z-!1ez3KYgj9eWwv*)0Q zKC#=1D5`2YQiaFDxSuo}%4=md3Aa^U9p6lM$!6C}c%mz1ia&23GU5l2Gh}v%i zD^pX{a?kx3XsB(o3Np1AKjW84b(}7L5r^AvI0Qc=o`C9s+wcf*avD0WcWbXcr8q?Q z)3UxkLvaPPGP5E%H(0_CNXgoJ1ZP3wmmKWMqgTe6tVEGaOe|fmsTvdtK%!AnuqAvY zNjm8M!C8U$TZI+H8+pjtjpsM)sal&b$@?U5GY#YQ@ROCGnbPtf<>=4TGNB-@7b`RM z$%|I-n^8w=gX1~4f>WN3V_{#;$oU?fH6J|Y+D7<$n@3G@Zs@no6Fo01JuMf$OPy6u z^&f=26<1j8_m^srxR(2RKyGdO9E$A#7gs}?Kd>OI-@qL2XG@mrjFy8%?->l%9F~lu zum@BXO6V_4KhhbI3gJnZTEe zvw7L4)`gP}%u5}XGtI#h6yZ{&3nMSt0g0Lwyg6u%46gR;E2l<%pu9@>3Ia__9cBRL z{GFKF!dzrpvd7QEe%ZxeS9#ZAaaEiTE?g~nS;~jY<0F2R9zCnUnrs6`pc@)ewpz=C zyPD4x#qOz%{?5(Re-klT*0bbFRI*w;)P3I8Hl+l5YCrEjwGj03)c`NTqhl|E)72U* zv`rGG&no44b$%sq0#U!)bk1VM2}jzmSueXE4opYrzSRv}u5+74ZB3nl?dHzhw*fRz z6-dD0qJzb6M3#0Pb;u++D2(N9-TxD63W@I_natZiylmEoWNm9g@eQTPnxi^Hs^;_A zO^=3O@cnXOISzNEJQij&<-fjY12F(YkAFPta4zs(6FA!6=hk%{r{C{u*Ku|~MC$1Q zM6x)7_h_n!OJ?V~{bUSX}%#Vz39dU9*rO zBs2pk^~i1qkmn`p8@Gkb#U8IiSg$nHBi zKh9JXNs7UHo(0hB^Up%J(5|;>Ibx1^(4w@TXcZ;I&UM+e;w?!eZGY@XsgU z4Q7{B1vo-3%0kfTlFfa|uwl>$`;!-K`mF+^5w#GB7IHicK$n?oyWhpICVs<9 z7CdmKQd=iq4N{vH?@@hd915NW7&IMQ10yjV>A=%t(Wzn;^ewRvMd=etUj?h3>=i3= z_1MZ`G%BH1+RR1>CTX<=X;X7>V#*2Hb&KALtmk^;f7{7Wa^Y#89h?La>8>Bo!msv* zF2Fw7&{#Hwur6>#j}|Cea5)Dj+|E#oAc$_x+R!Y>1n_)B@V?3}0_$~cw9C)hZ1>d~ zD(L)UjKH`eoM<2-zjdYwOeUKQUyPIIbiQWW_9CgzX?Dcw*`@GK2@3} z>>FuqfSi@7wALO76IOWu1< zQdLAcGTwrmLLL(zn252sqg2uv($X@^z@TcVqEgDrIycH-@IrEX&bNuG&j5GGArctC*fOYrP*YyiGc>~)EP*Z(GLr8EK zG_JeyGSZob`y0t;49fBhbtcslfY`t0+zAFVnwdX&@7viHjB{q`k_b)!b- z9d(0V53Oobdz=(cv*qcFo}Z?<=!80dYn*1EG(%kaQOi~#8?dBi$ezxk7$RdMm$7ab zzm&5+BMu_=9?}BJqF9BSlxZ)G{_5Zieim+`9vA{%_*D8A-rRmXauw^J(FxpBks8}r zD{qzX5esYet#NT2;&iJ0GBUH8I&38C($&#gGs!sgG+XL>VQDSJ4Fk6xCippW#bB)e zoq3hY2DTH0;hRCNl5q%v`ARh+F3J#W1J&Z91+1M~ zaiiRpr*vCZ5WdUM$J->&)z9)_-+xNMgmQpVy5f^SUY5W>F`|yXWGk8M#8N>O=mljg z3Z`s~1%2Dh&&S$wcHu8W24IVGgc>X6cZmScOm_g6&x5{c@VAF4qjC=gm0dA!BbXzB-tjG?@%^gJ^*7ndnFS^Iv4;ysq zhgqKVMC32bTDn5HA#4iT*C*CGfCkHCK=w;xCH5eAa8Ia!aen{Mh_>wYrW3!3mIUx$ zYtGIe$y?`~TU^OR$-T`P<+?3=-QDn(zl^hCS_p7t(iGFOg1q9V@orF;zM%hK3C`R^zFLx}GoMM~euwKh^Rki=Czx(5J+$1-1CR2F1u zi-%l%2ANE0(L0Z*6OFlLGjlV6f^DtpW@d>?jg!wl6gO?e zY!xN*#{@NoscO#$A@cqS_A^2TTjA~rRK;OHh1%MD=4V?X-R)FW=w@nY=36Whk#ZgNc}7XoIaow)O)vT8-(wg&!xTPQ^}ePJN& zq`r#H%V+3BH0StK@W@m^L=4RqVf=SP~e`#3% z?(NqU^ny$AwGy`^9k&lz|9j5V-H(VX1ZM_ z{yP(|XGF%lYNm@#M^c1uD@uf3+H9;({{=lX^jz&Vntlg5^EaP@%u?GZF7{EB!GFx>T98u?b;3gOJpaaa6!h6VJf3B`&Rhxek=!Iv|NAx z*1yM>f_g_G#Ih))e)-~KoxwD{(U9>p)0tV3*4&mRfO z!@VV4dJS_8bjs+zScxc^V&Ae$>jI5lAD^cUFT2xYbvv?ch84UFlmJ?3QfJ| z?;?MxeZb>96TVv)jIwNA8>jgp@=Q#iism~KA~Ak`5fZ2&c4c;}qM_7V({c!i_w#OR zi^lL#c`cF>CWDmm_a5P3AnT>@UwzY!cSVrh8JRmSu(DuJ4>1J?Z7XEsgwU475rs4pW)I|a9d{f}#o@!5{I-Hs~tZFdem&d|1C z`2#4+>%B~8$i>q@&xuJy3yFhY_PtRZijj^T##%m(*hRnN#=Dkz@b*E71q_#ZKTD&{ z{j(jSd)QCe{rVT?(4o}_bqiz_MNWdXEY)&F(^pJr*X>g=7!GTM-dl!bOsySvPQ zzH4NI7Ee%$pf?ZZ%l3iz-4@vFp&ypYiw20HhrUJ1bAQQ?@_8r#~ z7T@@o?`9rr-ui^Xh?dxXC(Xh3{zw13pa!-RVyhIFK3<%T<>}V9ZW!AG4ef0O(XBEE zsQyoR1&^exzreKi(RJPMCNY%4xJh(g3mpP@Q~?bgFrVt3>T{vz<3__; zIwEF%iOAtj_V&cS!Z2@{h2Ko-cg+CO&UeaA3OC#5s)4*q6i&Z3^~=Dsza$hGoYg3O z-r{_rfbHo}C3ferWY<6Z7uM+c5&;<&Z4eg;Cr?jLua})JoK9a{$Ulq5NX--6DoDBu zL+*mWT|Ov`Fbi)hmN~f^m!g0T;05p|(yYA6y}<|-zrPrl?nyOn2#>|ibk7NaNB7Wy zvWP1=8)Gy)e&Qj@-;o4{8+YI;OgVrqIkKR7+JsHb6B#AP(#`4YD_&o%f2f2Uw1`Lrk%jzSj<*JNsrP_fn*wvw}KPgFH=Db6VX|>spWXbn-t+uBG zD2{g`ljCm4O8U)tK~=+l;B5{3rmoyF&R0J76q=7Z(qu$`6!1$Kz0N-{f*(2<1H^}R zDlU1dbd>)h_47CX;|$Agf66fx;^+Rt1oTSgaVf1mN~q${%dp$%2gak(>@sT`sg#4+ zbUd-5seFY0jd#hw$!-je{`fc$H82_k`dtF6qrkNEf{k5cU1?P>2OwBemG)eJIV92U zolRC04UP&v@VZ=Ge*USo{Q$r}<{6>;J`(qZB|K!OlcDzFtr*eY1dz5-ai=c#?H>cI zo!Bqi%YYL?9Lxr(CMyOi?_p}Y_x-fdqV{Wq-So#Sb+Gp8pj(i~WN+l8nOM+uX`6 z`=G0*3&NIq+I0I2WD5Dgrr%0jGxQZPaUEAM@%FPpq@n9#yl8kyhHR()vo9FDBhLGU zFBxwOTj1S~>2~hO^BN1d-8Qi+%E~!LF{!9{RQ?Y}1XWcxq$(=*N461{|GH;F2Q~}W z<{;Cj&dZ*=yeI4n_S5Dl+q02%LR^XwG)0LfLWko^JuRLjLNtE(mtI=uTT}Xo7y;vn zj<=mR`5Wp?LPvfjj@2HYzJp_|osInJ8oJyH2F!P0R!eyBx<{OUeZz`@BagNq$NGAc z@KONj-AGe-^v45o-@tpwh69ySAxYG>Z76hrB;XYmrW@%g%r>f-rHdvaHK{JHmfoI} ztcSZ0Gchr#^~W<}JO17KidZ&+JGlQaE88K%6-v^h;qWF4-GP_#7F;4i>VbtG5Nkw< z!stTJ^x3edb1@r}c1vGRG0>Aup`0o0v*7`fCAK&B7OjrO)Y#ChDm}VGwYg!yz&=Bj zR62VHQAkC1!a@(#VLKTGJr6(4bB$v8yqj6eUjNKOCARO#-U^LZ-Z0{tkVJ!Yk!>XI zf{51SA*!r58nK|wJ8+o^0iWjKJD$lbGGhZiy)~8z1*WPul6Yd{G#w;jh1x5XsZi#s zCFHX&wB!-`RxgH;Y|gwU{ur1AEK3JU1pC9W_RXbJG~SvN{`YV_h@9UtJkZNfQE5_{z}vQDW#R#>u!KFqiK}lOt4t|1d5a$tuq51j#&{E zFdPn(L$Xtc7nA;~2)R*Y*WJP@=VM{74a<6V0)DYnk(Wb{K<^t{{!iTj*-gf|>x`;j zt2vB`8pm2{-s^T`56J4ibM;U#5ob|#joBf6J_*nb1Y%vmLxfrfrfc*br9!$s7(p9r zxlMs9bPE{9K(PGvA^_7Wwi=bDe(+EU=+~JER17J1eOqSsLH>9I{Ahc~jU4B;8AIvz zj_a`#Re&#GsP+|pL_vk`LjqU5*nMHrH(5iXL{#BCbU)uX;dnmKQZQ4qcE4&UOf znb)Q*_%i$ttf2UB?D@P@+KwGyq@KMHy=A?In8`ZO0L(>(Zpm*NJlQg7SDrKZUE7B^ zxME@Xg!^8%SeTZVOSbsb?=vqIsa^@68jl+?9){Rac1ZUZ;gYty!t z>o|GIpWf^`^o~prr#SXls7rU{+>z+Zyw)gMRz0`D{i9RgvFwp(clgE7>T0)+CWrw~kJ)64B@5TT+g{|cTa7M1H{_7Z{*_J`v95|Fv4QWFJYd@3-O z^UQzu;Xqa`wt0EbMF&XvBjMa{sVfI9ee$K;VZrVT2eD@6(VI<{lN!jDdyCpcm_yvX zV6tFV5euDJWVPn|T2B(q-+GDJ*25{nf)^Fu9S_C2FDx#<@~4$N|=CN}fGKV=@%!p<>9pzy&w zVUfMgCk$qhCBs;St@>XHt_dt|=|B8MH_*?>-LDN>0<`~nX1AEXB>bON;8_-d`Z40` zJAwD|jm9kT+-6MJy^OgC;k+D44y0h3sp1`GIU1yvL-$jX&+LaE<*TqCHq|%xn&EF$ zKQB?RXj9?DB!!!rFUw#fN2ysD4}P{k*5SqRzNLDj0q1Q~`qc?T+EA6@w@c3Fd0si% zNuFAtp+*78fbVSeXnUq9v(=8-wGlKjPs}|(yH?o*R?oeJoydlgd93Rjbn~^qIo1(F zW9h!fe({bpeeSMPW+bJo?mPe7x9q~qwxEqW?lhuLAUop+e@n5)Nj>QcZF|~L z${oicAM6cyyx4-ewjce-*dRlvUBq3i+ai2khlXa|1AET=y%3qxMo5KlG>m8GgO5&FRyOQkSJ*aC%{47Sn zs?zRX*a}w%z*gq^UcaWB{JU)1M*@XqN#i!+zKz6^c6u`slFPaY*YuAZaCj~Hb?4judi zD~gGmt=vBhtHI7>hu%&V4}ByA;;Pr^g6}-uA{P)u)qyVi;drO8 z2QNBUFg(%FNh-RpR9yoniW14x0EUbiG zMN10DIK|RB;NNTkd1EGMWwrj4@x$&5=By+@a-`y%cISb71O4HCel_3;TzwAh3%+1x z-c_j7mx9-R4z<>M(kKFK6Mq?{GrFjEcGmD^>n&a9SC`yZ?212!f??sz5DRB(K-&xt zfNWm#2MOu28%XZD*G)Q7dhhpaG0#9Hawh!&E}v5>xY9~6TQADmS$~2A8|B|M9%h1u z;TCy7?F(qcKC|DEoPD&?-6Y2wxR0{1Fv=EGkaj#(26B{cb)eXxw;&+{*9vX5D z?(q(!mt<7l(z|?Ju79erq2)h4T4OL;{AC$^q_5%Jclw@i`l3uu*+{v@(1tUCVxw8- zoj2foGrsJW4CmI!48*ASFfNbHZgXp()QiX%uWr+d|K)AIQ6B{2mA2jEb7UR;*@5~r zX!}y`(sO(PT5G}jd>hc8ICxf+u>4L6ILT&;>Bq^+#$h4gUQ23Km;txfMPwR<;fQ25cp!OX(rO~run^}JDQD}X zxu*FGuHs@c(_n(?_AB58+_Xl2QHN1wSZWNSrSW$Ond|WB2F8xpw)+;d)iuhp&3;In zdXuS{hR2-&`aC>_pvLUzfjTtvC#DEbv!WXf8H(~~Hi+9Y#wxkpTWUy-CjSoeK^UCO zk>iN6=8>*IPWr>kyf*x?|lQHzy_>D%OD{r;xXWGVu?6 zcGab*IZ_Y+=oAFBM=S0KnEYe$Z3~nQZRyt?_$U-_B@o}h@i7)g@B;p!+h-GAG|c#_ z-DewU@42V!A^Ar?kG`Z@aAiVktEn9^R_-=V`#kMW3nO%4;=osN)|F)*@7v447FJIFhC4^+e~|(jetX8;@x ziTy9talbQ|2MYbCpg1{XjlURU`j88*T>bN7TO;sGvnw(K!V}*JjZuS#VrCe`Zf9*I zRu0I|1Ni^`rWbq4QrmI7`DgonsNAm+#6;SRdHr`2aeFP#7ny+Hug&6uI=KMZ@MA_# zk29u8$D(;qsCw+{bei6Na>?Db3VuvEJ>j<8KuPt`umMpG2c-OaR}m1mj! zt~PrZ;aEw4VJsr2Q1e|xV!cY2_p_~Ys?E}S?x>anc`)ky*S6KJpH~!}aAuA(c&|-K zVHUg`ftHXwY~Ewq=GWIi(#5)lm6Db+-f5+#yOU2eU~O@_$(5HQQTRe?iiPd~M^r~% zeT=O;Qyi~q!`$Bu&8n4M-%a+ulPpHL`r~RIvLLyli%|RCC}qRN*6wJSe+7WC$=ZQi zRM+K}m23^rwF2iUd|WJ#hT3#(DNSYD(NS|Hx!UL>dQ*HQyknJbTfXMHfi*R|c8Q|~ zfVn*puu!+&;&@(ekz!-vH+Z<_2IV4FNQ388yp-P^T5U8FGbg`GMweH&x~}C_&8m+{ zH;iN@oh9aAgh)>6MRd-?Vp(MhNNr+DL%+!v_H!P!C~`3FL47Ne-;f8wunerBgW^Y* zuPLlIsLeS%I0;+la`w)d3{b~cVMTI!-@w;{srq{S5>MNy;t`shd`bS7wLXnl{{8~d zQ;1!3Q7OZ7j>EKMZCk%h?|Ytm4VUTqJn=~Y^XD+ z7u@n;XpR8OgXQu>E1I~bJd9FAK3Cwwkq4Caie9=0fLEb4?TKgj_!V0XPc`eXj8G64 zi#&#$huxE4P6T>Bujp=M4J)ZiZ`fVY>((4^I{SVcq{?}XO z`Q&4Vy?-a4dS3%yk-9)9cW2=AzJh<*>N{e?;K@#a*?{mZGF-SS(ElD*??%VfISGtn zGKKBRz&eZB)^!ls%f#G}o=<|07;$glWAfcA;*UR5RI;{CMBUyTDl<+ub&65Se-Ko) z%l2~0^A%aW!Y#~$)y=eJ5H-Jwpx{iME5;@4A&NX{^T)gwb)hH|0^8x>-!)+Oi~LsJ ztzBnN^}-@Ee$S?XTtTx|vmEEy#!uNgvlL6m`6NPUk|-(0 z4q@@~p$8aro} z0#FV7`nN6U5r&Ik#M}ifWstI8wnK>u*BUcVk=5pS0YNX14(gso6tocby)#>M22j|r zZE2Rf zGaD!yr({r()HdTIQRf0fz!b^kv_>`$mag(S2Ba#XQiTPy$S6fp32uh*wCp+fRObGz z8}vGEpplm~<`zR%Rs2u~_%V6R5&~YL$8g z5=d#)oMl2KPqH>x!SgsG^&QR_EQQOCCo=B5B>Po6EFRk&1mqba_agP_rx`Wy3KM;r}>d@ILuECue)>~zgM;d^&H`UuzqLq^5aXrI;{0>WmKee zQM(e$EYdO9-LO^X^{T(mJF-`ESCc=}9O9Dvzv3JjDcoG9>=|k?RgeBjP1;r{*xSCx z5YKBCwMMy{2YP-W8)$f{#40O>REfu{N`+3te+*95>qBW#$dV+Y8`~ANsB6&Mp1#GAL!? zsK~EqLFoHiGPGhYf5{?e$%R96lg0^*` zo&dk9HZ5TgqRWnE#SS@+D@s%!dLLzgQb5#Li**y=iXyNk4YNchUSQ>}goe32t$x1a z|9}KCaeUs623?3jMloPLf2B}`LQGyn3ru5$E+0XKggF|yk2)+-iZpbXT?R9zgHxO= zN)nX}Q)D-$7h$$(!=$#wA?WEhdP&uUaV#e41$YPPMd1F*t3T=tu*?+*Bs!_tLX_A4fZl8h)+dbX|X|xPg z+le@H?2LwqSL3aQEFJZNVmkU>#cAkdF}B{SMm6siHPUTmK6(SAn#MZ;McYawP%B=y^lWk;+ zmxWtCmK0s$K~$`_ORc;-h{(B%Xq7icqZRNho+j8|z>?TO7-14DH!P1uA>k>LI$D=r zFN2kwTVY5)9%J!U83ofA2Ozs@ZG2_fW$p;t0cvMjOLV?f^UA-}Ovvm`%j<E z)anovMLOJ%oD*pgEXw__lQt1e5aYSXH#-AB8Q3)|g=-r$yzpyL0M^uT*!He?4r^c= zvtYb5#5W;|E*I94>2cY~F33845gBH@powM%hLxpQ(BE+UPb}y-^!7WwngRHHaxr8G zLbT+AvviLtWO45A7tOG_589H50i_dQZek6#v9&U3MkjavE4Gz;J;Z@!krXGT5>=H~T zT7=NViq6bBTd^e(X_MAH)r^teQAtv|D71uPbJw<;pl`yBphejk*!*L>Lo2dM&)QH@ zL$&ETmuNkJdBhv5hmRQyE@L_~*+o!*lw%bmjd($d%HEv}zN+O4+>B*x2%r}We*SYeyM&ctV+RaZTjx(F$Cr=Fj=1&-j$*_a^tB zK=)W5b8B-RS+v>3F==h`?1w(jJM8vm*Qwa5u93S2KEZ4!@nR?PZ^>w z7>LX-_IlFvPdT`_hB-7ju+d~0+5a{a^;9x`Ijk5Sm*y5SPxnik78yAHg43^_^;m+a zqmUJk+L=cm37DuOh6l(~T_3jTJlKQ>GzPd$cHva>&(+Lr6AXr{yV~dFOE9HJDz_qL z$I?DG`~>ImJgDZBdpKC+H(jq`n}i(2#MfDiX~L*ZMgN)7o+_JJg9+!tb}XQ2HkSW#wUzAS+tsks45*R9AL)qQ600(o(3k`;?gZ6_mLP zufCd-6vvTEyd^4>(@y&K_$mGe^eg-rH`oygvz4SCA$s!{@f1;@tKnb*Sf2Uc%->)V;Pe=7lYI~m3M4*_%G zB0>XtY;c(?hVfQ_V5RD!bMOq|5)S-qpw!d;@fIe~5iDfn`#2B&xzv4zb^qY)+PyIK zf3sD>)(~bfQ}>^xEW*v(+^Hlw={cM-KT?eaI2#_dIP05{_T|#6E9D&@gt9g0Ba-#2 z&+E9d zb^3W}?0J66X(g)jjSK)m?g-U5ddJ414stt^o%R}qbP2^RdxASVWQTOR7(cQwp zVUfQM0Lnb3x#)5$q?tqSBGHp8`%}!ZYv)U0_(DOHG9?|W;elm|j<2}h9%xlaNJGO8 zUuj*Xbz>u?4AN4FrjzH1HSQf8rKCHJ06!omGSy1=E5}~)L+0w9)?WtgmfpK2maKUH zG#VbcR^Xk<`D0_ZSo#|tm}Lh|;Jds8^8qJz&|%jlnV@c+j8zDsqc0vNA2Mc{@y@5D z43J3G2J1X&XYCc6=6Aj3ijX)ECf*^|4L|~v?W_U=tFwO34|s&Z<WzqV!4UOM5(z@NHAy`Dxt*${eNC^9tzKnT!r!kqkS_ zXxI<6VE)tpZYeP~Ni8MhpUmM_FO3#8%0Kt`Cuyf0<^JgM z@|qRh-Cyqi94B^0mbi+4;a*F)igfzJ>RO|6dE}>LvJY=GGPTOh^J^4G3Y(Z@9H%~M z@VPN-ppOBxz#kVB0H|tl=I_yTfBI?PFgGB~3Xoag1`svWlv!ni$eOZ> z*QZeCIQYP+gC7MGu!*rOL>c6U%m;R^NFzjXMR;{R3y<=SeBQhpf8<4;g-0;7kgpts z!-R&xu>brbb?-gl_S_#J_!4@~Pcher=E^`g37~mEc%%|9)XB9Pj1~3yIDWnL&m>Z) z<{Lez&`Z3(8akZZA`d-g@RJlv{Jwt!C}=WSx3sOiKPT&}BR=jgI-)}KA@;!K@VilX z=LEQ+z|oh1O&$J?`KiNvzvC>?aV2YK+S6LZf#9l*tIOm7ub-tnW(;^}^^~pd4LqUy z8kOiW$8&UQ1o6$4U}iazLlMTLM35#9rUxhCGd9F9XE3)j^85F@-t(7#=;8u}6n17p z>3>`Nlp+2vuBflQZbfp;lhH-^nb_^}LB<`3Xo+|DH;5{%(+vpBZxz3w??}rjM@Hpr z_D7RSIFpW44}3%7aUo-Nm!H2_jJL2ODabX8E>H}$*VqEvl?Hh(M{P+eW^_BPI_br$ z9(~Gr^TjPt{i7z3h<$v)**)@8#4s=JB$UT*j@UdrT(UaxtzE!R<*b4$^6so7JP|X? zG3RU8F0qL5ZdXxQU{vW7^@#5#hzrv$a=_Z-{C6E%KsaI<#5}^}Y#;Uxi<;mb*Ak=0 z^xwL-0F{IJ&383VomJq5yaxp8V$Ek(%grlI;EHu_AgLr67VQV)=p*5Hgp@c#=CIzi zUxo45uA$`x{_FOrFvL(<@t>}0UR@J)&tzRceyq*_`gYbK&z3>xQFB+$lQ z&-}r*btDzhjTpoy2flLX9&-MA>)QCAXF#hXxaQWJn=}g$htdAb@t5i%h?)rKlUy;Z zM8i8J!Xb{8XQ2}5Ey{qd_hD9#)cU~T42)oYJ(G27)0SHXy&v6 zM&F?#Qp2xR%)l}~Fjrn(EHek5!|F4FEq7qgtlvi^Z)1|KO=d_BA}|Km8frnmY0-D) z^dekCVX)HX$fa9#*){=j934N!8_2byOb6)qUdN}><2Gf4toa425+h^;pRm~m`^o=1 zS%}){nzu`pKh9FoZXqmx2HC8%>D#LgS{FqA5>Tv|*ciZ2nT>Sa0Aohed8IPvhBF2>-7KkI-4G z>@CMz#cm!2aIW?6gp_plrO-D=1JtJHShOX(ufp11mzmXDHX{BMeS zN512;cg%rNnHI59+CnnlJS0+cbs=-{F1|^xmx{1*HXC3uUG%Y z!cg^DPPm>Gc60h4)Cj&&{UpAjRl@J-J{JL8JUp&ibPzqa%ca5YO+8r1cjp>?C_vTa zaG??p|4p+bw|9R=ssi9yKIdN*fjq-!x>PX`J>AwPQA%twz(rh!@Wo^Kmt^phmx&Vr z(R)KKp$1FP4|iuIO!|yO0RgUJ=r@?tMjc=4d5RC@B~6}XiY2KBRi%$#cYfMp=hFpO zvW5NoN1h7*eGtMpSd?tt$txTvZ|=LdZ0tv>s?}Ls0+o_UlBVfihuXr25Akt*h(0$u zWtU``>oFmkv((@KA{N1(`*aol?({?&X;EcL(l?^10IM9OI|&0a{hRX zh%gzB<$4w<0hI1DOIIM8b*c`uN0`MqK;*}=c=hxTGx8m4=s>>#wu$M4sl!ZSRMigt z`R}GiDkCu9P%m(0QSi+WBwf8!62^Mld`q