@bimetal/whiteboard-angular-components 0.34.0 → 0.36.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
1
  import { Component, Input, ViewChild, ElementRef, ChangeDetectionStrategy, NgZone, inject, signal, } from '@angular/core';
2
2
  import { CommonModule } from '@angular/common';
3
- import { screenToBoard, boardToScreen, WHITEBOARD_TOOLS, WHITEBOARD_ALIGN, WHITEBOARD_DISTRIBUTE, whiteboardConnectorPath, whiteboardDrawPath, whiteboardDashArray, whiteboardCommentAnchor, } from '@bimetal/whiteboard-headless';
3
+ import { screenToBoard, boardToScreen, WHITEBOARD_TOOLS, WHITEBOARD_ALIGN, WHITEBOARD_DISTRIBUTE, whiteboardConnectorPath, whiteboardDrawPath, whiteboardDashArray, whiteboardCommentAnchor, whiteboardShapeDomId, reportUnroutedWhiteboardError, } from '@bimetal/whiteboard-headless';
4
4
  import { createWhiteboardControllerBinding } from '@bimetal/angular';
5
5
  import { WhiteboardShapeComponent } from './WhiteboardShape.js';
6
6
  import { TransformHandlesComponent } from './TransformHandles.js';
@@ -13,195 +13,277 @@ import * as i1 from "@angular/common";
13
13
  const _c0 = ["viewportRef"];
14
14
  function WhiteboardComponent_button_2_Template(rf, ctx) { if (rf & 1) {
15
15
  const _r2 = i0.ɵɵgetCurrentView();
16
+ i0.ɵɵelementStart(0, "button", 31);
17
+ i0.ɵɵlistener("click", function WhiteboardComponent_button_2_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r2); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.onUndo()); });
18
+ i0.ɵɵtext(1, "\u21B6");
19
+ i0.ɵɵelementEnd();
20
+ } if (rf & 2) {
21
+ const ctx_r2 = i0.ɵɵnextContext();
22
+ i0.ɵɵproperty("disabled", !ctx_r2.snapshot.canUndo);
23
+ i0.ɵɵattribute("aria-label", ctx_r2.locale.undo)("title", ctx_r2.locale.undo);
24
+ } }
25
+ function WhiteboardComponent_button_3_Template(rf, ctx) { if (rf & 1) {
26
+ const _r4 = i0.ɵɵgetCurrentView();
27
+ i0.ɵɵelementStart(0, "button", 32);
28
+ i0.ɵɵlistener("click", function WhiteboardComponent_button_3_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r4); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.onRedo()); });
29
+ i0.ɵɵtext(1, "\u21B7");
30
+ i0.ɵɵelementEnd();
31
+ } if (rf & 2) {
32
+ const ctx_r2 = i0.ɵɵnextContext();
33
+ i0.ɵɵproperty("disabled", !ctx_r2.snapshot.canRedo);
34
+ i0.ɵɵattribute("aria-label", ctx_r2.locale.redo)("title", ctx_r2.locale.redo);
35
+ } }
36
+ function WhiteboardComponent_span_4_Template(rf, ctx) { if (rf & 1) {
37
+ i0.ɵɵelement(0, "span", 7);
38
+ } }
39
+ function WhiteboardComponent_button_5_Template(rf, ctx) { if (rf & 1) {
40
+ const _r5 = i0.ɵɵgetCurrentView();
16
41
  i0.ɵɵelementStart(0, "button", 33);
17
- i0.ɵɵlistener("click", function WhiteboardComponent_button_2_Template_button_click_0_listener() { const t_r3 = i0.ɵɵrestoreView(_r2).$implicit; const ctx_r3 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r3.onTool(t_r3.id)); });
42
+ i0.ɵɵlistener("click", function WhiteboardComponent_button_5_Template_button_click_0_listener() { const t_r6 = i0.ɵɵrestoreView(_r5).$implicit; const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.onTool(t_r6.id)); });
18
43
  i0.ɵɵtext(1);
19
44
  i0.ɵɵelementEnd();
20
45
  } if (rf & 2) {
21
- const t_r3 = ctx.$implicit;
22
- const ctx_r3 = i0.ɵɵnextContext();
23
- i0.ɵɵclassMap(ctx_r3.toolClass(t_r3.id));
24
- i0.ɵɵattribute("title", ctx_r3.locale.tools[t_r3.id])("aria-pressed", ctx_r3.activeTool === t_r3.id)("data-tool", t_r3.id);
46
+ const t_r6 = ctx.$implicit;
47
+ const ctx_r2 = i0.ɵɵnextContext();
48
+ i0.ɵɵclassMap(ctx_r2.toolClass(t_r6.id));
49
+ i0.ɵɵattribute("title", ctx_r2.locale.tools[t_r6.id])("aria-pressed", ctx_r2.activeTool === t_r6.id)("data-tool", t_r6.id);
25
50
  i0.ɵɵadvance();
26
- i0.ɵɵtextInterpolate(t_r3.glyph);
51
+ i0.ɵɵtextInterpolate(t_r6.glyph);
27
52
  } }
28
- function WhiteboardComponent_button_19_Template(rf, ctx) { if (rf & 1) {
29
- const _r5 = i0.ɵɵgetCurrentView();
30
- i0.ɵɵelementStart(0, "button", 5);
31
- i0.ɵɵlistener("click", function WhiteboardComponent_button_19_Template_button_click_0_listener() { const a_r6 = i0.ɵɵrestoreView(_r5).$implicit; const ctx_r3 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r3.onAlign(a_r6.edge)); });
53
+ function WhiteboardComponent_ng_container_7_button_16_Template(rf, ctx) { if (rf & 1) {
54
+ const _r8 = i0.ɵɵgetCurrentView();
55
+ i0.ɵɵelementStart(0, "button", 34);
56
+ i0.ɵɵlistener("click", function WhiteboardComponent_ng_container_7_button_16_Template_button_click_0_listener() { const a_r9 = i0.ɵɵrestoreView(_r8).$implicit; const ctx_r2 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r2.onAlign(a_r9.edge)); });
32
57
  i0.ɵɵtext(1);
33
58
  i0.ɵɵelementEnd();
34
59
  } if (rf & 2) {
35
- const a_r6 = ctx.$implicit;
36
- const ctx_r3 = i0.ɵɵnextContext();
37
- i0.ɵɵproperty("disabled", !ctx_r3.canAlign);
38
- i0.ɵɵattribute("title", ctx_r3.locale.alignLabels[a_r6.edge])("data-align", a_r6.edge);
60
+ const a_r9 = ctx.$implicit;
61
+ const ctx_r2 = i0.ɵɵnextContext(2);
62
+ i0.ɵɵproperty("disabled", !ctx_r2.canAlign);
63
+ i0.ɵɵattribute("title", ctx_r2.locale.alignLabels[a_r9.edge])("data-align", a_r9.edge);
39
64
  i0.ɵɵadvance();
40
- i0.ɵɵtextInterpolate(a_r6.glyph);
65
+ i0.ɵɵtextInterpolate(a_r9.glyph);
41
66
  } }
