├── .editorconfig ├── .eslintignore ├── .eslintrc ├── .github └── release.yml ├── .gitignore ├── .npmrc ├── Book1.xlsx ├── LICENSE ├── README.md ├── SampleData.xlsx ├── docs └── screen01.png ├── esbuild.config.mjs ├── main2.css ├── manifest-beta.json ├── manifest.json ├── officeTheme.xml ├── package-lock.json ├── package.json ├── spreadsheetData.json ├── src ├── Globals.d.ts ├── SettingTab.ts ├── Settings.ts ├── Views │ ├── SheetView.ts │ ├── save.svg │ └── spreadSheetWrapper.ts ├── main.ts └── utils │ ├── excelColors.ts │ ├── excelConverter.ts │ └── xlsxpread.js ├── styles.scss ├── tsconfig.json ├── version-bump.mjs ├── versions.json └── wb.json /.editorconfig: -------------------------------------------------------------------------------- 1 | # top-most EditorConfig file 2 | root = true 3 | 4 | [*] 5 | charset = utf-8 6 | end_of_line = lf 7 | insert_final_newline = true 8 | indent_style = space 9 | indent_size = 4 10 | tab_width = 4 11 | -------------------------------------------------------------------------------- /.eslintignore: -------------------------------------------------------------------------------- 1 | npm node_modules 2 | build -------------------------------------------------------------------------------- /.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "root": true, 3 | "parser": "@typescript-eslint/parser", 4 | "env": { "node": true }, 5 | "plugins": [ 6 | "@typescript-eslint" 7 | ], 8 | "extends": [ 9 | "eslint:recommended", 10 | "plugin:@typescript-eslint/eslint-recommended", 11 | "plugin:@typescript-eslint/recommended" 12 | ], 13 | "parserOptions": { 14 | "sourceType": "module" 15 | }, 16 | "rules": { 17 | "no-unused-vars": "off", 18 | "@typescript-eslint/no-unused-vars": ["error", { "args": "none" }], 19 | "@typescript-eslint/ban-ts-comment": "off", 20 | "no-prototype-builtins": "off", 21 | "@typescript-eslint/no-empty-function": "off" 22 | } 23 | } -------------------------------------------------------------------------------- /.github/release.yml: -------------------------------------------------------------------------------- 1 | name: Release Obsidian plugin 2 | 3 | on: 4 | push: 5 | tags: 6 | - "*" 7 | 8 | jobs: 9 | build: 10 | runs-on: ubuntu-latest 11 | 12 | steps: 13 | - uses: actions/checkout@v3 14 | 15 | - name: Use Node.js 16 | uses: actions/setup-node@v3 17 | with: 18 | node-version: "18.x" 19 | 20 | - name: Build plugin 21 | run: | 22 | npm install 23 | npm run build 24 | 25 | - name: Create release 26 | env: 27 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 28 | run: | 29 | tag="${GITHUB_REF#refs/tags/}" 30 | 31 | gh release create "$tag" \ 32 | --title="$tag" \ 33 | --draft \ 34 | main.js manifest.json styles.css 35 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # vscode 2 | .vscode 3 | 4 | # Intellij 5 | *.iml 6 | .idea 7 | 8 | # npm 9 | node_modules 10 | 11 | # Don't include the compiled main.js file in the repo. 12 | # They should be uploaded to GitHub releases instead. 13 | main.js 14 | styles.css 15 | 16 | # Exclude sourcemaps 17 | *.map 18 | 19 | # obsidian 20 | data.json 21 | 22 | # Exclude macOS Finder (System Explorer) View States 23 | .DS_Store 24 | -------------------------------------------------------------------------------- /.npmrc: -------------------------------------------------------------------------------- 1 | tag-version-prefix="" -------------------------------------------------------------------------------- /Book1.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Canna71/obsidian-sheets/4f33d6c741fb0ab0dfbd877586dc525c7c3c8518/Book1.xlsx -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) [2023] [Gabriele Cannata] 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Obsidian Sheets 2 | 3 | ![](docs/screen01.png) 4 | 5 | This plugin enables to work with tabular data directly in Obsidian: either storing data in the note itself, or on an external Excel or CSV file. 6 | The following files are supported: 7 | - XLSX 8 | - XLS 9 | - CSV 10 | 11 | 12 | ## Code Block Parameters 13 | 14 | In order to create a sheet it is enough to create a code block with the `sheet` name 15 | 16 | ~~~markdown 17 | ```sheet 18 | 19 | ``` 20 | ~~~ 21 | 22 | Following is the complete list of properties with their default values: 23 | 24 | ~~~YAML 25 | ```sheet 26 | filename: 27 | enableSave: 28 | autoSave: 29 | height: 540 30 | width: "auto" 31 | rows: 100 32 | cols: 26 33 | fontSize: 10 34 | cellHeight: 25 35 | cellWidth: 100 36 | ``` 37 | ~~~ 38 | 39 | 40 | If `filename` is provided, data is loaded from that file, if already existing. Otherwise it will be created upon save. 41 | If `filename` is not provided, data will be stored in the code block itself. 42 | 43 | Note that by default saving data to external files is disabled because - in general - there will be loss of information. This could be enabled at vault-level via the settings, or code-block level by specifying `enableSave: true` in the code block. 44 | When saving to file, by default it will also autosave after each modification. When saving to the code block in order to save one must click the save icon in the top left. 45 | 46 | ## Supported Formats 47 | 48 | When saving to code block, all formatting and changes done to the sheet are perserved. 49 | When saving to `XLSX` most formatting and data will be saved and read back. Note however that when reading an existing `XLSX` file, only a subset of functionality will be supported. 50 | Support of `XLS` is limited to data and cell merges 51 | CSV can, of course, only store data. 52 | 53 | 54 | ## Attributions 55 | 56 | This plugin uses the following libraries: 57 | 58 | https://github.com/SheetJS 59 | 60 | https://github.com/myliang/x-spreadsheet (forked here: https://github.com/Canna71/x-spreadsheet) 61 | 62 | https://github.com/exceljs/exceljs 63 | -------------------------------------------------------------------------------- /SampleData.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Canna71/obsidian-sheets/4f33d6c741fb0ab0dfbd877586dc525c7c3c8518/SampleData.xlsx -------------------------------------------------------------------------------- /docs/screen01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Canna71/obsidian-sheets/4f33d6c741fb0ab0dfbd877586dc525c7c3c8518/docs/screen01.png -------------------------------------------------------------------------------- /esbuild.config.mjs: -------------------------------------------------------------------------------- 1 | import esbuild from "esbuild"; 2 | import process from "process"; 3 | import builtins from 'builtin-modules' 4 | import {sassPlugin} from 'esbuild-sass-plugin' 5 | // import svgrPlugin from 'esbuild-plugin-svgr'; 6 | import { lessLoader } from 'esbuild-plugin-less'; 7 | // eslint-disable-next-line @typescript-eslint/no-var-requires 8 | // import * as path from 'path' 9 | import alias from 'esbuild-plugin-alias'; 10 | import path from 'path'; 11 | import { fileURLToPath } from 'url'; 12 | 13 | const __filename = fileURLToPath(import.meta.url); 14 | const __dirname = path.dirname(__filename); 15 | 16 | const banner = 17 | `/* 18 | THIS IS A GENERATED/BUNDLED FILE BY ESBUILD 19 | if you want to view the source, please visit the github repository of this plugin 20 | */ 21 | `; 22 | 23 | const prod = (process.argv[2] === 'production'); 24 | 25 | esbuild.build({ 26 | banner: { 27 | js: banner, 28 | }, 29 | entryPoints: ['src/main.ts'], 30 | bundle: true, 31 | minify: prod, 32 | external: [ 33 | 'obsidian', 34 | 'electron', 35 | '@codemirror/autocomplete', 36 | '@codemirror/collab', 37 | '@codemirror/commands', 38 | '@codemirror/language', 39 | '@codemirror/lint', 40 | '@codemirror/search', 41 | '@codemirror/state', 42 | '@codemirror/view', 43 | '@lezer/common', 44 | '@lezer/highlight', 45 | '@lezer/lr', 46 | ...builtins], 47 | format: 'cjs', 48 | watch: !prod, 49 | target: 'es2016', 50 | logLevel: "info", 51 | sourcemap: prod ? false : 'inline', 52 | treeShaking: true, 53 | outfile: 'main.js', 54 | // https://github.com/glromeo/esbuild-sass-plugin#--rewriting-relative-urls 55 | plugins: [ 56 | lessLoader({}), 57 | alias({ 58 | 'x-data-spreadsheet': path.resolve(__dirname,'node_modules/x-data-spreadsheet/dist/xspreadsheet.js') 59 | }), 60 | ], 61 | loader: { 62 | '.ts': 'ts', 63 | '.svg': 'text', 64 | } 65 | }).catch(() => process.exit(1)); 66 | 67 | esbuild.build({ 68 | entryPoints: ['styles.scss'], 69 | outfile: "styles.css", 70 | // outdir: "/", 71 | watch: !prod, 72 | plugins: [sassPlugin()] 73 | }).catch(() => process.exit(1)); 74 | // node_modules/x-data-spreadsheet/src/index.less 75 | 76 | /* 77 | 78 | { 79 | precompile(source, pathname) { 80 | const basedir = path.dirname(pathname) 81 | return source.replace(/(url\(['"]?)(\.\.?\/)([^'")]+['"]?\))/g, `$1${basedir}/$2$3`) 82 | } 83 | } 84 | */ 85 | -------------------------------------------------------------------------------- /main2.css: -------------------------------------------------------------------------------- 1 | /* node_modules/x-data-spreadsheet/src/index.less */ 2 | body { 3 | margin: 0; 4 | } 5 | .x-spreadsheet { 6 | font-size: 13px; 7 | line-height: normal; 8 | user-select: none; 9 | -moz-user-select: none; 10 | font-family: 11 | "Lato", 12 | "Source Sans Pro", 13 | Roboto, 14 | Helvetica, 15 | Arial, 16 | sans-serif; 17 | box-sizing: content-box; 18 | background: #fff; 19 | -webkit-font-smoothing: antialiased; 20 | } 21 | .x-spreadsheet textarea { 22 | font: 23 | 400 13px Arial, 24 | "Lato", 25 | "Source Sans Pro", 26 | Roboto, 27 | Helvetica, 28 | sans-serif; 29 | } 30 | .x-spreadsheet-sheet { 31 | position: relative; 32 | overflow: hidden; 33 | } 34 | .x-spreadsheet-table { 35 | vertical-align: bottom; 36 | } 37 | .x-spreadsheet-tooltip { 38 | font-family: inherit; 39 | position: absolute; 40 | padding: 5px 10px; 41 | color: #fff; 42 | border-radius: 1px; 43 | background: #000000; 44 | font-size: 12px; 45 | z-index: 201; 46 | } 47 | .x-spreadsheet-tooltip:before { 48 | pointer-events: none; 49 | position: absolute; 50 | left: calc(50% - 4px); 51 | top: -4px; 52 | content: ""; 53 | width: 8px; 54 | height: 8px; 55 | background: inherit; 56 | -webkit-transform: rotate(45deg); 57 | transform: rotate(45deg); 58 | z-index: 1; 59 | box-shadow: 1px 1px 3px -1px rgba(0, 0, 0, 0.3); 60 | } 61 | .x-spreadsheet-color-palette { 62 | padding: 5px; 63 | } 64 | .x-spreadsheet-color-palette table { 65 | margin: 0; 66 | padding: 0; 67 | border-collapse: separate; 68 | border-spacing: 2; 69 | background: #fff; 70 | } 71 | .x-spreadsheet-color-palette table td { 72 | margin: 0; 73 | cursor: pointer; 74 | border: 1px solid transparent; 75 | } 76 | .x-spreadsheet-color-palette table td:hover { 77 | border-color: #ddd; 78 | } 79 | .x-spreadsheet-color-palette table td .x-spreadsheet-color-palette-cell { 80 | width: 16px; 81 | height: 16px; 82 | } 83 | .x-spreadsheet-border-palette { 84 | padding: 6px; 85 | } 86 | .x-spreadsheet-border-palette table { 87 | margin: 0; 88 | padding: 0; 89 | border-collapse: separate; 90 | border-spacing: 0; 91 | background: #fff; 92 | table-layout: fixed; 93 | } 94 | .x-spreadsheet-border-palette table td { 95 | margin: 0; 96 | } 97 | .x-spreadsheet-border-palette .x-spreadsheet-border-palette-left { 98 | border-right: 1px solid #eee; 99 | padding-right: 6px; 100 | } 101 | .x-spreadsheet-border-palette .x-spreadsheet-border-palette-left .x-spreadsheet-border-palette-cell { 102 | width: 30px; 103 | height: 30px; 104 | cursor: pointer; 105 | text-align: center; 106 | } 107 | .x-spreadsheet-border-palette .x-spreadsheet-border-palette-left .x-spreadsheet-border-palette-cell .x-spreadsheet-icon-img { 108 | opacity: 0.8; 109 | } 110 | .x-spreadsheet-border-palette .x-spreadsheet-border-palette-left .x-spreadsheet-border-palette-cell:hover { 111 | background-color: #eee; 112 | } 113 | .x-spreadsheet-border-palette .x-spreadsheet-border-palette-right { 114 | padding-left: 6px; 115 | } 116 | .x-spreadsheet-border-palette .x-spreadsheet-border-palette-right .x-spreadsheet-toolbar-btn { 117 | margin-top: 0; 118 | margin-bottom: 3px; 119 | } 120 | .x-spreadsheet-border-palette .x-spreadsheet-border-palette-right .x-spreadsheet-line-type { 121 | position: relative; 122 | left: 0; 123 | top: -3px; 124 | } 125 | .x-spreadsheet-dropdown { 126 | position: relative; 127 | } 128 | .x-spreadsheet-dropdown .x-spreadsheet-dropdown-content { 129 | position: absolute; 130 | z-index: 200; 131 | background: #fff; 132 | box-shadow: 1px 2px 5px 2px rgba(51, 51, 51, 0.15); 133 | } 134 | .x-spreadsheet-dropdown.bottom-left .x-spreadsheet-dropdown-content { 135 | top: calc(100% + 5px); 136 | left: 0; 137 | } 138 | .x-spreadsheet-dropdown.bottom-right .x-spreadsheet-dropdown-content { 139 | top: calc(100% + 5px); 140 | right: 0; 141 | } 142 | .x-spreadsheet-dropdown.top-left .x-spreadsheet-dropdown-content { 143 | bottom: calc(100% + 5px); 144 | left: 0; 145 | } 146 | .x-spreadsheet-dropdown.top-right .x-spreadsheet-dropdown-content { 147 | bottom: calc(100% + 5px); 148 | right: 0; 149 | } 150 | .x-spreadsheet-dropdown .x-spreadsheet-dropdown-title { 151 | padding: 0 5px; 152 | display: inline-block; 153 | } 154 | .x-spreadsheet-dropdown .x-spreadsheet-dropdown-header .x-spreadsheet-icon.arrow-left { 155 | margin-left: 4px; 156 | } 157 | .x-spreadsheet-dropdown .x-spreadsheet-dropdown-header .x-spreadsheet-icon.arrow-right { 158 | width: 10px; 159 | margin-right: 4px; 160 | } 161 | .x-spreadsheet-dropdown .x-spreadsheet-dropdown-header .x-spreadsheet-icon.arrow-right .arrow-down { 162 | left: -130px; 163 | } 164 | .x-spreadsheet-resizer { 165 | position: absolute; 166 | z-index: 11; 167 | } 168 | .x-spreadsheet-resizer .x-spreadsheet-resizer-hover { 169 | background-color: rgba(75, 137, 255, 0.25); 170 | } 171 | .x-spreadsheet-resizer .x-spreadsheet-resizer-line { 172 | position: absolute; 173 | } 174 | .x-spreadsheet-resizer.horizontal { 175 | cursor: row-resize; 176 | } 177 | .x-spreadsheet-resizer.horizontal .x-spreadsheet-resizer-line { 178 | border-bottom: 2px dashed #4b89ff; 179 | left: 0; 180 | bottom: 0; 181 | } 182 | .x-spreadsheet-resizer.vertical { 183 | cursor: col-resize; 184 | } 185 | .x-spreadsheet-resizer.vertical .x-spreadsheet-resizer-line { 186 | border-right: 2px dashed #4b89ff; 187 | top: 0; 188 | right: 0; 189 | } 190 | .x-spreadsheet-scrollbar { 191 | position: absolute; 192 | bottom: 0; 193 | right: 0; 194 | background-color: #f4f5f8; 195 | opacity: 0.9; 196 | z-index: 12; 197 | } 198 | .x-spreadsheet-scrollbar.horizontal { 199 | right: 15px; 200 | overflow-x: scroll; 201 | overflow-y: hidden; 202 | } 203 | .x-spreadsheet-scrollbar.horizontal > div { 204 | height: 1px; 205 | background: #ddd; 206 | } 207 | .x-spreadsheet-scrollbar.vertical { 208 | bottom: 15px; 209 | overflow-x: hidden; 210 | overflow-y: scroll; 211 | } 212 | .x-spreadsheet-scrollbar.vertical > div { 213 | width: 1px; 214 | background: #ddd; 215 | } 216 | .x-spreadsheet-overlayer { 217 | position: absolute; 218 | left: 0; 219 | top: 0; 220 | z-index: 10; 221 | } 222 | .x-spreadsheet-overlayer .x-spreadsheet-overlayer-content { 223 | position: absolute; 224 | overflow: hidden; 225 | pointer-events: none; 226 | width: 100%; 227 | height: 100%; 228 | } 229 | .x-spreadsheet-editor, 230 | .x-spreadsheet-selector { 231 | box-sizing: content-box; 232 | position: absolute; 233 | overflow: hidden; 234 | pointer-events: none; 235 | top: 0; 236 | left: 0; 237 | width: 100%; 238 | height: 100%; 239 | } 240 | .x-spreadsheet-selector .hide-input { 241 | position: absolute; 242 | z-index: 0; 243 | } 244 | .x-spreadsheet-selector .hide-input input { 245 | padding: 0; 246 | width: 0; 247 | border: none !important; 248 | } 249 | .x-spreadsheet-selector .x-spreadsheet-selector-area { 250 | position: absolute; 251 | border: 2px solid #4b89ff; 252 | background: rgba(75, 137, 255, 0.1); 253 | z-index: 5; 254 | } 255 | .x-spreadsheet-selector .x-spreadsheet-selector-clipboard, 256 | .x-spreadsheet-selector .x-spreadsheet-selector-autofill { 257 | position: absolute; 258 | background: transparent; 259 | z-index: 100; 260 | } 261 | .x-spreadsheet-selector .x-spreadsheet-selector-clipboard { 262 | border: 2px dashed #4b89ff; 263 | } 264 | .x-spreadsheet-selector .x-spreadsheet-selector-autofill { 265 | border: 1px dashed rgba(0, 0, 0, 0.45); 266 | } 267 | .x-spreadsheet-selector .x-spreadsheet-selector-corner { 268 | pointer-events: auto; 269 | position: absolute; 270 | cursor: crosshair; 271 | font-size: 0; 272 | height: 5px; 273 | width: 5px; 274 | right: -5px; 275 | bottom: -5px; 276 | border: 2px solid #ffffff; 277 | background: #4b89ff; 278 | } 279 | .x-spreadsheet-editor { 280 | z-index: 20; 281 | } 282 | .x-spreadsheet-editor .x-spreadsheet-editor-area { 283 | position: absolute; 284 | text-align: left; 285 | border: 2px solid #4b89ff; 286 | line-height: 0; 287 | z-index: 100; 288 | pointer-events: auto; 289 | } 290 | .x-spreadsheet-editor .x-spreadsheet-editor-area textarea { 291 | box-sizing: content-box; 292 | border: none; 293 | padding: 0 3px; 294 | outline: none; 295 | resize: none; 296 | text-align: start; 297 | overflow-y: hidden; 298 | font: 299 | 400 13px Arial, 300 | "Lato", 301 | "Source Sans Pro", 302 | Roboto, 303 | Helvetica, 304 | sans-serif; 305 | color: inherit; 306 | white-space: normal; 307 | word-wrap: break-word; 308 | line-height: 22px; 309 | margin: 0; 310 | } 311 | .x-spreadsheet-editor .x-spreadsheet-editor-area .textline { 312 | overflow: hidden; 313 | visibility: hidden; 314 | position: fixed; 315 | top: 0; 316 | left: 0; 317 | } 318 | .x-spreadsheet-item { 319 | user-select: none; 320 | background: 0; 321 | border: 1px solid transparent; 322 | outline: none; 323 | height: 26px; 324 | color: rgba(0, 0, 0, 0.9); 325 | line-height: 26px; 326 | list-style: none; 327 | padding: 2px 10px; 328 | cursor: default; 329 | text-align: left; 330 | overflow: hidden; 331 | } 332 | .x-spreadsheet-item.disabled { 333 | pointer-events: none; 334 | opacity: 0.5; 335 | } 336 | .x-spreadsheet-item:hover, 337 | .x-spreadsheet-item.active { 338 | background: rgba(0, 0, 0, 0.05); 339 | } 340 | .x-spreadsheet-item.divider { 341 | height: 0; 342 | padding: 0; 343 | margin: 5px 0; 344 | border: none; 345 | border-bottom: 1px solid rgba(0, 0, 0, 0.1); 346 | } 347 | .x-spreadsheet-item .label { 348 | float: right; 349 | opacity: 0.65; 350 | font-size: 1em; 351 | } 352 | .x-spreadsheet-item.state, 353 | .x-spreadsheet-header.state { 354 | padding-left: 35px !important; 355 | position: relative; 356 | } 357 | .x-spreadsheet-item.state:before, 358 | .x-spreadsheet-header.state:before { 359 | content: ""; 360 | position: absolute; 361 | width: 10px; 362 | height: 10px; 363 | left: 12px; 364 | top: calc(50% - 5px); 365 | background: rgba(0, 0, 0, 0.08); 366 | border-radius: 2px; 367 | } 368 | .x-spreadsheet-item.state.checked:before, 369 | .x-spreadsheet-header.state.checked:before { 370 | background: #4b89ff; 371 | } 372 | .x-spreadsheet-checkbox { 373 | position: relative; 374 | display: inline-block; 375 | backface-visibility: hidden; 376 | outline: 0; 377 | vertical-align: baseline; 378 | font-style: normal; 379 | font-size: 1rem; 380 | line-height: 1em; 381 | } 382 | .x-spreadsheet-checkbox > input { 383 | position: absolute; 384 | top: 0; 385 | left: 0; 386 | opacity: 0 !important; 387 | outline: 0; 388 | z-index: -1; 389 | } 390 | .x-spreadsheet-suggest, 391 | .x-spreadsheet-contextmenu, 392 | .x-spreadsheet-sort-filter { 393 | position: absolute; 394 | box-shadow: 1px 2px 5px 2px rgba(51, 51, 51, 0.15); 395 | background: #fff; 396 | z-index: 100; 397 | width: 260px; 398 | pointer-events: auto; 399 | overflow: auto; 400 | } 401 | .x-spreadsheet-suggest { 402 | width: 200px; 403 | } 404 | .x-spreadsheet-filter { 405 | border: 1px solid #e9e9e9; 406 | font-size: 12px; 407 | margin: 10px; 408 | } 409 | .x-spreadsheet-filter .x-spreadsheet-header { 410 | padding: 0.5em 0.75em; 411 | background: #f8f8f9; 412 | border-bottom: 1px solid #e9e9e9; 413 | border-left: 1px solid transparent; 414 | } 415 | .x-spreadsheet-filter .x-spreadsheet-body { 416 | height: 200px; 417 | overflow-y: auto; 418 | } 419 | .x-spreadsheet-filter .x-spreadsheet-body .x-spreadsheet-item { 420 | height: 20px; 421 | line-height: 20px; 422 | } 423 | .x-spreadsheet-sort-filter .x-spreadsheet-buttons { 424 | margin: 10px; 425 | } 426 | .x-spreadsheet-toolbar, 427 | .x-spreadsheet-bottombar { 428 | height: 40px; 429 | padding: 0 30px; 430 | text-align: left; 431 | background: #f5f6f7; 432 | display: flex; 433 | } 434 | .x-spreadsheet-bottombar { 435 | position: relative; 436 | border-top: 1px solid #e0e2e4; 437 | } 438 | .x-spreadsheet-bottombar .x-spreadsheet-menu > li { 439 | line-height: 40px; 440 | height: 40px; 441 | padding-top: 0; 442 | padding-bottom: 0; 443 | vertical-align: middle; 444 | border-right: 1px solid #e8eaed; 445 | } 446 | .x-spreadsheet-menu { 447 | list-style: none; 448 | margin: 0; 449 | padding: 0; 450 | user-select: none; 451 | } 452 | .x-spreadsheet-menu > li { 453 | float: left; 454 | line-height: 1.25em; 455 | padding: 0.785em 1em; 456 | margin: 0; 457 | vertical-align: middle; 458 | text-align: left; 459 | font-weight: 400; 460 | color: #80868b; 461 | white-space: nowrap; 462 | cursor: pointer; 463 | transition: all 0.3s; 464 | font-weight: bold; 465 | } 466 | .x-spreadsheet-menu > li.active { 467 | background-color: #fff; 468 | color: rgba(0, 0, 0, 0.65); 469 | } 470 | .x-spreadsheet-menu > li .x-spreadsheet-icon { 471 | margin: 0 6px; 472 | } 473 | .x-spreadsheet-menu > li .x-spreadsheet-icon .x-spreadsheet-icon-img:hover { 474 | opacity: 0.85; 475 | } 476 | .x-spreadsheet-menu > li .x-spreadsheet-dropdown { 477 | display: inline-block; 478 | } 479 | .x-spreadsheet-toolbar { 480 | border-bottom: 1px solid #e0e2e4; 481 | } 482 | .x-spreadsheet-toolbar .x-spreadsheet-toolbar-btns { 483 | display: inline-flex; 484 | } 485 | .x-spreadsheet-toolbar .x-spreadsheet-toolbar-more { 486 | padding: 0 6px 6px; 487 | text-align: left; 488 | } 489 | .x-spreadsheet-toolbar .x-spreadsheet-toolbar-more .x-spreadsheet-toolbar-divider { 490 | margin-top: 0; 491 | } 492 | .x-spreadsheet-toolbar .x-spreadsheet-toolbar-btn { 493 | flex: 0 0 auto; 494 | display: inline-block; 495 | border: 1px solid transparent; 496 | height: 26px; 497 | line-height: 26px; 498 | min-width: 26px; 499 | margin: 6px 1px 0; 500 | padding: 0; 501 | text-align: center; 502 | border-radius: 2px; 503 | } 504 | .x-spreadsheet-toolbar .x-spreadsheet-toolbar-btn.disabled { 505 | pointer-events: none; 506 | opacity: 0.5; 507 | } 508 | .x-spreadsheet-toolbar .x-spreadsheet-toolbar-btn:hover, 509 | .x-spreadsheet-toolbar .x-spreadsheet-toolbar-btn.active { 510 | background: rgba(0, 0, 0, 0.08); 511 | } 512 | .x-spreadsheet-toolbar-divider { 513 | display: inline-block; 514 | border-right: 1px solid #e0e2e4; 515 | width: 0; 516 | vertical-align: middle; 517 | height: 18px; 518 | margin: 12px 3px 0; 519 | } 520 | .x-spreadsheet-print { 521 | position: absolute; 522 | left: 0; 523 | top: 0; 524 | z-index: 100; 525 | width: 100%; 526 | height: 100%; 527 | display: flex; 528 | flex-direction: column; 529 | } 530 | .x-spreadsheet-print-bar { 531 | background: #424242; 532 | height: 60px; 533 | line-height: 60px; 534 | padding: 0 30px; 535 | } 536 | .x-spreadsheet-print-bar .-title { 537 | color: #fff; 538 | font-weight: bold; 539 | font-size: 1.2em; 540 | float: left; 541 | } 542 | .x-spreadsheet-print-bar .-right { 543 | float: right; 544 | margin-top: 12px; 545 | } 546 | .x-spreadsheet-print-content { 547 | display: flex; 548 | flex: auto; 549 | flex-direction: row; 550 | background: #d0d0d0; 551 | height: calc(100% - 60px); 552 | } 553 | .x-spreadsheet-print-content .-sider { 554 | flex: 0 0 300px; 555 | width: 300px; 556 | border-left: 2px solid #ccc; 557 | background: #fff; 558 | } 559 | .x-spreadsheet-print-content .-content { 560 | flex: auto; 561 | overflow-x: auto; 562 | overflow-y: scroll; 563 | height: 100%; 564 | } 565 | .x-spreadsheet-canvas-card-wraper { 566 | margin: 40px 20px; 567 | } 568 | .x-spreadsheet-canvas-card { 569 | background: #fff; 570 | margin: auto; 571 | page-break-before: auto; 572 | page-break-after: always; 573 | box-shadow: 574 | 0 8px 10px 1px rgba(0, 0, 0, 0.14), 575 | 0 3px 14px 3px rgba(0, 0, 0, 0.12), 576 | 0 4px 5px 0 rgba(0, 0, 0, 0.2); 577 | } 578 | .x-spreadsheet-calendar { 579 | color: rgba(0, 0, 0, 0.65); 580 | background: #ffffff; 581 | user-select: none; 582 | } 583 | .x-spreadsheet-calendar .calendar-header { 584 | font-weight: 700; 585 | line-height: 30px; 586 | text-align: center; 587 | width: 100%; 588 | float: left; 589 | background: #f9fafb; 590 | } 591 | .x-spreadsheet-calendar .calendar-header .calendar-header-left { 592 | padding-left: 5px; 593 | float: left; 594 | } 595 | .x-spreadsheet-calendar .calendar-header .calendar-header-right { 596 | float: right; 597 | } 598 | .x-spreadsheet-calendar .calendar-header .calendar-header-right a { 599 | padding: 3px 0; 600 | margin-right: 2px; 601 | border-radius: 2px; 602 | } 603 | .x-spreadsheet-calendar .calendar-header .calendar-header-right a:hover { 604 | background: rgba(0, 0, 0, 0.08); 605 | } 606 | .x-spreadsheet-calendar .calendar-body { 607 | border-collapse: collapse; 608 | border-spacing: 0; 609 | } 610 | .x-spreadsheet-calendar .calendar-body th, 611 | .x-spreadsheet-calendar .calendar-body td { 612 | width: 100%/7; 613 | min-width: 32px; 614 | text-align: center; 615 | font-weight: 700; 616 | line-height: 30px; 617 | padding: 0; 618 | } 619 | .x-spreadsheet-calendar .calendar-body td > .cell:hover { 620 | background: #ecf6fd; 621 | } 622 | .x-spreadsheet-calendar .calendar-body td > .cell.active, 623 | .x-spreadsheet-calendar .calendar-body td > .cell.active:hover { 624 | background: #ecf6fd; 625 | color: #2185D0; 626 | } 627 | .x-spreadsheet-calendar .calendar-body td > .cell.disabled { 628 | pointer-events: none; 629 | opacity: 0.5; 630 | } 631 | .x-spreadsheet-datepicker { 632 | box-shadow: 2px 2px 5px rgba(0, 0, 0, 0.2); 633 | position: absolute; 634 | left: 0; 635 | top: calc(100% + 5px); 636 | z-index: 10; 637 | width: auto; 638 | } 639 | .x-spreadsheet-buttons { 640 | display: flex; 641 | justify-content: flex-end; 642 | } 643 | .x-spreadsheet-buttons .x-spreadsheet-button { 644 | margin-left: 8px; 645 | } 646 | .x-spreadsheet-button { 647 | display: inline-block; 648 | border-radius: 3px; 649 | line-height: 1em; 650 | min-height: 1em; 651 | white-space: nowrap; 652 | text-align: center; 653 | cursor: pointer; 654 | font-size: 1em; 655 | font-weight: 700; 656 | padding: 0.75em 1em; 657 | color: rgba(0, 0, 0, 0.6); 658 | background: #E0E1E2; 659 | text-decoration: none; 660 | font-family: 661 | "Lato", 662 | "proxima-nova", 663 | "Helvetica Neue", 664 | Arial, 665 | sans-serif; 666 | outline: none; 667 | vertical-align: baseline; 668 | zoom: 1; 669 | user-select: none; 670 | transition: all 0.1s linear; 671 | } 672 | .x-spreadsheet-button.active, 673 | .x-spreadsheet-button:hover { 674 | background-color: #C0C1C2; 675 | color: rgba(0, 0, 0, 0.8); 676 | } 677 | .x-spreadsheet-button.primary { 678 | color: #fff; 679 | background-color: #2185D0; 680 | } 681 | .x-spreadsheet-button.primary:hover, 682 | .x-spreadsheet-button.primary.active { 683 | color: #fff; 684 | background-color: #1678c2; 685 | } 686 | .x-spreadsheet-form-input { 687 | font-size: 1em; 688 | position: relative; 689 | font-weight: 400; 690 | display: inline-flex; 691 | color: rgba(0, 0, 0, 0.87); 692 | } 693 | .x-spreadsheet-form-input input { 694 | z-index: 1; 695 | margin: 0; 696 | max-width: 100%; 697 | flex: 1 0 auto; 698 | outline: 0; 699 | -webkit-tap-highlight-color: rgba(255, 255, 255, 0); 700 | text-align: left; 701 | line-height: 30px; 702 | height: 30px; 703 | padding: 0 8px; 704 | background: #fff; 705 | border: 1px solid #e9e9e9; 706 | border-radius: 3px; 707 | transition: box-shadow 0.1s ease, border-color 0.1s ease; 708 | box-shadow: inset 0 1px 2px hsla(0, 0%, 4%, 0.06); 709 | } 710 | .x-spreadsheet-form-input input:focus { 711 | border-color: #4b89ff; 712 | box-shadow: inset 0 1px 2px rgba(75, 137, 255, 0.2); 713 | } 714 | .x-spreadsheet-form-select { 715 | position: relative; 716 | display: inline-block; 717 | background: #fff; 718 | border: 1px solid #e9e9e9; 719 | border-radius: 2px; 720 | cursor: pointer; 721 | color: rgba(0, 0, 0, 0.87); 722 | user-select: none; 723 | box-shadow: inset 0 1px 2px hsla(0, 0%, 4%, 0.06); 724 | } 725 | .x-spreadsheet-form-select .input-text { 726 | text-overflow: ellipsis; 727 | white-space: nowrap; 728 | min-width: 60px; 729 | width: auto; 730 | height: 30px; 731 | line-height: 30px; 732 | padding: 0 8px; 733 | } 734 | .x-spreadsheet-form-fields { 735 | display: flex; 736 | flex-direction: row; 737 | flex-wrap: wrap; 738 | } 739 | .x-spreadsheet-form-fields .x-spreadsheet-form-field { 740 | flex: 0 1 auto; 741 | } 742 | .x-spreadsheet-form-fields .x-spreadsheet-form-field .label { 743 | display: inline-block; 744 | margin: 0 10px 0 0; 745 | } 746 | .x-spreadsheet-form-field { 747 | display: block; 748 | vertical-align: middle; 749 | margin-left: 10px; 750 | margin-bottom: 10px; 751 | } 752 | .x-spreadsheet-form-field:first-child { 753 | margin-left: 0; 754 | } 755 | .x-spreadsheet-form-field.error .x-spreadsheet-form-select, 756 | .x-spreadsheet-form-field.error input { 757 | border-color: #f04134; 758 | } 759 | .x-spreadsheet-form-field .tip { 760 | color: #f04134; 761 | font-size: 0.9em; 762 | } 763 | .x-spreadsheet-dimmer { 764 | display: none; 765 | position: absolute; 766 | top: 0 !important; 767 | left: 0 !important; 768 | width: 100%; 769 | height: 100%; 770 | text-align: center; 771 | vertical-align: middle; 772 | background-color: rgba(0, 0, 0, 0.6); 773 | opacity: 0; 774 | -webkit-animation-fill-mode: both; 775 | animation-fill-mode: both; 776 | -webkit-animation-duration: 0.5s; 777 | animation-duration: 0.5s; 778 | transition: background-color 0.5s linear; 779 | user-select: none; 780 | z-index: 1000; 781 | } 782 | .x-spreadsheet-dimmer.active { 783 | display: block; 784 | opacity: 1; 785 | } 786 | form fieldset { 787 | border: none; 788 | } 789 | form fieldset label { 790 | display: block; 791 | margin-bottom: 0.5em; 792 | font-size: 1em; 793 | color: #666; 794 | } 795 | form fieldset select { 796 | font-size: 1.1em; 797 | width: 100%; 798 | background-color: #fff; 799 | border: none; 800 | border-bottom: 2px solid #ddd; 801 | padding: 0.5em 0.85em; 802 | border-radius: 2px; 803 | } 804 | .x-spreadsheet-modal, 805 | .x-spreadsheet-toast { 806 | font-size: 13px; 807 | position: fixed; 808 | z-index: 1001; 809 | text-align: left; 810 | line-height: 1.25em; 811 | min-width: 360px; 812 | color: rgba(0, 0, 0, 0.87); 813 | font-family: 814 | "Lato", 815 | "Source Sans Pro", 816 | Roboto, 817 | Helvetica, 818 | Arial, 819 | sans-serif; 820 | border-radius: 4px; 821 | border: 1px solid rgba(0, 0, 0, 0.1); 822 | background-color: #fff; 823 | background-clip: padding-box; 824 | box-shadow: rgba(0, 0, 0, 0.2) 0px 2px 8px; 825 | } 826 | .x-spreadsheet-toast { 827 | background-color: rgba(255, 255, 255, 0.85); 828 | } 829 | .x-spreadsheet-modal-header, 830 | .x-spreadsheet-toast-header { 831 | font-weight: 600; 832 | background-clip: padding-box; 833 | background-color: rgba(255, 255, 255, 0.85); 834 | border-bottom: 1px solid rgba(0, 0, 0, 0.05); 835 | border-radius: 4px 4px 0 0; 836 | } 837 | .x-spreadsheet-modal-header .x-spreadsheet-icon, 838 | .x-spreadsheet-toast-header .x-spreadsheet-icon { 839 | position: absolute; 840 | right: 0.8em; 841 | top: 0.65em; 842 | border-radius: 18px; 843 | } 844 | .x-spreadsheet-modal-header .x-spreadsheet-icon:hover, 845 | .x-spreadsheet-toast-header .x-spreadsheet-icon:hover { 846 | opacity: 1; 847 | background: rgba(0, 0, 0, 0.08); 848 | } 849 | .x-spreadsheet-toast-header { 850 | color: #F2711C; 851 | } 852 | .x-spreadsheet-modal-header { 853 | border-bottom: 1px solid #e0e2e4; 854 | background: rgba(0, 0, 0, 0.08); 855 | font-size: 1.0785em; 856 | } 857 | .x-spreadsheet-modal-header, 858 | .x-spreadsheet-modal-content, 859 | .x-spreadsheet-toast-header, 860 | .x-spreadsheet-toast-content { 861 | padding: 0.75em 1em; 862 | } 863 | @media screen and (min-width: 320px) and (max-width: 480px) { 864 | .x-spreadsheet-toolbar { 865 | display: none; 866 | } 867 | } 868 | .x-spreadsheet-icon { 869 | width: 18px; 870 | height: 18px; 871 | margin: 1px 1px 2px 1px; 872 | text-align: center; 873 | vertical-align: middle; 874 | user-select: none; 875 | overflow: hidden; 876 | position: relative; 877 | display: inline-block; 878 | } 879 | .x-spreadsheet-icon .x-spreadsheet-icon-img { 880 | background-image: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0nMS4wJyBlbmNvZGluZz0nVVRGLTgnPz48IURPQ1RZUEUgc3ZnIFBVQkxJQyAiLS8vVzNDLy9EVEQgU1ZHIDEuMS8vRU4iICJodHRwOi8vd3d3LnczLm9yZy9HcmFwaGljcy9TVkcvMS4xL0RURC9zdmcxMS5kdGQiPjxzdmcgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgdmVyc2lvbj0iMS4xIiB4PSIwIiB5PSIwIiB3aWR0aD0iMjYycHgiIGhlaWdodD0iNzJweCIgdmlld0JveD0iMCAwIDI2MiA3MiIgcHJlc2VydmVBc3BlY3RSYXRpbz0ibm9uZSI+CjxnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMCwwKSI+PHBhdGggZmlsbD0iIzAwMDAwMCIgZmlsbC1ydWxlPSJldmVub2RkIiBkPSJNMTEuNTY1NjM5MSw0LjQzNDM2MDg4IEw5LDcgTDE2LDcgTDE2LDAgTDEzLjA0MTg0MjQsMi45NTgxNTc1OCBDMTEuNTkzNjc4NywxLjczNjM1OTU5IDkuNzIyNjA3NzUsMSA3LjY3OTU1MDgzLDEgQzQuMjIxMjYyNTgsMSAxLjI1NTc1NTk5LDMuMTA5ODQ5MDggMCw2IEwyLDcgQzIuOTM2NTg3NzUsNC42MDk3NDQwNiA1LjEyOTQzNjk3LDMuMDgwMTEyMjkgNy42Nzk1NTA4MywzIEM5LjE0ODgxMjQ3LDMuMDUyODc0NyAxMC40OTk0NzgzLDMuNTc4NjIwNTMgMTEuNTY1NjM5MSw0LjQzNDM2MDg4IFoiIHRyYW5zZm9ybT0ibWF0cml4KC0xIDAgMCAxIDE3IDUpIi8+CjwvZz4KPGcgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgxOCwwKSI+PHBhdGggZmlsbD0iIzAwMDAwMCIgZmlsbC1ydWxlPSJldmVub2RkIiBkPSJNMTEuNTY1NjM5MSw0LjQzNDM2MDg4IEw5LDcgTDE2LDcgTDE2LDAgTDEzLjA0MTg0MjQsMi45NTgxNTc1OCBDMTEuNTkzNjc4NywxLjczNjM1OTU5IDkuNzIyNjA3NzUsMSA3LjY3OTU1MDgzLDEgQzQuMjIxMjYyNTgsMSAxLjI1NTc1NTk5LDMuMTA5ODQ5MDggMCw2IEwyLDcgQzIuOTM2NTg3NzUsNC42MDk3NDQwNiA1LjEyOTQzNjk3LDMuMDgwMTEyMjkgNy42Nzk1NTA4MywzIEM5LjE0ODgxMjQ3LDMuMDUyODc0NyAxMC40OTk0NzgzLDMuNTc4NjIwNTMgMTEuNTY1NjM5MSw0LjQzNDM2MDg4IFoiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDEgNSkiLz4KPC9nPgo8ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHRyYW5zZm9ybT0idHJhbnNsYXRlKDM2LDApIj48cGF0aCBmaWxsPSIjMDAwMDAwIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiIGQ9Ik0xMywxNCBMMywxNCBMMywxMSBMMCwxMSBMMCw2LjAwNTkxOTA1IEMwLDQuODk4MDgwNTUgMC44OTQ1MTM3NTYsNCAxLjk5NDA2MDI4LDQgTDE0LjAwNTkzOTcsNCBDMTUuMTA3MjI4OCw0IDE2LDQuODg2NTU0ODQgMTYsNi4wMDU5MTkwNSBMMTYsMTEgTDEzLDExIEwxMywxNCBaIE01LDkgTDExLDkgTDExLDEyIEw1LDEyIEw1LDkgWiBNMywwIEwxMywwIEwxMywzIEwzLDMgTDMsMCBaIE0xMiw2IEwxNCw2IEwxNCw4IEwxMiw4IEwxMiw2IFoiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDEgMikiLz4KPC9nPgo8ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHRyYW5zZm9ybT0idHJhbnNsYXRlKDU0LDApIj48cGF0aCBmaWxsPSIjMDAwMDAwIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiIGQ9Ik05LDAgTDEsMCBDMC40NSwwIDAsMC40NSAwLDEgTDAsNCBDMCw0LjU1IDAuNDUsNSAxLDUgTDksNSBDOS41NSw1IDEwLDQuNTUgMTAsNCBMMTAsMyBMMTEsMyBMMTEsNiBMNCw2IEw0LDE0IEw2LDE0IEw2LDggTDEzLDggTDEzLDIgTDEwLDIgTDEwLDEgQzEwLDAuNDUgOS41NSwwIDksMCBaIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgzIDIpIi8+CjwvZz4KPGcgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSg3MiwwKSI+PHBhdGggZmlsbD0iIzAwMDAwMCIgZmlsbC1ydWxlPSJldmVub2RkIiBkPSJNMC4yNywxLjU1IEw1LjQzLDYuNyBMMywxMiBMNS41LDEyIEw3LjE0LDguNDIgTDExLjczLDEzIEwxMywxMS43MyBMMS41NSwwLjI3IEwwLjI3LDEuNTUgTDAuMjcsMS41NSBaIE0zLjgyLDAgTDUuODIsMiBMNy41OCwyIEw3LjAzLDMuMjEgTDguNzQsNC45MiBMMTAuMDgsMiBMMTQsMiBMMTQsMCBMMy44MiwwIEwzLjgyLDAgWiIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMiAzKSIvPgo8L2c+CjxnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoOTAsMCkiPjxwYXRoIGZpbGw9IiMwMDAwMDAiIGZpbGwtcnVsZT0iZXZlbm9kZCIgZD0iTTksMy41IEM5LDEuNTcgNy40MywwIDUuNSwwIEwxLjc3NjM1Njg0ZS0xNSwwIEwxLjc3NjM1Njg0ZS0xNSwxMiBMNi4yNSwxMiBDOC4wNCwxMiA5LjUsMTAuNTQgOS41LDguNzUgQzkuNSw3LjQ1IDguNzMsNi4zNCA3LjYzLDUuODIgQzguNDYsNS4yNCA5LDQuMzggOSwzLjUgWiBNNSwyIEM1LjgyOTk5OTkyLDIgNi41LDIuNjcgNi41LDMuNSBDNi41LDQuMzMgNS44Mjk5OTk5Miw1IDUsNSBMMyw1IEwzLDIgTDUsMiBaIE0zLDEwIEwzLDcgTDUuNSw3IEM2LjMyOTk5OTkyLDcgNyw3LjY3IDcsOC41IEM3LDkuMzMgNi4zMjk5OTk5MiwxMCA1LjUsMTAgTDMsMTAgWiIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoNCAzKSIvPgo8L2c+CjxnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMTA4LDApIj48cG9seWdvbiBmaWxsPSIjMDAwMDAwIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiIHBvaW50cz0iNCAwIDQgMiA2LjU4IDIgMi45MiAxMCAwIDEwIDAgMTIgOCAxMiA4IDEwIDUuNDIgMTAgOS4wOCAyIDEyIDIgMTIgMCIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMyAzKSIvPgo8L2c+CjxnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMTI2LDApIj48cGF0aCBmaWxsPSIjMDAwMDAwIiBkPSJNNiwxMiBDOC43NiwxMiAxMSw5Ljc2IDExLDcgTDExLDAgTDksMCBMOSw3IEM5LDguNzUwMjk5MTYgNy40OTkxMjgwNywxMCA2LDEwIEM0LjUwMDg3MTkzLDEwIDMsOC43NTgzNzQ4NiAzLDcgTDMsMCBMMSwwIEwxLDcgQzEsOS43NiAzLjI0LDEyIDYsMTIgWiBNMCwxMyBMMCwxNSBMMTIsMTUgTDEyLDEzIEwwLDEzIFoiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDMgMykiLz4KPC9nPgo8ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHRyYW5zZm9ybT0idHJhbnNsYXRlKDE0NCwwKSI+PHBhdGggZmlsbD0iIzAxMDEwMSIgZmlsbC1ydWxlPSJldmVub2RkIiBkPSJNMi44ODc1LDMuMDYgQzIuODg3NSwyLjYwMjUgMi45ODUsMi4xODYyNSAzLjE4Mzc1LDEuODA3NSBDMy4zODI1LDEuNDI4NzUgMy42NiwxLjEwNjI1IDQuMDIsMC44NCBDNC4zOCwwLjU3Mzc1IDQuODAzNzUsMC4zNjc1IDUuMjk4NzUsMC4yMjEyNSBDNS43OTM3NSwwLjA3NSA2LjMzMzc1LDAgNi45MjYyNSwwIEM3LjUzMzc1LDAgOC4wODUsMC4wODI1IDguNTgsMC4yNTEyNSBDOS4wNzUsMC40MiA5LjQ5ODc1LDAuNjUyNSA5Ljg1MTI1LDAuOTU2MjUgQzEwLjIwMzc1LDEuMjU2MjUgMTAuNDczNzUsMS42MTI1IDEwLjY2NSwyLjAyODc1IEMxMC44NTYyNSwyLjQ0MTI1IDEwLjk1LDIuODk1IDEwLjk1LDMuMzg2MjUgTDguNjkyNSwzLjM4NjI1IEM4LjY5MjUsMy4xNTc1IDguNjU1LDIuOTQzNzUgOC41ODM3NSwyLjc0ODc1IEM4LjUxMjUsMi41NSA4LjQsMi4zODEyNSA4LjI1LDIuMjQyNSBDOC4xLDIuMTAzNzUgNy45MTI1LDEuOTkxMjUgNy42ODc1LDEuOTE2MjUgQzcuNDYyNSwxLjgzNzUgNy4xOTYyNSwxLjggNi44ODg3NSwxLjggQzYuNTkyNSwxLjggNi4zMzc1LDEuODMzNzUgNi4xMTYyNSwxLjg5NzUgQzUuODk4NzUsMS45NjEyNSA1LjcxODc1LDIuMDUxMjUgNS41NzYyNSwyLjE2NzUgQzUuNDMzNzUsMi4yODM3NSA1LjMyNSwyLjQxODc1IDUuMjUzNzUsMi41NzI1IEM1LjE4MjUsMi43MjYyNSA1LjE0NSwyLjg5NSA1LjE0NSwzLjA2NzUgQzUuMTQ1LDMuNDI3NSA1LjMyODc1LDMuNzMxMjUgNS42OTYyNSwzLjk3NSBDNS43MTc4MDIwMywzLjk4OTA4MDY2IDUuNzM5NDIwMTIsNC4wMDMxMTcyOCA1Ljc2MTE4MzU3LDQuMDE3MzMzMTUgQzYuMDIzNDI5MjMsNC4xODg2MzE4NSA2LjUsNC41IDcsNSBMNCw1IEM0LDUgMy4yMTM3NSw0LjM3NjI1IDMuMTc2MjUsNC4zMDg3NSBDMi45ODUsMy45NTI1IDIuODg3NSwzLjUzNjI1IDIuODg3NSwzLjA2IFogTTE0LDYgTDAsNiBMMCw4IEw3LjIxODc1LDggQzcuMzUzNzUsOC4wNTI1IDcuNTE4NzUsOC4xMDUgNy42MzEyNSw4LjE1Mzc1IEM3LjkwODc1LDguMjc3NSA4LjEyNjI1LDguNDA4NzUgOC4yODM3NSw4LjUzNjI1IEM4LjQ0MTI1LDguNjY3NSA4LjU0NjI1LDguODEgOC42MDI1LDguOTYgQzguNjU4NzUsOS4xMTM3NSA4LjY4NSw5LjI4NjI1IDguNjg1LDkuNDczNzUgQzguNjg1LDkuNjUgOC42NTEyNSw5LjgxNSA4LjU4Mzc1LDkuOTY1IEM4LjUxNjI1LDEwLjExODc1IDguNDExMjUsMTAuMjUgOC4yNzI1LDEwLjM1ODc1IEM4LjEzMzc1LDEwLjQ2NzUgNy45NTM3NSwxMC41NTM3NSA3Ljc0LDEwLjYxNzUgQzcuNTIyNSwxMC42ODEyNSA3LjI3MTI1LDEwLjcxMTI1IDYuOTc4NzUsMTAuNzExMjUgQzYuNjUyNSwxMC43MTEyNSA2LjM1NjI1LDEwLjY3NzUgNi4wOSwxMC42MTM3NSBDNS44MjM3NSwxMC41NSA1LjU5ODc1LDEwLjQ0NSA1LjQxMTI1LDEwLjMwMjUgQzUuMjIzNzUsMTAuMTYgNS4wNzc1LDkuOTcyNSA0Ljk3MjUsOS43NDM3NSBDNC44Njc1LDkuNTE1IDQuNzgxMjUsOS4xNyA0Ljc4MTI1LDkgTDIuNTUsOSBDMi41NSw5LjI1MjUgMi42MSw5LjY4NzUgMi43MjYyNSwxMC4wMjUgQzIuODQyNSwxMC4zNjI1IDMuMDA3NSwxMC42NjYyNSAzLjIxMzc1LDEwLjkzMjUgQzMuNDIsMTEuMTk4NzUgMy42Njc1LDExLjQyNzUgMy45NDg3NSwxMS42MjI1IEM0LjIzLDExLjgxNzUgNC41MzM3NSwxMS45ODI1IDQuODYzNzUsMTIuMTEgQzUuMTkzNzUsMTIuMjQxMjUgNS41MzUsMTIuMzM4NzUgNS44OTg3NSwxMi4zOTg3NSBDNi4yNTg3NSwxMi40NjI1IDYuNjIyNSwxMi40OTI1IDYuOTgyNSwxMi40OTI1IEM3LjU4MjUsMTIuNDkyNSA4LjEzLDEyLjQyNSA4LjYxNzUsMTIuMjg2MjUgQzkuMTA1LDEyLjE0NzUgOS41MjUsMTEuOTQ4NzUgOS44NywxMS42OTM3NSBDMTAuMjE1LDExLjQzNSAxMC40ODEyNSwxMS4xMiAxMC42NzI1LDEwLjc0MTI1IEMxMC44NjM3NSwxMC4zNjI1IDEwLjk1Mzc1LDkuOTM1IDEwLjk1Mzc1LDkuNDU1IEMxMC45NTM3NSw5LjAwNSAxMC44NzUsOC42IDEwLjcyMTI1LDguMjQzNzUgQzEwLjY4Mzc1LDguMTU3NSAxMC42NDI1LDguMDc1IDEwLjU5Mzc1LDcuOTkyNSBMMTQsOCBMMTQsNiBaIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgyIDMpIi8+CjwvZz4KPGcgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgxNjIsMCkiPjxwYXRoIGZpbGw9IiMwMDAwMDAiIGZpbGwtcnVsZT0iZXZlbm9kZCIgZD0iTTcsMCBMNSwwIEwwLjUsMTIgTDIuNSwxMiBMMy42Miw5IEw4LjM3LDkgTDkuNDksMTIgTDExLjQ5LDEyIEw3LDAgTDcsMCBaIE00LjM4LDcgTDYsMi42NyBMNy42Miw3IEw0LjM4LDcgTDQuMzgsNyBaIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgzIDEpIi8+CjwvZz4KPGcgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgxODAsMCkiPjxnIGZpbGw9Im5vbmUiIGZpbGwtcnVsZT0iZXZlbm9kZCI+CiAgICA8cGF0aCBmaWxsPSIjMDAwMDAwIiBkPSJNMTQuNSw4Ljg3IEMxNC41LDguODcgMTMsMTAuNDkgMTMsMTEuNDkgQzEzLDEyLjMyIDEzLjY3LDEyLjk5IDE0LjUsMTIuOTkgQzE1LjMzLDEyLjk5IDE2LDEyLjMyIDE2LDExLjQ5IEMxNiwxMC41IDE0LjUsOC44NyAxNC41LDguODcgTDE0LjUsOC44NyBaIE0xMi43MSw2Ljc5IEw1LjkxLDAgTDQuODUsMS4wNiBMNi40NCwyLjY1IEwyLjI5LDYuNzkgQzEuOSw3LjE4IDEuOSw3LjgxIDIuMjksOC4yIEw2Ljc5LDEyLjcgQzYuOTksMTIuOSA3LjI0LDEzIDcuNSwxMyBDNy43NiwxMyA4LjAxLDEyLjkgOC4yMSwxMi43MSBMMTIuNzEsOC4yMSBDMTMuMSw3LjgyIDEzLjEsNy4xOCAxMi43MSw2Ljc5IEwxMi43MSw2Ljc5IFogTTQuMjEsNyBMNy41LDMuNzEgTDEwLjc5LDcgTDQuMjEsNyBMNC4yMSw3IFoiLz4KICA8L2c+CjwvZz4KPGcgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgxOTgsMCkiPjxwYXRoIGZpbGw9IiMwMDAwMDAiIGZpbGwtcnVsZT0iZXZlbm9kZCIgZD0iTTMsNiBMMSw2IEwxLDIgTDgsMiBMOCw0IEwzLDQgTDMsNiBaIE0xMCw0IEwxMCwyIEwxNywyIEwxNyw2IEwxNSw2IEwxNSw0IEwxMCw0IFogTTEwLDE0IEwxNSwxNCBMMTUsMTIgTDE3LDEyIEwxNywxNiBMMTAsMTYgTDEwLDE0IFogTTEsMTIgTDMsMTIgTDMsMTQgTDgsMTQgTDgsMTYgTDEsMTYgTDEsMTIgWiBNMSw4IEw1LDggTDUsNiBMOCw5IEw1LDEyIEw1LDEwIEwxLDEwIEwxLDggWiBNMTAsOSBMMTMsNiBMMTMsOCBMMTcsOCBMMTcsMTAgTDEzLDEwIEwxMywxMiBMMTAsOSBaIi8+CjwvZz4KPGcgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgyMTYsMCkiPjxwYXRoIGZpbGw9IiMwMDAwMDAiIGZpbGwtcnVsZT0iZXZlbm9kZCIgZD0iTTAsMTQgTDEwLDE0IEwxMCwxMiBMMCwxMiBMMCwxNCBaIE0xMCw0IEwwLDQgTDAsNiBMMTAsNiBMMTAsNCBaIE0wLDAgTDAsMiBMMTQsMiBMMTQsMCBMMCwwIFogTTAsMTAgTDE0LDEwIEwxNCw4IEwwLDggTDAsMTAgWiIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMiAyKSIvPgo8L2c+CjxnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMjM0LDApIj48cGF0aCBmaWxsPSIjMDAwMDAwIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiIGQ9Ik0yLDEyIEwyLDE0IEwxMiwxNCBMMTIsMTIgTDIsMTIgWiBNMiw0IEwyLDYgTDEyLDYgTDEyLDQgTDIsNCBaIE0wLDEwIEwxNCwxMCBMMTQsOCBMMCw4IEwwLDEwIFogTTAsMCBMMCwyIEwxNCwyIEwxNCwwIEwwLDAgWiIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMiAyKSIvPgo8L2c+CjxnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMCwxOCkiPjxwYXRoIGZpbGw9IiMwMDAwMDAiIGZpbGwtcnVsZT0iZXZlbm9kZCIgZD0iTTQsMTQgTDE0LDE0IEwxNCwxMiBMNCwxMiBMNCwxNCBaIE0wLDEwIEwxNCwxMCBMMTQsOCBMMCw4IEwwLDEwIFogTTAsMCBMMCwyIEwxNCwyIEwxNCwwIEwwLDAgWiBNNCw2IEwxNCw2IEwxNCw0IEw0LDQgTDQsNiBaIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgyIDIpIi8+CjwvZz4KPGcgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgxOCwxOCkiPjxwYXRoIGZpbGw9IiMwMDAwMDAiIGZpbGwtcnVsZT0iZXZlbm9kZCIgZD0iTTAsMCBMMCwyIEwxMiwyIEwxMiwwIEwwLDAgTDAsMCBaIE0yLjUsNyBMNSw3IEw1LDE0IEw3LDE0IEw3LDcgTDkuNSw3IEw2LDMuNSBMMi41LDcgTDIuNSw3IFoiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDMgMikiLz4KPC9nPgo8ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHRyYW5zZm9ybT0idHJhbnNsYXRlKDM2LDE4KSI+PHBhdGggZmlsbD0iIzAwMDAwMCIgZmlsbC1ydWxlPSJldmVub2RkIiBkPSJNOS41LDMgTDcsMyBMNywwIEw1LDAgTDUsMyBMMi41LDMgTDYsNi41IEw5LjUsMyBMOS41LDMgWiBNMCw4IEwwLDEwIEwxMiwxMCBMMTIsOCBMMCw4IEwwLDggWiBNMi41LDE1IEw1LDE1IEw1LDE4IEw3LDE4IEw3LDE1IEw5LjUsMTUgTDYsMTEuNSBMMi41LDE1IEwyLjUsMTUgWiIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMykiLz4KPC9nPgo8ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHRyYW5zZm9ybT0idHJhbnNsYXRlKDU0LDE4KSI+PHBhdGggZmlsbD0iIzAwMDAwMCIgZmlsbC1ydWxlPSJldmVub2RkIiBkPSJNOS41LDcgTDcsNyBMNywwIEw1LDAgTDUsNyBMMi41LDcgTDYsMTAuNSBMOS41LDcgTDkuNSw3IFogTTAsMTIgTDAsMTQgTDEyLDE0IEwxMiwxMiBMMCwxMiBMMCwxMiBaIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgzIDIpIi8+CjwvZz4KPGcgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSg3MiwxOCkiPjxwYXRoIGZpbGw9IiMwMDAwMDAiIGZpbGwtcnVsZT0iZXZlbm9kZCIgZD0iTTE0LDAgTDAsMCBMMCwyIEwxNCwyIEwxNCwwIFogTTAsMTIgTDQsMTIgTDQsMTAgTDAsMTAgTDAsMTIgWiBNMTEuNSw1IEwwLDUgTDAsNyBMMTEuNzUsNyBDMTIuNTgsNyAxMy4yNSw3LjY3IDEzLjI1LDguNSBDMTMuMjUsOS4zMyAxMi41OCwxMCAxMS43NSwxMCBMOSwxMCBMOSw4IEw2LDExIEw5LDE0IEw5LDEyIEwxMS41LDEyIEMxMy40MywxMiAxNSwxMC40MyAxNSw4LjUgQzE1LDYuNTcgMTMuNDMsNSAxMS41LDUgWiIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMiAzKSIvPgo8L2c+CjxnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoOTAsMTgpIj48cGF0aCBmaWxsPSIjMDAwMDAwIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiIGQ9Ik0wLDAgTDAsMSBMNiw3IEw2LDEyIEw4LDExIEw4LDcgTDE0LDEgTDE0LDAgTDAsMCBaIE00LDMgTDEwLDMgTDcsNiBMNCwzIFoiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDIgMykiLz4KPC9nPgo8ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHRyYW5zZm9ybT0idHJhbnNsYXRlKDEwOCwxOCkiPjxwb2x5Z29uIGZpbGw9IiMwMDAwMDAiIGZpbGwtcnVsZT0iZXZlbm9kZCIgcG9pbnRzPSIxMCAwIDAgMCAwIDEuOCA1LjUgNyAwIDEyLjIgMCAxNCAxMCAxNCAxMCAxMiAzLjEgMTIgOCA3IDMuMSAyIDEwIDIiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDQgMikiLz4KPC9nPgo8ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHRyYW5zZm9ybT0idHJhbnNsYXRlKDEyNiwxOCkiPjxwb2x5Z29uIGZpbGw9IiMwMDAwMDAiIGZpbGwtcnVsZT0iZXZlbm9kZCIgcG9pbnRzPSIwIDAgNCA0IDggMCIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoNSA3KSIvPgo8L2c+CjxnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMTQ0LDE4KSI+PHBvbHlnb24gZmlsbD0iIzAwMDAwMCIgZmlsbC1ydWxlPSJldmVub2RkIiBwb2ludHM9Ii0yIDIgMiA2IDYgMiIgdHJhbnNmb3JtPSJyb3RhdGUoLTkwIDggMykiLz4KPC9nPgo8ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHRyYW5zZm9ybT0idHJhbnNsYXRlKDE2MiwxOCkiPjxwYXRoIGZpbGw9IiMwMDAwMDAiIGZpbGwtcnVsZT0iZXZlbm9kZCIgZD0iTTEuOSw0IEMxLjksMi44NCAyLjg0LDEuOSA0LDEuOSBMOCwxLjkgTDgsMCBMNCwwIEMxLjc5LDAgMCwxLjc5IDAsNCBDMCw2LjIxIDEuNzksOCA0LDggTDgsOCBMOCw2LjEgTDQsNi4xIEMyLjg0LDYuMSAxLjksNS4xNiAxLjksNCBMMS45LDQgWiBNMTQsMCBMMTAsMCBMMTAsMS45IEwxNCwxLjkgQzE1LjE2LDEuOSAxNi4xLDIuODQgMTYuMSw0IEMxNi4xLDUuMTYgMTUuMTYsNi4xIDE0LDYuMSBMMTAsNi4xIEwxMCw4IEwxNCw4IEMxNi4yMSw4IDE4LDYuMjEgMTgsNCBDMTgsMS43OSAxNi4yMSwwIDE0LDAgTDE0LDAgWiBNNiw1IEwxMiw1IEwxMiwzIEw2LDMgTDYsNSBMNiw1IFoiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDAgNSkiLz4KPC9nPgo8ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHRyYW5zZm9ybT0idHJhbnNsYXRlKDE4MCwxOCkiPjxwYXRoIGZpbGw9IiMwMDAwMDAiIGZpbGwtcnVsZT0iZXZlbm9kZCIgZD0iTTE1LDAgQzE1LjU1LDAgMTYsMC40NSAxNiwxIEwxNiwxNSBDMTYsMTUuNTUgMTUuNTUsMTYgMTUsMTYgTDEsMTYgQzAuNDUsMTYgMCwxNS41NSAwLDE1IEwwLDEgQzAsMC40NSAwLjQ1LDAgMSwwIEwxNSwwIFogTTIsMiBMMiwxNCBMMTQsMTQgTDE0LDIgTDIsMiBaIE02LDEyIEw0LDEyIEw0LDcgTDYsNyBMNiwxMiBMNiwxMiBaIE05LDEyIEw3LDEyIEw3LDQgTDksNCBMOSwxMiBMOSwxMiBaIE0xMiwxMiBMMTAsMTIgTDEwLDggTDEyLDggTDEyLDEyIEwxMiwxMiBaIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgxIDEpIi8+CjwvZz4KPGcgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgxOTgsMTgpIj48ZyBmaWxsPSJub25lIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiPgogICAgPHBhdGggc3Ryb2tlPSIjMDAwMDAwIiBkPSJNMS41IDMuNUgxNi41VjE1LjVIMS41eiIvPgogICAgPHBhdGggZmlsbD0iIzAwMDAwMCIgZD0iTTYgOEg3VjE1SDZ6Ii8+CiAgICA8cGF0aCBmaWxsPSIjRDhEOEQ4IiBkPSJNMiA0SDE2VjdIMnoiLz4KICAgIDxwYXRoIGZpbGw9IiMwMDAwMDAiIGQ9Ik0yIDdIMTZWOEgyek0yIDExSDE2VjEySDJ6Ii8+CiAgPC9nPgo8L2c+CjxnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMjE2LDE4KSI+PHBhdGggZmlsbD0iIzAwMDAwMCIgZmlsbC1ydWxlPSJldmVub2RkIiBkPSJNMiwwLjUgQzEuMTcsMC41IDAuNSwxLjE3IDAuNSwyIEMwLjUsMi44MyAxLjE3LDMuNSAyLDMuNSBDMi44MywzLjUgMy41LDIuODMgMy41LDIgQzMuNSwxLjE3IDIuODMsMC41IDIsMC41IEwyLDAuNSBaIE0xMiwwLjUgQzExLjE3LDAuNSAxMC41LDEuMTcgMTAuNSwyIEMxMC41LDIuODMgMTEuMTcsMy41IDEyLDMuNSBDMTIuODMsMy41IDEzLjUsMi44MyAxMy41LDIgQzEzLjUsMS4xNyAxMi44MywwLjUgMTIsMC41IEwxMiwwLjUgWiBNNywwLjUgQzYuMTcsMC41IDUuNSwxLjE3IDUuNSwyIEM1LjUsMi44MyA2LjE3LDMuNSA3LDMuNSBDNy44MywzLjUgOC41LDIuODMgOC41LDIgQzguNSwxLjE3IDcuODMsMC41IDcsMC41IEw3LDAuNSBaIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgyIDcpIi8+CjwvZz4KPGcgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgyMzQsMTgpIj48cGF0aCBmaWxsPSIjMDAwMDAwIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiIGQ9Ik02LDQgTDYsMCBMNCwwIEw0LDQgTDAsNCBMMCw2IEw0LDYgTDQsMTAgTDYsMTAgTDYsNiBMMTAsNiBMMTAsNCBMNiw0IFoiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDQgNCkiLz4KPC9nPgo8ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHRyYW5zZm9ybT0idHJhbnNsYXRlKDAsMzYpIj48cGF0aCBmaWxsPSIjMDAwMDAwIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiIGQ9Ik0wLDAgTDAsMTQgTDE0LDE0IEwxNCwwIEwwLDAgTDAsMCBaIE02LDEyIEwyLDEyIEwyLDggTDYsOCBMNiwxMiBMNiwxMiBaIE02LDYgTDIsNiBMMiwyIEw2LDIgTDYsNiBMNiw2IFogTTEyLDEyIEw4LDEyIEw4LDggTDEyLDggTDEyLDEyIEwxMiwxMiBaIE0xMiw2IEw4LDYgTDgsMiBMMTIsMiBMMTIsNiBMMTIsNiBaIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgyIDIpIi8+CjwvZz4KPGcgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgxOCwzNikiPgogIDxnIGZpbGw9IiMwMDAwMDAiIGZpbGwtcnVsZT0iZXZlbm9kZCIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMiAyKSI+CiAgICA8cGF0aCBkPSJNMCwxNCBMMiwxNCBMMiwxMiBMMCwxMiBMMCwxNCBMMCwxNCBaIE0yLDMgTDAsMyBMMCw1IEwyLDUgTDIsMyBMMiwzIFogTTMsMTQgTDUsMTQgTDUsMTIgTDMsMTIgTDMsMTQgTDMsMTQgWiBNMTEsMCBMOSwwIEw5LDIgTDExLDIgTDExLDAgTDExLDAgWiBNMiwwIEwwLDAgTDAsMiBMMiwyIEwyLDAgTDIsMCBaIE01LDAgTDMsMCBMMywyIEw1LDIgTDUsMCBMNSwwIFogTTAsMTEgTDIsMTEgTDIsOSBMMCw5IEwwLDExIEwwLDExIFogTTksMTQgTDExLDE0IEwxMSwxMiBMOSwxMiBMOSwxNCBMOSwxNCBaIE0xMiwwIEwxMiwyIEwxNCwyIEwxNCwwIEwxMiwwIEwxMiwwIFogTTEyLDUgTDE0LDUgTDE0LDMgTDEyLDMgTDEyLDUgTDEyLDUgWiBNMTIsMTQgTDE0LDE0IEwxNCwxMiBMMTIsMTIgTDEyLDE0IEwxMiwxNCBaIE0xMiwxMSBMMTQsMTEgTDE0LDkgTDEyLDkgTDEyLDExIEwxMiwxMSBaIiBvcGFjaXR5PSIuNTQiLz4KICAgIDxwb2x5Z29uIHBvaW50cz0iOCAwIDYgMCA2IDYgMCA2IDAgOCA2IDggNiAxNCA4IDE0IDggOCAxNCA4IDE0IDYgOCA2Ii8+CiAgPC9nPgo8L2c+CjxnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMzYsMzYpIj4KICA8ZyBmaWxsPSIjMDAwMDAwIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDIgMikiPgogICAgPHBhdGggZD0iTTYsMTQgTDgsMTQgTDgsMTIgTDYsMTIgTDYsMTQgTDYsMTQgWiBNMywyIEw1LDIgTDUsMCBMMywwIEwzLDIgTDMsMiBaIE02LDExIEw4LDExIEw4LDkgTDYsOSBMNiwxMSBMNiwxMSBaIE0zLDE0IEw1LDE0IEw1LDEyIEwzLDEyIEwzLDE0IEwzLDE0IFogTTAsNSBMMiw1IEwyLDMgTDAsMyBMMCw1IEwwLDUgWiBNMCwxNCBMMiwxNCBMMiwxMiBMMCwxMiBMMCwxNCBMMCwxNCBaIE0wLDIgTDIsMiBMMiwwIEwwLDAgTDAsMiBMMCwyIFogTTAsMTEgTDIsMTEgTDIsOSBMMCw5IEwwLDExIEwwLDExIFogTTEyLDExIEwxNCwxMSBMMTQsOSBMMTIsOSBMMTIsMTEgTDEyLDExIFogTTEyLDE0IEwxNCwxNCBMMTQsMTIgTDEyLDEyIEwxMiwxNCBMMTIsMTQgWiBNMTIsNSBMMTQsNSBMMTQsMyBMMTIsMyBMMTIsNSBMMTIsNSBaIE0xMiwwIEwxMiwyIEwxNCwyIEwxNCwwIEwxMiwwIEwxMiwwIFogTTYsMiBMOCwyIEw4LDAgTDYsMCBMNiwyIEw2LDIgWiBNOSwyIEwxMSwyIEwxMSwwIEw5LDAgTDksMiBMOSwyIFogTTYsNSBMOCw1IEw4LDMgTDYsMyBMNiw1IEw2LDUgWiBNOSwxNCBMMTEsMTQgTDExLDEyIEw5LDEyIEw5LDE0IEw5LDE0IFoiIG9wYWNpdHk9Ii41NCIvPgogICAgPHBvbHlnb24gcG9pbnRzPSIwIDggMTQgOCAxNCA2IDAgNiIvPgogIDwvZz4KPC9nPgo8ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHRyYW5zZm9ybT0idHJhbnNsYXRlKDU0LDM2KSI+CiAgPGcgZmlsbD0iIzAwMDAwMCIgZmlsbC1ydWxlPSJldmVub2RkIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgyIDIpIj4KICAgIDxwYXRoIGQ9Ik0zLDE0IEw1LDE0IEw1LDEyIEwzLDEyIEwzLDE0IEwzLDE0IFogTTAsNSBMMiw1IEwyLDMgTDAsMyBMMCw1IEwwLDUgWiBNMCwyIEwyLDIgTDIsMCBMMCwwIEwwLDIgTDAsMiBaIE0zLDggTDUsOCBMNSw2IEwzLDYgTDMsOCBMMyw4IFogTTMsMiBMNSwyIEw1LDAgTDMsMCBMMywyIEwzLDIgWiBNMCwxNCBMMiwxNCBMMiwxMiBMMCwxMiBMMCwxNCBMMCwxNCBaIE0wLDggTDIsOCBMMiw2IEwwLDYgTDAsOCBMMCw4IFogTTAsMTEgTDIsMTEgTDIsOSBMMCw5IEwwLDExIEwwLDExIFogTTEyLDAgTDEyLDIgTDE0LDIgTDE0LDAgTDEyLDAgTDEyLDAgWiBNMTIsOCBMMTQsOCBMMTQsNiBMMTIsNiBMMTIsOCBMMTIsOCBaIE0xMiwxNCBMMTQsMTQgTDE0LDEyIEwxMiwxMiBMMTIsMTQgTDEyLDE0IFogTTEyLDUgTDE0LDUgTDE0LDMgTDEyLDMgTDEyLDUgTDEyLDUgWiBNMTIsMTEgTDE0LDExIEwxNCw5IEwxMiw5IEwxMiwxMSBMMTIsMTEgWiBNOSwxNCBMMTEsMTQgTDExLDEyIEw5LDEyIEw5LDE0IEw5LDE0IFogTTksOCBMMTEsOCBMMTEsNiBMOSw2IEw5LDggTDksOCBaIE05LDIgTDExLDIgTDExLDAgTDksMCBMOSwyIEw5LDIgWiIgb3BhY2l0eT0iLjU0Ii8+CiAgICA8cG9seWdvbiBwb2ludHM9IjYgMTQgOCAxNCA4IDAgNiAwIi8+CiAgPC9nPgo8L2c+CjxnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoNzIsMzYpIj4KICA8ZyBmaWxsPSIjMDAwMDAwIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDIgMikiPgogICAgPHBhdGggZD0iTTgsMyBMNiwzIEw2LDUgTDgsNSBMOCwzIEw4LDMgWiBNMTEsNiBMOSw2IEw5LDggTDExLDggTDExLDYgTDExLDYgWiBNOCw2IEw2LDYgTDYsOCBMOCw4IEw4LDYgTDgsNiBaIE04LDkgTDYsOSBMNiwxMSBMOCwxMSBMOCw5IEw4LDkgWiBNNSw2IEwzLDYgTDMsOCBMNSw4IEw1LDYgTDUsNiBaIiBvcGFjaXR5PSIuNTQiLz4KICAgIDxwYXRoIGQ9Ik0wLDAgTDE0LDAgTDE0LDE0IEwwLDE0IEwwLDAgWiBNMTIsMTIgTDEyLDIgTDIsMiBMMiwxMiBMMTIsMTIgWiIvPgogIDwvZz4KPC9nPgo8ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHRyYW5zZm9ybT0idHJhbnNsYXRlKDkwLDM2KSI+CiAgPGcgZmlsbD0iIzAwMDAwMCIgZmlsbC1ydWxlPSJldmVub2RkIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgyIDIpIj4KICAgIDxwYXRoIGQ9Ik02LDggTDgsOCBMOCw2IEw2LDYgTDYsOCBMNiw4IFogTTYsNSBMOCw1IEw4LDMgTDYsMyBMNiw1IEw2LDUgWiBNNiwxMSBMOCwxMSBMOCw5IEw2LDkgTDYsMTEgTDYsMTEgWiBNNiwxNCBMOCwxNCBMOCwxMiBMNiwxMiBMNiwxNCBMNiwxNCBaIE0zLDE0IEw1LDE0IEw1LDEyIEwzLDEyIEwzLDE0IEwzLDE0IFogTTMsMiBMNSwyIEw1LDAgTDMsMCBMMywyIEwzLDIgWiBNMyw4IEw1LDggTDUsNiBMMyw2IEwzLDggTDMsOCBaIE0xMiwxNCBMMTQsMTQgTDE0LDEyIEwxMiwxMiBMMTIsMTQgTDEyLDE0IFogTTEyLDggTDE0LDggTDE0LDYgTDEyLDYgTDEyLDggTDEyLDggWiBNMTIsMTEgTDE0LDExIEwxNCw5IEwxMiw5IEwxMiwxMSBMMTIsMTEgWiBNMTIsNSBMMTQsNSBMMTQsMyBMMTIsMyBMMTIsNSBMMTIsNSBaIE02LDIgTDgsMiBMOCwwIEw2LDAgTDYsMiBMNiwyIFogTTEyLDAgTDEyLDIgTDE0LDIgTDE0LDAgTDEyLDAgTDEyLDAgWiBNOSwxNCBMMTEsMTQgTDExLDEyIEw5LDEyIEw5LDE0IEw5LDE0IFogTTksOCBMMTEsOCBMMTEsNiBMOSw2IEw5LDggTDksOCBaIE05LDIgTDExLDIgTDExLDAgTDksMCBMOSwyIEw5LDIgWiIgb3BhY2l0eT0iLjU0Ii8+CiAgICA8cG9seWdvbiBwb2ludHM9IjAgMTQgMiAxNCAyIDAgMCAwIi8+CiAgPC9nPgo8L2c+CjxnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMTA4LDM2KSI+CiAgPGcgZmlsbD0iIzAwMDAwMCIgZmlsbC1ydWxlPSJldmVub2RkIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgyIDIpIj4KICAgIDxwYXRoIGQ9Ik0zLDggTDUsOCBMNSw2IEwzLDYgTDMsOCBMMyw4IFogTTAsMTQgTDIsMTQgTDIsMTIgTDAsMTIgTDAsMTQgTDAsMTQgWiBNNiwxNCBMOCwxNCBMOCwxMiBMNiwxMiBMNiwxNCBMNiwxNCBaIE02LDExIEw4LDExIEw4LDkgTDYsOSBMNiwxMSBMNiwxMSBaIE0zLDE0IEw1LDE0IEw1LDEyIEwzLDEyIEwzLDE0IEwzLDE0IFogTTAsMTEgTDIsMTEgTDIsOSBMMCw5IEwwLDExIEwwLDExIFogTTYsOCBMOCw4IEw4LDYgTDYsNiBMNiw4IEw2LDggWiBNMCw1IEwyLDUgTDIsMyBMMCwzIEwwLDUgTDAsNSBaIE0wLDggTDIsOCBMMiw2IEwwLDYgTDAsOCBMMCw4IFogTTEyLDggTDE0LDggTDE0LDYgTDEyLDYgTDEyLDggTDEyLDggWiBNMTIsMTEgTDE0LDExIEwxNCw5IEwxMiw5IEwxMiwxMSBMMTIsMTEgWiBNMTIsNSBMMTQsNSBMMTQsMyBMMTIsMyBMMTIsNSBMMTIsNSBaIE02LDUgTDgsNSBMOCwzIEw2LDMgTDYsNSBMNiw1IFogTTksMTQgTDExLDE0IEwxMSwxMiBMOSwxMiBMOSwxNCBMOSwxNCBaIE05LDggTDExLDggTDExLDYgTDksNiBMOSw4IEw5LDggWiBNMTIsMTQgTDE0LDE0IEwxNCwxMiBMMTIsMTIgTDEyLDE0IEwxMiwxNCBaIiBvcGFjaXR5PSIuNTQiLz4KICAgIDxwb2x5Z29uIHBvaW50cz0iMCAwIDAgMiAxNCAyIDE0IDAiLz4KICA8L2c+CjwvZz4KPGcgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgxMjYsMzYpIj4KICA8ZyBmaWxsPSIjMDAwMDAwIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDIgMikiPgogICAgPHBhdGggZD0iTTAsMiBMMiwyIEwyLDAgTDAsMCBMMCwyIEwwLDIgWiBNMywyIEw1LDIgTDUsMCBMMywwIEwzLDIgTDMsMiBaIE0zLDggTDUsOCBMNSw2IEwzLDYgTDMsOCBMMyw4IFogTTMsMTQgTDUsMTQgTDUsMTIgTDMsMTIgTDMsMTQgTDMsMTQgWiBNMCw1IEwyLDUgTDIsMyBMMCwzIEwwLDUgTDAsNSBaIE0wLDggTDIsOCBMMiw2IEwwLDYgTDAsOCBMMCw4IFogTTAsMTQgTDIsMTQgTDIsMTIgTDAsMTIgTDAsMTQgTDAsMTQgWiBNMCwxMSBMMiwxMSBMMiw5IEwwLDkgTDAsMTEgTDAsMTEgWiBNOSw4IEwxMSw4IEwxMSw2IEw5LDYgTDksOCBMOSw4IFogTTYsMTQgTDgsMTQgTDgsMTIgTDYsMTIgTDYsMTQgTDYsMTQgWiBNOSwxNCBMMTEsMTQgTDExLDEyIEw5LDEyIEw5LDE0IEw5LDE0IFogTTYsMiBMOCwyIEw4LDAgTDYsMCBMNiwyIEw2LDIgWiBNOSwyIEwxMSwyIEwxMSwwIEw5LDAgTDksMiBMOSwyIFogTTYsMTEgTDgsMTEgTDgsOSBMNiw5IEw2LDExIEw2LDExIFogTTYsNSBMOCw1IEw4LDMgTDYsMyBMNiw1IEw2LDUgWiBNNiw4IEw4LDggTDgsNiBMNiw2IEw2LDggTDYsOCBaIiBvcGFjaXR5PSIuNTQiLz4KICAgIDxwb2x5Z29uIHBvaW50cz0iMTIgMCAxMiAxNCAxNCAxNCAxNCAwIi8+CiAgPC9nPgo8L2c+CjxnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMTQ0LDM2KSI+CiAgPGcgZmlsbD0iIzAwMDAwMCIgZmlsbC1ydWxlPSJldmVub2RkIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgyIDIpIj4KICAgIDxwYXRoIGQ9Ik01LDAgTDMsMCBMMywyIEw1LDIgTDUsMCBMNSwwIFogTTgsNiBMNiw2IEw2LDggTDgsOCBMOCw2IEw4LDYgWiBNOCw5IEw2LDkgTDYsMTEgTDgsMTEgTDgsOSBMOCw5IFogTTExLDYgTDksNiBMOSw4IEwxMSw4IEwxMSw2IEwxMSw2IFogTTUsNiBMMyw2IEwzLDggTDUsOCBMNSw2IEw1LDYgWiBNMTEsMCBMOSwwIEw5LDIgTDExLDIgTDExLDAgTDExLDAgWiBNOCwzIEw2LDMgTDYsNSBMOCw1IEw4LDMgTDgsMyBaIE04LDAgTDYsMCBMNiwyIEw4LDIgTDgsMCBMOCwwIFogTTIsOSBMMCw5IEwwLDExIEwyLDExIEwyLDkgTDIsOSBaIE0xMiwxMSBMMTQsMTEgTDE0LDkgTDEyLDkgTDEyLDExIEwxMiwxMSBaIE0xMiw1IEwxNCw1IEwxNCwzIEwxMiwzIEwxMiw1IEwxMiw1IFogTTEyLDggTDE0LDggTDE0LDYgTDEyLDYgTDEyLDggTDEyLDggWiBNMTIsMCBMMTIsMiBMMTQsMiBMMTQsMCBMMTIsMCBMMTIsMCBaIE0yLDAgTDAsMCBMMCwyIEwyLDIgTDIsMCBMMiwwIFogTTIsMyBMMCwzIEwwLDUgTDIsNSBMMiwzIEwyLDMgWiBNMiw2IEwwLDYgTDAsOCBMMiw4IEwyLDYgTDIsNiBaIiBvcGFjaXR5PSIuNTQiLz4KICAgIDxwb2x5Z29uIHBvaW50cz0iMCAxNCAxNCAxNCAxNCAxMiAwIDEyIi8+CiAgPC9nPgo8L2c+CjxnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMTYyLDM2KSI+PHBhdGggZmlsbD0iIzAwMDAwMCIgZmlsbC1ydWxlPSJldmVub2RkIiBkPSJNNiwxNCBMOCwxNCBMOCwxMiBMNiwxMiBMNiwxNCBMNiwxNCBaIE0zLDggTDUsOCBMNSw2IEwzLDYgTDMsOCBMMyw4IFogTTMsMiBMNSwyIEw1LDAgTDMsMCBMMywyIEwzLDIgWiBNNiwxMSBMOCwxMSBMOCw5IEw2LDkgTDYsMTEgTDYsMTEgWiBNMywxNCBMNSwxNCBMNSwxMiBMMywxMiBMMywxNCBMMywxNCBaIE0wLDUgTDIsNSBMMiwzIEwwLDMgTDAsNSBMMCw1IFogTTAsMTQgTDIsMTQgTDIsMTIgTDAsMTIgTDAsMTQgTDAsMTQgWiBNMCwyIEwyLDIgTDIsMCBMMCwwIEwwLDIgTDAsMiBaIE0wLDggTDIsOCBMMiw2IEwwLDYgTDAsOCBMMCw4IFogTTYsOCBMOCw4IEw4LDYgTDYsNiBMNiw4IEw2LDggWiBNMCwxMSBMMiwxMSBMMiw5IEwwLDkgTDAsMTEgTDAsMTEgWiBNMTIsMTEgTDE0LDExIEwxNCw5IEwxMiw5IEwxMiwxMSBMMTIsMTEgWiBNMTIsMTQgTDE0LDE0IEwxNCwxMiBMMTIsMTIgTDEyLDE0IEwxMiwxNCBaIE0xMiw4IEwxNCw4IEwxNCw2IEwxMiw2IEwxMiw4IEwxMiw4IFogTTEyLDUgTDE0LDUgTDE0LDMgTDEyLDMgTDEyLDUgTDEyLDUgWiBNMTIsMCBMMTIsMiBMMTQsMiBMMTQsMCBMMTIsMCBMMTIsMCBaIE02LDIgTDgsMiBMOCwwIEw2LDAgTDYsMiBMNiwyIFogTTksMiBMMTEsMiBMMTEsMCBMOSwwIEw5LDIgTDksMiBaIE02LDUgTDgsNSBMOCwzIEw2LDMgTDYsNSBMNiw1IFogTTksMTQgTDExLDE0IEwxMSwxMiBMOSwxMiBMOSwxNCBMOSwxNCBaIE05LDggTDExLDggTDExLDYgTDksNiBMOSw4IEw5LDggWiIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMiAyKSIgb3BhY2l0eT0iLjU0Ii8+CjwvZz4KPGcgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgxODAsMzYpIj48cGF0aCBmaWxsPSIjMDAwMDAwIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiIGQ9Ik02LjUsMy42MiBMMCwxMC4xMiBMMCwxMyBMMi44OCwxMyBMOS4zOCw2LjUgTDYuNSwzLjYyIFogTTExLjg1LDQuMDIgQzEyLjA1LDMuODIgMTIuMDUsMy41MSAxMS44NSwzLjMxIEw5LjY4LDEuMTQgQzkuNDgsMC45NCA5LjE3LDAuOTQgOC45NywxLjE0IEw3LjYyLDIuNSBMMTAuNSw1LjM4IEwxMS44NSw0LjAyIEwxMS44NSw0LjAyIFoiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDQpIi8+CjwvZz4KPGcgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgxOTgsMzYpIj48cGF0aCBmaWxsPSIjMDAwMDAwIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiIGQ9Ik0wLDAgTDE0LDAgTDE0LDIgTDAsMiBMMCwwIFogTTAsNCBMNiw0IEw2LDYgTDAsNiBMMCw0IFogTTAsOCBMMiw4IEwyLDEwIEwwLDEwIEwwLDggWiBNOCw0IEwxNCw0IEwxNCw2IEw4LDYgTDgsNCBaIE00LDggTDYsOCBMNiwxMCBMNCwxMCBMNCw4IFogTTgsOCBMMTAsOCBMMTAsMTAgTDgsMTAgTDgsOCBaIE0xMiw4IEwxNCw4IEwxNCwxMCBMMTIsMTAgTDEyLDggWiIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMiA0KSIvPgo8L2c+CjxnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMjE2LDM2KSI+PHBvbHlnb24gZmlsbD0iIzAwMDAwMCIgZmlsbC1ydWxlPSJldmVub2RkIiBwb2ludHM9Ii0yIDIgMiA2IDYgMiIgdHJhbnNmb3JtPSJyb3RhdGUoOTAgMyAxMCkiLz4KPC9nPgo8ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHRyYW5zZm9ybT0idHJhbnNsYXRlKDIzNCwzNikiPjxwb2x5Z29uIGZpbGw9IiMwMDAwMDAiIGZpbGwtcnVsZT0iZXZlbm9kZCIgcG9pbnRzPSI3LjUzIDEuNTMgNi40NyAuNDcgNCAyLjk0IDEuNTMgLjQ3IC40NyAxLjUzIDIuOTQgNCAuNDcgNi40NyAxLjUzIDcuNTMgNCA1LjA2IDYuNDcgNy41MyA3LjUzIDYuNDcgNS4wNiA0IiB0cmFuc2Zvcm09InRyYW5zbGF0ZSg1IDUpIi8+CjwvZz4KPGcgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgwLDU0KSI+PHBvbHlnb24gZmlsbD0iIzAwMDAwMCIgZmlsbC1ydWxlPSJldmVub2RkIiBwb2ludHM9IjguNDQgLjQ0IDUgMy44OCAxLjU2IC40NCAuNSAxLjUgNSA2IDkuNSAxLjUiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDQgNikiLz4KPC9nPgo8ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHRyYW5zZm9ybT0idHJhbnNsYXRlKDE4LDU0KSI+PHBvbHlnb24gZmlsbD0iIzAwMDAwMCIgZmlsbC1ydWxlPSJldmVub2RkIiBwb2ludHM9IjUgMCAuNSA0LjUgMS41NiA1LjU2IDUgMi4xMiA4LjQ0IDUuNTYgOS41IDQuNSIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoNCA2KSIvPgo8L2c+CjxnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMzYsNTQpIj48cG9seWdvbiBmaWxsPSIjMDAwMDAwIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiIHBvaW50cz0iOC40NCAuNDQgNSAzLjg4IDEuNTYgLjQ0IC41IDEuNSA1IDYgOS41IDEuNSIgdHJhbnNmb3JtPSJyb3RhdGUoOTAgNCA4KSIvPgo8L2c+CjxnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoNTQsNTQpIj48cG9seWdvbiBmaWxsPSIjMDAwMDAwIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiIHBvaW50cz0iNSAwIC41IDQuNSAxLjU2IDUuNTYgNSAyLjEyIDguNDQgNS41NiA5LjUgNC41IiB0cmFuc2Zvcm09InJvdGF0ZSg5MCA0IDgpIi8+CjwvZz4KPGcgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSg3Miw1NCkiPjxwb2x5Z29uIGZpbGw9IiMwMDAwMDAiIGZpbGwtcnVsZT0iZXZlbm9kZCIgcG9pbnRzPSIxMiA1IDMuMTI1IDUgNy4wNiAxLjA2IDYgMCAwIDYgNiAxMiA3LjA2IDEwLjk0IDMuMTI1IDcgMTIgNyIgdHJhbnNmb3JtPSJtYXRyaXgoLTEgMCAwIDEgMTUgMykiLz4KPC9nPgo8ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHRyYW5zZm9ybT0idHJhbnNsYXRlKDkwLDU0KSI+PHBvbHlnb24gZmlsbD0iIzAwMDAwMCIgZmlsbC1ydWxlPSJldmVub2RkIiBwb2ludHM9IjEyIDUgMy4xMjUgNSA3LjA2IDEuMDYgNiAwIDAgNiA2IDEyIDcuMDYgMTAuOTQgMy4xMjUgNyAxMiA3IiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgzIDMpIi8+CjwvZz4KPC9zdmc+Cg==); 881 | position: absolute; 882 | width: 262px; 883 | height: 444px; 884 | opacity: 0.56; 885 | } 886 | .x-spreadsheet-icon .x-spreadsheet-icon-img.undo { 887 | left: 0; 888 | top: 0; 889 | } 890 | .x-spreadsheet-icon .x-spreadsheet-icon-img.redo { 891 | left: -18px; 892 | top: 0; 893 | } 894 | .x-spreadsheet-icon .x-spreadsheet-icon-img.print { 895 | left: -36px; 896 | top: 0; 897 | } 898 | .x-spreadsheet-icon .x-spreadsheet-icon-img.paintformat { 899 | left: -54px; 900 | top: 0; 901 | } 902 | .x-spreadsheet-icon .x-spreadsheet-icon-img.clearformat { 903 | left: -72px; 904 | top: 0; 905 | } 906 | .x-spreadsheet-icon .x-spreadsheet-icon-img.font-bold { 907 | left: -90px; 908 | top: 0; 909 | } 910 | .x-spreadsheet-icon .x-spreadsheet-icon-img.font-italic { 911 | left: -108px; 912 | top: 0; 913 | } 914 | .x-spreadsheet-icon .x-spreadsheet-icon-img.underline { 915 | left: -126px; 916 | top: 0; 917 | } 918 | .x-spreadsheet-icon .x-spreadsheet-icon-img.strike { 919 | left: -144px; 920 | top: 0; 921 | } 922 | .x-spreadsheet-icon .x-spreadsheet-icon-img.color { 923 | left: -162px; 924 | top: 0; 925 | } 926 | .x-spreadsheet-icon .x-spreadsheet-icon-img.bgcolor { 927 | left: -180px; 928 | top: 0; 929 | } 930 | .x-spreadsheet-icon .x-spreadsheet-icon-img.merge { 931 | left: -198px; 932 | top: 0; 933 | } 934 | .x-spreadsheet-icon .x-spreadsheet-icon-img.align-left { 935 | left: -216px; 936 | top: 0; 937 | } 938 | .x-spreadsheet-icon .x-spreadsheet-icon-img.align-center { 939 | left: -234px; 940 | top: 0; 941 | } 942 | .x-spreadsheet-icon .x-spreadsheet-icon-img.align-right { 943 | left: 0; 944 | top: -18px; 945 | } 946 | .x-spreadsheet-icon .x-spreadsheet-icon-img.align-top { 947 | left: -18px; 948 | top: -18px; 949 | } 950 | .x-spreadsheet-icon .x-spreadsheet-icon-img.align-middle { 951 | left: -36px; 952 | top: -18px; 953 | } 954 | .x-spreadsheet-icon .x-spreadsheet-icon-img.align-bottom { 955 | left: -54px; 956 | top: -18px; 957 | } 958 | .x-spreadsheet-icon .x-spreadsheet-icon-img.textwrap { 959 | left: -72px; 960 | top: -18px; 961 | } 962 | .x-spreadsheet-icon .x-spreadsheet-icon-img.autofilter { 963 | left: -90px; 964 | top: -18px; 965 | } 966 | .x-spreadsheet-icon .x-spreadsheet-icon-img.formula { 967 | left: -108px; 968 | top: -18px; 969 | } 970 | .x-spreadsheet-icon .x-spreadsheet-icon-img.arrow-down { 971 | left: -126px; 972 | top: -18px; 973 | } 974 | .x-spreadsheet-icon .x-spreadsheet-icon-img.arrow-right { 975 | left: -144px; 976 | top: -18px; 977 | } 978 | .x-spreadsheet-icon .x-spreadsheet-icon-img.link { 979 | left: -162px; 980 | top: -18px; 981 | } 982 | .x-spreadsheet-icon .x-spreadsheet-icon-img.chart { 983 | left: -180px; 984 | top: -18px; 985 | } 986 | .x-spreadsheet-icon .x-spreadsheet-icon-img.freeze { 987 | left: -198px; 988 | top: -18px; 989 | } 990 | .x-spreadsheet-icon .x-spreadsheet-icon-img.ellipsis { 991 | left: -216px; 992 | top: -18px; 993 | } 994 | .x-spreadsheet-icon .x-spreadsheet-icon-img.add { 995 | left: -234px; 996 | top: -18px; 997 | } 998 | .x-spreadsheet-icon .x-spreadsheet-icon-img.border-all { 999 | left: 0; 1000 | top: -36px; 1001 | } 1002 | .x-spreadsheet-icon .x-spreadsheet-icon-img.border-inside { 1003 | left: -18px; 1004 | top: -36px; 1005 | } 1006 | .x-spreadsheet-icon .x-spreadsheet-icon-img.border-horizontal { 1007 | left: -36px; 1008 | top: -36px; 1009 | } 1010 | .x-spreadsheet-icon .x-spreadsheet-icon-img.border-vertical { 1011 | left: -54px; 1012 | top: -36px; 1013 | } 1014 | .x-spreadsheet-icon .x-spreadsheet-icon-img.border-outside { 1015 | left: -72px; 1016 | top: -36px; 1017 | } 1018 | .x-spreadsheet-icon .x-spreadsheet-icon-img.border-left { 1019 | left: -90px; 1020 | top: -36px; 1021 | } 1022 | .x-spreadsheet-icon .x-spreadsheet-icon-img.border-top { 1023 | left: -108px; 1024 | top: -36px; 1025 | } 1026 | .x-spreadsheet-icon .x-spreadsheet-icon-img.border-right { 1027 | left: -126px; 1028 | top: -36px; 1029 | } 1030 | .x-spreadsheet-icon .x-spreadsheet-icon-img.border-bottom { 1031 | left: -144px; 1032 | top: -36px; 1033 | } 1034 | .x-spreadsheet-icon .x-spreadsheet-icon-img.border-none { 1035 | left: -162px; 1036 | top: -36px; 1037 | } 1038 | .x-spreadsheet-icon .x-spreadsheet-icon-img.line-color { 1039 | left: -180px; 1040 | top: -36px; 1041 | } 1042 | .x-spreadsheet-icon .x-spreadsheet-icon-img.line-type { 1043 | left: -198px; 1044 | top: -36px; 1045 | } 1046 | .x-spreadsheet-icon .x-spreadsheet-icon-img.close { 1047 | left: -234px; 1048 | top: -36px; 1049 | } 1050 | .x-spreadsheet-icon .x-spreadsheet-icon-img.chevron-down { 1051 | left: 0; 1052 | top: -54px; 1053 | } 1054 | .x-spreadsheet-icon .x-spreadsheet-icon-img.chevron-up { 1055 | left: -18px; 1056 | top: -54px; 1057 | } 1058 | .x-spreadsheet-icon .x-spreadsheet-icon-img.chevron-left { 1059 | left: -36px; 1060 | top: -54px; 1061 | } 1062 | .x-spreadsheet-icon .x-spreadsheet-icon-img.chevron-right { 1063 | left: -54px; 1064 | top: -54px; 1065 | } 1066 | /*# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsibm9kZV9tb2R1bGVzL3gtZGF0YS1zcHJlYWRzaGVldC9zcmMvaW5kZXgubGVzcyJdLAogICJzb3VyY2VzQ29udGVudCI6IFsiYm9keSB7XG4gIG1hcmdpbjogMDtcbn1cbi54LXNwcmVhZHNoZWV0IHtcbiAgZm9udC1zaXplOiAxM3B4O1xuICBsaW5lLWhlaWdodDogbm9ybWFsO1xuICB1c2VyLXNlbGVjdDogbm9uZTtcbiAgLW1vei11c2VyLXNlbGVjdDogbm9uZTtcbiAgZm9udC1mYW1pbHk6ICdMYXRvJywgJ1NvdXJjZSBTYW5zIFBybycsIFJvYm90bywgSGVsdmV0aWNhLCBBcmlhbCwgc2Fucy1zZXJpZjtcbiAgYm94LXNpemluZzogY29udGVudC1ib3g7XG4gIGJhY2tncm91bmQ6ICNmZmY7XG4gIC13ZWJraXQtZm9udC1zbW9vdGhpbmc6IGFudGlhbGlhc2VkO1xufVxuLngtc3ByZWFkc2hlZXQgdGV4dGFyZWEge1xuICBmb250OiA0MDAgMTNweCBBcmlhbCwgJ0xhdG8nLCAnU291cmNlIFNhbnMgUHJvJywgUm9ib3RvLCBIZWx2ZXRpY2EsIHNhbnMtc2VyaWY7XG59XG4ueC1zcHJlYWRzaGVldC1zaGVldCB7XG4gIHBvc2l0aW9uOiByZWxhdGl2ZTtcbiAgb3ZlcmZsb3c6IGhpZGRlbjtcbn1cbi54LXNwcmVhZHNoZWV0LXRhYmxlIHtcbiAgdmVydGljYWwtYWxpZ246IGJvdHRvbTtcbn1cbi54LXNwcmVhZHNoZWV0LXRvb2x0aXAge1xuICBmb250LWZhbWlseTogaW5oZXJpdDtcbiAgcG9zaXRpb246IGFic29sdXRlO1xuICBwYWRkaW5nOiA1cHggMTBweDtcbiAgY29sb3I6ICNmZmY7XG4gIGJvcmRlci1yYWRpdXM6IDFweDtcbiAgYmFja2dyb3VuZDogIzAwMDAwMDtcbiAgZm9udC1zaXplOiAxMnB4O1xuICB6LWluZGV4OiAyMDE7XG59XG4ueC1zcHJlYWRzaGVldC10b29sdGlwOmJlZm9yZSB7XG4gIHBvaW50ZXItZXZlbnRzOiBub25lO1xuICBwb3NpdGlvbjogYWJzb2x1dGU7XG4gIGxlZnQ6IGNhbGMoNTAlIC0gNHB4KTtcbiAgdG9wOiAtNHB4O1xuICBjb250ZW50OiBcIlwiO1xuICB3aWR0aDogOHB4O1xuICBoZWlnaHQ6IDhweDtcbiAgYmFja2dyb3VuZDogaW5oZXJpdDtcbiAgLXdlYmtpdC10cmFuc2Zvcm06IHJvdGF0ZSg0NWRlZyk7XG4gIHRyYW5zZm9ybTogcm90YXRlKDQ1ZGVnKTtcbiAgei1pbmRleDogMTtcbiAgYm94LXNoYWRvdzogMXB4IDFweCAzcHggLTFweCByZ2JhKDAsIDAsIDAsIDAuMyk7XG59XG4ueC1zcHJlYWRzaGVldC1jb2xvci1wYWxldHRlIHtcbiAgcGFkZGluZzogNXB4O1xufVxuLngtc3ByZWFkc2hlZXQtY29sb3ItcGFsZXR0ZSB0YWJsZSB7XG4gIG1hcmdpbjogMDtcbiAgcGFkZGluZzogMDtcbiAgYm9yZGVyLWNvbGxhcHNlOiBzZXBhcmF0ZTtcbiAgYm9yZGVyLXNwYWNpbmc6IDI7XG4gIGJhY2tncm91bmQ6ICNmZmY7XG59XG4ueC1zcHJlYWRzaGVldC1jb2xvci1wYWxldHRlIHRhYmxlIHRkIHtcbiAgbWFyZ2luOiAwO1xuICBjdXJzb3I6IHBvaW50ZXI7XG4gIGJvcmRlcjogMXB4IHNvbGlkIHRyYW5zcGFyZW50O1xufVxuLngtc3ByZWFkc2hlZXQtY29sb3ItcGFsZXR0ZSB0YWJsZSB0ZDpob3ZlciB7XG4gIGJvcmRlci1jb2xvcjogI2RkZDtcbn1cbi54LXNwcmVhZHNoZWV0LWNvbG9yLXBhbGV0dGUgdGFibGUgdGQgLngtc3ByZWFkc2hlZXQtY29sb3ItcGFsZXR0ZS1jZWxsIHtcbiAgd2lkdGg6IDE2cHg7XG4gIGhlaWdodDogMTZweDtcbn1cbi54LXNwcmVhZHNoZWV0LWJvcmRlci1wYWxldHRlIHtcbiAgcGFkZGluZzogNnB4O1xufVxuLngtc3ByZWFkc2hlZXQtYm9yZGVyLXBhbGV0dGUgdGFibGUge1xuICBtYXJnaW46IDA7XG4gIHBhZGRpbmc6IDA7XG4gIGJvcmRlci1jb2xsYXBzZTogc2VwYXJhdGU7XG4gIGJvcmRlci1zcGFjaW5nOiAwO1xuICBiYWNrZ3JvdW5kOiAjZmZmO1xuICB0YWJsZS1sYXlvdXQ6IGZpeGVkO1xufVxuLngtc3ByZWFkc2hlZXQtYm9yZGVyLXBhbGV0dGUgdGFibGUgdGQge1xuICBtYXJnaW46IDA7XG59XG4ueC1zcHJlYWRzaGVldC1ib3JkZXItcGFsZXR0ZSAueC1zcHJlYWRzaGVldC1ib3JkZXItcGFsZXR0ZS1sZWZ0IHtcbiAgYm9yZGVyLXJpZ2h0OiAxcHggc29saWQgI2VlZTtcbiAgcGFkZGluZy1yaWdodDogNnB4O1xufVxuLngtc3ByZWFkc2hlZXQtYm9yZGVyLXBhbGV0dGUgLngtc3ByZWFkc2hlZXQtYm9yZGVyLXBhbGV0dGUtbGVmdCAueC1zcHJlYWRzaGVldC1ib3JkZXItcGFsZXR0ZS1jZWxsIHtcbiAgd2lkdGg6IDMwcHg7XG4gIGhlaWdodDogMzBweDtcbiAgY3Vyc29yOiBwb2ludGVyO1xuICB0ZXh0LWFsaWduOiBjZW50ZXI7XG59XG4ueC1zcHJlYWRzaGVldC1ib3JkZXItcGFsZXR0ZSAueC1zcHJlYWRzaGVldC1ib3JkZXItcGFsZXR0ZS1sZWZ0IC54LXNwcmVhZHNoZWV0LWJvcmRlci1wYWxldHRlLWNlbGwgLngtc3ByZWFkc2hlZXQtaWNvbi1pbWcge1xuICBvcGFjaXR5OiAwLjg7XG59XG4ueC1zcHJlYWRzaGVldC1ib3JkZXItcGFsZXR0ZSAueC1zcHJlYWRzaGVldC1ib3JkZXItcGFsZXR0ZS1sZWZ0IC54LXNwcmVhZHNoZWV0LWJvcmRlci1wYWxldHRlLWNlbGw6aG92ZXIge1xuICBiYWNrZ3JvdW5kLWNvbG9yOiAjZWVlO1xufVxuLngtc3ByZWFkc2hlZXQtYm9yZGVyLXBhbGV0dGUgLngtc3ByZWFkc2hlZXQtYm9yZGVyLXBhbGV0dGUtcmlnaHQge1xuICBwYWRkaW5nLWxlZnQ6IDZweDtcbn1cbi54LXNwcmVhZHNoZWV0LWJvcmRlci1wYWxldHRlIC54LXNwcmVhZHNoZWV0LWJvcmRlci1wYWxldHRlLXJpZ2h0IC54LXNwcmVhZHNoZWV0LXRvb2xiYXItYnRuIHtcbiAgbWFyZ2luLXRvcDogMDtcbiAgbWFyZ2luLWJvdHRvbTogM3B4O1xufVxuLngtc3ByZWFkc2hlZXQtYm9yZGVyLXBhbGV0dGUgLngtc3ByZWFkc2hlZXQtYm9yZGVyLXBhbGV0dGUtcmlnaHQgLngtc3ByZWFkc2hlZXQtbGluZS10eXBlIHtcbiAgcG9zaXRpb246IHJlbGF0aXZlO1xuICBsZWZ0OiAwO1xuICB0b3A6IC0zcHg7XG59XG4ueC1zcHJlYWRzaGVldC1kcm9wZG93biB7XG4gIHBvc2l0aW9uOiByZWxhdGl2ZTtcbn1cbi54LXNwcmVhZHNoZWV0LWRyb3Bkb3duIC54LXNwcmVhZHNoZWV0LWRyb3Bkb3duLWNvbnRlbnQge1xuICBwb3NpdGlvbjogYWJzb2x1dGU7XG4gIHotaW5kZXg6IDIwMDtcbiAgYmFja2dyb3VuZDogI2ZmZjtcbiAgYm94LXNoYWRvdzogMXB4IDJweCA1cHggMnB4IHJnYmEoNTEsIDUxLCA1MSwgMC4xNSk7XG59XG4ueC1zcHJlYWRzaGVldC1kcm9wZG93bi5ib3R0b20tbGVmdCAueC1zcHJlYWRzaGVldC1kcm9wZG93bi1jb250ZW50IHtcbiAgdG9wOiBjYWxjKDEwMCUgKyA1cHgpO1xuICBsZWZ0OiAwO1xufVxuLngtc3ByZWFkc2hlZXQtZHJvcGRvd24uYm90dG9tLXJpZ2h0IC54LXNwcmVhZHNoZWV0LWRyb3Bkb3duLWNvbnRlbnQge1xuICB0b3A6IGNhbGMoMTAwJSArIDVweCk7XG4gIHJpZ2h0OiAwO1xufVxuLngtc3ByZWFkc2hlZXQtZHJvcGRvd24udG9wLWxlZnQgLngtc3ByZWFkc2hlZXQtZHJvcGRvd24tY29udGVudCB7XG4gIGJvdHRvbTogY2FsYygxMDAlICsgNXB4KTtcbiAgbGVmdDogMDtcbn1cbi54LXNwcmVhZHNoZWV0LWRyb3Bkb3duLnRvcC1yaWdodCAueC1zcHJlYWRzaGVldC1kcm9wZG93bi1jb250ZW50IHtcbiAgYm90dG9tOiBjYWxjKDEwMCUgKyA1cHgpO1xuICByaWdodDogMDtcbn1cbi54LXNwcmVhZHNoZWV0LWRyb3Bkb3duIC54LXNwcmVhZHNoZWV0LWRyb3Bkb3duLXRpdGxlIHtcbiAgcGFkZGluZzogMCA1cHg7XG4gIGRpc3BsYXk6IGlubGluZS1ibG9jaztcbn1cbi54LXNwcmVhZHNoZWV0LWRyb3Bkb3duIC54LXNwcmVhZHNoZWV0LWRyb3Bkb3duLWhlYWRlciAueC1zcHJlYWRzaGVldC1pY29uLmFycm93LWxlZnQge1xuICBtYXJnaW4tbGVmdDogNHB4O1xufVxuLngtc3ByZWFkc2hlZXQtZHJvcGRvd24gLngtc3ByZWFkc2hlZXQtZHJvcGRvd24taGVhZGVyIC54LXNwcmVhZHNoZWV0LWljb24uYXJyb3ctcmlnaHQge1xuICB3aWR0aDogMTBweDtcbiAgbWFyZ2luLXJpZ2h0OiA0cHg7XG59XG4ueC1zcHJlYWRzaGVldC1kcm9wZG93biAueC1zcHJlYWRzaGVldC1kcm9wZG93bi1oZWFkZXIgLngtc3ByZWFkc2hlZXQtaWNvbi5hcnJvdy1yaWdodCAuYXJyb3ctZG93biB7XG4gIGxlZnQ6IC0xMzBweDtcbn1cbi8qIHJlc2l6ZXIgKiovXG4ueC1zcHJlYWRzaGVldC1yZXNpemVyIHtcbiAgcG9zaXRpb246IGFic29sdXRlO1xuICB6LWluZGV4OiAxMTtcbn1cbi54LXNwcmVhZHNoZWV0LXJlc2l6ZXIgLngtc3ByZWFkc2hlZXQtcmVzaXplci1ob3ZlciB7XG4gIGJhY2tncm91bmQtY29sb3I6IHJnYmEoNzUsIDEzNywgMjU1LCAwLjI1KTtcbn1cbi54LXNwcmVhZHNoZWV0LXJlc2l6ZXIgLngtc3ByZWFkc2hlZXQtcmVzaXplci1saW5lIHtcbiAgcG9zaXRpb246IGFic29sdXRlO1xufVxuLngtc3ByZWFkc2hlZXQtcmVzaXplci5ob3Jpem9udGFsIHtcbiAgY3Vyc29yOiByb3ctcmVzaXplO1xufVxuLngtc3ByZWFkc2hlZXQtcmVzaXplci5ob3Jpem9udGFsIC54LXNwcmVhZHNoZWV0LXJlc2l6ZXItbGluZSB7XG4gIGJvcmRlci1ib3R0b206IDJweCBkYXNoZWQgIzRiODlmZjtcbiAgbGVmdDogMDtcbiAgYm90dG9tOiAwO1xufVxuLngtc3ByZWFkc2hlZXQtcmVzaXplci52ZXJ0aWNhbCB7XG4gIGN1cnNvcjogY29sLXJlc2l6ZTtcbn1cbi54LXNwcmVhZHNoZWV0LXJlc2l6ZXIudmVydGljYWwgLngtc3ByZWFkc2hlZXQtcmVzaXplci1saW5lIHtcbiAgYm9yZGVyLXJpZ2h0OiAycHggZGFzaGVkICM0Yjg5ZmY7XG4gIHRvcDogMDtcbiAgcmlnaHQ6IDA7XG59XG4vKiBzY3JvbGxiYXIgKi9cbi54LXNwcmVhZHNoZWV0LXNjcm9sbGJhciB7XG4gIHBvc2l0aW9uOiBhYnNvbHV0ZTtcbiAgYm90dG9tOiAwO1xuICByaWdodDogMDtcbiAgYmFja2dyb3VuZC1jb2xvcjogI2Y0ZjVmODtcbiAgb3BhY2l0eTogMC45O1xuICB6LWluZGV4OiAxMjtcbn1cbi54LXNwcmVhZHNoZWV0LXNjcm9sbGJhci5ob3Jpem9udGFsIHtcbiAgcmlnaHQ6IDE1cHg7XG4gIG92ZXJmbG93LXg6IHNjcm9sbDtcbiAgb3ZlcmZsb3cteTogaGlkZGVuO1xufVxuLngtc3ByZWFkc2hlZXQtc2Nyb2xsYmFyLmhvcml6b250YWwgPiBkaXYge1xuICBoZWlnaHQ6IDFweDtcbiAgYmFja2dyb3VuZDogI2RkZDtcbn1cbi54LXNwcmVhZHNoZWV0LXNjcm9sbGJhci52ZXJ0aWNhbCB7XG4gIGJvdHRvbTogMTVweDtcbiAgb3ZlcmZsb3cteDogaGlkZGVuO1xuICBvdmVyZmxvdy15OiBzY3JvbGw7XG59XG4ueC1zcHJlYWRzaGVldC1zY3JvbGxiYXIudmVydGljYWwgPiBkaXYge1xuICB3aWR0aDogMXB4O1xuICBiYWNrZ3JvdW5kOiAjZGRkO1xufVxuLyogQHtjc3MtcHJlZml4fS1vdmVybGF5ZXIgKi9cbi54LXNwcmVhZHNoZWV0LW92ZXJsYXllciB7XG4gIHBvc2l0aW9uOiBhYnNvbHV0ZTtcbiAgbGVmdDogMDtcbiAgdG9wOiAwO1xuICB6LWluZGV4OiAxMDtcbn1cbi54LXNwcmVhZHNoZWV0LW92ZXJsYXllciAueC1zcHJlYWRzaGVldC1vdmVybGF5ZXItY29udGVudCB7XG4gIHBvc2l0aW9uOiBhYnNvbHV0ZTtcbiAgb3ZlcmZsb3c6IGhpZGRlbjtcbiAgcG9pbnRlci1ldmVudHM6IG5vbmU7XG4gIHdpZHRoOiAxMDAlO1xuICBoZWlnaHQ6IDEwMCU7XG59XG4ueC1zcHJlYWRzaGVldC1lZGl0b3IsXG4ueC1zcHJlYWRzaGVldC1zZWxlY3RvciB7XG4gIGJveC1zaXppbmc6IGNvbnRlbnQtYm94O1xuICBwb3NpdGlvbjogYWJzb2x1dGU7XG4gIG92ZXJmbG93OiBoaWRkZW47XG4gIHBvaW50ZXItZXZlbnRzOiBub25lO1xuICB0b3A6IDA7XG4gIGxlZnQ6IDA7XG4gIHdpZHRoOiAxMDAlO1xuICBoZWlnaHQ6IDEwMCU7XG59XG4vKiBAe2Nzcy1wcmVmaXh9LXNlbGVjdG9yICovXG4ueC1zcHJlYWRzaGVldC1zZWxlY3RvciAuaGlkZS1pbnB1dCB7XG4gIHBvc2l0aW9uOiBhYnNvbHV0ZTtcbiAgei1pbmRleDogMDtcbn1cbi54LXNwcmVhZHNoZWV0LXNlbGVjdG9yIC5oaWRlLWlucHV0IGlucHV0IHtcbiAgcGFkZGluZzogMDtcbiAgd2lkdGg6IDA7XG4gIGJvcmRlcjogbm9uZSFpbXBvcnRhbnQ7XG59XG4ueC1zcHJlYWRzaGVldC1zZWxlY3RvciAueC1zcHJlYWRzaGVldC1zZWxlY3Rvci1hcmVhIHtcbiAgcG9zaXRpb246IGFic29sdXRlO1xuICBib3JkZXI6IDJweCBzb2xpZCAjNGI4OWZmO1xuICBiYWNrZ3JvdW5kOiByZ2JhKDc1LCAxMzcsIDI1NSwgMC4xKTtcbiAgei1pbmRleDogNTtcbn1cbi54LXNwcmVhZHNoZWV0LXNlbGVjdG9yIC54LXNwcmVhZHNoZWV0LXNlbGVjdG9yLWNsaXBib2FyZCxcbi54LXNwcmVhZHNoZWV0LXNlbGVjdG9yIC54LXNwcmVhZHNoZWV0LXNlbGVjdG9yLWF1dG9maWxsIHtcbiAgcG9zaXRpb246IGFic29sdXRlO1xuICBiYWNrZ3JvdW5kOiB0cmFuc3BhcmVudDtcbiAgei1pbmRleDogMTAwO1xufVxuLngtc3ByZWFkc2hlZXQtc2VsZWN0b3IgLngtc3ByZWFkc2hlZXQtc2VsZWN0b3ItY2xpcGJvYXJkIHtcbiAgYm9yZGVyOiAycHggZGFzaGVkICM0Yjg5ZmY7XG59XG4ueC1zcHJlYWRzaGVldC1zZWxlY3RvciAueC1zcHJlYWRzaGVldC1zZWxlY3Rvci1hdXRvZmlsbCB7XG4gIGJvcmRlcjogMXB4IGRhc2hlZCByZ2JhKDAsIDAsIDAsIDAuNDUpO1xufVxuLngtc3ByZWFkc2hlZXQtc2VsZWN0b3IgLngtc3ByZWFkc2hlZXQtc2VsZWN0b3ItY29ybmVyIHtcbiAgcG9pbnRlci1ldmVudHM6IGF1dG87XG4gIHBvc2l0aW9uOiBhYnNvbHV0ZTtcbiAgY3Vyc29yOiBjcm9zc2hhaXI7XG4gIGZvbnQtc2l6ZTogMDtcbiAgaGVpZ2h0OiA1cHg7XG4gIHdpZHRoOiA1cHg7XG4gIHJpZ2h0OiAtNXB4O1xuICBib3R0b206IC01cHg7XG4gIGJvcmRlcjogMnB4IHNvbGlkICNmZmZmZmY7XG4gIGJhY2tncm91bmQ6ICM0Yjg5ZmY7XG59XG4ueC1zcHJlYWRzaGVldC1lZGl0b3Ige1xuICB6LWluZGV4OiAyMDtcbn1cbi54LXNwcmVhZHNoZWV0LWVkaXRvciAueC1zcHJlYWRzaGVldC1lZGl0b3ItYXJlYSB7XG4gIHBvc2l0aW9uOiBhYnNvbHV0ZTtcbiAgdGV4dC1hbGlnbjogbGVmdDtcbiAgYm9yZGVyOiAycHggc29saWQgIzRiODlmZjtcbiAgbGluZS1oZWlnaHQ6IDA7XG4gIHotaW5kZXg6IDEwMDtcbiAgcG9pbnRlci1ldmVudHM6IGF1dG87XG59XG4ueC1zcHJlYWRzaGVldC1lZGl0b3IgLngtc3ByZWFkc2hlZXQtZWRpdG9yLWFyZWEgdGV4dGFyZWEge1xuICBib3gtc2l6aW5nOiBjb250ZW50LWJveDtcbiAgYm9yZGVyOiBub25lO1xuICBwYWRkaW5nOiAwIDNweDtcbiAgb3V0bGluZTogbm9uZTtcbiAgcmVzaXplOiBub25lO1xuICB0ZXh0LWFsaWduOiBzdGFydDtcbiAgb3ZlcmZsb3cteTogaGlkZGVuO1xuICBmb250OiA0MDAgMTNweCBBcmlhbCwgJ0xhdG8nLCAnU291cmNlIFNhbnMgUHJvJywgUm9ib3RvLCBIZWx2ZXRpY2EsIHNhbnMtc2VyaWY7XG4gIGNvbG9yOiBpbmhlcml0O1xuICB3aGl0ZS1zcGFjZTogbm9ybWFsO1xuICB3b3JkLXdyYXA6IGJyZWFrLXdvcmQ7XG4gIGxpbmUtaGVpZ2h0OiAyMnB4O1xuICBtYXJnaW46IDA7XG59XG4ueC1zcHJlYWRzaGVldC1lZGl0b3IgLngtc3ByZWFkc2hlZXQtZWRpdG9yLWFyZWEgLnRleHRsaW5lIHtcbiAgb3ZlcmZsb3c6IGhpZGRlbjtcbiAgdmlzaWJpbGl0eTogaGlkZGVuO1xuICBwb3NpdGlvbjogZml4ZWQ7XG4gIHRvcDogMDtcbiAgbGVmdDogMDtcbn1cbi54LXNwcmVhZHNoZWV0LWl0ZW0ge1xuICB1c2VyLXNlbGVjdDogbm9uZTtcbiAgYmFja2dyb3VuZDogMDtcbiAgYm9yZGVyOiAxcHggc29saWQgdHJhbnNwYXJlbnQ7XG4gIG91dGxpbmU6IG5vbmU7XG4gIGhlaWdodDogMjZweDtcbiAgY29sb3I6IHJnYmEoMCwgMCwgMCwgMC45KTtcbiAgbGluZS1oZWlnaHQ6IDI2cHg7XG4gIGxpc3Qtc3R5bGU6IG5vbmU7XG4gIHBhZGRpbmc6IDJweCAxMHB4O1xuICBjdXJzb3I6IGRlZmF1bHQ7XG4gIHRleHQtYWxpZ246IGxlZnQ7XG4gIG92ZXJmbG93OiBoaWRkZW47XG59XG4ueC1zcHJlYWRzaGVldC1pdGVtLmRpc2FibGVkIHtcbiAgcG9pbnRlci1ldmVudHM6IG5vbmU7XG4gIG9wYWNpdHk6IDAuNTtcbn1cbi54LXNwcmVhZHNoZWV0LWl0ZW06aG92ZXIsXG4ueC1zcHJlYWRzaGVldC1pdGVtLmFjdGl2ZSB7XG4gIGJhY2tncm91bmQ6IHJnYmEoMCwgMCwgMCwgMC4wNSk7XG59XG4ueC1zcHJlYWRzaGVldC1pdGVtLmRpdmlkZXIge1xuICBoZWlnaHQ6IDA7XG4gIHBhZGRpbmc6IDA7XG4gIG1hcmdpbjogNXB4IDA7XG4gIGJvcmRlcjogbm9uZTtcbiAgYm9yZGVyLWJvdHRvbTogMXB4IHNvbGlkIHJnYmEoMCwgMCwgMCwgMC4xKTtcbn1cbi54LXNwcmVhZHNoZWV0LWl0ZW0gLmxhYmVsIHtcbiAgZmxvYXQ6IHJpZ2h0O1xuICBvcGFjaXR5OiAwLjY1O1xuICBmb250LXNpemU6IDFlbTtcbn1cbi54LXNwcmVhZHNoZWV0LWl0ZW0uc3RhdGUsXG4ueC1zcHJlYWRzaGVldC1oZWFkZXIuc3RhdGUge1xuICBwYWRkaW5nLWxlZnQ6IDM1cHghaW1wb3J0YW50O1xuICBwb3NpdGlvbjogcmVsYXRpdmU7XG59XG4ueC1zcHJlYWRzaGVldC1pdGVtLnN0YXRlOmJlZm9yZSxcbi54LXNwcmVhZHNoZWV0LWhlYWRlci5zdGF0ZTpiZWZvcmUge1xuICBjb250ZW50OiAnJztcbiAgcG9zaXRpb246IGFic29sdXRlO1xuICB3aWR0aDogMTBweDtcbiAgaGVpZ2h0OiAxMHB4O1xuICBsZWZ0OiAxMnB4O1xuICB0b3A6IGNhbGMoNTAlIC0gNXB4KTtcbiAgYmFja2dyb3VuZDogcmdiYSgwLCAwLCAwLCAwLjA4KTtcbiAgYm9yZGVyLXJhZGl1czogMnB4O1xufVxuLngtc3ByZWFkc2hlZXQtaXRlbS5zdGF0ZS5jaGVja2VkOmJlZm9yZSxcbi54LXNwcmVhZHNoZWV0LWhlYWRlci5zdGF0ZS5jaGVja2VkOmJlZm9yZSB7XG4gIGJhY2tncm91bmQ6ICM0Yjg5ZmY7XG59XG4ueC1zcHJlYWRzaGVldC1jaGVja2JveCB7XG4gIHBvc2l0aW9uOiByZWxhdGl2ZTtcbiAgZGlzcGxheTogaW5saW5lLWJsb2NrO1xuICBiYWNrZmFjZS12aXNpYmlsaXR5OiBoaWRkZW47XG4gIG91dGxpbmU6IDA7XG4gIHZlcnRpY2FsLWFsaWduOiBiYXNlbGluZTtcbiAgZm9udC1zdHlsZTogbm9ybWFsO1xuICBmb250LXNpemU6IDFyZW07XG4gIGxpbmUtaGVpZ2h0OiAxZW07XG59XG4ueC1zcHJlYWRzaGVldC1jaGVja2JveCA+IGlucHV0IHtcbiAgcG9zaXRpb246IGFic29sdXRlO1xuICB0b3A6IDA7XG4gIGxlZnQ6IDA7XG4gIG9wYWNpdHk6IDAhaW1wb3J0YW50O1xuICBvdXRsaW5lOiAwO1xuICB6LWluZGV4OiAtMTtcbn1cbi54LXNwcmVhZHNoZWV0LXN1Z2dlc3QsXG4ueC1zcHJlYWRzaGVldC1jb250ZXh0bWVudSxcbi54LXNwcmVhZHNoZWV0LXNvcnQtZmlsdGVyIHtcbiAgcG9zaXRpb246IGFic29sdXRlO1xuICBib3gtc2hhZG93OiAxcHggMnB4IDVweCAycHggcmdiYSg1MSwgNTEsIDUxLCAwLjE1KTtcbiAgYmFja2dyb3VuZDogI2ZmZjtcbiAgei1pbmRleDogMTAwO1xuICB3aWR0aDogMjYwcHg7XG4gIHBvaW50ZXItZXZlbnRzOiBhdXRvO1xuICBvdmVyZmxvdzogYXV0bztcbn1cbi54LXNwcmVhZHNoZWV0LXN1Z2dlc3Qge1xuICB3aWR0aDogMjAwcHg7XG59XG4ueC1zcHJlYWRzaGVldC1maWx0ZXIge1xuICBib3JkZXI6IDFweCBzb2xpZCAjZTllOWU5O1xuICBmb250LXNpemU6IDEycHg7XG4gIG1hcmdpbjogMTBweDtcbn1cbi54LXNwcmVhZHNoZWV0LWZpbHRlciAueC1zcHJlYWRzaGVldC1oZWFkZXIge1xuICBwYWRkaW5nOiAwLjVlbSAwLjc1ZW07XG4gIGJhY2tncm91bmQ6ICNmOGY4Zjk7XG4gIGJvcmRlci1ib3R0b206IDFweCBzb2xpZCAjZTllOWU5O1xuICBib3JkZXItbGVmdDogMXB4IHNvbGlkIHRyYW5zcGFyZW50O1xufVxuLngtc3ByZWFkc2hlZXQtZmlsdGVyIC54LXNwcmVhZHNoZWV0LWJvZHkge1xuICBoZWlnaHQ6IDIwMHB4O1xuICBvdmVyZmxvdy15OiBhdXRvO1xufVxuLngtc3ByZWFkc2hlZXQtZmlsdGVyIC54LXNwcmVhZHNoZWV0LWJvZHkgLngtc3ByZWFkc2hlZXQtaXRlbSB7XG4gIGhlaWdodDogMjBweDtcbiAgbGluZS1oZWlnaHQ6IDIwcHg7XG59XG4ueC1zcHJlYWRzaGVldC1zb3J0LWZpbHRlciAueC1zcHJlYWRzaGVldC1idXR0b25zIHtcbiAgbWFyZ2luOiAxMHB4O1xufVxuLngtc3ByZWFkc2hlZXQtdG9vbGJhcixcbi54LXNwcmVhZHNoZWV0LWJvdHRvbWJhciB7XG4gIGhlaWdodDogNDBweDtcbiAgcGFkZGluZzogMCAzMHB4O1xuICB0ZXh0LWFsaWduOiBsZWZ0O1xuICBiYWNrZ3JvdW5kOiAjZjVmNmY3O1xuICBkaXNwbGF5OiBmbGV4O1xufVxuLngtc3ByZWFkc2hlZXQtYm90dG9tYmFyIHtcbiAgcG9zaXRpb246IHJlbGF0aXZlO1xuICBib3JkZXItdG9wOiAxcHggc29saWQgI2UwZTJlNDtcbn1cbi54LXNwcmVhZHNoZWV0LWJvdHRvbWJhciAueC1zcHJlYWRzaGVldC1tZW51ID4gbGkge1xuICBsaW5lLWhlaWdodDogNDBweDtcbiAgaGVpZ2h0OiA0MHB4O1xuICBwYWRkaW5nLXRvcDogMDtcbiAgcGFkZGluZy1ib3R0b206IDA7XG4gIHZlcnRpY2FsLWFsaWduOiBtaWRkbGU7XG4gIGJvcmRlci1yaWdodDogMXB4IHNvbGlkICNlOGVhZWQ7XG59XG4ueC1zcHJlYWRzaGVldC1tZW51IHtcbiAgbGlzdC1zdHlsZTogbm9uZTtcbiAgbWFyZ2luOiAwO1xuICBwYWRkaW5nOiAwO1xuICB1c2VyLXNlbGVjdDogbm9uZTtcbn1cbi54LXNwcmVhZHNoZWV0LW1lbnUgPiBsaSB7XG4gIGZsb2F0OiBsZWZ0O1xuICBsaW5lLWhlaWdodDogMS4yNWVtO1xuICBwYWRkaW5nOiAwLjc4NWVtIDFlbTtcbiAgbWFyZ2luOiAwO1xuICB2ZXJ0aWNhbC1hbGlnbjogbWlkZGxlO1xuICB0ZXh0LWFsaWduOiBsZWZ0O1xuICBmb250LXdlaWdodDogNDAwO1xuICBjb2xvcjogIzgwODY4YjtcbiAgd2hpdGUtc3BhY2U6IG5vd3JhcDtcbiAgY3Vyc29yOiBwb2ludGVyO1xuICB0cmFuc2l0aW9uOiBhbGwgMC4zcztcbiAgZm9udC13ZWlnaHQ6IGJvbGQ7XG59XG4ueC1zcHJlYWRzaGVldC1tZW51ID4gbGkuYWN0aXZlIHtcbiAgYmFja2dyb3VuZC1jb2xvcjogI2ZmZjtcbiAgY29sb3I6IHJnYmEoMCwgMCwgMCwgMC42NSk7XG59XG4ueC1zcHJlYWRzaGVldC1tZW51ID4gbGkgLngtc3ByZWFkc2hlZXQtaWNvbiB7XG4gIG1hcmdpbjogMCA2cHg7XG59XG4ueC1zcHJlYWRzaGVldC1tZW51ID4gbGkgLngtc3ByZWFkc2hlZXQtaWNvbiAueC1zcHJlYWRzaGVldC1pY29uLWltZzpob3ZlciB7XG4gIG9wYWNpdHk6IDAuODU7XG59XG4ueC1zcHJlYWRzaGVldC1tZW51ID4gbGkgLngtc3ByZWFkc2hlZXQtZHJvcGRvd24ge1xuICBkaXNwbGF5OiBpbmxpbmUtYmxvY2s7XG59XG4ueC1zcHJlYWRzaGVldC10b29sYmFyIHtcbiAgYm9yZGVyLWJvdHRvbTogMXB4IHNvbGlkICNlMGUyZTQ7XG59XG4ueC1zcHJlYWRzaGVldC10b29sYmFyIC54LXNwcmVhZHNoZWV0LXRvb2xiYXItYnRucyB7XG4gIGRpc3BsYXk6IGlubGluZS1mbGV4O1xufVxuLngtc3ByZWFkc2hlZXQtdG9vbGJhciAueC1zcHJlYWRzaGVldC10b29sYmFyLW1vcmUge1xuICBwYWRkaW5nOiAwIDZweCA2cHg7XG4gIHRleHQtYWxpZ246IGxlZnQ7XG59XG4ueC1zcHJlYWRzaGVldC10b29sYmFyIC54LXNwcmVhZHNoZWV0LXRvb2xiYXItbW9yZSAueC1zcHJlYWRzaGVldC10b29sYmFyLWRpdmlkZXIge1xuICBtYXJnaW4tdG9wOiAwO1xufVxuLngtc3ByZWFkc2hlZXQtdG9vbGJhciAueC1zcHJlYWRzaGVldC10b29sYmFyLWJ0biB7XG4gIGZsZXg6IDAgMCBhdXRvO1xuICBkaXNwbGF5OiBpbmxpbmUtYmxvY2s7XG4gIGJvcmRlcjogMXB4IHNvbGlkIHRyYW5zcGFyZW50O1xuICBoZWlnaHQ6IDI2cHg7XG4gIGxpbmUtaGVpZ2h0OiAyNnB4O1xuICBtaW4td2lkdGg6IDI2cHg7XG4gIG1hcmdpbjogNnB4IDFweCAwO1xuICBwYWRkaW5nOiAwO1xuICB0ZXh0LWFsaWduOiBjZW50ZXI7XG4gIGJvcmRlci1yYWRpdXM6IDJweDtcbn1cbi54LXNwcmVhZHNoZWV0LXRvb2xiYXIgLngtc3ByZWFkc2hlZXQtdG9vbGJhci1idG4uZGlzYWJsZWQge1xuICBwb2ludGVyLWV2ZW50czogbm9uZTtcbiAgb3BhY2l0eTogMC41O1xufVxuLngtc3ByZWFkc2hlZXQtdG9vbGJhciAueC1zcHJlYWRzaGVldC10b29sYmFyLWJ0bjpob3Zlcixcbi54LXNwcmVhZHNoZWV0LXRvb2xiYXIgLngtc3ByZWFkc2hlZXQtdG9vbGJhci1idG4uYWN0aXZlIHtcbiAgYmFja2dyb3VuZDogcmdiYSgwLCAwLCAwLCAwLjA4KTtcbn1cbi54LXNwcmVhZHNoZWV0LXRvb2xiYXItZGl2aWRlciB7XG4gIGRpc3BsYXk6IGlubGluZS1ibG9jaztcbiAgYm9yZGVyLXJpZ2h0OiAxcHggc29saWQgI2UwZTJlNDtcbiAgd2lkdGg6IDA7XG4gIHZlcnRpY2FsLWFsaWduOiBtaWRkbGU7XG4gIGhlaWdodDogMThweDtcbiAgbWFyZ2luOiAxMnB4IDNweCAwO1xufVxuLngtc3ByZWFkc2hlZXQtcHJpbnQge1xuICBwb3NpdGlvbjogYWJzb2x1dGU7XG4gIGxlZnQ6IDA7XG4gIHRvcDogMDtcbiAgei1pbmRleDogMTAwO1xuICB3aWR0aDogMTAwJTtcbiAgaGVpZ2h0OiAxMDAlO1xuICBkaXNwbGF5OiBmbGV4O1xuICBmbGV4LWRpcmVjdGlvbjogY29sdW1uO1xufVxuLngtc3ByZWFkc2hlZXQtcHJpbnQtYmFyIHtcbiAgYmFja2dyb3VuZDogIzQyNDI0MjtcbiAgaGVpZ2h0OiA2MHB4O1xuICBsaW5lLWhlaWdodDogNjBweDtcbiAgcGFkZGluZzogMCAzMHB4O1xufVxuLngtc3ByZWFkc2hlZXQtcHJpbnQtYmFyIC4tdGl0bGUge1xuICBjb2xvcjogI2ZmZjtcbiAgZm9udC13ZWlnaHQ6IGJvbGQ7XG4gIGZvbnQtc2l6ZTogMS4yZW07XG4gIGZsb2F0OiBsZWZ0O1xufVxuLngtc3ByZWFkc2hlZXQtcHJpbnQtYmFyIC4tcmlnaHQge1xuICBmbG9hdDogcmlnaHQ7XG4gIG1hcmdpbi10b3A6IDEycHg7XG59XG4ueC1zcHJlYWRzaGVldC1wcmludC1jb250ZW50IHtcbiAgZGlzcGxheTogZmxleDtcbiAgZmxleDogYXV0bztcbiAgZmxleC1kaXJlY3Rpb246IHJvdztcbiAgYmFja2dyb3VuZDogI2QwZDBkMDtcbiAgaGVpZ2h0OiBjYWxjKDEwMCUgLSA2MHB4KTtcbn1cbi54LXNwcmVhZHNoZWV0LXByaW50LWNvbnRlbnQgLi1zaWRlciB7XG4gIGZsZXg6IDAgMCAzMDBweDtcbiAgd2lkdGg6IDMwMHB4O1xuICBib3JkZXItbGVmdDogMnB4IHNvbGlkICNjY2M7XG4gIGJhY2tncm91bmQ6ICNmZmY7XG59XG4ueC1zcHJlYWRzaGVldC1wcmludC1jb250ZW50IC4tY29udGVudCB7XG4gIGZsZXg6IGF1dG87XG4gIG92ZXJmbG93LXg6IGF1dG87XG4gIG92ZXJmbG93LXk6IHNjcm9sbDtcbiAgaGVpZ2h0OiAxMDAlO1xufVxuLngtc3ByZWFkc2hlZXQtY2FudmFzLWNhcmQtd3JhcGVyIHtcbiAgbWFyZ2luOiA0MHB4IDIwcHg7XG59XG4ueC1zcHJlYWRzaGVldC1jYW52YXMtY2FyZCB7XG4gIGJhY2tncm91bmQ6ICNmZmY7XG4gIG1hcmdpbjogYXV0bztcbiAgcGFnZS1icmVhay1iZWZvcmU6IGF1dG87XG4gIHBhZ2UtYnJlYWstYWZ0ZXI6IGFsd2F5cztcbiAgYm94LXNoYWRvdzogMCA4cHggMTBweCAxcHggcmdiYSgwLCAwLCAwLCAwLjE0KSwgMCAzcHggMTRweCAzcHggcmdiYSgwLCAwLCAwLCAwLjEyKSwgMCA0cHggNXB4IDAgcmdiYSgwLCAwLCAwLCAwLjIpO1xufVxuLngtc3ByZWFkc2hlZXQtY2FsZW5kYXIge1xuICBjb2xvcjogcmdiYSgwLCAwLCAwLCAwLjY1KTtcbiAgYmFja2dyb3VuZDogI2ZmZmZmZjtcbiAgdXNlci1zZWxlY3Q6IG5vbmU7XG59XG4ueC1zcHJlYWRzaGVldC1jYWxlbmRhciAuY2FsZW5kYXItaGVhZGVyIHtcbiAgZm9udC13ZWlnaHQ6IDcwMDtcbiAgbGluZS1oZWlnaHQ6IDMwcHg7XG4gIHRleHQtYWxpZ246IGNlbnRlcjtcbiAgd2lkdGg6IDEwMCU7XG4gIGZsb2F0OiBsZWZ0O1xuICBiYWNrZ3JvdW5kOiAjZjlmYWZiO1xufVxuLngtc3ByZWFkc2hlZXQtY2FsZW5kYXIgLmNhbGVuZGFyLWhlYWRlciAuY2FsZW5kYXItaGVhZGVyLWxlZnQge1xuICBwYWRkaW5nLWxlZnQ6IDVweDtcbiAgZmxvYXQ6IGxlZnQ7XG59XG4ueC1zcHJlYWRzaGVldC1jYWxlbmRhciAuY2FsZW5kYXItaGVhZGVyIC5jYWxlbmRhci1oZWFkZXItcmlnaHQge1xuICBmbG9hdDogcmlnaHQ7XG59XG4ueC1zcHJlYWRzaGVldC1jYWxlbmRhciAuY2FsZW5kYXItaGVhZGVyIC5jYWxlbmRhci1oZWFkZXItcmlnaHQgYSB7XG4gIHBhZGRpbmc6IDNweCAwO1xuICBtYXJnaW4tcmlnaHQ6IDJweDtcbiAgYm9yZGVyLXJhZGl1czogMnB4O1xufVxuLngtc3ByZWFkc2hlZXQtY2FsZW5kYXIgLmNhbGVuZGFyLWhlYWRlciAuY2FsZW5kYXItaGVhZGVyLXJpZ2h0IGE6aG92ZXIge1xuICBiYWNrZ3JvdW5kOiByZ2JhKDAsIDAsIDAsIDAuMDgpO1xufVxuLngtc3ByZWFkc2hlZXQtY2FsZW5kYXIgLmNhbGVuZGFyLWJvZHkge1xuICBib3JkZXItY29sbGFwc2U6IGNvbGxhcHNlO1xuICBib3JkZXItc3BhY2luZzogMDtcbn1cbi54LXNwcmVhZHNoZWV0LWNhbGVuZGFyIC5jYWxlbmRhci1ib2R5IHRoLFxuLngtc3ByZWFkc2hlZXQtY2FsZW5kYXIgLmNhbGVuZGFyLWJvZHkgdGQge1xuICB3aWR0aDogMTAwJS83O1xuICBtaW4td2lkdGg6IDMycHg7XG4gIHRleHQtYWxpZ246IGNlbnRlcjtcbiAgZm9udC13ZWlnaHQ6IDcwMDtcbiAgbGluZS1oZWlnaHQ6IDMwcHg7XG4gIHBhZGRpbmc6IDA7XG59XG4ueC1zcHJlYWRzaGVldC1jYWxlbmRhciAuY2FsZW5kYXItYm9keSB0ZCA+IC5jZWxsOmhvdmVyIHtcbiAgYmFja2dyb3VuZDogI2VjZjZmZDtcbn1cbi54LXNwcmVhZHNoZWV0LWNhbGVuZGFyIC5jYWxlbmRhci1ib2R5IHRkID4gLmNlbGwuYWN0aXZlLFxuLngtc3ByZWFkc2hlZXQtY2FsZW5kYXIgLmNhbGVuZGFyLWJvZHkgdGQgPiAuY2VsbC5hY3RpdmU6aG92ZXIge1xuICBiYWNrZ3JvdW5kOiAjZWNmNmZkO1xuICBjb2xvcjogIzIxODVEMDtcbn1cbi54LXNwcmVhZHNoZWV0LWNhbGVuZGFyIC5jYWxlbmRhci1ib2R5IHRkID4gLmNlbGwuZGlzYWJsZWQge1xuICBwb2ludGVyLWV2ZW50czogbm9uZTtcbiAgb3BhY2l0eTogMC41O1xufVxuLngtc3ByZWFkc2hlZXQtZGF0ZXBpY2tlciB7XG4gIGJveC1zaGFkb3c6IDJweCAycHggNXB4IHJnYmEoMCwgMCwgMCwgMC4yKTtcbiAgcG9zaXRpb246IGFic29sdXRlO1xuICBsZWZ0OiAwO1xuICB0b3A6IGNhbGMoMTAwJSArIDVweCk7XG4gIHotaW5kZXg6IDEwO1xuICB3aWR0aDogYXV0bztcbn1cbi54LXNwcmVhZHNoZWV0LWJ1dHRvbnMge1xuICBkaXNwbGF5OiBmbGV4O1xuICBqdXN0aWZ5LWNvbnRlbnQ6IGZsZXgtZW5kO1xufVxuLngtc3ByZWFkc2hlZXQtYnV0dG9ucyAueC1zcHJlYWRzaGVldC1idXR0b24ge1xuICBtYXJnaW4tbGVmdDogOHB4O1xufVxuLngtc3ByZWFkc2hlZXQtYnV0dG9uIHtcbiAgZGlzcGxheTogaW5saW5lLWJsb2NrO1xuICBib3JkZXItcmFkaXVzOiAzcHg7XG4gIGxpbmUtaGVpZ2h0OiAxZW07XG4gIG1pbi1oZWlnaHQ6IDFlbTtcbiAgd2hpdGUtc3BhY2U6IG5vd3JhcDtcbiAgdGV4dC1hbGlnbjogY2VudGVyO1xuICBjdXJzb3I6IHBvaW50ZXI7XG4gIGZvbnQtc2l6ZTogMWVtO1xuICBmb250LXdlaWdodDogNzAwO1xuICBwYWRkaW5nOiAwLjc1ZW0gMWVtO1xuICBjb2xvcjogcmdiYSgwLCAwLCAwLCAwLjYpO1xuICBiYWNrZ3JvdW5kOiAjRTBFMUUyO1xuICB0ZXh0LWRlY29yYXRpb246IG5vbmU7XG4gIGZvbnQtZmFtaWx5OiBcIkxhdG9cIiwgXCJwcm94aW1hLW5vdmFcIiwgXCJIZWx2ZXRpY2EgTmV1ZVwiLCBBcmlhbCwgc2Fucy1zZXJpZjtcbiAgb3V0bGluZTogbm9uZTtcbiAgdmVydGljYWwtYWxpZ246IGJhc2VsaW5lO1xuICB6b29tOiAxO1xuICB1c2VyLXNlbGVjdDogbm9uZTtcbiAgdHJhbnNpdGlvbjogYWxsIDAuMXMgbGluZWFyO1xufVxuLngtc3ByZWFkc2hlZXQtYnV0dG9uLmFjdGl2ZSxcbi54LXNwcmVhZHNoZWV0LWJ1dHRvbjpob3ZlciB7XG4gIGJhY2tncm91bmQtY29sb3I6ICNDMEMxQzI7XG4gIGNvbG9yOiByZ2JhKDAsIDAsIDAsIDAuOCk7XG59XG4ueC1zcHJlYWRzaGVldC1idXR0b24ucHJpbWFyeSB7XG4gIGNvbG9yOiAjZmZmO1xuICBiYWNrZ3JvdW5kLWNvbG9yOiAjMjE4NUQwO1xufVxuLngtc3ByZWFkc2hlZXQtYnV0dG9uLnByaW1hcnk6aG92ZXIsXG4ueC1zcHJlYWRzaGVldC1idXR0b24ucHJpbWFyeS5hY3RpdmUge1xuICBjb2xvcjogI2ZmZjtcbiAgYmFja2dyb3VuZC1jb2xvcjogIzE2NzhjMjtcbn1cbi54LXNwcmVhZHNoZWV0LWZvcm0taW5wdXQge1xuICBmb250LXNpemU6IDFlbTtcbiAgcG9zaXRpb246IHJlbGF0aXZlO1xuICBmb250LXdlaWdodDogNDAwO1xuICBkaXNwbGF5OiBpbmxpbmUtZmxleDtcbiAgY29sb3I6IHJnYmEoMCwgMCwgMCwgMC44Nyk7XG59XG4ueC1zcHJlYWRzaGVldC1mb3JtLWlucHV0IGlucHV0IHtcbiAgei1pbmRleDogMTtcbiAgbWFyZ2luOiAwO1xuICBtYXgtd2lkdGg6IDEwMCU7XG4gIGZsZXg6IDEgMCBhdXRvO1xuICBvdXRsaW5lOiAwO1xuICAtd2Via2l0LXRhcC1oaWdobGlnaHQtY29sb3I6IHJnYmEoMjU1LCAyNTUsIDI1NSwgMCk7XG4gIHRleHQtYWxpZ246IGxlZnQ7XG4gIGxpbmUtaGVpZ2h0OiAzMHB4O1xuICBoZWlnaHQ6IDMwcHg7XG4gIHBhZGRpbmc6IDAgOHB4O1xuICBiYWNrZ3JvdW5kOiAjZmZmO1xuICBib3JkZXI6IDFweCBzb2xpZCAjZTllOWU5O1xuICBib3JkZXItcmFkaXVzOiAzcHg7XG4gIHRyYW5zaXRpb246IGJveC1zaGFkb3cgMC4xcyBlYXNlLCBib3JkZXItY29sb3IgMC4xcyBlYXNlO1xuICBib3gtc2hhZG93OiBpbnNldCAwIDFweCAycHggaHNsYSgwLCAwJSwgNCUsIDAuMDYpO1xufVxuLngtc3ByZWFkc2hlZXQtZm9ybS1pbnB1dCBpbnB1dDpmb2N1cyB7XG4gIGJvcmRlci1jb2xvcjogIzRiODlmZjtcbiAgYm94LXNoYWRvdzogaW5zZXQgMCAxcHggMnB4IHJnYmEoNzUsIDEzNywgMjU1LCAwLjIpO1xufVxuLngtc3ByZWFkc2hlZXQtZm9ybS1zZWxlY3Qge1xuICBwb3NpdGlvbjogcmVsYXRpdmU7XG4gIGRpc3BsYXk6IGlubGluZS1ibG9jaztcbiAgYmFja2dyb3VuZDogI2ZmZjtcbiAgYm9yZGVyOiAxcHggc29saWQgI2U5ZTllOTtcbiAgYm9yZGVyLXJhZGl1czogMnB4O1xuICBjdXJzb3I6IHBvaW50ZXI7XG4gIGNvbG9yOiByZ2JhKDAsIDAsIDAsIDAuODcpO1xuICB1c2VyLXNlbGVjdDogbm9uZTtcbiAgYm94LXNoYWRvdzogaW5zZXQgMCAxcHggMnB4IGhzbGEoMCwgMCUsIDQlLCAwLjA2KTtcbn1cbi54LXNwcmVhZHNoZWV0LWZvcm0tc2VsZWN0IC5pbnB1dC10ZXh0IHtcbiAgdGV4dC1vdmVyZmxvdzogZWxsaXBzaXM7XG4gIHdoaXRlLXNwYWNlOiBub3dyYXA7XG4gIG1pbi13aWR0aDogNjBweDtcbiAgd2lkdGg6IGF1dG87XG4gIGhlaWdodDogMzBweDtcbiAgbGluZS1oZWlnaHQ6IDMwcHg7XG4gIHBhZGRpbmc6IDAgOHB4O1xufVxuLngtc3ByZWFkc2hlZXQtZm9ybS1maWVsZHMge1xuICBkaXNwbGF5OiBmbGV4O1xuICBmbGV4LWRpcmVjdGlvbjogcm93O1xuICBmbGV4LXdyYXA6IHdyYXA7XG59XG4ueC1zcHJlYWRzaGVldC1mb3JtLWZpZWxkcyAueC1zcHJlYWRzaGVldC1mb3JtLWZpZWxkIHtcbiAgZmxleDogMCAxIGF1dG87XG59XG4ueC1zcHJlYWRzaGVldC1mb3JtLWZpZWxkcyAueC1zcHJlYWRzaGVldC1mb3JtLWZpZWxkIC5sYWJlbCB7XG4gIGRpc3BsYXk6IGlubGluZS1ibG9jaztcbiAgbWFyZ2luOiAwIDEwcHggMCAwO1xufVxuLngtc3ByZWFkc2hlZXQtZm9ybS1maWVsZCB7XG4gIGRpc3BsYXk6IGJsb2NrO1xuICB2ZXJ0aWNhbC1hbGlnbjogbWlkZGxlO1xuICBtYXJnaW4tbGVmdDogMTBweDtcbiAgbWFyZ2luLWJvdHRvbTogMTBweDtcbn1cbi54LXNwcmVhZHNoZWV0LWZvcm0tZmllbGQ6Zmlyc3QtY2hpbGQge1xuICBtYXJnaW4tbGVmdDogMDtcbn1cbi54LXNwcmVhZHNoZWV0LWZvcm0tZmllbGQuZXJyb3IgLngtc3ByZWFkc2hlZXQtZm9ybS1zZWxlY3QsXG4ueC1zcHJlYWRzaGVldC1mb3JtLWZpZWxkLmVycm9yIGlucHV0IHtcbiAgYm9yZGVyLWNvbG9yOiAjZjA0MTM0O1xufVxuLngtc3ByZWFkc2hlZXQtZm9ybS1maWVsZCAudGlwIHtcbiAgY29sb3I6ICNmMDQxMzQ7XG4gIGZvbnQtc2l6ZTogMC45ZW07XG59XG4ueC1zcHJlYWRzaGVldC1kaW1tZXIge1xuICBkaXNwbGF5OiBub25lO1xuICBwb3NpdGlvbjogYWJzb2x1dGU7XG4gIHRvcDogMCAhaW1wb3J0YW50O1xuICBsZWZ0OiAwICFpbXBvcnRhbnQ7XG4gIHdpZHRoOiAxMDAlO1xuICBoZWlnaHQ6IDEwMCU7XG4gIHRleHQtYWxpZ246IGNlbnRlcjtcbiAgdmVydGljYWwtYWxpZ246IG1pZGRsZTtcbiAgYmFja2dyb3VuZC1jb2xvcjogcmdiYSgwLCAwLCAwLCAwLjYpO1xuICBvcGFjaXR5OiAwO1xuICAtd2Via2l0LWFuaW1hdGlvbi1maWxsLW1vZGU6IGJvdGg7XG4gIGFuaW1hdGlvbi1maWxsLW1vZGU6IGJvdGg7XG4gIC13ZWJraXQtYW5pbWF0aW9uLWR1cmF0aW9uOiAwLjVzO1xuICBhbmltYXRpb24tZHVyYXRpb246IDAuNXM7XG4gIHRyYW5zaXRpb246IGJhY2tncm91bmQtY29sb3IgMC41cyBsaW5lYXI7XG4gIHVzZXItc2VsZWN0OiBub25lO1xuICB6LWluZGV4OiAxMDAwO1xufVxuLngtc3ByZWFkc2hlZXQtZGltbWVyLmFjdGl2ZSB7XG4gIGRpc3BsYXk6IGJsb2NrO1xuICBvcGFjaXR5OiAxO1xufVxuZm9ybSBmaWVsZHNldCB7XG4gIGJvcmRlcjogbm9uZTtcbn1cbmZvcm0gZmllbGRzZXQgbGFiZWwge1xuICBkaXNwbGF5OiBibG9jaztcbiAgbWFyZ2luLWJvdHRvbTogMC41ZW07XG4gIGZvbnQtc2l6ZTogMWVtO1xuICBjb2xvcjogIzY2Njtcbn1cbmZvcm0gZmllbGRzZXQgc2VsZWN0IHtcbiAgZm9udC1zaXplOiAxLjFlbTtcbiAgd2lkdGg6IDEwMCU7XG4gIGJhY2tncm91bmQtY29sb3I6ICNmZmY7XG4gIGJvcmRlcjogbm9uZTtcbiAgYm9yZGVyLWJvdHRvbTogMnB4IHNvbGlkICNkZGQ7XG4gIHBhZGRpbmc6IDAuNWVtIDAuODVlbTtcbiAgYm9yZGVyLXJhZGl1czogMnB4O1xufVxuLngtc3ByZWFkc2hlZXQtbW9kYWwsXG4ueC1zcHJlYWRzaGVldC10b2FzdCB7XG4gIGZvbnQtc2l6ZTogMTNweDtcbiAgcG9zaXRpb246IGZpeGVkO1xuICB6LWluZGV4OiAxMDAxO1xuICB0ZXh0LWFsaWduOiBsZWZ0O1xuICBsaW5lLWhlaWdodDogMS4yNWVtO1xuICBtaW4td2lkdGg6IDM2MHB4O1xuICBjb2xvcjogcmdiYSgwLCAwLCAwLCAwLjg3KTtcbiAgZm9udC1mYW1pbHk6ICdMYXRvJywgJ1NvdXJjZSBTYW5zIFBybycsIFJvYm90bywgSGVsdmV0aWNhLCBBcmlhbCwgc2Fucy1zZXJpZjtcbiAgYm9yZGVyLXJhZGl1czogNHB4O1xuICBib3JkZXI6IDFweCBzb2xpZCByZ2JhKDAsIDAsIDAsIDAuMSk7XG4gIGJhY2tncm91bmQtY29sb3I6ICNmZmY7XG4gIGJhY2tncm91bmQtY2xpcDogcGFkZGluZy1ib3g7XG4gIGJveC1zaGFkb3c6IHJnYmEoMCwgMCwgMCwgMC4yKSAwcHggMnB4IDhweDtcbn1cbi54LXNwcmVhZHNoZWV0LXRvYXN0IHtcbiAgYmFja2dyb3VuZC1jb2xvcjogcmdiYSgyNTUsIDI1NSwgMjU1LCAwLjg1KTtcbn1cbi54LXNwcmVhZHNoZWV0LW1vZGFsLWhlYWRlcixcbi54LXNwcmVhZHNoZWV0LXRvYXN0LWhlYWRlciB7XG4gIGZvbnQtd2VpZ2h0OiA2MDA7XG4gIGJhY2tncm91bmQtY2xpcDogcGFkZGluZy1ib3g7XG4gIGJhY2tncm91bmQtY29sb3I6IHJnYmEoMjU1LCAyNTUsIDI1NSwgMC44NSk7XG4gIGJvcmRlci1ib3R0b206IDFweCBzb2xpZCByZ2JhKDAsIDAsIDAsIDAuMDUpO1xuICBib3JkZXItcmFkaXVzOiA0cHggNHB4IDAgMDtcbn1cbi54LXNwcmVhZHNoZWV0LW1vZGFsLWhlYWRlciAueC1zcHJlYWRzaGVldC1pY29uLFxuLngtc3ByZWFkc2hlZXQtdG9hc3QtaGVhZGVyIC54LXNwcmVhZHNoZWV0LWljb24ge1xuICBwb3NpdGlvbjogYWJzb2x1dGU7XG4gIHJpZ2h0OiAwLjhlbTtcbiAgdG9wOiAwLjY1ZW07XG4gIGJvcmRlci1yYWRpdXM6IDE4cHg7XG59XG4ueC1zcHJlYWRzaGVldC1tb2RhbC1oZWFkZXIgLngtc3ByZWFkc2hlZXQtaWNvbjpob3Zlcixcbi54LXNwcmVhZHNoZWV0LXRvYXN0LWhlYWRlciAueC1zcHJlYWRzaGVldC1pY29uOmhvdmVyIHtcbiAgb3BhY2l0eTogMTtcbiAgYmFja2dyb3VuZDogcmdiYSgwLCAwLCAwLCAwLjA4KTtcbn1cbi54LXNwcmVhZHNoZWV0LXRvYXN0LWhlYWRlciB7XG4gIGNvbG9yOiAjRjI3MTFDO1xufVxuLngtc3ByZWFkc2hlZXQtbW9kYWwtaGVhZGVyIHtcbiAgYm9yZGVyLWJvdHRvbTogMXB4IHNvbGlkICNlMGUyZTQ7XG4gIGJhY2tncm91bmQ6IHJnYmEoMCwgMCwgMCwgMC4wOCk7XG4gIGZvbnQtc2l6ZTogMS4wNzg1ZW07XG59XG4ueC1zcHJlYWRzaGVldC1tb2RhbC1oZWFkZXIsXG4ueC1zcHJlYWRzaGVldC1tb2RhbC1jb250ZW50LFxuLngtc3ByZWFkc2hlZXQtdG9hc3QtaGVhZGVyLFxuLngtc3ByZWFkc2hlZXQtdG9hc3QtY29udGVudCB7XG4gIHBhZGRpbmc6IDAuNzVlbSAxZW07XG59XG5AbWVkaWEgc2NyZWVuIGFuZCAobWluLXdpZHRoOiAzMjBweCkgYW5kIChtYXgtd2lkdGg6IDQ4MHB4KSB7XG4gIC54LXNwcmVhZHNoZWV0LXRvb2xiYXIge1xuICAgIGRpc3BsYXk6IG5vbmU7XG4gIH1cbn1cbi54LXNwcmVhZHNoZWV0LWljb24ge1xuICB3aWR0aDogMThweDtcbiAgaGVpZ2h0OiAxOHB4O1xuICBtYXJnaW46IDFweCAxcHggMnB4IDFweDtcbiAgdGV4dC1hbGlnbjogY2VudGVyO1xuICB2ZXJ0aWNhbC1hbGlnbjogbWlkZGxlO1xuICB1c2VyLXNlbGVjdDogbm9uZTtcbiAgb3ZlcmZsb3c6IGhpZGRlbjtcbiAgcG9zaXRpb246IHJlbGF0aXZlO1xuICBkaXNwbGF5OiBpbmxpbmUtYmxvY2s7XG59XG4ueC1zcHJlYWRzaGVldC1pY29uIC54LXNwcmVhZHNoZWV0LWljb24taW1nIHtcbiAgYmFja2dyb3VuZC1pbWFnZTogdXJsKCcuLi9hc3NldHMvc3ByaXRlLnN2ZycpO1xuICBwb3NpdGlvbjogYWJzb2x1dGU7XG4gIHdpZHRoOiAyNjJweDtcbiAgaGVpZ2h0OiA0NDRweDtcbiAgb3BhY2l0eTogMC41Njtcbn1cbi54LXNwcmVhZHNoZWV0LWljb24gLngtc3ByZWFkc2hlZXQtaWNvbi1pbWcudW5kbyB7XG4gIGxlZnQ6IDA7XG4gIHRvcDogMDtcbn1cbi54LXNwcmVhZHNoZWV0LWljb24gLngtc3ByZWFkc2hlZXQtaWNvbi1pbWcucmVkbyB7XG4gIGxlZnQ6IC0xOHB4O1xuICB0b3A6IDA7XG59XG4ueC1zcHJlYWRzaGVldC1pY29uIC54LXNwcmVhZHNoZWV0LWljb24taW1nLnByaW50IHtcbiAgbGVmdDogLTM2cHg7XG4gIHRvcDogMDtcbn1cbi54LXNwcmVhZHNoZWV0LWljb24gLngtc3ByZWFkc2hlZXQtaWNvbi1pbWcucGFpbnRmb3JtYXQge1xuICBsZWZ0OiAtNTRweDtcbiAgdG9wOiAwO1xufVxuLngtc3ByZWFkc2hlZXQtaWNvbiAueC1zcHJlYWRzaGVldC1pY29uLWltZy5jbGVhcmZvcm1hdCB7XG4gIGxlZnQ6IC03MnB4O1xuICB0b3A6IDA7XG59XG4ueC1zcHJlYWRzaGVldC1pY29uIC54LXNwcmVhZHNoZWV0LWljb24taW1nLmZvbnQtYm9sZCB7XG4gIGxlZnQ6IC05MHB4O1xuICB0b3A6IDA7XG59XG4ueC1zcHJlYWRzaGVldC1pY29uIC54LXNwcmVhZHNoZWV0LWljb24taW1nLmZvbnQtaXRhbGljIHtcbiAgbGVmdDogLTEwOHB4O1xuICB0b3A6IDA7XG59XG4ueC1zcHJlYWRzaGVldC1pY29uIC54LXNwcmVhZHNoZWV0LWljb24taW1nLnVuZGVybGluZSB7XG4gIGxlZnQ6IC0xMjZweDtcbiAgdG9wOiAwO1xufVxuLngtc3ByZWFkc2hlZXQtaWNvbiAueC1zcHJlYWRzaGVldC1pY29uLWltZy5zdHJpa2Uge1xuICBsZWZ0OiAtMTQ0cHg7XG4gIHRvcDogMDtcbn1cbi54LXNwcmVhZHNoZWV0LWljb24gLngtc3ByZWFkc2hlZXQtaWNvbi1pbWcuY29sb3Ige1xuICBsZWZ0OiAtMTYycHg7XG4gIHRvcDogMDtcbn1cbi54LXNwcmVhZHNoZWV0LWljb24gLngtc3ByZWFkc2hlZXQtaWNvbi1pbWcuYmdjb2xvciB7XG4gIGxlZnQ6IC0xODBweDtcbiAgdG9wOiAwO1xufVxuLngtc3ByZWFkc2hlZXQtaWNvbiAueC1zcHJlYWRzaGVldC1pY29uLWltZy5tZXJnZSB7XG4gIGxlZnQ6IC0xOThweDtcbiAgdG9wOiAwO1xufVxuLngtc3ByZWFkc2hlZXQtaWNvbiAueC1zcHJlYWRzaGVldC1pY29uLWltZy5hbGlnbi1sZWZ0IHtcbiAgbGVmdDogLTIxNnB4O1xuICB0b3A6IDA7XG59XG4ueC1zcHJlYWRzaGVldC1pY29uIC54LXNwcmVhZHNoZWV0LWljb24taW1nLmFsaWduLWNlbnRlciB7XG4gIGxlZnQ6IC0yMzRweDtcbiAgdG9wOiAwO1xufVxuLngtc3ByZWFkc2hlZXQtaWNvbiAueC1zcHJlYWRzaGVldC1pY29uLWltZy5hbGlnbi1yaWdodCB7XG4gIGxlZnQ6IDA7XG4gIHRvcDogLTE4cHg7XG59XG4ueC1zcHJlYWRzaGVldC1pY29uIC54LXNwcmVhZHNoZWV0LWljb24taW1nLmFsaWduLXRvcCB7XG4gIGxlZnQ6IC0xOHB4O1xuICB0b3A6IC0xOHB4O1xufVxuLngtc3ByZWFkc2hlZXQtaWNvbiAueC1zcHJlYWRzaGVldC1pY29uLWltZy5hbGlnbi1taWRkbGUge1xuICBsZWZ0OiAtMzZweDtcbiAgdG9wOiAtMThweDtcbn1cbi54LXNwcmVhZHNoZWV0LWljb24gLngtc3ByZWFkc2hlZXQtaWNvbi1pbWcuYWxpZ24tYm90dG9tIHtcbiAgbGVmdDogLTU0cHg7XG4gIHRvcDogLTE4cHg7XG59XG4ueC1zcHJlYWRzaGVldC1pY29uIC54LXNwcmVhZHNoZWV0LWljb24taW1nLnRleHR3cmFwIHtcbiAgbGVmdDogLTcycHg7XG4gIHRvcDogLTE4cHg7XG59XG4ueC1zcHJlYWRzaGVldC1pY29uIC54LXNwcmVhZHNoZWV0LWljb24taW1nLmF1dG9maWx0ZXIge1xuICBsZWZ0OiAtOTBweDtcbiAgdG9wOiAtMThweDtcbn1cbi54LXNwcmVhZHNoZWV0LWljb24gLngtc3ByZWFkc2hlZXQtaWNvbi1pbWcuZm9ybXVsYSB7XG4gIGxlZnQ6IC0xMDhweDtcbiAgdG9wOiAtMThweDtcbn1cbi54LXNwcmVhZHNoZWV0LWljb24gLngtc3ByZWFkc2hlZXQtaWNvbi1pbWcuYXJyb3ctZG93biB7XG4gIGxlZnQ6IC0xMjZweDtcbiAgdG9wOiAtMThweDtcbn1cbi54LXNwcmVhZHNoZWV0LWljb24gLngtc3ByZWFkc2hlZXQtaWNvbi1pbWcuYXJyb3ctcmlnaHQge1xuICBsZWZ0OiAtMTQ0cHg7XG4gIHRvcDogLTE4cHg7XG59XG4ueC1zcHJlYWRzaGVldC1pY29uIC54LXNwcmVhZHNoZWV0LWljb24taW1nLmxpbmsge1xuICBsZWZ0OiAtMTYycHg7XG4gIHRvcDogLTE4cHg7XG59XG4ueC1zcHJlYWRzaGVldC1pY29uIC54LXNwcmVhZHNoZWV0LWljb24taW1nLmNoYXJ0IHtcbiAgbGVmdDogLTE4MHB4O1xuICB0b3A6IC0xOHB4O1xufVxuLngtc3ByZWFkc2hlZXQtaWNvbiAueC1zcHJlYWRzaGVldC1pY29uLWltZy5mcmVlemUge1xuICBsZWZ0OiAtMTk4cHg7XG4gIHRvcDogLTE4cHg7XG59XG4ueC1zcHJlYWRzaGVldC1pY29uIC54LXNwcmVhZHNoZWV0LWljb24taW1nLmVsbGlwc2lzIHtcbiAgbGVmdDogLTIxNnB4O1xuICB0b3A6IC0xOHB4O1xufVxuLngtc3ByZWFkc2hlZXQtaWNvbiAueC1zcHJlYWRzaGVldC1pY29uLWltZy5hZGQge1xuICBsZWZ0OiAtMjM0cHg7XG4gIHRvcDogLTE4cHg7XG59XG4ueC1zcHJlYWRzaGVldC1pY29uIC54LXNwcmVhZHNoZWV0LWljb24taW1nLmJvcmRlci1hbGwge1xuICBsZWZ0OiAwO1xuICB0b3A6IC0zNnB4O1xufVxuLngtc3ByZWFkc2hlZXQtaWNvbiAueC1zcHJlYWRzaGVldC1pY29uLWltZy5ib3JkZXItaW5zaWRlIHtcbiAgbGVmdDogLTE4cHg7XG4gIHRvcDogLTM2cHg7XG59XG4ueC1zcHJlYWRzaGVldC1pY29uIC54LXNwcmVhZHNoZWV0LWljb24taW1nLmJvcmRlci1ob3Jpem9udGFsIHtcbiAgbGVmdDogLTM2cHg7XG4gIHRvcDogLTM2cHg7XG59XG4ueC1zcHJlYWRzaGVldC1pY29uIC54LXNwcmVhZHNoZWV0LWljb24taW1nLmJvcmRlci12ZXJ0aWNhbCB7XG4gIGxlZnQ6IC01NHB4O1xuICB0b3A6IC0zNnB4O1xufVxuLngtc3ByZWFkc2hlZXQtaWNvbiAueC1zcHJlYWRzaGVldC1pY29uLWltZy5ib3JkZXItb3V0c2lkZSB7XG4gIGxlZnQ6IC03MnB4O1xuICB0b3A6IC0zNnB4O1xufVxuLngtc3ByZWFkc2hlZXQtaWNvbiAueC1zcHJlYWRzaGVldC1pY29uLWltZy5ib3JkZXItbGVmdCB7XG4gIGxlZnQ6IC05MHB4O1xuICB0b3A6IC0zNnB4O1xufVxuLngtc3ByZWFkc2hlZXQtaWNvbiAueC1zcHJlYWRzaGVldC1pY29uLWltZy5ib3JkZXItdG9wIHtcbiAgbGVmdDogLTEwOHB4O1xuICB0b3A6IC0zNnB4O1xufVxuLngtc3ByZWFkc2hlZXQtaWNvbiAueC1zcHJlYWRzaGVldC1pY29uLWltZy5ib3JkZXItcmlnaHQge1xuICBsZWZ0OiAtMTI2cHg7XG4gIHRvcDogLTM2cHg7XG59XG4ueC1zcHJlYWRzaGVldC1pY29uIC54LXNwcmVhZHNoZWV0LWljb24taW1nLmJvcmRlci1ib3R0b20ge1xuICBsZWZ0OiAtMTQ0cHg7XG4gIHRvcDogLTM2cHg7XG59XG4ueC1zcHJlYWRzaGVldC1pY29uIC54LXNwcmVhZHNoZWV0LWljb24taW1nLmJvcmRlci1ub25lIHtcbiAgbGVmdDogLTE2MnB4O1xuICB0b3A6IC0zNnB4O1xufVxuLngtc3ByZWFkc2hlZXQtaWNvbiAueC1zcHJlYWRzaGVldC1pY29uLWltZy5saW5lLWNvbG9yIHtcbiAgbGVmdDogLTE4MHB4O1xuICB0b3A6IC0zNnB4O1xufVxuLngtc3ByZWFkc2hlZXQtaWNvbiAueC1zcHJlYWRzaGVldC1pY29uLWltZy5saW5lLXR5cGUge1xuICBsZWZ0OiAtMTk4cHg7XG4gIHRvcDogLTM2cHg7XG59XG4ueC1zcHJlYWRzaGVldC1pY29uIC54LXNwcmVhZHNoZWV0LWljb24taW1nLmNsb3NlIHtcbiAgbGVmdDogLTIzNHB4O1xuICB0b3A6IC0zNnB4O1xufVxuLngtc3ByZWFkc2hlZXQtaWNvbiAueC1zcHJlYWRzaGVldC1pY29uLWltZy5jaGV2cm9uLWRvd24ge1xuICBsZWZ0OiAwO1xuICB0b3A6IC01NHB4O1xufVxuLngtc3ByZWFkc2hlZXQtaWNvbiAueC1zcHJlYWRzaGVldC1pY29uLWltZy5jaGV2cm9uLXVwIHtcbiAgbGVmdDogLTE4cHg7XG4gIHRvcDogLTU0cHg7XG59XG4ueC1zcHJlYWRzaGVldC1pY29uIC54LXNwcmVhZHNoZWV0LWljb24taW1nLmNoZXZyb24tbGVmdCB7XG4gIGxlZnQ6IC0zNnB4O1xuICB0b3A6IC01NHB4O1xufVxuLngtc3ByZWFkc2hlZXQtaWNvbiAueC1zcHJlYWRzaGVldC1pY29uLWltZy5jaGV2cm9uLXJpZ2h0IHtcbiAgbGVmdDogLTU0cHg7XG4gIHRvcDogLTU0cHg7XG59XG4iXSwKICAibWFwcGluZ3MiOiAiO0FBQUE7QUFDRTtBQUFBO0FBRUY7QUFDRTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFFRjtBQUNFO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFFRjtBQUNFO0FBQ0E7QUFBQTtBQUVGO0FBQ0U7QUFBQTtBQUVGO0FBQ0U7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBRUY7QUFDRTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUVGO0FBQ0U7QUFBQTtBQUVGO0FBQ0U7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBRUY7QUFDRTtBQUNBO0FBQ0E7QUFBQTtBQUVGO0FBQ0U7QUFBQTtBQUVGO0FBQ0U7QUFDQTtBQUFBO0FBRUY7QUFDRTtBQUFBO0FBRUY7QUFDRTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUVGO0FBQ0U7QUFBQTtBQUVGO0FBQ0U7QUFDQTtBQUFBO0FBRUY7QUFDRTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBRUY7QUFDRTtBQUFBO0FBRUY7QUFDRTtBQUFBO0FBRUY7QUFDRTtBQUFBO0FBRUY7QUFDRTtBQUNBO0FBQUE7QUFFRjtBQUNFO0FBQ0E7QUFDQTtBQUFBO0FBRUY7QUFDRTtBQUFBO0FBRUY7QUFDRTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBRUY7QUFDRTtBQUNBO0FBQUE7QUFFRjtBQUNFO0FBQ0E7QUFBQTtBQUVGO0FBQ0U7QUFDQTtBQUFBO0FBRUY7QUFDRTtBQUNBO0FBQUE7QUFFRjtBQUNFO0FBQ0E7QUFBQTtBQUVGO0FBQ0U7QUFBQTtBQUVGO0FBQ0U7QUFDQTtBQUFBO0FBRUY7QUFDRTtBQUFBO0FBR0Y7QUFDRTtBQUNBO0FBQUE7QUFFRjtBQUNFO0FBQUE7QUFFRjtBQUNFO0FBQUE7QUFFRjtBQUNFO0FBQUE7QUFFRjtBQUNFO0FBQ0E7QUFDQTtBQUFBO0FBRUY7QUFDRTtBQUFBO0FBRUY7QUFDRTtBQUNBO0FBQ0E7QUFBQTtBQUdGO0FBQ0U7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFFRjtBQUNFO0FBQ0E7QUFDQTtBQUFBO0FBRUY7QUFDRTtBQUNBO0FBQUE7QUFFRjtBQUNFO0FBQ0E7QUFDQTtBQUFBO0FBRUY7QUFDRTtBQUNBO0FBQUE7QUFHRjtBQUNFO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFFRjtBQUNFO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUVGO0FBQUE7QUFFRTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFHRjtBQUNFO0FBQ0E7QUFBQTtBQUVGO0FBQ0U7QUFDQTtBQUNBO0FBQUE7QUFFRjtBQUNFO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFFRjtBQUFBO0FBRUU7QUFDQTtBQUNBO0FBQUE7QUFFRjtBQUNFO0FBQUE7QUFFRjtBQUNFO0FBQUE7QUFFRjtBQUNFO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFFRjtBQUNFO0FBQUE7QUFFRjtBQUNFO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBRUY7QUFDRTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBRUY7QUFDRTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFFRjtBQUNFO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBRUY7QUFDRTtBQUNBO0FBQUE7QUFFRjtBQUFBO0FBRUU7QUFBQTtBQUVGO0FBQ0U7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBRUY7QUFDRTtBQUNBO0FBQ0E7QUFBQTtBQUVGO0FBQUE7QUFFRTtBQUNBO0FBQUE7QUFFRjtBQUFBO0FBRUU7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBRUY7QUFBQTtBQUVFO0FBQUE7QUFFRjtBQUNFO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUVGO0FBQ0U7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFFRjtBQUFBO0FBQUE7QUFHRTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBRUY7QUFDRTtBQUFBO0FBRUY7QUFDRTtBQUNBO0FBQ0E7QUFBQTtBQUVGO0FBQ0U7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUVGO0FBQ0U7QUFDQTtBQUFBO0FBRUY7QUFDRTtBQUNBO0FBQUE7QUFFRjtBQUNFO0FBQUE7QUFFRjtBQUFBO0FBRUU7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBRUY7QUFDRTtBQUNBO0FBQUE7QUFFRjtBQUNFO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBRUY7QUFDRTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBRUY7QUFDRTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUVGO0FBQ0U7QUFDQTtBQUFBO0FBRUY7QUFDRTtBQUFBO0FBRUY7QUFDRTtBQUFBO0FBRUY7QUFDRTtBQUFBO0FBRUY7QUFDRTtBQUFBO0FBRUY7QUFDRTtBQUFBO0FBRUY7QUFDRTtBQUNBO0FBQUE7QUFFRjtBQUNFO0FBQUE7QUFFRjtBQUNFO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFFRjtBQUNFO0FBQ0E7QUFBQTtBQUVGO0FBQUE7QUFFRTtBQUFBO0FBRUY7QUFDRTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUVGO0FBQ0U7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBRUY7QUFDRTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBRUY7QUFDRTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBRUY7QUFDRTtBQUNBO0FBQUE7QUFFRjtBQUNFO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUVGO0FBQ0U7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUVGO0FBQ0U7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUVGO0FBQ0U7QUFBQTtBQUVGO0FBQ0U7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBRUY7QUFDRTtBQUNBO0FBQ0E7QUFBQTtBQUVGO0FBQ0U7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFFRjtBQUNFO0FBQ0E7QUFBQTtBQUVGO0FBQ0U7QUFBQTtBQUVGO0FBQ0U7QUFDQTtBQUNBO0FBQUE7QUFFRjtBQUNFO0FBQUE7QUFFRjtBQUNFO0FBQ0E7QUFBQTtBQUVGO0FBQUE7QUFFRTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUVGO0FBQ0U7QUFBQTtBQUVGO0FBQUE7QUFFRTtBQUNBO0FBQUE7QUFFRjtBQUNFO0FBQ0E7QUFBQTtBQUVGO0FBQ0U7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFFRjtBQUNFO0FBQ0E7QUFBQTtBQUVGO0FBQ0U7QUFBQTtBQUVGO0FBQ0U7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFFRjtBQUFBO0FBRUU7QUFDQTtBQUFBO0FBRUY7QUFDRTtBQUNBO0FBQUE7QUFFRjtBQUFBO0FBRUU7QUFDQTtBQUFBO0FBRUY7QUFDRTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFFRjtBQUNFO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBRUY7QUFDRTtBQUNBO0FBQUE7QUFFRjtBQUNFO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBRUY7QUFDRTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBRUY7QUFDRTtBQUNBO0FBQ0E7QUFBQTtBQUVGO0FBQ0U7QUFBQTtBQUVGO0FBQ0U7QUFDQTtBQUFBO0FBRUY7QUFDRTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBRUY7QUFDRTtBQUFBO0FBRUY7QUFBQTtBQUVFO0FBQUE7QUFFRjtBQUNFO0FBQ0E7QUFBQTtBQUVGO0FBQ0U7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBRUY7QUFDRTtBQUNBO0FBQUE7QUFFRjtBQUNFO0FBQUE7QUFFRjtBQUNFO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFFRjtBQUNFO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFFRjtBQUFBO0FBRUU7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUVGO0FBQ0U7QUFBQTtBQUVGO0FBQUE7QUFFRTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFFRjtBQUFBO0FBRUU7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUVGO0FBQUE7QUFFRTtBQUNBO0FBQUE7QUFFRjtBQUNFO0FBQUE7QUFFRjtBQUNFO0FBQ0E7QUFDQTtBQUFBO0FBRUY7QUFBQTtBQUFBO0FBQUE7QUFJRTtBQUFBO0FBRUY7QUFDRTtBQUNFO0FBQUE7QUFBQTtBQUdKO0FBQ0U7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFFRjtBQUNFO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUVGO0FBQ0U7QUFDQTtBQUFBO0FBRUY7QUFDRTtBQUNBO0FBQUE7QUFFRjtBQUNFO0FBQ0E7QUFBQTtBQUVGO0FBQ0U7QUFDQTtBQUFBO0FBRUY7QUFDRTtBQUNBO0FBQUE7QUFFRjtBQUNFO0FBQ0E7QUFBQTtBQUVGO0FBQ0U7QUFDQTtBQUFBO0FBRUY7QUFDRTtBQUNBO0FBQUE7QUFFRjtBQUNFO0FBQ0E7QUFBQTtBQUVGO0FBQ0U7QUFDQTtBQUFBO0FBRUY7QUFDRTtBQUNBO0FBQUE7QUFFRjtBQUNFO0FBQ0E7QUFBQTtBQUVGO0FBQ0U7QUFDQTtBQUFBO0FBRUY7QUFDRTtBQUNBO0FBQUE7QUFFRjtBQUNFO0FBQ0E7QUFBQTtBQUVGO0FBQ0U7QUFDQTtBQUFBO0FBRUY7QUFDRTtBQUNBO0FBQUE7QUFFRjtBQUNFO0FBQ0E7QUFBQTtBQUVGO0FBQ0U7QUFDQTtBQUFBO0FBRUY7QUFDRTtBQUNBO0FBQUE7QUFFRjtBQUNFO0FBQ0E7QUFBQTtBQUVGO0FBQ0U7QUFDQTtBQUFBO0FBRUY7QUFDRTtBQUNBO0FBQUE7QUFFRjtBQUNFO0FBQ0E7QUFBQTtBQUVGO0FBQ0U7QUFDQTtBQUFBO0FBRUY7QUFDRTtBQUNBO0FBQUE7QUFFRjtBQUNFO0FBQ0E7QUFBQTtBQUVGO0FBQ0U7QUFDQTtBQUFBO0FBRUY7QUFDRTtBQUNBO0FBQUE7QUFFRjtBQUNFO0FBQ0E7QUFBQTtBQUVGO0FBQ0U7QUFDQTtBQUFBO0FBRUY7QUFDRTtBQUNBO0FBQUE7QUFFRjtBQUNFO0FBQ0E7QUFBQTtBQUVGO0FBQ0U7QUFDQTtBQUFBO0FBRUY7QUFDRTtBQUNBO0FBQUE7QUFFRjtBQUNFO0FBQ0E7QUFBQTtBQUVGO0FBQ0U7QUFDQTtBQUFBO0FBRUY7QUFDRTtBQUNBO0FBQUE7QUFFRjtBQUNFO0FBQ0E7QUFBQTtBQUVGO0FBQ0U7QUFDQTtBQUFBO0FBRUY7QUFDRTtBQUNBO0FBQUE7QUFFRjtBQUNFO0FBQ0E7QUFBQTtBQUVGO0FBQ0U7QUFDQTtBQUFBO0FBRUY7QUFDRTtBQUNBO0FBQUE7QUFFRjtBQUNFO0FBQ0E7QUFBQTsiLAogICJuYW1lcyI6IFtdCn0K */ 1067 | -------------------------------------------------------------------------------- /manifest-beta.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "obsidian-workbooks", 3 | "name": "Workbooks", 4 | "version": "1.0.0", 5 | "minAppVersion": "0.15.0", 6 | "description": "Work with Spreadsheets inside your notes", 7 | "author": "Gabriele Cannata", 8 | "authorUrl": "https://github.com/Canna71", 9 | "isDesktopOnly": true 10 | } 11 | -------------------------------------------------------------------------------- /manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "workbooks", 3 | "name": "Workbooks", 4 | "version": "1.0.1", 5 | "minAppVersion": "0.15.0", 6 | "description": "Work with Spreadsheets inside your notes", 7 | "author": "Gabriele Cannata", 8 | "authorUrl": "https://github.com/Canna71", 9 | "isDesktopOnly": true 10 | } 11 | -------------------------------------------------------------------------------- /officeTheme.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 | 244 | 245 | 246 | 247 | 248 | 249 | 250 | 251 | 252 | 253 | 254 | 255 | 256 | 257 | 258 | 259 | 260 | 261 | 262 | 263 | 264 | 265 | 266 | 267 | 268 | 269 | 270 | 271 | 272 | 273 | 274 | 275 | 276 | 277 | 278 | 279 | 280 | 281 | 282 | 283 | 284 | 285 | 286 | 287 | 288 | 289 | 290 | 291 | 292 | 293 | 294 | 295 | 296 | 297 | 298 | 299 | 300 | 301 | 302 | 303 | 304 | 305 | 306 | 307 | 308 | 309 | 310 | 311 | 312 | 313 | 314 | 315 | 316 | 317 | 318 | 319 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "obsidian-workbooks", 3 | "version": "1.0.1", 4 | "description": "Work with Spreadsheets inside your notes", 5 | "main": "main.js", 6 | "scripts": { 7 | "dev": "node esbuild.config.mjs", 8 | "build": "tsc -noEmit -skipLibCheck && node esbuild.config.mjs production", 9 | "version": "node version-bump.mjs && git add manifest.json versions.json", 10 | "scss": "ode-sass -w styles.scss styles.css" 11 | }, 12 | "keywords": [], 13 | "author": "", 14 | "license": "MIT", 15 | "devDependencies": { 16 | "@codemirror/language": "^6.2.1", 17 | "@types/node": "^16.11.6", 18 | "@types/react": "^18.0.17", 19 | "@types/react-dom": "^18.0.6", 20 | "@typescript-eslint/eslint-plugin": "5.29.0", 21 | "@typescript-eslint/parser": "5.29.0", 22 | "builtin-modules": "3.3.0", 23 | "esbuild": "0.14.47", 24 | "esbuild-plugin-svgr": "^1.0.1", 25 | "esbuild-sass-plugin": "^2.3.2", 26 | "esbuild-plugin-alias": "^0.2.1", 27 | "esbuild-plugin-less": "^1.2.1", 28 | "obsidian": "latest", 29 | "tslib": "2.4.0", 30 | "typescript": "4.7.4" 31 | }, 32 | "dependencies": { 33 | "exceljs": "^4.3.0", 34 | "react": "^18.2.0", 35 | "react-dom": "^18.2.0", 36 | "xlsx": "https://cdn.sheetjs.com/xlsx-0.20.0/xlsx-0.20.0.tgz" 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /spreadsheetData.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "name": "Sheet1", 4 | "freeze": "A1", 5 | "styles": [ 6 | { 7 | "bgcolor": "#fff2cd" 8 | }, 9 | { 10 | "bgcolor": "#d9e2f3" 11 | } 12 | ], 13 | "merges": [], 14 | "rows": { 15 | "0": { 16 | "cells": { 17 | "0": { 18 | "text": "Item" 19 | }, 20 | "1": { 21 | "text": "Cost" 22 | }, 23 | "2": { 24 | "text": "Qty" 25 | }, 26 | "3": { 27 | "text": "Price" 28 | } 29 | } 30 | }, 31 | "1": { 32 | "cells": { 33 | "0": { 34 | "text": "Laser", 35 | "style": 0 36 | }, 37 | "1": { 38 | "text": "100", 39 | "style": 0 40 | }, 41 | "2": { 42 | "text": "2", 43 | "style": 0 44 | }, 45 | "3": { 46 | "text": "=B2*C2", 47 | "style": 0 48 | } 49 | } 50 | }, 51 | "2": { 52 | "cells": { 53 | "0": { 54 | "text": "Gun", 55 | "style": 0 56 | }, 57 | "1": { 58 | "text": "123", 59 | "style": 0 60 | }, 61 | "2": { 62 | "text": "3", 63 | "style": 0 64 | }, 65 | "3": { 66 | "text": "=B3*C3", 67 | "style": 0 68 | } 69 | } 70 | }, 71 | "3": { 72 | "cells": { 73 | "0": { 74 | "text": "Some", 75 | "style": 0 76 | }, 77 | "1": { 78 | "text": "234", 79 | "style": 0 80 | }, 81 | "2": { 82 | "text": "1", 83 | "style": 0 84 | }, 85 | "3": { 86 | "text": "=B4*C4", 87 | "style": 0 88 | } 89 | } 90 | }, 91 | "4": { 92 | "cells": { 93 | "0": { 94 | "style": 0 95 | }, 96 | "1": { 97 | "style": 0 98 | }, 99 | "2": { 100 | "text": "3", 101 | "style": 0 102 | }, 103 | "3": { 104 | "text": "=B5*C5", 105 | "style": 0 106 | } 107 | } 108 | }, 109 | "5": { 110 | "cells": { 111 | "0": { 112 | "style": 0 113 | }, 114 | "1": { 115 | "style": 0 116 | }, 117 | "2": { 118 | "style": 0 119 | }, 120 | "3": { 121 | "text": "=B6*C6", 122 | "style": 0 123 | } 124 | } 125 | }, 126 | "6": { 127 | "cells": { 128 | "0": { 129 | "style": 0 130 | }, 131 | "1": { 132 | "style": 0 133 | }, 134 | "2": { 135 | "style": 0 136 | }, 137 | "3": { 138 | "text": "=B7*C7", 139 | "style": 0 140 | } 141 | } 142 | }, 143 | "7": { 144 | "cells": { 145 | "0": { 146 | "style": 0 147 | }, 148 | "1": { 149 | "style": 0 150 | }, 151 | "2": { 152 | "style": 0 153 | }, 154 | "3": { 155 | "text": "=SUM(D2:D7)", 156 | "style": 0 157 | } 158 | } 159 | }, 160 | "len": 100 161 | }, 162 | "cols": { 163 | "len": 26 164 | }, 165 | "validations": [], 166 | "autofilter": {} 167 | }, 168 | { 169 | "name": "sheet3", 170 | "freeze": "A1", 171 | "styles": [], 172 | "merges": [], 173 | "rows": { 174 | "0": { 175 | "cells": { 176 | "0": { 177 | "text": "12" 178 | }, 179 | "1": { 180 | "text": "23" 181 | } 182 | } 183 | }, 184 | "len": 100 185 | }, 186 | "cols": { 187 | "len": 26 188 | }, 189 | "validations": [], 190 | "autofilter": {} 191 | } 192 | ] 193 | -------------------------------------------------------------------------------- /src/Globals.d.ts: -------------------------------------------------------------------------------- 1 | declare module "*.module.css"; 2 | declare module "*.module.scss"; 3 | declare module "*.svg"; 4 | -------------------------------------------------------------------------------- /src/SettingTab.ts: -------------------------------------------------------------------------------- 1 | import SheetjsPlugin from "src/main"; 2 | import { App, PluginSettingTab, Setting } from "obsidian"; 3 | 4 | export class SheetjsSettingsTab extends PluginSettingTab { 5 | plugin: SheetjsPlugin; 6 | 7 | constructor(app: App, plugin: SheetjsPlugin) { 8 | super(app, plugin); 9 | this.plugin = plugin; 10 | } 11 | 12 | display(): void { 13 | const { containerEl } = this; 14 | 15 | containerEl.empty(); 16 | 17 | 18 | this.createToggle( 19 | containerEl, 20 | "Enable saving to file", 21 | "Enabling saving to external files (.xlsx, .xls, ,.csv)", 22 | "enableSaveToFile" 23 | ); 24 | 25 | this.createToggle( 26 | containerEl, 27 | "Auto save", 28 | "Saves automatically", 29 | "autoSave" 30 | ); 31 | } 32 | 33 | private createToggle( 34 | containerEl: HTMLElement, 35 | name: string, 36 | desc: string, 37 | prop: string 38 | ) { 39 | new Setting(containerEl) 40 | .setName(name) 41 | .setDesc(desc) 42 | .addToggle((bool) => 43 | bool 44 | .setValue((this.plugin.settings as any)[prop] as boolean) 45 | .onChange(async (value) => { 46 | (this.plugin.settings as any)[prop] = value; 47 | await this.plugin.saveSettings(); 48 | this.display(); 49 | }) 50 | ); 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /src/Settings.ts: -------------------------------------------------------------------------------- 1 | 2 | export interface SheetsSettings { 3 | enableSaveToFile: boolean; 4 | autoSave: boolean; 5 | } 6 | 7 | export const DEFAULT_SETTINGS: SheetsSettings = { 8 | enableSaveToFile: false, 9 | autoSave: true 10 | } 11 | 12 | -------------------------------------------------------------------------------- /src/Views/SheetView.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable @typescript-eslint/no-explicit-any */ 2 | // import * as React from "react"; 3 | // import { createRoot } from "react-dom/client"; 4 | // https://github.com/exceljs/exceljs#reading-xlsx 5 | import { 6 | MarkdownPostProcessorContext, 7 | parseYaml 8 | } from "obsidian"; 9 | import { SheetsSettings } from "src/Settings"; 10 | // import "x-data-spreadsheet/dist/xspreadsheet.css"; 11 | // import * as fs from "fs/promises" 12 | // import * as path from "path" 13 | 14 | import * as XLSX from "xlsx"; 15 | import * as ExcelJS from "exceljs"; 16 | import { stox } from "../utils/xlsxpread"; 17 | import { toSpreadsheet } from "src/utils/excelConverter"; 18 | import { 19 | createSpreadSheet, 20 | 21 | saveDataIntoBlock, 22 | 23 | saveToFile, 24 | } from "./spreadSheetWrapper"; 25 | import { Readable } from "stream"; 26 | import { moment } from "obsidian"; 27 | 28 | import saveIcon from "./save.svg"; 29 | 30 | const DEFAULT_OPTIONS = { 31 | height: 540, 32 | width: "auto", 33 | rows: 100, 34 | cols: 26, 35 | fontSize: 10, 36 | cellHeight: 25, 37 | cellWidth: 100, 38 | }; 39 | 40 | const MINHEIGHT = 400; 41 | 42 | // const saveIcon = 43 | // "data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBzdGFuZGFsb25lPSJubyI/PjwhRE9DVFlQRSBzdmcgUFVCTElDICItLy9XM0MvL0RURCBTVkcgMS4xLy9FTiIgImh0dHA6Ly93d3cudzMub3JnL0dyYXBoaWNzL1NWRy8xLjEvRFREL3N2ZzExLmR0ZCI+PHN2ZyB0PSIxNTc3MTc3MDkyOTg4IiBjbGFzcz0iaWNvbiIgdmlld0JveD0iMCAwIDEwMjQgMTAyNCIgdmVyc2lvbj0iMS4xIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHAtaWQ9IjI2NzgiIHdpZHRoPSIxOCIgaGVpZ2h0PSIxOCIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiPjxkZWZzPjxzdHlsZSB0eXBlPSJ0ZXh0L2NzcyI+PC9zdHlsZT48L2RlZnM+PHBhdGggZD0iTTIxMy4zMzMzMzMgMTI4aDU5Ny4zMzMzMzRhODUuMzMzMzMzIDg1LjMzMzMzMyAwIDAgMSA4NS4zMzMzMzMgODUuMzMzMzMzdjU5Ny4zMzMzMzRhODUuMzMzMzMzIDg1LjMzMzMzMyAwIDAgMS04NS4zMzMzMzMgODUuMzMzMzMzSDIxMy4zMzMzMzNhODUuMzMzMzMzIDg1LjMzMzMzMyAwIDAgMS04NS4zMzMzMzMtODUuMzMzMzMzVjIxMy4zMzMzMzNhODUuMzMzMzMzIDg1LjMzMzMzMyAwIDAgMSA4NS4zMzMzMzMtODUuMzMzMzMzeiBtMzY2LjkzMzMzNCAxMjhoMzQuMTMzMzMzYTI1LjYgMjUuNiAwIDAgMSAyNS42IDI1LjZ2MTE5LjQ2NjY2N2EyNS42IDI1LjYgMCAwIDEtMjUuNiAyNS42aC0zNC4xMzMzMzNhMjUuNiAyNS42IDAgMCAxLTI1LjYtMjUuNlYyODEuNmEyNS42IDI1LjYgMCAwIDEgMjUuNi0yNS42ek0yMTMuMzMzMzMzIDIxMy4zMzMzMzN2NTk3LjMzMzMzNGg1OTcuMzMzMzM0VjIxMy4zMzMzMzNIMjEzLjMzMzMzM3ogbTEyOCAwdjI1NmgzNDEuMzMzMzM0VjIxMy4zMzMzMzNoODUuMzMzMzMzdjI5OC42NjY2NjdhNDIuNjY2NjY3IDQyLjY2NjY2NyAwIDAgMS00Mi42NjY2NjcgNDIuNjY2NjY3SDI5OC42NjY2NjdhNDIuNjY2NjY3IDQyLjY2NjY2NyAwIDAgMS00Mi42NjY2NjctNDIuNjY2NjY3VjIxMy4zMzMzMzNoODUuMzMzMzMzek0yNTYgMjEzLjMzMzMzM2g4NS4zMzMzMzMtODUuMzMzMzMzeiBtNDI2LjY2NjY2NyAwaDg1LjMzMzMzMy04NS4zMzMzMzN6IG0wIDU5Ny4zMzMzMzR2LTEyOEgzNDEuMzMzMzMzdjEyOEgyNTZ2LTE3MC42NjY2NjdhNDIuNjY2NjY3IDQyLjY2NjY2NyAwIDAgMSA0Mi42NjY2NjctNDIuNjY2NjY3aDQyNi42NjY2NjZhNDIuNjY2NjY3IDQyLjY2NjY2NyAwIDAgMSA0Mi42NjY2NjcgNDIuNjY2NjY3djE3MC42NjY2NjdoLTg1LjMzMzMzM3ogbTg1LjMzMzMzMyAwaC04NS4zMzMzMzMgODUuMzMzMzMzek0zNDEuMzMzMzMzIDgxMC42NjY2NjdIMjU2aDg1LjMzMzMzM3oiIHAtaWQ9IjI2NzkiIGZpbGw9IiMyYzJjMmMiPjwvcGF0aD48L3N2Zz4="; 44 | 45 | export function processCodeBlock( 46 | source: string, 47 | el: HTMLElement, 48 | settings: SheetsSettings, 49 | ctx: MarkdownPostProcessorContext 50 | ) { 51 | // eslint-disable-next-line @typescript-eslint/no-unused-vars 52 | 53 | // const containerHeight = Math.clamp((ctx as any).containerEl.offsetHeight, 200, 800); 54 | // TODO: check this actually exists 55 | // let bgColor = "#ffffff"; 56 | // let fgColor = "#000"; //"#a0a0a0"; 57 | // const cel = document.getElementsByClassName("view-content")[0]; 58 | // if (cel) { 59 | // const styles = getComputedStyle(cel); 60 | // bgColor = bgColor || styles.getPropertyValue("background"); 61 | // fgColor = fgColor || styles.getPropertyValue("color"); 62 | // } 63 | 64 | if ((ctx as any).spreadsheet) return; 65 | 66 | const options = { ...DEFAULT_OPTIONS, enableSave: settings.enableSaveToFile, autoSave: settings.autoSave, ...parseYaml(source) }; 67 | 68 | options.height = Math.max(options.height, MINHEIGHT); 69 | 70 | const { 71 | filename, 72 | height, 73 | width, 74 | rows, 75 | cols, 76 | fontSize, 77 | cellHeight, 78 | cellWidth, 79 | } = options; 80 | const containerWidth = () => 81 | width === "auto" ? (ctx as any).containerEl.offsetWidth || 1024 : width; 82 | 83 | const container = el; //.createDiv(); 84 | container.style.width = containerWidth() + "px"; 85 | container.tabIndex = -1; 86 | if (container.parentElement) { 87 | container.parentElement.style.overflow = "hidden"; 88 | } 89 | 90 | // @ts-ignore 91 | const view = app.workspace.getActiveFileView(); 92 | const mode = view?.getMode() === "source" ? "edit" : "read"; 93 | 94 | const spreadsheet_options: any = { 95 | mode, // edit | read 96 | showToolbar: true, 97 | showGrid: true, 98 | showContextmenu: true, 99 | showValidation: false, 100 | view: { 101 | height: () => height, 102 | width: () => { 103 | const w = containerWidth(); 104 | return w; 105 | }, 106 | }, 107 | row: { 108 | len: rows, 109 | height: cellHeight, 110 | }, 111 | col: { 112 | len: cols, 113 | width: cellWidth, 114 | }, 115 | style: { 116 | // bgcolor: "#fff", 117 | align: "left", 118 | valign: "middle", 119 | textwrap: false, 120 | strike: false, 121 | underline: false, 122 | // color: "#000", 123 | font: { 124 | // name: font, 125 | size: fontSize, 126 | bold: false, 127 | italic: false, 128 | } as any, 129 | }, 130 | formats: [ 131 | { 132 | key: 'date', 133 | numfmt: moment.localeData().longDateFormat('L').toLowerCase() , 134 | label: moment().format("L"), 135 | title: 'Short Date' 136 | }, 137 | { 138 | key: 'longdate', 139 | numfmt: moment.localeData().longDateFormat('LL').toLowerCase(), 140 | label: moment().format("LL"), 141 | title: 'Long Date' 142 | }, 143 | ] 144 | // onKeyDown: (evt) => { 145 | // } 146 | }; 147 | 148 | if (!filename || options.enableSave) { 149 | const el = document.createElement("div"); 150 | el.innerHTML = saveIcon; 151 | spreadsheet_options.extendToolbar = { 152 | left: [ 153 | { 154 | tip: "Save", 155 | el: el.firstChild, 156 | shortcut: "Ctrl+S", 157 | onClick: (s: any, d: any) => { 158 | if (!filename) saveDataIntoBlock(s, d, ctx); 159 | else { 160 | saveToFile((ctx as any).spreadsheet, filename); 161 | } 162 | }, 163 | }, 164 | ], 165 | }; 166 | } 167 | 168 | // setTimeout(() => { 169 | if (filename !== undefined) { 170 | (async () => { 171 | let data = undefined; 172 | try { 173 | const fileContent = await app.vault.adapter.readBinary( 174 | filename 175 | ); 176 | 177 | data = await parseFileContent(filename, fileContent); 178 | } catch (e) { 179 | console.warn(e); 180 | } 181 | 182 | (ctx as any).spreadsheet = createSpreadSheet( 183 | container, 184 | spreadsheet_options, 185 | { ...options, data: data }, 186 | ctx 187 | ); 188 | // .loadData(); 189 | })(); 190 | } else { 191 | 192 | let wait = 0; 193 | if(!(ctx as any).containerEl.offsetWidth) { 194 | wait = 500; // hack for first opening 195 | } 196 | setTimeout(()=>{ 197 | (ctx as any).spreadsheet = createSpreadSheet( 198 | container, 199 | spreadsheet_options, 200 | { ...options }, 201 | ctx 202 | ); 203 | },wait); 204 | 205 | } 206 | // }, 0); 207 | 208 | // (ctx as any).spreadsheet = s; 209 | 210 | // see https://docs.sheetjs.com/docs/demos/grid/xs 211 | // https://docs.sheetjs.com/xspreadsheet/ 212 | // https://github.com/myliang/x-spreadsheet 213 | // https://forum.obsidian.md/t/saving-changes-in-codeblock-post-processor/47393 214 | // https://codesandbox.io/s/x-spreadsheet-react-3v1bw?file=/src/Spreadsheet.js:527-774 215 | // https://github.com/wolf-table/table 216 | } 217 | 218 | async function parseFileContent(filename: string, fileContent: ArrayBuffer) { 219 | const ext = filename.slice(filename.lastIndexOf(".")).toLowerCase(); 220 | if (ext === ".xlsx" || ext === ".csv") { 221 | const workbook = new ExcelJS.Workbook(); 222 | 223 | // let excelWorkbook : ExcelJS.Workbook | undefined = undefined; 224 | if(ext === ".csv") { 225 | 226 | await workbook.csv.read(new Readable({ 227 | read() { 228 | this.push(Buffer.from(fileContent)); 229 | this.push(null); 230 | } 231 | })); 232 | 233 | } else { 234 | await workbook.xlsx.load(fileContent); 235 | } 236 | 237 | const data2 = toSpreadsheet(workbook); 238 | return data2; 239 | } else { 240 | const xlsx = XLSX.read(fileContent, { 241 | cellStyles: true, 242 | sheetStubs: true, // > 243 | }); 244 | // eslint-disable-next-line @typescript-eslint/no-unused-vars 245 | const data = stox(xlsx); 246 | return data; 247 | } 248 | } 249 | -------------------------------------------------------------------------------- /src/Views/save.svg: -------------------------------------------------------------------------------- 1 | 3 | 6 | -------------------------------------------------------------------------------- /src/Views/spreadSheetWrapper.ts: -------------------------------------------------------------------------------- 1 | // import { Spreadsheet } from 'x-data-spreadsheet'; 2 | /* eslint-disable @typescript-eslint/no-explicit-any */ 3 | import { MarkdownPostProcessorContext, MarkdownView, Notice, debounce, stringifyYaml } from "obsidian"; 4 | import * as XLSX from "xlsx"; 5 | import { xtos } from "../utils/xlsxpread"; 6 | import { toExcelJS } from "src/utils/excelConverter"; 7 | import { SheetData, SpreadsheetData } from "x-data-spreadsheet"; 8 | // HACK 9 | import Spreadsheet from "x-data-spreadsheet"; 10 | import { getSheetjsSettings } from "src/main"; 11 | // import * as Spreadsheet from "x-data-spreadsheet"; 12 | // const { Spreadsheet } = require("x-data-spreadsheet"); 13 | 14 | 15 | function resolve_book_type(fileName: string): XLSX.BookType { 16 | const _BT: any = { 17 | xls: "biff8", 18 | htm: "html", 19 | slk: "sylk", 20 | socialcalc: "eth", 21 | Sh33tJS: "WTF", 22 | }; 23 | let bookType = "xlsx"; 24 | const ext = fileName.slice(fileName.lastIndexOf(".")).toLowerCase(); 25 | if (ext.match(/^\.[a-z]+$/)) { 26 | bookType = ext.slice(1); 27 | } 28 | bookType = _BT[bookType] || bookType; 29 | return bookType as XLSX.BookType; 30 | } 31 | 32 | // eslint-disable-next-line @typescript-eslint/no-unused-vars 33 | function applyStyles(ssdata: any, wb: XLSX.WorkBook) { 34 | for (const sheet of ssdata) { 35 | const { name, styles, rows } = sheet; 36 | for (const rowId in rows) { 37 | const cells = rows[rowId]["cells"]; 38 | for (const cellId in cells) { 39 | const cell = cells[cellId]; 40 | if (cell.style !== undefined) { 41 | const wbStyle = styleSS2WB(styles[cell.style]); 42 | //TODO: apply to the right WB cell 43 | const cellRef = XLSX.utils.encode_cell({ 44 | r: Number(rowId), 45 | c: Number(cellId), 46 | }); 47 | wb.Sheets[name][cellRef].s = wbStyle; 48 | } 49 | } 50 | } 51 | } 52 | } 53 | 54 | 55 | 56 | 57 | export interface SheetOptions { 58 | filename?: string; 59 | data?: any; 60 | enableSave?: boolean; 61 | autoSave?: boolean; 62 | } 63 | 64 | export function createSpreadSheet( 65 | container: HTMLElement, 66 | spreadsheet_options: any, 67 | options: SheetOptions, 68 | ctx: MarkdownPostProcessorContext 69 | ) { 70 | 71 | // const data: SheetData[] = prepareDataForLoading(options.data as SpreadsheetData) 72 | 73 | const spreadSheet = new Spreadsheet( 74 | container, 75 | spreadsheet_options 76 | ) 77 | // .loadData(options.data || {}); 78 | 79 | const settings = getSheetjsSettings() 80 | 81 | prepareDataForLoading(spreadSheet, options.data as SpreadsheetData) 82 | 83 | 84 | if(options.autoSave) { 85 | spreadSheet.change( 86 | debounce((_data) => { 87 | // save data 88 | if (options.filename && options.enableSave) { 89 | saveToFile(spreadSheet, options.filename); 90 | } else { 91 | // at the moment we avoid since this would cause re-rendering 92 | // saveDataIntoBlock(null,null,ctx) 93 | } 94 | 95 | // XLSX.writeFile(xtos(s.getData(data)) as any, filename); 96 | }, 1000) 97 | ); 98 | 99 | 100 | } 101 | 102 | return spreadSheet; 103 | } 104 | 105 | 106 | export function saveDataIntoBlock( 107 | data: any, 108 | sheet: any, 109 | ctx: MarkdownPostProcessorContext 110 | ) { 111 | const s = (ctx as any).spreadsheet as Spreadsheet; 112 | const dts = prepareDataForSaving( s ); 113 | 114 | const view = app.workspace.getActiveViewOfType(MarkdownView); 115 | if (!view) return; 116 | if (view.getMode() === "source") { 117 | const sec = ctx.getSectionInfo((ctx as any).el as HTMLElement); 118 | if (sec) { 119 | const obj = { data: dts }; 120 | const yaml = stringifyYaml(obj) + "\n"; 121 | view?.editor.replaceRange( 122 | yaml, 123 | { line: sec?.lineStart + 1, ch: 0 }, 124 | { line: sec?.lineEnd, ch: 0 }, 125 | "*" 126 | ); 127 | console.info("Data saved on code block"); 128 | } 129 | } else { 130 | // preview 131 | new Notice("Sheet not saved while in reading mode"); 132 | } 133 | } 134 | 135 | 136 | export async function saveToFile(spreadSheet: Spreadsheet, filename: string) { 137 | 138 | const spreadsheetData = spreadSheet.getData() as any[]; 139 | const bookType = resolve_book_type(filename); 140 | if(bookType === 'xlsx' || bookType === 'csv'){ 141 | const workbook = toExcelJS(spreadsheetData); 142 | if(bookType === 'xlsx'){ 143 | const buffer = await workbook.xlsx.writeBuffer(); 144 | app.vault.adapter.writeBinary(filename, buffer); 145 | } else { 146 | const buffer = await workbook.csv.writeBuffer(); 147 | app.vault.adapter.writeBinary(filename, buffer); 148 | } 149 | 150 | } else { 151 | const wb = xtos(spreadsheetData) as XLSX.WorkBook; 152 | // applyStyles(spreadsheetData, wb); 153 | const bytes = XLSX.write(wb, { 154 | bookType: bookType, 155 | type: "buffer", 156 | compression: true, 157 | bookSST: true, 158 | cellStyles: true, 159 | }); 160 | app.vault.adapter.writeBinary(filename, bytes); 161 | } 162 | 163 | 164 | 165 | 166 | 167 | 168 | // fs.writeFile(filename,bytes); 169 | 170 | } 171 | 172 | function styleSS2WB(ssstyle: any) { 173 | const style: any = { patternType: "solid" }; 174 | if (ssstyle.bgcolor) { 175 | style.bgColor = { 176 | rgb: ssstyle.bgcolor.substring(1), 177 | }; 178 | } 179 | 180 | if (ssstyle.color) { 181 | style.fgColor = { 182 | rgb: ssstyle.color.substring(1), 183 | }; 184 | } 185 | return style; 186 | } 187 | 188 | 189 | export function prepareDataForSaving(spreadSheet: Spreadsheet): SpreadsheetData { 190 | const data = spreadSheet.getData() as SheetData[]; 191 | 192 | // get some info 193 | const selector = (spreadSheet as any).sheet.data.selector; 194 | const sheetName = (spreadSheet as any).sheet.data.name; 195 | 196 | 197 | 198 | for(const sheet of data){ 199 | const actualStyles = []; 200 | const usedStyles = new Map(); 201 | if(sheet.styles !== undefined) { 202 | for(const rowId in sheet.rows) { 203 | const rowNum = Number(rowId) 204 | if(!isNaN(rowNum)) { 205 | const row = sheet.rows[rowNum]; 206 | for(const cellId in row.cells) { 207 | const cellNum = Number(cellId); 208 | const cell = row.cells[cellNum]; 209 | if(cell.style !== undefined){ 210 | if(usedStyles.has(cell.style)){ 211 | cell.style = usedStyles.get(cell.style) 212 | } else { 213 | actualStyles.push(sheet.styles[cell.style]) 214 | const index = actualStyles.length-1; 215 | usedStyles.set(cell.style, index) 216 | cell.style = index; 217 | } 218 | } 219 | } 220 | } 221 | } 222 | } 223 | sheet.styles = actualStyles; 224 | } 225 | 226 | const spreadSheetData : SpreadsheetData = {...data} 227 | 228 | spreadSheetData.state = { 229 | sheetName, 230 | selector 231 | } 232 | 233 | return spreadSheetData; 234 | } 235 | 236 | function prepareDataForLoading(spreadsheet:Spreadsheet, spreadSheetData: SpreadsheetData): Spreadsheet { 237 | if(spreadSheetData === undefined){ 238 | return spreadsheet.loadData({}); 239 | } else { 240 | const sheets = [] 241 | for(const sheetId in spreadSheetData){ 242 | const sheetNum = Number(sheetId) 243 | if(!isNaN(sheetNum)){ 244 | sheets[sheetNum] = spreadSheetData[sheetId] 245 | } 246 | } 247 | spreadsheet.loadData(sheets); 248 | if(spreadSheetData.state?.sheetName){ 249 | // const d = this.datas[index]; 250 | // this.sheet.resetData(d); 251 | const s = (spreadsheet as any); 252 | // const d = s.datas.find(d => d.name === spreadSheetData.state?.sheetName) 253 | const i = s.datas.findIndex((d:any) => d.name === spreadSheetData.state?.sheetName) 254 | 255 | const d = s.datas[i]; 256 | const selector = spreadSheetData.state?.selector 257 | if(selector){ 258 | // d.selector = spreadSheetData.state?.selector; 259 | d.selector.setIndexes(selector.ri, selector.ci); 260 | d.selector.range.sci = selector.range.sci; 261 | d.selector.range.sri = selector.range.sri; 262 | d.selector.range.eci = selector.range.eci; 263 | d.selector.range.eri = selector.range.eri; 264 | d.selector.range.h = selector.range.h; 265 | d.selector.range.w = selector.range.w; 266 | 267 | } 268 | if(i>=0){ 269 | // TODO: provide an ad hoc method in x-spreadsheet 270 | s.bottombar.clickSwap2(s.bottombar.items[i]); 271 | } 272 | 273 | } 274 | return spreadsheet; 275 | } 276 | } 277 | -------------------------------------------------------------------------------- /src/main.ts: -------------------------------------------------------------------------------- 1 | import { DEFAULT_SETTINGS, SheetsSettings } from "src/Settings"; 2 | import { addIcon, MarkdownView } from "obsidian"; 3 | 4 | 5 | // import { MathResult } from './Extensions/ResultMarkdownChild'; 6 | /* eslint-disable @typescript-eslint/no-unused-vars */ 7 | import { 8 | App, 9 | finishRenderMath, 10 | loadMathJax, 11 | Modal, 12 | Plugin, 13 | WorkspaceLeaf, 14 | } from "obsidian"; 15 | import { SheetjsSettingsTab } from "src/SettingTab"; 16 | import { processCodeBlock } from "./Views/SheetView"; 17 | 18 | 19 | const sheetSVG = ` 20 | `; 21 | 22 | // Remember to rename these classes and interfaces! 23 | 24 | let gSettings: SheetsSettings; 25 | 26 | export function getSheetjsSettings() { return gSettings; } 27 | export default class SheetjsPlugin extends Plugin { 28 | settings: SheetsSettings; 29 | 30 | async onload() { 31 | await this.loadSettings(); 32 | 33 | 34 | addIcon("sheet",sheetSVG); 35 | 36 | 37 | this.registerCodeBlock(); 38 | 39 | 40 | this.addSettingTab(new SheetjsSettingsTab(this.app, this)); 41 | } 42 | 43 | 44 | 45 | 46 | onunload() { 47 | } 48 | 49 | async loadSettings() { 50 | this.settings = Object.assign( 51 | {}, 52 | DEFAULT_SETTINGS, 53 | await this.loadData() 54 | ); 55 | gSettings = this.settings; 56 | } 57 | 58 | async saveSettings() { 59 | await this.saveData(this.settings); 60 | } 61 | 62 | 63 | 64 | async registerCodeBlock() { 65 | 66 | this.registerMarkdownCodeBlockProcessor( 67 | "sheet", 68 | (source, el, ctx) => { 69 | processCodeBlock(source, el, this.settings, ctx); 70 | } 71 | ); 72 | } 73 | 74 | } 75 | 76 | 77 | -------------------------------------------------------------------------------- /src/utils/excelColors.ts: -------------------------------------------------------------------------------- 1 | // Sample theme color index 2 | // const themeColorIndex = 1; // The theme color index (0-9) 3 | // const tintVal = -0.5; // The tint value (-1 to 1) 4 | 5 | // Sample Office Color Themes 6 | const officeThemeColors = [ 7 | [255, 255, 255], // White 8 | [0, 0, 0], // Black 9 | [238, 236, 225], // Tan 10 | [31, 73, 125], // Dark Blue 11 | [79, 129, 189], // Blue 12 | [192, 80, 77], // Red 13 | [155, 187, 89], // Green 14 | [128, 100, 162], // Purple 15 | [75, 172, 198], // Aqua 16 | [245, 150, 70], // Orange 17 | ]; 18 | 19 | const RGBToHSL = (r:number, g:number, b:number) => { 20 | r /= 255; 21 | g /= 255; 22 | b /= 255; 23 | const l = Math.max(r, g, b); 24 | const s = l - Math.min(r, g, b); 25 | const h = s 26 | ? l === r 27 | ? (g - b) / s 28 | : l === g 29 | ? 2 + (b - r) / s 30 | : 4 + (r - g) / s 31 | : 0; 32 | return [ 33 | 60 * h < 0 ? 60 * h + 360 : 60 * h, 34 | 100 * (s ? (l <= 0.5 ? s / (2 * l - s) : s / (2 - (2 * l - s))) : 0), 35 | (100 * (2 * l - s)) / 2, 36 | ]; 37 | }; 38 | 39 | // TODO: read theme from XML 40 | export function convertThemeColorToRGB( 41 | themeColorIndex: number, 42 | tintVal: number 43 | ) { 44 | const baseColor = officeThemeColors[themeColorIndex]; 45 | const baseHSL = RGBToHSL(baseColor[0],baseColor[1], baseColor[2]) //rgb2hsl(baseColor); 46 | const lumination = baseHSL[2]; 47 | if (tintVal < 0) { 48 | baseHSL[2] = lumination * (1.0 + tintVal); 49 | } else { 50 | baseHSL[2] = lumination * (1.0 - tintVal) + 100 * tintVal; 51 | } 52 | 53 | // return HSLToRGB(baseHSL[0] / 360, baseHSL[1] / 100, baseHSL[2] / 100); 54 | return hsl2rgb(baseHSL[0], baseHSL[1] / 100, baseHSL[2] / 100); 55 | } 56 | 57 | // input: h as an angle in [0,360] and s,l in [0,1] 58 | function hsl2rgb(h:number,s:number,l:number) 59 | { 60 | const a=s*Math.min(l,1-l); 61 | const f= (n:number,k=(n+h/30)%12) => l - a*Math.max(Math.min(k-3,9-k,1),-1); 62 | return [f(0)*255,f(8)*255,f(4)*255].map(Math.round); 63 | } 64 | 65 | export function rgbToHex(r:number, g:number, b:number) { 66 | return r.toString(16) + g.toString(16) + b.toString(16); 67 | } 68 | -------------------------------------------------------------------------------- /src/utils/excelConverter.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable @typescript-eslint/no-explicit-any */ 2 | import { 3 | BorderStyle, 4 | Borders, 5 | CellFormulaValue, 6 | Column, 7 | Table, 8 | Workbook, 9 | } from "exceljs"; 10 | import { convertThemeColorToRGB, rgbToHex } from "./excelColors"; 11 | import { CellData, CellStyle, RowData, SheetData } from "x-data-spreadsheet"; 12 | // import { SpreadsheetData } from "x-data-spreadsheet"; 13 | 14 | declare module "x-data-spreadsheet" { 15 | interface RowData { 16 | height?: number; 17 | } 18 | } 19 | 20 | type borderDir = "top" | "bottom" | "left" | "right"; 21 | 22 | export function toSpreadsheet(wb: Workbook) { 23 | function mapColor( 24 | oStyle: CellStyle, 25 | border: Partial, 26 | what: borderDir 27 | ) { 28 | if (border[what] && border[what]?.style && oStyle.border) { 29 | oStyle.border[what] = [ 30 | // eslint-disable-next-line @typescript-eslint/no-non-null-assertion 31 | border[what]!.style!.toString(), 32 | // eslint-disable-next-line @typescript-eslint/no-non-null-assertion 33 | "#" + getColor(border[what]!.color), 34 | ]; 35 | } 36 | } 37 | 38 | 39 | 40 | const out = wb.worksheets.map((ws) => { 41 | const ows: SheetData = { 42 | name: ws.name, 43 | rows: {}, 44 | cols: {}, 45 | merges: [], 46 | 47 | // freezes: 48 | }; 49 | 50 | ows.styles = []; 51 | 52 | if (ws.columns) { 53 | for (const col of ws.columns) { 54 | if (col.width && ows.cols && col.number) { 55 | ows.cols[col.number - 1] = { width: width2px(col.width) }; 56 | } 57 | } 58 | } 59 | // TODO: use options 60 | ows.cols!.len = Math.max(25, ws.actualColumnCount); 61 | 62 | ws.eachRow((row, rowNumber) => { 63 | const rowId = row.number - 1; 64 | const rowob: RowData = { 65 | cells: {}, 66 | }; 67 | 68 | if (ows.rows) { 69 | ows.rows[rowId] = rowob; 70 | } 71 | if (row.height) { 72 | // px = pt * ( 72pt / 96 ) 73 | 74 | rowob.height = pt2px(row.height); 75 | } 76 | if (row.hidden) { 77 | rowob.hidden = true; 78 | // TODO: implementit! 79 | } 80 | 81 | row.eachCell((cell, cellNumber) => { 82 | const cellOb: CellData = { 83 | text: "" 84 | }; 85 | 86 | try { 87 | cellOb.text = cell.text 88 | } catch {} 89 | 90 | if (cell.formula) cellOb.text = "=" + cell.formula; 91 | 92 | // style 93 | const oStyle: CellStyle = {}; 94 | if (cell.style.fill) { 95 | if (cell.style.fill.type === "pattern") { 96 | const fgColor = cell.style.fill.fgColor; 97 | if (fgColor) { 98 | const hexColor = getColor(fgColor); 99 | if (hexColor) { 100 | oStyle.bgcolor = "#" + hexColor; 101 | } 102 | } 103 | } 104 | } 105 | 106 | if (cell.style.border) { 107 | const border = cell.style.border; 108 | oStyle.border = {}; 109 | ["top", "bottom", "left", "right"].forEach((what) => { 110 | mapColor(oStyle, border, what as borderDir); 111 | }); 112 | } 113 | if (cell.style.font) { 114 | const font = cell.style.font; 115 | 116 | if (font.bold) { 117 | oStyle.font = oStyle.font || {}; 118 | oStyle.font.bold = true; 119 | } 120 | if (font.color) { 121 | const hexColor = getColor(font.color); 122 | if (hexColor) { 123 | oStyle.color = "#" + hexColor; 124 | } 125 | } 126 | if (font.italic) { 127 | oStyle.font = oStyle.font || {}; 128 | // oStyle.font 129 | oStyle.font.italic = true; 130 | } 131 | if (font.strike) { 132 | oStyle.strike = true; 133 | } 134 | if (font.underline) { 135 | oStyle.underline = true; 136 | } 137 | if (font.name) { 138 | oStyle.font = oStyle.font || {}; 139 | oStyle.font.name = font.name; 140 | } 141 | if (font.family) { 142 | oStyle.font = oStyle.font || {}; 143 | oStyle.font.family = font.family; 144 | } 145 | if (font.size) { 146 | oStyle.font = oStyle.font || {}; 147 | oStyle.font.size = font.size; 148 | } 149 | } 150 | if (cell.style.alignment) { 151 | // 152 | const alig = cell.style.alignment; 153 | if (alig.vertical) { 154 | (oStyle as any).valign = alig.vertical; 155 | } 156 | if (alig.horizontal) { 157 | (oStyle as any).align = alig.horizontal; 158 | } 159 | if (cell.style.alignment.wrapText) { 160 | oStyle.textwrap = true; 161 | } 162 | } 163 | if (cell.style.numFmt) { 164 | const numFmt = cell.style.numFmt; 165 | oStyle.format = numFmt; 166 | } 167 | if (cell.style.protection) { 168 | //TODO: 169 | } 170 | 171 | if (Object.keys(oStyle).length > 0 && ows.styles) { 172 | const j = JSON.stringify(oStyle); 173 | let styleIndex = ows.styles.findIndex( 174 | (s) => JSON.stringify(s) == j 175 | ); 176 | if (styleIndex < 0) { 177 | ows.styles?.push(oStyle); 178 | styleIndex = ows.styles.length - 1; 179 | } 180 | cellOb.style = styleIndex; 181 | } 182 | 183 | if (!cell.isMerged || !cell.model.master) { 184 | rowob.cells[Number(cell.col) - 1] = cellOb; 185 | if (cell.isMerged) { 186 | const merge = (ws as any)._merges[cell.address]; 187 | cellOb.merge = [ 188 | (merge.bottom - merge.top) as number, 189 | (merge.right - merge.left) as number, 190 | ]; 191 | } 192 | } else { 193 | // 194 | } 195 | }); 196 | }); 197 | 198 | // TODO: use options 199 | ows.rows!.len = Math.max(100, ws.actualRowCount); 200 | // merges 201 | const merges = []; 202 | for (const m in (ws as any)._merges) { 203 | const merge = (ws as any)._merges[m]; 204 | const range = merge.range; 205 | merges.push(range); 206 | } 207 | ows.merges = merges; 208 | 209 | if(typeof(ws.autoFilter) === "string"){ 210 | ows.autofilter = { 211 | ref: ws.autoFilter, 212 | filters: [], 213 | }; 214 | } 215 | 216 | return ows; 217 | }); 218 | 219 | return out; 220 | } 221 | function pt2px(pt: number) { 222 | return Math.round(pt * 1.3333333); 223 | } 224 | 225 | function px2pt(px: number) { 226 | return Math.round(px * 0.75); 227 | } 228 | 229 | function width2px(w: number) { 230 | // TODO: get actual character width 231 | // 10 units = 64px 232 | return Math.round(w * 6.4); 233 | } 234 | 235 | function px2width(px: number) { 236 | return Math.round(px * 0.15625); 237 | } 238 | 239 | function getColor(fgColor: any) { 240 | if (fgColor.argb) { 241 | const hex = fgColor.argb.substring(2); 242 | return hex; 243 | } else if (fgColor.theme !== undefined) { 244 | const theme = fgColor?.theme; 245 | const tint = (fgColor as any).tint || 0; 246 | const rgb = convertThemeColorToRGB(theme, tint); 247 | const hex = rgbToHex(rgb[0], rgb[1], rgb[2]); 248 | return hex; 249 | } 250 | } 251 | 252 | function toColor(hex: string) { 253 | return { 254 | argb: "FF" + hex.replace("#", ""), 255 | }; 256 | } 257 | 258 | export function toExcelJS(data: SheetData[]): Workbook { 259 | function mapBorderColor( 260 | borders: Partial, 261 | cellstyle: CellStyle, 262 | what: borderDir 263 | ) { 264 | if (cellstyle.border) { 265 | const brd = cellstyle.border[what]; 266 | if (brd) { 267 | const [style, color] = brd; 268 | borders[what] = { 269 | style: style as BorderStyle, 270 | color: toColor(color), 271 | }; 272 | } 273 | } 274 | } 275 | 276 | const workbook = new Workbook(); 277 | for (const ssheet of data) { 278 | const wsheet = workbook.addWorksheet(ssheet.name); 279 | 280 | if (ssheet.cols !== undefined) { 281 | const colIds = Object.keys(ssheet.cols) 282 | .filter((key) => !isNaN(Number(key))) 283 | .map((key) => Number(key)); 284 | 285 | const maxColid = Math.max(...colIds); 286 | 287 | const wscols: Partial[] = []; 288 | for (let colid = 0; colid <= maxColid; colid++) { 289 | const num = colid + 1; 290 | const col: Partial = { 291 | number: num, 292 | key: num.toString(), 293 | }; 294 | const scol = ssheet.cols[colid]; 295 | 296 | if (scol?.width) { 297 | col.width = px2width(scol.width); 298 | } 299 | wscols.push(col); 300 | } 301 | 302 | wsheet.columns = wscols; 303 | } 304 | 305 | if (ssheet.rows !== undefined) { 306 | for (const rowId in ssheet.rows) { 307 | if (!isNaN(Number(rowId))) { 308 | const rowNum = Number(rowId); 309 | const rowdata = ssheet.rows[rowNum]; 310 | 311 | const row = wsheet.getRow(rowNum + 1); 312 | // cells, height, hidden 313 | if (rowdata.hidden) { 314 | row.hidden = true; 315 | } 316 | if (rowdata.height !== undefined) { 317 | row.height = px2pt(rowdata.height); 318 | } 319 | for (const cellId in rowdata.cells) { 320 | const cellNum = Number(cellId); 321 | const celldata = rowdata.cells[cellNum]; 322 | const cell = row.getCell(cellNum + 1); 323 | 324 | if (celldata.text?.startsWith("=")) { 325 | cell.value = { 326 | formula: celldata.text.substring(1), 327 | } as CellFormulaValue; 328 | } else if (!isNaN(Number(celldata.text))) { 329 | cell.value = Number(celldata.text); 330 | } else if (!isNaN(Date.parse(celldata.text))) { 331 | cell.value = new Date(celldata.text); 332 | } else { 333 | cell.value = celldata.text; 334 | } 335 | 336 | // style 337 | if (celldata.style !== undefined) { 338 | const cellstyle = ssheet.styles![celldata.style]; 339 | if (cellstyle.bgcolor) { 340 | cell.style.fill = { 341 | type: "pattern", 342 | pattern: "solid", 343 | fgColor: toColor(cellstyle.bgcolor), 344 | }; 345 | } 346 | 347 | if (cellstyle.border) { 348 | const borders: Partial = {}; 349 | 350 | ["top", "bottom", "right", "left"].forEach( 351 | (what) => { 352 | mapBorderColor( 353 | borders, 354 | cellstyle, 355 | what as borderDir 356 | ); 357 | } 358 | ); 359 | cell.style.border = borders; 360 | } 361 | 362 | if (cellstyle.font) { 363 | cell.style.font = cell.style.font || {}; 364 | if (cellstyle.font.bold) 365 | cell.style.font.bold = true; 366 | if (cellstyle.font.family !== undefined) 367 | cell.style.font.family = 368 | cellstyle.font.family; 369 | if (cellstyle.font.italic) 370 | cell.style.font.italic = true; 371 | if (cellstyle.font.name) 372 | cell.style.font.name = cellstyle.font.name; 373 | if (cellstyle.font.size !== undefined) 374 | cell.style.font.size = cellstyle.font.size; 375 | } 376 | if (cellstyle.color !== undefined) { 377 | cell.style.font = cell.style.font || {}; 378 | cell.style.font.color = getColor( 379 | cellstyle.color 380 | ); 381 | } 382 | if (cellstyle.strike) { 383 | cell.style.font = cell.style.font || {}; 384 | cell.style.font.strike = true; 385 | } 386 | if (cellstyle.underline) { 387 | cell.style.font = cell.style.font || {}; 388 | cell.style.font.underline = true; 389 | } 390 | if (cellstyle.textwrap) { 391 | cell.style.alignment = 392 | cell.style.alignment || {}; 393 | cell.style.alignment.wrapText = true; 394 | } 395 | 396 | if (cellstyle.align !== undefined) { 397 | cell.style.alignment = 398 | cell.style.alignment || {}; 399 | cell.style.alignment.horizontal = 400 | cellstyle.align; 401 | } 402 | 403 | if (cellstyle.valign !== undefined) { 404 | cell.style.alignment = 405 | cell.style.alignment || {}; 406 | cell.style.alignment.vertical = 407 | cellstyle.valign; 408 | } 409 | 410 | if ( 411 | cellstyle.format !== undefined && 412 | cellstyle.format !== "" 413 | ) { 414 | cell.style.numFmt = cellstyle.format; 415 | // if(cellstyle.format === "percent") { 416 | // cell.style.numFmt = "0.00%" 417 | // } else if (cellstyle.format === "eur") { 418 | // cell.style.numFmt = `#,##0.00 "€"` 419 | // } else if (cellstyle.format === "usd") { 420 | // cell.style.numFmt = `#,##0.00 "$"` 421 | // } else if (cellstyle.format === "date") { 422 | // cell.style.numFmt === "mm-dd-yy" 423 | // } else if (cellstyle.format === "time") { 424 | // cell.style.numFmt === "[$-F400]h:mm:ss AM/PM" 425 | // } 426 | } 427 | } 428 | 429 | // cell.numFmt = "00.00" 430 | } 431 | } 432 | } 433 | } 434 | 435 | const merges = ssheet.merges; 436 | if (merges) { 437 | merges.forEach((merge) => { 438 | wsheet.mergeCells(merge); 439 | }); 440 | } 441 | 442 | if (ssheet.autofilter) { 443 | wsheet.autoFilter = ssheet.autofilter.ref; 444 | // (wsheet as any).autoFilter = ssheet.autofilter; 445 | } 446 | } 447 | 448 | // workbook.creator 449 | // workbook.category 450 | // workbook.company 451 | // workbook.created // Date 452 | // workbook.creator 453 | // workbook.keywords 454 | // workbook.lastModifiedBy 455 | // workbook.manager 456 | // workbook.modified // Date 457 | // workbook.subject 458 | // workbook.title 459 | 460 | return workbook; 461 | } 462 | -------------------------------------------------------------------------------- /src/utils/xlsxpread.js: -------------------------------------------------------------------------------- 1 | /*! xlsxspread.js (C) SheetJS LLC -- https://sheetjs.com/ */ 2 | /* eslint-env browser */ 3 | /*global XLSX */ 4 | /*exported stox, xtos */ 5 | 6 | import * as XLSX from "xlsx" 7 | 8 | /** 9 | * Converts data from SheetJS to x-spreadsheet 10 | * 11 | * @param {Object} wb SheetJS workbook object 12 | * 13 | * @returns {Object[]} An x-spreadsheet data 14 | */ 15 | export function stox(wb) { 16 | var out = []; 17 | wb.SheetNames.forEach(function (name) { 18 | var o = { name: name, rows: {} }; 19 | var ws = wb.Sheets[name]; 20 | if(!ws || !ws["!ref"]) return; 21 | var range = XLSX.utils.decode_range(ws['!ref']); 22 | // sheet_to_json will lost empty row and col at begin as default 23 | range.s = { r: 0, c: 0 }; 24 | var aoa = XLSX.utils.sheet_to_json(ws, { 25 | raw: false, 26 | header: 1, 27 | range: range 28 | }); 29 | 30 | aoa.forEach(function (r, i) { 31 | var cells = {}; 32 | r.forEach(function (c, j) { 33 | cells[j] = { text: c }; 34 | 35 | var cellRef = XLSX.utils.encode_cell({ r: i, c: j }); 36 | 37 | if ( ws[cellRef] != null && ws[cellRef].f != null) { 38 | cells[j].text = "=" + ws[cellRef].f; 39 | } 40 | }); 41 | o.rows[i] = { cells: cells }; 42 | }); 43 | 44 | o.merges = []; 45 | (ws["!merges"]||[]).forEach(function (merge, i) { 46 | //Needed to support merged cells with empty content 47 | if (o.rows[merge.s.r] == null) { 48 | o.rows[merge.s.r] = { cells: {} }; 49 | } 50 | if (o.rows[merge.s.r].cells[merge.s.c] == null) { 51 | o.rows[merge.s.r].cells[merge.s.c] = {}; 52 | } 53 | 54 | o.rows[merge.s.r].cells[merge.s.c].merge = [ 55 | merge.e.r - merge.s.r, 56 | merge.e.c - merge.s.c 57 | ]; 58 | 59 | o.merges[i] = XLSX.utils.encode_range(merge); 60 | }); 61 | 62 | out.push(o); 63 | }); 64 | 65 | return out; 66 | } 67 | 68 | /** 69 | * Converts data from x-spreadsheet to SheetJS 70 | * 71 | * @param {Object[]} sdata An x-spreadsheet data object 72 | * 73 | * @returns {Object} A SheetJS workbook object 74 | */ 75 | export function xtos(sdata) { 76 | var out = XLSX.utils.book_new(); 77 | sdata.forEach(function (xws) { 78 | var ws = {}; 79 | var rowobj = xws.rows; 80 | var minCoord = { r: 0, c: 0 }, maxCoord = { r: 0, c: 0 }; 81 | for (var ri = 0; ri < rowobj.len; ++ri) { 82 | var row = rowobj[ri]; 83 | if (!row) continue; 84 | 85 | Object.keys(row.cells).forEach(function (k) { 86 | var idx = +k; 87 | if (isNaN(idx)) return; 88 | 89 | var lastRef = XLSX.utils.encode_cell({ r: ri, c: idx }); 90 | if (ri > maxCoord.r) maxCoord.r = ri; 91 | if (idx > maxCoord.c) maxCoord.c = idx; 92 | 93 | var cellText = row.cells[k].text, type = "s"; 94 | if (!cellText) { 95 | cellText = ""; 96 | type = "z"; 97 | } else if (!isNaN(Number(cellText))) { 98 | cellText = Number(cellText); 99 | type = "n"; 100 | } else if (cellText.toLowerCase() === "true" || cellText.toLowerCase() === "false") { 101 | cellText = Boolean(cellText); 102 | type = "b"; 103 | } 104 | 105 | ws[lastRef] = { v: cellText, t: type }; 106 | 107 | if (type == "s" && cellText[0] == "=") { 108 | ws[lastRef].f = cellText.slice(1); 109 | } 110 | 111 | if (row.cells[k].merge != null) { 112 | if (ws["!merges"] == null) ws["!merges"] = []; 113 | 114 | ws["!merges"].push({ 115 | s: { r: ri, c: idx }, 116 | e: { 117 | r: ri + row.cells[k].merge[0], 118 | c: idx + row.cells[k].merge[1] 119 | } 120 | }); 121 | } 122 | }); 123 | } 124 | ws["!ref"] = minCoord ? XLSX.utils.encode_range({ 125 | s: minCoord, 126 | e: maxCoord 127 | }) : "A1"; 128 | 129 | XLSX.utils.book_append_sheet(out, ws, xws.name); 130 | }); 131 | 132 | return out; 133 | } -------------------------------------------------------------------------------- /styles.scss: -------------------------------------------------------------------------------- 1 | // @import "x-data-spreadsheet/dist/xspreadsheet.css" 2 | // 3 | @import "node_modules/x-data-spreadsheet/dist/xspreadsheet"; 4 | 5 | // override 6 | 7 | // .x-spreadsheet { 8 | // background: var(--background-primary); 9 | // } 10 | 11 | // .x-spreadsheet { 12 | // --ss-accent-h: var(--accent-h); 13 | // --ss-accent-s: var(--accent-s); 14 | // --ss-accent-l: var(--accent-l); 15 | // } 16 | 17 | .x-spreadsheet { 18 | 19 | --ss-accent-h: var(--accent-h); 20 | --ss-accent-s: var(--accent-s); 21 | --ss-accent-l: var(--accent-l); 22 | --ss-background: var(--background-primary); 23 | --ss-background-secondary: var(--background-secondary); 24 | --ss-background-alt: var(--background-primary-alt); 25 | --ss-background-secondary-alt: var(--background-secondary-alt); 26 | --ss-text-color: var(--text-normal); 27 | --ss-text-color-muted: var(--text-muted); 28 | --ss-border-color: var(--divider-color); 29 | --item-hover: var(--background-modifier-hover); 30 | --toolbar-bg-active: var(--background-modifier-hover); 31 | } 32 | 33 | // div.x-spreadsheet-sheet 34 | // > div.x-spreadsheet-overlayer 35 | // > div 36 | // > div.x-spreadsheet-editor 37 | // > div 38 | // > textarea { 39 | // background-color: #ffffff; 40 | // // background-color: var(--background-primary); 41 | 42 | // color: #000000; 43 | // // color: var(--text-normal); 44 | // box-shadow: inherit; 45 | // } 46 | .x-spreadsheet-editor { 47 | textarea { 48 | border-radius: 0px;; 49 | } 50 | } 51 | // .x-spreadsheet-tooltip { 52 | // color: var(--text-normal); 53 | // background: var(--background-primary); 54 | // } 55 | 56 | // .x-spreadsheet-color-palette table td:hover { 57 | // border-color: var(--background-modifier-border-hover); 58 | // } 59 | 60 | // .x-spreadsheet-border-palette 61 | // .x-spreadsheet-border-palette-left 62 | // .x-spreadsheet-border-palette-cell:hover { 63 | // background-color: var(--background-primary); 64 | // } 65 | 66 | // .x-spreadsheet-resizer .x-spreadsheet-resizer-hover { 67 | // background-color: rgba(75, 137, 255, 0.25); 68 | // } 69 | 70 | // .x-spreadsheet-item { 71 | // background: var(--background-secondary); 72 | 73 | // color: var(--text-muted); 74 | // } 75 | 76 | // .x-spreadsheet-menu > li { 77 | // color: var(--text-muted); 78 | 79 | // &.active { 80 | // background-color: var(--background-primary); 81 | // color: var(--text-normal); 82 | // } 83 | // } 84 | 85 | // .x-spreadsheet-print-bar .-title { 86 | // color: var(--text-normal); 87 | // } 88 | 89 | // .x-spreadsheet-calendar { 90 | // color: var(--text-normal); 91 | // background: var(--background-primary); 92 | 93 | // .calendar-body td > .cell.active { 94 | // background: var(--background-primary); 95 | 96 | // color: var(--text-normal); 97 | // } 98 | 99 | // .calendar-header { 100 | // background: var(--background-secondary); 101 | 102 | // .calendar-header-right a:hover { 103 | // background: rgba(0, 0, 0, 0.08); 104 | // } 105 | // } 106 | 107 | // .calendar-body td > .cell { 108 | // &:hover { 109 | // background: #ecf6fd; 110 | // } 111 | 112 | // &.active, 113 | // &.active:hover { 114 | // background: #ecf6fd; 115 | // color: #2185d0; 116 | // } 117 | // } 118 | // } 119 | 120 | // .x-spreadsheet-datepicker { 121 | // box-shadow: 2px 2px 5px rgba(0, 0, 0, 0.2); 122 | // } 123 | 124 | // .x-spreadsheet-button { 125 | // color: var(--text-muted); 126 | // background: var(--background-secondary); 127 | 128 | // &.active, 129 | // &:hover { 130 | // background-color: var(--background-secondary); 131 | // color: var(--text-normal); 132 | // } 133 | // } 134 | 135 | // .x-spreadsheet-button.primary { 136 | // color: var(--text-normal); 137 | // background-color: var(--background-secondary); 138 | 139 | // &:hover, 140 | // &.active { 141 | // color: var(--text-normal); 142 | // background-color: var(--background-secondary); 143 | // } 144 | // } 145 | 146 | // .x-spreadsheet-form-input { 147 | // color: rgba(0, 0, 0, 0.87); 148 | 149 | // input { 150 | // -webkit-tap-highlight-color: rgba(255, 255, 255, 0); 151 | // background: var(--background-primary); 152 | // border: 1px solid var(--background-modifier-border-hover); 153 | // box-shadow: inset 0 1px 2px hsla(0, 0%, 4%, 0.06); 154 | 155 | // &:focus { 156 | // border-color: #123456; 157 | // box-shadow: inset 0 1px 2px rgba(12, 34, 56, 0.2); 158 | // } 159 | // } 160 | // } 161 | 162 | // .x-spreadsheet-form-select { 163 | // background: #fff; 164 | // border: 1px solid #e9e9e9; 165 | // color: rgba(0, 0, 0, 0.87); 166 | // box-shadow: inset 0 1px 2px hsla(0, 0%, 4%, 0.06); 167 | // } 168 | 169 | // .x-spreadsheet-form-field.error .x-spreadsheet-form-select, 170 | // .x-spreadsheet-form-field.error input { 171 | // border-color: #f04134; 172 | // } 173 | // .x-spreadsheet-form-field .tip { 174 | // color: #f04134; 175 | // } 176 | 177 | // .x-spreadsheet-toolbar, 178 | // .x-spreadsheet-bottombar { 179 | 180 | // background: var(--background-secondary); 181 | 182 | // } 183 | 184 | // .x-spreadsheet-toolbar-btn { 185 | // color: var(--text-muted); 186 | // background: var(--background-secondary); 187 | // } 188 | 189 | div.x-spreadsheet { 190 | overflow: hidden; 191 | } 192 | 193 | .x-spreadsheet-dimmer.active { 194 | display: none; 195 | z-index: -1; 196 | } 197 | 198 | ul.x-spreadsheet-menu { 199 | padding: 0px; 200 | margin: 0px; 201 | } 202 | 203 | div.x-spreadsheet-toolbar div.x-spreadsheet-icon { 204 | cursor: pointer; 205 | img { 206 | cursor: pointer; 207 | } 208 | } 209 | 210 | .x-spreadsheet-border-palette table tr td { 211 | overflow-y: visible; 212 | overflow-x: visible; 213 | } 214 | 215 | 216 | 217 | 218 | .x-spreadsheet-icon-img.arrow-down { 219 | margin: 0; 220 | border: 0; 221 | } 222 | 223 | // TODO: create custom classes for each dropdown item, then sets limits accordingly 224 | // we suppose a min height of 400px for the whole spreadhsheet 225 | 226 | // .x-spreadsheet-dropdown .x-spreadsheet-dropdown-content { 227 | // max-height: 300px; 228 | // overflow-y: auto; 229 | // } 230 | 231 | // .x-spreadsheet-dropdown-content .x-spreadsheet-dropdown-content { 232 | // z-index: 201; 233 | // .x-spreadsheet-dropdown-content { 234 | // z-index: 202; 235 | // } 236 | // } 237 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "baseUrl": ".", 4 | "paths": { 5 | "x-data-spreadsheet": ["node_modules/x-data-spreadsheet"] 6 | }, 7 | "inlineSourceMap": true, 8 | "inlineSources": true, 9 | "module": "ESNext", 10 | "target": "ES6", 11 | "allowJs": true, 12 | "noImplicitAny": true, 13 | "moduleResolution": "node", 14 | "importHelpers": true, 15 | "isolatedModules": true, 16 | "strictNullChecks": true, 17 | "esModuleInterop": false, 18 | // "allowSyntheticDefaultImports": true, 19 | "lib": [ 20 | "DOM", 21 | "ES5", 22 | "ES6", 23 | "ES7" 24 | ], 25 | "jsx": "react" 26 | }, 27 | "include": [ 28 | "**/*.ts","**/*.tsx","**/*.svg" 29 | ], 30 | "exclude": ["node_modules"] 31 | } 32 | -------------------------------------------------------------------------------- /version-bump.mjs: -------------------------------------------------------------------------------- 1 | import { readFileSync, writeFileSync } from "fs"; 2 | 3 | const targetVersion = process.env.npm_package_version; 4 | 5 | // read minAppVersion from manifest.json and bump version to target version 6 | let manifest = JSON.parse(readFileSync("manifest.json", "utf8")); 7 | const { minAppVersion } = manifest; 8 | manifest.version = targetVersion; 9 | writeFileSync("manifest.json", JSON.stringify(manifest, null, "\t")); 10 | 11 | // update versions.json with target version and minAppVersion from manifest.json 12 | let versions = JSON.parse(readFileSync("versions.json", "utf8")); 13 | versions[targetVersion] = minAppVersion; 14 | writeFileSync("versions.json", JSON.stringify(versions, null, "\t")); 15 | -------------------------------------------------------------------------------- /versions.json: -------------------------------------------------------------------------------- 1 | { 2 | "1.0.0": "0.15.0" 3 | } 4 | -------------------------------------------------------------------------------- /wb.json: -------------------------------------------------------------------------------- 1 | { 2 | "opts": { 3 | "Date1904": false, 4 | "CalcPrecision": true, 5 | "RefreshAll": false, 6 | "FullCalc": false, 7 | "CalcMode": 1, 8 | "CalcCount": 100, 9 | "CalcIter": false, 10 | "CalcDelta": 0.001, 11 | "CalcSaveRecalc": true 12 | }, 13 | "SheetNames": [ 14 | "Sheet1", 15 | "sheet3" 16 | ], 17 | "Sheets": { 18 | "Sheet1": { 19 | "!margins": { 20 | "left": 0.75, 21 | "right": 0.75, 22 | "top": 1, 23 | "bottom": 1, 24 | "header": 0.5, 25 | "footer": 0.5 26 | }, 27 | "A1": { 28 | "v": "Item", 29 | "t": "s", 30 | "z": "General", 31 | "w": "Item" 32 | }, 33 | "B1": { 34 | "v": "Cost", 35 | "t": "s", 36 | "z": "General", 37 | "w": "Cost" 38 | }, 39 | "C1": { 40 | "v": "Qty", 41 | "t": "s", 42 | "z": "General", 43 | "w": "Qty" 44 | }, 45 | "D1": { 46 | "v": "Price", 47 | "t": "s", 48 | "z": "General", 49 | "w": "Price" 50 | }, 51 | "A2": { 52 | "v": "Laser", 53 | "t": "s", 54 | "z": "General", 55 | "w": "Laser", 56 | "s": { 57 | "patternType": "solid", 58 | "fgColor": { 59 | "rgb": "CCFFCC" 60 | }, 61 | "bgColor": { 62 | "rgb": "000000" 63 | } 64 | } 65 | }, 66 | "B2": { 67 | "v": 100, 68 | "t": "n", 69 | "z": "General", 70 | "w": "100", 71 | "s": { 72 | "patternType": "solid", 73 | "fgColor": { 74 | "rgb": "CCFFCC" 75 | }, 76 | "bgColor": { 77 | "rgb": "000000" 78 | } 79 | } 80 | }, 81 | "C2": { 82 | "v": 2, 83 | "t": "n", 84 | "z": "General", 85 | "w": "2", 86 | "s": { 87 | "patternType": "solid", 88 | "fgColor": { 89 | "rgb": "CCFFCC" 90 | }, 91 | "bgColor": { 92 | "rgb": "000000" 93 | } 94 | } 95 | }, 96 | "D2": { 97 | "v": "=B2*C2", 98 | "t": "s", 99 | "z": "General", 100 | "w": "=B2*C2", 101 | "s": { 102 | "patternType": "solid", 103 | "fgColor": { 104 | "rgb": "CCFFCC" 105 | }, 106 | "bgColor": { 107 | "rgb": "000000" 108 | } 109 | } 110 | }, 111 | "A3": { 112 | "v": "Gun", 113 | "t": "s", 114 | "z": "General", 115 | "w": "Gun", 116 | "s": { 117 | "patternType": "solid", 118 | "fgColor": { 119 | "rgb": "CCFFCC" 120 | }, 121 | "bgColor": { 122 | "rgb": "000000" 123 | } 124 | } 125 | }, 126 | "B3": { 127 | "v": 123, 128 | "t": "n", 129 | "z": "General", 130 | "w": "123", 131 | "s": { 132 | "patternType": "solid", 133 | "fgColor": { 134 | "rgb": "CCFFCC" 135 | }, 136 | "bgColor": { 137 | "rgb": "000000" 138 | } 139 | } 140 | }, 141 | "C3": { 142 | "v": 3, 143 | "t": "n", 144 | "z": "General", 145 | "w": "3", 146 | "s": { 147 | "patternType": "solid", 148 | "fgColor": { 149 | "rgb": "CCFFCC" 150 | }, 151 | "bgColor": { 152 | "rgb": "000000" 153 | } 154 | } 155 | }, 156 | "D3": { 157 | "v": "=B3*C3", 158 | "t": "s", 159 | "z": "General", 160 | "w": "=B3*C3", 161 | "s": { 162 | "patternType": "solid", 163 | "fgColor": { 164 | "rgb": "CCFFCC" 165 | }, 166 | "bgColor": { 167 | "rgb": "000000" 168 | } 169 | } 170 | }, 171 | "A4": { 172 | "v": "Some", 173 | "t": "s", 174 | "z": "General", 175 | "w": "Some", 176 | "s": { 177 | "patternType": "solid", 178 | "fgColor": { 179 | "rgb": "CCFFCC" 180 | }, 181 | "bgColor": { 182 | "rgb": "000000" 183 | } 184 | } 185 | }, 186 | "B4": { 187 | "v": 234, 188 | "t": "n", 189 | "z": "General", 190 | "w": "234", 191 | "s": { 192 | "patternType": "solid", 193 | "fgColor": { 194 | "rgb": "CCFFCC" 195 | }, 196 | "bgColor": { 197 | "rgb": "000000" 198 | } 199 | } 200 | }, 201 | "C4": { 202 | "v": 1, 203 | "t": "n", 204 | "z": "General", 205 | "w": "1", 206 | "s": { 207 | "patternType": "solid", 208 | "fgColor": { 209 | "rgb": "CCFFCC" 210 | }, 211 | "bgColor": { 212 | "rgb": "000000" 213 | } 214 | } 215 | }, 216 | "D4": { 217 | "v": "=B4*C4", 218 | "t": "s", 219 | "z": "General", 220 | "w": "=B4*C4", 221 | "s": { 222 | "patternType": "solid", 223 | "fgColor": { 224 | "rgb": "CCFFCC" 225 | }, 226 | "bgColor": { 227 | "rgb": "000000" 228 | } 229 | } 230 | }, 231 | "A5": { 232 | "t": "z" 233 | }, 234 | "B5": { 235 | "t": "z" 236 | }, 237 | "C5": { 238 | "v": 3, 239 | "t": "n", 240 | "z": "General", 241 | "w": "3" 242 | }, 243 | "D5": { 244 | "v": "=B5*C5", 245 | "t": "s", 246 | "z": "General", 247 | "w": "=B5*C5" 248 | }, 249 | "A6": { 250 | "t": "z" 251 | }, 252 | "B6": { 253 | "t": "z" 254 | }, 255 | "C6": { 256 | "t": "z" 257 | }, 258 | "D6": { 259 | "v": "=B6*C6", 260 | "t": "s", 261 | "z": "General", 262 | "w": "=B6*C6" 263 | }, 264 | "A7": { 265 | "t": "z" 266 | }, 267 | "B7": { 268 | "t": "z" 269 | }, 270 | "C7": { 271 | "t": "z" 272 | }, 273 | "D7": { 274 | "v": "=B7*C7", 275 | "t": "s", 276 | "z": "General", 277 | "w": "=B7*C7" 278 | }, 279 | "A8": { 280 | "t": "z" 281 | }, 282 | "B8": { 283 | "t": "z" 284 | }, 285 | "C8": { 286 | "t": "z" 287 | }, 288 | "D8": { 289 | "v": "=SUM(D2:D7)", 290 | "t": "s", 291 | "z": "General", 292 | "w": "=SUM(D2:D7)" 293 | }, 294 | "!ref": "A1:D8" 295 | }, 296 | "sheet3": { 297 | "!margins": { 298 | "left": 0.75, 299 | "right": 0.75, 300 | "top": 1, 301 | "bottom": 1, 302 | "header": 0.5, 303 | "footer": 0.5 304 | }, 305 | "A1": { 306 | "v": 12, 307 | "t": "n", 308 | "z": "General", 309 | "w": "12" 310 | }, 311 | "B1": { 312 | "v": 23, 313 | "t": "n", 314 | "z": "General", 315 | "w": "23" 316 | }, 317 | "A2": { 318 | "t": "z", 319 | "s": { 320 | "patternType": "solid", 321 | "fgColor": { 322 | "rgb": "CCFFCC" 323 | }, 324 | "bgColor": { 325 | "rgb": "000000" 326 | } 327 | } 328 | }, 329 | "B2": { 330 | "t": "z", 331 | "s": { 332 | "patternType": "solid", 333 | "fgColor": { 334 | "rgb": "CCFFCC" 335 | }, 336 | "bgColor": { 337 | "rgb": "000000" 338 | } 339 | } 340 | }, 341 | "C2": { 342 | "t": "z", 343 | "s": { 344 | "patternType": "solid", 345 | "fgColor": { 346 | "rgb": "CCFFCC" 347 | }, 348 | "bgColor": { 349 | "rgb": "000000" 350 | } 351 | } 352 | }, 353 | "D2": { 354 | "t": "z", 355 | "s": { 356 | "patternType": "solid", 357 | "fgColor": { 358 | "rgb": "CCFFCC" 359 | }, 360 | "bgColor": { 361 | "rgb": "000000" 362 | } 363 | } 364 | }, 365 | "A3": { 366 | "t": "z", 367 | "s": { 368 | "patternType": "solid", 369 | "fgColor": { 370 | "rgb": "CCFFCC" 371 | }, 372 | "bgColor": { 373 | "rgb": "000000" 374 | } 375 | } 376 | }, 377 | "B3": { 378 | "t": "z", 379 | "s": { 380 | "patternType": "solid", 381 | "fgColor": { 382 | "rgb": "CCFFCC" 383 | }, 384 | "bgColor": { 385 | "rgb": "000000" 386 | } 387 | } 388 | }, 389 | "C3": { 390 | "t": "z", 391 | "s": { 392 | "patternType": "solid", 393 | "fgColor": { 394 | "rgb": "CCFFCC" 395 | }, 396 | "bgColor": { 397 | "rgb": "000000" 398 | } 399 | } 400 | }, 401 | "D3": { 402 | "t": "z", 403 | "s": { 404 | "patternType": "solid", 405 | "fgColor": { 406 | "rgb": "CCFFCC" 407 | }, 408 | "bgColor": { 409 | "rgb": "000000" 410 | } 411 | } 412 | }, 413 | "A4": { 414 | "t": "z", 415 | "s": { 416 | "patternType": "solid", 417 | "fgColor": { 418 | "rgb": "CCFFCC" 419 | }, 420 | "bgColor": { 421 | "rgb": "000000" 422 | } 423 | } 424 | }, 425 | "B4": { 426 | "t": "z", 427 | "s": { 428 | "patternType": "solid", 429 | "fgColor": { 430 | "rgb": "CCFFCC" 431 | }, 432 | "bgColor": { 433 | "rgb": "000000" 434 | } 435 | } 436 | }, 437 | "C4": { 438 | "t": "z", 439 | "s": { 440 | "patternType": "solid", 441 | "fgColor": { 442 | "rgb": "CCFFCC" 443 | }, 444 | "bgColor": { 445 | "rgb": "000000" 446 | } 447 | } 448 | }, 449 | "D4": { 450 | "t": "z", 451 | "s": { 452 | "patternType": "solid", 453 | "fgColor": { 454 | "rgb": "CCFFCC" 455 | }, 456 | "bgColor": { 457 | "rgb": "000000" 458 | } 459 | } 460 | }, 461 | "!ref": "A1:D4" 462 | } 463 | }, 464 | "Preamble": { 465 | "!protect": false 466 | }, 467 | "Strings": [ 468 | { 469 | "t": "Item", 470 | "raw": "Item", 471 | "r": "Item" 472 | }, 473 | { 474 | "t": "Cost", 475 | "raw": "Cost", 476 | "r": "Cost" 477 | }, 478 | { 479 | "t": "Qty", 480 | "raw": "Qty", 481 | "r": "Qty" 482 | }, 483 | { 484 | "t": "Price", 485 | "raw": "Price", 486 | "r": "Price" 487 | }, 488 | { 489 | "t": "Laser", 490 | "raw": "Laser", 491 | "r": "Laser" 492 | }, 493 | { 494 | "t": "=B2*C2", 495 | "raw": "=B2*C2", 496 | "r": "=B2*C2" 497 | }, 498 | { 499 | "t": "Gun", 500 | "raw": "Gun", 501 | "r": "Gun" 502 | }, 503 | { 504 | "t": "=B3*C3", 505 | "raw": "=B3*C3", 506 | "r": "=B3*C3" 507 | }, 508 | { 509 | "t": "Some", 510 | "raw": "Some", 511 | "r": "Some" 512 | }, 513 | { 514 | "t": "=B4*C4", 515 | "raw": "=B4*C4", 516 | "r": "=B4*C4" 517 | }, 518 | { 519 | "t": "=B5*C5", 520 | "raw": "=B5*C5", 521 | "r": "=B5*C5" 522 | }, 523 | { 524 | "t": "=B6*C6", 525 | "raw": "=B6*C6", 526 | "r": "=B6*C6" 527 | }, 528 | { 529 | "t": "=B7*C7", 530 | "raw": "=B7*C7", 531 | "r": "=B7*C7" 532 | }, 533 | { 534 | "t": "=SUM(D2:D7)", 535 | "raw": "=SUM(D2:D7)", 536 | "r": "=SUM(D2:D7)" 537 | } 538 | ], 539 | "SSF": { 540 | "0": "General", 541 | "1": "0", 542 | "2": "0.00", 543 | "3": "#,##0", 544 | "4": "#,##0.00", 545 | "5": "#,##0\\ \"€\";\\-#,##0\\ \"€\"", 546 | "6": "#,##0\\ \"€\";[Red]\\-#,##0\\ \"€\"", 547 | "7": "#,##0.00\\ \"€\";\\-#,##0.00\\ \"€\"", 548 | "8": "#,##0.00\\ \"€\";[Red]\\-#,##0.00\\ \"€\"", 549 | "9": "0%", 550 | "10": "0.00%", 551 | "11": "0.00E+00", 552 | "12": "# ?/?", 553 | "13": "# ??/??", 554 | "14": "m/d/yy", 555 | "15": "d-mmm-yy", 556 | "16": "d-mmm", 557 | "17": "mmm-yy", 558 | "18": "h:mm AM/PM", 559 | "19": "h:mm:ss AM/PM", 560 | "20": "h:mm", 561 | "21": "h:mm:ss", 562 | "22": "m/d/yy h:mm", 563 | "37": "#,##0 ;(#,##0)", 564 | "38": "#,##0 ;[Red](#,##0)", 565 | "39": "#,##0.00;(#,##0.00)", 566 | "40": "#,##0.00;[Red](#,##0.00)", 567 | "41": "_-* #,##0_-;\\-* #,##0_-;_-* \"-\"_-;_-@_-", 568 | "42": "_-* #,##0\\ \"€\"_-;\\-* #,##0\\ \"€\"_-;_-* \"-\"\\ \"€\"_-;_-@_-", 569 | "43": "_-* #,##0.00_-;\\-* #,##0.00_-;_-* \"-\"??_-;_-@_-", 570 | "44": "_-* #,##0.00\\ \"€\"_-;\\-* #,##0.00\\ \"€\"_-;_-* \"-\"??\\ \"€\"_-;_-@_-", 571 | "45": "mm:ss", 572 | "46": "[h]:mm:ss", 573 | "47": "mmss.0", 574 | "48": "##0.0E+0", 575 | "49": "@", 576 | "56": "\"上午/下午 \"hh\"時\"mm\"分\"ss\"秒 \"", 577 | "164": "\"上午/下午 \"hh\"時\"mm\"分\"ss\"秒 \"" 578 | }, 579 | "Themes": { 580 | "themeElements": { 581 | "clrScheme": [ 582 | { 583 | "name": "lt1", 584 | "rgb": "FFFFFF" 585 | }, 586 | { 587 | "name": "dk1", 588 | "rgb": "000000" 589 | }, 590 | { 591 | "name": "lt2", 592 | "rgb": "E7E6E6" 593 | }, 594 | { 595 | "name": "dk2", 596 | "rgb": "44546A" 597 | }, 598 | { 599 | "name": "accent1", 600 | "rgb": "4472C4" 601 | }, 602 | { 603 | "name": "accent2", 604 | "rgb": "ED7D31" 605 | }, 606 | { 607 | "name": "accent3", 608 | "rgb": "A5A5A5" 609 | }, 610 | { 611 | "name": "accent4", 612 | "rgb": "FFC000" 613 | }, 614 | { 615 | "name": "accent5", 616 | "rgb": "5B9BD5" 617 | }, 618 | { 619 | "name": "accent6", 620 | "rgb": "70AD47" 621 | }, 622 | { 623 | "name": "hlink", 624 | "rgb": "0563C1" 625 | }, 626 | { 627 | "name": "folHlink", 628 | "rgb": "954F72" 629 | } 630 | ] 631 | }, 632 | "raw": "\r\n" 633 | }, 634 | "Metadata": { 635 | "Country": [ 636 | "US", 637 | "US" 638 | ] 639 | }, 640 | "Workbook": { 641 | "Sheets": [ 642 | { 643 | "Hidden": 0, 644 | "name": "Sheet1", 645 | "CodeName": "Sheet1" 646 | }, 647 | { 648 | "Hidden": 0, 649 | "name": "sheet3", 650 | "CodeName": "sheet3" 651 | } 652 | ], 653 | "WBProps": { 654 | "date1904": false 655 | }, 656 | "Views": [ 657 | {} 658 | ] 659 | }, 660 | "Custprops": { 661 | "SystemIdentifier": 66573, 662 | "CodePage": 10000, 663 | "AppVersion": "16.0000", 664 | "ScaleCrop": false, 665 | "LinksUpToDate": false, 666 | "SharedDoc": false, 667 | "HyperlinksChanged": false, 668 | "FMTID": "02d5cdd59c2e1b10939708002b2cf9ae", 669 | "LastAuthor": "Gabriele Cannata", 670 | "Application": "Microsoft Macintosh Excel", 671 | "ModifiedDate": "2023-08-04T11:22:18Z", 672 | "DocSecurity": 0, 673 | "Worksheets": 2, 674 | "SheetNames": [ 675 | "Sheet1", 676 | "sheet3" 677 | ] 678 | }, 679 | "Props": { 680 | "SystemIdentifier": 66573, 681 | "CodePage": 10000, 682 | "AppVersion": "16.0000", 683 | "ScaleCrop": false, 684 | "LinksUpToDate": false, 685 | "SharedDoc": false, 686 | "HyperlinksChanged": false, 687 | "FMTID": "02d5cdd59c2e1b10939708002b2cf9ae", 688 | "LastAuthor": "Gabriele Cannata", 689 | "Application": "Microsoft Macintosh Excel", 690 | "ModifiedDate": "2023-08-04T11:22:18Z", 691 | "DocSecurity": 0, 692 | "Worksheets": 2, 693 | "SheetNames": [ 694 | "Sheet1", 695 | "sheet3" 696 | ] 697 | } 698 | } 699 | --------------------------------------------------------------------------------