@deepseek-ai/dsh-client-ui-sidebar-documentpreview 0.1.7-alpha.2 → 0.1.7-rc.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.i18n.yaml CHANGED
@@ -1,6 +1,46 @@
1
- # Bilingual-pair consistency record (docs/i18n/README.md): the git blob hash of each
2
- # side as of the last confirmed-consistent state. Both languages carry equal authority;
3
- # after editing either side, bring the other along and re-record with:
1
+ # Bilingual-pair consistency record for README.md (docs/i18n/README.md): per heading
2
+ # section, a hash of its English and Chinese blocks outside code blocks and generated regions.
3
+ # After editing either side, bring the other along and re-record with:
4
4
  # pnpm run verify-translation-pairing --write packages/client/ui-sidebar-documentpreview/README.md
5
- README.md: 5507bd89f07bfd6225d4ecc1bc4500ceb2e30fe8
6
- README.zh.md: eec96c28654ae01aca6b89862d503af6c12296e8
5
+ /:
6
+ en: ef50065f5ff17aa1
7
+ zh: ee5d2b7986739fca
8
+ /deepseek-ai-dsh-client-ui-sidebar-documentpreview:
9
+ en: 5168e03d461318f5
10
+ zh: 7ad97d70ee331bfd
11
+ /deepseek-ai-dsh-client-ui-sidebar-documentpreview/summary:
12
+ en: a74c16667d0baada
13
+ zh: 4fd709ff9f98b84f
14
+ /deepseek-ai-dsh-client-ui-sidebar-documentpreview/table-of-contents:
15
+ en: 0dd8c3a22e28aacf
16
+ zh: c27c11bf4b5cceba
17
+ /deepseek-ai-dsh-client-ui-sidebar-documentpreview/what-it-registers:
18
+ en: a8eaf01a3a3390ee
19
+ zh: ddea36dbcc4a0159
20
+ /deepseek-ai-dsh-client-ui-sidebar-documentpreview/addresses:
21
+ en: 949156aa02ec8b07
22
+ zh: d3675754e2a37b5d
23
+ /deepseek-ai-dsh-client-ui-sidebar-documentpreview/how-it-reads:
24
+ en: 5d8bf2e43d9b6dd0
25
+ zh: b0d2d1d5a6f520db
26
+ /deepseek-ai-dsh-client-ui-sidebar-documentpreview/excel-preview:
27
+ en: b99b0e0b8efc2853
28
+ zh: 4327352d1334fc6b
29
+ /deepseek-ai-dsh-client-ui-sidebar-documentpreview/office-preview:
30
+ en: 372d8ce6492e6896
31
+ zh: 912f613bc9221aa3
32
+ /deepseek-ai-dsh-client-ui-sidebar-documentpreview/navigation:
33
+ en: 5cd81a7b3cdc83bd
34
+ zh: 4cdd1b7ede497925
35
+ /deepseek-ai-dsh-client-ui-sidebar-documentpreview/model-experience:
36
+ en: ca1deb99d0e44755
37
+ zh: f285fc56cee669ec
38
+ /deepseek-ai-dsh-client-ui-sidebar-documentpreview/model-experience/kv-cache-effect:
39
+ en: 7edb4c0bb5f13847
40
+ zh: ae5d0bbebe4aa563
41
+ /deepseek-ai-dsh-client-ui-sidebar-documentpreview/known-limitations-and-deferred-work:
42
+ en: 7be2ad2e198131f8
43
+ zh: 21b35eae72a49ad2
44
+ /deepseek-ai-dsh-client-ui-sidebar-documentpreview/known-limitations-and-deferred-work/dev-note:
45
+ en: 3d8904cb970145a3
46
+ zh: a0c0cddcfedf9e42
package/README.md CHANGED
@@ -46,7 +46,9 @@ After all text pages load, Markdown images use the authenticated `/api/file` rou
46
46
  <a id="how-it-reads"></a>
47
47
  ## How it reads
48
48
 
49
- Developer tools selects the HTML preview policy in both Web and desktop. The renderer receives `interactivePreview` from plugin assembly. Off uses a DOMPurify-sanitized complete static document in an iframe with no sandbox permissions: CSP blocks scripts, external resources, connections, forms, and nested frames; all `href` and `xlink:href` attributes, refresh directives, and declarative shadow roots are removed before reparsing. Inline styles and data images remain visible, and related files are not read. On uses the scripted Blob preview described below. A mode change unmounts the previous frame and aborts its pending related-file reads. Static preview releases CSS/JS resource subscriptions and keeps the root file watched. Other document formats retain their own policies.
49
+ Coding Tools selects the HTML preview policy in both Web and desktop. The renderer receives `interactivePreview` from plugin assembly. Off uses a DOMPurify-sanitized complete static document in an iframe with no sandbox permissions: CSP blocks scripts, external resources, connections, forms, and nested frames; all `href` and `xlink:href` attributes, refresh directives, and declarative shadow roots are removed before reparsing. Inline styles and data images remain visible, and related files are not read. On uses the scripted Blob preview described below. A mode change unmounts the previous frame and aborts its pending related-file reads. Static preview releases CSS/JS resource subscriptions and keeps the root file watched. Other document formats retain their own policies.
50
+
51
+ Both HTML modes set the initial iframe name to `dsh-sidebar-html-<tab-id>` for Desktop shortcut routing. This correlation does not grant the preview access to the parent document.
50
52
 
51
53
  The body reads its record, navigation and lifetime through `useTabInfo().tab`. `useResource<'file'>(tab.contentId)` supplies metadata; ordinary inject callbacks supply content reads:
52
54
 