42
- function WhiteboardComponent_button_20_Template(rf, ctx) { if (rf & 1) {
43
- const _r7 = i0.ɵɵgetCurrentView();
44
- i0.ɵɵelementStart(0, "button", 5);
45
- i0.ɵɵlistener("click", function WhiteboardComponent_button_20_Template_button_click_0_listener() { const d_r8 = i0.ɵɵrestoreView(_r7).$implicit; const ctx_r3 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r3.onDistribute(d_r8.axis)); });
67
+ function WhiteboardComponent_ng_container_7_button_17_Template(rf, ctx) { if (rf & 1) {
68
+ const _r10 = i0.ɵɵgetCurrentView();
69
+ i0.ɵɵelementStart(0, "button", 34);
70
+ i0.ɵɵlistener("click", function WhiteboardComponent_ng_container_7_button_17_Template_button_click_0_listener() { const d_r11 = i0.ɵɵrestoreView(_r10).$implicit; const ctx_r2 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r2.onDistribute(d_r11.axis)); });
46
71
  i0.ɵɵtext(1);
47
72
  i0.ɵɵelementEnd();
48
73
  } if (rf & 2) {
49
- const d_r8 = ctx.$implicit;
50
- const ctx_r3 = i0.ɵɵnextContext();
51
- i0.ɵɵproperty("disabled", !ctx_r3.canDistribute);
52
- i0.ɵɵattribute("title", ctx_r3.locale.distributeLabels[d_r8.axis])("data-distribute", d_r8.axis);
74
+ const d_r11 = ctx.$implicit;
75
+ const ctx_r2 = i0.ɵɵnextContext(2);
76
+ i0.ɵɵproperty("disabled", !ctx_r2.canDistribute);
77
+ i0.ɵɵattribute("title", ctx_r2.locale.distributeLabels[d_r11.axis])("data-distribute", d_r11.axis);
78
+ i0.ɵɵadvance();
79
+ i0.ɵɵtextInterpolate(d_r11.glyph);
80
+ } }
81
+ function WhiteboardComponent_ng_container_7_Template(rf, ctx) { if (rf & 1) {
82
+ const _r7 = i0.ɵɵgetCurrentView();
83
+ i0.ɵɵelementContainerStart(0);
84
+ i0.ɵɵelementStart(1, "button", 34);
85
+ i0.ɵɵlistener("click", function WhiteboardComponent_ng_container_7_Template_button_click_1_listener() { i0.ɵɵrestoreView(_r7); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.onBringToFront()); });
86
+ i0.ɵɵtext(2, "\u2B06");
87
+ i0.ɵɵelementEnd();
88
+ i0.ɵɵelementStart(3, "button", 34);
89
+ i0.ɵɵlistener("click", function WhiteboardComponent_ng_container_7_Template_button_click_3_listener() { i0.ɵɵrestoreView(_r7); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.onSendToBack()); });
90
+ i0.ɵɵtext(4, "\u2B07");
91
+ i0.ɵɵelementEnd();
92
+ i0.ɵɵelementStart(5, "button", 35);
93
+ i0.ɵɵlistener("click", function WhiteboardComponent_ng_container_7_Template_button_click_5_listener() { i0.ɵɵrestoreView(_r7); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.onToggleLock()); });
94
+ i0.ɵɵtext(6, "\uD83D\uDD12");
95
+ i0.ɵɵelementEnd();
96
+ i0.ɵɵelementStart(7, "button", 36);
97
+ i0.ɵɵlistener("click", function WhiteboardComponent_ng_container_7_Template_button_click_7_listener() { i0.ɵɵrestoreView(_r7); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.onGroup()); });
98
+ i0.ɵɵtext(8, "\u29C9");
99
+ i0.ɵɵelementEnd();
100
+ i0.ɵɵelementStart(9, "button", 37);
101
+ i0.ɵɵlistener("click", function WhiteboardComponent_ng_container_7_Template_button_click_9_listener() { i0.ɵɵrestoreView(_r7); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.onUngroup()); });
102
+ i0.ɵɵtext(10, "\u229F");
103
+ i0.ɵɵelementEnd();
104
+ i0.ɵɵelementStart(11, "button", 38);
105
+ i0.ɵɵlistener("click", function WhiteboardComponent_ng_container_7_Template_button_click_11_listener() { i0.ɵɵrestoreView(_r7); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.onDuplicate()); });
106
+ i0.ɵɵtext(12, "\u29C9\u207A");
107
+ i0.ɵɵelementEnd();
108
+ i0.ɵɵelementStart(13, "button", 34);
109
+ i0.ɵɵlistener("click", function WhiteboardComponent_ng_container_7_Template_button_click_13_listener() { i0.ɵɵrestoreView(_r7); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.onDeleteSelection()); });
110
+ i0.ɵɵtext(14, "\uD83D\uDDD1");
111
+ i0.ɵɵelementEnd();
112
+ i0.ɵɵelement(15, "span", 7);
113
+ i0.ɵɵtemplate(16, WhiteboardComponent_ng_container_7_button_16_Template, 2, 4, "button", 39)(17, WhiteboardComponent_ng_container_7_button_17_Template, 2, 4, "button", 39);
114
+ i0.ɵɵelement(18, "span", 7);
115
+ i0.ɵɵelementContainerEnd();
116
+ } if (rf & 2) {
117
+ const ctx_r2 = i0.ɵɵnextContext();
118
+ i0.ɵɵadvance();
119
+ i0.ɵɵproperty("disabled", !ctx_r2.hasSel);
120
+ i0.ɵɵattribute("title", ctx_r2.locale.bringToFront);
121
+ i0.ɵɵadvance(2);
122
+ i0.ɵɵproperty("disabled", !ctx_r2.hasSel);
123
+ i0.ɵɵattribute("title", ctx_r2.locale.sendToBack);
124
+ i0.ɵɵadvance(2);
125
+ i0.ɵɵproperty("disabled", !ctx_r2.hasSel);
126
+ i0.ɵɵattribute("title", ctx_r2.locale.lock);
127
+ i0.ɵɵadvance(2);
128
+ i0.ɵɵproperty("disabled", !ctx_r2.canGroup);
129
+ i0.ɵɵattribute("title", ctx_r2.locale.group);
130
+ i0.ɵɵadvance(2);
131
+ i0.ɵɵproperty("disabled", !ctx_r2.canUngroup);
132
+ i0.ɵɵattribute("title", ctx_r2.locale.ungroup);
133
+ i0.ɵɵadvance(2);
134
+ i0.ɵɵproperty("disabled", !ctx_r2.hasSel);
135
+ i0.ɵɵattribute("title", ctx_r2.locale.duplicate);
136
+ i0.ɵɵadvance(2);
137
+ i0.ɵɵproperty("disabled", !ctx_r2.hasSel);
138
+ i0.ɵɵattribute("title", ctx_r2.locale.delete);
139
+ i0.ɵɵadvance(3);
140
+ i0.ɵɵproperty("ngForOf", ctx_r2.aligns);
53
141
  i0.ɵɵadvance();
54
- i0.ɵɵtextInterpolate(d_r8.glyph);
142
+ i0.ɵɵproperty("ngForOf", ctx_r2.distributes);
55
143
  } }
