@anu3ev/fabric-image-editor 0.1.82 → 0.2.1

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.
Files changed (2) hide show
  1. package/dist/main.js +1159 -857
  2. package/package.json +1 -1
package/dist/main.js CHANGED
@@ -1,49 +1,49 @@
1
1
  var Ne = Object.defineProperty, Le = Object.defineProperties;
2
- var we = Object.getOwnPropertyDescriptors;
3
- var F = Object.getOwnPropertySymbols;
4
- var Me = Object.prototype.hasOwnProperty, me = Object.prototype.propertyIsEnumerable;
5
- var fe = (c, e, t) => e in c ? Ne(c, e, { enumerable: !0, configurable: !0, writable: !0, value: t }) : c[e] = t, I = (c, e) => {
2
+ var Te = Object.getOwnPropertyDescriptors;
3
+ var V = Object.getOwnPropertySymbols;
4
+ var Me = Object.prototype.hasOwnProperty, pe = Object.prototype.propertyIsEnumerable;
5
+ var me = (d, e, t) => e in d ? Ne(d, e, { enumerable: !0, configurable: !0, writable: !0, value: t }) : d[e] = t, I = (d, e) => {
6
6
  for (var t in e || (e = {}))
7
- Me.call(e, t) && fe(c, t, e[t]);
8
- if (F)
9
- for (var t of F(e))
10
- me.call(e, t) && fe(c, t, e[t]);
11
- return c;
12
- }, be = (c, e) => Le(c, we(e));
13
- var V = (c, e) => {
7
+ Me.call(e, t) && me(d, t, e[t]);
8
+ if (V)
9
+ for (var t of V(e))
10
+ pe.call(e, t) && me(d, t, e[t]);
11
+ return d;
12
+ }, be = (d, e) => Le(d, Te(e));
13
+ var G = (d, e) => {
14
14
  var t = {};
15
- for (var s in c)
16
- Me.call(c, s) && e.indexOf(s) < 0 && (t[s] = c[s]);
17
- if (c != null && F)
18
- for (var s of F(c))
19
- e.indexOf(s) < 0 && me.call(c, s) && (t[s] = c[s]);
15
+ for (var s in d)
16
+ Me.call(d, s) && e.indexOf(s) < 0 && (t[s] = d[s]);
17
+ if (d != null && V)
18
+ for (var s of V(d))
19
+ e.indexOf(s) < 0 && pe.call(d, s) && (t[s] = d[s]);
20
20
  return t;
21
21
  };
22
- var j = (c, e, t) => new Promise((s, a) => {
23
- var n = (r) => {
22
+ var y = (d, e, t) => new Promise((s, n) => {
23
+ var o = (r) => {
24
24
  try {
25
25
  i(t.next(r));
26
- } catch (d) {
27
- a(d);
26
+ } catch (c) {
27
+ n(c);
28
28
  }
29
- }, o = (r) => {
29
+ }, a = (r) => {
30
30
  try {
31
31
  i(t.throw(r));
32
- } catch (d) {
33
- a(d);
32
+ } catch (c) {
33
+ n(c);
34
34
  }
35
- }, i = (r) => r.done ? s(r.value) : Promise.resolve(r.value).then(n, o);
36
- i((t = t.apply(c, e)).next());
35
+ }, i = (r) => r.done ? s(r.value) : Promise.resolve(r.value).then(o, a);
36
+ i((t = t.apply(d, e)).next());
37
37
  });
38
- import { ActiveSelection as v, util as W, controlsUtils as Te, InteractiveFabricObject as je, loadSVGFromURL as ke, FabricImage as Z, Point as X, Gradient as pe, Rect as _e, Circle as Be, Triangle as xe, Group as te, Canvas as Re, Pattern as Ue } from "fabric";
39
- import { create as ze } from "jsondiffpatch";
38
+ import { ActiveSelection as v, util as F, controlsUtils as ke, InteractiveFabricObject as je, loadSVGFromURL as _e, FabricImage as z, Point as $, Gradient as ye, Rect as Be, Circle as xe, Triangle as Re, Group as U, Canvas as Ue, Pattern as Ye } from "fabric";
39
+ import { create as Ze } from "jsondiffpatch";
40
40
  import He from "diff-match-patch";
41
- var Ze = "useandom-26T198340PX75pxJACKVERYMINDBUSHWOLF_GQZbfghjklqvwyzrict", A = function() {
41
+ var ze = "useandom-26T198340PX75pxJACKVERYMINDBUSHWOLF_GQZbfghjklqvwyzrict", C = function() {
42
42
  for (var e = arguments.length > 0 && arguments[0] !== void 0 ? arguments[0] : 21, t = "", s = crypto.getRandomValues(new Uint8Array(e |= 0)); e--; )
43
- t += Ze[s[e] & 63];
43
+ t += ze[s[e] & 63];
44
44
  return t;
45
45
  };
46
- class P {
46
+ class W {
47
47
  /**
48
48
  * Конструктор принимает редактор и опции.
49
49
  * @param params
@@ -61,7 +61,7 @@ class P {
61
61
  * @param params.options.adaptCanvasToContainerOnResize — адаптировать канвас к размерам контейнера при изменении размеров окна
62
62
  */
63
63
  constructor({ editor: e, options: t = {} }) {
64
- this.isDragging = !1, this.lastMouseX = 0, this.lastMouseY = 0, this.isUndoRedoKeyPressed = !1, this.isSpacePressed = !1, this.savedSelection = [], this.canvasDragging = !1, this.mouseWheelZooming = !1, this.bringToFrontOnSelection = !1, this.resetObjectFitByDoubleClick = !1, this.copyObjectsByHotkey = !1, this.pasteImageFromClipboard = !1, this.undoRedoByHotKeys = !1, this.selectAllByHotkey = !1, this.deleteObjectsByHotkey = !1, this.adaptCanvasToContainerOnResize = !1, this.editor = e, this.canvas = e.canvas, this.options = t, this.handleContainerResizeBound = P.debounce(this.handleContainerResize.bind(this), 500), this.handleCopyEventBound = this.handleCopyEvent.bind(this), this.handlePasteEventBound = this.handlePasteEvent.bind(this), this.handleUndoRedoEventBound = this.handleUndoRedoEvent.bind(this), this.handleUndoRedoKeyUpBound = this.handleUndoRedoKeyUp.bind(this), this.handleSelectAllEventBound = this.handleSelectAllEvent.bind(this), this.handleDeleteObjectsEventBound = this.handleDeleteObjectsEvent.bind(this), this.handleSpaceKeyDownBound = this.handleSpaceKeyDown.bind(this), this.handleSpaceKeyUpBound = this.handleSpaceKeyUp.bind(this), this.handleObjectModifiedHistoryBound = P.debounce(this.handleObjectModifiedHistory.bind(this), 300), this.handleObjectRotatingHistoryBound = P.debounce(this.handleObjectRotatingHistory.bind(this), 300), this.handleObjectAddedHistoryBound = this.handleObjectAddedHistory.bind(this), this.handleObjectRemovedHistoryBound = this.handleObjectRemovedHistory.bind(this), this.handleOverlayUpdateBound = this.handleOverlayUpdate.bind(this), this.handleBackgroundUpdateBound = this.handleBackgroundUpdate.bind(this), this.handleCanvasDragStartBound = this.handleCanvasDragStart.bind(this), this.handleCanvasDraggingBound = this.handleCanvasDragging.bind(this), this.handleCanvasDragEndBound = this.handleCanvasDragEnd.bind(this), this.handleMouseWheelZoomBound = this.handleMouseWheelZoom.bind(this), this.handleBringToFrontBound = this.handleBringToFront.bind(this), this.handleResetObjectFitBound = this.handleResetObjectFit.bind(this), this.handleLockedSelectionBound = this._filterLockedSelection.bind(this), this.init();
64
+ this.isDragging = !1, this.lastMouseX = 0, this.lastMouseY = 0, this.isUndoRedoKeyPressed = !1, this.isSpacePressed = !1, this.savedSelection = [], this.canvasDragging = !1, this.mouseWheelZooming = !1, this.bringToFrontOnSelection = !1, this.resetObjectFitByDoubleClick = !1, this.copyObjectsByHotkey = !1, this.pasteImageFromClipboard = !1, this.undoRedoByHotKeys = !1, this.selectAllByHotkey = !1, this.deleteObjectsByHotkey = !1, this.adaptCanvasToContainerOnResize = !1, this.editor = e, this.canvas = e.canvas, this.options = t, this.handleContainerResizeBound = W.debounce(this.handleContainerResize.bind(this), 500), this.handleCopyEventBound = this.handleCopyEvent.bind(this), this.handlePasteEventBound = this.handlePasteEvent.bind(this), this.handleUndoRedoEventBound = this.handleUndoRedoEvent.bind(this), this.handleUndoRedoKeyUpBound = this.handleUndoRedoKeyUp.bind(this), this.handleSelectAllEventBound = this.handleSelectAllEvent.bind(this), this.handleDeleteObjectsEventBound = this.handleDeleteObjectsEvent.bind(this), this.handleSpaceKeyDownBound = this.handleSpaceKeyDown.bind(this), this.handleSpaceKeyUpBound = this.handleSpaceKeyUp.bind(this), this.handleObjectModifiedHistoryBound = W.debounce(this.handleObjectModifiedHistory.bind(this), 300), this.handleObjectRotatingHistoryBound = W.debounce(this.handleObjectRotatingHistory.bind(this), 300), this.handleObjectAddedHistoryBound = this.handleObjectAddedHistory.bind(this), this.handleObjectRemovedHistoryBound = this.handleObjectRemovedHistory.bind(this), this.handleOverlayUpdateBound = this.handleOverlayUpdate.bind(this), this.handleBackgroundUpdateBound = this.handleBackgroundUpdate.bind(this), this.handleCanvasDragStartBound = this.handleCanvasDragStart.bind(this), this.handleCanvasDraggingBound = this.handleCanvasDragging.bind(this), this.handleCanvasDragEndBound = this.handleCanvasDragEnd.bind(this), this.handleMouseWheelZoomBound = this.handleMouseWheelZoom.bind(this), this.handleBringToFrontBound = this.handleBringToFront.bind(this), this.handleResetObjectFitBound = this.handleResetObjectFit.bind(this), this.handleLockedSelectionBound = this._filterLockedSelection.bind(this), this.init();
65
65
  }
66
66
  /**
67
67
  * Инициализация всех обработчиков согласно опциям.
@@ -71,15 +71,15 @@ class P {
71
71
  adaptCanvasToContainerOnResize: e,
72
72
  canvasDragging: t,
73
73
  mouseWheelZooming: s,
74
- bringToFrontOnSelection: a,
75
- copyObjectsByHotkey: n,
76
- pasteImageFromClipboard: o,
74
+ bringToFrontOnSelection: n,
75
+ copyObjectsByHotkey: o,
76
+ pasteImageFromClipboard: a,
77
77
  undoRedoByHotKeys: i,
78
78
  selectAllByHotkey: r,
79
- deleteObjectsByHotkey: d,
79
+ deleteObjectsByHotkey: c,
80
80
  resetObjectFitByDoubleClick: h
81
81
  } = this.options;
82
- t && (this.canvas.on("mouse:down", this.handleCanvasDragStartBound), this.canvas.on("mouse:move", this.handleCanvasDraggingBound), this.canvas.on("mouse:up", this.handleCanvasDragEndBound), document.addEventListener("keydown", this.handleSpaceKeyDownBound, { capture: !0 }), document.addEventListener("keyup", this.handleSpaceKeyUpBound, { capture: !0 })), s && this.canvas.on("mouse:wheel", this.handleMouseWheelZoomBound), a && (this.canvas.on("selection:created", this.handleBringToFrontBound), this.canvas.on("selection:updated", this.handleBringToFrontBound)), h && this.canvas.on("mouse:dblclick", this.handleResetObjectFitBound), e && window.addEventListener("resize", this.handleContainerResizeBound, { capture: !0 }), n && document.addEventListener("keydown", this.handleCopyEventBound, { capture: !0 }), o && document.addEventListener("paste", this.handlePasteEventBound, { capture: !0 }), i && (document.addEventListener("keydown", this.handleUndoRedoEventBound, { capture: !0 }), document.addEventListener("keyup", this.handleUndoRedoKeyUpBound, { capture: !0 })), r && document.addEventListener("keydown", this.handleSelectAllEventBound, { capture: !0 }), d && document.addEventListener("keydown", this.handleDeleteObjectsEventBound, { capture: !0 }), this.canvas.on("object:modified", this.handleObjectModifiedHistoryBound), this.canvas.on("object:rotating", this.handleObjectRotatingHistoryBound), this.canvas.on("object:added", this.handleObjectAddedHistoryBound), this.canvas.on("object:removed", this.handleObjectRemovedHistoryBound), this.canvas.on("object:added", this.handleOverlayUpdateBound), this.canvas.on("selection:created", this.handleOverlayUpdateBound), this.canvas.on("selection:created", this.handleLockedSelectionBound), this.canvas.on("selection:updated", this.handleLockedSelectionBound), this.canvas.on("object:added", this.handleBackgroundUpdateBound), this.canvas.on("selection:created", this.handleBackgroundUpdateBound);
82
+ t && (this.canvas.on("mouse:down", this.handleCanvasDragStartBound), this.canvas.on("mouse:move", this.handleCanvasDraggingBound), this.canvas.on("mouse:up", this.handleCanvasDragEndBound), document.addEventListener("keydown", this.handleSpaceKeyDownBound, { capture: !0 }), document.addEventListener("keyup", this.handleSpaceKeyUpBound, { capture: !0 })), s && this.canvas.on("mouse:wheel", this.handleMouseWheelZoomBound), n && (this.canvas.on("selection:created", this.handleBringToFrontBound), this.canvas.on("selection:updated", this.handleBringToFrontBound)), h && this.canvas.on("mouse:dblclick", this.handleResetObjectFitBound), e && window.addEventListener("resize", this.handleContainerResizeBound, { capture: !0 }), o && document.addEventListener("keydown", this.handleCopyEventBound, { capture: !0 }), a && document.addEventListener("paste", this.handlePasteEventBound, { capture: !0 }), i && (document.addEventListener("keydown", this.handleUndoRedoEventBound, { capture: !0 }), document.addEventListener("keyup", this.handleUndoRedoKeyUpBound, { capture: !0 })), r && document.addEventListener("keydown", this.handleSelectAllEventBound, { capture: !0 }), c && document.addEventListener("keydown", this.handleDeleteObjectsEventBound, { capture: !0 }), this.canvas.on("object:modified", this.handleObjectModifiedHistoryBound), this.canvas.on("object:rotating", this.handleObjectRotatingHistoryBound), this.canvas.on("object:added", this.handleObjectAddedHistoryBound), this.canvas.on("object:removed", this.handleObjectRemovedHistoryBound), this.canvas.on("object:added", this.handleOverlayUpdateBound), this.canvas.on("selection:created", this.handleOverlayUpdateBound), this.canvas.on("selection:created", this.handleLockedSelectionBound), this.canvas.on("selection:updated", this.handleLockedSelectionBound), this.canvas.on("object:added", this.handleBackgroundUpdateBound), this.canvas.on("selection:created", this.handleBackgroundUpdateBound);
83
83
  }
84
84
  /**
85
85
  * При массовом выделении объектов удаляем из него залоченные.
@@ -89,31 +89,31 @@ class P {
89
89
  */
90
90
  _filterLockedSelection({ selected: e, e: t }) {
91
91
  if (!(e != null && e.length) || !(t instanceof MouseEvent) || e.length === 1) return;
92
- const { lockedObjects: s, unlockedObjects: a } = e.reduce(
93
- (o, i) => i.locked ? (o.lockedObjects.push(i), o) : (o.unlockedObjects.push(i), o),
92
+ const { lockedObjects: s, unlockedObjects: n } = e.reduce(
93
+ (a, i) => i.locked ? (a.lockedObjects.push(i), a) : (a.unlockedObjects.push(i), a),
94
94
  { lockedObjects: [], unlockedObjects: [] }
95
95
  );
96
96
  if (s.length === 0) return;
97
- if (a.length > 0) {
98
- if (a.length === 1)
99
- this.canvas.setActiveObject(a[0]);
97
+ if (n.length > 0) {
98
+ if (n.length === 1)
99
+ this.canvas.setActiveObject(n[0]);
100
100
  else {
101
- const o = new v(a, {
101
+ const a = new v(n, {
102
102
  canvas: this.canvas
103
103
  });
104
- this.canvas.setActiveObject(o);
104
+ this.canvas.setActiveObject(a);
105
105
  }
106
106
  this.canvas.requestRenderAll();
107
107
  return;
108
108
  }
109
- const n = new v(e, {
109
+ const o = new v(e, {
110
110
  canvas: this.canvas
111
111
  });
112
112
  this.editor.objectLockManager.lockObject({
113
- object: n,
113
+ object: o,
114
114
  skipInnerObjects: !0,
115
115
  withoutSave: !0
116
- }), this.canvas.setActiveObject(n), this.canvas.requestRenderAll();
116
+ }), this.canvas.setActiveObject(o), this.canvas.requestRenderAll();
117
117
  }
118
118
  /**
119
119
  * Обработчики для сохранения состояния редактора в истории.
@@ -157,8 +157,8 @@ class P {
157
157
  * @param event.code — код клавиши
158
158
  */
159
159
  handleCopyEvent(e) {
160
- const { ctrlKey: t, metaKey: s, code: a } = e;
161
- this._shouldIgnoreKeyboardEvent(e) || !t && !s || a !== "KeyC" || (e.preventDefault(), this.editor.clipboardManager.copy());
160
+ const { ctrlKey: t, metaKey: s, code: n } = e;
161
+ this._shouldIgnoreKeyboardEvent(e) || !t && !s || n !== "KeyC" || (e.preventDefault(), this.editor.clipboardManager.copy());
162
162
  }
163
163
  /**
164
164
  * Обработчик вставки объекта или изображения из буфера обмена.
@@ -175,9 +175,9 @@ class P {
175
175
  * @param event.code — код клавиши
176
176
  */
177
177
  handleUndoRedoEvent(e) {
178
- return j(this, null, function* () {
179
- const { ctrlKey: t, metaKey: s, code: a, repeat: n } = e;
180
- this._shouldIgnoreKeyboardEvent(e) || !t && !s || n || !/Mac/i.test(navigator.userAgent) && this.isUndoRedoKeyPressed || (a === "KeyZ" ? (e.preventDefault(), this.isUndoRedoKeyPressed = !0, yield this.editor.historyManager.undo()) : a === "KeyY" && (e.preventDefault(), this.isUndoRedoKeyPressed = !0, yield this.editor.historyManager.redo()));
178
+ return y(this, null, function* () {
179
+ const { ctrlKey: t, metaKey: s, code: n, repeat: o } = e;
180
+ this._shouldIgnoreKeyboardEvent(e) || !t && !s || o || !/Mac/i.test(navigator.userAgent) && this.isUndoRedoKeyPressed || (n === "KeyZ" ? (e.preventDefault(), this.isUndoRedoKeyPressed = !0, yield this.editor.historyManager.undo()) : n === "KeyY" && (e.preventDefault(), this.isUndoRedoKeyPressed = !0, yield this.editor.historyManager.redo()));
181
181
  });
182
182
  }
183
183
  /**
@@ -197,8 +197,8 @@ class P {
197
197
  */
198
198
  handleSelectAllEvent(e) {
199
199
  if (this._shouldIgnoreKeyboardEvent(e)) return;
200
- const { ctrlKey: t, metaKey: s, code: a } = e;
201
- !t && !s || a !== "KeyA" || (e.preventDefault(), this.editor.selectionManager.selectAll());
200
+ const { ctrlKey: t, metaKey: s, code: n } = e;
201
+ !t && !s || n !== "KeyA" || (e.preventDefault(), this.editor.selectionManager.selectAll());
202
202
  }
203
203
  /**
204
204
  * Обработчик для удаления объектов (Delete или Backspace).
@@ -216,11 +216,11 @@ class P {
216
216
  */
217
217
  handleSpaceKeyDown(e) {
218
218
  if (e.code !== "Space" || this._shouldIgnoreKeyboardEvent(e)) return;
219
- const { canvas: t, editor: s, isSpacePressed: a, isDragging: n } = this;
220
- if (a || n) return;
219
+ const { canvas: t, editor: s, isSpacePressed: n, isDragging: o } = this;
220
+ if (n || o) return;
221
221
  this.isSpacePressed = !0, e.preventDefault();
222
- const o = t.getActiveObject() || null;
223
- o instanceof v ? this.savedSelection = o.getObjects().slice() : o && (this.savedSelection = [o]), t.discardActiveObject(), t.set({
222
+ const a = t.getActiveObject() || null;
223
+ a instanceof v ? this.savedSelection = a.getObjects().slice() : a && (this.savedSelection = [a]), t.discardActiveObject(), t.set({
224
224
  selection: !1,
225
225
  defaultCursor: "grab"
226
226
  }), t.setCursor("grab"), s.canvasManager.getObjects().forEach((i) => {
@@ -259,8 +259,8 @@ class P {
259
259
  t.setActiveObject(e[0]);
260
260
  return;
261
261
  }
262
- const a = e.filter((o) => s.canvasManager.getObjects().includes(o)), n = new v(a, { canvas: t });
263
- t.setActiveObject(n);
262
+ const n = e.filter((a) => s.canvasManager.getObjects().includes(a)), o = new v(n, { canvas: t });
263
+ t.setActiveObject(o);
264
264
  }
265
265
  // --- Обработчики для событий canvas (Fabric) ---
266
266
  /**
@@ -273,15 +273,17 @@ class P {
273
273
  }
274
274
  /**
275
275
  * Перетаскивание канваса (mouse:move).
276
+ * Проверяет, разрешено ли перетаскивание при текущем зуме и применяет ограничения на панорамирование с помощью panConstraintManager.
276
277
  * @param options
277
278
  * @param options.e — объект события
278
- *
279
- * TODO: Надо как-то ограничить область перетаскивания, чтобы канвас не уходил сильно далеко за пределы экрана
280
279
  */
281
280
  handleCanvasDragging({ e }) {
282
281
  if (!this.isDragging || !this.isSpacePressed || !(e instanceof MouseEvent)) return;
283
- const t = this.canvas.viewportTransform;
284
- t[4] += e.clientX - this.lastMouseX, t[5] += e.clientY - this.lastMouseY, this.canvas.requestRenderAll(), this.lastMouseX = e.clientX, this.lastMouseY = e.clientY;
282
+ const { panConstraintManager: t, montageArea: s } = this.editor;
283
+ if (!t.isPanAllowed())
284
+ return;
285
+ const n = this.canvas.viewportTransform, o = n[4] + (e.clientX - this.lastMouseX), a = n[5] + (e.clientY - this.lastMouseY), i = t.constrainPan(o, a);
286
+ n[4] = i.x, n[5] = i.y, s.setCoords(), this.canvas.requestRenderAll(), this.lastMouseX = e.clientX, this.lastMouseY = e.clientY;
285
287
  }
286
288
  /**
287
289
  * Завершение перетаскивания канваса (mouse:up).
@@ -290,6 +292,18 @@ class P {
290
292
  handleCanvasDragEnd() {
291
293
  this.isDragging && (this.canvas.setViewportTransform(this.canvas.viewportTransform), this.isDragging = !1, this.isSpacePressed && (this.canvas.set("defaultCursor", "grab"), this.canvas.setCursor("grab")));
292
294
  }
295
+ /**
296
+ * Рассчитывает шаг зума на основе текущего масштаба канваса.
297
+ * Логика: один скролл изменяет зум на фиксированный процент от текущего значения.
298
+ *
299
+ * @param currentZoom - Текущий уровень зума канваса
300
+ * @param deltaY - Значение deltaY из WheelEvent
301
+ * @returns Шаг изменения зума
302
+ */
303
+ _calculateAdaptiveZoomStep(e) {
304
+ const t = this.canvas.getZoom(), s = 0.05, o = e / 100;
305
+ return -(t * s * o);
306
+ }
293
307
  /**
294
308
  * Обработчик зума колесиком мыши. Работает при зажатом Ctrl или Cmd.
295
309
  * @param options
@@ -297,8 +311,8 @@ class P {
297
311
  */
298
312
  handleMouseWheelZoom({ e }) {
299
313
  if (!e.ctrlKey && !e.metaKey) return;
300
- const s = -e.deltaY * 1e-3;
301
- this.editor.transformManager.zoom(s), e.preventDefault(), e.stopPropagation();
314
+ const t = this._calculateAdaptiveZoomStep(e.deltaY);
315
+ this.editor.zoomManager.handleMouseWheelZoom(t, e), e.preventDefault(), e.stopPropagation();
302
316
  }
303
317
  /**
304
318
  * Обработчик, поднимающий выделенные объекты на передний план.
@@ -325,22 +339,22 @@ class P {
325
339
  * @returns true если событие должно быть проигнорировано
326
340
  */
327
341
  _shouldIgnoreKeyboardEvent(e) {
328
- const t = document.activeElement, s = e.target, a = ["input", "textarea", "select"];
342
+ const t = document.activeElement, s = e.target, n = ["input", "textarea", "select"];
329
343
  if (s) {
330
- const o = s.tagName.toLowerCase();
331
- if (a.includes(o) || s.contentEditable === "true") return !0;
344
+ const a = s.tagName.toLowerCase();
345
+ if (n.includes(a) || s.contentEditable === "true") return !0;
332
346
  }
333
347
  if (t && t !== s) {
334
- const o = t.tagName.toLowerCase();
335
- if (a.includes(o) || t.contentEditable === "true") return !0;
348
+ const a = t.tagName.toLowerCase();
349
+ if (n.includes(a) || t.contentEditable === "true") return !0;
336
350
  }
337
- const n = window.getSelection();
338
- if (n && !n.isCollapsed && n.rangeCount > 0) {
339
- let r = n.getRangeAt(0).commonAncestorContainer;
351
+ const o = window.getSelection();
352
+ if (o && !o.isCollapsed && o.rangeCount > 0) {
353
+ let r = o.getRangeAt(0).commonAncestorContainer;
340
354
  r.nodeType === Node.TEXT_NODE && (r = r.parentElement);
341
- const { keyboardIgnoreSelectors: d } = this.options;
342
- if (d != null && d.length && r)
343
- for (const h of d)
355
+ const { keyboardIgnoreSelectors: c } = this.options;
356
+ if (c != null && c.length && r)
357
+ for (const h of c)
344
358
  try {
345
359
  const l = r;
346
360
  if (l.matches && l.matches(h) || l.closest && l.closest(h))
@@ -365,14 +379,14 @@ class P {
365
379
  */
366
380
  static debounce(e, t) {
367
381
  let s = null;
368
- return function(...a) {
382
+ return function(...n) {
369
383
  s !== null && clearTimeout(s), s = setTimeout(() => {
370
- e.apply(this, a);
384
+ e.apply(this, n);
371
385
  }, t);
372
386
  };
373
387
  }
374
388
  }
375
- class Ye {
389
+ class Pe {
376
390
  /**
377
391
  * Класс для динамической загрузки внешних модулей.
378
392
  */
@@ -390,21 +404,21 @@ class Ye {
390
404
  return this.loaders[e] ? (this.cache.has(e) || this.cache.set(e, this.loaders[e]()), this.cache.get(e)) : Promise.reject(new Error(`Unknown module "${e}"`));
391
405
  }
392
406
  }
393
- function Pe(c) {
407
+ function We(d) {
394
408
  return new Worker(
395
409
  "" + new URL("assets/worker-CN39s7P7.js", import.meta.url).href,
396
410
  {
397
- name: c == null ? void 0 : c.name
411
+ name: d == null ? void 0 : d.name
398
412
  }
399
413
  );
400
414
  }
401
- class We {
415
+ class Fe {
402
416
  /**
403
417
  * @param scriptUrl — URL скрипта воркера.
404
418
  * По-умолчанию использует DefaultWorker из соседнего файла
405
419
  */
406
420
  constructor(e) {
407
- e ? this.worker = new Worker(e, { type: "module" }) : this.worker = new Pe(), this._callbacks = /* @__PURE__ */ new Map(), this.worker.onmessage = this._handleMessage.bind(this);
421
+ e ? this.worker = new Worker(e, { type: "module" }) : this.worker = new We(), this._callbacks = /* @__PURE__ */ new Map(), this.worker.onmessage = this._handleMessage.bind(this);
408
422
  }
409
423
  /**
410
424
  * Обработчик сообщений от воркера
@@ -417,12 +431,12 @@ class We {
417
431
  * @returns
418
432
  */
419
433
  _handleMessage({ data: e }) {
420
- const { requestId: t, success: s, data: a, error: n } = e, o = this._callbacks.get(t);
421
- if (!o) {
434
+ const { requestId: t, success: s, data: n, error: o } = e, a = this._callbacks.get(t);
435
+ if (!a) {
422
436
  console.warn(`No callback found for requestId: ${t}`);
423
437
  return;
424
438
  }
425
- s ? o.resolve(a) : o.reject(new Error(n)), this._callbacks.delete(t);
439
+ s ? a.resolve(n) : a.reject(new Error(o)), this._callbacks.delete(t);
426
440
  }
427
441
  /**
428
442
  * Универсальный метод отправки команды в воркер
@@ -432,9 +446,9 @@ class We {
432
446
  * @returns Promise, который будет выполнен, когда воркер вернет ответ
433
447
  */
434
448
  post(e, t, s = []) {
435
- const a = `${e}:${A(8)}`;
436
- return new Promise((n, o) => {
437
- this._callbacks.set(a, { resolve: n, reject: o }), this.worker.postMessage({ action: e, payload: t, requestId: a }, s);
449
+ const n = `${e}:${C(8)}`;
450
+ return new Promise((o, a) => {
451
+ this._callbacks.set(n, { resolve: o, reject: a }), this.worker.postMessage({ action: e, payload: t, requestId: n }, s);
438
452
  });
439
453
  }
440
454
  /**
@@ -444,112 +458,112 @@ class We {
444
458
  this.worker.terminate();
445
459
  }
446
460
  }
447
- const O = 12, Fe = 2, se = 8, ae = 20, Ve = 100, ne = 20, oe = 8, Ge = 100, Q = 32, ie = 1, Xe = "#2B2D33", re = "#3D8BF4", ce = "#FFFFFF";
448
- function G(c, e, t, s, a) {
449
- const n = O, o = Fe;
450
- c.save(), c.translate(e, t), c.rotate(W.degreesToRadians(a.angle)), c.fillStyle = ce, c.strokeStyle = re, c.lineWidth = ie, c.beginPath(), c.roundRect(-n / 2, -n / 2, n, n, o), c.fill(), c.stroke(), c.restore();
461
+ const k = 12, Ve = 2, ne = 8, oe = 20, Ge = 100, ae = 20, ie = 8, Xe = 100, Q = 32, re = 1, $e = "#2B2D33", ce = "#3D8BF4", de = "#FFFFFF";
462
+ function X(d, e, t, s, n) {
463
+ const o = k, a = Ve;
464
+ d.save(), d.translate(e, t), d.rotate(F.degreesToRadians(n.angle)), d.fillStyle = de, d.strokeStyle = ce, d.lineWidth = re, d.beginPath(), d.roundRect(-o / 2, -o / 2, o, o, a), d.fill(), d.stroke(), d.restore();
451
465
  }
452
- function ye(c, e, t, s, a) {
453
- const n = se, o = ae, i = Ve;
454
- c.save(), c.translate(e, t), c.rotate(W.degreesToRadians(a.angle)), c.fillStyle = ce, c.strokeStyle = re, c.lineWidth = ie, c.beginPath(), c.roundRect(-n / 2, -o / 2, n, o, i), c.fill(), c.stroke(), c.restore();
466
+ function ve(d, e, t, s, n) {
467
+ const o = ne, a = oe, i = Ge;
468
+ d.save(), d.translate(e, t), d.rotate(F.degreesToRadians(n.angle)), d.fillStyle = de, d.strokeStyle = ce, d.lineWidth = re, d.beginPath(), d.roundRect(-o / 2, -a / 2, o, a, i), d.fill(), d.stroke(), d.restore();
455
469
  }
456
- function Ie(c, e, t, s, a) {
457
- const n = ne, o = oe, i = Ge;
458
- c.save(), c.translate(e, t), c.rotate(W.degreesToRadians(a.angle)), c.fillStyle = ce, c.strokeStyle = re, c.lineWidth = ie, c.beginPath(), c.roundRect(-n / 2, -o / 2, n, o, i), c.fill(), c.stroke(), c.restore();
470
+ function Ie(d, e, t, s, n) {
471
+ const o = ae, a = ie, i = Xe;
472
+ d.save(), d.translate(e, t), d.rotate(F.degreesToRadians(n.angle)), d.fillStyle = de, d.strokeStyle = ce, d.lineWidth = re, d.beginPath(), d.roundRect(-o / 2, -a / 2, o, a, i), d.fill(), d.stroke(), d.restore();
459
473
  }
460
- const Qe = "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyMCIgaGVpZ2h0PSIyMCIgZmlsbD0ibm9uZSI+PHBhdGggZmlsbD0iI2ZmZiIgZD0iTTE4Ljc1IDQuMzc1djMuNzVhLjYyNS42MjUgMCAwIDEtLjYyNS42MjVoLTMuNzVhLjYyNS42MjUgMCAwIDEgMC0xLjI1aDIuMTRsLTIuMDc3LTEuOTAzLS4wMi0uMDE5YTYuMjUgNi4yNSAwIDEgMC0uMTMgOC45NjcuNjI2LjYyNiAwIDAgMSAuODYuOTA5QTcuNDU2IDcuNDU2IDAgMCAxIDEwIDE3LjVoLS4xMDNhNy41IDcuNSAwIDEgMSA1LjM5Ni0xMi44MTJMMTcuNSA2LjcwM1Y0LjM3NWEuNjI1LjYyNSAwIDAgMSAxLjI1IDBaIi8+PC9zdmc+", De = new Image();
461
- De.src = Qe;
462
- function $e(c, e, t, s, a) {
463
- const o = Q / 2;
464
- c.save(), c.translate(e, t), c.rotate(W.degreesToRadians(a.angle)), c.fillStyle = Xe, c.beginPath(), c.arc(0, 0, o, 0, 2 * Math.PI), c.fill(), c.drawImage(De, -o / 2, -o / 2, o, o), c.restore();
474
+ const Qe = "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyMCIgaGVpZ2h0PSIyMCIgZmlsbD0ibm9uZSI+PHBhdGggZmlsbD0iI2ZmZiIgZD0iTTE4Ljc1IDQuMzc1djMuNzVhLjYyNS42MjUgMCAwIDEtLjYyNS42MjVoLTMuNzVhLjYyNS42MjUgMCAwIDEgMC0xLjI1aDIuMTRsLTIuMDc3LTEuOTAzLS4wMi0uMDE5YTYuMjUgNi4yNSAwIDEgMC0uMTMgOC45NjcuNjI2LjYyNiAwIDAgMSAuODYuOTA5QTcuNDU2IDcuNDU2IDAgMCAxIDEwIDE3LjVoLS4xMDNhNy41IDcuNSAwIDEgMSA1LjM5Ni0xMi44MTJMMTcuNSA2LjcwM1Y0LjM3NWEuNjI1LjYyNSAwIDAgMSAxLjI1IDBaIi8+PC9zdmc+", Oe = new Image();
475
+ Oe.src = Qe;
476
+ function Ke(d, e, t, s, n) {
477
+ const a = Q / 2;
478
+ d.save(), d.translate(e, t), d.rotate(F.degreesToRadians(n.angle)), d.fillStyle = $e, d.beginPath(), d.arc(0, 0, a, 0, 2 * Math.PI), d.fill(), d.drawImage(Oe, -a / 2, -a / 2, a, a), d.restore();
465
479
  }
466
- const Ke = {
480
+ const Je = {
467
481
  // Угловые точки
468
482
  tl: {
469
- render: G,
470
- sizeX: O,
471
- sizeY: O,
483
+ render: X,
484
+ sizeX: k,
485
+ sizeY: k,
472
486
  offsetX: 0,
473
487
  offsetY: 0
474
488
  },
475
489
  tr: {
476
- render: G,
477
- sizeX: O,
478
- sizeY: O,
490
+ render: X,
491
+ sizeX: k,
492
+ sizeY: k,
479
493
  offsetX: 0,
480
494
  offsetY: 0
481
495
  },
482
496
  bl: {
483
- render: G,
484
- sizeX: O,
485
- sizeY: O,
497
+ render: X,
498
+ sizeX: k,
499
+ sizeY: k,
486
500
  offsetX: 0,
487
501
  offsetY: 0
488
502
  },
489
503
  br: {
490
- render: G,
491
- sizeX: O,
492
- sizeY: O,
504
+ render: X,
505
+ sizeX: k,
506
+ sizeY: k,
493
507
  offsetX: 0,
494
508
  offsetY: 0
495
509
  },
496
510
  // Середина вертикалей
497
511
  ml: {
498
- render: ye,
499
- sizeX: se,
500
- sizeY: ae,
512
+ render: ve,
513
+ sizeX: ne,
514
+ sizeY: oe,
501
515
  offsetX: 0,
502
516
  offsetY: 0
503
517
  },
504
518
  mr: {
505
- render: ye,
506
- sizeX: se,
507
- sizeY: ae,
519
+ render: ve,
520
+ sizeX: ne,
521
+ sizeY: oe,
508
522
  offsetX: 0,
509
523
  offsetY: 0
510
524
  },
511
525
  // Середина горизонталей
512
526
  mt: {
513
527
  render: Ie,
514
- sizeX: ne,
515
- sizeY: oe,
528
+ sizeX: ae,
529
+ sizeY: ie,
516
530
  offsetX: 0,
517
531
  offsetY: 0
518
532
  },
519
533
  mb: {
520
534
  render: Ie,
521
- sizeX: ne,
522
- sizeY: oe,
535
+ sizeX: ae,
536
+ sizeY: ie,
523
537
  offsetX: 0,
524
538
  offsetY: 0
525
539
  },
526
540
  // Специальный «rotate» контрол
527
541
  mtr: {
528
- render: $e,
542
+ render: Ke,
529
543
  sizeX: Q,
530
544
  sizeY: Q,
531
545
  offsetX: 0,
532
546
  offsetY: -Q
533
547
  }
534
548
  };
535
- class Je {
549
+ class qe {
536
550
  static apply() {
537
- const e = Te.createObjectDefaultControls();
538
- Object.entries(Ke).forEach(([t, s]) => {
551
+ const e = ke.createObjectDefaultControls();
552
+ Object.entries(Je).forEach(([t, s]) => {
539
553
  Object.assign(e[t], {
540
554
  render: s.render,
541
555
  sizeX: s.sizeX,
542
556
  sizeY: s.sizeY,
543
557
  offsetX: s.offsetX,
544
558
  offsetY: s.offsetY
545
- }), t === "mtr" && (e[t].cursorStyle = "grab", e[t].mouseDownHandler = (n, o, i, r) => {
559
+ }), t === "mtr" && (e[t].cursorStyle = "grab", e[t].mouseDownHandler = (o, a, i, r) => {
546
560
  var h;
547
- (h = o.target.canvas) == null || h.setCursor("grabbing");
561
+ (h = a.target.canvas) == null || h.setCursor("grabbing");
548
562
  });
549
563
  }), je.ownDefaults.controls = e, je.ownDefaults.snapAngle = 1;
550
564
  }
551
565
  }
552
- const qe = "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyMCIgaGVpZ2h0PSIyMCIgZmlsbD0ibm9uZSI+PHBhdGggZmlsbD0iI2ZmZiIgZmlsbC1ydWxlPSJldmVub2RkIiBkPSJNNi44NzUgMi41YS42MjUuNjI1IDAgMCAwLS42MjUuNjI0VjYuMjVIMy4xMjVhLjYyNS42MjUgMCAwIDAtLjYyNS42MjV2MTBjMCAuMzQ1LjI4LjYyNS42MjUuNjI1aDEwYy4zNDUgMCAuNjI1LS4yOC42MjUtLjYyNXYtMy4xMjZoMy4xMjVjLjM0NSAwIC42MjUtLjI4LjYyNS0uNjI1di0xMGEuNjI1LjYyNSAwIDAgMC0uNjI1LS42MjVoLTEwWm02Ljg3NSAxMGgyLjVWMy43NUg3LjV2Mi41aDUuNjI1Yy4zNDUgMCAuNjI1LjI4LjYyNS42MjV2NS42MjRabS0xMCAzLjc1VjcuNWg4Ljc1djguNzVIMy43NVoiIGNsaXAtcnVsZT0iZXZlbm9kZCIvPjwvc3ZnPg==", et = "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyMCIgaGVpZ2h0PSIyMCIgZmlsbD0ibm9uZSI+PHBhdGggZmlsbD0iI2ZmZiIgZmlsbC1ydWxlPSJldmVub2RkIiBkPSJNMi41IDcuNWMwLS42OS41Ni0xLjI1IDEuMjUtMS4yNWgxMi41Yy42OSAwIDEuMjUuNTYgMS4yNSAxLjI1djguNzVjMCAuNjktLjU2IDEuMjUtMS4yNSAxLjI1SDMuNzVjLS42OSAwLTEuMjUtLjU2LTEuMjUtMS4yNVY3LjVabTEzLjc1IDBIMy43NXY4Ljc1aDEyLjVWNy41WiIgY2xpcC1ydWxlPSJldmVub2RkIi8+PHBhdGggZmlsbD0iI2ZmZiIgZmlsbC1ydWxlPSJldmVub2RkIiBkPSJNMTAgMS44NzVhMi4xODggMi4xODggMCAwIDAtMi4xODggMi4xODh2Mi44MTJhLjYyNS42MjUgMCAxIDEtMS4yNSAwVjQuMDYyYTMuNDM3IDMuNDM3IDAgMSAxIDYuODc1IDB2Mi44MTNhLjYyNS42MjUgMCAxIDEtMS4yNSAwVjQuMDYyQTIuMTg4IDIuMTg4IDAgMCAwIDEwIDEuODc2WiIgY2xpcC1ydWxlPSJldmVub2RkIi8+PHBhdGggZmlsbD0iI2ZmZiIgZD0iTTEwIDEyLjgxM2EuOTM3LjkzNyAwIDEgMCAwLTEuODc1LjkzNy45MzcgMCAwIDAgMCAxLjg3NFoiLz48L3N2Zz4=", tt = "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyMCIgaGVpZ2h0PSIyMCIgZmlsbD0ibm9uZSI+PHBhdGggZmlsbD0iI2ZmZiIgZD0iTTE2LjI1IDYuMjVINy41VjQuMzc1YTIuNSAyLjUgMCAwIDEgMi41LTIuNWMxLjIgMCAyLjI4MS44NiAyLjUxMiAyYS42MjUuNjI1IDAgMCAwIDEuMjI2LS4yNWMtLjM1NC0xLjczOC0xLjkyNS0zLTMuNzM4LTNhMy43NTQgMy43NTQgMCAwIDAtMy43NSAzLjc1VjYuMjVoLTIuNUExLjI1IDEuMjUgMCAwIDAgMi41IDcuNXY4Ljc1YTEuMjUgMS4yNSAwIDAgMCAxLjI1IDEuMjVoMTIuNWExLjI1IDEuMjUgMCAwIDAgMS4yNS0xLjI1VjcuNWExLjI1IDEuMjUgMCAwIDAtMS4yNS0xLjI1Wm0wIDEwSDMuNzVWNy41aDEyLjV2OC43NVptLTUuMzEzLTQuMzc1YS45MzcuOTM3IDAgMSAxLTEuODc0IDAgLjkzNy45MzcgMCAwIDEgMS44NzQgMFoiLz48L3N2Zz4K", st = "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyMCIgaGVpZ2h0PSIyMCIgZmlsbD0ibm9uZSI+PHBhdGggZmlsbD0iI2ZmZiIgZD0iTTIuNSA4LjEyNSAxMCAxMi41bDcuNS00LjM3NUwxMCAzLjc1IDIuNSA4LjEyNVoiLz48cGF0aCBmaWxsPSIjZmZmIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiIGQ9Ik05LjY4NSAzLjIxYS42MjUuNjI1IDAgMCAxIC42MyAwbDcuNSA0LjM3NWEuNjI1LjYyNSAwIDAgMSAwIDEuMDhsLTcuNSA0LjM3NWEuNjI1LjYyNSAwIDAgMS0uNjMgMGwtNy41LTQuMzc1YS42MjUuNjI1IDAgMCAxIDAtMS4wOGw3LjUtNC4zNzVaTTMuNzQgOC4xMjUgMTAgMTEuNzc2bDYuMjYtMy42NTFMMTAgNC40NzQgMy43NCA4LjEyNVoiIGNsaXAtcnVsZT0iZXZlbm9kZCIvPjxwYXRoIGZpbGw9IiNmZmYiIGZpbGwtcnVsZT0iZXZlbm9kZCIgZD0iTTUuNCA5LjQ2YS42MjUuNjI1IDAgMCAxIC42MyAwTDEwIDExLjc3NmwzLjk3LTIuMzE2YS42MjUuNjI1IDAgMCAxIC42MyAwbDMuMjE1IDEuODc1YS42MjUuNjI1IDAgMCAxIDAgMS4wOGwtNy41IDQuMzc1YS42MjUuNjI1IDAgMCAxLS42MyAwbC03LjUtNC4zNzVhLjYyNS42MjUgMCAwIDEgMC0xLjA4TDUuNCA5LjQ2Wm0tMS42NiAyLjQxNUwxMCAxNS41MjZsNi4yNi0zLjY1MS0xLjk3NC0xLjE1MS0zLjk3MSAyLjMxNmEuNjI1LjYyNSAwIDAgMS0uNjMgMGwtMy45Ny0yLjMxNi0xLjk3NSAxLjE1MVoiIGNsaXAtcnVsZT0iZXZlbm9kZCIvPjwvc3ZnPg==", at = "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyMCIgaGVpZ2h0PSIyMCIgZmlsbD0ibm9uZSI+PHBhdGggZmlsbD0iI2ZmZiIgZmlsbC1ydWxlPSJldmVub2RkIiBkPSJNOS42ODUgMy4yMWEuNjI1LjYyNSAwIDAgMSAuNjMgMGw3LjUgNC4zNzVhLjYyNS42MjUgMCAwIDEgMCAxLjA4bC03LjUgNC4zNzVhLjYyNS42MjUgMCAwIDEtLjYzIDBsLTcuNS00LjM3NWEuNjI1LjYyNSAwIDAgMSAwLTEuMDhsNy41LTQuMzc1Wk0zLjc0IDguMTI1IDEwIDExLjc3Nmw2LjI2LTMuNjUxTDEwIDQuNDc0IDMuNzQgOC4xMjVaIiBjbGlwLXJ1bGU9ImV2ZW5vZGQiLz48cGF0aCBmaWxsPSIjZmZmIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiIGQ9Ik01LjcxNCAxMCAxMCAxMi41bDQuMjg2LTIuNSAzLjIxNCAxLjg3NUwxMCAxNi4yNWwtNy41LTQuMzc1TDUuNzE0IDEwWiIgY2xpcC1ydWxlPSJldmVub2RkIi8+PHBhdGggZmlsbD0iI2ZmZiIgZmlsbC1ydWxlPSJldmVub2RkIiBkPSJNNS40IDkuNDZhLjYyNS42MjUgMCAwIDEgLjYzIDBMMTAgMTEuNzc2bDMuOTctMi4zMTZhLjYyNS42MjUgMCAwIDEgLjYzIDBsMy4yMTUgMS44NzVhLjYyNS42MjUgMCAwIDEgMCAxLjA4bC03LjUgNC4zNzVhLjYyNS42MjUgMCAwIDEtLjYzIDBsLTcuNS00LjM3NWEuNjI1LjYyNSAwIDAgMSAwLTEuMDhMNS40IDkuNDZabS0xLjY2IDIuNDE1TDEwIDE1LjUyNmw2LjI2LTMuNjUxLTEuOTc0LTEuMTUxLTMuOTcxIDIuMzE2YS42MjUuNjI1IDAgMCAxLS42MyAwbC0zLjk3LTIuMzE2LTEuOTc1IDEuMTUxWiIgY2xpcC1ydWxlPSJldmVub2RkIi8+PC9zdmc+", nt = "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyMCIgaGVpZ2h0PSIyMCIgZmlsbD0ibm9uZSI+PHBhdGggZmlsbD0iI2ZmZiIgZD0ibTIuNSA2LjI1IDcuNSA0LjM3NSA3LjUtNC4zNzVMMTAgMS44NzUgMi41IDYuMjVaIi8+PHBhdGggZmlsbD0iI2ZmZiIgZmlsbC1ydWxlPSJldmVub2RkIiBkPSJNOS42ODUgMS4zMzVhLjYyNS42MjUgMCAwIDEgLjYzIDBsNy41IDQuMzc1YS42MjUuNjI1IDAgMCAxIDAgMS4wOGwtNy41IDQuMzc1YS42MjUuNjI1IDAgMCAxLS42MyAwbC03LjUtNC4zNzVhLjYyNS42MjUgMCAwIDEgMC0xLjA4bDcuNS00LjM3NVpNMy43NCA2LjI1IDEwIDkuOTAxbDYuMjYtMy42NTFMMTAgMi41OTkgMy43NCA2LjI1WiIgY2xpcC1ydWxlPSJldmVub2RkIi8+PHBhdGggZmlsbD0iI2ZmZiIgZmlsbC1ydWxlPSJldmVub2RkIiBkPSJNNS40IDExLjMzNWEuNjI1LjYyNSAwIDAgMSAuNjMgMEwxMCAxMy42NTFsMy45Ny0yLjMxNmEuNjI1LjYyNSAwIDAgMSAuNjMgMGwzLjIxNSAxLjg3NWEuNjI1LjYyNSAwIDAgMSAwIDEuMDhsLTcuNSA0LjM3NWEuNjI1LjYyNSAwIDAgMS0uNjMgMGwtNy41LTQuMzc1YS42MjUuNjI1IDAgMCAxIDAtMS4wOEw1LjQgMTEuMzM1Wk0zLjc0IDEzLjc1IDEwIDE3LjQwMWw2LjI2LTMuNjUxLTEuOTc0LTEuMTUxLTMuOTcxIDIuMzE2YS42MjUuNjI1IDAgMCAxLS42MyAwbC0zLjk3LTIuMzE2TDMuNzQgMTMuNzVaIiBjbGlwLXJ1bGU9ImV2ZW5vZGQiLz48cGF0aCBmaWxsPSIjZmZmIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiIGQ9Ik01LjQgNy41ODVhLjYyNS42MjUgMCAwIDEgLjYzIDBMMTAgOS45MDFsMy45Ny0yLjMxNmEuNjI1LjYyNSAwIDAgMSAuNjMgMGwzLjIxNSAxLjg3NWEuNjI1LjYyNSAwIDAgMSAwIDEuMDhsLTcuNSA0LjM3NWEuNjI1LjYyNSAwIDAgMS0uNjMgMGwtNy41LTQuMzc1YS42MjUuNjI1IDAgMCAxIDAtMS4wOEw1LjQgNy41ODVaTTMuNzQgMTAgMTAgMTMuNjUxIDE2LjI2IDEwbC0xLjk3NC0xLjE1MS0zLjk3MSAyLjMxNmEuNjI1LjYyNSAwIDAgMS0uNjMgMGwtMy45Ny0yLjMxNkwzLjc0IDEwWiIgY2xpcC1ydWxlPSJldmVub2RkIi8+PC9zdmc+", ot = "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyMCIgaGVpZ2h0PSIyMCIgZmlsbD0ibm9uZSI+PHBhdGggZmlsbD0iI2ZmZiIgZmlsbC1ydWxlPSJldmVub2RkIiBkPSJNMS45NiAxMy40MzVhLjYyNS42MjUgMCAwIDEgLjg1NS0uMjI1TDEwIDE3LjQwMWw3LjE4NS00LjE5YS42MjUuNjI1IDAgMCAxIC42MyAxLjA3OWwtNy41IDQuMzc1YS42MjUuNjI1IDAgMCAxLS42MyAwbC03LjUtNC4zNzVhLjYyNS42MjUgMCAwIDEtLjIyNS0uODU1Wk05LjY4NSAxLjMzNWEuNjI1LjYyNSAwIDAgMSAuNjMgMGw3LjUgNC4zNzVhLjYyNS42MjUgMCAwIDEgMCAxLjA4bC03LjUgNC4zNzVhLjYyNS42MjUgMCAwIDEtLjYzIDBsLTcuNS00LjM3NWEuNjI1LjYyNSAwIDAgMSAwLTEuMDhsNy41LTQuMzc1Wk0zLjc0IDYuMjUgMTAgOS45MDFsNi4yNi0zLjY1MUwxMCAyLjU5OSAzLjc0IDYuMjVaIiBjbGlwLXJ1bGU9ImV2ZW5vZGQiLz48cGF0aCBmaWxsPSIjZmZmIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiIGQ9Im01LjcxNCAxMS44NzUgNC4yODYgMi41IDQuMjg2LTIuNUwxNy41IDEzLjc1IDEwIDE4LjEyNSAyLjUgMTMuNzVsMy4yMTQtMS44NzVaIiBjbGlwLXJ1bGU9ImV2ZW5vZGQiLz48cGF0aCBmaWxsPSIjZmZmIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiIGQ9Ik01LjQgMTEuMzM1YS42MjUuNjI1IDAgMCAxIC42MyAwTDEwIDEzLjY1MWwzLjk3LTIuMzE2YS42MjUuNjI1IDAgMCAxIC42MyAwbDMuMjE1IDEuODc1YS42MjUuNjI1IDAgMCAxIDAgMS4wOGwtNy41IDQuMzc1YS42MjUuNjI1IDAgMCAxLS42MyAwbC03LjUtNC4zNzVhLjYyNS42MjUgMCAwIDEgMC0xLjA4TDUuNCAxMS4zMzVaTTMuNzQgMTMuNzUgMTAgMTcuNDAxbDYuMjYtMy42NTEtMS45NzQtMS4xNTEtMy45NzEgMi4zMTZhLjYyNS42MjUgMCAwIDEtLjYzIDBsLTMuOTctMi4zMTZMMy43NCAxMy43NVoiIGNsaXAtcnVsZT0iZXZlbm9kZCIvPjxwYXRoIGZpbGw9IiNmZmYiIGZpbGwtcnVsZT0iZXZlbm9kZCIgZD0iTTUuNCA3LjU4NWEuNjI1LjYyNSAwIDAgMSAuNjMgMEwxMCA5LjkwMWwzLjk3LTIuMzE2YS42MjUuNjI1IDAgMCAxIC42MyAwbDMuMjE1IDEuODc1YS42MjUuNjI1IDAgMCAxIDAgMS4wOGwtNy41IDQuMzc1YS42MjUuNjI1IDAgMCAxLS42MyAwbC03LjUtNC4zNzVhLjYyNS42MjUgMCAwIDEgMC0xLjA4TDUuNCA3LjU4NVpNMy43NCAxMCAxMCAxMy42NTEgMTYuMjYgMTBsLTEuOTc0LTEuMTUxLTMuOTcxIDIuMzE2YS42MjUuNjI1IDAgMCAxLS42MyAwbC0zLjk3LTIuMzE2TDMuNzQgMTBaIiBjbGlwLXJ1bGU9ImV2ZW5vZGQiLz48L3N2Zz4=", it = "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyMCIgaGVpZ2h0PSIyMCIgZmlsbD0ibm9uZSI+PHBhdGggZmlsbD0iI0VDNEU0MCIgZmlsbC1ydWxlPSJldmVub2RkIiBkPSJNOC4xMjUgMS4yNUExLjg3NSAxLjg3NSAwIDAgMCA2LjI1IDMuMTI1di42MjVIMy4xMjVhLjYyNS42MjUgMCAwIDAgMCAxLjI1aC42MjV2MTEuMjVBMS4yNSAxLjI1IDAgMCAwIDUgMTcuNWgxMGExLjI1IDEuMjUgMCAwIDAgMS4yNS0xLjI1VjVoLjYyNWEuNjI1LjYyNSAwIDAgMCAwLTEuMjVIMTMuNzV2LS42MjVhMS44NzUgMS44NzUgMCAwIDAtMS44NzUtMS44NzVoLTMuNzVabTQuMzc1IDIuNXYtLjYyNWEuNjI1LjYyNSAwIDAgMC0uNjI1LS42MjVoLTMuNzVhLjYyNS42MjUgMCAwIDAtLjYyNS42MjV2LjYyNWg1Wk01IDE2LjI1VjVoMTB2MTEuMjVINVpNOC4xMjUgNy41Yy4zNDUgMCAuNjI1LjI4LjYyNS42MjV2NWEuNjI1LjYyNSAwIDEgMS0xLjI1IDB2LTVjMC0uMzQ1LjI4LS42MjUuNjI1LS42MjVabTQuMzc1IDUuNjI1di01YS42MjUuNjI1IDAgMCAwLTEuMjUgMHY1YS42MjUuNjI1IDAgMSAwIDEuMjUgMFoiIGNsaXAtcnVsZT0iZXZlbm9kZCIvPjwvc3ZnPg==", Y = {
566
+ const et = "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyMCIgaGVpZ2h0PSIyMCIgZmlsbD0ibm9uZSI+PHBhdGggZmlsbD0iI2ZmZiIgZmlsbC1ydWxlPSJldmVub2RkIiBkPSJNNi44NzUgMi41YS42MjUuNjI1IDAgMCAwLS42MjUuNjI0VjYuMjVIMy4xMjVhLjYyNS42MjUgMCAwIDAtLjYyNS42MjV2MTBjMCAuMzQ1LjI4LjYyNS42MjUuNjI1aDEwYy4zNDUgMCAuNjI1LS4yOC42MjUtLjYyNXYtMy4xMjZoMy4xMjVjLjM0NSAwIC42MjUtLjI4LjYyNS0uNjI1di0xMGEuNjI1LjYyNSAwIDAgMC0uNjI1LS42MjVoLTEwWm02Ljg3NSAxMGgyLjVWMy43NUg3LjV2Mi41aDUuNjI1Yy4zNDUgMCAuNjI1LjI4LjYyNS42MjV2NS42MjRabS0xMCAzLjc1VjcuNWg4Ljc1djguNzVIMy43NVoiIGNsaXAtcnVsZT0iZXZlbm9kZCIvPjwvc3ZnPg==", tt = "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyMCIgaGVpZ2h0PSIyMCIgZmlsbD0ibm9uZSI+PHBhdGggZmlsbD0iI2ZmZiIgZmlsbC1ydWxlPSJldmVub2RkIiBkPSJNMi41IDcuNWMwLS42OS41Ni0xLjI1IDEuMjUtMS4yNWgxMi41Yy42OSAwIDEuMjUuNTYgMS4yNSAxLjI1djguNzVjMCAuNjktLjU2IDEuMjUtMS4yNSAxLjI1SDMuNzVjLS42OSAwLTEuMjUtLjU2LTEuMjUtMS4yNVY3LjVabTEzLjc1IDBIMy43NXY4Ljc1aDEyLjVWNy41WiIgY2xpcC1ydWxlPSJldmVub2RkIi8+PHBhdGggZmlsbD0iI2ZmZiIgZmlsbC1ydWxlPSJldmVub2RkIiBkPSJNMTAgMS44NzVhMi4xODggMi4xODggMCAwIDAtMi4xODggMi4xODh2Mi44MTJhLjYyNS42MjUgMCAxIDEtMS4yNSAwVjQuMDYyYTMuNDM3IDMuNDM3IDAgMSAxIDYuODc1IDB2Mi44MTNhLjYyNS42MjUgMCAxIDEtMS4yNSAwVjQuMDYyQTIuMTg4IDIuMTg4IDAgMCAwIDEwIDEuODc2WiIgY2xpcC1ydWxlPSJldmVub2RkIi8+PHBhdGggZmlsbD0iI2ZmZiIgZD0iTTEwIDEyLjgxM2EuOTM3LjkzNyAwIDEgMCAwLTEuODc1LjkzNy45MzcgMCAwIDAgMCAxLjg3NFoiLz48L3N2Zz4=", st = "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyMCIgaGVpZ2h0PSIyMCIgZmlsbD0ibm9uZSI+PHBhdGggZmlsbD0iI2ZmZiIgZD0iTTE2LjI1IDYuMjVINy41VjQuMzc1YTIuNSAyLjUgMCAwIDEgMi41LTIuNWMxLjIgMCAyLjI4MS44NiAyLjUxMiAyYS42MjUuNjI1IDAgMCAwIDEuMjI2LS4yNWMtLjM1NC0xLjczOC0xLjkyNS0zLTMuNzM4LTNhMy43NTQgMy43NTQgMCAwIDAtMy43NSAzLjc1VjYuMjVoLTIuNUExLjI1IDEuMjUgMCAwIDAgMi41IDcuNXY4Ljc1YTEuMjUgMS4yNSAwIDAgMCAxLjI1IDEuMjVoMTIuNWExLjI1IDEuMjUgMCAwIDAgMS4yNS0xLjI1VjcuNWExLjI1IDEuMjUgMCAwIDAtMS4yNS0xLjI1Wm0wIDEwSDMuNzVWNy41aDEyLjV2OC43NVptLTUuMzEzLTQuMzc1YS45MzcuOTM3IDAgMSAxLTEuODc0IDAgLjkzNy45MzcgMCAwIDEgMS44NzQgMFoiLz48L3N2Zz4K", nt = "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyMCIgaGVpZ2h0PSIyMCIgZmlsbD0ibm9uZSI+PHBhdGggZmlsbD0iI2ZmZiIgZD0iTTIuNSA4LjEyNSAxMCAxMi41bDcuNS00LjM3NUwxMCAzLjc1IDIuNSA4LjEyNVoiLz48cGF0aCBmaWxsPSIjZmZmIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiIGQ9Ik05LjY4NSAzLjIxYS42MjUuNjI1IDAgMCAxIC42MyAwbDcuNSA0LjM3NWEuNjI1LjYyNSAwIDAgMSAwIDEuMDhsLTcuNSA0LjM3NWEuNjI1LjYyNSAwIDAgMS0uNjMgMGwtNy41LTQuMzc1YS42MjUuNjI1IDAgMCAxIDAtMS4wOGw3LjUtNC4zNzVaTTMuNzQgOC4xMjUgMTAgMTEuNzc2bDYuMjYtMy42NTFMMTAgNC40NzQgMy43NCA4LjEyNVoiIGNsaXAtcnVsZT0iZXZlbm9kZCIvPjxwYXRoIGZpbGw9IiNmZmYiIGZpbGwtcnVsZT0iZXZlbm9kZCIgZD0iTTUuNCA5LjQ2YS42MjUuNjI1IDAgMCAxIC42MyAwTDEwIDExLjc3NmwzLjk3LTIuMzE2YS42MjUuNjI1IDAgMCAxIC42MyAwbDMuMjE1IDEuODc1YS42MjUuNjI1IDAgMCAxIDAgMS4wOGwtNy41IDQuMzc1YS42MjUuNjI1IDAgMCAxLS42MyAwbC03LjUtNC4zNzVhLjYyNS42MjUgMCAwIDEgMC0xLjA4TDUuNCA5LjQ2Wm0tMS42NiAyLjQxNUwxMCAxNS41MjZsNi4yNi0zLjY1MS0xLjk3NC0xLjE1MS0zLjk3MSAyLjMxNmEuNjI1LjYyNSAwIDAgMS0uNjMgMGwtMy45Ny0yLjMxNi0xLjk3NSAxLjE1MVoiIGNsaXAtcnVsZT0iZXZlbm9kZCIvPjwvc3ZnPg==", ot = "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyMCIgaGVpZ2h0PSIyMCIgZmlsbD0ibm9uZSI+PHBhdGggZmlsbD0iI2ZmZiIgZmlsbC1ydWxlPSJldmVub2RkIiBkPSJNOS42ODUgMy4yMWEuNjI1LjYyNSAwIDAgMSAuNjMgMGw3LjUgNC4zNzVhLjYyNS42MjUgMCAwIDEgMCAxLjA4bC03LjUgNC4zNzVhLjYyNS42MjUgMCAwIDEtLjYzIDBsLTcuNS00LjM3NWEuNjI1LjYyNSAwIDAgMSAwLTEuMDhsNy41LTQuMzc1Wk0zLjc0IDguMTI1IDEwIDExLjc3Nmw2LjI2LTMuNjUxTDEwIDQuNDc0IDMuNzQgOC4xMjVaIiBjbGlwLXJ1bGU9ImV2ZW5vZGQiLz48cGF0aCBmaWxsPSIjZmZmIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiIGQ9Ik01LjcxNCAxMCAxMCAxMi41bDQuMjg2LTIuNSAzLjIxNCAxLjg3NUwxMCAxNi4yNWwtNy41LTQuMzc1TDUuNzE0IDEwWiIgY2xpcC1ydWxlPSJldmVub2RkIi8+PHBhdGggZmlsbD0iI2ZmZiIgZmlsbC1ydWxlPSJldmVub2RkIiBkPSJNNS40IDkuNDZhLjYyNS42MjUgMCAwIDEgLjYzIDBMMTAgMTEuNzc2bDMuOTctMi4zMTZhLjYyNS42MjUgMCAwIDEgLjYzIDBsMy4yMTUgMS44NzVhLjYyNS42MjUgMCAwIDEgMCAxLjA4bC03LjUgNC4zNzVhLjYyNS42MjUgMCAwIDEtLjYzIDBsLTcuNS00LjM3NWEuNjI1LjYyNSAwIDAgMSAwLTEuMDhMNS40IDkuNDZabS0xLjY2IDIuNDE1TDEwIDE1LjUyNmw2LjI2LTMuNjUxLTEuOTc0LTEuMTUxLTMuOTcxIDIuMzE2YS42MjUuNjI1IDAgMCAxLS42MyAwbC0zLjk3LTIuMzE2LTEuOTc1IDEuMTUxWiIgY2xpcC1ydWxlPSJldmVub2RkIi8+PC9zdmc+", at = "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyMCIgaGVpZ2h0PSIyMCIgZmlsbD0ibm9uZSI+PHBhdGggZmlsbD0iI2ZmZiIgZD0ibTIuNSA2LjI1IDcuNSA0LjM3NSA3LjUtNC4zNzVMMTAgMS44NzUgMi41IDYuMjVaIi8+PHBhdGggZmlsbD0iI2ZmZiIgZmlsbC1ydWxlPSJldmVub2RkIiBkPSJNOS42ODUgMS4zMzVhLjYyNS42MjUgMCAwIDEgLjYzIDBsNy41IDQuMzc1YS42MjUuNjI1IDAgMCAxIDAgMS4wOGwtNy41IDQuMzc1YS42MjUuNjI1IDAgMCAxLS42MyAwbC03LjUtNC4zNzVhLjYyNS42MjUgMCAwIDEgMC0xLjA4bDcuNS00LjM3NVpNMy43NCA2LjI1IDEwIDkuOTAxbDYuMjYtMy42NTFMMTAgMi41OTkgMy43NCA2LjI1WiIgY2xpcC1ydWxlPSJldmVub2RkIi8+PHBhdGggZmlsbD0iI2ZmZiIgZmlsbC1ydWxlPSJldmVub2RkIiBkPSJNNS40IDExLjMzNWEuNjI1LjYyNSAwIDAgMSAuNjMgMEwxMCAxMy42NTFsMy45Ny0yLjMxNmEuNjI1LjYyNSAwIDAgMSAuNjMgMGwzLjIxNSAxLjg3NWEuNjI1LjYyNSAwIDAgMSAwIDEuMDhsLTcuNSA0LjM3NWEuNjI1LjYyNSAwIDAgMS0uNjMgMGwtNy41LTQuMzc1YS42MjUuNjI1IDAgMCAxIDAtMS4wOEw1LjQgMTEuMzM1Wk0zLjc0IDEzLjc1IDEwIDE3LjQwMWw2LjI2LTMuNjUxLTEuOTc0LTEuMTUxLTMuOTcxIDIuMzE2YS42MjUuNjI1IDAgMCAxLS42MyAwbC0zLjk3LTIuMzE2TDMuNzQgMTMuNzVaIiBjbGlwLXJ1bGU9ImV2ZW5vZGQiLz48cGF0aCBmaWxsPSIjZmZmIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiIGQ9Ik01LjQgNy41ODVhLjYyNS42MjUgMCAwIDEgLjYzIDBMMTAgOS45MDFsMy45Ny0yLjMxNmEuNjI1LjYyNSAwIDAgMSAuNjMgMGwzLjIxNSAxLjg3NWEuNjI1LjYyNSAwIDAgMSAwIDEuMDhsLTcuNSA0LjM3NWEuNjI1LjYyNSAwIDAgMS0uNjMgMGwtNy41LTQuMzc1YS42MjUuNjI1IDAgMCAxIDAtMS4wOEw1LjQgNy41ODVaTTMuNzQgMTAgMTAgMTMuNjUxIDE2LjI2IDEwbC0xLjk3NC0xLjE1MS0zLjk3MSAyLjMxNmEuNjI1LjYyNSAwIDAgMS0uNjMgMGwtMy45Ny0yLjMxNkwzLjc0IDEwWiIgY2xpcC1ydWxlPSJldmVub2RkIi8+PC9zdmc+", it = "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyMCIgaGVpZ2h0PSIyMCIgZmlsbD0ibm9uZSI+PHBhdGggZmlsbD0iI2ZmZiIgZmlsbC1ydWxlPSJldmVub2RkIiBkPSJNMS45NiAxMy40MzVhLjYyNS42MjUgMCAwIDEgLjg1NS0uMjI1TDEwIDE3LjQwMWw3LjE4NS00LjE5YS42MjUuNjI1IDAgMCAxIC42MyAxLjA3OWwtNy41IDQuMzc1YS42MjUuNjI1IDAgMCAxLS42MyAwbC03LjUtNC4zNzVhLjYyNS42MjUgMCAwIDEtLjIyNS0uODU1Wk05LjY4NSAxLjMzNWEuNjI1LjYyNSAwIDAgMSAuNjMgMGw3LjUgNC4zNzVhLjYyNS42MjUgMCAwIDEgMCAxLjA4bC03LjUgNC4zNzVhLjYyNS42MjUgMCAwIDEtLjYzIDBsLTcuNS00LjM3NWEuNjI1LjYyNSAwIDAgMSAwLTEuMDhsNy41LTQuMzc1Wk0zLjc0IDYuMjUgMTAgOS45MDFsNi4yNi0zLjY1MUwxMCAyLjU5OSAzLjc0IDYuMjVaIiBjbGlwLXJ1bGU9ImV2ZW5vZGQiLz48cGF0aCBmaWxsPSIjZmZmIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiIGQ9Im01LjcxNCAxMS44NzUgNC4yODYgMi41IDQuMjg2LTIuNUwxNy41IDEzLjc1IDEwIDE4LjEyNSAyLjUgMTMuNzVsMy4yMTQtMS44NzVaIiBjbGlwLXJ1bGU9ImV2ZW5vZGQiLz48cGF0aCBmaWxsPSIjZmZmIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiIGQ9Ik01LjQgMTEuMzM1YS42MjUuNjI1IDAgMCAxIC42MyAwTDEwIDEzLjY1MWwzLjk3LTIuMzE2YS42MjUuNjI1IDAgMCAxIC42MyAwbDMuMjE1IDEuODc1YS42MjUuNjI1IDAgMCAxIDAgMS4wOGwtNy41IDQuMzc1YS42MjUuNjI1IDAgMCAxLS42MyAwbC03LjUtNC4zNzVhLjYyNS42MjUgMCAwIDEgMC0xLjA4TDUuNCAxMS4zMzVaTTMuNzQgMTMuNzUgMTAgMTcuNDAxbDYuMjYtMy42NTEtMS45NzQtMS4xNTEtMy45NzEgMi4zMTZhLjYyNS42MjUgMCAwIDEtLjYzIDBsLTMuOTctMi4zMTZMMy43NCAxMy43NVoiIGNsaXAtcnVsZT0iZXZlbm9kZCIvPjxwYXRoIGZpbGw9IiNmZmYiIGZpbGwtcnVsZT0iZXZlbm9kZCIgZD0iTTUuNCA3LjU4NWEuNjI1LjYyNSAwIDAgMSAuNjMgMEwxMCA5LjkwMWwzLjk3LTIuMzE2YS42MjUuNjI1IDAgMCAxIC42MyAwbDMuMjE1IDEuODc1YS42MjUuNjI1IDAgMCAxIDAgMS4wOGwtNy41IDQuMzc1YS42MjUuNjI1IDAgMCAxLS42MyAwbC03LjUtNC4zNzVhLjYyNS42MjUgMCAwIDEgMC0xLjA4TDUuNCA3LjU4NVpNMy43NCAxMCAxMCAxMy42NTEgMTYuMjYgMTBsLTEuOTc0LTEuMTUxLTMuOTcxIDIuMzE2YS42MjUuNjI1IDAgMCAxLS42MyAwbC0zLjk3LTIuMzE2TDMuNzQgMTBaIiBjbGlwLXJ1bGU9ImV2ZW5vZGQiLz48L3N2Zz4=", rt = "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyMCIgaGVpZ2h0PSIyMCIgZmlsbD0ibm9uZSI+PHBhdGggZmlsbD0iI0VDNEU0MCIgZmlsbC1ydWxlPSJldmVub2RkIiBkPSJNOC4xMjUgMS4yNUExLjg3NSAxLjg3NSAwIDAgMCA2LjI1IDMuMTI1di42MjVIMy4xMjVhLjYyNS42MjUgMCAwIDAgMCAxLjI1aC42MjV2MTEuMjVBMS4yNSAxLjI1IDAgMCAwIDUgMTcuNWgxMGExLjI1IDEuMjUgMCAwIDAgMS4yNS0xLjI1VjVoLjYyNWEuNjI1LjYyNSAwIDAgMCAwLTEuMjVIMTMuNzV2LS42MjVhMS44NzUgMS44NzUgMCAwIDAtMS44NzUtMS44NzVoLTMuNzVabTQuMzc1IDIuNXYtLjYyNWEuNjI1LjYyNSAwIDAgMC0uNjI1LS42MjVoLTMuNzVhLjYyNS42MjUgMCAwIDAtLjYyNS42MjV2LjYyNWg1Wk01IDE2LjI1VjVoMTB2MTEuMjVINVpNOC4xMjUgNy41Yy4zNDUgMCAuNjI1LjI4LjYyNS42MjV2NWEuNjI1LjYyNSAwIDEgMS0xLjI1IDB2LTVjMC0uMzQ1LjI4LS42MjUuNjI1LS42MjVabTQuMzc1IDUuNjI1di01YS42MjUuNjI1IDAgMCAwLTEuMjUgMHY1YS42MjUuNjI1IDAgMSAwIDEuMjUgMFoiIGNsaXAtcnVsZT0iZXZlbm9kZCIvPjwvc3ZnPg==", P = {
553
567
  style: {
554
568
  position: "absolute",
555
569
  display: "none",
@@ -616,54 +630,54 @@ const qe = "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMj
616
630
  ],
617
631
  offsetTop: 50,
618
632
  icons: {
619
- copyPaste: qe,
620
- delete: it,
621
- lock: et,
622
- unlock: tt,
623
- bringToFront: nt,
624
- sendToBack: ot,
625
- bringForward: st,
626
- sendBackwards: at
633
+ copyPaste: et,
634
+ delete: rt,
635
+ lock: tt,
636
+ unlock: st,
637
+ bringToFront: at,
638
+ sendToBack: it,
639
+ bringForward: nt,
640
+ sendBackwards: ot
627
641
  },
628
642
  handlers: {
629
- copyPaste: (c) => j(null, null, function* () {
630
- c.clipboardManager.copyPaste();
643
+ copyPaste: (d) => y(null, null, function* () {
644
+ d.clipboardManager.copyPaste();
631
645
  }),
632
- delete: (c) => {
633
- c.deletionManager.deleteSelectedObjects();
646
+ delete: (d) => {
647
+ d.deletionManager.deleteSelectedObjects();
634
648
  },
635
- lock: (c) => {
636
- c.objectLockManager.lockObject();
649
+ lock: (d) => {
650
+ d.objectLockManager.lockObject();
637
651
  },
638
- unlock: (c) => {
639
- c.objectLockManager.unlockObject();
652
+ unlock: (d) => {
653
+ d.objectLockManager.unlockObject();
640
654
  },
641
- bringForward: (c) => {
642
- c.layerManager.bringForward();
655
+ bringForward: (d) => {
656
+ d.layerManager.bringForward();
643
657
  },
644
- bringToFront: (c) => {
645
- c.layerManager.bringToFront();
658
+ bringToFront: (d) => {
659
+ d.layerManager.bringToFront();
646
660
  },
647
- sendToBack: (c) => {
648
- c.layerManager.sendToBack();
661
+ sendToBack: (d) => {
662
+ d.layerManager.sendToBack();
649
663
  },
650
- sendBackwards: (c) => {
651
- c.layerManager.sendBackwards();
664
+ sendBackwards: (d) => {
665
+ d.layerManager.sendBackwards();
652
666
  }
653
667
  }
654
668
  };
655
- class rt {
669
+ class ct {
656
670
  constructor({ editor: e }) {
657
671
  this.currentTarget = null, this.currentLocked = !1, this.isTransforming = !1, this.editor = e, this.canvas = e.canvas, this.options = e.options, this._initToolbar();
658
672
  }
659
673
  _initToolbar() {
660
674
  if (!this.options.showToolbar) return;
661
675
  const e = this.options.toolbar || {};
662
- this.config = be(I(I({}, Y), e), {
663
- style: I(I({}, Y.style), e.style || {}),
664
- btnStyle: I(I({}, Y.btnStyle), e.btnStyle || {}),
665
- icons: I(I({}, Y.icons), e.icons || {}),
666
- handlers: I(I({}, Y.handlers), e.handlers || {})
676
+ this.config = be(I(I({}, P), e), {
677
+ style: I(I({}, P.style), e.style || {}),
678
+ btnStyle: I(I({}, P.btnStyle), e.btnStyle || {}),
679
+ icons: I(I({}, P.icons), e.icons || {}),
680
+ handlers: I(I({}, P.handlers), e.handlers || {})
667
681
  }), this.currentTarget = null, this.currentLocked = !1, this.isTransforming = !1, this._onMouseDown = this._handleMouseDown.bind(this), this._onObjectMoving = this._startTransform.bind(this), this._onObjectScaling = this._startTransform.bind(this), this._onObjectRotating = this._startTransform.bind(this), this._onMouseUp = this._endTransform.bind(this), this._onObjectModified = this._endTransform.bind(this), this._onSelectionChange = this._updateToolbar.bind(this), this._onSelectionClear = () => {
668
682
  this.el.style.display = "none";
669
683
  }, this._createDOM(), this._bindEvents();
@@ -674,11 +688,11 @@ class rt {
674
688
  _createDOM() {
675
689
  const { style: e } = this.config;
676
690
  this.el = document.createElement("div"), Object.assign(this.el.style, e), this.canvas.wrapperEl.appendChild(this.el), this._onBtnOver = (t) => {
677
- const a = t.target.closest("button");
678
- a && Object.assign(a.style, this.config.btnHover);
691
+ const n = t.target.closest("button");
692
+ n && Object.assign(n.style, this.config.btnHover);
679
693
  }, this._onBtnOut = (t) => {
680
- const a = t.target.closest("button");
681
- a && Object.assign(a.style, this.config.btnStyle);
694
+ const n = t.target.closest("button");
695
+ n && Object.assign(n.style, this.config.btnStyle);
682
696
  }, this.el.addEventListener("mouseover", this._onBtnOver), this.el.addEventListener("mouseout", this._onBtnOut);
683
697
  }
684
698
  /**
@@ -690,13 +704,13 @@ class rt {
690
704
  _renderButtons(e) {
691
705
  this.el.innerHTML = "";
692
706
  for (const t of e) {
693
- const { name: s, handle: a } = t, { icons: n = {}, btnStyle: o, handlers: i = {} } = this.config, r = document.createElement("button");
694
- r.innerHTML = n[a] ? `<img src="${n[a]}" title="${s}" />` : s, Object.assign(r.style, o), r.onclick = () => {
695
- var d;
696
- return (d = i[a]) == null ? void 0 : d.call(i, this.editor);
697
- }, r.onmousedown = (d) => {
698
- d.stopPropagation(), d.preventDefault();
699
- }, r.ondragstart = (d) => d.preventDefault(), this.el.appendChild(r);
707
+ const { name: s, handle: n } = t, { icons: o = {}, btnStyle: a, handlers: i = {} } = this.config, r = document.createElement("button");
708
+ r.innerHTML = o[n] ? `<img src="${o[n]}" title="${s}" />` : s, Object.assign(r.style, a), r.onclick = () => {
709
+ var c;
710
+ return (c = i[n]) == null ? void 0 : c.call(i, this.editor);
711
+ }, r.onmousedown = (c) => {
712
+ c.stopPropagation(), c.preventDefault();
713
+ }, r.ondragstart = (c) => c.preventDefault(), this.el.appendChild(r);
700
714
  }
701
715
  }
702
716
  /**
@@ -752,12 +766,12 @@ class rt {
752
766
  this.el.style.display = "none";
753
767
  return;
754
768
  }
755
- const { el: t, config: s, canvas: a } = this;
769
+ const { el: t, config: s, canvas: n } = this;
756
770
  e.setCoords();
757
- const n = a.getZoom(), [, , , , o, i] = a.viewportTransform, { x: r } = e.getCenterPoint(), { top: d, height: h } = e.getBoundingRect(), u = r * n + o - t.offsetWidth / 2, g = s.offsetTop || 0, M = (d + h) * n + i + g;
771
+ const o = n.getZoom(), [, , , , a, i] = n.viewportTransform, { x: r } = e.getCenterPoint(), { top: c, height: h } = e.getBoundingRect(), g = r * o + a - t.offsetWidth / 2, u = s.offsetTop || 0, f = (c + h) * o + i + u;
758
772
  Object.assign(t.style, {
759
- left: `${u}px`,
760
- top: `${M}px`,
773
+ left: `${g}px`,
774
+ top: `${f}px`,
761
775
  display: "flex"
762
776
  });
763
777
  }
@@ -768,7 +782,7 @@ class rt {
768
782
  this.el.removeEventListener("mouseover", this._onBtnOver), this.el.removeEventListener("mouseout", this._onBtnOut), this.canvas.off("mouse:down", this._onMouseDown), this.canvas.off("object:moving", this._onObjectMoving), this.canvas.off("object:scaling", this._onObjectScaling), this.canvas.off("object:rotating", this._onObjectRotating), this.canvas.off("mouse:up", this._onMouseUp), this.canvas.off("object:modified", this._onObjectModified), this.canvas.off("selection:created", this._onSelectionChange), this.canvas.off("selection:updated", this._onSelectionChange), this.canvas.off("after:render", this._onSelectionChange), this.canvas.off("selection:cleared", this._onSelectionClear), this.el.remove();
769
783
  }
770
784
  }
771
- const ct = {
785
+ const dt = {
772
786
  position: "absolute",
773
787
  display: "none",
774
788
  background: "#2B2D33",
@@ -782,8 +796,8 @@ const ct = {
782
796
  "pointer-events": "none",
783
797
  "white-space": "nowrap",
784
798
  "box-shadow": "0 2px 8px rgba(0, 0, 0, 0.2)"
785
- }, ve = 16, Ae = 16, dt = "fabric-editor-angle-indicator";
786
- class de {
799
+ }, Ae = 16, Ce = 16, lt = "fabric-editor-angle-indicator";
800
+ class le {
787
801
  constructor({ editor: e }) {
788
802
  this.isActive = !1, this.currentAngle = 0, this.editor = e, this.canvas = e.canvas, this.options = e.options, this._createDOM(), this._bindEvents();
789
803
  }
@@ -791,7 +805,7 @@ class de {
791
805
  * Создание DOM-элемента индикатора
792
806
  */
793
807
  _createDOM() {
794
- this.el = document.createElement("div"), this.el.className = dt, Object.entries(ct).forEach(([e, t]) => {
808
+ this.el = document.createElement("div"), this.el.className = lt, Object.entries(dt).forEach(([e, t]) => {
795
809
  this.el.style.setProperty(e, t);
796
810
  }), this.canvas.wrapperEl.appendChild(this.el);
797
811
  }
@@ -811,7 +825,7 @@ class de {
811
825
  return;
812
826
  }
813
827
  const s = t.angle || 0;
814
- this.currentAngle = de._normalizeAngle(s), this.el.textContent = `${this.currentAngle}°`, this._positionIndicator(e.e), this.isActive || this._showIndicator();
828
+ this.currentAngle = le._normalizeAngle(s), this.el.textContent = `${this.currentAngle}°`, this._positionIndicator(e.e), this.isActive || this._showIndicator();
815
829
  }
816
830
  /**
817
831
  * Обработчик отпускания кнопки мыши
@@ -842,9 +856,9 @@ class de {
842
856
  */
843
857
  _positionIndicator(e) {
844
858
  const t = this.canvas.wrapperEl.getBoundingClientRect();
845
- let s = e.clientX - t.left + ve, a = e.clientY - t.top + Ae;
846
- const n = this.el.getBoundingClientRect(), o = n.width, i = n.height;
847
- s + o > t.width && (s = e.clientX - t.left - o - ve), a + i > t.height && (a = e.clientY - t.top - i - Ae), this.el.style.left = `${s}px`, this.el.style.top = `${a}px`;
859
+ let s = e.clientX - t.left + Ae, n = e.clientY - t.top + Ce;
860
+ const o = this.el.getBoundingClientRect(), a = o.width, i = o.height;
861
+ s + a > t.width && (s = e.clientX - t.left - a - Ae), n + i > t.height && (n = e.clientY - t.top - i - Ce), this.el.style.left = `${s}px`, this.el.style.top = `${n}px`;
848
862
  }
849
863
  /**
850
864
  * Показать индикатор
@@ -875,7 +889,7 @@ class de {
875
889
  this.canvas && (this.canvas.off("object:rotating", this._onObjectRotating), this.canvas.off("mouse:up", this._onMouseUp), this.canvas.off("object:modified", this._onObjectModified), this.canvas.off("selection:cleared", this._onSelectionCleared)), (e = this.el) != null && e.parentNode && this.el.parentNode.removeChild(this.el), this.el = null, this.editor = null, this.canvas = null, this.options = null;
876
890
  }
877
891
  }
878
- class $ {
892
+ class K {
879
893
  constructor({ editor: e }) {
880
894
  this.editor = e, this.canvas = e.canvas, this._historySuspendCount = 0, this.baseState = null, this.patches = [], this.currentIndex = 0, this.maxHistoryLength = e.options.maxHistoryLength, this.totalChangesCount = 0, this.baseStateChangesCount = 0, this._createDiffPatcher();
881
895
  }
@@ -887,7 +901,7 @@ class $ {
887
901
  return this.patches[this.currentIndex - 1] || null;
888
902
  }
889
903
  _createDiffPatcher() {
890
- this.diffPatcher = ze({
904
+ this.diffPatcher = Ze({
891
905
  objectHash(e) {
892
906
  const t = e;
893
907
  return [
@@ -943,10 +957,10 @@ class $ {
943
957
  */
944
958
  getFullState() {
945
959
  const { baseState: e, currentIndex: t, patches: s } = this;
946
- let a = JSON.parse(JSON.stringify(e));
947
- for (let n = 0; n < t; n += 1)
948
- a = this.diffPatcher.patch(a, s[n].diff);
949
- return console.log("getFullState state", a), a;
960
+ let n = JSON.parse(JSON.stringify(e));
961
+ for (let o = 0; o < t; o += 1)
962
+ n = this.diffPatcher.patch(n, s[o].diff);
963
+ return console.log("getFullState state", n), n;
950
964
  }
951
965
  /**
952
966
  * Сохраняем текущее состояние в виде диффа от последнего сохранённого полного состояния.
@@ -982,7 +996,7 @@ class $ {
982
996
  console.log("Нет изменений для сохранения.");
983
997
  return;
984
998
  }
985
- console.log("baseState", this.baseState), this.currentIndex < this.patches.length && this.patches.splice(this.currentIndex), console.log("diff", s), this.totalChangesCount += 1, this.patches.push({ id: A(), diff: s }), this.currentIndex += 1, this.patches.length > this.maxHistoryLength && (this.baseState = this.diffPatcher.patch(this.baseState, this.patches[0].diff), this.patches.shift(), this.currentIndex -= 1, this.baseStateChangesCount += 1), console.log("Состояние сохранено. Текущий индекс истории:", this.currentIndex);
999
+ console.log("baseState", this.baseState), this.currentIndex < this.patches.length && this.patches.splice(this.currentIndex), console.log("diff", s), this.totalChangesCount += 1, this.patches.push({ id: C(), diff: s }), this.currentIndex += 1, this.patches.length > this.maxHistoryLength && (this.baseState = this.diffPatcher.patch(this.baseState, this.patches[0].diff), this.patches.shift(), this.currentIndex -= 1, this.baseStateChangesCount += 1), console.log("Состояние сохранено. Текущий индекс истории:", this.currentIndex);
986
1000
  }
987
1001
  /**
988
1002
  * Сериализует customData объектов в строку. Это необходимо чтобы при вызове loadFromJSON fabricjs не пытался обрабатывать свойства внутри customData, как свойства FabricObject, если их названия совпадают с зарезервированными.
@@ -1015,19 +1029,19 @@ class $ {
1015
1029
  * @fires editor:history-state-loaded
1016
1030
  */
1017
1031
  loadStateFromFullState(e) {
1018
- return j(this, null, function* () {
1032
+ return y(this, null, function* () {
1019
1033
  if (!e) return;
1020
1034
  console.log("loadStateFromFullState fullState", e);
1021
- const { canvas: t, canvasManager: s, interactionBlocker: a, backgroundManager: n } = this.editor, { width: o, height: i } = t;
1022
- a.overlayMask = null, $._serializeCustomData(e), yield t.loadFromJSON(e, (l, u) => {
1023
- $._deserializeCustomData(l, u);
1035
+ const { canvas: t, canvasManager: s, interactionBlocker: n, backgroundManager: o } = this.editor, { width: a, height: i } = t;
1036
+ n.overlayMask = null, K._serializeCustomData(e), yield t.loadFromJSON(e, (l, g) => {
1037
+ K._deserializeCustomData(l, g);
1024
1038
  });
1025
1039
  const r = t.getObjects().find((l) => l.id === "montage-area");
1026
- r && (this.editor.montageArea = r, (o !== t.getWidth() || i !== t.getHeight()) && s.updateCanvas());
1027
- const d = t.getObjects().find((l) => l.id === "overlay-mask");
1028
- d && (a.overlayMask = d, a.overlayMask.visible = !1);
1040
+ r && (this.editor.montageArea = r, (a !== t.getWidth() || i !== t.getHeight()) && s.updateCanvas());
1041
+ const c = t.getObjects().find((l) => l.id === "overlay-mask");
1042
+ c && (n.overlayMask = c, n.overlayMask.visible = !1);
1029
1043
  const h = t.getObjects().find((l) => l.id === "background");
1030
- h ? (n.backgroundObject = h, n.refresh()) : n.removeBackground({ withoutSave: !0 }), t.renderAll(), t.fire("editor:history-state-loaded", {
1044
+ h ? (o.backgroundObject = h, o.refresh()) : o.removeBackground({ withoutSave: !0 }), t.renderAll(), t.fire("editor:history-state-loaded", {
1031
1045
  fullState: e,
1032
1046
  currentIndex: this.currentIndex,
1033
1047
  totalChangesCount: this.totalChangesCount,
@@ -1042,7 +1056,7 @@ class $ {
1042
1056
  * @fires editor:undo
1043
1057
  */
1044
1058
  undo() {
1045
- return j(this, null, function* () {
1059
+ return y(this, null, function* () {
1046
1060
  if (!this.skipHistory) {
1047
1061
  if (this.currentIndex <= 0) {
1048
1062
  console.log("Нет предыдущих состояний для отмены.");
@@ -1079,7 +1093,7 @@ class $ {
1079
1093
  * @fires editor:redo
1080
1094
  */
1081
1095
  redo() {
1082
- return j(this, null, function* () {
1096
+ return y(this, null, function* () {
1083
1097
  if (!this.skipHistory) {
1084
1098
  if (this.currentIndex >= this.patches.length) {
1085
1099
  console.log("Нет состояний для повтора.");
@@ -1112,8 +1126,8 @@ class $ {
1112
1126
  });
1113
1127
  }
1114
1128
  }
1115
- const lt = 0.1, ht = 2, ut = 0.1, gt = 90, U = 16, z = 16, k = 4096, _ = 4096, Ce = "application/image-editor:";
1116
- class N {
1129
+ const ht = 0.1, gt = 2, Se = 0.1, ut = 90, Z = 16, H = 16, B = 4096, x = 4096, De = "application/image-editor:";
1130
+ class _ {
1117
1131
  constructor({ editor: e }) {
1118
1132
  this.editor = e, this.options = e.options, this._createdBlobUrls = [], this.acceptContentTypes = this.editor.options.acceptContentTypes, this.acceptFormats = this.getAllowedFormatsFromContentTypes();
1119
1133
  }
@@ -1130,111 +1144,111 @@ class N {
1130
1144
  * @returns возвращает Promise с объектом изображения или null в случае ошибки
1131
1145
  */
1132
1146
  importImage(e) {
1133
- return j(this, null, function* () {
1147
+ return y(this, null, function* () {
1134
1148
  const {
1135
1149
  source: t,
1136
1150
  scale: s = `image-${this.options.scaleType}`,
1137
- withoutSave: a = !1,
1138
- fromClipboard: n = !1,
1139
- isBackground: o = !1,
1151
+ withoutSave: n = !1,
1152
+ fromClipboard: o = !1,
1153
+ isBackground: a = !1,
1140
1154
  withoutSelection: i = !1
1141
1155
  } = e;
1142
1156
  if (!t) return null;
1143
- const { canvas: r, montageArea: d, transformManager: h, historyManager: l, errorManager: u } = this.editor, g = yield this.getContentType(t), M = N.getFormatFromContentType(g), { acceptContentTypes: m, acceptFormats: p } = this;
1144
- if (!this.isAllowedContentType(g)) {
1145
- const f = `Неверный contentType для изображения: ${g}. Ожидается один из: ${this.acceptContentTypes.join(", ")}.`;
1146
- return u.emitError({
1157
+ const { canvas: r, montageArea: c, transformManager: h, historyManager: l, errorManager: g } = this.editor, u = yield this.getContentType(t), f = _.getFormatFromContentType(u), { acceptContentTypes: M, acceptFormats: b } = this;
1158
+ if (!this.isAllowedContentType(u)) {
1159
+ const m = `Неверный contentType для изображения: ${u}. Ожидается один из: ${this.acceptContentTypes.join(", ")}.`;
1160
+ return g.emitError({
1147
1161
  origin: "ImageManager",
1148
1162
  method: "importImage",
1149
1163
  code: "INVALID_CONTENT_TYPE",
1150
- message: f,
1164
+ message: m,
1151
1165
  data: {
1152
1166
  source: t,
1153
- format: M,
1154
- contentType: g,
1155
- acceptContentTypes: m,
1156
- acceptFormats: p,
1157
- fromClipboard: n,
1158
- isBackground: o,
1167
+ format: f,
1168
+ contentType: u,
1169
+ acceptContentTypes: M,
1170
+ acceptFormats: b,
1171
+ fromClipboard: o,
1172
+ isBackground: a,
1159
1173
  withoutSelection: i
1160
1174
  }
1161
1175
  }), null;
1162
1176
  }
1163
1177
  l.suspendHistory();
1164
1178
  try {
1165
- let f, b;
1179
+ let m, p;
1166
1180
  if (t instanceof File)
1167
- f = URL.createObjectURL(t);
1181
+ m = URL.createObjectURL(t);
1168
1182
  else if (typeof t == "string") {
1169
- const D = yield (yield fetch(t, { mode: "cors" })).blob();
1170
- f = URL.createObjectURL(D);
1183
+ const S = yield (yield fetch(t, { mode: "cors" })).blob();
1184
+ m = URL.createObjectURL(S);
1171
1185
  } else
1172
- return u.emitError({
1186
+ return g.emitError({
1173
1187
  origin: "ImageManager",
1174
1188
  method: "importImage",
1175
1189
  code: "INVALID_SOURCE_TYPE",
1176
1190
  message: "Неверный тип источника изображения. Ожидается URL или объект File.",
1177
1191
  data: {
1178
1192
  source: t,
1179
- format: M,
1180
- contentType: g,
1181
- acceptContentTypes: m,
1182
- acceptFormats: p,
1183
- fromClipboard: n,
1184
- isBackground: o,
1193
+ format: f,
1194
+ contentType: u,
1195
+ acceptContentTypes: M,
1196
+ acceptFormats: b,
1197
+ fromClipboard: o,
1198
+ isBackground: a,
1185
1199
  withoutSelection: i
1186
1200
  }
1187
1201
  }), null;
1188
- if (this._createdBlobUrls.push(f), M === "svg") {
1189
- const C = yield ke(f);
1190
- b = W.groupSVGElements(C.objects, C.options);
1202
+ if (this._createdBlobUrls.push(m), f === "svg") {
1203
+ const A = yield _e(m);
1204
+ p = F.groupSVGElements(A.objects, A.options);
1191
1205
  } else
1192
- b = yield Z.fromURL(f, { crossOrigin: "anonymous" });
1193
- const { width: S, height: T } = b;
1194
- if (b instanceof Z) {
1195
- const C = b.getElement();
1196
- let D = "";
1197
- if (C instanceof HTMLImageElement ? D = C.src : C instanceof HTMLCanvasElement && (D = C.toDataURL()), T > _ || S > k) {
1198
- const B = yield this.resizeImageToBoundaries(D, "max"), L = URL.createObjectURL(B);
1199
- this._createdBlobUrls.push(L), b = yield Z.fromURL(L, { crossOrigin: "anonymous" });
1200
- } else if (T < z || S < U) {
1201
- const B = yield this.resizeImageToBoundaries(D, "min"), L = URL.createObjectURL(B);
1202
- this._createdBlobUrls.push(L), b = yield Z.fromURL(L, { crossOrigin: "anonymous" });
1206
+ p = yield z.fromURL(m, { crossOrigin: "anonymous" });
1207
+ const { width: D, height: w } = p;
1208
+ if (p instanceof z) {
1209
+ const A = p.getElement();
1210
+ let S = "";
1211
+ if (A instanceof HTMLImageElement ? S = A.src : A instanceof HTMLCanvasElement && (S = A.toDataURL()), w > x || D > B) {
1212
+ const L = yield this.resizeImageToBoundaries(S, "max"), O = URL.createObjectURL(L);
1213
+ this._createdBlobUrls.push(O), p = yield z.fromURL(O, { crossOrigin: "anonymous" });
1214
+ } else if (w < H || D < Z) {
1215
+ const L = yield this.resizeImageToBoundaries(S, "min"), O = URL.createObjectURL(L);
1216
+ this._createdBlobUrls.push(O), p = yield z.fromURL(O, { crossOrigin: "anonymous" });
1203
1217
  }
1204
1218
  }
1205
- if (b.set("id", `${b.type}-${A()}`), b.set("format", M), s === "scale-montage")
1206
- this.editor.canvasManager.scaleMontageAreaToImage({ object: b, withoutSave: !0 });
1219
+ if (p.set("id", `${p.type}-${C()}`), p.set("format", f), s === "scale-montage")
1220
+ this.editor.canvasManager.scaleMontageAreaToImage({ object: p, withoutSave: !0 });
1207
1221
  else {
1208
- const { width: C, height: D } = d, B = this.calculateScaleFactor({ imageObject: b, scaleType: s });
1209
- s === "image-contain" && B < 1 ? h.fitObject({ object: b, type: "contain", withoutSave: !0 }) : s === "image-cover" && (S > C || T > D) && h.fitObject({ object: b, type: "cover", withoutSave: !0 });
1222
+ const { width: A, height: S } = c, L = this.calculateScaleFactor({ imageObject: p, scaleType: s });
1223
+ s === "image-contain" && L < 1 ? h.fitObject({ object: p, type: "contain", withoutSave: !0 }) : s === "image-cover" && (D > A || w > S) && h.fitObject({ object: p, type: "cover", withoutSave: !0 });
1210
1224
  }
1211
- r.add(b), r.centerObject(b), i || r.setActiveObject(b), r.renderAll(), l.resumeHistory(), a || l.saveState();
1212
- const H = {
1213
- image: b,
1214
- format: M,
1215
- contentType: g,
1225
+ r.add(p), r.centerObject(p), i || r.setActiveObject(p), r.renderAll(), l.resumeHistory(), n || l.saveState();
1226
+ const T = {
1227
+ image: p,
1228
+ format: f,
1229
+ contentType: u,
1216
1230
  scale: s,
1217
- withoutSave: a,
1231
+ withoutSave: n,
1218
1232
  source: t,
1219
- fromClipboard: n,
1220
- isBackground: o,
1233
+ fromClipboard: o,
1234
+ isBackground: a,
1221
1235
  withoutSelection: i
1222
1236
  };
1223
- return r.fire("editor:image-imported", H), H;
1224
- } catch (f) {
1225
- return u.emitError({
1237
+ return r.fire("editor:image-imported", T), T;
1238
+ } catch (m) {
1239
+ return g.emitError({
1226
1240
  origin: "ImageManager",
1227
1241
  method: "importImage",
1228
1242
  code: "IMPORT_FAILED",
1229
- message: `Ошибка импорта изображения: ${f.message}`,
1243
+ message: `Ошибка импорта изображения: ${m.message}`,
1230
1244
  data: {
1231
1245
  source: t,
1232
- format: M,
1233
- contentType: g,
1246
+ format: f,
1247
+ contentType: u,
1234
1248
  scale: s,
1235
- withoutSave: a,
1236
- fromClipboard: n,
1237
- isBackground: o,
1249
+ withoutSave: n,
1250
+ fromClipboard: o,
1251
+ isBackground: a,
1238
1252
  withoutSelection: i
1239
1253
  }
1240
1254
  }), l.resumeHistory(), null;
@@ -1250,24 +1264,24 @@ class N {
1250
1264
  * @returns возвращает Promise с Blob-объектом уменьшенного изображения
1251
1265
  */
1252
1266
  resizeImageToBoundaries(e, t = "max") {
1253
- return j(this, null, function* () {
1254
- let s = `Размер изображения больше максимального размера канваса, поэтому оно будет уменьшено до максимальных размеров c сохранением пропорций: ${k}x${_}`;
1255
- t === "min" && (s = `Размер изображения меньше минимального размера канваса, поэтому оно будет увеличено до минимальных размеров c сохранением пропорций: ${U}x${z}`);
1256
- const a = {
1267
+ return y(this, null, function* () {
1268
+ let s = `Размер изображения больше максимального размера канваса, поэтому оно будет уменьшено до максимальных размеров c сохранением пропорций: ${B}x${x}`;
1269
+ t === "min" && (s = `Размер изображения меньше минимального размера канваса, поэтому оно будет увеличено до минимальных размеров c сохранением пропорций: ${Z}x${H}`);
1270
+ const n = {
1257
1271
  dataURL: e,
1258
1272
  sizeType: t,
1259
- maxWidth: k,
1260
- maxHeight: _,
1261
- minWidth: U,
1262
- minHeight: z
1273
+ maxWidth: B,
1274
+ maxHeight: x,
1275
+ minWidth: Z,
1276
+ minHeight: H
1263
1277
  };
1264
1278
  return this.editor.errorManager.emitWarning({
1265
1279
  origin: "ImageManager",
1266
1280
  method: "resizeImageToBoundaries",
1267
1281
  code: "IMAGE_RESIZE_WARNING",
1268
1282
  message: s,
1269
- data: a
1270
- }), this.editor.workerManager.post("resizeImage", a);
1283
+ data: n
1284
+ }), this.editor.workerManager.post("resizeImage", n);
1271
1285
  });
1272
1286
  }
1273
1287
  /**
@@ -1282,105 +1296,105 @@ class N {
1282
1296
  * @fires editor:canvas-exported
1283
1297
  */
1284
1298
  exportCanvasAsImageFile() {
1285
- return j(this, arguments, function* (e = {}) {
1299
+ return y(this, arguments, function* (e = {}) {
1286
1300
  const {
1287
1301
  fileName: t = "image.png",
1288
1302
  contentType: s = "image/png",
1289
- exportAsBase64: a = !1,
1290
- exportAsBlob: n = !1
1291
- } = e, { canvas: o, montageArea: i, workerManager: r, interactionBlocker: d } = this.editor;
1303
+ exportAsBase64: n = !1,
1304
+ exportAsBlob: o = !1
1305
+ } = e, { canvas: a, montageArea: i, workerManager: r, interactionBlocker: c } = this.editor;
1292
1306
  try {
1293
- const h = s === "application/pdf", l = h ? "image/jpg" : s, u = N.getFormatFromContentType(l);
1307
+ const h = s === "application/pdf", l = h ? "image/jpg" : s, g = _.getFormatFromContentType(l);
1294
1308
  i.setCoords();
1295
- const { left: g, top: M, width: m, height: p } = i.getBoundingRect(), f = yield o.clone(["id", "format", "locked"]);
1296
- f.enableRetinaScaling = !1, ["image/jpg", "image/jpeg"].includes(l) && (f.backgroundColor = "#ffffff");
1297
- const b = f.getObjects().find((y) => y.id === i.id);
1298
- if (b && (b.visible = !1), d != null && d.isBlocked) {
1299
- const y = f.getObjects().find((w) => w.id === d.overlayMask.id);
1300
- y && (y.visible = !1);
1309
+ const { left: u, top: f, width: M, height: b } = i.getBoundingRect(), m = yield a.clone(["id", "format", "locked"]);
1310
+ m.enableRetinaScaling = !1, ["image/jpg", "image/jpeg"].includes(l) && (m.backgroundColor = "#ffffff");
1311
+ const p = m.getObjects().find((j) => j.id === i.id);
1312
+ if (p && (p.visible = !1), c != null && c.isBlocked) {
1313
+ const j = m.getObjects().find((E) => E.id === c.overlayMask.id);
1314
+ j && (j.visible = !1);
1301
1315
  }
1302
- f.viewportTransform = [1, 0, 0, 1, -g, -M], f.setDimensions({ width: m, height: p }, { backstoreOnly: !0 }), f.renderAll();
1303
- const S = f.getObjects().filter((y) => y.format).every((y) => y.format === "svg");
1304
- if (u === "svg" && S) {
1305
- const y = f.toSVG();
1306
- f.dispose();
1307
- const E = {
1308
- image: N._exportSVGStringAsFile(y, {
1309
- exportAsBase64: a,
1310
- exportAsBlob: n,
1316
+ m.viewportTransform = [1, 0, 0, 1, -u, -f], m.setDimensions({ width: M, height: b }, { backstoreOnly: !0 }), m.renderAll();
1317
+ const D = m.getObjects().filter((j) => j.format).every((j) => j.format === "svg");
1318
+ if (g === "svg" && D) {
1319
+ const j = m.toSVG();
1320
+ m.dispose();
1321
+ const N = {
1322
+ image: _._exportSVGStringAsFile(j, {
1323
+ exportAsBase64: n,
1324
+ exportAsBlob: o,
1311
1325
  fileName: t
1312
1326
  }),
1313
1327
  format: "svg",
1314
1328
  contentType: "image/svg+xml",
1315
1329
  fileName: t.replace(/\.[^/.]+$/, ".svg")
1316
1330
  };
1317
- return o.fire("editor:canvas-exported", E), E;
1331
+ return a.fire("editor:canvas-exported", N), N;
1318
1332
  }
1319
- const T = yield new Promise((y, w) => {
1320
- f.getElement().toBlob((E) => {
1321
- E ? y(E) : w(new Error("Failed to create Blob from canvas"));
1333
+ const w = yield new Promise((j, E) => {
1334
+ m.getElement().toBlob((N) => {
1335
+ N ? j(N) : E(new Error("Failed to create Blob from canvas"));
1322
1336
  });
1323
1337
  });
1324
- if (f.dispose(), n) {
1325
- const y = {
1326
- image: T,
1327
- format: u,
1338
+ if (m.dispose(), o) {
1339
+ const j = {
1340
+ image: w,
1341
+ format: g,
1328
1342
  contentType: l,
1329
1343
  fileName: t
1330
1344
  };
1331
- return o.fire("editor:canvas-exported", y), y;
1345
+ return a.fire("editor:canvas-exported", j), j;
1332
1346
  }
1333
- const H = yield createImageBitmap(T), C = yield r.post(
1347
+ const T = yield createImageBitmap(w), A = yield r.post(
1334
1348
  "toDataURL",
1335
- { format: u, quality: 1, bitmap: H },
1336
- [H]
1349
+ { format: g, quality: 1, bitmap: T },
1350
+ [T]
1337
1351
  );
1338
1352
  if (h) {
1339
- const w = m * 0.264583, E = p * 0.264583, Ee = (yield this.editor.moduleLoader.loadModule("jspdf")).jsPDF, ee = new Ee({
1340
- orientation: w > E ? "landscape" : "portrait",
1353
+ const E = M * 0.264583, N = b * 0.264583, te = (yield this.editor.moduleLoader.loadModule("jspdf")).jsPDF, se = new te({
1354
+ orientation: E > N ? "landscape" : "portrait",
1341
1355
  unit: "mm",
1342
- format: [w, E]
1356
+ format: [E, N]
1343
1357
  });
1344
- if (ee.addImage(String(C), "JPG", 0, 0, w, E), a) {
1345
- const ge = {
1346
- image: ee.output("datauristring"),
1358
+ if (se.addImage(String(A), "JPG", 0, 0, E, N), n) {
1359
+ const fe = {
1360
+ image: se.output("datauristring"),
1347
1361
  format: "pdf",
1348
1362
  contentType: "application/pdf",
1349
1363
  fileName: t
1350
1364
  };
1351
- return o.fire("editor:canvas-exported", ge), ge;
1365
+ return a.fire("editor:canvas-exported", fe), fe;
1352
1366
  }
1353
- const Oe = ee.output("blob"), ue = {
1354
- image: new File([Oe], t, { type: "application/pdf" }),
1367
+ const we = se.output("blob"), ue = {
1368
+ image: new File([we], t, { type: "application/pdf" }),
1355
1369
  format: "pdf",
1356
1370
  contentType: "application/pdf",
1357
1371
  fileName: t
1358
1372
  };
1359
- return o.fire("editor:canvas-exported", ue), ue;
1373
+ return a.fire("editor:canvas-exported", ue), ue;
1360
1374
  }
1361
- if (a) {
1362
- const y = {
1363
- image: C,
1364
- format: u,
1375
+ if (n) {
1376
+ const j = {
1377
+ image: A,
1378
+ format: g,
1365
1379
  contentType: l,
1366
1380
  fileName: t
1367
1381
  };
1368
- return o.fire("editor:canvas-exported", y), y;
1382
+ return a.fire("editor:canvas-exported", j), j;
1369
1383
  }
1370
- const D = u === "svg" && !S ? t.replace(/\.[^/.]+$/, ".png") : t, L = {
1371
- image: new File([T], D, { type: l }),
1372
- format: u,
1384
+ const S = g === "svg" && !D ? t.replace(/\.[^/.]+$/, ".png") : t, O = {
1385
+ image: new File([w], S, { type: l }),
1386
+ format: g,
1373
1387
  contentType: l,
1374
- fileName: D
1388
+ fileName: S
1375
1389
  };
1376
- return o.fire("editor:canvas-exported", L), L;
1390
+ return a.fire("editor:canvas-exported", O), O;
1377
1391
  } catch (h) {
1378
1392
  return this.editor.errorManager.emitError({
1379
1393
  origin: "ImageManager",
1380
1394
  method: "exportCanvasAsImageFile",
1381
1395
  code: "IMAGE_EXPORT_FAILED",
1382
1396
  message: `Ошибка экспорта изображения: ${h.message}`,
1383
- data: { contentType: s, fileName: t, exportAsBase64: a, exportAsBlob: n }
1397
+ data: { contentType: s, fileName: t, exportAsBase64: n, exportAsBlob: o }
1384
1398
  }), null;
1385
1399
  }
1386
1400
  });
@@ -1397,88 +1411,88 @@ class N {
1397
1411
  * @fires editor:object-exported
1398
1412
  */
1399
1413
  exportObjectAsImageFile() {
1400
- return j(this, arguments, function* (e = {}) {
1414
+ return y(this, arguments, function* (e = {}) {
1401
1415
  const {
1402
1416
  object: t,
1403
1417
  fileName: s = "image.png",
1404
- contentType: a = "image/png",
1405
- exportAsBase64: n = !1,
1406
- exportAsBlob: o = !1
1407
- } = e, { canvas: i, workerManager: r } = this.editor, d = t || i.getActiveObject();
1408
- if (!d)
1418
+ contentType: n = "image/png",
1419
+ exportAsBase64: o = !1,
1420
+ exportAsBlob: a = !1
1421
+ } = e, { canvas: i, workerManager: r } = this.editor, c = t || i.getActiveObject();
1422
+ if (!c)
1409
1423
  return this.editor.errorManager.emitError({
1410
1424
  origin: "ImageManager",
1411
1425
  method: "exportObjectAsImageFile",
1412
1426
  code: "NO_OBJECT_SELECTED",
1413
1427
  message: "Не выбран объект для экспорта",
1414
- data: { contentType: a, fileName: s, exportAsBase64: n, exportAsBlob: o }
1428
+ data: { contentType: n, fileName: s, exportAsBase64: o, exportAsBlob: a }
1415
1429
  }), null;
1416
1430
  try {
1417
- const h = N.getFormatFromContentType(a);
1431
+ const h = _.getFormatFromContentType(n);
1418
1432
  if (h === "svg") {
1419
- const m = d.toSVG(), p = N._exportSVGStringAsFile(m, {
1420
- exportAsBase64: n,
1421
- exportAsBlob: o,
1433
+ const M = c.toSVG(), b = _._exportSVGStringAsFile(M, {
1434
+ exportAsBase64: o,
1435
+ exportAsBlob: a,
1422
1436
  fileName: s
1423
- }), f = {
1424
- object: d,
1425
- image: p,
1437
+ }), m = {
1438
+ object: c,
1439
+ image: b,
1426
1440
  format: h,
1427
1441
  contentType: "image/svg+xml",
1428
1442
  fileName: s.replace(/\.[^/.]+$/, ".svg")
1429
1443
  };
1430
- return i.fire("editor:object-exported", f), f;
1444
+ return i.fire("editor:object-exported", m), m;
1431
1445
  }
1432
- if (n && d instanceof Z) {
1433
- const m = yield createImageBitmap(d.getElement()), p = yield r.post(
1446
+ if (o && c instanceof z) {
1447
+ const M = yield createImageBitmap(c.getElement()), b = yield r.post(
1434
1448
  "toDataURL",
1435
1449
  {
1436
1450
  format: h,
1437
1451
  quality: 1,
1438
- bitmap: m
1452
+ bitmap: M
1439
1453
  },
1440
- [m]
1441
- ), f = {
1442
- object: d,
1443
- image: p,
1454
+ [M]
1455
+ ), m = {
1456
+ object: c,
1457
+ image: b,
1444
1458
  format: h,
1445
- contentType: a,
1459
+ contentType: n,
1446
1460
  fileName: s
1447
1461
  };
1448
- return i.fire("editor:object-exported", f), f;
1462
+ return i.fire("editor:object-exported", m), m;
1449
1463
  }
1450
- const l = d.toCanvasElement({
1464
+ const l = c.toCanvasElement({
1451
1465
  enableRetinaScaling: !1
1452
- }), u = yield new Promise((m, p) => {
1453
- l.toBlob((f) => {
1454
- f ? m(f) : p(new Error("Failed to create Blob from canvas"));
1466
+ }), g = yield new Promise((M, b) => {
1467
+ l.toBlob((m) => {
1468
+ m ? M(m) : b(new Error("Failed to create Blob from canvas"));
1455
1469
  });
1456
1470
  });
1457
- if (o) {
1458
- const m = {
1459
- object: d,
1460
- image: u,
1471
+ if (a) {
1472
+ const M = {
1473
+ object: c,
1474
+ image: g,
1461
1475
  format: h,
1462
- contentType: a,
1476
+ contentType: n,
1463
1477
  fileName: s
1464
1478
  };
1465
- return i.fire("editor:object-exported", m), m;
1479
+ return i.fire("editor:object-exported", M), M;
1466
1480
  }
1467
- const g = new File([u], s, { type: a }), M = {
1468
- object: d,
1469
- image: g,
1481
+ const u = new File([g], s, { type: n }), f = {
1482
+ object: c,
1483
+ image: u,
1470
1484
  format: h,
1471
- contentType: a,
1485
+ contentType: n,
1472
1486
  fileName: s
1473
1487
  };
1474
- return i.fire("editor:object-exported", M), M;
1488
+ return i.fire("editor:object-exported", f), f;
1475
1489
  } catch (h) {
1476
1490
  return this.editor.errorManager.emitError({
1477
1491
  origin: "ImageManager",
1478
1492
  method: "exportObjectAsImageFile",
1479
1493
  code: "IMAGE_EXPORT_FAILED",
1480
1494
  message: `Ошибка экспорта объекта: ${h.message}`,
1481
- data: { contentType: a, fileName: s, exportAsBase64: n, exportAsBlob: o }
1495
+ data: { contentType: n, fileName: s, exportAsBase64: o, exportAsBlob: a }
1482
1496
  }), null;
1483
1497
  }
1484
1498
  });
@@ -1494,7 +1508,7 @@ class N {
1494
1508
  * @returns массив допустимых форматов изображений
1495
1509
  */
1496
1510
  getAllowedFormatsFromContentTypes() {
1497
- return this.acceptContentTypes.map((e) => N.getFormatFromContentType(e)).filter((e) => e);
1511
+ return this.acceptContentTypes.map((e) => _.getFormatFromContentType(e)).filter((e) => e);
1498
1512
  }
1499
1513
  /**
1500
1514
  * Проверяет, является ли contentType допустимым типом изображения.
@@ -1510,7 +1524,7 @@ class N {
1510
1524
  * @public
1511
1525
  */
1512
1526
  getContentType(e) {
1513
- return j(this, null, function* () {
1527
+ return y(this, null, function* () {
1514
1528
  return typeof e == "string" ? this.getContentTypeFromUrl(e) : e.type || "application/octet-stream";
1515
1529
  });
1516
1530
  }
@@ -1521,7 +1535,7 @@ class N {
1521
1535
  * @public
1522
1536
  */
1523
1537
  getContentTypeFromUrl(e) {
1524
- return j(this, null, function* () {
1538
+ return y(this, null, function* () {
1525
1539
  if (e.startsWith("data:")) {
1526
1540
  const t = e.match(/^data:([^;]+)/);
1527
1541
  return t ? t[1] : "application/octet-stream";
@@ -1545,11 +1559,11 @@ class N {
1545
1559
  getContentTypeFromExtension(e) {
1546
1560
  var t;
1547
1561
  try {
1548
- const a = (t = new URL(e).pathname.split(".").pop()) == null ? void 0 : t.toLowerCase(), n = {};
1549
- return this.acceptContentTypes.forEach((o) => {
1550
- const i = N.getFormatFromContentType(o);
1551
- i && (n[i] = o);
1552
- }), a && n[a] || "application/octet-stream";
1562
+ const n = (t = new URL(e).pathname.split(".").pop()) == null ? void 0 : t.toLowerCase(), o = {};
1563
+ return this.acceptContentTypes.forEach((a) => {
1564
+ const i = _.getFormatFromContentType(a);
1565
+ i && (o[i] = a);
1566
+ }), n && o[n] || "application/octet-stream";
1553
1567
  } catch (s) {
1554
1568
  return console.warn("Не удалось определить расширение из URL:", e, s), "application/octet-stream";
1555
1569
  }
@@ -1567,8 +1581,8 @@ class N {
1567
1581
  }) {
1568
1582
  const { montageArea: s } = this.editor;
1569
1583
  if (!s || !e) return 1;
1570
- const a = s.width, n = s.height, { width: o, height: i } = e;
1571
- return t === "contain" || t === "image-contain" ? Math.min(a / o, n / i) : t === "cover" || t === "image-cover" ? Math.max(a / o, n / i) : 1;
1584
+ const n = s.width, o = s.height, { width: a, height: i } = e;
1585
+ return t === "contain" || t === "image-contain" ? Math.min(n / a, o / i) : t === "cover" || t === "image-cover" ? Math.max(n / a, o / i) : 1;
1572
1586
  }
1573
1587
  /**
1574
1588
  * Преобразует SVG-строку в Blob, файл, или base64
@@ -1584,9 +1598,9 @@ class N {
1584
1598
  static _exportSVGStringAsFile(e, {
1585
1599
  exportAsBase64: t,
1586
1600
  exportAsBlob: s,
1587
- fileName: a = "image.svg"
1601
+ fileName: n = "image.svg"
1588
1602
  } = {}) {
1589
- return s ? new Blob([e], { type: "image/svg+xml" }) : t ? `data:image/svg+xml;base64,${window.btoa(encodeURIComponent(e))}` : new File([e], a.replace(/\.[^/.]+$/, ".svg"), { type: "image/svg+xml" });
1603
+ return s ? new Blob([e], { type: "image/svg+xml" }) : t ? `data:image/svg+xml;base64,${window.btoa(encodeURIComponent(e))}` : new File([e], n.replace(/\.[^/.]+$/, ".svg"), { type: "image/svg+xml" });
1590
1604
  }
1591
1605
  /**
1592
1606
  * Извлекает чистый формат (subtype) из contentType,
@@ -1600,11 +1614,11 @@ class N {
1600
1614
  return t ? t[1] : "";
1601
1615
  }
1602
1616
  }
1603
- const x = (c, e, t) => Math.max(Math.min(c, t), e), Se = (c, e) => c * e, ft = (c, e) => new X(c / 2, e / 2);
1604
- function Mt(c) {
1605
- return ((c == null ? void 0 : c.type) === "image" || (c == null ? void 0 : c.format) === "svg") && typeof (c == null ? void 0 : c.width) == "number" && typeof (c == null ? void 0 : c.height) == "number";
1617
+ const R = (d, e, t) => Math.max(Math.min(d, t), e), Ee = (d, e) => d * e, ft = (d, e) => new $(d / 2, e / 2);
1618
+ function mt(d) {
1619
+ return ((d == null ? void 0 : d.type) === "image" || (d == null ? void 0 : d.format) === "svg") && typeof (d == null ? void 0 : d.width) == "number" && typeof (d == null ? void 0 : d.height) == "number";
1606
1620
  }
1607
- class mt {
1621
+ class Mt {
1608
1622
  /**
1609
1623
  * @param options
1610
1624
  * @param options.editor – экземпляр редактора
@@ -1628,26 +1642,26 @@ class mt {
1628
1642
  * @param options.adaptCanvasToContainer - Адаптировать канвас к контейнеру
1629
1643
  * @fires editor:resolution-width-changed
1630
1644
  */
1631
- setResolutionWidth(e, { preserveProportional: t, withoutSave: s, adaptCanvasToContainer: a } = {}) {
1632
- var M;
1645
+ setResolutionWidth(e, { preserveProportional: t, withoutSave: s, adaptCanvasToContainer: n } = {}) {
1646
+ var f;
1633
1647
  if (!e) return;
1634
1648
  const {
1635
- canvas: n,
1636
- montageArea: o,
1649
+ canvas: o,
1650
+ montageArea: a,
1637
1651
  options: { canvasBackstoreWidth: i }
1638
- } = this.editor, { width: r, height: d } = o, h = x(Number(e), U, k);
1639
- if (!i || i === "auto" || a ? this.adaptCanvasToContainer() : i ? this.setCanvasBackstoreWidth(Number(i)) : this.setCanvasBackstoreWidth(h), o.set({ width: h }), (M = n.clipPath) == null || M.set({ width: h }), t) {
1640
- const m = h / r, p = Se(d, m);
1641
- this.setResolutionHeight(p);
1652
+ } = this.editor, { width: r, height: c } = a, h = R(Number(e), Z, B);
1653
+ if (!i || i === "auto" || n ? this.adaptCanvasToContainer() : i ? this.setCanvasBackstoreWidth(Number(i)) : this.setCanvasBackstoreWidth(h), a.set({ width: h }), (f = o.clipPath) == null || f.set({ width: h }), t) {
1654
+ const M = h / r, b = Ee(c, M);
1655
+ this.setResolutionHeight(b);
1642
1656
  return;
1643
1657
  }
1644
- const { left: l, top: u } = this.getObjectDefaultCoords(o), g = n.getZoom();
1645
- n.setViewportTransform([g, 0, 0, g, l, u]), this.centerMontageArea(), s || this.editor.historyManager.saveState(), n.fire("editor:resolution-width-changed", {
1658
+ const { left: l, top: g } = this.getObjectDefaultCoords(a), u = o.getZoom();
1659
+ o.setViewportTransform([u, 0, 0, u, l, g]), this.centerMontageArea(), s || this.editor.historyManager.saveState(), o.fire("editor:resolution-width-changed", {
1646
1660
  width: h,
1647
1661
  preserveProportional: t,
1648
1662
  withoutSave: s,
1649
- adaptCanvasToContainer: a
1650
- });
1663
+ adaptCanvasToContainer: n
1664
+ }), this.editor.panConstraintManager.updateBounds();
1651
1665
  }
1652
1666
  /**
1653
1667
  * Устанавливаем внутреннюю высоту канваса (для экспорта)
@@ -1658,26 +1672,26 @@ class mt {
1658
1672
  * @param options.adaptCanvasToContainer - Адаптировать канвас к контейнеру
1659
1673
  * @fires editor:resolution-height-changed
1660
1674
  */
1661
- setResolutionHeight(e, { preserveProportional: t, withoutSave: s, adaptCanvasToContainer: a } = {}) {
1662
- var M;
1675
+ setResolutionHeight(e, { preserveProportional: t, withoutSave: s, adaptCanvasToContainer: n } = {}) {
1676
+ var f;
1663
1677
  if (!e) return;
1664
1678
  const {
1665
- canvas: n,
1666
- montageArea: o,
1679
+ canvas: o,
1680
+ montageArea: a,
1667
1681
  options: { canvasBackstoreHeight: i }
1668
- } = this.editor, { width: r, height: d } = o, h = x(Number(e), z, _);
1669
- if (!i || i === "auto" || a ? this.adaptCanvasToContainer() : i ? this.setCanvasBackstoreHeight(Number(i)) : this.setCanvasBackstoreHeight(h), o.set({ height: h }), (M = n.clipPath) == null || M.set({ height: h }), t) {
1670
- const m = h / d, p = Se(r, m);
1671
- this.setResolutionWidth(p);
1682
+ } = this.editor, { width: r, height: c } = a, h = R(Number(e), H, x);
1683
+ if (!i || i === "auto" || n ? this.adaptCanvasToContainer() : i ? this.setCanvasBackstoreHeight(Number(i)) : this.setCanvasBackstoreHeight(h), a.set({ height: h }), (f = o.clipPath) == null || f.set({ height: h }), t) {
1684
+ const M = h / c, b = Ee(r, M);
1685
+ this.setResolutionWidth(b);
1672
1686
  return;
1673
1687
  }
1674
- const { left: l, top: u } = this.getObjectDefaultCoords(o), g = n.getZoom();
1675
- n.setViewportTransform([g, 0, 0, g, l, u]), this.centerMontageArea(), s || this.editor.historyManager.saveState(), n.fire("editor:resolution-height-changed", {
1688
+ const { left: l, top: g } = this.getObjectDefaultCoords(a), u = o.getZoom();
1689
+ o.setViewportTransform([u, 0, 0, u, l, g]), this.centerMontageArea(), s || this.editor.historyManager.saveState(), o.fire("editor:resolution-height-changed", {
1676
1690
  height: h,
1677
1691
  preserveProportional: t,
1678
1692
  withoutSave: s,
1679
- adaptCanvasToContainer: a
1680
- });
1693
+ adaptCanvasToContainer: n
1694
+ }), this.editor.panConstraintManager.updateBounds();
1681
1695
  }
1682
1696
  /**
1683
1697
  * Центрирует монтажную область и ClipPath точно по центру канваса
@@ -1685,16 +1699,16 @@ class mt {
1685
1699
  */
1686
1700
  centerMontageArea() {
1687
1701
  var r;
1688
- const { canvas: e, montageArea: t } = this.editor, s = e.getWidth(), a = e.getHeight(), n = e.getZoom(), o = ft(s, a);
1702
+ const { canvas: e, montageArea: t } = this.editor, s = e.getWidth(), n = e.getHeight(), o = e.getZoom(), a = ft(s, n);
1689
1703
  t.set({
1690
1704
  left: s / 2,
1691
- top: a / 2
1705
+ top: n / 2
1692
1706
  }), (r = e.clipPath) == null || r.set({
1693
1707
  left: s / 2,
1694
- top: a / 2
1708
+ top: n / 2
1695
1709
  }), e.renderAll();
1696
1710
  const i = e.viewportTransform;
1697
- i[4] = s / 2 - o.x * n, i[5] = a / 2 - o.y * n, e.setViewportTransform(i), e.renderAll();
1711
+ i[4] = s / 2 - a.x * o, i[5] = n / 2 - a.y * o, e.setViewportTransform(i), e.renderAll();
1698
1712
  }
1699
1713
  /**
1700
1714
  * Метод для получения координат объекта с учетом текущего зума
@@ -1710,7 +1724,7 @@ class mt {
1710
1724
  code: "NO_ACTIVE_OBJECT",
1711
1725
  message: "Не выбран объект для получения координат"
1712
1726
  }), { left: 0, top: 0 };
1713
- const { width: a, height: n } = s, o = t.getZoom(), i = (a - a * o) / 2, r = (n - n * o) / 2;
1727
+ const { width: n, height: o } = s, a = t.getZoom(), i = (n - n * a) / 2, r = (o - o * a) / 2;
1714
1728
  return { left: i, top: r };
1715
1729
  }
1716
1730
  /**
@@ -1718,7 +1732,7 @@ class mt {
1718
1732
  */
1719
1733
  setCanvasBackstoreWidth(e) {
1720
1734
  if (!e || typeof e != "number") return;
1721
- const t = x(e, U, k);
1735
+ const t = R(e, Z, B);
1722
1736
  this.editor.canvas.setDimensions({ width: t }, { backstoreOnly: !0 });
1723
1737
  }
1724
1738
  /**
@@ -1727,7 +1741,7 @@ class mt {
1727
1741
  */
1728
1742
  setCanvasBackstoreHeight(e) {
1729
1743
  if (!e || typeof e != "number") return;
1730
- const t = x(e, z, _);
1744
+ const t = R(e, H, x);
1731
1745
  this.editor.canvas.setDimensions({ height: t }, { backstoreOnly: !0 });
1732
1746
  }
1733
1747
  /**
@@ -1736,8 +1750,8 @@ class mt {
1736
1750
  * с учётом минимальных и максимальных значений.
1737
1751
  */
1738
1752
  adaptCanvasToContainer() {
1739
- const { canvas: e } = this.editor, t = this.getEditorContainer(), s = t.clientWidth, a = t.clientHeight, n = x(s, U, k), o = x(a, z, _);
1740
- e.setDimensions({ width: n, height: o }, { backstoreOnly: !0 });
1753
+ const { canvas: e } = this.editor, t = this.getEditorContainer(), s = t.clientWidth, n = t.clientHeight, o = R(s, Z, B), a = R(n, H, x);
1754
+ e.setDimensions({ width: o, height: a }, { backstoreOnly: !0 });
1741
1755
  }
1742
1756
  /**
1743
1757
  * Обновляет размеры канваса без изменения позиций объектов.
@@ -1750,15 +1764,15 @@ class mt {
1750
1764
  montageArea: t,
1751
1765
  montageArea: {
1752
1766
  width: s,
1753
- height: a
1767
+ height: n
1754
1768
  }
1755
- } = this.editor, n = t.left, o = t.top;
1756
- this.setResolutionWidth(s, { adaptCanvasToContainer: !0, withoutSave: !0 }), this.setResolutionHeight(a, { adaptCanvasToContainer: !0, withoutSave: !0 }), this.centerMontageArea();
1757
- const i = t.left - n, r = t.top - o;
1769
+ } = this.editor, o = t.left, a = t.top;
1770
+ this.setResolutionWidth(s, { adaptCanvasToContainer: !0, withoutSave: !0 }), this.setResolutionHeight(n, { adaptCanvasToContainer: !0, withoutSave: !0 }), this.centerMontageArea();
1771
+ const i = t.left - o, r = t.top - a;
1758
1772
  if (i !== 0 || r !== 0) {
1759
- const d = e.getActiveObject(), h = [];
1760
- if ((d == null ? void 0 : d.type) === "activeselection") {
1761
- const l = d;
1773
+ const c = e.getActiveObject(), h = [];
1774
+ if ((c == null ? void 0 : c.type) === "activeselection") {
1775
+ const l = c;
1762
1776
  h.push(...l.getObjects()), e.discardActiveObject();
1763
1777
  }
1764
1778
  if (e.getObjects().forEach((l) => {
@@ -1778,8 +1792,8 @@ class mt {
1778
1792
  }
1779
1793
  e.renderAll(), e.fire("editor:canvas-updated", {
1780
1794
  width: s,
1781
- height: a
1782
- });
1795
+ height: n
1796
+ }), this.editor.panConstraintManager.updateBounds();
1783
1797
  }
1784
1798
  /**
1785
1799
  * Заготовка.
@@ -1888,32 +1902,32 @@ class mt {
1888
1902
  */
1889
1903
  setDisplayDimension({ element: e = "canvas", dimension: t, value: s } = {}) {
1890
1904
  if (!s) return;
1891
- const { canvas: a } = this.editor, n = [];
1905
+ const { canvas: n } = this.editor, o = [];
1892
1906
  switch (e) {
1893
1907
  case "canvas":
1894
- n.push(a.lowerCanvasEl, a.upperCanvasEl);
1908
+ o.push(n.lowerCanvasEl, n.upperCanvasEl);
1895
1909
  break;
1896
1910
  case "wrapper":
1897
- n.push(a.wrapperEl);
1911
+ o.push(n.wrapperEl);
1898
1912
  break;
1899
1913
  case "container":
1900
- n.push(this.getEditorContainer());
1914
+ o.push(this.getEditorContainer());
1901
1915
  break;
1902
1916
  default:
1903
- n.push(a.lowerCanvasEl, a.upperCanvasEl);
1917
+ o.push(n.lowerCanvasEl, n.upperCanvasEl);
1904
1918
  }
1905
- const o = t === "width" ? "width" : "height";
1919
+ const a = t === "width" ? "width" : "height";
1906
1920
  if (typeof s == "string") {
1907
- n.forEach((r) => {
1908
- r.style[o] = s;
1921
+ o.forEach((r) => {
1922
+ r.style[a] = s;
1909
1923
  });
1910
1924
  return;
1911
1925
  }
1912
1926
  if (isNaN(s)) return;
1913
1927
  const i = `${s}px`;
1914
- n.forEach((r) => {
1915
- r.style[o] = i;
1916
- }), a.fire(`editor:display-${e}-${o}-changed`, {
1928
+ o.forEach((r) => {
1929
+ r.style[a] = i;
1930
+ }), n.fire(`editor:display-${e}-${a}-changed`, {
1917
1931
  element: e,
1918
1932
  value: s
1919
1933
  });
@@ -1928,28 +1942,28 @@ class mt {
1928
1942
  */
1929
1943
  scaleMontageAreaToImage({ object: e, preserveAspectRatio: t, withoutSave: s } = {}) {
1930
1944
  const {
1931
- canvas: a,
1932
- montageArea: n,
1933
- transformManager: o,
1945
+ canvas: n,
1946
+ montageArea: o,
1947
+ transformManager: a,
1934
1948
  options: {
1935
1949
  montageAreaWidth: i,
1936
1950
  montageAreaHeight: r
1937
1951
  }
1938
- } = this.editor, d = e || a.getActiveObject();
1939
- if (!Mt(d)) return;
1940
- const { width: h, height: l } = d;
1941
- let u = Math.min(h, k), g = Math.min(l, _);
1952
+ } = this.editor, c = e || n.getActiveObject();
1953
+ if (!mt(c)) return;
1954
+ const { width: h, height: l } = c;
1955
+ let g = Math.min(h, B), u = Math.min(l, x);
1942
1956
  if (t) {
1943
1957
  const {
1944
- width: M,
1945
- height: m
1946
- } = n, p = h / M, f = l / m, b = Math.max(p, f);
1947
- u = M * b, g = m * b;
1958
+ width: f,
1959
+ height: M
1960
+ } = o, b = h / f, m = l / M, p = Math.max(b, m);
1961
+ g = f * p, u = M * p;
1948
1962
  }
1949
- this.setResolutionWidth(u, { withoutSave: !0 }), this.setResolutionHeight(g, { withoutSave: !0 }), this.editor.backgroundManager.backgroundObject && this.editor.backgroundManager.refresh(), (h > i || l > r) && o.calculateAndApplyDefaultZoom(), o.resetObject({ object: d, withoutSave: !0 }), a.centerObject(d), a.renderAll(), s || this.editor.historyManager.saveState(), a.fire("editor:montage-area-scaled-to-image", {
1950
- object: d,
1951
- width: u,
1952
- height: g,
1963
+ this.setResolutionWidth(g, { withoutSave: !0 }), this.setResolutionHeight(u, { withoutSave: !0 }), this.editor.backgroundManager.backgroundObject && this.editor.backgroundManager.refresh(), (h > i || l > r) && this.editor.zoomManager.calculateAndApplyDefaultZoom(), a.resetObject({ object: c, withoutSave: !0 }), n.centerObject(c), n.renderAll(), s || this.editor.historyManager.saveState(), n.fire("editor:montage-area-scaled-to-image", {
1964
+ object: c,
1965
+ width: g,
1966
+ height: u,
1953
1967
  preserveAspectRatio: t,
1954
1968
  withoutSave: s
1955
1969
  });
@@ -1972,13 +1986,13 @@ class mt {
1972
1986
  const {
1973
1987
  canvas: t,
1974
1988
  transformManager: s,
1975
- historyManager: a,
1989
+ historyManager: n,
1976
1990
  options: {
1977
- montageAreaWidth: n,
1978
- montageAreaHeight: o
1991
+ montageAreaWidth: o,
1992
+ montageAreaHeight: a
1979
1993
  }
1980
1994
  } = this.editor;
1981
- s.resetZoom(), this.setResolutionWidth(n, { withoutSave: !0 }), this.setResolutionHeight(o, { withoutSave: !0 }), t.renderAll(), s.resetObjects(), e || a.saveState(), t.fire("editor:default-scale-set");
1995
+ this.editor.zoomManager.resetZoom(), this.setResolutionWidth(o, { withoutSave: !0 }), this.setResolutionHeight(a, { withoutSave: !0 }), t.renderAll(), s.resetObjects(), e || n.saveState(), t.fire("editor:default-scale-set");
1982
1996
  }
1983
1997
  /**
1984
1998
  * Получение всех объектов внутри монтажной области редактора
@@ -1989,72 +2003,16 @@ class mt {
1989
2003
  canvas: e,
1990
2004
  montageArea: t,
1991
2005
  interactionBlocker: { overlayMask: s },
1992
- backgroundManager: { backgroundObject: a }
2006
+ backgroundManager: { backgroundObject: n }
1993
2007
  } = this.editor;
1994
2008
  return e.getObjects().filter(
1995
- (o) => o.id !== t.id && o.id !== (s == null ? void 0 : s.id) && o.id !== (a == null ? void 0 : a.id)
2009
+ (a) => a.id !== t.id && a.id !== (s == null ? void 0 : s.id) && a.id !== (n == null ? void 0 : n.id)
1996
2010
  );
1997
2011
  }
1998
2012
  }
1999
- class bt {
2013
+ class pt {
2000
2014
  constructor({ editor: e }) {
2001
- this.editor = e, this.options = e.options, this.minZoom = this.options.minZoom || lt, this.maxZoom = this.options.maxZoom || ht, this.defaultZoom = this.options.defaultScale;
2002
- }
2003
- /**
2004
- * Метод рассчитывает и применяет зум по умолчанию для монтажной области редактора.
2005
- * Зум рассчитывается исходя из размеров контейнера редактора и текущих размеров монтажной области.
2006
- * Расчёт происходит таким образом, чтобы монтажная область визуально целиком помещалась в контейнер редактора.
2007
- * Если scale не передан, то используется значение из options.defaultScale.
2008
- * @param scale - Желаемый масштаб относительно размеров контейнера редактора.
2009
- */
2010
- calculateAndApplyDefaultZoom(e = this.options.defaultScale) {
2011
- const { canvas: t } = this.editor, s = t.editorContainer, a = s.clientWidth, n = s.clientHeight, { width: o, height: i } = this.editor.montageArea, r = a / o * e, d = n / i * e;
2012
- this.defaultZoom = Math.min(r, d), this.setZoom();
2013
- }
2014
- /**
2015
- * Увеличение/уменьшение масштаба
2016
- * @param scale - Шаг зума
2017
- * @param options - Координаты зума (по умолчанию центр канваса)
2018
- * @param options.pointX - Координата X точки зума
2019
- * @param options.pointY - Координата Y точки зума
2020
- * @fires editor:zoom-changed
2021
- * Если передавать координаты курсора, то нужно быть аккуратнее, так как юзер может выйти за пределы рабочей области
2022
- */
2023
- zoom(e = ut, t = {}) {
2024
- var u, g;
2025
- if (!e) return;
2026
- const { minZoom: s, maxZoom: a } = this, { canvas: n } = this.editor, o = n.getZoom(), i = n.getCenterPoint(), r = (u = t.pointX) != null ? u : i.x, d = (g = t.pointY) != null ? g : i.y, h = new X(r, d);
2027
- let l = Number((o + Number(e)).toFixed(2));
2028
- l > a && (l = a), l < s && (l = s), n.zoomToPoint(h, l), n.fire("editor:zoom-changed", {
2029
- currentZoom: n.getZoom(),
2030
- zoom: l,
2031
- point: h
2032
- });
2033
- }
2034
- /**
2035
- * Установка зума
2036
- * @param zoom - Зум
2037
- * @fires editor:zoom-changed
2038
- */
2039
- setZoom(e = this.defaultZoom) {
2040
- const { minZoom: t, maxZoom: s } = this, { canvas: a } = this.editor, n = new X(a.getCenterPoint());
2041
- let o = e;
2042
- e > s && (o = s), e < t && (o = t), a.zoomToPoint(n, o), a.fire("editor:zoom-changed", {
2043
- currentZoom: a.getZoom(),
2044
- zoom: o,
2045
- point: n
2046
- });
2047
- }
2048
- /**
2049
- * Сброс зума
2050
- * @fires editor:zoom-changed
2051
- */
2052
- resetZoom() {
2053
- const { canvas: e } = this.editor, t = new X(e.getCenterPoint());
2054
- e.zoomToPoint(t, this.defaultZoom), this.editor.canvas.fire("editor:zoom-changed", {
2055
- currentZoom: e.getZoom(),
2056
- point: t
2057
- });
2015
+ this.editor = e, this.options = e.options;
2058
2016
  }
2059
2017
  /**
2060
2018
  * Поворот объекта на заданный угол
@@ -2063,14 +2021,14 @@ class bt {
2063
2021
  * @param options.withoutSave - Не сохранять состояние
2064
2022
  * @fires editor:object-rotated
2065
2023
  */
2066
- rotate(e = gt, { withoutSave: t } = {}) {
2067
- const { canvas: s, historyManager: a } = this.editor, n = s.getActiveObject();
2068
- if (!n) return;
2069
- const o = n.angle + e;
2070
- n.rotate(o), n.setCoords(), s.renderAll(), t || a.saveState(), s.fire("editor:object-rotated", {
2071
- object: n,
2024
+ rotate(e = ut, { withoutSave: t } = {}) {
2025
+ const { canvas: s, historyManager: n } = this.editor, o = s.getActiveObject();
2026
+ if (!o) return;
2027
+ const a = o.angle + e;
2028
+ o.rotate(a), o.setCoords(), s.renderAll(), t || n.saveState(), s.fire("editor:object-rotated", {
2029
+ object: o,
2072
2030
  withoutSave: t,
2073
- angle: o
2031
+ angle: a
2074
2032
  });
2075
2033
  }
2076
2034
  /**
@@ -2080,9 +2038,9 @@ class bt {
2080
2038
  * @fires editor:object-flipped-x
2081
2039
  */
2082
2040
  flipX({ withoutSave: e } = {}) {
2083
- const { canvas: t, historyManager: s } = this.editor, a = t.getActiveObject();
2084
- a && (a.flipX = !a.flipX, t.renderAll(), e || s.saveState(), t.fire("editor:object-flipped-x", {
2085
- object: a,
2041
+ const { canvas: t, historyManager: s } = this.editor, n = t.getActiveObject();
2042
+ n && (n.flipX = !n.flipX, t.renderAll(), e || s.saveState(), t.fire("editor:object-flipped-x", {
2043
+ object: n,
2086
2044
  withoutSave: e
2087
2045
  }));
2088
2046
  }
@@ -2093,9 +2051,9 @@ class bt {
2093
2051
  * @fires editor:object-flipped-y
2094
2052
  */
2095
2053
  flipY({ withoutSave: e } = {}) {
2096
- const { canvas: t, historyManager: s } = this.editor, a = t.getActiveObject();
2097
- a && (a.flipY = !a.flipY, t.renderAll(), e || s.saveState(), t.fire("editor:object-flipped-y", {
2098
- object: a,
2054
+ const { canvas: t, historyManager: s } = this.editor, n = t.getActiveObject();
2055
+ n && (n.flipY = !n.flipY, t.renderAll(), e || s.saveState(), t.fire("editor:object-flipped-y", {
2056
+ object: n,
2099
2057
  withoutSave: e
2100
2058
  }));
2101
2059
  }
@@ -2112,11 +2070,11 @@ class bt {
2112
2070
  opacity: t = 1,
2113
2071
  withoutSave: s
2114
2072
  } = {}) {
2115
- const { canvas: a, historyManager: n } = this.editor, o = e || a.getActiveObject();
2116
- o && (o instanceof v ? o.getObjects().forEach((i) => {
2073
+ const { canvas: n, historyManager: o } = this.editor, a = e || n.getActiveObject();
2074
+ a && (a instanceof v ? a.getObjects().forEach((i) => {
2117
2075
  i.set("opacity", t);
2118
- }) : o.set("opacity", t), a.renderAll(), s || n.saveState(), a.fire("editor:object-opacity-changed", {
2119
- object: o,
2076
+ }) : a.set("opacity", t), n.renderAll(), s || o.saveState(), n.fire("editor:object-opacity-changed", {
2077
+ object: a,
2120
2078
  opacity: t,
2121
2079
  withoutSave: s
2122
2080
  }));
@@ -2136,24 +2094,24 @@ class bt {
2136
2094
  object: e,
2137
2095
  type: t = this.options.scaleType,
2138
2096
  withoutSave: s,
2139
- fitAsOneObject: a
2097
+ fitAsOneObject: n
2140
2098
  } = {}) {
2141
- const { canvas: n, historyManager: o } = this.editor, i = e || n.getActiveObject();
2099
+ const { canvas: o, historyManager: a } = this.editor, i = e || o.getActiveObject();
2142
2100
  if (i) {
2143
- if (i instanceof v && !a) {
2101
+ if (i instanceof v && !n) {
2144
2102
  const r = i.getObjects();
2145
- n.discardActiveObject(), r.forEach((h) => {
2103
+ o.discardActiveObject(), r.forEach((h) => {
2146
2104
  this._fitSingleObject(h, t);
2147
2105
  });
2148
- const d = new v(r, { canvas: n });
2149
- n.setActiveObject(d);
2106
+ const c = new v(r, { canvas: o });
2107
+ o.setActiveObject(c);
2150
2108
  } else
2151
2109
  this._fitSingleObject(i, t);
2152
- n.renderAll(), s || o.saveState(), n.fire("editor:object-fitted", {
2110
+ o.renderAll(), s || a.saveState(), o.fire("editor:object-fitted", {
2153
2111
  object: i,
2154
2112
  type: t,
2155
2113
  withoutSave: s,
2156
- fitAsOneObject: a
2114
+ fitAsOneObject: n
2157
2115
  });
2158
2116
  }
2159
2117
  }
@@ -2164,11 +2122,11 @@ class bt {
2164
2122
  * @private
2165
2123
  */
2166
2124
  _fitSingleObject(e, t) {
2167
- const { canvas: s, montageArea: a } = this.editor, { width: n, height: o, scaleX: i = 1, scaleY: r = 1, angle: d = 0 } = e, h = n * Math.abs(i), l = o * Math.abs(r), u = d * Math.PI / 180, g = Math.abs(Math.cos(u)), M = Math.abs(Math.sin(u)), m = h * g + l * M, p = h * M + l * g, f = a.width, b = a.height;
2168
- let S;
2169
- t === "contain" ? S = Math.min(f / m, b / p) : S = Math.max(f / m, b / p), e.set({
2170
- scaleX: i * S,
2171
- scaleY: r * S
2125
+ const { canvas: s, montageArea: n } = this.editor, { width: o, height: a, scaleX: i = 1, scaleY: r = 1, angle: c = 0 } = e, h = o * Math.abs(i), l = a * Math.abs(r), g = c * Math.PI / 180, u = Math.abs(Math.cos(g)), f = Math.abs(Math.sin(g)), M = h * u + l * f, b = h * f + l * u, m = n.width, p = n.height;
2126
+ let D;
2127
+ t === "contain" ? D = Math.min(m / M, p / b) : D = Math.max(m / M, p / b), e.set({
2128
+ scaleX: i * D,
2129
+ scaleY: r * D
2172
2130
  }), s.centerObject(e);
2173
2131
  }
2174
2132
  /**
@@ -2189,35 +2147,239 @@ class bt {
2189
2147
  */
2190
2148
  resetObject({ object: e, alwaysFitObject: t = !1, withoutSave: s = !1 } = {}) {
2191
2149
  const {
2192
- canvas: a,
2193
- montageArea: n,
2194
- imageManager: o,
2150
+ canvas: n,
2151
+ montageArea: o,
2152
+ imageManager: a,
2195
2153
  historyManager: i,
2196
2154
  options: { scaleType: r }
2197
- } = this.editor, d = e || a.getActiveObject();
2198
- if (!d || d.locked) return;
2199
- if (i.suspendHistory(), d.type === "image" || d.format === "svg" || d.set({
2155
+ } = this.editor, c = e || n.getActiveObject();
2156
+ if (!c || c.locked) return;
2157
+ if (i.suspendHistory(), c.type === "image" || c.format === "svg" || c.set({
2200
2158
  scaleX: 1,
2201
2159
  scaleY: 1,
2202
2160
  flipX: !1,
2203
2161
  flipY: !1,
2204
2162
  angle: 0
2205
2163
  }), t)
2206
- this.fitObject({ object: d, withoutSave: !0, fitAsOneObject: !0 });
2164
+ this.fitObject({ object: c, withoutSave: !0, fitAsOneObject: !0 });
2207
2165
  else {
2208
- const { width: l, height: u } = n, { width: g, height: M } = d, m = o.calculateScaleFactor({
2209
- imageObject: d,
2166
+ const { width: l, height: g } = o, { width: u, height: f } = c, M = a.calculateScaleFactor({
2167
+ imageObject: c,
2210
2168
  scaleType: r
2211
2169
  });
2212
- r === "contain" && m < 1 || r === "cover" && (g > l || M > u) ? this.fitObject({ object: d, withoutSave: !0, fitAsOneObject: !0 }) : d.set({ scaleX: 1, scaleY: 1 });
2170
+ r === "contain" && M < 1 || r === "cover" && (u > l || f > g) ? this.fitObject({ object: c, withoutSave: !0, fitAsOneObject: !0 }) : c.set({ scaleX: 1, scaleY: 1 });
2213
2171
  }
2214
- d.set({ flipX: !1, flipY: !1, angle: 0 }), a.centerObject(d), a.renderAll(), i.resumeHistory(), s || i.saveState(), a.fire("editor:object-reset", {
2215
- object: d,
2172
+ c.set({ flipX: !1, flipY: !1, angle: 0 }), n.centerObject(c), n.renderAll(), i.resumeHistory(), s || i.saveState(), n.fire("editor:object-reset", {
2173
+ object: c,
2216
2174
  withoutSave: s,
2217
2175
  alwaysFitObject: t
2218
2176
  });
2219
2177
  }
2220
2178
  }
2179
+ class bt {
2180
+ constructor({ editor: e }) {
2181
+ this.editor = e, this.options = e.options, this.minZoom = this.options.minZoom || ht, this.maxZoom = this.options.maxZoom || gt, this.defaultZoom = this.options.defaultScale;
2182
+ }
2183
+ /**
2184
+ * Вспомогательный метод для вычисления размеров масштабированной монтажной области
2185
+ * @param zoom - Масштаб для расчета
2186
+ * @returns Размеры масштабированной монтажной области
2187
+ * @private
2188
+ */
2189
+ _getScaledMontageDimensions(e) {
2190
+ const { montageArea: t } = this.editor;
2191
+ return {
2192
+ width: t.width * e,
2193
+ height: t.height * e
2194
+ };
2195
+ }
2196
+ /**
2197
+ * Ограничивает координаты курсора видимыми границами монтажной области
2198
+ * @param event - Событие колеса мыши
2199
+ * @returns Ограниченные координаты в canvas-пространстве
2200
+ * @private
2201
+ */
2202
+ _getClampedPointerCoordinates(e) {
2203
+ const { canvas: t, montageArea: s } = this.editor, n = t.getPointer(e, !0), o = t.viewportTransform, a = t.getZoom(), i = s.left - s.width / 2, r = s.left + s.width / 2, c = s.top - s.height / 2, h = s.top + s.height / 2, l = i * a + o[4], g = r * a + o[4], u = c * a + o[5], f = h * a + o[5], M = Math.max(l, Math.min(g, n.x)), b = Math.max(u, Math.min(f, n.y));
2204
+ return {
2205
+ x: M,
2206
+ y: b
2207
+ };
2208
+ }
2209
+ /**
2210
+ * Вычисляет зум при котором монтажная область точно помещается в viewport
2211
+ * @returns Минимальный зум для полного размещения монтажной области
2212
+ * @private
2213
+ */
2214
+ _calculateFitZoom() {
2215
+ const { canvas: e, montageArea: t } = this.editor, s = e.getWidth(), n = e.getHeight(), o = s / t.width, a = n / t.height;
2216
+ return Math.max(o, a);
2217
+ }
2218
+ /**
2219
+ * Вычисляет целевую позицию viewport для центрирования монтажной области
2220
+ * @param zoom - Текущий зум
2221
+ * @returns Целевые координаты viewport transform
2222
+ * @private
2223
+ */
2224
+ _calculateTargetViewportPosition(e) {
2225
+ const { canvas: t, montageArea: s } = this.editor, n = t.getWidth(), o = t.getHeight(), a = n / 2, i = o / 2, r = s.left, c = s.top;
2226
+ return {
2227
+ x: a - r * e,
2228
+ y: i - c * e
2229
+ };
2230
+ }
2231
+ /**
2232
+ * Проверяет наличие пустого пространства вокруг монтажной области
2233
+ * @param zoom - Текущий зум
2234
+ * @returns Максимальное соотношение пустого пространства к размеру viewport
2235
+ * @private
2236
+ */
2237
+ _calculateEmptySpaceRatio(e) {
2238
+ const { canvas: t, montageArea: s } = this.editor, n = t.viewportTransform, o = t.getWidth(), a = t.getHeight(), i = s.left - s.width / 2, r = s.left + s.width / 2, c = s.top - s.height / 2, h = s.top + s.height / 2, l = -n[4] / e, g = (-n[4] + o) / e, u = -n[5] / e, f = (-n[5] + a) / e, M = l < i, b = g > r, m = u < c, p = f > h;
2239
+ if (!(M || b || m || p)) return 0;
2240
+ const w = Math.max(0, i - l), T = Math.max(0, g - r), A = Math.max(0, c - u), S = Math.max(0, f - h), L = Math.max(w, T), O = Math.max(A, S), j = L / o, E = O / a;
2241
+ return Math.max(j, E);
2242
+ }
2243
+ /**
2244
+ * Вычисляет плавный шаг перемещения viewport к центру с ускорением
2245
+ * @param targetVpt - Целевая позиция viewport
2246
+ * @param zoom - Текущий зум
2247
+ * @param fitZoom - Зум при котором монтажная область помещается в viewport
2248
+ * @param zoomStep - Шаг изменения зума
2249
+ * @param maxEmptyRatio - Максимальная доля пустого пространства
2250
+ * @returns Вычисленный шаг перемещения viewport
2251
+ * @private
2252
+ */
2253
+ _calculateSmoothCenteringStep(e, t, s, n, o) {
2254
+ const { canvas: a, montageArea: i } = this.editor, r = a.viewportTransform, c = a.getWidth(), h = a.getHeight(), l = e.x - r[4], g = e.y - r[5], u = Math.abs(n), f = t - s;
2255
+ if (Math.abs(f) / u <= 0.1)
2256
+ return { x: l, y: g };
2257
+ const b = c / 2, m = h / 2, p = i.left, D = i.top, w = b - p * s, T = m - D * s, A = (w - r[4]) / (t - s), S = (T - r[5]) / (t - s), L = A * u, O = S * u, j = L * o, E = O * o, N = Math.abs(j) > Math.abs(l) ? l : j, te = Math.abs(E) > Math.abs(g) ? g : E;
2258
+ return { x: N, y: te };
2259
+ }
2260
+ /**
2261
+ * Применяет плавное центрирование viewport при приближении к defaultZoom.
2262
+ * При zoom <= defaultZoom монтажная область полностью центрируется.
2263
+ * При zoom > defaultZoom применяется плавная интерполяция в пределах переходного диапазона.
2264
+ * @param zoom - Текущий зум
2265
+ * @param isZoomingOut - Флаг, указывающий что происходит zoom-out (уменьшение масштаба)
2266
+ * @param zoomStep - Шаг зума (адаптивно рассчитанный)
2267
+ * @returns true если центрирование было применено
2268
+ * @private
2269
+ */
2270
+ _applyViewportCentering(e, t = !1, s = Se) {
2271
+ const { canvas: n } = this.editor, o = this._getScaledMontageDimensions(e), a = n.getWidth(), i = n.getHeight(), r = o.width > a || o.height > i, c = this._calculateFitZoom(), h = e - c;
2272
+ if (!(!r || h) && !t)
2273
+ return !1;
2274
+ const g = n.viewportTransform, u = this._calculateTargetViewportPosition(e);
2275
+ if (!r)
2276
+ return g[4] = u.x, g[5] = u.y, n.setViewportTransform(g), !0;
2277
+ if (t && !r) {
2278
+ const f = this._calculateEmptySpaceRatio(e);
2279
+ if (f > 0) {
2280
+ const M = this._calculateSmoothCenteringStep(u, e, c, s, f);
2281
+ return g[4] += M.x, g[5] += M.y, n.setViewportTransform(g), !0;
2282
+ }
2283
+ }
2284
+ return !1;
2285
+ }
2286
+ /**
2287
+ * Метод рассчитывает и применяет зум по умолчанию для монтажной области редактора.
2288
+ * Зум рассчитывается исходя из размеров контейнера редактора и текущих размеров монтажной области.
2289
+ * Расчёт происходит таким образом, чтобы монтажная область визуально целиком помещалась в контейнер редактора.
2290
+ * Если scale не передан, то используется значение из options.defaultScale.
2291
+ * @param scale - Желаемый масштаб относительно размеров контейнера редактора.
2292
+ */
2293
+ calculateAndApplyDefaultZoom(e = this.options.defaultScale) {
2294
+ const { canvas: t } = this.editor, s = t.editorContainer, n = s.clientWidth || t.getWidth(), o = s.clientHeight || t.getHeight(), { width: a, height: i } = this.editor.montageArea, r = n / a * e, c = o / i * e;
2295
+ this.defaultZoom = Math.min(r, c), this.setZoom(), this.editor.panConstraintManager.updateBounds();
2296
+ }
2297
+ /**
2298
+ * Обработчик зума колесом мыши с автоматическим определением точки зума.
2299
+ * Логика выбора точки зума:
2300
+ * - При zoom-out (уменьшении): зум к текущему центру монтажной области
2301
+ * - При zoom-in (увеличении): зум к позиции курсора (ограниченной границами монтажной области)
2302
+ * - Если zoom < defaultZoom или монтажная область помещается во viewport - зум к центру монтажной области
2303
+ * @param scale - Шаг зума
2304
+ * @param event - Событие колеса мыши
2305
+ * @fires editor:zoom-changed
2306
+ */
2307
+ handleMouseWheelZoom(e, t) {
2308
+ const { canvas: s, montageArea: n } = this.editor, o = s.getZoom(), a = e < 0, i = this._getScaledMontageDimensions(o), r = s.getWidth(), c = s.getHeight(), h = i.width > r || i.height > c;
2309
+ if (a) {
2310
+ if (!h)
2311
+ this.zoom(e, {
2312
+ pointX: n.left,
2313
+ pointY: n.top
2314
+ });
2315
+ else {
2316
+ const g = this._getClampedPointerCoordinates(t);
2317
+ this.zoom(e, {
2318
+ pointX: g.x,
2319
+ pointY: g.y
2320
+ });
2321
+ }
2322
+ return;
2323
+ }
2324
+ if (e < 0 || !h) {
2325
+ this.zoom(e, {
2326
+ pointX: n.left,
2327
+ pointY: n.top
2328
+ });
2329
+ return;
2330
+ }
2331
+ const l = this._getClampedPointerCoordinates(t);
2332
+ this.zoom(e, {
2333
+ pointX: l.x,
2334
+ pointY: l.y
2335
+ });
2336
+ }
2337
+ /**
2338
+ * Увеличение/уменьшение масштаба
2339
+ * @param scale - Шаг зума
2340
+ * @param options - Координаты зума (по умолчанию центр канваса)
2341
+ * @param options.pointX - Координата X точки зума
2342
+ * @param options.pointY - Координата Y точки зума
2343
+ * @fires editor:zoom-changed
2344
+ */
2345
+ zoom(e = Se, t = {}) {
2346
+ var u, f;
2347
+ if (!e) return;
2348
+ const { minZoom: s, maxZoom: n } = this, { canvas: o } = this.editor, a = e < 0, i = o.getZoom(), r = o.getCenterPoint(), c = (u = t.pointX) != null ? u : r.x, h = (f = t.pointY) != null ? f : r.y, l = new $(c, h);
2349
+ this.editor.montageArea.setCoords(), this.editor.canvas.requestRenderAll();
2350
+ let g = Number((i + Number(e)).toFixed(3));
2351
+ g > n && (g = n), g < s && (g = s), o.zoomToPoint(l, g), this.editor.panConstraintManager.updateBounds(), this._applyViewportCentering(g, a, e), o.fire("editor:zoom-changed", {
2352
+ currentZoom: o.getZoom(),
2353
+ zoom: g,
2354
+ point: l
2355
+ });
2356
+ }
2357
+ /**
2358
+ * Установка зума
2359
+ * @param zoom - Зум
2360
+ * @fires editor:zoom-changed
2361
+ */
2362
+ setZoom(e = this.defaultZoom) {
2363
+ const { minZoom: t, maxZoom: s } = this, { canvas: n } = this.editor, o = new $(n.getCenterPoint());
2364
+ let a = e;
2365
+ e > s && (a = s), e < t && (a = t), n.zoomToPoint(o, a), n.fire("editor:zoom-changed", {
2366
+ currentZoom: n.getZoom(),
2367
+ zoom: a,
2368
+ point: o
2369
+ }), this.editor.panConstraintManager.updateBounds();
2370
+ }
2371
+ /**
2372
+ * Сброс зума
2373
+ * @fires editor:zoom-changed
2374
+ */
2375
+ resetZoom() {
2376
+ const { canvas: e } = this.editor, t = new $(e.getCenterPoint());
2377
+ e.zoomToPoint(t, this.defaultZoom), this.editor.canvas.fire("editor:zoom-changed", {
2378
+ currentZoom: e.getZoom(),
2379
+ point: t
2380
+ }), this.editor.panConstraintManager.updateBounds();
2381
+ }
2382
+ }
2221
2383
  class jt {
2222
2384
  constructor({ editor: e }) {
2223
2385
  this.editor = e, this.isBlocked = !1, this.overlayMask = null, this._createOverlay();
@@ -2248,8 +2410,8 @@ class jt {
2248
2410
  const { canvas: e, montageArea: t, historyManager: s } = this.editor;
2249
2411
  if (!t || !this.overlayMask) return;
2250
2412
  s.suspendHistory(), t.setCoords();
2251
- const { left: a, top: n, width: o, height: i } = t.getBoundingRect();
2252
- this.overlayMask.set({ left: a, top: n, width: o, height: i }), e.discardActiveObject(), this.editor.layerManager.bringToFront(this.overlayMask, { withoutSave: !0 }), s.resumeHistory();
2413
+ const { left: n, top: o, width: a, height: i } = t.getBoundingRect();
2414
+ this.overlayMask.set({ left: n, top: o, width: a, height: i }), e.discardActiveObject(), this.editor.layerManager.bringToFront(this.overlayMask, { withoutSave: !0 }), s.resumeHistory();
2253
2415
  }
2254
2416
  /**
2255
2417
  * Выключает редактор:
@@ -2260,8 +2422,8 @@ class jt {
2260
2422
  block() {
2261
2423
  if (this.isBlocked || !this.overlayMask) return;
2262
2424
  const { canvas: e, canvasManager: t, historyManager: s } = this.editor;
2263
- s.suspendHistory(), this.isBlocked = !0, e.discardActiveObject(), e.selection = !1, e.skipTargetFind = !0, t.getObjects().forEach((a) => {
2264
- a.evented = !1, a.selectable = !1;
2425
+ s.suspendHistory(), this.isBlocked = !0, e.discardActiveObject(), e.selection = !1, e.skipTargetFind = !0, t.getObjects().forEach((n) => {
2426
+ n.evented = !1, n.selectable = !1;
2265
2427
  }), e.upperCanvasEl.style.pointerEvents = "none", e.lowerCanvasEl.style.pointerEvents = "none", this.overlayMask.visible = !0, this.refresh(), e.fire("editor:disabled"), s.resumeHistory();
2266
2428
  }
2267
2429
  /**
@@ -2270,12 +2432,12 @@ class jt {
2270
2432
  unblock() {
2271
2433
  if (!this.isBlocked || !this.overlayMask) return;
2272
2434
  const { canvas: e, canvasManager: t, historyManager: s } = this.editor;
2273
- s.suspendHistory(), this.isBlocked = !1, e.selection = !0, e.skipTargetFind = !1, t.getObjects().forEach((a) => {
2274
- a.evented = !0, a.selectable = !0;
2435
+ s.suspendHistory(), this.isBlocked = !1, e.selection = !0, e.skipTargetFind = !1, t.getObjects().forEach((n) => {
2436
+ n.evented = !0, n.selectable = !0;
2275
2437
  }), e.upperCanvasEl.style.pointerEvents = "", e.lowerCanvasEl.style.pointerEvents = "", this.overlayMask.visible = !1, e.requestRenderAll(), e.fire("editor:enabled"), s.resumeHistory();
2276
2438
  }
2277
2439
  }
2278
- class R {
2440
+ class Y {
2279
2441
  constructor({ editor: e }) {
2280
2442
  this.editor = e, this.backgroundObject = null;
2281
2443
  }
@@ -2290,28 +2452,28 @@ class R {
2290
2452
  customData: t = {},
2291
2453
  withoutSave: s = !1
2292
2454
  }) {
2293
- var a;
2455
+ var n;
2294
2456
  try {
2295
- const { historyManager: n } = this.editor, { backgroundObject: o } = this;
2296
- if (n.suspendHistory(), o && o.backgroundType === "color") {
2297
- if (o.fill === e) {
2298
- n.resumeHistory();
2457
+ const { historyManager: o } = this.editor, { backgroundObject: a } = this;
2458
+ if (o.suspendHistory(), a && a.backgroundType === "color") {
2459
+ if (a.fill === e) {
2460
+ o.resumeHistory();
2299
2461
  return;
2300
2462
  }
2301
- o.set({
2463
+ a.set({
2302
2464
  fill: e,
2303
- backgroundId: `background-${A()}`
2465
+ backgroundId: `background-${C()}`
2304
2466
  }), this.editor.canvas.requestRenderAll();
2305
2467
  } else
2306
2468
  this._removeCurrentBackground(), this._createColorBackground(e);
2307
- (a = this.backgroundObject) == null || a.set({ customData: t }), this.editor.canvas.fire("editor:background:changed", { type: "color", color: e }), n.resumeHistory(), s || n.saveState();
2308
- } catch (n) {
2469
+ (n = this.backgroundObject) == null || n.set({ customData: t }), this.editor.canvas.fire("editor:background:changed", { type: "color", color: e }), o.resumeHistory(), s || o.saveState();
2470
+ } catch (o) {
2309
2471
  this.editor.errorManager.emitError({
2310
2472
  code: "BACKGROUND_CREATION_FAILED",
2311
2473
  origin: "BackgroundManager",
2312
2474
  method: "setColorBackground",
2313
2475
  message: "Не удалось установить цветовой фон",
2314
- data: { error: n }
2476
+ data: { error: o }
2315
2477
  });
2316
2478
  }
2317
2479
  }
@@ -2326,32 +2488,32 @@ class R {
2326
2488
  customData: t = {},
2327
2489
  withoutSave: s = !1
2328
2490
  }) {
2329
- var a;
2491
+ var n;
2330
2492
  try {
2331
- const { historyManager: n } = this.editor, { backgroundObject: o } = this;
2332
- if (n.suspendHistory(), o && o.backgroundType === "gradient") {
2333
- const i = R._createFabricGradient(e);
2334
- if (R._isGradientEqual(o.fill, i)) {
2335
- n.resumeHistory();
2493
+ const { historyManager: o } = this.editor, { backgroundObject: a } = this;
2494
+ if (o.suspendHistory(), a && a.backgroundType === "gradient") {
2495
+ const i = Y._createFabricGradient(e);
2496
+ if (Y._isGradientEqual(a.fill, i)) {
2497
+ o.resumeHistory();
2336
2498
  return;
2337
2499
  }
2338
- o.set({
2500
+ a.set({
2339
2501
  fill: i,
2340
- backgroundId: `background-${A()}`
2502
+ backgroundId: `background-${C()}`
2341
2503
  }), this.editor.canvas.requestRenderAll();
2342
2504
  } else
2343
2505
  this._removeCurrentBackground(), this._createGradientBackground(e);
2344
- (a = this.backgroundObject) == null || a.set({ customData: t }), this.editor.canvas.fire("editor:background:changed", {
2506
+ (n = this.backgroundObject) == null || n.set({ customData: t }), this.editor.canvas.fire("editor:background:changed", {
2345
2507
  type: "gradient",
2346
2508
  gradientParams: e
2347
- }), n.resumeHistory(), s || n.saveState();
2348
- } catch (n) {
2509
+ }), o.resumeHistory(), s || o.saveState();
2510
+ } catch (o) {
2349
2511
  this.editor.errorManager.emitError({
2350
2512
  code: "BACKGROUND_CREATION_FAILED",
2351
2513
  origin: "BackgroundManager",
2352
2514
  method: "setGradientBackground",
2353
2515
  message: "Не удалось установить градиентный фон",
2354
- data: { error: n }
2516
+ data: { error: o }
2355
2517
  });
2356
2518
  }
2357
2519
  }
@@ -2363,9 +2525,9 @@ class R {
2363
2525
  angle: e,
2364
2526
  startColor: t,
2365
2527
  endColor: s,
2366
- startPosition: a,
2367
- endPosition: n,
2368
- customData: o = {},
2528
+ startPosition: n,
2529
+ endPosition: o,
2530
+ customData: a = {},
2369
2531
  withoutSave: i = !1
2370
2532
  }) {
2371
2533
  this.setGradientBackground({
@@ -2374,10 +2536,10 @@ class R {
2374
2536
  angle: e,
2375
2537
  startColor: t,
2376
2538
  endColor: s,
2377
- startPosition: a,
2378
- endPosition: n
2539
+ startPosition: n,
2540
+ endPosition: o
2379
2541
  },
2380
- customData: o,
2542
+ customData: a,
2381
2543
  withoutSave: i
2382
2544
  });
2383
2545
  }
@@ -2389,12 +2551,12 @@ class R {
2389
2551
  centerX: e,
2390
2552
  centerY: t,
2391
2553
  radius: s,
2392
- startColor: a,
2393
- endColor: n,
2394
- startPosition: o,
2554
+ startColor: n,
2555
+ endColor: o,
2556
+ startPosition: a,
2395
2557
  endPosition: i,
2396
2558
  customData: r = {},
2397
- withoutSave: d = !1
2559
+ withoutSave: c = !1
2398
2560
  }) {
2399
2561
  this.setGradientBackground({
2400
2562
  gradient: {
@@ -2402,13 +2564,13 @@ class R {
2402
2564
  centerX: e,
2403
2565
  centerY: t,
2404
2566
  radius: s,
2405
- startColor: a,
2406
- endColor: n,
2407
- startPosition: o,
2567
+ startColor: n,
2568
+ endColor: o,
2569
+ startPosition: a,
2408
2570
  endPosition: i
2409
2571
  },
2410
2572
  customData: r,
2411
- withoutSave: d
2573
+ withoutSave: c
2412
2574
  });
2413
2575
  }
2414
2576
  /**
@@ -2417,26 +2579,26 @@ class R {
2417
2579
  * @param options.imageUrl - URL изображения
2418
2580
  * @param options.withoutSave - Если true, не сохранять состояние в историю
2419
2581
  */
2420
- setImageBackground(a) {
2421
- return j(this, arguments, function* ({
2582
+ setImageBackground(n) {
2583
+ return y(this, arguments, function* ({
2422
2584
  imageSource: e,
2423
2585
  customData: t = {},
2424
2586
  withoutSave: s = !1
2425
2587
  }) {
2426
2588
  try {
2427
- const { historyManager: n } = this.editor;
2428
- n.suspendHistory(), yield this._createImageBackground(e, t), this.editor.canvas.fire("editor:background:changed", {
2589
+ const { historyManager: o } = this.editor;
2590
+ o.suspendHistory(), yield this._createImageBackground(e, t), this.editor.canvas.fire("editor:background:changed", {
2429
2591
  type: "image",
2430
2592
  imageSource: e,
2431
2593
  backgroundObject: this.backgroundObject
2432
- }), n.resumeHistory(), s || n.saveState();
2433
- } catch (n) {
2594
+ }), o.resumeHistory(), s || o.saveState();
2595
+ } catch (o) {
2434
2596
  this.editor.errorManager.emitError({
2435
2597
  code: "BACKGROUND_CREATION_FAILED",
2436
2598
  origin: "BackgroundManager",
2437
2599
  method: "setImageBackground",
2438
2600
  message: "Не удалось установить изображение в качестве фона",
2439
- data: { error: n }
2601
+ data: { error: o }
2440
2602
  });
2441
2603
  }
2442
2604
  });
@@ -2468,8 +2630,8 @@ class R {
2468
2630
  const { canvas: e, montageArea: t, historyManager: s } = this.editor;
2469
2631
  if (!t || !this.backgroundObject) return;
2470
2632
  s.suspendHistory(), this.editor.transformManager.fitObject({ object: this.backgroundObject, withoutSave: !0, type: "cover" });
2471
- const a = e.getObjects(), n = a.indexOf(t), o = a.indexOf(this.backgroundObject);
2472
- this.backgroundObject && o !== n + 1 && e.moveObjectTo(this.backgroundObject, n + 1), e.requestRenderAll(), s.resumeHistory();
2633
+ const n = e.getObjects(), o = n.indexOf(t), a = n.indexOf(this.backgroundObject);
2634
+ this.backgroundObject && a !== o + 1 && e.moveObjectTo(this.backgroundObject, o + 1), e.requestRenderAll(), s.resumeHistory();
2473
2635
  }
2474
2636
  /**
2475
2637
  * Создает цветовой фон.
@@ -2484,7 +2646,7 @@ class R {
2484
2646
  hasControls: !1,
2485
2647
  id: "background",
2486
2648
  backgroundType: "color",
2487
- backgroundId: `background-${A()}`
2649
+ backgroundId: `background-${C()}`
2488
2650
  }, { withoutSelection: !0 }), this.refresh();
2489
2651
  }
2490
2652
  /**
@@ -2501,9 +2663,9 @@ class R {
2501
2663
  hasControls: !1,
2502
2664
  id: "background",
2503
2665
  backgroundType: "gradient",
2504
- backgroundId: `background-${A()}`
2666
+ backgroundId: `background-${C()}`
2505
2667
  }, { withoutSelection: !0 }), this.refresh();
2506
- const t = R._createFabricGradient(e);
2668
+ const t = Y._createFabricGradient(e);
2507
2669
  this.backgroundObject.set("fill", t), this.editor.canvas.requestRenderAll();
2508
2670
  }
2509
2671
  /**
@@ -2511,15 +2673,15 @@ class R {
2511
2673
  * @param source - источник изображения (URL или File)
2512
2674
  */
2513
2675
  _createImageBackground(e, t) {
2514
- return j(this, null, function* () {
2515
- var a;
2516
- const { image: s } = (a = yield this.editor.imageManager.importImage({
2676
+ return y(this, null, function* () {
2677
+ var n;
2678
+ const { image: s } = (n = yield this.editor.imageManager.importImage({
2517
2679
  source: e,
2518
2680
  withoutSave: !0,
2519
2681
  isBackground: !0,
2520
2682
  withoutSelection: !0,
2521
2683
  scale: "image-cover"
2522
- })) != null ? a : {};
2684
+ })) != null ? n : {};
2523
2685
  if (!s)
2524
2686
  throw new Error("Не удалось загрузить изображение");
2525
2687
  s.set({
@@ -2529,7 +2691,7 @@ class R {
2529
2691
  hasControls: !1,
2530
2692
  id: "background",
2531
2693
  backgroundType: "image",
2532
- backgroundId: `background-${A()}`,
2694
+ backgroundId: `background-${C()}`,
2533
2695
  customData: t
2534
2696
  }), this._removeCurrentBackground(), this.backgroundObject = s, this.refresh();
2535
2697
  });
@@ -2548,38 +2710,38 @@ class R {
2548
2710
  const {
2549
2711
  startColor: t,
2550
2712
  endColor: s,
2551
- startPosition: a = 0,
2552
- endPosition: n = 100
2553
- } = e, o = [
2554
- { offset: a / 100, color: t },
2555
- { offset: n / 100, color: s }
2713
+ startPosition: n = 0,
2714
+ endPosition: o = 100
2715
+ } = e, a = [
2716
+ { offset: n / 100, color: t },
2717
+ { offset: o / 100, color: s }
2556
2718
  ];
2557
2719
  if (e.type === "linear") {
2558
- const l = e.angle * Math.PI / 180, u = R._angleToCoords(l);
2559
- return new pe({
2720
+ const l = e.angle * Math.PI / 180, g = Y._angleToCoords(l);
2721
+ return new ye({
2560
2722
  type: "linear",
2561
2723
  gradientUnits: "percentage",
2562
- coords: u,
2563
- colorStops: o
2724
+ coords: g,
2725
+ colorStops: a
2564
2726
  });
2565
2727
  }
2566
2728
  const {
2567
2729
  centerX: i = 50,
2568
2730
  centerY: r = 50,
2569
- radius: d = 50
2731
+ radius: c = 50
2570
2732
  } = e, h = {
2571
2733
  x1: i / 100,
2572
2734
  y1: r / 100,
2573
2735
  x2: i / 100,
2574
2736
  y2: r / 100,
2575
2737
  r1: 0,
2576
- r2: d / 100
2738
+ r2: c / 100
2577
2739
  };
2578
- return new pe({
2740
+ return new ye({
2579
2741
  type: "radial",
2580
2742
  gradientUnits: "percentage",
2581
2743
  coords: h,
2582
- colorStops: o
2744
+ colorStops: a
2583
2745
  });
2584
2746
  }
2585
2747
  /**
@@ -2603,14 +2765,14 @@ class R {
2603
2765
  */
2604
2766
  static _isGradientEqual(e, t) {
2605
2767
  if (!e || !t || e.type !== t.type) return !1;
2606
- const s = e.colorStops || [], a = t.colorStops || [];
2607
- return s.length !== a.length || !s.every((o, i) => {
2608
- const r = a[i];
2609
- return o.color === r.color && Math.abs(o.offset - r.offset) < 1e-4;
2768
+ const s = e.colorStops || [], n = t.colorStops || [];
2769
+ return s.length !== n.length || !s.every((a, i) => {
2770
+ const r = n[i];
2771
+ return a.color === r.color && Math.abs(a.offset - r.offset) < 1e-4;
2610
2772
  }) ? !1 : e.type === "linear" && t.type === "linear" ? Math.abs(e.coords.x1 - t.coords.x1) < 1e-4 && Math.abs(e.coords.y1 - t.coords.y1) < 1e-4 && Math.abs(e.coords.x2 - t.coords.x2) < 1e-4 && Math.abs(e.coords.y2 - t.coords.y2) < 1e-4 : e.type === "radial" && t.type === "radial" ? Math.abs(e.coords.x1 - t.coords.x1) < 1e-4 && Math.abs(e.coords.y1 - t.coords.y1) < 1e-4 && Math.abs(e.coords.x2 - t.coords.x2) < 1e-4 && Math.abs(e.coords.y2 - t.coords.y2) < 1e-4 && Math.abs(e.coords.r1 - t.coords.r1) < 1e-4 && Math.abs(e.coords.r2 - t.coords.r2) < 1e-4 : !1;
2611
2773
  }
2612
2774
  }
2613
- class K {
2775
+ class J {
2614
2776
  constructor({ editor: e }) {
2615
2777
  this.editor = e;
2616
2778
  }
@@ -2622,13 +2784,13 @@ class K {
2622
2784
  * @fires editor:object-bring-to-front
2623
2785
  */
2624
2786
  bringToFront(e, { withoutSave: t } = {}) {
2625
- const { canvas: s, historyManager: a } = this.editor;
2626
- a.suspendHistory();
2627
- const n = e || s.getActiveObject();
2628
- n && (n instanceof v ? n.getObjects().forEach((o) => {
2629
- s.bringObjectToFront(o);
2630
- }) : s.bringObjectToFront(n), s.renderAll(), a.resumeHistory(), t || a.saveState(), s.fire("editor:object-bring-to-front", {
2631
- object: n,
2787
+ const { canvas: s, historyManager: n } = this.editor;
2788
+ n.suspendHistory();
2789
+ const o = e || s.getActiveObject();
2790
+ o && (o instanceof v ? o.getObjects().forEach((a) => {
2791
+ s.bringObjectToFront(a);
2792
+ }) : s.bringObjectToFront(o), s.renderAll(), n.resumeHistory(), t || n.saveState(), s.fire("editor:object-bring-to-front", {
2793
+ object: o,
2632
2794
  withoutSave: t
2633
2795
  }));
2634
2796
  }
@@ -2640,11 +2802,11 @@ class K {
2640
2802
  * @fires editor:object-bring-forward
2641
2803
  */
2642
2804
  bringForward(e, { withoutSave: t } = {}) {
2643
- const { canvas: s, historyManager: a } = this.editor;
2644
- a.suspendHistory();
2645
- const n = e || s.getActiveObject();
2646
- n && (n instanceof v ? K._moveSelectionForward(s, n) : s.bringObjectForward(n), s.renderAll(), a.resumeHistory(), t || a.saveState(), s.fire("editor:object-bring-forward", {
2647
- object: n,
2805
+ const { canvas: s, historyManager: n } = this.editor;
2806
+ n.suspendHistory();
2807
+ const o = e || s.getActiveObject();
2808
+ o && (o instanceof v ? J._moveSelectionForward(s, o) : s.bringObjectForward(o), s.renderAll(), n.resumeHistory(), t || n.saveState(), s.fire("editor:object-bring-forward", {
2809
+ object: o,
2648
2810
  withoutSave: t
2649
2811
  }));
2650
2812
  }
@@ -2658,21 +2820,21 @@ class K {
2658
2820
  sendToBack(e, { withoutSave: t } = {}) {
2659
2821
  const {
2660
2822
  canvas: s,
2661
- montageArea: a,
2662
- historyManager: n,
2663
- interactionBlocker: { overlayMask: o },
2823
+ montageArea: n,
2824
+ historyManager: o,
2825
+ interactionBlocker: { overlayMask: a },
2664
2826
  backgroundManager: { backgroundObject: i }
2665
2827
  } = this.editor;
2666
- n.suspendHistory();
2828
+ o.suspendHistory();
2667
2829
  const r = e || s.getActiveObject();
2668
2830
  if (r) {
2669
2831
  if (r instanceof v) {
2670
- const d = r.getObjects();
2671
- for (let h = d.length - 1; h >= 0; h -= 1)
2672
- s.sendObjectToBack(d[h]);
2832
+ const c = r.getObjects();
2833
+ for (let h = c.length - 1; h >= 0; h -= 1)
2834
+ s.sendObjectToBack(c[h]);
2673
2835
  } else
2674
2836
  s.sendObjectToBack(r);
2675
- i && s.sendObjectToBack(i), s.sendObjectToBack(a), o && s.sendObjectToBack(o), s.renderAll(), n.resumeHistory(), t || n.saveState(), s.fire("editor:object-send-to-back", {
2837
+ i && s.sendObjectToBack(i), s.sendObjectToBack(n), a && s.sendObjectToBack(a), s.renderAll(), o.resumeHistory(), t || o.saveState(), s.fire("editor:object-send-to-back", {
2676
2838
  object: r,
2677
2839
  withoutSave: t
2678
2840
  });
@@ -2687,14 +2849,14 @@ class K {
2687
2849
  sendBackwards(e, { withoutSave: t } = {}) {
2688
2850
  const {
2689
2851
  canvas: s,
2690
- montageArea: a,
2691
- historyManager: n,
2692
- interactionBlocker: { overlayMask: o },
2852
+ montageArea: n,
2853
+ historyManager: o,
2854
+ interactionBlocker: { overlayMask: a },
2693
2855
  backgroundManager: { backgroundObject: i }
2694
2856
  } = this.editor;
2695
- n.suspendHistory();
2857
+ o.suspendHistory();
2696
2858
  const r = e || s.getActiveObject();
2697
- r && (r instanceof v ? K._moveSelectionBackwards(s, r) : s.sendObjectBackwards(r), i && s.sendObjectToBack(i), s.sendObjectToBack(a), o && s.sendObjectToBack(o), s.renderAll(), n.resumeHistory(), t || n.saveState(), s.fire("editor:object-send-backwards", {
2859
+ r && (r instanceof v ? J._moveSelectionBackwards(s, r) : s.sendObjectBackwards(r), i && s.sendObjectToBack(i), s.sendObjectToBack(n), a && s.sendObjectToBack(a), s.renderAll(), o.resumeHistory(), t || o.saveState(), s.fire("editor:object-send-backwards", {
2698
2860
  object: r,
2699
2861
  withoutSave: t
2700
2862
  }));
@@ -2706,15 +2868,15 @@ class K {
2706
2868
  * @param activeSelection - активное выделение
2707
2869
  */
2708
2870
  static _moveSelectionForward(e, t) {
2709
- const s = e.getObjects(), a = t.getObjects();
2710
- if (!a.some((i) => {
2871
+ const s = e.getObjects(), n = t.getObjects();
2872
+ if (!n.some((i) => {
2711
2873
  const r = s.indexOf(i);
2712
- for (let d = r + 1; d < s.length; d += 1)
2713
- if (!a.includes(s[d]))
2874
+ for (let c = r + 1; c < s.length; c += 1)
2875
+ if (!n.includes(s[c]))
2714
2876
  return !0;
2715
2877
  return !1;
2716
2878
  })) return;
2717
- a.map((i) => ({ obj: i, index: s.indexOf(i) })).sort((i, r) => r.index - i.index).forEach((i) => {
2879
+ n.map((i) => ({ obj: i, index: s.indexOf(i) })).sort((i, r) => r.index - i.index).forEach((i) => {
2718
2880
  e.bringObjectForward(i.obj);
2719
2881
  });
2720
2882
  }
@@ -2725,20 +2887,20 @@ class K {
2725
2887
  * @param activeSelection - активное выделение
2726
2888
  */
2727
2889
  static _moveSelectionBackwards(e, t) {
2728
- const s = e.getObjects(), a = t.getObjects();
2729
- if (!a.some((i) => {
2890
+ const s = e.getObjects(), n = t.getObjects();
2891
+ if (!n.some((i) => {
2730
2892
  const r = s.indexOf(i);
2731
- for (let d = r - 1; d >= 0; d -= 1)
2732
- if (!a.includes(s[d]))
2893
+ for (let c = r - 1; c >= 0; c -= 1)
2894
+ if (!n.includes(s[c]))
2733
2895
  return !0;
2734
2896
  return !1;
2735
2897
  })) return;
2736
- a.map((i) => ({ obj: i, index: s.indexOf(i) })).sort((i, r) => i.index - r.index).forEach((i) => {
2898
+ n.map((i) => ({ obj: i, index: s.indexOf(i) })).sort((i, r) => i.index - r.index).forEach((i) => {
2737
2899
  e.sendObjectBackwards(i.obj);
2738
2900
  });
2739
2901
  }
2740
2902
  }
2741
- class pt {
2903
+ class yt {
2742
2904
  /**
2743
2905
  * Менеджер фигур для редактора.
2744
2906
  * @param options - Опции и настройки менеджера фигур.
@@ -2762,15 +2924,15 @@ class pt {
2762
2924
  * @param flags.withoutSelection - Не выделять объект
2763
2925
  * @param flags.withoutAdding - Не добавлять объект в canvas
2764
2926
  */
2765
- addRectangle(h = {}, { withoutSelection: r, withoutAdding: d } = {}) {
2927
+ addRectangle(h = {}, { withoutSelection: r, withoutAdding: c } = {}) {
2766
2928
  var l = h, {
2767
- id: e = `rect-${A()}`,
2929
+ id: e = `rect-${C()}`,
2768
2930
  left: t,
2769
2931
  top: s,
2770
- width: a = 100,
2771
- height: n = 100,
2772
- fill: o = "blue"
2773
- } = l, i = V(l, [
2932
+ width: n = 100,
2933
+ height: o = 100,
2934
+ fill: a = "blue"
2935
+ } = l, i = G(l, [
2774
2936
  "id",
2775
2937
  "left",
2776
2938
  "top",
@@ -2778,15 +2940,15 @@ class pt {
2778
2940
  "height",
2779
2941
  "fill"
2780
2942
  ]);
2781
- const { canvas: u } = this.editor, g = new _e(I({
2943
+ const { canvas: g } = this.editor, u = new Be(I({
2782
2944
  id: e,
2783
2945
  left: t,
2784
2946
  top: s,
2785
- width: a,
2786
- height: n,
2787
- fill: o
2947
+ width: n,
2948
+ height: o,
2949
+ fill: a
2788
2950
  }, i));
2789
- return !t && !s && u.centerObject(g), d || (u.add(g), r || u.setActiveObject(g), u.renderAll()), g;
2951
+ return !t && !s && g.centerObject(u), c || (g.add(u), r || g.setActiveObject(u), g.renderAll()), u;
2790
2952
  }
2791
2953
  /**
2792
2954
  * Добавление круга
@@ -2804,28 +2966,28 @@ class pt {
2804
2966
  * @param flags.withoutSelection - Не выделять объект
2805
2967
  * @param flags.withoutAdding - Не добавлять объект в canvas
2806
2968
  */
2807
- addCircle(d = {}, { withoutSelection: i, withoutAdding: r } = {}) {
2808
- var h = d, {
2809
- id: e = `circle-${A()}`,
2969
+ addCircle(c = {}, { withoutSelection: i, withoutAdding: r } = {}) {
2970
+ var h = c, {
2971
+ id: e = `circle-${C()}`,
2810
2972
  left: t,
2811
2973
  top: s,
2812
- radius: a = 50,
2813
- fill: n = "green"
2814
- } = h, o = V(h, [
2974
+ radius: n = 50,
2975
+ fill: o = "green"
2976
+ } = h, a = G(h, [
2815
2977
  "id",
2816
2978
  "left",
2817
2979
  "top",
2818
2980
  "radius",
2819
2981
  "fill"
2820
2982
  ]);
2821
- const { canvas: l } = this.editor, u = new Be(I({
2983
+ const { canvas: l } = this.editor, g = new xe(I({
2822
2984
  id: e,
2823
2985
  left: t,
2824
2986
  top: s,
2825
- fill: n,
2826
- radius: a
2827
- }, o));
2828
- return !t && !s && l.centerObject(u), r || (l.add(u), i || l.setActiveObject(u), l.renderAll()), u;
2987
+ fill: o,
2988
+ radius: n
2989
+ }, a));
2990
+ return !t && !s && l.centerObject(g), r || (l.add(g), i || l.setActiveObject(g), l.renderAll()), g;
2829
2991
  }
2830
2992
  /**
2831
2993
  * Добавление треугольника
@@ -2844,15 +3006,15 @@ class pt {
2844
3006
  * @param flags.withoutSelection - Не выделять объект
2845
3007
  * @param flags.withoutAdding - Не добавлять объект в canvas
2846
3008
  */
2847
- addTriangle(h = {}, { withoutSelection: r, withoutAdding: d } = {}) {
3009
+ addTriangle(h = {}, { withoutSelection: r, withoutAdding: c } = {}) {
2848
3010
  var l = h, {
2849
- id: e = `triangle-${A()}`,
3011
+ id: e = `triangle-${C()}`,
2850
3012
  left: t,
2851
3013
  top: s,
2852
- width: a = 100,
2853
- height: n = 100,
2854
- fill: o = "yellow"
2855
- } = l, i = V(l, [
3014
+ width: n = 100,
3015
+ height: o = 100,
3016
+ fill: a = "yellow"
3017
+ } = l, i = G(l, [
2856
3018
  "id",
2857
3019
  "left",
2858
3020
  "top",
@@ -2860,18 +3022,18 @@ class pt {
2860
3022
  "height",
2861
3023
  "fill"
2862
3024
  ]);
2863
- const { canvas: u } = this.editor, g = new xe(I({
3025
+ const { canvas: g } = this.editor, u = new Re(I({
2864
3026
  id: e,
2865
3027
  left: t,
2866
3028
  top: s,
2867
- fill: o,
2868
- width: a,
2869
- height: n
3029
+ fill: a,
3030
+ width: n,
3031
+ height: o
2870
3032
  }, i));
2871
- return !t && !s && u.centerObject(g), d || (u.add(g), r || u.setActiveObject(g), u.renderAll()), g;
3033
+ return !t && !s && g.centerObject(u), c || (g.add(u), r || g.setActiveObject(u), g.renderAll()), u;
2872
3034
  }
2873
3035
  }
2874
- class yt {
3036
+ class vt {
2875
3037
  /**
2876
3038
  * @param options
2877
3039
  * @param options.editor - экземпляр редактора с доступом к canvas
@@ -2899,18 +3061,18 @@ class yt {
2899
3061
  * Асинхронное клонирование для внутреннего буфера
2900
3062
  */
2901
3063
  _cloneToInternalClipboard(e) {
2902
- return j(this, null, function* () {
3064
+ return y(this, null, function* () {
2903
3065
  const { canvas: t, errorManager: s } = this.editor;
2904
3066
  try {
2905
- const a = yield e.clone(["format"]);
2906
- this.clipboard = a, t.fire("editor:object-copied", { object: a });
2907
- } catch (a) {
3067
+ const n = yield e.clone(["format"]);
3068
+ this.clipboard = n, t.fire("editor:object-copied", { object: n });
3069
+ } catch (n) {
2908
3070
  s.emitError({
2909
3071
  origin: "ClipboardManager",
2910
3072
  method: "_cloneToInternalClipboard",
2911
3073
  code: "CLONE_FAILED",
2912
3074
  message: "Ошибка клонирования объекта для внутреннего буфера",
2913
- data: a
3075
+ data: n
2914
3076
  });
2915
3077
  }
2916
3078
  });
@@ -2919,7 +3081,7 @@ class yt {
2919
3081
  * Копирование в системный буфер обмена
2920
3082
  */
2921
3083
  _copyToSystemClipboard(e) {
2922
- return j(this, null, function* () {
3084
+ return y(this, null, function* () {
2923
3085
  const { errorManager: t } = this.editor;
2924
3086
  if (typeof ClipboardItem == "undefined" || !navigator.clipboard)
2925
3087
  return t.emitWarning({
@@ -2929,8 +3091,8 @@ class yt {
2929
3091
  message: "navigator.clipboard не поддерживается в этом браузере или отсутствует HTTPS-соединение."
2930
3092
  }), !1;
2931
3093
  try {
2932
- const s = e.toObject(["format"]), a = JSON.stringify(s);
2933
- return e.type === "image" ? this._copyImageToClipboard(e, a) : this._copyTextToClipboard(a);
3094
+ const s = e.toObject(["format"]), n = JSON.stringify(s);
3095
+ return e.type === "image" ? this._copyImageToClipboard(e, n) : this._copyTextToClipboard(n);
2934
3096
  } catch (s) {
2935
3097
  return t.emitError({
2936
3098
  origin: "ClipboardManager",
@@ -2946,12 +3108,12 @@ class yt {
2946
3108
  * Копирование изображения в буфер обмена
2947
3109
  */
2948
3110
  _copyImageToClipboard(e, t) {
2949
- return j(this, null, function* () {
3111
+ return y(this, null, function* () {
2950
3112
  try {
2951
- const a = e.toCanvasElement({ enableRetinaScaling: !1 }).toDataURL(), n = a.slice(5).split(";")[0], o = a.split(",")[1], i = atob(o), r = new Uint8Array(i.length);
3113
+ const n = e.toCanvasElement({ enableRetinaScaling: !1 }).toDataURL(), o = n.slice(5).split(";")[0], a = n.split(",")[1], i = atob(a), r = new Uint8Array(i.length);
2952
3114
  for (let l = 0; l < i.length; l += 1)
2953
3115
  r[l] = i.charCodeAt(l);
2954
- const d = new Blob([r.buffer], { type: n }), h = new ClipboardItem({ [n]: d });
3116
+ const c = new Blob([r.buffer], { type: o }), h = new ClipboardItem({ [o]: c });
2955
3117
  return yield navigator.clipboard.write([h]), console.info("Image copied to clipboard successfully"), !0;
2956
3118
  } catch (s) {
2957
3119
  return this.editor.errorManager.emitWarning({
@@ -2968,9 +3130,9 @@ class yt {
2968
3130
  * Копирование текста в буфер обмена
2969
3131
  */
2970
3132
  _copyTextToClipboard(e) {
2971
- return j(this, null, function* () {
3133
+ return y(this, null, function* () {
2972
3134
  try {
2973
- const t = `${Ce}${e}`;
3135
+ const t = `${De}${e}`;
2974
3136
  return yield navigator.clipboard.writeText(t), console.info("Text copied to clipboard successfully"), !0;
2975
3137
  } catch (t) {
2976
3138
  const { errorManager: s } = this.editor;
@@ -2991,8 +3153,8 @@ class yt {
2991
3153
  _addClonedObjectToCanvas(e) {
2992
3154
  const { canvas: t, historyManager: s } = this.editor;
2993
3155
  if (t.discardActiveObject(), e instanceof v) {
2994
- s.suspendHistory(), e.canvas = t, e.forEachObject((a) => {
2995
- t.add(a);
3156
+ s.suspendHistory(), e.canvas = t, e.forEachObject((n) => {
3157
+ t.add(n);
2996
3158
  }), t.setActiveObject(e), t.requestRenderAll(), s.resumeHistory(), s.saveState();
2997
3159
  return;
2998
3160
  }
@@ -3003,7 +3165,7 @@ class yt {
3003
3165
  * @param source - источник изображения (data URL или URL)
3004
3166
  */
3005
3167
  _handleImageImport(e) {
3006
- return j(this, null, function* () {
3168
+ return y(this, null, function* () {
3007
3169
  var s;
3008
3170
  const { image: t } = (s = yield this.editor.imageManager.importImage({
3009
3171
  source: e,
@@ -3019,25 +3181,30 @@ class yt {
3019
3181
  * @fires editor:object-pasted
3020
3182
  */
3021
3183
  copyPaste(e) {
3022
- return j(this, null, function* () {
3184
+ return y(this, null, function* () {
3023
3185
  const { canvas: t } = this.editor, s = e || t.getActiveObject();
3024
3186
  if (!s || s.locked) return !1;
3025
3187
  try {
3026
- const a = yield s.clone(["format"]);
3027
- return a.set({
3028
- id: `${a.type}-${A()}`,
3029
- left: a.left + 10,
3030
- top: a.top + 10,
3188
+ const n = yield s.clone(["format"]);
3189
+ return n instanceof v && n.forEachObject((o) => {
3190
+ o.set({
3191
+ id: `${o.type}-${C()}`,
3192
+ evented: !0
3193
+ });
3194
+ }), n.set({
3195
+ id: `${n.type}-${C()}`,
3196
+ left: n.left + 10,
3197
+ top: n.top + 10,
3031
3198
  evented: !0
3032
- }), this._addClonedObjectToCanvas(a), t.fire("editor:object-duplicated", { object: a }), !0;
3033
- } catch (a) {
3034
- const { errorManager: n } = this.editor;
3035
- return n.emitError({
3199
+ }), this._addClonedObjectToCanvas(n), t.fire("editor:object-duplicated", { object: n }), !0;
3200
+ } catch (n) {
3201
+ const { errorManager: o } = this.editor;
3202
+ return o.emitError({
3036
3203
  origin: "ClipboardManager",
3037
3204
  method: "copyPaste",
3038
3205
  code: "COPY_PASTE_FAILED",
3039
3206
  message: "Ошибка создания копии объекта",
3040
- data: a
3207
+ data: n
3041
3208
  }), !1;
3042
3209
  }
3043
3210
  });
@@ -3049,21 +3216,21 @@ class yt {
3049
3216
  * @param event.clipboardData.items — элементы буфера обмена
3050
3217
  */
3051
3218
  handlePasteEvent(t) {
3052
- return j(this, arguments, function* ({ clipboardData: e }) {
3219
+ return y(this, arguments, function* ({ clipboardData: e }) {
3053
3220
  var r;
3054
3221
  if (!((r = e == null ? void 0 : e.items) != null && r.length)) {
3055
3222
  this.paste();
3056
3223
  return;
3057
3224
  }
3058
3225
  const s = e.getData("text/plain");
3059
- if (s && s.startsWith(Ce)) {
3226
+ if (s && s.startsWith(De)) {
3060
3227
  this.paste();
3061
3228
  return;
3062
3229
  }
3063
- const { items: a } = e, n = a[a.length - 1], o = n.getAsFile();
3064
- if (n.type !== "text/html" && o) {
3065
- const d = new FileReader();
3066
- d.onload = (h) => {
3230
+ const { items: n } = e, o = n[n.length - 1], a = o.getAsFile();
3231
+ if (o.type !== "text/html" && a) {
3232
+ const c = new FileReader();
3233
+ c.onload = (h) => {
3067
3234
  h.target && this._handleImageImport(h.target.result).catch((l) => {
3068
3235
  this.editor.errorManager.emitError({
3069
3236
  origin: "ClipboardManager",
@@ -3073,20 +3240,20 @@ class yt {
3073
3240
  data: l
3074
3241
  });
3075
3242
  });
3076
- }, d.readAsDataURL(o);
3243
+ }, c.readAsDataURL(a);
3077
3244
  return;
3078
3245
  }
3079
3246
  const i = e.getData("text/html");
3080
3247
  if (i) {
3081
3248
  const l = new DOMParser().parseFromString(i, "text/html").querySelector("img");
3082
3249
  if (l != null && l.src) {
3083
- this._handleImageImport(l.src).catch((u) => {
3250
+ this._handleImageImport(l.src).catch((g) => {
3084
3251
  this.editor.errorManager.emitError({
3085
3252
  origin: "ClipboardManager",
3086
3253
  method: "handlePasteEvent",
3087
3254
  code: "PASTE_HTML_IMAGE_FAILED",
3088
3255
  message: "Ошибка вставки изображения из HTML",
3089
- data: u
3256
+ data: g
3090
3257
  });
3091
3258
  });
3092
3259
  return;
@@ -3100,13 +3267,18 @@ class yt {
3100
3267
  * @fires editor:object-pasted
3101
3268
  */
3102
3269
  paste() {
3103
- return j(this, null, function* () {
3270
+ return y(this, null, function* () {
3104
3271
  const { canvas: e } = this.editor;
3105
3272
  if (!this.clipboard) return !1;
3106
3273
  try {
3107
3274
  const t = yield this.clipboard.clone(["format"]);
3108
- return e.discardActiveObject(), t.set({
3109
- id: `${t.type}-${A()}`,
3275
+ return e.discardActiveObject(), t instanceof v && t.forEachObject((s) => {
3276
+ s.set({
3277
+ id: `${s.type}-${C()}`,
3278
+ evented: !0
3279
+ });
3280
+ }), t.set({
3281
+ id: `${t.type}-${C()}`,
3110
3282
  left: t.left + 10,
3111
3283
  top: t.top + 10,
3112
3284
  evented: !0
@@ -3124,7 +3296,7 @@ class yt {
3124
3296
  });
3125
3297
  }
3126
3298
  }
3127
- class J {
3299
+ class q {
3128
3300
  constructor({ editor: e }) {
3129
3301
  this.editor = e;
3130
3302
  }
@@ -3137,8 +3309,8 @@ class J {
3137
3309
  * @fires editor:object-locked
3138
3310
  */
3139
3311
  lockObject({ object: e, skipInnerObjects: t, withoutSave: s } = {}) {
3140
- const { canvas: a, historyManager: n } = this.editor, o = e || a.getActiveObject();
3141
- if (!o || o.locked) return;
3312
+ const { canvas: n, historyManager: o } = this.editor, a = e || n.getActiveObject();
3313
+ if (!a || a.locked) return;
3142
3314
  const i = {
3143
3315
  lockMovementX: !0,
3144
3316
  lockMovementY: !0,
@@ -3149,10 +3321,10 @@ class J {
3149
3321
  lockSkewingY: !0,
3150
3322
  locked: !0
3151
3323
  };
3152
- o.set(i), !t && J._isGroupOrSelection(o) && o.getObjects().forEach((d) => {
3153
- d.set(i);
3154
- }), a.renderAll(), s || n.saveState(), a.fire("editor:object-locked", {
3155
- object: o,
3324
+ a.set(i), !t && q._isGroupOrSelection(a) && a.getObjects().forEach((c) => {
3325
+ c.set(i);
3326
+ }), n.renderAll(), s || o.saveState(), n.fire("editor:object-locked", {
3327
+ object: a,
3156
3328
  skipInnerObjects: t,
3157
3329
  withoutSave: s
3158
3330
  });
@@ -3165,9 +3337,9 @@ class J {
3165
3337
  * @fires editor:object-unlocked
3166
3338
  */
3167
3339
  unlockObject({ object: e, withoutSave: t } = {}) {
3168
- const { canvas: s, historyManager: a } = this.editor, n = e || s.getActiveObject();
3169
- if (!n) return;
3170
- const o = {
3340
+ const { canvas: s, historyManager: n } = this.editor, o = e || s.getActiveObject();
3341
+ if (!o) return;
3342
+ const a = {
3171
3343
  lockMovementX: !1,
3172
3344
  lockMovementY: !1,
3173
3345
  lockRotation: !1,
@@ -3177,15 +3349,15 @@ class J {
3177
3349
  lockSkewingY: !1,
3178
3350
  locked: !1
3179
3351
  };
3180
- n.set(o), J._isGroupOrSelection(n) && n.getObjects().forEach((i) => {
3181
- i.set(o);
3182
- }), s.renderAll(), t || a.saveState(), s.fire("editor:object-unlocked", {
3183
- object: n,
3352
+ o.set(a), q._isGroupOrSelection(o) && o.getObjects().forEach((i) => {
3353
+ i.set(a);
3354
+ }), s.renderAll(), t || n.saveState(), s.fire("editor:object-unlocked", {
3355
+ object: o,
3184
3356
  withoutSave: t
3185
3357
  });
3186
3358
  }
3187
3359
  static _isGroupOrSelection(e) {
3188
- return e instanceof v || e instanceof te;
3360
+ return e instanceof v || e instanceof U;
3189
3361
  }
3190
3362
  }
3191
3363
  class It {
@@ -3193,58 +3365,103 @@ class It {
3193
3365
  this.editor = e;
3194
3366
  }
3195
3367
  /**
3196
- * Группировка объектов
3197
- * @param options
3198
- * @param options.withoutSave - Не сохранять состояние
3199
- * @param options.object - массив объектов для группировки
3200
- * @fires editor:objects-grouped
3368
+ * Получить объекты для группировки
3369
+ * @private
3370
+ */
3371
+ _getObjectsToGroup(e) {
3372
+ if (Array.isArray(e))
3373
+ return e.length > 0 ? e : null;
3374
+ const t = e || this.editor.canvas.getActiveObject();
3375
+ return !t || !(t instanceof v) ? null : t.getObjects();
3376
+ }
3377
+ /**
3378
+ * Получить группы для разгруппировки
3379
+ * @private
3201
3380
  */
3381
+ _getGroupsToUngroup(e) {
3382
+ if (Array.isArray(e)) {
3383
+ const s = e.filter((n) => n instanceof U);
3384
+ return s.length > 0 ? s : null;
3385
+ }
3386
+ if (e instanceof v) {
3387
+ const s = e.getObjects().filter((n) => n instanceof U);
3388
+ return s.length > 0 ? s : null;
3389
+ }
3390
+ const t = e || this.editor.canvas.getActiveObject();
3391
+ if (!t) return null;
3392
+ if (t instanceof v) {
3393
+ const s = t.getObjects().filter((n) => n instanceof U);
3394
+ return s.length > 0 ? s : null;
3395
+ }
3396
+ return t instanceof U ? [t] : null;
3397
+ }
3398
+ /**
3399
+ * Группировка объектов
3400
+ * @param options
3401
+ * @param options.target - объект ActiveSelection или массив объектов для группировки
3402
+ * @param options.withoutSave - Не сохранять состояние
3403
+ * @fires editor:objects-grouped
3404
+ */
3202
3405
  group({
3203
- object: e,
3204
- withoutSave: t
3406
+ target: e,
3407
+ withoutSave: t = !1
3205
3408
  } = {}) {
3206
- const { canvas: s, historyManager: a } = this.editor;
3207
- a.suspendHistory();
3208
- const n = e || s.getActiveObject();
3209
- if (!n || !(n instanceof v)) return;
3210
- const o = n.getObjects(), i = new te(o);
3211
- o.forEach((r) => s.remove(r)), i.set("id", `${i.type}-${A()}`), s.add(i), s.setActiveObject(i), s.renderAll(), a.resumeHistory(), t || a.saveState(), s.fire("editor:objects-grouped", {
3212
- object: n,
3213
- group: i,
3214
- withoutSave: t
3215
- });
3409
+ const { canvas: s, historyManager: n } = this.editor, o = this._getObjectsToGroup(e);
3410
+ if (!o) return null;
3411
+ try {
3412
+ n.suspendHistory();
3413
+ const a = new U(o, {
3414
+ id: `group-${C()}`
3415
+ });
3416
+ o.forEach((r) => s.remove(r)), s.add(a), s.setActiveObject(a), s.requestRenderAll();
3417
+ const i = {
3418
+ group: a,
3419
+ withoutSave: t
3420
+ };
3421
+ return s.fire("editor:objects-grouped", i), i;
3422
+ } finally {
3423
+ n.resumeHistory(), t || n.saveState();
3424
+ }
3216
3425
  }
3217
3426
  /**
3218
- * Разгруппировка объектов
3219
- * @param options
3220
- * @param options.object - объект для разгруппировки
3221
- * @param options.withoutSave - Не сохранять состояние
3222
- * @returns данные о разгруппировке или null, если объект не является группой
3223
- * @fires editor:objects-ungrouped
3224
- */
3427
+ * Разгруппировка объектов
3428
+ * @param options
3429
+ * @param options.target - объект Group, массив групп или ActiveSelection с группами для разгруппировки
3430
+ * @param options.withoutSave - Не сохранять состояние
3431
+ * @returns данные о разгруппировке или null, если нет групп для разгруппировки
3432
+ * @fires editor:objects-ungrouped
3433
+ */
3225
3434
  ungroup({
3226
- object: e,
3227
- withoutSave: t
3435
+ target: e,
3436
+ withoutSave: t = !1
3228
3437
  } = {}) {
3229
- const { canvas: s, historyManager: a } = this.editor, n = e || s.getActiveObject();
3230
- if (!(n instanceof te)) return null;
3231
- a.suspendHistory();
3232
- const o = n.removeAll();
3233
- s.remove(n), o.forEach((d) => s.add(d));
3234
- const i = new v(o, {
3235
- canvas: s
3236
- });
3237
- s.setActiveObject(i), s.renderAll(), a.resumeHistory(), t || a.saveState();
3238
- const r = {
3239
- object: n,
3240
- selection: i,
3241
- ungroupedObjects: o,
3242
- withoutSave: t
3243
- };
3244
- return s.fire("editor:objects-ungrouped", r), r;
3438
+ const { canvas: s, historyManager: n } = this.editor, o = this._getGroupsToUngroup(e);
3439
+ if (!o) return null;
3440
+ try {
3441
+ n.suspendHistory();
3442
+ const a = [];
3443
+ o.forEach((c) => {
3444
+ const h = c.removeAll();
3445
+ s.remove(c), h.forEach((l) => {
3446
+ s.add(l), a.push(l);
3447
+ });
3448
+ });
3449
+ const i = new v(a, {
3450
+ canvas: s
3451
+ });
3452
+ s.setActiveObject(i), s.requestRenderAll();
3453
+ const r = {
3454
+ selection: i,
3455
+ ungroupedObjects: a,
3456
+ withoutSave: t
3457
+ };
3458
+ return s.fire("editor:objects-ungrouped", r), r;
3459
+ } finally {
3460
+ n.resumeHistory(), t || n.saveState();
3461
+ }
3245
3462
  }
3246
3463
  }
3247
- class vt {
3464
+ class At {
3248
3465
  constructor({ editor: e }) {
3249
3466
  this.editor = e;
3250
3467
  }
@@ -3255,11 +3472,11 @@ class vt {
3255
3472
  selectAll() {
3256
3473
  const { canvas: e, canvasManager: t, objectLockManager: s } = this.editor;
3257
3474
  e.discardActiveObject();
3258
- const a = t.getObjects(), n = a.some((i) => i.locked), o = a.length > 1 ? new v(t.getObjects(), { canvas: e }) : a[0];
3259
- n && s.lockObject({ object: o, skipInnerObjects: !0, withoutSave: !0 }), e.setActiveObject(o), e.requestRenderAll(), e.fire("editor:all-objects-selected", { selected: o });
3475
+ const n = t.getObjects(), o = n.some((i) => i.locked), a = n.length > 1 ? new v(t.getObjects(), { canvas: e }) : n[0];
3476
+ o && s.lockObject({ object: a, skipInnerObjects: !0, withoutSave: !0 }), e.setActiveObject(a), e.requestRenderAll(), e.fire("editor:all-objects-selected", { selected: a });
3260
3477
  }
3261
3478
  }
3262
- class le {
3479
+ class he {
3263
3480
  constructor({ editor: e }) {
3264
3481
  this.editor = e;
3265
3482
  }
@@ -3277,11 +3494,11 @@ class le {
3277
3494
  * @returns массив всех удаленных объектов (включая саму группу)
3278
3495
  */
3279
3496
  _handleGroupDeletion(e) {
3280
- var a;
3281
- const { groupingManager: t } = this.editor, { ungroupedObjects: s = [] } = (a = t.ungroup({
3497
+ var n;
3498
+ const { groupingManager: t } = this.editor, { ungroupedObjects: s = [] } = (n = t.ungroup({
3282
3499
  object: e,
3283
3500
  withoutSave: !0
3284
- })) != null ? a : {};
3501
+ })) != null ? n : {};
3285
3502
  return this.deleteSelectedObjects({
3286
3503
  objects: s,
3287
3504
  withoutSave: !0,
@@ -3301,27 +3518,27 @@ class le {
3301
3518
  withoutSave: t = !1,
3302
3519
  _isRecursiveCall: s = !1
3303
3520
  } = {}) {
3304
- const { canvas: a, historyManager: n } = this.editor, i = (e || a.getActiveObjects()).filter((h) => !h.locked);
3521
+ const { canvas: n, historyManager: o } = this.editor, i = (e || n.getActiveObjects()).filter((h) => !h.locked);
3305
3522
  if (!(i != null && i.length)) return null;
3306
- s || n.suspendHistory();
3523
+ s || o.suspendHistory();
3307
3524
  const r = [];
3308
3525
  if (i.forEach((h) => {
3309
- if (le._isUngroupableGroup(h)) {
3526
+ if (he._isUngroupableGroup(h)) {
3310
3527
  const l = this._handleGroupDeletion(h);
3311
3528
  r.push(...l);
3312
3529
  return;
3313
3530
  }
3314
- a.remove(h), r.push(h);
3531
+ n.remove(h), r.push(h);
3315
3532
  }), s) return null;
3316
- a.discardActiveObject(), a.renderAll(), n.resumeHistory(), t || n.saveState();
3317
- const d = {
3533
+ n.discardActiveObject(), n.renderAll(), o.resumeHistory(), t || o.saveState();
3534
+ const c = {
3318
3535
  objects: r,
3319
3536
  withoutSave: t
3320
3537
  };
3321
- return a.fire("editor:objects-deleted", d), d;
3538
+ return n.fire("editor:objects-deleted", c), c;
3322
3539
  }
3323
3540
  }
3324
- const At = {
3541
+ const Ct = {
3325
3542
  IMAGE_MANAGER: {
3326
3543
  /**
3327
3544
  * Некорректный Content-Type изображения
@@ -3420,7 +3637,7 @@ const At = {
3420
3637
  INVALID_GRADIENT_FORMAT: "INVALID_GRADIENT_FORMAT"
3421
3638
  }
3422
3639
  };
3423
- class q {
3640
+ class ee {
3424
3641
  constructor({ editor: e }) {
3425
3642
  this._buffer = [], this.editor = e;
3426
3643
  }
@@ -3446,20 +3663,20 @@ class q {
3446
3663
  * @param options.message — текст ошибки (опционально, если не передан, то используется код ошибки)
3447
3664
  * @fires editor:error
3448
3665
  */
3449
- emitError({ origin: e = "ImageEditor", method: t = "Unknown Method", code: s, data: a, message: n }) {
3450
- if (!q.isValidErrorCode(s)) {
3666
+ emitError({ origin: e = "ImageEditor", method: t = "Unknown Method", code: s, data: n, message: o }) {
3667
+ if (!ee.isValidErrorCode(s)) {
3451
3668
  console.warn("Неизвестный код ошибки: ", { code: s, origin: e, method: t });
3452
3669
  return;
3453
3670
  }
3454
3671
  if (!s) return;
3455
- const o = n || s;
3456
- console.error(`${e}. ${t}. ${s}. ${o}`, a);
3672
+ const a = o || s;
3673
+ console.error(`${e}. ${t}. ${s}. ${a}`, n);
3457
3674
  const i = {
3458
3675
  code: s,
3459
3676
  origin: e,
3460
3677
  method: t,
3461
- message: o,
3462
- data: a
3678
+ message: a,
3679
+ data: n
3463
3680
  };
3464
3681
  this._buffer.push(I({
3465
3682
  type: "editor:error"
@@ -3475,19 +3692,19 @@ class q {
3475
3692
  * @param options.message — текст предупреждения (опционально, если не передан, то используется код предупреждения)
3476
3693
  * @fires editor:warning
3477
3694
  */
3478
- emitWarning({ origin: e = "ImageEditor", method: t = "Unknown Method", code: s, message: a, data: n }) {
3479
- if (!q.isValidErrorCode(s)) {
3695
+ emitWarning({ origin: e = "ImageEditor", method: t = "Unknown Method", code: s, message: n, data: o }) {
3696
+ if (!ee.isValidErrorCode(s)) {
3480
3697
  console.warn("Неизвестный код предупреждения: ", { code: s, origin: e, method: t });
3481
3698
  return;
3482
3699
  }
3483
- const o = a || s;
3484
- console.warn(`${e}. ${t}. ${s}. ${o}`, n);
3700
+ const a = n || s;
3701
+ console.warn(`${e}. ${t}. ${s}. ${a}`, o);
3485
3702
  const i = {
3486
3703
  code: s,
3487
3704
  origin: e,
3488
3705
  method: t,
3489
- message: o,
3490
- data: n
3706
+ message: a,
3707
+ data: o
3491
3708
  };
3492
3709
  this._buffer.push(I({
3493
3710
  type: "editor:warning"
@@ -3499,17 +3716,102 @@ class q {
3499
3716
  * @returns true, если код допустим, иначе false
3500
3717
  */
3501
3718
  static isValidErrorCode(e) {
3502
- return e ? Object.values(At).some((t) => Object.values(t).includes(e)) : !1;
3719
+ return e ? Object.values(Ct).some((t) => Object.values(t).includes(e)) : !1;
3503
3720
  }
3504
3721
  }
3505
- class he {
3722
+ class St {
3723
+ constructor({ editor: e }) {
3724
+ this.currentBounds = null, this.editor = e;
3725
+ }
3726
+ /**
3727
+ * Рассчитывает границы перетаскивания на основе текущего зума.
3728
+ * Границы зависят от соотношения currentZoom к defaultZoom.
3729
+ * Если currentZoom <= defaultZoom, перетаскивание блокируется.
3730
+ * Если currentZoom > defaultZoom, границы рассчитываются как ~50% размера монтажной области.
3731
+ *
3732
+ * @returns Объект с границами перетаскивания
3733
+ */
3734
+ calculatePanBounds() {
3735
+ const { canvas: e, montageArea: t, zoomManager: s } = this.editor, { defaultZoom: n } = s, o = e.getZoom();
3736
+ if (o <= n)
3737
+ return {
3738
+ minX: 0,
3739
+ maxX: 0,
3740
+ minY: 0,
3741
+ maxY: 0,
3742
+ canPan: !1
3743
+ };
3744
+ const a = t.width * o, i = t.height * o, r = a / 2, c = i / 2;
3745
+ return {
3746
+ minX: -r,
3747
+ maxX: r,
3748
+ minY: -c,
3749
+ maxY: c,
3750
+ canPan: !0
3751
+ };
3752
+ }
3753
+ /**
3754
+ * Проверяет, разрешено ли перетаскивание при текущем зуме.
3755
+ * @returns true если можно перетаскивать
3756
+ */
3757
+ isPanAllowed() {
3758
+ var e, t;
3759
+ return this.currentBounds || this.updateBounds(), (t = (e = this.currentBounds) == null ? void 0 : e.canPan) != null ? t : !1;
3760
+ }
3761
+ /**
3762
+ * Ограничивает координаты viewportTransform границами.
3763
+ * Координаты vpt[4] и vpt[5] представляют смещение канваса.
3764
+ *
3765
+ * @param vptX - текущее смещение по X из viewportTransform[4]
3766
+ * @param vptY - текущее смещение по Y из viewportTransform[5]
3767
+ * @returns Скорректированные координаты смещения
3768
+ */
3769
+ constrainPan(e, t) {
3770
+ if (!this.currentBounds || !this.currentBounds.canPan)
3771
+ return { x: 0, y: 0 };
3772
+ const { canvas: s, montageArea: n } = this.editor, o = s.getZoom(), a = n.left, i = n.top, r = s.getWidth() / 2, c = s.getHeight() / 2, h = a * o + e - r, l = i * o + t - c, g = Math.max(
3773
+ this.currentBounds.minX,
3774
+ Math.min(this.currentBounds.maxX, h)
3775
+ ), u = Math.max(
3776
+ this.currentBounds.minY,
3777
+ Math.min(this.currentBounds.maxY, l)
3778
+ ), f = g + r - a * o, M = u + c - i * o;
3779
+ return {
3780
+ x: f,
3781
+ y: M
3782
+ };
3783
+ }
3784
+ /**
3785
+ * Получить текущие границы перетаскивания (геттер для внешнего использования).
3786
+ * @returns Текущие границы или null если они ещё не рассчитаны
3787
+ */
3788
+ getPanBounds() {
3789
+ return this.currentBounds;
3790
+ }
3791
+ /**
3792
+ * Получить текущее смещение монтажной области относительно центра канваса.
3793
+ * @returns Объект с координатами смещения
3794
+ */
3795
+ getCurrentOffset() {
3796
+ const { canvas: e, montageArea: t } = this.editor, s = e.getZoom(), n = e.viewportTransform, o = t.left, a = t.top, i = e.getWidth() / 2, r = e.getHeight() / 2, c = o * s + n[4] - i, h = a * s + n[5] - r;
3797
+ return { x: c, y: h };
3798
+ }
3799
+ /**
3800
+ * Обновить границы перетаскивания.
3801
+ * Вызывается при изменении зума или размеров монтажной области.
3802
+ */
3803
+ updateBounds() {
3804
+ this.currentBounds = this.calculatePanBounds();
3805
+ }
3806
+ }
3807
+ class ge {
3506
3808
  /**
3507
3809
  * Конструктор класса ImageEditor.
3508
3810
  * @param canvasId - идентификатор канваса, в котором будет создан редактор
3509
3811
  * @param options - опции и настройки редактора
3510
3812
  */
3511
3813
  constructor(e, t) {
3512
- this.options = t, this.containerId = e, this.editorId = `${e}-${A()}`, this.clipboard = null, this.init();
3814
+ this.options = t, this.containerId = e, this.editorId = `${e}-${C()}`, this.clipboard = null, this.init();
3513
3815
  }
3514
3816
  /**
3515
3817
  * Инициализация редактора.
@@ -3517,27 +3819,27 @@ class he {
3517
3819
  * @fires editor:ready
3518
3820
  */
3519
3821
  init() {
3520
- return j(this, null, function* () {
3822
+ return y(this, null, function* () {
3521
3823
  const {
3522
3824
  editorContainerWidth: e,
3523
3825
  editorContainerHeight: t,
3524
3826
  canvasWrapperWidth: s,
3525
- canvasWrapperHeight: a,
3526
- canvasCSSWidth: n,
3527
- canvasCSSHeight: o,
3827
+ canvasWrapperHeight: n,
3828
+ canvasCSSWidth: o,
3829
+ canvasCSSHeight: a,
3528
3830
  initialImage: i,
3529
3831
  initialStateJSON: r,
3530
- scaleType: d,
3832
+ scaleType: c,
3531
3833
  showRotationAngle: h,
3532
3834
  _onReadyCallback: l
3533
3835
  } = this.options;
3534
- if (Je.apply(), this.canvas = new Re(this.containerId, this.options), this.moduleLoader = new Ye(), this.workerManager = new We(), this.errorManager = new q({ editor: this }), this.historyManager = new $({ editor: this }), this.toolbar = new rt({ editor: this }), this.transformManager = new bt({ editor: this }), this.canvasManager = new mt({ editor: this }), this.imageManager = new N({ editor: this }), this.layerManager = new K({ editor: this }), this.shapeManager = new pt({ editor: this }), this.interactionBlocker = new jt({ editor: this }), this.backgroundManager = new R({ editor: this }), this.clipboardManager = new yt({ editor: this }), this.objectLockManager = new J({ editor: this }), this.groupingManager = new It({ editor: this }), this.selectionManager = new vt({ editor: this }), this.deletionManager = new le({ editor: this }), h && (this.angleIndicator = new de({ editor: this })), this._createMontageArea(), this._createClippingArea(), this.listeners = new P({ editor: this, options: this.options }), this.canvasManager.setEditorContainerWidth(e), this.canvasManager.setEditorContainerHeight(t), this.canvasManager.setCanvasWrapperWidth(s), this.canvasManager.setCanvasWrapperHeight(a), this.canvasManager.setCanvasCSSWidth(n), this.canvasManager.setCanvasCSSHeight(o), this.canvasManager.updateCanvas(), this.transformManager.calculateAndApplyDefaultZoom(), i != null && i.source) {
3836
+ if (qe.apply(), this.canvas = new Ue(this.containerId, this.options), this.moduleLoader = new Pe(), this.workerManager = new Fe(), this.errorManager = new ee({ editor: this }), this.historyManager = new K({ editor: this }), this.toolbar = new ct({ editor: this }), this.transformManager = new pt({ editor: this }), this.zoomManager = new bt({ editor: this }), this.canvasManager = new Mt({ editor: this }), this.imageManager = new _({ editor: this }), this.layerManager = new J({ editor: this }), this.shapeManager = new yt({ editor: this }), this.interactionBlocker = new jt({ editor: this }), this.backgroundManager = new Y({ editor: this }), this.clipboardManager = new vt({ editor: this }), this.objectLockManager = new q({ editor: this }), this.groupingManager = new It({ editor: this }), this.selectionManager = new At({ editor: this }), this.deletionManager = new he({ editor: this }), this.panConstraintManager = new St({ editor: this }), h && (this.angleIndicator = new le({ editor: this })), this._createMontageArea(), this._createClippingArea(), this.listeners = new W({ editor: this, options: this.options }), this.canvasManager.setEditorContainerWidth(e), this.canvasManager.setEditorContainerHeight(t), this.canvasManager.setCanvasWrapperWidth(s), this.canvasManager.setCanvasWrapperHeight(n), this.canvasManager.setCanvasCSSWidth(o), this.canvasManager.setCanvasCSSHeight(a), this.canvasManager.updateCanvas(), this.zoomManager.calculateAndApplyDefaultZoom(), i != null && i.source) {
3535
3837
  const {
3536
- source: u,
3537
- scale: g = `image-${d}`,
3538
- withoutSave: M = !0
3838
+ source: g,
3839
+ scale: u = `image-${c}`,
3840
+ withoutSave: f = !0
3539
3841
  } = i;
3540
- yield this.imageManager.importImage({ source: u, scale: g, withoutSave: M });
3842
+ yield this.imageManager.importImage({ source: g, scale: u, withoutSave: f });
3541
3843
  }
3542
3844
  r && this.historyManager.loadStateFromFullState(r), this.historyManager.saveState(), console.log("editor:ready"), this.canvas.fire("editor:ready", this), typeof l == "function" && l(this);
3543
3845
  });
@@ -3553,7 +3855,7 @@ class he {
3553
3855
  this.montageArea = this.shapeManager.addRectangle({
3554
3856
  width: e,
3555
3857
  height: t,
3556
- fill: he._createMosaicPattern(),
3858
+ fill: ge._createMosaicPattern(),
3557
3859
  stroke: null,
3558
3860
  strokeWidth: 0,
3559
3861
  selectable: !1,
@@ -3604,13 +3906,13 @@ class he {
3604
3906
  const e = document.createElement("canvas");
3605
3907
  e.width = 20, e.height = 20;
3606
3908
  const t = e.getContext("2d");
3607
- return t.fillStyle = "#ddd", t.fillRect(0, 0, 40, 40), t.fillStyle = "#ccc", t.fillRect(0, 0, 10, 10), t.fillRect(10, 10, 10, 10), new Ue({
3909
+ return t.fillStyle = "#ddd", t.fillRect(0, 0, 40, 40), t.fillStyle = "#ccc", t.fillRect(0, 0, 10, 10), t.fillRect(10, 10, 10, 10), new Ye({
3608
3910
  source: e,
3609
3911
  repeat: "repeat"
3610
3912
  });
3611
3913
  }
3612
3914
  }
3613
- const Ct = {
3915
+ const Dt = {
3614
3916
  /**
3615
3917
  * Опции редактора
3616
3918
  */
@@ -3700,18 +4002,18 @@ const Ct = {
3700
4002
  resetObjectFitByDoubleClick: !0,
3701
4003
  keyboardIgnoreSelectors: []
3702
4004
  };
3703
- function wt(c, e = {}) {
3704
- const t = I(I({}, Ct), e), s = document.getElementById(c);
4005
+ function kt(d, e = {}) {
4006
+ const t = I(I({}, Dt), e), s = document.getElementById(d);
3705
4007
  if (!s)
3706
- return Promise.reject(new Error(`Контейнер с ID "${c}" не найден.`));
3707
- const a = document.createElement("canvas");
3708
- return a.id = `${c}-canvas`, s.appendChild(a), t.editorContainer = s, new Promise((n) => {
3709
- t._onReadyCallback = n;
3710
- const o = new he(a.id, t);
3711
- window[c] = o;
4008
+ return Promise.reject(new Error(`Контейнер с ID "${d}" не найден.`));
4009
+ const n = document.createElement("canvas");
4010
+ return n.id = `${d}-canvas`, s.appendChild(n), t.editorContainer = s, new Promise((o) => {
4011
+ t._onReadyCallback = o;
4012
+ const a = new ge(n.id, t);
4013
+ window[d] = a;
3712
4014
  });
3713
4015
  }
3714
4016
  export {
3715
- wt as default
4017
+ kt as default
3716
4018
  };
3717
4019
  //# sourceMappingURL=main.js.map