@atlaskit/editor-plugin-show-diff 19.0.3 → 19.0.4
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/CHANGELOG.md +11 -0
- package/dist/cjs/pm-plugins/calculateDiff/calculateDiffDecorations.js +57 -93
- package/dist/cjs/pm-plugins/decorations/colorSchemes/factory.js +1 -1
- package/dist/cjs/pm-plugins/decorations/colorSchemes/standard.js +1 -26
- package/dist/cjs/pm-plugins/decorations/createBlockChangedDecoration.js +12 -24
- package/dist/cjs/pm-plugins/decorations/createBlockChangedDecoration.styles.legacy.js +25 -57
- package/dist/cjs/pm-plugins/decorations/createChangedRowDecorationWidgets.js +22 -60
- package/dist/cjs/pm-plugins/decorations/createInlineChangedDecoration.js +8 -16
- package/dist/cjs/pm-plugins/decorations/createInlineChangedDecoration.styles.legacy.js +7 -22
- package/dist/cjs/pm-plugins/decorations/createNodeChangedDecorationWidget.js +34 -52
- package/dist/cjs/pm-plugins/decorations/decorationKeys.js +6 -14
- package/dist/cjs/pm-plugins/decorations/utils/createDeletedLineBreakWidget.js +3 -8
- package/dist/cjs/pm-plugins/decorations/utils/wrapBlockNodeView.js +132 -205
- package/dist/cjs/pm-plugins/decorations/utils/wrapBlockNodeViewStyles.js +13 -20
- package/dist/cjs/pm-plugins/decorations/utils/wrapBlockNodeViewStyles.legacy.js +6 -10
- package/dist/cjs/pm-plugins/getDefaultDiffType.js +10 -0
- package/dist/cjs/pm-plugins/getScrollableDecorations.js +5 -15
- package/dist/cjs/pm-plugins/main.js +45 -53
- package/dist/cjs/pm-plugins/resolveDiffContributors.js +18 -4
- package/dist/cjs/showDiffPlugin.js +14 -24
- package/dist/cjs/showDiffPluginType.js +1 -1
- package/dist/cjs/ui/ContributorTag/contributorAvatarRenderer.js +19 -9
- package/dist/cjs/ui/ContributorTag/contributorTagController.js +28 -3
- package/dist/cjs/ui/ContributorTag/contributorTagIcons.js +2 -2
- package/dist/es2019/pm-plugins/calculateDiff/calculateDiffDecorations.js +67 -105
- package/dist/es2019/pm-plugins/decorations/colorSchemes/factory.js +1 -1
- package/dist/es2019/pm-plugins/decorations/colorSchemes/standard.js +0 -26
- package/dist/es2019/pm-plugins/decorations/createBlockChangedDecoration.js +11 -23
- package/dist/es2019/pm-plugins/decorations/createBlockChangedDecoration.styles.legacy.js +25 -57
- package/dist/es2019/pm-plugins/decorations/createChangedRowDecorationWidgets.js +22 -60
- package/dist/es2019/pm-plugins/decorations/createInlineChangedDecoration.js +8 -18
- package/dist/es2019/pm-plugins/decorations/createInlineChangedDecoration.styles.legacy.js +8 -23
- package/dist/es2019/pm-plugins/decorations/createNodeChangedDecorationWidget.js +34 -54
- package/dist/es2019/pm-plugins/decorations/decorationKeys.js +6 -16
- package/dist/es2019/pm-plugins/decorations/utils/createDeletedLineBreakWidget.js +2 -7
- package/dist/es2019/pm-plugins/decorations/utils/wrapBlockNodeView.js +53 -125
- package/dist/es2019/pm-plugins/decorations/utils/wrapBlockNodeViewStyles.js +11 -12
- package/dist/es2019/pm-plugins/decorations/utils/wrapBlockNodeViewStyles.legacy.js +6 -7
- package/dist/es2019/pm-plugins/getDefaultDiffType.js +2 -0
- package/dist/es2019/pm-plugins/getScrollableDecorations.js +6 -19
- package/dist/es2019/pm-plugins/main.js +49 -65
- package/dist/es2019/pm-plugins/resolveDiffContributors.js +18 -3
- package/dist/es2019/showDiffPlugin.js +12 -24
- package/dist/es2019/showDiffPluginType.js +1 -1
- package/dist/es2019/ui/ContributorTag/contributorAvatarRenderer.js +19 -9
- package/dist/es2019/ui/ContributorTag/contributorTagController.js +30 -2
- package/dist/es2019/ui/ContributorTag/contributorTagIcons.js +2 -2
- package/dist/esm/pm-plugins/calculateDiff/calculateDiffDecorations.js +56 -92
- package/dist/esm/pm-plugins/decorations/colorSchemes/factory.js +1 -1
- package/dist/esm/pm-plugins/decorations/colorSchemes/standard.js +0 -26
- package/dist/esm/pm-plugins/decorations/createBlockChangedDecoration.js +12 -24
- package/dist/esm/pm-plugins/decorations/createBlockChangedDecoration.styles.legacy.js +25 -57
- package/dist/esm/pm-plugins/decorations/createChangedRowDecorationWidgets.js +22 -60
- package/dist/esm/pm-plugins/decorations/createInlineChangedDecoration.js +8 -16
- package/dist/esm/pm-plugins/decorations/createInlineChangedDecoration.styles.legacy.js +8 -23
- package/dist/esm/pm-plugins/decorations/createNodeChangedDecorationWidget.js +34 -52
- package/dist/esm/pm-plugins/decorations/decorationKeys.js +6 -14
- package/dist/esm/pm-plugins/decorations/utils/createDeletedLineBreakWidget.js +3 -8
- package/dist/esm/pm-plugins/decorations/utils/wrapBlockNodeView.js +132 -205
- package/dist/esm/pm-plugins/decorations/utils/wrapBlockNodeViewStyles.js +13 -20
- package/dist/esm/pm-plugins/decorations/utils/wrapBlockNodeViewStyles.legacy.js +6 -10
- package/dist/esm/pm-plugins/getDefaultDiffType.js +4 -0
- package/dist/esm/pm-plugins/getScrollableDecorations.js +6 -16
- package/dist/esm/pm-plugins/main.js +44 -52
- package/dist/esm/pm-plugins/resolveDiffContributors.js +18 -4
- package/dist/esm/showDiffPlugin.js +14 -24
- package/dist/esm/showDiffPluginType.js +1 -1
- package/dist/esm/ui/ContributorTag/contributorAvatarRenderer.js +19 -9
- package/dist/esm/ui/ContributorTag/contributorTagController.js +28 -3
- package/dist/esm/ui/ContributorTag/contributorTagIcons.js +2 -2
- package/dist/types/pm-plugins/decorations/colorSchemes/factory.d.ts +1 -1
- package/dist/types/pm-plugins/decorations/colorSchemes/standard.d.ts +0 -3
- package/dist/types/pm-plugins/decorations/colorSchemes/types.d.ts +1 -1
- package/dist/types/pm-plugins/decorations/createBlockChangedDecoration.d.ts +1 -3
- package/dist/types/pm-plugins/decorations/createBlockChangedDecoration.styles.legacy.d.ts +2 -3
- package/dist/types/pm-plugins/decorations/createChangedRowDecorationWidgets.d.ts +1 -3
- package/dist/types/pm-plugins/decorations/createInlineChangedDecoration.d.ts +2 -3
- package/dist/types/pm-plugins/decorations/createInlineChangedDecoration.styles.legacy.d.ts +2 -3
- package/dist/types/pm-plugins/decorations/createNodeChangedDecorationWidget.d.ts +2 -3
- package/dist/types/pm-plugins/decorations/decorationKeys.d.ts +5 -8
- package/dist/types/pm-plugins/decorations/utils/createDeletedLineBreakWidget.d.ts +3 -5
- package/dist/types/pm-plugins/decorations/utils/wrapBlockNodeView.d.ts +4 -6
- package/dist/types/pm-plugins/decorations/utils/wrapBlockNodeViewStyles.d.ts +3 -4
- package/dist/types/pm-plugins/decorations/utils/wrapBlockNodeViewStyles.legacy.d.ts +4 -4
- package/dist/types/pm-plugins/getDefaultDiffType.d.ts +2 -0
- package/dist/types/pm-plugins/getScrollableDecorations.d.ts +1 -2
- package/dist/types/pm-plugins/main.d.ts +0 -1
- package/dist/types/showDiffPluginType.d.ts +1 -3
- package/docs/smart-diff-design.md +13 -29
- package/package.json +5 -5
- package/dist/cjs/pm-plugins/isExtendedEnabled.js +0 -23
- package/dist/es2019/pm-plugins/isExtendedEnabled.js +0 -13
- package/dist/esm/pm-plugins/isExtendedEnabled.js +0 -17
- package/dist/types/pm-plugins/isExtendedEnabled.d.ts +0 -12
|
@@ -8,8 +8,8 @@ import { getActiveDiffAnnouncement } from '../ui/DiffNavigation/announceActiveDi
|
|
|
8
8
|
import { calculateDiffDecorations } from './calculateDiff/calculateDiffDecorations';
|
|
9
9
|
import { isDiffDecoration, isDiffDecorationSpec } from './decorations/decorationKeys';
|
|
10
10
|
import { enforceCustomStepRegisters } from './enforceCustomStepRegisters';
|
|
11
|
+
import { getDefaultDiffType } from './getDefaultDiffType';
|
|
11
12
|
import { getScrollableDecorations } from './getScrollableDecorations';
|
|
12
|
-
import { getDefaultDiffType, isExtendedEnabled } from './isExtendedEnabled';
|
|
13
13
|
import { NodeViewSerializer } from './NodeViewSerializer';
|
|
14
14
|
import { rebindReveal } from './revealAnimation';
|
|
15
15
|
import { scrollToDecoration } from './scrollToDiff';
|
|
@@ -61,21 +61,18 @@ export const createPlugin = (config, getIntl, api, onEditorView) => {
|
|
|
61
61
|
state: {
|
|
62
62
|
init(_, _state) {
|
|
63
63
|
// We do initial setup after we setup the editor view
|
|
64
|
-
const defaultDiffType = getDefaultDiffType();
|
|
65
64
|
return {
|
|
66
65
|
steps: [],
|
|
67
66
|
stepAttributions: [],
|
|
68
67
|
originalDoc: undefined,
|
|
69
68
|
decorations: DecorationSet.empty,
|
|
70
69
|
isDisplayingChanges: false,
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
diffDescriptors: []
|
|
78
|
-
} : {})
|
|
70
|
+
isInverted: false,
|
|
71
|
+
diffType: getDefaultDiffType(),
|
|
72
|
+
hideDeletedDiffs: false,
|
|
73
|
+
hideAddedDiffsUnderline: false,
|
|
74
|
+
showIndicators: false,
|
|
75
|
+
diffDescriptors: []
|
|
79
76
|
};
|
|
80
77
|
},
|
|
81
78
|
apply: (tr, currentPluginState, oldState, newState) => {
|
|
@@ -83,7 +80,7 @@ export const createPlugin = (config, getIntl, api, onEditorView) => {
|
|
|
83
80
|
let newPluginState = currentPluginState;
|
|
84
81
|
if (meta) {
|
|
85
82
|
if ((meta === null || meta === void 0 ? void 0 : meta.action) === 'SHOW_DIFF' || (meta === null || meta === void 0 ? void 0 : meta.action) === 'REVEAL_COMPLETE') {
|
|
86
|
-
var _newPluginState$color, _newPluginState, _newPluginState2, _newPluginState3, _newPluginState4, _newPluginState5, _newPluginState6, _newPluginState7, _newPluginState8, _newPluginState9, _newPluginState0
|
|
83
|
+
var _newPluginState$color, _newPluginState, _newPluginState2, _newPluginState3, _newPluginState4, _newPluginState5, _newPluginState6, _newPluginState7, _newPluginState8, _newPluginState9, _newPluginState0;
|
|
87
84
|
// REVEAL_COMPLETE repaints with the reveal dropped, so the decorations render their
|
|
88
85
|
// ordinary resting style. Without it the reveal stays in state indefinitely and the
|
|
89
86
|
// next unrelated repaint re-emits the hidden, zero-width highlight with no animation
|
|
@@ -115,26 +112,22 @@ export const createPlugin = (config, getIntl, api, onEditorView) => {
|
|
|
115
112
|
activeIndexPos: newPluginState.activeIndexPos,
|
|
116
113
|
api,
|
|
117
114
|
tagMountContext,
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
reveal: (_newPluginState1 = newPluginState) === null || _newPluginState1 === void 0 ? void 0 : _newPluginState1.reveal
|
|
130
|
-
} : {})
|
|
115
|
+
isInverted: (_newPluginState2 = newPluginState) === null || _newPluginState2 === void 0 ? void 0 : _newPluginState2.isInverted,
|
|
116
|
+
diffType: (_newPluginState3 = newPluginState) === null || _newPluginState3 === void 0 ? void 0 : _newPluginState3.diffType,
|
|
117
|
+
hideDeletedDiffs: (_newPluginState4 = newPluginState) === null || _newPluginState4 === void 0 ? void 0 : _newPluginState4.hideDeletedDiffs,
|
|
118
|
+
hideAddedDiffsUnderline: (_newPluginState5 = newPluginState) === null || _newPluginState5 === void 0 ? void 0 : _newPluginState5.hideAddedDiffsUnderline,
|
|
119
|
+
showIndicators: (_newPluginState6 = newPluginState) === null || _newPluginState6 === void 0 ? void 0 : _newPluginState6.showIndicators,
|
|
120
|
+
smartThresholds: (_newPluginState7 = newPluginState) === null || _newPluginState7 === void 0 ? void 0 : _newPluginState7.smartThresholds,
|
|
121
|
+
deletedDiffPlacement: (_newPluginState8 = newPluginState) === null || _newPluginState8 === void 0 ? void 0 : _newPluginState8.deletedDiffPlacement,
|
|
122
|
+
inlineDeletedDiffPlacement: (_newPluginState9 = newPluginState) === null || _newPluginState9 === void 0 ? void 0 : _newPluginState9.inlineDeletedDiffPlacement,
|
|
123
|
+
// SHOW_DIFF only. The scroll-to-next recalculation further down deliberately
|
|
124
|
+
// omits this so stepping through changes cannot replay the choreography.
|
|
125
|
+
reveal: (_newPluginState0 = newPluginState) === null || _newPluginState0 === void 0 ? void 0 : _newPluginState0.reveal
|
|
131
126
|
});
|
|
132
127
|
// Update the decorations and their ids
|
|
133
128
|
newPluginState.decorations = decorations;
|
|
134
129
|
newPluginState.contributorTags = contributorTags;
|
|
135
|
-
|
|
136
|
-
newPluginState.diffDescriptors = diffDescriptors;
|
|
137
|
-
}
|
|
130
|
+
newPluginState.diffDescriptors = diffDescriptors;
|
|
138
131
|
} else if ((meta === null || meta === void 0 ? void 0 : meta.action) === 'HIDE_DIFF') {
|
|
139
132
|
newPluginState = {
|
|
140
133
|
...currentPluginState,
|
|
@@ -150,20 +143,17 @@ export const createPlugin = (config, getIntl, api, onEditorView) => {
|
|
|
150
143
|
* Reset isInverted & diffType state when hiding diffs
|
|
151
144
|
* Otherwise this should persist for the diff-showing session
|
|
152
145
|
*/
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
diffDescriptors: []
|
|
159
|
-
} : {})
|
|
146
|
+
isInverted: false,
|
|
147
|
+
diffType: getDefaultDiffType(),
|
|
148
|
+
hideDeletedDiffs: false,
|
|
149
|
+
hideAddedDiffsUnderline: false,
|
|
150
|
+
diffDescriptors: []
|
|
160
151
|
};
|
|
161
152
|
} else if ((meta === null || meta === void 0 ? void 0 : meta.action) === 'SCROLL_TO_NEXT' || (meta === null || meta === void 0 ? void 0 : meta.action) === 'SCROLL_TO_PREVIOUS') {
|
|
162
|
-
var _newPluginState11;
|
|
163
153
|
// Update the active index in plugin state and recalculate decorations
|
|
164
|
-
const decorations = getScrollableDecorations(currentPluginState.decorations, newState.doc
|
|
154
|
+
const decorations = getScrollableDecorations(currentPluginState.decorations, newState.doc);
|
|
165
155
|
if (decorations.length > 0) {
|
|
166
|
-
var _currentPluginState$a, _newPluginState$color2,
|
|
156
|
+
var _currentPluginState$a, _newPluginState$color2, _newPluginState1;
|
|
167
157
|
// Initialize to -1 if undefined so that the first "next" scroll takes us to index 0 (first change).
|
|
168
158
|
// This allows the UI to start with no selection and only highlight on first user interaction.
|
|
169
159
|
let nextIndex = (_currentPluginState$a = currentPluginState.activeIndex) !== null && _currentPluginState$a !== void 0 ? _currentPluginState$a : -1;
|
|
@@ -196,27 +186,23 @@ export const createPlugin = (config, getIntl, api, onEditorView) => {
|
|
|
196
186
|
state: newState,
|
|
197
187
|
pluginState: newPluginState,
|
|
198
188
|
nodeViewSerializer,
|
|
199
|
-
colorScheme: (_newPluginState$color2 = (
|
|
189
|
+
colorScheme: (_newPluginState$color2 = (_newPluginState1 = newPluginState) === null || _newPluginState1 === void 0 ? void 0 : _newPluginState1.colorScheme) !== null && _newPluginState$color2 !== void 0 ? _newPluginState$color2 : config === null || config === void 0 ? void 0 : config.colorScheme,
|
|
200
190
|
intl: getIntl(),
|
|
201
191
|
activeIndexPos: newPluginState.activeIndexPos,
|
|
202
192
|
api,
|
|
203
193
|
tagMountContext,
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
inlineDeletedDiffPlacement: newPluginState.inlineDeletedDiffPlacement
|
|
213
|
-
} : {})
|
|
194
|
+
isInverted: newPluginState.isInverted,
|
|
195
|
+
diffType: newPluginState.diffType,
|
|
196
|
+
hideDeletedDiffs: newPluginState.hideDeletedDiffs,
|
|
197
|
+
hideAddedDiffsUnderline: newPluginState.hideAddedDiffsUnderline,
|
|
198
|
+
showIndicators: newPluginState.showIndicators,
|
|
199
|
+
smartThresholds: newPluginState.smartThresholds,
|
|
200
|
+
deletedDiffPlacement: newPluginState.deletedDiffPlacement,
|
|
201
|
+
inlineDeletedDiffPlacement: newPluginState.inlineDeletedDiffPlacement
|
|
214
202
|
});
|
|
215
203
|
newPluginState.decorations = updatedDecorations;
|
|
216
204
|
newPluginState.contributorTags = updatedContributorTags;
|
|
217
|
-
|
|
218
|
-
newPluginState.diffDescriptors = updatedDiffDescriptors;
|
|
219
|
-
}
|
|
205
|
+
newPluginState.diffDescriptors = updatedDiffDescriptors;
|
|
220
206
|
}
|
|
221
207
|
} else {
|
|
222
208
|
newPluginState = {
|
|
@@ -263,10 +249,10 @@ export const createPlugin = (config, getIntl, api, onEditorView) => {
|
|
|
263
249
|
// Scroll to the first decoration when scrollIntoView was requested.
|
|
264
250
|
// Use the same filtered/position-sorted list as the active-index path
|
|
265
251
|
// so "first" reliably means the topmost scrollable diff in the document.
|
|
266
|
-
if (pluginState !== null && pluginState !== void 0 && pluginState.scrollIntoView
|
|
252
|
+
if (pluginState !== null && pluginState !== void 0 && pluginState.scrollIntoView) {
|
|
267
253
|
var _cancelPendingScrollT;
|
|
268
254
|
(_cancelPendingScrollT = cancelPendingScrollToDecoration) === null || _cancelPendingScrollT === void 0 ? void 0 : _cancelPendingScrollT();
|
|
269
|
-
cancelPendingScrollToDecoration = scrollToDecoration(view, getScrollableDecorations(pluginState.decorations, view.state.doc
|
|
255
|
+
cancelPendingScrollToDecoration = scrollToDecoration(view, getScrollableDecorations(pluginState.decorations, view.state.doc), undefined, api);
|
|
270
256
|
|
|
271
257
|
// Reset the flag so we don't scroll again on subsequent updates
|
|
272
258
|
view.dispatch(view.state.tr.setMeta(showDiffPluginKey, {
|
|
@@ -280,7 +266,7 @@ export const createPlugin = (config, getIntl, api, onEditorView) => {
|
|
|
280
266
|
if ((pluginState === null || pluginState === void 0 ? void 0 : pluginState.activeIndex) !== undefined && activeIndexChanged) {
|
|
281
267
|
var _cancelPendingScrollT2;
|
|
282
268
|
(_cancelPendingScrollT2 = cancelPendingScrollToDecoration) === null || _cancelPendingScrollT2 === void 0 ? void 0 : _cancelPendingScrollT2();
|
|
283
|
-
const scrollableDecorations = getScrollableDecorations(pluginState.decorations, view.state.doc
|
|
269
|
+
const scrollableDecorations = getScrollableDecorations(pluginState.decorations, view.state.doc);
|
|
284
270
|
const activeDecoration = scrollableDecorations[pluginState.activeIndex];
|
|
285
271
|
if (activeDecoration) {
|
|
286
272
|
// EDITOR-7926: use editor-common's command instead of the expand plugin API to
|
|
@@ -293,17 +279,15 @@ export const createPlugin = (config, getIntl, api, onEditorView) => {
|
|
|
293
279
|
// screen-reader user gets silence. Announced through the live region rather than by
|
|
294
280
|
// focusing the change, since the "next change" control has to stay focused to be
|
|
295
281
|
// pressed again. After the scroll above, so the announcement never precedes it.
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
api === null || api === void 0 ? void 0 : (_api$accessibilityUti = api.accessibilityUtils) === null || _api$accessibilityUti === void 0 ? void 0 : _api$accessibilityUti.actions.ariaNotify(announcement);
|
|
306
|
-
}
|
|
282
|
+
const announcement = getActiveDiffAnnouncement({
|
|
283
|
+
activeIndex: pluginState.activeIndex,
|
|
284
|
+
contributorTags: pluginState.contributorTags,
|
|
285
|
+
decorations: scrollableDecorations,
|
|
286
|
+
intl: getIntl()
|
|
287
|
+
});
|
|
288
|
+
if (announcement) {
|
|
289
|
+
var _api$accessibilityUti;
|
|
290
|
+
api === null || api === void 0 ? void 0 : (_api$accessibilityUti = api.accessibilityUtils) === null || _api$accessibilityUti === void 0 ? void 0 : _api$accessibilityUti.actions.ariaNotify(announcement);
|
|
307
291
|
}
|
|
308
292
|
}
|
|
309
293
|
},
|
|
@@ -10,9 +10,19 @@ const ROVO_AGENT_TYPES = new Set(['convo-ai', 'rovo_chat']);
|
|
|
10
10
|
const SHOW_DIFF_AGENT_BRANDS = {
|
|
11
11
|
'agent-brand-claude': 'claude',
|
|
12
12
|
'agent-brand-chatgpt': 'chatgpt',
|
|
13
|
+
'agent-brand-figma': 'figma',
|
|
14
|
+
'agent-brand-lovable': 'lovable',
|
|
15
|
+
'agent-brand-replit': 'replit',
|
|
13
16
|
'agent-brand-rovo': 'rovo'
|
|
14
17
|
};
|
|
15
18
|
|
|
19
|
+
/**
|
|
20
|
+
* Brands that prefer the account's real avatar over their fixed glyph when the invoking profile
|
|
21
|
+
* has one. Claude/ChatGPT/Rovo intentionally keep their fixed glyph always (see `AGENT_KIND_ICONS`
|
|
22
|
+
* in `contributorAvatarRenderer.ts`).
|
|
23
|
+
*/
|
|
24
|
+
const AVATAR_ELIGIBLE_BRANDS = new Set(['figma', 'lovable', 'replit']);
|
|
25
|
+
|
|
16
26
|
/** Known external agent types emitted by Confluence's agent identification service that carry
|
|
17
27
|
* no `@atlaskit/agent-color` brand — a generic labelled fallback. */
|
|
18
28
|
const EXTERNAL_AGENT_NAMES = {
|
|
@@ -53,19 +63,24 @@ const resolveUser = (userId, profilesByAccountId) => {
|
|
|
53
63
|
const resolveAgent = (attribution, profilesByAccountId) => {
|
|
54
64
|
var _attribution$agentTyp2, _attribution$agentId2;
|
|
55
65
|
const agentType = (_attribution$agentTyp2 = attribution.agentType) === null || _attribution$agentTyp2 === void 0 ? void 0 : _attribution$agentTyp2.trim().toLowerCase();
|
|
66
|
+
// `agentType` may be a named id (e.g. `mcp_lovable_agent`) or a display name (e.g. `lovable`).
|
|
56
67
|
const brand = agentType ? getThirdPartyAgentColor({
|
|
68
|
+
agentNamedId: agentType,
|
|
57
69
|
agentName: agentType
|
|
58
70
|
}) : undefined;
|
|
59
71
|
const diffBrand = brand ? SHOW_DIFF_AGENT_BRANDS[brand.scheme] : undefined;
|
|
72
|
+
const agentId = (_attribution$agentId2 = attribution.agentId) === null || _attribution$agentId2 === void 0 ? void 0 : _attribution$agentId2.trim();
|
|
73
|
+
const agentProfile = agentId ? profilesByAccountId.get(agentId) : undefined;
|
|
60
74
|
if (diffBrand && brand) {
|
|
61
75
|
return {
|
|
62
76
|
agentKind: diffBrand,
|
|
63
77
|
kind: 'agent',
|
|
64
|
-
name: brand.name
|
|
78
|
+
name: brand.name,
|
|
79
|
+
...(AVATAR_ELIGIBLE_BRANDS.has(diffBrand) && agentProfile !== null && agentProfile !== void 0 && agentProfile.avatarUrl ? {
|
|
80
|
+
avatarUrl: agentProfile.avatarUrl
|
|
81
|
+
} : {})
|
|
65
82
|
};
|
|
66
83
|
}
|
|
67
|
-
const agentId = (_attribution$agentId2 = attribution.agentId) === null || _attribution$agentId2 === void 0 ? void 0 : _attribution$agentId2.trim();
|
|
68
|
-
const agentProfile = agentId ? profilesByAccountId.get(agentId) : undefined;
|
|
69
84
|
if (agentProfile) {
|
|
70
85
|
return {
|
|
71
86
|
...(agentProfile.agentBrand ? {
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { UNSAFE_expValNoExposure } from '@atlaskit/platform-feature-experiments/unsafe-exp-val-no-exposure';
|
|
3
3
|
import { fg } from '@atlaskit/platform-feature-flags/fg';
|
|
4
|
-
import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
|
|
5
4
|
import { areAttributionColorGatesEnabled, resolveContributors } from './pm-plugins/decorations/colorSchemes/attributions';
|
|
6
5
|
import { getDeletedWidgets } from './pm-plugins/getDeletedWidgets';
|
|
7
6
|
import { getScrollableDecorations } from './pm-plugins/getScrollableDecorations';
|
|
@@ -67,12 +66,10 @@ export const showDiffPlugin = ({
|
|
|
67
66
|
showDiff: params => ({
|
|
68
67
|
tr
|
|
69
68
|
}) => {
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
});
|
|
75
|
-
}
|
|
69
|
+
var _api$userIntent;
|
|
70
|
+
api === null || api === void 0 ? void 0 : (_api$userIntent = api.userIntent) === null || _api$userIntent === void 0 ? void 0 : _api$userIntent.commands.setCurrentUserIntent('viewingDiff')({
|
|
71
|
+
tr
|
|
72
|
+
});
|
|
76
73
|
const reveal = resolveReveal(params === null || params === void 0 ? void 0 : params.reveal, editorView);
|
|
77
74
|
|
|
78
75
|
// Capture snapshot BEFORE transaction dispatch (last moment outgoing DOM exists).
|
|
@@ -99,15 +96,13 @@ export const showDiffPlugin = ({
|
|
|
99
96
|
hideDiff: ({
|
|
100
97
|
tr
|
|
101
98
|
}) => {
|
|
99
|
+
var _api$userIntent2;
|
|
102
100
|
if (editorView) {
|
|
103
101
|
cancelReveal(editorView);
|
|
104
102
|
}
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
tr
|
|
109
|
-
});
|
|
110
|
-
}
|
|
103
|
+
api === null || api === void 0 ? void 0 : (_api$userIntent2 = api.userIntent) === null || _api$userIntent2 === void 0 ? void 0 : _api$userIntent2.commands.setCurrentUserIntent('default')({
|
|
104
|
+
tr
|
|
105
|
+
});
|
|
111
106
|
return tr.setMeta(showDiffPluginKey, {
|
|
112
107
|
steps: [],
|
|
113
108
|
stepAttributions: [],
|
|
@@ -141,9 +136,6 @@ export const showDiffPlugin = ({
|
|
|
141
136
|
}];
|
|
142
137
|
},
|
|
143
138
|
contentComponent: () => {
|
|
144
|
-
if (!expValEquals('platform_editor_diff_plugin_extended', 'isEnabled', true)) {
|
|
145
|
-
return null;
|
|
146
|
-
}
|
|
147
139
|
// Rendered here sharing decoration anchor span DOM context (tags mount separately).
|
|
148
140
|
return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(IndicatorBarContentComponent, {
|
|
149
141
|
api: api
|
|
@@ -154,9 +146,7 @@ export const showDiffPlugin = ({
|
|
|
154
146
|
return {
|
|
155
147
|
isDisplayingChanges: false,
|
|
156
148
|
activeIndex: undefined,
|
|
157
|
-
|
|
158
|
-
diffDescriptors: []
|
|
159
|
-
} : {})
|
|
149
|
+
diffDescriptors: []
|
|
160
150
|
};
|
|
161
151
|
}
|
|
162
152
|
const pluginState = showDiffPluginKey.getState(editorState);
|
|
@@ -165,11 +155,9 @@ export const showDiffPlugin = ({
|
|
|
165
155
|
isDisplayingChanges: decorationCount.length > 0,
|
|
166
156
|
activeIndex: pluginState === null || pluginState === void 0 ? void 0 : pluginState.activeIndex,
|
|
167
157
|
numberOfChanges: decorationCount.length,
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
showIndicators: pluginState === null || pluginState === void 0 ? void 0 : pluginState.showIndicators
|
|
172
|
-
} : {})
|
|
158
|
+
contributorTags: pluginState === null || pluginState === void 0 ? void 0 : pluginState.contributorTags,
|
|
159
|
+
diffDescriptors: pluginState === null || pluginState === void 0 ? void 0 : pluginState.diffDescriptors,
|
|
160
|
+
showIndicators: pluginState === null || pluginState === void 0 ? void 0 : pluginState.showIndicators
|
|
173
161
|
};
|
|
174
162
|
}
|
|
175
163
|
};
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
|
|
20
20
|
/** Branded agent presentations supported by contributor tags. */
|
|
21
21
|
|
|
22
|
-
export const DIFF_AGENT_BRANDS = new Set(['rovo', 'claude', 'chatgpt']);
|
|
22
|
+
export const DIFF_AGENT_BRANDS = new Set(['rovo', 'claude', 'chatgpt', 'figma', 'lovable', 'replit']);
|
|
23
23
|
|
|
24
24
|
/** The brand id `@atlaskit/agent-color` registers each `AgentBrandColorScheme` under. */
|
|
25
25
|
|
|
@@ -5,11 +5,11 @@ import { convertToInlineCss } from '@atlaskit/editor-common/lazy-node-view';
|
|
|
5
5
|
import { getContributorTagIcon } from './contributorTagIcons';
|
|
6
6
|
|
|
7
7
|
/**
|
|
8
|
-
* Agent kinds with a custom contributor-tag icon.
|
|
9
|
-
* `
|
|
10
|
-
* `
|
|
11
|
-
*
|
|
12
|
-
*
|
|
8
|
+
* Agent kinds with a custom contributor-tag icon. Figma/Lovable/Replit have no entry here — they
|
|
9
|
+
* always render the real avatar `resolveDiffContributors` supplies, falling back to the generic
|
|
10
|
+
* `aiAgent` glyph (see `showContributorIcon`) on load failure. The declared type stays the wider
|
|
11
|
+
* `TagContributor['agentKind']` so indexing below (with `'identified' | 'external'` in play too)
|
|
12
|
+
* stays safely partial.
|
|
13
13
|
*/
|
|
14
14
|
const AGENT_KIND_ICONS = {
|
|
15
15
|
claude: 'claude',
|
|
@@ -17,6 +17,14 @@ const AGENT_KIND_ICONS = {
|
|
|
17
17
|
rovo: 'rovoHex'
|
|
18
18
|
};
|
|
19
19
|
|
|
20
|
+
/**
|
|
21
|
+
* Brands that always render their fixed glyph, even when the contributor also carries an
|
|
22
|
+
* `avatarUrl`. Figma/Lovable/Replit are excluded here and use the real avatar when
|
|
23
|
+
* `resolveDiffContributors` supplies one, falling back to the generic `aiAgent` glyph on load
|
|
24
|
+
* failure.
|
|
25
|
+
*/
|
|
26
|
+
const FIXED_GLYPH_AGENT_KINDS = new Set(['claude', 'chatgpt', 'rovo']);
|
|
27
|
+
|
|
20
28
|
/** The size `@atlaskit/avatar`'s `xxsmall` rendered at. */
|
|
21
29
|
const AVATAR_SIZE = AVATAR_SIZES.xxsmall;
|
|
22
30
|
/** `xxsmall` also carried a `space.025` margin — the same 2px — which is where the ring is painted. */
|
|
@@ -108,13 +116,15 @@ export const contributorAvatarRenderer = ({
|
|
|
108
116
|
shape.appendChild(fallback);
|
|
109
117
|
return;
|
|
110
118
|
}
|
|
111
|
-
|
|
119
|
+
const icon = (_AGENT_KIND_ICONS = AGENT_KIND_ICONS[(_contributor$agentKin = contributor.agentKind) !== null && _contributor$agentKin !== void 0 ? _contributor$agentKin : 'external']) !== null && _AGENT_KIND_ICONS !== void 0 ? _AGENT_KIND_ICONS : 'aiAgent';
|
|
120
|
+
shape.appendChild(getContributorTagIcon(icon, doc));
|
|
112
121
|
};
|
|
113
122
|
if (contributor.avatarUrl) {
|
|
114
123
|
var _contributor$agentKin2;
|
|
115
|
-
//
|
|
116
|
-
|
|
117
|
-
|
|
124
|
+
// Claude/ChatGPT/Rovo always use their fixed glyph, even when the profile also has an
|
|
125
|
+
// avatar URL. Other agents (e.g. Figma/Lovable/Replit) and users prefer the real avatar.
|
|
126
|
+
const usesFixedGlyph = isAgent && FIXED_GLYPH_AGENT_KINDS.has((_contributor$agentKin2 = contributor.agentKind) !== null && _contributor$agentKin2 !== void 0 ? _contributor$agentKin2 : 'external');
|
|
127
|
+
if (usesFixedGlyph) {
|
|
118
128
|
showContributorIcon();
|
|
119
129
|
} else {
|
|
120
130
|
image = doc.createElement('img');
|
|
@@ -25,6 +25,15 @@ const getTagAccent = ({
|
|
|
25
25
|
const chatgptBrandColor = getThirdPartyAgentColor({
|
|
26
26
|
agentName: 'chatgpt'
|
|
27
27
|
});
|
|
28
|
+
const figmaBrandColor = getThirdPartyAgentColor({
|
|
29
|
+
agentName: 'figma'
|
|
30
|
+
});
|
|
31
|
+
const lovableBrandColor = getThirdPartyAgentColor({
|
|
32
|
+
agentName: 'lovable'
|
|
33
|
+
});
|
|
34
|
+
const replitBrandColor = getThirdPartyAgentColor({
|
|
35
|
+
agentName: 'replit'
|
|
36
|
+
});
|
|
28
37
|
|
|
29
38
|
/** Brand accents for agent kinds with no ADS token match. New agents opt in by adding an entry. */
|
|
30
39
|
const AGENT_KIND_ACCENT_OVERRIDES = {
|
|
@@ -37,6 +46,24 @@ const AGENT_KIND_ACCENT_OVERRIDES = {
|
|
|
37
46
|
background: chatgptBrandColor.bold,
|
|
38
47
|
text: chatgptBrandColor.boldText
|
|
39
48
|
}
|
|
49
|
+
} : {}),
|
|
50
|
+
...(figmaBrandColor ? {
|
|
51
|
+
figma: {
|
|
52
|
+
background: figmaBrandColor.bold,
|
|
53
|
+
text: figmaBrandColor.boldText
|
|
54
|
+
}
|
|
55
|
+
} : {}),
|
|
56
|
+
...(lovableBrandColor ? {
|
|
57
|
+
lovable: {
|
|
58
|
+
background: lovableBrandColor.bold,
|
|
59
|
+
text: lovableBrandColor.boldText
|
|
60
|
+
}
|
|
61
|
+
} : {}),
|
|
62
|
+
...(replitBrandColor ? {
|
|
63
|
+
replit: {
|
|
64
|
+
background: replitBrandColor.bold,
|
|
65
|
+
text: replitBrandColor.boldText
|
|
66
|
+
}
|
|
40
67
|
} : {})
|
|
41
68
|
};
|
|
42
69
|
|
|
@@ -330,8 +357,9 @@ export class ContributorTagController {
|
|
|
330
357
|
stackIndex
|
|
331
358
|
});
|
|
332
359
|
if (index < stack.length - 1) {
|
|
333
|
-
//
|
|
334
|
-
|
|
360
|
+
// Sits the leading avatar of a connected pair flush against the one behind it, with
|
|
361
|
+
// no overlap and no extra gap.
|
|
362
|
+
avatar.element.style.setProperty('margin-inline-end', '0');
|
|
335
363
|
}
|
|
336
364
|
container.appendChild(avatar.element);
|
|
337
365
|
this.avatars.push(avatar);
|
|
@@ -25,8 +25,8 @@ const AI_AGENT_ICON_SVG = `<svg width="12" height="12" fill="none" viewBox="0 0
|
|
|
25
25
|
/** `RovoHexIcon` from `@atlaskit/logo/rovo-hex/icon`, at the 16px `xxsmall` renders. */
|
|
26
26
|
const ROVO_HEX_ICON_SVG = `<svg width="16" height="16" viewBox="0 0 24 24" role="presentation" style="display:block"><path fill="#1868db" fill-rule="evenodd" d="m13.227 16.789-7.154 4.169-3.403-1.96a2.72 2.72 0 0 1-1.362-2.355V7.366c0-.973.518-1.87 1.361-2.354l6.044-3.487-.038.114a3.6 3.6 0 0 0-.172 1.088v9.278c0 1.274.68 2.45 1.786 3.085z" clip-rule="evenodd"/><path fill="#6a9a23" fill-rule="evenodd" d="m11.296 15.671-7.193 4.153 6.607 3.812a2.73 2.73 0 0 0 2.676.026l.048-.033a2.73 2.73 0 0 0 1.232-1.525 2.7 2.7 0 0 0 .127-.822v-3.594z" clip-rule="evenodd"/><path fill="#af59e1" fill-rule="evenodd" d="m21.477 5.003-4.404-2.539-5.904 4.89 2.69 1.556a3.56 3.56 0 0 1 1.785 3.086v9.277a3.6 3.6 0 0 1-.21 1.202l6.044-3.486a2.71 2.71 0 0 0 1.362-2.355V7.357c0-.97-.521-1.87-1.363-2.354" clip-rule="evenodd"/><path fill="#fca700" fill-rule="evenodd" d="M12.74 8.266 9.353 6.312V2.718c0-.283.044-.56.127-.821A2.73 2.73 0 0 1 10.71.372V.37a.4.4 0 0 0 .048-.033 2.73 2.73 0 0 1 2.676.026l6.499 3.75z" clip-rule="evenodd"/></svg>`;
|
|
27
27
|
|
|
28
|
-
/**
|
|
29
|
-
const CLAUDE_ICON_SVG = `<svg width="
|
|
28
|
+
/** Claude hexagon lockup from the brand asset: the hexagon and knot glyph both baked in. */
|
|
29
|
+
const CLAUDE_ICON_SVG = `<svg width="16" height="18" viewBox="0 0 16 18" fill="none" role="presentation" style="display:block"><path fill="#D97757" d="M14.5007 3.28903L9.50384 0.402344C8.5736 -0.13506 7.42701 -0.134016 6.49774 0.405082L1.49458 3.30759C0.569434 3.8443 0 4.83297 0 5.90253V11.1804C0 12.2519 0.571497 13.2421 1.49931 13.7781L6.49931 16.6666C7.42787 17.203 8.57213 17.203 9.50069 16.6666L14.5007 13.7781C15.4285 13.2421 16 12.2519 16 11.1804V5.88671C16 4.8152 15.4285 3.82504 14.5007 3.28903Z"/><path fill="#FAF9F6" d="M5.19791 10.055L7.0123 9.03681L7.04267 8.94806L7.0123 8.89907H6.92357L6.62 8.88034L5.58321 8.85232L4.68418 8.815L3.81317 8.76826L3.59367 8.72158L3.38818 8.4507L3.4092 8.31526L3.59367 8.1915L3.85754 8.21485L4.44133 8.25455L5.317 8.31526L5.95216 8.35262L6.89321 8.4507H7.04267L7.06368 8.38999L7.0123 8.35262L6.97261 8.31526L6.06658 7.70112L5.08582 7.05196L4.5721 6.67834L4.29422 6.48919L4.15411 6.31172L4.09339 5.92409L4.34559 5.64621L4.68418 5.66956L4.77058 5.69291L5.11384 5.95678L5.84708 6.52422L6.80448 7.22943L6.94459 7.34618L7.00063 7.30649L7.00763 7.27846L6.94459 7.17338L6.42385 6.23233L5.86809 5.27492L5.62057 4.87795L5.55519 4.63977C5.53183 4.54169 5.51549 4.45996 5.51549 4.35956L5.80271 3.96959L5.9615 3.91821L6.34446 3.96959L6.50558 4.10969L6.74377 4.65378L7.12907 5.51077L7.72686 6.676L7.90199 7.0216L7.99539 7.34152L8.0304 7.43959H8.09113V7.38354L8.14018 6.72737L8.23124 5.92175L8.31999 4.88496L8.35032 4.59307L8.49511 4.24279L8.78232 4.05365L9.00649 4.16107L9.19098 4.42494L9.16533 4.5954L9.05555 5.30762L8.84073 6.42381L8.70062 7.17105H8.78232L8.87574 7.07764L9.25401 6.57559L9.88922 5.78165L10.1694 5.4664L10.4963 5.11847L10.7065 4.95267H11.1035L11.3953 5.38701L11.2646 5.83535L10.8559 6.35375L10.5173 6.79276L10.0316 7.4466L9.72807 7.96966L9.7561 8.0117L9.82849 8.00469L10.926 7.77118L11.5191 7.66376L12.2266 7.54233L12.5466 7.69178L12.5816 7.84356L12.4555 8.15414L11.6989 8.34095L10.8116 8.51842L9.48985 8.83136L9.4735 8.84303L9.49223 8.86637L10.0877 8.92241L10.3422 8.93639H10.9657L12.1262 9.02283L12.4298 9.2236L12.612 9.46881L12.5816 9.6556L12.1146 9.89382L11.4841 9.74434L10.013 9.3941L9.50858 9.26797H9.43849V9.31004L9.85882 9.721L10.6294 10.4169L11.5938 11.3136L11.6429 11.5354L11.5191 11.7106L11.3884 11.6918L10.5407 11.0544L10.2137 10.7672L9.4735 10.1436H9.42451V10.209L9.59495 10.4589L10.4963 11.8133L10.543 12.2289L10.4776 12.3644L10.2441 12.4461L9.98726 12.3994L9.45952 11.6592L8.91544 10.8255L8.47645 10.0783L8.42271 10.1086L8.16352 12.8991L8.04207 13.0416L7.76188 13.149L7.52837 12.9715L7.40461 12.6843L7.52837 12.1168L7.67781 11.3766L7.79925 10.7881L7.90899 10.0573L7.97438 9.81443L7.96971 9.79808L7.916 9.80507L7.36491 10.5617L6.5266 11.6942L5.86342 12.4041L5.70463 12.4671L5.42909 12.3247L5.45477 12.0702L5.60889 11.8436L6.5266 10.6761L7.08002 9.95217L7.4373 9.53421L7.43497 9.47349H7.41395L4.97607 11.0567L4.54174 11.1127L4.35493 10.9376L4.37828 10.6504L4.46702 10.557L5.20024 10.0526L5.19791 10.055Z"/></svg>`;
|
|
30
30
|
|
|
31
31
|
/** ChatGPT hexagon lockup from the brand asset: the hexagon and knot glyph both baked in. */
|
|
32
32
|
const CHATGPT_ICON_SVG = `<svg width="16" height="18" viewBox="0 0 16 18" fill="none" role="presentation" style="display:block"><path fill="#14120B" d="M14.5007 3.289L9.50384 0.402314C8.5736 -0.13509 7.42701 -0.134047 6.49774 0.405051L1.49458 3.30756C0.569434 3.84427 0 4.83294 0 5.9025V11.1804C0 12.2519 0.571497 13.2421 1.49931 13.7781L6.49931 16.6666C7.42787 17.203 8.57213 17.203 9.50069 16.6666L14.5007 13.7781C15.4285 13.2421 16 12.2519 16 11.1804V5.88668C16 4.81517 15.4285 3.82501 14.5007 3.289Z"/><path fill="white" d="M12.255 7.39338C12.4813 6.54514 12.2618 5.60258 11.5963 4.93713C10.9309 4.2717 9.9884 4.05217 9.1401 4.27852C8.51863 3.65837 7.59268 3.37721 6.68362 3.62082C5.77456 3.86436 5.11322 4.57087 4.88512 5.41867C4.03733 5.64676 3.33082 6.30819 3.08727 7.21717C2.84372 8.12623 3.12482 9.05218 3.74503 9.67365C3.51868 10.5219 3.73823 11.4645 4.40366 12.1299C5.06909 12.7953 6.01159 13.0149 6.85992 12.7885C7.48137 13.4087 8.4074 13.6898 9.31638 13.4463C10.2254 13.2027 10.8868 12.4962 11.1149 11.6485C11.9627 11.4203 12.6692 10.7589 12.9127 9.84993C13.1563 8.94089 12.8752 8.01491 12.255 7.39347V7.39338ZM11.1878 5.34578C11.6387 5.79673 11.8247 6.41226 11.7457 6.99902L9.62799 5.77632C9.53872 5.72478 9.42871 5.72478 9.3395 5.77632L6.85992 7.20789V6.26917C6.85992 6.20333 6.89519 6.1417 6.95226 6.10877L8.84042 5.01867C9.58854 4.60079 10.5519 4.7099 11.1878 5.34578H11.1878ZM8.00001 7.21703L9.14016 7.87529V9.19183L8.00001 9.85009L6.85984 9.19183V7.87529L8.00001 7.21703ZM5.37616 6.04832C5.38831 5.19153 5.96453 4.41177 6.83319 4.17899C7.44917 4.01397 8.07524 4.16069 8.54389 4.52241L6.42609 5.74505C6.33682 5.79656 6.28184 5.89186 6.28184 5.99489V8.85803L5.4689 8.38867C5.41189 8.35573 5.37616 8.29433 5.37616 8.22846V6.04826V6.04832ZM3.64542 7.36674C3.81044 6.75079 4.25056 6.28191 4.79817 6.05694V8.50232C4.79817 8.60534 4.85315 8.70061 4.94241 8.75216L7.42202 10.1837L6.60904 10.6531C6.55203 10.686 6.48098 10.6862 6.42397 10.6533L4.53581 9.56321C3.79984 9.12427 3.41272 8.23534 3.64542 7.36674ZM4.81224 11.7213C4.36129 11.2704 4.17534 10.6549 4.25429 10.0681L6.37201 11.2908C6.4613 11.3423 6.57129 11.3423 6.6605 11.2908L9.1401 9.85923V10.7979C9.1401 10.8638 9.10483 10.9254 9.04774 10.9584L7.15958 12.0485C6.41145 12.4663 5.44809 12.3572 4.81215 11.7213H4.81224ZM10.6238 11.0188C10.6117 11.8756 10.0355 12.6554 9.1668 12.8881C8.55083 13.0532 7.92476 12.9064 7.45613 12.5447L9.57391 11.322C9.6632 11.2705 9.71816 11.1753 9.71816 11.0722V8.20906L10.5311 8.67845C10.5881 8.71139 10.6238 8.77279 10.6238 8.83866V11.0189V11.0188ZM12.3546 9.70035C12.1896 10.3163 11.7494 10.7852 11.2018 11.0101V8.5648C11.2018 8.46178 11.1469 8.36648 11.0576 8.31496L8.57798 6.88339L9.39095 6.41401C9.44796 6.38107 9.51902 6.38085 9.57603 6.41378L11.4642 7.50388C12.2002 7.94285 12.5873 8.83178 12.3546 9.70035Z"/></svg>`;
|