56
- function WhiteboardComponent__svg_path_33_Template(rf, ctx) { if (rf & 1) {
144
+ function WhiteboardComponent__svg_path_19_Template(rf, ctx) { if (rf & 1) {
57
145
  i0.ɵɵnamespaceSVG();
58
- i0.ɵɵelement(0, "path", 34);
146
+ i0.ɵɵelement(0, "path", 40);
59
147
  } if (rf & 2) {
60
- const c_r9 = ctx.$implicit;
61
- i0.ɵɵattribute("data-connector-id", c_r9.id)("d", c_r9.d)("stroke", c_r9.stroke)("stroke-width", c_r9.strokeWidth)("stroke-dasharray", c_r9.dash)("opacity", c_r9.opacity)("marker-end", c_r9.markerEnd)("marker-start", c_r9.markerStart);
148
+ const c_r12 = ctx.$implicit;
149
+ i0.ɵɵattribute("data-connector-id", c_r12.id)("d", c_r12.d)("stroke", c_r12.stroke)("stroke-width", c_r12.strokeWidth)("stroke-dasharray", c_r12.dash)("opacity", c_r12.opacity)("marker-end", c_r12.markerEnd)("marker-start", c_r12.markerStart);
62
150
  } }
63
- function WhiteboardComponent__svg_path_34_Template(rf, ctx) { if (rf & 1) {
151
+ function WhiteboardComponent__svg_path_20_Template(rf, ctx) { if (rf & 1) {
64
152
  i0.ɵɵnamespaceSVG();
65
- i0.ɵɵelement(0, "path", 35);
153
+ i0.ɵɵelement(0, "path", 41);
66
154
  } if (rf & 2) {
67
- const ctx_r3 = i0.ɵɵnextContext();
68
- i0.ɵɵattribute("d", ctx_r3.connectorPreviewD);
155
+ const ctx_r2 = i0.ɵɵnextContext();
156
+ i0.ɵɵattribute("d", ctx_r2.connectorPreviewD);
69
157
  } }
70
- function WhiteboardComponent__svg_path_35_Template(rf, ctx) { if (rf & 1) {
158
+ function WhiteboardComponent__svg_path_21_Template(rf, ctx) { if (rf & 1) {
71
159
  i0.ɵɵnamespaceSVG();
72
- i0.ɵɵelement(0, "path", 36);
160
+ i0.ɵɵelement(0, "path", 42);
73
161
  } if (rf & 2) {
74
- const ctx_r3 = i0.ɵɵnextContext();
75
- i0.ɵɵattribute("d", ctx_r3.drawPreviewPath);
162
+ const ctx_r2 = i0.ɵɵnextContext();
163
+ i0.ɵɵattribute("d", ctx_r2.drawPreviewPath);
76
164
  } }
77
- function WhiteboardComponent__svg_line_36_Template(rf, ctx) { if (rf & 1) {
165
+ function WhiteboardComponent__svg_line_22_Template(rf, ctx) { if (rf & 1) {
78
166
  i0.ɵɵnamespaceSVG();
79
- i0.ɵɵelement(0, "line", 37);
167
+ i0.ɵɵelement(0, "line", 43);
80
168
  } if (rf & 2) {
81
- const g_r10 = ctx.$implicit;
82
- i0.ɵɵattribute("data-guide-axis", g_r10.axis)("x1", g_r10.x1)("y1", g_r10.y1)("x2", g_r10.x2)("y2", g_r10.y2);
169
+ const g_r13 = ctx.$implicit;
170
+ i0.ɵɵattribute("data-guide-axis", g_r13.axis)("x1", g_r13.x1)("y1", g_r13.y1)("x2", g_r13.x2)("y2", g_r13.y2);
83
171
  } }
84
- function WhiteboardComponent_bm_wb_shape_37_Template(rf, ctx) { if (rf & 1) {
85
- const _r11 = i0.ɵɵgetCurrentView();
86
- i0.ɵɵelementStart(0, "bm-wb-shape", 38);
87
- i0.ɵɵlistener("shapePointerDown", function WhiteboardComponent_bm_wb_shape_37_Template_bm_wb_shape_shapePointerDown_0_listener($event) { const v_r12 = i0.ɵɵrestoreView(_r11).$implicit; const ctx_r3 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r3.onShapeDown(v_r12.shape.id, $event)); })("shapeDoubleClick", function WhiteboardComponent_bm_wb_shape_37_Template_bm_wb_shape_shapeDoubleClick_0_listener($event) { const v_r12 = i0.ɵɵrestoreView(_r11).$implicit; const ctx_r3 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r3.onShapeDblClick(v_r12.shape.id, $event)); });
172
+ function WhiteboardComponent_bm_wb_shape_23_Template(rf, ctx) { if (rf & 1) {
173
+ const _r14 = i0.ɵɵgetCurrentView();
174
+ i0.ɵɵelementStart(0, "bm-wb-shape", 44);
175
+ i0.ɵɵlistener("shapePointerDown", function WhiteboardComponent_bm_wb_shape_23_Template_bm_wb_shape_shapePointerDown_0_listener($event) { const v_r15 = i0.ɵɵrestoreView(_r14).$implicit; const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.onShapeDown(v_r15.shape.id, $event)); })("shapeDoubleClick", function WhiteboardComponent_bm_wb_shape_23_Template_bm_wb_shape_shapeDoubleClick_0_listener($event) { const v_r15 = i0.ɵɵrestoreView(_r14).$implicit; const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.onShapeDblClick(v_r15.shape.id, $event)); });
88
176
  i0.ɵɵelementEnd();
89
177
  } if (rf & 2) {
90
- const v_r12 = ctx.$implicit;
91
- const ctx_r3 = i0.ɵɵnextContext();
92
- i0.ɵɵproperty("shape", v_r12.shape)("selected", v_r12.selected)("dropTarget", ctx_r3.snapshot.dropTargetId === v_r12.shape.id)("lockedLabel", ctx_r3.locale.locked);
178
+ const v_r15 = ctx.$implicit;
179
+ const ctx_r2 = i0.ɵɵnextContext();
180
+ i0.ɵɵproperty("shape", v_r15.shape)("selected", v_r15.selected)("focused", v_r15.focused)("dropTarget", ctx_r2.snapshot.dropTargetId === v_r15.shape.id)("lockedLabel", ctx_r2.locale.locked)("domId", ctx_r2.shapeDomId(v_r15.shape.id))("ariaLabel", v_r15.ariaLabel);
93
181
  } }
94
- function WhiteboardComponent_div_38_Template(rf, ctx) { if (rf & 1) {
95
- i0.ɵɵelement(0, "div", 39);
182
+ function WhiteboardComponent_div_24_Template(rf, ctx) { if (rf & 1) {
183
+ i0.ɵɵelement(0, "div", 45);
96
184
  } if (rf & 2) {
97
- const mq_r13 = ctx.ngIf;
98
- i0.ɵɵstyleProp("left", mq_r13.x, "px")("top", mq_r13.y, "px")("width", mq_r13.width, "px")("height", mq_r13.height, "px");
185
+ const mq_r16 = ctx.ngIf;
186
+ i0.ɵɵstyleProp("left", mq_r16.x, "px")("top", mq_r16.y, "px")("width", mq_r16.width, "px")("height", mq_r16.height, "px");
99
187
  } }
100
- function WhiteboardComponent_div_39_Template(rf, ctx) { if (rf & 1) {
101
- i0.ɵɵelement(0, "div", 40);
188
+ function WhiteboardComponent_div_25_Template(rf, ctx) { if (rf & 1) {
189
+ i0.ɵɵelement(0, "div", 46);
102
190
  } if (rf & 2) {
103
- const cp_r14 = ctx.ngIf;
104
- i0.ɵɵstyleProp("left", cp_r14.x, "px")("top", cp_r14.y, "px")("width", cp_r14.width, "px")("height", cp_r14.height, "px");
191
+ const cp_r17 = ctx.ngIf;
192
+ i0.ɵɵstyleProp("left", cp_r17.x, "px")("top", cp_r17.y, "px")("width", cp_r17.width, "px")("height", cp_r17.height, "px");
105
193
  } }
106
- function WhiteboardComponent_bm_wb_transform_handles_40_Template(rf, ctx) { if (rf & 1) {
107
- const _r15 = i0.ɵɵgetCurrentView();
108
- i0.ɵɵelementStart(0, "bm-wb-transform-handles", 41);
109
- i0.ɵɵlistener("resize", function WhiteboardComponent_bm_wb_transform_handles_40_Template_bm_wb_transform_handles_resize_0_listener($event) { const tv_r16 = i0.ɵɵrestoreView(_r15).ngIf; const ctx_r3 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r3.onResizeIntent(tv_r16.shape.id, $event)); })("rotate", function WhiteboardComponent_bm_wb_transform_handles_40_Template_bm_wb_transform_handles_rotate_0_listener($event) { const tv_r16 = i0.ɵɵrestoreView(_r15).ngIf; const ctx_r3 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r3.onRotate(tv_r16.shape.id, $event)); });
194
+ function WhiteboardComponent_bm_wb_transform_handles_26_Template(rf, ctx) { if (rf & 1) {
195
+ const _r18 = i0.ɵɵgetCurrentView();
196
+ i0.ɵɵelementStart(0, "bm-wb-transform-handles", 47);
197
+ i0.ɵɵlistener("resize", function WhiteboardComponent_bm_wb_transform_handles_26_Template_bm_wb_transform_handles_resize_0_listener($event) { const tv_r19 = i0.ɵɵrestoreView(_r18).ngIf; const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.onResizeIntent(tv_r19.shape.id, $event)); })("rotate", function WhiteboardComponent_bm_wb_transform_handles_26_Template_bm_wb_transform_handles_rotate_0_listener($event) { const tv_r19 = i0.ɵɵrestoreView(_r18).ngIf; const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.onRotate(tv_r19.shape.id, $event)); });
110
198
  i0.ɵɵelementEnd();
111
199
  } if (rf & 2) {
112
- const tv_r16 = ctx.ngIf;
113
- i0.ɵɵproperty("view", tv_r16);
200
+ const tv_r19 = ctx.ngIf;
201
+ i0.ɵɵproperty("view", tv_r19);
114
202
  } }
115
- function WhiteboardComponent_button_41_Template(rf, ctx) { if (rf & 1) {
116
- const _r17 = i0.ɵɵgetCurrentView();
117
- i0.ɵɵelementStart(0, "button", 42);
118
- i0.ɵɵlistener("pointerdown", function WhiteboardComponent_button_41_Template_button_pointerdown_0_listener($event) { i0.ɵɵrestoreView(_r17); const ctx_r3 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r3.stop($event)); })("click", function WhiteboardComponent_button_41_Template_button_click_0_listener($event) { const p_r18 = i0.ɵɵrestoreView(_r17).$implicit; const ctx_r3 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r3.onPinClick(p_r18.id, $event)); });
203
+ function WhiteboardComponent_button_27_Template(rf, ctx) { if (rf & 1) {
204
+ const _r20 = i0.ɵɵgetCurrentView();
205
+ i0.ɵɵelementStart(0, "button", 48);
206
+ i0.ɵɵlistener("pointerdown", function WhiteboardComponent_button_27_Template_button_pointerdown_0_listener($event) { i0.ɵɵrestoreView(_r20); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.stop($event)); })("click", function WhiteboardComponent_button_27_Template_button_click_0_listener($event) { const p_r21 = i0.ɵɵrestoreView(_r20).$implicit; const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.onPinClick(p_r21.id, $event)); });
119
207
  i0.ɵɵtext(1);
120
208
  i0.ɵɵelementEnd();
121
209
  } if (rf & 2) {
122
- const p_r18 = ctx.$implicit;
123
- const ctx_r3 = i0.ɵɵnextContext();
124
- i0.ɵɵclassMap(ctx_r3.pinClass(p_r18));
125
- i0.ɵɵstyleProp("left", p_r18.x, "px")("top", p_r18.y, "px");
126
- i0.ɵɵattribute("data-comment-id", p_r18.id)("title", p_r18.text);
210
+ const p_r21 = ctx.$implicit;
211
+ const ctx_r2 = i0.ɵɵnextContext();
212
+ i0.ɵɵclassMap(ctx_r2.pinClass(p_r21));
213
+ i0.ɵɵstyleProp("left", p_r21.x, "px")("top", p_r21.y, "px");
214
+ i0.ɵɵattribute("data-comment-id", p_r21.id)("title", p_r21.text);
127
215
  i0.ɵɵadvance();
128
- i0.ɵɵtextInterpolate(p_r18.glyph);
216
+ i0.ɵɵtextInterpolate(p_r21.glyph);
129
217
  } }
130
- function WhiteboardComponent__svg_svg_42__svg_line_1_Template(rf, ctx) { if (rf & 1) {
218
+ function WhiteboardComponent__svg_svg_28__svg_line_1_Template(rf, ctx) { if (rf & 1) {
131
219
  i0.ɵɵnamespaceSVG();
132
- i0.ɵɵelement(0, "line", 45);
220
+ i0.ɵɵelement(0, "line", 51);
133
221
  } if (rf & 2) {
134
- const seg_r19 = ctx.$implicit;
135
- i0.ɵɵattribute("x1", seg_r19.x1)("y1", seg_r19.y1)("x2", seg_r19.x2)("y2", seg_r19.y2)("stroke-opacity", seg_r19.opacity);
222
+ const seg_r22 = ctx.$implicit;
223
+ i0.ɵɵattribute("x1", seg_r22.x1)("y1", seg_r22.y1)("x2", seg_r22.x2)("y2", seg_r22.y2)("stroke-opacity", seg_r22.opacity);
136
224
  } }
137
- function WhiteboardComponent__svg_svg_42_Template(rf, ctx) { if (rf & 1) {
225
+ function WhiteboardComponent__svg_svg_28_Template(rf, ctx) { if (rf & 1) {
138
226
  i0.ɵɵnamespaceSVG();
139
- i0.ɵɵelementStart(0, "svg", 43);
140
- i0.ɵɵtemplate(1, WhiteboardComponent__svg_svg_42__svg_line_1_Template, 1, 5, "line", 44);
227
+ i0.ɵɵelementStart(0, "svg", 49);
228
+ i0.ɵɵtemplate(1, WhiteboardComponent__svg_svg_28__svg_line_1_Template, 1, 5, "line", 50);
141
229
  i0.ɵɵelementEnd();
142
230
  } if (rf & 2) {
143
- const ls_r20 = ctx.ngIf;
144
- const ctx_r3 = i0.ɵɵnextContext();
231
+ const ls_r23 = ctx.ngIf;
232
+ const ctx_r2 = i0.ɵɵnextContext();
145
233
  i0.ɵɵadvance();
146
- i0.ɵɵproperty("ngForOf", ls_r20)("ngForTrackBy", ctx_r3.trackIndex);
234
+ i0.ɵɵproperty("ngForOf", ls_r23)("ngForTrackBy", ctx_r2.trackIndex);
147
235
  } }
148
- function WhiteboardComponent_bm_wb_comment_thread_43_Template(rf, ctx) { if (rf & 1) {
149
- const _r21 = i0.ɵɵgetCurrentView();
150
- i0.ɵɵelementStart(0, "bm-wb-comment-thread", 46);
151
- i0.ɵɵlistener("commit", function WhiteboardComponent_bm_wb_comment_thread_43_Template_bm_wb_comment_thread_commit_0_listener($event) { i0.ɵɵrestoreView(_r21); const ctx_r3 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r3.onCommitDraft($event)); })("close", function WhiteboardComponent_bm_wb_comment_thread_43_Template_bm_wb_comment_thread_close_0_listener() { i0.ɵɵrestoreView(_r21); const ctx_r3 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r3.onCancelDraft()); });
236
+ function WhiteboardComponent_bm_wb_comment_thread_29_Template(rf, ctx) { if (rf & 1) {
237
+ const _r24 = i0.ɵɵgetCurrentView();
238
+ i0.ɵɵelementStart(0, "bm-wb-comment-thread", 52);
239
+ i0.ɵɵlistener("commit", function WhiteboardComponent_bm_wb_comment_thread_29_Template_bm_wb_comment_thread_commit_0_listener($event) { i0.ɵɵrestoreView(_r24); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.onCommitDraft($event)); })("close", function WhiteboardComponent_bm_wb_comment_thread_29_Template_bm_wb_comment_thread_close_0_listener() { i0.ɵɵrestoreView(_r24); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.onCancelDraft()); });
152
240
  i0.ɵɵelementEnd();
153
241
  } if (rf & 2) {
154
- const at_r22 = ctx.ngIf;
155
- const ctx_r3 = i0.ɵɵnextContext();
156
- i0.ɵɵproperty("at", at_r22)("initial", "")("existing", false)("resolved", false)("locale", ctx_r3.locale);
242
+ const at_r25 = ctx.ngIf;
243
+ const ctx_r2 = i0.ɵɵnextContext();
244
+ i0.ɵɵproperty("at", at_r25)("initial", "")("existing", false)("resolved", false)("locale", ctx_r2.locale);
157
245
  } }
158
- function WhiteboardComponent_bm_wb_comment_thread_44_Template(rf, ctx) { if (rf & 1) {
159
- const _r23 = i0.ɵɵgetCurrentView();
160
- i0.ɵɵelementStart(0, "bm-wb-comment-thread", 47);
161
- i0.ɵɵlistener("commit", function WhiteboardComponent_bm_wb_comment_thread_44_Template_bm_wb_comment_thread_commit_0_listener($event) { const ot_r24 = i0.ɵɵrestoreView(_r23).ngIf; const ctx_r3 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r3.onCommitThread(ot_r24.id, $event)); })("close", function WhiteboardComponent_bm_wb_comment_thread_44_Template_bm_wb_comment_thread_close_0_listener() { i0.ɵɵrestoreView(_r23); const ctx_r3 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r3.onCloseThread()); })("resolve", function WhiteboardComponent_bm_wb_comment_thread_44_Template_bm_wb_comment_thread_resolve_0_listener() { const ot_r24 = i0.ɵɵrestoreView(_r23).ngIf; const ctx_r3 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r3.onResolveThread(ot_r24.id)); })("delete", function WhiteboardComponent_bm_wb_comment_thread_44_Template_bm_wb_comment_thread_delete_0_listener() { const ot_r24 = i0.ɵɵrestoreView(_r23).ngIf; const ctx_r3 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r3.onDeleteThread(ot_r24.id)); });
246
+ function WhiteboardComponent_bm_wb_comment_thread_30_Template(rf, ctx) { if (rf & 1) {
247
+ const _r26 = i0.ɵɵgetCurrentView();
248
+ i0.ɵɵelementStart(0, "bm-wb-comment-thread", 53);
249
+ i0.ɵɵlistener("commit", function WhiteboardComponent_bm_wb_comment_thread_30_Template_bm_wb_comment_thread_commit_0_listener($event) { const ot_r27 = i0.ɵɵrestoreView(_r26).ngIf; const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.onCommitThread(ot_r27.id, $event)); })("close", function WhiteboardComponent_bm_wb_comment_thread_30_Template_bm_wb_comment_thread_close_0_listener() { i0.ɵɵrestoreView(_r26); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.onCloseThread()); })("resolve", function WhiteboardComponent_bm_wb_comment_thread_30_Template_bm_wb_comment_thread_resolve_0_listener() { const ot_r27 = i0.ɵɵrestoreView(_r26).ngIf; const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.onResolveThread(ot_r27.id)); })("delete", function WhiteboardComponent_bm_wb_comment_thread_30_Template_bm_wb_comment_thread_delete_0_listener() { const ot_r27 = i0.ɵɵrestoreView(_r26).ngIf; const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.onDeleteThread(ot_r27.id)); });
162
250
  i0.ɵɵelementEnd();
163
251
  } if (rf & 2) {
164
- const ot_r24 = ctx.ngIf;
165
- const ctx_r3 = i0.ɵɵnextContext();
166
- i0.ɵɵproperty("at", ot_r24.at)("initial", ot_r24.text)("existing", true)("resolved", ot_r24.resolved)("locale", ctx_r3.locale);
252
+ const ot_r27 = ctx.ngIf;
253
+ const ctx_r2 = i0.ɵɵnextContext();
254
+ i0.ɵɵproperty("at", ot_r27.at)("identity", ot_r27.id)("initial", ot_r27.text)("existing", true)("resolved", ot_r27.resolved)("locale", ctx_r2.locale);
167
255
  } }
168
- function WhiteboardComponent_bm_wb_style_panel_45_Template(rf, ctx) { if (rf & 1) {
169
- const _r25 = i0.ɵɵgetCurrentView();
170
- i0.ɵɵelementStart(0, "bm-wb-style-panel", 48);
171
- i0.ɵɵlistener("styleInput", function WhiteboardComponent_bm_wb_style_panel_45_Template_bm_wb_style_panel_styleInput_0_listener($event) { i0.ɵɵrestoreView(_r25); const ctx_r3 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r3.onStyleInput($event)); });
256
+ function WhiteboardComponent_bm_wb_style_panel_31_Template(rf, ctx) { if (rf & 1) {
257
+ const _r28 = i0.ɵɵgetCurrentView();
258
+ i0.ɵɵelementStart(0, "bm-wb-style-panel", 54);
259
+ i0.ɵɵlistener("styleInput", function WhiteboardComponent_bm_wb_style_panel_31_Template_bm_wb_style_panel_styleInput_0_listener($event) { i0.ɵɵrestoreView(_r28); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.onStyleInput($event)); });
172
260
  i0.ɵɵelementEnd();
173
261
  } if (rf & 2) {
174
- const ps_r26 = ctx.ngIf;
175
- const ctx_r3 = i0.ɵɵnextContext();
176
- i0.ɵɵstyleMap(ps_r26);
177
- i0.ɵɵproperty("locale", ctx_r3.locale);
262
+ const ps_r29 = ctx.ngIf;
263
+ const ctx_r2 = i0.ɵɵnextContext();
264
+ i0.ɵɵstyleMap(ps_r29);
265
+ i0.ɵɵproperty("locale", ctx_r2.locale);
178
266
  } }
179
- function WhiteboardComponent_div_46_Template(rf, ctx) { if (rf & 1) {
180
- const _r27 = i0.ɵɵgetCurrentView();
181
- i0.ɵɵelementStart(0, "div", 49)(1, "span");
267
+ function WhiteboardComponent_div_32_Template(rf, ctx) { if (rf & 1) {
268
+ i0.ɵɵelementStart(0, "div")(1, "span");
182
269
  i0.ɵɵtext(2);
183
- i0.ɵɵelementEnd();
184
- i0.ɵɵelementStart(3, "button", 50);
185
- i0.ɵɵlistener("click", function WhiteboardComponent_div_46_Template_button_click_3_listener() { i0.ɵɵrestoreView(_r27); const ctx_r3 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r3.onUndo()); });
186
- i0.ɵɵtext(4);
187
270
  i0.ɵɵelementEnd()();
188
271
  } if (rf & 2) {
189
- const u_r28 = ctx.ngIf;
190
- const ctx_r3 = i0.ɵɵnextContext();
272
+ const u_r30 = ctx.ngIf;
273
+ i0.ɵɵclassMap("bm-wb__toast" + (u_r30.kind === "error" ? " bm-wb__toast--error" : ""));
274
+ i0.ɵɵattribute("role", u_r30.kind === "error" ? "alert" : "status");
191
275
  i0.ɵɵadvance(2);
192
- i0.ɵɵtextInterpolate(u_r28.description);
193
- i0.ɵɵadvance(2);
194
- i0.ɵɵtextInterpolate(ctx_r3.locale.undo);
276
+ i0.ɵɵtextInterpolate(u_r30.description);
195
277
  } }
196
- function WhiteboardComponent_bm_wb_text_dialog_47_Template(rf, ctx) { if (rf & 1) {
197
- const _r29 = i0.ɵɵgetCurrentView();
198
- i0.ɵɵelementStart(0, "bm-wb-text-dialog", 51);
199
- i0.ɵɵlistener("save", function WhiteboardComponent_bm_wb_text_dialog_47_Template_bm_wb_text_dialog_save_0_listener($event) { i0.ɵɵrestoreView(_r29); const ctx_r3 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r3.onSaveShape($event)); })("close", function WhiteboardComponent_bm_wb_text_dialog_47_Template_bm_wb_text_dialog_close_0_listener() { i0.ɵɵrestoreView(_r29); const ctx_r3 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r3.onCloseDialog()); })("delete", function WhiteboardComponent_bm_wb_text_dialog_47_Template_bm_wb_text_dialog_delete_0_listener() { const ds_r30 = i0.ɵɵrestoreView(_r29).ngIf; const ctx_r3 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r3.onDeleteShape(ds_r30.id)); });
278
+ function WhiteboardComponent_bm_wb_text_dialog_33_Template(rf, ctx) { if (rf & 1) {
279
+ const _r31 = i0.ɵɵgetCurrentView();
280
+ i0.ɵɵelementStart(0, "bm-wb-text-dialog", 55);
281
+ i0.ɵɵlistener("save", function WhiteboardComponent_bm_wb_text_dialog_33_Template_bm_wb_text_dialog_save_0_listener($event) { i0.ɵɵrestoreView(_r31); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.onSaveShape($event)); })("close", function WhiteboardComponent_bm_wb_text_dialog_33_Template_bm_wb_text_dialog_close_0_listener() { i0.ɵɵrestoreView(_r31); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.onCloseDialog()); })("delete", function WhiteboardComponent_bm_wb_text_dialog_33_Template_bm_wb_text_dialog_delete_0_listener() { const ds_r32 = i0.ɵɵrestoreView(_r31).ngIf; const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.onDeleteShape(ds_r32.id)); });
200
282
  i0.ɵɵelementEnd();
201
283
  } if (rf & 2) {
202
- const ds_r30 = ctx.ngIf;
203
- const ctx_r3 = i0.ɵɵnextContext();
204
- i0.ɵɵproperty("initial", ds_r30.text)("locale", ctx_r3.locale);
284
+ const ds_r32 = ctx.ngIf;
285
+ const ctx_r2 = i0.ɵɵnextContext();
286
+ i0.ɵɵproperty("initial", ds_r32.text)("locale", ctx_r2.locale);
205
287
  } }
