4;){const e=t.findIndex(t=>!t.live);if(e<0)break;clearTimeout(t[e].evict),t.splice(e,1)}}_warmScheduleEvict(t,e){if(clearTimeout(t.evict),!(t.dlg||t.vp&&"view"!==t.vp.mode))return;const i=t.freed,s=t.owner;t.evict=window.setTimeout(()=>{if(t.evict=0,t.freed!==i||t.owner!==s)return;var n;t.dlg=null,t.vp=(n=t.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,t.frameFingerprint="";const o=n_.get(e);if(!t.live&&o&&o.length>1){const e=o.indexOf(t);e>=0&&o.splice(e,1)}},r_+250)}_warmAdoptViewport(t){const e=this._warmVp;if(!e||this._warmSlot?.path!==location.pathname)return void(this._warmVp=null);if(this._hashApplied||!this._model.find(t=>t.id===e.space))return void(this._warmVp=null);this._space=e.space,this._navApplied=!0,this._adoptMode("view"!==e.mode&&this._canEdit&&!t.kiosk?e.mode:"view"),this._pendingNavMode="view"===e.mode||this._canEdit||t.kiosk?null:e.mode,this._zoom=e.zoom;const i=this._effectiveProjection(),s=i===e.projection&&this._labsIso===e.activeLabsIso;if(this._view=s&&e.view?{...e.view}:null,this._viewModeSnap=s&&e.snap?{...e.snap}:null,!s&&e.logicalCenter){const t="iso"===i?Mp([e.logicalCenter.x,e.logicalCenter.y],0):[e.logicalCenter.x,e.logicalCenter.y];this._applyView(e.zoom,t[0],t[1])}var n;this._tool="openwall"===(n=e.tool)||"closewall"===n?"boundary":"opening"===(n=function(t){return"partition"===t?"draw":t}(n))?"draw":"string"==typeof n&&f_.has(n)?n:"draw",this._decorTool=e.decorTool,this._showHidden=e.showHidden,this._showFar!==e.showFar&&(this._showFar=e.showFar,this._frame=null),this._selId=e.selId,this._rszSel=e.rszSel,this._decorSel=e.decorSel,this._warmVpArmed=!0}_warmPatch(t,e=!1){if(this._config?.kiosk)return;const i=a_(this._config);if(!this._warmSlot||this._warmKey===i){if(!this._warmSlot){if(!e)return;const t=this.parentNode;this._warmKey=i,this._warmSlot={owner:this._warmGen,path:location.pathname,place:t?new WeakRef(t):null,idx:this._warmIdx(t),live:!0,hdrH:this._hdrH,stageH:0,vp:null,frameFingerprint:"",devices:null,dlg:null,freed:0,evict:0};const s=n_.get(i)||[];for(s.push(this._warmSlot),n_.set(i,s),this._warmTrim(s);n_.size>8;){const t=n_.keys().next().value;if(void 0===t||t===i)break;for(const e of n_.get(t)||[])clearTimeout(e.evict);n_.delete(t)}}Object.assign(this._warmSlot,t)}}_warmViewportState(){const t=this._effectiveProjection();return{space:this._space,mode:this._mode,projection:t,activeLabsIso:this._labsIso,logicalCenter:this._logicalViewCenter(t),zoom:this._zoom,view:this._view?{...this._view}:null,snap:this._viewModeSnap?{...this._viewModeSnap}:null,tool:this._tool,decorTool:this._decorTool,showHidden:this._showHidden,showFar:this._showFar,selId:this._selId,rszSel:this._rszSel,decorSel:this._decorSel}}_warmDialogState(){const t=(t,e)=>({kind:t,space:this._space,mode:this._mode,data:e});return this._tapConfirm||this._alignDialog||this._mergeDialog||this._importDialog||this._backupExportDialog||this._backupImportDialog?null:this._openingInfo?t("openingInfo",this._openingInfo.id):this._infoCard?t("info",this._infoCard.id):this._rulesDialog?this._rulesDialog.busy?null:t("rules",this._rulesDialog):this._settingsDialog?this._settingsDialog.busy?null:t("settings",this._settingsDialog):this._markerDialog?this._markerDialog.busy?null:t("marker",this._markerDialog):this._openingDialog?t("opening",this._openingDialog):this._backdropDialog?t("backdrop",this._backdropDialog):this._decorShapeDialog?t("decorShape",this._decorShapeDialog):this._decorTextDialog?t("decorText",this._decorTextDialog):this._roomDialog?t("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:t("space",this._spaceDialog):null}_warmSnapshot(){if(this._booting||this._config?.kiosk||"steady"!==this._continuity.state)return;const t={vp:this._warmViewportState(),frameFingerprint:this._continuity.frameFingerprint,devices:this._devices};if(this._warmRevivePending||(t.dlg=this._warmDialogState()),this.isConnected&&this._warmSlot?.owner===this._warmGen){const e=this.parentNode;t.place=e?new WeakRef(e):null,t.idx=this._warmIdx(e)}this._warmPatch(t)}_warmReviveDialog(){this._warmRevivePending=!1;const t=this._warmSlot;if(this._warmReviveTimer=void 0,!t||!t.dlg)return;const e=t.dlg,i=t.freed;if(t.dlg=null,t.freed=0,clearTimeout(t.evict),t.evict=0,i&&!(Date.now()-i>r_)&&e.space===this._space&&e.mode===this._mode){switch(e.kind){case"space":this._spaceDialog={...e.data,busy:!1,savedBusy:!1};break;case"marker":this._markerDialog={...e.data,busy:!1};break;case"settings":this._settingsDialog={...e.data,busy:!1};break;case"rules":this._rulesDialog={...e.data,busy:!1};break;case"opening":this._openingDialog={...e.data};break;case"backdrop":this._backdropDialog={...e.data};break;case"decorShape":this._decorShapeDialog={...e.data};break;case"decorText":{this._decorTextDialog={...e.data};const t=String(this._decorTextDialog?.text??"").length;this._decorTextSelection={start:t,end:t};break}case"room":{const t=e.data;this._roomEditId=t.editId,this._roomFill=t.fill,this._roomCustomFill=t.customFill||null,this._roomTempSrc=t.tempSrc,this._roomHumSrc=t.humSrc,this._roomSrcOpen=t.srcOpen,this._roomSrcFilter=t.srcFilter,this._roomNameScale=t.nameScale,this._roomLabelScale=t.labelScale,this._areaSel=t.areaSel,this._nameSel=t.nameSel,this._pendingSplit=t.pendingSplit,this._wallFaceBatch=t.wallFaceBatch||null,this._path=t.path,this._wallFaceBatch&&(this._activeDraftId=this._wallFaceBatch.activeDraftId,this._draftSegmentCms=[...this._wallFaceBatch.activeCms]),this._roomDialog=!0;break}case"info":{const t=this._devices.find(t=>t.id===e.data);t&&(this._infoCard=t);break}case"openingInfo":{const t=(this._curSpaceCfg?.openings||[]).find(t=>t.id===e.data);t&&(this._openingInfo=t);break}}this.requestUpdate()}}_cacheSnapshot(){if(this._serverCfg)try{this._cfgContentFingerprint=eh(this._serverCfg),this._layoutContentFingerprint=eh(this._layout),this._virtualLights=function(t,e,i){if(t.configRev===i)return t;const s=new Set((Array.isArray(e?.markers)?e.markers:[]).filter(yn).map(t=>t.id));return{...t,configRev:i,off:new Set([...t.off].filter(t=>s.has(t)))}}(this._virtualLights,this._serverCfg,this._cfgRev),localStorage.setItem(c_,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(t,e,i="plan"){return this._booting&&!this._continuity.hasCompleteFrame?this._continuity.token:(this._continuityDataReady=e,this._continuityPaintToken=-1,this._stagedDeviceSnapshotToken=-1,this._resumeSettling=!0,this._continuity.beginCandidate(t,i))}_continuityStageValid(){const t=this._stageEl;return!!t&&t.clientWidth>0&&t.clientHeight>0}_continuityAssetsReady(){if(!this._model.length)return!1;const t=this._model.length?this._spaceModel():null;return!t?.bg?.href||this._signer.isReady(this.hass,t.bg.href)}_initialSpaceSelection(t){return function(t){const e=new Set(t.spaceIds.filter(t=>!!t));if(!e.size)return{id:null,source:"none"};const i=[["hash",!1===t.acceptHash?null:t.hashSpace],["current",t.preserveCurrent?t.currentSpace:null],["saved",t.savedSpace],["default",t.defaultSpace],["first",t.spaceIds[0]]];for(const[t,s]of i)if(s&&e.has(s))return{id:s,source:t};return{id:null,source:"none"}}({spaceIds:t.map(t=>t.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(t){const e=this._initialSpaceSelection(t);return e.id?(this._space=e.id,"hash"===e.source&&(this._hashApplied=!0),"saved"===e.source&&(this._navApplied=!0),e):e}_candidateBackdrop(t,e=this._space){const i=Gl(t),s=this._initialSpaceSelection(i).id||(i.some(t=>t.id===e)?e:i[0]?.id);return i.find(t=>t.id===s)?.bg?.href||""}_visualFrameFingerprint(){const t=this._stageEl,e=t?[t.clientWidth,t.clientHeight]:[0,0];return ih([this._cfgRev,this._cfgContentFingerprint||eh(this._serverCfg),this._layoutRev,this._layoutContentFingerprint||eh(this._layout),this._space,this._mode,this._view,e,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 t=this._continuity.token;if(this._candidateDeviceSnapshot&&this._candidateDeviceSnapshot!==this._visibleDeviceSnapshot&&this._stagedDeviceSnapshotToken!==t)return this._stagedDeviceSnapshotToken=t,void this.requestUpdate();this._continuityPaintToken!==t&&(this._continuityPaintToken=t,this._continuity.candidateReady(t)&&this._continuity.commitAfterPaint(t,{updateComplete:()=>this.updateComplete,stageValid:()=>this.isConnected&&this._continuityStageValid(),assetsReady:()=>this._continuityAssetsReady(),frameFingerprint:()=>this._visualFrameFingerprint()}).then(e=>{e&&t===this._continuity.token?(this._resumeSettling=!1,this._renderSnapshotAt=Date.now(),this._candidateDeviceSnapshot&&(this._visibleDeviceSnapshot=this._candidateDeviceSnapshot),this._candidateDeviceSnapshot=null,this._stagedDeviceSnapshotToken=-1,this._warmSnapshot()):t===this._continuity.token&&(this._continuityPaintToken=-1,this._stagedDeviceSnapshotToken=-1,this._candidateDeviceSnapshot=null,this.requestUpdate())}))}_onBackdropLoaded(t,e){this._signer.markLoaded(this.hass,t,e),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 t="connection"===this._continuity.recoveryReason;return W`t.stopPropagation()}
@click=${t=>t.stopPropagation()}
diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md
index 8c13d815..0b864b06 100644
--- a/docs/CHANGELOG.md
+++ b/docs/CHANGELOG.md
@@ -1,6 +1,6 @@
# Changelog
-## v1.65.0-beta.2 — 2026-08-18
+## v1.65.0-beta.3 — 2026-08-19
- Editor color controls now open a single House Plan picker with saturation,
brightness, hue, exact HEX and opacity together. The nested browser color
@@ -11,6 +11,33 @@
unavailable targets separately, while confirmation still re-resolves the
live state and cancels if the target set changed
([#103](https://github.com/Matysh/houseplan-card/issues/103)).
+- Doors, windows, gates and open passages can now be placed in finished
+ independent Walls segments. They cut the full wall depth, move with their
+ host, keep the same Home Assistant state/actions as room-wall openings and
+ are removed only through an explicit cascade confirmation. Openings no
+ longer break the structural wall axis, so drawing a closed contour still
+ offers the room even when one of its walls already contains an opening.
+ Space backups preserve the opening-to-wall binding when imported, while the
+ editor's visual snap guide keeps its physical gap across the opening
+ ([#132](https://github.com/Matysh/houseplan-card/issues/132),
+ [#185](https://github.com/Matysh/houseplan-card/issues/185)).
+- Door, window and gate contacts and locks now keep working when they are live
+ YAML entities without a `unique_id` and therefore have no Entity Registry
+ row. The picker, View animation, lock badge and opening info card now follow
+ the same exact reference, while disabled, orphaned and missing entities
+ remain unavailable ([#117](https://github.com/Matysh/houseplan-card/issues/117)).
+- Glow now remains fail-dark if wall boolean geometry cannot be built: a light
+ source inside a partition-hosted window or exterior opening stays suppressed,
+ while valid interior passages remain transparent
+ ([#187](https://github.com/Matysh/houseplan-card/issues/187)).
+- The Plan editor's snap guide now leaves a real gap across openings hosted by
+ independent Walls segments, so hover and clicks inside a door, window, gate
+ or passage no longer snap to wall material that is not there
+ ([#189](https://github.com/Matysh/houseplan-card/issues/189)).
+- Small fixes and improvements.
+
+## v1.65.0-beta.2 — 2026-08-18
+
- Composite Home Assistant devices with several light/switch entities now let
you choose the exact entity operated by **Toggle state**. The dialog previews
the selected target immediately, preserves missing choices with a warning,
@@ -28,24 +55,6 @@
Create/Keep/Cancel decisions. Ctrl/Cmd+click no longer adds an extra point
while the chain is still too short to close
([#173](https://github.com/Matysh/houseplan-card/issues/173)).
-- Doors, windows, gates and open passages can now be placed in finished
- independent Walls segments. They cut the full wall depth, move with their
- host, keep the same Home Assistant state/actions as room-wall openings and
- are removed only through an explicit cascade confirmation. Openings no
- longer break the structural wall axis, so drawing a closed contour still
- offers the room even when one of its walls already contains an opening.
- Space backups preserve the opening-to-wall binding when imported, while the
- editor's visual snap guide keeps its physical gap across the opening
- ([#132](https://github.com/Matysh/houseplan-card/issues/132),
- [#185](https://github.com/Matysh/houseplan-card/issues/185)).
-- Glow now remains fail-dark if wall boolean geometry cannot be built: a light
- source inside a partition-hosted window or exterior opening stays suppressed,
- while valid interior passages remain transparent
- ([#187](https://github.com/Matysh/houseplan-card/issues/187)).
-- The Plan editor's snap guide now leaves a real gap across openings hosted by
- independent Walls segments, so hover and clicks inside a door, window, gate
- or passage no longer snap to wall material that is not there
- ([#189](https://github.com/Matysh/houseplan-card/issues/189)).
- Collinear exterior walls now change thickness exactly at their saved
breakpoint. After splitting a room, a 10 cm wall therefore keeps its full
depth up to the divider without leaking onto an adjacent zero-thickness
@@ -86,12 +95,6 @@
([#166](https://github.com/Matysh/houseplan-card/issues/166)).
- Small fixes and improvements.
-- Door, window and gate contacts and locks now keep working when they are live
- YAML entities without a `unique_id` and therefore have no Entity Registry
- row. The picker, View animation, lock badge and opening info card now follow
- the same exact reference, while disabled, orphaned and missing entities
- remain unavailable ([#117](https://github.com/Matysh/houseplan-card/issues/117)).
-
## v1.64.0-beta.3 — 2026-08-14
- Large plans no longer recompute an unused physical-wall union on every floor
diff --git a/docs/CHANGELOG.ru.md b/docs/CHANGELOG.ru.md
index 2c84be39..cad4c7cb 100755
--- a/docs/CHANGELOG.ru.md
+++ b/docs/CHANGELOG.ru.md
@@ -6,7 +6,7 @@
> **Правило проекта:** оба файла пополняются в одном коммите с самим
> изменением — как и остальная документация (см. docs/STATUS.md).
-## v1.65.0-beta.2 — 2026-08-18
+## v1.65.0-beta.3 — 2026-08-19
- Выбор цвета в редакторах теперь сразу открывает единую палитру House Plan с
насыщенностью, яркостью, оттенком, точным HEX и прозрачностью. Вложенный
@@ -18,6 +18,34 @@
включённых целей и недоступные цели; перед выполнением состояние по-прежнему
вычисляется заново, а смена набора целей отменяет команду
([#103](https://github.com/Matysh/houseplan-card/issues/103)).
+- Дверь, окно, ворота и открытый проём теперь можно поставить в законченный
+ независимый отрезок «Стен». Проём прорезает его на всю глубину, движется
+ вместе со своей стеной, сохраняет обычные состояния и действия Home
+ Assistant, а при удалении стены удаляется только после отдельного
+ подтверждения. Проём больше не разрывает структурную ось стены: замкнутый
+ контур предлагает создать комнату, даже если в одной из стен уже есть проём.
+ Импорт резервной копии этажа сохраняет привязку проёма к стене, а визуальная
+ направляющая привязки по-прежнему показывает физический разрыв в месте проёма
+ ([#132](https://github.com/Matysh/houseplan-card/issues/132),
+ [#185](https://github.com/Matysh/houseplan-card/issues/185)).
+- Датчики и замки дверей, окон и ворот теперь работают и для живых
+ YAML-сущностей без `unique_id`, у которых поэтому нет строки в Entity
+ Registry. Список выбора, анимация в Просмотре, значок замка и карточка проёма
+ используют одну точную ссылку; отключённые, потерянные и отсутствующие
+ сущности по-прежнему недоступны
+ ([#117](https://github.com/Matysh/houseplan-card/issues/117)).
+- Glow теперь остаётся непрозрачным при сбое построения объединённой геометрии
+ стен: источник света внутри окна или внешнего проёма в независимой стене
+ подавляется, а корректный внутренний проход по-прежнему пропускает свет
+ ([#187](https://github.com/Matysh/houseplan-card/issues/187)).
+- Визуальная направляющая привязки в редакторе Плана теперь сохраняет реальный
+ разрыв в проёме независимого отрезка «Стены»: ховер и клик внутри двери,
+ окна, ворот или прохода больше не привязываются к отсутствующей кладке
+ ([#189](https://github.com/Matysh/houseplan-card/issues/189)).
+- Мелкие исправления и улучшения.
+
+## v1.65.0-beta.2 — 2026-08-18
+
- У составных устройств Home Assistant с несколькими сущностями света/реле
теперь можно выбрать точную сущность для действия **«Переключить состояние»**.
Диалог сразу показывает новую цель, сохраняет пропавший выбор с
@@ -37,24 +65,6 @@
Create/«Оставить стенами»/Cancel применяются атомарно. Ctrl/Cmd+клик не
добавляет лишнюю точку, пока для замыкания ещё недостаточно рёбер
([#173](https://github.com/Matysh/houseplan-card/issues/173)).
-- Дверь, окно, ворота и открытый проём теперь можно поставить в законченный
- независимый отрезок «Стен». Проём прорезает его на всю глубину, движется
- вместе со своей стеной, сохраняет обычные состояния и действия Home
- Assistant, а при удалении стены удаляется только после отдельного
- подтверждения. Проём больше не разрывает структурную ось стены: замкнутый
- контур предлагает создать комнату, даже если в одной из стен уже есть проём.
- Импорт резервной копии этажа сохраняет привязку проёма к стене, а визуальная
- направляющая привязки по-прежнему показывает физический разрыв в месте проёма
- ([#132](https://github.com/Matysh/houseplan-card/issues/132),
- [#185](https://github.com/Matysh/houseplan-card/issues/185)).
-- Glow теперь остаётся непрозрачным при сбое построения объединённой геометрии
- стен: источник света внутри окна или внешнего проёма в независимой стене
- подавляется, а корректный внутренний проход по-прежнему пропускает свет
- ([#187](https://github.com/Matysh/houseplan-card/issues/187)).
-- Визуальная направляющая привязки в редакторе Плана теперь сохраняет реальный
- разрыв в проёме независимого отрезка «Стены»: ховер и клик внутри двери,
- окна, ворот или прохода больше не привязываются к отсутствующей кладке
- ([#189](https://github.com/Matysh/houseplan-card/issues/189)).
- Коллинеарные внешние стены теперь меняют толщину точно в сохранённой точке
перехода. После разделения комнаты стена 10 см сохраняет полную толщину до
перегородки и не продолжается по соседнему фасаду с нулевой толщиной; План,
@@ -98,13 +108,6 @@
([#166](https://github.com/Matysh/houseplan-card/issues/166)).
- Мелкие исправления и улучшения.
-- Датчики и замки дверей, окон и ворот теперь работают и для живых
- YAML-сущностей без `unique_id`, у которых поэтому нет строки в Entity
- Registry. Список выбора, анимация в Просмотре, значок замка и карточка проёма
- используют одну точную ссылку; отключённые, потерянные и отсутствующие
- сущности по-прежнему недоступны
- ([#117](https://github.com/Matysh/houseplan-card/issues/117)).
-
## v1.64.0-beta.3 — 2026-08-14
- Большие планы больше не пересчитывают неиспользуемое объединение физических
diff --git a/docs/RELEASE-NOTES.md b/docs/RELEASE-NOTES.md
index 92fc7a59..30fe0dfb 100644
--- a/docs/RELEASE-NOTES.md
+++ b/docs/RELEASE-NOTES.md
@@ -1,16 +1,18 @@
-
+
## Основное
-- Редактор Плана получил единый инструмент «Стены», открытые проёмы и исправленную геометрию стыков и переходов толщины.
-- Управление составными устройствами стало точнее: выбор сущности для переключения, связанные виртуальные источники и назначения комнат без HA-зон работают согласованно.
+- Двери, окна, ворота и открытые проёмы теперь можно размещать в независимых отрезках «Стен»; структурное замыкание комнат и физические разрывы привязки остаются согласованными.
+- Выбор цвета и прозрачности открывается одной палитрой House Plan, а подтверждение «Переключить состояние» показывает текущее и ожидаемое состояние.
+- YAML-сущности проёмов без `unique_id` теперь корректно работают в Просмотре, карточке проёма и действиях замка.
- Мелкие исправления и улучшения.
## Highlights
-- The Plan editor now has one Walls tool, open passages and corrected junction and thickness-transition geometry.
-- Composite-device control is more precise: exact toggle targets, linked virtual sources and room assignments without HA Areas now stay consistent.
+- Doors, windows, gates and open passages can now be placed in independent Walls segments, while structural room closure and physical snap gaps stay consistent.
+- Color and opacity now open in one House Plan picker, while **Toggle state** confirmation shows the current and expected state.
+- Opening YAML entities without a `unique_id` now work correctly in View, the opening card and lock actions.
- Small fixes and improvements.
-[Полный список изменений на русском](https://github.com/Matysh/houseplan-card/blob/v1.65.0-beta.2/docs/CHANGELOG.ru.md)
-· [Full changelog in English](https://github.com/Matysh/houseplan-card/blob/v1.65.0-beta.2/docs/CHANGELOG.md)
+[Полный список изменений на русском](https://github.com/Matysh/houseplan-card/blob/v1.65.0-beta.3/docs/CHANGELOG.ru.md)
+· [Full changelog in English](https://github.com/Matysh/houseplan-card/blob/v1.65.0-beta.3/docs/CHANGELOG.md)
diff --git a/docs/STATUS.md b/docs/STATUS.md
index 2ea6af62..2d7577bb 100644
--- a/docs/STATUS.md
+++ b/docs/STATUS.md
@@ -17,12 +17,12 @@ change must pass through a published beta/RC before stable. Stable release
commits are promotion-only (versions, generated bundles and release/changelog
metadata). Only an explicit owner-approved emergency hotfix may skip this gate.
-## Snapshot (2026-08-18)
+## Snapshot (2026-08-19)
| Item | State |
|---|---|
-| Version | **v1.65.0-beta.2** everywhere (manifest, const.py, package.json, CARD_VERSION) — prerelease candidate for the current `S8-merged` queue |
-| Current local cycle | v1.65.0-beta.2 candidate carries #150, #157, #170, #172, #173, #174 and #178: the Plan editor has one continuous Walls tool plus open passages and corrected wall-thickness junctions; room bindings without HA Areas, linked virtual sources and exact toggle targets now retain their intended ownership. Publication waits for a green exact-SHA Validate and fail-closed prerelease preflight; stable v1.64.0 remains unchanged. |
+| Version | **v1.65.0-beta.3** everywhere (manifest, const.py, package.json, CARD_VERSION) — prerelease candidate for the current `S8-merged` queue |
+| Current local cycle | v1.65.0-beta.3 candidate carries #57, #103, #113, #117, #132, #184, #185, #187 and #189: color and opacity share one picker, toggle confirmations expose their exact result, independent Walls support openings with consistent snap/light geometry, and registry-less opening entities stay operable. Stale space/model references now fail safely. Publication waits for a green exact-SHA Validate and fail-closed prerelease preflight; stable v1.64.0 remains unchanged. |
| Hidden Labs Stage | #89 Stage 1 ships in v1.63.0-beta.1. #122 Stage 2 ships in v1.64.0 and evolves the same hidden, expiring `iso` experiment with matte walls, a low exterior floor edge, restrained shared shadows and live vertical door/window/gate panels. Flat remains default; editors and `houseplan-space-card` remain flat; live floor effects and HA actions remain unchanged. Public activation remains a separate task. |
| Workflow | Superseded 2026-08-12: the pre-1.62 rule of "local edits without tests or commits" is **dead** — since release 1.62 every product change follows `PROCESS.md` (issue in `S5-ready`+, branch `issue/-slug`, trailers on every commit, review pipeline; `AGENTS.md` is the summary). Release mechanics below remain current. A requested pre-release gets a production build plus the smallest targeted unit/smoke set covering the changed surfaces, one tested `dev` commit/tag and a GitHub Release with `prerelease=true`; `main` stays untouched. The complete local frontend/backend/smoke gate runs only before a stable release, after which `main` is fast-forwarded to the exact tested `dev` SHA and the GitHub Release uses `prerelease=false`. Release bodies are short and bilingual (Russian first): only significant user changes get individual bullets, while minor/code-only work is grouped as `Мелкие исправления и улучшения` / `Small fixes and improvements`; every body ends with separate links to the Russian and English changelogs. Detailed RU/EN changelog bullets may link the corresponding closed GitHub Issues; open or partially delivered issues are never presented as shipped. Telegram announcements are sent only for stable releases; beta and RC publication is silent. `docs/RELEASE-NOTES.md` is the current canonical body instance; `npm run release:prerelease -- --issues=… --yes` is the primary local publication path and the manual `Publish prerelease` workflow is its GitHub-only equivalent once present on `main`. Nothing is copied to the home instance by hand |
| GitHub | https://github.com/Matysh/houseplan-card — [Issues](https://github.com/Matysh/houseplan-card/issues) are the canonical task records; their labels carry priority and workflow status (`PROCESS.md` §9). GitHub Projects is no longer used. `main` carries stable releases; pre-release tags may point directly at `dev`. Work lands on `dev` and is merged into `main` for a stable release, so `dev` is normally equal to or ahead of `main`, never behind. Push via SSH key `ha_jb` (remote git@github.com:…); API releases via the fine-grained PAT in `~/.git-credentials` (Contents R/W, issued 2026-07-23) |
diff --git a/docs/images/06-device-display-preview.png b/docs/images/06-device-display-preview.png
index eb845281..5d53977d 100644
Binary files a/docs/images/06-device-display-preview.png and b/docs/images/06-device-display-preview.png differ
diff --git a/docs/images/06-device-editor.png b/docs/images/06-device-editor.png
index fec6ef66..5910d291 100644
Binary files a/docs/images/06-device-editor.png and b/docs/images/06-device-editor.png differ
diff --git a/docs/images/screenshots.json b/docs/images/screenshots.json
index 9effdd8d..101d30b8 100644
--- a/docs/images/screenshots.json
+++ b/docs/images/screenshots.json
@@ -1,7 +1,7 @@
{
"version": 1,
"fixture": "synthetic-only",
- "sourceFingerprint": "b324ee6d7896c4c2aaef51f5681b4818a6ffae5d779bf9d38faaf85a0d998903",
+ "sourceFingerprint": "9cf7a16bbc4f0bde8ec29d7b58b52e0f616fc14601a183ea1df347477321a5da",
"captureScriptSha256": "34f2219790d46efd8250e7a1bd829cb8fc0b0547e1260635fefa52407551b41b",
"command": "npm run build && node demo/docs/capture.mjs",
"scenarios": {
@@ -13,7 +13,7 @@
},
"theme": "dark",
"language": "en",
- "sourceSha256": "b324ee6d7896c4c2aaef51f5681b4818a6ffae5d779bf9d38faaf85a0d998903",
+ "sourceSha256": "9cf7a16bbc4f0bde8ec29d7b58b52e0f616fc14601a183ea1df347477321a5da",
"imageSha256": "d36b6f9f8139f31ef73a780c6511a640a26055efd9d7a24c24fd48b1d8379bf0"
},
"view-touch": {
@@ -24,7 +24,7 @@
},
"theme": "dark",
"language": "en",
- "sourceSha256": "b324ee6d7896c4c2aaef51f5681b4818a6ffae5d779bf9d38faaf85a0d998903",
+ "sourceSha256": "9cf7a16bbc4f0bde8ec29d7b58b52e0f616fc14601a183ea1df347477321a5da",
"imageSha256": "358e25ff9984d0fb0c03cfbb848df40c425fdfe64cd5f4f613b1e754ca9d4249"
},
"space-create": {
@@ -35,7 +35,7 @@
},
"theme": "dark",
"language": "en",
- "sourceSha256": "b324ee6d7896c4c2aaef51f5681b4818a6ffae5d779bf9d38faaf85a0d998903",
+ "sourceSha256": "9cf7a16bbc4f0bde8ec29d7b58b52e0f616fc14601a183ea1df347477321a5da",
"imageSha256": "c53db2e5c642a5549c13f3c93a5b359fed69bdb2621bf71a243a877ffcb95e6b"
},
"room-contour-close": {
@@ -46,7 +46,7 @@
},
"theme": "dark",
"language": "en",
- "sourceSha256": "b324ee6d7896c4c2aaef51f5681b4818a6ffae5d779bf9d38faaf85a0d998903",
+ "sourceSha256": "9cf7a16bbc4f0bde8ec29d7b58b52e0f616fc14601a183ea1df347477321a5da",
"imageSha256": "5ca7f24642926072ccbc5bf48341c5310329918631b147c116f9c29e20e4927e"
},
"plan-context-tray": {
@@ -57,7 +57,7 @@
},
"theme": "dark",
"language": "en",
- "sourceSha256": "b324ee6d7896c4c2aaef51f5681b4818a6ffae5d779bf9d38faaf85a0d998903",
+ "sourceSha256": "9cf7a16bbc4f0bde8ec29d7b58b52e0f616fc14601a183ea1df347477321a5da",
"imageSha256": "164b79fd9075a1425cffe3c85c88b689dfda90b79856bb4ed6655507b166b3e0"
},
"device-editor": {
@@ -68,8 +68,8 @@
},
"theme": "dark",
"language": "en",
- "sourceSha256": "b324ee6d7896c4c2aaef51f5681b4818a6ffae5d779bf9d38faaf85a0d998903",
- "imageSha256": "7c3e25534fc819c45431907616c3d523961505859ee68af27cce2daec9f04fb0"
+ "sourceSha256": "9cf7a16bbc4f0bde8ec29d7b58b52e0f616fc14601a183ea1df347477321a5da",
+ "imageSha256": "7a22a81e2abedf5a520bd36b7509d953cbfa9962b48c0ffbc233666a6215c04b"
},
"device-display-preview": {
"file": "06-device-display-preview.png",
@@ -79,8 +79,8 @@
},
"theme": "dark",
"language": "en",
- "sourceSha256": "b324ee6d7896c4c2aaef51f5681b4818a6ffae5d779bf9d38faaf85a0d998903",
- "imageSha256": "f6014caed7b7d28790b8548996ba09d806a4e4d51fbb7e8d3fb3c582ebe49167"
+ "sourceSha256": "9cf7a16bbc4f0bde8ec29d7b58b52e0f616fc14601a183ea1df347477321a5da",
+ "imageSha256": "df3a54395c83bffd7a161f1fb3de0143e12e76567535aedf9883873ead74df91"
},
"background-editor": {
"file": "07-background-editor.png",
@@ -90,7 +90,7 @@
},
"theme": "dark",
"language": "en",
- "sourceSha256": "b324ee6d7896c4c2aaef51f5681b4818a6ffae5d779bf9d38faaf85a0d998903",
+ "sourceSha256": "9cf7a16bbc4f0bde8ec29d7b58b52e0f616fc14601a183ea1df347477321a5da",
"imageSha256": "d7cfe70551d9260169df8efd832e32ed7df99c7f60b55d1fd4a8322bd4c47175"
},
"room-card": {
@@ -101,7 +101,7 @@
},
"theme": "dark",
"language": "en",
- "sourceSha256": "b324ee6d7896c4c2aaef51f5681b4818a6ffae5d779bf9d38faaf85a0d998903",
+ "sourceSha256": "9cf7a16bbc4f0bde8ec29d7b58b52e0f616fc14601a183ea1df347477321a5da",
"imageSha256": "176abba71d41cfb045a33f82a794d9fbb2a5d3c48e6df66e6ec3a8e448311b11"
},
"device-info": {
@@ -112,7 +112,7 @@
},
"theme": "dark",
"language": "en",
- "sourceSha256": "b324ee6d7896c4c2aaef51f5681b4818a6ffae5d779bf9d38faaf85a0d998903",
+ "sourceSha256": "9cf7a16bbc4f0bde8ec29d7b58b52e0f616fc14601a183ea1df347477321a5da",
"imageSha256": "2199ed88b215bf2bff63bf665028f78b2aa6a92c3032b803931790f2ef071893"
}
}
diff --git a/package-lock.json b/package-lock.json
index 51d32eee..dfb7033a 100755
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,12 +1,12 @@
{
"name": "houseplan-card",
- "version": "1.65.0-beta.2",
+ "version": "1.65.0-beta.3",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "houseplan-card",
- "version": "1.65.0-beta.2",
+ "version": "1.65.0-beta.3",
"license": "MIT",
"dependencies": {
"lit": "^3.1.3",
diff --git a/package.json b/package.json
index d8670011..eca4c578 100755
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "houseplan-card",
- "version": "1.65.0-beta.2",
+ "version": "1.65.0-beta.3",
"description": "Interactive house plan Lovelace card for Home Assistant",
"license": "MIT",
"type": "module",
diff --git a/src/houseplan-card.ts b/src/houseplan-card.ts
index e7d5ddc9..e1d88610 100755
--- a/src/houseplan-card.ts
+++ b/src/houseplan-card.ts
@@ -254,7 +254,7 @@ import {
} from './opening-placement';
import { safeStoredColor } from './color';
-const CARD_VERSION = '1.65.0-beta.2';
+const CARD_VERSION = '1.65.0-beta.3';
const DISPLAY_LABEL_KEYS: Record = {
badge: 'display.badge',
icon_ripple: 'display.icon_ripple',