@eternalheart/angular-file-preview 1.6.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (119) hide show
  1. package/LICENSE +22 -0
  2. package/README.md +879 -0
  3. package/README.zh-CN.md +876 -0
  4. package/lib/LICENSE +22 -0
  5. package/lib/README.md +879 -0
  6. package/lib/components/preview/file-preview-toolbar.d.ts +19 -0
  7. package/lib/components/preview/nav-arrows.d.ts +25 -0
  8. package/lib/components/preview/renderer-outlet.d.ts +23 -0
  9. package/lib/components/preview/toolbar-button.d.ts +12 -0
  10. package/lib/components/resizable-split.d.ts +32 -0
  11. package/lib/di/locale.service.d.ts +12 -0
  12. package/lib/di/request.service.d.ts +20 -0
  13. package/lib/di/theme-mode.d.ts +6 -0
  14. package/lib/di/theme.service.d.ts +9 -0
  15. package/lib/fesm2022/eternalheart-angular-file-preview-avifLoader-BP3fgcMm-CZsJ9svm.mjs +55 -0
  16. package/lib/fesm2022/eternalheart-angular-file-preview-avifLoader-BP3fgcMm-CZsJ9svm.mjs.map +1 -0
  17. package/lib/fesm2022/eternalheart-angular-file-preview-eternalheart-angular-file-preview-RendererError-DtNihCIX-DtNihCIX.mjs +58 -0
  18. package/lib/fesm2022/eternalheart-angular-file-preview-eternalheart-angular-file-preview-RendererError-DtNihCIX-DtNihCIX.mjs.map +1 -0
  19. package/lib/fesm2022/eternalheart-angular-file-preview-eternalheart-angular-file-preview-UobTf36G.mjs +5835 -0
  20. package/lib/fesm2022/eternalheart-angular-file-preview-eternalheart-angular-file-preview-UobTf36G.mjs.map +1 -0
  21. package/lib/fesm2022/eternalheart-angular-file-preview-eternalheart-angular-file-preview-base.types-D5x7QPey-D5x7QPey.mjs +17 -0
  22. package/lib/fesm2022/eternalheart-angular-file-preview-eternalheart-angular-file-preview-base.types-D5x7QPey-D5x7QPey.mjs.map +1 -0
  23. package/lib/fesm2022/eternalheart-angular-file-preview-eternalheart-angular-file-preview-index--7d8Hgi0-D-sg24Qs.mjs +284 -0
  24. package/lib/fesm2022/eternalheart-angular-file-preview-eternalheart-angular-file-preview-index--7d8Hgi0-D-sg24Qs.mjs.map +1 -0
  25. package/lib/fesm2022/eternalheart-angular-file-preview-eternalheart-angular-file-preview-index-6dZS_Cfs-B1itLV5R.mjs +703 -0
  26. package/lib/fesm2022/eternalheart-angular-file-preview-eternalheart-angular-file-preview-index-6dZS_Cfs-B1itLV5R.mjs.map +1 -0
  27. package/lib/fesm2022/eternalheart-angular-file-preview-eternalheart-angular-file-preview-index-B1ANUCTy-BRs7TMLn.mjs +231 -0
  28. package/lib/fesm2022/eternalheart-angular-file-preview-eternalheart-angular-file-preview-index-B1ANUCTy-BRs7TMLn.mjs.map +1 -0
  29. package/lib/fesm2022/eternalheart-angular-file-preview-eternalheart-angular-file-preview-index-BEaqpRV8-BidVIVlO.mjs +552 -0
  30. package/lib/fesm2022/eternalheart-angular-file-preview-eternalheart-angular-file-preview-index-BEaqpRV8-BidVIVlO.mjs.map +1 -0
  31. package/lib/fesm2022/eternalheart-angular-file-preview-eternalheart-angular-file-preview-index-BGqTRZbm-CAOLRw20.mjs +688 -0
  32. package/lib/fesm2022/eternalheart-angular-file-preview-eternalheart-angular-file-preview-index-BGqTRZbm-CAOLRw20.mjs.map +1 -0
  33. package/lib/fesm2022/eternalheart-angular-file-preview-eternalheart-angular-file-preview-index-Bv3JRXKn-B4Wewc-4.mjs +273 -0
  34. package/lib/fesm2022/eternalheart-angular-file-preview-eternalheart-angular-file-preview-index-Bv3JRXKn-B4Wewc-4.mjs.map +1 -0
  35. package/lib/fesm2022/eternalheart-angular-file-preview-eternalheart-angular-file-preview-index-C0McUoqT-DJ35bhIz.mjs +288 -0
  36. package/lib/fesm2022/eternalheart-angular-file-preview-eternalheart-angular-file-preview-index-C0McUoqT-DJ35bhIz.mjs.map +1 -0
  37. package/lib/fesm2022/eternalheart-angular-file-preview-eternalheart-angular-file-preview-index-C518mdUd-B5SCzrzU.mjs +550 -0
  38. package/lib/fesm2022/eternalheart-angular-file-preview-eternalheart-angular-file-preview-index-C518mdUd-B5SCzrzU.mjs.map +1 -0
  39. package/lib/fesm2022/eternalheart-angular-file-preview-eternalheart-angular-file-preview-index-CDjKPqyW-CmX5sdkL.mjs +102 -0
  40. package/lib/fesm2022/eternalheart-angular-file-preview-eternalheart-angular-file-preview-index-CDjKPqyW-CmX5sdkL.mjs.map +1 -0
  41. package/lib/fesm2022/eternalheart-angular-file-preview-eternalheart-angular-file-preview-index-CHi9tOe0-NOeQYAnM.mjs +516 -0
  42. package/lib/fesm2022/eternalheart-angular-file-preview-eternalheart-angular-file-preview-index-CHi9tOe0-NOeQYAnM.mjs.map +1 -0
  43. package/lib/fesm2022/eternalheart-angular-file-preview-eternalheart-angular-file-preview-index-CQwhffym-DAGw4Xy_.mjs +823 -0
  44. package/lib/fesm2022/eternalheart-angular-file-preview-eternalheart-angular-file-preview-index-CQwhffym-DAGw4Xy_.mjs.map +1 -0
  45. package/lib/fesm2022/eternalheart-angular-file-preview-eternalheart-angular-file-preview-index-CSCTj7ft-BfqruUyY.mjs +164 -0
  46. package/lib/fesm2022/eternalheart-angular-file-preview-eternalheart-angular-file-preview-index-CSCTj7ft-BfqruUyY.mjs.map +1 -0
  47. package/lib/fesm2022/eternalheart-angular-file-preview-eternalheart-angular-file-preview-index-Cb1RLXeO-Bj9gjS1Z.mjs +655 -0
  48. package/lib/fesm2022/eternalheart-angular-file-preview-eternalheart-angular-file-preview-index-Cb1RLXeO-Bj9gjS1Z.mjs.map +1 -0
  49. package/lib/fesm2022/eternalheart-angular-file-preview-eternalheart-angular-file-preview-index-Cw90Kdyg-BzrW_cyx.mjs +207 -0
  50. package/lib/fesm2022/eternalheart-angular-file-preview-eternalheart-angular-file-preview-index-Cw90Kdyg-BzrW_cyx.mjs.map +1 -0
  51. package/lib/fesm2022/eternalheart-angular-file-preview-eternalheart-angular-file-preview-index-D35x1nwM-CugEEXjg.mjs +199 -0
  52. package/lib/fesm2022/eternalheart-angular-file-preview-eternalheart-angular-file-preview-index-D35x1nwM-CugEEXjg.mjs.map +1 -0
  53. package/lib/fesm2022/eternalheart-angular-file-preview-eternalheart-angular-file-preview-index-D9jJNzeM-mWX59Aj2.mjs +194 -0
  54. package/lib/fesm2022/eternalheart-angular-file-preview-eternalheart-angular-file-preview-index-D9jJNzeM-mWX59Aj2.mjs.map +1 -0
  55. package/lib/fesm2022/eternalheart-angular-file-preview-eternalheart-angular-file-preview-index-DbmuvdvN-C29uLyt2.mjs +94 -0
  56. package/lib/fesm2022/eternalheart-angular-file-preview-eternalheart-angular-file-preview-index-DbmuvdvN-C29uLyt2.mjs.map +1 -0
  57. package/lib/fesm2022/eternalheart-angular-file-preview-eternalheart-angular-file-preview-index-DsNNZ59Q-C8MaSME6.mjs +468 -0
  58. package/lib/fesm2022/eternalheart-angular-file-preview-eternalheart-angular-file-preview-index-DsNNZ59Q-C8MaSME6.mjs.map +1 -0
  59. package/lib/fesm2022/eternalheart-angular-file-preview-eternalheart-angular-file-preview-index-DufW2Fuc-CTosCut6.mjs +193 -0
  60. package/lib/fesm2022/eternalheart-angular-file-preview-eternalheart-angular-file-preview-index-DufW2Fuc-CTosCut6.mjs.map +1 -0
  61. package/lib/fesm2022/eternalheart-angular-file-preview-eternalheart-angular-file-preview-index-TSTa_Q7E-DBhkL6pV.mjs +184 -0
  62. package/lib/fesm2022/eternalheart-angular-file-preview-eternalheart-angular-file-preview-index-TSTa_Q7E-DBhkL6pV.mjs.map +1 -0
  63. package/lib/fesm2022/eternalheart-angular-file-preview-eternalheart-angular-file-preview-index-pG0Ko5mI-DthQJg-X.mjs +492 -0
  64. package/lib/fesm2022/eternalheart-angular-file-preview-eternalheart-angular-file-preview-index-pG0Ko5mI-DthQJg-X.mjs.map +1 -0
  65. package/lib/fesm2022/eternalheart-angular-file-preview-eternalheart-angular-file-preview-shiki-highlight-CL9cG481-BKfwdOpN.mjs +68 -0
  66. package/lib/fesm2022/eternalheart-angular-file-preview-eternalheart-angular-file-preview-shiki-highlight-CL9cG481-BKfwdOpN.mjs.map +1 -0
  67. package/lib/fesm2022/eternalheart-angular-file-preview-heicLoader-CH_raQNn-BSXHd_oi.mjs +36 -0
  68. package/lib/fesm2022/eternalheart-angular-file-preview-heicLoader-CH_raQNn-BSXHd_oi.mjs.map +1 -0
  69. package/lib/fesm2022/eternalheart-angular-file-preview-jp2Loader-ldvCSsvm-DJEhfimG.mjs +121 -0
  70. package/lib/fesm2022/eternalheart-angular-file-preview-jp2Loader-ldvCSsvm-DJEhfimG.mjs.map +1 -0
  71. package/lib/fesm2022/eternalheart-angular-file-preview-psdLoader-D5CkupyY-D5Gegcdg.mjs +78 -0
  72. package/lib/fesm2022/eternalheart-angular-file-preview-psdLoader-D5CkupyY-D5Gegcdg.mjs.map +1 -0
  73. package/lib/fesm2022/eternalheart-angular-file-preview-rawLoader-0mLvxCNp-CCXn9Rdp.mjs +81 -0
  74. package/lib/fesm2022/eternalheart-angular-file-preview-rawLoader-0mLvxCNp-CCXn9Rdp.mjs.map +1 -0
  75. package/lib/fesm2022/eternalheart-angular-file-preview-tiffLoader-CmUAD1vO-0JqIws9t.mjs +59 -0
  76. package/lib/fesm2022/eternalheart-angular-file-preview-tiffLoader-CmUAD1vO-0JqIws9t.mjs.map +1 -0
  77. package/lib/fesm2022/eternalheart-angular-file-preview.mjs +2 -0
  78. package/lib/fesm2022/eternalheart-angular-file-preview.mjs.map +1 -0
  79. package/lib/file-preview-content.d.ts +65 -0
  80. package/lib/file-preview-embed.d.ts +30 -0
  81. package/lib/file-preview-modal.d.ts +34 -0
  82. package/lib/fp-core.d.ts +1 -0
  83. package/lib/index.css +2119 -0
  84. package/lib/index.d.ts +11 -0
  85. package/lib/renderers/Audio/index.d.ts +74 -0
  86. package/lib/renderers/Cad/index.d.ts +45 -0
  87. package/lib/renderers/Cad/toolbar.d.ts +15 -0
  88. package/lib/renderers/Csv/index.d.ts +26 -0
  89. package/lib/renderers/Doc/index.d.ts +19 -0
  90. package/lib/renderers/Docx/index.d.ts +42 -0
  91. package/lib/renderers/Epub/index.d.ts +57 -0
  92. package/lib/renderers/Font/font-preview-line.d.ts +26 -0
  93. package/lib/renderers/Font/index.d.ts +52 -0
  94. package/lib/renderers/Image/index.d.ts +79 -0
  95. package/lib/renderers/Json/index.d.ts +61 -0
  96. package/lib/renderers/Markdown/index.d.ts +35 -0
  97. package/lib/renderers/Mobi/index.d.ts +51 -0
  98. package/lib/renderers/Msg/index.d.ts +47 -0
  99. package/lib/renderers/Pdf/index.d.ts +55 -0
  100. package/lib/renderers/Ppt/index.d.ts +19 -0
  101. package/lib/renderers/Pptx/index.d.ts +29 -0
  102. package/lib/renderers/RendererError.d.ts +9 -0
  103. package/lib/renderers/RendererLoading.d.ts +7 -0
  104. package/lib/renderers/Subtitle/index.d.ts +25 -0
  105. package/lib/renderers/Text/index.d.ts +29 -0
  106. package/lib/renderers/Unsupported/index.d.ts +15 -0
  107. package/lib/renderers/Video/index.d.ts +28 -0
  108. package/lib/renderers/Xlsx/index.d.ts +25 -0
  109. package/lib/renderers/Xml/index.d.ts +26 -0
  110. package/lib/renderers/Zip/index.d.ts +58 -0
  111. package/lib/renderers/Zip/tree-item.d.ts +29 -0
  112. package/lib/renderers/base.types.d.ts +10 -0
  113. package/lib/renderers/lazy.d.ts +23 -0
  114. package/lib/renderers/registry.d.ts +13 -0
  115. package/lib/renderers/toolbar.types.d.ts +19 -0
  116. package/lib/types.d.ts +26 -0
  117. package/lib/utils/audio-player.d.ts +20 -0
  118. package/lib/utils/shiki-highlight.d.ts +7 -0
  119. package/package.json +119 -0