206
288
  /** Per-instance SVG marker id counter — document-global ids would collide across
207
289
  * two mounted boards and `url(#…)` would resolve to the wrong marker. */
@@ -226,6 +308,9 @@ export class WhiteboardComponent {
226
308
  config;
227
309
  darkMode = false;
228
310
  dir;
311
+ /** Show the undo/redo button pair in the toolbar (default true). UI-only — the
312
+ * controller's undo()/redo() and keyboard shortcuts stay active when hidden. */
313
+ showUndoRedo = true;
229
314
  /** Surfaces infrastructure errors (a domain rejection is an undo toast). */
230
315
  onError;
231
316
  /** OBSERVE hook (STANDALONE only): fires when the selected shapes change (ids, empty on clear). */
@@ -237,11 +322,24 @@ export class WhiteboardComponent {
237
322
  unsub;
238
323
  zone = inject(NgZone, { optional: true }) ?? undefined;
239
324
  resizeObserver;
240
- tools = WHITEBOARD_TOOLS;
325
+ /** mcp-64: im View-Only bleiben nur select/laser. */
326
+ get tools() { return this.snapshot.config.readOnly ? WHITEBOARD_TOOLS.filter(t => t.id === 'select' || t.id === 'laser') : WHITEBOARD_TOOLS; }
241
327
  aligns = WHITEBOARD_ALIGN;
242
328
  distributes = WHITEBOARD_DISTRIBUTE;
243
- arrowId = `bm-wb-arrow-${wbMarkerSeq++}`;
329
+ // One instance token worn by every id this board mints: the arrow marker (existing
330
+ // shape, unchanged) and the shapes (mcp-78).
331
+ instance = wbMarkerSeq++;
332
+ arrowId = `bm-wb-arrow-${this.instance}`;
333
+ uid = `bm-wb-${this.instance}`;
244
334
  markerUrl = `url(#${this.arrowId})`;
335
+ /** The shared id formula — never a per-stack string concat. */
336
+ shapeDomId(shapeId) { return whiteboardShapeDomId(this.uid, shapeId); }
337
+ /** aria-activedescendant for the board: the controller publishes the id ONLY while
338
+ * that shape is rendered (shapes are culled), so this can never dangle. */
339
+ activeDescendantDomId() {
340
+ const id = this.snapshot.activeDescendantId;
341
+ return id ? this.shapeDomId(id) : null;
342
+ }
245
343
  get ctrl() { return this.ctrlRef; }
246
344
  get snapshot() { return this.snapshotSig(); }
247
345
  get viewport() { return this.snapshot.viewport; }
@@ -410,13 +508,15 @@ export class WhiteboardComponent {
410
508
  this.snapshotSig = sig;
411
509
  }
412
510
  else {
413
- this.binding = createWhiteboardControllerBinding({
511
+ // bimetal-181: der GETTER ist die Aussage — die Pfeilfunktion liest `this` bei
512
+ // jedem Callback-Aufruf erneut, statt den Stand von ngOnInit festzunageln.
513
+ this.binding = createWhiteboardControllerBinding(() => ({
414
514
  store: this.store,
415
515
  canvasId: this.canvasId,
416
516
  config: this.config,
417
- onError: (err) => this.onError?.(err),
517
+ onError: (err) => (this.onError ?? reportUnroutedWhiteboardError)(err),
418
518
  onSelectionChange: this.onSelectionChange,
419
- }, this.zone);
519
+ }), this.zone);
420
520
  this.ctrlRef = this.binding.ctrl;
421
521
  this.snapshotSig = this.binding.snapshot;
422
522
  }
@@ -511,7 +611,9 @@ export class WhiteboardComponent {
511
611
  }
512
612
  onKeydown(e) {
513
613
  this.ctrl.handleKeydown({
514
- key: e.key, ctrlKey: e.ctrlKey, metaKey: e.metaKey, shiftKey: e.shiftKey,
614
+ key: e.key, ctrlKey: e.ctrlKey, metaKey: e.metaKey, shiftKey: e.shiftKey, altKey: e.altKey,
615
+ // isSelfTarget (mcp-78 review R1): the toolbar lives inside this root, so its buttons' keystrokes bubble here. Without this the scene keys swallowed Tab/Enter/Space for every button in the component.
616
+ isSelfTarget: e.target === e.currentTarget,
515
617
  isEditable: isEditableTarget(e.target), preventDefault: () => e.preventDefault(),
516
618
  });
517
619
  }
@@ -528,6 +630,7 @@ export class WhiteboardComponent {
528
630
  onDistribute(axis) { this.ctrl.voidDistributeSelection(axis); }
529
631
  onResetViewport() { this.ctrl.resetViewport(); }
530
632
  onUndo() { this.ctrl.voidUndo(); }
633
+ onRedo() { this.ctrl.voidRedo(); }
531
634
  onStyleInput(raw) { this.ctrl.voidSetSelectionStyleFromInput(raw); }
532
635
  // ── Comments ──
533
636
  onPinClick(id, e) { e.stopPropagation(); this.ctrl.openCommentThread(id); }
@@ -552,97 +655,50 @@ export class WhiteboardComponent {
552
655
  } if (rf & 2) {
553
656
  let _t;
554
657
  i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.viewportRef = _t.first);
555
- } }, hostAttrs: [2, "display", "block", "width", "100%", "height", "100%"], inputs: { controller: "controller", store: "store", canvasId: "canvasId", config: "config", darkMode: "darkMode", dir: "dir", onError: "onError", onSelectionChange: "onSelectionChange" }, features: [i0.ɵɵNgOnChangesFeature], decls: 48, vars: 47, consts: [["viewportRef", ""], ["role", "application", "tabindex", "0", 1, "bm-wb", 3, "keydown"], [1, "bm-wb__toolbar"], ["type", "button", 3, "class", "click", 4, "ngFor", "ngForOf"], [1, "bm-wb__toolbar-sep"], ["type", "button", 1, "bm-wb__btn", 3, "click", "disabled"], ["type", "button", 1, "bm-wb__btn", "bm-wb__lock-btn", 3, "click", "disabled"], ["type", "button", "data-action", "group", 1, "bm-wb__btn", 3, "click", "disabled"], ["type", "button", "data-action", "ungroup", 1, "bm-wb__btn", 3, "click", "disabled"], ["type", "button", "data-action", "duplicate", 1, "bm-wb__btn", 3, "click", "disabled"], ["type", "button", "class", "bm-wb__btn", 3, "disabled", "click", 4, "ngFor", "ngForOf"], ["type", "button", 1, "bm-wb__btn", 3, "click"], [1, "bm-wb__toolbar-zoom"], ["data-testid", "wb-viewport", 3, "pointerdown", "ngStyle"], [1, "bm-wb__scene"], ["data-testid", "wb-connectors", 1, "bm-wb__connectors"], ["markerWidth", "8", "markerHeight", "8", "refX", "7", "refY", "4", "orient", "auto"], ["d", "M0,0 L7,4 L0,8 Z", "fill", "context-stroke"], ["class", "bm-wb__connector", 4, "ngFor", "ngForOf", "ngForTrackBy"], ["class", "bm-wb__connector-preview", 4, "ngIf"], ["class", "bm-wb__draw-preview", "data-testid", "wb-draw-preview", 4, "ngIf"], ["class", "bm-wb__guide", 4, "ngFor", "ngForOf", "ngForTrackBy"], [3, "shape", "selected", "dropTarget", "lockedLabel", "shapePointerDown", "shapeDoubleClick", 4, "ngFor", "ngForOf", "ngForTrackBy"], ["class", "bm-wb__marquee", 3, "left", "top", "width", "height", 4, "ngIf"], ["class", "bm-wb__create-preview", 3, "left", "top", "width", "height", 4, "ngIf"], [3, "view", "resize", "rotate", 4, "ngIf"], ["type", "button", 3, "class", "left", "top", "pointerdown", "click", 4, "ngFor", "ngForOf", "ngForTrackBy"], ["class", "bm-wb__laser-layer", "data-testid", "wb-laser-layer", 4, "ngIf"], [3, "at", "initial", "existing", "resolved", "locale", "commit", "close", 4, "ngIf"], [3, "at", "initial", "existing", "resolved", "locale", "commit", "close", "resolve", "delete", 4, "ngIf"], [3, "style", "locale", "styleInput", 4, "ngIf"], ["class", "bm-wb__toast", "role", "status", 4, "ngIf"], [3, "initial", "locale", "save", "close", "delete", 4, "ngIf"], ["type", "button", 3, "click"], [1, "bm-wb__connector"], [1, "bm-wb__connector-preview"], ["data-testid", "wb-draw-preview", 1, "bm-wb__draw-preview"], [1, "bm-wb__guide"], [3, "shapePointerDown", "shapeDoubleClick", "shape", "selected", "dropTarget", "lockedLabel"], [1, "bm-wb__marquee"], [1, "bm-wb__create-preview"], [3, "resize", "rotate", "view"], ["type", "button", 3, "pointerdown", "click"], ["data-testid", "wb-laser-layer", 1, "bm-wb__laser-layer"], ["class", "bm-wb__laser", "data-testid", "wb-laser", 4, "ngFor", "ngForOf", "ngForTrackBy"], ["data-testid", "wb-laser", 1, "bm-wb__laser"], [3, "commit", "close", "at", "initial", "existing", "resolved", "locale"], [3, "commit", "close", "resolve", "delete", "at", "initial", "existing", "resolved", "locale"], [3, "styleInput", "locale"], ["role", "status", 1, "bm-wb__toast"], ["type", "button", 1, "bm-wb__toast-btn", 3, "click"], [3, "save", "close", "delete", "initial", "locale"]], template: function WhiteboardComponent_Template(rf, ctx) { if (rf & 1) {
658
+ } }, hostAttrs: [2, "display", "block", "width", "100%", "height", "100%"], inputs: { controller: "controller", store: "store", canvasId: "canvasId", config: "config", darkMode: "darkMode", dir: "dir", showUndoRedo: "showUndoRedo", onError: "onError", onSelectionChange: "onSelectionChange" }, features: [i0.ɵɵNgOnChangesFeature], decls: 34, vars: 36, consts: [["viewportRef", ""], ["role", "application", "tabindex", "0", 1, "bm-wb", 3, "keydown"], [1, "bm-wb__toolbar"], ["type", "button", "class", "bm-wb__btn bm-wb__btn--undo", 3, "disabled", "click", 4, "ngIf"], ["type", "button", "class", "bm-wb__btn bm-wb__btn--redo", 3, "disabled", "click", 4, "ngIf"], ["class", "bm-wb__toolbar-sep", 4, "ngIf"], ["type", "button", 3, "class", "click", 4, "ngFor", "ngForOf"], [1, "bm-wb__toolbar-sep"], [4, "ngIf"], ["type", "button", 1, "bm-wb__btn", 3, "click"], [1, "bm-wb__toolbar-zoom"], ["data-testid", "wb-viewport", 3, "pointerdown", "ngStyle"], [1, "bm-wb__scene"], ["data-testid", "wb-connectors", 1, "bm-wb__connectors"], ["markerWidth", "8", "markerHeight", "8", "refX", "7", "refY", "4", "orient", "auto"], ["d", "M0,0 L7,4 L0,8 Z", "fill", "context-stroke"], ["class", "bm-wb__connector", 4, "ngFor", "ngForOf", "ngForTrackBy"], ["class", "bm-wb__connector-preview", 4, "ngIf"], ["class", "bm-wb__draw-preview", "data-testid", "wb-draw-preview", 4, "ngIf"], ["class", "bm-wb__guide", 4, "ngFor", "ngForOf", "ngForTrackBy"], [3, "shape", "selected", "focused", "dropTarget", "lockedLabel", "domId", "ariaLabel", "shapePointerDown", "shapeDoubleClick", 4, "ngFor", "ngForOf", "ngForTrackBy"], ["class", "bm-wb__marquee", 3, "left", "top", "width", "height", 4, "ngIf"], ["class", "bm-wb__create-preview", 3, "left", "top", "width", "height", 4, "ngIf"], [3, "view", "resize", "rotate", 4, "ngIf"], ["type", "button", 3, "class", "left", "top", "pointerdown", "click", 4, "ngFor", "ngForOf", "ngForTrackBy"], ["class", "bm-wb__laser-layer", "data-testid", "wb-laser-layer", 4, "ngIf"], [3, "at", "initial", "existing", "resolved", "locale", "commit", "close", 4, "ngIf"], [3, "at", "identity", "initial", "existing", "resolved", "locale", "commit", "close", "resolve", "delete", 4, "ngIf"], [3, "style", "locale", "styleInput", 4, "ngIf"], [3, "class", 4, "ngIf"], [3, "initial", "locale", "save", "close", "delete", 4, "ngIf"], ["type", "button", 1, "bm-wb__btn", "bm-wb__btn--undo", 3, "click", "disabled"], ["type", "button", 1, "bm-wb__btn", "bm-wb__btn--redo", 3, "click", "disabled"], ["type", "button", 3, "click"], ["type", "button", 1, "bm-wb__btn", 3, "click", "disabled"], ["type", "button", 1, "bm-wb__btn", "bm-wb__lock-btn", 3, "click", "disabled"], ["type", "button", "data-action", "group", 1, "bm-wb__btn", 3, "click", "disabled"], ["type", "button", "data-action", "ungroup", 1, "bm-wb__btn", 3, "click", "disabled"], ["type", "button", "data-action", "duplicate", 1, "bm-wb__btn", 3, "click", "disabled"], ["type", "button", "class", "bm-wb__btn", 3, "disabled", "click", 4, "ngFor", "ngForOf"], [1, "bm-wb__connector"], [1, "bm-wb__connector-preview"], ["data-testid", "wb-draw-preview", 1, "bm-wb__draw-preview"], [1, "bm-wb__guide"], [3, "shapePointerDown", "shapeDoubleClick", "shape", "selected", "focused", "dropTarget", "lockedLabel", "domId", "ariaLabel"], [1, "bm-wb__marquee"], [1, "bm-wb__create-preview"], [3, "resize", "rotate", "view"], ["type", "button", 3, "pointerdown", "click"], ["data-testid", "wb-laser-layer", 1, "bm-wb__laser-layer"], ["class", "bm-wb__laser", "data-testid", "wb-laser", 4, "ngFor", "ngForOf", "ngForTrackBy"], ["data-testid", "wb-laser", 1, "bm-wb__laser"], [3, "commit", "close", "at", "initial", "existing", "resolved", "locale"], [3, "commit", "close", "resolve", "delete", "at", "identity", "initial", "existing", "resolved", "locale"], [3, "styleInput", "locale"], [3, "save", "close", "delete", "initial", "locale"]], template: function WhiteboardComponent_Template(rf, ctx) { if (rf & 1) {
556
659
  const _r1 = i0.ɵɵgetCurrentView();
557
660
  i0.ɵɵelementStart(0, "div", 1);
558
661
  i0.ɵɵlistener("keydown", function WhiteboardComponent_Template_div_keydown_0_listener($event) { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.onKeydown($event)); });
559
662
  i0.ɵɵelementStart(1, "div", 2);
560
- i0.ɵɵtemplate(2, WhiteboardComponent_button_2_Template, 2, 6, "button", 3);
561
- i0.ɵɵelement(3, "span", 4);
562
- i0.ɵɵelementStart(4, "button", 5);
563
- i0.ɵɵlistener("click", function WhiteboardComponent_Template_button_click_4_listener() { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.onBringToFront()); });
564
- i0.ɵɵtext(5, "\u2B06");
565
- i0.ɵɵelementEnd();
566
- i0.ɵɵelementStart(6, "button", 5);
567
- i0.ɵɵlistener("click", function WhiteboardComponent_Template_button_click_6_listener() { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.onSendToBack()); });
568
- i0.ɵɵtext(7, "\u2B07");
569
- i0.ɵɵelementEnd();
570
- i0.ɵɵelementStart(8, "button", 6);
571
- i0.ɵɵlistener("click", function WhiteboardComponent_Template_button_click_8_listener() { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.onToggleLock()); });
572
- i0.ɵɵtext(9, "\uD83D\uDD12");
573
- i0.ɵɵelementEnd();
574
- i0.ɵɵelementStart(10, "button", 7);
575
- i0.ɵɵlistener("click", function WhiteboardComponent_Template_button_click_10_listener() { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.onGroup()); });
576
- i0.ɵɵtext(11, "\u29C9");
577
- i0.ɵɵelementEnd();
578
- i0.ɵɵelementStart(12, "button", 8);
579
- i0.ɵɵlistener("click", function WhiteboardComponent_Template_button_click_12_listener() { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.onUngroup()); });
580
- i0.ɵɵtext(13, "\u229F");
581
- i0.ɵɵelementEnd();
582
- i0.ɵɵelementStart(14, "button", 9);
583
- i0.ɵɵlistener("click", function WhiteboardComponent_Template_button_click_14_listener() { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.onDuplicate()); });
584
- i0.ɵɵtext(15, "\u29C9\u207A");
585
- i0.ɵɵelementEnd();
586
- i0.ɵɵelementStart(16, "button", 5);
587
- i0.ɵɵlistener("click", function WhiteboardComponent_Template_button_click_16_listener() { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.onDeleteSelection()); });
588
- i0.ɵɵtext(17, "\uD83D\uDDD1");
589
- i0.ɵɵelementEnd();
590
- i0.ɵɵelement(18, "span", 4);
591
- i0.ɵɵtemplate(19, WhiteboardComponent_button_19_Template, 2, 4, "button", 10)(20, WhiteboardComponent_button_20_Template, 2, 4, "button", 10);
592
- i0.ɵɵelement(21, "span", 4);
593
- i0.ɵɵelementStart(22, "button", 11);
594
- i0.ɵɵlistener("click", function WhiteboardComponent_Template_button_click_22_listener() { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.onResetViewport()); });
595
- i0.ɵɵtext(23, "\u2316");
663
+ i0.ɵɵtemplate(2, WhiteboardComponent_button_2_Template, 2, 3, "button", 3)(3, WhiteboardComponent_button_3_Template, 2, 3, "button", 4)(4, WhiteboardComponent_span_4_Template, 1, 0, "span", 5)(5, WhiteboardComponent_button_5_Template, 2, 6, "button", 6);
664
+ i0.ɵɵelement(6, "span", 7);
665
+ i0.ɵɵtemplate(7, WhiteboardComponent_ng_container_7_Template, 19, 16, "ng-container", 8);
666
+ i0.ɵɵelementStart(8, "button", 9);
667
+ i0.ɵɵlistener("click", function WhiteboardComponent_Template_button_click_8_listener() { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.onResetViewport()); });
668
+ i0.ɵɵtext(9, "\u2316");
596
669
  i0.ɵɵelementEnd();
