@formicoidea/labre-core 0.37.0 → 0.38.2
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.
- package/dist/_pkgs/affine-block-frame/frame-manager.d.ts +31 -0
- package/dist/_pkgs/affine-block-frame/frame-manager.js +62 -2
- package/dist/_pkgs/affine-block-frame/frame-tool.js +6 -2
- package/dist/_pkgs/affine-block-surface/extensions/audit.js +12 -34
- package/dist/_pkgs/affine-block-surface/extensions/reading-toolbar.js +12 -12
- package/dist/_pkgs/affine-block-surface/extensions/reading.js +10 -28
- package/dist/_pkgs/affine-block-surface/extensions/validation.d.ts +321 -16
- package/dist/_pkgs/affine-block-surface/extensions/validation.js +945 -62
- package/dist/_pkgs/affine-block-surface/framework-background/facts.d.ts +24 -0
- package/dist/_pkgs/affine-block-surface/framework-background/facts.js +31 -0
- package/dist/_pkgs/affine-block-surface/framework-background/index.d.ts +1 -0
- package/dist/_pkgs/affine-block-surface/framework-background/index.js +1 -0
- package/dist/_pkgs/affine-block-surface/framework-background/stacking.d.ts +131 -0
- package/dist/_pkgs/affine-block-surface/framework-background/stacking.js +184 -0
- package/dist/_pkgs/affine-block-surface/utils/sort.d.ts +15 -1
- package/dist/_pkgs/affine-block-surface/utils/sort.js +30 -31
- package/dist/_pkgs/affine-block-surface/view.js +5 -0
- package/dist/_pkgs/affine-components/highlight-dropdown-menu/highlight-duotone-icon.js +8 -8
- package/dist/_pkgs/affine-components/highlight-dropdown-menu/text-duotone-icon.js +11 -11
- package/dist/_pkgs/affine-components/icons/text.js +426 -426
- package/dist/_pkgs/affine-gfx-group/element-renderer/utils.js +3 -1
- package/dist/_pkgs/affine-gfx-template/index.d.ts +1 -0
- package/dist/_pkgs/affine-gfx-template/index.js +1 -0
- package/dist/_pkgs/affine-gfx-template/make-snapshot.d.ts +16 -2
- package/dist/_pkgs/affine-gfx-template/make-snapshot.js +43 -4
- package/dist/_pkgs/affine-gfx-template/services/template-middlewares.js +1 -0
- package/dist/_pkgs/affine-gfx-template/services/template.d.ts +6 -0
- package/dist/_pkgs/affine-gfx-template/services/template.js +6 -0
- package/dist/_pkgs/affine-gfx-template/snapshot-from-action.d.ts +20 -0
- package/dist/_pkgs/affine-gfx-template/snapshot-from-action.js +205 -0
- package/dist/_pkgs/affine-gfx-template/toolbar/template-panel.js +4 -0
- package/dist/_pkgs/affine-gfx-template/toolbar/template-type.d.ts +13 -0
- package/dist/_pkgs/affine-inline-link/link-node/configs/toolbar.d.ts +11 -17
- package/dist/_pkgs/affine-inline-link/link-node/configs/toolbar.js +55 -14
- package/dist/_pkgs/affine-model/elements/cynefin/cynefin.d.ts +9 -20
- package/dist/_pkgs/affine-model/elements/cynefin/cynefin.js +7 -28
- package/dist/_pkgs/affine-model/elements/edgy/board.d.ts +9 -21
- package/dist/_pkgs/affine-model/elements/edgy/board.js +8 -29
- package/dist/_pkgs/affine-model/elements/edgy/facets.d.ts +14 -28
- package/dist/_pkgs/affine-model/elements/edgy/facets.js +12 -36
- package/dist/_pkgs/affine-model/elements/estuarine/estuarine.d.ts +9 -19
- package/dist/_pkgs/affine-model/elements/estuarine/estuarine.js +7 -27
- package/dist/_pkgs/affine-shared/services/link-preview-service/link-preview-service.d.ts +28 -0
- package/dist/_pkgs/affine-shared/services/link-preview-service/link-preview-service.js +20 -3
- package/dist/_pkgs/affine-widget-edgeless-auto-connect/index.js +124 -124
- package/dist/_pkgs/affine-widget-edgeless-zoom-toolbar/index.js +26 -26
- package/dist/_pkgs/affine-widget-keyboard-toolbar/icons.js +98 -98
- package/dist/_pkgs/affine-widget-page-dragging-area/index.js +10 -10
- package/dist/_pkgs/affine-widget-viewport-overlay/index.js +13 -13
- package/dist/_pkgs/data-view/core/group-by/renderer/boolean-group.js +11 -11
- package/dist/_pkgs/data-view/core/utils/menu-title.js +17 -17
- package/dist/_pkgs/data-view/view-presets/table/pc-virtual/group/top/group-title.js +18 -18
- package/dist/_pkgs/std/gfx/model/surface/surface-model.js +12 -2
- package/package.json +1 -1
|
@@ -35,6 +35,37 @@ export declare class EdgelessFrameManager extends GfxExtension {
|
|
|
35
35
|
}>(a: T, b: T): 0 | 1 | -1;
|
|
36
36
|
private _addChildrenToLegacyFrame;
|
|
37
37
|
private _addFrameBlock;
|
|
38
|
+
/**
|
|
39
|
+
* The index a frame gets when it is placed at `bound`.
|
|
40
|
+
*
|
|
41
|
+
* A frame's index is deliberately at the BACK of the stack, so it renders
|
|
42
|
+
* behind everything it owns. On a bare canvas that is right. On a framework
|
|
43
|
+
* board it is not: a Wardley map — a C4 board, a BPMN pool, any
|
|
44
|
+
* `FrameworkBackgroundElementModel` — is an OPAQUE canvas element, so a
|
|
45
|
+
* frame sent behind the whole surface goes behind the paint and only the
|
|
46
|
+
* part overhanging the board stays visible. The back of the SURFACE and the
|
|
47
|
+
* back of the BOARD are two different depths.
|
|
48
|
+
*
|
|
49
|
+
* So the frame lands just above the topmost background it covers, which is
|
|
50
|
+
* still behind every artefact drawn on that board — the depth a Wardley zone
|
|
51
|
+
* already needed, for the same reason, in #213. See
|
|
52
|
+
* {@link indexOverBackgrounds}.
|
|
53
|
+
*/
|
|
54
|
+
frameIndexAt(bound: Bound): string;
|
|
55
|
+
/**
|
|
56
|
+
* A frame DROPPED onto a framework background is raised above it, exactly as
|
|
57
|
+
* a frame drawn there is ({@link frameIndexAt}) — same gesture, arriving a
|
|
58
|
+
* moment later.
|
|
59
|
+
*
|
|
60
|
+
* Only ever upwards, and only while the frame is actually BELOW a background
|
|
61
|
+
* it overlaps. So a frame already above one is left alone (a drag writes an
|
|
62
|
+
* index at most once, and only on the move that buries it), and undo is safe
|
|
63
|
+
* for the same reason: the restored position is the one the frame came from,
|
|
64
|
+
* where nothing overlapping was above it. A frame the author sent to the
|
|
65
|
+
* back on purpose is only raised again if they move it — on a board, moving
|
|
66
|
+
* a frame means wanting to see it.
|
|
67
|
+
*/
|
|
68
|
+
private _watchFrameMoved;
|
|
38
69
|
private _watchElementAdded;
|
|
39
70
|
/**
|
|
40
71
|
* Whether `element` fully encloses `frame`.
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Overlay } from '../affine-block-surface/index.js';
|
|
1
|
+
import { indexOverBackgrounds, Overlay, stackedElementsOf, } from '../affine-block-surface/index.js';
|
|
2
2
|
import { FrameworkBackgroundElementModel } from '../affine-model/index.js';
|
|
3
3
|
import { EditPropsStore } from '../affine-shared/services/index.js';
|
|
4
4
|
import { DisposableGroup } from '../global/disposable/index.js';
|
|
@@ -100,6 +100,7 @@ export class EdgelessFrameManager extends GfxExtension {
|
|
|
100
100
|
super(gfx);
|
|
101
101
|
this._disposable = new DisposableGroup();
|
|
102
102
|
this._watchElementAdded();
|
|
103
|
+
this._watchFrameMoved();
|
|
103
104
|
}
|
|
104
105
|
static framePresentationComparator(a, b) {
|
|
105
106
|
function stringCompare(a, b) {
|
|
@@ -145,7 +146,7 @@ export class EdgelessFrameManager extends GfxExtension {
|
|
|
145
146
|
.applyLastProps('affine:frame', {
|
|
146
147
|
title: new Text(new Y.Text(`Frame ${this.frames.length + 1}`)),
|
|
147
148
|
xywh: bound.serialize(),
|
|
148
|
-
index: this.
|
|
149
|
+
index: this.frameIndexAt(bound),
|
|
149
150
|
presentationIndex: this.generatePresentationIndex(),
|
|
150
151
|
});
|
|
151
152
|
const id = this.gfx.doc.addBlock('affine:frame', props, surfaceModel);
|
|
@@ -155,6 +156,65 @@ export class EdgelessFrameManager extends GfxExtension {
|
|
|
155
156
|
}
|
|
156
157
|
return frameModel;
|
|
157
158
|
}
|
|
159
|
+
/**
|
|
160
|
+
* The index a frame gets when it is placed at `bound`.
|
|
161
|
+
*
|
|
162
|
+
* A frame's index is deliberately at the BACK of the stack, so it renders
|
|
163
|
+
* behind everything it owns. On a bare canvas that is right. On a framework
|
|
164
|
+
* board it is not: a Wardley map — a C4 board, a BPMN pool, any
|
|
165
|
+
* `FrameworkBackgroundElementModel` — is an OPAQUE canvas element, so a
|
|
166
|
+
* frame sent behind the whole surface goes behind the paint and only the
|
|
167
|
+
* part overhanging the board stays visible. The back of the SURFACE and the
|
|
168
|
+
* back of the BOARD are two different depths.
|
|
169
|
+
*
|
|
170
|
+
* So the frame lands just above the topmost background it covers, which is
|
|
171
|
+
* still behind every artefact drawn on that board — the depth a Wardley zone
|
|
172
|
+
* already needed, for the same reason, in #213. See
|
|
173
|
+
* {@link indexOverBackgrounds}.
|
|
174
|
+
*/
|
|
175
|
+
frameIndexAt(bound) {
|
|
176
|
+
return (indexOverBackgrounds(stackedElementsOf(this.gfx), bound) ??
|
|
177
|
+
this.gfx.layer.generateIndex(true));
|
|
178
|
+
}
|
|
179
|
+
/**
|
|
180
|
+
* A frame DROPPED onto a framework background is raised above it, exactly as
|
|
181
|
+
* a frame drawn there is ({@link frameIndexAt}) — same gesture, arriving a
|
|
182
|
+
* moment later.
|
|
183
|
+
*
|
|
184
|
+
* Only ever upwards, and only while the frame is actually BELOW a background
|
|
185
|
+
* it overlaps. So a frame already above one is left alone (a drag writes an
|
|
186
|
+
* index at most once, and only on the move that buries it), and undo is safe
|
|
187
|
+
* for the same reason: the restored position is the one the frame came from,
|
|
188
|
+
* where nothing overlapping was above it. A frame the author sent to the
|
|
189
|
+
* back on purpose is only raised again if they move it — on a board, moving
|
|
190
|
+
* a frame means wanting to see it.
|
|
191
|
+
*/
|
|
192
|
+
_watchFrameMoved() {
|
|
193
|
+
this._disposable.add(this.gfx.doc.slots.blockUpdated.subscribe(payload => {
|
|
194
|
+
if (payload.type !== 'update' ||
|
|
195
|
+
!payload.isLocal ||
|
|
196
|
+
payload.flavour !== 'affine:frame' ||
|
|
197
|
+
payload.props.key !== 'xywh') {
|
|
198
|
+
return;
|
|
199
|
+
}
|
|
200
|
+
const frame = this.gfx.getElementById(payload.id);
|
|
201
|
+
// A nested frame keeps its parent's ordering: `compare` reads the
|
|
202
|
+
// ancestor's index, so raising the child would change nothing.
|
|
203
|
+
if (!frame || !isFrameBlock(frame) || frame.group !== null)
|
|
204
|
+
return;
|
|
205
|
+
const siblings = stackedElementsOf(this.gfx, frame);
|
|
206
|
+
const box = frame.elementBound;
|
|
207
|
+
const buried = siblings.some(element => element.isBackground &&
|
|
208
|
+
element.index > frame.index &&
|
|
209
|
+
Bound.deserialize(element.xywh).isOverlapWithBound(box));
|
|
210
|
+
if (!buried)
|
|
211
|
+
return;
|
|
212
|
+
const over = indexOverBackgrounds(siblings, box);
|
|
213
|
+
if (over !== null) {
|
|
214
|
+
this.gfx.updateElement(frame, { index: over });
|
|
215
|
+
}
|
|
216
|
+
}));
|
|
217
|
+
}
|
|
158
218
|
_watchElementAdded() {
|
|
159
219
|
if (!this.gfx.surface) {
|
|
160
220
|
return;
|
|
@@ -44,12 +44,16 @@ export class FrameTool extends BaseTool {
|
|
|
44
44
|
return;
|
|
45
45
|
if (!this._frame) {
|
|
46
46
|
const frames = this.gfx.layer.blocks.filter(block => block.flavour === 'affine:frame');
|
|
47
|
+
const bound = Bound.fromPoints([this._startPoint, currentPoint]);
|
|
47
48
|
const props = this.std
|
|
48
49
|
.get(EditPropsStore)
|
|
49
50
|
.applyLastProps('affine:frame', {
|
|
50
51
|
title: new Text(new Y.Text(`Frame ${frames.length + 1}`)),
|
|
51
|
-
xywh:
|
|
52
|
-
|
|
52
|
+
xywh: bound.serialize(),
|
|
53
|
+
// Not the raw back of the stack: a frame drawn on a framework
|
|
54
|
+
// background must sit just above it, or the author draws blind
|
|
55
|
+
// behind an opaque map. See `EdgelessFrameManager.frameIndexAt`.
|
|
56
|
+
index: this.frameManager.frameIndexAt(bound),
|
|
53
57
|
presentationIndex: this.frameManager.generatePresentationIndex(),
|
|
54
58
|
});
|
|
55
59
|
const id = this.doc.addBlock('affine:frame', props, this.gfx.surface);
|
|
@@ -31,7 +31,7 @@ import { getAuditCriteria, requestAudit, TelemetryProvider, } from '../../affine
|
|
|
31
31
|
import { GfxControllerIdentifier, GfxPrimitiveElementModel, roleIsA, } from '../../std/gfx/index.js';
|
|
32
32
|
import { z } from 'zod';
|
|
33
33
|
import { backgroundInstanceZones, backgroundPlot, } from '../framework-background/def.js';
|
|
34
|
-
import { backgroundAxisFacts } from '../framework-background/facts.js';
|
|
34
|
+
import { backgroundAxisFacts, containingFrame, } from '../framework-background/facts.js';
|
|
35
35
|
import { ValidationManager, ValidationRuleIdentifier, } from './validation.js';
|
|
36
36
|
/**
|
|
37
37
|
* `map.audit` takes no required parameter: the assistant audits what is
|
|
@@ -105,6 +105,7 @@ function collectFrames(rules, elements) {
|
|
|
105
105
|
const profileId = el.validationProfile;
|
|
106
106
|
frames.push({
|
|
107
107
|
def,
|
|
108
|
+
id: el.id,
|
|
108
109
|
bound: el.elementBound,
|
|
109
110
|
fact: {
|
|
110
111
|
elementId: el.id,
|
|
@@ -135,41 +136,12 @@ function collectFrames(rules, elements) {
|
|
|
135
136
|
}
|
|
136
137
|
return frames;
|
|
137
138
|
}
|
|
138
|
-
/** Squared edge-to-edge gap — the same attribution heuristic the engine uses. */
|
|
139
|
-
function gapSquared(frame, bound) {
|
|
140
|
-
const dx = Math.max(frame.x - bound.maxX, bound.x - frame.maxX, 0);
|
|
141
|
-
const dy = Math.max(frame.y - bound.maxY, bound.y - frame.maxY, 0);
|
|
142
|
-
return dx * dx + dy * dy;
|
|
143
|
-
}
|
|
144
|
-
/**
|
|
145
|
-
* The frame an element belongs to: the one that CONTAINS it, failing that the
|
|
146
|
-
* nearest by edge-to-edge gap, ties broken by the smaller id.
|
|
147
|
-
*
|
|
148
|
-
* Deliberately the same answer `attributeBackground` gives inside the engine —
|
|
149
|
-
* an audit that attributed an element to a different map than the rule that
|
|
150
|
-
* indicted it would produce two findings about one component that disagree
|
|
151
|
-
* about which map it is on.
|
|
152
|
-
*/
|
|
153
|
-
function attribute(bound, frames) {
|
|
154
|
-
let nearest = null;
|
|
155
|
-
let nearestDistance = Infinity;
|
|
156
|
-
for (const frame of frames) {
|
|
157
|
-
if (frame.bound.contains(bound))
|
|
158
|
-
return frame;
|
|
159
|
-
const distance = gapSquared(frame.bound, bound);
|
|
160
|
-
if (distance < nearestDistance ||
|
|
161
|
-
(distance === nearestDistance &&
|
|
162
|
-
nearest !== null &&
|
|
163
|
-
frame.fact.elementId < nearest.fact.elementId)) {
|
|
164
|
-
nearestDistance = distance;
|
|
165
|
-
nearest = frame;
|
|
166
|
-
}
|
|
167
|
-
}
|
|
168
|
-
return nearest;
|
|
169
|
-
}
|
|
170
139
|
/**
|
|
171
140
|
* Where an element's centre sits inside a frame's PLOT, as ratios.
|
|
172
141
|
*
|
|
142
|
+
* A POSITION, not a membership test: it is asked only about an element some
|
|
143
|
+
* frame already contains, and answers where in that frame's plot it lies.
|
|
144
|
+
*
|
|
173
145
|
* Ratios of the plot and not of the element box: a Wardley transition drawn at
|
|
174
146
|
* `0.4` is 40 % of the PLOT, not of the map element, and the margin between the
|
|
175
147
|
* two is exactly where the axis titles live. `backgroundPlot` is the one place
|
|
@@ -262,7 +234,13 @@ export function collectAuditFacts(std) {
|
|
|
262
234
|
if (role === undefined || frameIds.has(el.id))
|
|
263
235
|
continue;
|
|
264
236
|
const bound = el.elementBound;
|
|
265
|
-
|
|
237
|
+
// Membership is WHOLE containment (PF2.4), and there is no nearest-frame
|
|
238
|
+
// fallback: an element straddling the edge of a map is not on it, so the
|
|
239
|
+
// audit reports it exactly as it reports one on bare canvas — id and role,
|
|
240
|
+
// no frame, no position, no zone. Anything else would tell an assistant a
|
|
241
|
+
// component is on a map the engine is simultaneously indicting it for
|
|
242
|
+
// hanging off.
|
|
243
|
+
const frame = containingFrame(bound, frames, candidate => candidate.bound);
|
|
266
244
|
if (frame === null) {
|
|
267
245
|
elementFacts.push({ id: el.id, role });
|
|
268
246
|
continue;
|
|
@@ -58,18 +58,18 @@ const READ_LABEL_FALLBACK = 'Read this component';
|
|
|
58
58
|
* Drawn inline like its neighbours: this package does not depend on
|
|
59
59
|
* `@blocksuite/icons` and one glyph is not worth a new dependency.
|
|
60
60
|
*/
|
|
61
|
-
const ReadIcon = html `<svg
|
|
62
|
-
width="20"
|
|
63
|
-
height="20"
|
|
64
|
-
viewBox="0 0 24 24"
|
|
65
|
-
fill="none"
|
|
66
|
-
stroke="currentColor"
|
|
67
|
-
stroke-width="2"
|
|
68
|
-
stroke-linecap="round"
|
|
69
|
-
stroke-linejoin="round"
|
|
70
|
-
>
|
|
71
|
-
<path d="M2 12s3.5-6 10-6 10 6 10 6-3.5 6-10 6-10-6-10-6z" />
|
|
72
|
-
<circle cx="12" cy="12" r="3" />
|
|
61
|
+
const ReadIcon = html `<svg
|
|
62
|
+
width="20"
|
|
63
|
+
height="20"
|
|
64
|
+
viewBox="0 0 24 24"
|
|
65
|
+
fill="none"
|
|
66
|
+
stroke="currentColor"
|
|
67
|
+
stroke-width="2"
|
|
68
|
+
stroke-linecap="round"
|
|
69
|
+
stroke-linejoin="round"
|
|
70
|
+
>
|
|
71
|
+
<path d="M2 12s3.5-6 10-6 10 6 10 6-3.5 6-10 6-10-6-10-6z" />
|
|
72
|
+
<circle cx="12" cy="12" r="3" />
|
|
73
73
|
</svg>`;
|
|
74
74
|
/** The command this module drives. Spelled once. */
|
|
75
75
|
const ELEMENT_READ_ID = 'element.read';
|
|
@@ -8,7 +8,7 @@ import { effect, signal } from '@preact/signals-core';
|
|
|
8
8
|
// reading is a one-way read of pure declaration data that must never pull a
|
|
9
9
|
// canvas in.
|
|
10
10
|
import { backgroundPlot, } from '../framework-background/def.js';
|
|
11
|
-
import { backgroundTransitionBands } from '../framework-background/facts.js';
|
|
11
|
+
import { backgroundTransitionBands, containingFrame, } from '../framework-background/facts.js';
|
|
12
12
|
/** Deepest role chain reported by {@link ReadingNodeType.specialises}. */
|
|
13
13
|
const MAX_ROLE_DEPTH = 32;
|
|
14
14
|
/** Numeric slack on the two geometry comparisons. Model units. */
|
|
@@ -127,7 +127,7 @@ const centreOf = (bound) => [
|
|
|
127
127
|
bound.y + bound.h / 2,
|
|
128
128
|
];
|
|
129
129
|
/**
|
|
130
|
-
* The frame the subject sits ON —
|
|
130
|
+
* The frame the subject sits ON — the one that WHOLLY CONTAINS it (PF2.4).
|
|
131
131
|
*
|
|
132
132
|
* Deliberately not the "nearest map" attribution the validation engine uses: a
|
|
133
133
|
* finding has to be filed against some map even when the subject is off in the
|
|
@@ -135,40 +135,22 @@ const centreOf = (bound) => [
|
|
|
135
135
|
* invented fact. A component beside the map has no phase, and the panel says
|
|
136
136
|
* nothing rather than something plausible.
|
|
137
137
|
*
|
|
138
|
-
* The
|
|
139
|
-
*
|
|
138
|
+
* The whole bound and not the centre: a node overhanging the edge of the map is
|
|
139
|
+
* not on it yet, which is what the engine already says about it.
|
|
140
140
|
*
|
|
141
141
|
* ## Two frames under one component
|
|
142
142
|
*
|
|
143
|
-
*
|
|
144
|
-
*
|
|
145
|
-
*
|
|
146
|
-
* maps of different sizes are a board that has not decided what it is, and a
|
|
147
|
-
* reading that quietly picked one of them by area would be harder to argue with
|
|
148
|
-
* than one that picked the first. The day a framework needs nesting, this is the
|
|
149
|
-
* one function to change.
|
|
143
|
+
* Ties go to the SMALLER id, which is the tie-break `containingFrame` and the
|
|
144
|
+
* engine share — one function for one question, and an answer that cannot
|
|
145
|
+
* depend on the order a `Y.Map` was rebuilt in.
|
|
150
146
|
*/
|
|
151
147
|
function frameOf(element, elements, profile) {
|
|
152
148
|
const frame = profile.frame;
|
|
153
149
|
if (!frame)
|
|
154
150
|
return null;
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
continue;
|
|
159
|
-
if (candidate.role === undefined)
|
|
160
|
-
continue;
|
|
161
|
-
if (!roleIsA(candidate.role, frame.backgroundRole, profile.roles))
|
|
162
|
-
continue;
|
|
163
|
-
const bound = candidate.elementBound;
|
|
164
|
-
if (cx >= bound.x &&
|
|
165
|
-
cx <= bound.x + bound.w &&
|
|
166
|
-
cy >= bound.y &&
|
|
167
|
-
cy <= bound.y + bound.h) {
|
|
168
|
-
return candidate;
|
|
169
|
-
}
|
|
170
|
-
}
|
|
171
|
-
return null;
|
|
151
|
+
return containingFrame(element.elementBound, elements.filter(candidate => candidate.id !== element.id &&
|
|
152
|
+
candidate.role !== undefined &&
|
|
153
|
+
roleIsA(candidate.role, frame.backgroundRole, profile.roles)), candidate => candidate.elementBound);
|
|
172
154
|
}
|
|
173
155
|
/**
|
|
174
156
|
* The phase, read from the position and the frame's DECLARED zones.
|