@@ -0,0 +1,102 @@
1
+ import * as i0 from '@angular/core';
2
+ import { input, inject, signal, effect, untracked, ChangeDetectionStrategy, Component } from '@angular/core';
3
+ import { DomSanitizer } from '@angular/platform-browser';
4
+ import { L as LocaleService, R as RequestService, g as getFallbackTranslator, k as Tg } from './eternalheart-angular-file-preview-eternalheart-angular-file-preview-UobTf36G.mjs';
5
+ import { R as RendererError } from './eternalheart-angular-file-preview-eternalheart-angular-file-preview-RendererError-DtNihCIX-DtNihCIX.mjs';
6
+
7
+ class DocRenderer {
8
+ constructor() {
9
+ this.url = input.required();
10
+ this.locale = inject(LocaleService, { optional: true });
11
+ this.request = inject(RequestService, { optional: true });
12
+ this.sanitizer = inject(DomSanitizer);
13
+ this.t = this.locale?.t() ?? getFallbackTranslator();
14
+ this.html = signal('');
15
+ this.loading = signal(true);
16
+ this.error = signal(null);
17
+ this.getToolbarGroups = () => [];
18
+ effect(() => {
19
+ const newUrl = this.url();
20
+ if (newUrl) {
21
+ untracked(() => {
22
+ void this.loadDoc();
23
+ });
24
+ }
25
+ });
26
+ }
27
+ trust(html) {
28
+ return this.sanitizer.bypassSecurityTrustHtml(html);
29
+ }
30
+ async loadDoc() {
31
+ this.loading.set(true);
32
+ this.error.set(null);
33
+ this.html.set('');
34
+ try {
35
+ const fetcher = this.request?.fetcher() ?? ((u, init) => fetch(u, init));
36
+ const response = await fetcher(this.url());
37
+ if (!response.ok)
38
+ throw new Error('load failed');
39
+ const buffer = await response.arrayBuffer();
40
+ this.html.set(await Tg(buffer));
41
+ }
42
+ catch (err) {
43
+ console.error('Doc 解析错误:', err);
44
+ this.error.set(this.t('doc.parse_failed'));
45
+ }
46
+ finally {
47
+ this.loading.set(false);
48
+ }
49
+ }
50
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.25", ngImport: i0, type: DocRenderer, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
51
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.25", type: DocRenderer, isStandalone: true, selector: "afp-doc-renderer", inputs: { url: { classPropertyName: "url", publicName: "url", isSignal: true, isRequired: true, transformFunction: null } }, host: { classAttribute: "afp-block afp-w-full afp-h-full" }, ngImport: i0, template: `
52
+ @if (loading()) {
53
+ <div class="afp-flex afp-items-center afp-justify-center afp-w-full afp-h-full">
54
+ <div
55
+ class="afp-w-12 afp-h-12 afp-border-4 afp-border-line-strong afp-border-t-spinner-head afp-rounded-full afp-animate-spin"
56
+ ></div>
57
+ </div>
58
+ } @else if (error()) {
59
+ <afp-renderer-error [message]="error()!" />
60
+ } @else {
61
+ <div class="afp-docx-container afp-w-full afp-h-full afp-overflow-auto afp-py-6 afp-px-4">
62
+ <div class="afp-flex afp-flex-col afp-items-center">
63
+ <div class="afp-legacy-doc-paper">
64
+ <div [innerHTML]="trust(html())"></div>
65
+ </div>
66
+ </div>
67
+ </div>
68
+ }
69
+ `, isInline: true, dependencies: [{ kind: "component", type: RendererError, selector: "afp-renderer-error", inputs: ["message", "detail", "showIcon"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
70
+ }
71
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.25", ngImport: i0, type: DocRenderer, decorators: [{
72
+ type: Component,
73
+ args: [{
74
+ selector: 'afp-doc-renderer',
75
+ standalone: true,
76
+ imports: [RendererError],
77
+ changeDetection: ChangeDetectionStrategy.OnPush,
78
+ host: { class: 'afp-block afp-w-full afp-h-full' },
79
+ template: `
80
+ @if (loading()) {
81
+ <div class="afp-flex afp-items-center afp-justify-center afp-w-full afp-h-full">
82
+ <div
83
+ class="afp-w-12 afp-h-12 afp-border-4 afp-border-line-strong afp-border-t-spinner-head afp-rounded-full afp-animate-spin"
84
+ ></div>
85
+ </div>
86
+ } @else if (error()) {
87
+ <afp-renderer-error [message]="error()!" />
88
+ } @else {
89
+ <div class="afp-docx-container afp-w-full afp-h-full afp-overflow-auto afp-py-6 afp-px-4">
90
+ <div class="afp-flex afp-flex-col afp-items-center">
91
+ <div class="afp-legacy-doc-paper">
92
+ <div [innerHTML]="trust(html())"></div>
93
+ </div>
94
+ </div>
95
+ </div>
96
+ }
97
+ `,
98
+ }]
99
+ }], ctorParameters: () => [] });
100
+
101
+ export { DocRenderer };
102
+ //# sourceMappingURL=eternalheart-angular-file-preview-eternalheart-angular-file-preview-index-CDjKPqyW-CmX5sdkL.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"eternalheart-angular-file-preview-eternalheart-angular-file-preview-index-CDjKPqyW-CmX5sdkL.mjs","sources":["../fesm2022/eternalheart-angular-file-preview-index-CDjKPqyW.mjs"],"sourcesContent":["import * as i0 from '@angular/core';\nimport { input, inject, signal, effect, untracked, ChangeDetectionStrategy, Component } from '@angular/core';\nimport { DomSanitizer } from '@angular/platform-browser';\nimport { L as LocaleService, R as RequestService, g as getFallbackTranslator } from './eternalheart-angular-file-preview-eternalheart-angular-file-preview-DXwNhxAB.mjs';\nimport { R as RendererError } from './eternalheart-angular-file-preview-RendererError-DtNihCIX.mjs';\nimport { renderLegacyDocHtml } from '@eternalheart/file-preview-core';\n\nclass DocRenderer {\n constructor() {\n this.url = input.required();\n this.locale = inject(LocaleService, { optional: true });\n this.request = inject(RequestService, { optional: true });\n this.sanitizer = inject(DomSanitizer);\n this.t = this.locale?.t() ?? getFallbackTranslator();\n this.html = signal('');\n this.loading = signal(true);\n this.error = signal(null);\n this.getToolbarGroups = () => [];\n effect(() => {\n const newUrl = this.url();\n if (newUrl) {\n untracked(() => {\n void this.loadDoc();\n });\n }\n });\n }\n trust(html) {\n return this.sanitizer.bypassSecurityTrustHtml(html);\n }\n async loadDoc() {\n this.loading.set(true);\n this.error.set(null);\n this.html.set('');\n try {\n const fetcher = this.request?.fetcher() ?? ((u, init) => fetch(u, init));\n const response = await fetcher(this.url());\n if (!response.ok)\n throw new Error('load failed');\n const buffer = await response.arrayBuffer();\n this.html.set(await renderLegacyDocHtml(buffer));\n }\n catch (err) {\n console.error('Doc 解析错误:', err);\n this.error.set(this.t('doc.parse_failed'));\n }\n finally {\n this.loading.set(false);\n }\n }\n static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: \"12.0.0\", version: \"19.2.25\", ngImport: i0, type: DocRenderer, deps: [], target: i0.ɵɵFactoryTarget.Component }); }\n static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: \"17.0.0\", version: \"19.2.25\", type: DocRenderer, isStandalone: true, selector: \"afp-doc-renderer\", inputs: { url: { classPropertyName: \"url\", publicName: \"url\", isSignal: true, isRequired: true, transformFunction: null } }, host: { classAttribute: \"afp-block afp-w-full afp-h-full\" }, ngImport: i0, template: `\n @if (loading()) {\n <div class=\"afp-flex afp-items-center afp-justify-center afp-w-full afp-h-full\">\n <div\n class=\"afp-w-12 afp-h-12 afp-border-4 afp-border-line-strong afp-border-t-spinner-head afp-rounded-full afp-animate-spin\"\n ></div>\n </div>\n } @else if (error()) {\n <afp-renderer-error [message]=\"error()!\" />\n } @else {\n <div class=\"afp-docx-container afp-w-full afp-h-full afp-overflow-auto afp-py-6 afp-px-4\">\n <div class=\"afp-flex afp-flex-col afp-items-center\">\n <div class=\"afp-legacy-doc-paper\">\n <div [innerHTML]=\"trust(html())\"></div>\n </div>\n </div>\n </div>\n }\n `, isInline: true, dependencies: [{ kind: \"component\", type: RendererError, selector: \"afp-renderer-error\", inputs: [\"message\", \"detail\", \"showIcon\"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }\n}\ni0.ɵɵngDeclareClassMetadata({ minVersion: \"12.0.0\", version: \"19.2.25\", ngImport: i0, type: DocRenderer, decorators: [{\n type: Component,\n args: [{\n selector: 'afp-doc-renderer',\n standalone: true,\n imports: [RendererError],\n changeDetection: ChangeDetectionStrategy.OnPush,\n host: { class: 'afp-block afp-w-full afp-h-full' },\n template: `\n @if (loading()) {\n <div class=\"afp-flex afp-items-center afp-justify-center afp-w-full afp-h-full\">\n <div\n class=\"afp-w-12 afp-h-12 afp-border-4 afp-border-line-strong afp-border-t-spinner-head afp-rounded-full afp-animate-spin\"\n ></div>\n </div>\n } @else if (error()) {\n <afp-renderer-error [message]=\"error()!\" />\n } @else {\n <div class=\"afp-docx-container afp-w-full afp-h-full afp-overflow-auto afp-py-6 afp-px-4\">\n <div class=\"afp-flex afp-flex-col afp-items-center\">\n <div class=\"afp-legacy-doc-paper\">\n <div [innerHTML]=\"trust(html())\"></div>\n </div>\n </div>\n </div>\n }\n `,\n }]\n }], ctorParameters: () => [] });\n\nexport { DocRenderer };\n//# sourceMappingURL=eternalheart-angular-file-preview-index-CDjKPqyW.mjs.map\n"],"names":["renderLegacyDocHtml"],"mappings":"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"}
@@ -0,0 +1,516 @@
1
+ import * as i0 from '@angular/core';
2
+ import { input, inject, viewChild, signal, afterNextRender, effect, untracked, DestroyRef, output, ChangeDetectionStrategy, Component } from '@angular/core';
3
+ import * as i1 from 'lucide-angular';
4
+ import { X, List, ChevronLeft, ChevronRight, Minimize2, Maximize2, LucideAngularModule } from 'lucide-angular';
5
+ import 'foliate-js/view.js';
6
+ import { L as LocaleService, R as RequestService, g as getFallbackTranslator } from './eternalheart-angular-file-preview-eternalheart-angular-file-preview-UobTf36G.mjs';
7
+ import { R as RendererError } from './eternalheart-angular-file-preview-eternalheart-angular-file-preview-RendererError-DtNihCIX-DtNihCIX.mjs';
8
+ import { T as ToolbarEventEmitter } from './eternalheart-angular-file-preview-eternalheart-angular-file-preview-base.types-D5x7QPey-D5x7QPey.mjs';
9
+
10
+ const READER_CSS = `
11
+ @namespace epub "http://www.idpf.org/2007/ops";
12
+ html { color-scheme: light; }
13
+ body {
14
+ background: #ffffff !important;
15
+ color: #1a1a1a !important;
16
+ font-family: "Noto Serif SC", "Source Han Serif SC", Georgia, "Times New Roman", serif !important;
17
+ font-size: 16px !important;
18
+ line-height: 2 !important;
19
+ max-width: 100% !important;
20
+ box-sizing: border-box !important;
21
+ word-break: break-word !important;
22
+ overflow-wrap: break-word !important;
23
+ }
24
+ p, li, blockquote, dd { line-height: 2; text-align: justify; }
25
+ p { text-indent: 2em; margin: 0.8em 0; }
26
+ h1 { text-align: center; margin: 1.5em 0 1em; }
27
+ h2 { margin: 1.2em 0 0.8em; }
28
+ h3 { margin: 1em 0 0.6em; }
29
+ img { max-width: 100% !important; height: auto !important; }
30
+ a { color: #2563eb; text-decoration: none; }
31
+ pre { white-space: pre-wrap !important; }
32
+ `;
33
+ const A4_WIDTH = 794;
34
+ const INITIAL_RENDER_TIMEOUT_MS = 10_000;
35
+ async function renderInitialPage(renderer) {
36
+ const nextPromise = renderer.next?.();
37
+ if (!nextPromise)
38
+ return;
39
+ let timer;
40
+ try {
41
+ await Promise.race([
42
+ nextPromise,
43
+ new Promise((_, reject) => {
44
+ timer = window.setTimeout(() => reject(new Error('MOBI initial render timed out')), INITIAL_RENDER_TIMEOUT_MS);
45
+ }),
46
+ ]);
47
+ }
48
+ finally {
49
+ if (timer !== undefined)
50
+ window.clearTimeout(timer);
51
+ }
52
+ }
53
+ class MobiTocList {
54
+ constructor() {
55
+ this.items = input.required();
56
+ this.activeHref = input('');
57
+ this.depth = input(0);
58
+ this.select = output();
59
+ }
60
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.25", ngImport: i0, type: MobiTocList, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
61
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.25", type: MobiTocList, isStandalone: true, selector: "afp-mobi-toc-list", inputs: { items: { classPropertyName: "items", publicName: "items", isSignal: true, isRequired: true, transformFunction: null }, activeHref: { classPropertyName: "activeHref", publicName: "activeHref", isSignal: true, isRequired: false, transformFunction: null }, depth: { classPropertyName: "depth", publicName: "depth", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { select: "select" }, ngImport: i0, template: `
62
+ <ul [style.listStyle]="'none'" [style.padding]="'0'" [style.margin]="depth() > 0 ? '0 0 0 16px' : '0'">
63
+ @for (item of items(); track (item.href ?? item.label) + '-' + $index) {
64
+ <li>
65
+ @if (item.href) {
66
+ <button
67
+ type="button"
68
+ class="afp-w-full afp-text-left afp-py-2 afp-px-3 afp-text-sm afp-rounded afp-transition-all afp-truncate"
69
+ [class.afp-text-fg-primary]="activeHref() === item.href"
70
+ [class.afp-bg-surface-3]="activeHref() === item.href"
71
+ [class.afp-font-medium]="activeHref() === item.href"
72
+ [class.afp-text-fg-secondary]="activeHref() !== item.href"
73
+ [class.hover:afp-text-fg-primary]="activeHref() !== item.href"
74
+ [class.hover:afp-bg-surface-2]="activeHref() !== item.href"
75
+ [title]="item.label"
76
+ style="background: none; border: none; cursor: pointer"
77
+ (click)="select.emit(item.href)"
78
+ >
79
+ {{ item.label?.trim() }}
80
+ </button>
81
+ } @else {
82
+ <div class="afp-w-full afp-py-2 afp-px-3 afp-text-sm afp-text-fg-tertiary afp-truncate">
83
+ {{ item.label?.trim() }}
84
+ </div>
85
+ }
86
+ @if (item.subitems?.length) {
87
+ <afp-mobi-toc-list
88
+ [items]="item.subitems!"
89
+ [activeHref]="activeHref()"
90
+ [depth]="depth() + 1"
91
+ (select)="select.emit($event)"
92
+ />
93
+ }
94
+ </li>
95
+ }
96
+ </ul>
97
+ `, isInline: true, dependencies: [{ kind: "component", type: MobiTocList, selector: "afp-mobi-toc-list", inputs: ["items", "activeHref", "depth"], outputs: ["select"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
98
+ }
99
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.25", ngImport: i0, type: MobiTocList, decorators: [{
100
+ type: Component,
101
+ args: [{
102
+ selector: 'afp-mobi-toc-list',
103
+ standalone: true,
104
+ changeDetection: ChangeDetectionStrategy.OnPush,
105
+ template: `
106
+ <ul [style.listStyle]="'none'" [style.padding]="'0'" [style.margin]="depth() > 0 ? '0 0 0 16px' : '0'">
107
+ @for (item of items(); track (item.href ?? item.label) + '-' + $index) {
108
+ <li>
109
+ @if (item.href) {
110
+ <button
111
+ type="button"
112
+ class="afp-w-full afp-text-left afp-py-2 afp-px-3 afp-text-sm afp-rounded afp-transition-all afp-truncate"
113
+ [class.afp-text-fg-primary]="activeHref() === item.href"
114
+ [class.afp-bg-surface-3]="activeHref() === item.href"
115
+ [class.afp-font-medium]="activeHref() === item.href"
116
+ [class.afp-text-fg-secondary]="activeHref() !== item.href"
117
+ [class.hover:afp-text-fg-primary]="activeHref() !== item.href"
118
+ [class.hover:afp-bg-surface-2]="activeHref() !== item.href"
119
+ [title]="item.label"
120
+ style="background: none; border: none; cursor: pointer"
121
+ (click)="select.emit(item.href)"
122
+ >
123
+ {{ item.label?.trim() }}
124
+ </button>
125
+ } @else {
126
+ <div class="afp-w-full afp-py-2 afp-px-3 afp-text-sm afp-text-fg-tertiary afp-truncate">
127
+ {{ item.label?.trim() }}
128
+ </div>
129
+ }
130
+ @if (item.subitems?.length) {
131
+ <afp-mobi-toc-list
132
+ [items]="item.subitems!"
133
+ [activeHref]="activeHref()"
134
+ [depth]="depth() + 1"
135
+ (select)="select.emit($event)"
136
+ />
137
+ }
138
+ </li>
139
+ }
140
+ </ul>
141
+ `,
142
+ }]
143
+ }] });
144
+ class MobiRenderer {
145
+ constructor() {
146
+ this.url = input.required();
147
+ this.emitter = new ToolbarEventEmitter();
148
+ this.locale = inject(LocaleService, { optional: true });
149
+ this.request = inject(RequestService, { optional: true });
150
+ this.t = this.locale?.t() ?? getFallbackTranslator();
151
+ this.host = viewChild('hostRef');
152
+ this.xIcon = X;
153
+ this.a4Width = A4_WIDTH;
154
+ this.currentChapter = signal(1);
155
+ this.totalChapters = signal(1);
156
+ this.loading = signal(false);
157
+ this.error = signal(null);
158
+ this.toc = signal([]);
159
+ this.showToc = signal(false);
160
+ this.activeTocHref = signal('');
161
+ this.isFullWidth = signal(false);
162
+ this.mounted = signal(false);
163
+ this.viewInstance = null;
164
+ this.totalLocations = 1;
165
+ this.getToolbarGroups = () => [
166
+ {
167
+ items: [
168
+ {
169
+ type: 'button',
170
+ icon: List,
171
+ tooltip: this.t('toolbar.toc'),
172
+ action: () => this.toggleToc(),
173
+ disabled: this.toc().length === 0,
174
+ active: this.showToc(),
175
+ },
176
+ ],
177
+ },
178
+ {
179
+ items: [
180
+ {
181
+ type: 'button',
182
+ icon: ChevronLeft,
183
+ tooltip: this.t('toolbar.prev_page'),
184
+ action: () => this.prevPage(),
185
+ disabled: this.currentChapter() <= 1,
186
+ },
187
+ {
188
+ type: 'text',
189
+ content: `${this.currentChapter()} / ${this.totalChapters()}`,
190
+ minWidth: '4rem',
191
+ },
192
+ {
193
+ type: 'button',
194
+ icon: ChevronRight,
195
+ tooltip: this.t('toolbar.next_page'),
196
+ action: () => this.nextPage(),
197
+ disabled: this.currentChapter() >= this.totalChapters(),
198
+ },
199
+ ],
200
+ },
201
+ {
202
+ items: [
203
+ {
204
+ type: 'button',
205
+ icon: this.isFullWidth() ? Minimize2 : Maximize2,
206
+ tooltip: this.isFullWidth() ? this.t('toolbar.normal_width') : this.t('toolbar.full_width'),
207
+ action: () => this.toggleFullWidth(),
208
+ active: this.isFullWidth(),
209
+ },
210
+ ],
211
+ },
212
+ ];
213
+ this.onToolbarChange = (listener) => this.emitter.subscribe(listener);
214
+ afterNextRender(() => this.mounted.set(true));
215
+ effect(() => {
216
+ const url = this.url();
217
+ const mounted = this.mounted();
218
+ if (!mounted || !url)
219
+ return;
220
+ untracked(() => { void this.load(); });
221
+ });
222
+ effect(() => {
223
+ this.currentChapter();
224
+ this.totalChapters();
225
+ this.isFullWidth();
226
+ this.showToc();
227
+ this.loading();
228
+ this.toc().length;
229
+ this.emitter.notify();
230
+ });
231
+ const paginatorErrorHandler = (e) => {
232
+ if (e.filename?.includes('paginator')) {
233
+ e.preventDefault();
234
+ }
235
+ };
236
+ window.addEventListener('error', paginatorErrorHandler);
237
+ inject(DestroyRef).onDestroy(() => {
238
+ window.removeEventListener('error', paginatorErrorHandler);
239
+ try {
240
+ this.viewInstance?.close?.();
241
+ }
242
+ catch { /* ignore */ }
243
+ try {
244
+ this.viewInstance?.book?.destroy?.();
245
+ }
246
+ catch { /* ignore */ }
247
+ this.viewInstance = null;
248
+ this.host()?.nativeElement?.replaceChildren();
249
+ });
250
+ }
251
+ handleTocClick(href) {
252
+ this.activeTocHref.set(href);
253
+ this.showToc.set(false);
254
+ this.viewInstance?.goTo(href).catch(() => { });
255
+ }
256
+ prevPage() {
257
+ this.viewInstance?.prev().catch(() => { });
258
+ }
259
+ nextPage() {
260
+ this.viewInstance?.next().catch(() => { });
261
+ }
262
+ toggleToc() {
263
+ this.showToc.update((v) => !v);
264
+ }
265
+ toggleFullWidth() {
266
+ this.isFullWidth.update((v) => !v);
267
+ if (this.viewInstance?.renderer) {
268
+ this.viewInstance.renderer.setAttribute('max-inline-size', this.isFullWidth() ? '9999' : '720');
269
+ }
270
+ }
271
+ reportProgress(current, total) {
272
+ if (Number.isFinite(total) && total > 0)
273
+ this.totalLocations = total;
274
+ const safeCurrent = Number.isFinite(current) ? current : 0;
275
+ this.currentChapter.set(Math.max(1, safeCurrent + 1));
276
+ this.totalChapters.set(this.totalLocations);
277
+ }
278
+ async load() {
279
+ const host = this.host()?.nativeElement;
280
+ if (!host)
281
+ return;
282
+ this.loading.set(true);
283
+ this.error.set(null);
284
+ this.toc.set([]);
285
+ this.showToc.set(false);
286
+ this.activeTocHref.set('');
287
+ this.totalLocations = 1;
288
+ this.currentChapter.set(1);
289
+ this.totalChapters.set(1);
290
+ host.replaceChildren();
291
+ this.viewInstance = null;
292
+ let progressReported = false;
293
+ const sectionPagesMap = new Map();
294
+ try {
295
+ const view = document.createElement('foliate-view');
296
+ host.appendChild(view);
297
+ this.viewInstance = view;
298
+ view.addEventListener('relocate', (e) => {
299
+ const detail = e.detail;
300
+ if (!detail)
301
+ return;
302
+ const sectionCount = this.viewInstance?.book?.sections.length ?? 0;
303
+ const renderer = this.viewInstance?.renderer;
304
+ const sectionIdx = renderer?.getContents?.()[0]?.index ?? -1;
305
+ if (renderer
306
+ && typeof renderer.page === 'number'
307
+ && Number.isFinite(renderer.page)
308
+ && typeof renderer.pages === 'number'
309
+ && Number.isFinite(renderer.pages)
310
+ && renderer.pages > 2
311
+ && sectionIdx >= 0) {
312
+ progressReported = true;
313
+ const curSectionPages = renderer.pages - 2;
314
+ sectionPagesMap.set(sectionIdx, curSectionPages);
315
+ let pagesBefore = 0;
316
+ for (let i = 0; i < sectionIdx; i++) {
317
+ pagesBefore += sectionPagesMap.get(i) ?? 0;
318
+ }
319
+ const currentPage = pagesBefore + Math.min(curSectionPages, Math.max(1, renderer.page));
320
+ const atEnd = (detail.fraction ?? 0) >= 0.999;
321
+ let total;
322
+ if (sectionCount === 1) {
323
+ total = curSectionPages;
324
+ }
325
+ else if (atEnd) {
326
+ total = currentPage;
327
+ }
328
+ else {
329
+ const sections = this.viewInstance?.book?.sections ?? [];
330
+ const curSize = sections[sectionIdx]?.size ?? 0;
331
+ const ratio = curSize > 0 ? curSectionPages / curSize : 0;
332
+ let est = 0;
333
+ for (let i = 0; i < sectionCount; i++) {
334
+ if (sectionPagesMap.has(i)) {
335
+ est += sectionPagesMap.get(i);
336
+ }
337
+ else {
338
+ const s = sections[i]?.size ?? 0;
339
+ est += Math.max(1, Math.round(s * ratio));
340
+ }
341
+ }
342
+ total = Math.max(currentPage, est);
343
+ }
344
+ this.reportProgress(currentPage - 1, total);
345
+ const tocItem = detail.tocItem;
346
+ if (tocItem?.href)
347
+ this.activeTocHref.set(tocItem.href);
348
+ return;
349
+ }
350
+ const loc = detail.location;
351
+ if (loc
352
+ && typeof loc.current === 'number'
353
+ && Number.isFinite(loc.current)
354
+ && typeof loc.total === 'number'
355
+ && Number.isFinite(loc.total)) {
356
+ progressReported = true;
357
+ const atEnd = (detail.fraction ?? 0) >= 0.999;
358
+ const actualTotal = atEnd ? loc.current + 1 : loc.total;
359
+ this.reportProgress(loc.current, actualTotal);
360
+ }
361
+ else {
362
+ const sections = this.viewInstance?.book?.sections ?? [];
363
+ const idx = detail.index ?? 0;
364
+ const frac = detail.fraction ?? 0;
365
+ const total = Math.max(sections.length, 1);
366
+ this.reportProgress(Math.round((idx + frac) / total * total), total);
367
+ }
368
+ const tocItem = detail.tocItem;
369
+ if (tocItem?.href)
370
+ this.activeTocHref.set(tocItem.href);
371
+ });
372
+ const fetcher = this.request?.fetcher() ?? ((u, init) => fetch(u, init));
373
+ const res = await fetcher(this.url());
374
+ if (!res.ok)
375
+ throw new Error(`请求失败: ${res.status}`);
376
+ const blob = await res.blob();
377
+ let name = 'book.mobi';
378
+ try {
379
+ const u = new URL(this.url(), window.location.href);
380
+ const base = u.pathname.split('/').pop();
381
+ if (base)
382
+ name = decodeURIComponent(base);
383
+ }
384
+ catch { /* blob: URL */ }
385
+ await view.open(new File([blob], name));
386
+ const renderer = view.renderer;
387
+ if (renderer) {
388
+ renderer.setAttribute('animated', '');
389
+ renderer.setAttribute('max-inline-size', '720');
390
+ renderer.setAttribute('margin', '48');
391
+ renderer.setAttribute('gap', '5%');
392
+ await renderInitialPage(renderer);
393
+ renderer.setStyles?.(READER_CSS);
394
+ }
395
+ this.toc.set((view.book?.toc ?? []));
396
+ this.loading.set(false);
397
+ if (!progressReported) {
398
+ this.reportProgress(0, view.book?.sections.length ?? 1);
399
+ }
400
+ }
401
+ catch (err) {
402
+ console.error('MOBI/AZW3 加载错误:', err);
403
+ this.error.set(this.t('mobi.load_failed'));
404
+ this.loading.set(false);
405
+ }
406
+ }
407
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.25", ngImport: i0, type: MobiRenderer, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
408
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.25", type: MobiRenderer, isStandalone: true, selector: "afp-mobi-renderer", inputs: { url: { classPropertyName: "url", publicName: "url", isSignal: true, isRequired: true, transformFunction: null } }, host: { classAttribute: "afp-block afp-w-full afp-h-full" }, viewQueries: [{ propertyName: "host", first: true, predicate: ["hostRef"], descendants: true, isSignal: true }], ngImport: i0, template: `
409
+ <div class="afp-relative afp-w-full afp-h-full afp-flex afp-justify-center afp-bg-surface-1 afp-overflow-hidden">
410
+ @if (error()) {
411
+ <afp-renderer-error [message]="error()!" class="afp-absolute afp-inset-0" />
412
+ }
413
+
414
+ @if (loading() && !error()) {
415
+ <div class="afp-absolute afp-inset-0 afp-flex afp-items-center afp-justify-center afp-z-10">
416
+ <div class="afp-w-12 afp-h-12 afp-border-4 afp-border-line-strong afp-border-t-spinner-head afp-rounded-full afp-animate-spin"></div>
417
+ </div>
418
+ }
419
+
420
+ @if (toc().length > 0) {
421
+ <div
422
+ class="afp-absolute afp-inset-0 afp-z-20 afp-flex afp-transition-opacity afp-duration-300"
423
+ [style.opacity]="showToc() ? 1 : 0"
424
+ [style.pointerEvents]="showToc() ? 'auto' : 'none'"
425
+ >
426
+ <div
427
+ class="afp-w-72 afp-max-w-[80%] afp-h-full afp-bg-surface-overlay afp-backdrop-blur-xl afp-border-r afp-border-line-weak afp-flex afp-flex-col afp-shadow-2xl afp-transition-transform afp-duration-300"
428
+ [style.transform]="showToc() ? 'translateX(0)' : 'translateX(-100%)'"
429
+ >
430
+ <div class="afp-flex afp-items-center afp-justify-between afp-px-4 afp-py-3 afp-border-b afp-border-line-weak afp-flex-shrink-0">
431
+ <span class="afp-text-fg-primary afp-font-medium afp-text-sm">{{ t('toolbar.toc') }}</span>
432
+ <button type="button" class="toc-close-btn" (click)="showToc.set(false)">
433
+ <i-lucide [img]="xIcon" class="afp-w-4 afp-h-4" />
434
+ </button>
435
+ </div>
436
+ <div class="afp-flex-1 afp-overflow-y-auto afp-py-4 afp-px-1">
437
+ <afp-mobi-toc-list [items]="toc()" [activeHref]="activeTocHref()" (select)="handleTocClick($event)" />
438
+ </div>
439
+ </div>
440
+ <div
441
+ class="afp-flex-1 afp-transition-opacity afp-duration-300"
442
+ [style.background]="showToc() ? 'rgba(0,0,0,0.3)' : 'transparent'"
443
+ (click)="showToc.set(false)"
444
+ ></div>
445
+ </div>
446
+ }
447
+
448
+ @if (!error()) {
449
+ <div
450
+ #hostRef
451
+ class="afp-h-full afp-bg-surface-toolbar afp-shadow-lg"
452
+ [style.width]="isFullWidth() ? '100%' : a4Width + 'px'"
453
+ [style.maxWidth]="'100%'"
454
+ [style.transition]="'width 0.3s ease'"
455
+ ></div>
456
+ }
457
+ </div>
458
+ `, isInline: true, styles: [".toc-close-btn{color:var(--fp-fg-tertiary);background:none;border:none;cursor:pointer;transition:color .15s}.toc-close-btn:hover{color:var(--fp-fg-primary)}\n"], dependencies: [{ kind: "component", type: RendererError, selector: "afp-renderer-error", inputs: ["message", "detail", "showIcon"] }, { kind: "ngmodule", type: LucideAngularModule }, { kind: "component", type: i1.LucideAngularComponent, selector: "lucide-angular, lucide-icon, i-lucide, span-lucide", inputs: ["class", "name", "img", "color", "absoluteStrokeWidth", "size", "strokeWidth"] }, { kind: "component", type: MobiTocList, selector: "afp-mobi-toc-list", inputs: ["items", "activeHref", "depth"], outputs: ["select"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
459
+ }
460
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.25", ngImport: i0, type: MobiRenderer, decorators: [{
461
+ type: Component,
462
+ args: [{ selector: 'afp-mobi-renderer', standalone: true, imports: [RendererError, LucideAngularModule, MobiTocList], changeDetection: ChangeDetectionStrategy.OnPush, host: { class: 'afp-block afp-w-full afp-h-full' }, template: `
463
+ <div class="afp-relative afp-w-full afp-h-full afp-flex afp-justify-center afp-bg-surface-1 afp-overflow-hidden">
464
+ @if (error()) {
465
+ <afp-renderer-error [message]="error()!" class="afp-absolute afp-inset-0" />
466
+ }
467
+
468
+ @if (loading() && !error()) {
469
+ <div class="afp-absolute afp-inset-0 afp-flex afp-items-center afp-justify-center afp-z-10">
470
+ <div class="afp-w-12 afp-h-12 afp-border-4 afp-border-line-strong afp-border-t-spinner-head afp-rounded-full afp-animate-spin"></div>
471
+ </div>
472
+ }
473
+
474
+ @if (toc().length > 0) {
475
+ <div
476
+ class="afp-absolute afp-inset-0 afp-z-20 afp-flex afp-transition-opacity afp-duration-300"
477
+ [style.opacity]="showToc() ? 1 : 0"
478
+ [style.pointerEvents]="showToc() ? 'auto' : 'none'"
479
+ >
480
+ <div
481
+ class="afp-w-72 afp-max-w-[80%] afp-h-full afp-bg-surface-overlay afp-backdrop-blur-xl afp-border-r afp-border-line-weak afp-flex afp-flex-col afp-shadow-2xl afp-transition-transform afp-duration-300"
482
+ [style.transform]="showToc() ? 'translateX(0)' : 'translateX(-100%)'"
483
+ >
484
+ <div class="afp-flex afp-items-center afp-justify-between afp-px-4 afp-py-3 afp-border-b afp-border-line-weak afp-flex-shrink-0">
485
+ <span class="afp-text-fg-primary afp-font-medium afp-text-sm">{{ t('toolbar.toc') }}</span>
486
+ <button type="button" class="toc-close-btn" (click)="showToc.set(false)">
487
+ <i-lucide [img]="xIcon" class="afp-w-4 afp-h-4" />
488
+ </button>
489
+ </div>
490
+ <div class="afp-flex-1 afp-overflow-y-auto afp-py-4 afp-px-1">
491
+ <afp-mobi-toc-list [items]="toc()" [activeHref]="activeTocHref()" (select)="handleTocClick($event)" />
492
+ </div>
493
+ </div>
494
+ <div
495
+ class="afp-flex-1 afp-transition-opacity afp-duration-300"
496
+ [style.background]="showToc() ? 'rgba(0,0,0,0.3)' : 'transparent'"
497
+ (click)="showToc.set(false)"
498
+ ></div>
499
+ </div>
500
+ }
501
+
502
+ @if (!error()) {
503
+ <div
504
+ #hostRef
505
+ class="afp-h-full afp-bg-surface-toolbar afp-shadow-lg"
506
+ [style.width]="isFullWidth() ? '100%' : a4Width + 'px'"
507
+ [style.maxWidth]="'100%'"
508
+ [style.transition]="'width 0.3s ease'"
509
+ ></div>
510
+ }
511
+ </div>
512
+ `, styles: [".toc-close-btn{color:var(--fp-fg-tertiary);background:none;border:none;cursor:pointer;transition:color .15s}.toc-close-btn:hover{color:var(--fp-fg-primary)}\n"] }]
513
+ }], ctorParameters: () => [] });
514
+
515
+ export { MobiRenderer, MobiTocList };
516
+ //# sourceMappingURL=eternalheart-angular-file-preview-eternalheart-angular-file-preview-index-CHi9tOe0-NOeQYAnM.mjs.map