@elabs-ai/components-viewer 4.0.0

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 (140) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +143 -0
  3. package/dist/chunk-2NQ4RSJ3.js +18 -0
  4. package/dist/chunk-2NQ4RSJ3.js.map +1 -0
  5. package/dist/chunk-3U3MESBU.js +21 -0
  6. package/dist/chunk-3U3MESBU.js.map +1 -0
  7. package/dist/chunk-4OFQYALG.js +147 -0
  8. package/dist/chunk-4OFQYALG.js.map +1 -0
  9. package/dist/chunk-5OMONA2G.js +87 -0
  10. package/dist/chunk-5OMONA2G.js.map +1 -0
  11. package/dist/chunk-AORNMH77.js +58 -0
  12. package/dist/chunk-AORNMH77.js.map +1 -0
  13. package/dist/chunk-BCF3RWRL.js +18 -0
  14. package/dist/chunk-BCF3RWRL.js.map +1 -0
  15. package/dist/chunk-FELIAGKI.js +22 -0
  16. package/dist/chunk-FELIAGKI.js.map +1 -0
  17. package/dist/chunk-GGR7BNW4.js +18 -0
  18. package/dist/chunk-GGR7BNW4.js.map +1 -0
  19. package/dist/chunk-H3OAON3D.js +22 -0
  20. package/dist/chunk-H3OAON3D.js.map +1 -0
  21. package/dist/chunk-HMG2ERXH.js +17 -0
  22. package/dist/chunk-HMG2ERXH.js.map +1 -0
  23. package/dist/chunk-KOMDRWOU.js +21 -0
  24. package/dist/chunk-KOMDRWOU.js.map +1 -0
  25. package/dist/chunk-NMA57QZ7.js +117 -0
  26. package/dist/chunk-NMA57QZ7.js.map +1 -0
  27. package/dist/chunk-RGWDIQJR.js +26 -0
  28. package/dist/chunk-RGWDIQJR.js.map +1 -0
  29. package/dist/chunk-SLXRUYT3.js +91 -0
  30. package/dist/chunk-SLXRUYT3.js.map +1 -0
  31. package/dist/chunk-UJIJECEF.js +21 -0
  32. package/dist/chunk-UJIJECEF.js.map +1 -0
  33. package/dist/chunk-UL43NGUG.js +68 -0
  34. package/dist/chunk-UL43NGUG.js.map +1 -0
  35. package/dist/chunk-VO2273Z2.js +55 -0
  36. package/dist/chunk-VO2273Z2.js.map +1 -0
  37. package/dist/code-adapter-ADZ4UOGN.js +226 -0
  38. package/dist/code-adapter-ADZ4UOGN.js.map +1 -0
  39. package/dist/csv-adapter-6VU3FFVU.js +100 -0
  40. package/dist/csv-adapter-6VU3FFVU.js.map +1 -0
  41. package/dist/docx-adapter-5CQDHWTD.js +383 -0
  42. package/dist/docx-adapter-5CQDHWTD.js.map +1 -0
  43. package/dist/image-adapter-WOHZR24J.js +132 -0
  44. package/dist/image-adapter-WOHZR24J.js.map +1 -0
  45. package/dist/index.d.ts +1353 -0
  46. package/dist/index.js +1364 -0
  47. package/dist/index.js.map +1 -0
  48. package/dist/json-adapter-ZUW5GQHE.js +90 -0
  49. package/dist/json-adapter-ZUW5GQHE.js.map +1 -0
  50. package/dist/markdown-adapter-YC6WTBS4.js +214 -0
  51. package/dist/markdown-adapter-YC6WTBS4.js.map +1 -0
  52. package/dist/media-adapter-MCTB4GBH.js +78 -0
  53. package/dist/media-adapter-MCTB4GBH.js.map +1 -0
  54. package/dist/pdf-adapter-5PMKEXUD.js +424 -0
  55. package/dist/pdf-adapter-5PMKEXUD.js.map +1 -0
  56. package/dist/pptx-adapter-6GEQLS2Z.js +351 -0
  57. package/dist/pptx-adapter-6GEQLS2Z.js.map +1 -0
  58. package/dist/text-adapter-NFNWB5W3.js +81 -0
  59. package/dist/text-adapter-NFNWB5W3.js.map +1 -0
  60. package/dist/xlsx-adapter-CM2Y6AKQ.js +167 -0
  61. package/dist/xlsx-adapter-CM2Y6AKQ.js.map +1 -0
  62. package/package.json +103 -0
  63. package/src/adapters/code/code-adapter.test.tsx +221 -0
  64. package/src/adapters/code/code-adapter.tsx +272 -0
  65. package/src/adapters/code/code-language.test.ts +45 -0
  66. package/src/adapters/code/code-language.ts +100 -0
  67. package/src/adapters/code/code-manifest.ts +19 -0
  68. package/src/adapters/code/code-theme.test.ts +46 -0
  69. package/src/adapters/code/code-theme.ts +99 -0
  70. package/src/adapters/csv/csv-adapter.test.tsx +169 -0
  71. package/src/adapters/csv/csv-adapter.tsx +146 -0
  72. package/src/adapters/csv/csv-manifest.ts +20 -0
  73. package/src/adapters/docx/docx-adapter.test.tsx +192 -0
  74. package/src/adapters/docx/docx-adapter.tsx +328 -0
  75. package/src/adapters/docx/docx-manifest.ts +18 -0
  76. package/src/adapters/docx/docx-model.test.ts +181 -0
  77. package/src/adapters/docx/docx-model.ts +294 -0
  78. package/src/adapters/image/image-adapter.test.tsx +141 -0
  79. package/src/adapters/image/image-adapter.tsx +191 -0
  80. package/src/adapters/image/image-manifest.ts +15 -0
  81. package/src/adapters/index.ts +64 -0
  82. package/src/adapters/json/json-adapter.test.tsx +77 -0
  83. package/src/adapters/json/json-adapter.tsx +141 -0
  84. package/src/adapters/json/json-manifest.ts +11 -0
  85. package/src/adapters/markdown/markdown-adapter.test.tsx +228 -0
  86. package/src/adapters/markdown/markdown-adapter.tsx +353 -0
  87. package/src/adapters/markdown/markdown-manifest.ts +21 -0
  88. package/src/adapters/markdown/markdown-marks.test.ts +85 -0
  89. package/src/adapters/markdown/markdown-marks.ts +119 -0
  90. package/src/adapters/media/media-adapter.test.tsx +79 -0
  91. package/src/adapters/media/media-adapter.tsx +123 -0
  92. package/src/adapters/media/media-manifest.ts +17 -0
  93. package/src/adapters/office-fixture.ts +239 -0
  94. package/src/adapters/pdf/pdf-adapter.test.tsx +489 -0
  95. package/src/adapters/pdf/pdf-adapter.tsx +599 -0
  96. package/src/adapters/pdf/pdf-engine.ts +171 -0
  97. package/src/adapters/pdf/pdf-fixture.ts +27 -0
  98. package/src/adapters/pdf/pdf-manifest.ts +30 -0
  99. package/src/adapters/pdf/pdf-text.test.ts +171 -0
  100. package/src/adapters/pdf/pdf-text.ts +202 -0
  101. package/src/adapters/pptx/pptx-adapter.test.tsx +241 -0
  102. package/src/adapters/pptx/pptx-adapter.tsx +341 -0
  103. package/src/adapters/pptx/pptx-manifest.ts +19 -0
  104. package/src/adapters/pptx/pptx-model.test.ts +219 -0
  105. package/src/adapters/pptx/pptx-model.ts +248 -0
  106. package/src/adapters/text/text-adapter.test.tsx +125 -0
  107. package/src/adapters/text/text-adapter.tsx +117 -0
  108. package/src/adapters/text/text-manifest.ts +19 -0
  109. package/src/adapters/xlsx/xlsx-adapter.test.tsx +159 -0
  110. package/src/adapters/xlsx/xlsx-adapter.tsx +250 -0
  111. package/src/adapters/xlsx/xlsx-manifest.ts +26 -0
  112. package/src/components/grid-text.test.ts +68 -0
  113. package/src/components/grid-text.ts +77 -0
  114. package/src/components/marked-text.tsx +36 -0
  115. package/src/components/sheet-table.tsx +142 -0
  116. package/src/core/errors.ts +120 -0
  117. package/src/core/highlight-marks.test.ts +95 -0
  118. package/src/core/highlight-marks.ts +95 -0
  119. package/src/core/highlight-resolve.test.ts +208 -0
  120. package/src/core/highlight-resolve.ts +191 -0
  121. package/src/core/highlight.ts +125 -0
  122. package/src/core/registry.test.ts +172 -0
  123. package/src/core/registry.ts +188 -0
  124. package/src/core/scroll-host.ts +42 -0
  125. package/src/core/text-index.test.ts +95 -0
  126. package/src/core/text-index.ts +159 -0
  127. package/src/core/types.ts +285 -0
  128. package/src/core/use-highlight-scroll.ts +59 -0
  129. package/src/core/use-page-control.ts +47 -0
  130. package/src/core/use-paged-scroll.ts +194 -0
  131. package/src/core/use-viewport-size.ts +54 -0
  132. package/src/core/zoom.ts +56 -0
  133. package/src/file-viewer/file-viewer-context.tsx +239 -0
  134. package/src/file-viewer/file-viewer-find.tsx +204 -0
  135. package/src/file-viewer/file-viewer-pager.tsx +120 -0
  136. package/src/file-viewer/file-viewer-zoom.tsx +166 -0
  137. package/src/file-viewer/file-viewer.stories.tsx +947 -0
  138. package/src/file-viewer/file-viewer.test.tsx +947 -0
  139. package/src/file-viewer/file-viewer.tsx +1143 -0
  140. package/src/index.ts +157 -0