597
- i0.ɵɵelementStart(24, "span", 12);
598
- i0.ɵɵtext(25);
670
+ i0.ɵɵelementStart(10, "span", 10);
671
+ i0.ɵɵtext(11);
599
672
  i0.ɵɵelementEnd()();
600
- i0.ɵɵelementStart(26, "div", 13, 0);
601
- i0.ɵɵlistener("pointerdown", function WhiteboardComponent_Template_div_pointerdown_26_listener($event) { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.onViewportPointerDown($event)); });
602
- i0.ɵɵelementStart(28, "div", 14);
673
+ i0.ɵɵelementStart(12, "div", 11, 0);
674
+ i0.ɵɵlistener("pointerdown", function WhiteboardComponent_Template_div_pointerdown_12_listener($event) { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.onViewportPointerDown($event)); });
675
+ i0.ɵɵelementStart(14, "div", 12);
603
676
  i0.ɵɵnamespaceSVG();
604
- i0.ɵɵelementStart(29, "svg", 15)(30, "defs")(31, "marker", 16);
605
- i0.ɵɵelement(32, "path", 17);
677
+ i0.ɵɵelementStart(15, "svg", 13)(16, "defs")(17, "marker", 14);
678
+ i0.ɵɵelement(18, "path", 15);
606
679
  i0.ɵɵelementEnd()();
