vkedit 3.2.5 → 3.2.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.en.md CHANGED
@@ -3,14 +3,15 @@
3
3
  [![NPM Version](https://img.shields.io/npm/v/vkedit?style=flat-square)](https://www.npmjs.com/package/vkedit)
4
4
  [![License](https://img.shields.io/npm/l/vkedit?style=flat-square)](LICENSE)
5
5
  [![Node.js](https://img.shields.io/node/v/vkedit?style=flat-square)](package.json)
6
+ [![Live Demo](https://img.shields.io/badge/Live%20Demo-vkedit.org-orange?style=flat-square)](https://vkedit.org)
6
7
 
7
8
  A visual canvas designer component built on Vue 3 and Konva.js. Features a plugin-based architecture for label, QR code, barcode, receipt, business card, and certificate template design and print layout.
8
9
 
9
- **[中文](README.md)**
10
+ **[中文](README.md)** | **[Live Demo](https://vkedit.org)** | **[Docs](https://docs.vkedit.org)**
10
11
 
11
12
  ---
12
13
 
13
- ![Project Preview](./截图/image.png)
14
+ ![Project Preview](https://raw.githubusercontent.com/pwg-code/vkedit/main/截图/image.png)
14
15
 
15
16
  ---
16
17
 
@@ -103,243 +104,14 @@ host.setStatus({
103
104
  </script>
104
105
  ```
105
106
 
106
- ### Vkedit Component Props
107
-
108
- | Prop | Type | Default | Description |
109
- | ------------------- | ------------ | ------- | ------------------------ |
110
- | `host` | `EditorHost` | - | Editor host instance |
111
- | `showToolbox` | `boolean` | `true` | Show left toolbox |
112
- | `showPropertyPanel` | `boolean` | `true` | Show right property panel|
113
- | `showToolbar` | `boolean` | `true` | Show top toolbar |
114
-
115
- ---
116
-
117
- ## Configuration
118
-
119
- ### createEditorHost Options
120
-
121
- `createEditorHost(options)` creates a host instance and automatically installs core plugins. Optional plugins are controlled by the following options:
122
-
123
- | Option | Type | Default | Description |
124
- | ------------------------ | --------- | ------- | -------------------------- |
125
- | `basePropertyPanel` | `boolean` | `false` | Base element property panel|
126
- | `baseCanvasPropertyPanel`| `boolean` | `true` | Canvas property panel |
127
- | `exportPlugin` | `boolean` | `true` | Export plugin |
128
- | `previewPlugin` | `boolean` | `true` | Preview plugin |
129
- | `importPlugin` | `boolean` | `true` | Import plugin |
130
-
131
- ### Canvas State
132
-
133
- Update canvas state via `host.setStatus()`, which supports partial updates:
134
-
135
- ```typescript
136
- interface IEditorState {
137
- zoom: number // Zoom level
138
- currentTool: string // Current tool
139
- snapToGrid: boolean // Snap to grid
140
- showGrid: boolean // Show grid
141
- width: number // Canvas width (pixels)
142
- height: number // Canvas height (pixels)
143
- wmm: number // Canvas width (millimeters)
144
- hmm: number // Canvas height (millimeters)
145
- dpm: number // Dots per millimeter (DPI / 25.4)
146
- }
147
- ```
148
-
149
- `width`/`height` and `wmm`/`hmm` are automatically converted via `dpm`. Setting `dpm` recalculates pixel dimensions from the current millimeter sizes.
150
-
151
- ---
152
-
153
- ## Plugin List
154
-
155
- ### Core Plugins (auto-installed by createEditorHost)
156
-
157
- | Plugin | Description |
158
- | --- | --- |
159
- | `ToolbarManagerPlugin` | Top toolbar management |
160
- | `GraphicToolManagerPlugin` | Graphic tool management |
161
- | `GraphicManagerPlugin` | Graphic rendering management |
162
- | `PropertyPanelManagerPlugin` | Dynamic property panel rendering |
163
- | `ElementManagerPlugin` | Element lifecycle management |
164
- | `SelectionPlugin` | Element selection and multi-select |
165
- | `KeyDownPlugin` | Keyboard shortcuts |
166
- | `SnapPlugin` | Grid snapping |
167
- | `ClipboardPlugin` | Copy / cut / paste |
168
- | `AlignPlugin` | Alignment and distribution |
169
- | `ContextMenuManagerPlugin` | Context menu |
170
-
171
- ### Feature Plugins (enabled via options)
172
-
173
- | Plugin | Option | Description |
174
- | --- | --- | --- |
175
- | `ExportPlugin` | `exportPlugin` | Export JSON / PNG / JPG / PDF |
176
- | `ImportPlugin` | `importPlugin` | Import JSON files |
177
- | `PreviewPlugin` | `previewPlugin` | Preview and print preview |
178
-
179
- ### Graphic Plugins (manually installed)
180
-
181
- | Plugin | Element Type | Description |
182
- | --- | --- | --- |
183
- | `RectPlugin` | `rect` | Rectangle with fill and stroke |
184
- | `TextPlugin` | `text` | Text with font, alignment, and style |
185
- | `LinePlugin` | `line` | Line with color and width |
186
- | `TablePlugin` | `table` | Table with rows, merged cells, and borders |
187
- | `QrcodePlugin` | `qr` | QR code with foreground/background colors |
188
- | `BarcodePlugin` | `barcode` | Barcode supporting CODE128, EAN-13, etc. |
189
- | `ChartPlugin` | `chart` | Chart powered by ECharts |
190
-
191
- ---
192
-
193
- ## Core Concepts
194
-
195
- ### EditorHost
196
-
197
- `EditorHost` is the core host class of the editor, managing plugins, state, commands, and history. After creating an instance via `createEditorHost()`, all operations revolve around the `host`.
198
-
199
- ### Plugin System
200
-
201
- Plugins are managed via `installPlugin` / `uninstallPlugin` / `getPlugin`. Plugins must extend `BasePlugin` and implement the `onInstall()` hook. `getPlugin` supports generic type inference:
202
-
203
- ```typescript
204
- const rectPlugin = host.getPlugin('rect-plugin') // inferred as RectPlugin
205
- const exportPlugin = host.getPlugin('export-plugin')
206
- ```
207
-
208
- ### Command Pattern
209
-
210
- All reversible operations are implemented as commands. `executeCommand()` executes a command and pushes it onto the history stack, while `undo()` / `redo()` navigate the stack:
211
-
212
- ```typescript
213
- host.executeCommand(command) // execute and push
214
- host.undo() // undo
215
- host.redo() // redo
216
- ```
217
-
218
- ### Event System
219
-
220
- The editor provides type-safe event communication via `emit` / `on` / `off`:
221
-
222
- ```typescript
223
- // Listen for element added
224
- host.on('element:added', (payload) => {
225
- console.log('Element added:', payload.element)
226
- })
227
-
228
- // Listen for selection changed
229
- host.on('selection:changed', (payload) => {
230
- console.log('Selected:', payload.selection)
231
- })
232
- ```
233
-
234
- For the full event list and custom event extension, refer to the API documentation.
235
-
236
- ---
237
-
238
- ## Common Operations
239
-
240
- ### Export / Import JSON
241
-
242
- ```typescript
243
- // Export to JSON string
244
- const json = host.toJSON()
245
-
246
- // Load from JSON string
247
- host.loadJSON(json)
248
- ```
249
-
250
- Use ExportPlugin / ImportPlugin to trigger file download and file picker:
251
-
252
- ```typescript
253
- const exportPlugin = host.getPlugin('export-plugin')
254
- exportPlugin.handleExportJSON() // download .json file
255
- exportPlugin.handleExportImage() // download PNG image
256
- exportPlugin.handleExportPdf() // download PDF document
257
-
258
- const importPlugin = host.getPlugin('import-plugin')
259
- importPlugin.handleImportJSON() // open file picker
260
- ```
261
-
262
- ### Undo / Redo
263
-
264
- ```typescript
265
- host.undo()
266
- host.redo()
267
- ```
268
-
269
- ### Listen to Events
270
-
271
- ```typescript
272
- host.on('selection:changed', (payload) => {
273
- console.log('Selected element IDs:', payload.selection)
274
- })
275
- ```
276
-
277
- ### Add Element (via command)
278
-
279
- ```typescript
280
- import { AddElementCommand } from 'vkedit'
281
-
282
- const elementManager = host.getPlugin('element-manager-plugin')
283
- const element = elementManager.createElement('rect')
284
- host.executeCommand(new AddElementCommand(host, element))
285
- ```
286
-
287
- ### Update Element Property (via command)
288
-
289
- ```typescript
290
- import { UpdatePropertyCommand } from 'vkedit'
291
-
292
- host.executeCommand(
293
- new UpdatePropertyCommand(host, element, 'fill', 'red', 'blue')
294
- )
295
- ```
296
-
297
- ### Batch Operations
298
-
299
- ```typescript
300
- import { BatchCommand, UpdatePropertyCommand } from 'vkedit'
301
-
302
- const batch = new BatchCommand(host, [
303
- new UpdatePropertyCommand(host, el1, 'fill', 'red', 'blue'),
304
- new UpdatePropertyCommand(host, el2, 'fill', 'red', 'green'),
305
- ])
306
- host.executeCommand(batch)
307
- ```
308
-
309
- ---
310
-
311
- ## Use Cases
312
-
313
- | Scenario | Applicable Plugins |
314
- | --- | --- |
315
- | Label template design | QR code, barcode, text, rectangle, table |
316
- | QR code design | QR code, text, rectangle |
317
- | Barcode design | Barcode, text, line |
318
- | Receipt design | Table, text, rectangle, line |
319
- | Business card design | Text, rectangle, line |
320
- | Certificate design | Text, rectangle, table |
321
- | Data visualization | Chart, text, rectangle |
322
-
323
- ---
324
-
325
- ## Available Commands
326
-
327
- | Command | Constructor Params | Description |
328
- | --- | --- | --- |
329
- | `AddElementCommand` | `(host, element)` | Add element |
330
- | `RemoveElementCommand` | `(host, element)` | Remove element |
331
- | `TransformElementCommand` | `(host, element, oldState, newState)` | Transform element (position/size/rotation) |
332
- | `UpdatePropertyCommand` | `(host, element, propertyPath, oldValue, newValue)` | Update property |
333
- | `BatchCommand` | `(host, commands, description?)` | Batch command |
334
- | `AlignElementsCommand` | `(host, alignment, elementIds)` | Align elements |
335
- | `DistributeElementsCommand` | `(host, direction, elementIds)` | Distribute elements |
336
- | `ChangeLayerOrderCommand` | `(host, elementId, direction)` | Change layer order |
337
- | `ClearSelectionCommand` | `(host)` | Clear selection |
107
+ > For full tutorials, API docs, and online examples, visit [docs.vkedit.org](https://docs.vkedit.org).
338
108
 
339
109
  ---
340
110
 
341
111
  ## Links
342
112
 
113
+ - [Website](https://vkedit.org)
114
+ - [Docs](https://docs.vkedit.org)
343
115
  - [npm](https://www.npmjs.com/package/vkedit)
344
116
  - [GitHub Releases](https://github.com/pwg-code/vkedit/releases)
345
117
  - [Vue.js](https://vuejs.org/)
@@ -372,11 +144,11 @@ If vkedit helps you, consider buying the author a coffee.
372
144
  <table>
373
145
  <tr>
374
146
  <td align="center">
375
- <img src="./截图/reward-alipay.png" width="200" alt="Alipay" />
147
+ <img src="https://raw.githubusercontent.com/pwg-code/vkedit/main/截图/reward-alipay.png" width="200" alt="Alipay" />
376
148
  <br>Alipay
377
149
  </td>
378
150
  <td align="center">
379
- <img src="./截图/reward-wechat.png" width="200" alt="WeChat Pay" />
151
+ <img src="https://raw.githubusercontent.com/pwg-code/vkedit/main/截图/reward-wechat.png" width="200" alt="WeChat Pay" />
380
152
  <br>WeChat
381
153
  </td>
382
154
  </tr>
package/README.md CHANGED
@@ -3,27 +3,28 @@
3
3
  [![NPM Version](https://img.shields.io/npm/v/vkedit?style=flat-square)](https://www.npmjs.com/package/vkedit)
4
4
  [![License](https://img.shields.io/npm/l/vkedit?style=flat-square)](LICENSE)
5
5
  [![Node.js](https://img.shields.io/node/v/vkedit?style=flat-square)](package.json)
6
+ [![在线示例](https://img.shields.io/badge/在线示例-vkedit.org-orange?style=flat-square)](https://vkedit.org)
6
7
 
7
8
  基于 Vue 3 与 Konva.js 的可视化画布设计器组件,采用插件化架构,适用于标签、二维码、条码、票据、名片、证书等模板设计与打印排版场景。
8
9
 
9
- **[English](README.en.md)**
10
+ **[English](README.en.md)** | **[在线示例](https://vkedit.org)** | **[文档](https://docs.vkedit.org)**
10
11
 
11
12
  ---
12
13
 
13
- ![项目预览](./截图/image.png)
14
+ ![项目预览](https://raw.githubusercontent.com/pwg-code/vkedit/main/截图/image.png)
14
15
 
15
16
  ---
16
17
 
17
18
  ## 特性
18
19
 
19
- - **插件化架构** 核心功能与图形元素均以插件形式注册,按需启用
20
- - **7 种图形元素** 矩形、文本、线条、表格、二维码、条形码、图表(ECharts)
21
- - **撤销/重做** 基于命令模式,所有修改操作可逆
22
- - **导入/导出** JSON 序列化、PNG/JPG 图片、PDF 文档
23
- - **对齐与分布** 左/右/上/下/居中对齐、水平/垂直均分
24
- - **标尺与缩放** 毫米级精度标尺、可配置 DPM(每毫米点数)
25
- - **事件驱动** 类型安全的事件系统,插件间松耦合通信
26
- - **TypeScript** 完整类型定义,泛型推断插件与元素类型
20
+ - **插件化架构** - 核心功能与图形元素均以插件形式注册,按需启用
21
+ - **7 种图形元素** - 矩形、文本、线条、表格、二维码、条形码、图表(ECharts)
22
+ - **撤销/重做** - 基于命令模式,所有修改操作可逆
23
+ - **导入/导出** - JSON 序列化、PNG/JPG 图片、PDF 文档
24
+ - **对齐与分布** - 左/右/上/下/居中对齐、水平/垂直均分
25
+ - **标尺与缩放** - 毫米级精度标尺、可配置 DPM(每毫米点数)
26
+ - **事件驱动** - 类型安全的事件系统,插件间松耦合通信
27
+ - **TypeScript** - 完整类型定义,泛型推断插件与元素类型
27
28
 
28
29
  ---
29
30
 
@@ -103,243 +104,14 @@ host.setStatus({
103
104
  </script>
104
105
  ```
105
106
 
106
- ### Vkedit 组件 Props
107
-
108
- | Prop | 类型 | 默认值 | 说明 |
109
- | ------------------- | ------------ | ------ | ---------------- |
110
- | `host` | `EditorHost` | — | 编辑器宿主实例 |
111
- | `showToolbox` | `boolean` | `true` | 显示左侧工具箱 |
112
- | `showPropertyPanel` | `boolean` | `true` | 显示右侧属性面板 |
113
- | `showToolbar` | `boolean` | `true` | 显示顶部工具栏 |
114
-
115
- ---
116
-
117
- ## 配置
118
-
119
- ### createEditorHost 选项
120
-
121
- `createEditorHost(options)` 创建宿主实例并自动安装核心插件。可选插件通过以下选项控制:
122
-
123
- | 选项 | 类型 | 默认值 | 说明 |
124
- | ------------------------- | --------- | ------- | ---------------- |
125
- | `basePropertyPanel` | `boolean` | `false` | 基础元素属性面板 |
126
- | `baseCanvasPropertyPanel` | `boolean` | `true` | 画布属性面板 |
127
- | `exportPlugin` | `boolean` | `true` | 导出插件 |
128
- | `previewPlugin` | `boolean` | `true` | 预览插件 |
129
- | `importPlugin` | `boolean` | `true` | 导入插件 |
130
-
131
- ### 画布状态
132
-
133
- 通过 `host.setStatus()` 更新画布状态,支持部分更新:
134
-
135
- ```typescript
136
- interface IEditorState {
137
- zoom: number // 缩放级别
138
- currentTool: string // 当前工具
139
- snapToGrid: boolean // 网格吸附
140
- showGrid: boolean // 网格显示
141
- width: number // 画布宽度(像素)
142
- height: number // 画布高度(像素)
143
- wmm: number // 画布宽度(毫米)
144
- hmm: number // 画布高度(毫米)
145
- dpm: number // 每毫米点数(DPI / 25.4)
146
- }
147
- ```
148
-
149
- `width`/`height` 与 `wmm`/`hmm` 通过 `dpm` 自动换算。设置 `dpm` 会以当前毫米尺寸重新计算像素宽高。
150
-
151
- ---
152
-
153
- ## 插件列表
154
-
155
- ### 核心插件(createEditorHost 自动安装)
156
-
157
- | 插件 | 说明 |
158
- | ---------------------------- | ---------------- |
159
- | `ToolbarManagerPlugin` | 顶部工具栏管理 |
160
- | `GraphicToolManagerPlugin` | 图形工具管理 |
161
- | `GraphicManagerPlugin` | 图形渲染管理 |
162
- | `PropertyPanelManagerPlugin` | 属性面板动态渲染 |
163
- | `ElementManagerPlugin` | 元素生命周期管理 |
164
- | `SelectionPlugin` | 元素选择与多选 |
165
- | `KeyDownPlugin` | 键盘快捷键 |
166
- | `SnapPlugin` | 网格吸附 |
167
- | `ClipboardPlugin` | 复制/剪切/粘贴 |
168
- | `AlignPlugin` | 对齐与分布 |
169
- | `ContextMenuManagerPlugin` | 右键菜单 |
170
-
171
- ### 功能插件(通过选项启用)
172
-
173
- | 插件 | 选项 | 说明 |
174
- | --------------- | --------------- | --------------------------- |
175
- | `ExportPlugin` | `exportPlugin` | 导出 JSON / PNG / JPG / PDF |
176
- | `ImportPlugin` | `importPlugin` | 导入 JSON 文件 |
177
- | `PreviewPlugin` | `previewPlugin` | 预览与打印预览 |
178
-
179
- ### 图形插件(手动安装)
180
-
181
- | 插件 | 元素类型 | 说明 |
182
- | --------------- | --------- | ----------------------------------- |
183
- | `RectPlugin` | `rect` | 矩形,支持填充、描边 |
184
- | `TextPlugin` | `text` | 文本,支持字体、对齐、样式 |
185
- | `LinePlugin` | `line` | 线条,支持颜色、宽度 |
186
- | `TablePlugin` | `table` | 表格,支持行列、合并单元格、边框 |
187
- | `QrcodePlugin` | `qr` | 二维码,支持前景/背景色 |
188
- | `BarcodePlugin` | `barcode` | 条形码,支持 CODE128、EAN-13 等格式 |
189
- | `ChartPlugin` | `chart` | 图表,基于 ECharts |
190
-
191
- ---
192
-
193
- ## 核心概念
194
-
195
- ### EditorHost
196
-
197
- `EditorHost` 是编辑器的核心宿主类,管理插件、状态、命令和历史记录。通过 `createEditorHost()` 创建实例后,所有操作都围绕 `host` 进行。
198
-
199
- ### 插件系统
200
-
201
- 插件通过 `installPlugin` / `uninstallPlugin` / `getPlugin` 管理。插件需继承 `BasePlugin` 并实现 `onInstall()` 钩子。`getPlugin` 支持泛型推断:
202
-
203
- ```typescript
204
- const rectPlugin = host.getPlugin('rect-plugin') // 自动推断为 RectPlugin
205
- const exportPlugin = host.getPlugin('export-plugin')
206
- ```
207
-
208
- ### 命令模式
209
-
210
- 所有可撤销的操作通过命令实现。`executeCommand()` 执行命令并压入历史栈,`undo()` / `redo()` 在栈中导航:
211
-
212
- ```typescript
213
- host.executeCommand(command) // 执行并入栈
214
- host.undo() // 撤销
215
- host.redo() // 重做
216
- ```
217
-
218
- ### 事件系统
219
-
220
- 编辑器通过 `emit` / `on` / `off` 实现类型安全的事件通信:
221
-
222
- ```typescript
223
- // 监听元素添加
224
- host.on('element:added', (payload) => {
225
- console.log('元素已添加:', payload.element)
226
- })
227
-
228
- // 监听选择变化
229
- host.on('selection:changed', (payload) => {
230
- console.log('选中元素:', payload.selection)
231
- })
232
- ```
233
-
234
- 完整事件列表及自定义事件扩展请参阅 API 文档。
235
-
236
- ---
237
-
238
- ## 常用操作
239
-
240
- ### 导出 / 导入 JSON
241
-
242
- ```typescript
243
- // 导出为 JSON 字符串
244
- const json = host.toJSON()
245
-
246
- // 从 JSON 字符串加载
247
- host.loadJSON(json)
248
- ```
249
-
250
- 通过 ExportPlugin / ImportPlugin 可触发文件下载和文件选择:
251
-
252
- ```typescript
253
- const exportPlugin = host.getPlugin('export-plugin')
254
- exportPlugin.handleExportJSON() // 下载 .json 文件
255
- exportPlugin.handleExportImage() // 下载 PNG 图片
256
- exportPlugin.handleExportPdf() // 下载 PDF 文档
257
-
258
- const importPlugin = host.getPlugin('import-plugin')
259
- importPlugin.handleImportJSON() // 弹出文件选择器
260
- ```
261
-
262
- ### 撤销 / 重做
263
-
264
- ```typescript
265
- host.undo()
266
- host.redo()
267
- ```
268
-
269
- ### 监听事件
270
-
271
- ```typescript
272
- host.on('selection:changed', (payload) => {
273
- console.log('选中元素 ID:', payload.selection)
274
- })
275
- ```
276
-
277
- ### 添加元素(通过命令)
278
-
279
- ```typescript
280
- import { AddElementCommand } from 'vkedit'
281
-
282
- const elementManager = host.getPlugin('element-manager-plugin')
283
- const element = elementManager.createElement('rect')
284
- host.executeCommand(new AddElementCommand(host, element))
285
- ```
286
-
287
- ### 更新元素属性(通过命令)
288
-
289
- ```typescript
290
- import { UpdatePropertyCommand } from 'vkedit'
291
-
292
- host.executeCommand(
293
- new UpdatePropertyCommand(host, element, 'fill', 'red', 'blue')
294
- )
295
- ```
296
-
297
- ### 批量操作
298
-
299
- ```typescript
300
- import { BatchCommand, UpdatePropertyCommand } from 'vkedit'
301
-
302
- const batch = new BatchCommand(host, [
303
- new UpdatePropertyCommand(host, el1, 'fill', 'red', 'blue'),
304
- new UpdatePropertyCommand(host, el2, 'fill', 'red', 'green'),
305
- ])
306
- host.executeCommand(batch)
307
- ```
308
-
309
- ---
310
-
311
- ## 适用场景
312
-
313
- | 场景 | 适用插件 |
314
- | ------------ | -------------------------------- |
315
- | 标签模板设计 | 二维码、条形码、文本、矩形、表格 |
316
- | 二维码设计 | 二维码、文本、矩形 |
317
- | 条码设计 | 条形码、文本、线条 |
318
- | 票据设计 | 表格、文本、矩形、线条 |
319
- | 名片设计 | 文本、矩形、线条 |
320
- | 证书设计 | 文本、矩形、表格 |
321
- | 数据可视化 | 图表、文本、矩形 |
322
-
323
- ---
324
-
325
- ## 可用命令
326
-
327
- | 命令 | 构造参数 | 说明 |
328
- | --------------------------- | --------------------------------------------------- | -------------------------- |
329
- | `AddElementCommand` | `(host, element)` | 添加元素 |
330
- | `RemoveElementCommand` | `(host, element)` | 移除元素 |
331
- | `TransformElementCommand` | `(host, element, oldState, newState)` | 变换元素(位置/大小/旋转) |
332
- | `UpdatePropertyCommand` | `(host, element, propertyPath, oldValue, newValue)` | 更新属性 |
333
- | `BatchCommand` | `(host, commands, description?)` | 批量命令 |
334
- | `AlignElementsCommand` | `(host, alignment, elementIds)` | 对齐元素 |
335
- | `DistributeElementsCommand` | `(host, direction, elementIds)` | 分布元素 |
336
- | `ChangeLayerOrderCommand` | `(host, elementId, direction)` | 调整图层顺序 |
337
- | `ClearSelectionCommand` | `(host)` | 清空选择 |
107
+ > 完整教程、API 文档与在线示例请访问 [docs.vkedit.org](https://docs.vkedit.org)。
338
108
 
339
109
  ---
340
110
 
341
111
  ## 链接
342
112
 
113
+ - [官网](https://vkedit.org)
114
+ - [文档](https://docs.vkedit.org)
343
115
  - [npm](https://www.npmjs.com/package/vkedit)
344
116
  - [GitHub Releases](https://github.com/pwg-code/vkedit/releases)
345
117
  - [Vue.js](https://vuejs.org/)
@@ -370,11 +142,11 @@ host.executeCommand(batch)
370
142
  <table>
371
143
  <tr>
372
144
  <td align="center">
373
- <img src="./截图/reward-alipay.png" width="200" alt="支付宝打赏" />
145
+ <img src="https://raw.githubusercontent.com/pwg-code/vkedit/main/截图/reward-alipay.png" width="200" alt="支付宝打赏" />
374
146
  <br>支付宝
375
147
  </td>
376
148
  <td align="center">
377
- <img src="./截图/reward-wechat.png" width="200" alt="微信打赏" />
149
+ <img src="https://raw.githubusercontent.com/pwg-code/vkedit/main/截图/reward-wechat.png" width="200" alt="微信打赏" />
378
150
  <br>微信
379
151
  </td>
380
152
  </tr>
@@ -4996,10 +4996,22 @@ function RK(r) {
4996
4996
  });
4997
4997
  }
4998
4998
  function I(P) {
4999
- r.emit("stage:mouseenter", { ...P, source: "use-stage-event", timestamp: Date.now() });
4999
+ r.emit("stage:mouseenter", {
5000
+ ...P,
5001
+ evt: P,
5002
+ point: { x: i.value, y: a.value },
5003
+ source: "use-stage-event",
5004
+ timestamp: Date.now()
5005
+ });
5000
5006
  }
5001
5007
  function D(P) {
5002
- r.emit("stage:mouseleave", { ...P, source: "use-stage-event", timestamp: Date.now() });
5008
+ r.emit("stage:mouseleave", {
5009
+ ...P,
5010
+ evt: P,
5011
+ point: { x: i.value, y: a.value },
5012
+ source: "use-stage-event",
5013
+ timestamp: Date.now()
5014
+ });
5003
5015
  }
5004
5016
  function N(P) {
5005
5017
  P.evt.preventDefault(), r.emit("stage:contextmenu", { ...P, source: "use-stage-event", timestamp: Date.now() });
@@ -66378,7 +66390,7 @@ endobj\r
66378
66390
  var u = l.getContext("2d");
66379
66391
  u.fillStyle = "#fff", u.fillRect(0, 0, l.width, l.height);
66380
66392
  var f = { ignoreMouse: !0, ignoreAnimation: !0, ignoreDimensions: !0 }, c = this;
66381
- return (vr.canvg ? Promise.resolve(vr.canvg) : import("./index.es-CEBX1sXY.js")).catch(function(h) {
66393
+ return (vr.canvg ? Promise.resolve(vr.canvg) : import("./index.es-B1gCGYT7.js")).catch(function(h) {
66382
66394
  return Promise.reject(new Error("Could not load canvg: " + h));
66383
66395
  }).then(function(h) {
66384
66396
  return h.default ? h.default : h;
@@ -67482,14 +67494,17 @@ class Iw extends Ai {
67482
67494
  return;
67483
67495
  }
67484
67496
  if (e.ctrlKey && e.code === "KeyZ") {
67497
+ if (!this.isCanvasFocused()) return;
67485
67498
  e.preventDefault(), this.host.undo();
67486
67499
  return;
67487
67500
  }
67488
67501
  if (e.ctrlKey && e.code === "KeyY") {
67502
+ if (!this.isCanvasFocused()) return;
67489
67503
  e.preventDefault(), this.host.redo();
67490
67504
  return;
67491
67505
  }
67492
67506
  if (e.code === "Delete") {
67507
+ if (!this.isCanvasFocused()) return;
67493
67508
  this.deleteSelectionElement();
67494
67509
  return;
67495
67510
  }
@@ -67539,6 +67554,17 @@ class Iw extends Ai {
67539
67554
  const t = document.activeElement;
67540
67555
  return t ? t.tagName === "INPUT" || t.tagName === "TEXTAREA" ? !0 : t.isContentEditable : !1;
67541
67556
  }
67557
+ /**
67558
+ * 判断当前焦点是否落在画布舞台容器内(由 StageView 在 onMounted 写入 host.stageState.wrapperEl)。
67559
+ * 用于 Ctrl+Z / Ctrl+Y / Delete 等影响画布历史/选中元素的快捷键守卫:
67560
+ * 焦点不在画布时应让位给输入框/浏览器原生行为。
67561
+ */
67562
+ isCanvasFocused() {
67563
+ const t = this.host?.stageState?.wrapperEl;
67564
+ if (!t) return !1;
67565
+ const e = document.activeElement;
67566
+ return e ? t.contains(e) : !1;
67567
+ }
67542
67568
  copySelection() {
67543
67569
  if (!this.host) return;
67544
67570
  const t = this.host.getPlugin("selection-plugin").getSelectionElements();
@@ -70076,11 +70102,11 @@ class XM extends Ai {
70076
70102
  if (this.host) {
70077
70103
  if (this.elementsPlugin = this.host.getPlugin("element-manager-plugin"), !this.elementsPlugin)
70078
70104
  throw new Error("SelectionPlugin requires ElementManagerPlugin to be installed first.");
70079
- this.host.on("stage:mousedown", this.handleMouseDown.bind(this)), this.host.on("stage:mousemove", this.handleMouseMove.bind(this)), this.host.on("stage:mouseup", this.handleMouseUp.bind(this)), this.host.on("element:added", this.handleElementAdded.bind(this)), this.host.on("element:removed", this.handleElementRemoved.bind(this)), this.host.on("stage:mouseleave", this.handleMouseUp.bind(this));
70105
+ this.host.on("stage:mousedown", this.handleMouseDown.bind(this)), this.host.on("stage:mousemove", this.handleMouseMove.bind(this)), this.host.on("stage:mouseup", this.handleMouseUp.bind(this)), this.host.on("element:added", this.handleElementAdded.bind(this)), this.host.on("element:removed", this.handleElementRemoved.bind(this)), this.host.on("stage:mouseleave", this.endSelectionDraft.bind(this));
70080
70106
  }
70081
70107
  }
70082
70108
  onUninstall() {
70083
- this.host && (this.host.off("stage:mousedown", this.handleMouseDown.bind(this)), this.host.off("stage:mousemove", this.handleMouseMove.bind(this)), this.host.off("stage:mouseup", this.handleMouseUp.bind(this)), this.host.off("element:added", this.handleElementAdded.bind(this)), this.host.off("element:removed", this.handleElementRemoved.bind(this)), this.host.off("stage:mouseleave", this.handleMouseUp.bind(this)));
70109
+ this.host && (this.host.off("stage:mousedown", this.handleMouseDown.bind(this)), this.host.off("stage:mousemove", this.handleMouseMove.bind(this)), this.host.off("stage:mouseup", this.handleMouseUp.bind(this)), this.host.off("element:added", this.handleElementAdded.bind(this)), this.host.off("element:removed", this.handleElementRemoved.bind(this)), this.host.off("stage:mouseleave", this.endSelectionDraft.bind(this)));
70084
70110
  }
70085
70111
  handleMouseDown(t) {
70086
70112
  t.evt.button === 0 && (!this.host || this.host.status.currentTool !== "select" || this.isClickOnTransformer(t) || (this.selectionStart = t.point, this.selectionEnd = t.point, this.mouseDownId = this.getClickElementId(t), this.mouseDownId || (this.isSelecting = !0)));
@@ -70097,17 +70123,28 @@ class XM extends Ai {
70097
70123
  !this.isSelecting || !this.host || (this.selectionEnd = t.point);
70098
70124
  }
70099
70125
  handleMouseUp(t) {
70126
+ if (!t || !t.evt || !t.point) {
70127
+ this.endSelectionDraft();
70128
+ return;
70129
+ }
70100
70130
  const e = this.isModifierPressed(t.evt), n = this.isDragged(t);
70101
70131
  if (this.isSelecting) {
70102
70132
  const i = this.findElementsInRect(this.selectionStart, this.selectionEnd);
70103
- e && n ? i.forEach((a) => this.selectionIds.add(a)) : this.selectionIds = i, this.isSelecting = !1, this.emitSelectionChanged();
70133
+ e && n ? i.forEach((a) => this.selectionIds.add(a)) : this.selectionIds = i, this.isSelecting = !1, this.mouseDownId = null, this.emitSelectionChanged();
70104
70134
  } else if (this.mouseDownId) {
70105
70135
  const i = this.elementsPlugin?.elements.get(this.mouseDownId);
70106
70136
  if (!i || i.locked || !i.visible)
70107
70137
  return;
70108
- e && !n ? (this.selectionIds.has(this.mouseDownId) ? this.selectionIds.delete(this.mouseDownId) : this.selectionIds.add(this.mouseDownId), this.emitSelectionChanged()) : e || (this.selectionIds.size > 1 && this.selectionIds.has(this.mouseDownId) && !n ? (this.selectionIds.clear(), this.selectionIds.add(this.mouseDownId), this.emitSelectionChanged()) : this.selectionIds.has(this.mouseDownId) || (this.selectionIds.clear(), this.selectionIds.add(this.mouseDownId), this.emitSelectionChanged()));
70138
+ e && !n ? (this.selectionIds.has(this.mouseDownId) ? this.selectionIds.delete(this.mouseDownId) : this.selectionIds.add(this.mouseDownId), this.emitSelectionChanged()) : e || (this.selectionIds.size > 1 && this.selectionIds.has(this.mouseDownId) && !n ? (this.selectionIds.clear(), this.selectionIds.add(this.mouseDownId), this.emitSelectionChanged()) : this.selectionIds.has(this.mouseDownId) || (this.selectionIds.clear(), this.selectionIds.add(this.mouseDownId), this.emitSelectionChanged())), this.mouseDownId = null;
70109
70139
  }
70110
70140
  }
70141
+ /**
70142
+ * 清理框选 / 按下草稿状态(鼠标移出画布或异常事件触发时使用)。
70143
+ * 不会触发 selection:changed,也不访问 event.evt / event.point。
70144
+ */
70145
+ endSelectionDraft() {
70146
+ this.isSelecting = !1, this.mouseDownId = null;
70147
+ }
70111
70148
  // 判断是否按下修饰键 Ctrl/Cmd/Shift(三者等价,不区分)
70112
70149
  isModifierPressed(t) {
70113
70150
  return t.ctrlKey || t.metaKey || t.shiftKey;
@@ -1,4 +1,4 @@
1
- import { c as Da, _ as Va, g as il } from "./index-Bisex1w7.js";
1
+ import { c as Da, _ as Va, g as il } from "./index-Aa1HXlw6.js";
2
2
  var fn = {}, cn = {}, cr, vn;
3
3
  function Q() {
4
4
  if (vn) return cr;
@@ -14,6 +14,12 @@ export declare class KeyDownPlugin extends BasePlugin {
14
14
  private getStep;
15
15
  private moveSelection;
16
16
  private isInputFocused;
17
+ /**
18
+ * 判断当前焦点是否落在画布舞台容器内(由 StageView 在 onMounted 写入 host.stageState.wrapperEl)。
19
+ * 用于 Ctrl+Z / Ctrl+Y / Delete 等影响画布历史/选中元素的快捷键守卫:
20
+ * 焦点不在画布时应让位给输入框/浏览器原生行为。
21
+ */
22
+ private isCanvasFocused;
17
23
  private copySelection;
18
24
  private pasteFromClipboard;
19
25
  private deleteSelectionElement;
@@ -16,6 +16,11 @@ export declare class SelectionPlugin extends BasePlugin {
16
16
  private isClickOnTransformer;
17
17
  private handleMouseMove;
18
18
  private handleMouseUp;
19
+ /**
20
+ * 清理框选 / 按下草稿状态(鼠标移出画布或异常事件触发时使用)。
21
+ * 不会触发 selection:changed,也不访问 event.evt / event.point。
22
+ */
23
+ private endSelectionDraft;
19
24
  private isModifierPressed;
20
25
  private isDragged;
21
26
  private emitSelectionChanged;
package/dist/vkedit.css CHANGED
@@ -1 +1 @@
1
- :root{--vkedit-color-white: #ffffff;--vkedit-color-bg: #ffffff;--vkedit-color-bg-hover: var(--vkedit-color-neutral-100);--vkedit-color-bg-active: var(--vkedit-color-neutral-200);--vkedit-color-neutral-100: oklch(97% 0 0);--vkedit-color-neutral-200: oklch(92.2% 0 0);--vkedit-color-neutral-400: oklch(70.8% 0 0);--vkedit-color-neutral-500: oklch(55.6% 0 0);--vkedit-color-neutral-700: oklch(37.1% 0 0);--vkedit-color-neutral-800: oklch(26.9% 0 0);--vkedit-color-red-500: oklch(63.7% .237 25.331);--vkedit-color-red-600: oklch(57.7% .245 27.325);--vkedit-color-gray-200: oklch(92.8% .006 264.531);--vkedit-color-gray-600: oklch(44.6% .03 256.802);--vkedit-spacing-xs: .125rem;--vkedit-spacing-sm: .25rem;--vkedit-spacing-md: .5rem;--vkedit-spacing-lg: .75rem;--vkedit-spacing-xl: 2rem;--vkedit-font-sans: ui-sans-serif, system-ui, sans-serif;--vkedit-font-mono: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;--vkedit-font-size-xs: .75rem;--vkedit-font-size-sm: .8125rem;--vkedit-font-size-base: .875rem;--vkedit-font-size-lg: .9375rem;--vkedit-font-size-xl: 1.0625rem;--vkedit-font-weight-medium: 500;--vkedit-font-weight-bold: 700;--vkedit-radius-sm: .25rem;--vkedit-radius-md: .375rem;--vkedit-radius-lg: .5rem;--vkedit-radius-xl: .75rem;--vkedit-radius-full: 9999px;--vkedit-shadow-sm: 0 1px 2px 0 rgb(0 0 0 / .05);--vkedit-shadow-md: 0 4px 6px -1px rgb(0 0 0 / .1);--vkedit-shadow-lg: 0 10px 15px -3px rgb(0 0 0 / .1);--vkedit-color-border: var(--vkedit-color-neutral-200);--vkedit-color-bg-dark: #1e1e1e;--vkedit-color-bg-dark-hover: #2a2a2a;--vkedit-color-bg-dark-active: #3a3a3a;--vkedit-color-panel-bg: rgba(30, 30, 30, .92);--vkedit-color-toolbar-bg: rgba(30, 30, 30, .65);--vkedit-color-border-dark: rgba(255, 255, 255, .08);--vkedit-color-border-dark-hover: rgba(255, 255, 255, .15);--vkedit-color-text-dark: #e0e0e0;--vkedit-color-text-dark-secondary: #c4c4c4;--vkedit-color-canvas-area: #1a1a2e;--vkedit-blur-panel: blur(12px);--vkedit-shadow-panel: 0 4px 16px rgba(0, 0, 0, .3);--vkedit-toolbar-gap: 2px;--vkedit-toolbar-divider-color: rgba(255, 255, 255, .12);--vkedit-toolbar-top: 33px;--vkedit-transition-colors: color, background-color, border-color, .15s ease}.vkedit-editor :where(*,*:before,*:after){box-sizing:border-box}.vkedit-editor :where(h1,h2,h3,h4,h5,h6){font-size:inherit;font-weight:inherit}.vkedit-editor :where(button,input,select,textarea){font:inherit;color:inherit}.vkedit-editor :where(ol,ul,menu){list-style:none}.vkedit-editor :where(img,svg,video,canvas){display:block;vertical-align:middle}@keyframes vkedit-scale-in{0%{opacity:0;transform:scale(.95)}to{opacity:1;transform:scale(1)}}@keyframes vkedit-scale-out{0%{opacity:1;transform:scale(1)}to{opacity:0;transform:scale(.95)}}@keyframes vkedit-fade-in{0%{opacity:0}to{opacity:1}}@keyframes vkedit-fade-out{0%{opacity:1}to{opacity:0}}@keyframes vkedit-toolbar-enter{0%{opacity:0;transform:translate(-50%) translateY(-6px)}to{opacity:1;transform:translate(-50%) translateY(0)}}@keyframes vkedit-toolbar-leave{0%{opacity:1;transform:translate(-50%) translateY(0)}to{opacity:0;transform:translate(-50%) translateY(-6px)}}.vkedit-editor{position:relative;width:100%;height:100vh;overflow:hidden;background:var(--vkedit-color-canvas-area)}.vkedit-editor .vkedit-btn--ghost{color:var(--vkedit-color-text-dark)}.vkedit-editor .vkedit-btn--ghost:hover{background:var(--vkedit-color-bg-dark-hover)}.vkedit-editor .vkedit-btn--outline{color:var(--vkedit-color-text-dark);border-color:var(--vkedit-color-border-dark);background:transparent}.vkedit-editor .vkedit-btn--outline:hover{background:var(--vkedit-color-bg-dark-hover)}.vkedit-editor .vkedit-btn--default{background:var(--vkedit-color-bg-dark-hover);color:var(--vkedit-color-white)}.vkedit-editor .vkedit-btn--default:hover{background:var(--vkedit-color-bg-dark-active)}.vkedit-editor .vkedit-btn--secondary{background:var(--vkedit-color-bg-dark-hover);color:var(--vkedit-color-text-dark)}.vkedit-editor .vkedit-btn--secondary:hover{background:var(--vkedit-color-bg-dark-active)}.vkedit-editor .vkedit-input{background:#0003;border-color:var(--vkedit-color-border-dark);color:var(--vkedit-color-text-dark)}.vkedit-editor .vkedit-input::placeholder{color:var(--vkedit-color-text-dark-secondary)}.vkedit-editor .vkedit-input:focus-visible{box-shadow:0 0 0 1px var(--vkedit-color-border-dark-hover)}.vkedit-editor .vkedit-input-mm__btn{background:var(--vkedit-color-bg-dark-hover);border-color:var(--vkedit-color-border-dark);color:var(--vkedit-color-text-dark)}.vkedit-editor .vkedit-input-mm__btn:hover{background:var(--vkedit-color-bg-dark-active)}.vkedit-editor .vkedit-input-mm__display,.vkedit-editor .vkedit-input-mm__input{background:#0003;border-color:var(--vkedit-color-border-dark);color:var(--vkedit-color-text-dark)}.vkedit-editor .vkedit-label{color:var(--vkedit-color-text-dark-secondary)}.vkedit-editor .vkedit-select{background:#0003;border-color:var(--vkedit-color-border-dark);color:var(--vkedit-color-text-dark)}.vkedit-editor .vkedit-select:focus-visible{box-shadow:0 0 0 1px var(--vkedit-color-border-dark-hover)}.vkedit-editor .vkedit-dropdown__content{background:var(--vkedit-color-bg-dark);border-color:var(--vkedit-color-border-dark);color:var(--vkedit-color-text-dark)}.vkedit-editor .vkedit-dropdown__item{color:var(--vkedit-color-text-dark)}.vkedit-editor .vkedit-dropdown__item:hover,.vkedit-editor .vkedit-switch{background:var(--vkedit-color-bg-dark-hover)}.vkedit-editor .vkedit-switch:has(.vkedit-editor .vkedit-switch__input:checked){background:#536f9d}.vkedit-editor .vkedit-toggle{color:var(--vkedit-color-text-dark)}.vkedit-editor .vkedit-toggle:hover{background:var(--vkedit-color-bg-dark-hover)}.vkedit-editor .vkedit-toggle--on{background:var(--vkedit-color-bg-dark-active);color:var(--vkedit-color-white)}.vkedit-editor .vkedit-editor__minwidth-warning{position:absolute;inset:0;z-index:1000;display:flex;align-items:center;justify-content:center;background:var(--vkedit-color-canvas-area);color:var(--vkedit-color-text-dark);font-size:var(--vkedit-font-size-lg);text-align:center;padding:var(--vkedit-spacing-lg)}.vkedit-editor .vkedit-editor__minwidth-warning p{max-width:320px;line-height:1.6}@media(max-width:1023px){.vkedit-editor .vkedit-floating-toolbox,.vkedit-editor .vkedit-floating-toolbox--collapsed{width:44px}.vkedit-editor .vkedit-floating-toolbox .vkedit-floating-toolbox__title span,.vkedit-editor .vkedit-floating-toolbox--collapsed .vkedit-floating-toolbox__title span,.vkedit-editor .vkedit-floating-toolbox .vkedit-floating-toolbox__title .vkedit-floating-toolbox__toggle,.vkedit-editor .vkedit-floating-toolbox--collapsed .vkedit-floating-toolbox__title .vkedit-floating-toolbox__toggle{display:none}.vkedit-editor .vkedit-floating-toolbox .vkedit-floating-toolbox__title,.vkedit-editor .vkedit-floating-toolbox--collapsed .vkedit-floating-toolbox__title{border-bottom:none;padding:var(--vkedit-spacing-xs)}.vkedit-editor .vkedit-floating-toolbox .vkedit-floating-toolbox__content,.vkedit-editor .vkedit-floating-toolbox--collapsed .vkedit-floating-toolbox__content{display:none}.vkedit-editor .vkedit-floating-toolbox .vkedit-floating-toolbox__collapsed-icon,.vkedit-editor .vkedit-floating-toolbox--collapsed .vkedit-floating-toolbox__collapsed-icon{display:flex}.vkedit-editor .vkedit-floating-property-panel,.vkedit-editor .vkedit-floating-property-panel--collapsed{width:44px}.vkedit-editor .vkedit-floating-toolbar{padding:0 4px;font-size:var(--vkedit-font-size-xs);gap:0}.vkedit-editor .vkedit-floating-toolbar .vkedit-btn--ghost{height:28px;padding:0 4px}.vkedit-editor .vkedit-floating-toolbar .vkedit-toolbar__label{display:none}}.vkedit-floating-toolbar{position:absolute;top:var(--vkedit-toolbar-top);left:50%;transform:translate(-50%);z-index:100;display:flex;align-items:center;gap:0;height:40px;padding:0 8px;background:var(--vkedit-color-toolbar-bg);backdrop-filter:var(--vkedit-blur-panel);-webkit-backdrop-filter:var(--vkedit-blur-panel);border:1px solid var(--vkedit-color-border-dark-hover);border-radius:var(--vkedit-radius-xl);box-shadow:var(--vkedit-shadow-panel);color:var(--vkedit-color-text-dark);font-size:var(--vkedit-font-size-sm);transition:opacity .2s ease,transform .2s ease}.vkedit-toolbar__group{display:flex;align-items:center;gap:var(--vkedit-toolbar-gap)}.vkedit-toolbar__divider{width:1px;height:20px;margin:0 6px;background:var(--vkedit-toolbar-divider-color);flex-shrink:0}.vkedit-floating-toolbox{position:absolute;top:52px;left:37px;width:180px;z-index:90;background:var(--vkedit-color-panel-bg);backdrop-filter:var(--vkedit-blur-panel);-webkit-backdrop-filter:var(--vkedit-blur-panel);border:1px solid var(--vkedit-color-border-dark);border-radius:8px;box-shadow:var(--vkedit-shadow-panel);max-height:calc(100vh - 64px);font-size:var(--vkedit-font-size-sm);color:var(--vkedit-color-text-dark);transition:width .2s ease;display:flex;flex-direction:column}.vkedit-floating-toolbox__toggle{width:24px;height:24px;display:flex;align-items:center;justify-content:center;background:transparent;border:none;border-radius:4px;cursor:pointer;color:var(--vkedit-color-text-dark-secondary);flex-shrink:0}.vkedit-floating-toolbox__toggle:hover{background:var(--vkedit-color-bg-dark-hover);color:var(--vkedit-color-text-dark)}.vkedit-floating-toolbox__collapsed-icon{display:none;align-items:center;justify-content:center;height:44px;color:var(--vkedit-color-text-dark-secondary);cursor:pointer}.vkedit-floating-toolbox--collapsed{width:44px;overflow:hidden;align-items:center;justify-content:center}.vkedit-floating-toolbox--collapsed .vkedit-floating-toolbox__title{padding:var(--vkedit-spacing-xs);border-bottom:none}.vkedit-floating-toolbox--collapsed .vkedit-floating-toolbox__title span,.vkedit-floating-toolbox--collapsed .vkedit-floating-toolbox__title .vkedit-floating-toolbox__toggle,.vkedit-floating-toolbox--collapsed .vkedit-floating-toolbox__content{display:none}.vkedit-floating-toolbox--collapsed .vkedit-floating-toolbox__collapsed-icon{display:flex}.vkedit-floating-toolbox__title{display:flex;align-items:center;justify-content:space-between;padding:var(--vkedit-spacing-sm) var(--vkedit-spacing-md);font-size:var(--vkedit-font-size-sm);font-weight:var(--vkedit-font-weight-bold);border-bottom:1px solid var(--vkedit-color-border-dark);flex-shrink:0}.vkedit-floating-toolbox__content{padding:var(--vkedit-spacing-sm);display:flex;flex-direction:column;gap:var(--vkedit-spacing-xs)}.vkedit-floating-toolbox__content .vkedit-btn{width:100%;justify-content:center}.vkedit-stage-view{position:absolute;inset:0;width:100%;height:100%;z-index:1;overflow:hidden}.vkedit-status-bar{position:absolute;bottom:16px;left:50%;transform:translate(-50%);z-index:90;display:flex;align-items:center;justify-content:space-between;gap:16px;background:#000000a6;backdrop-filter:blur(12px);-webkit-backdrop-filter:blur(12px);border:1px solid rgba(255,255,255,.1);border-radius:8px;padding:0 16px;height:36px;color:#e0e0e0;font-size:var(--vkedit-font-size-sm);-webkit-user-select:none;user-select:none;white-space:nowrap}.vkedit-status-bar__section{display:flex;align-items:center;gap:8px}.vkedit-status-bar__zoom-controls{display:flex;align-items:center;gap:4px}.vkedit-status-bar__btn{display:flex;align-items:center;justify-content:center;width:28px;height:28px;border:none;background:transparent;border-radius:4px;cursor:pointer;color:#e0e0e0}.vkedit-status-bar__btn:hover{background:#ffffff1a}.vkedit-status-bar__zoom-value{font-size:var(--vkedit-font-size-sm);font-weight:500;min-width:44px;text-align:center;color:#e0e0e0}.vkedit-status-bar__coords{font-size:var(--vkedit-font-size-sm);font-variant-numeric:tabular-nums;color:#e0e0e0;letter-spacing:.02em}.vkedit-status-bar__cursor-icon{display:flex;align-items:center;justify-content:center;width:28px;height:28px}.vkedit-context-menu{position:absolute;z-index:200;min-width:160px;border-radius:8px;border:1px solid var(--vkedit-color-border-dark);background:var(--vkedit-color-bg-dark);backdrop-filter:var(--vkedit-blur-panel);-webkit-backdrop-filter:var(--vkedit-blur-panel);padding:4px;box-shadow:var(--vkedit-shadow-panel);color:var(--vkedit-color-text-dark);font-size:var(--vkedit-font-size-sm)}.vkedit-context-menu__item{display:block;width:100%;padding:4px 8px;border:none;border-radius:4px;background:transparent;font-size:var(--vkedit-font-size-sm);cursor:pointer;text-align:left;color:var(--vkedit-color-text-dark)}.vkedit-context-menu__item:hover{background:var(--vkedit-color-bg-dark-hover)}.vkedit-help-guide{position:absolute;bottom:16px;right:16px;z-index:95}.vkedit-help-guide__btn{display:flex;align-items:center;justify-content:center;width:36px;height:36px;border:1px solid rgba(255,255,255,.1);border-radius:8px;background:#000000a6;backdrop-filter:blur(12px);-webkit-backdrop-filter:blur(12px);cursor:pointer;color:#e0e0e0}.vkedit-help-guide__btn:hover{background:#ffffff26}.vkedit-help-guide__overlay{position:fixed;inset:0;z-index:999;display:flex;align-items:center;justify-content:center;background:#0000004d}.vkedit-help-guide__popup{width:380px;max-height:80vh;overflow-y:auto;border:1px solid var(--vkedit-color-border-dark, rgba(255, 255, 255, .08));border-radius:12px;background:var(--vkedit-color-bg-dark, #1e1e1e);backdrop-filter:var(--vkedit-blur-panel, blur(12px));-webkit-backdrop-filter:var(--vkedit-blur-panel, blur(12px));box-shadow:var(--vkedit-shadow-panel, 0 4px 16px rgba(0, 0, 0, .3));color:var(--vkedit-color-text-dark, #e0e0e0);font-size:var(--vkedit-font-size-base);-webkit-user-select:none;user-select:none}.vkedit-help-guide__header{display:flex;align-items:center;justify-content:space-between;padding:16px 20px 12px;border-bottom:1px solid rgba(255,255,255,.08)}.vkedit-help-guide__title{font-size:var(--vkedit-font-size-xl);font-weight:600}.vkedit-help-guide__close{display:flex;align-items:center;justify-content:center;width:28px;height:28px;border:none;border-radius:4px;background:transparent;cursor:pointer;color:#999}.vkedit-help-guide__close:hover{background:#ffffff1a;color:#e0e0e0}.vkedit-help-guide__list{padding:12px 20px 16px}.vkedit-help-guide__group{margin-bottom:14px}.vkedit-help-guide__group:last-child{margin-bottom:0}.vkedit-help-guide__group-title{font-size:var(--vkedit-font-size-xs);font-weight:600;color:#999;text-transform:uppercase;letter-spacing:.05em;margin-bottom:8px}.vkedit-help-guide__item{display:flex;align-items:center;gap:6px;padding:5px 0;line-height:1.5}.vkedit-help-guide__sep{color:#666;font-size:var(--vkedit-font-size-xs)}.vkedit-help-guide__desc{margin-left:auto;color:#999;font-size:var(--vkedit-font-size-sm);white-space:nowrap}.vkedit-help-guide__item kbd{display:inline-flex;align-items:center;justify-content:center;min-width:22px;height:22px;padding:0 5px;border:1px solid rgba(255,255,255,.15);border-radius:4px;background:#ffffff14;font-family:inherit;font-size:var(--vkedit-font-size-xs);line-height:1;color:#e0e0e0;white-space:nowrap}.vkedit-floating-property-panel,.vkedit-property-panel{position:absolute;top:52px;right:12px;width:240px;z-index:90;background:var(--vkedit-color-panel-bg);backdrop-filter:var(--vkedit-blur-panel);-webkit-backdrop-filter:var(--vkedit-blur-panel);border:1px solid var(--vkedit-color-border-dark);border-radius:8px;box-shadow:var(--vkedit-shadow-panel);max-height:calc(100vh - 64px);overflow-y:auto;font-size:var(--vkedit-font-size-sm);color:var(--vkedit-color-text-dark);transition:width .2s ease;display:flex;flex-direction:column}.vkedit-floating-property-panel__toggle{width:24px;height:24px;display:flex;align-items:center;justify-content:center;background:transparent;border:none;border-radius:4px;cursor:pointer;color:var(--vkedit-color-text-dark-secondary);flex-shrink:0}.vkedit-floating-property-panel__toggle:hover{background:var(--vkedit-color-bg-dark-hover);color:var(--vkedit-color-text-dark)}.vkedit-floating-property-panel__collapsed-icon{display:none;align-items:center;justify-content:center;height:44px;color:var(--vkedit-color-text-dark-secondary);cursor:pointer}.vkedit-floating-property-panel--collapsed{width:44px;overflow:hidden;align-items:center;justify-content:center}.vkedit-floating-property-panel--collapsed .vkedit-floating-property-panel__title{padding:var(--vkedit-spacing-xs);border-bottom:none}.vkedit-floating-property-panel--collapsed .vkedit-floating-property-panel__title span,.vkedit-floating-property-panel--collapsed .vkedit-floating-property-panel__title .vkedit-floating-property-panel__toggle,.vkedit-floating-property-panel--collapsed .vkedit-floating-property-panel__content{display:none}.vkedit-floating-property-panel--collapsed .vkedit-floating-property-panel__collapsed-icon{display:flex}.vkedit-floating-property-panel__title{display:flex;align-items:center;justify-content:space-between;padding:var(--vkedit-spacing-sm) var(--vkedit-spacing-md);font-size:var(--vkedit-font-size-sm);font-weight:var(--vkedit-font-weight-bold);border-bottom:1px solid var(--vkedit-color-border-dark);flex-shrink:0}.vkedit-floating-property-panel__content{padding:var(--vkedit-spacing-md);overflow:hidden auto;display:grid;grid-template-columns:1fr;gap:var(--vkedit-spacing-md)}.vkedit-btn{display:inline-flex;align-items:center;justify-content:center;gap:var(--vkedit-spacing-sm);white-space:nowrap;border-radius:var(--vkedit-radius-md);font-size:var(--vkedit-font-size-sm);font-weight:var(--vkedit-font-weight-medium);transition:var(--vkedit-transition-colors);cursor:pointer;border:none;line-height:1}.vkedit-btn:focus-visible{outline:none;box-shadow:0 0 0 1px var(--vkedit-color-neutral-400)}.vkedit-btn:disabled{pointer-events:none;opacity:.5}.vkedit-btn svg{pointer-events:none;width:16px;height:16px;flex-shrink:0}.vkedit-btn--default{background:var(--vkedit-color-neutral-800);color:var(--vkedit-color-white)}.vkedit-btn--default:hover{background:var(--vkedit-color-neutral-700)}.vkedit-btn--destructive{background:var(--vkedit-color-red-500);color:var(--vkedit-color-white)}.vkedit-btn--destructive:hover{background:var(--vkedit-color-red-600)}.vkedit-btn--outline{border:1px solid var(--vkedit-color-border);background:var(--vkedit-color-white)}.vkedit-btn--outline:hover,.vkedit-btn--secondary{background:var(--vkedit-color-neutral-100)}.vkedit-btn--secondary:hover{background:var(--vkedit-color-neutral-200)}.vkedit-btn--ghost:hover{background:var(--vkedit-color-neutral-100)}.vkedit-btn--link{text-decoration:underline;text-underline-offset:4px}.vkedit-btn--link:hover{text-decoration:none}.vkedit-btn--default{height:28px;padding:0 .5rem}.vkedit-btn--xs{height:24px;padding:0 .375rem;font-size:var(--vkedit-font-size-xs)}.vkedit-btn--sm{height:26px;padding:0 .375rem;font-size:var(--vkedit-font-size-xs)}.vkedit-btn--lg{height:32px;padding:0 .75rem}.vkedit-btn--icon{height:28px;width:28px;padding:0}.vkedit-btn--icon-sm{height:24px;width:24px;padding:0}.vkedit-btn--icon-lg{height:32px;width:32px;padding:0}.vkedit-toggle{display:inline-flex;align-items:center;justify-content:center;border-radius:var(--vkedit-radius-md);font-size:var(--vkedit-font-size-sm);font-weight:var(--vkedit-font-weight-medium);border:none;background:transparent;cursor:pointer;white-space:nowrap;outline:none}.vkedit-toggle:hover{background:var(--vkedit-color-neutral-100)}.vkedit-toggle--on{background:var(--vkedit-color-neutral-100);color:var(--vkedit-color-neutral-800)}.vkedit-toggle:focus-visible{box-shadow:0 0 0 3px rgb(from var(--vkedit-color-neutral-400) r g b/.5)}.vkedit-toggle:disabled{pointer-events:none;opacity:.5}.vkedit-toggle svg{pointer-events:none;width:16px;height:16px;flex-shrink:0}.vkedit-toggle--default{height:36px;min-width:36px;padding:0 var(--vkedit-spacing-sm)}.vkedit-toggle--sm{height:32px;min-width:32px;padding:0 6px}.vkedit-toggle--lg{height:40px;min-width:40px;padding:0 10px}.vkedit-input{display:flex;height:28px;width:100%;border-radius:var(--vkedit-radius-md);border:1px solid var(--vkedit-color-border);background:transparent;padding:0 var(--vkedit-spacing-sm);font-size:var(--vkedit-font-size-sm);box-shadow:var(--vkedit-shadow-sm);transition:var(--vkedit-transition-colors)}.vkedit-input::placeholder{color:var(--vkedit-color-neutral-500)}.vkedit-input:focus-visible{outline:none;box-shadow:0 0 0 1px var(--vkedit-color-neutral-400)}.vkedit-input:disabled{cursor:not-allowed;opacity:.5}.vkedit-label{font-size:var(--vkedit-font-size-sm);font-weight:var(--vkedit-font-weight-medium);line-height:1;margin-bottom:var(--vkedit-spacing-xs)}.vkedit-select{display:flex;height:28px;width:100%;border-radius:var(--vkedit-radius-md);border:1px solid var(--vkedit-color-border);background:transparent;padding:0 var(--vkedit-spacing-sm);font-size:var(--vkedit-font-size-sm);box-shadow:var(--vkedit-shadow-sm);transition:var(--vkedit-transition-colors);cursor:pointer}.vkedit-select:focus-visible{outline:none;box-shadow:0 0 0 1px var(--vkedit-color-neutral-400)}.vkedit-select:disabled{cursor:not-allowed;opacity:.5}.vkedit-switch{display:inline-flex;height:20px;width:36px;flex-shrink:0;cursor:pointer;align-items:center;border-radius:var(--vkedit-radius-full);border:2px solid transparent;background:#d4d4d4;transition:var(--vkedit-transition-colors);box-shadow:var(--vkedit-shadow-sm);position:relative}.vkedit-switch__input{position:absolute;opacity:0;width:0;height:0}.vkedit-switch__thumb{display:block;height:16px;width:16px;border-radius:var(--vkedit-radius-full);background:var(--vkedit-color-white);box-shadow:var(--vkedit-shadow-lg);transition:transform .15s ease}.vkedit-switch:has(.vkedit-switch__input:checked){background:#6a87b7}.vkedit-switch:has(.vkedit-switch__input:checked) .vkedit-switch__thumb{transform:translate(16px)}.vkedit-switch:has(.vkedit-switch__input:disabled){cursor:not-allowed;opacity:.5}.vkedit-input-mm{display:flex;align-items:center;gap:0}.vkedit-input-mm__btn{display:flex;align-items:center;justify-content:center;height:28px;width:28px;border:1px solid var(--vkedit-color-border);background:transparent;font-size:var(--vkedit-font-size-lg);cursor:pointer;-webkit-user-select:none;user-select:none}.vkedit-input-mm__btn:first-child{border-radius:var(--vkedit-radius-md) 0 0 var(--vkedit-radius-md);border-right:none}.vkedit-input-mm__btn:last-child{border-radius:0 var(--vkedit-radius-md) var(--vkedit-radius-md) 0;border-left:none}.vkedit-input-mm__btn:hover{background:var(--vkedit-color-neutral-100)}.vkedit-input-mm__field{flex:1}.vkedit-input-mm__display,.vkedit-input-mm__input{display:flex;height:28px;width:100%;border:1px solid var(--vkedit-color-border);border-left:none;border-right:none;background:transparent;padding:0 var(--vkedit-spacing-sm);font-size:var(--vkedit-font-size-sm);text-align:center;transition:var(--vkedit-transition-colors)}.vkedit-input-mm__display:focus-visible,.vkedit-input-mm__input:focus-visible{outline:none;box-shadow:0 0 0 1px var(--vkedit-color-neutral-400);position:relative;z-index:1}.vkedit-dropdown{position:relative;display:inline-block}.vkedit-dropdown__overlay{position:fixed;top:0;left:0;width:100%;height:100%;z-index:150}.vkedit-dropdown__content{position:fixed;z-index:160;min-width:160px;max-height:300px;overflow-x:hidden;overflow-y:auto;border-radius:8px;border:1px solid var(--vkedit-color-border-dark);background:var(--vkedit-color-bg-dark);backdrop-filter:var(--vkedit-blur-panel);-webkit-backdrop-filter:var(--vkedit-blur-panel);padding:4px;box-shadow:var(--vkedit-shadow-panel);color:var(--vkedit-color-text-dark)}.vkedit-dropdown__label{padding:4px 8px;font-size:var(--vkedit-font-size-sm);font-weight:var(--vkedit-font-weight-medium);color:var(--vkedit-color-text-dark-secondary)}.vkedit-dropdown__sep{height:1px;margin:4px 0;background:var(--vkedit-color-border-dark)}.vkedit-dropdown__item{display:flex;align-items:center;gap:var(--vkedit-spacing-sm);width:100%;padding:4px 8px;border:none;border-radius:4px;background:transparent;font-size:var(--vkedit-font-size-sm);cursor:pointer;text-align:left;color:var(--vkedit-color-text-dark)}.vkedit-dropdown__item:hover{background:var(--vkedit-color-bg-dark-hover)}.vkedit-dropdown__item svg{width:16px;height:16px;flex-shrink:0}.vkedit-scale-enter-active{animation:vkedit-scale-in .15s ease-out}.vkedit-scale-leave-active{animation:vkedit-scale-out .15s ease-in}body:has(.vkedit-editor) .vkedit-dropdown__content{background:var(--vkedit-color-bg-dark);border-color:var(--vkedit-color-border-dark);color:var(--vkedit-color-text-dark)}body:has(.vkedit-editor) .vkedit-dropdown__item{color:var(--vkedit-color-text-dark)}body:has(.vkedit-editor) .vkedit-dropdown__item:hover{background:var(--vkedit-color-bg-dark-hover)}.vkedit-btn-group{display:flex;align-items:stretch;width:fit-content}.vkedit-property__title{font-size:var(--vkedit-font-size-xl);font-weight:var(--vkedit-font-weight-bold);padding-bottom:var(--vkedit-spacing-sm);color:var(--vkedit-color-text-dark)}.vkedit-property__label{font-size:var(--vkedit-font-size-sm);color:var(--vkedit-color-text-dark-secondary);display:block}.vkedit-property__grid{display:grid;grid-template-columns:repeat(2,1fr);gap:var(--vkedit-spacing-md);align-items:center;padding:var(--vkedit-spacing-sm) 0}.vkedit-property__col-full{grid-column:1/-1}.vkedit-chart__field{width:100%;border:1px solid var(--vkedit-color-border);border-radius:var(--vkedit-radius-md);padding:0 var(--vkedit-spacing-sm)}.vkedit-chart__input{width:100%;border:1px solid var(--vkedit-color-border);border-radius:var(--vkedit-radius-md);padding:0 var(--vkedit-spacing-sm);height:36px}.vkedit-chart__textarea{width:100%;border:1px solid var(--vkedit-color-border);border-radius:var(--vkedit-radius-md);padding:var(--vkedit-spacing-xs) var(--vkedit-spacing-sm);font-family:var(--vkedit-font-mono);font-size:var(--vkedit-font-size-xs);height:192px;resize:vertical}.vkedit-chart__error{color:var(--vkedit-color-red-500);font-size:var(--vkedit-font-size-xs);margin-top:4px}.vkedit-chart__section{padding-top:var(--vkedit-spacing-md);font-weight:var(--vkedit-font-weight-bold)}.vkedit-input-mm__input[data-v-47959cb1]::-webkit-outer-spin-button,.vkedit-input-mm__input[data-v-47959cb1]::-webkit-inner-spin-button{-webkit-appearance:none;margin:0}.vkedit-input-mm__input[data-v-47959cb1]{-moz-appearance:textfield}.vkedit-input-mm__input[data-v-f78ba536]::-webkit-outer-spin-button,.vkedit-input-mm__input[data-v-f78ba536]::-webkit-inner-spin-button{-webkit-appearance:none;margin:0}.vkedit-input-mm__input[data-v-f78ba536]{-moz-appearance:textfield}.vkedit-icon[data-v-b4ed0b97]{display:inline-flex;align-items:center;justify-content:center;flex-shrink:0;line-height:1}.vkedit-icon[data-v-b4ed0b97] svg{width:100%;height:100%;display:block;fill:currentColor}.vkedit-toolbar-enter-active[data-v-f04619fe]{animation:vkedit-toolbar-enter .2s ease-out}.vkedit-toolbar-leave-active[data-v-f04619fe]{animation:vkedit-toolbar-leave .15s ease-in}
1
+ :root{--vkedit-color-white: #ffffff;--vkedit-color-bg: #ffffff;--vkedit-color-bg-hover: var(--vkedit-color-neutral-100);--vkedit-color-bg-active: var(--vkedit-color-neutral-200);--vkedit-color-neutral-100: oklch(97% 0 0);--vkedit-color-neutral-200: oklch(92.2% 0 0);--vkedit-color-neutral-400: oklch(70.8% 0 0);--vkedit-color-neutral-500: oklch(55.6% 0 0);--vkedit-color-neutral-700: oklch(37.1% 0 0);--vkedit-color-neutral-800: oklch(26.9% 0 0);--vkedit-color-red-500: oklch(63.7% .237 25.331);--vkedit-color-red-600: oklch(57.7% .245 27.325);--vkedit-color-gray-200: oklch(92.8% .006 264.531);--vkedit-color-gray-600: oklch(44.6% .03 256.802);--vkedit-spacing-xs: .125rem;--vkedit-spacing-sm: .25rem;--vkedit-spacing-md: .5rem;--vkedit-spacing-lg: .75rem;--vkedit-spacing-xl: 2rem;--vkedit-font-sans: ui-sans-serif, system-ui, sans-serif;--vkedit-font-mono: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;--vkedit-font-size-xs: .75rem;--vkedit-font-size-sm: .8125rem;--vkedit-font-size-base: .875rem;--vkedit-font-size-lg: .9375rem;--vkedit-font-size-xl: 1.0625rem;--vkedit-font-weight-medium: 500;--vkedit-font-weight-bold: 700;--vkedit-radius-sm: .25rem;--vkedit-radius-md: .375rem;--vkedit-radius-lg: .5rem;--vkedit-radius-xl: .75rem;--vkedit-radius-full: 9999px;--vkedit-shadow-sm: 0 1px 2px 0 rgb(0 0 0 / .05);--vkedit-shadow-md: 0 4px 6px -1px rgb(0 0 0 / .1);--vkedit-shadow-lg: 0 10px 15px -3px rgb(0 0 0 / .1);--vkedit-color-border: var(--vkedit-color-neutral-200);--vkedit-color-bg-dark: #1e1e1e;--vkedit-color-bg-dark-hover: #2a2a2a;--vkedit-color-bg-dark-active: #3a3a3a;--vkedit-color-panel-bg: rgba(30, 30, 30, .92);--vkedit-color-toolbar-bg: rgba(30, 30, 30, .65);--vkedit-color-border-dark: rgba(255, 255, 255, .08);--vkedit-color-border-dark-hover: rgba(255, 255, 255, .15);--vkedit-color-text-dark: #e0e0e0;--vkedit-color-text-dark-secondary: #c4c4c4;--vkedit-color-canvas-area: #1a1a2e;--vkedit-blur-panel: blur(12px);--vkedit-shadow-panel: 0 4px 16px rgba(0, 0, 0, .3);--vkedit-toolbar-gap: 2px;--vkedit-toolbar-divider-color: rgba(255, 255, 255, .12);--vkedit-toolbar-top: 33px;--vkedit-transition-colors: color, background-color, border-color, .15s ease}.vkedit-editor :where(*,*:before,*:after){box-sizing:border-box}.vkedit-editor :where(h1,h2,h3,h4,h5,h6){font-size:inherit;font-weight:inherit}.vkedit-editor :where(button,input,select,textarea){font:inherit;color:inherit}.vkedit-editor :where(ol,ul,menu){list-style:none}.vkedit-editor :where(img,svg,video,canvas){display:block;vertical-align:middle}@keyframes vkedit-scale-in{0%{opacity:0;transform:scale(.95)}to{opacity:1;transform:scale(1)}}@keyframes vkedit-scale-out{0%{opacity:1;transform:scale(1)}to{opacity:0;transform:scale(.95)}}@keyframes vkedit-fade-in{0%{opacity:0}to{opacity:1}}@keyframes vkedit-fade-out{0%{opacity:1}to{opacity:0}}@keyframes vkedit-toolbar-enter{0%{opacity:0;transform:translate(-50%) translateY(-6px)}to{opacity:1;transform:translate(-50%) translateY(0)}}@keyframes vkedit-toolbar-leave{0%{opacity:1;transform:translate(-50%) translateY(0)}to{opacity:0;transform:translate(-50%) translateY(-6px)}}.vkedit-editor{position:relative;width:100%;height:100vh;overflow:hidden;background:var(--vkedit-color-canvas-area)}.vkedit-editor .vkedit-editor__minwidth-warning{position:absolute;inset:0;z-index:1000;display:flex;align-items:center;justify-content:center;background:var(--vkedit-color-canvas-area);color:var(--vkedit-color-text-dark);font-size:var(--vkedit-font-size-lg);text-align:center;padding:var(--vkedit-spacing-lg)}.vkedit-editor .vkedit-editor__minwidth-warning p{max-width:320px;line-height:1.6}@media(max-width:1023px){.vkedit-editor .vkedit-floating-toolbox,.vkedit-editor .vkedit-floating-toolbox--collapsed{width:44px}.vkedit-editor .vkedit-floating-toolbox .vkedit-floating-toolbox__title span,.vkedit-editor .vkedit-floating-toolbox--collapsed .vkedit-floating-toolbox__title span,.vkedit-editor .vkedit-floating-toolbox .vkedit-floating-toolbox__title .vkedit-floating-toolbox__toggle,.vkedit-editor .vkedit-floating-toolbox--collapsed .vkedit-floating-toolbox__title .vkedit-floating-toolbox__toggle{display:none}.vkedit-editor .vkedit-floating-toolbox .vkedit-floating-toolbox__title,.vkedit-editor .vkedit-floating-toolbox--collapsed .vkedit-floating-toolbox__title{border-bottom:none;padding:var(--vkedit-spacing-xs)}.vkedit-editor .vkedit-floating-toolbox .vkedit-floating-toolbox__content,.vkedit-editor .vkedit-floating-toolbox--collapsed .vkedit-floating-toolbox__content{display:none}.vkedit-editor .vkedit-floating-toolbox .vkedit-floating-toolbox__collapsed-icon,.vkedit-editor .vkedit-floating-toolbox--collapsed .vkedit-floating-toolbox__collapsed-icon{display:flex}.vkedit-editor .vkedit-floating-property-panel,.vkedit-editor .vkedit-floating-property-panel--collapsed{width:44px}.vkedit-editor .vkedit-floating-toolbar{padding:0 4px;font-size:var(--vkedit-font-size-xs);gap:0}.vkedit-editor .vkedit-floating-toolbar .vkedit-btn--ghost{height:28px;padding:0 4px}.vkedit-editor .vkedit-floating-toolbar .vkedit-toolbar__label{display:none}}body:has(.vkedit-editor) .vkedit-btn--ghost{color:var(--vkedit-color-text-dark)}body:has(.vkedit-editor) .vkedit-btn--ghost:hover{background:var(--vkedit-color-bg-dark-hover)}body:has(.vkedit-editor) .vkedit-btn--outline{color:var(--vkedit-color-text-dark);border-color:var(--vkedit-color-border-dark);background:transparent}body:has(.vkedit-editor) .vkedit-btn--outline:hover{background:var(--vkedit-color-bg-dark-hover)}body:has(.vkedit-editor) .vkedit-btn--default{background:var(--vkedit-color-bg-dark-hover);color:var(--vkedit-color-white)}body:has(.vkedit-editor) .vkedit-btn--default:hover{background:var(--vkedit-color-bg-dark-active)}body:has(.vkedit-editor) .vkedit-btn--secondary{background:var(--vkedit-color-bg-dark-hover);color:var(--vkedit-color-text-dark)}body:has(.vkedit-editor) .vkedit-btn--secondary:hover{background:var(--vkedit-color-bg-dark-active)}body:has(.vkedit-editor) .vkedit-input{background:#0003;border-color:var(--vkedit-color-border-dark);color:var(--vkedit-color-text-dark)}body:has(.vkedit-editor) .vkedit-input::placeholder{color:var(--vkedit-color-text-dark-secondary)}body:has(.vkedit-editor) .vkedit-input:focus-visible{box-shadow:0 0 0 1px var(--vkedit-color-border-dark-hover)}body:has(.vkedit-editor) .vkedit-input-mm__btn{background:var(--vkedit-color-bg-dark-hover);border-color:var(--vkedit-color-border-dark);color:var(--vkedit-color-text-dark)}body:has(.vkedit-editor) .vkedit-input-mm__btn:hover{background:var(--vkedit-color-bg-dark-active)}body:has(.vkedit-editor) .vkedit-input-mm__display,body:has(.vkedit-editor) .vkedit-input-mm__input{background:#0003;border-color:var(--vkedit-color-border-dark);color:var(--vkedit-color-text-dark)}body:has(.vkedit-editor) .vkedit-label{color:var(--vkedit-color-text-dark-secondary)}body:has(.vkedit-editor) .vkedit-select{background:#0003;border-color:var(--vkedit-color-border-dark);color:var(--vkedit-color-text-dark)}body:has(.vkedit-editor) .vkedit-select:focus-visible{box-shadow:0 0 0 1px var(--vkedit-color-border-dark-hover)}body:has(.vkedit-editor) .vkedit-switch{background:var(--vkedit-color-bg-dark-hover)}body:has(.vkedit-editor) .vkedit-switch:has(body:has(.vkedit-editor) .vkedit-switch__input:checked){background:#536f9d}body:has(.vkedit-editor) .vkedit-toggle{color:var(--vkedit-color-text-dark)}body:has(.vkedit-editor) .vkedit-toggle:hover{background:var(--vkedit-color-bg-dark-hover)}body:has(.vkedit-editor) .vkedit-toggle--on{background:var(--vkedit-color-bg-dark-active);color:var(--vkedit-color-white)}.vkedit-floating-toolbar{position:absolute;top:var(--vkedit-toolbar-top);left:50%;transform:translate(-50%);z-index:100;display:flex;align-items:center;gap:0;height:40px;padding:0 8px;background:var(--vkedit-color-toolbar-bg);backdrop-filter:var(--vkedit-blur-panel);-webkit-backdrop-filter:var(--vkedit-blur-panel);border:1px solid var(--vkedit-color-border-dark-hover);border-radius:var(--vkedit-radius-xl);box-shadow:var(--vkedit-shadow-panel);color:var(--vkedit-color-text-dark);font-size:var(--vkedit-font-size-sm);transition:opacity .2s ease,transform .2s ease}.vkedit-toolbar__group{display:flex;align-items:center;gap:var(--vkedit-toolbar-gap)}.vkedit-toolbar__divider{width:1px;height:20px;margin:0 6px;background:var(--vkedit-toolbar-divider-color);flex-shrink:0}.vkedit-floating-toolbox{position:absolute;top:52px;left:37px;width:180px;z-index:90;background:var(--vkedit-color-panel-bg);backdrop-filter:var(--vkedit-blur-panel);-webkit-backdrop-filter:var(--vkedit-blur-panel);border:1px solid var(--vkedit-color-border-dark);border-radius:8px;box-shadow:var(--vkedit-shadow-panel);max-height:calc(100vh - 64px);font-size:var(--vkedit-font-size-sm);color:var(--vkedit-color-text-dark);transition:width .2s ease;display:flex;flex-direction:column}.vkedit-floating-toolbox__toggle{width:24px;height:24px;display:flex;align-items:center;justify-content:center;background:transparent;border:none;border-radius:4px;cursor:pointer;color:var(--vkedit-color-text-dark-secondary);flex-shrink:0}.vkedit-floating-toolbox__toggle:hover{background:var(--vkedit-color-bg-dark-hover);color:var(--vkedit-color-text-dark)}.vkedit-floating-toolbox__collapsed-icon{display:none;align-items:center;justify-content:center;height:44px;color:var(--vkedit-color-text-dark-secondary);cursor:pointer}.vkedit-floating-toolbox--collapsed{width:44px;overflow:hidden;align-items:center;justify-content:center}.vkedit-floating-toolbox--collapsed .vkedit-floating-toolbox__title{padding:var(--vkedit-spacing-xs);border-bottom:none}.vkedit-floating-toolbox--collapsed .vkedit-floating-toolbox__title span,.vkedit-floating-toolbox--collapsed .vkedit-floating-toolbox__title .vkedit-floating-toolbox__toggle,.vkedit-floating-toolbox--collapsed .vkedit-floating-toolbox__content{display:none}.vkedit-floating-toolbox--collapsed .vkedit-floating-toolbox__collapsed-icon{display:flex}.vkedit-floating-toolbox__title{display:flex;align-items:center;justify-content:space-between;padding:var(--vkedit-spacing-sm) var(--vkedit-spacing-md);font-size:var(--vkedit-font-size-sm);font-weight:var(--vkedit-font-weight-bold);border-bottom:1px solid var(--vkedit-color-border-dark);flex-shrink:0}.vkedit-floating-toolbox__content{padding:var(--vkedit-spacing-sm);display:flex;flex-direction:column;gap:var(--vkedit-spacing-xs)}.vkedit-floating-toolbox__content .vkedit-btn{width:100%;justify-content:center}.vkedit-stage-view{position:absolute;inset:0;width:100%;height:100%;z-index:1;overflow:hidden}.vkedit-status-bar{position:absolute;bottom:16px;left:50%;transform:translate(-50%);z-index:90;display:flex;align-items:center;justify-content:space-between;gap:16px;background:#000000a6;backdrop-filter:blur(12px);-webkit-backdrop-filter:blur(12px);border:1px solid rgba(255,255,255,.1);border-radius:8px;padding:0 16px;height:36px;color:#e0e0e0;font-size:var(--vkedit-font-size-sm);-webkit-user-select:none;user-select:none;white-space:nowrap}.vkedit-status-bar__section{display:flex;align-items:center;gap:8px}.vkedit-status-bar__zoom-controls{display:flex;align-items:center;gap:4px}.vkedit-status-bar__btn{display:flex;align-items:center;justify-content:center;width:28px;height:28px;border:none;background:transparent;border-radius:4px;cursor:pointer;color:#e0e0e0}.vkedit-status-bar__btn:hover{background:#ffffff1a}.vkedit-status-bar__zoom-value{font-size:var(--vkedit-font-size-sm);font-weight:500;min-width:44px;text-align:center;color:#e0e0e0}.vkedit-status-bar__coords{font-size:var(--vkedit-font-size-sm);font-variant-numeric:tabular-nums;color:#e0e0e0;letter-spacing:.02em}.vkedit-status-bar__cursor-icon{display:flex;align-items:center;justify-content:center;width:28px;height:28px}.vkedit-context-menu{position:absolute;z-index:200;min-width:160px;border-radius:8px;border:1px solid var(--vkedit-color-border-dark);background:var(--vkedit-color-bg-dark);backdrop-filter:var(--vkedit-blur-panel);-webkit-backdrop-filter:var(--vkedit-blur-panel);padding:4px;box-shadow:var(--vkedit-shadow-panel);color:var(--vkedit-color-text-dark);font-size:var(--vkedit-font-size-sm);display:flex;flex-direction:column;gap:2px}.vkedit-context-menu__item{display:block;width:100%;padding:4px 8px;border:none;border-radius:4px;background:transparent;font-size:var(--vkedit-font-size-sm);cursor:pointer;text-align:left;color:var(--vkedit-color-text-dark)}.vkedit-context-menu__item:hover{background:var(--vkedit-color-bg-dark-hover)}.vkedit-context-menu>button{width:100%;justify-content:flex-start}.vkedit-help-guide{position:absolute;bottom:16px;right:16px;z-index:95}.vkedit-help-guide__btn{display:flex;align-items:center;justify-content:center;width:36px;height:36px;border:1px solid rgba(255,255,255,.1);border-radius:8px;background:#000000a6;backdrop-filter:blur(12px);-webkit-backdrop-filter:blur(12px);cursor:pointer;color:#e0e0e0}.vkedit-help-guide__btn:hover{background:#ffffff26}.vkedit-help-guide__overlay{position:fixed;inset:0;z-index:999;display:flex;align-items:center;justify-content:center;background:#0000004d}.vkedit-help-guide__popup{width:380px;max-height:80vh;overflow-y:auto;border:1px solid var(--vkedit-color-border-dark, rgba(255, 255, 255, .08));border-radius:12px;background:var(--vkedit-color-bg-dark, #1e1e1e);backdrop-filter:var(--vkedit-blur-panel, blur(12px));-webkit-backdrop-filter:var(--vkedit-blur-panel, blur(12px));box-shadow:var(--vkedit-shadow-panel, 0 4px 16px rgba(0, 0, 0, .3));color:var(--vkedit-color-text-dark, #e0e0e0);font-size:var(--vkedit-font-size-base);-webkit-user-select:none;user-select:none}.vkedit-help-guide__header{display:flex;align-items:center;justify-content:space-between;padding:16px 20px 12px;border-bottom:1px solid rgba(255,255,255,.08)}.vkedit-help-guide__title{font-size:var(--vkedit-font-size-xl);font-weight:600}.vkedit-help-guide__close{display:flex;align-items:center;justify-content:center;width:28px;height:28px;border:none;border-radius:4px;background:transparent;cursor:pointer;color:#999}.vkedit-help-guide__close:hover{background:#ffffff1a;color:#e0e0e0}.vkedit-help-guide__list{padding:12px 20px 16px}.vkedit-help-guide__group{margin-bottom:14px}.vkedit-help-guide__group:last-child{margin-bottom:0}.vkedit-help-guide__group-title{font-size:var(--vkedit-font-size-xs);font-weight:600;color:#999;text-transform:uppercase;letter-spacing:.05em;margin-bottom:8px}.vkedit-help-guide__item{display:flex;align-items:center;gap:6px;padding:5px 0;line-height:1.5}.vkedit-help-guide__sep{color:#666;font-size:var(--vkedit-font-size-xs)}.vkedit-help-guide__desc{margin-left:auto;color:#999;font-size:var(--vkedit-font-size-sm);white-space:nowrap}.vkedit-help-guide__item kbd{display:inline-flex;align-items:center;justify-content:center;min-width:22px;height:22px;padding:0 5px;border:1px solid rgba(255,255,255,.15);border-radius:4px;background:#ffffff14;font-family:inherit;font-size:var(--vkedit-font-size-xs);line-height:1;color:#e0e0e0;white-space:nowrap}.vkedit-floating-property-panel,.vkedit-property-panel{position:absolute;top:52px;right:12px;width:240px;z-index:90;background:var(--vkedit-color-panel-bg);backdrop-filter:var(--vkedit-blur-panel);-webkit-backdrop-filter:var(--vkedit-blur-panel);border:1px solid var(--vkedit-color-border-dark);border-radius:8px;box-shadow:var(--vkedit-shadow-panel);max-height:calc(100vh - 64px);overflow-y:auto;font-size:var(--vkedit-font-size-sm);color:var(--vkedit-color-text-dark);transition:width .2s ease;display:flex;flex-direction:column}.vkedit-floating-property-panel__toggle{width:24px;height:24px;display:flex;align-items:center;justify-content:center;background:transparent;border:none;border-radius:4px;cursor:pointer;color:var(--vkedit-color-text-dark-secondary);flex-shrink:0}.vkedit-floating-property-panel__toggle:hover{background:var(--vkedit-color-bg-dark-hover);color:var(--vkedit-color-text-dark)}.vkedit-floating-property-panel__collapsed-icon{display:none;align-items:center;justify-content:center;height:44px;color:var(--vkedit-color-text-dark-secondary);cursor:pointer}.vkedit-floating-property-panel--collapsed{width:44px;overflow:hidden;align-items:center;justify-content:center}.vkedit-floating-property-panel--collapsed .vkedit-floating-property-panel__title{padding:var(--vkedit-spacing-xs);border-bottom:none}.vkedit-floating-property-panel--collapsed .vkedit-floating-property-panel__title span,.vkedit-floating-property-panel--collapsed .vkedit-floating-property-panel__title .vkedit-floating-property-panel__toggle,.vkedit-floating-property-panel--collapsed .vkedit-floating-property-panel__content{display:none}.vkedit-floating-property-panel--collapsed .vkedit-floating-property-panel__collapsed-icon{display:flex}.vkedit-floating-property-panel__title{display:flex;align-items:center;justify-content:space-between;padding:var(--vkedit-spacing-sm) var(--vkedit-spacing-md);font-size:var(--vkedit-font-size-sm);font-weight:var(--vkedit-font-weight-bold);border-bottom:1px solid var(--vkedit-color-border-dark);flex-shrink:0}.vkedit-floating-property-panel__content{padding:var(--vkedit-spacing-md);overflow:hidden auto;display:grid;grid-template-columns:1fr;gap:var(--vkedit-spacing-md)}.vkedit-btn{display:inline-flex;align-items:center;justify-content:center;gap:var(--vkedit-spacing-sm);white-space:nowrap;border-radius:var(--vkedit-radius-md);font-size:var(--vkedit-font-size-sm);font-weight:var(--vkedit-font-weight-medium);transition:var(--vkedit-transition-colors);cursor:pointer;border:none;line-height:1}.vkedit-btn:focus-visible{outline:none;box-shadow:0 0 0 1px var(--vkedit-color-neutral-400)}.vkedit-btn:disabled{pointer-events:none;opacity:.5}.vkedit-btn svg{pointer-events:none;width:16px;height:16px;flex-shrink:0}.vkedit-btn--default{background:var(--vkedit-color-neutral-800);color:var(--vkedit-color-white)}.vkedit-btn--default:hover{background:var(--vkedit-color-neutral-700)}.vkedit-btn--destructive{background:var(--vkedit-color-red-500);color:var(--vkedit-color-white)}.vkedit-btn--destructive:hover{background:var(--vkedit-color-red-600)}.vkedit-btn--outline{border:1px solid var(--vkedit-color-border);background:var(--vkedit-color-white)}.vkedit-btn--outline:hover,.vkedit-btn--secondary{background:var(--vkedit-color-neutral-100)}.vkedit-btn--secondary:hover{background:var(--vkedit-color-neutral-200)}.vkedit-btn--ghost:hover{background:var(--vkedit-color-neutral-100)}.vkedit-btn--link{text-decoration:underline;text-underline-offset:4px}.vkedit-btn--link:hover{text-decoration:none}.vkedit-btn--default{height:28px;padding:0 .5rem}.vkedit-btn--xs{height:24px;padding:0 .375rem;font-size:var(--vkedit-font-size-xs)}.vkedit-btn--sm{height:26px;padding:0 .375rem;font-size:var(--vkedit-font-size-xs)}.vkedit-btn--lg{height:32px;padding:0 .75rem}.vkedit-btn--icon{height:28px;width:28px;padding:0}.vkedit-btn--icon-sm{height:24px;width:24px;padding:0}.vkedit-btn--icon-lg{height:32px;width:32px;padding:0}.vkedit-toggle{display:inline-flex;align-items:center;justify-content:center;border-radius:var(--vkedit-radius-md);font-size:var(--vkedit-font-size-sm);font-weight:var(--vkedit-font-weight-medium);border:none;background:transparent;cursor:pointer;white-space:nowrap;outline:none}.vkedit-toggle:hover{background:var(--vkedit-color-neutral-100)}.vkedit-toggle--on{background:var(--vkedit-color-neutral-100);color:var(--vkedit-color-neutral-800)}.vkedit-toggle:focus-visible{box-shadow:0 0 0 3px rgb(from var(--vkedit-color-neutral-400) r g b/.5)}.vkedit-toggle:disabled{pointer-events:none;opacity:.5}.vkedit-toggle svg{pointer-events:none;width:16px;height:16px;flex-shrink:0}.vkedit-toggle--default{height:36px;min-width:36px;padding:0 var(--vkedit-spacing-sm)}.vkedit-toggle--sm{height:32px;min-width:32px;padding:0 6px}.vkedit-toggle--lg{height:40px;min-width:40px;padding:0 10px}.vkedit-input{display:flex;height:28px;width:100%;border-radius:var(--vkedit-radius-md);border:1px solid var(--vkedit-color-border);background:transparent;padding:0 var(--vkedit-spacing-sm);font-size:var(--vkedit-font-size-sm);box-shadow:var(--vkedit-shadow-sm);transition:var(--vkedit-transition-colors)}.vkedit-input::placeholder{color:var(--vkedit-color-neutral-500)}.vkedit-input:focus-visible{outline:none;box-shadow:0 0 0 1px var(--vkedit-color-neutral-400)}.vkedit-input:disabled{cursor:not-allowed;opacity:.5}.vkedit-label{font-size:var(--vkedit-font-size-sm);font-weight:var(--vkedit-font-weight-medium);line-height:1;margin-bottom:var(--vkedit-spacing-xs)}.vkedit-select{display:flex;height:28px;width:100%;border-radius:var(--vkedit-radius-md);border:1px solid var(--vkedit-color-border);background:transparent;padding:0 var(--vkedit-spacing-sm);font-size:var(--vkedit-font-size-sm);box-shadow:var(--vkedit-shadow-sm);transition:var(--vkedit-transition-colors);cursor:pointer}.vkedit-select:focus-visible{outline:none;box-shadow:0 0 0 1px var(--vkedit-color-neutral-400)}.vkedit-select:disabled{cursor:not-allowed;opacity:.5}.vkedit-switch{display:inline-flex;height:20px;width:36px;flex-shrink:0;cursor:pointer;align-items:center;border-radius:var(--vkedit-radius-full);border:2px solid transparent;background:#d4d4d4;transition:var(--vkedit-transition-colors);box-shadow:var(--vkedit-shadow-sm);position:relative}.vkedit-switch__input{position:absolute;opacity:0;width:0;height:0}.vkedit-switch__thumb{display:block;height:16px;width:16px;border-radius:var(--vkedit-radius-full);background:var(--vkedit-color-white);box-shadow:var(--vkedit-shadow-lg);transition:transform .15s ease}.vkedit-switch:has(.vkedit-switch__input:checked){background:#6a87b7}.vkedit-switch:has(.vkedit-switch__input:checked) .vkedit-switch__thumb{transform:translate(16px)}.vkedit-switch:has(.vkedit-switch__input:disabled){cursor:not-allowed;opacity:.5}.vkedit-input-mm{display:flex;align-items:center;gap:0}.vkedit-input-mm__btn{display:flex;align-items:center;justify-content:center;height:28px;width:28px;border:1px solid var(--vkedit-color-border);background:transparent;font-size:var(--vkedit-font-size-lg);cursor:pointer;-webkit-user-select:none;user-select:none}.vkedit-input-mm__btn:first-child{border-radius:var(--vkedit-radius-md) 0 0 var(--vkedit-radius-md);border-right:none}.vkedit-input-mm__btn:last-child{border-radius:0 var(--vkedit-radius-md) var(--vkedit-radius-md) 0;border-left:none}.vkedit-input-mm__btn:hover{background:var(--vkedit-color-neutral-100)}.vkedit-input-mm__field{flex:1}.vkedit-input-mm__display,.vkedit-input-mm__input{display:flex;height:28px;width:100%;border:1px solid var(--vkedit-color-border);border-left:none;border-right:none;background:transparent;padding:0 var(--vkedit-spacing-sm);font-size:var(--vkedit-font-size-sm);text-align:center;transition:var(--vkedit-transition-colors)}.vkedit-input-mm__display:focus-visible,.vkedit-input-mm__input:focus-visible{outline:none;box-shadow:0 0 0 1px var(--vkedit-color-neutral-400);position:relative;z-index:1}.vkedit-dropdown{position:relative;display:inline-block}.vkedit-dropdown__overlay{position:fixed;top:0;left:0;width:100%;height:100%;z-index:150}.vkedit-dropdown__content{position:fixed;z-index:160;min-width:160px;max-height:300px;overflow-x:hidden;overflow-y:auto;border-radius:8px;border:1px solid var(--vkedit-color-border-dark);background:var(--vkedit-color-bg-dark);backdrop-filter:var(--vkedit-blur-panel);-webkit-backdrop-filter:var(--vkedit-blur-panel);padding:4px;box-shadow:var(--vkedit-shadow-panel);color:var(--vkedit-color-text-dark)}.vkedit-dropdown__label{padding:4px 8px;font-size:var(--vkedit-font-size-sm);font-weight:var(--vkedit-font-weight-medium);color:var(--vkedit-color-text-dark-secondary)}.vkedit-dropdown__sep{height:1px;margin:4px 0;background:var(--vkedit-color-border-dark)}.vkedit-dropdown__item{display:flex;align-items:center;gap:var(--vkedit-spacing-sm);width:100%;padding:4px 8px;border:none;border-radius:4px;background:transparent;font-size:var(--vkedit-font-size-sm);cursor:pointer;text-align:left;color:var(--vkedit-color-text-dark)}.vkedit-dropdown__item:hover{background:var(--vkedit-color-bg-dark-hover)}.vkedit-dropdown__item svg{width:16px;height:16px;flex-shrink:0}.vkedit-scale-enter-active{animation:vkedit-scale-in .15s ease-out}.vkedit-scale-leave-active{animation:vkedit-scale-out .15s ease-in}body:has(.vkedit-editor) .vkedit-dropdown__content{background:var(--vkedit-color-bg-dark);border-color:var(--vkedit-color-border-dark);color:var(--vkedit-color-text-dark)}body:has(.vkedit-editor) .vkedit-dropdown__item{color:var(--vkedit-color-text-dark)}body:has(.vkedit-editor) .vkedit-dropdown__item:hover{background:var(--vkedit-color-bg-dark-hover)}.vkedit-btn-group{display:flex;align-items:stretch;width:fit-content}.vkedit-property__title{font-size:var(--vkedit-font-size-xl);font-weight:var(--vkedit-font-weight-bold);padding-bottom:var(--vkedit-spacing-sm);color:var(--vkedit-color-text-dark)}.vkedit-property__label{font-size:var(--vkedit-font-size-sm);color:var(--vkedit-color-text-dark-secondary);display:block}.vkedit-property__grid{display:grid;grid-template-columns:repeat(2,1fr);gap:var(--vkedit-spacing-md);align-items:center;padding:var(--vkedit-spacing-sm) 0}.vkedit-property__col-full{grid-column:1/-1}.vkedit-chart__field{width:100%;border:1px solid var(--vkedit-color-border);border-radius:var(--vkedit-radius-md);padding:0 var(--vkedit-spacing-sm)}.vkedit-chart__input{width:100%;border:1px solid var(--vkedit-color-border);border-radius:var(--vkedit-radius-md);padding:0 var(--vkedit-spacing-sm);height:36px}.vkedit-chart__textarea{width:100%;border:1px solid var(--vkedit-color-border);border-radius:var(--vkedit-radius-md);padding:var(--vkedit-spacing-xs) var(--vkedit-spacing-sm);font-family:var(--vkedit-font-mono);font-size:var(--vkedit-font-size-xs);height:192px;resize:vertical}.vkedit-chart__error{color:var(--vkedit-color-red-500);font-size:var(--vkedit-font-size-xs);margin-top:4px}.vkedit-chart__section{padding-top:var(--vkedit-spacing-md);font-weight:var(--vkedit-font-weight-bold)}.vkedit-input-mm__input[data-v-47959cb1]::-webkit-outer-spin-button,.vkedit-input-mm__input[data-v-47959cb1]::-webkit-inner-spin-button{-webkit-appearance:none;margin:0}.vkedit-input-mm__input[data-v-47959cb1]{-moz-appearance:textfield}.vkedit-input-mm__input[data-v-f78ba536]::-webkit-outer-spin-button,.vkedit-input-mm__input[data-v-f78ba536]::-webkit-inner-spin-button{-webkit-appearance:none;margin:0}.vkedit-input-mm__input[data-v-f78ba536]{-moz-appearance:textfield}.vkedit-icon[data-v-b4ed0b97]{display:inline-flex;align-items:center;justify-content:center;flex-shrink:0;line-height:1}.vkedit-icon[data-v-b4ed0b97] svg{width:100%;height:100%;display:block;fill:currentColor}.vkedit-toolbar-enter-active[data-v-f04619fe]{animation:vkedit-toolbar-enter .2s ease-out}.vkedit-toolbar-leave-active[data-v-f04619fe]{animation:vkedit-toolbar-leave .15s ease-in}
package/dist/vkedit.es.js CHANGED
@@ -1,4 +1,4 @@
1
- import { A as s, J as n, e as t, K as o, O as l, P as r, L as i, M as m, N as P, B as u, f as p, aI as g, aJ as d, aK as C, b as T, aH as E, h as c, d as y, Y as h, Z as S, S as B, W as b, X as x, a as M, Q as k, C as L, $ as V, aG as R, D as A, E as I, a0 as v, aM as H, aL as w, a1 as D, a2 as G, a3 as N, a4 as Q, a5 as O, a6 as U, a7 as f, ab as F, ac as K, a8 as j, a9 as q, aa as z, ad as J, ae as Z, af as _, ag as W, ah as X, ai as Y, aj as $, an as aa, ao as ea, ak as sa, al as na, am as ta, R as oa, ap as la, ar as ra, aq as ia, as as ma, aw as Pa, ax as ua, ay as pa, at as ga, au as da, av as Ca, aC as Ta, aD as Ea, aE as ca, i as ya, az as ha, aA as Sa, aB as Ba, aF as ba, T as xa, U as Ma, j as ka, r as La, s as Va, l as Ra, V as Aa, q as Ia, p as va, m as Ha, n as wa, o as Da, k as Ga, t as Na, u as Qa, v as Oa, w as Ua, x as fa, y as Fa, z as Ka, F as ja, H as qa, G as za, I as Ja } from "./index-Bisex1w7.js";
1
+ import { A as s, J as n, e as t, K as o, O as l, P as r, L as i, M as m, N as P, B as u, f as p, aI as g, aJ as d, aK as C, b as T, aH as E, h as c, d as y, Y as h, Z as S, S as B, W as b, X as x, a as M, Q as k, C as L, $ as V, aG as R, D as A, E as I, a0 as v, aM as H, aL as w, a1 as D, a2 as G, a3 as N, a4 as Q, a5 as O, a6 as U, a7 as f, ab as F, ac as K, a8 as j, a9 as q, aa as z, ad as J, ae as Z, af as _, ag as W, ah as X, ai as Y, aj as $, an as aa, ao as ea, ak as sa, al as na, am as ta, R as oa, ap as la, ar as ra, aq as ia, as as ma, aw as Pa, ax as ua, ay as pa, at as ga, au as da, av as Ca, aC as Ta, aD as Ea, aE as ca, i as ya, az as ha, aA as Sa, aB as Ba, aF as ba, T as xa, U as Ma, j as ka, r as La, s as Va, l as Ra, V as Aa, q as Ia, p as va, m as Ha, n as wa, o as Da, k as Ga, t as Na, u as Qa, v as Oa, w as Ua, x as fa, y as Fa, z as Ka, F as ja, H as qa, G as za, I as Ja } from "./index-Aa1HXlw6.js";
2
2
  export {
3
3
  s as AddElementCommand,
4
4
  n as Align,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vkedit",
3
- "version": "3.2.5",
3
+ "version": "3.2.7",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "engines": {
@@ -18,6 +18,7 @@
18
18
  "scripts": {
19
19
  "dev": "vite",
20
20
  "build": "vue-tsc --noEmit && vite build && pnpm pack",
21
+ "build:playground": "vue-tsc --noEmit && vite build --config vite.playground.config.ts",
21
22
  "prepublishOnly": "npm run build",
22
23
  "preview": "vite preview",
23
24
  "build-only": "vite build",
@@ -65,10 +66,15 @@
65
66
  "component"
66
67
  ],
67
68
  "license": "MIT",
69
+ "author": "pwg <168715824@qq.com>",
70
+ "homepage": "https://vkedit.org",
68
71
  "repository": {
69
72
  "type": "git",
70
73
  "url": "https://github.com/pwg-code/vkedit.git"
71
74
  },
75
+ "bugs": {
76
+ "url": "https://github.com/pwg-code/vkedit/issues"
77
+ },
72
78
  "devDependencies": {
73
79
  "@iconify/vue": "^5.0.0",
74
80
  "@tsconfig/node22": "^22.0.2",