@@ -55,22 +57,22 @@ The body reads its record, navigation and lifetime through `useTabInfo().tab`. `
55
57
  - **Complete bytes** — PDF, HTML, common images, and spreadsheets call `remote.workspaceFiles.readBytes(sessionId, path, {}, signal)`. The binary Remote returns `data: Uint8Array<ArrayBuffer>` directly for `{ kind: 'bytes', data }`. The Host's `maxFileBytes` cap rejects oversized files rather than truncating them. PDF and spreadsheet renderers copy retained bytes before Worker transfer, keeping the Preview buffer usable. Bytes stay in transient view state, never persisted layouts or Session JSONL. Loading-mode changes retire previous results.
56
58
  - **Reload** — manual reload rereads only the current Preview tab through its Remote callbacks, preserving its scroll preference and retiring older requests. Automatic refresh uses the same callbacks after a `ResourceGroup` member changes. Each member's first metadata establishes a baseline without triggering reload or first-read version reconciliation; later changes received during a read remain pending for another refresh. Reads neither refresh shared metadata nor clear another tab's notice.
57
59
 
58
- When Developer tools is enabled, HTML fills the body edge to edge in a Blob iframe with exactly `sandbox="allow-scripts"`, without `allow-same-origin`; scripts cannot access the parent application's origin or file reader. The renderer loads directly declared relative `.js` classic scripts and `.css` stylesheets through its injected Remote callback, with fixed safety limits of 4 MiB per asset, 32 MiB total, and 64 distinct assets. Host code resolves the related path, and `readBytes` with `baseFile` returns native bytes. The dependency Resource is added after the read returns, using its `absolutePath` or a string `error.details.path` on failure; without a Host path, the Client does not guess one. Inside the renderer, base64 is used only to embed the iframe bootstrap payload in script text. A `<base href>` leaves dependency resolution to the browser, as do HTTPS resources. Local module imports, CSS `url()`/`@import`, and dynamic `fetch` do not use Host file access. Read failures, invalid UTF-8, or exceeded limits fail the preview rather than publishing a partial asset package. Replacing or unmounting the document releases its Blob URL.
60
+ When Coding Tools is enabled, HTML fills the body edge to edge in a Blob iframe with exactly `sandbox="allow-scripts"`, without `allow-same-origin`; scripts cannot access the parent application's origin or file reader. The renderer loads directly declared relative `.js` classic scripts and `.css` stylesheets through its injected Remote callback, with fixed safety limits of 4 MiB per asset, 32 MiB total, and 64 distinct assets. Host code resolves the related path, and `readBytes` with `baseFile` returns native bytes. The dependency Resource is added after the read returns, using its `absolutePath` or a string `error.details.path` on failure; without a Host path, the Client does not guess one. Inside the renderer, base64 is used only to embed the iframe bootstrap payload in script text. A `<base href>` leaves dependency resolution to the browser, as do HTTPS resources. Local module imports, CSS `url()`/`@import`, and dynamic `fetch` do not use Host file access. Read failures, invalid UTF-8, or exceeded limits fail the preview rather than publishing a partial asset package. Replacing or unmounting the document releases its Blob URL.
59
61
 
60
62
  PNG, JPEG, GIF, WebP, BMP, ICO, and SVG render through Blob URLs in an `<img>` static-image context, rounded inside a 12px inset. Images default to fit width without enlarging content smaller than the pane; 100% uses the image's intrinsic CSS-pixel width. The shared zoom controls can produce horizontal and vertical scrolling, but do not provide drag-to-pan. Zoom changes retain the same `<img>` and Blob URL, so animated images continue playing. Raster formats can soften above their intrinsic size, while SVG remains on the browser's vector rendering path. SVG markup never enters the application DOM or an iframe, so its scripts cannot execute or reach the parent page. Replacing or unmounting the image revokes its Blob URL.
61
63
 
62
- Shared copy comes from `sidebarDocumentPreview`; each builtin renderer owns its localized labels. PDF and converted Office previews use a graphite background in light mode and a matte-black background in dark mode, with subtle page shadows and original document colors. PDF and image previews share a floating control with **Fit width**, 25%, 50%, 100%, 150%, and 200% choices plus 25% incremental zoom across the 25%–400% fixed range. Fit width is the default and tracks pane resizing; 100% means the PDF's 96-DPI page size or the image's intrinsic CSS-pixel size. On fine pointers, the control starts hidden, slides up when the pointer enters the bottom 72 CSS pixels, and slides down after a 420 ms leave delay; hover, keyboard focus, an open menu, and an active gesture keep it visible, while devices without hover keep it visible continuously. Chromium maps a macOS trackpad pinch to the same live, pointer-anchored path as Ctrl+wheel; the control displays the gesture percentage, and the settled value survives body remounts until the tab closes. HTML previews do not expose zoom controls.
64
+ Shared copy comes from `sidebarDocumentPreview`; each builtin renderer owns its localized labels. PDF and converted Office previews use a cool light-grey background in light mode and a matte-black background in dark mode, with subtle page shadows and original document colors. PDF and image previews share a floating control with **Fit width**, 25%, 50%, 100%, 150%, and 200% choices plus 25% incremental zoom across the 25%–400% fixed range. Fit width is the default and tracks pane resizing; 100% means the PDF's 96-DPI page size or the image's intrinsic CSS-pixel size. On fine pointers, the control starts hidden, slides up when the pointer enters the bottom 72 CSS pixels, and slides down after a 420 ms leave delay; hover, keyboard focus, an open menu, and an active gesture keep it visible, while devices without hover keep it visible continuously. Chromium maps a macOS trackpad pinch to the same live, pointer-anchored path as Ctrl+wheel; the control displays the gesture percentage, and the settled value survives body remounts until the tab closes. HTML previews do not expose zoom controls. After zoom settles or fit width changes, nearby PDF pages redraw at the resolved scale multiplied by the device pixel ratio. The previous bitmap and selectable text stay visible until the replacement bitmap is ready; offscreen pages refresh when they approach the viewport.
63
65
 
64
- Initial reads, additional pages, and HTML/PDF/image preparation share the ongoing `StateDot` loader, which exposes its label to assistive technology and respects reduced-motion preferences; every wait before content exists centres the loader in the pane, so opening a file shows one indicator in one position until the body appears. Loaded pages stay visible while another page loads. The PDF body loads its package-local `client.pdf.js` chunk only when a PDF preview mounts; PDF.js, its Worker source, and embedded support data stay out of the startup `client.js`. PDF pages fill the pane's width edge to edge as one vertical sequence and render lazily near the viewport; an unrendered page holds its place as a quiet 3:4 placeholder block. PDF.js’s official TextLayerBuilder manages selection boundaries and normalized copying over an aligned text layer. Its companion styles keep blank line breaks unhighlighted; alignment accounts for PDF page units, page rotation, and viewport resizing, and page disposal cancels both layers. Image-only PDFs contain no selectable text. Code previews show a tertiary-colored language label and a copy icon with a tooltip; wrapping remains in the document toolbar. They show source line numbers by default without including them in copied text; plain text uses the same font size and line height as code. Code sits on the pane's own background rather than the chat card's fill; its banner is adjacent to a full-height inner scrollport, so both scrollbars begin below the copy control.
66
+ Initial reads and renderer preparation, including Office conversion, share a centered 28px ongoing `StateDot` with the visible localized status “Rendering document...”. The status exposes the same accessible name and respects reduced-motion preferences. Additional text pages keep a compact inline spinner while loaded content stays visible. The PDF body loads its package-local `client.pdf.js` chunk only when a PDF preview mounts; PDF.js, its Worker source, and embedded support data stay out of the startup `client.js`. PDF and converted Word/PowerPoint pages form a vertical sequence with 12px page gaps and a 12px outer inset showing the theme-specific document background; fit width reserves this inset, and pages render lazily near the viewport; an unrendered page holds its place as a quiet 3:4 placeholder block. PDF.js’s official TextLayerBuilder manages selection boundaries and normalized copying over an aligned text layer. Its companion styles keep blank line breaks unhighlighted; alignment accounts for PDF page units, page rotation, and viewport resizing, and page disposal cancels both layers. Image-only PDFs contain no selectable text. Code previews show a tertiary-colored language label and a copy icon with a tooltip; wrapping remains in the document toolbar. They show source line numbers by default without including them in copied text; plain text uses the same font size and line height as code. Code sits on the pane's own background rather than the chat card's fill; its banner is adjacent to a full-height inner scrollport, so both scrollbars begin below the copy control.
65
67
 
66
68
  <a id="excel-preview"></a>
67
69
  ## Excel preview
68
70
 
69
- Open `.xlsx`, `.xls`, `.csv`, and `.tsv` directly in the browser with worksheet tabs, cell selection, copying, and a read-only formula bar. XLSX retains fonts, solid fills, borders, number formats, rich text, merged cells, row and column sizes, hidden rows/columns/sheets, and frozen headings. XLS retains saved values, formulas, number formats, merges, and available row/column metadata; fonts, borders, and frozen panes are unsupported. Workbooks display saved formula results without recalculating; missing results remain blank, and a compact formula-bar warning marks workbooks whose displayed results may be incomplete or inaccurate. The workbook viewport follows preview pane size changes without reloading its sheets or selection. Spreadsheet preview does not call the Office conversion service.
71
+ Open `.xlsx`, `.xls`, `.csv`, and `.tsv` directly in the browser with worksheet tabs, cell selection, copying, and a read-only formula bar. XLSX retains fonts, solid fills, borders, number formats, rich text, merged cells, row and column sizes, hidden rows/columns/sheets, and frozen headings. XLS retains saved values, formulas, number formats, merges, and available row/column metadata; fonts, borders, and frozen panes are unsupported. Workbooks display saved formula results without recalculating; missing results remain blank, and a compact formula-bar warning marks workbooks whose displayed results may be incomplete or inaccurate. The workbook viewport fills the preview pane and follows its size changes without reloading its sheets or selection. Worksheet tabs start at the left edge; overflowing tabs scroll with horizontal trackpad gestures or left/right navigation beside a separate zoom control. Spreadsheet controls retain dark text on their light background in both app themes. Pixel-based trackpad gestures pan the grid on both axes together, including diagonally, at the gesture’s speed; frozen headings stay fixed. Reversing direction at a sheet edge retains the next gesture’s movement. Selection statistics and inactive worksheet menu arrows are hidden. Frozen headings remain fixed while scrolling, without freeze dividers or drag handles. Spreadsheet preview does not call the Office conversion service.
70
72
 
71
73
  XLSX preview omits DrawingML parts from an in-memory copy before parsing and ignores worksheet drawing references. The original file and worksheet XML remain unchanged. A notice above the table lists detected charts, images, shapes, and conditional formatting that are not displayed, and recommends opening the workbook in a system application. Files without these detected features have no notice; formula warnings remain separate.
72
74
 
73
- CSV and TSV default to the spreadsheet viewer and also offer Plain text. Commas and tabs delimit their fields respectively; quoted separators, escaped quotes, multiline fields, empty fields, and unequal row lengths are supported. The first row remains data. Values remain literal strings, including leading zeros, dates, booleans, and formula-looking text. Text files accept UTF-8 or BOM-marked UTF-16; invalid encoding receives conversion guidance. Malformed quoted fields fail the table preview rather than silently dropping data.
75
+ CSV and TSV default to the spreadsheet viewer and also offer Plain text; CSV additionally offers syntax-highlighted Code. Commas and tabs delimit their fields respectively; quoted separators, escaped quotes, multiline fields, empty fields, and unequal row lengths are supported. The first row remains data. Values remain literal strings, including leading zeros, dates, booleans, and formula-looking text. Text files accept UTF-8 or BOM-marked UTF-16; invalid encoding receives conversion guidance. Malformed quoted fields fail the table preview rather than silently dropping data.
74
76
 
75
77
  Configure `excel` on the same `ui-sidebar-documentpreview` entry. These limits complement the Host's complete-file read limit; they do not cap browser process memory or decompression allocations.
76
78
 
@@ -82,7 +84,7 @@ Configure `excel` on the same `ui-sidebar-documentpreview` entry. These limits c
82
84
 
83
85
  The lazy Excel chunk bundles FortuneSheet, ExcelJS for XLSX, SheetJS CE for XLS, and PapaParse for CSV/TSV. Package-local, React-independent adapters map parser output directly to FortuneSheet cells and share cell formatting and initial selection. Third-party license texts remain in the published chunk; SheetJS CE retains its Apache-2.0 terms. Each parse owns a disposable Worker and transfers a copy of retained file bytes; replacement, unmount, failure, and timeout terminate that Worker. The stylesheet is scoped to the Excel preview. Charts, drawings/images, pivot tables, conditional formatting, editing, recalculation, and export are unsupported; font availability, Excel column-width approximation, and theme-tint approximation can affect fidelity. Hyperlinks display as text without loading their targets. ExcelJS decodes entity spellings in cached XLSX string formula results again; a saved literal `&lt;` is displayed as `<`.
84
86
 
85
- The read-only formula bar displays formulas and cell text literally. Copying preserves an HTML table with escaped cell contents, including saved formula results. The [FortuneSheet patch rationale](../../../.agents/notes/implemented/feature/2026-09-16-browser-excel-preview.md) explains the requirements for retaining these behaviors and worksheet selection when upgrading the dependency.
87
+ The read-only formula bar displays formulas and cell text literally on one line, with horizontal scrolling for long content. Copying preserves an HTML table with escaped cell contents, including saved formula results. The [FortuneSheet patch rationale](../../../.agents/notes/implemented/feature/2026-09-16-browser-excel-preview.md) explains the requirements for retaining these behaviors and worksheet selection when upgrading the dependency.
86
88
 
87
89
  The pinned [ExcelJS patch](../../../patches/exceljs@4.4.0.patch) resolves the workbook, styles, shared strings, worksheets, comments, Tables, and VML through package relationships, including absolute and relative targets and ASCII case-equivalent part names, and recognizes SpreadsheetML and VML names by namespace URI. Strict OOXML SpreadsheetML and relationship URIs map to the same supported preview features; this is not full Strict conformance. XML parts accept UTF-8 and either byte order of UTF-16; CDATA contributes literal text. Drawing and conditional-format notices follow relationships regardless of part directories. Unreferenced `xl/drawings/*.xml` parts and their relationship files are also omitted, without adding notices; comment VML remains. Missing referenced parts and ambiguous case-equivalent ZIP entries fail the preview. Comments and Table metadata survive parsing but have no dedicated preview controls. The patch covers the Node sources and `dist/exceljs.js`; its browser entry selects that patched bundle. Dependency upgrades must preserve both entry paths and pass the [independent-writer regressions and fuzz diagnostics](tests/fuzz/README.md).
88
90
 
@@ -112,6 +114,8 @@ Office registration, loading, caching, and font notices live in `src/client/offi
112
114
 
113
115
  The Office Remote returns converted PDFs as native `Uint8Array` values through Connection's multipart binary transport. Renderers borrow retained bytes read-only and copy them before Worker transfer.
114
116
 
117
+ The page refresh shortcut reuses the selected preview’s reload operation, including its request retirement and scroll retention. The header reload tooltip and ARIA combination follow the effective shortcut binding.
118
+
115
119
  </details>
116
120
 
117
121
  <a id="navigation"></a>
@@ -134,7 +138,7 @@ No direct effect; what the user reads here never enters a model request.
134
138
  - **Preview, not editing.** The viewers provide no file editing or shared search interface; a directory address fails with `not-regular-file`. Unknown extensions use the plain-text reader and remain subject to its UTF-8/NUL checks.
135
139
  - **Office conversion limits.** The preview does not launch native Office editors or download an engine. Binary `.doc` and `.ppt` files return no missing-font diagnostics. Conversion fidelity and resource limits belong to the [LibreOffice provider](../../document/office-to-pdf/README.md).
136
140
  - **Sequential text and bounded complete files.** Deep source lines require the preceding pages; PDF, HTML, and images require a complete result within the Host's `maxFileBytes` cap.
137
- - **PDF zoom does not increase raster resolution.** PDF pages render at 96 DPI times the device pixel ratio, subject to the existing 16-million-pixel canvas limit, and fixed zoom enlarges that bitmap. High percentages can therefore soften page text; viewport-near rerendering at the settled zoom remains deferred.
141
+ - **PDF raster allocation is bounded.** Each page bitmap is capped at 16,777,216 pixels; very large pages or high zoom on high-density displays can still render below device resolution.
138
142
  - **Byte-view scroll state is not restored.** PDF, HTML, and images can return to the top when their renderer remounts or reloads; fixed PDF and image zoom can overflow horizontally, and HTML iframe scrolling belongs to its opaque browsing context.
139
143
  - **Finite local HTML dependencies.** Only direct classic `.js` and stylesheet `.css` references are packed. Browser-resolved resources retain browser origin and network restrictions; no runtime file-read bridge is exposed to the iframe.
140
144
  - **Scroll writes are unthrottled.** Every scroll event records its offset in the store; the line blocks are memoized so the resulting re-render hands React the same elements back.
package/README.zh.md CHANGED
@@ -46,7 +46,9 @@ tab 使用 `fileAddressFor` 构造的 Session 地址,携带相对或绝对路
46
46
  <a id="how-it-reads"></a>
47
47
  ## 怎么读
48
48
 
49
- Web 和桌面端均通过开发者工具选择 HTML 预览策略。渲染器从插件组装层接收 `interactivePreview`。关闭时,将经 DOMPurify 清理的完整静态文档放入不授予沙箱权限的 iframe:CSP 禁止脚本、外部资源、连接、表单和嵌套框架;所有 `href` 和 `xlink:href` 属性、刷新指令及声明式 Shadow DOM 均在重新解析前被移除。行内样式和 data 图片仍可显示,不读取关联文件。开启时使用下述支持脚本的 Blob 预览。切换模式会卸载之前的框架并中止其待处理关联文件读取。静态预览释放 CSS/JS 的 Resource 订阅,根文件继续监听。其他文档格式保持各自策略。
49
+ Web 和桌面端均通过代码工作工具选择 HTML 预览策略。渲染器从插件组装层接收 `interactivePreview`。关闭时,将经 DOMPurify 清理的完整静态文档放入不授予沙箱权限的 iframe:CSP 禁止脚本、外部资源、连接、表单和嵌套框架;所有 `href` 和 `xlink:href` 属性、刷新指令及声明式 Shadow DOM 均在重新解析前被移除。行内样式和 data 图片仍可显示,不读取关联文件。开启时使用下述支持脚本的 Blob 预览。切换模式会卸载之前的框架并中止其待处理关联文件读取。静态预览释放 CSS/JS 的 Resource 订阅,根文件继续监听。其他文档格式保持各自策略。
50
+
51
+ 两种 HTML 模式均将 iframe 初始名称设为 `dsh-sidebar-html-<tab-id>`,供 Desktop 快捷键路由关联目标。这种关联不授予预览访问父文档的权限。
50
52
 
51
53
  正文通过 `useTabInfo().tab` 读取记录、导航和生命周期。`useResource<'file'>(tab.contentId)` 提供元数据,普通 inject 回调提供内容读取:
52
54
 
@@ -55,22 +57,22 @@ Web 和桌面端均通过开发者工具选择 HTML 预览策略。渲染器从
55
57
  - **完整字节** —— PDF、HTML、常见图片和表格调用 `remote.workspaceFiles.readBytes(sessionId, path, {}, signal)`。二进制 Remote 直接返回 `data: Uint8Array<ArrayBuffer>`,供 `{ kind: 'bytes', data }` 使用。Host 的 `maxFileBytes` 上限拒绝超大文件,不截断。PDF 和表格渲染器在传给 Worker 前复制保留的字节,使 Preview 缓冲区仍可使用。字节仅保存在临时视图状态中,绝不进入持久布局或 Session JSONL。加载模式变化会淘汰先前结果。
56
58
  - **重新载入** —— 手动重新载入仅让当前 Preview tab 通过自己的 Remote 回调重读,保留滚动偏好并淘汰旧请求。`ResourceGroup` 成员变化后,自动刷新使用相同回调。各成员首次元数据仅建立基线,不触发重新载入或首读版本对账;后续在读取期间收到的变化仍会留待下一次刷新。读取既不刷新共享元数据,也不清除其它 tab 的提示。
57
59
 
58
- 开启开发者工具时,HTML 以贴合正文四边的 Blob iframe 运行,沙箱属性严格为 `sandbox="allow-scripts"`,不含 `allow-same-origin`;脚本无法访问父应用的源或文件读取接口。渲染器通过注入的 Remote 回调,加载直接声明的相对 `.js` 经典脚本和 `.css` 样式表;固定安全上限为单个资源 4 MiB、总计 32 MiB、64 个不同资源。Host 代码解析关联路径,带 `baseFile` 的 `readBytes` 返回原生字节。依赖 Resource 在读取返回后加入,使用返回的 `absolutePath`,失败时则使用字符串类型的 `error.details.path`;没有 Host 路径时,Client 不自行猜测。在渲染器内部,base64 仅用于把 iframe 引导载荷嵌入脚本文本。`<base href>` 将依赖解析交给浏览器,HTTPS 资源也由浏览器处理。本地模块 import、CSS `url()`/`@import` 和动态 `fetch` 不使用 Host 文件访问。读取失败、无效 UTF-8 或超出上限都使预览失败,不发布部分资源包。替换或卸载文档会释放其 Blob URL。
60
+ 开启代码工作工具时,HTML 以贴合正文四边的 Blob iframe 运行,沙箱属性严格为 `sandbox="allow-scripts"`,不含 `allow-same-origin`;脚本无法访问父应用的源或文件读取接口。渲染器通过注入的 Remote 回调,加载直接声明的相对 `.js` 经典脚本和 `.css` 样式表;固定安全上限为单个资源 4 MiB、总计 32 MiB、64 个不同资源。Host 代码解析关联路径,带 `baseFile` 的 `readBytes` 返回原生字节。依赖 Resource 在读取返回后加入,使用返回的 `absolutePath`,失败时则使用字符串类型的 `error.details.path`;没有 Host 路径时,Client 不自行猜测。在渲染器内部,base64 仅用于把 iframe 引导载荷嵌入脚本文本。`<base href>` 将依赖解析交给浏览器,HTTPS 资源也由浏览器处理。本地模块 import、CSS `url()`/`@import` 和动态 `fetch` 不使用 Host 文件访问。读取失败、无效 UTF-8 或超出上限都使预览失败,不发布部分资源包。替换或卸载文档会释放其 Blob URL。
59
61
 
60
62
  PNG、JPEG、GIF、WebP、BMP、ICO 和 SVG 通过 Blob URL 在 `<img>` 静态图片上下文中渲染,带 12px 内边距和圆角。图片默认适应宽度,但不会放大小于面板的内容;100% 使用图片的固有 CSS 像素宽度。共享缩放控件可产生横向和纵向滚动,但不提供拖拽平移。缩放不会替换 `<img>` 或 Blob URL,因此动画图片会继续播放。位图超过固有尺寸后可能变虚,SVG 则继续使用浏览器的矢量渲染路径。SVG 标记绝不进入应用 DOM 或 iframe,因此其中的脚本无法执行,也无法访问父页面。替换或卸载图片会撤销其 Blob URL。
61
63
 
62
- 共享文案来自 `sidebarDocumentPreview`;各内置渲染器拥有自己的本地化标签。PDF 与转换后的 Office 预览在浅色模式下使用石墨灰底色,在深色模式下使用哑黑底色,页面带有轻微阴影并保留文档原色。PDF 与图片预览共用浮动控件,提供**适应宽度**、25%、50%、100%、150% 和 200% 选项,并在 25%–400% 固定范围内按 25% 逐级缩放。适应宽度是默认模式并跟随面板尺寸;100% 表示 PDF 的 96 DPI 页面尺寸或图片的固有 CSS 像素尺寸。在精细指针设备上,控件初始隐藏;指针进入底部 72 个 CSS 像素时向上滑入,离开 420 ms 后向下退出;控件悬停、键盘焦点、菜单展开和手势进行期间保持显示,无 hover 的设备则始终显示。Chromium 将 macOS 触控板捏合映射到与 Ctrl+滚轮相同的实时指针锚定路径;控件同步显示手势比例,静止后的值在正文重新挂载后继续保留,直至 tab 关闭。HTML 预览不显示缩放控件。
64
+ 共享文案来自 `sidebarDocumentPreview`;各内置渲染器拥有自己的本地化标签。PDF 与转换后的 Office 预览在浅色模式下使用冷调浅灰底色,在深色模式下使用哑黑底色,页面带有轻微阴影并保留文档原色。PDF 与图片预览共用浮动控件,提供**适应宽度**、25%、50%、100%、150% 和 200% 选项,并在 25%–400% 固定范围内按 25% 逐级缩放。适应宽度是默认模式并跟随面板尺寸;100% 表示 PDF 的 96 DPI 页面尺寸或图片的固有 CSS 像素尺寸。在精细指针设备上,控件初始隐藏;指针进入底部 72 个 CSS 像素时向上滑入,离开 420 ms 后向下退出;控件悬停、键盘焦点、菜单展开和手势进行期间保持显示,无 hover 的设备则始终显示。Chromium 将 macOS 触控板捏合映射到与 Ctrl+滚轮相同的实时指针锚定路径;控件同步显示手势比例,静止后的值在正文重新挂载后继续保留,直至 tab 关闭。HTML 预览不显示缩放控件。缩放稳定或适应宽度发生变化后,视口附近的 PDF 页面按最终缩放比例乘以设备像素比重绘。新位图完成前保留原有画面和可选文字层;屏幕外的页面在接近视口时更新。
63
65
 
64
- 首次读取、追加页及 HTML/PDF/图片准备共用 ongoing `StateDot` loading,其标签暴露给辅助技术,并遵循减少动态效果偏好;内容出现前的每个等待都把 loading 居中在面板中,打开文件到正文出现始终是同一位置的一个标记。下一页加载期间保留已显示的内容。PDF 正文仅在 PDF 预览挂载时加载包内 `client.pdf.js` chunk;PDF.js、Worker 源码和内嵌支持数据不会进入启动 `client.js`。PDF 页面贴边占满面板宽度,组成一个纵向连续序列并在接近视口时惰性渲染;未渲染的页以安静的 3:4 占位块保持位置。PDF.js 官方 TextLayerBuilder 在与画面重合的文字层上管理选区边界和复制文本规范化。配套样式不高亮空白换行;对齐同时考虑 PDF 页面单位、页面旋转与视口宽度变化,页面释放时取消两层渲染。纯图片 PDF 不包含可选取的文字。代码预览使用 tertiary 色的语言名称和带提示的复制图标;换行仍由文档工具栏控制。默认显示源码行号,但复制文本不包含行号;纯文本与代码使用相同字号和行高。代码直接坐在分栏自身的背景上,而不是会话卡片的填充色;复制条与占满剩余高度的内部滚动区相邻,因此横纵滚动条都从复制控件下方开始。
66
+ 首次读取及渲染器准备(包括 Office 转换)共用居中的 28px ongoing `StateDot`,下方显示本地化状态文字“文档渲染中...”。状态向辅助技术提供相同的名称,并遵循减少动态效果偏好。追加文本页时使用紧凑的行内转圈,同时保留已显示的内容。PDF 正文仅在 PDF 预览挂载时加载包内 `client.pdf.js` chunk;PDF.js、Worker 源码和内嵌支持数据不会进入启动 `client.js`。PDF 与转换后的 Word/PowerPoint 页面组成纵向序列,页间距与四周留白均为 12px,露出当前主题的文档背景色;适应宽度会预留此留白,页面在接近视口时惰性渲染;未渲染的页以安静的 3:4 占位块保持位置。PDF.js 官方 TextLayerBuilder 在与画面重合的文字层上管理选区边界和复制文本规范化。配套样式不高亮空白换行;对齐同时考虑 PDF 页面单位、页面旋转与视口宽度变化,页面释放时取消两层渲染。纯图片 PDF 不包含可选取的文字。代码预览使用 tertiary 色的语言名称和带提示的复制图标;换行仍由文档工具栏控制。默认显示源码行号,但复制文本不包含行号;纯文本与代码使用相同字号和行高。代码直接坐在分栏自身的背景上,而不是会话卡片的填充色;复制条与占满剩余高度的内部滚动区相邻,因此横纵滚动条都从复制控件下方开始。
65
67
 
66
68
  <a id="excel-preview"></a>
67
69
  ## Excel 预览
68
70
 
69
- 直接在浏览器中打开 `.xlsx`、`.xls`、`.csv` 和 `.tsv`,支持工作表标签、单元格选择、复制和只读公式栏。XLSX 保留字体、纯色填充、边框、数字格式、富文本、合并单元格、行列尺寸、隐藏行列及工作表,以及冻结标题。XLS 保留已保存的值、公式、数字格式、合并及可用的行列元数据;不支持字体、边框和冻结窗格。工作簿显示已保存的公式结果而不重新计算;缺少的结果保持为空,公式栏旁的紧凑提示会标记显示结果可能不完整或不准确的工作簿。工作簿视图随预览面板尺寸变化自动调整,无需重新加载工作表或选择状态。表格预览不调用 Office 转换服务。
71
+ 直接在浏览器中打开 `.xlsx`、`.xls`、`.csv` 和 `.tsv`,支持工作表标签、单元格选择、复制和只读公式栏。XLSX 保留字体、纯色填充、边框、数字格式、富文本、合并单元格、行列尺寸、隐藏行列及工作表,以及冻结标题。XLS 保留已保存的值、公式、数字格式、合并及可用的行列元数据;不支持字体、边框和冻结窗格。工作簿显示已保存的公式结果而不重新计算;缺少的结果保持为空,公式栏旁的紧凑提示会标记显示结果可能不完整或不准确的工作簿。工作簿视图填满预览面板,并随面板尺寸变化自动调整,无需重新加载工作表或选择状态。工作表标签从左侧边缘开始排列;标签溢出时可用触控板横向手势或左右按钮滚动,缩放控件独立占位。表格控件在应用的明暗两种主题下均保持浅色背景和深色文字。触控板的像素位移可同时平移表格的横纵两个方向,包括斜向平移,移动距离跟随手势;冻结标题保持固定。到达工作表边缘后反向移动,仍会保留下一次手势的位移。隐藏选区统计栏及无效的工作表菜单箭头。冻结标题在滚动时保持固定,不显示冻结分隔线和拖拽条。表格预览不调用 Office 转换服务。
70
72
 
71
73
  XLSX 预览在解析前从内存副本中移除 DrawingML 部件,并忽略工作表的绘图引用。原文件和工作表 XML 保持不变。表格上方的提示列出实际检测到但未展示的图表、图片、形状和条件格式,并建议使用系统应用打开工作簿。未检测到这些内容的文件不显示此提示;公式提示保持独立。
72
74
 
73
- CSV 和 TSV 默认使用表格查看器,也可选择纯文本。两者分别以逗号和制表符分隔字段,支持引号内分隔符、转义引号、多行字段、空字段和不等长行。首行仍作为数据。值保持为字面字符串,包括前导零、日期、布尔值和类似公式的文本。文本文件支持 UTF-8 或带 BOM 的 UTF-16;无效编码会显示转换提示。引号字段格式错误会使表格预览失败,不会静默丢弃数据。
75
+ CSV 和 TSV 默认使用表格查看器,也可选择纯文本;CSV 还提供带语法高亮的 Code 预览。两者分别以逗号和制表符分隔字段,支持引号内分隔符、转义引号、多行字段、空字段和不等长行。首行仍作为数据。值保持为字面字符串,包括前导零、日期、布尔值和类似公式的文本。文本文件支持 UTF-8 或带 BOM 的 UTF-16;无效编码会显示转换提示。引号字段格式错误会使表格预览失败,不会静默丢弃数据。
74
76
 
75
77
  在同一个 `ui-sidebar-documentpreview` 条目上配置 `excel`。这些限制补充 Host 的完整文件读取限制,但不限制浏览器进程内存或解压分配量。
76
78
 
@@ -82,7 +84,7 @@ CSV 和 TSV 默认使用表格查看器,也可选择纯文本。两者分别
82
84
 
83
85
  惰性 Excel chunk 打包 FortuneSheet、用于 XLSX 的 ExcelJS、用于 XLS 的 SheetJS CE,以及用于 CSV/TSV 的 PapaParse。包内独立于 React 的适配层将解析结果直接映射为 FortuneSheet 单元格,并复用单元格格式化和初始选区。第三方许可证文本保留在发布的 chunk 中;SheetJS CE 保留其 Apache-2.0 条款。每次解析拥有一个独立可释放的 Worker,并传输所保留文件字节的副本;内容替换、卸载、失败或超时都会终止该 Worker。样式表仅作用于 Excel 预览区域。暂不支持图表、绘图/图片、数据透视表、条件格式、编辑、重新计算和导出;字体可用性、Excel 列宽近似和主题色明暗近似会影响保真度。超链接显示为文本,不加载目标地址。ExcelJS 会再次解码 XLSX 字符串公式缓存结果中的实体写法;保存的字面文本 `&lt;` 会显示为 `<`。
84
86
 
85
- 只读公式栏按字面显示公式和单元格文本。复制时保留 HTML 表格,并转义单元格内容,包括已保存的公式结果。[FortuneSheet 补丁决策](../../../.agents/notes/implemented/feature/2026-09-16-browser-excel-preview.zh.md)说明升级依赖时保留这些行为与工作表选区的要求。
87
+ 只读公式栏以单行按字面显示公式和单元格文本,长内容可横向滚动。复制时保留 HTML 表格,并转义单元格内容,包括已保存的公式结果。[FortuneSheet 补丁决策](../../../.agents/notes/implemented/feature/2026-09-16-browser-excel-preview.zh.md)说明升级依赖时保留这些行为与工作表选区的要求。
86
88
 
87
89
  固定版本的 [ExcelJS 补丁](../../../patches/exceljs@4.4.0.patch)通过包内关系解析工作簿、样式、共享字符串、工作表、批注、Table 和 VML,支持绝对及相对目标,以及 ASCII 大小写等价的部件名,并按命名空间 URI 识别 SpreadsheetML 和 VML 名称。Strict OOXML 的 SpreadsheetML 和关系 URI 映射到相同的已支持预览功能;这不代表完整支持 Strict 标准。XML 部件支持 UTF-8 及两种字节序的 UTF-16;CDATA 按字面文本读取。绘图和条件格式提示按关系查找内容,不依赖部件目录。未被引用的 `xl/drawings/*.xml` 部件及其关系文件也会被移除,但不会产生提示;批注 VML 保持不变。缺失引用部件或存在大小写等价的歧义 ZIP 条目会使预览失败。解析保留批注和 Table 元数据,但预览器没有专门展示它们的控件。补丁同时覆盖 Node 源码和 `dist/exceljs.js`,浏览器入口选择已修补的 bundle。升级依赖时必须保留两个入口的行为,并通过[独立写入器回归测试和 fuzz 诊断](tests/fuzz/README.zh.md)。
88
90
 
@@ -112,6 +114,8 @@ Office 注册、加载、缓存和字体提示位于 `src/client/office/`。注
112
114
 
113
115
  Office Remote 通过 Connection 的 multipart 二进制传输返回原生 `Uint8Array` PDF。渲染器以只读方式借用保留的字节,并在传给 Worker 前复制。
114
116
 
117
+ 页面刷新快捷键复用所选预览的重载操作,包括旧请求失效与滚动位置保留。头部重载 Tooltip 和 ARIA 组合随有效快捷键绑定更新。
118
+
115
119
  </details>
116
120
 
117
121
  <a id="navigation"></a>
@@ -134,7 +138,7 @@ Office Remote 通过 Connection 的 multipart 二进制传输返回原生 `Uint8
134
138
  - **预览而非编辑。** 查看器不提供文件编辑或共享搜索接口;目录地址以 `not-regular-file` 失败。未知扩展名使用纯文本读取,仍受其 UTF-8/NUL 检查限制。
135
139
  - **Office 转换限制。** 预览不启动原生 Office 编辑器,也不下载引擎。二进制 `.doc` 和 `.ppt` 文件不返回缺失字体诊断。转换保真度与资源限制由 [LibreOffice 提供方](../../document/office-to-pdf/README.zh.md)负责。
136
140
  - **文本顺序分页,完整文件受限。** 定位到较深处的源码行需要先加载此前各页;PDF、HTML 和图片必须取得 Host `maxFileBytes` 上限内的完整结果。
137
- - **PDF 缩放不会提高栅格分辨率。** PDF 页面按 96 DPI 乘以设备像素比绘制,并受现有 1600 万像素 Canvas 上限约束;固定缩放会放大这张位图,因此高比例下页面文字可能变虚。按稳定缩放比例重绘视口附近页面仍属于延期工作。
141
+ - **PDF 栅格分配有上限。** 每页位图最多为 16,777,216 像素;超大页面或高像素密度屏幕上的高比例缩放仍可能低于设备分辨率。
138
142
  - **字节视图不恢复滚动位置。** PDF、HTML 与图片的渲染器重新挂载或重新载入时可能回到顶部;固定 PDF 与图片缩放可产生横向滚动,HTML iframe 的滚动属于其不透明浏览上下文。
139
143
  - **本地 HTML 依赖集合有限。** 只打包直接引用的经典 `.js` 脚本和 `.css` 样式表。浏览器解析的资源仍受浏览器源与网络规则限制;iframe 不获得运行时文件读取桥接。
140
144
  - **滚动写入未节流。** 每次滚动事件都把偏移记进 store;行块已 memo 化,于是由此引发的重渲染交还给 React 的是同一批元素。
@@ -28117,7 +28117,7 @@ window.__ModuleLoader__.load({
28117
28117
  return stringify(rnds);
28118
28118
  }
28119
28119
  //#endregion
28120
- //#region ../../../node_modules/.pnpm/@fortune-sheet+core@1.0.4_patch_hash=488dad2a7648b7d4df31f6bd776b7849fd0fb85be8f1acf268efff758caba3c0/node_modules/@fortune-sheet/core/dist/index.esm.js
28120
+ //#region ../../../node_modules/.pnpm/@fortune-sheet+core@1.0.4_patch_hash=8791a230763dbf853fd65d627c68c31de37209992851377855e16cf08ea70532/node_modules/@fortune-sheet/core/dist/index.esm.js
28121
28121
  function _arrayLikeToArray$1(r, a) {
28122
28122
  (null == a || a > r.length) && (a = r.length);
28123
28123
  for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e];
@@ -117212,6 +117212,7 @@ window.__ModuleLoader__.load({
117212
117212
  {
117213
117213
  key: "drawFreezeLine",
117214
117214
  value: function drawFreezeLine(_ref2) {
117215
+ if (this.sheetCtx.allowEdit === false) return;
117215
117216
  var horizontalTop = _ref2.horizontalTop, verticalLeft = _ref2.verticalLeft;
117216
117217
  var renderCtx = this.canvasElement.getContext("2d");
117217
117218
  if (!renderCtx) return;
@@ -119983,6 +119984,14 @@ window.__ModuleLoader__.load({
119983
119984
  var _cache$searchDialog;
119984
119985
  if (((_cache$searchDialog = cache.searchDialog) === null || _cache$searchDialog === void 0 ? void 0 : _cache$searchDialog.mouseEnter) && ctx.showSearch && ctx.showReplace) return;
119985
119986
  if (ctx.filterContextMenu != null) return;
119987
+ if (ctx.allowEdit === false && e.deltaMode === 0) {
119988
+ scrollbarX.scrollLeft += e.deltaX;
119989
+ scrollbarY.scrollTop += e.deltaY;
119990
+ ctx.scrollLeft = scrollbarX.scrollLeft;
119991
+ ctx.scrollTop = scrollbarY.scrollTop;
119992
+ e.preventDefault();
119993
+ return;
119994
+ }
119986
119995
  var scrollLeft = scrollbarX.scrollLeft;
119987
119996
  var scrollTop = scrollbarY.scrollTop;
119988
119997
  var visibledatacolumn_c = ctx.visibledatacolumn;
@@ -123098,7 +123107,7 @@ window.__ModuleLoader__.load({
123098
123107
  an.createDraft.bind(an);
123099
123108
  an.finishDraft.bind(an);
123100
123109
  //#endregion
123101
- //#region ../../../node_modules/.pnpm/@fortune-sheet+react@1.0.4_patch_hash=c17549e117c8fb99f408497c1e84292c21f25516fb762a325_8b85be79aa50b34ab61b9b25a7ac8f27/node_modules/@fortune-sheet/react/dist/index.esm.js
123110
+ //#region ../../../node_modules/.pnpm/@fortune-sheet+react@1.0.4_patch_hash=2932e52e79afcd4ced08cfa123b5eded786c85043da32f622_87505320529149716b9d208b3b5e2a06/node_modules/@fortune-sheet/react/dist/index.esm.js
123102
123111
  var import_runtime = /* @__PURE__ */ __toESM((/* @__PURE__ */ __commonJSMin(((exports, module) => {
123103
123112
  /**
123104
123113
  * Copyright (c) 2014-present, Facebook, Inc.
@@ -129914,8 +129923,17 @@ window.__ModuleLoader__.load({
129914
129923
  (0, react.useEffect)(function() {
129915
129924
  var tabCurrent = tabContainerRef.current;
129916
129925
  if (!tabCurrent) return;
129917
- setIsShowScrollBtn(tabCurrent.scrollWidth - 2 > tabCurrent.clientWidth);
129918
- }, [context.luckysheetfile]);
129926
+ var availableWidth = tabCurrent.clientWidth;
129927
+ if (context.allowEdit === false) {
129928
+ availableWidth += leftScrollRef.current ? leftScrollRef.current.offsetWidth : 0;
129929
+ availableWidth += rightScrollRef.current ? rightScrollRef.current.offsetWidth : 0;
129930
+ }
129931
+ setIsShowScrollBtn(tabCurrent.scrollWidth - 2 > availableWidth);
129932
+ }, [
129933
+ context.luckysheetfile,
129934
+ context.allowEdit,
129935
+ context.luckysheetTableContentHW[0]
129936
+ ]);
129919
129937
  var onAddSheetClick = (0, react.useCallback)(function() {
129920
129938
  return setTimeout(function() {
129921
129939
  setContext(function(draftCtx) {
@@ -133550,7 +133568,7 @@ window.__ModuleLoader__.load({
133550
133568
  }), /*#__PURE__*/ react.default.createElement("div", { className: "fortune-stat-area" }, /*#__PURE__*/ react.default.createElement("div", { className: "luckysheet-sheet-selection-calInfo" }, !!calInfo.count && /*#__PURE__*/ react.default.createElement("div", { style: { width: "60px" } }, formula.count, ": ", calInfo.count), !!calInfo.numberC && !!calInfo.sum && /*#__PURE__*/ react.default.createElement("div", null, formula.sum, ": ", calInfo.sum), !!calInfo.numberC && !!calInfo.average && /*#__PURE__*/ react.default.createElement("div", null, formula.average, ": ", calInfo.average), !!calInfo.numberC && !!calInfo.max && /*#__PURE__*/ react.default.createElement("div", null, formula.max, ": ", calInfo.max), !!calInfo.numberC && !!calInfo.min && /*#__PURE__*/ react.default.createElement("div", null, formula.min, ": ", calInfo.min))))));
133551
133569
  });