607
- i0.ɵɵtemplate(33, WhiteboardComponent__svg_path_33_Template, 1, 8, "path", 18)(34, WhiteboardComponent__svg_path_34_Template, 1, 1, "path", 19)(35, WhiteboardComponent__svg_path_35_Template, 1, 1, "path", 20)(36, WhiteboardComponent__svg_line_36_Template, 1, 5, "line", 21);
680
+ i0.ɵɵtemplate(19, WhiteboardComponent__svg_path_19_Template, 1, 8, "path", 16)(20, WhiteboardComponent__svg_path_20_Template, 1, 1, "path", 17)(21, WhiteboardComponent__svg_path_21_Template, 1, 1, "path", 18)(22, WhiteboardComponent__svg_line_22_Template, 1, 5, "line", 19);
608
681
  i0.ɵɵelementEnd();
609
- i0.ɵɵtemplate(37, WhiteboardComponent_bm_wb_shape_37_Template, 1, 4, "bm-wb-shape", 22)(38, WhiteboardComponent_div_38_Template, 1, 8, "div", 23)(39, WhiteboardComponent_div_39_Template, 1, 8, "div", 24)(40, WhiteboardComponent_bm_wb_transform_handles_40_Template, 1, 1, "bm-wb-transform-handles", 25)(41, WhiteboardComponent_button_41_Template, 2, 9, "button", 26)(42, WhiteboardComponent__svg_svg_42_Template, 2, 2, "svg", 27);
682
+ i0.ɵɵtemplate(23, WhiteboardComponent_bm_wb_shape_23_Template, 1, 7, "bm-wb-shape", 20)(24, WhiteboardComponent_div_24_Template, 1, 8, "div", 21)(25, WhiteboardComponent_div_25_Template, 1, 8, "div", 22)(26, WhiteboardComponent_bm_wb_transform_handles_26_Template, 1, 1, "bm-wb-transform-handles", 23)(27, WhiteboardComponent_button_27_Template, 2, 9, "button", 24)(28, WhiteboardComponent__svg_svg_28_Template, 2, 2, "svg", 25);
610
683
  i0.ɵɵelementEnd();
