├── LICENSE.txt ├── README.md ├── css ├── bootstrap-4.5.2.min.css ├── main.css └── offcanvas.css ├── database_files └── healthcare_records.db ├── exports ├── exported_healthcare_records.zip ├── icd9_mapping.json ├── patient_diagnosis.json ├── patient_info.json └── query.sql ├── img ├── CORS_error.png ├── basic_demo.gif ├── buy_me_a_taco.png ├── cover_image.png ├── encode_base64.gif ├── favicon-120.png ├── favicon-152.png ├── favicon-16x16.ico ├── favicon-196.png ├── favicon-32x32.ico ├── favicon-48x48.ico ├── favicon-76.png ├── icon.png ├── import_db.gif ├── logo.png ├── logo_white.png ├── site-logo.png ├── updated_layout(laptops_n_desktops).png ├── updated_layout(mobile).jpg ├── updated_layout(mobile-sidebar).jpg └── wasm_to_blob.png ├── index.html └── js ├── bootstrap-native-v4.js ├── custom.js ├── ie10-viewport-bug-workaround.js ├── polyfill.js ├── sql-asm-memory-growth.min.js ├── sql-asm.min.js ├── sql-browser.min.js ├── sql-wasm.min.js ├── sql-wasm.wasm └── sql_wasm_dataURL.js /LICENSE.txt: -------------------------------------------------------------------------------- 1 | MIT license 2 | =========== 3 | 4 | Copyright (c) 2017 sql.js authors (see AUTHORS) 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | 24 | 25 | 26 | # Some portions of the Makefile taken from: 27 | Copyright 2017 Ryusei Yamaguchi 28 | 29 | Permission is hereby granted, free of charge, to any person obtaining a copy of 30 | this software and associated documentation files (the "Software"), to deal in 31 | the Software without restriction, including without limitation the rights to 32 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 33 | the Software, and to permit persons to whom the Software is furnished to do so, 34 | subject to the following conditions: 35 | 36 | The above copyright notice and this permission notice shall be included in all 37 | copies or substantial portions of the Software. 38 | 39 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 40 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 41 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 42 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 43 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 44 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |
2 | logo 3 | 4 | # 💻 SQLite Browser Utility 5 | 6 | ### 🛠️ Read & Export SQLite Data in a JavaScript-enabled Browser. No server setup required. Just 🖱 double-click HTML file. 7 | 8 | **Original work by kripken (sql.js). C to JavaScript compiler by kripken (emscripten).** 9 | 10 |
11 | 12 | ### 👀 Preview 13 | 14 | 15 | 16 | #### Demo (1) File Import 17 | 18 | 19 | #### Demo (2) Data Export 20 | 21 | 22 | ### 🌟 Try it yourself 23 | [**Live Demo :: Link**](https://incubated-geek-cc.github.io/SQLiteBrowserUtility/) 24 | 25 | ### ✍ Read related post here 26 | 27 | [**Article :: Link :: 5 Key MySQL Operations which SQLite Commands can Emulate**](https://medium.com/geekculture/5-key-mysql-operations-which-sqlite-commands-can-emulate-b7a1a202856d) 28 |
29 | [**Article :: Link :: Implement SQLite on web with JavaScript — both Node & Browser with sql.js plugin**](https://medium.com/weekly-webtips/implement-sqlite-on-web-with-javascript-both-node-browser-with-sql-js-14448fd7a3cb) 30 |
31 | [**Article :: Link :: Read & Export SQLite Data in a JavaScript-enabled Browser Locally**](https://medium.com/weekly-webtips/read-export-sqlite-data-in-a-javascript-enabled-browser-locally-b655deda879d) 32 |
33 | [**Article :: Link :: How To Load & Run Local WASM Modules Without A Server Using Client-Side JavaScript**](https://geek-cc.medium.com/how-to-load-run-local-wasm-modules-without-a-server-using-client-side-javascript-692f7b89da7d) 34 | 35 | 36 | ### ⚠ Current Status: WIP 37 | 38 |

As of October 2023, UI has been changed to:

39 | 40 | #### Preview (1) On laptops and desktops 41 | 42 | 43 | 44 | #### Preview (2) On mobile 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 |
With sidebarWithout sidebar
60 | 61 |
62 | 「✓」 Include code editor and browse tables into a single view
63 | 「✓」 Code editor wrap lines toggle button
64 | 「✓」 Mobile-responsiveness
65 | 「✓」 Replace code editor area with latest query reflected i.e. when table is selected
66 | 「✓」 Export sample database
67 | 「✓」 Export updated database
68 | 「✓」 Include 'Reset' ⟲ button (clear cache & reload page)
69 | 「✓」 UI/UX refinement - e.g. disable/enable selections before/after uploads, drag & drop file feature added 70 |
71 | 72 |

Join me on 📝 Medium at ~ ξ(🎀˶❛◡❛) @geek-cc

73 | 74 | --- 75 | 76 | #### 🌮 Please buy me a Taco! 😋 -------------------------------------------------------------------------------- /css/main.css: -------------------------------------------------------------------------------- 1 | html, 2 | body { 3 | padding:0; 4 | margin:0; 5 | overflow:hidden; 6 | } 7 | body { 8 | width:100vw; 9 | height:100vh; 10 | padding: 0; 11 | font-family: system-ui,-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Oxygen,Ubuntu,Cantarell,"Fira Sans","Droid Sans","Helvetica Neue",Arial,sans-serif; 12 | font-size: 1rem; 13 | overflow-y:auto; 14 | } 15 | /*summary { 16 | display: list-item; 17 | cursor: pointer; 18 | list-style: none; 19 | margin-left: 15px; 20 | padding-left: 5px; 21 | } 22 | 23 | details[open] > summary:first-of-type { 24 | list-style-type: disclosure-open; 25 | list-style: none; 26 | margin-left: 15px; 27 | padding-left: 5px; 28 | margin-bottom: 0.325rem; 29 | }*/ 30 | body { 31 | overflow-y: auto; 32 | margin:0; 33 | padding:0; 34 | color: #54667a; 35 | background: #f2f7f8; 36 | position: relative; 37 | } 38 | #main-wrapper { 39 | margin-top: calc(0.3125rem + 35px + 1rem); 40 | height: calc(100% - 0.3125rem - 35px - 1rem - 1px); 41 | } 42 | #upload { 43 | display:none; 44 | } 45 | div#tableRecords.table-responsive { 46 | height:calc(100vh - 170px - .5rem); 47 | overflow-y:scroll; 48 | } 49 | 50 | div#tableQueryRecords.table-responsive { 51 | /*height: calc(100% - 0.3125rem - 0.3125rem - 35px - 1px - 2.5em - 28vh);*/ 52 | width: calc(100% - 8px); 53 | overflow-y: scroll; 54 | } 55 | 56 | div#tableQueryRecords.table-responsive table { 57 | min-width: 100%; 58 | height: calc(100% - 8px); 59 | } 60 | 61 | #infoPanel { 62 | overflow-y:auto; 63 | } 64 | 65 | .datatable.btn-link { 66 | width:100%; 67 | text-align: left; 68 | font-weight: 400; 69 | color: rgb(8 152 138); 70 | text-decoration: none; 71 | border: 0.5px solid rgba(28,205,188); 72 | } 73 | .datatable.btn-link:hover, 74 | .page-link:hover { 75 | color: #07695f; 76 | text-decoration: none; 77 | background-color: rgba(28,205,188,0.1); 78 | } 79 | .page-link.focus, 80 | .page-link:focus, 81 | .datatable.btn-link.focus, 82 | .datatable.btn-link:focus { 83 | box-shadow: 0 0 0 0.2rem rgba(8, 152, 138, .25); 84 | text-decoration: none; 85 | } 86 | 87 | a.datatable.btn-link { 88 | text-wrap: nowrap; 89 | overflow-x: hidden; 90 | text-overflow: ellipsis; 91 | } 92 | 93 | #currentQueryPageNo.form-control:focus { 94 | color: #495057; 95 | background-color: #fff; 96 | border-color: rgba(8, 152, 138); 97 | outline: 0; 98 | box-shadow: 0 0 0 0.2rem rgba(8, 152, 138, .25); 99 | } 100 | 101 | .table td, 102 | .table th { 103 | padding: 0.25rem; 104 | border-top: 1px solid #dee2e6; 105 | } 106 | hr { 107 | margin-top: 0.5rem; 108 | margin-bottom: 0.5rem; 109 | } 110 | hr.invisible-divider { 111 | border-top: 1px solid transparent; 112 | } 113 | a.page-link, 114 | a.dropdown-item { 115 | cursor:pointer; 116 | display: inline-flex; 117 | } 118 | #currentPageNo, #currentQueryPageNo { 119 | height: calc(31px - 0.5rem - 2px); 120 | width: calc(50px - 1rem); 121 | } 122 | .dropdown-item:focus, 123 | .dropdown-item:hover { 124 | background-color: #f0f5fb; 125 | } 126 | .page-item.disabled .page-link, 127 | .page-link { 128 | border-color:transparent; 129 | } 130 | 131 | #tableQueryDetails, 132 | #tableDetails { 133 | padding: 0.2rem 0; 134 | } 135 | 136 | #codeEditor, #lineCounter { 137 | margin: 0; 138 | padding: 10px 0; 139 | /*height: 28vh;*/ 140 | border-radius: 0; 141 | resize: none; 142 | font-size: 13.333333333px; 143 | font-family: "Courier New", Courier, monospace; 144 | tab-size: 2; 145 | -webkit-hyphens: none; 146 | -moz-hyphens: none; 147 | -ms-hyphens: none; 148 | hyphens: none; 149 | line-height: 1.45; 150 | outline: none; 151 | border-width: 0; 152 | -moz-box-sizing: border-box; 153 | -webkit-box-sizing: border-box; 154 | box-sizing: border-box; 155 | } 156 | /*#codeEditor { 157 | padding-left: calc(50px + 5px); 158 | width: calc(100% - 8px); 159 | background-color: #fefefd; 160 | border: 1px solid rgba(28,205,188); 161 | color: rgba(8,152,138); 162 | white-space: pre-wrap; 163 | }*/ 164 | #codeEditor { 165 | padding-left: calc(50px + 5px); 166 | width: calc(100% - 8px); 167 | background-color: #fefefd; 168 | border: 1px solid rgba(28,205,188); 169 | color: rgba(8,152,138); 170 | white-space: break-spaces; 171 | word-break: break-word; 172 | overflow-wrap: break-word; 173 | overflow-x: visible; 174 | overflow-y: auto; 175 | } 176 | #lineCounter { 177 | display: flex; 178 | overflow-y: hidden; 179 | text-align: right; 180 | box-shadow: none; 181 | color: #707070; 182 | background-color: #d8d8d8; 183 | position: absolute; 184 | width: 50px; 185 | background-color: rgba(28,205,188,.25); 186 | color: rgba(8,152,138); 187 | } 188 | #lineCounter:focus-visible, 189 | #codeEditor:focus-visible { 190 | outline:none; 191 | } 192 | 193 | #errorDisplay { 194 | height:1.0rem; 195 | } 196 | #tablePagination, 197 | #errorDisplay { 198 | font-family: Segoe ui emoji; 199 | } 200 | #tableQueryPagination { 201 | display: inline-flex; 202 | font-family: Segoe ui symbol; 203 | } 204 | .unicode { 205 | font-family: Cambria; 206 | } 207 | .emoji { 208 | font-family: Segoe ui emoji; 209 | } 210 | .symbol { 211 | font-family: Segoe ui symbol; 212 | } 213 | 214 | #site-logo { 215 | height: calc(35px); 216 | } 217 | li.nav-item { 218 | display: inline; 219 | } 220 | .bg-none { 221 | background:transparent!important; 222 | } 223 | nav.fixed-top { 224 | transition: all 250ms; 225 | z-index: 10; 226 | box-shadow: rgba(0, 0, 0, 0.05) 0px 6px 24px 0px, rgba(0, 0, 0, 0.08) 0px 0px 0px 1px; 227 | background-color: rgba(28, 205, 188, .1); 228 | } 229 | #top-header { 230 | padding: 0.25rem 0.5rem; 231 | color: rgba(28,205,188); 232 | box-shadow: rgba(0, 0, 0, 0.05) 0px 6px 24px 0px, rgba(0, 0, 0, 0.08) 0px 0px 0px 1px; 233 | } 234 | .nowrap { 235 | white-space:nowrap; 236 | } 237 | .ps-active-y { 238 | overflow-y:auto; 239 | } 240 | #main-wrapper { 241 | overflow: hidden; 242 | } 243 | #main-wrapper .page-wrapper { 244 | margin-left: 240px; 245 | height: calc(100% - 0.3125rem - 0.3125rem - 35px + 2.5rem - 1px); 246 | display: block; 247 | } 248 | .page-wrapper { 249 | position: relative; 250 | background: #f2f7f8; 251 | display: none; 252 | transition: .2s ease-in; 253 | } 254 | #main-wrapper .page-wrapper >.container-fluid { 255 | min-width: calc(100vw - 240px - 5.5em); 256 | height: calc(100% - 0.3125rem - 0.3125rem + 0.5rem + 170px); 257 | margin: auto; 258 | position: relative; 259 | } 260 | #toggleSidebarBtn { 261 | position: fixed; 262 | box-shadow: rgba(17, 17, 26, 0.1) 0px 0px 16px; 263 | height: 29px; 264 | width: 29px; 265 | z-index: 20; 266 | margin: 2px; 267 | } 268 | .showTblCol:hover { 269 | cursor:pointer; 270 | opacity: 0.8; 271 | } 272 | #datatable table.table { 273 | display: flow-root; 274 | table-layout: fixed; 275 | margin-bottom: 0; 276 | } 277 | #datatable { 278 | height: calc(100vh - 5.375rem - 40px); 279 | overflow-y:auto; 280 | } 281 | aside.left-sidebar { 282 | position: fixed; 283 | width: 240px; 284 | height: calc(100% - 0.3125rem - 0.3125rem - 35px - 1rem - 1px); 285 | top: calc(0.3125rem + 35px + 1rem); 286 | z-index: 4; 287 | background: #fff; 288 | box-shadow: 1px 0 20px rgba(0,0,0,.08); 289 | transition: .2s ease-in; 290 | } 291 | 292 | .ps-container { 293 | -ms-touch-action: auto; 294 | touch-action: auto; 295 | -ms-overflow-style: none; 296 | } 297 | .scroll-sidebar { 298 | padding-bottom: 2.35rem; 299 | height: calc(100vh - 40px); 300 | position: relative; 301 | } 302 | .custom-scrollbar::-webkit-scrollbar { 303 | width: 8px; 304 | height: 8px; 305 | } 306 | 307 | .custom-scrollbar::-webkit-scrollbar-track { 308 | border-radius: 12px; 309 | background-color: #cccccc; 310 | } 311 | 312 | .custom-scrollbar::-webkit-scrollbar-thumb { 313 | background: rgba(8,152,138); 314 | border-radius: 12px; 315 | } 316 | 317 | /* 318 | .custom-scrollbar::-webkit-scrollbar-track { 319 | -webkit-box-shadow: inset 0 0 6px rgba(0,0,0,0.6); 320 | background-color: #CCCCCC; 321 | } 322 | 323 | .custom-scrollbar::-webkit-scrollbar { 324 | width: 8px; 325 | } 326 | 327 | .custom-scrollbar::-webkit-scrollbar-thumb { 328 | background-color: #FFF; 329 | background-image: -webkit-linear-gradient(90deg, 330 | rgba(0, 0, 0, 1) 0%, 331 | rgba(0, 0, 0, 1) 25%, 332 | transparent 100%, 333 | rgba(0, 0, 0, 1) 75%, 334 | transparent) 335 | }*/ 336 | 337 | span.icon-symbol { 338 | font-size:1.1rem; 339 | } 340 | 341 | .page-item.active .page-link { 342 | z-index: 3; 343 | color: #fff; 344 | background-color: #343a40; 345 | border-color: #343a40; 346 | } 347 | 348 | .page-link { 349 | position: relative; 350 | display: block; 351 | padding: 0.5rem 0.75rem; 352 | margin-left: -1px; 353 | line-height: 1.25; 354 | color: #343a40; 355 | background-color: rgba(0,0,0,.05); 356 | border: 1px solid #dee2e6; 357 | } 358 | 359 | .switch { 360 | position: relative; 361 | display: inline-block; 362 | width: 26px; 363 | height: .925rem; 364 | margin-top: 0.5rem; 365 | margin-bottom: 0; 366 | } 367 | 368 | .switch input { 369 | opacity: 0; 370 | width: 0; 371 | height: 0; 372 | } 373 | 374 | .slider { 375 | position: absolute; 376 | cursor: pointer; 377 | top: 0; 378 | left: 0; 379 | right: 0; 380 | bottom: 0; 381 | background-color: rgba(0,0,0,.05); 382 | -webkit-transition: .4s; 383 | transition: .4s; 384 | } 385 | 386 | .slider:before { 387 | position: absolute; 388 | content: ""; 389 | height: 11px; 390 | width: 11px; 391 | left: 2px; 392 | bottom: 2px; 393 | background-color: white; 394 | -webkit-transition: .4s; 395 | transition: .4s; 396 | } 397 | 398 | input:checked + .slider { 399 | background-color: #343a40; 400 | } 401 | 402 | input:focus + .slider { 403 | box-shadow: 0 0 1px #343a40; 404 | } 405 | 406 | input:checked + .slider:before { 407 | -webkit-transform: translateX(11px); 408 | -ms-transform: translateX(11px); 409 | transform: translateX(11px); 410 | } 411 | 412 | /* Rounded sliders */ 413 | .slider.round { 414 | border-radius: 17px; 415 | } 416 | 417 | .slider.round:before { 418 | border-radius: 50%; 419 | } 420 | 421 | span.toggle-switch-caption { 422 | display: inline-table; 423 | font-size: .925rem; 424 | font-variant: proportional-width; 425 | vertical-align: top; 426 | margin-top: 0.25rem; 427 | width: calc(100% - 1.45rem); 428 | white-space: break-spaces; 429 | } 430 | 431 | #page-footer { 432 | position: fixed; 433 | z-index: 8000; 434 | left: 0; 435 | right: 0; 436 | top: 0; 437 | width: 100%; 438 | background: #dee2e6; 439 | } 440 | 441 | #tablePaginationWrapper { 442 | overflow-x:auto; 443 | } 444 | 445 | #currentPageNo { 446 | font-size:small; 447 | } 448 | 449 | #tablePagination div.row.no-gutters.page-link.page-link { 450 | display: inline-flex; 451 | } 452 | 453 | button.deleteRow, 454 | button.saveRow { 455 | height: 31px; 456 | width: 31px; 457 | } 458 | button.deleteRow { 459 | padding-left: 0.45em; 460 | } 461 | 462 | .no-touch { 463 | pointer-events:none; 464 | } 465 | .unselectable { 466 | -moz-user-select: none; 467 | -webkit-user-select: none; 468 | -ms-user-select: none; 469 | } 470 | /* 471 | details > summary { 472 | &::marker { 473 | content: '⯈'; 474 | } 475 | } 476 | details[open] > summary { 477 | &::marker { 478 | content: '⯆'; 479 | } 480 | } 481 | */ 482 | .w-20 { 483 | width:20%!important; 484 | } 485 | 486 | .w-35 { 487 | width:35%!important; 488 | } 489 | 490 | #filters { 491 | overflow-x: auto; 492 | width: calc(100% - 8px); 493 | margin-bottom:8px; 494 | } 495 | 496 | #databaseTables.scroll-sidebar { 497 | height:calc(100% - .3125rem - .3125rem - 20px); 498 | } 499 | 500 | .smallCaption { 501 | font: small-caption; 502 | /*color:rgba(28,205,188);*/ 503 | font-size: xx-small; 504 | } 505 | 506 | .copyrightNote { 507 | font-stretch: ultra-condensed; 508 | font-family: emoji; 509 | } 510 | 511 | .table-striped tbody tr:nth-of-type(odd) { 512 | /*background-color: #F0F9FE;#1CCDBC*/ 513 | background-color: rgba(28,205,188,.05); 514 | } 515 | 516 | 517 | .btn-outline-primary { 518 | color: #007bff; 519 | border-color: #007bff; 520 | } 521 | 522 | .btn-outline-custom-one { 523 | color: rgba(8,152,138); 524 | border-color: rgba(8,152,138); 525 | } 526 | .btn-outline-custom-one:hover { 527 | color: #fff; 528 | background-color: rgba(8,152,138); 529 | border-color: rgba(8,152,138); 530 | } 531 | .btn-outline-custom-two { 532 | color: rgba(28, 205, 188); 533 | border-color: rgba(28, 205, 188); 534 | } 535 | .btn-outline-custom-two:hover { 536 | color: #fff; 537 | background-color: rgba(28, 205, 188); 538 | border-color: rgba(28, 205, 188); 539 | } 540 | 541 | 542 | /*Darker Green*/ 543 | .text-custom-one { 544 | color:#08988a !important; 545 | } 546 | .bg-custom-one { 547 | background-color: rgba(8,152,138) !important; 548 | } 549 | .bg-custom-one-25 { 550 | background-color: rgba(8,152,138,.25) !important; 551 | } 552 | .border-custom-one { 553 | border-color: rgba(8,152,138) !important; 554 | } 555 | 556 | #dropFileZone { 557 | height: calc(100% - 0.3125rem - 0.3125rem - 35px - 1rem - 1px - 1rem); 558 | top: calc(0.3125rem + 35px + 1rem); 559 | } 560 | #dropFileZone .card-body { 561 | border-width: 3px; 562 | border-style: dashed; 563 | } 564 | /*#dropFileZone > div.card-body.rounded-0.p-4.border-custom-one.text-center > h4:nth-child(1) { 565 | padding-top:4.25rem; 566 | }*/ 567 | /*Lighter Green*/ 568 | .text-custom-two { 569 | color:#1ccdbc !important; 570 | } 571 | .bg-custom-two { 572 | background-color: rgba(28,205,188) !important; 573 | } 574 | .bg-custom-two-05 { 575 | background-color: rgba(28,205,188,.05) !important; 576 | } 577 | .border-custom-two { 578 | border-color: rgba(28,205,188) !important; 579 | } 580 | 581 | .page-link { 582 | color:#08988a; 583 | } 584 | .page-item.disabled .page-link, 585 | .page-link { 586 | background:transparent; 587 | } 588 | 589 | #upload-btn, #hint-btn, #runQueryBtn { 590 | display: inline-flex; 591 | } 592 | #runQueryBtn { 593 | font-size: calc(.8rem - 0.125rem); 594 | margin-bottom: 0.125rem; 595 | } 596 | 597 | button.navbar-toggler, 598 | button.navbar-toggler:focus-visible, 599 | button.navbar-toggler:focus { 600 | outline: none; 601 | border-width: 1.75px; 602 | } 603 | 604 | ul.nav.navbar-nav { 605 | display:inline; 606 | } 607 | 608 | .dropdown-menu .divider { 609 | height: 1px; 610 | margin: 1px 0; 611 | overflow: hidden; 612 | background-color: #e5e5e5; 613 | } 614 | 615 | .pagination-sm .page-link { 616 | padding: 0.125rem 0.5rem; 617 | font-size: .875rem; 618 | line-height: 1.5; 619 | } 620 | 621 | .attribution { 622 | background: rgba(28,205,188,.25); 623 | border: 1px solid rgba(28,205,188); 624 | color: rgb(8 152 138); 625 | position: fixed; 626 | right: 1px; 627 | bottom: 1px; 628 | font-size: x-small; 629 | } 630 | 631 | .attribution-icon { 632 | padding:7.5px; 633 | background-position: center; 634 | background-repeat:no-repeat; 635 | background-size: contain; 636 | } 637 | 638 | aside.left-sidebar span.symbol.d-inline-block { 639 | width: 2em; 640 | } 641 | .site-header-btn:hover:not(:disabled), 642 | .site-header-btn:active:not(:disabled), 643 | .site-header-btn:focus:not(:disabled) { 644 | box-shadow: 0 0 0 4px rgba(8,152,138, .25); 645 | cursor:pointer; 646 | } 647 | .site-header-icon { 648 | background-position: center; 649 | background-repeat: no-repeat; 650 | background-size: contain; 651 | } 652 | 653 | /* [START]
+ CSS for accordion */ 654 | .user-select-none { 655 | -webkit-user-select: none!important; 656 | -moz-user-select: none!important; 657 | user-select: none!important; 658 | } 659 | details[open] { 660 | box-shadow: 0 2px 5px 0 rgba(8,152,138, .25); 661 | } 662 | summary:focus { 663 | color: #005fcc; 664 | } 665 | summary::-webkit-details-marker { 666 | display: none; 667 | } 668 | .accordion-item:not(:first-of-type) { 669 | border-top: 0; 670 | } 671 | .accordion-item:first-of-type .accordion-button { 672 | border-top-left-radius: calc(0rem - 1px); 673 | border-top-right-radius: calc(0rem - 1px); 674 | } 675 | .accordion-body > button:last-child { 676 | border-bottom:0; 677 | } 678 | details.accordion-item[open] .accordion-button::after { 679 | background-image: url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4KPHN2ZyBmaWxsPSJyZ2JhKDI1NSwgMjU1LCAyNTUpIiB2aWV3Qm94PSIwIDAgMjU2IDI1NiIgaWQ9IkZsYXQiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CiAgPHBhdGggZD0iTTEyOCwxODhhMTEuOTYxODcsMTEuOTYxODcsMCwwLDEtOC40ODUzNS0zLjUxNDY1bC04MC04MGExMi4wMDAxLDEyLjAwMDEsMCwwLDEsMTYuOTcwNy0xNi45NzA3TDEyOCwxNTkuMDI5M2w3MS41MTQ2NS03MS41MTQ2NWExMi4wMDAxLDEyLjAwMDEsMCwwLDEsMTYuOTcwNywxNi45NzA3bC04MCw4MEExMS45NjE4NywxMS45NjE4NywwLDAsMSwxMjgsMTg4WiIvPgo8L3N2Zz4='); 680 | transform: rotate(-180deg); 681 | -webkit-transition: .4s; 682 | transition: .4s; 683 | } 684 | details.accordion-item:not([open]) .accordion-button::after { 685 | transform: unset; 686 | -webkit-transition: unset; 687 | transition: unset; 688 | } 689 | .accordion-button { 690 | position: relative; 691 | display: flex; 692 | align-items: center; 693 | width: 100%; 694 | text-align: left; 695 | border: 0; 696 | border-radius: 0; 697 | overflow-anchor: none; 698 | -webkit-transition: color 0.15s ease-in-out, background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out, border-radius 0.15s ease; 699 | transition: color 0.15s ease-in-out, background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out, border-radius 0.15s ease; 700 | } 701 | details.accordion-item[open] .accordion-button { 702 | color: rgba(255, 255, 255); 703 | background-color: rgba(28, 205, 188); 704 | } 705 | details.accordion-item:not([open]) .accordion-button { 706 | color: rgba(8, 152, 138); 707 | background-color: rgba(28, 205, 188, .1); 708 | } 709 | details.accordion-item:not([open]) .accordion-button:hover{ 710 | color: rgba(8, 152, 138); 711 | background-color: rgba(28, 205, 188, .25); 712 | } 713 | @media(prefers-reduced-motion:reduce) { 714 | .accordion-button { 715 | transition: none; 716 | } 717 | } 718 | .accordion-button:not(.collapsed)::after { 719 | background-image: url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4KPHN2ZyBmaWxsPSJyZ2JhKDgsIDE1MiwgMTM4KSIgdmlld0JveD0iMCAwIDI1NiAyNTYiIGlkPSJGbGF0IiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPgogIDxwYXRoIGQ9Ik0xMjgsMTg4YTExLjk2MTg3LDExLjk2MTg3LDAsMCwxLTguNDg1MzUtMy41MTQ2NWwtODAtODBhMTIuMDAwMSwxMi4wMDAxLDAsMCwxLDE2Ljk3MDctMTYuOTcwN0wxMjgsMTU5LjAyOTNsNzEuNTE0NjUtNzEuNTE0NjVhMTIuMDAwMSwxMi4wMDAxLDAsMCwxLDE2Ljk3MDcsMTYuOTcwN2wtODAsODBBMTEuOTYxODcsMTEuOTYxODcsMCwwLDEsMTI4LDE4OFoiLz4KPC9zdmc+'); 720 | transform: rotate(-180deg); 721 | } 722 | .accordion-button::after { 723 | flex-shrink: 0; 724 | width: 1rem; 725 | height: 1rem; 726 | margin-left: auto; 727 | content: ""; 728 | background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23111'%3e%3cpath fill-rule='evenodd' d='M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708z'/%3e%3c/svg%3e"); 729 | background-repeat: no-repeat; 730 | background-size: 1rem; 731 | transition: 0.2s ease-in-out; 732 | } 733 | @media(prefers-reduced-motion:reduce) { 734 | .accordion-button::after { 735 | transition: none; 736 | } 737 | } 738 | .accordion-button:hover { 739 | z-index: 2; 740 | } 741 | .accordion-button:focus { 742 | z-index: 3; 743 | border-color: rgba(8,152,138); 744 | outline: 0; 745 | box-shadow: 0 0 0 0.25rem rgba(28, 205, 188, .15); 746 | } 747 | .accordion-header { 748 | margin-bottom: 0; 749 | white-space: nowrap; 750 | font-size: .875rem; 751 | } 752 | .accordion-body { 753 | margin-bottom: 0; 754 | padding: 0 0.125rem; 755 | } 756 | .accordion-item { 757 | color:rgba(8, 152, 138); 758 | } 759 | .accordion-item:first-of-type .accordion-button { 760 | border-top-left-radius: calc(0rem - 1px); 761 | border-top-right-radius: calc(0rem - 1px); 762 | } 763 | span.icon { 764 | background-position:center; 765 | background-size:contain; 766 | background-repeat:no-repeat; 767 | } 768 | 769 | span.icon.icon-database { 770 | background-image: url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAzMiAzMiI+DQogICAgPHBhdGggZmlsbD0ncmdiYSg4LCAxNTIsIDEzOCcgZD0iTTE2IDBjLTguODM3IDAtMTYgMi4yMzktMTYgNXY0YzAgMi43NjEgNy4xNjMgNSAxNiA1czE2LTIuMjM5IDE2LTV2LTRjMC0yLjc2MS03LjE2My01LTE2LTV6Ii8+DQogICAgPHBhdGggZmlsbD0ncmdiYSg4LCAxNTIsIDEzOCcgZD0iTTE2IDE3Yy04LjgzNyAwLTE2LTIuMjM5LTE2LTV2NmMwIDIuNzYxIDcuMTYzIDUgMTYgNXMxNi0yLjIzOSAxNi01di02YzAgMi43NjEtNy4xNjMgNS0xNiA1eiIvPg0KICAgIDxwYXRoIGZpbGw9J3JnYmEoOCwgMTUyLCAxMzgnIGQ9Ik0xNiAyNmMtOC44MzcgMC0xNi0yLjIzOS0xNi01djZjMCAyLjc2MSA3LjE2MyA1IDE2IDVzMTYtMi4yMzkgMTYtNXYtNmMwIDIuNzYxLTcuMTYzIDUtMTYgNXoiLz4NCjwvc3ZnPg=='); 771 | } 772 | /* [END]
+ CSS for accordion */ 773 | 774 | 775 | #databaseTables > div.accordion-wrapper.small.border-top.border-bottom > .btn { 776 | background: rgba(28, 205, 188, .1); 777 | } 778 | #databaseTables > div.accordion-wrapper.small.border-top.border-bottom > .btn:focus { 779 | z-index: 3; 780 | border-color: rgba(8,152,138); 781 | outline: 0; 782 | box-shadow: 0 0 0 0.25rem rgba(28, 205, 188, .15); 783 | } 784 | #databaseTables > div.accordion-wrapper.small.border-top.border-bottom > .btn:hover { 785 | background-color: rgba(28, 205, 188, .25); 786 | } 787 | 788 | .attribution-icon[data-profile='github'] { 789 | background-image: url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyOCAzMiI+DQo8cGF0aCBmaWxsPSdyZ2IoOCAxNTIgMTM4KScgZD0iTTI1IDJoLTIyYy0xLjY1NiAwLTMgMS4zNDQtMyAzdjIyYzAgMS42NTYgMS4zNDQgMyAzIDNoMjJjMS42NTYgMCAzLTEuMzQ0IDMtM3YtMjJjMC0xLjY1Ni0xLjM0NC0zLTMtM3pNMTcuMzMxIDI1Ljk4MWMtMC41MjUgMC4wOTQtMC43MTktMC4yMzEtMC43MTktMC41IDAtMC4zMzcgMC4wMTItMi4wNjMgMC4wMTItMy40NTYgMC0wLjk3NS0wLjMyNS0xLjU5NC0wLjcwNi0xLjkxOSAyLjMxMy0wLjI1NiA0Ljc1LTAuNTc1IDQuNzUtNC41NjkgMC0xLjEzNy0wLjQwNi0xLjcwNi0xLjA2OS0yLjQzOCAwLjEwNi0wLjI2OSAwLjQ2Mi0xLjM3NS0wLjEwNi0yLjgxMy0wLjg2OS0wLjI2OS0yLjg1NiAxLjExOS0yLjg1NiAxLjExOS0wLjgyNS0wLjIzMS0xLjcxOS0wLjM1LTIuNi0wLjM1cy0xLjc3NSAwLjExOS0yLjYgMC4zNWMwIDAtMS45ODgtMS4zODctMi44NTYtMS4xMTktMC41NjkgMS40MzEtMC4yMTkgMi41MzctMC4xMDYgMi44MTMtMC42NjIgMC43MzEtMC45NzUgMS4zLTAuOTc1IDIuNDM4IDAgMy45NzUgMi4zMzEgNC4zMTMgNC42NDQgNC41NjktMC4zIDAuMjY5LTAuNTY5IDAuNzMxLTAuNjYyIDEuMzk0LTAuNTk0IDAuMjY5LTIuMTEyIDAuNzMxLTMuMDE5LTAuODY5LTAuNTY5LTAuOTg4LTEuNTk0LTEuMDY5LTEuNTk0LTEuMDY5LTEuMDEzLTAuMDEyLTAuMDY5IDAuNjM3LTAuMDY5IDAuNjM3IDAuNjc1IDAuMzEzIDEuMTUgMS41MTIgMS4xNSAxLjUxMiAwLjYwNiAxLjg1NiAzLjUwNiAxLjIzMSAzLjUwNiAxLjIzMSAwIDAuODY5IDAuMDEyIDIuMjgxIDAuMDEyIDIuNTM4IDAgMC4yNjktMC4xODggMC41OTQtMC43MTkgMC41LTQuMTI1LTEuMzgxLTcuMDEzLTUuMzA2LTcuMDEzLTkuODk0IDAtNS43MzggNC4zODgtMTAuMDk0IDEwLjEyNS0xMC4wOTRzMTAuMzg3IDQuMzU2IDEwLjM4NyAxMC4wOTRjMC4wMDYgNC41ODctMi43OTQgOC41MTktNi45MTkgOS44OTR6TTExLjIgMjIuMTYzYy0wLjExOSAwLjAyNS0wLjIzMS0wLjAyNS0wLjI0NC0wLjEwNi0wLjAxMi0wLjA5NCAwLjA2OS0wLjE3NSAwLjE4OC0wLjIgMC4xMTktMC4wMTIgMC4yMzEgMC4wMzggMC4yNDQgMC4xMTkgMC4wMTkgMC4wODEtMC4wNjMgMC4xNjMtMC4xODggMC4xODh6TTEwLjYwNiAyMi4xMDZjMCAwLjA4MS0wLjA5NCAwLjE1LTAuMjE5IDAuMTUtMC4xMzcgMC4wMTItMC4yMzEtMC4wNTYtMC4yMzEtMC4xNSAwLTAuMDgxIDAuMDk0LTAuMTUgMC4yMTktMC4xNSAwLjExOS0wLjAxMiAwLjIzMSAwLjA1NiAwLjIzMSAwLjE1ek05Ljc1IDIyLjAzOGMtMC4wMjUgMC4wODEtMC4xNSAwLjExOS0wLjI1NiAwLjA4MS0wLjExOS0wLjAyNS0wLjItMC4xMTktMC4xNzUtMC4yczAuMTUtMC4xMTkgMC4yNTYtMC4wOTRjMC4xMjUgMC4wMzggMC4yMDYgMC4xMzEgMC4xNzUgMC4yMTJ6TTguOTgxIDIxLjdjLTAuMDU2IDAuMDY5LTAuMTc1IDAuMDU2LTAuMjY5LTAuMDM4LTAuMDk0LTAuMDgxLTAuMTE5LTAuMi0wLjA1Ni0wLjI1NiAwLjA1Ni0wLjA2OSAwLjE3NS0wLjA1NiAwLjI2OSAwLjAzOCAwLjA4MSAwLjA4MSAwLjExMyAwLjIwNiAwLjA1NiAwLjI1NnpNOC40MTIgMjEuMTMxYy0wLjA1NiAwLjAzOC0wLjE2MiAwLTAuMjMxLTAuMDk0cy0wLjA2OS0wLjIgMC0wLjI0NGMwLjA2OS0wLjA1NiAwLjE3NS0wLjAxMiAwLjIzMSAwLjA4MSAwLjA2OSAwLjA5NCAwLjA2OSAwLjIwNiAwIDAuMjU2ek04LjAwNiAyMC41MjVjLTAuMDU2IDAuMDU2LTAuMTUgMC4wMjUtMC4yMTktMC4wMzgtMC4wNjktMC4wODEtMC4wODEtMC4xNzUtMC4wMjUtMC4yMTkgMC4wNTYtMC4wNTYgMC4xNS0wLjAyNSAwLjIxOSAwLjAzOCAwLjA2OSAwLjA4MSAwLjA4MSAwLjE3NSAwLjAyNSAwLjIxOXpNNy41ODggMjAuMDYzYy0wLjAyNSAwLjA1Ni0wLjEwNiAwLjA2OS0wLjE3NSAwLjAyNS0wLjA4MS0wLjAzOC0wLjExOS0wLjEwNi0wLjA5NC0wLjE2MyAwLjAyNS0wLjAzOCAwLjA5NC0wLjA1NiAwLjE3NS0wLjAyNSAwLjA4MSAwLjA0NCAwLjExOSAwLjExMyAwLjA5NCAwLjE2M3oiLz4NCjwvc3ZnPg==') 790 | } 791 | .attribution-icon[data-profile='medium'] { 792 | background-image: url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA0MCAzMiI+DQo8cGF0aCBmaWxsPSdyZ2IoOCAxNTIgMTM4KScgZD0iTTExLjI4MSA0LjY0MWMtNi4yMyAwLTExLjI4MSA1LjA4Ni0xMS4yODEgMTEuMzU5czUuMDUxIDExLjM1OSAxMS4yODEgMTEuMzU5IDExLjI4MS01LjA4NSAxMS4yODEtMTEuMzU5LTUuMDUxLTExLjM1OS0xMS4yODEtMTEuMzU5ek0yOS4yOTcgNS4zMDdjLTMuMTE1IDAtNS42NCA0Ljc4OS01LjY0IDEwLjY5M3MyLjUyNSAxMC42OTQgNS42NDEgMTAuNjk0IDUuNjQxLTQuNzg5IDUuNjQxLTEwLjY5NGgtMGMwLTUuOTA2LTIuNTI1LTEwLjY5My01LjY0LTEwLjY5M3pNMzguMDE2IDYuNDIxYy0xLjA5NSAwLTEuOTgzIDQuMjg5LTEuOTgzIDkuNThzMC44ODggOS41OCAxLjk4MyA5LjU4IDEuOTg0LTQuMjkgMS45ODQtOS41OGMwLTUuMjkxLTAuODg4LTkuNTc5LTEuOTg0LTkuNTc5eiIvPg0KPC9zdmc+'); 793 | } 794 | .attribution-icon[data-profile='linkedin'] { 795 | background-image: url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyOCAzMiI+DQo8cGF0aCBmaWxsPSdyZ2IoOCAxNTIgMTM4KScgZD0iTTI2IDJoLTI0LjAwNmMtMS4xIDAtMS45OTQgMC45MDYtMS45OTQgMi4wMTl2MjMuOTYyYzAgMS4xMTMgMC44OTQgMi4wMTkgMS45OTQgMi4wMTloMjQuMDA2YzEuMSAwIDItMC45MDYgMi0yLjAxOXYtMjMuOTYyYzAtMS4xMTItMC45LTIuMDE5LTItMi4wMTl6TTguNDYzIDI2aC00LjE1di0xMy4zNjNoNC4xNTZ2MTMuMzYzek02LjM4OCAxMC44MTNjLTEuMzMxIDAtMi40MDYtMS4wODEtMi40MDYtMi40MDZzMS4wNzUtMi40MDYgMi40MDYtMi40MDZjMS4zMjUgMCAyLjQwNiAxLjA4MSAyLjQwNiAyLjQwNiAwIDEuMzMxLTEuMDc1IDIuNDA2LTIuNDA2IDIuNDA2ek0yNC4wMTkgMjZoLTQuMTV2LTYuNWMwLTEuNTUtMC4wMzEtMy41NDQtMi4xNTYtMy41NDQtMi4xNjIgMC0yLjQ5NCAxLjY4OC0yLjQ5NCAzLjQzMXY2LjYxM2gtNC4xNXYtMTMuMzYzaDMuOTgxdjEuODI1aDAuMDU2YzAuNTU2LTEuMDUwIDEuOTEyLTIuMTU2IDMuOTMxLTIuMTU2IDQuMiAwIDQuOTgxIDIuNzY5IDQuOTgxIDYuMzY5djcuMzI1eiIvPg0KPC9zdmc+'); 796 | } 797 | .attribution-icon[data-profile='twitter'] { 798 | background-image: url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyOCAzMiI+DQo8cGF0aCBmaWxsPSdyZ2IoOCAxNTIgMTM4KScgZD0iTTQgMmMtMi4yMDYgMC00IDEuNzk0LTQgNHYyMGMwIDIuMjA2IDEuNzk0IDQgNCA0aDIwYzIuMjA2IDAgNC0xLjc5NCA0LTR2LTIwYzAtMi4yMDYtMS43OTQtNC00LTRoLTIwek0yMS45NTYgMTIuNDU2djBjMCA1LjQxOS00LjEyNSAxMS42NjItMTEuNjYyIDExLjY2Mi0yLjMyNSAwLTQuNDgxLTAuNjc1LTYuMjk0LTEuODM3IDAuMzMxIDAuMDM4IDAuNjUgMC4wNTAgMC45ODcgMC4wNTAgMS45MTkgMCAzLjY4MS0wLjY1IDUuMDg4LTEuNzUtMS44LTAuMDM4LTMuMzEzLTEuMjE5LTMuODMxLTIuODQ0IDAuNjMxIDAuMDk0IDEuMiAwLjA5NCAxLjg1LTAuMDc1LTEuODc1LTAuMzgxLTMuMjgxLTIuMDMxLTMuMjgxLTQuMDI1di0wLjA1MGMwLjU0NCAwLjMwNiAxLjE4MSAwLjQ5NCAxLjg1IDAuNTE5LTAuNTYzLTAuMzc1LTEuMDI1LTAuODgxLTEuMzQ0LTEuNDc1cy0wLjQ4Ny0xLjI2Mi0wLjQ4MS0xLjkzOGMwLTAuNzYyIDAuMi0xLjQ2MyAwLjU1Ni0yLjA2OSAyLjAxOSAyLjQ4NyA1LjA1MCA0LjExMiA4LjQ1IDQuMjg3LTAuNTgxLTIuNzgxIDEuNS01LjAzNyA0LTUuMDM3IDEuMTgxIDAgMi4yNDQgMC40OTQgMi45OTQgMS4yOTQgMC45MjUtMC4xNzUgMS44MTMtMC41MTkgMi42LTAuOTg4LTAuMzA2IDAuOTUtMC45NSAxLjc1LTEuOCAyLjI1NiAwLjgyNS0wLjA4OCAxLjYyNS0wLjMxOSAyLjM2My0wLjYzNy0wLjU1NiAwLjgxOS0xLjI1NiAxLjU0NC0yLjA1NiAyLjEyNSAwLjAxMiAwLjE3NSAwLjAxMiAwLjM1NiAwLjAxMiAwLjUzMXoiLz4NCjwvc3ZnPg==') 799 | } -------------------------------------------------------------------------------- /css/offcanvas.css: -------------------------------------------------------------------------------- 1 | /* Prevent scroll on narrow devices */ 2 | /* html, 3 | body { 4 | overflow-x: hidden; 5 | } 6 | 7 | body { 8 | padding-top: 62px; 9 | } */ 10 | @media (max-width: 768px) { 11 | .offcanvas-collapse { 12 | position: fixed; 13 | top: 58px; 14 | /* Height of navbar */ 15 | bottom: 0; 16 | left: 100%; 17 | width: 100%; 18 | padding-right: 1rem; 19 | padding-left: 1rem; 20 | overflow-y: auto; 21 | visibility: hidden; 22 | background-color: #5d4482; 23 | transition: visibility .3s ease-in-out, -webkit-transform .3s ease-in-out; 24 | transition: transform .3s ease-in-out, visibility .3s ease-in-out; 25 | transition: transform .3s ease-in-out, visibility .3s ease-in-out, -webkit-transform .3s ease-in-out; 26 | z-index: 10; 27 | } 28 | 29 | .offcanvas-collapse.open { 30 | visibility: visible; 31 | -webkit-transform: translateX(-100%); 32 | transform: translateX(-100%); 33 | } 34 | } 35 | 36 | .nav-scroller { 37 | position: relative; 38 | z-index: 2; 39 | height: 2.75rem; 40 | overflow-y: hidden; 41 | } 42 | 43 | .nav-scroller .nav { 44 | display: -ms-flexbox; 45 | display: flex; 46 | -ms-flex-wrap: nowrap; 47 | flex-wrap: nowrap; 48 | padding-bottom: 1rem; 49 | margin-top: -1px; 50 | overflow-x: auto; 51 | color: rgba(255, 255, 255, .75); 52 | text-align: center; 53 | white-space: nowrap; 54 | -webkit-overflow-scrolling: touch; 55 | } 56 | 57 | .nav-underline .nav-link { 58 | padding-top: .75rem; 59 | padding-bottom: .75rem; 60 | font-size: .875rem; 61 | color: #6c757d; 62 | } 63 | 64 | .nav-underline .nav-link:hover { 65 | color: #007bff; 66 | } 67 | 68 | .nav-underline .active { 69 | font-weight: 500; 70 | color: #343a40; 71 | } 72 | 73 | .text-white-50 { 74 | color: rgba(255, 255, 255, .5); 75 | } 76 | 77 | .lh-100 { 78 | line-height: 1; 79 | } 80 | 81 | .lh-125 { 82 | line-height: 1.25; 83 | } 84 | 85 | .lh-150 { 86 | line-height: 1.5; 87 | } 88 | -------------------------------------------------------------------------------- /database_files/healthcare_records.db: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/incubated-geek-cc/SQLiteBrowserUtility/0001c61c8b90bb42c4c18c9508a8e751d68c82e7/database_files/healthcare_records.db -------------------------------------------------------------------------------- /exports/exported_healthcare_records.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/incubated-geek-cc/SQLiteBrowserUtility/0001c61c8b90bb42c4c18c9508a8e751d68c82e7/exports/exported_healthcare_records.zip -------------------------------------------------------------------------------- /exports/query.sql: -------------------------------------------------------------------------------- 1 | SELECT patient_id,diagnosis_code,icd9_description 2 | FROM 3 | (SELECT 4 | patient_id, 5 | diagnosis_code 6 | FROM patient_diagnosis) A LEFT JOIN 7 | (SELECT icd9_code, icd9_description FROM icd9_mapping) B 8 | ON A.diagnosis_code = B.icd9_code; -------------------------------------------------------------------------------- /img/CORS_error.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/incubated-geek-cc/SQLiteBrowserUtility/0001c61c8b90bb42c4c18c9508a8e751d68c82e7/img/CORS_error.png -------------------------------------------------------------------------------- /img/basic_demo.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/incubated-geek-cc/SQLiteBrowserUtility/0001c61c8b90bb42c4c18c9508a8e751d68c82e7/img/basic_demo.gif -------------------------------------------------------------------------------- /img/buy_me_a_taco.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/incubated-geek-cc/SQLiteBrowserUtility/0001c61c8b90bb42c4c18c9508a8e751d68c82e7/img/buy_me_a_taco.png -------------------------------------------------------------------------------- /img/cover_image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/incubated-geek-cc/SQLiteBrowserUtility/0001c61c8b90bb42c4c18c9508a8e751d68c82e7/img/cover_image.png -------------------------------------------------------------------------------- /img/encode_base64.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/incubated-geek-cc/SQLiteBrowserUtility/0001c61c8b90bb42c4c18c9508a8e751d68c82e7/img/encode_base64.gif -------------------------------------------------------------------------------- /img/favicon-120.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/incubated-geek-cc/SQLiteBrowserUtility/0001c61c8b90bb42c4c18c9508a8e751d68c82e7/img/favicon-120.png -------------------------------------------------------------------------------- /img/favicon-152.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/incubated-geek-cc/SQLiteBrowserUtility/0001c61c8b90bb42c4c18c9508a8e751d68c82e7/img/favicon-152.png -------------------------------------------------------------------------------- /img/favicon-16x16.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/incubated-geek-cc/SQLiteBrowserUtility/0001c61c8b90bb42c4c18c9508a8e751d68c82e7/img/favicon-16x16.ico -------------------------------------------------------------------------------- /img/favicon-196.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/incubated-geek-cc/SQLiteBrowserUtility/0001c61c8b90bb42c4c18c9508a8e751d68c82e7/img/favicon-196.png -------------------------------------------------------------------------------- /img/favicon-32x32.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/incubated-geek-cc/SQLiteBrowserUtility/0001c61c8b90bb42c4c18c9508a8e751d68c82e7/img/favicon-32x32.ico -------------------------------------------------------------------------------- /img/favicon-48x48.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/incubated-geek-cc/SQLiteBrowserUtility/0001c61c8b90bb42c4c18c9508a8e751d68c82e7/img/favicon-48x48.ico -------------------------------------------------------------------------------- /img/favicon-76.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/incubated-geek-cc/SQLiteBrowserUtility/0001c61c8b90bb42c4c18c9508a8e751d68c82e7/img/favicon-76.png -------------------------------------------------------------------------------- /img/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/incubated-geek-cc/SQLiteBrowserUtility/0001c61c8b90bb42c4c18c9508a8e751d68c82e7/img/icon.png -------------------------------------------------------------------------------- /img/import_db.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/incubated-geek-cc/SQLiteBrowserUtility/0001c61c8b90bb42c4c18c9508a8e751d68c82e7/img/import_db.gif -------------------------------------------------------------------------------- /img/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/incubated-geek-cc/SQLiteBrowserUtility/0001c61c8b90bb42c4c18c9508a8e751d68c82e7/img/logo.png -------------------------------------------------------------------------------- /img/logo_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/incubated-geek-cc/SQLiteBrowserUtility/0001c61c8b90bb42c4c18c9508a8e751d68c82e7/img/logo_white.png -------------------------------------------------------------------------------- /img/site-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/incubated-geek-cc/SQLiteBrowserUtility/0001c61c8b90bb42c4c18c9508a8e751d68c82e7/img/site-logo.png -------------------------------------------------------------------------------- /img/updated_layout(laptops_n_desktops).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/incubated-geek-cc/SQLiteBrowserUtility/0001c61c8b90bb42c4c18c9508a8e751d68c82e7/img/updated_layout(laptops_n_desktops).png -------------------------------------------------------------------------------- /img/updated_layout(mobile).jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/incubated-geek-cc/SQLiteBrowserUtility/0001c61c8b90bb42c4c18c9508a8e751d68c82e7/img/updated_layout(mobile).jpg -------------------------------------------------------------------------------- /img/updated_layout(mobile-sidebar).jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/incubated-geek-cc/SQLiteBrowserUtility/0001c61c8b90bb42c4c18c9508a8e751d68c82e7/img/updated_layout(mobile-sidebar).jpg -------------------------------------------------------------------------------- /img/wasm_to_blob.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/incubated-geek-cc/SQLiteBrowserUtility/0001c61c8b90bb42c4c18c9508a8e751d68c82e7/img/wasm_to_blob.png -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 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 | SQLite Browser Tool ⸬ A Lightweight Client-Side JavaScript For Offline Use 36 | 37 | 38 | 39 | 65 | 66 | 67 | 70 | 71 | 72 | 73 |
74 | 82 | 83 |
Upload SQLite File:
84 | 85 |
86 | Drag & Drop 87 |
88 | …or 89 | 93 |
94 | 95 | 96 |
97 | 98 | 99 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | -------------------------------------------------------------------------------- /js/custom.js: -------------------------------------------------------------------------------- 1 | document.addEventListener('DOMContentLoaded', async() => { 2 | console.log('DOMContentLoaded'); 3 | 4 | const acceptedFileTypes = ['.sqlite', '.sqlite3', '.db', '.db3', '.s3db', '.mbtiles']; 5 | 6 | const dbFormatErr = '⚠ 𝗨𝗽𝗹𝗼𝗮𝗱𝗲𝗱 𝗳𝗶𝗹𝗲 𝘁𝘆𝗽𝗲 𝗶𝘀 𝗻𝗼𝘁 𝘀𝘂𝗽𝗽𝗼𝗿𝘁𝗲𝗱. 𝗟𝗶𝘀𝘁 𝗼𝗳 𝘀𝘂𝗽𝗽𝗼𝗿𝘁𝗲𝗱 𝗳𝗶𝗹𝗲 𝗳𝗼𝗿𝗺𝗮𝘁𝘀 𝗮𝗿𝗲:' + '\n' + 7 | '◾ .𝗌𝗊𝗅𝗂𝗍𝖾' + '\n' + 8 | '◾ .𝗌𝗊𝗅𝗂𝗍𝖾𝟥' + '\n' + 9 | '◾ .𝖽𝖻' + '\n' + 10 | '◾ .𝖽𝖻𝟥' + '\n' + 11 | '◾ .𝗌𝟥𝖽𝖻' + '\n' + 12 | '◾ .𝗌𝗅𝟥' + '\n' + 13 | '◾ .𝗆𝖻𝗍𝗂𝗅𝖾𝗌' + '\n' + 14 | '𝘗𝘭𝘦𝘢𝘴𝘦 𝘵𝘳𝘺 𝘢𝘨𝘢𝘪𝘯.'; 15 | 16 | // Uint8Array to Base64 17 | const convertBitArrtoB64 = (bitArr) => (btoa(bitArr.reduce((data, byte) => data + String.fromCharCode(byte), ''))); 18 | // Base64 to Uint8Array 19 | const convertB64ToBitArr = (b64Str) => (Uint8Array.from(atob((b64Str.includes(';base64,') ? (b64Str.split(','))[1] : b64Str)), (v) => v.charCodeAt(0))); 20 | 21 | const dropFileZone = document.querySelector('#dropFileZone'); 22 | const dropFileInnerZone = dropFileZone.querySelector('.card-body'); 23 | 24 | const clearCache = document.querySelector('#clearCache'); 25 | clearCache.addEventListener('click', async() => { 26 | requestAnimationFrame(async() => { 27 | localStorage.clear(); 28 | sessionStorage.clear(); 29 | const response =await indexedDB.databases(); 30 | console.log(response); 31 | for(let obj of response) { 32 | indexedDB.deleteDatabase(obj.name); 33 | } 34 | 35 | location.reload(); 36 | }); 37 | }); 38 | 39 | const copyrightYearDisplay = document.querySelector('#copyrightYearDisplay'); 40 | copyrightYearDisplay.innerHTML = new Date().getFullYear(); 41 | 42 | const popoverTargets = document.querySelectorAll('[data-content]'); 43 | Array.from(popoverTargets).map( 44 | popTarget => new BSN.Popover(popTarget, { 45 | placement: 'right', 46 | animation: 'show', 47 | delay: 100, 48 | dismissible: true, 49 | trigger: 'click' 50 | }) 51 | ); 52 | 53 | const elementsTooltip = document.querySelectorAll('[title]'); 54 | Array.from(elementsTooltip).map( 55 | tip => new BSN.Tooltip(tip, { 56 | placement: 'top', //string 57 | animation: 'slideNfade', // CSS class 58 | delay: 150, // integer 59 | }) 60 | ); 61 | 62 | const tabTargets = document.querySelectorAll('#initTabs .nav-link'); 63 | Array.from(tabTargets).map( 64 | tab => new BSN.Tab(tab, { 65 | height: true 66 | }) 67 | ); 68 | 69 | if (!window.FileReader) { 70 | errorDisplay.innerHTML = ' WARNING: Your browser does not support HTML5 \'FileReader\' function required to open a file.'; 71 | return; 72 | } 73 | if (!window.Blob) { 74 | errorDisplay.innerHTML = ' WARNING: Your browser does not support HTML5 \'Blob\' function required to save a file.'; 75 | return; 76 | } 77 | 78 | // IE8 79 | // IE9+ and other modern browsers 80 | function triggerEvent(el, type) { 81 | let e = (('createEvent' in document) ? document.createEvent('HTMLEvents') : document.createEventObject()); 82 | if ('createEvent' in document) { 83 | e.initEvent(type, false, true); 84 | el.dispatchEvent(e); 85 | } else { 86 | e.eventType = type; 87 | el.fireEvent('on' + e.eventType, e); 88 | } 89 | } 90 | 91 | function htmlToElement(html) { 92 | let documentFragment = document.createDocumentFragment(); 93 | let template = document.createElement('template'); 94 | template.innerHTML = html.trim(); 95 | for (let i = 0, e = template.content.childNodes.length; i < e; i++) { 96 | documentFragment.appendChild(template.content.childNodes[i].cloneNode(true)); 97 | } 98 | return documentFragment; 99 | } 100 | 101 | const toggleSidebarBtn = document.querySelector('#toggleSidebarBtn'); 102 | const asideLeftSidebar = document.querySelector('aside.left-sidebar'); 103 | const mainWrapper = document.querySelector('#main-wrapper'); 104 | const pageWrapper = mainWrapper.querySelector('.page-wrapper'); 105 | toggleSidebarBtn.addEventListener('click', (evt) => { 106 | let currentVal = evt.target.value; 107 | let latestVal = (currentVal == 'true') ? 'false' : 'true'; 108 | toggleSidebarBtn.value = latestVal; 109 | if (latestVal == 'true') { 110 | asideLeftSidebar['style']['width'] = '0px'; 111 | pageWrapper['style']['margin-left'] = '0px'; 112 | } else if (latestVal == 'false') { 113 | asideLeftSidebar['style']['width'] = '240px'; 114 | pageWrapper['style']['margin-left'] = '240px'; 115 | } 116 | }); 117 | 118 | const infoModalBtn = document.querySelector('#infoModalBtn'); 119 | const infoModalContent = ` 123 | 138 | `; 142 | //

Proceed to upload an SQLite file (.sqlite, .sqlite3, .db, .db3, .s3db, .sl3)

143 | async function showLoadingSignal(modalTitle) { 144 | let modalHeader = ''; 145 | const modalContent = ``; 153 | 154 | siteModalInstance.setContent(modalHeader + modalContent); 155 | await new Promise((resolve, reject) => setTimeout(resolve, 100)); // wait 100 milliseconds 156 | siteModalInstance.show(); 157 | return await Promise.resolve('Loading'); 158 | } 159 | 160 | 161 | const siteModalInstance = new BSN.Modal( 162 | '#siteModal', { 163 | content: '', 164 | backdrop: false, 165 | keyboard: false 166 | } 167 | ); 168 | infoModalBtn.addEventListener('click', async() => { 169 | siteModalInstance.setContent(infoModalContent); 170 | await new Promise((resolve, reject) => setTimeout(resolve, 100)); 171 | siteModalInstance.toggle(); 172 | }); 173 | triggerEvent(infoModalBtn, 'click'); 174 | 175 | const displayedRecordsRange = document.querySelector('#displayedRecordsRange'); 176 | const noOfTablesDisplay = document.querySelector('#noOfTablesDisplay'); 177 | 178 | const dbTableDetails = document.querySelector('#dbTableDetails'); 179 | const errorDisplay = document.querySelector('#errorDisplay'); 180 | 181 | const codeEditor = document.querySelector('#codeEditor'); 182 | const lineCounter = document.querySelector('#lineCounter'); 183 | const filters = document.querySelector('#filters'); 184 | 185 | const runQueryBtn = document.querySelector('#runQueryBtn'); 186 | 187 | const sql_wasm_typedarray = convertB64ToBitArr(sql_wasm_dataURL); // uInt8Array 188 | const sql_wasm_blob = new Blob([sql_wasm_typedarray], { 189 | type: 'application/wasm' 190 | }); 191 | const SQL = await initSqlJs({ 192 | locateFile: filename => URL.createObjectURL(sql_wasm_blob) 193 | }); 194 | 195 | // console.log(SQL); 196 | // const SQL = await initSqlJs({ 197 | // locateFile: filename => './js/sql-wasm.wasm' 198 | // }); 199 | // console.log(SQL); 200 | 201 | var db = null; 202 | 203 | const tblIcon = '▦ '; 204 | const nil = '---'; 205 | const recordsPerPage = 100; 206 | // =============== QUERY TAB ============================= 207 | var queryStmt = ''; 208 | var queryResultset = []; 209 | 210 | var currentQueryPage = 1; 211 | var originalQueryStmt = ''; 212 | var noOfQueryPages = 1; 213 | var totalNoOfQueryRecords = 0; 214 | var queryOffset = 0; 215 | 216 | const tableQueryRecords = document.querySelector('#tableQueryRecords'); 217 | const tableQueryPagination = document.querySelector('#tableQueryPagination'); 218 | 219 | const exportQueryAsJSON = document.querySelector('#exportQueryAsJSON'); 220 | const exportEditorQuery = document.querySelector('#exportEditorQuery'); 221 | const exportSampleDB = document.querySelector('#exportSampleDB'); 222 | 223 | var firstQueryPageBtn, prevQueryPageBtn, currentQueryPageNo, nextQueryPageBtn, lastQueryPageBtn; 224 | 225 | const paginationBtnProps = { 226 | // // ===================== 227 | 'firstQueryPageBtn': { 228 | 'className': 'page-item disabled', 229 | 'linkClassName': 'page-link rounded-0 border-left border-top border-bottom border-right-0 font-weight-bolder', 230 | 'linkTitle': 'first', 231 | 'linkInnerText': '«' // ⏮ 232 | }, 233 | 'prevQueryPageBtn': { 234 | 'className': 'page-item disabled', 235 | 'linkClassName': 'page-link rounded-0 border-left border-top border-bottom border-right-0 font-weight-bolder', 236 | 'linkTitle': 'previous', 237 | 'linkInnerText': '‹' // ⏪ 238 | }, 239 | 'nextQueryPageBtn': { 240 | 'className': 'page-item', 241 | 'linkClassName': 'page-link rounded-0 border-right-0 font-weight-bolder', 242 | 'linkTitle': 'next', 243 | 'linkInnerText': '›' // ⏩ 244 | }, 245 | 'lastQueryPageBtn': { 246 | 'className': 'page-item', 247 | 'linkClassName': 'page-link rounded-0 border font-weight-bolder', 248 | 'linkTitle': 'last', 249 | 'linkInnerText': '»' // ⏭ 250 | } 251 | }; 252 | 253 | async function initPaginationBtn(paginationBtnType, tablePaginationEle) { 254 | try { 255 | let paginationBtn = document.createElement('li'); 256 | paginationBtn.id = paginationBtnType; 257 | paginationBtn.className = paginationBtnProps[paginationBtnType]['className']; 258 | 259 | let pageBtnLink = document.createElement('a'); 260 | pageBtnLink.className = paginationBtnProps[paginationBtnType]['linkClassName']; 261 | pageBtnLink.setAttribute('title', paginationBtnProps[paginationBtnType]['linkTitle']); 262 | pageBtnLink.innerText = paginationBtnProps[paginationBtnType]['linkInnerText']; 263 | 264 | tablePaginationEle.appendChild(paginationBtn); 265 | paginationBtn.appendChild(pageBtnLink); 266 | 267 | return await Promise.resolve(paginationBtn); 268 | } catch (err) { 269 | errorDisplay.innerHTML = ` ERROR: ${err.message}`; 270 | console.log(err); 271 | } 272 | } 273 | 274 | async function initInputPageNo(tablePaginationEle, currentPageNoID, currentPageVal, noOfPagesVal) { 275 | try { 276 | let currentPageNoLi = document.createElement('li'); 277 | currentPageNoLi.className = 'page-item'; 278 | let currentPageNoLink = document.createElement('a'); 279 | currentPageNoLink.className = 'page-link border-right-0'; 280 | 281 | let currentPageNo = document.createElement('input'); 282 | currentPageNo.id = currentPageNoID; 283 | currentPageNo.className = 'form-control form-control-sm rounded-0 pt-0 pb-0 pl-1 pr-0'; 284 | currentPageNo.setAttribute('type', 'number'); 285 | currentPageNo.value = currentPageVal; 286 | currentPageNo.setAttribute('min', 1); 287 | currentPageNo.setAttribute('max', noOfPagesVal); 288 | 289 | let boldTextPrefix = document.createElement('b'); 290 | boldTextPrefix.className = 'pl-1 pr-1'; 291 | boldTextPrefix.innerText = '/'; 292 | 293 | let boldTextSuffix = document.createElement('b'); 294 | boldTextSuffix.className = ''; 295 | boldTextSuffix.innerText = noOfPagesVal; 296 | 297 | tablePaginationEle.appendChild(currentPageNoLi); 298 | currentPageNoLi.appendChild(currentPageNoLink); 299 | currentPageNoLink.appendChild(currentPageNo); 300 | currentPageNoLink.appendChild(boldTextPrefix); 301 | currentPageNoLink.appendChild(boldTextSuffix); 302 | 303 | return await Promise.resolve(currentPageNo); 304 | } catch (err) { 305 | errorDisplay.innerHTML = ` ERROR: ${err.message}`; 306 | console.log(err); 307 | } 308 | } 309 | 310 | function removeAllChildNodes(parent) { 311 | try { 312 | while (parent.firstChild) { 313 | parent.removeChild(parent.firstChild); 314 | } 315 | } catch (err) { 316 | errorDisplay.innerHTML = ` ERROR: ${err.message}`; 317 | console.log(err); 318 | } 319 | } 320 | 321 | function getResultSetAsRowJSON(_db, _sqlQuery) { 322 | try { 323 | let _resultset = _db.exec(_sqlQuery); 324 | let _columns = _resultset[0]['columns']; 325 | let _values = _resultset[0]['values']; 326 | let rowJSONOutput = []; 327 | for (let valArr of _values) { 328 | let obj = {}; 329 | for (let v in valArr) { 330 | obj[_columns[v]] = valArr[v]; 331 | } 332 | rowJSONOutput.push(obj); 333 | } 334 | return rowJSONOutput; 335 | } catch (err) { 336 | errorDisplay.innerHTML = ` ERROR: ${err.message}`; 337 | console.log(err); 338 | } 339 | } 340 | 341 | async function renderDatatable(resultset, tableRecordsEle) { 342 | try { 343 | let status = await showLoadingSignal('Running SQL query'); 344 | console.log(status); 345 | 346 | tableRecordsEle.innerHTML = ''; 347 | errorDisplay.innerHTML = ''; 348 | 349 | let tableHtmlStr = ''; 350 | tableHtmlStr += ''; 351 | tableHtmlStr += ''; 352 | tableHtmlStr += ''; 353 | tableHtmlStr += ''; 354 | tableHtmlStr += ''; 355 | let tableValues = resultset[0]['values']; 356 | for (let v in tableValues) { 357 | tableHtmlStr += ''; 358 | } 359 | tableHtmlStr += ''; 360 | tableHtmlStr += '
' + resultset[0]['columns'].join('') + '
' + (parseInt(v) + 1) + '' + tableValues[v].join('') + '
'; 361 | tableHtmlStr += '
'; 362 | tableRecordsEle.innerHTML = tableHtmlStr; 363 | 364 | await new Promise((resolve, reject) => setTimeout(resolve, 100)); 365 | siteModalInstance.hide(); 366 | await new Promise((resolve, reject) => setTimeout(resolve, 100)); 367 | return await Promise.resolve('success'); 368 | } catch (err) { 369 | errorDisplay.innerHTML = ` ERROR: ${err.message}`; 370 | console.log(err); 371 | } 372 | } 373 | 374 | async function setQueryPaginationClass() { 375 | try { 376 | currentQueryPageNo.value = currentQueryPage; 377 | if (currentQueryPage == 1) { 378 | if (!firstQueryPageBtn.classList.contains('disabled')) { 379 | firstQueryPageBtn.classList.add('disabled'); 380 | } 381 | if (!prevQueryPageBtn.classList.contains('disabled')) { 382 | prevQueryPageBtn.classList.add('disabled'); 383 | } 384 | } else if (currentQueryPage > 1) { 385 | if (firstQueryPageBtn.classList.contains('disabled')) { 386 | firstQueryPageBtn.classList.remove('disabled'); 387 | } 388 | if (prevQueryPageBtn.classList.contains('disabled')) { 389 | prevQueryPageBtn.classList.remove('disabled'); 390 | } 391 | } 392 | if (currentQueryPage == noOfQueryPages) { 393 | if (!nextQueryPageBtn.classList.contains('disabled')) { 394 | nextQueryPageBtn.classList.add('disabled'); 395 | } 396 | if (!lastQueryPageBtn.classList.contains('disabled')) { 397 | lastQueryPageBtn.classList.add('disabled'); 398 | } 399 | } else if (currentQueryPage < noOfQueryPages) { 400 | if (nextQueryPageBtn.classList.contains('disabled')) { 401 | nextQueryPageBtn.classList.remove('disabled'); 402 | } 403 | if (lastQueryPageBtn.classList.contains('disabled')) { 404 | lastQueryPageBtn.classList.remove('disabled'); 405 | } 406 | } 407 | queryOffset = (currentQueryPage - 1) * recordsPerPage; 408 | queryStmt = 'SELECT * FROM (' + originalQueryStmt + ') LIMIT ' + queryOffset + ',' + recordsPerPage; 409 | queryResultset = db.exec(queryStmt); 410 | // console.log(['originalQueryStmt',originalQueryStmt]); 411 | // console.log(['queryStmt',queryStmt]); 412 | await renderDatatable(queryResultset, tableQueryRecords); 413 | codeEditor.value = queryStmt; 414 | 415 | displayedRecordsRange.innerHTML = `Showing ${queryOffset} to ${queryOffset+recordsPerPage} of ${totalNoOfQueryRecords} rows`; 416 | 417 | setQueryRecordsHeight(); 418 | } catch (err) { 419 | errorDisplay.innerHTML = ` ERROR: ${err.message}`; 420 | console.log(err); 421 | } 422 | } 423 | 424 | function setQueryRecordsHeight() { 425 | const sidebar = document.querySelector('aside.left-sidebar'); 426 | const codeEditor = document.querySelector('#codeEditor'); 427 | const filters = document.querySelector('#filters'); 428 | const errorDisplay = document.querySelector('#errorDisplay'); 429 | 430 | let cssHeight = sidebar.clientHeight - codeEditor.clientHeight - filters.clientHeight - errorDisplay.clientHeight - 8; 431 | tableQueryRecords['style']['height'] = `calc(${cssHeight}px - 2rem)`; 432 | } 433 | 434 | function appendTableSelectable() { 435 | sqlQuery = 'SELECT name AS table_name FROM sqlite_master WHERE type =\'table\' AND name NOT LIKE \'sqlite_%\''; 436 | resultset = getResultSetAsRowJSON(db, sqlQuery); 437 | 438 | let noOfTables = resultset.length; 439 | noOfTablesDisplay.innerHTML = noOfTables; 440 | 441 | let allDisplayedTables = {}; 442 | for (let c of dbTableDetails.children) { 443 | let tbl = c.textContent; 444 | tbl = tbl.replace(tblIcon, ''); 445 | allDisplayedTables[tbl] = true; 446 | } 447 | 448 | let displayedTablesArr = Object.keys(allDisplayedTables); 449 | for (let rowObj of resultset) { 450 | let tblName = rowObj['table_name']; // {table_name: 'icd9_mapping'} 451 | if (!displayedTablesArr.includes(tblName)) { 452 | loadTableSelectable(tblName); 453 | } 454 | } 455 | } 456 | 457 | runQueryBtn.addEventListener('click', async(e) => { 458 | try { 459 | queryStmt = codeEditor.value; 460 | originalQueryStmt = queryStmt.trim(); 461 | if (originalQueryStmt.charAt(originalQueryStmt.length - 1) == ';') { 462 | originalQueryStmt = originalQueryStmt.substr(0, originalQueryStmt.length - 1); 463 | } 464 | // ================================================ 465 | let toExec = true; 466 | try { 467 | errorDisplay.innerHTML = ''; 468 | queryStmt = 'SELECT COUNT(*) FROM (' + originalQueryStmt + ')'; 469 | queryResultset = db.exec(queryStmt); 470 | } catch (err) { 471 | toExec = false; 472 | } 473 | if (!toExec) { 474 | db.run(originalQueryStmt); 475 | appendTableSelectable(); 476 | } else { 477 | // ================================================ 478 | removeAllChildNodes(tableQueryPagination); 479 | // ================================================ 480 | currentQueryPage = 1; 481 | queryOffset = (currentQueryPage - 1) * recordsPerPage; 482 | // ================================================ 483 | totalNoOfQueryRecords = queryResultset[0]['values'][0]; 484 | totalNoOfQueryRecords = parseInt(totalNoOfQueryRecords); 485 | noOfQueryPages = totalNoOfQueryRecords / recordsPerPage; 486 | noOfQueryPages = Math.ceil(noOfQueryPages); 487 | // ================================================ 488 | displayedRecordsRange.innerHTML = `Showing ${queryOffset} to ${queryOffset+recordsPerPage} of ${totalNoOfQueryRecords} rows`; 489 | // ================================================ 490 | firstQueryPageBtn = await initPaginationBtn('firstQueryPageBtn', tableQueryPagination); 491 | // ================================================ 492 | prevQueryPageBtn = await initPaginationBtn('prevQueryPageBtn', tableQueryPagination); 493 | // ================================================ 494 | currentQueryPageNo = await initInputPageNo(tableQueryPagination, 'currentQueryPageNo', currentQueryPage, noOfQueryPages); 495 | // ================================================ 496 | nextQueryPageBtn = await initPaginationBtn('nextQueryPageBtn', tableQueryPagination); 497 | // ================================================ 498 | lastQueryPageBtn = await initPaginationBtn('lastQueryPageBtn', tableQueryPagination); 499 | // ================================================ 500 | // render datatable records 501 | queryStmt = 'SELECT * FROM (' + originalQueryStmt + ') LIMIT ' + queryOffset + ',' + recordsPerPage; 502 | queryResultset = db.exec(queryStmt); 503 | // console.log(['originalQueryStmt',originalQueryStmt]); 504 | // console.log(['queryStmt',queryStmt]); 505 | await renderDatatable(queryResultset, tableQueryRecords); 506 | codeEditor.value = queryStmt; 507 | 508 | currentQueryPageNo.addEventListener('change', (evt0) => { 509 | evt0.stopPropagation(); 510 | currentQueryPage = parseInt(evt0.target.value); 511 | setQueryPaginationClass(); 512 | }); 513 | firstQueryPageBtn.addEventListener('click', (evt1) => { 514 | evt1.stopPropagation(); 515 | currentQueryPage = 1; 516 | setQueryPaginationClass(); 517 | }); 518 | prevQueryPageBtn.addEventListener('click', (evt2) => { 519 | evt2.stopPropagation(); 520 | if (currentQueryPage > 1) { 521 | currentQueryPage = currentQueryPage - 1; 522 | setQueryPaginationClass(); 523 | } 524 | }); 525 | nextQueryPageBtn.addEventListener('click', (evt3) => { 526 | evt3.stopPropagation(); 527 | if (currentQueryPage < noOfQueryPages) { 528 | currentQueryPage = currentQueryPage + 1; 529 | setQueryPaginationClass(); 530 | } 531 | }); 532 | lastQueryPageBtn.addEventListener('click', (evt4) => { 533 | evt4.stopPropagation(); 534 | currentQueryPage = noOfQueryPages; 535 | setQueryPaginationClass(); 536 | }); 537 | } 538 | } catch (err) { 539 | errorDisplay.innerHTML = ` ERROR: ${err.message}`; 540 | console.log(err); 541 | } 542 | }); 543 | 544 | 545 | exportQueryAsJSON.addEventListener('click', async() => { 546 | try { 547 | let status = await showLoadingSignal('Exporting data resultset'); 548 | console.log(status); 549 | 550 | let jsonObj = getResultSetAsRowJSON(db, 'SELECT * FROM (' + originalQueryStmt + ')'); 551 | let jsonStr = JSON.stringify(jsonObj); 552 | let textblob = new Blob([jsonStr], { 553 | type: 'application/json' 554 | }); 555 | let dwnlnk = document.createElement('a'); 556 | dwnlnk.download = 'resultset.json'; 557 | if (window.webkitURL != null) { 558 | dwnlnk.href = window.webkitURL.createObjectURL(textblob); 559 | } 560 | dwnlnk.click(); 561 | } catch (err) { 562 | errorDisplay.innerHTML = ` ERROR: ${err.message}`; 563 | console.log(err); 564 | } finally { 565 | await new Promise((resolve, reject) => setTimeout(resolve, 100)); 566 | siteModalInstance.hide(); 567 | } 568 | }); 569 | 570 | exportEditorQuery.addEventListener('click', async() => { 571 | try { 572 | let status = await showLoadingSignal('Saving SQL script'); 573 | console.log(status); 574 | 575 | let queryStr = codeEditor.value; 576 | let textblob = new Blob([queryStr], { 577 | type: 'text/plain' 578 | }); 579 | let dwnlnk = document.createElement('a'); 580 | dwnlnk.download = 'query.sql'; 581 | if (window.webkitURL != null) { 582 | dwnlnk.href = window.webkitURL.createObjectURL(textblob); 583 | } 584 | dwnlnk.click(); 585 | } catch (err) { 586 | errorDisplay.innerHTML = ` ERROR: ${err.message}`; 587 | console.log(err); 588 | } finally { 589 | await new Promise((resolve, reject) => setTimeout(resolve, 100)); 590 | siteModalInstance.hide(); 591 | } 592 | }); 593 | 594 | exportSampleDB.addEventListener('click', async() => { 595 | try { 596 | let status = await showLoadingSignal('Downloading sample database'); 597 | console.log(status); 598 | 599 | let dwnlnk = document.createElement('a'); 600 | dwnlnk.download = 'healthcare_records.db'; 601 | dwnlnk.href = './database_files/healthcare_records.db'; 602 | dwnlnk.click(); 603 | } catch (err) { 604 | errorDisplay.innerHTML = ` ERROR: ${err.message}`; 605 | console.log(err); 606 | } finally { 607 | await new Promise((resolve, reject) => setTimeout(resolve, 100)); 608 | siteModalInstance.hide(); 609 | } 610 | }); 611 | 612 | function loadTableSelectable(tblName) { 613 | let tblClickableBtn = document.createElement('button'); 614 | tblClickableBtn.setAttribute('type', 'button'); 615 | tblClickableBtn.setAttribute('class', 'btn btn-sm btn-link border-left-0 border-right-0 border-top-0 border-custom-two rounded-0 datatable pt-2 pb-2 pr-3 pl-4'); 616 | tblClickableBtn.innerHTML = `${tblIcon}${tblName}`; 617 | 618 | dbTableDetails.appendChild(tblClickableBtn); 619 | try { 620 | tblClickableBtn.addEventListener('click', async(e) => { 621 | e.stopPropagation(); 622 | 623 | let selected_tbl_name = tblClickableBtn.innerText; 624 | selected_tbl_name = selected_tbl_name.replace(tblIcon, ''); 625 | // ================================================ 626 | originalQueryStmt = 'SELECT COUNT(*) FROM `' + selected_tbl_name + '`'; 627 | queryStmt = originalQueryStmt; 628 | queryResultset = db.exec(queryStmt); 629 | // ================================================ 630 | removeAllChildNodes(tableQueryPagination); 631 | // ================================================ 632 | currentQueryPage = 1; 633 | queryOffset = (currentQueryPage - 1) * recordsPerPage; 634 | // ================================================ 635 | totalNoOfQueryRecords = queryResultset[0]['values'][0]; 636 | totalNoOfQueryRecords = parseInt(totalNoOfQueryRecords); 637 | noOfQueryPages = totalNoOfQueryRecords / recordsPerPage; 638 | noOfQueryPages = Math.ceil(noOfQueryPages); 639 | // ================================================ 640 | displayedRecordsRange.innerHTML = `Showing ${queryOffset} to ${queryOffset+recordsPerPage} of ${totalNoOfQueryRecords} rows`; 641 | // ================================================ 642 | firstQueryPageBtn = await initPaginationBtn('firstQueryPageBtn', tableQueryPagination); 643 | // ================================================ 644 | prevQueryPageBtn = await initPaginationBtn('prevQueryPageBtn', tableQueryPagination); 645 | // ================================================ 646 | currentQueryPageNo = await initInputPageNo(tableQueryPagination, 'currentQueryPageNo', currentQueryPage, noOfQueryPages); 647 | // ================================================ 648 | nextQueryPageBtn = await initPaginationBtn('nextQueryPageBtn', tableQueryPagination); 649 | // ================================================ 650 | lastQueryPageBtn = await initPaginationBtn('lastQueryPageBtn', tableQueryPagination); 651 | // ================================================ 652 | // render datatable records 653 | originalQueryStmt = 'SELECT * FROM `' + selected_tbl_name + '`'; 654 | queryStmt = 'SELECT * FROM (' + originalQueryStmt + ') LIMIT ' + queryOffset + ',' + recordsPerPage; 655 | queryResultset = db.exec(queryStmt); 656 | // console.log(['originalQueryStmt',originalQueryStmt]); 657 | // console.log(['queryStmt',queryStmt]); 658 | await renderDatatable(queryResultset, tableQueryRecords); 659 | codeEditor.value = queryStmt; 660 | 661 | currentQueryPageNo.addEventListener('change', (evt0) => { 662 | evt0.stopPropagation(); 663 | currentQueryPage = parseInt(evt0.target.value); 664 | setQueryPaginationClass(); 665 | }); 666 | firstQueryPageBtn.addEventListener('click', (evt1) => { 667 | evt1.stopPropagation(); 668 | currentQueryPage = 1; 669 | setQueryPaginationClass(); 670 | }); 671 | prevQueryPageBtn.addEventListener('click', (evt2) => { 672 | evt2.stopPropagation(); 673 | if (currentQueryPage > 1) { 674 | currentQueryPage = currentQueryPage - 1; 675 | setQueryPaginationClass(); 676 | } 677 | }); 678 | nextQueryPageBtn.addEventListener('click', (evt3) => { 679 | evt3.stopPropagation(); 680 | if (currentQueryPage < noOfQueryPages) { 681 | currentQueryPage = currentQueryPage + 1; 682 | setQueryPaginationClass(); 683 | } 684 | }); 685 | lastQueryPageBtn.addEventListener('click', (evt4) => { 686 | evt4.stopPropagation(); 687 | currentQueryPage = noOfQueryPages; 688 | setQueryPaginationClass(); 689 | }); 690 | }); 691 | } catch (err) { 692 | errorDisplay.innerHTML = ` ERROR: ${err.message}`; 693 | console.log(err); 694 | } 695 | } 696 | 697 | function readFileAsArrayBuffer(file) { 698 | return new Promise((resolve, reject) => { 699 | let fileredr = new FileReader(); 700 | fileredr.onload = () => resolve(fileredr.result); 701 | fileredr.onerror = () => reject(fileredr); 702 | fileredr.readAsArrayBuffer(file); 703 | }); 704 | } 705 | const fileNameDisplay = document.querySelector('#fileNameDisplay'); 706 | const fileSizeDisplay = document.querySelector('#fileSizeDisplay'); 707 | 708 | const upload = document.querySelector('#upload'); 709 | upload.addEventListener('click', (ev) => { 710 | ev.currentTarget.value = ''; 711 | }); 712 | dropFileZone.addEventListener('dragenter', (e) => { 713 | e.preventDefault(); 714 | e.stopPropagation(); 715 | dropFileInnerZone.classList.add('bg-custom-two-05'); 716 | }); 717 | dropFileZone.addEventListener('dragleave', (e) => { 718 | e.preventDefault(); 719 | e.stopPropagation(); 720 | dropFileInnerZone.classList.remove('bg-custom-two-05'); 721 | }); 722 | dropFileZone.addEventListener('dragover', (e) => { 723 | e.preventDefault(); 724 | e.stopPropagation(); 725 | dropFileInnerZone.classList.add('bg-custom-two-05'); 726 | }); 727 | 728 | async function importDBFile(file) { 729 | try { 730 | fileNameDisplay.innerText = file.name; 731 | fileSizeDisplay.innerText = `${parseInt(file.size/1024)} ㎅`; 732 | 733 | let arrayBuffer = await readFileAsArrayBuffer(file); 734 | let uInt8Array = new Uint8Array(arrayBuffer); 735 | db = new SQL.Database(uInt8Array); 736 | sqlQuery = 'SELECT name AS table_name FROM sqlite_master WHERE type =\'table\' AND name NOT LIKE \'sqlite_%\''; 737 | resultset = getResultSetAsRowJSON(db, sqlQuery); 738 | 739 | let noOfTables = resultset.length; 740 | noOfTablesDisplay.innerHTML = noOfTables; 741 | 742 | for (let rowObj of resultset) { 743 | let tblName = rowObj['table_name']; // {table_name: 'icd9_mapping'} 744 | loadTableSelectable(tblName); 745 | } 746 | } catch (err) { 747 | errorDisplay.innerHTML = ` ERROR: ${err.message}`; 748 | console.log(err); 749 | } finally { 750 | upload.setAttribute('disabled', ''); 751 | upload.classList.add('no-touch'); 752 | upload.classList.add('unselectable'); 753 | 754 | dropFileZone.setAttribute('hidden', ''); 755 | mainWrapper.removeAttribute('hidden'); 756 | 757 | let tableTab = document.querySelector('details.accordion-item:not([open]):first-of-type .accordion-button'); 758 | if (tableTab != null) { 759 | tableTab.click(); 760 | } 761 | triggerEvent(window, 'resize'); 762 | } 763 | return await Promise.resolve('success'); 764 | } 765 | 766 | dropFileZone.addEventListener("drop", async(e) => { 767 | e.preventDefault(); 768 | e.stopPropagation(); 769 | dropFileInnerZone.classList.remove("bg-custom-two-05"); 770 | 771 | errorDisplay.innerHTML = ''; 772 | upload.value = ''; 773 | 774 | let draggedData = e.dataTransfer; 775 | let file = draggedData.files[0]; 776 | if (!file) return; 777 | 778 | let fname = (file.name); 779 | let ext = fname.substr(fname.lastIndexOf('.')); // '.db' 780 | if (!acceptedFileTypes.includes(ext)) { 781 | alert(dbFormatErr); 782 | return; 783 | } 784 | 785 | await importDBFile(file); 786 | let initTable = document.querySelector('#dbTableDetails.accordion-body:first-of-type button.datatable'); 787 | if (initTable != null) { 788 | initTable.click(); 789 | } 790 | }); // drop file change event 791 | 792 | upload.addEventListener('change', async(ev) => { 793 | errorDisplay.innerHTML = ''; 794 | 795 | let file = ev.currentTarget.files[0]; 796 | if (!file) return; 797 | 798 | let fname = (file.name); 799 | let ext = fname.substr(fname.lastIndexOf('.')); // '.db' 800 | if (!acceptedFileTypes.includes(ext)) { 801 | alert(dbFormatErr); 802 | return; 803 | } 804 | 805 | await importDBFile(file); 806 | let initTable = document.querySelector('#dbTableDetails.accordion-body:first-of-type button.datatable'); 807 | if (initTable != null) { 808 | initTable.click(); 809 | } 810 | }); // upload file change event 811 | 812 | 813 | 814 | 815 | const exportDB = document.querySelector('#exportDB'); 816 | exportDB.addEventListener('click', async(evt) => { 817 | try { 818 | let status = await showLoadingSignal('Exporting database'); 819 | console.log(status); 820 | 821 | const arrayBuffer = db.export(); 822 | let uInt8Array = new Uint8Array(arrayBuffer); 823 | let b64Str = convertBitArrtoB64(uInt8Array); 824 | 825 | let dwnlnk = document.createElement('a'); 826 | dwnlnk.download = `exported_${fileNameDisplay.innerText}`; 827 | dwnlnk.href = `data:application/x-sqlite3;base64,${b64Str}`; 828 | dwnlnk.click(); 829 | } catch (err) { 830 | errorDisplay.innerHTML = ` ERROR: ${err.message}`; 831 | console.log(err); 832 | } finally { 833 | await new Promise((resolve, reject) => setTimeout(resolve, 100)); 834 | siteModalInstance.hide(); 835 | } 836 | }); 837 | 838 | // Prepare an sql statement 839 | // sqlQuery="WITH tables AS \n" + 840 | // "(SELECT name, sql FROM sqlite_master \n" + 841 | // "WHERE type = 'table' AND name NOT LIKE 'sqlite_%' AND name='"+ tblName +"')\n" + 842 | // "SELECT cid,fields.name FROM tables \n" + 843 | // "CROSS JOIN pragma_table_info(tables.name) fields"; 844 | // console.log(sqlQuery); 845 | // stmt = db.prepare(sqlQuery); 846 | // resultset = db.exec(sqlQuery); 847 | // console.log(resultset); 848 | // Bind values to the parameters and fetch the results of the query 849 | // resultObj = stmt.getAsObject({':tblNameVal' : tblName}); 850 | // console.log(resultObj); // Will print {a:1, b:'world'} 851 | // free the memory used by the statement 852 | // stmt.free(); 853 | // ================================== Query Editor Tab =========================== 854 | const sampleQueryStmt = 'SELECT patient_id,diagnosis_code,icd9_description FROM' + 855 | '\n (SELECT patient_id,diagnosis_code FROM patient_diagnosis) A' + 856 | '\nLEFT JOIN ' + 857 | '\n (SELECT icd9_code, icd9_description FROM icd9_mapping) B' + 858 | '\nON A.diagnosis_code = B.icd9_code;'; 859 | 860 | function line_counter(codeEditor, lineCounter) { 861 | const codeEditorWidth = codeEditor.clientWidth; 862 | const lineCounterWidth = lineCounter.clientWidth; 863 | 864 | const codeEditorLeftPadding = 5; // padding-left = 5 of #codeEditor 865 | const codeEditorEditableWidth = codeEditorWidth - lineCounterWidth - codeEditorLeftPadding; 866 | 867 | let lines = codeEditor.value.split('\n'); 868 | let lineCount = lines.length; 869 | let outarr = new Array(); 870 | for (let x = 0; x < lineCount; x++) { 871 | if ((lines[x].length * 8) + codeEditorLeftPadding > codeEditorEditableWidth) { 872 | outarr.push(`${parseInt(x + 1)}.`); 873 | let nbWrap = Math.floor(((lines[x].length * 8) + codeEditorLeftPadding) / codeEditorEditableWidth); 874 | for (let y = 0; y < nbWrap; y++) { 875 | outarr.push(' '); 876 | } 877 | } else { 878 | outarr.push(`${parseInt(x + 1)}.`); 879 | } 880 | } 881 | lineCounter.value = outarr.join('\n'); 882 | } 883 | 884 | function bindEventsToCodeEditor(codeEditor, lineCounter) { 885 | codeEditor.addEventListener('scroll', () => { 886 | lineCounter.scrollTop = codeEditor.scrollTop; 887 | lineCounter.scrollLeft = codeEditor.scrollLeft; 888 | }); 889 | codeEditor.addEventListener('input', () => { 890 | line_counter(codeEditor, lineCounter); 891 | }); 892 | codeEditor.addEventListener('keydown', (e) => { 893 | let { 894 | key 895 | } = e; 896 | let { 897 | value, 898 | selectionStart, 899 | selectionEnd 900 | } = codeEditor; 901 | if (key === 'Tab') { 902 | e.preventDefault(); 903 | codeEditor.value = value.slice(0, selectionStart) + '\t' + value.slice(selectionEnd); 904 | codeEditor.setSelectionRange(selectionStart + 2, selectionStart + 1) 905 | } 906 | if (key === 'Enter' && (e.metaKey || e.ctrlKey)) { 907 | e.preventDefault(); 908 | triggerEvent(runQueryBtn, 'click'); 909 | } 910 | }); 911 | } 912 | 913 | window.addEventListener('resize', (evt) => { 914 | let w = window.innerWidth; 915 | if (w < 720) { 916 | toggleSidebarBtn.value = false; 917 | } else { 918 | toggleSidebarBtn.value = true; 919 | } 920 | triggerEvent(toggleSidebarBtn, 'click'); 921 | setQueryRecordsHeight(); 922 | 923 | const codeEditor = document.querySelector('#codeEditor'); 924 | const lineCounter = document.querySelector('#lineCounter'); 925 | line_counter(codeEditor, lineCounter); 926 | bindEventsToCodeEditor(codeEditor, lineCounter); 927 | }); 928 | triggerEvent(window, 'resize'); 929 | 930 | }); // DOMContentLoaded 931 | -------------------------------------------------------------------------------- /js/ie10-viewport-bug-workaround.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * IE10 viewport hack for Surface/desktop Windows 8 bug 3 | * Copyright 2014-2015 Twitter, Inc. 4 | * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) 5 | */ 6 | !function() { 7 | "use strict" 8 | if (navigator.userAgent.match(/IEMobile\/10\.0/)) { 9 | var e = document.createElement("style") 10 | e.appendChild(document.createTextNode("@-ms-viewport{width:auto!important}")), 11 | document.querySelector("head").appendChild(e) 12 | } 13 | }() 14 | -------------------------------------------------------------------------------- /js/polyfill.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * Native JavaScript for Bootstrap Polyfill v4.0.8 (https://thednp.github.io/bootstrap.native/) 3 | * Copyright 2015-2021 © dnp_theme 4 | * Licensed under MIT (https://github.com/thednp/bootstrap.native/blob/master/LICENSE) 5 | */ 6 | "use strict"; 7 | if (!Array.prototype.some) { 8 | Array.prototype.some = function(fun, thisArg) { 9 | 10 | if (this == null) { 11 | throw new TypeError('Array.prototype.some called on null or undefined'); 12 | } 13 | 14 | if (typeof fun !== 'function') { 15 | throw new TypeError(); 16 | } 17 | 18 | var t = Object(this); 19 | var len = t.length >>> 0; 20 | 21 | for (var i = 0; i < len; i++) { 22 | if (i in t && fun.call(thisArg, t[i], i, t)) { 23 | return true; 24 | } 25 | } 26 | 27 | return false; 28 | }; 29 | } 30 | 31 | if (!Array.prototype.find) { 32 | Object.defineProperty(Array.prototype, 'find', { 33 | value: function(predicate) { 34 | if (this == null) { 35 | throw TypeError('"this" is null or not defined'); 36 | } 37 | 38 | var o = Object(this), len = o.length >>> 0; 39 | 40 | if (typeof predicate !== 'function') { 41 | throw TypeError('predicate must be a function'); 42 | } 43 | 44 | var thisArg = arguments[1], k = 0; 45 | while (k < len) { 46 | var kValue = o[k]; 47 | if (predicate.call(thisArg, kValue, k, o)) { 48 | return kValue; 49 | } 50 | k++; 51 | } 52 | 53 | return undefined; 54 | }, 55 | configurable: true, 56 | writable: true 57 | }); 58 | } 59 | 60 | if (!Array.prototype.includes) { 61 | Array.prototype.includes = function(searchElement /*, fromIndex*/ ) { 62 | var O = Object(this); 63 | var len = parseInt(O.length) || 0; 64 | if (len === 0) { 65 | return false; 66 | } 67 | var n = parseInt(arguments[1]) || 0; 68 | var k; 69 | if (n >= 0) { 70 | k = n; 71 | } else { 72 | k = len + n; 73 | if (k < 0) {k = 0;} 74 | } 75 | var currentElement; 76 | while (k < len) { 77 | currentElement = O[k]; 78 | if (searchElement === currentElement || 79 | (searchElement !== searchElement && currentElement !== currentElement)) { 80 | return true; 81 | } 82 | k++; 83 | } 84 | return false; 85 | }; 86 | } 87 | 88 | if (!Array.from) { 89 | Array.from = (function () { 90 | var toStr = Object.prototype.toString; 91 | var isCallable = function (fn) { 92 | return typeof fn === 'function' || toStr.call(fn) === '[object Function]'; 93 | }; 94 | var toInteger = function (value) { 95 | var number = Number(value); 96 | if (isNaN(number)) { return 0; } 97 | if (number === 0 || !isFinite(number)) { return number; } 98 | return (number > 0 ? 1 : -1) * Math.floor(Math.abs(number)); 99 | }; 100 | var maxSafeInteger = Math.pow(2, 53) - 1; 101 | var toLength = function (value) { 102 | var len = toInteger(value); 103 | return Math.min(Math.max(len, 0), maxSafeInteger); 104 | }; 105 | 106 | return function from(arrayLike/*, mapFn, thisArg */) { 107 | var C = this, items = Object(arrayLike); 108 | if (arrayLike == null) { 109 | throw new TypeError('Array.from requires an array-like object - not null or undefined'); 110 | } 111 | var mapFn = arguments.length > 1 ? arguments[1] : void undefined, T; 112 | if (typeof mapFn !== 'undefined') { 113 | if (!isCallable(mapFn)) { 114 | throw new TypeError('Array.from: when provided, the second argument must be a function'); 115 | } 116 | 117 | if (arguments.length > 2) { 118 | T = arguments[2]; 119 | } 120 | } 121 | var len = toLength(items.length); 122 | var A = isCallable(C) ? Object(new C(len)) : new Array(len); 123 | 124 | var k = 0; 125 | var kValue; 126 | while (k < len) { 127 | kValue = items[k]; 128 | if (mapFn) { 129 | A[k] = typeof T === 'undefined' ? mapFn(kValue, k) : mapFn.call(T, kValue, k); 130 | } else { 131 | A[k] = kValue; 132 | } 133 | k += 1; 134 | } 135 | A.length = len; 136 | return A; 137 | } 138 | }()); 139 | } 140 | 141 | if (!Object.keys) { 142 | Object.keys = function(obj) { 143 | var keys = []; 144 | 145 | for (var i in obj) { 146 | if (obj.hasOwnProperty(i)) { 147 | keys.push(i); 148 | } 149 | } 150 | 151 | return keys; 152 | }; 153 | } 154 | 155 | if (typeof Object.assign !== 'function') { 156 | Object.defineProperty(Object, "assign", { 157 | value: function assign(target, varArgs) { // .length of function is 2 158 | var arguments$1 = arguments; 159 | 160 | if (target === null || target === undefined) { 161 | throw new TypeError('Cannot convert undefined or null to object'); 162 | } 163 | 164 | var to = Object(target); 165 | 166 | for (var index = 1; index < arguments.length; index++) { 167 | var nextSource = arguments$1[index]; 168 | 169 | if (nextSource !== null && nextSource !== undefined) { 170 | for (var nextKey in nextSource) { 171 | if (Object.prototype.hasOwnProperty.call(nextSource, nextKey)) { 172 | to[nextKey] = nextSource[nextKey]; 173 | } 174 | } 175 | } 176 | } 177 | return to; 178 | }, 179 | writable: true, 180 | configurable: true 181 | }); 182 | } 183 | 184 | if (!Element.prototype.matches) { 185 | Element.prototype.matches = Element.prototype.webkitMatchesSelector || Element.prototype.oMatchesSelector || Element.prototype.msMatchesSelector || Element.prototype.mozMatchesSelector; 186 | } 187 | 188 | if (!Element.prototype.closest) { 189 | Element.prototype.closest = function closest(selector) { 190 | var node = this; 191 | 192 | while (node) { 193 | if (node.matches(selector)) { return node; } 194 | else { node = 'SVGElement' in window && node instanceof SVGElement ? node.parentNode : node.parentElement; } 195 | } 196 | 197 | return null; 198 | }; 199 | } 200 | 201 | if (!window.Event || !Window.prototype.Event) { 202 | window.Event = Window.prototype.Event = Document.prototype.Event = Element.prototype.Event = function Event(type, eventInitDict) { 203 | if (!type) { throw new Error('Not enough arguments'); } 204 | var event, 205 | bubbles = eventInitDict && eventInitDict.bubbles !== undefined ? eventInitDict.bubbles : false, 206 | cancelable = eventInitDict && eventInitDict.cancelable !== undefined ? eventInitDict.cancelable : false; 207 | if ( 'createEvent' in document ) { 208 | event = document.createEvent('Event'); 209 | event.initEvent(type, bubbles, cancelable); 210 | } else { 211 | event = document.createEventObject(); 212 | event.type = type; 213 | event.bubbles = bubbles; 214 | event.cancelable = cancelable; 215 | } 216 | return event; 217 | }; 218 | } 219 | 220 | if ( !window.CustomEvent || !Window.prototype.CustomEvent) { 221 | window.CustomEvent = Window.prototype.CustomEvent = Document.prototype.CustomEvent = Element.prototype.CustomEvent = function CustomEvent(type, eventInitDict) { 222 | if (!type) { 223 | throw Error('TypeError: Failed to construct "CustomEvent": An event name must be provided.'); 224 | } 225 | var event = new Event(type, eventInitDict); 226 | event.detail = eventInitDict && eventInitDict.detail || null; 227 | return event; 228 | }; 229 | } 230 | 231 | if (!Node.prototype.contains) { 232 | Node.prototype.contains = function (el) { 233 | while (el = el.parentNode) { 234 | if (el === this) { return true; } 235 | } 236 | return false; 237 | }; 238 | } 239 | 240 | if (!Number.isNaN) { 241 | Number.isNaN = function(value) { 242 | return typeof value === 'number' 243 | && value !== value; 244 | }; 245 | } 246 | 247 | if (!String.prototype.includes) { 248 | String.prototype.includes = function(search, start) { 249 | if (search instanceof RegExp) { 250 | throw TypeError('first argument must not be a RegExp'); 251 | } 252 | if (start === undefined) { start = 0; } 253 | return this.indexOf(search, start) !== -1; 254 | }; 255 | } 256 | -------------------------------------------------------------------------------- /js/sql-wasm.min.js: -------------------------------------------------------------------------------- 1 | var initSqlJsPromise=void 0,initSqlJs=function(Re){return initSqlJsPromise=initSqlJsPromise||new Promise(function(I,E){var B,x,S,H,G,O,R,a,t=void 0!==Re?Re:{},T=t.onAbort,e=(t.onAbort=function(t){E(new Error(t)),T&&T(t)},t.postRun=t.postRun||[],t.postRun.push(function(){I(t)}),module=void 0,(B=B||(void 0!==t?t:{})).onRuntimeInitialized=function(){function s(t,e){switch(typeof e){case"boolean":F(t,e?1:0);break;case"number":J(t,e);break;case"string":W(t,e,-1,-1);break;case"object":var n;null===e?R(t):null!=e.length?(n=qe(e),K(t,n,e.length,-1),xe(n)):T(t,"Wrong API use : tried to return a value of an unknown type ("+e+").",-1);break;default:R(t)}}function l(t,e){for(var n=[],r=0;r>>0),null!=t){var e=this.filename,n=e;if((r="/")&&(r="string"==typeof r?r:St(r),n=e?tt(r+"/"+e):r),e=ie(!0,!0),n=Jt(n,4095&(void 0!==e?e:438)|32768,0),t){if("string"==typeof t){for(var r=Array(t.length),i=0,a=t.length;i{O||(G=require("fs"),O=require("path"))},x=function(t,e){return R(),t=O.normalize(t),G.readFileSync(t,e?void 0:"utf8")},H=t=>t=(t=x(t,!0)).buffer?t:new Uint8Array(t),S=(t,n,r)=>{R(),t=O.normalize(t),G.readFile(t,function(t,e){t?r(t):n(e.buffer)})},1{var e=new XMLHttpRequest;return e.open("GET",t,!1),e.send(null),e.responseText},o&&(H=t=>{var e=new XMLHttpRequest;return e.open("GET",t,!1),e.responseType="arraybuffer",e.send(null),new Uint8Array(e.response)}),S=(t,e,n)=>{var r=new XMLHttpRequest;r.open("GET",t,!0),r.responseType="arraybuffer",r.onload=()=>{200==r.status||0==r.status&&r.response?e(r.response):n()},r.onerror=n,r.send(null)}),B.print||console.log.bind(console)),s=B.printErr||console.warn.bind(console);Object.assign(B,e),B.thisProgram&&(j=B.thisProgram),B.wasmBinary&&(a=B.wasmBinary),B.noExitRuntime;"object"!=typeof WebAssembly&&d("no native wasm support detected");var N,P,Q,V,z,l,f,U,J,W=!1,K="undefined"!=typeof TextDecoder?new TextDecoder("utf8"):void 0;function F(t,e,n){var r=e+n;for(n=e;t[n]&&!(r<=n);)++n;if(16>10,56320|1023&o)))):r+=String.fromCharCode(o)}return r}function Y(t,e){return t?F(V,t,e):""}function X(t,e,n,r){if(!(0>6}else{if(o<=65535){if(r<=n+2)break;e[n++]=224|o>>12}else{if(r<=n+3)break;e[n++]=240|o>>18,e[n++]=128|o>>12&63}e[n++]=128|o>>6&63}e[n++]=128|63&o}}return e[n]=0,n-i}function $(t){for(var e=0,n=0;n>0];case"i16":return z[t>>1];case"i32":case"i64":return l[t>>2];case"float":return U[t>>2];case"double":return J[t>>3];case"*":return f[t>>2];default:d("invalid type for getValue: "+e)}return null}function ct(t){var e="i32";switch(e=e.endsWith("*")?"*":e){case"i1":case"i8":Q[t>>0]=0;break;case"i16":z[t>>1]=0;break;case"i32":l[t>>2]=0;break;case"i64":m=[0,(p=0,1<=+Math.abs(p)?0>>0:~~+Math.ceil((p-(~~p>>>0))/4294967296)>>>0:0)],l[t>>2]=m[0],l[t+4>>2]=m[1];break;case"float":U[t>>2]=0;break;case"double":J[t>>3]=0;break;case"*":f[t>>2]=0;break;default:d("invalid type for setValue: "+e)}}h="sql-wasm.wasm",st()||(e=h,h=B.locateFile?B.locateFile(e,n):n+e);var ht=(t,e)=>{for(var n=0,r=t.length-1;0<=r;r--){var i=t[r];"."===i?t.splice(r,1):".."===i?(t.splice(r,1),n++):n&&(t.splice(r,1),n--)}if(e)for(;n;n--)t.unshift("..");return t},tt=t=>{var e="/"===t.charAt(0),n="/"===t.substr(-1);return(t=(t=ht(t.split("/").filter(t=>!!t),!e).join("/"))||e?t:".")&&n&&(t+="/"),(e?"/":"")+t},pt=t=>{var e=/^(\/?|)([\s\S]*?)((?:\.{1,2}|[^\/]+?|)(\.[^.\/]*|))(?:[\/]*)$/.exec(t).slice(1);return t=e[0],e=e[1],t||e?t+(e=e&&e.substr(0,e.length-1)):"."},mt=t=>{if("/"===t)return"/";var e=(t=(t=tt(t)).replace(/\/$/,"")).lastIndexOf("/");return-1===e?t:t.substr(e+1)};function bt(){for(var t="",e=!1,n=arguments.length-1;-1<=n&&!e;n--){if("string"!=typeof(e=0<=n?arguments[n]:"/"))throw new TypeError("Arguments to path.resolve must be strings");if(!e)return"";t=e+"/"+t,e="/"===e.charAt(0)}return(e?"/":"")+(t=ht(t.split("/").filter(t=>!!t),!e).join("/"))||"."}function dt(t,e){var n=Array($(t)+1);return t=X(t,n,0,n.length),e&&(n.length=t),n}var wt=[];function _t(t,e){wt[t]={input:[],output:[],Xa:e},zt(t,kt)}var yt,vt,gt,qt,kt={open:function(t){var e=wt[t.node.rdev];if(!e)throw new y(43);t.tty=e,t.seekable=!1},close:function(t){t.tty.Xa.fsync(t.tty)},fsync:function(t){t.tty.Xa.fsync(t.tty)},read:function(t,e,n,r){if(!t.tty||!t.tty.Xa.tb)throw new y(60);for(var i=0,a=0;a>>0),0!=n&&(e=Math.max(e,256)),n=t.Ia,t.Ia=new Uint8Array(e),0=t.node.Ma)return 0;if(8<(t=Math.min(t.node.Ma-i,r))&&a.subarray)e.set(a.subarray(i,i+t),n);else for(r=0;r{if(!(t=bt("/",t)))return{path:"",node:null};if(8<(e=Object.assign({rb:!0,kb:0},e)).kb)throw new y(32);t=ht(t.split("/").filter(t=>!!t),!1);for(var n=Mt,r="/",i=0;i{for(var e;;){if(t===t.parent)return t=t.Ra.ub,e?"/"!==t[t.length-1]?t+"/"+e:t+e:t;e=e?t.name+"/"+e:t.name,t=t.parent}},Ht=(t,e)=>{for(var n=0,r=0;r>>0)%_.length},Gt=t=>{var e=Ht(t.parent.id,t.name);if(_[e]===t)_[e]=t.Wa;else for(e=_[e];e;){if(e.Wa===t){e.Wa=t.Wa;break}e=e.Wa}},g=(t,e)=>{var n;if(n=(n=q(t,"x"))?n:t.Ga.lookup?0:2)throw new y(n,t);for(n=_[Ht(t.id,e)];n;n=n.Wa){var r=n.name;if(n.parent.id===t.id&&r===e)return n}return t.Ga.lookup(t,e)},Ot=(t,e,n,r)=>(t=new ke(t,e,n,r),e=Ht(t.parent.id,t.name),t.Wa=_[e],_[e]=t),Rt={r:0,"r+":2,w:577,"w+":578,a:1089,"a+":1090},Tt=t=>{var e=["r","w","rw"][3&t];return 512&t&&(e+="w"),e},q=(t,e)=>!Et&&(e.includes("r")&&!(292&t.mode)||e.includes("w")&&!(146&t.mode)||e.includes("x")&&!(73&t.mode))?2:0,jt=(t,e)=>{try{return g(t,e),20}catch(t){}return q(t,"wx")},Dt=(t,e,n)=>{try{var r=g(t,e)}catch(t){return t.Ka}if(t=q(t,"wx"))return t;if(n){if(16384!=(61440&r.mode))return 54;if(r===r.parent||"/"===St(r))return 10}else if(16384==(61440&r.mode))return 31;return 0},Lt=(t=0)=>{for(;t<=4096;t++)if(!i[t])return t;throw new y(33)},Nt=(t,e)=>(gt||((gt=function(){this.$a={}}).prototype={},Object.defineProperties(gt.prototype,{object:{get:function(){return this.node},set:function(t){this.node=t}},flags:{get:function(){return this.$a.flags},set:function(t){this.$a.flags=t}},position:{get:function(){return this.$a.position},set:function(t){this.$a.position=t}}})),t=Object.assign(new gt,t),e=Lt(e),t.fd=e,i[e]=t),Pt={open:t=>{t.Ha=At[t.node.rdev].Ha,t.Ha.open&&t.Ha.open(t)},Ta:()=>{throw new y(70)}},zt=(t,e)=>{At[t]={Ha:e}},Ut=(t,e)=>{var n="/"===e,r=!e;if(n&&Mt)throw new y(10);if(!n&&!r){var i=v(e,{rb:!1});if(e=i.path,(i=i.node).Va)throw new y(10);if(16384!=(61440&i.mode))throw new y(54)}((t=t.Ra(e={type:t,Kb:{},ub:e,Eb:[]})).Ra=e).root=t,n?Mt=t:i&&(i.Va=e,i.Ra&&i.Ra.Eb.push(e))},Jt=(t,e,n)=>{var r=v(t,{parent:!0}).node;if(!(t=mt(t))||"."===t||".."===t)throw new y(28);var i=jt(r,t);if(i)throw new y(i);if(r.Ga.ab)return r.Ga.ab(r,t,e,n);throw new y(63)},r=(t,e)=>Jt(t,1023&(void 0!==e?e:511)|16384,0),Wt=(t,e,n)=>{void 0===n&&(n=e,e=438),Jt(t,8192|e,n)},Kt=(t,e)=>{if(!bt(t))throw new y(44);var n=v(e,{parent:!0}).node;if(!n)throw new y(44);e=mt(e);var r=jt(n,e);if(r)throw new y(r);if(!n.Ga.symlink)throw new y(63);n.Ga.symlink(n,e,t)},Ft=t=>{var e=v(t,{parent:!0}).node,n=(t=mt(t),g(e,t)),r=Dt(e,t,!0);if(r)throw new y(r);if(!e.Ga.rmdir)throw new y(63);if(n.Va)throw new y(10);e.Ga.rmdir(e,t),Gt(n)},Ct=t=>{var e=v(t,{parent:!0}).node;if(!e)throw new y(44);t=mt(t);var n=g(e,t),r=Dt(e,t,!1);if(r)throw new y(r);if(!e.Ga.unlink)throw new y(63);if(n.Va)throw new y(10);e.Ga.unlink(e,t),Gt(n)},Bt=t=>{if(!(t=v(t).node))throw new y(44);if(t.Ga.readlink)return bt(St(t.parent),t.Ga.readlink(t));throw new y(28)},Qt=(t,e)=>{if(!(t=v(t,{Sa:!e}).node))throw new y(44);if(t.Ga.Pa)return t.Ga.Pa(t);throw new y(63)},Vt=t=>Qt(t,!0),Yt=(t,e)=>{if(!(t="string"==typeof t?v(t,{Sa:!0}).node:t).Ga.Oa)throw new y(63);t.Ga.Oa(t,{mode:4095&e|-4096&t.mode,timestamp:Date.now()})},Xt=(t,e)=>{if(e<0)throw new y(28);if(!(t="string"==typeof t?v(t,{Sa:!0}).node:t).Ga.Oa)throw new y(63);if(16384==(61440&t.mode))throw new y(31);if(32768!=(61440&t.mode))throw new y(28);var n=q(t,"w");if(n)throw new y(n);t.Ga.Oa(t,{size:e,timestamp:Date.now()})},et=(t,e,n)=>{if(""===t)throw new y(44);if("string"==typeof e){var r=Rt[e];if(void 0===r)throw Error("Unknown file open mode: "+e);e=r}if(n=64&e?4095&(void 0===n?438:n)|32768:0,"object"==typeof t)var i=t;else{t=tt(t);try{i=v(t,{Sa:!(131072&e)}).node}catch(t){}}if(r=!1,64&e)if(i){if(128&e)throw new y(20)}else i=Jt(t,n,0),r=!0;if(!i)throw new y(44);if(8192==(61440&i.mode)&&(e&=-513),65536&e&&16384!=(61440&i.mode))throw new y(54);if(!r&&(n=i?40960==(61440&i.mode)?32:16384==(61440&i.mode)&&("r"!==Tt(e)||512&e)?31:q(i,Tt(e)):44))throw new y(n);return 512&e&&!r&&Xt(i,0),e&=-131713,(i=Nt({node:i,path:St(i),flags:e,seekable:!0,position:0,Ha:i.Ha,Ib:[],error:!1})).Ha.open&&i.Ha.open(i),!B.logReadFiles||1&e||(t in(qt=qt||{})||(qt[t]=1)),i},$t=t=>{if(null===t.fd)throw new y(8);t.hb&&(t.hb=null);try{t.Ha.close&&t.Ha.close(t)}catch(t){throw t}finally{i[t.fd]=null}t.fd=null},Zt=(t,e,n)=>{if(null===t.fd)throw new y(8);if(!t.seekable||!t.Ha.Ta)throw new y(70);if(0!=n&&1!=n&&2!=n)throw new y(28);t.position=t.Ha.Ta(t,e,n),t.Ib=[]},te=(t,e,n,r,i)=>{if(r<0||i<0)throw new y(28);if(null===t.fd)throw new y(8);if(1==(2097155&t.flags))throw new y(8);if(16384==(61440&t.node.mode))throw new y(31);if(!t.Ha.read)throw new y(28);var a=void 0!==i;if(a){if(!t.seekable)throw new y(70)}else i=t.position;return e=t.Ha.read(t,e,n,r,i),a||(t.position+=e),e},ee=(t,e,n,r,i)=>{if(r<0||i<0)throw new y(28);if(null===t.fd)throw new y(8);if(0==(2097155&t.flags))throw new y(8);if(16384==(61440&t.node.mode))throw new y(31);if(!t.Ha.write)throw new y(28);t.seekable&&1024&t.flags&&Zt(t,0,2);var a=void 0!==i;if(a){if(!t.seekable)throw new y(70)}else i=t.position;return e=t.Ha.write(t,e,n,r,i,void 0),a||(t.position+=e),e},ne=t=>{var e=et(t,0),n=(t=Qt(t).size,new Uint8Array(t));return te(e,n,0,t,0),t=n,$t(e),t},re=()=>{y||((y=function(t,e){this.node=e,this.Hb=function(t){this.Ka=t},this.Hb(t),this.message="FS error"}).prototype=Error(),y.prototype.constructor=y,[44].forEach(t=>{xt[t]=new y(t),xt[t].stack=""}))},ie=(t,e)=>{var n=0;return t&&(n|=365),e&&(n|=146),n},ae=(t,u,a)=>{t=tt("/dev/"+t);var e=ie(!!u,!!a),n=(vt=vt||64,vt++<<8|0);zt(n,{open:t=>{t.seekable=!1},close:()=>{a&&a.buffer&&a.buffer.length&&a(10)},read:(t,e,n,r)=>{for(var i=0,a=0;a{for(var i=0;i>2]=r.dev,l[n+8>>2]=r.ino,l[n+12>>2]=r.mode,f[n+16>>2]=r.nlink,l[n+20>>2]=r.uid,l[n+24>>2]=r.gid,l[n+28>>2]=r.rdev,m=[r.size>>>0,(p=r.size,1<=+Math.abs(p)?0>>0:~~+Math.ceil((p-(~~p>>>0))/4294967296)>>>0:0)],l[n+40>>2]=m[0],l[n+44>>2]=m[1],l[n+48>>2]=4096,l[n+52>>2]=r.blocks,m=[Math.floor(r.atime.getTime()/1e3)>>>0,(p=Math.floor(r.atime.getTime()/1e3),1<=+Math.abs(p)?0>>0:~~+Math.ceil((p-(~~p>>>0))/4294967296)>>>0:0)],l[n+56>>2]=m[0],l[n+60>>2]=m[1],f[n+64>>2]=0,m=[Math.floor(r.mtime.getTime()/1e3)>>>0,(p=Math.floor(r.mtime.getTime()/1e3),1<=+Math.abs(p)?0>>0:~~+Math.ceil((p-(~~p>>>0))/4294967296)>>>0:0)],l[n+72>>2]=m[0],l[n+76>>2]=m[1],f[n+80>>2]=0,m=[Math.floor(r.ctime.getTime()/1e3)>>>0,(p=Math.floor(r.ctime.getTime()/1e3),1<=+Math.abs(p)?0>>0:~~+Math.ceil((p-(~~p>>>0))/4294967296)>>>0:0)],l[n+88>>2]=m[0],l[n+92>>2]=m[1],f[n+96>>2]=0,m=[r.ino>>>0,(p=r.ino,1<=+Math.abs(p)?0>>0:~~+Math.ceil((p-(~~p>>>0))/4294967296)>>>0:0)],l[n+104>>2]=m[0],l[n+108>>2]=m[1],0}var ue=void 0;function se(){return l[(ue+=4)-4>>2]}function M(t){if(t=i[t])return t;throw new y(8)}function le(t){return f[t>>2]+4294967296*l[t+4>>2]}function fe(t){var e=$(t)+1,n=Ee(e);return n&&X(t,Q,n,e),n}function ce(t,e,n){function r(t){return(t=t.toTimeString().match(/\(([A-Za-z ]+)\)$/))?t[1]:"GMT"}var i,a,o,u;ce.Bb||(ce.Bb=!0,t=t,e=e,n=n,i=(new Date).getFullYear(),a=new Date(i,0,1),o=new Date(i,6,1),i=a.getTimezoneOffset(),u=o.getTimezoneOffset(),l[t>>2]=60*Math.max(i,u),l[e>>2]=Number(i!=u),t=r(a),e=r(o),t=fe(t),e=fe(e),u>2]=t,f[n+4>>2]=e):(f[n>>2]=e,f[n+4>>2]=t))}var he=u?()=>{var t=process.hrtime();return 1e3*t[0]+t[1]/1e6}:()=>performance.now(),pe={};function me(){if(!be){var t,e={USER:"web_user",LOGNAME:"web_user",PATH:"/",PWD:"/",HOME:"/home/web_user",LANG:("object"==typeof navigator&&navigator.languages&&navigator.languages[0]||"C").replace("-","_")+".UTF-8",_:j||"./this.program"};for(t in pe)void 0===pe[t]?delete e[t]:e[t]=pe[t];var n=[];for(t in e)n.push(t+"="+e[t]);be=n}return be}var be,A=void 0,de=[];function we(e,n){if(!A){A=new WeakMap;var r=c.length;if(A)for(var i=0;i<0+r;i++){var a=c.get(i);a&&A.set(a,i)}}if(A.has(e))return A.get(e);if(de.length)r=de.pop();else{try{c.grow(1)}catch(t){if(t instanceof RangeError)throw"Unable to grow wasm table. Set ALLOW_TABLE_GROWTH.";throw t}r=c.length-1}try{c.set(r,e)}catch(t){if(!(t instanceof TypeError))throw t;if("function"==typeof WebAssembly.Function){for(var i=WebAssembly.Function,a={i:"i32",j:"i64",f:"f32",d:"f64",p:"i32"},o={parameters:[],results:"v"==n[0]?[]:[a[n[0]]]},u=1;u>7),u=0;u>7),n.push.apply(n,i),n.push(2,7,1,1,101,1,102,0,0,7,5,1,1,102,0,0),n=new WebAssembly.Module(new Uint8Array(n)),n=new WebAssembly.Instance(n,{e:{f:e}}).exports.f}c.set(r,n)}return A.set(e,r),r}function _e(t){A.delete(c.get(t)),de.push(t)}var ye,ve=0,ge=1;function qe(t){var e=(ve==ge?nt:Ee)(t.length);return t.subarray||t.slice||(t=new Uint8Array(t)),V.set(t,e),e}function ke(t,e,n,r){this.parent=t=t||this,this.Ra=t.Ra,this.Va=null,this.id=It++,this.name=e,this.mode=n,this.Ga={},this.Ha={},this.rdev=r}Object.defineProperties(ke.prototype,{read:{get:function(){return 365==(365&this.mode)},set:function(t){t?this.mode|=365:this.mode&=-366}},write:{get:function(){return 146==(146&this.mode)},set:function(t){t?this.mode|=146:this.mode&=-147}}}),re(),_=Array(4096),Ut(w,"/"),r("/tmp"),r("/home"),r("/home/web_user"),r("/dev"),zt(259,{read:()=>0,write:(t,e,n,r)=>r}),Wt("/dev/null",259),_t(1280,n),_t(1536,e),Wt("/dev/tty",1280),Wt("/dev/tty1",1536),n=function(){var t;if("object"==typeof crypto&&"function"==typeof crypto.getRandomValues)return t=new Uint8Array(1),()=>(crypto.getRandomValues(t),t[0]);if(u)try{var e=require("crypto");return()=>e.randomBytes(1)[0]}catch(t){}return()=>d("randomDevice")}(),ae("random",n),ae("urandom",n),r("/dev/shm"),r("/dev/shm/tmp"),r("/proc"),ye=r("/proc/self"),r("/proc/self/fd"),Ut({Ra:()=>{var t=Ot(ye,"fd",16895,73);return t.Ga={lookup:(t,e)=>{var n=i[+e];if(n)return(t={parent:null,Ra:{ub:"fake"},Ga:{readlink:()=>n.path}}).parent=t;throw new y(8)}},t}},"/proc/self/fd");var Me,Ae={a:function(t,e,n,r){d("Assertion failed: "+Y(t)+", at: "+[e?Y(e):"unknown filename",n,r?Y(r):"unknown function"])},h:function(t,e){try{return t=Y(t),Yt(t,e),0}catch(t){if(t instanceof y)return-t.Ka;throw t}},H:function(t,e,n){try{if(e=k(t,e=Y(e)),-8&n)return-28;var r=v(e,{Sa:!0}).node;return r?(t="",4&n&&(t+="r"),2&n&&(t+="w"),1&n&&(t+="x"),t&&q(r,t)?-2:0):-44}catch(t){if(t instanceof y)return-t.Ka;throw t}},i:function(t,e){try{var n=i[t];if(n)return Yt(n.node,e),0;throw new y(8)}catch(t){if(t instanceof y)return-t.Ka;throw t}},g:function(t){try{var e=i[t];if(!e)throw new y(8);var n=e.node,r="string"==typeof n?v(n,{Sa:!0}).node:n;if(r.Ga.Oa)return r.Ga.Oa(r,{timestamp:Date.now()}),0;throw new y(63)}catch(t){if(t instanceof y)return-t.Ka;throw t}},b:function(t,e,n){ue=n;try{var r=M(t);switch(e){case 0:var i=se();return i<0?-28:Nt(r,i).fd;case 1:case 2:return 0;case 3:return r.flags;case 4:return i=se(),r.flags|=i,0;case 5:return i=se(),z[i+0>>1]=2,0;case 6:case 7:return 0;case 16:case 8:return-28;case 9:return l[Ie()>>2]=28,-1;default:return-28}}catch(t){if(t instanceof y)return-t.Ka;throw t}},G:function(t,e){try{var n=M(t);return oe(Qt,n.path,e)}catch(t){if(t instanceof y)return-t.Ka;throw t}},l:function(t,e,n){try{if(e=n+2097152>>>0<4194305-!!e?(e>>>0)+4294967296*n:NaN,isNaN(e))return-61;var r=i[t];if(!r)throw new y(8);if(0==(2097155&r.flags))throw new y(28);return Xt(r.node,e),0}catch(t){if(t instanceof y)return-t.Ka;throw t}},B:function(t,e){try{if(0===e)return-28;var n=$("/")+1;return e>2]/1e6,1e3*le(n+=16)+l[n+8>>2]/1e6):r=Date.now(),t=r;var r,i,a=v(e,{Sa:!0}).node;return a.Ga.Oa(a,{timestamp:Math.max(t,i)}),0}catch(t){if(t instanceof y)return-t.Ka;throw t}},e:function(){return Date.now()},j:function(t,e){t=new Date(1e3*le(t)),l[e>>2]=t.getSeconds(),l[e+4>>2]=t.getMinutes(),l[e+8>>2]=t.getHours(),l[e+12>>2]=t.getDate(),l[e+16>>2]=t.getMonth(),l[e+20>>2]=t.getFullYear()-1900,l[e+24>>2]=t.getDay();var n=new Date(t.getFullYear(),0,1),r=(l[e+28>>2]=(t.getTime()-n.getTime())/864e5|0,l[e+36>>2]=-60*t.getTimezoneOffset(),new Date(t.getFullYear(),6,1).getTimezoneOffset()),n=n.getTimezoneOffset();l[e+32>>2]=0|(r!=n&&t.getTimezoneOffset()==Math.min(n,r))},w:function(t,e,n,r,i,a){try{var o=M(r);if(0!=(2&e)&&0==(2&n)&&2!=(2097155&o.flags))throw new y(2);if(1==(2097155&o.flags))throw new y(2);if(!o.Ha.bb)throw new y(43);var u=o.Ha.bb(o,t,i,e,n),s=u.Fb;return l[a>>2]=u.vb,s}catch(t){if(t instanceof y)return-t.Ka;throw t}},x:function(t,e,n,r,i,a){try{var o,u=M(i);2&n&&(o=V.slice(t,t+e),u&&u.Ha.cb&&u.Ha.cb(u,o,a,e,r))}catch(t){if(t instanceof y)return-t.Ka;throw t}},n:ce,q:function(){return 2147483648},d:he,c:function(t){var e=V.length;if(2147483648<(t>>>=0))return!1;for(var n=1;n<=4;n*=2){var r=e*(1+.2/n),r=Math.min(r,t+100663296),i=Math;r=Math.max(t,r),i=i.min.call(i,2147483648,r+(65536-r%65536)%65536);t:{try{N.grow(i-P.byteLength+65535>>>16),C();var a=1;break t}catch(t){}a=void 0}if(a)return!0}return!1},z:function(r,i){var a=0;return me().forEach(function(t,e){var n=i+a;for(e=f[r+4*e>>2]=n,n=0;n>0]=t.charCodeAt(n);Q[e>>0]=0,a+=t.length+1}),0},A:function(t,e){var n=me(),r=(f[t>>2]=n.length,0);return n.forEach(function(t){r+=t.length+1}),f[e>>2]=r,0},f:function(t){try{var e=M(t);return $t(e),0}catch(t){if(t instanceof y)return t.Ka;throw t}},m:function(t,e){try{var n=M(t);return Q[e>>0]=n.tty?2:16384==(61440&n.mode)?3:40960==(61440&n.mode)?7:4,0}catch(t){if(t instanceof y)return t.Ka;throw t}},u:function(t,e,n,r){try{t:{var i=M(t);t=e;for(var a=e=0;a>2],u=f[t+4>>2],s=(t+=8,te(i,Q,o,u));if(s<0){var l=-1;break t}if(e+=s,s>2]=l,0}catch(t){if(t instanceof y)return t.Ka;throw t}},k:function(t,e,n,r,i){try{if(e=n+2097152>>>0<4194305-!!e?(e>>>0)+4294967296*n:NaN,isNaN(e))return 61;var a=M(t);return Zt(a,e,r),m=[a.position>>>0,(p=a.position,1<=+Math.abs(p)?0>>0:~~+Math.ceil((p-(~~p>>>0))/4294967296)>>>0:0)],l[i>>2]=m[0],l[i+4>>2]=m[1],a.hb&&0===e&&0===r&&(a.hb=null),0}catch(t){if(t instanceof y)return t.Ka;throw t}},C:function(t){try{var e=M(t);return e.Ha&&e.Ha.fsync?e.Ha.fsync(e):0}catch(t){if(t instanceof y)return t.Ka;throw t}},r:function(t,e,n,r){try{t:{var i=M(t);t=e;for(var a=e=0;a>2],u=f[t+4>>2],s=(t+=8,ee(i,Q,o,u));if(s<0){var l=-1;break t}e+=s}l=e}return f[r>>2]=l,0}catch(t){if(t instanceof y)return t.Ka;throw t}}},Ie=(!function(){function e(t){B.asm=t.exports,N=B.asm.I,C(),c=B.asm.Aa,it.unshift(B.asm.J),b--,B.monitorRunDependencies&&B.monitorRunDependencies(b),0==b&&(null!==ot&&(clearInterval(ot),ot=null),ut&&(t=ut,ut=null,t()))}function n(t){e(t.instance)}function r(t){return function(){if(!a&&(D||o)){if("function"==typeof fetch&&!h.startsWith("file://"))return fetch(h,{credentials:"same-origin"}).then(function(t){if(t.ok)return t.arrayBuffer();throw"failed to load wasm binary file at '"+h+"'"}).catch(lt);if(S)return new Promise(function(e,t){S(h,function(t){e(new Uint8Array(t))},t)})}return Promise.resolve().then(lt)}().then(function(t){return WebAssembly.instantiate(t,i)}).then(function(t){return t}).then(t,function(t){s("failed to asynchronously prepare wasm: "+t),d(t)})}var i={a:Ae};if(b++,B.monitorRunDependencies&&B.monitorRunDependencies(b),B.instantiateWasm)try{return B.instantiateWasm(i,e)}catch(t){return s("Module.instantiateWasm callback failed with error: "+t)}a||"function"!=typeof WebAssembly.instantiateStreaming||st()||h.startsWith("file://")||u||"function"!=typeof fetch?r(n):fetch(h,{credentials:"same-origin"}).then(function(t){return WebAssembly.instantiateStreaming(t,i).then(n,function(t){return s("wasm streaming compile failed: "+t),s("falling back to ArrayBuffer instantiation"),r(n)})})}(),B.___wasm_call_ctors=function(){return(B.___wasm_call_ctors=B.asm.J).apply(null,arguments)},B._sqlite3_free=function(){return(B._sqlite3_free=B.asm.K).apply(null,arguments)},B._sqlite3_value_double=function(){return(B._sqlite3_value_double=B.asm.L).apply(null,arguments)},B._sqlite3_value_text=function(){return(B._sqlite3_value_text=B.asm.M).apply(null,arguments)},B.___errno_location=function(){return(Ie=B.___errno_location=B.asm.N).apply(null,arguments)}),Ee=(B._sqlite3_prepare_v2=function(){return(B._sqlite3_prepare_v2=B.asm.O).apply(null,arguments)},B._sqlite3_step=function(){return(B._sqlite3_step=B.asm.P).apply(null,arguments)},B._sqlite3_finalize=function(){return(B._sqlite3_finalize=B.asm.Q).apply(null,arguments)},B._sqlite3_reset=function(){return(B._sqlite3_reset=B.asm.R).apply(null,arguments)},B._sqlite3_value_int=function(){return(B._sqlite3_value_int=B.asm.S).apply(null,arguments)},B._sqlite3_clear_bindings=function(){return(B._sqlite3_clear_bindings=B.asm.T).apply(null,arguments)},B._sqlite3_value_blob=function(){return(B._sqlite3_value_blob=B.asm.U).apply(null,arguments)},B._sqlite3_value_bytes=function(){return(B._sqlite3_value_bytes=B.asm.V).apply(null,arguments)},B._sqlite3_value_type=function(){return(B._sqlite3_value_type=B.asm.W).apply(null,arguments)},B._sqlite3_result_blob=function(){return(B._sqlite3_result_blob=B.asm.X).apply(null,arguments)},B._sqlite3_result_double=function(){return(B._sqlite3_result_double=B.asm.Y).apply(null,arguments)},B._sqlite3_result_error=function(){return(B._sqlite3_result_error=B.asm.Z).apply(null,arguments)},B._sqlite3_result_int=function(){return(B._sqlite3_result_int=B.asm._).apply(null,arguments)},B._sqlite3_result_int64=function(){return(B._sqlite3_result_int64=B.asm.$).apply(null,arguments)},B._sqlite3_result_null=function(){return(B._sqlite3_result_null=B.asm.aa).apply(null,arguments)},B._sqlite3_result_text=function(){return(B._sqlite3_result_text=B.asm.ba).apply(null,arguments)},B._sqlite3_sql=function(){return(B._sqlite3_sql=B.asm.ca).apply(null,arguments)},B._sqlite3_aggregate_context=function(){return(B._sqlite3_aggregate_context=B.asm.da).apply(null,arguments)},B._sqlite3_column_count=function(){return(B._sqlite3_column_count=B.asm.ea).apply(null,arguments)},B._sqlite3_data_count=function(){return(B._sqlite3_data_count=B.asm.fa).apply(null,arguments)},B._sqlite3_column_blob=function(){return(B._sqlite3_column_blob=B.asm.ga).apply(null,arguments)},B._sqlite3_column_bytes=function(){return(B._sqlite3_column_bytes=B.asm.ha).apply(null,arguments)},B._sqlite3_column_double=function(){return(B._sqlite3_column_double=B.asm.ia).apply(null,arguments)},B._sqlite3_column_text=function(){return(B._sqlite3_column_text=B.asm.ja).apply(null,arguments)},B._sqlite3_column_type=function(){return(B._sqlite3_column_type=B.asm.ka).apply(null,arguments)},B._sqlite3_column_name=function(){return(B._sqlite3_column_name=B.asm.la).apply(null,arguments)},B._sqlite3_bind_blob=function(){return(B._sqlite3_bind_blob=B.asm.ma).apply(null,arguments)},B._sqlite3_bind_double=function(){return(B._sqlite3_bind_double=B.asm.na).apply(null,arguments)},B._sqlite3_bind_int=function(){return(B._sqlite3_bind_int=B.asm.oa).apply(null,arguments)},B._sqlite3_bind_text=function(){return(B._sqlite3_bind_text=B.asm.pa).apply(null,arguments)},B._sqlite3_bind_parameter_index=function(){return(B._sqlite3_bind_parameter_index=B.asm.qa).apply(null,arguments)},B._sqlite3_normalized_sql=function(){return(B._sqlite3_normalized_sql=B.asm.ra).apply(null,arguments)},B._sqlite3_errmsg=function(){return(B._sqlite3_errmsg=B.asm.sa).apply(null,arguments)},B._sqlite3_exec=function(){return(B._sqlite3_exec=B.asm.ta).apply(null,arguments)},B._sqlite3_changes=function(){return(B._sqlite3_changes=B.asm.ua).apply(null,arguments)},B._sqlite3_close_v2=function(){return(B._sqlite3_close_v2=B.asm.va).apply(null,arguments)},B._sqlite3_create_function_v2=function(){return(B._sqlite3_create_function_v2=B.asm.wa).apply(null,arguments)},B._sqlite3_open=function(){return(B._sqlite3_open=B.asm.xa).apply(null,arguments)},B._malloc=function(){return(Ee=B._malloc=B.asm.ya).apply(null,arguments)}),xe=B._free=function(){return(xe=B._free=B.asm.za).apply(null,arguments)},Se=(B._RegisterExtensionFunctions=function(){return(B._RegisterExtensionFunctions=B.asm.Ba).apply(null,arguments)},B._emscripten_builtin_memalign=function(){return(Se=B._emscripten_builtin_memalign=B.asm.Ca).apply(null,arguments)}),He=B.stackSave=function(){return(He=B.stackSave=B.asm.Da).apply(null,arguments)},Ge=B.stackRestore=function(){return(Ge=B.stackRestore=B.asm.Ea).apply(null,arguments)},nt=B.stackAlloc=function(){return(nt=B.stackAlloc=B.asm.Fa).apply(null,arguments)};function Oe(){function t(){if(!Me&&(Me=!0,B.calledRun=!0,!W)){if(B.noFSInit||yt||(yt=!0,re(),B.stdin=B.stdin,B.stdout=B.stdout,B.stderr=B.stderr,B.stdin?ae("stdin",B.stdin):Kt("/dev/tty","/dev/stdin"),B.stdout?ae("stdout",null,B.stdout):Kt("/dev/tty","/dev/stdout"),B.stderr?ae("stderr",null,B.stderr):Kt("/dev/tty1","/dev/stderr"),et("/dev/stdin",0),et("/dev/stdout",1),et("/dev/stderr",1)),Et=!1,ft(it),B.onRuntimeInitialized&&B.onRuntimeInitialized(),B.postRun)for("function"==typeof B.postRun&&(B.postRun=[B.postRun]);B.postRun.length;){var t=B.postRun.shift();at.unshift(t)}ft(at)}}if(!(0"number"===t||"boolean"===t);return"string"!==f&&e&&!t?B["_"+l]:function(){var t=l,e=f,n=c,r=arguments,i={string:t=>{var e,n=0;return null!=t&&0!==t&&(e=1+(t.length<<2),n=nt(e),X(t,V,n,e)),n},array:t=>{var e=nt(t.length);return Q.set(t,e),e}},a=(t=B["_"+t],[]),o=0;if(r)for(var u=0;u