133552
133570
  //#endregion
133553
- //#region \0dsh-inline-css:/home/runner/work/deepseek-harness/deepseek-harness/node_modules/.pnpm/@fortune-sheet+react@1.0.4_patch_hash=c17549e117c8fb99f408497c1e84292c21f25516fb762a325_8b85be79aa50b34ab61b9b25a7ac8f27/node_modules/@fortune-sheet/react/dist/index.css.mjs
133571
+ //#region \0dsh-inline-css:/home/runner/work/deepseek-harness/deepseek-harness/node_modules/.pnpm/@fortune-sheet+react@1.0.4_patch_hash=2932e52e79afcd4ced08cfa123b5eded786c85043da32f622_87505320529149716b9d208b3b5e2a06/node_modules/@fortune-sheet/react/dist/index.css.mjs
133554
133572
  var index_css_default = ".fortune-container{background-color:#fff;flex-direction:column;width:100%;height:100%;margin:0;padding:0;font-family:Helvetica Neue,Helvetica,Arial,PingFang SC,Hiragino Sans GB,Heiti SC,Microsoft YaHei,WenQuanYi Micro Hei,sans-serif;display:flex;position:relative}.fortune-workarea{width:100%}.fortune-popover-backdrop{z-index:1003;width:100%;height:100%;position:absolute;top:0;left:0}.fortune-modal-container{background:#ffffff80;justify-content:center;align-items:center;display:flex}html::-webkit-scrollbar-button{display:none}.fortune-stat-area{justify-content:flex-end;align-items:center;display:flex}.fortune-sheet-container{flex-direction:column;flex:1;display:flex}.fortune-col-body{flex-direction:row;flex:1;display:flex}.fortune-sheet-area{flex:1;position:relative}.fortune-sheet-canvas-placeholder,.fortune-sheet-canvas{width:100%;height:100%;display:block}.fortune-sheet-canvas{position:absolute}.fortune-sheet-overlay{outline-style:none;width:100%;height:100%;position:absolute}.fortune-cell-area{border-collapse:collapse;cursor:default;outline-style:none;position:relative;overflow:hidden}.fortune-row-body{flex-direction:row;display:flex}.fortune-row-header{color:#5e5e5e;cursor:default;outline-style:none;flex-shrink:0;width:45px;margin-top:-2px;padding:2px 0 0;position:relative;overflow:hidden}.fortune-row-header-hover{z-index:11;background-color:#c2c2c266;border:0;width:100%;margin-top:2px;display:none;position:absolute;right:0}.fortune-row-header-selected{z-index:10;background-color:#4c4c4c1a;border-right:1px solid #0188fb;width:100%;margin-top:2px;display:none;position:absolute;right:0}.fortune-col-header-wrap{flex-direction:row;display:flex}.fortune-col-header{color:#5e5e5e;cursor:default;outline-style:none;flex:1;height:19px;padding:0;position:relative;overflow:hidden}.fortune-col-header-hover{color:#5e5e5e;cursor:default;z-index:11;background-color:#c2c2c266;border:0;height:100%;margin-left:0;display:none;position:absolute;bottom:0}.fortune-col-header-hover .header-arrow{position:absolute;top:50%;right:6px;transform:translateY(-44%)}.fortune-col-header-selected{color:#5e5e5e;cursor:default;z-index:10;background-color:#4c4c4c1a;border-bottom:1px solid #0188fb;height:100%;margin-left:0;display:none;position:absolute;bottom:0}.fortune-left-top{cursor:pointer;background-color:#fff;border:1px solid #dfdfdf;border-width:0 1px 1px 0;width:44.5px;height:18.5px;padding-top:0;padding-left:0;position:relative}.fortune-add-row-button{cursor:pointer;color:#262a33;background-color:#fff;border:1px solid #c8c8c8;border-radius:4px;outline:none;align-items:center;margin:0 8px;padding:1px 20px;font-size:14px;line-height:20px;display:inline-flex}.luckysheet-cell-selected-focus{pointer-events:none;z-index:14;background:#0050d026;margin:0;display:none;position:absolute}.fortune-selection-copy{pointer-events:none;z-index:18;border:none;margin:0;position:absolute}.fortune-selection-copy .fortune-copy{z-index:18;background-color:#0000;position:absolute}.fortune-selection-highlight{z-index:14;border:none;margin:0;position:absolute}.fortune-cell-selected-extend{pointer-events:none;z-index:16;border:1px dashed #0188fb;margin:-1px 0 0 -1px;display:none;position:absolute}.fortune-cell-selected-move{cursor:move;z-index:16;border:2px solid #0188fb;margin:-1px 0 0 -1px;display:none;position:absolute}.luckysheet-cell-selected{pointer-events:none;z-index:15;box-sizing:content-box;background:#0188fb26;border:1px solid #0188fb;margin:-1px 0 0 -1px;display:none;position:absolute}.luckysheet-cs-inner-border{pointer-events:none;border:1px solid #fff;position:absolute;inset:0}.luckysheet-cs-fillhandle{cursor:crosshair;z-index:16;pointer-events:auto;background-color:#0188fb;border:1px solid #fff;width:6px;height:6px;position:absolute;bottom:-5px;right:-5px}.luckysheet-cs-draghandle{cursor:move;opacity:.01;z-index:15;pointer-events:auto;background-color:#fff;border:2px solid #fff;position:absolute}.luckysheet-cs-draghandle-top{height:2px;top:-4px;left:-2px;right:-2px}.luckysheet-cs-draghandle-bottom{height:2px;bottom:-4px;left:-2px;right:0}.luckysheet-cs-draghandle-left{width:2px;top:0;bottom:0;left:-4px}.luckysheet-cs-draghandle-right{width:2px;top:0;bottom:0;right:-4px}.luckysheet-cs-touchhandle{z-index:100;pointer-events:auto;touch-action:auto;width:16px;height:16px;padding:5px;display:none;position:absolute}.luckysheet-cs-touchhandle:before{content:\"\";box-sizing:border-box;background-color:#fff;border:.5px solid #00000026;border-radius:50%;width:16px;height:16px;display:block}.luckysheet-cs-touchhandle-lt{top:-13px;left:-13px}.luckysheet-cs-touchhandle-lb{bottom:-13px;left:-13px}.luckysheet-cs-touchhandle-rt{top:-13px;right:-13px}.luckysheet-cs-touchhandle-rb{bottom:-13px;right:-13px}.luckysheet-cs-touchhandle .luckysheet-cs-touchhandle-btn{box-sizing:border-box;z-index:11;background-color:#018ffb;background-position:50%;border-radius:50%;width:10px;height:10px;position:absolute;top:8px;left:8px}.luckysheet-input-box{z-index:15;flex-direction:column;font:400 13px arial,sans,sans-serif;display:flex;position:absolute}.luckysheet-input-box-inner{text-align:left;resize:none;white-space:pre-wrap;word-wrap:break-word;box-sizing:border-box;background-color:#fff;border:1px solid #5292f7;outline:none;max-width:9900px;max-height:9900px;margin:0;padding:0 2px;font:400 13px arial,sans,sans-serif;right:auto;overflow:hidden auto;-webkit-box-shadow:0 2px 5px #0006;-moz-box-shadow:0 2px 5px #0006;box-shadow:0 2px 5px #0006}.luckysheet-cell-input{cursor:text;white-space:pre-wrap;outline:none;width:100%;margin:0}.luckysheet-formula-text-color{color:#000}.luckysheet-formula-text-string{color:#228b22}.luckysheet-cell-flow{touch-action:manipulation;border:0;margin:0;padding:0;position:relative}.luckysheet-cell-flow-clip{border-collapse:collapse;cursor:default;touch-action:manipulation;width:5000000px;overflow:hidden}.luckysheet-cell-flow-col{touch-action:manipulation;float:left;direction:ltr;border:0;margin:0;padding:0;position:relative;overflow:hidden}.luckysheet-cell-sheettable{text-align:left;color:#000;font-size:11pt;text-decoration:none;position:relative}.luckysheet-bottom-controll-row{z-index:1000;height:30px;position:absolute;bottom:38px;left:0}#luckysheet-bottom-add-row{margin-top:-2px;margin-right:5px;padding:5px 20px}#luckysheet-bottom-add-row-input{width:40px;min-width:40px}#luckysheet-bottom-return-top{margin-top:-2px;margin-left:10px;padding:5px 6px}.luckysheet-cell-flow-column{height:inherit;width:inherit;z-index:1;touch-action:manipulation;position:absolute;top:0;left:0}.luckysheet-cell-flow-column-line{height:inherit;border-right:1px solid #d4d4d4;position:absolute}.luckysheet-cell-flow-row{text-align:left;height:inherit;width:inherit;z-index:1;touch-action:manipulation;position:absolute;top:0;left:0}.luckysheet-cell-flow-row-line{width:inherit;border-bottom:1px solid #d4d4d4;position:absolute}.fortune-cols-change-size,.fortune-rows-change-size,.fortune-change-size-line,.fortune-cols-freeze-handle,.fortune-rows-freeze-handle,.fortune-freeze-drag-line{-webkit-user-drag:none;-webkit-user-select:none;-moz-user-select:none;user-select:none;z-index:12;position:absolute}.fortune-cols-change-size{cursor:ew-resize;opacity:0;background:#0188fb;width:5px;height:100%}.fortune-rows-change-size{cursor:ns-resize;opacity:0;background:#0188fb;width:100%;height:5px}.fortune-change-size-line{z-index:15;cursor:ew-resize;border-style:solid;border-color:#0188fb}.fortune-cols-freeze-handle{cursor:grab;z-index:20;background-color:#ddd;width:3px;height:100%;position:absolute;left:0}.fortune-rows-freeze-handle{cursor:grab;z-index:20;background-color:#ddd;width:100%;height:3px;position:absolute;top:0}.fortune-freeze-drag-line{z-index:15;cursor:ew-resize;border-style:solid;border-color:#ccc}.luckysheet-postil-dialog-move{pointer-events:none;margin:0;padding:0;position:absolute;inset:0}.luckysheet-postil-dialog-move .luckysheet-postil-dialog-move-item{pointer-events:all;cursor:move;position:absolute}.luckysheet-postil-dialog-move .luckysheet-postil-dialog-move-item-t{width:100%;height:3px;top:-4px;left:0}.luckysheet-postil-dialog-move .luckysheet-postil-dialog-move-item-r{width:3px;height:100%;top:0;right:-4px}.luckysheet-postil-dialog-move .luckysheet-postil-dialog-move-item-b{width:100%;height:3px;bottom:-4px;left:0}.luckysheet-postil-dialog-move .luckysheet-postil-dialog-move-item-l{width:3px;height:100%;top:0;left:-4px}.luckysheet-postil-show-active .luckysheet-postil-dialog-move .luckysheet-postil-dialog-move-item{border-color:#0188fb}.luckysheet-postil-dialog-resize{pointer-events:none;margin:0;padding:0;position:absolute;inset:-2px}.luckysheet-postil-dialog-resize .luckysheet-postil-dialog-resize-item{pointer-events:all;border:1px solid #0188fb;width:6px;height:6px;position:absolute}.luckysheet-postil-dialog-resize .luckysheet-postil-dialog-resize-item-lt{cursor:nw-resize;top:-6px;left:-6px}.luckysheet-postil-dialog-resize .luckysheet-postil-dialog-resize-item-mt{cursor:n-resize;margin-left:-4px;top:-6px;left:50%}.luckysheet-postil-dialog-resize .luckysheet-postil-dialog-resize-item-lm{cursor:w-resize;margin-top:-4px;top:50%;left:-6px}.luckysheet-postil-dialog-resize .luckysheet-postil-dialog-resize-item-rm{cursor:e-resize;margin-top:-4px;top:50%;right:-6px}.luckysheet-postil-dialog-resize .luckysheet-postil-dialog-resize-item-rt{cursor:ne-resize;top:-6px;right:-6px}.luckysheet-postil-dialog-resize .luckysheet-postil-dialog-resize-item-lb{cursor:sw-resize;bottom:-6px;left:-6px}.luckysheet-postil-dialog-resize .luckysheet-postil-dialog-resize-item-mb{cursor:s-resize;margin-left:-4px;bottom:-6px;left:50%}.luckysheet-postil-dialog-resize .luckysheet-postil-dialog-resize-item-rb{cursor:se-resize;bottom:-6px;right:-6px}.fortune-selection-copy-top{background-position:bottom;height:2px;top:0;left:0;right:0}.fortune-selection-copy-right{width:2px;top:0;bottom:0;right:0}.fortune-selection-copy-bottom{height:2px;bottom:0;left:0;right:0}.fortune-selection-copy-left{background-position:100%;width:2px;top:0;bottom:0;left:0}.fortune-selection-copy-hc{z-index:8;border:2px dashed #12a5ff;position:absolute;inset:0}.luckysheet-modal-dialog-resize{pointer-events:none;border:2px solid #0188fb;margin:0;padding:0;position:absolute;inset:-2px}.luckysheet-modal-dialog-resize-item{pointer-events:all;background:#fff;border:2px solid #0188fb;border-radius:6px;width:6px;height:6px;position:absolute}.luckysheet-modal-dialog-resize-item-lt{cursor:se-resize;top:-6px;left:-6px}.luckysheet-modal-dialog-resize-item-mt{cursor:s-resize;margin-left:-4px;top:-6px;left:50%}.luckysheet-modal-dialog-resize-item-rt{cursor:ne-resize;top:-6px;right:-6px}.luckysheet-modal-dialog-resize-item-lm{cursor:w-resize;margin-top:-4px;top:50%;left:-6px}.luckysheet-modal-dialog-resize-item-rm{cursor:w-resize;margin-top:-4px;top:50%;right:-6px}.luckysheet-modal-dialog-resize-item-lb{cursor:ne-resize;bottom:-6px;left:-6px}.luckysheet-modal-dialog-resize-item-mb{cursor:s-resize;margin-left:-4px;bottom:-6px;left:50%}.luckysheet-modal-dialog-resize-item-rb{cursor:se-resize;bottom:-6px;right:-6px}.fortune-formula-functionrange-highlight .fortune-copy{z-index:18;cursor:move;opacity:.9;box-sizing:content-box;background:#0188fb;position:absolute}.fortune-formula-functionrange-highlight .fortune-selection-copy-top{border-top:2px solid #fff;border-bottom:2px solid #fff;top:-2px}.fortune-formula-functionrange-highlight .fortune-selection-copy-right{border-left:2px solid #fff;border-right:2px solid #fff;right:-2px}.fortune-formula-functionrange-highlight .fortune-selection-copy-bottom{border-top:2px solid #fff;border-bottom:2px solid #fff;bottom:-2px}.fortune-formula-functionrange-highlight .fortune-selection-copy-left{border-left:2px solid #fff;border-right:2px solid #fff;left:-2px}.fortune-formula-functionrange-highlight .fortune-selection-copy-hc{opacity:.03;z-index:initial;border:2px solid #5e5e5e}.fortune-selection-highlight-lt{cursor:se-resize;top:-3px;left:-3px}.fortune-selection-highlight-rt{cursor:ne-resize;top:-3px;right:-3px}.fortune-selection-highlight-lb{cursor:ne-resize;bottom:-3px;left:-3px}.fortune-selection-highlight-rb{cursor:se-resize;bottom:-3px;right:-3px}.fortune-formula-functionrange-highlight .luckysheet-highlight{z-index:19;background:#0188fb;border:1px solid #fff;width:6px;height:6px;position:absolute}.fortune-presence-username{white-space:nowrap;text-overflow:ellipsis;box-sizing:content-box;color:#fff;padding:2px 6px;font-size:12px;position:absolute;left:-2px;overflow:hidden}.fortune-presence-selection{opacity:.7;border-style:solid;border-width:1px;position:absolute}.luckysheet-filter-options{color:#897bff;cursor:pointer;z-index:200;display:\"block\";background:#fff;border:1px solid #897bff;border-radius:3px;height:15px;margin-left:0;padding:0 4px;font-size:12px;position:absolute;top:3px}.luckysheet-filter-options:hover{color:#fff;background:#897bff;border:1px solid #fff}.luckysheet-filter-options-active{color:#fff;background:#897bff;border:1px solid #897bff;padding:0 1px}.caret{border:4px solid #0000;width:0;height:0;margin-top:6px;display:inline-block}.caret.down{border-top-color:#897bff}.luckysheet-filter-options:hover .caret.down{border-top-color:#fff}.luckysheet-filter-selected{background:#fff0}#luckysheet-dataVerification-showHintBox{z-index:1000;-webkit-user-select:none;-moz-user-select:none;user-select:none;cursor:default;white-space:nowrap;background-color:#fff;border:1px solid #ccc;padding:10px;font-size:12px;display:none;position:absolute;box-shadow:0 2px 4px #0003}#luckysheet-dataVerification-dropdown-btn{z-index:10;background-color:#fff;width:20px;height:20px;display:none;position:absolute;overflow:hidden}.sr-only{clip:rect(0, 0, 0, 0);white-space:nowrap;border:0;width:1px;height:1px;margin:-1px;padding:0;position:absolute;overflow:hidden}.luckysheet-formula-search-c{color:#535353;z-index:1003;background:#fff;border:1px solid #0003;width:300px;font-size:12px;position:absolute;box-shadow:0 2px 4px #0003}.luckysheet-formula-search-c .luckysheet-formula-search-item{cursor:pointer;background:#fff;padding:5px 10px}.luckysheet-formula-search-c .luckysheet-formula-search-item .luckysheet-formula-search-detail{color:#444;display:none}.luckysheet-formula-search-c .luckysheet-formula-search-item .luckysheet-formula-search-func{color:#222;font-size:14px}.luckysheet-formula-search-c .luckysheet-formula-search-item-active{background:#f5f5f5;border-top:1px solid #ebebeb;border-bottom:1px solid #ebebeb;display:block}.luckysheet-formula-search-c .luckysheet-formula-search-item-active .luckysheet-formula-search-detail{display:block}.luckysheet-formula-help-c{color:#535353;z-index:1003;background:#fff;border:1px solid #0003;width:300px;font-size:12px;position:absolute;box-shadow:0 2px 4px #0003}.luckysheet-formula-help-c .luckysheet-formula-help-content{max-height:300px;overflow-y:scroll}.luckysheet-formula-help-content-example{margin-top:5px}.luckysheet-formula-help-title{background:#f5f5f5;border-top:1px solid #ebebeb;border-bottom:1px solid #ebebeb;padding:2px 10px;font-size:14px;display:block}.luckysheet-formula-help-title-formula{word-break:break-word;width:250px}.luckysheet-arguments-help-section{color:#222;margin-top:5px;margin-bottom:5px}.luckysheet-arguments-help-section-title{color:#666;padding:1px 10px}.luckysheet-arguments-help-parameter-content{word-wrap:break-word;padding:1px 10px;display:inline-block}.luckysheet-arguments-help-formula{padding:1px 10px;font-size:14px}.luckysheet-arguments-help-parameter-active{background-color:#fff9b2}.luckysheet-formula-help-collapse{cursor:pointer;color:#bbb;font-size:16px;position:absolute;top:0;right:25px}.luckysheet-formula-help-close{cursor:pointer;color:#bbb;font-size:16px;position:absolute;top:0;right:5px}.luckysheet-formula-help-close:hover,.luckysheet-formula-help-collapse:hover{color:#555}.luckysheet-scrollbar-ltr{z-index:1003;position:absolute;overflow:hidden}.luckysheet-scrollbar-ltr div{width:1px;height:1px}.luckysheet-scrollbar-x{bottom:0;overflow-x:scroll}.luckysheet-scrollbar-y{top:0;right:0;overflow-y:scroll}.luckysheet-scrollbar-ltr::-webkit-scrollbar{background-color:#0000;width:8px;height:8px}.luckysheet-scrollbar-ltr::-webkit-scrollbar-track{background-color:#0000}.luckysheet-scrollbar-ltr::-webkit-scrollbar-thumb{background-color:#babac0;border-radius:16px}.luckysheet-scrollbar-ltr::-webkit-scrollbar-button{display:none}.fortune-dialog{box-sizing:border-box;background:#fff;border-radius:6px;max-width:90%;max-height:90%;overflow:auto;box-shadow:5px 5px 30px #0000001a}.fortune-dialog-box-button-container{justify-content:center;align-items:center;display:flex}.fortune-dialog-box-content{padding:0 25px}.fortune-dialog-box-button-container{padding-top:10px;padding-bottom:20px}.fortune-message-box-button{cursor:pointer;border:none;border-radius:4px;outline:none;align-items:center;margin:0 8px;padding:6px 12px;font-size:14px;line-height:20px;display:inline-flex}.fortune-message-box-button.button-default{color:#262a33;background-color:#fff;border:1px solid #ebebeb}.fortune-message-box-button.button-primary{color:#fff;background-color:#0188fb}.fortune-modal-dialog-header{outline:0;justify-content:flex-end;display:flex}.fortune-modal-dialog-icon-close{color:#d4d4d4;opacity:.3}.fortune-modal-dialog-icon-close:hover{opacity:.7}#fortune-search-replace{z-index:1002;padding:30px 42px;position:absolute}#fortune-search-replace .icon-close{position:absolute;top:3px;right:3px}#fortune-search-replace .tabBox{margin-top:10px;font-size:0}#fortune-search-replace .tabBox span{text-align:center;border:1px solid #ebebeb;width:100px;font-size:14px;line-height:2;display:inline-block}#fortune-search-replace .tabBox span.on{color:#fff;background-color:#8c89fe;border-color:#726efe}#fortune-search-replace .ctBox{border:1px solid #ebebeb;min-width:500px;padding:5px 10px;font-size:14px}#fortune-search-replace .ctBox .row{flex-direction:row;justify-content:space-between;display:flex}#fortune-search-replace .inputBox{height:90px;position:relative}#fortune-search-replace .inputBox .textboxs{height:30px;line-height:30px}#fortune-search-replace .checkboxs{height:90px}#fortune-search-replace .checkboxs div{height:30px;line-height:30px}#fortune-search-replace .checkboxs input[type=checkbox]{float:left;margin-top:9px}#fortune-search-replace .btnBox{margin-top:10px}#fortune-search-replace .btnBox .button-default{margin-left:0;margin-right:8px}#fortune-search-replace .close-button{margin-top:10px;margin-left:0}#fortune-search-replace #searchAllbox{border:1px solid #d4d4d4;height:210px;margin-top:10px;position:relative;overflow-y:auto}#fortune-search-replace #searchAllbox .boxTitle{box-sizing:border-box;background-color:#fff;border-bottom:1px solid #d4d4d4;width:100%;height:30px;padding:0 5px;line-height:29px;position:sticky;top:0;left:0}#fortune-search-replace #searchAllbox .boxTitle span{text-align:center;display:inline-block}#fortune-search-replace #searchAllbox .boxTitle span:first-of-type,#fortune-search-replace #searchAllbox .boxTitle span:nth-of-type(2){width:25%}#fortune-search-replace #searchAllbox .boxTitle span:nth-of-type(3){width:50%}#fortune-search-replace #searchAllbox .boxMain .boxItem{box-sizing:border-box;border-bottom:1px solid #d4d4d4;height:30px;padding:0 5px;line-height:29px}#fortune-search-replace #searchAllbox .boxMain .boxItem.on{color:#fff;background-color:#8c89fe}#fortune-search-replace #searchAllbox .boxMain .boxItem span{text-align:center;float:left;display:block}#fortune-search-replace #searchAllbox .boxMain .boxItem span:first-of-type,#fortune-search-replace #searchAllbox .boxMain .boxItem span:nth-of-type(2){text-overflow:ellipsis;white-space:nowrap;width:25%;overflow:hidden}#fortune-search-replace #searchAllbox .boxMain .boxItem span:nth-of-type(3){text-overflow:ellipsis;white-space:nowrap;width:50%;overflow:hidden}.fortune-link-modify-modal{z-index:300;background-color:#fff;border:.5px solid #e5e5e5;border-radius:6px;padding:6px 20px 10px;position:absolute;overflow:hidden;box-shadow:0 2px 6px #00000029}.fortune-link-modify-modal.link-toolbar{flex-direction:row;align-items:center;padding:2px 8px 2px 16px;display:flex}.fortune-link-modify-modal .link-content{margin-right:6px}.fortune-link-modify-modal .link-content:hover{color:#2674fb;cursor:pointer}.fortune-link-modify-modal .divider{background-color:#e0e0e0;flex-shrink:0;width:1px;height:16px;margin:0 6px}.fortune-link-modify-modal .fortune-toolbar-button{padding:6px}.fortune-link-modify-modal .fortune-toolbar-button:hover{cursor:pointer;background-color:#0000000f}.fortune-link-modify-modal.range-selection-modal{-webkit-user-select:auto;-moz-user-select:auto;user-select:auto;background-color:#fff;width:380px;padding:22px}.fortune-link-modify-line{padding-top:10px}.fortune-link-modify-title{color:#333;width:74px;height:16px;margin-right:6px;padding:7px 0;font-size:12px;line-height:16px;display:inline-block}.fortune-link-modify-input,.fortune-link-modify-select{box-sizing:border-box;-webkit-user-select:auto;-moz-user-select:auto;-ms-user-select:auto;user-select:auto;border:1px solid #d9d9d9;border-radius:5px;outline:none;width:232px;height:26px;padding:1px 8px;font-size:12px}.fortune-link-modify-input:focus,.fortune-link-modify-modal .range-selection-input:focus{border-color:#4d90fe}.fortune-link-modify-input.error-input,.fortune-link-modify-modal .range-selection-input.error-input{border:1px solid #ef4e2f!important}.fortune-link-modify-cell-selector{cursor:pointer;-webkit-appearance:none;-moz-appearance:none;appearance:none;border:none;width:20px;padding:4px;display:inline-block;position:absolute;right:24px}.fortune-link-modify-modal .modal-title{color:#000000e0;margin-bottom:12px;font-size:16px;font-weight:500;line-height:24px}.fortune-link-modify-modal .range-selection-input{-webkit-box-sizing:border-box;box-sizing:border-box;-webkit-appearance:none;-moz-appearance:none;appearance:none;border:1px solid #e0e0e0;border-radius:4px;outline:none;width:100%;height:32px;margin:0;padding:7px 11px;font-size:14px;display:block}.fortune-link-modify-modal .modal-icon-close{cursor:pointer;position:absolute;top:22px;right:22px}.fortune-link-modify-modal .validation-input-tip{color:#ef4e2f;height:17px;margin:3px 0;font-size:12px}.fortune-link-modify-modal .button-group{display:flex}.fortune-link-modify-modal .modal-footer{justify-content:flex-end;padding:0 0 5px;display:flex}.fortune-link-modify-modal.range-selection-modal .modal-footer{padding:0}.fortune-link-modify-modal .button-basic{cursor:pointer;border-radius:4px;flex-flow:row;justify-content:center;align-items:center;width:88px;height:32px;padding:0;font-size:14px;display:flex}.fortune-link-modify-modal .button-default{color:#262a33;background-color:#fff;border:1px solid #ebebeb}.fortune-link-modify-modal .button-primary{color:#fff;background-color:#0188fb;margin-left:14px}#fortune-data-verification{-webkit-user-select:none;-moz-user-select:none;user-select:none;min-width:500px;padding:10px 0}#fortune-data-verification .title{font-size:16px}#fortune-data-verification .box{font-size:14px}#fortune-data-verification .box .box-item{border-bottom:1px solid #e1e4e8;padding:10px}#fortune-data-verification .box .box-item .box-item-title{margin-bottom:10px;font-size:14px;font-weight:600}#fortune-data-verification .box .box-item .data-verification-range{border:1px solid #d4d4d4;width:100%;height:30px}#fortune-data-verification .box .box-item .show-box-item{margin-top:6px;font-size:12px}#fortune-data-verification .box .box-item .show-box-item .check-box{height:30px;margin-bottom:10px;line-height:30px}#fortune-data-verification .box .box-item .show-box-item .check-box input{box-sizing:border-box;border:1px solid #d4d4d4;height:30px;padding:0 10px}#fortune-data-verification .input-box input{box-sizing:border-box;border:1px solid #d4d4d4;height:30px;margin-top:6px;padding:4px 10px}#fortune-data-verification .input-box span{margin:0 16px}.data-verification-range .formulaInputFocus{width:calc(100% - 30px);height:30px;padding:0 10px px;float:left;box-sizing:border-box;border:none;outline-style:none}.data-verification-range .icon{float:right;cursor:pointer;margin-top:4px;margin-right:5px}#fortune-data-verification .box .box-item .data-verification-type-select{border-color:#d4d4d4;outline-style:none;width:100%;height:30px}#fortune-data-verification .box .box-item .check{font-size:12px;line-height:24px}#fortune-data-verification .box .box-item .check input{vertical-align:text-top}#fortune-data-verification .button-basic{text-align:center;vertical-align:middle;touch-action:manipulation;cursor:pointer;white-space:nowrap;-webkit-user-select:none;-moz-user-select:none;user-select:none;border-radius:2px;margin-top:10px;margin-bottom:0;padding:4px 8px;font-size:14px;font-weight:400;line-height:1.42857;display:inline-block}#fortune-data-verification .button-primary{color:#fff;background:#0188fb;border:1px solid #0188fb;margin-right:10px}#fortune-data-verification .button-close{color:#333;background-color:#fff;border:1px solid #ccc;margin-right:10px}#range-dialog{color:#000;z-index:100003;-webkit-user-select:none;-moz-user-select:none;user-select:none;background:#fff padding-box padding-box;border:1px solid #0005;outline:0;padding:30px 42px;position:fixed;top:50%;left:50%;transform:translate(-50%,-90%);box-shadow:0 4px 16px #0003}#range-dialog .dialog-title{color:#000;cursor:default;background-color:#fff;margin:0 0 16px;font-size:16px;font-weight:400;line-height:24px}#range-dialog input{-webkit-user-select:none;-moz-user-select:none;user-select:none;border:1px solid #d4d4d4;outline-style:none;height:30px;padding:0 10px}#range-dialog .button-primary{color:#fff;background:#0188fb;border:1px solid #0188fb;margin-right:10px}#range-dialog .button-close{color:#333;background-color:#fff;border:1px solid #ccc;margin-right:10px}#luckysheet-dataVerification-dropdown-List{z-index:10000;box-sizing:border-box;background-color:#fff;border:1px solid #ccc;font-size:12px;position:absolute;box-shadow:0 2px 4px #0003}#luckysheet-dataVerification-dropdown-List .dropdown-List-item{box-sizing:border-box;cursor:pointer;padding:5px 10px}#luckysheet-dataVerification-dropdown-List .dropdown-List-item:hover{background-color:#e1e1e1}.condition-format-sub-menu{cursor:default;z-index:1004;box-sizing:border-box;-webkit-user-select:none;-moz-user-select:none;user-select:none;background:#fff;border:1px solid #0003;outline:none;font-size:12px;position:absolute;top:-8px;box-shadow:0 2px 4px #0003}.condition-format-item{z-index:1005;justify-content:space-between;padding:6px 18px;display:flex}.condition-format-item:hover{background:#efefef}.condition-format-item span{color:#afafaf;font-size:10px}.horizontal-line{border-top:1px solid #ebebeb;margin-top:6px;margin-bottom:6px}.condition-rules .button-basic{text-align:center;vertical-align:middle;touch-action:manipulation;cursor:pointer;white-space:nowrap;-webkit-user-select:none;-moz-user-select:none;user-select:none;border-radius:2px;margin-top:10px;margin-bottom:0;padding:4px 8px;font-size:14px;font-weight:400;line-height:1.42857;display:inline-block}.condition-rules .button-primary{color:#fff;background:#0188fb;border:1px solid #0188fb;margin-right:10px}.condition-rules .button-close{color:#333;background-color:#fff;border:1px solid #ccc}.condition-rules{padding:0 42px 34px;font-size:12px}.condition-rules-title{color:#000;cursor:default;margin-bottom:18px;font-size:16px}.conditin-rules-value{margin:5px 0;font-weight:600}.condition-rules-inpbox{border:1px solid #d4d4d4;width:198px;height:28px}.condition-rules-input{float:left;border:none;outline-style:none;width:150px;height:28px;padding:0 10px}.condition-relues-inputicon{float:right;cursor:pointer;margin-top:2px;margin-right:5px}.condition-rules-set-title{margin:6px 0}.condition-rules-setbox{border:1px solid #d4d4d4}.condition-rules-set{padding:5px 10px}.condition-rules-color{height:30px;line-height:30px;position:relative}.condition-rules-check{float:left;margin-top:10px}.condition-rules-label{-webkit-user-select:none;-moz-user-select:none;user-select:none;width:80px;display:inline-block}.condition-rules-select-color{background:#f5f5f5;border:1px solid #e5e5e5;padding:2px;position:absolute;top:50%;left:50%;transform:translate(20%,-50%)}.condition-rules-between-box{align-items:center;display:flex}.condition-rules-between-inpbox{border:1px solid #d4d4d4;width:108px;height:28px}.condition-rules-between-input{float:left;border:none;outline-style:none;width:60px;height:28px;padding:0 10px}.condition-rules-date{border:none;width:98%;line-height:26px}.condition-rules-select{width:150px;height:30px}.condition-rules-project-box{align-items:center;display:flex}.condition-rules-project-input{margin:0 6px}.fortune-toolbar{white-space:nowrap;background:#fafafc;border-bottom:1px solid #d4d4d4;flex-direction:row;align-items:center;padding:5px 0 3px 15px;display:flex;position:relative}.fortune-toolbar-divider{background-color:#e0e0e0;flex-shrink:0;width:1px;height:20px;margin:0 6px}.fortune-toolbar-menu-line{justify-content:space-between;align-items:center;display:flex;position:relative}.fortune-toolbar-menu-divider{width:\"100%\";background-color:#e0e0e0;height:1px;margin:2px 6px}.fortune-toolbar-button,.fortune-toolbar-combo{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;background:0;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;outline:none;align-items:center;margin:2px 4px;padding:2px;text-decoration:none;list-style:none;display:flex}.fortune-toolbar-combo-button,.fortune-toolbar-combo-arrow{align-items:center;display:flex}.fortune-toolbar-button:hover,.fortune-toolbar-combo:hover,.fortune-toolbar-combo-arrow:hover{cursor:pointer;background-color:#0000000f}.fortune-toolbar-button:active,.fortune-toolbar-combo:active{cursor:pointer;background-color:#0000001f}.fortune-toobar-combo-container{position:relative}.fortune-toolbar-combo-popup{white-space:nowrap;z-index:1004;position:absolute;top:32px;left:0}.fortune-toolbar-select,.fortune-toolbar-color-picker{background:#fff;border-radius:6px;padding:10px;box-shadow:2px 2px 10px #0003}.fortune-toolbar-select{max-height:75vh;padding-left:0;padding-right:0;overflow:auto}.fortune-toolbar-combo-button{font-size:12px}.fortune-toolbar-select-option{cursor:pointer;-webkit-user-select:none;-moz-user-select:none;user-select:none;min-width:60px;padding:8px 12px;font-size:12px}.fortune-toolbar-select-option:hover{background:#efefef}.fortune-toolbar-select::-webkit-scrollbar{display:none}.fortune-toolbar-color-picker-row{flex-direction:row;display:flex}.fortune-toolbar-combo-text{margin:0 4px}.fortune-toolbar-color-picker-item{cursor:pointer;width:16px;height:16px;margin:1px}.fortune-tooltip{visibility:hidden;color:#fff;text-align:center;z-index:25;white-space:nowrap;background-color:#666;border-radius:2px;padding:6px;font-size:12px;position:absolute;top:40px}.fortune-toolbar-button:hover .fortune-tooltip,.fortune-toolbar-combo:hover .fortune-tooltip{visibility:visible}.fortune-toolbar-more-container{z-index:1002;background:#fff;flex-flow:wrap;align-self:flex-end;align-items:center;max-width:348px;margin-right:40px;display:flex;position:absolute;top:40px;box-shadow:2px 2px 10px #0003}.fortune-toolbar-subtext{-o-transition:all .218s;text-align:right;opacity:.5;filter:alpha(opacity=50);color:#000;-webkit-user-select:none;-moz-user-select:none;user-select:none;padding-top:1px;padding-left:24px;font-family:Arial;font-size:12px;line-height:100%;-webkit-transition:all .218s;-moz-transition:all .218s;transition:all .218s;left:auto}.toolbar-item-sub-menu{cursor:default;z-index:1004;box-sizing:border-box;-webkit-user-select:none;-moz-user-select:none;user-select:none;background:#fff;border:1px solid #0003;border-radius:6px;outline:none;font-size:12px;position:absolute;box-shadow:0 2px 4px #0003}#fortune-custom-color{background:#f0f0f0;border:1px solid #0003;border-radius:6px;min-width:164px;font-size:12px;box-shadow:0 2px 4px #0003}#fortune-custom-color .color-reset{color:#333;cursor:pointer;white-space:nowrap;vertical-align:middle;-webkit-user-select:none;-moz-user-select:none;user-select:none;background:#fff;border-radius:6px;padding:10px 24px 10px 8px;list-style:none;position:relative}#fortune-custom-color .color-reset:hover{background:#e6e6e6}#fortune-custom-color .custom-color{background:#fff;border-radius:6px;justify-content:space-around;align-items:center;margin:1px 0;padding:10px;display:flex;position:relative}.fortune-border-select-menu{position:absolute;bottom:0}.fortune-border-color-preview{height:3px}.fortune-border-select-option{min-width:60px;height:24px;padding:8px 12px;font-size:12px;line-height:24px}.fortune-border-select-option:hover{cursor:pointer;background:#efefef}.fortune-border-style-preview{height:3px;overflow:hidden}.fortune-border-style-picker-menu{padding:0 10px}.fortune-border-style-picker-menu:hover{cursor:pointer;background:#efefef}#luckysheet-search-formula{font-size:12px}#luckysheet-search-formula .inpbox{margin-bottom:5px}#luckysheet-search-formula .inpbox div{margin-bottom:5px;display:block}#luckysheet-search-formula .inpbox input{box-sizing:border-box;border:1px solid #d4d4d4;width:100%;height:24px;padding:0 10px;font-size:12px;line-height:24px}#luckysheet-search-formula .selbox{margin-bottom:5px}#luckysheet-search-formula .selbox select{box-sizing:border-box;border:1px solid #d4d4d4;width:50%;height:24px;font-size:12px;line-height:24px}#luckysheet-search-formula .listbox label{margin-bottom:5px;display:block}#formulaTypeList,.formulaList{border:1px solid #d4d4d4;width:300px;height:170px;overflow-y:scroll}.listBox{border-bottom:1px solid #d4d4d4;padding:5px}.listBox.on{color:#fff;background-color:#8c89fe}#fortune-split-column{min-width:500px}#fortune-split-column label{-webkit-user-select:none;-moz-user-select:none;user-select:none}#fortune-split-column .title{font-size:16px}#fortune-split-column .splitDelimiters{margin-top:10px}#fortune-split-column .splitSymbols{border:1px solid #dfdfdf;margin:5px 0;padding:5px;position:relative}#fortune-split-column .splitSymbol{font-size:14px}#fortune-split-column .splitSimple{position:absolute;top:114px;left:0}#fortune-split-column #otherValue{width:50px;margin-left:5px;padding:0 5px}#fortune-split-column .splitDataPreview{margin-top:26px;font-size:14px}#fortune-split-column .splitColumnData{border:1px solid #dfdfdf;height:100px;margin:5px 0;padding:5px;overflow-y:scroll}#fortune-split-column .button-basic{text-align:center;vertical-align:middle;touch-action:manipulation;cursor:pointer;white-space:nowrap;-webkit-user-select:none;-moz-user-select:none;user-select:none;border-radius:2px;margin-bottom:0;padding:4px 8px;font-size:14px;font-weight:400;line-height:1.42857;display:inline-block}#fortune-split-column .button-primary{color:#fff;background:#0188fb;border:1px solid #0188fb;margin-right:10px}#fortune-split-column .button-close{color:#333;background-color:#fff;border:1px solid #ccc}#fortune-split-column table{border-collapse:collapse}#fortune-split-column tr{vertical-align:inherit;border-color:inherit;display:table-row}#fortune-split-column td{vertical-align:inherit;border:1px solid #333;display:table-cell}label{cursor:default}#fortune-location-condition{min-width:500px}#fortune-location-condition .title{color:#000;cursor:default;background-color:#fff;font-size:16px;font-weight:400;line-height:48px}#fortune-location-condition .listbox{color:#000;border:1px solid #dfdfdf;padding:10px;font-size:14px}#fortune-location-condition .listbox .listItem{padding:5px 0}#fortune-location-condition .listbox .listItem input[type=radio]{float:left;margin-top:5px}#fortune-location-condition .listItem{padding:5px 0}#fortune-location-condition .listItem .subItem{height:30px;padding:0 10px;display:block}#fortune-location-condition input[type=radio]{float:left;margin-top:3px}#fortune-location-condition .listbox .listItem .subbox{height:30px;padding:0 10px}#fortune-location-condition .listbox .listItem .subbox .subItem{float:left;margin-right:5px}#fortune-location-condition .button-basic{text-align:center;vertical-align:middle;touch-action:manipulation;cursor:pointer;white-space:nowrap;-webkit-user-select:none;-moz-user-select:none;user-select:none;border-radius:2px;margin-top:10px;margin-bottom:0;padding:4px 8px;font-size:14px;font-weight:400;line-height:1.42857;display:inline-block}#fortune-location-condition .button-primary{color:#fff;background:#0188fb;border:1px solid #0188fb;margin-right:10px}#fortune-location-condition .button-close{color:#333;background-color:#fff;border:1px solid #ccc}.listBox{justify-content:space-between;display:flex}.inpbox{margin-bottom:10px}.decimal-places-input{width:70px}.format-list{border:1px solid #d4d4d4;width:300px;height:170px;overflow-y:scroll}.fortune-fx-editor{border-bottom:1px solid #d4d4d4;flex-direction:row;height:28px;display:flex}.fortune-fx-icon{align-items:center;margin:0 12px;display:flex}.fortune-name-box-container{border-right:1px solid #d4d4d4;align-items:center;width:99px;font-size:14px;display:flex}.fortune-name-box{text-align:center;cursor:text;white-space:nowrap;word-wrap:break-word;-webkit-nbsp-mode:space;-webkit-line-break:after-white-space;background-color:#fff;outline:none;width:100%;margin:0;overflow:hidden;-webkit-transform:translateZ(0)}.fortune-fx-input-container{border-left:1px solid #e5e5e5;flex:1;align-items:center;padding:0;display:flex;position:relative;overflow:visible}.fortune-fx-input{cursor:text;white-space:pre-wrap;word-wrap:break-word;-webkit-nbsp-mode:space;-webkit-line-break:after-white-space;box-sizing:border-box;color:#000;text-align:left;background-color:#fff;outline:none;flex:1;height:100%;margin:0;padding-top:7px;padding-left:2px;font-size:14px;line-height:14px;overflow-y:scroll;-webkit-transform:translateZ(0)}.fortune-fx-input[contenteditable=true]{-webkit-user-modify:read-write-plaintext-only}.luckysheet-sheet-area{box-sizing:border-box;color:#444;-webkit-touch-callout:none;cursor:default;background-color:#fafafc;justify-content:space-between;align-items:center;width:100%;height:31px;margin:0;padding:0 30px 0 44px;transition:all .3s;display:flex;position:relative}#luckysheet-sheet-content{flex:3;align-items:center;width:0;display:flex}#luckysheet-bottom-pager{z-index:1;text-align:right;white-space:nowrap;background-color:#fafafc;flex:2;width:0}.luckysheet-sheet-area>div,.luckysheet-sheet-area .luckysheet-sheets-item{display:inline-block}.fortune-sheettab-container{vertical-align:bottom;max-width:54%;margin-left:0;padding:0;display:inline-block;position:relative}.fortune-sheettab-container .boundary{z-index:1;background:#fff;width:6px;height:100%;position:absolute;top:0}.fortune-sheettab-container .boundary-left{background-image:linear-gradient(to right, var(--tw-gradient-stops));--tw-gradient-from:#4445;--tw-gradient-stops:var(--tw-gradient-from), var(--tw-gradient-to,#8880);left:0}.fortune-sheettab-container .boundary-right{background-image:linear-gradient(to left, var(--tw-gradient-stops));--tw-gradient-from:#4445;--tw-gradient-stops:var(--tw-gradient-from), var(--tw-gradient-to,#8880);right:0}.fortune-sheettab-container .fortune-sheettab-container-c{white-space:nowrap;vertical-align:bottom;max-width:100%;margin-left:0;padding:0;display:inline-block;position:relative;overflow:hidden}.luckysheet-sheet-container-menu-hide .luckysheet-sheets-item{padding-right:5px!important}.luckysheet-sheet-container-menu-hide .luckysheet-sheets-item-menu{display:none!important}.luckysheet-sheet-area div.luckysheet-sheets-item{color:#676464;cursor:pointer;box-sizing:border-box;vertical-align:middle;background-color:#fafafc;border-left:1px solid #e0e0e0;border-right:1px solid #e0e0e0;min-width:30px;height:29px;margin-right:-1px;padding:2px 19px 0 5px;font-size:13px;line-height:29px;transition:all .1s;position:relative;top:0}.luckysheet-sheet-area div.luckysheet-sheets-item:last-child{margin-right:1px}.luckysheet-sheet-area div.luckysheet-sheets-item:hover{color:#490500;background-color:#efefef}.luckysheet-sheet-area div.luckysheet-sheets-item .luckysheet-sheets-item-menu{color:#a1a1a1;text-align:center;width:15px;height:100%;margin-left:2px;display:inline-block;position:absolute;top:-2px;right:0}.luckysheet-sheet-area div.luckysheet-sheets-item .luckysheet-sheets-item-menu:hover{color:#2a2a2a;cursor:pointer}.luckysheet-sheet-area div.luckysheet-sheets-item .luckysheet-sheets-item-name{padding:0 3px}.luckysheet-sheets-item-color{width:100%;height:10%;position:absolute;bottom:0;left:0}.luckysheet-sheet-area div.luckysheet-sheets-item .luckysheet-sheets-item-name[contenteditable=true]{-moz-user-modify:read-write-plaintext-only;-webkit-user-modify:read-write-plaintext-only;border:1px solid #d9d9d9;min-width:8px;height:18px;margin:-4px -1px;line-height:18px;display:inline-block;-webkit-user-select:text!important;-moz-user-select:text!important;-ms-user-select:text!important}.luckysheet-sheet-area div.luckysheet-sheets-item .luckysheet-sheets-item-name[contenteditable=true]:focus{border:1px solid #4d90fe;outline:none;-webkit-box-shadow:inset 0 1px 2px #0000004d;-moz-box-shadow:inset 0 1px 2px #0000004d;box-shadow:inset 0 1px 2px #0000004d}.luckysheet-sheet-area div.luckysheet-sheets-item-active{color:#222;cursor:default;background-color:#efefef;border-top-color:#fff;height:29px;line-height:29px}.luckysheet-sheet-area div.luckysheet-sheets-item-active:hover{color:#222;background-color:#ececec}.fortune-sheettab-button{justify-content:center;align-items:center;width:29px;height:29px;display:flex}.fortune-sheettab-button:hover{background-color:#efefef;justify-content:center;align-items:center;width:29px;height:29px;display:flex}.luckysheet-noselected-text{-moz-user-select:-moz-test;-khtml-user-select:none;-webkit-user-select:none;-ms-user-select:none;user-select:none}.fortune-sheettab-scroll{cursor:pointer;align-items:center;height:29px;padding:0 5px;display:flex}.fortune-sheettab-scroll:hover{background-color:#e0e0e0}.fortune-sheettab-placeholder{vertical-align:middle;width:30px;height:29px;line-height:29px;display:inline-block}.sheet-list-container{flex-direction:column;justify-content:flex-end;display:flex;overflow:visible}.luckysheet-sheet-selection-calInfo{align-content:center;align-self:flex-end;height:22px;padding:0 0 0 44px;font-size:12px;display:flex}.luckysheet-sheet-selection-calInfo div{white-space:nowrap;margin:auto 7px auto 0}.luckysheet-sheets-item-function{width:12px;height:24px;position:absolute;top:4px;right:2px}.fortune-sheet-area-right{display:flex!important}.fortune-zoom-container{white-space:nowrap;-webkit-user-select:none;-moz-user-select:none;user-select:none;align-items:center;display:flex;overflow:visible}.fortune-zoom-button{cursor:pointer;justify-content:center;align-items:center;width:24px;height:24px;display:flex}.fortune-zoom-button:hover{background:#efefef}.fortune-zoom-ratio{color:#1e1e1f;cursor:pointer;justify-content:center;width:48px;font-size:12px;display:flex;position:relative}.fortune-zoom-ratio-current{width:100%}.fortune-zoom-ratio-item:hover{background:#efefef}.fortune-zoom-ratio-menu{z-index:1004;background:#fff;border-radius:6px;padding:10px 0;line-height:24px;position:absolute;bottom:30px;left:0;box-shadow:2px 2px 10px #0003}.fortune-zoom-ratio-text{padding:0 10px}.fortune-context-menu{cursor:default;z-index:1004;box-sizing:border-box;-webkit-user-select:none;-moz-user-select:none;user-select:none;background:#fff;border:1px solid #0003;border-radius:4px;outline:none;max-height:100%;margin:0;padding:6px 0;font-size:13px;transition:opacity .218s;position:absolute;overflow-y:auto;box-shadow:2px 2px 20px #00000026}.fortune-context-menu input.luckysheet-mousedown-cancel{text-align:center;width:35px;margin-left:5px;margin-right:5px}.fortune-context-menu-divider{width:\"100%\";background-color:#e0e0e0;height:1px;margin:4px 0}.luckysheet-cols-menu .luckysheet-cols-menuitem{color:#333;cursor:pointer;white-space:nowrap;vertical-align:middle;-webkit-user-select:none;-moz-user-select:none;user-select:none;margin:0;padding:1px 24px 1px 8px;list-style:none;position:relative}.luckysheet-cols-menu .luckysheet-cols-menuitem:hover,.luckysheet-cols-menu .luckysheet-cols-menuitem-hover{background:#efefef}.luckysheet-cols-menu .luckysheet-cols-menuitem .luckysheet-cols-menuitem-content{color:#333;cursor:pointer;white-space:nowrap;-webkit-user-select:none;-moz-user-select:none;user-select:none;margin:0;padding:6px 7em 6px 30px;list-style:none;position:relative}.fortune-filter-menu .luckysheet-cols-menuitem{padding:0}.fortune-filter-menu .luckysheet-cols-menuitem .luckysheet-cols-menuitem-content{padding:7px 24px}.fortune-menuitem-row{white-space:pre;align-items:center;padding:7px 24px;display:flex}.fortune-byvalue-btn{cursor:pointer;color:#00f;text-decoration:underline}.luckysheet-filter-bycolor-submenu .button-basic,.fortune-filter-menu .button-basic{cursor:pointer;border-radius:4px;flex-flow:row;justify-content:center;align-items:center;padding:4px 8px;font-size:14px;display:flex}.luckysheet-filter-bycolor-submenu .button-basic{margin:5px 20px}.luckysheet-filter-bycolor-submenu .button-default,.fortune-filter-menu .button-default{color:#262a33;background-color:#fff;border:1px solid #ebebeb;margin-left:10px}.luckysheet-filter-bycolor-submenu .button-default:hover,.fortune-filter-menu .button-default:hover{background-color:#e6e6e6}.luckysheet-filter-bycolor-submenu .button-primary,.fortune-filter-menu .button-primary{color:#fff;background-color:#0188fb}.luckysheet-filter-bycolor-submenu .button-primary:hover,.fortune-filter-menu .button-primary:hover{background:#5391ff}.fortune-filter-menu .button-danger{color:#fff;background-color:#d9534f;margin-left:10px}.fortune-filter-menu .button-danger:hover{background-color:#c9302c}.filter-bycolor-container{justify-content:space-between;align-items:center;display:flex}.filtermenu-input-container{padding:0}.filtermenu-input-container input.luckysheet-mousedown-cancel{box-sizing:border-box;-webkit-user-select:auto;-moz-user-select:auto;-ms-user-select:auto;user-select:auto;text-align:start;border:1px solid #a1a1a1;border-radius:3px;outline:none;width:230px;height:26px;margin:0 20px;padding:1px 8px;font-size:12px}.filtermenu-input-container input.luckysheet-mousedown-cancel:focus{border:1px solid #0188fb;outline:none}.byvalue-btn-row{justify-content:space-between;align-items:flex-start;padding-bottom:0}.filter-caret{border:4px solid #0000;width:0;height:0;display:inline-block}.filter-caret.right{border-left-color:#000;margin-left:2px;margin-right:3px}.filter-caret.down{border-top-color:#000;margin-top:5px;margin-right:5px}.filter-checkbox{margin-left:0;margin-right:5px}#luckysheet-filter-byvalue-select{min-height:100px;padding:4px 24px;overflow:hidden auto}#luckysheet-filter-byvalue-select .count,#luckysheet-pivotTableFilter-byvalue-select .count{color:gray;margin-left:5px}#luckysheet-filter-byvalue-select .select-item{align-items:center;display:flex}.luckysheet-filter-bycolor-submenu{z-index:1004;background-color:#fff;border:1px solid #0003;min-width:170px;padding:5px 0;font-size:12px;position:absolute}.luckysheet-filter-bycolor-submenu .title{color:#333;text-align:center;background-color:#f4f4f4;padding:10px;font-weight:600}.luckysheet-filter-bycolor-submenu .one-color-tip{text-align:center;padding:7px 30px}.luckysheet-filter-bycolor-submenu .color-list{max-height:128px;overflow:auto}.luckysheet-filter-bycolor-submenu .item{cursor:pointer;background-color:#fff;padding:5px 40px 5px 20px;position:relative}.luckysheet-filter-bycolor-submenu .item:hover{background-color:#d3d3d3}.luckysheet-filter-bycolor-submenu .item .color-label{border:1px solid #d1d1d1;width:70px;height:20px;display:block}.luckysheet-filter-bycolor-submenu .item input[type=checkbox]{position:absolute;top:6px;right:10px}.change-color-triangle{position:absolute;top:3px;right:-18px}.fortune-sort-title{color:#000;cursor:default;background-color:#fff;margin:0 0 16px;font-size:16px;font-weight:400;line-height:24px}.fortune-sort-modal>div{margin-bottom:10px}.fortune-sort-tablec td{white-space:nowrap;padding:5px}.fortune-sort-button{margin-top:10px;margin-bottom:25px}#fortune-change-color{background:#f0f0f0;border:1px solid #0003;border-radius:6px;min-width:164px;height:252px;position:absolute;bottom:-110px;left:197px;box-shadow:0 2px 4px #0003}#fortune-change-color .color-reset{color:#333;cursor:pointer;white-space:nowrap;vertical-align:middle;-webkit-user-select:none;-moz-user-select:none;user-select:none;background:#fff;border-radius:6px;padding:10px 24px 10px 8px;list-style:none;position:relative}#fortune-change-color .color-reset:hover{background:#e6e6e6}#fortune-change-color .custom-color{background:#fff;border-radius:6px;justify-content:space-around;align-items:center;margin:1px 0;padding:10px;display:flex;position:relative}.button-basic{text-align:center;vertical-align:middle;touch-action:manipulation;cursor:pointer;white-space:nowrap;-webkit-user-select:none;-moz-user-select:none;user-select:none;border-radius:2px;margin-bottom:0;padding:4px 8px;font-size:12px;font-weight:400;line-height:1.42857;display:inline-block}.button-primary{color:#fff;background:#0188fb;border:1px solid #0188fb;margin-right:-4px}.fortune-sheet-list{z-index:10002;min-width:120px;max-height:60%;margin-left:72px;position:absolute;bottom:53px;overflow:hidden auto}.fortune-sheet-list-item{cursor:pointer;width:100%;height:30px;margin-right:46px;line-height:30px}.fortune-sheet-list-item-name{margin-right:15px;position:relative}.fortune-sheet-list-item-name .luckysheet-sheets-list-item-color{width:6%;height:100%;position:absolute;bottom:0;left:-6px}.fortune-sheet-list :hover{background-color:#efefef}.fortune-sheet-hidden-button{justify-content:flex-end;margin-right:15px;display:inline-flex;position:absolute;right:0}.fortune-sheet-hidden-button :hover{background-color:#d0d0d0}.fortune-sheet-selected-check-sapce{width:20px;margin-left:15px;display:inline-block}";