611
- i0.ɵɵtemplate(43, WhiteboardComponent_bm_wb_comment_thread_43_Template, 1, 5, "bm-wb-comment-thread", 28)(44, WhiteboardComponent_bm_wb_comment_thread_44_Template, 1, 5, "bm-wb-comment-thread", 29);
684
+ i0.ɵɵtemplate(29, WhiteboardComponent_bm_wb_comment_thread_29_Template, 1, 5, "bm-wb-comment-thread", 26)(30, WhiteboardComponent_bm_wb_comment_thread_30_Template, 1, 6, "bm-wb-comment-thread", 27);
612
685
  i0.ɵɵelementEnd();
613
- i0.ɵɵtemplate(45, WhiteboardComponent_bm_wb_style_panel_45_Template, 1, 3, "bm-wb-style-panel", 30)(46, WhiteboardComponent_div_46_Template, 5, 2, "div", 31)(47, WhiteboardComponent_bm_wb_text_dialog_47_Template, 1, 2, "bm-wb-text-dialog", 32);
686
+ i0.ɵɵtemplate(31, WhiteboardComponent_bm_wb_style_panel_31_Template, 1, 3, "bm-wb-style-panel", 28)(32, WhiteboardComponent_div_32_Template, 3, 4, "div", 29)(33, WhiteboardComponent_bm_wb_text_dialog_33_Template, 1, 2, "bm-wb-text-dialog", 30);
614
687
  i0.ɵɵelementEnd();
