-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsupercharged-local-file-directory-browser-8.0.9.3.js
4186 lines (4168 loc) · 500 KB
/
supercharged-local-file-directory-browser-8.0.9.3.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
/* eslint-disable no-case-declarations, no-fallthrough, indent, no-mixed-spaces-and-tabs, no-multi-spaces, no-return-assign, no-useless-escape, quotes */
/* jshint esversion: 6 */
// ==UserScript==
// @name Supercharged Local Directory File Browser
// @version 8.0.9.3
// @description Makes directory index pages (either local or remote open directories) actually useful. Adds sidebar and content preview pane; keyboard navigation; sorting; light/dark UI; preview images/fonts in navigable grids; browse subdirectories w/o page reload (“tree view”); media playback, shuffle/loop options; basic playlist (m3u, extm3u) & cuesheet (.cue) support; create, edit, preview, save markdown/plain text files; open font files, view complete glyph repertoire, save glyphs as .svg; more.
// @author gaspar_schot
// @license GPL-3.0-or-later
// @homepageURL https://openuserjs.org/scripts/gaspar_schot/Supercharged_Local_Directory_File_Browser
// @icon data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAIAAAACAAgMAAAC+UIlYAAAACVBMVEUmRcmZzP8zmf8pVcWPAAAAAXRSTlMAQObYZgAAAFBJREFUeF7tyqERwDAMBEE3mX5UiqDmqwwziTPHjG7xrmzrLFtRaApDIRiKQlMYCsFQFJrCUAiGotAU5hTA1WB4fhkMBsOJwWAwgHvB8CHpBcTbpxy4RZNvAAAAAElFTkSuQmCC
// @match file://*/*
// @match https://www.example.com/path/to/directory/*
// @require https://cdn.jsdelivr.net/npm/[email protected]/dist/markdown-it.min.js
// @require https://cdn.jsdelivr.net/npm/[email protected]/dist/markdown-it-footnote.min.js
// @require https://cdn.jsdelivr.net/npm/[email protected]/dist/markdown-it-toc-made-right.min.js
// @require https://cdn.jsdelivr.net/npm/[email protected]/dist/markdown-it-sub.min.js
// @require https://cdn.jsdelivr.net/npm/[email protected]/dist/markdown-it-sup.min.js
// @require https://cdn.jsdelivr.net/npm/[email protected]/dist/markdown-it-deflist.min.js
// @require https://cdn.jsdelivr.net/npm/[email protected]/dist/markdown-it-multimd-table.min.js
// @require https://cdn.jsdelivr.net/npm/[email protected]/dist/markdown-it-center-text.min.js
// @require https://cdn.jsdelivr.net/npm/[email protected]/dist/opentype.min.js
// @require https://cdn.jsdelivr.net/npm/@gerhobbelt/[email protected]/dist/markdownItCheckbox.umd.js
// @updateURL https://openuserjs.org/meta/gaspar_schot/Supercharged_Local_Directory_File_Browser.meta.js
// ==/UserScript==
(function() {
// ************ J + M + J ************* //
'use strict';
// ***** UI SETTINGS ***** //
const UI_Prefs_Bool = {
alternate_background: true, apps_as_dirs: true, autoload_index_files: true, ignore_ignored_items: true, media_autoload: true, media_autoplay: true, media_play_all: true,
show_details: true, show_ignored_items: true, show_image_thumbnails: true, show_image_thumbnails_always: true, show_large_image_thumbnails: true, show_invisibles: true, show_numbers: true,
show_sidebar: true, text_editing_enable: true, texteditor_split_view: true, texteditor_sync_scroll: true, use_custom_icons: true, audio_player_on_top: true
}
const UI_Prefs_Non_Bool = {
grid_font_size: 1, // Default = 1
grid_image_size: 184, // Default = 184 (200px - 16px)
sort_by: 'default', // Choose from: 'name', 'size', 'date', 'kind', 'ext', 'default ( = Chrome sorting: dirs on top, files alphabetical).
sort_direction: 'ascending', // Choose from: 'ascending' (A-Z) [default] or 'descending' (Z-A).
texteditor_view: 'styled', // Options: 'raw','styled','html'
theme: 'light', // Options: 'light' or 'dark'
ui_font: 'system-ui, sans-serif', // Choose an installed font for the UI; if undefined, use browser defaults instead. [system-ui, sans-serif]
ui_font_size: '13px', // Choose a default UI font size; use any standard CSS units.
ui_scale: '100',
}
let UI_Settings = {...UI_Prefs_Bool, ...UI_Prefs_Non_Bool};
const Item_Kinds = {
dir: ['/'], // loaded in iframe#content_iframe
app: ['app/','app','appimage','apk','exe','ipa','ipk','jar','msi','wsf'], // generally ignored; some apps may be opened as directories
alias: ['alias','desktop','directory','lnk','symlink','symlink/'],
archive: ['7z','archive','b6z','bin','bzip','bz2','cbr','dmg','gz','iso','mpkg','pkg','rar','sit','sitx','tar','tar.gz','zip','zipx','zxp'], // ignored
audio: ['aac','aif','aiff','ape','flac','m4a','mka','mp3','ogg','opus','wav'], // loaded in audio#audio
bin: ['a','ase','bundle','dll','dyld','dylib','gem','icc','msi','profraw','pyc','pyo','o','rakefile','ri','so','torrent','xml','2','opml','qm','scpt','uo','vsix','zwc'], // ignored
code: ['bak','bash','bash_profile','bashrc','bat','cgi','com','c','cfg','cnf','codes','coffee','conf','csh','cshrc','cson','css','cuetxt','custom_aliases','d','default','description','dist','editorconfig', 'emacs','example','gemspec','gitconfig','gitignore','gitignore_global','h','hd','ini','js','json','jsx','less','list','local','login','logout','lua','mkshrc','old','pc','php','pl','plist','pre-oh-my-zsh','profile','pth','py','rb','rc','rdoc','sass','settings','sh','strings','taskrc','tcl','viminfo','vimrc','vue','vtt','yaml','yml','zlogin','zlogout','zpreztorc','zprofile','zsh','zshenv','zshrc'], // treated as text, opened in iframe#content_iframe text editor
database: ['accdb','db','dbf','mdb','pdb','sql', 'sqlite','sqlitedb','sqlite3'], // ignored
ebook: ['azw','azw1','azw3','azw4','epub','ibook','kfx','mobi','tpz'], // ignored
font: ['otf','ttf','woff','woff2','afm','pfb','pfm','tfm'], // opened in div#content_font
graphics: ['afdesign','afpub','ai','book','dtp','eps','fm','icml','icns','idml','indb','indd','indt','inx','mif','pmd','pub','qxb','qxd','qxp','sla','swf','ai','arw','cr2','dng','eps','jpf','nef','psd','psd','raw', 'tif','tiff'], // ignored
htm: ['htm','html','xhtm','xhtml'], // opened in iframe#content_iframe
image: ['apng','bmp','gif','ico','jpeg','jpg','png','svg','webp'],
link: ['url','webloc','inetloc'],
markdown: ['md','markdown','mdown','mkdn','mkd','mdwn','mdtxt','mdtext','mk'], // treated as text, opened in iframe#content_iframe text editor
other_ignored: ['alias','cue','dat','dic','idx','xmp'],
office: ['csv','doc','docx','key','numbers','odf','ods','odt','pages','rtf','scriv','wpd','wps','xlr','xls','xlsx','xlm'], // ignored
playlist: ['m3u','m3u8','pls','asx','wpl','xspf'],
pdf: ['pdf'], // open in #content_pdf
system: ['DS_Store','ds_store','icon','ics','spotlight-v100/','temporaryitems/','documentrevisions-v100/','trashes/','fseventsd/','dbfseventsd','file','programdata','localized'], // ignored system items
text: ['log','nfo','txt','text','readme'], // opened in iframe#content_iframe text editor
video: ['m4v','mkv','mov','mp4','mpeg','webm'] // loaded in video#content_video
};
const Item_Settings = { // ITEM_SETTINGS: Ignore or Exclude files by extension (prevents browser from attempting to download the file).
ignored: [...Item_Kinds.archive,...Item_Kinds.bin,...Item_Kinds.database,...Item_Kinds.graphics,...Item_Kinds.other_ignored,...Item_Kinds.office,...Item_Kinds.playlist,...Item_Kinds.system]
};
// ***** UTILITIES ***** //
function loadFileURL() { // ===> LOAD FILE URL
// if window.location points to a file, change the location to the file's container dir, add search_param of file name; then load the file's container dir and load file in content pane.
let search_params = searchParamsGet();
search_params.set( 'file', window.location.pathname.split('/').reverse()[0]);
window.location = window.location.pathname.slice( 0,window.location.pathname.lastIndexOf('/') ) +'/?'+ search_params ;
return;
}
if ( !window.location.pathname.endsWith('/') && window.top === window.self ) { loadFileURL(); } // load file urls
//==============================//
function isTopWindow() { return ( window.top === window.self || false ) } // ===> TOP WINDOW OR IFRAME
function getBrowser() { //*** needs testing for new userAgentData object --> what are possible brand names?; combine with getOS() // ===> GET BROWSER
let brand = ( navigator.userAgentData !== undefined ? navigator.userAgentData.brands[1].brand.toLowerCase() : navigator.userAgent );
switch(true) {
case brand === 'chromium' || ( /chrome?chromium/.test(brand) ): return 'is_chrome';
case brand === 'msie' || ( /msie/.test(brand) ): return 'is_explorer';
// case brand === 'edge' || ( /edge/.test(brand) ): return 'is_edge'; // need case for ms edge
case brand === 'opera' || ( /opera/.test(brand) ): return 'is_opera';
case brand === 'safari' || ( /safari/.test(brand) ): return 'is_safari';
case brand === 'firefox' || ( !/chrome|chromium/.test(brand) ): return 'is_gecko';
}
}
function getOS() { // modded from https://***stackoverflow.com/questions/38241480/detect-macos-ios-windows-android-and-linux-os-with-js // ===> GET OS
let platform = ( navigator.userAgentData !== undefined ? navigator.userAgentData.platform : window.navigator.platform ).toLowerCase();
let macos_platforms = ['macos','macintosh','macintel','macppc','mac68k'], windows_platforms = ['win32','win64','windows','wince'], os = null;
switch(true) {
case macos_platforms.indexOf(platform) !== -1: os = 'macos'; break;
case windows_platforms.indexOf(platform) !== -1: os = 'windows'; break;
// case iosPlatforms.indexOf(platform) !== -1: os = 'ios'; break; // just in case;
// case /Android/.test(userAgent): os = 'android'; break; // just in case;
case !os && /Linux/.test(platform): os = 'linux'; break;
}
return os;
}
function newURL(link) { try { return new URL(link,document.baseURI); } catch( error ) { return new URL(encodeURI(link) ); } } // ===> NEW URL
function decodeURIComponentSafe(str) { if ( !str ) { return str; } // ===> DECODE URI COMPONENT SAFE; // Fix "%" error in file name; see stackoverflow.com/questions/7449588/why-does-decodeuricomponent-lock-up-my-browser
try { return decodeURIComponent(str.replace(/%(?![0-9a-fA-F]{2})/g,'%25') ).replace(/\"/g,'\"'); } catch(e) { return str; } // replace % with %25 if not followed by two a-f/number; replace " with html entity
}
//function sanitizeReservedChars(str) { let chars = ['#','$','&','+',',','/',':',';','=','?','@','[',']']; }
//function escapeStr(str) { str = str.replace(/([$?*+()[]|^])/g,'\\$1'); return str; } // ===> ESCAPE STRING
function convertHex2Decimal(d) { return parseInt(d, 16); }
function convertDecimal2Hex(d, padding) { let hex = Number(d).toString(16); hex = ( isNaN(hex) ? null : "000000".substr(0, padding - hex.length) + hex ); return hex; }
//==============================//
const window_protocol = window.location.protocol; // GLOBAL: protocol
//const window_origin = window_protocol +'//'+ window.location.host; // GLOBAL: origin
let window_location = decodeURIComponentSafe( [location.protocol, '//', location.host, location.pathname].join('') ); // GLOBAL: current location
const current_dir_path = window_location.replace(/([/|_|—])/g,'$1<wbr>').replace(/\\/g,'/'); // GLOBAL: current dir path w/o query string for display
// const current_dir = window_location.split('/').slice(-2,-1).toString(); // GLOBAL: current dir
//==============================//
function setLocation(link) { window.location = link; }
function changeLocation(args) { // args[0] === href, args[1] === 'external || ok'
switch(true) {
case args[1] === 'external': window.open(args[0]); break; // open external menu links: about, coffee, contact
case args[1] === 'ok': window.location = args[0]; break;
case ( /has_\w+list/.test(getClassNames('body'))): args = window.location.href; // nobreak; show playlist warning
default: showWarning( 'setLocation',args.toString() );
}
}
function searchParamsGet() { let search_params = new URL(window.location).searchParams; search_params.sort(); return search_params; } // ===> GET SEARCH PARAMS
function searchParamSet(key,value,bool) { let search_params = searchParamsGet(); search_params.set( key, value ); if ( bool !== false ) { updateSearchParams(search_params);} } // ===> SET SEARCH PARAM (bool false = don't update)
function searchParamDelete(key) { let search_params = searchParamsGet(); search_params.delete(key); updateSearchParams(search_params); } // ===> REMOVE SEARCH PARAM
function updateSearchParams(search_params) { // ===> UPDATE SEARCH PARAMS
search_params = sanitizeSearchParams(search_params); search_params.sort(); // sort and sanitize params
let search_params_str = search_params.toString().replace(/%2F/g,'').replace('/','').replace(/%2Cfalse/g,''); // further sanitization
let new_location = ( search_params_str.length === 0 ? window.location.pathname : window.location.pathname +'?'+ search_params_str ); // don't add ? if no search params
window.history.replaceState({}, document.title, new_location); // set new location
if ( isTopWindow() ) { updateParentLinks(); }
}
function sanitizeSearchParams(search_params_str) { // remove search_params that are not in UI_Settings
for ( let entry of search_params_str.entries() ) { if ( !UI_Settings[entry[0]] && !/selected|history|width/.test(entry[0]) ) { search_params_str.delete(entry[0]); } } return search_params_str;
}
function getCurrentUIPref(pref_id) { // ===> GET SEARCH PARAM value by key
let search_params = searchParamsGet(), value = '';
switch(true) {
case pref_id === 'width': if ( !isTopWindow() ) { return; } // width: set the stored sidebar width or use default 30%
value = ( !search_params.has(pref_id) || window.innerWidth === 0 ? 30 : Math.round(100 * Number.parseInt(search_params.get('width'))/window.innerWidth) ); break; // percentage
case pref_id === 'parent_id':
value = ( search_params.has(pref_id) ? search_params.get(pref_id) : UI_Settings?.[pref_id] ? UI_Settings[pref_id].toString() : '' ); break; //
default: // if query_string has key/value pair, use it, else use key/value pair from UI_Settings
value = ( search_params.has(pref_id) ? search_params.get(pref_id) : UI_Settings?.[pref_id] ? UI_Settings[pref_id].toString() : pref_id ).toString();
value = ( value.replace('%2F','').replace('/','') ?? '' ); // some servers add a '/' to end of query string
} return value;
}
function getNewUIPref(key) {
let value, bool_prefs = Object.keys(UI_Prefs_Bool);
let non_bool_prefs = {
'sort_direction_ascending': {'sort_direction':'descending'}, 'sort_direction_descending': {'sort_direction':'ascending'}, 'sort_by_name': {'sort_by':'name'},
'sort_by_default': {'sort_by':'default'}, 'sort_by_duration': {'sort_by':'duration'}, 'sort_by_size': {'sort_by':'size'},
'sort_by_date': {'sort_by':'date'}, 'sort_by_kind': {'sort_by':'kind'}, 'sort_by_ext': {'sort_by':'ext'},
'texteditor_view': {'texteditor_view':getCurrentUIPref('texteditor_view')},
'texteditor_view_raw': {'texteditor_view':'raw'}, 'texteditor_view_styled': {'texteditor_view':'styled'}, 'texteditor_view_html': {'texteditor_view':'html'},
'theme': {'theme':(getCurrentUIPref('theme') === 'light' ? 'dark' : 'light') },
'theme_dark': {'theme':'dark'}, 'theme_light': {'theme':'light'},
'ui_font': {'ui_font':getCurrentUIPref('ui_font')},'ui_scale': {'ui_scale':getCurrentUIPref('ui_scale')}
}
switch(true) {
case bool_prefs.includes(key): return ( getCurrentUIPref(key) === 'true' ? [key,'false'] : [key,'true']); // toggle bool prefs
default: value = Object.values( non_bool_prefs[key] ).toString(); key = Object.keys(non_bool_prefs[key]).toString(); return [key,value]; // get value for key; then key (i.e., don't redefine key before getting value)
}
}
let str = ''; // global str var;
function timeoutID() { return window.setTimeout( () => { str = ''; }, 1000 ); } // ===> TIMEOUT ID: reset typed string to '' after 1.5 sec.
//==============================//
function getEl(sel) { try { return document.querySelector(sel); } catch (error) { return null; } }
function getEls(sel) { try { return document.querySelectorAll(sel); } catch (error) { return null; } }
function elExists(sel) { return ( document.querySelector(sel) !== null ? true : false ); }
function fileNotFound(e,id) {
if ( e.type === 'error') { if (id === 'content_audio') { addClass('#content_pane','has_audio_error'); setContentTitle('has_audio_error'); } else { addClass('#content_pane','content_error'); closeContent(); setContentTitle('error'); } }
}
function getVisibleElsBySelector(sel) { // ===> GET VISIBLE ELS BY SELECTOR // remove els with display:none or 0 width/height
let els = Array.from( getEls(sel) ).filter( (el) => { let el_styles = window.getComputedStyle(el); return ( el_styles.getPropertyValue('display') !== 'none' || ( el.offsetWidth > 0 || el.offsetHeight > 0 ) ); });
return els;
}
function getContentPaneData() { return getAttr('#content_pane','data-content'); } // ===> GET CONTENT_PANE DATA content
function hasContent(args) { // ===> HAS CONTENT?
switch(true) {
case args === undefined: return ( hasClass('#content_pane','has_audio') || getContentPaneData() !== 'has_null' ? true : false ); // has any content
case args.includes('audio'): return ( hasClass('#content_pane','has_audio') && (args.includes('ignore') || getContentPaneData() === 'has_null') ? true : false ); // has audio only or ignore other content
case args.includes('_'): return hasClass('#content_pane','has_'+args);
default: return ( args.split(',').includes( getContentPaneData()?.split('_')[1] ) ? true : false ); // has named content (e.g., pdf, iframe)
}
}
function initContentError(id,content_el_id) { if ( id !== 'close' ) { getEl(content_el_id).addEventListener('error',(e) => { fileNotFound(e,content_el_id); }); } } // ===> INIT CONTENT ERROR
//==============================//
function getClassNames(sel) { return getEl(sel)?.className; }
function hasClass(sel,classname) { let el = getEl(sel); return el?.classList.contains(classname); } // ===> HAS CLASS
function addClass(sel,classname) { let els = Array.from(getEls(sel)), classes = classname.split(' ').filter(item => item); els?.forEach( el => el.classList.add(...classes) ); } // ===> ADD CLASS
function removeClass(sel,classname) { // ===> REMOVE CLASS
let els = Array.from(getEls(sel)), classes = ( classname?.split(' ')?.filter(item => item) || null );
if ( classname === undefined || classes === null ) { els?.forEach( el => el.removeAttribute('class') ); } else { els?.forEach( el => el.classList.remove(...classes) ); } // if no className, remove all classes
}
function addRemoveClassSiblings(sel,classname) { // ===> ADD/REMOVE CLASS SIBLINGS
let el = document.querySelector(sel), siblings = el?.parentElement.children;
if ( el !== null ) { Array.from(siblings).forEach( sibling => sibling.classList.remove(...classname.replace(/\s{2,}/g,' ').split(' ') ) ); addClass(sel,classname); } // remove class from els & add class to selected el
}
//==============================//
function getAttr(sel,attributeName) { return getEl(sel)?.getAttribute(attributeName); } // ===> GET ATTRIBUTE
function hasAttr(sel,attributeName) { return getEl(sel)?.hasAttribute(attributeName); } // ===> HAS ATTRIBUTE
function setAttr(sel,attributeName,value) { getEl(sel)?.setAttribute(attributeName,value); } // ===> SET ATTRIBUTE
function removeAttr(sel,attributeNamesArr) { // ===> REMOVE ATTRIBUTE
if ( typeof attributeNamesArr === 'string' ) { attributeNamesArr = [attributeNamesArr]; }
let els = getEls(sel); Array.from(els)?.forEach( el => attributeNamesArr.forEach( attributeName => el.removeAttribute(attributeName) ) );
}
function getData(sel,keyname) { let el = ( typeof sel === 'string' ? getEl(sel) : sel ); return el?.getAttribute('data-'+keyname); } // ===> GET DATASET
function setData(sel,keyname,value) { if ( elExists(sel) ) { setAttr(sel,'data-'+keyname, value); } } // ===> SET DATASET
function deleteData(sel,keyname) { removeAttr(sel,'data-'+keyname); } // ===> REMOVE DATASET
function setStyle(sel,property,value) { getEl(sel)?.style.setProperty(property,value); } // ===> SET STYLE
function setValue(sel,value) { getEl(sel).value = value; } // ===> SET VALUE
//==============================//
function clickThis(sel) { let el = getEl(sel); ( el?.querySelector('a')?.click() || el?.click() ) } // ===> CLICK THIS by CSS selector
// function dblclick(el,func) { var evt = new MouseEvent('dblclick'); el.addEventListener(evt,func); el.dispatchEvent(evt); } // ===> DOUBLE CLICK
function altKey(e) { return ( !e.metaKey && !e.ctrlKey && e.altKey && !e.shiftKey ); } // ===> ALT KEY test
function altShiftKey(e) { return ( !e.metaKey && !e.ctrlKey && e.altKey && e.shiftKey ); } // ===> ALT SHIFT KEY test
function cmdKey(e) { return ( (e.metaKey || e.ctrlKey) && !e.altKey && !e.shiftKey ); } // ===> CMD/CTRL KEY test
function cmdAltKey(e) { return ( (e.metaKey || e.ctrlKey) && e.altKey && !e.shiftKey ); } // ===> CMD/CTRL ALT KEY test
function cmdShiftKey(e) { return ( (e.metaKey || e.ctrlKey) && !e.altKey && e.shiftKey ); } // ===> CMD/CTRL SHIFT KEY test
// function cmdAltShiftKey(e) { return ( (e.metaKey || e.ctrlKey) && e.altKey && e.shiftKey; } // ===> CMD/CTRL ALT SHIFT KEY test (not used)
function eStopPrevent(e) { e?.preventDefault(); e?.stopPropagation(); }
//============================//
// ***** BASIC UI FUNCTIONS ***** //
function isInViewport(sel) { const rect = ( getEl(sel) !== null ? getEl(sel).getBoundingClientRect() : null ); if ( rect === null ) { return false; }
return ( rect.top >= getEl('#sidebar_header').offsetHeight && rect.bottom <= (window.innerHeight - getEl('#sidebar_footer').offsetHeight || document.documentElement.clientHeight - getEl('#sidebar_footer').offsetHeight) );
}
function scrollThis(container_ID,sel,bool) { // ===> SCROLL to Selected Item
let container = getEl(container_ID);
if ( container?.height === 0 || isInViewport(sel) ) { return; } // don't scroll hidden elements
let scroll_el = container?.querySelector(sel), scroll_behavior = ( ( bool !== undefined || bool === true ) ? 'instant' : 'smooth' ), scroll_block = ( hasClass('body','is_gecko') ? 'start' : 'center' );
scroll_el?.scrollIntoView({ behavior:scroll_behavior, block:scroll_block, inline:'nearest' });
}
function mouseMove(e,sel,startX,startY,elOffsetLeft,elOffsetTop) { // ===> Init events to allow glyphs to be dragged into view
let scale_factor = ( sel === '#font_specimen_glyph' ? 2 : 1 ); // scale_factor needed for svg glyphs
setStyle(sel,'left',elOffsetLeft + (e.pageX - startX)*scale_factor + 'px'); setStyle(sel,'top',elOffsetTop + (e.pageY - startY)*scale_factor +'px');
}
//==============================// OPEN/SAVE FILES
function openFile(args) { menuClose(); // ===> OPEN FILE; type: font or playlist.
if ( window.File && window.FileReader && window.FileList && window.Blob ) { // if browser supports file API...
let files = args[0].target.files[0], id = args[1], reader = new FileReader();
switch(id) { case 'open_font': reader.readAsArrayBuffer(files); break; case 'open_playlist': reader.readAsText(files); break; } // get the file reader
reader.onload = () => { // on file reader load
switch(true) {
case id === 'open_font': openFontFile(files,reader); break;
case id === 'open_playlist': openPlaylist(files.name,'',reader.result); break;
} // open the file
return true;
}
getEl('#'+id).value = ''; // reset input to allow same item to be reopened immediately after closing
} else { alert('Can\'t open file: file APIs are not fully supported in this browser.'); } // else error
}
function saveFile(content,mimetype,file_name) { // ===> SAVE FILE
let blob = new Blob([content], {type: mimetype});
let download_el = window.document.createElement('a'); download_el.style = "display:none"; download_el.href = window.URL.createObjectURL(blob); download_el.download = file_name; // define & style download_el
document.body.appendChild(download_el); download_el.click(); document.body.removeChild(download_el); URL.revokeObjectURL(blob); // add download_el, click, & remove
}
// END UTILITIES
//==============================//
// ***** SET UP UI ELEMENTS ***** //
function updateParentLinkSearchParams(str) { //*** decrement selected and history values ***// // ===> UPDATE PARENT LINK SEARCH PARAMS
let query_str = new URLSearchParams(str); query_str.sort(); // make new search params from window.location.search
let history = ( query_str.has('history') ? query_str.get('history') : undefined );
switch(true) {
case history !== undefined:
history = history.split(' ');
switch(true) {
case history.length > 1: query_str.set('selected',history[0]); history.shift(); query_str.set('history',history.join('+')); break;
case history.length === 1: query_str.set('selected',history[0]); history.shift(); query_str.delete('history'); break;
}
break;
default: query_str.delete('selected');
}
return decodeURIComponentSafe(query_str.toString());
}
function createParentLinks() { // ===> CREATE PARENT LINKS
let link, links = [], search_params = searchParamsGet(); search_params.sort();
let query_str = search_params.toString();
let link_pieces = window_location.split('/'); link_pieces = link_pieces.slice(2,-2); // make array of parent directories; remove beginning and ending empty elements and current directory
while ( link_pieces.length > 0 ) { // while there are link pieces...
query_str = updateParentLinkSearchParams(query_str); // update selected and history
link = window_protocol +'//'+ link_pieces.join('/') + '/?' + query_str; links.push(link); link_pieces.pop(); // assemble link; add to link array; remove last link piece and repeat...
}
return links;
}
function createParentLinkItems() { // ===> CREATE PARENT LINK ITEMS
let parent_link_menu_items = [], links = createParentLinks();
for ( let i = 0; i < links.length; i++ ) {
let display_name = links[i].split('/?')[0]; display_name = display_name.replace(/\//g,'\/<wbr>');
let menu_item = `<li><a id="parents_link_${i}" href="${ links[i] }" class="display_block padding_4_8">${ display_name }/</a></li>`;
parent_link_menu_items.push(menu_item);
}
let parent_link = ( links[0] === undefined ? window.location.href : links[0]); parent_link = parent_link.replace(/parents_link_/,'parent_link_');
return [parent_link_menu_items.join(''),parent_link]; // return parents link items
}
function updateParentLinks() { // ===> UPDATE PARENT LINKS and init new item events
let links = createParentLinkItems(); getEl('#parents_links').innerHTML = links[0]; getEl('#parent_dir_nav a').href = links[1]; // add the links
getEls('#sidebar_menu_parent a,#parents_links a').forEach( el => el.onclick = function(e) { eStopPrevent(e); showWarning('changeLocation',[this.href,'false']); }); // reinit onclick
}
//==============================//
// SVG UI ICONS
const SVG_UI_Icons = {
'arrow': '<svg class="icon_arrow invert" viewBox=\'0 0 20 20\' xmlns=\'http://www.w3.org/2000/svg\' class=\'invert\'><path fill=\'%23888\' fill-opacity=\'.75\' d=\'m4 4 12 6-12 6z\'/></svg>',
'bookmark': '<svg viewBox=\'0 0 20 20\' xmlns=\'http://www.w3.org/2000/svg\' class=\'invert\'><path fill=\'%23888\' d=\'m2 2c0-1.1.9-2 2-2h12a2 2 0 0 1 2 2v18l-8-4-8 4zm2 0v15l6-3 6 3v-15z\'/></svg>',
'check_mark': '<svg viewBox=\'0 0 12 9\' xmlns=\'http://www.w3.org/2000/svg\'><path fill=\'currentColor\' d=\'m-.071 10.929 2.571-2.571 4.5 4.499 10.285-10.285 2.571 2.572-12.856 12.856z\' transform=\'matrix(.55 0 0 .55 .578932 -1.01245)\'/></svg>',
'chevron': '<svg viewBox=\'0 0 24 14\' id=\'svg_chevron\' xmlns=\'http://www.w3.org/2000/svg\'><path d=\'m0 0v14h3v-11h11v-3z\' transform=\'matrix(.707107 .707107 -.707107 .707107 11.8995 1)\'/></svg>',
'document': '<svg viewBox=\'0 0 20 20\' xmlns=\'http://www.w3.org/2000/svg\'><path fill=\'%23222222\' d=\'M4 18h12V6h-4V2H4v16zm-2 1V0h12l4 4v16H2v-1z\' /></svg>',
'error': '<svg viewBox=\'0 0 20 20\' xmlns=\'http://www.w3.org/2000/svg\'><g fill-opacity=\'.75\'><path d=\'m1.075 18.05 8.146-16.683c.236-.484.924-.491 1.169-.011l8.537 16.683c.223.435-.093.952-.582.952h-16.683c-.483 0-.799-.507-.587-.941z\' fill=\'%23ffb636\' /><path d=\'m11.055 7.131-.447 6.003c-.034.45-.425.787-.874.753-.408-.03-.724-.356-.753-.753l-.447-6.003c-.052-.696.47-1.302 1.167-1.354.696-.052 1.302.47 1.354 1.166.005.061.004.129 0 .188zm-1.26 8.037c-.641 0-1.159.518-1.159 1.158 0 .641.518 1.159 1.159 1.159.64 0 1.158-.518 1.158-1.159 0-.64-.518-1.158-1.158-1.158z\'/></g></svg>',
'external_link': '<svg viewBox=\'0 0 14 14\' xmlns=\'http://www.w3.org/2000/svg\'><path d=\'M10.443,2.5l-3.439,-0l0,-1.5l5.996,0l0,6.02l-1.5,0l0,-3.455l-5.716,5.715l-1.06,-1.06l5.719,-5.72Zm1.057,5.5l-0,5l-10.5,0l-0,-10.5l5,0l-0,1.5l-3.5,0l-0,7.5l7.5,0l-0,-3.5l1.5,0Z\' style=\'fill:%23888;\'/></svg>',
'folder': '<svg viewBox=\'0 0 20 20\'><path fill=\'%23222\' d=\'m0 4c0-1.1.9-2 2-2h7l2 2h7a2 2 0 0 1 2 2v10a2 2 0 0 1 -2 2h-16a2 2 0 0 1 -2-2zm2 2v10h16v-10z\'/></svg>',
'grid': '<svg viewBox=\'0 0 20 20\'><path fill=\'currentColor\' d=\'M0 0h9v9H0V0zm2 2v5h5V2H2zm-2 9h9v9H0v-9zm2 2v5h5v-5H2zm9-13h9v9h-9V0zm2 2v5h5V2h-5zm-2 9h9v9h-9v-9zm2 2v5h5v-5h-5z\' /></svg>',
'menu': '<svg viewBox=\'0 0 13 10\'><g fill=\'%23222\'><path d=\'m0 0h13v2h-13z\'/><path d=\'m0 4h13v2h-13z\'/><path d=\'m0 8h13v2h-13z\'/></g></svg>',
'minus': '<svg viewBox=\'0 0 20 20\'><path fill=\'%23222\' d=\'m1 8h18v4h-18z\'/></svg>',
'multiply': '<svg viewBox=\'0 0 20 20\' id=\'svg_multiply\'><path fill=\'%23222\' d=\'m10 7 6-6 3 3-6 6 6 6-3 3-6-6-6 6-3-3 6-6-6-6 3-3z\'/></svg>',
'music': '<svg width=\'100%\' height=\'100%\' viewBox=\'0 0 84 84\' version=\'1.1\' xmlns=\'http://www.w3.org/2000/svg\' xml:space=\'preserve\' style=\'fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2;\'><path d=\'M66.613,58.258c-0,3.775 -1.721,6.934 -5.163,9.475c-3.154,2.309 -6.683,3.463 -10.588,3.463c-2.283,-0 -4.158,-0.538 -5.616,-1.617c-1.621,-1.229 -2.429,-2.95 -2.429,-5.158c-0,-3.492 1.658,-6.558 4.966,-9.204c3.134,-2.488 6.496,-3.734 10.088,-3.734c3.029,0 5.237,0.605 6.625,1.809l-0,-39.538l-28.146,7.584l-0,44.891c-0,3.775 -1.721,6.929 -5.158,9.471c-3.159,2.313 -6.688,3.467 -10.588,3.467c-2.287,-0 -4.158,-0.542 -5.625,-1.617c-1.617,-1.233 -2.425,-2.954 -2.425,-5.158c0,-3.492 1.658,-6.559 4.967,-9.204c3.133,-2.488 6.496,-3.734 10.087,-3.734c3.029,0 5.238,0.604 6.621,1.809l0,-48.355l32.383,-8.741l0.001,54.091Z\' style=\'fill:%23888;fill-opacity:0.4;fill-rule:nonzero;\'/></svg>',
'plus': '<svg viewBox=\'0 0 20 20\'><path fill=\'%23222\' d=\'m8.001 1h3.999v7h7v4h-7l-.001 7h-3.999v-7h-7v-4h7z\'/></svg>',
'prev_next_track': '<svg viewBox=\'0 0 20 20\'><path fill=\'%23222\' d=\'m13 5h2v10h-2zm-8 0 8 5-8 5z\'/></svg>',
'spinner': '<svg viewBox=\'0 0 100 100\' class=\'display_none invert\' preserveAspectRatio=\'xMidYMid\' width=\'32\' height=\'32\' xmlns=\'http://www.w3.org/2000/svg\' id=\'loading_spinner\'><animateTransform attributeName=\'transform\' type=\'rotate\' values=\'0;45\' keyTimes=\'0;1\' dur=\'0.25s\' repeatCount=\'indefinite\'/><path fill=\'%23000\' fill-opacity=\'.66\' d=\'m29.49-5.5h8v11h-8a30 30 0 0 1 -4.75 11.46l5.66 5.66-7.78 7.78-5.66-5.66a30 30 0 0 1 -11.46 4.75v8h-11v-8a30 30 0 0 1 -11.46-4.75l-5.66 5.66-7.78-7.78 5.66-5.66a30 30 0 0 1 -4.75-11.46h-8v-11h8a30 30 0 0 1 4.75-11.46l-5.66-5.66 7.78-7.78 5.66 5.66a30 30 0 0 1 11.46-4.75v-8h11v8a30 30 0 0 1 11.46 4.75l5.66-5.66 7.78 7.78-5.66 5.66a30 30 0 0 1 4.75 11.46m-29.49-14.5a20 20 0 1 0 0 40 20 20 0 1 0 0-40\' transform=\'matrix(.7189408 .69507131 -.69507131 .7189408 50 50)\'/></svg>',
'toggle': '<svg viewBox=\'0 0 20 20\'><g fill=\'%23222\'><path d=\'m10.207 9.293-.707.707 5.657 5.657 1.414-1.414-4.242-4.243 4.242-4.243-1.414-1.414z\'/><path d=\'m4.207 9.293-.707.707 5.657 5.657 1.414-1.414-4.242-4.243 4.242-4.243-1.414-1.414z\'/></g></svg>',
'ui_layout': '<svg width=\'100px\' height=\'100%\' viewBox=\'0 0 50 39\' version=\'1.1\' xmlns=\'http://www.w3.org/2000/svg\' xmlns:xlink=\'http://www.w3.org/1999/xlink\' xml:space=\'preserve\' xmlns:serif=\'http://www.serif.com/\' style=\'fill-rule:evenodd;clip-rule:evenodd;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:1.5;\'><rect x=\'0.5\' y=\'0.5\' width=\'14.5\' height=\'38\' style=\'fill:rgb(204,204,204);\'/><path d=\'M50,0L50,39L0,39L0,0L50,0ZM49,1L1,1L1,38L49,38L49,1Z\'/><path d=\'M15,0.5L15,38.5\' style=\'fill:none;stroke:black;stroke-width:1px;\'/><g transform=\'matrix(1,0,0,1,0,1.5)\'><path d=\'M0.5,5L15,5\' style=\'fill:none;stroke:black;stroke-width:1px;\'/></g><g transform=\'matrix(1,0,0,1,15.0936,-0.5)\'><path d=\'M0,5L34.406,5\' style=\'fill:none;stroke:black;stroke-width:1px;\'/></g><g><g transform=\'matrix(1,0,0,1,0,1.5)\'><path d=\'M2.5,7L3,7\' style=\'fill:none;stroke:black;stroke-width:1px;\'/></g><g transform=\'matrix(1,0,0,1,0,1.5)\'><path d=\'M2.5,7L3,7\' style=\'fill:none;stroke:black;stroke-width:1px;\'/></g><g transform=\'matrix(1,0,0,1,0,3.5)\'><path d=\'M2.5,7L3,7\' style=\'fill:none;stroke:black;stroke-width:1px;\'/></g><g transform=\'matrix(1,0,0,1,0,5.5)\'><path d=\'M2.5,7L3,7\' style=\'fill:none;stroke:black;stroke-width:1px;\'/></g><g transform=\'matrix(1,0,0,1,0,7.5)\'><path d=\'M2.5,7L3,7\' style=\'fill:none;stroke:black;stroke-width:1px;\'/></g><g transform=\'matrix(1,0,0,1,0,9.5)\'><path d=\'M2.5,7L3,7\' style=\'fill:none;stroke:black;stroke-width:1px;\'/></g><g transform=\'matrix(1,0,0,1,0,11.5)\'><path d=\'M2.5,7L3,7\' style=\'fill:none;stroke:black;stroke-width:1px;\'/></g><g transform=\'matrix(1,0,0,1,0,13.5)\'><path d=\'M2.5,7L3,7\' style=\'fill:none;stroke:black;stroke-width:1px;\'/></g><g transform=\'matrix(1,0,0,1,0,15.5)\'><path d=\'M2.5,7L3,7\' style=\'fill:none;stroke:black;stroke-width:1px;\'/></g><g transform=\'matrix(1,0,0,1,0,17.5)\'><path d=\'M2.5,7L3,7\' style=\'fill:none;stroke:black;stroke-width:1px;\'/></g><g transform=\'matrix(1,0,0,1,0,19.5)\'><path d=\'M2.5,7L3,7\' style=\'fill:none;stroke:black;stroke-width:1px;\'/></g><g transform=\'matrix(1,0,0,1,0,21.5)\'><path d=\'M2.5,7L3,7\' style=\'fill:none;stroke:black;stroke-width:1px;\'/></g><g transform=\'matrix(1,0,0,1,0,23.5)\'><path d=\'M2.5,7L3,7\' style=\'fill:none;stroke:black;stroke-width:1px;\'/></g><g transform=\'matrix(1,0,0,1,0,25.5)\'><path d=\'M2.5,7L3,7\' style=\'fill:none;stroke:black;stroke-width:1px;\'/></g><g transform=\'matrix(1,0,0,1,0,27.5)\'><path d=\'M2.5,7L3,7\' style=\'fill:none;stroke:black;stroke-width:1px;\'/></g><path d=\'M0.5,36.5L15,36.5\' style=\'fill:none;stroke:black;stroke-width:1px;\'/><g transform=\'matrix(1,0,0,1,0,1.5)\'><path d=\'M5,7L13,7\' style=\'fill:none;stroke:black;stroke-width:1px;\'/></g><g transform=\'matrix(1,0,0,1,0,3.5)\'><path d=\'M5,7L13,7\' style=\'fill:none;stroke:black;stroke-width:1px;\'/></g><g transform=\'matrix(1,0,0,1,0,5.5)\'><path d=\'M5,7L13,7\' style=\'fill:none;stroke:black;stroke-width:1px;\'/></g><g transform=\'matrix(1,0,0,1,0,7.5)\'><path d=\'M5,7L13,7\' style=\'fill:none;stroke:black;stroke-width:1px;\'/></g><g transform=\'matrix(1,0,0,1,0,9.5)\'><path d=\'M5,7L13,7\' style=\'fill:none;stroke:black;stroke-width:1px;\'/></g><g transform=\'matrix(1,0,0,1,0,11.5)\'><path d=\'M5,7L13,7\' style=\'fill:none;stroke:black;stroke-width:1px;\'/></g><g transform=\'matrix(1,0,0,1,0,13.5)\'><path d=\'M5,7L13,7\' style=\'fill:none;stroke:black;stroke-width:1px;\'/></g><g transform=\'matrix(1,0,0,1,0,15.5)\'><path d=\'M5,7L13,7\' style=\'fill:none;stroke:black;stroke-width:1px;\'/></g><g transform=\'matrix(1,0,0,1,0,17.5)\'><path d=\'M5,7L13,7\' style=\'fill:none;stroke:black;stroke-width:1px;\'/></g><g transform=\'matrix(1,0,0,1,0,19.5)\'><path d=\'M5,7L13,7\' style=\'fill:none;stroke:black;stroke-width:1px;\'/></g><g transform=\'matrix(1,0,0,1,0,21.5)\'><path d=\'M5,7L13,7\' style=\'fill:none;stroke:black;stroke-width:1px;\'/></g><g transform=\'matrix(1,0,0,1,0,23.5)\'><path d=\'M5,7L13,7\' style=\'fill:none;stroke:black;stroke-width:1px;\'/></g><g transform=\'matrix(1,0,0,1,0,25.5)\'><path d=\'M5,7L13,7\' style=\'fill:none;stroke:black;stroke-width:1px;\'/></g><g transform=\'matrix(1,0,0,1,0,27.5)\'><path d=\'M5,7L13,7\' style=\'fill:none;stroke:black;stroke-width:1px;\'/></g></g><g class=\'invert\'><g transform=\'matrix(1.42857,0,0,1.42857,22.5,10.5)\'><path d=\'M0.369,9.141C0.117,8.463 0,7.745 0,7C0,3.137 3.137,0 7,0C10.863,0 14,3.137 14,7L13.863,8.353L10.01,4.5L6.51,8L4.01,5.5L0.369,9.141Z\' style=\'fill:rgb(128,128,255);fill-rule:nonzero;\'/></g><g transform=\'matrix(1.42857,0,0,1.42857,22.5,10.5)\'><path d=\'M0.839,10.151L0.369,9.141L4.01,5.5L6.51,8L10.01,4.5L13.863,8.353C13.787,8.748 13.662,9.131 13.522,9.5L3.151,12.845C2.858,12.651 2.572,12.429 2.313,12.194L0.839,10.151Z\' style=\'fill:white;fill-rule:nonzero;\'/></g><g transform=\'matrix(1.42857,0,0,1.42857,22.5,10.5)\'><path d=\'M13.522,9.5C12.532,12.14 9.983,14 7,14C5.574,14 4.247,13.579 3.151,12.845L10.01,5.979L13.522,9.5Z\' style=\'fill:rgb(51,51,204);fill-rule:nonzero;\'/></g><g transform=\'matrix(1.42857,0,0,1.42857,22.5,10.5)\'><path d=\'M0.839,10.151L4.01,6.979L5.771,8.74L2.312,12.194C1.721,11.562 1.233,10.881 0.839,10.151Z\' style=\'fill:rgb(51,51,204);fill-rule:nonzero;\'/></g><g transform=\'matrix(1.42857,0,0,1.42857,22.5,10.5)\'><circle cx=\'6\' cy=\'3.5\' r=\'1.5\' style=\'fill:white;\'/></g></g></svg>'
};
function get_SVG_UI_Icon(icon_name) { return `url("data:image/svg+xml;utf8,${ SVG_UI_Icons[icon_name] }")`; }
const SVG_UI_File_Icons = { // n.b.: order is important
'file_icon_dir': '<svg viewBox=\'0 0 14 14\' xmlns=\'http://www.w3.org/2000/svg\'><path d=\'m6 2.5-1-1.5h-5v12h14v-10.5z\' fill=\'%2339f\'/><path d=\'m1.5 4h11v7.5h-11z\' fill=\'%239cf\'/></svg>',
'file_icon_dir_open': '<svg viewBox=\'0 0 14 14\' clip-rule=\'evenodd\' fill-rule=\'evenodd\' xmlns=\'http://www.w3.org/2000/svg\'><path d=\'m6.1 2.7-1.3-1.7h-4.8v12h14v-10.3z\' fill=\'%2339f\' fill-rule=\'nonzero\'/><path d=\'m7 6h5.5v5.5h-11z\' fill=\'%239cf\'/></svg>',
'file_icon_file': '<svg viewBox=\'0 0 14 14\' xmlns=\'http://www.w3.org/2000/svg\'><path d=\'m8.3 0h-6.8v14h11v-9.8l-4.2-4.2z\' fill=\'%23888\'/><g fill=\'%23fff\'><path d=\'m11 12.5h-8v-11h3.8v4.2h4.2z\'/><path d=\'m8.3 4.2h1.9l-1.9-2z\'/></g></svg>',
'file_icon_invisible': '<svg viewBox=\'0 0 14 14\' xmlns=\'http://www.w3.org/2000/svg\'><path d=\'m8.3 0h-6.8v14h11v-9.8l-4.2-4.2z\' fill=\'%23888\'/><path d=\'m11 12.5h-8v-11h3.8v4.2h4.2z\' fill=\'%23bbb\'/><path d=\'m8.3 4.2h1.9l-1.9-2z\' fill=\'%23bbb\'/><circle cx=\'7\' cy=\'9\' fill=\'%23878787\' r=\'1.5\'/></svg>',
'file_icon_ignored': '<svg viewBox=\'0 0 14 14\' xmlns=\'http://www.w3.org/2000/svg\'><path d=\'M 10.695,1.774 1.856,10.613 3.482,12.239 12.321,3.4 Z M 7,2 c 2.8,0 5,2.2 5,5 0,2.8 -2.2,5 -5,5 C 4.2,12 2,9.8 2,7 2,4.2 4.2,2 7,2 M 7,0 C 3.1,0 0,3.1 0,7 c 0,3.9 3.1,7 7,7 3.9,0 7,-3.1 7,-7 C 14,3.1 10.9,0 7,0 Z\' style=\'fill:%23888888;fill-opacity:1\' /></svg>',
'file_icon_dirinvisible': '<svg viewBox=\'0 0 14 14\' xmlns=\'http://www.w3.org/2000/svg\'><path d=\'m6 2.5-1-1.5h-5v12h14v-10.5z\' fill=\'%23888\'/><path d=\'m1.5 4h11v7.5h-11z\' fill=\'%23bbb\'/><circle cx=\'7\' cy=\'7.5\' fill=\'%23888\' r=\'1.5\'/></svg>',
'file_icon_alias': '<svg viewBox=\'0 0 14 14\' xmlns=\'http://www.w3.org/2000/svg\'><path d=\'m0 0h14v14h-14z\' fill=\'%23808080\'/><path d=\'m3 12.5c0-3.863 2.253-7.5 6.259-7.5\' fill=\'none\' stroke=\'%23fc6\' stroke-width=\'3\'/><path d=\'m13 5-4-4v8z\' fill=\'%23fc6\'/></svg>',
'file_icon_archive': '<svg viewBox=\'0 0 14 14\' xmlns=\'http://www.w3.org/2000/svg\'><path d=\'m11 8.5v-1h2v2l-5 1h-2v1.5h4v1h-4v1h-3v-1h-2v-1h2v-1.5h-2v-2h2v-6.5h-2v-2h7l5 1v2h-2v-1h-5v6.5z\' fill=\'%23666\'/></svg>',
'file_icon_app': '<svg viewBox=\'0 0 14 14\' xmlns=\'http://www.w3.org/2000/svg\'><path d=\'m6.125 0-.292 1.859c-.587.135-1.146.38-1.64.693v-.018l-1.532-1.094-1.221 1.221 1.094 1.532h.018c-.313.495-.559 1.051-.693 1.64l-1.859.292v1.75l1.859.292c.134.589.38 1.145.693 1.64h-.018l-1.094 1.532 1.221 1.221 1.532-1.094v-.018c.494.313 1.053.558 1.64.693l.292 1.859h1.75l.292-1.859c.596-.137 1.14-.372 1.64-.693l1.532 1.112 1.221-1.221-1.112-1.532c.309-.492.523-1.057.656-1.64l1.896-.292v-1.75l-1.896-.292c-.133-.583-.347-1.148-.656-1.64h.018l1.094-1.532-1.221-1.221-1.532 1.094v.018c-.5-.321-1.044-.556-1.64-.693l-.292-1.859h-1.75zm.875 4.667c1.288 0 2.333 1.036 2.333 2.333s-1.045 2.333-2.333 2.333-2.333-1.036-2.333-2.333 1.045-2.333 2.333-2.333z\' fill=\'%237a7ab8\'/></svg>',
'file_icon_audio': '<svg viewBox=\'0 0 14 14\' xmlns=\'http://www.w3.org/2000/svg\'><circle cx=\'7\' cy=\'7\' fill=\'%230f8a8a\' r=\'7\'/><g fill=\'%23fff\'><path d=\'m11 9.5c-.019.681-.796 1.339-1.75 1.475-.966.138-1.75-.31-1.75-1s.784-1.362 1.75-1.5c.268-.038.523-.031.75.013v-4.488h-4v6.5c-.019.681-.796 1.339-1.75 1.475-.966.138-1.75-.31-1.75-1s.784-1.362 1.75-1.5c.268-.038.523-.031.75.013v-6.488l6-1z\'/><path d=\'m11 2-6 1v2l6-1z\'/></g></svg>',
'file_icon_code': '<svg viewBox=\'0 0 14 14\' xmlns=\'http://www.w3.org/2000/svg\'><path d=\'m14 0h-14v14h14z\' fill=\'%2372d\'/><g fill=\'%23fff\'><path d=\'m5.923 12.965c-1.049 0-1.784-.161-2.209-.48-.425-.317-.638-.82-.638-1.503v-2.067c0-.446-.146-.764-.438-.95-.292-.188-.709-.281-1.256-.281v-1.368c.547 0 .967-.094 1.259-.28s.438-.5.438-.938v-2.092c0-.675.217-1.172.65-1.491.432-.32 1.164-.479 2.195-.479v1.312c-.401.01-.718.09-.952.24-.233.15-.348.426-.348.827v1.985c0 .876-.511 1.396-1.532 1.559v.083c1.021.154 1.532.67 1.532 1.544v1.997c0 .41.116.688.349.835.233.146.55.223.951.232z\'/><path d=\'m8.076 12.965v-1.313c.392-.009.706-.089.944-.239.236-.15.355-.426.355-.829v-1.996c0-.867.511-1.382 1.531-1.545v-.084c-1.02-.164-1.53-.679-1.53-1.546v-1.997c0-.41-.116-.688-.349-.834-.232-.146-.549-.224-.951-.233v-1.313c1.049 0 1.785.159 2.21.479.423.319.637.821.637 1.505v2.065c0 .447.146.765.438.951.292.187.711.28 1.257.28v1.367c-.546.012-.967.107-1.259.287-.293.183-.438.5-.438.945v2.08c0 .674-.217 1.172-.65 1.491-.432.319-1.165.479-2.195.479z\'/></g></svg>',
'file_icon_database': '<svg viewBox=\'0 0 14 14\' xmlns=\'http://www.w3.org/2000/svg\'><path d=\'m14 2.5v9c0 1.38-3.137 2.5-7 2.5s-7-1.12-7-2.5v-9\' fill=\'%23808080\'/><path d=\'m13 2.5v9c0 .828-2.689 1.5-6 1.5s-6-.672-6-1.5v-9\' fill=\'%23b4b4b4\'/><path d=\'m14 8.5c0 1.38-3.137 2.5-7 2.5s-7-1.12-7-2.5\' fill=\'%23808080\'/><path d=\'m13 8.5c0 .828-2.689 1.5-6 1.5s-6-.672-6-1.5\' fill=\'%23b4b4b4\'/><path d=\'m14 5.5c0 1.38-3.137 2.5-7 2.5s-7-1.12-7-2.5\' fill=\'%23808080\'/><path d=\'m13 5.5c0 .828-2.689 1.5-6 1.5s-6-.672-6-1.5\' fill=\'%23b4b4b4\'/><ellipse cx=\'7\' cy=\'2.5\' fill=\'%23808080\' rx=\'7\' ry=\'2.5\'/><ellipse cx=\'7\' cy=\'2.5\' fill=\'%23b4b4b4\' rx=\'5.5\' ry=\'1.5\'/></svg>',
'file_icon_ebook': '<svg clip-rule=\'evenodd\' fill-rule=\'evenodd\' stroke-linejoin=\'round\' stroke-miterlimit=\'2\' viewBox=\'0 0 14 14\' xmlns=\'http://www.w3.org/2000/svg\'><path d=\'m2.668-.001c1.705.001 3.492.35 4.332 1.257.84-.908 2.627-1.256 4.332-1.257h2.668v12.541c-.818 0-2.181.005-3 .023-1.184.026-3.008.42-3 1.437l-1-.017-1 .017c.008-1.017-2-1.437-3-1.437-.819 0-2.182-.023-3-.023v-12.541zm-1.168 1.5v9.501h1.286c1.086.025 2.213.081 3.204.568l.01.006v-8.576c0-1.136-1.49-1.398-2.336-1.47-.708-.059-1.438-.029-2.164-.029zm11 0c-.726 0-1.456-.03-2.164.029-.846.072-2.336.334-2.336 1.47v8.576l.01-.006c.991-.487 2.118-.543 3.204-.568h1.286z\' fill=\'%23222\' fill-rule=\'nonzero\'/></svg>',
'file_icon_font': '<svg viewBox=\'0 0 14 14\' xmlns=\'http://www.w3.org/2000/svg\'><path d=\'m14 0h-14v14h14z\' fill=\'%23709\'/><path d=\'m4.678 11.179h1.393v-8.266h-2.616v1.052h-1.455v-2.553h10v2.554h-1.456v-1.053h-2.599v8.266h1.347v1.409h-4.614z\' fill=\'%23fff\'/></svg>',
'file_icon_graphics': '<svg viewBox=\'0 0 14 14\' xmlns=\'http://www.w3.org/2000/svg\'><path d=\'m0 0h14v14h-14z\' fill=\'%23808080\'/><path d=\'m7.774 8.285 4.726 4.715-8-3.525-1.5-4.975h-2v-3.5h3.525l-.025 2 5 1.5 3.5 8-4.7-4.752c.127-.22.2-.476.2-.748 0-.828-.672-1.5-1.5-1.5s-1.5.672-1.5 1.5.672 1.5 1.5 1.5c.283 0 .548-.079.774-.215z\' fill=\'%23ccc\'/></svg>',
'file_icon_htm': '<svg viewBox=\'0 0 14 14\' xmlns=\'http://www.w3.org/2000/svg\'><path d=\'m6.967.5c-3.553.018-6.467 2.947-6.467 6.5 0 3.566 2.934 6.5 6.5 6.5s6.5-2.934 6.5-6.5c0-3.553-2.914-6.482-6.467-6.5zm.033 0v13m6.5-6.5h-13m1.467-4c3.004 2.143 7.062 2.143 10.066 0m0 8c-3.004-2.143-7.062-2.143-10.066 0m4.533-10.333c-1.874 1.582-2.957 3.914-2.957 6.366 0 2.453 1.083 4.785 2.957 6.367m1 0c1.874-1.582 2.957-3.914 2.957-6.367 0-2.452-1.083-4.784-2.957-6.366\' fill=\'%23fff\' stroke=\'%23e44d26\'/></svg>',
'file_icon_ignoredimage': '<svg viewBox=\'0 0 14 14\' xmlns=\'http://www.w3.org/2000/svg\'><path d=\'m.369 9.141c-.252-.678-.369-1.396-.369-2.141 0-3.863 3.137-7 7-7s7 3.137 7 7l-.137 1.353-3.853-3.853-3.5 3.5-2.5-2.5z\' fill=\'%23808080\'/><path d=\'m.839 10.151-.47-1.01 3.641-3.641 2.5 2.5 3.5-3.5 3.853 3.853c-.076.395-.201.778-.341 1.147l-10.371 3.345c-.293-.194-.579-.416-.838-.651z\' fill=\'%23fff\'/><path d=\'m13.522 9.5c-.99 2.64-3.539 4.5-6.522 4.5-1.426 0-2.753-.421-3.849-1.155l6.859-6.866z\' fill=\'%23808080\'/><path d=\'m.839 10.151 3.171-3.172 1.761 1.761-3.459 3.454c-.591-.632-1.079-1.313-1.473-2.043z\' fill=\'%23808080\'/><circle cx=\'6\' cy=\'3.5\' fill=\'%23fff\' r=\'1.5\'/></svg>',
'file_icon_image': '<svg viewBox=\'0 0 14 14\' xmlns=\'http://www.w3.org/2000/svg\'><path d=\'m.369 9.141c-.252-.678-.369-1.396-.369-2.141 0-3.863 3.137-7 7-7s7 3.137 7 7l-.137 1.353-3.853-3.853-3.5 3.5-2.5-2.5z\' fill=\'%238080ff\'/><path d=\'m.839 10.151-.47-1.01 3.641-3.641 2.5 2.5 3.5-3.5 3.853 3.853c-.076.395-.201.778-.341 1.147l-10.371 3.345c-.293-.194-.579-.416-.838-.651z\' fill=\'%23fff\'/><path d=\'m13.522 9.5c-.99 2.64-3.539 4.5-6.522 4.5-1.426 0-2.753-.421-3.849-1.155l6.859-6.866z\' fill=\'%2333c\'/><path d=\'m.839 10.151 3.171-3.172 1.761 1.761-3.459 3.454c-.591-.632-1.079-1.313-1.473-2.043z\' fill=\'%2333c\'/><circle cx=\'6\' cy=\'3.5\' fill=\'%23fff\' r=\'1.5\'/></svg>',
'file_icon_markdown': '<svg viewBox=\'0 0 14 14\' xmlns=\'http://www.w3.org/2000/svg\'><path d=\'m14 0h-14v14h14z\' fill=\'%236a6a95\'/><path d=\'m12 11.5h-2.5v-5.143l-2.5 2.948-2.5-2.948v5.143h-2.5v-9h2.273l2.721 3.377 2.733-3.377h2.273z\' fill=\'%23ddd\'/></svg>',
'file_icon_office': '<svg viewBox=\'0 0 14 14\' xmlns=\'http://www.w3.org/2000/svg\'><path d=\'m0 0h14v14h-14z\' fill=\'%23808080\'/><g fill=\'%23cdcdcd\'><path d=\'m10 1.5h2.5v1h-2.5z\'/><path d=\'m10 4h2.5v1h-2.5z\'/><path d=\'m10 6.5h2.5v1h-2.5z\'/><path d=\'m10 9h2.5v1h-2.5z\'/><path d=\'m10 11.5h2.5v1h-2.5z\'/><path d=\'m6.5 1.5h2.5v1h-2.5z\'/><path d=\'m6.5 4h2.5v1h-2.5z\'/><path d=\'m6.5 6.5h2.5v1h-2.5z\'/><path d=\'m6.5 9h2.5v1h-2.5z\'/><path d=\'m6.5 11.5h2.5v1h-2.5z\'/><path d=\'m1.5 1.5h4v11h-4z\'/></g></svg>',
'file_icon_pdf': '<svg clip-rule=\'evenodd\' fill-rule=\'evenodd\' viewBox=\'0 0 14 14\' xmlns=\'http://www.w3.org/2000/svg\'><path d=\'m0 0h13.999986v13.999986h-13.999986z\' fill=\'%23e0382d\' stroke-width=\'.259259\'/><path d=\'m45 31.2c-2.6-2.7-9.7-1.6-11.4-1.4-2.5-2.4-4.2-5.3-4.8-6.3.9-2.7 1.5-5.4 1.6-8.3 0-2.5-1-5.2-3.8-5.2-1 0-1.9.6-2.4 1.4-1.2 2.1-.7 6.3 1.2 10.6-1.1 3.1-2.1 6.1-4.9 11.4-2.9 1.2-9 4-9.5 7-.2.9.1 1.8.8 2.5.7.6 1.6.9 2.5.9 3.7 0 7.3-5.1 9.8-9.4 2.1-.7 5.4-1.7 8.7-2.3 3.9 3.4 7.3 3.9 9.1 3.9 2.4 0 3.3-1 3.6-1.9.5-1 .2-2.1-.5-2.9zm-2.5 1.7c-.1.7-1 1.4-2.6 1-1.9-.5-3.6-1.4-5.1-2.6 1.3-.2 4.2-.5 6.3-.1.8.2 1.6.7 1.4 1.7zm-16.7-20.6c.2-.3.5-.5.8-.5.9 0 1.1 1.1 1.1 2-.1 2.1-.5 4.2-1.2 6.2-1.5-4-1.2-6.8-.7-7.7zm-.2 19.4c.8-1.6 1.9-4.4 2.3-5.6.9 1.5 2.4 3.3 3.2 4.1 0 .1-3.1.7-5.5 1.5zm-5.9 4c-2.3 3.8-4.7 6.2-6 6.2-.2 0-.4-.1-.6-.2-.3-.2-.4-.5-.3-.9.3-1.4 2.9-3.3 6.9-5.1z\' fill=\'%23fff\' fill-rule=\'nonzero\' transform=\'matrix(.344737 0 0 .35503 -2.77114 -2.5503)\'/></svg>',
'file_icon_playlist': '<svg viewBox=\'0 0 14 14\' clip-rule=\'evenodd\' fill-rule=\'evenodd\' xmlns=\'http://www.w3.org/2000/svg\'><path d=\'m0 0h14v14h-14z\' fill=\'%23888\' fill-rule=\'nonzero\'/><path d=\'m1.5 1.5h8v1h-8zm0 2.5h8v1h-8zm0 2.5h8v1h-8zm0 2.5h7v1h-7zm0 2.5h5.5v1h-5.5zm9.5-10h1v10c-.019.681-.796 1.339-1.75 1.475-.966.138-1.75-.31-1.75-1s.784-1.362 1.75-1.5a2.28 2.28 0 0 1 .75.013z\' fill=\'%23fff\'/></svg>',
'file_icon_text': '<svg viewBox=\'0 0 14 14\' xmlns=\'http://www.w3.org/2000/svg\'><path d=\'m14 0h-14v14h14z\' fill=\'%236a6a95\'/><g fill=\'%23fff\'><path d=\'m6.5 1.5h6v1h-6z\'/><path d=\'m1.5 1.5h3.5v3.5h-3.5z\'/><path d=\'m1.5 6.5h11v1h-11z\'/><path d=\'m6.5 4h6v1h-6z\'/><path d=\'m1.5 11.5h8v1h-8z\'/><path d=\'m1.5 9h11v1h-11z\'/></g></svg>',
'file_icon_video': '<svg viewBox=\'0 0 14 14\' xmlns=\'http://www.w3.org/2000/svg\'><path d=\'m14 14v-14h-14v14z\'/><g fill=\'%23fff\'><path d=\'m9.5 3v-2h-2v2z\'/><path d=\'m3.5 3v-2h-2v2z\'/><path d=\'m6.5 3v-2h-2v2z\'/><path d=\'m12.5 3v-2h-2v2z\'/><path d=\'m9.5 13v-2h-2v2z\'/><path d=\'m3.5 13v-2h-2v2z\'/><path d=\'m6.5 13v-2h-2v2z\'/><path d=\'m12.5 13v-2h-2v2z\'/></g><path d=\'m12.5 10v-6h-11v6z\' fill=\'%23eda412\'/></svg>',
'file_icon_bin': '', 'file_icon_other': '', // <-- these two use file_icon_system:
'file_icon_system': '<svg viewBox=\'0 0 14 14\' xmlns=\'http://www.w3.org/2000/svg\'><path d=\'m0 0h14v14h-14z\' fill=\'%23808080\'/><g fill=\'%23ccc\'><path d=\'m1.247 6.495h3.263v-1.067h-.881v-3.835h-.974c-.371.232-.727.371-1.284.479v.82h.928v2.536h-1.052z\'/><path d=\'m7 6.588c1.082 0 1.825-.89 1.825-2.567 0-1.67-.743-2.521-1.825-2.521s-1.825.843-1.825 2.521c0 1.677.743 2.567 1.825 2.567zm0-1.021c-.309 0-.572-.247-.572-1.546s.263-1.5.572-1.5.572.201.572 1.5-.263 1.546-.572 1.546z\'/><path d=\'m9.598 6.495h3.263v-1.067h-.882v-3.835h-.974c-.371.232-.727.371-1.283.479v.82h.927v2.536h-1.051z\'/><path d=\'m2.825 12.588c1.082 0 1.824-.89 1.824-2.567 0-1.67-.742-2.521-1.824-2.521-1.083 0-1.825.843-1.825 2.521 0 1.677.742 2.567 1.825 2.567zm0-1.021c-.31 0-.572-.247-.572-1.546s.262-1.5.572-1.5c.309 0 .572.201.572 1.5s-.263 1.546-.572 1.546z\'/><path d=\'m5.423 12.495h3.263v-1.067h-.882v-3.835h-.974c-.371.232-.727.371-1.284.479v.82h.928v2.536h-1.051z\'/><path d=\'m11.175 12.588c1.083 0 1.825-.89 1.825-2.567 0-1.67-.742-2.521-1.825-2.521-1.082 0-1.824.843-1.824 2.521 0 1.677.742 2.567 1.824 2.567zm0-1.021c-.309 0-.572-.247-.572-1.546s.263-1.5.572-1.5c.31 0 .572.201.572 1.5s-.262 1.546-.572 1.546z\'/></g></svg>'
};
const SVG_Text_Editing_UI_Icons = {
'toggle_theme': '<svg viewBox=\'0 0 16 16\' clip-rule=\'evenodd\' fill-rule=\'evenodd\' xmlns=\'http://www.w3.org/2000/svg\'><path d=\'m8 0c4.415 0 8 3.585 8 8s-3.585 8-8 8-8-3.585-8-8 3.585-8 8-8zm0 2c3.311 0 6 2.689 6 6s-2.689 6-6 6z\' fill=\'%23333\'/></svg>',
'text_editing': '<svg version=\'1.1\' id=\'Layer_1\' xmlns:serif=\'http://www.serif.com/\' xmlns=\'http://www.w3.org/2000/svg\' xmlns:xlink=\'http://www.w3.org/1999/xlink\' x=\'0px\' y=\'0px\' viewBox=\'0 0 1297.6 1301.6\' style=\'enable-background:new 0 0 1297.6 1301.6;\' xml:space=\'preserve\'><polygon style=\'fill:%23222;\' points=\'1049,600.6 1049,1150.6 149,1150.6 149,250.6 699,250.6 699,101.6 0,101.6 0,1301.6 1200,1301.6 1200,600.6 \'/><rect x=\'421.7\' y=\'375.9\' transform=\'matrix(0.7071 -0.7071 0.7071 0.7071 -95.8103 720.4032)\' style=\'fill:%23222;\' width=\'800\' height=\'200\'/><rect x=\'1113.4\' y=\'17.7\' transform=\'matrix(0.7071 -0.7071 0.7071 0.7071 262.3587 868.8007)\' style=\'fill:%23222;\' width=\'133\' height=\'200\'/><polyline style=\'fill:%23222;\' points=\'345.9,951.8 439.9,716.3 581.3,857.7 \'/></svg>',
'show_markdown': '<svg viewBox=\'0 0 100 60\' xmlns=\'http://www.w3.org/2000/svg\' width=\'100\'><g fill=\'%23333\'><path d=\'M42.215 60l.17-46.24h-.255L30.06 60h-7.99L10.255 13.76H10L10.169 60H.905V-.18H14.59l11.56 44.03h.34L37.794-.18H52.16V60h-9.945zM99.589 29.996c0 9.519-1.997 16.901-5.992 22.142C89.602 57.38 83.722 60 75.959 60H60.914V-.18h15.13c7.706 0 13.558 2.65 17.553 7.948 3.995 5.299 5.992 12.708 5.992 22.228zm-10.2 0c0-3.57-.326-6.686-.978-9.35-.651-2.663-1.572-4.873-2.762-6.63-1.19-1.756-2.607-3.073-4.25-3.953-1.645-.878-3.43-1.317-5.355-1.317h-4.845v42.33h4.845c1.926 0 3.711-.438 5.355-1.317 1.643-.878 3.06-2.195 4.25-3.953 1.189-1.756 2.11-3.952 2.762-6.587.651-2.637.978-5.709.978-9.223z\'/></g></svg>',
'show_source': '<svg viewBox=\'0 0 22 14\' xmlns=\'http://www.w3.org/2000/svg\' fill-rule=\'evenodd\' clip-rule=\'evenodd\'><path fill=\'none\' d=\'M0 0h21.996v14H0z\'/><clipPath id=\'a\'><path d=\'M0 0h21.996v14H0z\'/></clipPath><g clip-path=\'url(%23a)\' fill=\'%23333\'><path d=\'M0 7.393v-.786l6.062-3.5.75 1.3L2.32 7l4.492 2.593-.75 1.3L0 7.393zM21.996 6.607v.786l-6.062 3.5-.75-1.3L19.676 7l-4.492-2.593.75-1.3 6.062 3.5zM15.15 1.313l-1.3-.75-7 12.124 1.3.75 7-12.124z\'/></g></svg>',
'show_preview': '<svg viewBox=\'0 0 16 16\' xmlns=\'http://www.w3.org/2000/svg\' fill-rule=\'evenodd\' clip-rule=\'evenodd\'><path d=\'M10 2.5V1H0v1.5h4V15h2V2.5h4zM9 6.5V8h2v4.053c0 2.211 1.547 3.442 3 3.442.989 0 1.556-.258 2-.495v-1.5c-.565.257-.882.376-1.507.376-.847 0-1.493-.474-1.493-1.876V8h2.5V6.5H13v-3h-1.98v3H9z\' fill=\'%23333\' fill-rule=\'nonzero\'/></svg>',
'show_html': '<svg viewBox=\'0 0 22 16\' xmlns=\'http://www.w3.org/2000/svg\' fill-rule=\'evenodd\' clip-rule=\'evenodd\'><path fill=\'none\' d=\'M0 0h21.022v16H0z\'/><clipPath id=\'a\'><path d=\'M0 0h21.022v16H0z\'/></clipPath><g clip-path=\'url(%23a)\' fill=\'%23333\'><path d=\'M7.732.222L9.5 1.99 3.49 8l6.01 6.01-1.768 1.768L-.046 8 7.732.222zM13.268 15.778L11.5 14.01 17.51 8 11.5 1.99 13.268.222 21.046 8l-7.778 7.778z\'/></g></svg>',
'toggle_split': '<svg viewBox=\'0 0 16 16\' xmlns=\'http://www.w3.org/2000/svg\' fill-rule=\'evenodd\' clip-rule=\'evenodd\'><path d=\'M0 0v16h16V0H0zm14 14H9V2h5v12zm-7 0H2V2h5v12z\' fill=\'%23333\' fill-rule=\'nonzero\'/></svg>',
'save_btn': '<svg viewBox=\'0 0 16 16\' xmlns=\'http://www.w3.org/2000/svg\' fill-rule=\'evenodd\' clip-rule=\'evenodd\'><g fill=\'currentColor\'><path d=\'M16 0v10.02L14 10V2H2v8l-2 .02V0h16z\' fill-rule=\'nonzero\'/><path d=\'M7 5h2v9H7z\'/><path d=\'M3.757 11.757l1.415-1.414L8 13.172l2.828-2.829 1.415 1.414L8 16l-4.243-4.243z\'/></g></svg>',
'save_btn_edited': '<svg viewBox=\'0 0 16 16\' xmlns=\'http://www.w3.org/2000/svg\' fill-rule=\'evenodd\' clip-rule=\'evenodd\'><g fill=\'%23DD2222\'><path d=\'M16 0v10.02L14 10V2H2v8l-2 .02V0h16z\' fill-rule=\'nonzero\'/><path d=\'M7 5h2v9H7z\'/><path d=\'M3.757 11.757l1.415-1.414L8 13.172l2.828-2.829 1.415 1.414L8 16l-4.243-4.243z\'/></g></svg>'
};
// ===> GET SVG UI ICON by name
function get_SVG_UI_File_Icon(icon_name) { // ===> GET SVG UI FILE Icon by name
switch(icon_name) {
case 'favicon': return '<link href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAIAAAACAAgMAAAC+UIlYAAAACVBMVEUmRcmZzP8zmf8pVcWPAAAAAXRSTlMAQObYZgAAAFBJREFUeF7tyqERwDAMBEE3mX5UiqDmqwwziTPHjG7xrmzrLFtRaApDIRiKQlMYCsFQFJrCUAiGotAU5hTA1WB4fhkMBsOJwWAwgHvB8CHpBcTbpxy4RZNvAAAAAElFTkSuQmCC" rel="icon" sizes="16x16" />';
case 'file_icon_dir_default': return 'url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAd5JREFUeNqMU79rFUEQ/vbuodFEEkzAImBpkUabFP4ldpaJhZXYm/RiZWsv/hkWFglBUyTIgyAIIfgIRjHv3r39MePM7N3LcbxAFvZ2b2bn22/mm3XMjF+HL3YW7q28YSIw8mBKoBihhhgCsoORot9d3/ywg3YowMXwNde/PzGnk2vn6PitrT+/PGeNaecg4+qNY3D43vy16A5wDDd4Aqg/ngmrjl/GoN0U5V1QquHQG3q+TPDVhVwyBffcmQGJmSVfyZk7R3SngI4JKfwDJ2+05zIg8gbiereTZRHhJ5KCMOwDFLjhoBTn2g0ghagfKeIYJDPFyibJVBtTREwq60SpYvh5++PpwatHsxSm9QRLSQpEVSd7/TYJUb49TX7gztpjjEffnoVw66+Ytovs14Yp7HaKmUXeX9rKUoMoLNW3srqI5fWn8JejrVkK0QcrkFLOgS39yoKUQe292WJ1guUHG8K2o8K00oO1BTvXoW4yasclUTgZYJY9aFNfAThX5CZRmczAV52oAPoupHhWRIUUAOoyUIlYVaAa/VbLbyiZUiyFbjQFNwiZQSGl4IDy9sO5Wrty0QLKhdZPxmgGcDo8ejn+c/6eiK9poz15Kw7Dr/vN/z6W7q++091/AQYA5mZ8GYJ9K0AAAAAASUVORK5CYII= ")';
case 'file_icon_file_default': return 'url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAIAAACQkWg2AAAABnRSTlMAAAAAAABupgeRAAABHUlEQVR42o2RMW7DIBiF3498iHRJD5JKHurL+CRVBp+i2T16tTynF2gO0KSb5ZrBBl4HHDBuK/WXACH4eO9/CAAAbdvijzLGNE1TVZXfZuHg6XCAQESAZXbOKaXO57eiKG6ft9PrKQIkCQqFoIiQFBGlFIB5nvM8t9aOX2Nd18oDzjnPgCDpn/BH4zh2XZdlWVmWiUK4IgCBoFMUz9eP6zRN75cLgEQhcmTQIbl72O0f9865qLAAsURAAgKBJKEtgLXWvyjLuFsThCSstb8rBCaAQhDYWgIZ7myM+TUBjDHrHlZcbMYYk34cN0YSLcgS+wL0fe9TXDMbY33fR2AYBvyQ8L0Gk8MwREBrTfKe4TpTzwhArXWi8HI84h/1DfwI5mhxJamFAAAAAElFTkSuQmCC ")';
default: return 'url("data:image/svg+xml;utf8,'+ SVG_UI_File_Icons[icon_name] +'")';
}
}
function CSS_UI_Icon_Rules() { // programatically add File icon CSS rules // ===> CSS UI ICON RULES
let rules = '', kind, class_name;
for ( let icon in SVG_UI_File_Icons ) {
kind = icon.slice(icon.lastIndexOf('_') + 1);
class_name = kind;
if ( class_name !== ('file') ) { // exceptions:
if ( kind === 'dirinvisible' ) { class_name = 'dir.invisible'; }
if ( kind === 'ignoredimage' ) { class_name = 'ignored_image'; }
if ( kind === 'open' ) { class_name = 'has_subdirectory'; kind = 'dir_open'; }
if ( /alias|symlink/.test(kind) ) { class_name = 'link'; }
if ( /bin|other/.test(kind) ) { kind = 'system'; }
// add rules for dir_list items, content_header, stats details:
rules += `body:not(.use_custom_icons_false) .${ class_name } .has_icon_before_before, #content_pane[data-content^="has_${ class_name }"] #content_title span::before,body:not(.use_custom_icons_false) .${ class_name }.has_icon_before::before, .${ class_name } .has_icon_before::before { background-image: url("data:image/svg+xml;utf8,${ SVG_UI_File_Icons['file_icon_'+kind] }"); }`; // add custom file icons
}
}
return rules;
}
// END SVG UI ICONS
//==============================// UI HTML
// SIDEBAR ELEMENTS
function Sidebar_Elements(body_id,parent_link) { // Assemble directory elements for both top and iframe directories
const sidebar_header_menu_elements = `
<li id="go_to_item" class="no_checkmark border_bottom" title="Go to item..."><span class="menu_item">Go to item… (⌘⇧J)</span><input id="go_to_item_input" class="display_none resize_none whitespace_pre" rows="1" placeholder="Item row number" spellcheck="false" /></li>
<li id="menu_sort_by" class="has_submenu border_bottom error_display_none"><span class="menu_item">Sort by…</span>${SVG_UI_Icons.arrow}
<ul id="sort_menu" class="submenu box_shadow_menu background_grey_80 border_all"> <li id="menu_sort_by_name" class="is_submenu_item toggle_UI_pref sorting" data-ui_pref="sort_by_name"><span class="menu_item">Name</span></li> <li id="menu_sort_by_duration" class="is_submenu_item toggle_UI_pref sorting" data-ui_pref="sort_by_duration"><span class="menu_item">Duration</span></li> <li id="menu_sort_by_size" class="is_submenu_item toggle_UI_pref sorting" data-ui_pref="sort_by_size"><span class="menu_item">Size</span></li> <li id="menu_sort_by_date" class="is_submenu_item toggle_UI_pref sorting" data-ui_pref="sort_by_date"><span class="menu_item">Date</span></li> <li id="menu_sort_by_kind" class="is_submenu_item toggle_UI_pref sorting" data-ui_pref="sort_by_kind"><span class="menu_item">Kind</span></li> <li id="menu_sort_by_ext" class="is_submenu_item toggle_UI_pref sorting" data-ui_pref="sort_by_ext"><span class="menu_item">Extension</span></li> <li id="menu_sort_by_default" class="is_submenu_item toggle_UI_pref sorting" data-ui_pref="sort_by_default"><span class="menu_item">Default</span></li> </ul></li>
<li id="UI_settings" class="has_submenu"><span class="menu_item">UI Preferences</span>${SVG_UI_Icons.arrow}
<ul id="UI_settings_submenu" class="submenu box_shadow_menu background_grey_80 border_all"> <li id="menu_theme_container" class="is_submenu_item" title="Set the main UI theme (light or dark)."><span id="menu_theme" class="toggle_UI_pref menu_item checkmark ignore_warning" data-ui_pref="theme"><span> Theme</span></span></li> <li id="alternate_background" class="is_submenu_item toggle_UI_pref ignore_warning" data-ui_pref="alternate_background" title="Alternate backgrounds of directory items."><span class="menu_item checkmark">Alternate Backgrounds</span></li> <li id="show_numbers" class="is_submenu_item toggle_UI_pref ignore_warning border_bottom error_display_none" data-ui_pref="show_numbers" title="Number directory list items."><span class="menu_item checkmark">Show Numbers</span></li> <li id="use_custom_icons" class="is_submenu_item toggle_UI_pref ignore_warning" data-ui_pref="use_custom_icons" title="Use custom or browser/server default file and dir icons"><span class="menu_item checkmark">Use Custom Icons</span></li> <li id="show_image_thumbnails" class="is_submenu_item toggle_UI_pref ignore_warning" data-ui_pref="show_image_thumbnails" title="Show image thumbnails in directory list items."><span class="menu_item checkmark">Show Image Thumbnails</span></li> <li id="show_large_image_thumbnails" class="is_submenu_item toggle_UI_pref ignore_warning" data-ui_pref="show_large_image_thumbnails" title="Use large image thumbnails."><span class="menu_item checkmark">Use Large Image Thumbnails</span></li> <li id="show_image_thumbnails_always" class="is_submenu_item toggle_UI_pref ignore_warning border_bottom" data-ui_pref="show_image_thumbnails_always" title="Always show image thumbnails no matter how many images are in directory."><span class="menu_item checkmark">Always Show Image Thumbnails</span></li> <li id="audio_player_on_top" class="is_submenu_item toggle_UI_pref" data-ui_pref="audio_player_on_top" title="Toggle off to place the audio player at the bottom of the content pane."><span class="menu_item checkmark">Audio Player at Top</span></li> <li id="ui_font" class="is_submenu_item ignore_warning no_checkmark border_top" data-ui_pref="ui_font" title="Enter the name of an installed font."><span class="menu_item">Set UI Font…</span><input id="ui_font_input" class="display_none resize_none whitespace_pre" rows="1" placeholder="CSS Font Family" spellcheck="false" /></li> <li id="ui_scale" class="is_submenu_item ignore_warning display_flex flex_column no_checkmark" data-ui_pref="ui_scale" title="Scale the UI. Double-click to reset."><span class="menu_item">Scale UI…</span><span id="ui_scale_input_container" class="flex_justify_center_row padding_4_6"><input id="ui_scale_input" class="width_100 whitespace_pre display_block resize_none" type="range" min="75" max="125" step="1" placeholder="Scale UI"></span></li> </ul></li>
<li id="file_handling" class="has_submenu error_display_none"><span class="menu_item">File Handling Preferences</span>${SVG_UI_Icons.arrow}
<ul id="file_handling_submenu" class="submenu box_shadow_menu background_grey_80 border_all"> <li id="show_invisible_items" class="is_submenu_item toggle_UI_pref" data-ui_pref="show_invisibles" title="Show/hide invisible items"><span class="menu_item checkmark">Show Invisible Items (⌘⇧I)</span></li> <li id="show_ignored_items" class="is_submenu_item toggle_UI_pref" data-ui_pref="show_ignored_items" title="Show/hide ignored items (from the list of ignored file types in the user settings)."><span class="menu_item checkmark">Show Ignored Items</span></li> <li id="ignore_ignored_items" class="is_submenu_item toggle_UI_pref border_bottom" data-ui_pref="ignore_ignored_items" title="If checked, the browser will not attempt to load ignored items (from the list of ignored file types in the user settings). It is recommended to leave this checked."><span class="menu_item checkmark">Ignore Ignored Items</span></li> <li id="autoload_index_files" class="is_submenu_item toggle_UI_pref" data-ui_pref="autoload_index_files" title="Automatically load html index file."><span id="autoload_index_files_menu" class="menu_item checkmark">Autoload Index Files</span></li> </ul></li>
<li id="media_settings" class="has_submenu error_display_none"><span class="menu_item">Media Preferences</span>${SVG_UI_Icons.arrow}
<ul id="UI_settings_submenu" class="submenu box_shadow_menu background_grey_80 border_all"> <li id="media_autoload" class="is_submenu_item toggle_UI_pref" data-ui_pref="media_autoload" title="Automatically select and load the first media item in a directory and cover art (if any)."><span id="media_autoload_menu" class="menu_item checkmark">Autoload Media</span></li> <li id="media_autoplay" class="is_submenu_item toggle_UI_pref" data-ui_pref="media_autoplay" title="Automatically play the next media item."><span id="media_autoload_menu" class="menu_item checkmark">Autoplay Media</span></li> <li id="media_play_all" class="is_submenu_item toggle_UI_pref border_bottom" data-ui_pref="media_play_all" title="If checked, autoplay all media types (i.e., audio and video), else just autoplay the currently selected/playing media type."><span class="menu_item checkmark">Play All Media Files</span></li> <li id="loop_media_files" class="is_submenu_item" title="If checked, loop media playback."><span id="loop_media_menu" class="menu_item">Loop Media Playback</span></li> <li id="shuffle_media_files" class="is_submenu_item border_bottom" title="If checked, shuffle media playback."><span id="shuffle_media_menu" class="menu_item">Shuffle Media Playback</span></li> <li id="refresh_media_durations" class="is_submenu_item border_bottom" title=""><span id="refresh_media_durations_menu" class="menu_item">Refresh Media Durations</span></li> </ul></li>
<li id="text_editing" class="has_submenu error_display_none"><span class="menu_item">Text Editing Preferences</span>${SVG_UI_Icons.arrow} <ul id="text_editing_menu" class="submenu box_shadow_menu background_grey_80 border_all"> <li id="texteditor_menu_item" class="is_submenu_item border_bottom" title="Toggle the main text editor."><span id="texteditor" class="menu_item">Toggle Main Text Editor</span></li> <li id="toggle_text_editing" class="error_display_none border_bottom" title="Enable/disable editing of text files. Does not effect main text editor."><span id="text_editing_enable" class="menu_item checkmark" data-ui_pref="text_editing_enable"><span id="disable">Text File Editing </span></span></li> <li id="texteditor_split_view" class="is_submenu_item toggle_UI_pref border_bottom" data-ui_pref="texteditor_split_view" title="Toggle display of default text view and both source and rendered text."><span class="menu_item checkmark">Split View</span></li> <li id="toggle_texteditor_raw_menu" class="is_submenu_item toggle_UI_pref" data-ui_pref="texteditor_view_raw"><span id="toggle_texteditor_raw" class="menu_item">View Source Text</span></li> <li id="toggle_texteditor_preview_menu" class="is_submenu_item toggle_UI_pref" data-ui_pref="texteditor_view_styled"><span id="toggle_texteditor_preview" class="menu_item">View Styled Text</span></li> <li id="toggle_texteditor_html_menu" class="is_submenu_item toggle_UI_pref" data-ui_pref="texteditor_view_html"><span id="toggle_texteditor_html" class="menu_item">View Rendered HTML</span></li></ul>
<li id="default_settings" class="menu_item border_bottom"><span class="" href="#" title="Delete custom UI preferences stored in the URL query string and reload page.">Default Preferences</span></li>
<li id="playlist_options" class="has_submenu border_bottom error_display_none"><span class="menu_item">Playlists</span>${SVG_UI_Icons.arrow} <ul id="playlist_menu" class="submenu box_shadow_menu background_grey_80 border_all"> <li id="open_playlist_container" class="is_submenu_item"><label id="open_playlist_label" class="menu_item" for="open_playlist" title="Open local .m3u playlist/filelist file.">Open Playlist/Filelist File…</label><input type="file" id="open_playlist" name="open_playlist" accept=".m3u,.m3u8"></li> <li id="close_playlist_container" class="is_submenu_item display_none"><span id="close_playlist" class="menu_item" href="#">Close Playlist/Filelist</span></li> <li class="is_submenu_item"><span id="make_playlist" class="menu_item border_top error_display_none" href="#" title="Make an .m3u playlist/filelist of the items in the current directory (if any).">Make Playlist/Filelist…</span></li> </ul></li>
<li id="open_font_file" class="border_bottom error_display_none"><label id="open_font_label" class="menu_item" for="open_font" title="Open font file (.oft, .ttf, .woff) to view glyph repertoire and font info; save individual glyphs as .svg.">Open Font File…</label><input type="file" id="open_font" name="open_font" accept=".otf,.ttf,.woff"></li>
<li id="about" class="menu_item" title="Go to script home page."><a id="about_link" class="flex_grow_1 ignore_warning" href="https://openuserjs.org/scripts/gaspar_schot/Supercharged_Local_Directory_File_Browser" target="_blank"><span class="icon_container"></span>Script Home ↗</a></li>
<li id="show_help" class="menu_item" title="Show help."><span class="flex_grow_1"><span class="icon_container"></span>Help</span></li>
<li id="donate" class="menu_item" title="Buy me a coffee!"><a id="donate_link" class="flex_grow_1 ignore_warning" href="https://www.buymeacoffee.com/fiLtliTFxQ" target="_blank" rel="noopener"><span class="icon_container"></span>Buy me a Coffee <svg xmlns="http://www.w3.org/2000/svg" width="14px" viewBox="0 0 64 64" enable-background="new 0 0 64 64"><path d="m32 2c-16.568 0-30 13.432-30 30 0 16.568 13.432 30 30 30s30-13.432 30-30c0-16.568-13.432-30-30-30m0 48c-1.371-1.814-20.53-12.883-16.602-25.218 3.53-11.073 15.094-6.597 16.602-.594 1.094-5.635 12.949-10.694 16.604.584 3.925 12.136-15.237 23.785-16.604 25.228" fill="#757575"/></svg></a></li>
<li id="contact" class="menu_item" title="Send me an email."><a id="contact_link" class="flex_grow_1 ignore_warning" href="mailto:[email protected]"><span class="icon_container"></span>Contact</a></li>
`;
const sidebar_header_elements = function(body_id,parent_link) {
let parent_links = createParentLinkItems(), sidebar_header_title_element = '', sidebar_header_menus ='', sidebar_texteditor_element ='';
let checked = ( getCurrentUIPref('show_invisibles') === 'true' ? 'checked="true"' : '' );
const sidebar_header_utilities_row_1 = `<div id="sidebar_header_utilities_row_1" class="background_grey_80"> <ul class="display_flex flex_row position_relative background_grey_80 border_bottom"> <li id="directory_buttons_left" class="display_flex no_highlight"> <button id="show_details" class="toggle_UI_pref pointer outline_none" data-ui_pref="show_details" tabindex="-1" title="Toggle display of directory item detail information (⌘⇧D)"><span id="show"> details</span></button></li> <li class="display_flex no_highlight"><label id="show_invisibles_container" for="inv_checkbox" class="margin_0 padding_0 flex_justify_center_row"><input class="toggle_UI_pref margin_0" type="checkbox" id="show_invisibles" data-ui_pref="show_invisibles" title="Toggle display of invisible items (⌘⇧;I)" name="inv_checkbox" tabindex="-1"${ checked } /><span> Show Invisibles</span></label> </li> <li id="show_grid_btn" class="has_flyout_menu width_24px display_none position_relative pointer margin_0 padding_0 z_index_9997 no_highlight" tabindex="-1" title="Show Grid (⌘G)"><div class="display_flex width_14px_contents background_grey_80">${ SVG_UI_Icons.grid}</div> <ul class="menu has_popout_menu display_none position_absolute margin_0 padding_0 box_shadow_menu border_all background_grey_80"><div class="display_flex width_24px width_14px_contents">${ SVG_UI_Icons.grid}</div> <li id="show_image_grid" class="item_1 border_right border_bottom background_grey_80">Show Image Grid</li> <li id="show_font_grid" class="item_2 border_right background_grey_80">Show Font Grid</li> </ul> </li></ul></div>`;
const sidebar_header_utilities_row_2 = `<div id="sidebar_header_utilities_row_2" class="background_grey_80"> <ul id="sorting_row_1" class="whitespace_pre pointer container display_flex flex_justify_contents border_bottom"> <li id="sort_by_name" class="whitespace_pre pointer toggle_UI_pref name sorting align_left no_highlight" data-ui_pref="sort_by_name" title="Sort by name"><span><input id="play_toggle" class="whitespace_pre pointer display_none position_relative" type="checkbox" tabindex="-1" checked="true" />Name</span></li> <li id="sort_by_default" class="whitespace_pre pointer toggle_UI_pref sorting align_right no_highlight" data-ui_pref="sort_by_default" title="Default sort"><span>Default</span></li> <li id="sort_by_duration" class="whitespace_pre pointer toggle_UI_pref sorting align_right display_none no_highlight" data-ui_pref="sort_by_duration" title="Sort by media duration"><span>Duration</span></li> </ul>
<ul id="sorting_row_2" class="whitespace_pre pointer iframe_item border_bottom display_none"> <li id="sort_by_ext" class="whitespace_pre pointer toggle_UI_pref details sorting align_left no_highlight" data-ui_pref="sort_by_ext" title="Sort by extension"><span>Ext</span></li> <li id="sort_by_duration" class="whitespace_pre pointer toggle_UI_pref sorting align_right display_none no_highlight" data-ui_pref="sort_by_duration" title="Sort by media duration"><span>Duration</span></li> <li id="sort_by_size" class="whitespace_pre pointer toggle_UI_pref details sorting align_center no_highlight" data-ui_pref="sort_by_size" title="Sort by size"><span>Size</span></li> <li id="sort_by_date" class="whitespace_pre pointer toggle_UI_pref details sorting align_center no_highlight" data-ui_pref="sort_by_date" title="Sort by date"><span>Date</span></li> <li id="sort_by_kind" class="whitespace_pre pointer toggle_UI_pref details sorting align_right no_highlight" data-ui_pref="sort_by_kind" title="Sort by kind"><span>Kind</span></li> </ul> </div>`;
switch(body_id) {
case 'top_body':
sidebar_header_title_element = `<div id="sidebar_header_title" class="display_flex flex_row border_bottom background_grey_75 normal"><div id="sidebar_header_title_div" class="align_center padding_4_6"></div></div>`;
sidebar_header_menus = `<div id="sidebar_menus" class="display_flex flex_row background_grey_75 border_bottom pointer">
<div id="sidebar_menu_parent" class="menu_container flex_justify_center width_24px padding_0"> <nav id="parent_dir_nav" class="flex_justify_center invert"><a href="${ parent_links[1] }" title="Parent Directory (⌘↑)" class="flex_justify_center"><div class="display_flex">${ SVG_UI_Icons.chevron }${ SVG_UI_Icons.multiply }</div></a></nav> </div>
<div id="sidebar_menu_parents" class="menu_container padding_0 flex_grow_1"> <nav id="parents_dir_nav" class="display_flex border_right line_height_1_4 border_left"> <div id="current_dir_path" class="bold flex_justify_center hyphens_none pointer z_index_9998" title="Parent Directories"><span class="has_icon_before">${ current_dir_path }</span></div> </nav> <ul id="parents_links" class="menu background_grey_85 position_absolute position_LR_0 border_top border_bottom margin_0 padding_0 display_none box_shadow_menu z_index_9998">${ parent_links[0] }</ul> </div>
<div id="sidebar_menu_main_container" class="menu_container width_24px flex_justify_center margin_0 padding_0"> <nav id="dir_menu_main_container_nav" class="invert pointer width_14px_contents" title="Show main menu (⌘E); navigate by arrow keys or typed string."><div class="display_flex">${ SVG_UI_Icons.menu }</div></nav> <ul id="sidebar_menu_main" class="menu position_absolute background_grey_80 border_top border_bottom margin_0 padding_0 display_none box_shadow_menu position_LR_0 z_index_9998"> ${ sidebar_header_menu_elements } </ul> </div> </div>`;
sidebar_texteditor_element = `<ul id="show_texteditor" class="bold border_bottom display_none"><li class="padding_4_6 width_100 background_grey_80" title="Toggle Text Editor (⌘⇧E)"><span>Text Editor</span></li></ul>`; break;
case 'iframe': sidebar_header_menus = `<ul id="change_dirs" class="flex_justify_center_row flex_justify_contents border_bottom background_grey_75"> <li id="parent" class="flex_grow_1 no_highlight"><a href="${ parent_link }" id="iframe_parent_link" class="display_inline_flex" title="Go to parent directory"><span class="width_14px_contents invert">${ SVG_UI_Icons.chevron }</span>Parent Directory</a></li> <li id="open_in_sidebar" class="align_right flex_grow_1 no_highlight"><a href="#" title="Open this directory in sidebar">Open in Sidebar<span class="width_14px_contents invert transform_rotate_270_contents">${ SVG_UI_Icons.chevron }</span></a></li> </ul>`; break;
}
return `<header id="sidebar_header" class="display_flex flex_column text_color_default font_size_small user_select_none z_index_3"> ${ sidebar_header_title_element }
<div id="sidebar_header_utilities" class="display_flex flex_column"> ${ sidebar_header_menus } ${ sidebar_header_utilities_row_1 } ${ sidebar_header_utilities_row_2 } ${ sidebar_texteditor_element } </div>
</header>`;
}
let sidebar_footer_utilities = '', sidebar_utilities = '';
if ( body_id === 'top_body' ) { // various elements not needed in iframe directories
sidebar_footer_utilities = `<div id="sidebar_footer_utilities" class="width_24px flex_justify_center position_relative pointer z_index_1 background_grey_80 border_left border_right"><div class="width_18px_contents display_flex transform_rotate_180"><span class="invert">${ SVG_UI_Icons.toggle }</span></div> <ul class="has_popout_menu margin_0 padding_0 display_none border_all position_absolute background_grey_80"> <li id="open_in_content_pane" class="align_right border_bottom padding_4_6">Open Sidebar in Content Pane</li> <li id="show_directory_source" class="align_right padding_4_6" data-kind="show_directory_source">View Sidebar Directory Source</li> </ul> </div>`;
sidebar_utilities = `<div id="sidebar_utilities"><div id="handle" class="position_absolute z_index_1"></div> <div id="show_sidebar" class="toggle_UI_pref width_24px width_18px_contents position_absolute flex_justify_center invert pointer z_index_9997" data-ui_pref="show_sidebar" title="Toggle Sidebar (⌘\\)">${ SVG_UI_Icons.toggle }</div></div> </div>`;
}
const sidebar_nav = `<nav id="sidebar_nav" class="display_flex flex_column background_grey_85 font_size_small"><div id="dir_nav_inner" class="position_relative"> <div id="directory_list_outer" class="position_relative"><ol id="directory_list" class="display_flex flex_column margin_0 padding_0 text_color_default border_bottom" tabindex="0">insert_prepped_index</ol></div> </div></nav>`;
const sidebar_footer = `<footer id="sidebar_footer" class="display_flex flex_row position_relative background_grey_85 border_top text_color_default error_display_none font_size_small user_select_none">insert_stats${ sidebar_footer_utilities }</footer>`;
return `<div id="sidebar" class="${body_id} display_flex flex_column position_relative border_right padding_0 z_index_1" style="width:${ Number(getCurrentUIPref("width")) }%"> ${ sidebar_header_elements(body_id,parent_link) } ${ sidebar_nav } ${ sidebar_footer } ${ sidebar_utilities } </div>`;
}
//==============================//
// CONTENT PANE ELEMENTS
function Content_Pane_Elements(id) {
const content_audio_elements = `<div id="content_audio_title" class="flex_justify_center_row background_grey_80 bold align_center" title="Click to toggle .m3u playlist entry."><span class="pointer line_height_1_4"></span></div>
<div id="content_audio_container" class="content_el track_title_container display_flex flex_row border_bottom background_grey_80">
<div id="audio_container" class="display_flex flex_row border_all">
<nav id="cuesheet_track_list_container_audio" class="cuesheet_track_list_container border_right" title="Cue sheet track list"> <div class="box_shadow_menu display_none font_size_small position_absolute position_LR_0 z_index_1"><ul id="cuesheet_track_list_audio" class="cuesheet_track_list background_grey_85 border_bottom margin_0 padding_0"> </ul></div> </nav>
<div id="prev_track" class="prev_next_btn audio_controls flex_justify_center pointer" title="Previous track"><div class="display_flex width_24px_contents transform_rotate_180">${ SVG_UI_Icons.prev_next_track }</div></div> <div id="next_track" class="prev_next_btn audio_controls flex_justify_center border_right pointer" title="Next track"><div class="display_flex width_24px_contents">${ SVG_UI_Icons.prev_next_track }</div></div>
<audio id="content_audio" class="media_player outline_none" preload="auto" tabindex="0" controls>Sorry, your browser does not support HTML5 audio.</audio>
<div id="close_audio" class="audio_controls border_left flex_justify_center position_relative pointer" title="Close audio"><div class="display_flex width_14px_contents">${ SVG_UI_Icons.multiply }</div></div>
<div id="audio_options" class="display_flex flex_column"> <label id="loop_label" for="loop"><input type="checkbox" id="loop" name="loop" tabindex="0" />Loop</label> <label id="shuffle_label" class="whitespace_pre" for="shuffle"><input type="checkbox" id="shuffle" name="shuffle" tabindex="0" />Shuffle</label> </div>
</div>
</div>
<div id="content_audio_playlist_item" class="playlist_entry_container border_bottom background_grey_85 align_center display_none"><textarea id="content_audio_playlist_item_textarea" class="text_color_default padding_4_6 border_0 outline_none" rows="3" spellcheck="false"></textarea></div>`;
const text_editing_ui_elements = `<div id="texteditor_toolbar" class="border_bottom background_grey_80 position_relative text_color_default display_flex user_select_none width_100">
<ul id="toolbar_buttons" class="display_flex flex_row flex_grow_1 margin_0 padding_0"> <li id="toggle_texteditor_view_raw" class="toggle_UI_pref toolbar_icon display_flex no_highlight" data-ui_pref="texteditor_view_raw" title="Show source"><div class="display_flex width_16px_contents invert">${ SVG_Text_Editing_UI_Icons.show_markdown }</div></li> <li id="toggle_texteditor_view_styled" class="toggle_UI_pref toolbar_icon display_flex no_highlight" data-ui_pref="texteditor_view_styled" title="Show rendered markdown"><div class="display_flex width_14px_contents invert">${ SVG_Text_Editing_UI_Icons.show_preview }</div></li> <li id="toggle_texteditor_view_html" class="toggle_UI_pref toolbar_icon display_flex no_highlight" data-ui_pref="texteditor_view_html" title="Show formatted HTML"><div class="display_flex width_18px_contents invert">${ SVG_Text_Editing_UI_Icons.show_html }</div></li> <li id="toggle_texteditor_split_view" class="toggle_UI_pref toolbar_icon display_flex no_highlight" data-ui_pref="texteditor_split_view" title="Toggle Split View"><div class="display_flex width_14px_contents invert">${ SVG_Text_Editing_UI_Icons.toggle_split }</div></li> <li id="texteditor_sync_scroll" class="toggle_UI_pref checkbox_container flex_justify_center_row no_highlight" data-ui_pref="texteditor_sync_scroll"><input id="texteditor_sync_scroll_input" class="toggle_UI_pref flex_justify_center_row position_relative" data-ui_pref="texteditor_sync_scroll" name="texteditor_sync_scroll" type="checkbox"><label id="texteditor_sync_scroll_label" for="texteditor_sync_scroll" class="toggle_UI_pref flex_justify_center_row whitespace_pre" data-ui_pref="texteditor_sync_scroll">Sync Scroll</label></li> <li class="display_flex flex_grow_1 no_highlight"> </li> <li id="clear_text" class="toolbar_icon no_highlight" title="Clear Text">Clear</li> <li id="save_btn" class="has_flyout_menu width_24px display_flex position_relative pointer margin_0 padding_0 z_index_9997" title=""><div class="display_flex width_14px_contents">${ SVG_Text_Editing_UI_Icons.save_btn}</div><ul class="menu has_popout_menu display_none position_absolute margin_0 padding_0 box_shadow_menu border_top border_bottom border_left background_grey_80"> <li id="save_text" class="item_1 border_right border_bottom background_grey_85" title="Save source text"><span id="save_text_link" target="_blank">Save Source</span></li> <li id="save_btn_icon" class="item_1 no_highlight">${ SVG_Text_Editing_UI_Icons.save_btn}</li> <li id="save_HTML" class="item_2 border_right background_grey_85" title="Save rendered html"><span id="save_HTML_link" target="_blank">Save HTML</span></li> </ul></li> </ul> </div>
<div id="text_container" class="display_flex flex_grow_1 overflow_hidden"> <textarea id="texteditor_raw_pane" class="texteditor_pane margin_0 border_0 height_100 line_height_1_2 text_color_default resize_none display_none z_index_1 outline_none" tabindex="0"></textarea> <div id="texteditor_styled_pane" class="texteditor_pane margin_0 border_0 line_height_1_2 text_color_default height_100 display_none markdown_body z_index_1" tabindex="0"></div> <textarea id="texteditor_html_pane" class="texteditor_pane margin_0 height_100 line_height_1_2 border_0 text_color_default resize_none display_none z_index_1 outline_none" tabindex="0" readonly></textarea> <div id="text_editing_handle" class="position_absolute z_index_3"></div> </div>
`;
const content_text_elements = `<div id="content_texteditor" class="background_grey_85 margin_0 padding_0 width_100 height_100 overflow_hidden position_absolute z_index_1 flex_column flex_grow_1 display_none">${ text_editing_ui_elements }</div>`;
const content_font_toolbar = `<div id="font_toolbar" class="display_none margin_0 position_relative background_grey_80 border_bottom user_select_none z_index_3">
<ol id="font_specimen_variants" class="display_none flex_row flex_grow_1 border_bottom"><li id="font_variants" class="flex_justify_center no_highlight" title="Font Variants"><select id="font_variant_select" data-tab_order="10" name="Font Variants">
<option value="">OpenType Feature Tags</option>
<optgroup label="Caps"> <option value="normal" data-prop="font-variant-caps" data-value="normal">Normal </option> <option value="smcp" title="smcp" data-prop="font-variant-caps" data-value="small-caps">Small Caps </option> <option value="c2sc" title="c2sc" data-prop="font-variant-caps" data-value="all-small-caps">All Small Caps </option> <option value="pcap" title="pcap" data-prop="font-variant-caps" data-value="petite-caps">Petite Caps </option> <option value="c2pc" title="c2pc" data-prop="font-variant-caps" data-value="all-petit-caps">All Petite Caps </option> <option value="unic" title="unic" data-prop="font-variant-caps" data-value="unicase">Unicase </option> <option value="titl" title="titl" data-prop="font-variant-caps" data-value="titling-caps">Titling Caps </option> <option value="case" title="case">Case Sensitive Forms </option> <option value="ordn" title="ordn">Ordinals </option> </optgroup>
<optgroup label="Alternatives"> <option value="normal" data-prop="font-variant-alternates" data-value="normal">Normal </option> <option value="aalt" title="aalt">Access All Alternates </option> <option value="nalt" title="nalt" data-prop="font-variant-alternates" data-value="'nalt'">Annotation 1–99 </option> <option value="cv01" title="cv01" data-prop="font-variant-alternates" data-value="'cv01'">Character Variant 1–99 </option> <option value="calt" title="calt" data-prop="font-variant-alternates" data-value="cv01">Contextual Alts 1–99 </option> <option value="hist" title="hist">Historical Forms </option> <option value="ornm" title="ornm" data-prop="font-variant-alternates" data-value="ornm">Ornaments 1–99 </option> <option value="salt" title="salt" data-prop="font-variant-alternates" data-value="salt">Stylistic Alternates 1–99 </option> <option value="ss01" title="ss01" data-prop="font-variant-alternates" data-value="ss01">Stylistic Set 1–20 </option> <option value="swsh" title="swsh" data-prop="font-variant-alternates" data-value="'swsh'">Swash 1–99 </option> <option value="cswh" title="cswh">Contextual Swash </option> </optgroup>
<optgroup label="Ligatures"> <option value="normal" data-prop="font-variant-ligatures" data-value="normal">Normal </option> <option value="liga" title="liga" data-prop="font-variant-ligatures" data-value="common-ligatures">Common Ligatures </option> <option value="clig" title="clig" data-prop="font-variant-ligatures" data-value="contextual">Contextual Ligatures </option> <option value="dlig" title="dlig" data-prop="font-variant-ligatures" data-value="discretionary-ligatures">Discretionary Ligatures </option> <option value="hlig" title="hlig" data-prop="font-variant-ligatures" data-value="historical-ligatures">Historical Ligatures </option> </optgroup>
<optgroup label="Numbers"> <option value="normal" data-prop="font-variant-numeric" data-value="normal">Normal </option> <option value="dnom" title="dnom" data-prop="font-variant-numeric" data-value="ordinal">Ordinal </option> <option value="zero" title="zero" data-prop="font-variant-numeric" data-value="slashed-zero">Slashed Zero </option> <option value="lnum" title="lnum" data-prop="font-variant-numeric" data-value="lining-nums">Lining Figures </option> <option value="onum" title="onum" data-prop="font-variant-numeric" data-value="oldstyle-nums">Oldstyle Figures </option> <option value="pnum" title="pnum" data-prop="font-variant-numeric" data-value="proportional-nums">Proportional Figures </option> <option value="tnum" title="tnum" data-prop="font-variant-numeric" data-value="tablular-nums">Tabular Figures </option> <option value="frac" title="frac" data-prop="font-variant-numeric" data-value="diagonal-fractions">Fractions </option> <option value="afrc" title="afrc" data-prop="font-variant-numeric" data-value="stacked-fractions">Alternative Fractions </option> <option value="numr" title="numr">Numerator </option> <option value="sinf" title="sinf">Scientific Inferiors </option> <option value="mgrk" title="mgrk">Mathematical Greek </option> </optgroup>
<optgroup label="Position"> <option value="normal" data-prop="font-variant-position" data-value="normal">Normal </option> <option value="subs" title="subs" data-prop="font-variant-position" data-value="sub">Subscript </option> <option value="sups" title="sups" data-prop="font-variant-position" data-value="super">Superscript </option> </optgroup>
</select></li>
<li id="font_tag" class="flex_justify_center no_highlight" data-salt=""><span class="flex_justify_center position_relative"><textarea id="font_tag_textarea" data-tab_order="12" class="resize_none outline_none" rows="1" cols="5" spellcheck="false" maxlength="8" placeholder="otftag" title="Enter an OpenType Feature Tag (e.g.: “smcp”)"></textarea></span></li>
<li class="spacer no_highlight width_100"></li>
<li id="unicode_char_planes" class="flex_justify_center no_highlight" title="Unicode Code Ranges"><select id="unicode_char_ranges_select" data-tab_order="13">
<option value="">Unicode Code Ranges</option>
<optgroup label="Basic Multilingual Plane"> <option id="BMP_Range_01" value="BMP_Range_01" data-block_start="0000" data-block_end="0FFF">BMP-01: U+0000–U+0FFF</option> <option id="BMP_Range_02" value="BMP_Range_02" data-block_start="1000" data-block_end="1FFF">BMP-02: U+1000–U+1FFF</option> <option id="BMP_Range_03" value="BMP_Range_03" data-block_start="2000" data-block_end="2FFF">BMP-03: U+2000–U+2FFF</option> <option id="BMP_Range_04" value="BMP_Range_04" data-block_start="3000" data-block_end="3FFF">BMP-04: U+3000–U+3FFF</option> <option id="BMP_Range_05" value="BMP_Range_05" data-block_start="4000" data-block_end="4FFF">BMP-05: U+4000–U+4FFF</option> <option id="BMP_Range_06" value="BMP_Range_06" data-block_start="5000" data-block_end="5FFF">BMP-06: U+5000–U+5FFF</option> <option id="BMP_Range_07" value="BMP_Range_07" data-block_start="6000" data-block_end="6FFF">BMP-07: U+6000–U+6FFF</option> <option id="BMP_Range_08" value="BMP_Range_08" data-block_start="7000" data-block_end="7FFF">BMP-08: U+7000–U+7FFF</option> <option id="BMP_Range_09" value="BMP_Range_09" data-block_start="8000" data-block_end="8FFF">BMP-09: U+8000–U+8FFF</option> <option id="BMP_Range_10" value="BMP_Range_10" data-block_start="9000" data-block_end="9FFF">BMP-10: U+9000–U+9FFF</option> <option id="BMP_Range_11" value="BMP_Range_11" data-block_start="A000" data-block_end="AFFF">BMP-11: U+A000–U+AFFF</option> <option id="BMP_Range_12" value="BMP_Range_12" data-block_start="B000" data-block_end="BFFF">BMP-12: U+B000–U+BFFF</option> <option id="BMP_Range_13" value="BMP_Range_13" data-block_start="C000" data-block_end="CFFF">BMP-13: U+C000–U+CFFF</option> <option id="BMP_Range_14" value="BMP_Range_14" data-block_start="D000" data-block_end="DFFF">BMP-14: U+D000–U+DFFF</option> <option id="BMP_Range_15" value="BMP_Range_15" data-block_start="E000" data-block_end="EFFF">BMP-15: U+E000–U+EFFF</option> <option id="BMP_Range_16" value="BMP_Range_16" data-block_start="F000" data-block_end="FFFF">BMP-16: U+F000–U+FFFF</option> </optgroup>
<optgroup label="Supplementary Multilingual Plane" data-block_start="10000" data-block_end="10FFF"> <option id="SMP_Range_01" value="SMP_Range_01">SMP-01: U+10000–U+10FFF</option> <option id="SMP_Range_02" value="SMP_Range_02" data-block_start="11000" data-block_end="11FFF">SMP-02: U+11000–U+11FFF</option> <option id="SMP_Range_03" value="SMP_Range_03" data-block_start="12000" data-block_end="12FFF">SMP-03: U+12000–U+12FFF</option> <option id="SMP_Range_04" value="SMP_Range_04" data-block_start="13000" data-block_end="13FFF">SMP-04: U+13000–U+13FFF</option> <option id="SMP_Range_05" value="SMP_Range_05" data-block_start="14000" data-block_end="14FFF">SMP-05: U+14000–U+14FFF</option> <option id="SMP_Range_06" value="SMP_Range_06" data-block_start="15000" data-block_end="15FFF">SMP-06: U+15000–U+15FFF</option> <option id="SMP_Range_07" value="SMP_Range_07" data-block_start="16000" data-block_end="16FFF">SMP-07: U+16000–U+16FFF</option> <option id="SMP_Range_08" value="SMP_Range_08" data-block_start="17000" data-block_end="17FFF">SMP-08: U+17000–U+17FFF</option> <option id="SMP_Range_09" value="SMP_Range_09" data-block_start="18000" data-block_end="18FFF">SMP-09: U+18000–U+18FFF</option> <option id="SMP_Range_10" value="SMP_Range_10" data-block_start="19000" data-block_end="19FFF">SMP-10: U+19000–U+19FFF</option> <option id="SMP_Range_11" value="SMP_Range_11" data-block_start="1A000" data-block_end="1AFFF">SMP-11: U+1A000–U+1AFFF</option> <option id="SMP_Range_12" value="SMP_Range_12" data-block_start="1B000" data-block_end="1BFFF">SMP-12: U+1B000–U+1BFFF</option> <option id="SMP_Range_13" value="SMP_Range_13" data-block_start="1C000" data-block_end="1CFFF">SMP-13: U+1C000–U+1CFFF</option> <option id="SMP_Range_14" value="SMP_Range_14" data-block_start="1D000" data-block_end="1DFFF">SMP-14: U+1D000–U+1DFFF</option> <option id="SMP_Range_15" value="SMP_Range_15" data-block_start="1E000" data-block_end="1EFFF">SMP-15: U+1E000–U+1EFFF</option> <option id="SMP_Range_16" value="SMP_Range_16" data-block_start="1F000" data-block_end="1FFFF">SMP-16: U+1F000–U+1FFFF</option> </optgroup>
<optgroup label="Supplementary Ideographic Plane" data-block_start="20000" data-block_end="20FFF"> <option id="SIP_Range_01" value="SIP_Range_01">SIP-01: U+20000–U+20FFF</option> <option id="SIP_Range_02" value="SIP_Range_02" data-block_start="21000" data-block_end="21FFF">SIP-02: U+21000–U+21FFF</option> <option id="SIP_Range_03" value="SIP_Range_03" data-block_start="22000" data-block_end="22FFF">SIP-03: U+22000–U+22FFF</option> <option id="SIP_Range_04" value="SIP_Range_04" data-block_start="23000" data-block_end="23FFF">SIP-04: U+23000–U+23FFF</option> <option id="SIP_Range_05" value="SIP_Range_05" data-block_start="24000" data-block_end="24FFF">SIP-05: U+24000–U+24FFF</option> <option id="SIP_Range_06" value="SIP_Range_06" data-block_start="25000" data-block_end="25FFF">SIP-06: U+25000–U+25FFF</option> <option id="SIP_Range_07" value="SIP_Range_07" data-block_start="26000" data-block_end="26FFF">SIP-07: U+26000–U+26FFF</option> <option id="SIP_Range_08" value="SIP_Range_08" data-block_start="27000" data-block_end="27FFF">SIP-08: U+27000–U+27FFF</option> <option id="SIP_Range_09" value="SIP_Range_09" data-block_start="28000" data-block_end="28FFF">SIP-09: U+28000–U+28FFF</option> <option id="SIP_Range_10" value="SIP_Range_10" data-block_start="29000" data-block_end="29FFF">SIP-10: U+29000–U+29FFF</option> <option id="SIP_Range_11" value="SIP_Range_11" data-block_start="2A000" data-block_end="2AFFF">SIP-11: U+2A000–U+2AFFF</option> <option id="SIP_Range_12" value="SIP_Range_12" data-block_start="2B000" data-block_end="2BFFF">SIP-12: U+2B000–U+2BFFF</option> <option id="SIP_Range_13" value="SIP_Range_13" data-block_start="2C000" data-block_end="2CFFF">SIP-13: U+2C000–U+2CFFF</option> <option id="SIP_Range_14" value="SIP_Range_14" data-block_start="2D000" data-block_end="2DFFF">SIP-14: U+2D000–U+2DFFF</option> <option id="SIP_Range_15" value="SIP_Range_15" data-block_start="2E000" data-block_end="2EFFF">SIP-15: U+2E000–U+2EFFF</option> <option id="SIP_Range_16" value="SIP_Range_16" data-block_start="2F000" data-block_end="2FFFF">SIP-16: U+2F000–U+2FFFF</option> </optgroup>
<optgroup label="Tertiary Ideographic Plane" data-block_start="30000" data-block_end="30FFF"> <option id="TIP_Range_01" value="TIP_Range_01">TIP-01: U+30000–U+30FFF</option> <option id="TIP_Range_02" value="TIP_Range_02" data-block_start="31000" data-block_end="31FFF">TIP-02: U+31000–U+31FFF</option> </optgroup>
<optgroup label="Supplementary Special-Purpose Plane" data-block_start="E0000" data-block_end="E0FFF"> <option id="SSP_Range_01" value="SSP_Range_01">SSP-01: U+E0000–U+E0FFF</option> </optgroup>
</select></li> </ol>
<ol id="font_specimen_adjustments" class="display_flex flex_row flex_grow_1">
<li class="no_highlight" data-inputid="font_size"><span class="flex_justify_center"><input type="range" id="font_size" data-tab_order="14" name="font_size" min="0" max="2" step="any"><label for="font_size">Font Size</label></span></li> <li class="no_highlight display_none" data-inputid="line_height"><span class="flex_justify_center"><input type="range" id="line_height" data-tab_order="15" name="line_height" min="-1.2" max="1.2" step="any"><label for="line_height">Line Height</label></span></li> <li class="no_highlight display_none" data-inputid="letter_spacing"><span class="flex_justify_center"><input type="range" id="letter_spacing" data-tab_order="16" name="letter_spacing" min="-100" max="100" step="1"><label for="letter_spacing">Letter Spacing</label></span></li> <li class="spacer no_highlight width_100"></li> <li data-inputid="text_color" class="display_flex no_highlight"><span class="flex_justify_center position_relative"><textarea id="text_color" class="whitespace_pre resize_none outline_none" data-tab_order="17" rows="1" cols="7" spellcheck="false" placeholder="CSS color"></textarea> Text Color</span></li> <li data-inputid="text_stroke_width" class="display_flex no_highlight"><span class="flex_justify_center"><input type="range" id="text_stroke_width" data-tab_order="18" name="font_size" min="-0.5" max="0.5" step="any" title="In supported browsers only."><label for="text_stroke_width">Text Stroke Width</label></span></li> <li data-inputid="text_stroke_color" class="display_flex no_highlight"><span class="flex_justify_center position_relative"><textarea id="text_stroke_color" class="whitespace_pre resize_none outline_none" data-tab_order="19" rows="1" cols="7" spellcheck="false" placeholder="CSS color"></textarea>Text Stroke Color</span></li>
</ol></div>`;
const content_font_sample_string = `ABCDEFGHIJKLMNOPQRSTUVWXYZ<br />abcdefghijklmnopqrstuvwxyz<br />0123456789<br />!"#$%&'()*+,-./:;<=>?@[\\]^_\`{|}~`;
const content_font_lorem_string = `Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.`;
const content_font_viewer = '<div id="font_file_viewer" class="position_absolute position_0 display_none"><div id="font_file_glyph_viewer" class="invert margin_0 padding_0 position_absolute position_0 display_none z_index_2"></div><ol id="font_file_grid" class="font_grid position_relative padding_0 align_center display_grid overflow_x_hidden"></ol></div>';
const content_font_elements = `<div id="font_specimen_viewer" class="padding_0 display_none">
<ol id="font_specimen_grid" class="font_grid display_grid overflow_visible"></ol>
<div id="font_specimen"> <div id="font_specimen_1" class="specimen border_bottom_x margin_0 overflow_visible normal" data-tab_order="1" contenteditable="true">${ content_font_sample_string }</div> <div id="font_specimen_2" class="specimen border_bottom_x align_left overflow_visible normal" data-tab_order="2" contenteditable="true" tabindex="0"><h2 id="specimen_2" class="margin_0 line_height_1 normal">Typography</h2><p id="specimen_2H4">The art of using types to produce impressions on paper, vellum, &c.</p></div> <div id="font_specimen_3" class="specimen border_bottom_x align_justify overflow_visible normal line_height_1" data-tab_order="3" contenteditable="true"><h3 id="specimen_3" class="margin_0 normal">S P E C I M E N</h3><p id="specimen_3H3" class="margin_0">Typography is the work of typesetters (also known as compositors), typographers, graphic designers, art directors, manga artists, comic book artists, graffiti artists, and, now, anyone who arranges words, letters, numbers, and symbols for publication, display, or distribution.</p></div> <div id="font_specimen_4" class="specimen overflow_visible normal" data-tab_order="4" contenteditable="true" tabindex="0"><div id="lorem" class="lorem align_justify">${ content_font_lorem_string }</div><div id="lorem_2" class="lorem align_justify">${ content_font_lorem_string }</div><div id="lorem_3" class="lorem align_justify">${ content_font_lorem_string }</div></div> </div>
<div id="font_specimen_glyph_viewer" class="background_grey_90 display_none overflow_visible normal"> <div id="font_specimen_glyph" class="flex_justify_center position_fixed position_0 z_index_2" data-scale="1"></div><div id="font_specimen_glyph_overlay" class="position_fixed position_0 background_grey_100 user_select_none z_index_1"></div> </div>
</div> ${ content_font_viewer }`;
const content_header_elements = `<header id="content_header" class="font_size_small z_index_3">
<div id="audio_wrapper" class="text_color_default background_grey_80 display_none">${ content_audio_elements }</div>
<div id="content_title_container" class="title display_flex text_color_default border_bottom">
<div id="title_buttons_left" class="display_flex padding_4_6 align_left"> <nav id="cuesheet_track_list_container_video" class="cuesheet_track_list_container background_grey_75" title="Cue sheet track list"><div class="box_shadow_menu display_none font_size_small position_absolute position_LR_0 z_index_1"><ul id="cuesheet_track_list_video" class="cuesheet_track_list border_bottom margin_0 padding_0 display_none"></ul></div></nav> <button id="reload_btn" class=" outline_none" tabindex="-1"><span></span></button> <button id="prev_next_btns" class="split_btn padding_0 position_relative display_none outline_none" tabindex="-1"><span id="prev_btn" class="prev_next_btn flex_justify_center"><span class="transform_rotate_270_contents">${ SVG_UI_Icons.chevron }</span></span><span id="next_btn" class="prev_next_btn flex_justify_center"><span class="display_flex transform_rotate_90_contents">${ SVG_UI_Icons.chevron }</span></span></button> </div>
<div id="content_title" class="pointer align_center hyphens_none line_height_1_4 flex_justify_center_row flex_grow_1"><div><span class="has_icon_before has_icon_after bold"></span></div></div>
<div id="title_buttons_right" class="display_flex padding_4_6 align_right"> <button id="scale" class="split_btn padding_0 position_relative display_none outline_none" tabindex="-1"><span id="decrease" class="flex_justify_center" title="Reduce"><span class="display_flex width_10px_contents">${ SVG_UI_Icons.minus }</span></span><span id="increase" class="flex_justify_center" title="Enlarge"><span class="display_flex width_10px_contents">${ SVG_UI_Icons.plus }</span></span></button> <button id="open_in_texteditor" class="display_none outline_none" title="Open in Text Editor" tabindex="-1"><span>Edit</span></button> <button id="save_svg" class="display_none whitespace_pre outline_none" title="Save glyph as svg"><span>Save SVG</span></button> <button id="close_btn" class="outline_none" tabindex="-1" title="Close Content"><span></span></button></div>
</div>
<div id="content_playlist_item" class="playlist_entry_container border_bottom background_grey_85 align_center display_none"><textarea id="content_playlist_item_textarea" class="text_color_default padding_4_6 border_0 outline_none" rows="3" spellcheck="false"></textarea></div>
${ content_font_toolbar }
</header>`;
switch(true) { // ASSEMBLE CONTENT ELEMENTS
case id === 'content_font_viewer': return content_font_viewer;
case id === 'content_text_elements': return content_text_elements;
default: return `<div id="content_pane" class="display_flex flex_column flex_grow_1 position_relative padding_0" data-content="has_null"> ${ content_header_elements } <main id="content_container" class="display_flex position_relative background_grey_90 no_hover margin_0 padding_0"> ${ SVG_UI_Icons.spinner } <ol id="content_grid" class="content_el" data-kind="grid"></ol> ${ content_text_elements } <div id="content_font" class="content_el background_grey_90 hyphens_none position_relative text_color_default" spellcheck="false" data-kind="font">${ content_font_elements }</div> <div id="content_image_container" class="content_el background_grey_95 position_relative margin_0" data-kind="image"><img id="content_image" class="content_el position_relative" src="#" alt="" tabindex="0" /></div> <embed id="content_pdf" class="content_el position_relative border_0" tabindex="0" data-kind="pdf"> <div id="content_video_container" class="display_none track_title_container"><video id="content_video" class="content_el media_player background_grey_95 media" controls data-kind="video">Your browser does not support the video tag.</video></div> <iframe id="content_iframe" class="content_el position_relative border_0" name="content_iframe" sandbox="allow-scripts allow-same-origin allow-modals allow-popups" tabindex="0"></iframe> <iframe id="content_iframe_utility" class="display_none" name="content_iframe_utility" sandbox="allow-scripts allow-same-origin allow-modals allow-popups" tabindex="0"></iframe> </main></div>`;
}
}
//==============================//
// UTILITIES HTML (warnings and help)
function Utilities_Elements(body_id) {
let utilities_warning_elements = `<header id="warnings_header" class="text_color_default background_grey_85"><h3 id="warning_header" class="display_none margin_0"><span>Warning:</span></h3><h3 id="make_playlist_header" class="display_none margin_0 normal"><span>Make Playlist/Filelist (.m3u)</span></h3></header>
<ul id="warnings" class="text_color_default background_grey_85"> <li id="warning_open_font" class="warning">Are you sure you want to close the font file?</li> <li id="warning_close_font" class="warning">Are you sure you want to close the font file?</li> <li id="warning_unsaved_text" class="warning">You have unsaved changes.</li> <li id="warning_clear_text" class="warning">Are you sure you want to clear all your text?</li> <li id="warning_local_file" class="warning">Can’t load local file from non-local page.</li> <li id="warning_close_playlist" class="warning">Are you sure you want to close the playlist?</li> <li id="warning_local_playlist" class="warning">This playlist contains local files. <br /> Please reload this playlist from a local page in order to play them.</li> <li id="warning_non_local_file" class="warning">This is a non-local file/dir/link. Would you like to open it in a new window?</li> <li id="warning_make_playlist" class="warning"><form id="make_playlist_form" action="#"><fieldset class="margin_0 padding_0 border_0"> <ul id="make_playlist_options_sublist"><li><input name="make_playlist" type="radio" id="all_items" checked><label for="all_items">All items</label></li> <li class="indent"><input name="make_playlist" type="radio" id="directories_only"><label for="directories_only">Directories only</label></li> <li class="indent"><input name="make_playlist" type="radio" id="files_only"><label for="files_only">Files only</label></li> <li><input name="make_playlist" type="radio" id="media_files_only"><label for="media_files_only">All media files</label></li> <li class="indent"><input name="make_playlist" type="radio" id="audio_files_only"><label for="audio_files_only">Audio files only</label></li> <li class="indent"><input name="make_playlist" type="radio" id="video_files_only"><label for="video_files_only">Video files only</label></li> <li><input name="make_playlist" type="radio" id="all_non_media_files"><label for="all_non_media_files">All non-media items</label></li></ul></fieldset></form></li> </ul>
<div id="warning_buttons_container" class="display_flex flex_column background_grey_90"><div id="warning_buttons" class="display_flex flex_row"> <button id="warning_btn_dont_save" class="warning_button">Don’t Save</button> <button id="warning_btn_cancel" class="warning_button">Cancel</button> <button id="warning_btn_clear" class="warning_button">Clear</button> <button id="warning_btn_save" class="warning_button">Save</button> <button id="warning_btn_ok" class="warning_button">OK</button> </div></div>`;
let utilities_help_elements = `
<header id="help_header" class="title padding_4_6 position_LR_0 text_color_default border_bottom background_grey_75 align_center position_fixed z_index_3"><button style="visibility:hidden;float:left"><span>Close</span></button><span class="bold">HELP</span><button id="close_help" class="focus outline_none" style="float:right;"><span>Close</span></button></header>
<nav id="help_contents" class="align_center background_grey_85 no_hover border_bottom"><h2 id="contents" style="margin-bottom:0;"><strong>CONTENTS</strong></h2> <ul class="margin_0 no_highlight bold"><li class="no_highlight"><a class="internal" href="#about">I. About this Script</a></li><li class="no_highlight"><a class="internal" href="#shortcuts">II. Keyboard Shortcuts</a></li><li class="no_highlight"><a class="internal" href="#usage">III. Usage</a></li><li class="no_highlight"><a class="internal" href="#other">IV. Other Script Functions</a></li><li class="no_highlight"><a class="internal" href="#troubleshooting">V. Troubleshooting</a></li></ul> </nav>
<section class="line_height_1_4">
<article><h2 id="about"><strong>I. ABOUT THIS SCRIPT</strong></h2>
<dl><dt><a href="https://openuserjs.org/scripts/gaspar_schot/Supercharged_Local_Directory_File_Browser" class="has_icon_before link" target="_blank">Script home: openuserjs.org</a></dt></dl> <dl><dt>GENERAL INFORMATION</dt> <dd>This script works on <strong>local directories</strong>, as well as many remote server-generated index pages or “<strong>open directories</strong>”.</dd> <dd>By default, userscripts do not run on local file:/// urls, so for this script to work on local directories you will need to enable it in your browser’s extension settings (e.g.: For Tampermonkey in Chrome, open the Chrome extensions page, click the details button for Tampermonkey and check ‘Allow access to file URLs’).</dd> <dd>To make the script work on a remote <strong>open directory</strong>, you must add its URL to the list of allowed sites in the settings for this userscript, as provided by your userscript manager.</dd> <dd>Because server configurations vary, the script may not work perfectly (or at all) on some open directories. You may also need to allow—or block—javascript on some ODs, and/or allow cookies. Please let me know if you encounter any problems.</dd> <dd>This script was developed in the latest version of Vivaldi, running on the latest MacOS. It has been <em>minimally</em> tested in other Chrome-based browsers, Safari, and Firefox, and has been <strong>not</strong> been tested in any other browsers or OSes. No effort has been made to ensure compatibility with older browsers. Please report any issues. </dd></dl> <dl><dt><span class="invert" style="float:left; margin:4px 6px 0 0;">${ SVG_UI_Icons.ui_layout }</span>The UI consists of two main parts:</dt> <dd>(1) the directory list <strong>SIDEBAR</strong> on the left and </dd> <dd>(2) the <strong>CONTENT PANE</strong> on the right.</dd> <dd>The Sidebar shows all the items in the current directory, while the Content Pane shows a preview of items selected in the Sidebar.</dd></dl> <dl><dt>1. The <strong>SIDEBAR</strong> comprises a <strong>HEADER</strong>, the <strong>DIRECTORY LIST</strong> itself, and a <strong>FOOTER</strong>.</dt> <dd>The <strong>Sidebar</strong> is resizeable; it can be hidden completely by clicking the double-chevron icon at the Sidebar top right or typing <b>⌘\</b>.</dd></dl>
<dl><dt>1A. The <strong>SIDEBAR HEADER</strong> contains a <strong>Parent Directory</strong> button, a <strong>Parent Directories</strong> menu which displays separate links for all the parent directories, and the <strong>Main Menu</strong>.</dt> <dd>Below these are <strong>Show Details</strong> and <strong>Show Invisibles</strong> items, a <strong>Show Grid</strong> button (when appropriate), and sort by <strong>Name</strong> or <strong>Default</strong> items.</dd> <dd>If <strong>Show Details</strong> is selected, additional sorting options are shown, along with the <strong>Text Editor</strong> item.</dd> <dd>All of these items are also available in the Main Menu, and some can be toggled via keyboard shortcuts (see below).</dd></dl> <dl><dt>1B. The <strong>DIRECTORY LIST</strong> displays the items in the current directory.</dt> <dd>Directory items can be selected with the arrow keys or by clicking.</dd> <dd>Selecting an item will preview it in the content pane.</dd> <dd>Multiple directories, fonts, or images can be selected with shift+arrowkey, cmd+click, or shift+click.</dd> <dd>Directories can be previewed in the content pane or toggled open in the sidebar to create a “tree view” of the directory by clicking the folder icon or typing Cmd→.</dd></dl> <dl><dt>1C. The <strong>SIDEBAR FOOTER</strong> displays <strong>Stats</strong> for the items in the current directory.</dt> <dd>Detailed stats can be shown by clicking the footer.</dd> <dd>There is also a popup menu on the right of the footer with options to display the Sidebar directory or the raw directory index in the Content Pane.</dd></dl> <dl><dt>2. The <strong>CONTENT PANE</strong> displays the selected sidebar item.</dt> <dd>The content pane can be focused by tabbing from the sidebar or clicking. Links in HTML files can be navigated via the tab key.</dd> <dd>Clicking the title of the content pane title reveals an EXTM3U-formatted playlist item for use in an EXTM3U file.</dd></dl> <dl><dt>Previewed Content</dt></dl> <dl><dt>Previewed Directories</dt> <dd>Previewed directories in the Content Pane inherit the sorting and other UI preferences from the Sidebar directory list. They can be navigated independently from the Sidebar via the “Parent Directory” link in the header or Cmd-Up Arrow.</dd> <dd>An item in the content pane header allows previewed directories to be opened into the sidebar.</dd> <dd>A selected item can be previewed by pressing the spacebar. This is similar to the “quicklook” function in MacOS.</dd> <dd>Double-clicking a selected directory list item or typing Cmd-Down Arrow will open it in the content pane, replacing the previewed directory. Closing the item via the Close Button or Cmd-W will restore the original previewed directory.</dd></dl> </article>
<article><h2 id="shortcuts" class="border_top_x padding_top_1rem"><strong>II. KEYBOARD SHORTCUTS</strong></h2>
<ul id="utilities_help" class="info_list background_grey_80 font_size_small border_all padding_0 no_highlight"> <li class="info_list_header display_grid align_center bold no_hover no_highlight"><span class="col_1">SHORTCUT</span><span class="col_2">DESCRIPTION</span></li> <li class="display_grid no_hover no_highlight"><span class="col_1"><kbd>↑</kbd> or <kbd>↓</kbd></span><span class="col_2">Select the previous/next sidebar item or previewed directory item.<br />If audio is playing, and the previous/next file is also audio, the file will be highlighted but not loaded in the audio player; press <kbd>return</kbd> to load it.</span></li> <li class="display_grid no_hover no_highlight"><span class="col_1"><kbd>←</kbd> or <kbd>→</kbd></span><span class="col_2">Select prev/next item of the same kind as the current selection.<br />If current selection is a media file, select and begin playback of the next media item.</span></li> <li class="display_grid no_hover no_highlight"><span class="col_1"><kbd>⌥</kbd><kbd>←</kbd> or <kbd>→</kbd></span><span class="col_2">Skip media ±10 seconds.</span></li> <li class="display_grid no_hover no_highlight"><span class="col_1"><kbd>⌥</kbd><kbd>⇧</kbd><kbd>←</kbd> or <kbd>→</kbd></span><span class="col_2">Skip media ±30 seconds.</span></li> <li class="display_grid no_hover no_highlight"><span class="col_1"><kbd>⌘</kbd><kbd>↑</kbd></span><span class="col_2">Go to parent directory.</span></li> <li class="display_grid no_hover no_highlight"><span class="col_1"><kbd>⌘</kbd><kbd>↓</kbd></span><span class="col_2">Go to selected sidebar directory.</span></li> <li class="display_grid no_hover no_highlight"><span class="col_1"><kbd>⌘</kbd><kbd>→</kbd></span><span class="col_2">Open selected sidebar directory as subdirectory.</span></li> <li class="display_grid no_hover no_highlight"><span class="col_1"><kbd>⌘</kbd><kbd>←</kbd></span><span class="col_2">1. Close selected subdirectory, or <br />2. jump from selected subdirectory item to parent directory, or <br />3. jump up to closest open subdirectory, or <br />4. jump up to top of directory list.</span></li> <li class="display_grid no_hover no_highlight"><span class="col_1"><kbd>⇧</kbd><kbd>↑</kbd> or <kbd>↓</kbd> or <kbd>←</kbd> or <kbd>→</kbd></span><span class="col_2">Select multiple sidebar items: directories, images, or fonts only. Multiple images and fonts will open a grid view in the content pane.</span></li> <li class="display_grid no_hover no_highlight"><span class="col_1"><kbd>⇧</kbd><kbd>Click</kbd></span><span class="col_2">Select a range of sidebar items: directories, images, or fonts only. Multiple images and fonts will open a grid view in the content pane.</span></li> <li class="display_grid no_hover no_highlight"><span class="col_1"><kbd>Escape</kbd></span><span class="col_2">Close menus and help, unfocus textareas and content pane, etc.</span></li> <li class="display_grid no_hover no_highlight"><span class="col_1"><kbd>Return</kbd></span><span class="col_2">Open selected sidebar directory, select file, or pause/play media.</span></li> <li class="display_grid no_hover no_highlight"><span class="col_1"><kbd>Space</kbd></span><span class="col_2">Pause/Play media files (if media player loaded).<br />“Quicklook” selected content pane directory list item.</span></li> <li class="display_grid no_hover no_highlight"><span class="col_1"><kbd>⌘</kbd><kbd>A</kbd></span><span class="col_2">Select all sidebar items of selected type; works with dirs, images, and fonts. Images and fonts will open a grid view in the content pane.</span></li> <li class="display_grid no_hover no_highlight"><span class="col_1"><kbd>Tab</kbd></span><span class="col_2">Toggle focus between sidebar and content pane.</span></li> <li class="display_grid no_hover no_highlight"><span class="col_1"><kbd>⌘</kbd><kbd>⇧</kbd><kbd>D</kbd></span><span class="col_2">Toggle file details (size, date modified, kind) in some index page types.</span></li> <li class="display_grid no_hover no_highlight"><span class="col_1"><kbd>⌘</kbd><kbd>E</kbd></span><span class="col_2">Toggle main menu.</span></li> <li class="display_grid no_hover no_highlight"><span class="col_1"><kbd>⌘</kbd><kbd>⇧</kbd><kbd>E</kbd></span><span class="col_2">Show text editor.</span></li> <li class="display_grid no_hover no_highlight"><span class="col_1"><kbd>⌘</kbd><kbd>G</kbd></span><span class="col_2">Show or reload image or font grids.</span></li> <li class="display_grid no_hover no_highlight"><span class="col_1"><kbd>⌘</kbd><kbd>⇧</kbd><kbd>I</kbd></span><span class="col_2">Toggle invisible files.</span></li> <li class="display_grid no_hover no_highlight"><span class="col_1"><kbd>⌘</kbd><kbd>⇧</kbd><kbd>J</kbd></span><span class="col_2">Go to item by row number.</span></li> <li class="display_grid no_hover no_highlight"><span class="col_1"><kbd>⌘</kbd><kbd>⇧</kbd><kbd>O</kbd></span><span class="col_2">Open selected sidebar item in new window/tab.</span></li> <li class="display_grid no_hover no_highlight"><span class="col_1"><kbd>⌘</kbd><kbd>R</kbd></span><span class="col_2">Reload grids and previewed content, reset scaled images/fonts, reset media files to beginning.</span></li> <li class="display_grid no_hover no_highlight"><span class="col_1"><kbd>⌘</kbd><kbd>W</kbd></span><span class="col_2">Close previewed content (doesn’t work in all browsers; use close button instead), or close window if no content is being previewed.</span></li> <li class="display_grid no_hover no_highlight"><span class="col_1"><kbd>⌘</kbd><kbd>⇧</kbd><kbd><</kbd> or <kbd>></kbd></span><span class="col_2">Scale preview items and grids.</span></li> <li class="display_grid no_hover no_highlight"><span class="col_1"><kbd>⌘</kbd><kbd>\\</kbd></span><span class="col_2">Toggle sidebar.</span></li> <li class="display_grid no_hover no_highlight"><span class="col_1"><kbd>⇧</kbd><kbd>⌘</kbd><kbd>\\</kbd></span><span class="col_2">Toggle text editor split view.</span></li></ul> </article>
<article><h2 id="usage" class="border_top_x padding_top_1rem"><strong>III. USAGE</strong></h2>
<p><span class="width_14px_contents">${ SVG_UI_Icons.menu }</span><strong> MAIN MENU</strong> (⌘+E)<br />The Main Menu contains the following top-level items:<p>
<ul class="border_all no_highlight bold" style="display:inline-block;"> <li class="no_highlight padding_4_6 border_bottom">1. Go to item... (⌘+⇧+J)</li> <li class="no_highlight padding_4_6 border_bottom">2. Sort by... ${SVG_UI_Icons.arrow}</li> <li class="no_highlight padding_4_6">3. UI Preferences ${SVG_UI_Icons.arrow}</li> <li class="no_highlight padding_4_6">4. File Handling Preferences ${SVG_UI_Icons.arrow}</li> <li class="no_highlight padding_4_6">5. Media Preferences ${SVG_UI_Icons.arrow}</li> <li class="no_highlight padding_4_6">6. Text Editing Preferences ${SVG_UI_Icons.arrow}</li> <li class="no_highlight padding_4_6 border_bottom">7. Default Preferences</li> <li class="no_highlight padding_4_6 border_bottom">8. Playlists ${SVG_UI_Icons.arrow}</li> <li class="no_highlight padding_4_6 border_bottom">9. Open Font File...</li> <li class="no_highlight padding_4_6">10. Script Home</li> <li class="no_highlight padding_4_6">11. Help</li> <li class="no_highlight padding_4_6">12. Buy me a Coffee</li> <li class="no_highlight padding_4_6">13. Contact</li></ul>
<dl class="border_top_x padding_top_1rem"><dt>1. Go to Item...</dt> <dd>Select a sidebar item by its row number (displayed if "Show Numbers" pref is set). Useful especially for large directories. Directory list can also be navigated by typed strings.</dd></dl>
<p class="border_top_x"><strong>2. SORT BY...</strong> ${SVG_UI_Icons.arrow}<br />Sort directory items by <strong>Name</strong>, <strong>Size</strong>, <strong>Date</strong>, <strong>Kind</strong>, <strong>Extension</strong>, <strong>Duration</strong> (media items only). <strong>Default</strong> sort = sort items by Name, with directories on top.</p>
<dl><dd>Clicking the sort preference again will reverse the sort.</dd> <dd>Sorting preferences are also available in the Sidebar Header.</dd> <dd>Note that many server configurations don’t report directory size, so when sorting by size, directories will be on top, sorted by name.</dd></dl>
<p class="border_top_x"><strong>3. UI PREFERENCES</strong> ${SVG_UI_Icons.arrow}<br />Selecting these preferences items will add the new setting to the URL query string, so that the setting will persist as you navigate within the same window, or if you bookmark the page.</p>
<dl><dt>a. Light Theme/Dark Theme</dt> <dd>Change the UI theme.</dd></dl> <dl><dt>b. Alternate Backgrounds</dt> <dd>Alternate background colors for directory list items.</dd></dl> <dl><dt>c. Show Numbers</dt> <dd>Show numbers for directory list items.</dd></dl> <dl><dt>d. Use Custom Icons</dt> <dd>If enabled, use custom file and directory icons provided by the script; if disabled, use the browser’s default icons.</dd></dl> <dl><dt>e. Show Image Thumbnails</dt> <dd>Replace image file icons with a thumbnail icon of the image itself. Enabling this setting may slow down page load, because each image file in the directory must be downloaded.</dd></dl> <dl><dt>f. Use Large Image Thumbnails</dt> <dd>If “Show Image Thumbnails” is also enabled, a larger version of the image thumbnail is displayed.</dd></dl> <dl><dt>g. Always Show Image Thumbnails</dt> <dd>Image thumbnails are always shown, no matter how many images are in the directory. This overrides the default behavior which automatically disables thumbnail display for directories containing more than 2000 items in order to improve performance.</dd></dl> <dl><dt>h. Audio Player at Top</dt> <dd>Disable this item in order to position the audio player at the bottom of the content pane.</dd></dl> <dl><dt>i. Set UI Font</dt> <dd>Set a custom font for the UI.</dd></dl> <dl><dt>j. Scale UI</dt> <dd>Scale the entire UI (50%–150%). Double-click the label to quickly reset the scale to 100%.</dd></dl>
<p class="border_top_x"><strong>4. FILE HANDLING PREFERENCES</strong> ${SVG_UI_Icons.arrow}</p>
<dl><dt>a. Show/Hide Invisible Items</dt> <dd>It does what it says on the tin…</dd></dl> <dl><dt>b. Show/Hide Ignored Items</dt> <dd>Ignored items include files that the browser cannot handle natively (e.g., common Office and graphics files, various binary files, etc.). Hide them to reduce clutter.</dd></dl> <dl><dt>c. Ignore Ignored Items</dt> <dd>Prevent normal browser behavior for handling such files, which is to open a download file dialog.</dd></dl> <dl><dt>d. Autoload Index Files</dt> <dd>Automatically load “index.html” or similar files in the Content Pane when the directory loads.</dd></dl>
<p class="border_top_x"><strong>5. MEDIA PREFERENCES</strong> ${SVG_UI_Icons.arrow}</p>
<dl><dt>a. Autoload Media</dt> <dd>If enabled, automatically load the first media file (audio or video) when the directory loads.</dd> <dd>For audio files, this will also automatically load any “cover art” (image file) found in the same directory. The script will first look for an image file with <i>exactly</i> the same name as the currently selected/playing audio file, followed in order by files containing the words “cover”, “front”, “album”, “jacket”, “sleeve”, “cd”, “disc”, “insert”, “liner”, or “notes.” If it finds no matching files, it will load the first image file it finds. Cover art will be automatically loaded whenever a new audio file is selected for playback.</dd></dl> <dl><dt>b. Autoplay Media</dt> <dd>If enabled, play the next media file when the currently playing media file ends.</dd></dl> <dl><dt>c. Play All Media Files</dt> <dd>If disabled (and Autoplay Media enabled), only play media of the same type (audio or video) as the currently playing media file.</dd></dl> <dl><dt>d. Loop Media Playback</dt> <dd>Loop media playback to the first media item when the last media item ends and continue playing. This option can also be enabled from the audio player.</dd></dl> <dl><dt>e. Shuffle Media Playback</dt> <dd>Randomize the order of media playback. This option can also be enabled from the audio player.</dd> <dd>A media item selected via the up/down arrow keys will be played after the currently playing item. This give you the option to play a specific item while continuing with shuffle play.</dd></dl>
<p class="border_top_x"><strong>6. TEXT EDITING PREFERENCES</strong> ${SVG_UI_Icons.arrow}</p>
<dl><dt>a. Text Editing Enabled/Disabled</dt><dd>If text editing is disabled, text files are displayed as normal files.</dd></dl> <dl><dt>b. Text Editing Options</dt><dd>Toggle the Text Editor. Select Editor UI theme: Default = same as main UI. Toggle split view. Select view of raw text, preview text, rendered HTML.</dd></dl> <dl class="border_top_x padding_top_1rem padding_bottom_1rem"><dt>7. DEFAULT PREFERENCES</dt><dd>Resets UI to defaults by removing manually set preferences from the URL query string.</dd></dl>
<p class="border_top_x"><strong>8. PLAYLISTS</strong> ${SVG_UI_Icons.arrow}</p>
<dl><dt>a. Open Playlist/Filelist…</dt> <dd>Click to load a local .m3u file. See below for more details.</dd></dl> <dl><dt>b. Make Playlist/Filelist…</dt><dd>Make an .m3u playlist/filelist of the items in the current sidebar directory, with option to include audio only, video only, all media, all non-media, all items, directories or files only.</dd></dl> <dl class="border_top_x padding_top_1rem"><dt><strong>9. OPEN FONT FILE…</strong></dt> <dd>Load a local font file to view its complete glyph repertoire in a grid and information about the font.</dd> <dd>Note that this function is different from previewing a font from the sidebar.</dd> <dd>Font file glyph grids can be navigated with the arrow keys. Individual glyphs can be selected by clicking them or pressing <strong>Return</strong>.</dd> <dd>Individual glyphs may be saved as .svg files.</dd></dl> <dl class="border_top_x padding_top_1rem"><dt><strong>10. SCRIPT HOME</strong></dt> <dd><strong><a href="https://openuserjs.org/scripts/gaspar_schot/Supercharged_Local_Directory_File_Browser" class="link text_color_default" target="_blank">openuserjs.org</a></strong>.</dd></dl> <dl><dt><strong>11. HELP</strong></dt><dd>Show this help page.</dd></dl> <dl><dt><strong>12. BUY ME A COFFEE</strong></dt><dd><strong><a id="donate_link" class="ignore_warning" href="https://www.buymeacoffee.com/fiLtliTFxQ" target="_blank" rel="noopener">Coding is a lot of work...</a></strong></dd></dl> <dl><dt><strong>13. CONTACT</strong></dt><dd><strong><a id="contact_link" class="ignore_warning" href="mailto:[email protected]">Email</a></strong> me about anything to do with the script.</dd></dl> </article>
<article><h2 id="other" class=" border_top_x padding_top_1rem"><strong>IV. OTHER SCRIPT FUNCTIONS</strong></h2>
<dl><dt>NAVIGATION</dt> <dd>Use the up and down arrow keys to navigate items in the sidebar and previewed directories in the content pane.</dd> <dd>Use the left and right arrow keys to navigate items of the same kind as the currently selected item.</dd> <dd>Use the Tab key to toggle the focus between the sidebar and the content pane.</dd> <dd>Type a letter or letters to navigate the directory by file name.</dd> <dd>Type <b>⌘↓</b> to navigate to the selected directory.</dd> <dd>Click a directory icon in the sidebar or select it and type <b>⌘→</b> to open subdirectory; to close, click the icon again or type <b>⌘←</b>.</dd></dl> <dl><dt>IMAGES, FONTS, and FONT GLYPHS</dt><dd>These previewed items can be scaled with <b>⌘+/–</b> keys.</dd></dl> <dl><dt>FONT and IMAGE GRIDS</dt><dd>If a directory contains fonts and/or image files, the “Show Grid” icon will appear in the sidebar. Click it or type <b>⌘G</b> to show a grid of the available items.</dd> <dd>Grids can be navigated with the arrow keys, and individual grid items may be viewed by clicking them or pressing <b>Return</b>.</dd> <dd>When a grid item is being viewed, the grid can still be navigated with the arrow keys.</dd> <dd>Closing a selected grid item will show the grid again.</dd></dl> <dl><dt>PLAYLISTS AND FILELISTS (m3u)</dt><dd>The script supports basic .m3u playlists containing links to audio or video files, but it also has custom support for “filelists,” which are standard .m3u files that contain links to <i>any</i> type of file or directory.</dd> <dd>Playlist files can be opened via the menu item.</dd> <dd>However, for ease of use, if you change the extension of an ordinary .m3u file to .txt, the script will read it normally as an editable text file. Double-clicking such a file in the sidebar or typing <b>⌘↓</b> or <b>⌘+Return</b> will open it as a playlist/filelist. Please note that the text file must begin with “#EXTM3U&sdquo; for this work.</dd></dl> <dl><dt>CUE SHEETS (cue)</dt><dd>When a media file (audio or video) is loaded, the script will look for a .cue file in the same directory with <i>EXACTLY</i> the same name as the media file.</dd> <dd>If it finds one, it will load the Track ID, the PERFORMER, the TITLE, and the INDEX (time position) into a menu next to the audio player; there is no support for other commands.</dd> <dd>Tracks can be selected by clicking the item, and played or paused by clicking the selected item.</dd> <dd>.cue files can also be selected independently in the sidebar and edited and saved (locally). This may be handy for creating “on the fly” bookmarks for a long media track before closing the page.</dd> <dd>Note that you can also create and save (locally) a new .cue file by using the Text Editor.</dd> <dd>Note (MacOS): If you prefer not to clutter the sidebar with .cue files, you may make them invisible by adding a dot to beginning of the file name; the script will still find them.</dd></dl> </article>
<article><h2 id="troubleshooting" class="border_top_x padding_top_1rem"><strong>V. TROUBLESHOOTING</strong></h2>
<dl><dt>The script doesn’t work with a specific directory.</dt><dd>If you have a javascript blocker installed in your browser (and if you don’t, you should), try disabling some of the site-specific scripts and XHR requests, as they may be interfering with the execution of this script.</dd> <dd>Alternately, if you do have a javascript blocker installed, you may need to allow some scripts and XHR requests instead.</dd> <dd>If the open directory still does not display correctly, check to see if cookies from the site are blocked.</dd> <dd>Try deleting preferences from the Main Menu or removing the query string from the URL in the browser.</dd></dl> <dl><dt>A specific item in a directory does not display correctly.</dt><dd>Confirm that the file is one that browser is capable of rendering. This script cannot display files that the browser itself cannot display.</dd> <dd>If the item is from a playlist (m3u) and links to a remote site (e.g., archive.org), check your javascript blocker and cookies for any that need to be allowed from that site.</dd></dl> <dl><dt>If you think you have found a bug, please <a class="ignore_warning" href="mailto:[email protected]"><b><i>contact me</i></b></a>.</dt></dl><p> </p>
</article></section>`;
let help_elements = ''; if ( body_id === 'top_body' ) { help_elements = `<aside id="help_container" class="background_grey_95 text_color_default no_hover display_none">${ utilities_help_elements }</aside>`; }
return `<div id="utilities" class="position_absolute display_none position_LR_0 z_index_9999"> <aside id="warnings_container" class="overflow_hidden background_grey_90 hyphens_none z_index_9999">${ utilities_warning_elements }</aside> ${ help_elements } </div>`;
}
// ===> END UI HTML
//==============================//
// ===> STYLES
const background_images = `
.menu_item::before { content:""; width:12px; max-width:12px; min-width:12px; height:9px; margin:2px 0 -2px; background-position:center; background-repeat:no-repeat; display:flex; }
.submenu .menu_item::before { width:24px; max-width:24px; min-width:24px; }
.has_background, .has_background_before::before, .has_background_after::after { background-repeat:no-repeat; background-position:center; background-color:transparent !important; }
.bookmark > a::before { background-image:${ get_SVG_UI_Icon("bookmark") }; }
:is(.sort_by_default #menu_sort_by_default, .sort_by_name #menu_sort_by_name, .sort_by_duration #menu_sort_by_duration, .sort_by_size #menu_sort_by_size, .sort_by_date #menu_sort_by_date, .sort_by_kind #menu_sort_by_kind, .sort_by_ext #menu_sort_by_ext, #menu_theme_container, #toggle_text_editing) .menu_item::before, :is(.sort_by_default #sort_by_default, .sort_by_name #sort_by_name, .sort_by_duration #sort_by_duration, .sort_by_size #sort_by_size, .sort_by_date #sort_by_date, .sort_by_kind #sort_by_kind, .sort_by_ext #sort_by_ext) span::before, .loop_media #loop_media_menu::before, .shuffle_media #shuffle_media_menu::before, .background_color_check_mark::before, .texteditor_view_raw #toggle_texteditor_raw::before, .texteditor_view_styled #toggle_texteditor_preview::before, .texteditor_view_html #toggle_texteditor_html::before, body:not(.text_editing_enable_false) #text_editing_enable::before, .texteditor_view_html #texteditor_view_html::before, .cuesheet_track.selected .cue_track_id::before, .menu_item.checkmark::before
{ background-image:${ get_SVG_UI_Icon("check_mark") }; }
:is( .show_invisibles_false #show_invisible_items, .alternate_background_false #alternate_background, .show_numbers_false #show_numbers, .use_custom_icons_false #use_custom_icons, .show_image_thumbnails_false #show_image_thumbnails, .show_image_thumbnails_always_false #show_image_thumbnails_always, .show_large_image_thumbnails_false #show_large_image_thumbnails, .show_ignored_items_false #show_ignored_items, .ignore_ignored_items_false #ignore_ignored_items, .autoload_index_files_false #autoload_index_files, .media_autoload_false #media_autoload, .media_autoplay_false #media_autoplay, .media_play_all_false #media_play_all, .texteditor_split_view_false:not(.has_texteditor) #texteditor_split_view ) .menu_item.checkmark::before, body.audio_player_on_top_false #audio_player_on_top .menu_item.checkmark::before
{ background-image:none; }
.sort_by_default #sort_by_default span::after, .sort_by_name #sort_by_name span::after, .sort_by_duration #sort_by_duration span::after, .sort_by_size #sort_by_size span::after, .sort_by_date #sort_by_date span::after, .sort_by_kind #sort_by_kind span::after, .sort_by_ext #sort_by_ext span::after { background-image:${ get_SVG_UI_Icon("chevron") }; background-size:75%; transform:rotate(180deg); }
.is_error #sidebar_nav, .is_error #current_dir_path span::before { background-image:${ get_SVG_UI_Icon("error") }; }
.is_error #sidebar_nav { background-repeat:no-repeat; background-position:center top 6rem; background-size:6rem;}
.is_error #current_dir_path span::before { float:none; display:inline-flex; margin:0 0 -2px 0; width:24px; }
#content_pane[data-content="has_ignored"] #content_container { background-image:${ get_SVG_UI_File_Icon('file_icon_ignored') }; background-size:28px; }
#content_pane.has_audio[data-content="has_null"]:not([data-loaded="unloaded"]) #content_container, #content_pane.has_audio:not([data-content]) #content_container, .has_audio #content_pane[data-content="has_null"]:not([data-loaded="unloaded"]) #content_container, .has_audio #content_pane:not([data-content])[data-loaded="loaded"] #content_container
{ background-image:${ get_SVG_UI_Icon("music") }; }
${ CSS_UI_Icon_Rules() }
#sidebar_menu_main ul a::before { background-image:${ get_SVG_UI_File_Icon('file_icon_file') }; }
#sidebar_menu_main ul a[href^="file"]::before, #current_dir_path span::before { background-image:${ get_SVG_UI_File_Icon('file_icon_dir') }; margin-bottom:-3px; }
#sidebar_menu_main ul a[href^="http"]::before { background-image:${ get_SVG_UI_File_Icon('file_icon_htm') }; }
body.use_custom_icons_false .dir .has_icon_before_before { background-image:${ get_SVG_UI_File_Icon('file_icon_dir_default') }; background-size:auto 13px; }
body.use_custom_icons_false.show_image_thumbnails_false .file:not(.app) .has_icon_before_before, body.use_custom_icons_false:not(.show_image_thumbnails_false) .file:not(.app) .has_icon_before_before
{ background-image:${ get_SVG_UI_File_Icon('file_icon_file_default') }; background-size:auto 13px; }
body:not(.use_custom_icons_false).show_image_thumbnails_false .image .has_icon_before_before { background-image:${ get_SVG_UI_File_Icon('file_icon_image') } }
.has_playlist #current_dir_path span::before { background-image:${get_SVG_UI_File_Icon('file_icon_playlist')}; display:inline-flex; margin:-2px 0 0; width:24px; vertical-align:middle;}
.dirlist_item.dir:not(.has_subdirectory) .has_icon_before_before:hover { background-image:${ get_SVG_UI_Icon('chevron') }; transform:rotate(90deg); filter:invert(1); }
.dirlist_item.dir.has_subdirectory .has_icon_before_before:hover { background-image:${ get_SVG_UI_Icon('chevron') }; transform:rotate(180deg); filter:invert(1); }
.dirlist_item.non_local .name_span span::before { background-image:${ get_SVG_UI_Icon('external_link') }; content:""; width:20px; min-width:20px; height:14px; margin-top:-3px; margin-bottom:-3px; background-position:left center; background-repeat:no-repeat; background-blend-mode:screen; display:inline-block; }
.dirlist_item:is(.dir,.other,.system,.bin,.invisible,.markdown):is(.selected,:hover) a .has_icon_before_before { filter:brightness(var(--brightness_low)); }
.theme_light .dirlist_item.audio:is(.selected,:hover) a .has_icon_before_before { mix-blend-mode: hard-light; filter:brightness(0.75) contrast(2) saturate(2.66); }
.theme_dark .dirlist_item.audio:is(.selected,:hover) a .has_icon_before_before, .dirlist_item.content_loaded.non_local .name_span span::before { filter:brightness(1.33); }
.dirlist_item.selected:is(.archive,.app) a .has_icon_before_before, .dirlist_item:is(.archive,.app):hover a .has_icon_before_before { filter:brightness(var(--brightness_high)) saturate(6); }
.dirlist_item.non_local:is(.selected,.audio_loaded) .name_span span::before, body:not(.no_hover) .dirlist_item.non_local:hover .name_span span::before { filter:brightness(2); }
.dirlist_subdir_loading .has_icon_before_before { background-image:${ get_SVG_UI_Icon('spinner') } !important; filter:invert(1); background-size:20px; }
`;
const global_styles = `
.theme_light { --percent_100:100%; --percent_95:95%; --percent_90:90%; --percent_85:85%; --percent_80:80%; --percent_75:75%; --percent_70:70%; --percent_65:65%; --percent_60:60%; --percent_55:55%;
--percent_50:50%; --percent_45:45%; --percent_40:40%; --percent_35:35%; --percent_30:30%; --percent_25:25%; --percent_20:20%; --percent_15:15%; --percent_10:10%; --percent_05:05%; --percent_00:00%;
--border_lum:40%; --border_lum_inverted:40%; --brightness_low:1.15; --brightness_med:1.33; --brightness_high:1.875;
--non_media_item_background_h:216deg; --non_media_item_background_s:100%; --non_media_item_background_l:50%; --non_media_item_background_a:0.8;
--media_item_background_h:180deg; --media_item_background_s:100%; --media_item_background_l:33%; --media_item_background_a:1;
--texteditor_item_background_h:250deg; --texteditor_item_background_s:66%; --texteditor_item_background_l:66%; --texteditor_item_background_a:1.00; }
.theme_dark { --percent_100:00%; --percent_95:05%; --percent_90:10%; --percent_85:15%; --percent_80:20%; --percent_75:25%; --percent_70:30%; --percent_65:35%; --percent_60:40%; --percent_55:45%;
--percent_50:50%; --percent_45:55%; --percent_40:60%; --percent_35:65%; --percent_30:70%; --percent_25:75%; --percent_20:80%; --percent_15:85%; --percent_10:90%; --percent_05:95%; --percent_00:100%;
--border_lum:05%; --border_lum_inverted:40%; --brightness_low:1.15; --brightness_med:1.5; --brightness_high:1.66;
--non_media_item_background_h:216deg; --non_media_item_background_s:80%; --non_media_item_background_l:60%; --non_media_item_background_a:0.8;
--media_item_background_h:180deg; --media_item_background_s:50%; --media_item_background_l:40%; --media_item_background_a:1;
--texteditor_item_background_h:250deg; --texteditor_item_background_s:50%; --texteditor_item_background_l:60%; --texteditor_item_background_a:1.00; }
li, div { --non_media_background: hsla(var(--non_media_item_background_h), var(--non_media_item_background_s), var(--non_media_item_background_l), var(--non_media_item_background_a));
--media_background: hsla(var(--media_item_background_h), var(--media_item_background_s), var(--media_item_background_l), var(--media_item_background_a));
--texteditor_item_background: hsla(var(--texteditor_item_background_h), var(--texteditor_item_background_s), var(--texteditor_item_background_l), var(--texteditor_item_background_a)); }
:root { --font_size_small:0.875rem; color-scheme:none; }
:root, html, body { margin:0; padding:0; border:0; border-radius:0; overflow:hidden; display:flex; flex-direction:row; width:100%; height:100vh; font-family:${UI_Prefs_Non_Bool.ui_font}; font-size:${ UI_Prefs_Non_Bool.ui_font_size}; hyphens:auto; transform-origin:0 0; }
a, a:hover { color:inherit; font-weight:inherit; text-decoration:none !important; }
ul, li { list-style:none; }
svg { margin:auto; }
button, .warning_button { background-color:hsl(0,0%,95%); border:solid 1px #333; border-radius:3px; height:18px; font-size:0.875em; font-family:${UI_Prefs_Non_Bool.ui_font} !important; cursor:pointer; }
button.focus, button:focus, .warning_button { border-radius:3px !important; border-style:solid !important; border-width:1px !important; border-color:#222 !important; }
.selected, .audio_loaded { --background_opacity:1; } :hover, .hovered { --background_opacity:0.75; }
.focus_content #sidebar .selected, .focus_content #sidebar .audio_loaded { --background_opacity:0.50; opacity:1; }
.focus_content #sidebar :hover, .focus_content #sidebar .hovered { --background_opacity:0.25; }
.align_left { text-align:left; } .align_center { text-align:center; } .align_right { text-align:right; } .align_justify { text-align:justify; text-justify:inter-character; hyphens:auto; }
.background_grey_60 { background-color:hsl(0,0%,var(--percent_60)); } .background_grey_65 { background-color:hsl(0,0%,var(--percent_65)); }
.background_grey_70 { background-color:hsl(0,0%,var(--percent_70)); } .background_grey_75, body { background-color:hsl(0,0%,var(--percent_75)); }
.background_grey_80 { background-color:hsl(0,0%,var(--percent_80)); }
.background_grey_85, .dirlist_item:nth-of-type(odd), .cuesheet_track:not(.header):nth-of-type(odd), #utilities_help li:nth-of-type(even), body.alternate_background_false .dirlist_item:nth-of-type(even)
{ background-color:hsl(0,0%,var(--percent_85)); }
.background_grey_90, .dirlist_item:nth-of-type(even), .cuesheet_track:not(.header):nth-of-type(even), #stats li:nth-of-type(even) { background-color:hsl(0,0%,var(--percent_90)); }
.background_grey_95, .background_grey_90:not(.no_hover):hover, .background_grey_90.hovered, .background_grey_90.selected, .background_grey_90:focus { background-color:hsl(0,0%,var(--percent_95)); }
.background_grey_100, .background_grey_95:not(.no_hover):hover, .background_grey_95.hovered, .background_grey_95.selected { background-color:hsl(0,0%,var(--percent_100)); }
${ background_images }
.border_0 { border: none; } .border_all { border: solid 1px hsl(0,0%,var(--border_lum)); }
.border_top { border-top: solid 1px hsl(0,0%,var(--border_lum)); } .border_right { border-right: solid 1px hsl(0,0%,var(--border_lum)); }
.border_bottom { border-bottom: solid 1px hsl(0,0%,var(--border_lum)); } .border_left { border-left: solid 1px hsl(0,0%,var(--border_lum)); }
.border_top_x { border-top: solid 1px hsl(0,0%,var(--border_lum_inverted)); } .border_right_x { border-right: solid 1px hsl(0,0%,var(--border_lum_inverted)); } /* "x" = inverted for theme_dark */
.border_bottom_x { border-bottom: solid 1px hsl(0,0%,var(--border_lum_inverted)); } .border_left_x { border-left: solid 1px hsl(0,0%,var(--border_lum_inverted)); }
.box_shadow_menu { box-shadow:0px 4px 6px -3px #000; }
.display_grid, .info_list:hover li, .has_flyout_menu:hover ul { display:grid; }
.display_none, .error_display_none { display:none; } .display_block { display:block; } .display_flex { display:flex; } .display_inline_flex { display:inline-flex; } .flex_column { flex-direction:column; } flex-direction:column; } .flex_row { flex-direction:row; }
.flex_justify_center { display:flex; flex-direction:column; justify-content:center; flex-grow:1; align-items:center; align-self:stretch; text-align:center; }
.flex_justify_center_row { display:flex; flex-direction:row; justify-content:center; flex-grow:1; align-items:center; }
.flex_justify_contents { justify-content:space-between; }
.flex_grow_1 { flex-grow:1; }
.font_size_small { font-size:var(--font_size_small); }
.has_flyout_menu { outline:none; justify-content:center; align-content:center; }
.has_flyout_menu ul li { width:100%; margin:0; padding:4px 6px; text-align:right; box-sizing:border-box; white-space:pre; grid-column:1; }
.has_flyout_menu ul div { grid-column:2; padding-top:8px; }
.has_flyout_menu .item_1 { grid-row:1; } .has_flyout_menu .item_2 { grid-row:2; }
.height_100 { height:100%; }
.hyphens_none { hyphens:none; }
.info_list { color:hsl(0,0%,var(--percent_10)); }
.info_list li { grid-template-columns:minmax(33%,100%) min(66%); border-top:solid 1px hsl(0,0%,var(--border_lum)); }
.info_list li.info_list_header { border-top:none; }
.info_list li .col_1 { font-weight:bold; text-align:right; border-right:solid 1px hsl(0,0%,var(--border_lum)); }
.info_list span { display:inline-block; padding:4px 6px; }
.line_height_1 { line-height:1; } .line_height_1_2, .info_list span { line-height:1.2; } .line_height_1_4 { line-height:1.4; }
.margin_0, header, footer, nav, ol, ul, li { margin:0; }
.media.local input { cursor:not-allowed; }
.normal { font-weight:normal; }
.outline_none, .outline_none:focus, .outline_none:focus-visible { outline:none; }
.overflow_auto { overflow:auto; } .overflow_hidden { overflow:hidden; } .overflow_visible { overflow:visible; } .overflow_x_hidden { overflow-x:hidden; }
.padding_0, header, footer, nav, a, ol, ul, li { padding:0; }
.padding_4_6 { padding:4px 6px; } .padding_4_8 { padding:4px 8px; } .padding_6_8 { padding:6px 8px; } .padding_top_1rem { padding-top:1rem; } .padding_bottom_1rem { padding-bottom:1rem; }
.pointer, label, input { cursor:pointer; } .cursor_default { cursor:default; }
div:has(> input[disabled]), input[disabled], input[disabled] + label { cursor:not-allowed; }
.position_absolute { position:absolute; } .position_relative { position:relative; } .position_fixed { position:fixed; } .position_0 { top:0; right:0; bottom:0; left:0; } .position_LR_0 { left:0; right:0; }
.resize_none { resize:none; }
.theme_dark .invert { filter:invert(1); }
.transform_rotate_90, .transform_rotate_90_contents > * { transform:rotate(90deg); } .transform_rotate_180, .transform_rotate_180_contents > * { transform:rotate(180deg); }
.transform_rotate_270, .transform_rotate_270_contents > * { transform:rotate(270deg); }
.user_select_none { -webkit-user-select:none; -moz-user-select:none; user-select:none; }
.whitespace_pre { white-space:pre; }
.width_10px, .width_10px_contents > * { width:10px; max-width:10px; min-width:10px; } .width_12px, .width_12px_contents > * { width:12px; max-width:12px; min-width:12px; }
.width_14px, .width_14px_contents > * { width:14px; max-width:14px; min-width:14px; } .width_16px, .width_16px_contents > * { width:16px; max-width:16px; min-width:16px; }
.width_18px, .width_18px_contents > * { width:18px; max-width:18px; min-width:18px; } .width_24px, .width_24px_contents > * { width:24px; max-width:24px; min-width:24px; }
.width_100 { width:100% !important; }
.z_index_1 { z-index:1; } .z_index_2 { z-index:2; } .z_index_3 { z-index:3; } .z_index_9997 { z-index:9997; } .z_index_9998 { z-index:9998; } .z_index_9999 { z-index:9999; }
/* NON-MEDIA ITEMS BACKGROUND */
li.selected:not(.media), li:not(.media):not(.no_highlight):hover, li.hovered, li.content_loaded
{ background-color:var(--non_media_background) !important; } /* all selected items, hovered non-dirlist items */
li.grid_item:hover, li.grid_item.hovered { --non_media_item_background_a:0.40; background-color:var(--non_media_background); } /* hovered grid items */
#sidebar_nav li:not(.media):hover { --non_media_item_background_a:0.5; background-color:var(--non_media_background); } /* hovered dirlist items */
li.grid_item.selected { --non_media_item_background_a:0.75; background-color:var(--non_media_background); } /* selected grid items */
body.no_hover li.grid_item:is(:not(.selected):hover,.hovered), body.no_hover li.grid_item:is(:not(.selected):hover,.hovered) * { background-color:transparent !important; color:initial !important; }
li.selected + li.selected:nth-of-type(even), li.dir.hovered + li.hovered:nth-of-type(even), li.file.hovered + li.hovered:nth-of-type(odd), .info_list li:nth-of-type(even) { --non_media_item_background_a:0.60; } /* alternate highlight background with multiple selections, show stats*/
/* MEDIA ITEMS BACKGROUND */
li.media[class*="loaded"] { --media_item_background_a:0.9; background-color:var(--media_background) !important; } /* loaded audio, selected video */
li.media.selected:not([class*="loaded"]) { --media_item_background_a:0.7; background-color:var(--media_background) !important; } /* selected audio */
li.media:hover { --media_item_background_a:0.5; background-color:var(--media_background) !important; } /* hovered media */
/* UNHIGHLIGHTED ITEMS: menu visible, .focus_content, .no_hover */
body[class*="has_menu"] #sidebar_nav, body.focus_content #sidebar_nav { --non_media_item_background_s:0%; --media_item_background_s:0%; }
body.theme_light[class*="has_menu"] #sidebar_nav, body.focus_content #sidebar_nav { --media_item_background_l:50%; --non_media_item_background_l:50%; }
body.theme_dark[class*="has_menu"] #sidebar_nav, body.focus_content #sidebar_nav { --media_item_background_l:40%; --non_media_item_background_l:30%; }
body.no_hover #sidebar_menus li:not(.selected):not(.hovered):hover { background-color:inherit !important; color:unset !important; }
body.no_hover #sidebar_nav li:nth-of-type(even):not(.selected):hover { background-color:hsl(0,0%,var(--percent_80)) !important; }
body.no_hover #sidebar_nav li:nth-of-type(odd):not(.selected):hover { background-color:hsl(0,0%,var(--percent_85)) !important; }
body.no_hover #sidebar_nav li:not(.selected):hover { color:unset !important; }
/* TEXTEDITOR ITEMS*/
body:is(.has_texteditor,.texteditor_edited) #show_texteditor li { background-color:var(--texteditor_item_background); }
#show_texteditor li:hover { --texteditor_item_background_a:0.7; background-color:var(--texteditor_item_background) !important; }
/* TEXT COLOR */
li:where(.selected,:hover,.hovered),
li:where(.hovered,:hover) li:is(.selected:hover,.selected),
.content_loaded, .audio_loaded, body.has_texteditor #show_texteditor, body.texteditor_edited #show_texteditor,
.no_hover .grid_item:is(.selected,:hover,.hovered), .no_hover .grid_item:is(.selected,:hover,.hovered) *, .grid_item:is(.selected,:hover,.hovered), .grid_item:is(.selected,:hover,.hovered) *, .grid_item.selected::before, .grid_item.selected::after
{ color:white !important; } /* white */
.text_color_default,
body.no_hover.theme_dark li.grid_item:is(:not(.selected):hover,.hovered), body.no_hover.theme_dark li.grid_item:is(:not(.selected):hover,.hovered) *,
li:is(.selected,:hover,.hovered) li:not(.selected), body.no_hover #sidebar_menus li:is(.selected,:hoever,.hovered) li:not(.selected):hover,
.no_highlight,
.no_highlight:hover,
.no_highlight > li:hover,
:hover:not(#svg_container) > svg,
.font_glyph_item::before,.font_glyph_item::after,#font_specimen_viewer::before,.has_font_specimen_glyph #font_specimen_viewer::after,#font_file_glyph_viewer::before,#font_file_glyph_viewer::after
{ color:hsl(0,0%,var(--percent_10)) !important; } /* default */
/* FONT WEIGHT */
li:is(.selected,:hover,.hovered) li, body.no_hover li:hover, li:not(.grid_item).no_hover:hover, body.no_hover #sidebar_menus li.hovered li:not(.selected):hover, li:is(.selected,:hover,.hovered) li:not(.selected), body.no_hover #sidebar_menus li:is(.selected,:hoever,.hovered) li:not(.selected):hover { font-weight:normal !important; }
.bold, li:not(.grid_item):hover,li.hovered,li.hovered li:is(:hover,.selected),li:not(.grid_item):not(.audio).selected,li.selected li:hover, li.media[class*="_loaded"], #show_image_grid:hover, #show_font_grid:hover,dt
{ font-weight:bold !important; }
#content_pane[data-content="has_ignored"]::before { opacity:0.3; }
.has_warning #sidebar, .has_warning #content_pane, .focus_content .dirlist_item, body:is(.has_menu,.has_menu_parents,.has_menu_stats,.has_menu_grid.has_images.has_fonts) .dirlist_item:not(.hovered), body:is(.has_menu,.has_menu_parents,.has_menu_stats,.has_menu_grid.has_images.has_fonts) #content_pane, #sidebar_menu_parent:not(:hover), #sidebar_menu_main_container:not(:hover) nav, #show_grid_btn, .split_btn span, .disabled:not(.local) { opacity:0.75; }
body.has_menu_footer .dirlist_item.hovered, .disabled:not(.local).selected { opacity:0.84; }
#show_grid_btn:hover, #prev_next_btns span:hover, #sidebar_footer_utilities:hover, .split_btn span:hover { opacity:1.0; }
`;
const utilities_styles = `
#utilities { top:0; justify-content:center; }
#warnings_container { width:26em; flex-direction:column; border-radius:0 0 3px 3px; box-shadow:0px 2px 12px #333; font-size:0.875em; color:#111; display:none; }
#warnings_header { padding:1rem 1.5rem; background-position:left 1.25rem center; background-repeat:no-repeat; background-size:24px; }
#warnings_container:not(.warning_make_playlist) #warnings_header { background-image:${ get_SVG_UI_Icon("error") }; }
#warnings_header h3 { text-indent:2.25em; }
#warnings_container:not(.warning_make_playlist) h3#warning_header, #warnings_container.warning_make_playlist h3#make_playlist_header, .warning_button.show, #warnings div.show, .has_warning #utilities, .has_warning #warnings_container, .has_help #utilities, .has_help #help_container, .warning_open_font #warnings #warning_open_font, .warning_unsaved_text #warnings #warning_unsaved_text, .warning_clear_text #warnings #warning_clear_text, .warning_local_file #warnings #warning_local_file, .warning_close_playlist #warnings #warning_close_playlist, .warning_local_playlist #warnings #warning_local_playlist, .warning_non_local_file #warnings #warning_non_local_file, .warning_close_font #warnings #warning_close_font { display:flex;}
#warnings .warning { padding:0 1.5rem 1rem; display:none; }
#warning_buttons_container { padding:1rem 1.5rem; }
button.focus, button:focus { background-color:#0E4399; color:#EEE; outline:none; }
.warning_button { min-width:4em; display:none; font-size:1em; justify-content:center; }
#warning_btn_cancel + #warning_btn_save, #warning_btn_dont_save + #warning_btn_cancel, #warning_btn_clear { margin-right:auto; }
#warning_btn_cancel, #warning_btn_clear, #warning_btn_save { margin-left:0.5rem; }
#warnings_container.clear #warning_buttons { justify-content:space-between; }
#warning_make_playlist fieldset div { padding:0 0 2px; } #warning_make_playlist .indent { text-indent:2em; } #warning_make_playlist input { margin-right:6px; }
.has_warning::before, .has_overlay::before { content:""; position:fixed; top:0; right:0; bottom:0; left:0; z-index:9998;-webkit-user-select:none;-moz-user-select:none; user-select:none; }
#help_container { padding:0 1em 1em; overflow:auto; flex-direction:column; } #help_container > header { grid-template-columns:5em auto fit-content(100%); }
#help_contents { margin: 1em -1em 0; padding:1em; } #help_container dt { color:var(--media_background); }
#help_container h2 { color: var(--non_media_background); } #help_container dd { margin-inline-start:1em; } #help_container dd:before { content:"\u2219"; margin-right:6px; }
#help_container dl + p { margin-top:1rem; padding-top:1rem; } #help_container ol li { list-style:decimal; }
#help_container kbd { min-width:1em; height:fit-content; padding:2px 6px; display:inline-block; border:solid 1px #888; border-radius:3px; text-align:center; font-family:inherit; font-size:0.875em; background-color:hsl(0,0%,var(--percent_90)); } #help_main_menu svg { margin: 0 0 -2px; width:12px; } #help_container svg.icon_arrow { height:14px; margin-bottom:-2px; }
#help_bookmarks::before { background-image: ${ get_SVG_UI_Icon("bookmark") }; }
.has_help #utilities, .has_help #help_container { bottom:0; }
`;
const sidebar_header_menu_styles = `
/* PARENTS MENU */
#parent_dir_nav #svg_chevron { width:18px; } #parent_dir_nav #svg_multiply { width:14px; }
#parent_dir_nav #svg_multiply, body:is(.has_playlist,.has_filelist) #svg_chevron, body:is(:not(.has_playlist),:not(.has_filelist)) #sidebar_header #close_playlist_container { display:none; }
body.has_playlist #parent_dir_nav #svg_multiply, body.has_filelist #parent_dir_nav #svg_multiply, body:is(.has_playlist,.has_filelist) #sidebar_header #close_playlist_container { display:flex; }
#current_dir_path { padding:3px 6px; word-break:break-word; }
/* MAIN MENU */
#sidebar_menu_main li { display:flex; }
.has_menu #sidebar_menu_main, .has_menu_parents #parents_links, body:not(.no_hover) #sidebar_menus .has_submenu:hover .submenu, #sidebar_menu_main .has_submenu.hovered .submenu, #sidebar_menu_main li.has_submenu.selected .submenu { display:block; }
#sidebar_menu_main li.has_submenu { position:relative; justify-content:space-between; }
#sidebar_menu_main li.bookmark a::before { content:""; width:24px; max-width:24px; min-width:24px; height:12px; background-size:12px; }
.submenu { width:100%; max-width:240px; display:none; margin:0; padding:0; box-sizing:border-box; position:absolute; left:100%; }
#sidebar_menu_main ul.submenu li a { padding:6px 8px 6px 0; }
#sidebar_menu_main input { width:0; float:left; }
.menu_item { margin:0; padding:5px 8px 5px 0; display:flex; flex-grow:1; text-align:left; }
#sidebar_menu_main .selected ~ li:hover .submenu, #sidebar_menu_main .selected ~ li .submenu:hover, .has_open, #sidebar_menu_main .show_input span.menu_item, .text_editing_enable_false:not(.has_texteditor) #sidebar_menu_main li#texteditor_split_view, .text_editing_enable_false:not(.has_texteditor) #toggle_texteditor_html_menu { display:none; }
#sidebar_menu_main .show_input input { display:unset; margin:2px 6px; width:100%; }
/* menu right arrow */
#sidebar_menu_main svg { margin: 0 6px; width:12px; }
#sidebar_menu_main li:is(.selected,.hovered:not(:hover),:hover) svg { filter:invert(1); } body.no_hover:not(.theme_dark) #sidebar_menu_main li:not(.selected):not(.hovered):hover svg { filter:invert(0); }
#ui_scale span.menu_item::after { content:attr(data-value); } #ui_scale_input_container, #ui_scale.show_input span + span { display:flex; } #ui_scale_input_container { padding-left:18px; padding-right:8px; }
/* IFRAME MENUS */
#parent { padding:5px 3px 5px 0; } #parent span { padding:0px 1px; }
#open_in_sidebar { padding:5px 2px 5px 3px; }
`;
const sidebar_header_styles = ` /* for both sidebar and content_iframe */
#sidebar { font-variant-numeric:tabular-nums; } #sidebar.top_body { min-width:200px; } #sidebar.iframe { min-width:500px; flex-basis:100%; }
#sidebar_header_title_div { letter-spacing:0.5em; text-indent:0.75em; flex-basis:100%; }
#sidebar_header_title_div:before { content:"INDEX OF"; } .has_playlist #sidebar_header_title_div:before { content:"PLAYLIST"; } .has_filelist #sidebar_header_title_div:before { content:"FILELIST"; }
${ sidebar_header_menu_styles }
/* SIDEBAR BUTTONS */
#directory_buttons_left { padding:6px; }
#show_details { margin-top:0; margin-right:8px; padding:0 4px; }
#show::before { content:"Show "; }
/* GRID BTN ---> combine style with save_btn */
#show_grid_btn { margin:0 0 0 auto; }
#show_grid_btn ul { padding-left:0px; top:-1px; right:-1px; }
#show_grid_btn ul:after { content:""; position:absolute; z-index:-1; top:0; bottom:0; left:0; right:0; background-color:hsl(0,0%,var(--percent_80)); }
#show_grid_btn ul:not(:has(li:hover)):hover { background-color:var(--non_media_background); }
#show_grid_btn ul:not(:has(li:hover)):hover svg { color:white !important; }
#show_grid_btn.has_grid div { color:#118888; }
#top_body:is(.has_images,.has_fonts) #show_grid_btn { display:flex; }
#top_body.has_images.has_fonts #show_grid_btn:hover ul { display:grid; }
/* SORTING ITEMS */
#sidebar_header_utilities_row_2 .sorting { grid-row:1; }
body:not(.show_details_false) #sorting_row_2 { display:grid; }
#sorting_row_1 span, #sorting_row_2 span, .sorting span::before, .sorting span::after { display:inline-block; }
#sorting_row_1 span, #sorting_row_2 span { padding:6px 0; }
#sorting_row_1.iframe span, #sorting_row_2.iframe span { padding:4px 0; }
#sidebar_header_utilities_row_2 span::before, #sidebar_header_utilities_row_2 span::after, .sorting .menu_item::after { content:""; width:16px; height:8px; color:#CCC; background-position:center; background-repeat:no-repeat; background-size:10px; }
.sorting.down span::after, .sort_direction_descending .sorting span::after { transform:rotate(0deg) !important; }
#sort_by_name input { margin:-2px 6px -2px 0; bottom:-2px; }
#sort_by_ext { grid-column: span 2; }
.has_media #sort_by_ext { grid-column: span 1; }
.has_media #sort_by_default { text-align:center; }
#sort_by_default.iframe, .iframe #sort_by_size, .iframe #sort_by_date { text-align:right; }
.has_media #sort_by_duration, .has_playlist #sort_by_duration, #content_body.has_media #sorting_row_2 #sort_by_duration { display:unset; }
#content_body #sorting_row_1 #sort_by_duration, #top_body #sorting_row_2 #sort_by_duration { display:none; }
/* TEXT EDITOR ITEM */
body:not(.show_details_false) #show_texteditor, body.has_texteditor #show_texteditor { display:flex; }
#show_texteditor a { padding-left:10px; }
`;
const sidebar_nav_styles = ` /* for both sidebar and content dirlists */
#sidebar_nav { overflow-y:hidden; flex-basis:100%; margin-bottom:-1px; }
#dir_nav_inner { overflow:auto; }
#sidebar_nav ol { -webkit-margin-before:0em !important; -webkit-margin-after:0em !important; -webkit-padding-start:0em; }
#directory_list { counter-reset:item; transition:opacity .125s; }
#directory_list:empty { border-bottom:0; padding:100%; }
.dirlist_item_input, .dirlist_item_details, .dirlist_item_details span, .dirlist_item_media_duration, .details.ext, .dirlist_item.error::before, .dirlist_item_name_a::before,
body.show_invisibles_false:not(.has_menu_stats) .dirlist_item.invisible.ignored, body.show_invisibles_false:not(.show_ignored_false):not(.has_menu_stats) .dirlist_item.invisible:not(.ignored),
body.show_invisibles_false.show_ignored_items_false:not(.has_menu_stats) .dirlist_item.ignored, body.show_invisibles_false.show_ignored_items_false:not(.has_menu_stats) .dirlist_item.invisible,
body.show_ignored_items_false:not(.show_invisibles_false):not(.has_menu_stats) .dirlist_item.ignored:not(.invisible) { display:none; }
.dirlist_item { margin-inline-start:0; display:grid; grid-gap:0; }
.top_item { grid-template-columns:minmax(8rem,auto) minmax(6em,1fr) minmax(auto,6em); }
.dirlist_item_name { grid-row:1; display:flex; -webkit-padding-start:0; -moz-padding-start:0; word-break:break-word; }
.top_item .dirlist_item_name { grid-column:1 / span 3; padding:6px 12px 6px 0; }
.dirlist_item_name::before { counter-increment:item; content:counter(item); min-width:36px; height:14px; max-height:14px; min-height:14px; text-align:right; padding:0 3px 0 0; text-indent:6px; }
.dirlist_item_input { margin:1px 6px 0 0; max-height:13px; }
.dirlist_item .desc.dirlist_item_details { padding:0 6px 4px 40px; grid-column:1 / span 3; text-align:left; white-space:unset; }
.has_icon_before::before, .has_icon_before_before, .has_icon_after::after { content:""; display:inline-block; background-position:center; background-repeat:no-repeat; background-size:14px,0px; }
.has_icon_before::before, .has_icon_before_before, .show_large_image_thumbnails_false .dirlist_item.image .has_icon_before_before, .show_image_thumbnails_false .dirlist_item.image .has_icon_before_before, .has_icon_after:not([data-after])::after { width:14px; height:14px; max-width:20px; max-height:14px; min-width:14px; min-height:14px; margin:0 6px; }
.dirlist_item.image .has_icon_before_before { width:56px; height:56px; max-width:56px; max-height:56px; min-width:56px; min-height:56px; margin:0 6px; background-position:top; background-size:contain,0px; }
.ignored:not(.selected) .has_icon_before::before, .ignored:not(.selected) .has_icon_before_before, .focus_content .has_icon_before_before, .has_quicklook #sidebar { filter:grayscale(100%); }
.focus_content li:is(.selected,.hovered,:hover) .has_icon_before_before { filter:grayscale(0%); }
/* MEDIA ITEMS */
.top_item.media .dirlist_item_name { grid-column:1 / span 2; padding-right:0; }
.top_item.media .dirlist_item_media_duration { grid-column:3; padding:6px 12px 6px 0; }
.dirlist_item.media .dirlist_item_media_duration { grid-row:1; }
.iframe_item.media .dirlist_item_media_duration { grid-column:2; }
.media:not(.local) .dirlist_item_media_duration { display:unset; }
.dirlist_item.media .dirlist_item_media_duration:not([data-duration="NaN"]):empty
{ background-image:${ get_SVG_UI_Icon('spinner') } !important; background-position:top 3px right 10px; background-repeat:no-repeat; background-size:20px; }
.dirlist_item_media_duration[data-duration="NaN"]::after { content:"[Error]"; }
/* SORTING BORDERS */
.sort_by_default:not(.show_invisibles_false) .dir.invisible + .dir:not(.invisible), .sort_by_default:not(.show_invisibles_false) .dir:not(.invisible) + .dir.invisible {border-top:solid 1px hsl(0,0%,var(--border_lum));}
/* ITEM DETAILS */
.dirlist_item_details { text-align:right; white-space:nowrap; }
.top_item .dirlist_item_details { padding:0 12px 4px 0; }
.dirlist_item_details.size { padding-left:12px; }
.dirlist_item_details.date { padding-bottom:0; height:1em; max-height:1em; overflow-wrap:break-word; }
.dirlist_item_details.kind::first-letter { text-transform:uppercase; }
#content_body .iframe_item { grid-template-columns: minmax(20em,100%) minmax(4em,6em) minmax(6em,8em) minmax(6em,14em) minmax(6em,8em); }
#content_body .iframe_item.non_media .dirlist_item_name { grid-column:1 / span 2; }
#content_body .iframe_item .dirlist_item_details { grid-row:1; height:1ex; }
#content_body .iframe_item .desc.dirlist_item_details { grid-row:2; grid-column:1 / span 6; height:auto; padding:0 6px 4px 40px; }
#content_body .iframe_item .dirlist_item_name_a, #content_body .iframe_item > span { padding:5px 16px 5px 0; }
body:not(.show_numbers_false) .dirlist_item_name_a::before { display:initial; }
body:not(.show_details_false) .dirlist_item_details, .media .dirlist_item_input { display:unset; }
.disabled, .ignore_ignored_items li.ignored, .has_filelist [id$="sort_by_size"], .has_playlist [id$="sort_by_size"], .has_filelist [id$="sort_by_date"], .has_playlist [id$="sort_by_date"]
{ cursor:not-allowed; opacity:0.75; }
.dirlist_item.error { display:block; padding:6px 8px; }
.dirlist_item.ignored.local .dirlist_item_name_a::after { content:"\\00a0[local file]"; display:contents; font-style:italic; }
.is_error #is_error { display:block !important; grid:none !important; grid-template-columns:none !important; }
.is_error #is_error_items { display:block; }
`;
const iframe_dir_styles = `${ global_styles }
#content_body { overflow-x:auto; font-size:${ (parseFloat(UI_Prefs_Non_Bool.ui_font_size) * 0.875) + UI_Prefs_Non_Bool.ui_font_size.replace(/\d*/,'') }; }
.theme_dark .sorting span::before, .theme_dark .sorting span::after { filter:invert(1); }
#content_body:not(.show_details_false) #show::before { content:"Hide "; }
#content_body.show_details_false .iframe_item { grid-template-columns:auto; }
#content_body.show_details_false .media .dirlist_item_media_duration, #content_body #content_pane, #content_body .content_el,
#content_body.has_quicklook div[id^="title_buttons"], #content_body.has_quicklook #content_pane.has_audio :is(#content_title_container,#content_container),
#content_body.has_quicklook #content_pane[data-content="has_ignored"] #content_iframe, #content_body.has_quicklook #content_pane[data-content="has_pdf"] #content_pdf { display:none; }
#content_body.has_quicklook #sidebar_nav { opacity:0.6; }
#content_body.has_quicklook #content_pane { display:flex; padding:2em; position:absolute; z-index:1; left:0; right:0; top:0; bottom:0; justify-content:center; }
#content_body.has_quicklook #content_header { background-color:hsl(0,0%,var(--percent_85)); border-radius: 3px 3px 0 0; border:solid 1px hsl(0,0%,var(--border_lum)); border-bottom:0; }
#content_body.has_quicklook #content_container { padding:6px; background-color:hsl(0,0%,var(--percent_85)); box-shadow:0 0 12px #000; border-radius: 0 0 3px 3px; border:solid 1px hsl(0,0%,var(--border_lum)); border-top:0; contain:unset; flex-basis:unset; }
#content_body.has_quicklook .content_el { width:100%; }
#content_body.has_quicklook .content_el.has_content { border:solid 1px hsl(0,0%,var(--border_lum)); box-sizing:border-box; }
#content_body.has_quicklook .content_el.has_content, #content_body.has_quicklook .content_el:has(.has_content), #content_body.has_quicklook #content_pane.has_audio #content_audio_container
{ display:flex; z-index:1; }
#content_body.has_quicklook #content_pane.has_audio #content_header { margin:auto; } #content_body.has_quicklook #content_pane.has_audio #audio_wrapper { padding:0 6px; }
#content_body.has_quicklook #content_pane.has_audio #content_audio_container { padding:0; } #content_body.has_quicklook #content_pane.has_audio #audio_options { display:none; }
#content_body.has_quicklook #content_container:has(#content_font.has_content, #content_pdf.has_content,#content_iframe.has_content),#content_body.has_quicklook #content_pane[data-content="has_ignored"] #content_container { height:50%; flex-basis:unset; }
#content_body.has_quicklook #content_container:has(#content_image.has_content) { display:table; flex-basis:unset; }
#content_body.has_quicklook #content_video.has_content { position:static; }
#content_body.has_quicklook #content_pane:not([data-content="has_ignored"]) #content_font.has_content { display:grid; }
#content_body.has_quicklook #content_pane[class*="has_font_specimen"] #font_specimen_viewer { display:flex; }
#content_body.has_quicklook #content_image_container, #content_body.has_quicklook #content_iframe { max-height:88vh; }
#content_header, #content_body.has_quicklook #content_image_container, #content_body.has_quicklook #content_container:has(#content_video.has_content) { padding:0; }
#content_pane[data-content="has_pdf"] #content_container { background-image:${ get_SVG_UI_File_Icon('file_icon_ignored') }; background-size:28px; }
`;
const sidebar_footer_styles = ` /* for both sidebar and content_iframe */
.has_menu_stats #stats_summary, .stats_kind span.file, .stats_kind span.media, .has_menu_stats #sidebar_footer_utilities { display:none; }
#stats_container { max-height:33vh; }
.theme_light #sidebar_footer_utilities:hover ul, .theme_light #sidebar_footer:hover, .theme_light #stats_details_summary { box-shadow:0px -4px 4px 0px rgba(128,128,128,0.6); }
.theme_dark #sidebar_footer_utilities:hover ul, .theme_dark #sidebar_footer:hover, .theme_dark #stats_details_summary { box-shadow:0px -4px 4px 0px rgba(32,32,32,0.6); }
#stats_details_summary_dirs .stats_kind::before { background-image:${ get_SVG_UI_File_Icon("file_icon_dir") }; }
#stats_details_summary_files .stats_kind::before { background-image:${ get_SVG_UI_File_Icon("file_icon_file_default") }; }
#stats_details_summary, #stats_details_items_container { overflow-y:scroll; }
#stats_summary_totals, .has_media #total_duration { display:flex; text-align:left; white-space:normal; padding-right:1em; }
#stats a { padding:3px 12px 3px 0; }
#stats a::before { content:attr(data-count); width:36px; text-align:right; }
.stats_kind span { margin-right:0.5em; white-space:pre; display:flex; }
.stats_kind > span::first-letter { text-transform:uppercase; }
#stats_details_items li.audio a span span::after { content:attr(data-audio_duration); white-space:pre; }
#stats_details_items li.video a span span::after { content:attr(data-video_duration); white-space:pre; }
#total_duration::after { content:attr(data-time_remaining); white-space:pre; }
.has_media #total_duration::before { content:"Total Time:\\00a0"; }
.stats_list_item_name_a { -webkit-padding-start:0; padding:1px 0; } .stats_list_item span::first-letter { text-transform:uppercase; }
#stats_summary, #stats_details_summary { margin-block-start:0; margin-block-end:0; }
#stats a.dirlist_item_name_a:before { display:inline-block; }
#stats_details_items { max-height:25vh; }
#stats_container, .has_menu_stats #stats_details_summary, .has_menu_stats #stats_details_items { display:block; }
#sidebar_footer_utilities { right:-1px; } #sidebar_footer_utilities svg { margin:2px 2px 0 0; opacity:0.75; }
#sidebar_footer_utilities ul { bottom:0; right:-1px; white-space:nowrap; box-shadow:-0px -3px 6px -3px #333; } #sidebar_footer_utilities:hover ul { display:block; }
`;
const sidebar_utilities_styles = `
#show_sidebar { top:0; right:0; height:21px; opacity:0.75; } #show_sidebar:hover { opacity:1; }
body.show_sidebar_false #handle { display:none; } body.show_sidebar_false #show_sidebar { left:2px; transform:rotate(180deg); }
body.show_sidebar_false #sidebar { width:0 !important; min-width:0; position:absolute; top:2px; left:-1px; }
body.show_sidebar_false #sidebar_header, body.show_sidebar_false #sidebar_footer { z-index:unset; display:none; } body.show_sidebar_false #sidebar_nav { visibility:hidden; }
body.show_sidebar_false #directory_list_outer { min-width:0; } body.show_sidebar_false #content_pane { width:100% !important; }
body.show_sidebar_false #title_buttons_left { padding-left:24px; } #handle { top:0; bottom:0; right:-4px; width:7px; cursor:col-resize; }
.has_overlay #handle { z-index:9999; }
`;
const sidebar_styles = `${ sidebar_header_styles } ${ sidebar_nav_styles } ${ sidebar_footer_styles } ${ sidebar_utilities_styles }`;
/* CONTENT PANE STYLES */
const content_pane_header_styles = `
/***** CONTENT TITLE *****/
#content_title_container { overflow-x:scroll; }
#content_title { min-width:16em; min-height:18px; padding:4px 8px; word-break:break-word; } #content_title *:empty { display:none; }
#content_title span { pointer-events:none; } #content_title span::before, #content_title span::after { font-weight:normal; margin-bottom:-3px; }
#content_pane.has_font_specimen #content_title div::before { content:"Font"; }
#content_pane.has_font_file #content_title div::before, #content_pane.has_font_file_glyph #content_title div::before { content:"Glyphs from font"; }
.has_directory_source #content_title div::before { content:"Source of" !important; }
.has_directory_source #content_title span::before { background-image:${ get_SVG_UI_File_Icon("file_icon_dir_default") }; height:14px !important; background-size:contain; }
#content_pane[data-content="has_grid"] #content_title div::before { content:"Fonts and Images from"; }
#content_pane[data-content="has_grid"].has_font_grid #content_title div::before { content:"Fonts from"; }
#content_pane[data-content="has_grid"].has_image_grid #content_title div::before { content:"Images from"; }
#content_pane[data-content="has_ignored"] #content_title div::before { content:"Ignored content"; }
#content_pane[data-content="has_dir"] #content_title div::before { content:"Index of"; }
body.has_texteditor.texteditor_view_raw.texteditor_split_view_false #content_title div::after { content:" (Source Text)"; }
body.has_texteditor.texteditor_view_styled.texteditor_split_view_false #content_title div::after { content:" (Text Preview)"; }
body.has_texteditor.texteditor_view_html.texteditor_split_view_false #content_title div::after { content:" (HTML Preview)"; }
body.has_texteditor #content_title div::before { content:"Text Editor" !important ; font-weight:bold; }
body.texteditor_edited.has_texteditor #content_title div::before { content:"Text Editor (edited)" !important; font-weight:bold; }
body.has_texteditor #content_title span { display:none; }
body.has_texteditor #content_title span::before { background-image:${ get_SVG_UI_File_Icon("file_icon_markdown") }; }
body:not(.text_editing_enable_false):not(.has_quicklook) #content_pane:is([data-content="has_text"],[data-content="has_code"],[data-content="has_markdown"]) #content_title span::after
{ background-image:url("data:image/svg+xml;utf8,${ SVG_UI_File_Icons.file_icon_ebook}"); pointer-events:all; opacity:0.66; }
body.text_editing_enable_false #content_pane:is([data-content="has_text"],[data-content="has_code"],[data-content="has_markdown"]) #content_title span::after
{ background-image:url("data:image/svg+xml;utf8,${ SVG_Text_Editing_UI_Icons.text_editing }"); pointer-events:all; opacity:0.66; }
#content_pane:is([data-content="has_text"],[data-content="has_code"],[data-content="has_markdown"]) #content_title:hover span::after { opacity:1 !important; }
body.theme_dark #content_pane:not([data-content="has_image"]):not([data-content="has_grid"]) #content_title span::after { filter:invert(1) !important; }
#content_pane[data-loaded="unloaded"] #content_title { display:flex; justify-content:center; align-items:center; }
#content_pane[data-loaded="unloaded"] #content_title div::before { content:"Loading..." }
#content_pane[data-loaded="unloaded"] #content_title span { display:none; }
#content_pane[data-content="has_grid"] #content_title span::before { background-image:${ get_SVG_UI_File_Icon("file_icon_dir") }; height:14px !important;}
#content_pane[data-content="has_grid"] #content_title span::after { content:attr(data-grid_count_items); font-weight:normal; white-space:pre; margin:0; }
#content_pane[data-content="has_image"] #content_title span::after { content:attr(data-after); font-weight:normal; white-space:pre; margin:0; }
#content_pane.content_error #content_title span::before, #content_pane.content_error #content_container, #content_pane.has_audio_error #content_audio_title span::before {background-image:${ get_SVG_UI_Icon("error")}; }
body.is_error:not(.has_directory_source) #content_title span::before, #content_pane.content_error #content_title div::before { content:"ERROR:"; white-space:pre; display:inline; }
/* CONTENT TITLE BUTTONS LEFT */
#reload_btn { width:52px; } #reload_btn::before { content:"Reload"; }
#prev_next_btns { margin-left:4px; } #prev_next_btns span { width:2em; height:16px; } #prev_next_btns span:active { background-color:#0E4399; } #prev_next_btns:focus { background-color:white; }
#prev_next_btns svg { width:12px; }
/* CONTENT TITLE BUTTONS RIGHT */
#scale { margin-right:4px; background-color:#FFF; } #scale span { width:2em; }
#close_btn { width:52px; } #close_btn::before { content:"Close"; } body.has_texteditor #close_btn::before { content:"Hide"; } #content_pane[data-content="has_null"] #close_btn { display:none !important; }
.split_btn::after { content:""; position:absolute; top:0; bottom:0; left:calc(50% - 1px); border-left:solid 1px #333; } .split_btn span { display:inline-flex; }
#open_in_texteditor { margin-right:4px; }
`;
const content_pane_audio_styles = `
/* CONTENT AUDIO TITLE */
#content_audio_title span { padding:4px 6px 0; }
#content_audio_title span::before { content:""; padding-right:22px; height:14px !important; font-weight:normal; background-image:${ get_SVG_UI_File_Icon("file_icon_audio") }; background-position:center; background-position:right 4px center; background-repeat:no-repeat; }
#content_pane.has_audio #content_audio_title span::before, #content_pane[data-content="has_video"] #content_title div::before { content:"Playing:"; }
#content_pane.has_audio.has_audio_error #content_audio_title span::before { content:"ERROR:"; }
#content_pane.has_audio.has_audio_error #content_audio_container { padding-top:0; }
#content_pane.has_audio.has_audio_error #audio_container { display:none; }
/* CONTENT AUDIO PLAYER */
#content_audio_container { justify-content:center; padding:2px 6px 6px; overflow-x:auto; flex-wrap:wrap; display:flex; }
#audio_container { margin:0 100%; height:32px; background-color:rgb(241, 243, 244); }
#prev_track, #next_track { width:2rem; }
#content_audio { height:32px; }
audio::-webkit-media-controls-enclosure { border-radius:0; }
#close_audio { width:32px; }
#audio_options { margin-top:0; margin-right:calc(-6em - 8px); padding:0 4px; width:6em; justify-content:start; }
#loop_label input { margin:0px 4px 2px; }
#shuffle_label input { margin:2px 4px 0px; } #shuffle_label::after { content:attr(data-shufflecount); }
/* CUE SHEET MENU */
#content_pane.has_audio .cuesheet_track .icon.has_icon_before_before { background-image:${ get_SVG_UI_File_Icon("file_icon_audio") }; }
#content_pane.has_video .cuesheet_track .icon.has_icon_before_before { background-image:${ get_SVG_UI_File_Icon("file_icon_video") }; }
.cuesheet_track_list_container { background-image:${get_SVG_UI_File_Icon("file_icon_playlist")}; background-repeat:no-repeat; background-size:18px; background-color:inherit; display:none; }
.cuesheet_track_list_container:hover > div, .cuesheet_track_list_container.has_menu > div { display:flex; flex-direction:column; margin-top:-1px; overflow:hidden; max-height:100%; }