133555
133573
  //#endregion
133556
133574
  //#region \0dsh-excel-worker-source
@@ -133650,7 +133668,7 @@ window.__ModuleLoader__.load({
133650
133668
  }
133651
133669
  //#endregion
133652
133670
  //#region \0dsh-css:/home/runner/work/deepseek-harness/deepseek-harness/packages/client/ui-sidebar-documentpreview/src/client/excel/ExcelBody.module.css.mjs
133653
- const css = "._3HaaOG_body{white-space:normal;height:100%;min-height:0;font-family:var(--dsw-font,sans-serif);flex-direction:column;display:flex;overflow:hidden}._3HaaOG_workbook{color-scheme:light;flex:1;min-width:0;min-height:0;position:relative}._3HaaOG_notice{color:var(--dsw-alias-state-warn-label);background:var(--dsw-alias-state-warn-tertiary);font-size:var(--dsh-content-font-size-secondary,13px);overflow-wrap:anywhere;flex:none;align-items:flex-start;gap:8px;padding:8px 12px;line-height:1.5;display:flex}._3HaaOG_notice>svg{flex:none;margin-top:2px}._3HaaOG_formulaWarning{z-index:3;width:20px;height:20px;color:var(--dsw-alias-state-warn-label);background:0 0;border:0;border-radius:4px;padding:3px;display:flex;position:absolute;top:4px;left:142px}._3HaaOG_formulaWarning:hover,._3HaaOG_formulaWarning:focus-visible{background:var(--dsw-alias-state-warn-tertiary);outline:none}._3HaaOG_withFormulaWarning .fortune-fx-input{padding-left:24px}._3HaaOG_status{height:100%;color:var(--dsw-alias-label-secondary);justify-content:center;align-items:center;gap:8px;padding:16px;display:flex}";
133671
+ const css = "._3HaaOG_body{white-space:normal;height:100%;min-height:0;font-family:var(--dsw-font,sans-serif);flex-direction:column;display:flex;overflow:hidden}._3HaaOG_workbook{color-scheme:light;color:canvastext;flex:1;min-width:0;min-height:0;position:relative}._3HaaOG_workbook .fortune-stat-area,._3HaaOG_workbook .luckysheet-sheets-item-function,._3HaaOG_workbook .fortune-cols-freeze-handle,._3HaaOG_workbook .fortune-rows-freeze-handle{display:none}._3HaaOG_workbook .luckysheet-sheet-area div.luckysheet-sheets-item{padding-right:5px}._3HaaOG_workbook .luckysheet-sheet-area{padding:0}._3HaaOG_workbook #luckysheet-sheet-content{flex:1;min-width:0}._3HaaOG_workbook .fortune-sheettab-container{flex:1;min-width:0;max-width:100%}._3HaaOG_workbook .fortune-sheettab-container .fortune-sheettab-container-c{overscroll-behavior-x:contain;scrollbar-width:none;overflow:auto hidden}._3HaaOG_workbook .fortune-sheettab-scroll,._3HaaOG_workbook .fortune-sheet-area-right{flex:none}._3HaaOG_workbook .fortune-fx-input-container{min-width:0}._3HaaOG_workbook .fortune-fx-input{white-space:nowrap;scrollbar-width:none;min-width:0;overflow:auto hidden}._3HaaOG_notice{color:var(--dsw-alias-state-warn-label);background:var(--dsw-alias-state-warn-tertiary);font-size:var(--dsh-content-font-size-secondary,13px);overflow-wrap:anywhere;flex:none;align-items:flex-start;gap:8px;padding:8px 12px;line-height:1.5;display:flex}._3HaaOG_notice>svg{flex:none;margin-top:2px}._3HaaOG_formulaWarning{z-index:3;width:20px;height:20px;color:var(--dsw-alias-state-warn-label);border-radius:var(--dsw-radius-sm);background:0 0;border:0;padding:3px;display:flex;position:absolute;top:4px;left:142px}._3HaaOG_formulaWarning:hover,._3HaaOG_formulaWarning:focus-visible{background:var(--dsw-alias-state-warn-tertiary);outline:none}._3HaaOG_withFormulaWarning .fortune-fx-input{padding-left:24px}._3HaaOG_status{height:100%;color:var(--dsw-alias-label-secondary);justify-content:center;align-items:center;gap:8px;padding:16px;display:flex}";
133654
133672
  const tagId = "@deepseek-ai/dsh-client-ui-sidebar-documentpreview/ExcelBody.module.css";
133655
133673
  if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId) + "]") === null) {
133656
133674
  const tag = document.createElement("style");
@@ -133677,7 +133695,7 @@ window.__ModuleLoader__.load({
133677
133695
  * @param props - Complete workbook bytes, limits, and locale.
133678
133696
  * @returns An isolated spreadsheet surface with cancellable loading.
133679
133697
  */
133680
- function ExcelBody({ content, format, limits, t }) {
133698
+ function ExcelBody({ content, format, limits, t, loading }) {
133681
133699
  const data = content.kind === "bytes" ? content.data : void 0;
133682
133700
  const [state, setState] = (0, react.useState)();
133683
133701
  const [attempt, setAttempt] = (0, react.useState)(0);
@@ -133724,13 +133742,7 @@ window.__ModuleLoader__.load({
133724
133742
  role: "alert",
133725
133743
  children: t("invalid")
133726
133744
  });
133727
- if (state?.data !== data || state.format !== format) return (0, react_jsx_runtime.jsx)("span", {
133728
- className: ExcelBody_module_css_default.status,
133729
- role: "status",
133730
- "aria-label": t("loading"),
133731
- "data-document-loading": true,
133732
- children: (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.StateDot, { state: "ongoing" })
133733
- });
133745
+ if (state?.data !== data || state.format !== format) return loading;
133734
133746
  if ("error" in state) return (0, react_jsx_runtime.jsxs)("div", {
133735
133747
  className: ExcelBody_module_css_default.status,
133736
133748
  role: "alert",