615
688
  } if (rf & 2) {
616
689
  let tmp_2_0;
617
- i0.ɵɵattribute("data-theme", ctx.darkMode ? "dark" : null)("dir", (tmp_2_0 = ctx.dir) !== null && tmp_2_0 !== undefined ? tmp_2_0 : null)("aria-label", ctx.snapshot.ariaLabel);
690
+ i0.ɵɵattribute("data-theme", ctx.darkMode ? "dark" : null)("dir", (tmp_2_0 = ctx.dir) !== null && tmp_2_0 !== undefined ? tmp_2_0 : null)("aria-label", ctx.snapshot.ariaLabel)("aria-activedescendant", ctx.activeDescendantDomId());
618
691
  i0.ɵɵadvance(2);
692
+ i0.ɵɵproperty("ngIf", ctx.showUndoRedo && !ctx.snapshot.config.readOnly);
693
+ i0.ɵɵadvance();
694
+ i0.ɵɵproperty("ngIf", ctx.showUndoRedo && !ctx.snapshot.config.readOnly);
695
+ i0.ɵɵadvance();
696
+ i0.ɵɵproperty("ngIf", ctx.showUndoRedo && !ctx.snapshot.config.readOnly);
697
+ i0.ɵɵadvance();
619
698
  i0.ɵɵproperty("ngForOf", ctx.tools);
620
699
  i0.ɵɵadvance(2);
621
- i0.ɵɵproperty("disabled", !ctx.hasSel);
622
- i0.ɵɵattribute("title", ctx.locale.bringToFront);
623
- i0.ɵɵadvance(2);
624
- i0.ɵɵproperty("disabled", !ctx.hasSel);
625
- i0.ɵɵattribute("title", ctx.locale.sendToBack);
626
- i0.ɵɵadvance(2);
627
- i0.ɵɵproperty("disabled", !ctx.hasSel);
628
- i0.ɵɵattribute("title", ctx.locale.lock);
629
- i0.ɵɵadvance(2);
630
- i0.ɵɵproperty("disabled", !ctx.canGroup);
631
- i0.ɵɵattribute("title", ctx.locale.group);
632
- i0.ɵɵadvance(2);
633
- i0.ɵɵproperty("disabled", !ctx.canUngroup);
634
- i0.ɵɵattribute("title", ctx.locale.ungroup);
635
- i0.ɵɵadvance(2);
636
- i0.ɵɵproperty("disabled", !ctx.hasSel);
637
- i0.ɵɵattribute("title", ctx.locale.duplicate);
638
- i0.ɵɵadvance(2);
639
- i0.ɵɵproperty("disabled", !ctx.hasSel);
640
- i0.ɵɵattribute("title", ctx.locale.delete);
641
- i0.ɵɵadvance(3);
642
- i0.ɵɵproperty("ngForOf", ctx.aligns);
700
+ i0.ɵɵproperty("ngIf", !ctx.snapshot.config.readOnly);
643
701
  i0.ɵɵadvance();
644
- i0.ɵɵproperty("ngForOf", ctx.distributes);
645
- i0.ɵɵadvance(2);
646
702
  i0.ɵɵattribute("title", ctx.locale.resetZoom);
647
703
  i0.ɵɵadvance(3);
648
704
  i0.ɵɵtextInterpolate1("", ctx.zoomPct, "%");
@@ -678,7 +734,7 @@ export class WhiteboardComponent {
678
734
  i0.ɵɵadvance();
679
735
  i0.ɵɵproperty("ngIf", ctx.openThread);
680
736
  i0.ɵɵadvance();
681
- i0.ɵɵproperty("ngIf", ctx.panelStyle);
737
+ i0.ɵɵproperty("ngIf", !ctx.snapshot.config.readOnly && ctx.panelStyle);
682
738
  i0.ɵɵadvance();
683
739
  i0.ɵɵproperty("ngIf", ctx.undo);
684
740
  i0.ɵɵadvance();
@@ -702,8 +758,12 @@ export class WhiteboardComponent {
702
758
  ],
703
759
  changeDetection: ChangeDetectionStrategy.OnPush,
704
760
  template: `
705
- <div class="bm-wb" [attr.data-theme]="darkMode ? 'dark' : null" [attr.dir]="dir ?? null" role="application" [attr.aria-label]="snapshot.ariaLabel" tabindex="0" (keydown)="onKeydown($event)">
761
+ <div class="bm-wb" [attr.data-theme]="darkMode ? 'dark' : null" [attr.dir]="dir ?? null" role="application" [attr.aria-label]="snapshot.ariaLabel" tabindex="0"
762
+ [attr.aria-activedescendant]="activeDescendantDomId()" (keydown)="onKeydown($event)">
706
763
  <div class="bm-wb__toolbar">
764
+ <button *ngIf="showUndoRedo && !snapshot.config.readOnly" type="button" class="bm-wb__btn bm-wb__btn--undo" [attr.aria-label]="locale.undo" [attr.title]="locale.undo" [disabled]="!snapshot.canUndo" (click)="onUndo()">↶</button>
765
+ <button *ngIf="showUndoRedo && !snapshot.config.readOnly" type="button" class="bm-wb__btn bm-wb__btn--redo" [attr.aria-label]="locale.redo" [attr.title]="locale.redo" [disabled]="!snapshot.canRedo" (click)="onRedo()">↷</button>
766
+ <span *ngIf="showUndoRedo && !snapshot.config.readOnly" class="bm-wb__toolbar-sep"></span>
707
767
  <button
708
768
  *ngFor="let t of tools"
709
769
  type="button"
@@ -713,6 +773,8 @@ export class WhiteboardComponent {
713
773
  [attr.data-tool]="t.id"
714
774
  (click)="onTool(t.id)">{{ t.glyph }}</button>
715
775
  <span class="bm-wb__toolbar-sep"></span>
776
+ <!-- mcp-64: Mutations-Cluster fällt im View-Only-Modus. -->
777
+ <ng-container *ngIf="!snapshot.config.readOnly">
716
778
  <button type="button" class="bm-wb__btn" [attr.title]="locale.bringToFront" [disabled]="!hasSel" (click)="onBringToFront()">⬆</button>
717
779
  <button type="button" class="bm-wb__btn" [attr.title]="locale.sendToBack" [disabled]="!hasSel" (click)="onSendToBack()">⬇</button>
718
780
  <button type="button" class="bm-wb__btn bm-wb__lock-btn" [attr.title]="locale.lock" [disabled]="!hasSel" (click)="onToggleLock()">🔒</button>
@@ -738,6 +800,7 @@ export class WhiteboardComponent {
738
800
  [disabled]="!canDistribute"
739
801
  (click)="onDistribute(d.axis)">{{ d.glyph }}</button>
740
802
  <span class="bm-wb__toolbar-sep"></span>
803
+ </ng-container>
741
804
  <button type="button" class="bm-wb__btn" [attr.title]="locale.resetZoom" (click)="onResetViewport()">⌖</button>
742
805
  <span class="bm-wb__toolbar-zoom">{{ zoomPct }}%</span>
743
806
  </div>
@@ -779,8 +842,11 @@ export class WhiteboardComponent {
779
842
  *ngFor="let v of snapshot.shapes; trackBy: trackShape"
780
843
  [shape]="v.shape"
781
844
  [selected]="v.selected"
845
+ [focused]="v.focused"
782
846
  [dropTarget]="snapshot.dropTargetId === v.shape.id"
783
847
  [lockedLabel]="locale.locked"
848
+ [domId]="shapeDomId(v.shape.id)"
849
+ [ariaLabel]="v.ariaLabel"
784
850
  (shapePointerDown)="onShapeDown(v.shape.id, $event)"
785
851
  (shapeDoubleClick)="onShapeDblClick(v.shape.id, $event)"></bm-wb-shape>
786
852
 
@@ -828,6 +894,7 @@ export class WhiteboardComponent {
828
894
  <bm-wb-comment-thread
829
895
  *ngIf="openThread as ot"
830
896
  [at]="ot.at"
897
+ [identity]="ot.id"
831
898
  [initial]="ot.text"
832
899
  [existing]="true"
833
900
  [resolved]="ot.resolved"
@@ -838,15 +905,17 @@ export class WhiteboardComponent {
838
905
  (delete)="onDeleteThread(ot.id)"></bm-wb-comment-thread>
839
906
  </div>
840
907
 
908
+ <!-- mcp-64 R1 (Review F7): das Stil-Panel ist eine reine Mutations-Fläche — im View-Only fällt es ganz. -->
841
909
  <bm-wb-style-panel
842
- *ngIf="panelStyle as ps"
910
+ *ngIf="!snapshot.config.readOnly && panelStyle as ps"
843
911
  [style]="ps"
844
912
  [locale]="locale"
845
913
  (styleInput)="onStyleInput($event)"></bm-wb-style-panel>
846
914
 
847
- <div *ngIf="undo as u" class="bm-wb__toast" role="status">
915
+ <!-- Feedback-only now (ticket-15): the undo/redo affordance moved to the persistent
916
+ toolbar buttons; the toast just narrates the last outcome. -->
917
+ <div *ngIf="undo as u" [class]="'bm-wb__toast' + (u.kind === 'error' ? ' bm-wb__toast--error' : '')" [attr.role]="u.kind === 'error' ? 'alert' : 'status'">
848
918
  <span>{{ u.description }}</span>
849
- <button type="button" class="bm-wb__toast-btn" (click)="onUndo()">{{ locale.undo }}</button>
850
919
  </div>
851
920
 
852
921
  <bm-wb-text-dialog
@@ -873,6 +942,8 @@ export class WhiteboardComponent {
873
942
  type: Input
874
943
  }], dir: [{
875
944
  type: Input
945
+ }], showUndoRedo: [{
946
+ type: Input
876
947
  }], onError: [{
877
948
  type: Input
878
949
  }], onSelectionChange: [{
@@ -881,5 +952,5 @@ export class WhiteboardComponent {
881
952
  type: ViewChild,
882
953
  args: ['viewportRef']
883
954
  }] }); })();
884
- (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(WhiteboardComponent, { className: "WhiteboardComponent", filePath: "components/whiteboard.ts", lineNumber: 227 }); })();
955
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(WhiteboardComponent, { className: "WhiteboardComponent", filePath: "components/whiteboard.ts", lineNumber: 243 }); })();
885
956
  //# sourceMappingURL=Whiteboard.js.map