@@ -0,0 +1,123 @@
1
+ "use client";
2
+
3
+ /**
4
+ * Video / audio adapter — native elements, deliberately.
5
+ *
6
+ * `@elabs-ai/components-ai` ships a designed `AudioPlayer` built on
7
+ * `media-chrome`, and this adapter does NOT reach for it: `ai` is a Layer-2
8
+ * sibling, so importing it would be a sideways edge the dependency gate rejects
9
+ * (and would pull a chat package into a file viewer). Native `<video controls>`
10
+ * / `<audio controls>` are the honest answer here — they bring the platform's
11
+ * own accessible transport, keyboard handling, picture-in-picture, captions
12
+ * menu and OS media keys, none of which a custom skin gets for free.
13
+ *
14
+ * The plan's "extract `AudioPlayer` down to `ui`" would let both sides share one
15
+ * skinned player. That is a real refactor of an existing component with its own
16
+ * tests and stories, so it is tracked separately rather than smuggled in here.
17
+ */
18
+
19
+ import { cn, StatePanel, useLocale, type ResolvedFileSource } from "@elabs-ai/components-ui";
20
+ import { useEffect, useState } from "react";
21
+
22
+ import { toViewerError } from "../../core/errors";
23
+ import type {
24
+ AdapterDocument,
25
+ AdapterLoadContext,
26
+ AdapterModule,
27
+ AdapterRendererProps,
28
+ FileAdapter,
29
+ } from "../../core/types";
30
+ import { mediaManifest } from "./media-manifest";
31
+
32
+ export interface MediaDocument extends AdapterDocument {
33
+ kind: "media";
34
+ /** A URL the element can play — the source's own URL, or a minted object URL. */
35
+ url: string;
36
+ /** Which element to render. `resolveFileKind` already decided this. */
37
+ media: "video" | "audio";
38
+ }
39
+
40
+ class MediaAdapter implements FileAdapter {
41
+ #source?: ResolvedFileSource;
42
+
43
+ async load(source: ResolvedFileSource, context: AdapterLoadContext): Promise<MediaDocument> {
44
+ this.#source = source;
45
+ try {
46
+ // Deliberately `url()`, never `bytes()`: an object URL lets the browser
47
+ // stream and seek. Buffering a 2 GB video into memory to hand it to a
48
+ // `<video>` element would be the wrong shape at every size.
49
+ const url = await source.url(context.signal);
50
+ return { kind: "media", url, media: source.category === "audio" ? "audio" : "video" };
51
+ } catch (error) {
52
+ throw toViewerError(error, "read-failed", { fileName: source.name });
53
+ }
54
+ }
55
+
56
+ dispose(): void {
57
+ this.#source?.revoke();
58
+ this.#source = undefined;
59
+ }
60
+ }
61
+
62
+ function MediaRenderer({ document: doc, source, className }: AdapterRendererProps) {
63
+ const media = doc as MediaDocument;
64
+ const { t } = useLocale();
65
+ const [failed, setFailed] = useState(false);
66
+
67
+ useEffect(() => setFailed(false), [media.url]);
68
+
69
+ if (failed) {
70
+ // Terminal: the browser has no decoder for this codec. Retrying cannot help,
71
+ // so this states the fact rather than offering a button that does nothing.
72
+ // The panel carries `role="alert"` itself, and sits centred like every other
73
+ // viewer state — a message pinned to the top-left of an empty pane reads as
74
+ // a broken render.
75
+ return (
76
+ <div className={cn("flex min-h-full flex-col justify-center p-4", className)}>
77
+ <StatePanel
78
+ kind="error"
79
+ title={t("viewer.media.unsupportedTitle")}
80
+ description={t("viewer.media.unsupported", { name: source.name })}
81
+ />
82
+ </div>
83
+ );
84
+ }
85
+
86
+ const label = t("viewer.media.label", { name: source.name });
87
+
88
+ if (media.media === "audio") {
89
+ return (
90
+ <div className={cn("flex min-h-full items-center justify-center", className)}>
91
+ <audio
92
+ src={media.url}
93
+ controls
94
+ aria-label={label}
95
+ onError={() => setFailed(true)}
96
+ className="w-full max-w-lg"
97
+ />
98
+ </div>
99
+ );
100
+ }
101
+
102
+ return (
103
+ <div className={cn("flex min-h-full items-center justify-center", className)}>
104
+ <video
105
+ src={media.url}
106
+ controls
107
+ // No autoplay: a viewer opens files the reader chose to look at, not to
108
+ // listen to. Sound starting on its own is the reason browsers block it.
109
+ aria-label={label}
110
+ onError={() => setFailed(true)}
111
+ className="max-h-full max-w-full"
112
+ />
113
+ </div>
114
+ );
115
+ }
116
+
117
+ const adapterModule: AdapterModule = {
118
+ manifest: mediaManifest,
119
+ create: () => new MediaAdapter(),
120
+ Renderer: MediaRenderer,
121
+ };
122
+
123
+ export default adapterModule;
@@ -0,0 +1,17 @@
1
+ import type { AdapterManifest } from "../../core/types";
2
+ import { PROTOCOL_VERSION } from "../../core/types";
3
+
4
+ /**
5
+ * Eager, data-only.
6
+ *
7
+ * No `requires`: the browser is the decoder, so this adapter has no optional
8
+ * peer and can never report `parser-missing`. A codec the browser cannot play is
9
+ * a different failure — the `<video>` element's own `error` event — and it is
10
+ * reported where it happens, in the renderer.
11
+ */
12
+ export const mediaManifest: AdapterManifest = {
13
+ id: "media",
14
+ protocol: PROTOCOL_VERSION,
15
+ categories: ["video", "audio"],
16
+ mediaTypes: ["video/", "audio/"],
17
+ };
@@ -0,0 +1,239 @@
1
+ /**
2
+ * Frozen Office fixtures — a real `.docx`, `.pptx` and `.xlsx`, generated once
3
+ * and pinned here so stories and tests need no network and no binary asset.
4
+ *
5
+ * Each one is a genuine OOXML package (a zip of XML parts with content types
6
+ * and relationships), not a stub: mammoth really converts the Word file, SheetJS
7
+ * really reads the workbook's two sheets and its date column, and jszip really
8
+ * unzips the deck — including the relationship that points slide 1 at its
9
+ * speaker notes. A hand-waved fixture could not prove any of that.
10
+ *
11
+ * They are deliberately MINIMAL: the Word file has no theme, and the deck holds
12
+ * exactly the parts this adapter reads. They exercise the adapters; they are not
13
+ * samples of what PowerPoint writes.
14
+ */
15
+
16
+ export const SAMPLE_DOCX_BASE64 =
17
+ "UEsDBAoAAAAIAOZTCl0HL3psCwEAAMICAAATAAAAW0NvbnRlbnRfVHlwZXNdLnhtbK2SzU7DMBCE730Ky1eUOHBACCXpgZ8j" +
18
+ "cCgPYOxNYmGvLa9TmrfHaSFICKoeelzNzsyn1dbrnbNsC5GMx4ZflhVngMprg33DXzePxQ1nlCRqaT1Cwycgvm5X9WYKQCyb" +
19
+ "kRo+pBRuhSA1gJNU+gCYlc5HJ1MeYy+CVO+yB3FVVddCeUyAqUhzBm9XjNX30MnRJvawy8qBJSdwdndYndsaLkOwRsmUZTGr" +
20
+ "4j9rBEtHvFvUvxiLL74yO/c7NJhAFz8lz/lE0WhgLzKmJ+lyovjwUQvt1ehyS3kc949K33VGweKf00L0Cojy7Z0tF8VJg6eg" +
21
+ "UJos0PlBDrmnEODo3iBm1/khluhvjlrsX7D9BFBLAwQKAAAAAADmUwpdAAAAAAAAAAAAAAAABgAAAF9yZWxzL1BLAwQKAAAA" +
22
+ "CADmUwpdIBuG6rIAAAAuAQAACwAAAF9yZWxzLy5yZWxzjc+7DoIwFAbgnadozi4FB2MMhcWYsBp8gKY9lEZ6SVsvvL0dHMQ4" +
23
+ "OJ7bd/I33dPM5I4hamcZ1GUFBK1wUlvF4DKcNnsgMXEr+ewsMlgwQtcWzRlnnvJNnLSPJCM2MphS8gdKo5jQ8Fg6jzZPRhcM" +
24
+ "T7kMinourlwh3VbVjoZPA9qCkBVLeskg9LIGMiwe/+HdOGqBRyduBm368eVrI8s8KEwMHi5IKt/tMrNAc0q6itm+AFBLAwQK" +
25
+ "AAAAAADmUwpdAAAAAAAAAAAAAAAABQAAAHdvcmQvUEsDBAoAAAAIAOZTCl2BJu6HvwEAAJ0FAAARAAAAd29yZC9kb2N1bWVu" +
26
+ "dC54bWy9lN1umzAUx+/7FJalXQ6SaJoyFFxFW6v1olLXbQ/gwAmgGts6NjDefjaGqilNm6hSb8yxOef/8/mQN5f/akFaQFMp" +
27
+ "mdJltKAEZKbyShYp/fvn+vOaEmO5zLlQElLag6GX7GLTJbnKmhqkJU5BmqRLaWmtTuLYZCXU3ERKg3T/9gprbt0Wi7hTmGtU" +
28
+ "GRjjALWIV4vF17jmlaSjDJ4io/b7KoMf4wWCCILg1iVhykobyi4IcXfcqbz35rDRzC93OHx+214A6ZKWi5T+BO4TXtKYbeJH" +
29
+ "n2Gx7FfD0QKKniC0FXTeww5+GLwPASHKZ5MYzTNXMo1gAFug7B5akA2QAqEjBzrTEsi7cI9xZ9ly/ekl7yMUwgtXUGMJf41R" +
30
+ "PWPsXfnOgdQcH8BGb1TjtXKvXiz3PRS+i6fpyqYesxGtmOQXXnf4d5NPZ1Nrx4AZ9er2akt2wC3RgssPhm/vtt9JCSInsybM" +
31
+ "4WWv3TBW8oFgUuUpxZv8G30idt0I4SZVK5wpPYY+07U7EeywC0IZO5zosTHz2w0n2bGYYeCPB8UD722478956C/R6vb9XN+a" +
32
+ "87jLaH0ad7BD5b0ZnipvTQ8r+w9QSwMECgAAAAgA5lMKXWCmSMe8AAAARwEAAA8AAAB3b3JkL3N0eWxlcy54bWyVjjFuwzAM" +
33
+ "RfecguCeyPZQFIalbEG7twcgbNY2IFGCKMTx7augaYEOHbqRePyPfzjfgocrZ12jWGxPDQLLGKdVZovvb5fjM4IWkol8FLa4" +
34
+ "s+LZHYat17J7Vqh50X6zuJSSemN0XDiQnmJiqewj5kClrnk2W8xTynFk1aoP3nRN82QCrYLuAPDthK0ve6q/EmWaM6UF4YFe" +
35
+ "J4svTPd2LboaEAr3+yv5WuALQIvGDeaR+L+4+1Pc/Rb/jOo+AVBLAwQKAAAACADmUwpdxtYBy8wAAAA/AQAAEgAAAHdvcmQv" +
36
+ "bnVtYmVyaW5nLnhtbFWPwW7CMAyG7zxF5DskcJhQ1YQb0i47bQ+QtgYqJU4Vp+329jOlSHBy/Pv39zv16TcGNWHmPpGF/c6A" +
37
+ "QmpT19PVws/3eXsExcVT50MitPCHDCe3qeeKxthgFp8SBHE1W7iVMlRac3vD6HmXBiSZXVKOvkibr3pOuRtyapFZNmPQB2M+" +
38
+ "dPQ9gdsoJVjfcMm+LV9jVG/dZ2fBgBNLmIKMeilPRW45xyLi5EVrxhCwgHa1XsxLfSGtSbQk0IO8XzhvcU+cWUl031wfj5+7" +
39
+ "f1BLAwQKAAAAAADmUwpdAAAAAAAAAAAAAAAACwAAAHdvcmQvX3JlbHMvUEsDBAoAAAAIAOZTCl1Y8NHK8AAAAFICAAAcAAAA" +
40
+ "d29yZC9fcmVscy9kb2N1bWVudC54bWwucmVsc62SwU7DMAyG73uKyHeabgcEqOkugLQDF1QeIKRuGy1xoiRD7dtjQDAmgeCw" +
41
+ "oxP/nz9Habazd+IFU7aBFKyrGgSSCb2lUcFTd39xBSIXTb12gVDBghm27ap5RKcLZ/JkYxYMoaxgKiXeSJnNhF7nKkQkvhlC" +
42
+ "8rpwmUYZtdnrEeWmri9l+s6AdiXECVbsegVp169BdEvE/+DDMFiDt8EcPFL5YYrMZXG8guh0GrEo+Kgr5oD81WBzTgM6+GdM" +
43
+ "/L5Hia+jPzyuz+kxMSk5S/ujxxs2Mxdn7aPDygTPoRhS+ex5CD2Pv5sLJtLvqo08+QrtK1BLAQIUAAoAAAAIAOZTCl0HL3ps" +
44
+ "CwEAAMICAAATAAAAAAAAAAAAAAAAAAAAAABbQ29udGVudF9UeXBlc10ueG1sUEsBAhQACgAAAAAA5lMKXQAAAAAAAAAAAAAA" +
45
+ "AAYAAAAAAAAAAAAQAAAAPAEAAF9yZWxzL1BLAQIUAAoAAAAIAOZTCl0gG4bqsgAAAC4BAAALAAAAAAAAAAAAAAAAAGABAABf" +
46
+ "cmVscy8ucmVsc1BLAQIUAAoAAAAAAOZTCl0AAAAAAAAAAAAAAAAFAAAAAAAAAAAAEAAAADsCAAB3b3JkL1BLAQIUAAoAAAAI" +
47
+ "AOZTCl2BJu6HvwEAAJ0FAAARAAAAAAAAAAAAAAAAAF4CAAB3b3JkL2RvY3VtZW50LnhtbFBLAQIUAAoAAAAIAOZTCl1gpkjH" +
48
+ "vAAAAEcBAAAPAAAAAAAAAAAAAAAAAEwEAAB3b3JkL3N0eWxlcy54bWxQSwECFAAKAAAACADmUwpdxtYBy8wAAAA/AQAAEgAA" +
49
+ "AAAAAAAAAAAAAAA1BQAAd29yZC9udW1iZXJpbmcueG1sUEsBAhQACgAAAAAA5lMKXQAAAAAAAAAAAAAAAAsAAAAAAAAAAAAQ" +
50
+ "AAAAMQYAAHdvcmQvX3JlbHMvUEsBAhQACgAAAAgA5lMKXVjw0crwAAAAUgIAABwAAAAAAAAAAAAAAAAAWgYAAHdvcmQvX3Jl" +
51
+ "bHMvZG9jdW1lbnQueG1sLnJlbHNQSwUGAAAAAAkACQAgAgAAhAcAAAAA";
52
+ export const SAMPLE_PPTX_BASE64 =
53
+ "UEsDBAoAAAAIAOZTCl2PfV4kEwEAAFsDAAATAAAAW0NvbnRlbnRfVHlwZXNdLnhtbMWTy2rDMBBF9/kKoW2x5WRRSrGdRR/L" +
54
+ "ttD0A4Q8tkX1QjMJyd9XtlvcljY0EOhKGs3cew8DKtd7a9gOImrvKr7MC87AKd9o11X8ZXOfXXGGJF0jjXdQ8QMgX9eLcnMI" +
55
+ "gCyJHVa8JwrXQqDqwUrMfQCXOq2PVlIqYyeCVK+yA7EqikuhvCNwlNHgwesFY+UttHJriN3tU2diSQ6c3UyjQ1rFZQhGK0mp" +
56
+ "LYau+E0aweAR7c413xizd748KccZ7HXAiznkMa0o6gbYk4z0IG1yFCGQCBEwZYya/DjxD6m+bbWCxqutTZL8s5k1X8rcSu3+" +
57
+ "wIMmPeJ0LM8NNLqeCLH6LwjnCfB5IpnvZ9/JbP3BVIrxb9RvUEsDBAoAAAAAAOZTCl0AAAAAAAAAAAAAAAAGAAAAX3JlbHMv" +
58
+ "UEsDBAoAAAAIAOZTCl062VMktAAAADEBAAALAAAAX3JlbHMvLnJlbHONz80KwjAMB/D7nqLk7rp5EBG7XUTYVeYDlDbrhusH" +
59
+ "TRX39hZPTjx4TPLPL+TYPu3MHhhp8k5AXVbA0CmvJ2cEXPvzZg+MknRazt6hgAUJ2qY4XnCWKe/QOAViGXEkYEwpHDgnNaKV" +
60
+ "VPqALk8GH61MuYyGB6lu0iDfVtWOx08DmoKxFcs6LSB2ugbWLwH/4f0wTApPXt0tuvTjylciyzIaTAJCSDxEpNx8p8ssA8+P" +
61
+ "8tWnzQtQSwMECgAAAAAA5lMKXQAAAAAAAAAAAAAAAAQAAABwcHQvUEsDBAoAAAAIAOZTCl06hacWvAAAAEMBAAAUAAAAcHB0" +
62
+ "L3ByZXNlbnRhdGlvbi54bWyNj8GqwjAQRffvK8LsNbWgPoqpGxEEl/oBoZnaQDIJmSj690Z9PKord/dyuIeZ1frqnbhgYhtI" +
63
+ "wWxagUDqgrF0UnA8bCe/IDhrMtoFQgU3ZFi3P6vYxISMlHUuS1EsxE1UMOQcGym5G9BrnoaIVFgfkte51HSS4513sq6qhfTa" +
64
+ "EvxJ0jeS0Pe2w03ozr64XpKE7inlwUaGtpzIzuzMnvN/FtYoqOcLEKl5xLQzM5CfeDnC9QPLsUq+v97eAVBLAwQKAAAAAADm" +
65
+ "UwpdAAAAAAAAAAAAAAAACgAAAHBwdC9fcmVscy9QSwMECgAAAAgA5lMKXc1vxve7AAAArQEAAB8AAABwcHQvX3JlbHMvcHJl" +
66
+ "c2VudGF0aW9uLnhtbC5yZWxzvZBBCsIwEEX3niLM3qbtQkSadiOCW9EDhGTaBtskZKLY2xtEwYKCK5d/hv/mMVVzGwd2xUDG" +
67
+ "WQFFlgNDq5w2thNwOu6Wa2AUpdVycBYFTEjQ1IvqgIOMqUO98cQSxJKAPka/4ZxUj6OkzHm0adO6MMqYYui4l+osO+Rlnq94" +
68
+ "eGdAvWBshmV7LSDsdQHsOHn8Be/a1ijcOnUZ0cYPVzgNRmMCytBhFPCIz2mRJRrwrx7lnzzKl0fFZ1+u71BLAwQKAAAAAADm" +
69
+ "UwpdAAAAAAAAAAAAAAAACwAAAHBwdC9zbGlkZXMvUEsDBAoAAAAIAOZTCl0ADAsgMwEAAM0CAAAVAAAAcHB0L3NsaWRlcy9z" +
70
+ "bGlkZTEueG1snVLLbsMgELz7K1ZIPTYkPVSRZROlVXqrlDbpBxCziS1hjBbixH9fIC9V6qHpZdhdmNmBpZgdWw09kms6U7LJ" +
71
+ "aMwATdWpxuxK9rV+e5wycF4aJXVnsGQDOjYTWWFzpxUEsnG5LVntvc05d1WNrXSjzqIJe9uOWulDSjtuCR0aL31o1Gr+NB4/" +
72
+ "81Y2hp1F5F9EFMlDcPaDLzKAYKdaaSWiLbsmxFhMZWdPYUpMv7JLEik6rbYGP9hwL994jYyLgl82+fX8TcAfXzo1iELmNgJF" +
73
+ "8OJjL8kj6QEI+wYPBY/ViJTQJrEz92SM35zdYXITBBg06hgm9U+vn9ij2SPsCA8wmT784vUCSwLd63Orq8DifTGHDUoPVktz" +
74
+ "N32+nL9CjeHvbLX0971UdknThGOYhp6lYgi+AVBLAwQKAAAACADmUwpdrICdZFABAADoAwAAFQAAAHBwdC9zbGlkZXMvc2xp" +
75
+ "ZGUyLnhtbK2TyW7DIBCG734KxL2ZNKqqyrKJGjW5Raqa9AGImdqWMEZA0/jtCzhrlyipepkFmJ+PGTsbbxpJ1mhs3aqc3g6G" +
76
+ "lKAqWlGrMqevy9nNAyXWcSW4bBXmtENLxyzJdGqlIL5Y2VTntHJOpwC2qLDhdtBqVH7vrTUNdz41JWiDFpXjzl/USBgNh/fQ" +
77
+ "8FrRrQi/REQY/uHJTupZQojHKRZSsICllwYxLMZlq/swJmq90M+Gxaj3uiKu0/5drnYSKbAMdpuwP38QcJtJKzqW8VQHY4Jx" +
78
+ "7AVL/yibQUiCNdHqqLEt6XngAHQF28oLUFKLjR/QHxEnHTG4RvWOV1OWhuuqLmaGNxjEtvlR+MQdj9esZByGj/pr46FzPfsJ" +
79
+ "5lABe4mzQr8+65sSRLJLEafz6eM/AN4NRvNr6KL3nQz+pMFw1Hv4MpdkN7b48Ycw/g9JXPTBJ1BLAwQKAAAAAADmUwpdAAAA" +
80
+ "AAAAAAAAAAAAEQAAAHBwdC9zbGlkZXMvX3JlbHMvUEsDBAoAAAAIAOZTCl03hw3StQAAADcBAAAgAAAAcHB0L3NsaWRlcy9f" +
81
+ "cmVscy9zbGlkZTEueG1sLnJlbHONz70KwjAQB/Ddpwi3m7QOImLqIoKr1gcIybUNtpeQi2Lf3owVHBzv63f8D8f3NIoXJvaB" +
82
+ "NNSyAoFkg/PUa7i35/UOBGdDzoyBUMOMDMdmdbjiaHK54cFHFgUh1jDkHPdKsR1wMixDRCqTLqTJ5FKmXkVjH6ZHtamqrUpL" +
83
+ "A5qVEF+suDgN6eJqEO0c8R8+dJ23eAr2OSHlH18UhYx8G73DoprUY9Yg5aK9XKll8UGVuOorb/MBUEsDBAoAAAAAAOZTCl0A" +
84
+ "AAAAAAAAAAAAAAAQAAAAcHB0L25vdGVzU2xpZGVzL1BLAwQKAAAACADmUwpdZEYW8gwBAADNAQAAHwAAAHBwdC9ub3Rlc1Ns" +
85
+ "aWRlcy9ub3Rlc1NsaWRlMS54bWyNUU1PwzAMve9XWDlDUzggVLWZtANXkDp+QNaatVLjREnWtf8eJ91A3Lj4K37Pfk69X8wE" +
86
+ "M/owWmrEU1EKQOpsP9K5EZ/Ht8dXASFq6vVkCRuxYhB7tatdRTZiAIZTqFwjhhhdJWXoBjQ6FNYh8duX9UZHTv1ZOo8BKerI" +
87
+ "o8wkn8vyRRo9kriR6P+Q9F5febc/eLUD4IW6duoV++COHjEVczm4LcwJza378CpHm3cDxNWxspPtVwFjv/AZhFS1vPfIH9gv" +
88
+ "T1wO3K5qXblkfDJRvfO+cB0jUw4IHmekCwJdzAn9Q6oRDHxKsHxwiBZabYpaJmSyPluXB974Nw3yLmKLsroUZsG7vF/6C/UN" +
89
+ "UEsBAhQACgAAAAgA5lMKXY99XiQTAQAAWwMAABMAAAAAAAAAAAAAAAAAAAAAAFtDb250ZW50X1R5cGVzXS54bWxQSwECFAAK" +
90
+ "AAAAAADmUwpdAAAAAAAAAAAAAAAABgAAAAAAAAAAABAAAABEAQAAX3JlbHMvUEsBAhQACgAAAAgA5lMKXTrZUyS0AAAAMQEA" +
91
+ "AAsAAAAAAAAAAAAAAAAAaAEAAF9yZWxzLy5yZWxzUEsBAhQACgAAAAAA5lMKXQAAAAAAAAAAAAAAAAQAAAAAAAAAAAAQAAAA" +
92
+ "RQIAAHBwdC9QSwECFAAKAAAACADmUwpdOoWnFrwAAABDAQAAFAAAAAAAAAAAAAAAAABnAgAAcHB0L3ByZXNlbnRhdGlvbi54" +
93
+ "bWxQSwECFAAKAAAAAADmUwpdAAAAAAAAAAAAAAAACgAAAAAAAAAAABAAAABVAwAAcHB0L19yZWxzL1BLAQIUAAoAAAAIAOZT" +
94
+ "Cl3Nb8b3uwAAAK0BAAAfAAAAAAAAAAAAAAAAAH0DAABwcHQvX3JlbHMvcHJlc2VudGF0aW9uLnhtbC5yZWxzUEsBAhQACgAA" +
95
+ "AAAA5lMKXQAAAAAAAAAAAAAAAAsAAAAAAAAAAAAQAAAAdQQAAHBwdC9zbGlkZXMvUEsBAhQACgAAAAgA5lMKXQAMCyAzAQAA" +
96
+ "zQIAABUAAAAAAAAAAAAAAAAAngQAAHBwdC9zbGlkZXMvc2xpZGUxLnhtbFBLAQIUAAoAAAAIAOZTCl2sgJ1kUAEAAOgDAAAV" +
97
+ "AAAAAAAAAAAAAAAAAAQGAABwcHQvc2xpZGVzL3NsaWRlMi54bWxQSwECFAAKAAAAAADmUwpdAAAAAAAAAAAAAAAAEQAAAAAA" +
98
+ "AAAAABAAAACHBwAAcHB0L3NsaWRlcy9fcmVscy9QSwECFAAKAAAACADmUwpdN4cN0rUAAAA3AQAAIAAAAAAAAAAAAAAAAAC2" +
99
+ "BwAAcHB0L3NsaWRlcy9fcmVscy9zbGlkZTEueG1sLnJlbHNQSwECFAAKAAAAAADmUwpdAAAAAAAAAAAAAAAAEAAAAAAAAAAA" +
100
+ "ABAAAACpCAAAcHB0L25vdGVzU2xpZGVzL1BLAQIUAAoAAAAIAOZTCl1kRhbyDAEAAM0BAAAfAAAAAAAAAAAAAAAAANcIAABw" +
101
+ "cHQvbm90ZXNTbGlkZXMvbm90ZXNTbGlkZTEueG1sUEsFBgAAAAAOAA4AfgMAACAKAAAAAA==";
102
+ export const SAMPLE_XLSX_BASE64 =
103
+ "UEsDBBQAAAAIAAAAAADxYTwnbgEAAEIDAAAaAAAAeGwvX3JlbHMvd29ya2Jvb2sueG1sLnJlbHOzsa/IzVEoSy0qzszPs1Uy" +
104
+ "1DNQUkjNS85PycxLt1UKDXHTtVBSKC5JzEtJzMnPS7VVqkwtVrK34+WyCUrNSSzJzM8rzsgsKFaoyM3JK7ZVyigpKbDS1y9O" +
105
+ "zkjNTSzWyy9IzavIzUnLL8pNLCnWyy9K1y9ITM5OTE/VNzIwMNMvSkUyQ8nOJgjJTAXPFFulIs8UQyWFkMqCVFslwmbnp6Vl" +
106
+ "Jqe65CeX5qbmlegbYVihX55flF2ckZpaoqQQkliUnlpiq1SeDxUq1i/OSE0tMdSryM1R0rezweYYIyWFEHo6xkivIjcHl2OM" +
107
+ "lRRCqOaYkozU3FQlhZDEovTUElulkgwgV78EJGiohydATJQUQqjmhuKSypzUYiWFEKgjiktAfL2K3BwlfTuboNScxJLM/Lzi" +
108
+ "jMwCBc8UW6UizxRTJYUQ6lmfkZpa4ptakpiSWJKopBCSCAmK3FSIiF5Fbg7IHfpBqTmJJZn5ecUZmQXFdgBQSwMEFAAAAAgA" +
109
+ "AAAAADAPiGsVDAAA3h0AABMAAAB4bC90aGVtZS90aGVtZTEueG1ss7GvyM1RKEstKs7Mz7NVMtQzUFJIzUvOT8nMS7dVCg1x" +
110
+ "07VQUiguScxLSczJz0u1VapMLVayt+Plskm0KslIzU1VqMjNySu2SrRVyigpKbDS1y9OzkjNTSzWyy9IzavIzUnLL8pNLCnW" +
111
+ "yy9K108pSizPzEvPzdE3MjAw089NzMxTUshLzE21VfJPS8tMTlUIyQAaqWRnkwgx3DUnNTc1r6TYzibRKjmnKDgZaHSqQh6S" +
112
+ "DiWQ2pRsQzubRKviymLnnCKFssQcW6XyzLyU/PKQ1IoSJYWcxOIS55wiWyUDAwMgUNK3s9FPtIJqyikxtLNJxKJXSQGuz83N" +
113
+ "DQiU9MH6oBpSso3sbBKtiovSk5xzihTKEnNslQzdTCzNXZT0weqgCnJKjOxsElHVubq6OrsaKumD1UEVJCYnp+aVGNrZJKKq" +
114
+ "NXGzMHRyUYKYiaQIwjSys0lEVe9sYGpg4qKErB6sKDE5OTWvxNgOGJIobrZ0cnIytVTSB7sFSRGEaWJnk4hqvoWBmYmjkZI+" +
115
+ "knqwosTk5NS8ElM7m0RU9SZOjs7OZkr6SOrBihKTk1PzSszsbBJR1buZW5qZmCkhqwcrysjJzMu2s0lEVQ2KUTc3aMzAlaTl" +
116
+ "53jkZOZl29kkoiq3MDAwsDBQgiQAhCr9RCt46rKzSbRKy88rCU7OSM3FktZyE7Pyi9zy80rsbBKtchJLMvMUSioLUtMSk1Nt" +
117
+ "lZwTc5OKMhOV9O1sEq1SExVK4DJK+iCh5GKFEjQhkF0KxclFmQUltkpeBYl5SgolcCXv96x9v2ezwvs9Gx43bXnctP1xc/Pj" +
118
+ "pvVK+nY2iVYoGj0S89KVFBAaXy+f+GZug8KrzQteT5mqpI9NfbGSAkL903XdT/ZOVtLHprBESQGh8Nm0Dc+3bHg2o+/l6ilK" +
119
+ "+hjKHYsSk5QUEMpDMnNTixX8UssVgvJzE/OU9DF0eKQmFSkpkKIjJCMxU0kBSUdiRn5uohI4zNPy80oUipOLMgtKbJVcSzIy" +
120
+ "lZAU+lUm5iQqYapzSs1LRw68sKLMvJREJUyF7qVZRUpIbg3OKCotyVTSt7NJtErLzytRKE4uyiwosVXyzsgtUkJS6Jufn+OU" +
121
+ "X5SYp6SPqTYvJVFJoaSyIDUtMTnVVimkNC89UQmb5UWlSgoIdUGJiWWZSph2OyfmoUSta2lBRmpuZiIkUabl55UoFCcXZRaU" +
122
+ "2Co5Z6QWKSE5MyAnMa8kMT01L7VEwTkjtSg/OzVVSd/OJtEKRVtkZmamElK4+mYmF+UX56eVKERmKjglZpZkYgmSkMykEiWk" +
123
+ "hITQ5JGZm5iTWJmohOnnkIzERCWksPENU3DKz8lUwvS1S2pZohKyysS89MQcJX07m0SrtPy8EoXi5KLMghJbpZDUnFIlpGB0" +
124
+ "TywtSczNVMI0MiQxN0dJoaSyIDUtMTnVVsknsSQjUQnTkcGVRclKCgh1rsUlRYl56ak5+QquKanFxYlKmHr8iyoTlZCc652Y" +
125
+ "k5mXnogl2n1zKnOVFBCmeycWlWRmJyphmumTmJ+vpIBQ6ZKf7ZyRmFuQqISpNjgzL0NJAaHWszg7Pz8nUSEgvyRRCVO5b35e" +
126
+ "OnIOAfHzczIT8xSccER3WGZqiRJSdIdk5qYWK/illisE5ecm5mHJB6GZ6RlKSE7yhaeq0Mz0jNIiJWCVk2iVlp9XolCcXJRZ" +
127
+ "UGKr5J6aX6SElH6DK3PSElPzlICZDFiko5TUuZl5+UVu+XkldjaJVpjFdk5mUlGmkr6dTaLVyC22SyoLUtMSk1NtlRyLMhNz" +
128
+ "sGQej1TUwhqXupCMxKFWRLskluYFpOZlKOnb2SRapeXnlSgUJxdlFpTYKnmP3BI6vzg/rURh5JbQJZUFqWmJyam2St6Jw7yE" +
129
+ "xpWXqV8uI4pi/USrtPy8EkhbG9zyzi0JxtHwTsvMyQkuqcxJ9SkusQMW4sX5OZkpbpk5OXY2iVbFyRmpuanOOUUKZYk5tkoF" +
130
+ "Gc45RUr6djZAC4qR1aUXJaa4ZebkKBTll4RnlmQEZyQWpNoqGSrZ2SRapRf7FIONTi9WKMgvtlUyULIDChdjM9sOKFGSmVei" +
131
+ "UJaYY6tkamBgYADqVyZaFSeW+OanKJSBhI0NDAwMDEDiIHfAjLGzAfLSi+1sEq3SiyEWGZsaGBgoEWmZsbmBgYESsA+TaFVM" +
132
+ "jmWGBgYGBgZKRNpmaGoAdJq+nU2iVTGybSAXGygBxfUTrYqTM1JzU51ziuxsgLz0YjsbMAUNzZzMPIXEvHRbJUMzIwMDAwMD" +
133
+ "JYXi5MSc1BRbJUMlSB84HRotdjaJVjA2laPIEOJroIMTrYozElNSFcoSc2yVUISR/GdobECL0EROKIQdYUyVQDZQ0rez0U+0" +
134
+ "SocHMpCDnpty8oJLKnNSfYpL7GwSrXLyFMptlSxNjUyVFJITC2yV0nISS5QUknMLUmyVivPSlRQSc9LzbJWSS4qU7GwSrYqR" +
135
+ "81hxckZqbqpzTpFCWWKOrVJBhnNOkRJYFcLHlqYGEI8lWhUnlvjmpyiUJebYKhkamBpAxIFOLIaZY2cD4iFbUVBUXOKSWJyh" +
136
+ "UAbSVZwPLAmUICMeOXl2NolWOXkg9xuZmhgYKCkkU8UDWAoT4lxhbGFoYDBgrtBPtMrJQ47a1LS01OSS4JLKnFSf4hI7m0Qr" +
137
+ "JBE74OAHhOtTDJbLLy1JLQrOSClXSMopLQpKTLFVMjEwMDBQUkjJLC6xVTIyACe1lMwiWyVTEwOgjIGSQlF+SXhmSUZwRmJB" +
138
+ "qq2SgZKdTaJVcVF6knNOkUJZYo6tkgFw1MbAQAkknphTkJGoUAYSNbYwMDBQ0rezAboZqhwc83A32NnoJ1ohOQ/OCy6pzElF" +
139
+ "uB2N61NcYmeTaAU3BpdXjA0MDJQUUjKp4RVQxlUamV5JtCpOTs1LNU6xs0m0Sk7MTS1KVCgoKi6xVcovKsnITy9KLMjITHYr" +
140
+ "ys8rUbKzSbQqyi9RyEkssVUyUFLIyc+zVQLSRalltkoGSvp2NvqJVhAz7GwSrXIy0zNKgjLTFYoy022VSjKKUlMDSpQUUjKL" +
141
+ "bJVKlPAaZmhkAEypBkoQI2EG2dnoJ1ohObe4wDjFzibRKim1LDUnRKHcVsnM2BTofYUMWyUjcGkC0Q9Rp59olZqWlppcElxS" +
142
+ "mZNqZ4PKh+aupHS3zJyc4JLKnFSoSHF+TmaKW2ZOjp1NolVxckZqbqpzTpFCWWKOrVJBhnNOkZI+2N/FyOpghTeVa0UTYKox" +
143
+ "AAVKolUxUjlsbGpgYGAAEtdPtCpOzkjNTXXOKbKzAfLSi+1sEq3SixUK8ottlSD67WwSreCqFMoSc2yVCjKcc4qU7IASJZl5" +
144
+ "JQplIDETUwMDA5ChQNVIVYGlgQFMlBwnGBoYGBgYKOF1QzHCOiNwiaVvZ5NoVYxknZGpqQEe6/QTrdKLfYpL7GwSrQoSSzIU" +
145
+ "ChJLMmyVkjOLknNSlexsEq1AFWpIflBqcolCjq2SKbhBqFBiq6RrYWBgYKCkUGSrBBVMslUytDAACerb2QANBplnZwNkpMMr" +
146
+ "6EQrGJvK8Q0aADdQAtqbaFWM5HtjUNPRACQOdEZxckZqbqpzTpGdDZCXXmxnk2iVXqxQkF9sq2RIWmCDzVXCsM4IFAcGIHGg" +
147
+ "BcXJGam5qc45RXDr9BOt0ot9ikvsbBKtQIFDfGCbAhkGSgooYW0KZBgoAd0ANBZkGlpQ6ydaoWdRoFAarB9iB8rVJRmpuanI" +
148
+ "c1H5SVmpySUuqWmJpTklxXY2iVbFBS6paXY2IEZAkb6dTaJVUn5KZUARmJlTXBJcUpmTqm9nk2hVXAJk2dkkWuXkBaWmKWSm" +
149
+ "VNgqGSrZ2SRaFcNCQqEsMcdWKTE5OTWvxFAJ0kQGqwZZkJaZkxOUCtVorGRHSCNUPUhralpaanJJUCpUs5GSHSHNcB0g7WnA" +
150
+ "rlpQKlRzbiZwQE0JiwE5JYZK+nY2+olWUPV2NkB2McTXIBYspHLyXFLT7GwSrYoLyAgyIhyfkxeUmgayIA05yAyU7GwSrYqT" +
151
+ "M1JzU51zihTKEnNslRKTk1PzSgyV9O1s9BOtoOpBWuEBoJCZUmFLTETBdYC0pxEVZCUVhkr6djb6iVZQ9XY2QHZxSWVOqp0N" +
152
+ "kJWTBw4pIAsz4aVWlBQlOucUBSdnpOam+hSX6NuBDAInWTsAUEsDBBQAAAAIAAAAAABypxDXRQMAAK8EAAANAAAAeGwvc3R5" +
153
+ "bGVzLnhtbLOxr8jNUShLLSrOzM+zVTLUM1BSSM1Lzk/JzEu3VQoNcdO1UFIoLknMS0nMyc9LtVWqTC1Wsrfj5bIpLqnMSQ3O" +
154
+ "SE0tUajIzckrtlXKKCkpsNLXL07OSM1NLNbLL0jNq8jNScsvyk0sKdbLL0rXLy4oSk1MKQZpys3RNzIwMNPPTczMU1KoAJlg" +
155
+ "VVZiq0TYkPy0tMzkVJf85NLc1LwSfSOQKSn5yQFF+QXFYSGVBanFSnY2eaW5brklxQrJ+aV5JbZKhkp2UCGFvNJct9wSzxRb" +
156
+ "JVMzJYW0/KLcxBLn/JRUWyW1wtL8EusnO7qe9nboP9nR/bS3Q0GtECSWkaFWCKKfzWxSAyvKzVUrBAk87WhTKwQxiovVCkH0" +
157
+ "8+WTFNTAepT07Wz080pBlhXb2aTl55UUI7sGJGBnU1ylUJaYY6tkaKSkb2eTnJ+TX6RQkpGam2qrZKikb2eTl5ibqlAGUuGc" +
158
+ "mJOZVJSppG9nk5aYm5lTqVAGEjZSAuorTs5IzU2FqMvNzMsvUgIK6qfl55XY2YCpYqADMnNyihWgwWGkZGeTBhSwsylILClJ" +
159
+ "Lcpzy8zJUShIBLNDKgtSbZXy8vNSlfTtbPTTgFJ2NgRUpxclVhoamSrpwzXop2Xm5BTb2STlF6WkFhUrQG02VLKzgQjZ2eSk" +
160
+ "ppXo29kUZaZnlOjb2ZTkF+jb2STll5Tk5+rb2aRkJqbn5yXm6NvZ6CflF6WkFtnZQBnFdjbJqTk5wSXAFBiRVqyAZHZFmkIe" +
161
+ "PIINlBTS8vNKPFNslUDMzJwczxQwMym/KCW1yDMFxNEHOjk5FWGaHdjsiDS4saDAIt1YhYo0zxRbJQMlhcSCgpxKv9LcpNQi" +
162
+ "t3xQarNVMlQCxi2KmYYmSgpp+Xklnim2ID1pmTk5nilgZlJ+UUpqkWcKmEPQUH2QV4COh/giuKQyJ7VYITm/NK/EVslQyc4m" +
163
+ "OTUH4lOFvMTcVFslv/yi3MQcJQW4wUmlmTklmXmeKbZKBkooYVNsZ5NSkQYPFrBsSWJSTmpwSWUOwhYDJYWU1LTE0pySkESY" +
164
+ "pK1SSCKM7Zuaklmaa6mkAFUVkFmWXxJcUpmTaqsUkAljQ1SZKOnb2egXl1TmpAaDCg07AFBLAwQUAAAACAAAAAAAI09v904C" +
165
+ "AACKAwAAGAAAAHhsL3dvcmtzaGVldHMvc2hlZXQxLnhtbLOxr8jNUShLLSrOzM+zVTLUM1BSSM1Lzk/JzEu3VQoNcdO1UFIo" +
166
+ "LknMS0nMyc9LtVWqTC1Wsrfj5bIpzy/KLs5ITS1RqMjNySu2VcooKSmw0tcvTs5IzU0s1ssvSM2ryM1Jyy/KTSwp1ssvStcv" +
167
+ "LihKTUwpzgBqys3RNzIwMNPPTczMU1KoAJlgVWSrRNiM/LS0zORUl/zk0tzUvBJ9I5AhRak5iSWZ+XnFGZkFxUp2NimZual5" +
168
+ "xZn5eQpFqWm2So6GVs4mSvp2NsUZQJvDMlPLi+1s4GyF8vyi7KT8/OywzNRyzxRbJQMlfTsb/eKM1NSSsMzUcphal8SSRDub" +
169
+ "ovxyhSJbJUMlO5tkhSJbJUdDJYUSW6XikiIlO5syu6DU9Mz8PBv9Mjsb/WQ7G7ASJ0MlVCVlqXmlqTb6yGqcDZWQ1Tjn5Ben" +
170
+ "ptjoQ5XoF+WX29lArTZSsrNJViiyVXI0UlJAstrV19XRRh+qA6zAyQiotMzOxMjAwMDAwEYfWc7ZSEmh2FYJ5A+gCjNDQyM9" +
171
+ "AwtjY2MIMLPRhyrWR7baWMnOJlmhyFbJ0VhJAclqxwBHZxt9qA6wAidjoNIyO0MLAwMDAwM0q42VFEi22kTJziZZochWydFE" +
172
+ "SQHZ6tzUoszkxGIb/TI7G/1kOxuwIicToPIyOzNDAwMDAwM0602UFIi3Xh+cDiBxn5mel1+UmuJaVJRfVGxng8xVyCvNTUot" +
173
+ "Ci7JL0pNcSwOSa0osVUyVFIoLixKRU6B+pnpeflFqSmuRUX5IDP0y/OLssG5yA4AUEsDBBQAAAAIAAAAAABewLRe4wEAAIkC" +
174
+ "AAAYAAAAeGwvd29ya3NoZWV0cy9zaGVldDIueG1ss7GvyM1RKEstKs7Mz7NVMtQzUFJIzUvOT8nMS7dVCg1x07VQUiguScxL" +
175
+ "SczJz0u1VapMLVayt+PlsinPL8ouzkhNLVGoyM3JK7ZVyigpKbDS1y9OzkjNTSzWyy9IzavIzUnLL8pNLCnWyy9K1y8uKEpN" +
176
+ "TCnOAGrKzdE3MjAw089NzMxTUqgAmWBVZKtE2Iz8tLTM5FSX/OTS3NS8En0jkCFFqTmJJZn5ecUZmQXFSnY2KZm5qXnFmfl5" +
177
+ "CkWpabZKjoZWTsZK+nY2xRlAm8MyU8uL7WzgbIXy/KLspPz87LDM1HLPFFslAyV9Oxv94ozU1JKwzNRymFqXxJJEO5ui/HKF" +
178
+ "IlslQyU7m2SFIlslR0MlhRJbpeKSIiU7mzK7kNTEXBv9Mjsb/WQ7G7ACJ0MlZAUBqfkFOak2+lAl+kX55XY2UEONlOxswHoc" +
179
+ "jZQUkAx1zUvPzEtNLcrMS7fRh2oEq3MyAuooszM2sdGHCusjm2esZGcDVudorKSAZF5wYk5qsY0+VAtYhZMxUG2ZnaGRjT5U" +
180
+ "WB9skj44GCBez0zPyy9KTXEtKsovKrazQeYq5JXmJqUWBZfkF6WmOBaHpFaU2CoZKikUFxalIkeAfmZ6Xn5RaoprUVE+yAz9" +
181
+ "8vyibHAisgMAUEsDBBQAAAAIAAAAAABggACBgAIAAIgDAAAPAAAAeGwvbWV0YWRhdGEueG1ss7GvyM1RKEstKs7Mz7NVMtQz" +
182
+ "UFJIzUvOT8nMS7dVCg1x07VQUiguScxLSczJz0u1VapMLVayt+PlsslNLUlMSSxJVKjIzckrtlXKKCkpsNLXL07OSM1NLNbL" +
183
+ "L0jNq8jNScsvyk0sKdbLL0rXLy4oSk1MKc5ITS3JzdE3MjAw089NzMxTUqgAmWBVkVOUYquEZkxuZnJRfnF+Wolecn6ufn5a" +
184
+ "WmZyqn4xmkGG5vpFmckZKYkliUoKUMNSEm2VyDQrpTIvMTczObGoKLFSyY5LQcEmF+rXkMqC1GKF5PzSvBJbJUMlO6CcggKK" +
185
+ "rEJeYm6qrVKEj4tjQJCSQm5mXnBpQUF+UUlqSlgqLJCNDAwMDJQUkvMLKm2VDJUUChKLS1Idc3JslWCcsMSc0tRiWyUgPze1" +
186
+ "KD3VVgnIKi7IySxxyywqLrEFWq5QlF/unJ8TnJGZVmIL4ifnpCYWueWDw9sWpBMs4Jyfm5uaV1IMFkksLs5Mz7NVMlRSSM5P" +
187
+ "LUpOtQWZm5yak+ObWpJoq2SopG/HBfSvfm5qSWJKYkliSGVBarEdF1AorbSktCjVNxUirpCH4s3kfNQQScq24wLSQGCTWlHi" +
188
+ "U1xixwXhKiiABBRKizJtlaqTUpKSLJJTknXTEg1TdU0szVJ1Ey1MzXWNk43TjA2SDYwsk41rley4YFoVFGwqUhKtUirB0eNY" +
189
+ "VJRYGVCUX5BaVJKZWqyQ5lIJFrdVMlRSSHPOz8lJLChOTbFVMlDSB3lKAQxs9FMrSuygrgFz4K6z0U/KBjnbRj+tFNmvdlwK" +
190
+ "CjbJqZAwSkksSVRIxu3domSFElslQyWFMlsluMU2+jCTk1MRxthx2ejDwtkOAFBLAwQUAAAACAAAAAAABd9viycBAAB0AQAA" +
191
+ "DwAAAHhsL3dvcmtib29rLnhtbLOxr8jNUShLLSrOzM+zVTLUM1BSSM1Lzk/JzEu3VQoNcdO1UFIoLknMS0nMyc9LtVWqTC1W" +
192
+ "srfj5bIpzy/KTsrPz1aoyM3JK7ZVyigpKbDS1y9OzkjNTSzWyy9IzavIzUnLL8pNLCnWyy9K1y8uKEpNTCnOSE0tyc3RNzIw" +
193
+ "MNPPTczMU1KoAJlgVWSrRNiM/LS0zORUl/zk0tzUvBJ9I5AhRak5iSWZ+XnFGZkFxUp2NuVQlwUUKSTnp6T6Jeam2iqFZGQW" +
194
+ "h+dDnKykb2dTnAF0RrGdDZhWyEsEqQlKLUvNK01VUijOSE0t8UyxVTJUUiiyykyxVSryTDFU0odqgyr3SE1MSc4vzStRUoBr" +
195
+ "MFJSgGswUtK3s9EvzkhNLQFapF+eD7HdDgBQSwMEFAAAAAgAAAAAAEpqEflVAQAATAIAAAsAAABfcmVscy8ucmVsc7Oxr8jN" +
196
+ "UShLLSrOzM+zVTLUM1BSSM1Lzk/JzEu3VQoNcdO1UFIoLknMS0nMyc9LtVWqTC1Wsrfj5bIJSs1JLMnMzyvOyCwoVqjIzckr" +
197
+ "tlXKKCkpsNLXL07OSM1NLNbLL0jNq8jNScsvyk0sKdbLL0rXL0hMzk5MT9U3MjAw0y9KRTJDyc4mCMlMBc8UW6UizxQjJYWQ" +
198
+ "yoJUWyVKzNbPTS1JTEksSdRPzi9K1S0oyi9ILSrJTC1WUghJLEpPLbFVSslPDijKLyjWTwaq0KvIzVHSt7PB5iBjJYUQIh2U" +
199
+ "n5aWmZzqkp9cmpuaV6JvZGBgpl+UmpNYkpmfV5yRWVCsn1pRkpqXkpqiW4DPSYkFBXoVuTm4XGSopBBCNRflp6VlJqe65CeX" +
200
+ "5qbmlSgphCQWpaeW2CpV5OiX5xdlJ+XnZ+tV5OaA3KIflJqTWJKZn1eckVlQbAcAUEsDBBQAAAAIAAAAAAD/k6M7lAEAAFEC" +
201
+ "AAAQAAAAZG9jUHJvcHMvYXBwLnhtbLOxr8jNUShLLSrOzM+zVTLUM1BSSM1Lzk/JzEu3VQoNcdO1UFIoLknMS0nMyc9LtVWq" +
202
+ "TC1Wsrfj5bIJKMovSC0qyUwtVqjIzckrtlXKKCkpsNLXL07OSM1NLNbLL0jNq8jNScsvyk0sKdbLL0rXz09Ly0xOdclPLs1N" +
203
+ "zSvRNzIwMNNPrShJzUtJTdEtKIIZqKRQATLRqqzEVok8Q1PykwOK8guKw0IqC1KLlexsHAsKcjKTE0sy8/PsgjNSU0u8gm30" +
204
+ "HQsQgjYeqYkpmXnpAYmZRcV2NmUlVmWpySX5RQrFmVWptkpGSgpJicWpIZUFqbZKZYlFmYl5JUp2NiBliWCOnQ2QnVNQXFJk" +
205
+ "F55flF2cAbSj2Ea/rMQKImijD2SWIalFZmea2BnZ6AMVABk2KArBHLBD7Gz0PVKRnRiSWZKTWuyfFpBYVFJsh9/FOQXFJUVK" +
206
+ "diD3QpwTlFqWmleaaqMPtBQiYlNWYgVheaQmpiTnl+aV2OgjZPWBzLLU5JL8IqBDQjJRrNYPKMovSC0qyUwttgMAUEsDBBQA" +
207
+ "AAAIAAAAAADWknwRDAEAAFoBAAARAAAAZG9jUHJvcHMvY29yZS54bWyzsa/IzVEoSy0qzszPs1Uy1DNQUkjNS85PycxLt1UK" +
208
+ "DXHTtVBSKC5JzEtJzMnPS7VVqkwtVrK34+WySS6wSs4vSg0oyi9ILSrJTC1WqMjNySu2Si6wVcooKSmw0tcvTs5IzU0s1ssv" +
209
+ "SM2ryM1Jyy/KTSwp1ssvStcvSEzOTkxP1TcyMDDTz00tSUxJLEnUT84vStUtKIKZqKRQATYyJdlWCWpkQWlRjl4+0ICUZP3U" +
210
+ "nNTc1LySYn1DPUN9JQWY2pLUotxiWyUsGkpSgTL6SnCVuZkllQWptkpYlKYkQyT1laCqK4ozbZWgCsvLy/XKjfVA/jAyMDDU" +
211
+ "j/D1CU4GeVU3M6+4JDEvOVVJ3w4AUEsDBBQAAAAIAAAAAADHdcmNlwMAAJ0IAAATAAAAW0NvbnRlbnRfVHlwZXNdLnhtbLOx" +
212
+ "r8jNUShLLSrOzM+zVTLUM1BSSM1Lzk/JzEu3VQoNcdO1UFIoLknMS0nMyc9LtVWqTC1Wsrfj5bIJqSxILVaoyM3JK7ZVyigp" +
213
+ "KbDS1y9OzkjNTSzWyy9IzavIzUnLL8pNLCnWyy9K1y9ITM5OTE/VNzIwMNNPzs8rSc0r0S2pBJqhpFABMsSqojjFVglqUHl5" +
214
+ "uV65sR5Io5GBgaF+hK9PcDLIbCUFmOJMWyVCinUz84pLEvOSU5XsbFxS0xJLc0oUXCtKUvOKM0GercjNUVJwzgc7JaSyINVW" +
215
+ "KbGgICczObEkMz9PvyI3R0nfzgaLvqTMPCUFnPrK8lL0cot1UyuSU3P0ijNSU0v0kjLzEosq9XITk4vyXfMSk3JSU/RyEzPz" +
216
+ "lPSxml+Wm6OE210g8/NRwlc3Py0tMzk1JT+5NDc1r0SvLDfHpSixPDMvXUkfqwUpiSWJSgp4fYDfhtz8lNQc7ZREoDH6WG1I" +
217
+ "yi1QUkCxIDM3MT1VPym3QEkfq46CvHQlBSw6CvLSlbD7Ij0zTUkBi470zDQlfax2pOamKWHTUaGbmpumhF1PeW6aEnY95blp" +
218
+ "Stj1ZBWkK2HzS1ZBaroSds9kFQClSNRTkpmmhM1pJZlpaUrYXQbUkqZEop6ClDQlVC2JBQU5mcmJJZn5efoFKWlK+nY2Lqlp" +
219
+ "iaU5JQquFSWpecWZ+Xm2SkWpOcVKCigRhKyxLC9FDy2VFSSCywi9otScxJLM/LzijMyCYu2K3BwlYEb0L0stKspMSVUISCwq" +
220
+ "8UvMTbVV0q/I0S/PL8pOys/P1qvIzVGiJNcUFxSlJqYUZwAzbG6OHiTj5gIzqXYFQfuLM1JTS4r1izOAlKFeRW6OEvUcUp5f" +
221
+ "lA02X7uCJHcY6VXk5ijR3x0lGam5qfolINJQj9KgKMkAGqZdkZujpG9n41+WWlSUmZKqEJBYVOKXmJtqq6RfkaNfXFKZk1qs" +
222
+ "V5Gbo6TgnJ9XkppXElJZkGqrlFhQkJOZnFiSmZ+nX5aXopdfkJpXkZuTll+Um1hSrJuflpaZnJqSn1yam5pXoldcUJSamFKc" +
223
+ "kZpakpujV1wCMlQbT9JLyU8OKMovKNZPzi9K1avIzVEiyXZYUk/OL0rVLSjKL0gtKslMLSbKxsSCAr2K3BwlkixE825qBTCf" +
224
+ "pqSm6BYQZTcwnHNTSxJTEksS9Spyc5QosRotpDNSU0t8UyFma1fk5ijp29noh1QWpBbbAQBQSwECAAAUAAAACAAAAAAA8WE8" +
225
+ "J24BAABCAwAAGgAAAAAAAAAAAAAAAAAAAAAAeGwvX3JlbHMvd29ya2Jvb2sueG1sLnJlbHNQSwECAAAUAAAACAAAAAAAMA+I" +
226
+ "axUMAADeHQAAEwAAAAAAAAAAAAAAAACmAQAAeGwvdGhlbWUvdGhlbWUxLnhtbFBLAQIAABQAAAAIAAAAAABypxDXRQMAAK8E" +
227
+ "AAANAAAAAAAAAAAAAAAAAOwNAAB4bC9zdHlsZXMueG1sUEsBAgAAFAAAAAgAAAAAACNPb/dOAgAAigMAABgAAAAAAAAAAAAA" +
228
+ "AAAAXBEAAHhsL3dvcmtzaGVldHMvc2hlZXQxLnhtbFBLAQIAABQAAAAIAAAAAABewLRe4wEAAIkCAAAYAAAAAAAAAAAAAAAA" +
229
+ "AOATAAB4bC93b3Jrc2hlZXRzL3NoZWV0Mi54bWxQSwECAAAUAAAACAAAAAAAYIAAgYACAACIAwAADwAAAAAAAAAAAAAAAAD5" +
230
+ "FQAAeGwvbWV0YWRhdGEueG1sUEsBAgAAFAAAAAgAAAAAAAXfb4snAQAAdAEAAA8AAAAAAAAAAAAAAAAAphgAAHhsL3dvcmti" +
231
+ "b29rLnhtbFBLAQIAABQAAAAIAAAAAABKahH5VQEAAEwCAAALAAAAAAAAAAAAAAAAAPoZAABfcmVscy8ucmVsc1BLAQIAABQA" +
232
+ "AAAIAAAAAAD/k6M7lAEAAFECAAAQAAAAAAAAAAAAAAAAAHgbAABkb2NQcm9wcy9hcHAueG1sUEsBAgAAFAAAAAgAAAAAANaS" +
233
+ "fBEMAQAAWgEAABEAAAAAAAAAAAAAAAAAOh0AAGRvY1Byb3BzL2NvcmUueG1sUEsBAgAAFAAAAAgAAAAAAMd1yY2XAwAAnQgA" +
234
+ "ABMAAAAAAAAAAAAAAAAAdR4AAFtDb250ZW50X1R5cGVzXS54bWxQSwUGAAAAAAsACwDBAgAAPSIAAAAA";
235
+
236
+ /** The same files as data URIs, ready to hand to `FileViewer` as a `url` source. */
237
+ export const SAMPLE_DOCX_DATA_URI = `data:application/vnd.openxmlformats-officedocument.wordprocessingml.document;base64,${SAMPLE_DOCX_BASE64}`;
238
+ export const SAMPLE_PPTX_DATA_URI = `data:application/vnd.openxmlformats-officedocument.presentationml.presentation;base64,${SAMPLE_PPTX_BASE64}`;
239
+ export const SAMPLE_XLSX_DATA_URI = `data:application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;base64,${SAMPLE_XLSX_BASE64}`;