forked from monster860/ntdf-tools
-
Notifications
You must be signed in to change notification settings - Fork 0
/
gamefile_reader.html
3247 lines (3052 loc) · 263 KB
/
gamefile_reader.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
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
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<script src="FileSaver.js"></script>
<script src="three.min.js"></script>
<script>
THREE.ShaderChunk.color_pars_vertex = `
#ifdef USE_COLOR
varying vec4 vColor;
attribute float alpha;
#endif
`;
THREE.ShaderChunk.color_vertex = `
#ifdef USE_COLOR
vColor.xyz = color.xyz;
vColor.w = alpha;
#endif
`;
THREE.ShaderChunk.color_pars_fragment = `
#ifdef USE_COLOR
varying vec4 vColor;
#endif
`;
THREE.ShaderChunk.color_fragment = `
#ifdef USE_COLOR
diffuseColor.rgba *= vColor.rgba;
#endif
`;
const file_sectors = [0x00000000, 0x0000003A, 0x00000074, 0x000000AE, 0x000000F8, 0x000000F8, 0x000000F8, 0x000000F8, 0x00000260, 0x00000260, 0x00000545, 0x000006F8, 0x000008B0, 0x00000A5C, 0x00000C17, 0x00000DD8, 0x00000F94, 0x00001147, 0x00001300, 0x00001493, 0x00001649, 0x0000181F, 0x000019AD, 0x00001B6D, 0x00001D03, 0x00001EA6, 0x00002049, 0x000021FE, 0x000023A0, 0x0000254A, 0x000026EA, 0x00002876, 0x00002A01, 0x00002B64, 0x00002D12, 0x00002E8C, 0x00003019, 0x000031D2, 0x00003375, 0x00003518, 0x000036AB, 0x0000384F, 0x00003A0F, 0x00003BBF, 0x00003D5F, 0x00003F16, 0x000040CD, 0x0000427F, 0x00004444, 0x000045ED, 0x0000478A, 0x0000492A, 0x00004AB6, 0x00004C5D, 0x00004DFE, 0x00004F8D, 0x00005122, 0x000052F0, 0x000054C6, 0x0000567B, 0x000057F3, 0x000059A4, 0x00005B64, 0x00005D08, 0x00005EC8, 0x00006088, 0x00006248, 0x000063F4, 0x000065C7, 0x0000676A, 0x00006908, 0x00006AA8, 0x00006C7B, 0x00006E4E, 0x00007019, 0x0000719D, 0x0000735E, 0x00007511, 0x000076C4, 0x0000786D, 0x00007A20, 0x00007BD4, 0x00007D8B, 0x00007F3A, 0x000080ED, 0x000082AB, 0x0000843E, 0x000085F4, 0x000087BA, 0x00008948, 0x00008B03, 0x00008C99, 0x00008E3C, 0x00008FE0, 0x00009195, 0x00009336, 0x000094DE, 0x0000967E, 0x0000980A, 0x00009995, 0x00009AF8, 0x00009CAE, 0x00009E28, 0x00009FB5, 0x0000A16E, 0x0000A30B, 0x0000A4A8, 0x0000A63B, 0x0000A7DF, 0x0000A99F, 0x0000AB4F, 0x0000ACEF, 0x0000AEA4, 0x0000B059, 0x0000B20A, 0x0000B3C0, 0x0000B569, 0x0000B706, 0x0000B8A6, 0x0000BA32, 0x0000BBD9, 0x0000BD79, 0x0000BF08, 0x0000C09D, 0x0000C26B, 0x0000C42E, 0x0000C5E3, 0x0000C75B, 0x0000C909, 0x0000CAC6, 0x0000CC6A, 0x0000CE2A, 0x0000CFEA, 0x0000D1AA, 0x0000D349, 0x0000D51C, 0x0000D6BF, 0x0000D85D, 0x0000D9FD, 0x0000DBD0, 0x0000DDA3, 0x0000DF6E, 0x0000E0F2, 0x0000E2B3, 0x0000E466, 0x00010BAE, 0x000118AD, 0x00011CFA, 0x0001211F, 0x00012544, 0x00012905, 0x00012E7E, 0x0001323F, 0x0001368C, 0x00013A25, 0x00013E36, 0x000141E3, 0x00014590, 0x00014A55, 0x00014E3E, 0x0001515F, 0x00015520, 0x00015981, 0x00015D92, 0x0001627F, 0x0001676C, 0x00016BCD, 0x00017092, 0x00017543, 0x00017990, 0x00017DDD, 0x00018216, 0x00018663, 0x00018A24, 0x00018F9D, 0x0001935E, 0x0001971F, 0x00019AE0, 0x00019E79, 0x0001A23A, 0x0001A64B, 0x0001ADB8, 0x0001B525, 0x0001BC92, 0x0001BF27, 0x0001C1BC, 0x0001C929, 0x0001D096, 0x0001D42F, 0x0001D7C8, 0x0001DF35, 0x0001E256, 0x0001E437, 0x0001E974, 0x0001ED85, 0x0001F196, 0x0001F43F, 0x0001F850, 0x0001FD8D, 0x000203A6, 0x000209BF, 0x00020D80, 0x000211CD, 0x000215F2, 0x00021A17, 0x00021DD8, 0x00022351, 0x00022712, 0x00022B5F, 0x00022FE8, 0x000233F9, 0x00023882, 0x00023D33, 0x000241F8, 0x00024645, 0x00024966, 0x00024E17, 0x00025278, 0x00025689, 0x00025AD6, 0x00025FC3, 0x00026424, 0x000268E9, 0x00026D9A, 0x000271E7, 0x00027634, 0x00027A6D, 0x00027EBA, 0x00028343, 0x00028754, 0x00028BA1, 0x00028FEE, 0x0002949F, 0x00029838, 0x00029BF9, 0x0002A00A, 0x0002A457, 0x0002A8A4, 0x0002ACF1, 0x0002AF86, 0x0002B21B, 0x0002B668, 0x0002BAB5, 0x0002BE4E, 0x0002C1E7, 0x0002C954, 0x0002CC75, 0x0002D126, 0x0002D663, 0x0002DA74, 0x0002DE85, 0x0002E12E, 0x0002E53F, 0x0002EA7C, 0x0002F095, 0x0002F6AE, 0x0002FB37, 0x0002FB5E, 0x0002FB86, 0x0002FB9C, 0x0002FBB6, 0x0002FBDD, 0x0002FC12, 0x0002FC31, 0x0002FC59, 0x0002FC79, 0x0002FC8E, 0x0002FCAE, 0x0002FCD6, 0x0002FCFC, 0x0002FD1B, 0x0002FD37, 0x0002FD62, 0x0002FD79, 0x0002FD91, 0x0002FDA2, 0x0002FDA2, 0x0002FDA2, 0x0002FDA2, 0x0002FDA2, 0x0002FDA2, 0x0002FDA2, 0x0002FDA2, 0x0002FDA2, 0x0002FDA2, 0x0002FDA2, 0x0002FDA2, 0x0002FDA2, 0x0002FDA2, 0x0002FDA2, 0x0002FDA2, 0x0002FDA2, 0x0002FDA2, 0x0002FDA2, 0x0002FDA2, 0x0002FDA2, 0x0002FDA2, 0x0002FDA2, 0x0002FDA2, 0x0002FDA2, 0x0002FDA2, 0x0002FDA2, 0x0002FDA2, 0x0002FDA2, 0x0002FDA2, 0x0002FDA2, 0x0002FDA2, 0x0002FDA2, 0x0002FDA2, 0x0002FDA2, 0x0002FDA2, 0x0002FDA2, 0x0002FDA2, 0x0002FDA2, 0x0002FDA2, 0x0002FDA2, 0x0002FDA2, 0x0002FDA2, 0x0002FDA2, 0x0002FDA2, 0x0002FDA2, 0x0002FDA2, 0x0002FDA2, 0x0002FDA2, 0x0002FDA2, 0x0002FDA2, 0x0002FDA2, 0x0002FDA2, 0x0002FDA2, 0x0002FDA2, 0x0002FDA2, 0x0002FDA2, 0x0002FDA2, 0x0002FDA2, 0x0002FDA2, 0x0002FDA2, 0x0002FDA2, 0x0002FDA2, 0x0002FDA2, 0x0002FDA2, 0x0002FDA2, 0x0002FDA2, 0x0002FDA2, 0x0002FDA2, 0x0002FDA2, 0x0002FDA2, 0x0002FDA2, 0x0002FDA2, 0x0002FE13, 0x0002FE27, 0x0002FE3E, 0x0002FE73, 0x0002FEA2, 0x0002FEC5, 0x0002FF02, 0x0002FF23, 0x0002FF58, 0x0002FF5A, 0x0002FF5C, 0x0002FF5E, 0x0002FF60, 0x0002FF96, 0x0002FFC8, 0x0002FFF9, 0x00030024, 0x0003005D, 0x000300BB, 0x0003010F, 0x00030173, 0x000301AA, 0x000301E0, 0x00030217, 0x0003024F, 0x00030286, 0x000302B6, 0x000302E6, 0x0003031C, 0x00030350, 0x0003037C, 0x000303B5, 0x000303E4, 0x00030417, 0x00030419, 0x0003044C, 0x0003047E, 0x000304E3, 0x000304E5, 0x00030519, 0x00030587, 0x000305DC, 0x00030627, 0x00030629, 0x000306EB, 0x0003071E, 0x00030751, 0x000307A6, 0x000307B5, 0x000307D7, 0x000307DE, 0x000307F4, 0x00030830, 0x0003086C, 0x000308A8, 0x000308B7, 0x000308D7, 0x00030905, 0x0003093D, 0x00030954, 0x00030976, 0x00030982, 0x0003098F, 0x0003099B, 0x000309C2, 0x000309F2, 0x00030A00, 0x00030A2C, 0x00030A4E, 0x00030A7F, 0x00030A84, 0x00030A99, 0x00030AB1, 0x00030AB6, 0x00030ACB, 0x00030AE3, 0x00030AF6, 0x00030B29, 0x00030B4C, 0x00030B63, 0x00030B76, 0x00030BA7, 0x00030BB6, 0x00030BBD, 0x00030BEE, 0x00030C21, 0x00030C4E, 0x00030C80, 0x00030C9F, 0x00030CAF, 0x00030CB5, 0x00030CE5, 0x00030D17, 0x00030D48, 0x00030D60, 0x00030D91, 0x00030DBB, 0x00030DE9, 0x00030DF6, 0x00030E0E, 0x00030E2C, 0x00030E4A, 0x00030E78, 0x00030E7D, 0x00030E99, 0x00030EAE, 0x00030ECA, 0x00030EE6, 0x00030EEB, 0x00030EEF, 0x00030EF3, 0x00030EF8, 0x00030EFE, 0x00030F02, 0x00030F18, 0x00030F2B, 0x00030F47, 0x00030F67, 0x00030F8A, 0x00030FAF, 0x00030FCE, 0x00030FF2, 0x00031010, 0x0003102D, 0x0003104B, 0x00031069, 0x00031087, 0x000310A5, 0x000310C3, 0x000310E6, 0x00031109, 0x0003112C, 0x0003114D, 0x00031173, 0x00031199, 0x000311BC, 0x000311E0, 0x00031204, 0x00031230, 0x0003124C, 0x00031264, 0x0003127C, 0x0003129D, 0x000312B8, 0x000312D1, 0x000312D3, 0x000314C2, 0x000314C3, 0x0003151F, 0x00031520, 0x0003157C, 0x0003157D, 0x00031740, 0x00031741, 0x000317D3, 0x000317D4, 0x0003184F, 0x000318F0, 0x0003199C, 0x00031A44, 0x00031AE8, 0x00031B9A, 0x00031C49, 0x00031D09, 0x00031DAD, 0x00031E7D, 0x00031F56, 0x0003202B, 0x00032103, 0x000321E6, 0x000322BE, 0x0003239D, 0x0003243D, 0x0003243E, 0x0003243F, 0x00032440, 0x00032441, 0x00032442, 0x00032443, 0x0003259E, 0x0003259F, 0x000325E9, 0x000325EF, 0x00032692, 0x0003269F, 0x000327F3, 0x0003282A, 0x000328DB, 0x000329C6, 0x00032A82, 0x00032B12, 0x00032B6D, 0x00032BD3, 0x00032C61, 0x00032D3F, 0x00032E1D, 0x00032E7D, 0x00032E83, 0x00032E8A, 0x00032E92, 0x00032EA4, 0x00032EB2, 0x00032EBE, 0x00032ECA, 0x00032ED0, 0x00032ED7, 0x00032EE8, 0x00032EFE, 0x00032F07, 0x00032F16, 0x00032F25, 0x00032F3D, 0x00032F48, 0x00032F53, 0x00032F62, 0x00032F78, 0x00032F87, 0x00032F96, 0x00032FA1, 0x00032FB3, 0x00032FC5, 0x00032FCC, 0x00032FDA, 0x00032FE9, 0x00032FF6, 0x00032FFE, 0x0003300E, 0x0003301E, 0x00033028, 0x00034A48, 0x00034AC9, 0x00034B4A, 0x00034BCB, 0x00034C4C, 0x00034CCD, 0x00034D4E, 0x00034DCF, 0x00034E50, 0x00034ED1, 0x00034F52, 0x00034FD3, 0x00035054, 0x000350D5, 0x00035156, 0x000351D7, 0x00035258, 0x000352D9, 0x0003531A, 0x0003539B, 0x0003541C, 0x0003549D, 0x0003551E, 0x0003559F, 0x00035620, 0x000356A1, 0x00035722, 0x000357A3, 0x00035824, 0x000358A5, 0x00035926, 0x000359A7, 0x00035A28, 0x00035AA9, 0x00035B2A, 0x00035BAB, 0x00035C2C, 0x00035CAD, 0x00035D2E, 0x00035DAF, 0x00035E30, 0x00035EB1, 0x00035F32, 0x00035FB3, 0x00036034, 0x000360B5, 0x00036136, 0x000361B7, 0x00036238, 0x000362B9, 0x0003633A, 0x000363BB, 0x0003643C, 0x000364BD, 0x0003653E, 0x000365BF, 0x00036640, 0x000366C1, 0x00036742, 0x000367C3, 0x00036844, 0x000368C5, 0x00036946, 0x000369C7, 0x00036A48, 0x00036AC9, 0x00036B4A, 0x00036BCB, 0x00036C4C, 0x00036CCD, 0x00036D4E, 0x00036DCF, 0x00036E50, 0x00036ED1, 0x00036F52, 0x00036FD3, 0x00037054, 0x000370D5, 0x00037156, 0x000371D7, 0x00037258, 0x000372D9, 0x0003735A, 0x000373DB, 0x0003745C, 0x000374DD, 0x0003755E, 0x000375DF, 0x00037660, 0x000376E1, 0x00037762, 0x000377E3, 0x00037864, 0x000378E5, 0x00037966, 0x000379E7, 0x00037A68, 0x00037AE9, 0x00037B6A, 0x00037BEB, 0x00037C6C, 0x00037CED, 0x00038115, 0x0003859D, 0x00038905, 0x00038BC9, 0x00038E34, 0x00038F7D, 0x0003975A, 0x00039F9B, 0x0003A3C3, 0x0003A84B, 0x0003ABB3, 0x0003AE77, 0x0003B0E2, 0x0003B50A, 0x0003B992, 0x0003BCFA, 0x0003BFBE, 0x0003C229, 0x0003CA6C, 0x0003CAEA, 0x0003CB68, 0x0003D365, 0x0003D523, 0x0003D678, 0x0003DC65, 0x0003E191, 0x0003E7F6, 0x0003ECB4, 0x0003F457, 0x0003F55C, 0x0003F5E4, 0x0003F66C, 0x0003F787, 0x0003F8A2, 0x0003F92A, 0x0003FDFD, 0x000404F1, 0x0004069C, 0x00040842, 0x00040AA8, 0x00040DE9, 0x00040ECD, 0x00040F88, 0x00041402, 0x00041C88, 0x00041CF1, 0x000420B7, 0x0004247D, 0x000429EB, 0x00042AC5, 0x00042BD1, 0x00042CF6, 0x00042D9B, 0x00043406, 0x00043B3A, 0x00043CC6, 0x00043DEA, 0x00044F20, 0x0004516F, 0x000453C1, 0x000456AF, 0x0004599D, 0x00045AD7, 0x00045C13, 0x0004609E, 0x000462E3, 0x0004646F, 0x00046914, 0x00046B1F, 0x00046C2B, 0x00047082, 0x0004767C, 0x00047BDF, 0x00047CA1, 0x0004815A, 0x00048C62, 0x0004901B, 0x00049258, 0x00049449, 0x0004A4AB, 0x0004B20E, 0x0004B271, 0x0004B46F, 0x0004B66D, 0x0004B878, 0x0004BACA, 0x0004BCDD, 0x0004BE84, 0x0004C091, 0x0004C29E, 0x0004C434, 0x0004C64B, 0x0004C758, 0x0004C891, 0x0004DB83, 0x0004DCBF, 0x0004DF96, 0x0004E07F, 0x0004E5A8, 0x0004F19E, 0x0004F383, 0x0004F568, 0x0004F833, 0x0004F91C, 0x0004FE31, 0x000502C4, 0x0005051A, 0x0005065D, 0x00050A14, 0x00050D9F, 0x00051236, 0x000517A0, 0x00052683, 0x00052A28, 0x00052F8F, 0x00053617, 0x0005389F, 0x000539EB, 0x0005452B, 0x000545B0, 0x00054677, 0x00054884, 0x00054FAE, 0x00055327, 0x000553A8, 0x00055430, 0x00055799, 0x00055989, 0x00055B7F, 0x00055D71, 0x00055F04, 0x0005612D, 0x00056245, 0x0005635D, 0x00056475, 0x0005658D, 0x000566A5, 0x000566A6, 0x00056B39, 0x00056C51, 0x00056D69, 0x00056E81, 0x00056F99, 0x000570B1, 0x000583AA, 0x00058839, 0x00058944, 0x00058B66, 0x00058FF1, 0x0005936A, 0x00059483, 0x0005959C, 0x00059791, 0x00059BA7, 0x00059C30, 0x00059CB9, 0x0005A035, 0x0005A1D7, 0x0005A379, 0x0005A78E, 0x0005A97E, 0x0005AB6E, 0x0005AD5E, 0x0005AF4E, 0x0005BA3F, 0x0005C25F, 0x0005C8BB, 0x0005CE58, 0x0005D3DD, 0x0005D4C4, 0x0005DAD0, 0x0005E12C, 0x0005E1E2, 0x0005E8B1, 0x0005E96B, 0x0005EA25, 0x0005EADF, 0x0005EF11, 0x0005F3A5, 0x0005F822, 0x0005FCCD, 0x0005FFF8, 0x0005FFF9, 0x00060462, 0x00060608, 0x00060916, 0x00061B8C, 0x00061DF8, 0x0006213C, 0x0006224E, 0x00062352, 0x00062548, 0x0006265A, 0x0006278C, 0x00062880, 0x0006298C, 0x00062D33, 0x00062EB0, 0x0006303D, 0x0006314F, 0x00063281, 0x00063A40, 0x00064657, 0x00064CEC, 0x00064F42, 0x0006503F, 0x0006513C, 0x0006528F, 0x00065CA5, 0x0006620C, 0x0006653A, 0x00066803, 0x0006688B, 0x000669E0, 0x00066C80, 0x00067D5D, 0x00067DEB, 0x00067FA7, 0x00068154, 0x0006826F, 0x0006853F, 0x00068626, 0x0006870D, 0x000689CD, 0x00068AD2, 0x00068B4F, 0x00068BCC, 0x00068BCD, 0x00069615, 0x00069616, 0x00069694, 0x0006A32D, 0x0006A3EE, 0x0006A4AD, 0x0006A510, 0x0006A9C6, 0x0006AAE1, 0x0006ABFC, 0x0006AD17, 0x0006AE32, 0x0006AF4D, 0x0006B068, 0x0006B162, 0x0006B25C, 0x0006B356, 0x0006B450, 0x0006B54A, 0x0006B644, 0x0006B72B, 0x0006B812, 0x0006B8F9, 0x0006B9E0, 0x0006BAC7, 0x0006BBAE, 0x0006BC95, 0x0006BD7C, 0x0006CCB6, 0x0006CEAA, 0x0006D09A, 0x0006D177, 0x0006D254, 0x0006D2DF, 0x0006D3A5, 0x0006D54E, 0x0006D959, 0x0006DC37, 0x0006DD4D, 0x0006DE5F, 0x0006E0E1, 0x0006E7EC, 0x0006E8DF, 0x0006EB9F, 0x0006EC95, 0x0006F0B9, 0x0006F3B4, 0x0006F6AF, 0x0006F9AA, 0x0006FB31, 0x00070ED3, 0x00070F7B, 0x000710A2, 0x000711C8, 0x000712AE, 0x000713CB, 0x000714CF, 0x000715D3, 0x00071853, 0x00071971, 0x00071C88, 0x00071EA2, 0x00072084, 0x00072361, 0x00073703, 0x000737AB, 0x000738D2, 0x000739F8, 0x00073ADE, 0x00073BFB, 0x00073CFF, 0x00073E03, 0x00074083, 0x000741A1, 0x000744B8, 0x000746D2, 0x000748B4, 0x00074B91, 0x00074FB0, 0x00076139, 0x0007720C, 0x00077641, 0x00077763, 0x00077D2C, 0x00078C66, 0x00079E74, 0x00079F69, 0x0007A0A6, 0x0007A161, 0x0007A29A, 0x0007A59E, 0x0007A8CE, 0x0007AADB, 0x0007ADD8, 0x0007B0A9, 0x0007B188, 0x0007B386, 0x0007BB8B, 0x0007BBBC, 0x0007BFCA, 0x0007C103, 0x0007C23C, 0x0007C5F9, 0x0007C709, 0x0007C819, 0x0007CDAD, 0x0007CE73, 0x0007CF39, 0x0007D2E6, 0x0007D4A7, 0x0007D668, 0x0007DCAC, 0x0007E04F, 0x0007E3F2, 0x0007E8D8, 0x0007E9DC, 0x0007EAE0, 0x0007FD00, 0x0007FDDD, 0x0007FECA, 0x00080024, 0x000801DB, 0x0008037A, 0x000804C9, 0x00080767, 0x00080949, 0x00080B5D, 0x00080D73, 0x00080F6A, 0x0008118F, 0x000813A7, 0x0008154E, 0x00081604, 0x00081805, 0x00081A8E, 0x00081C70, 0x00081E49, 0x00081FEA, 0x0008222C, 0x0008246A, 0x0008266C, 0x000828AB, 0x000829BF, 0x00082AFC, 0x00082BFD, 0x00082CFF, 0x00082DF5, 0x00082F0B, 0x0008301F, 0x00083077, 0x0008405C, 0x000842D5, 0x0008454E, 0x00084853, 0x00084ACC, 0x00084BD0, 0x00084C5D, 0x00084D8A, 0x0008507D, 0x00085370, 0x00085BF6, 0x00085C80, 0x00085EE0, 0x0008641D, 0x00086522, 0x0008665E, 0x0008679A, 0x0008692E, 0x00087852, 0x000879BA, 0x00087B22, 0x0008876A, 0x00089D0A, 0x0008A09F, 0x0008B7C3, 0x0008C4BF, 0x0008C4ED, 0x0008D058, 0x0008D32B, 0x0008D725, 0x0008DB21, 0x0008E066, 0x0008E5AB, 0x0008EC2F, 0x0008FF4A, 0x0009122D, 0x00091352, 0x0009147F, 0x000915AA, 0x000916E0, 0x000927E0, 0x000927E1, 0x000936F2, 0x0009384A, 0x000939A2, 0x00093CF0, 0x00093E02, 0x00093F1F, 0x0009403C, 0x00094145, 0x00094350, 0x000946FC, 0x00094AE4, 0x00094D6D, 0x00094E71, 0x00094F75, 0x0009506B, 0x00095170, 0x00095304, 0x00095424, 0x00095533, 0x00095653, 0x000959CA, 0x00095AC0, 0x00095AC1, 0x00095C36, 0x0009632B, 0x00096745, 0x000969EB, 0x00096E23, 0x00096F7C, 0x00097107, 0x00097247, 0x00097E8F, 0x000981A3, 0x000986BD, 0x000986BE, 0x00098927, 0x00098A3D, 0x00098B53, 0x000990A4, 0x000991A9, 0x000992AE, 0x00099992, 0x00099DC6, 0x00099ED0, 0x00099FDA, 0x0009A389, 0x0009A464, 0x0009A53F, 0x0009A61A, 0x0009A6F5, 0x0009AE2D, 0x0009AFAF, 0x0009B722, 0x0009B826, 0x0009BAD4, 0x0009BBD9, 0x0009BCF4, 0x0009BE12, 0x0009BFE4, 0x0009C0FD, 0x0009C21C, 0x0009C3BF, 0x0009C49E, 0x0009C5B7, 0x0009C6D3, 0x0009CCB2, 0x0009D22F, 0x0009D363, 0x0009D4BA, 0x0009D5BF, 0x0009D6DF, 0x0009D7C6, 0x0009DC4D, 0x0009EC05, 0x0009F13B, 0x0009F4CA, 0x000A0431, 0x000A08C6, 0x000A0DDB, 0x000A1115, 0x000A156F, 0x000A16B2, 0x000A18A2, 0x000A19BB, 0x000A1B6E, 0x000A1D2F, 0x000A2EA8, 0x000A3049, 0x000A32FD, 0x000A35B1, 0x000A38F7, 0x000A3A68, 0x000A3D15, 0x000A3FC2, 0x000A4165, 0x000A4308, 0x000A4364, 0x000A43C0, 0x000A4529, 0x000A4699, 0x000A4946, 0x000A4BF3, 0x000A4D99, 0x000A4F3F, 0x000A5156, 0x000A51CD, 0x000A549E, 0x000A57A8, 0x000A5A55, 0x000A5D02, 0x000A5D5E, 0x000A5F08, 0x000A60B2, 0x000A6117, 0x000A6177, 0x000A631A, 0x000A64BD, 0x000A6565, 0x000A65E0, 0x000A7467, 0x000A7592, 0x000A76CA, 0x000A7A56, 0x000A7B60, 0x000A7C6A, 0x000A7D96, 0x000A7EC2, 0x000A8411, 0x000A851E, 0x000A862F, 0x000A873C, 0x000A8849, 0x000A96C4, 0x000A9BC0, 0x000AA0BE, 0x000AA395, 0x000AAA24, 0x000AABAF, 0x000AAD3A, 0x000AAD3B, 0x000AB75D, 0x000ABB1C, 0x000ABB7B, 0x000ABBD9, 0x000ABDDF, 0x000ABDE0, 0x000ACDBF, 0x000ADBC8, 0x000AEF30, 0x000AFF70, 0x000B10F6, 0x000B20B0, 0x000B3605, 0x000B388F, 0x000B3890, 0x000B455A, 0x000B4668, 0x000B4B10, 0x000B4EAA, 0x000B5AC4, 0x000B5C00, 0x000B5F1C, 0x000B627B, 0x000B6707, 0x000B68FB, 0x000B6EF6, 0x000B7542, 0x000B7637, 0x000B7BA5, 0x000B7D4F, 0x000B7EEB, 0x000B8715, 0x000B8C69, 0x000B8EAA, 0x000B90D8, 0x000B9142, 0x000B9285, 0x000B9705, 0x000B9B31, 0x000B9D94, 0x000BA08F, 0x000BA38A, 0x000BA712, 0x000BA9B6, 0x000BAEA0, 0x000BB365, 0x000BB7DE, 0x000BBCF3, 0x000BC124, 0x000BC56F, 0x000BC9DE, 0x000BCDAA, 0x000BD142, 0x000BD6AD, 0x000BDC75, 0x000BDF2B, 0x000BE304, 0x000BE7A1, 0x000BEB23, 0x000BEE22, 0x000BF017, 0x000BF53C, 0x000C043B, 0x000C04F9, 0x000C05BD, 0x000C064D, 0x000C075C, 0x000C086B, 0x000C097A, 0x000C0A89, 0x000C0B8D, 0x000C0C91, 0x000C0D95, 0x000C0EAA, 0x000C0FBF, 0x000C10D4, 0x000C11E9, 0x000C15E5, 0x000C1721, 0x000C1B69, 0x000C229C, 0x000C2524, 0x000C27A7, 0x000C28CE, 0x000C312B, 0x000C42F7, 0x000C49A1, 0x000C4DCA, 0x000C4EEF, 0x000C5936, 0x000C59AA, 0x000C5EAD, 0x000C5F0F, 0x000C5F78, 0x000C64E0, 0x000C65EF, 0x000C66F3, 0x000C794A, 0x000C7CE7, 0x000C7F74, 0x000C831E, 0x000C841F, 0x000C8513, 0x000C85F2, 0x000C8801, 0x000C8905, 0x000C8E13, 0x000C9093, 0x000C9313, 0x000C9593, 0x000C96A8, 0x000C9988, 0x000CA880, 0x000CAF7D, 0x000CB751, 0x000CC7F2, 0x000CCC28, 0x000CCE20, 0x000CD33B, 0x000CD55E, 0x000CE55B, 0x000CEB0D, 0x000CEE15, 0x000CF01F, 0x000CF1EB, 0x000D0413, 0x000D089A, 0x000D099B, 0x000D0B87, 0x000D0DF9, 0x000D0E79, 0x000D1779, 0x000D1CF6, 0x000D2943, 0x000D2D64, 0x000D30D5, 0x000D327C, 0x000D35D4, 0x000D38F9, 0x000D3A0B, 0x000D3E06, 0x000D43DC, 0x000D4830, 0x000D50D3, 0x000D5F2C, 0x000D60EA, 0x000D64FA, 0x000D68FD, 0x000D6CF7, 0x000D7107, 0x000D74B4, 0x000D78B4, 0x000D7B9D, 0x000D7D81, 0x000D8D3D, 0x000D99C1, 0x000DA016, 0x000DA230, 0x000DA3B0, 0x000DB6A6, 0x000DC3B4, 0x000DC55A, 0x000DC5B6, 0x000DC61A, 0x000DC773, 0x000DC893, 0x000DC9F9, 0x000DCB93, 0x000DCC94, 0x000DCEA7, 0x000DCF7E, 0x000DD247, 0x000DD46C, 0x000DDBB1, 0x000DE2B6, 0x000DE88A, 0x000DF247, 0x000DF5F9, 0x000DFAB0, 0x000DFDA5, 0x000DFEBD, 0x000E0246, 0x000E0360, 0x000E0534, 0x000E062E, 0x000E077E, 0x000E08A4, 0x000E0C8D, 0x000E0D92, 0x000E102D, 0x000E16A7, 0x000E1A68, 0x000E1E29, 0x000E21EA, 0x000E28C2];
const file_sizes = [0x0000003A, 0x0000003A, 0x0000003A, 0x0000004A, 0x00000000, 0x00000000, 0x00000000, 0x00000168, 0x00000000, 0x000002E5, 0x000001B3, 0x000001B8, 0x000001AC, 0x000001BB, 0x000001C1, 0x000001BC, 0x000001B3, 0x000001B9, 0x00000193, 0x000001B6, 0x000001D6, 0x0000018E, 0x000001C0, 0x00000196, 0x000001A3, 0x000001A3, 0x000001B5, 0x000001A2, 0x000001AA, 0x000001A0, 0x0000018C, 0x0000018B, 0x00000163, 0x000001AE, 0x0000017A, 0x0000018D, 0x000001B9, 0x000001A3, 0x000001A3, 0x00000193, 0x000001A4, 0x000001C0, 0x000001B0, 0x000001A0, 0x000001B7, 0x000001B7, 0x000001B2, 0x000001C5, 0x000001A9, 0x0000019D, 0x000001A0, 0x0000018C, 0x000001A7, 0x000001A1, 0x0000018F, 0x00000195, 0x000001CE, 0x000001D6, 0x000001B5, 0x00000178, 0x000001B1, 0x000001C0, 0x000001A4, 0x000001C0, 0x000001C0, 0x000001C0, 0x000001AC, 0x000001D3, 0x000001A3, 0x0000019E, 0x000001A0, 0x000001D3, 0x000001D3, 0x000001CB, 0x00000184, 0x000001C1, 0x000001B3, 0x000001B3, 0x000001A9, 0x000001B3, 0x000001B4, 0x000001B7, 0x000001AF, 0x000001B3, 0x000001BE, 0x00000193, 0x000001B6, 0x000001C6, 0x0000018E, 0x000001BB, 0x00000196, 0x000001A3, 0x000001A4, 0x000001B5, 0x000001A1, 0x000001A8, 0x000001A0, 0x0000018C, 0x0000018B, 0x00000163, 0x000001B6, 0x0000017A, 0x0000018D, 0x000001B9, 0x0000019D, 0x0000019D, 0x00000193, 0x000001A4, 0x000001C0, 0x000001B0, 0x000001A0, 0x000001B5, 0x000001B5, 0x000001B1, 0x000001B6, 0x000001A9, 0x0000019D, 0x000001A0, 0x0000018C, 0x000001A7, 0x000001A0, 0x0000018F, 0x00000195, 0x000001CE, 0x000001C3, 0x000001B5, 0x00000178, 0x000001AE, 0x000001BD, 0x000001A4, 0x000001C0, 0x000001C0, 0x000001C0, 0x0000019F, 0x000001D3, 0x000001A3, 0x0000019E, 0x000001A0, 0x000001D3, 0x000001D3, 0x000001CB, 0x00000184, 0x000001C1, 0x000001B3, 0x00002748, 0x00000CFF, 0x0000044D, 0x00000425, 0x00000425, 0x000003C1, 0x00000579, 0x000003C1, 0x0000044D, 0x00000399, 0x00000411, 0x000003AD, 0x000003AD, 0x000004C5, 0x000003E9, 0x00000321, 0x000003C1, 0x00000461, 0x00000411, 0x000004ED, 0x000004ED, 0x00000461, 0x000004C5, 0x000004B1, 0x0000044D, 0x0000044D, 0x00000439, 0x0000044D, 0x000003C1, 0x00000579, 0x000003C1, 0x000003C1, 0x000003C1, 0x00000399, 0x000003C1, 0x00000411, 0x0000076D, 0x0000076D, 0x0000076D, 0x00000295, 0x00000295, 0x0000076D, 0x0000076D, 0x00000399, 0x00000399, 0x0000076D, 0x00000321, 0x000001E1, 0x0000053D, 0x00000411, 0x00000411, 0x000002A9, 0x00000411, 0x0000053D, 0x00000619, 0x00000619, 0x000003C1, 0x0000044D, 0x00000425, 0x00000425, 0x000003C1, 0x00000579, 0x000003C1, 0x0000044D, 0x00000489, 0x00000411, 0x00000489, 0x000004B1, 0x000004C5, 0x0000044D, 0x00000321, 0x000004B1, 0x00000461, 0x00000411, 0x0000044D, 0x000004ED, 0x00000461, 0x000004C5, 0x000004B1, 0x0000044D, 0x0000044D, 0x00000439, 0x0000044D, 0x00000489, 0x00000411, 0x0000044D, 0x0000044D, 0x000004B1, 0x00000399, 0x000003C1, 0x00000411, 0x0000044D, 0x0000044D, 0x0000044D, 0x00000295, 0x00000295, 0x0000044D, 0x0000044D, 0x00000399, 0x00000399, 0x0000076D, 0x00000321, 0x000004B1, 0x0000053D, 0x00000411, 0x00000411, 0x000002A9, 0x00000411, 0x0000053D, 0x00000619, 0x00000619, 0x00000489, 0x00000027, 0x00000028, 0x00000016, 0x0000001A, 0x00000027, 0x00000035, 0x0000001F, 0x00000028, 0x00000020, 0x00000015, 0x00000020, 0x00000028, 0x00000026, 0x0000001F, 0x0000001C, 0x0000002B, 0x00000017, 0x00000018, 0x00000011, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000071, 0x00000014, 0x00000017, 0x00000035, 0x0000002F, 0x00000023, 0x0000003D, 0x00000021, 0x00000035, 0x00000002, 0x00000002, 0x00000002, 0x00000002, 0x00000036, 0x00000032, 0x00000031, 0x0000002B, 0x00000039, 0x0000005E, 0x00000054, 0x00000064, 0x00000037, 0x00000036, 0x00000037, 0x00000038, 0x00000037, 0x00000030, 0x00000030, 0x00000036, 0x00000034, 0x0000002C, 0x00000039, 0x0000002F, 0x00000033, 0x00000002, 0x00000033, 0x00000032, 0x00000065, 0x00000002, 0x00000034, 0x0000006E, 0x00000055, 0x0000004B, 0x00000002, 0x000000C2, 0x00000033, 0x00000033, 0x00000055, 0x0000000F, 0x00000022, 0x00000007, 0x00000016, 0x0000003C, 0x0000003C, 0x0000003C, 0x0000000F, 0x00000020, 0x0000002E, 0x00000038, 0x00000017, 0x00000022, 0x0000000C, 0x0000000D, 0x0000000C, 0x00000027, 0x00000030, 0x0000000E, 0x0000002C, 0x00000022, 0x00000031, 0x00000005, 0x00000015, 0x00000018, 0x00000005, 0x00000015, 0x00000018, 0x00000013, 0x00000033, 0x00000023, 0x00000017, 0x00000013, 0x00000031, 0x0000000F, 0x00000007, 0x00000031, 0x00000033, 0x0000002D, 0x00000032, 0x0000001F, 0x00000010, 0x00000006, 0x00000030, 0x00000032, 0x00000031, 0x00000018, 0x00000031, 0x0000002A, 0x0000002E, 0x0000000D, 0x00000018, 0x0000001E, 0x0000001E, 0x0000002E, 0x00000005, 0x0000001C, 0x00000015, 0x0000001C, 0x0000001C, 0x00000005, 0x00000004, 0x00000004, 0x00000005, 0x00000006, 0x00000004, 0x00000016, 0x00000013, 0x0000001C, 0x00000020, 0x00000023, 0x00000025, 0x0000001F, 0x00000024, 0x0000001E, 0x0000001D, 0x0000001E, 0x0000001E, 0x0000001E, 0x0000001E, 0x0000001E, 0x00000023, 0x00000023, 0x00000023, 0x00000021, 0x00000026, 0x00000026, 0x00000023, 0x00000024, 0x00000024, 0x0000002C, 0x0000001C, 0x00000018, 0x00000018, 0x00000021, 0x0000001B, 0x00000019, 0x00000002, 0x000001EF, 0x00000001, 0x0000005C, 0x00000001, 0x0000005C, 0x00000001, 0x000001C3, 0x00000001, 0x00000092, 0x00000001, 0x0000007B, 0x000000A1, 0x000000AC, 0x000000A8, 0x000000A4, 0x000000B2, 0x000000AF, 0x000000C0, 0x000000A4, 0x000000D0, 0x000000D9, 0x000000D5, 0x000000D8, 0x000000E3, 0x000000D8, 0x000000DF, 0x000000A0, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x0000015B, 0x00000001, 0x0000004A, 0x00000006, 0x000000A3, 0x0000000D, 0x00000154, 0x00000037, 0x000000B1, 0x000000EB, 0x000000BC, 0x00000090, 0x0000005B, 0x00000066, 0x0000008E, 0x000000DE, 0x000000DE, 0x00000060, 0x00000006, 0x00000007, 0x00000008, 0x00000012, 0x0000000E, 0x0000000C, 0x0000000C, 0x00000006, 0x00000007, 0x00000011, 0x00000016, 0x00000009, 0x0000000F, 0x0000000F, 0x00000018, 0x0000000B, 0x0000000B, 0x0000000F, 0x00000016, 0x0000000F, 0x0000000F, 0x0000000B, 0x00000012, 0x00000012, 0x00000007, 0x0000000E, 0x0000000F, 0x0000000D, 0x00000008, 0x00000010, 0x00000010, 0x0000000A, 0x00001A20, 0x00000081, 0x00000081, 0x00000081, 0x00000081, 0x00000081, 0x00000081, 0x00000081, 0x00000081, 0x00000081, 0x00000081, 0x00000081, 0x00000081, 0x00000081, 0x00000081, 0x00000081, 0x00000081, 0x00000081, 0x00000041, 0x00000081, 0x00000081, 0x00000081, 0x00000081, 0x00000081, 0x00000081, 0x00000081, 0x00000081, 0x00000081, 0x00000081, 0x00000081, 0x00000081, 0x00000081, 0x00000081, 0x00000081, 0x00000081, 0x00000081, 0x00000081, 0x00000081, 0x00000081, 0x00000081, 0x00000081, 0x00000081, 0x00000081, 0x00000081, 0x00000081, 0x00000081, 0x00000081, 0x00000081, 0x00000081, 0x00000081, 0x00000081, 0x00000081, 0x00000081, 0x00000081, 0x00000081, 0x00000081, 0x00000081, 0x00000081, 0x00000081, 0x00000081, 0x00000081, 0x00000081, 0x00000081, 0x00000081, 0x00000081, 0x00000081, 0x00000081, 0x00000081, 0x00000081, 0x00000081, 0x00000081, 0x00000081, 0x00000081, 0x00000081, 0x00000081, 0x00000081, 0x00000081, 0x00000081, 0x00000081, 0x00000081, 0x00000081, 0x00000081, 0x00000081, 0x00000081, 0x00000081, 0x00000081, 0x00000081, 0x00000081, 0x00000081, 0x00000081, 0x00000081, 0x00000081, 0x00000081, 0x00000081, 0x00000081, 0x00000081, 0x00000081, 0x00000081, 0x00000081, 0x00000081, 0x00000081, 0x00000081, 0x00000428, 0x00000488, 0x00000368, 0x000002C4, 0x0000026B, 0x00000149, 0x000007DD, 0x00000841, 0x00000428, 0x00000488, 0x00000368, 0x000002C4, 0x0000026B, 0x00000428, 0x00000488, 0x00000368, 0x000002C4, 0x0000026B, 0x00000843, 0x0000007E, 0x0000007E, 0x000007FD, 0x000001BE, 0x00000155, 0x000005ED, 0x0000052C, 0x00000665, 0x000004BE, 0x000007A3, 0x00000105, 0x00000088, 0x00000088, 0x0000011B, 0x0000011B, 0x00000088, 0x000004D3, 0x000006F4, 0x000001AB, 0x000001A6, 0x00000266, 0x00000341, 0x000000E4, 0x000000BB, 0x0000047A, 0x00000886, 0x00000069, 0x000003C6, 0x000003C6, 0x0000056E, 0x000000DA, 0x0000010C, 0x00000125, 0x000000A5, 0x0000066B, 0x00000734, 0x0000018C, 0x00000124, 0x00001136, 0x0000024F, 0x00000252, 0x000002EE, 0x000002EE, 0x0000013A, 0x0000013C, 0x0000048B, 0x00000245, 0x0000018C, 0x000004A5, 0x0000020B, 0x0000010C, 0x00000457, 0x000005FA, 0x00000563, 0x000000C2, 0x000004B9, 0x00000B08, 0x000003B9, 0x0000023D, 0x000001F1, 0x00001062, 0x00000D63, 0x00000063, 0x000001FE, 0x000001FE, 0x0000020B, 0x00000252, 0x00000213, 0x000001A7, 0x0000020D, 0x0000020D, 0x00000196, 0x00000217, 0x0000010D, 0x00000139, 0x000012F2, 0x0000013C, 0x000002D7, 0x000000E9, 0x00000529, 0x00000BF6, 0x000001E5, 0x000001E5, 0x000002CB, 0x000000E9, 0x00000515, 0x00000493, 0x00000256, 0x00000143, 0x000003B7, 0x0000038B, 0x00000497, 0x0000056A, 0x00000EE3, 0x000003A5, 0x00000567, 0x00000688, 0x00000288, 0x0000014C, 0x00000B40, 0x00000085, 0x000000C7, 0x0000020D, 0x0000072A, 0x00000379, 0x00000081, 0x00000088, 0x00000369, 0x000001F0, 0x000001F6, 0x000001F2, 0x00000193, 0x00000229, 0x00000118, 0x00000118, 0x00000118, 0x00000118, 0x00000118, 0x00000001, 0x00000493, 0x00000118, 0x00000118, 0x00000118, 0x00000118, 0x00000118, 0x000012F9, 0x0000048F, 0x0000010B, 0x00000222, 0x0000048B, 0x00000379, 0x00000119, 0x00000119, 0x000001F5, 0x00000416, 0x00000089, 0x00000089, 0x0000037C, 0x000001A2, 0x000001A2, 0x00000415, 0x000001F0, 0x000001F0, 0x000001F0, 0x000001F0, 0x00000AF1, 0x00000820, 0x0000065C, 0x0000059D, 0x00000585, 0x000000E7, 0x0000060C, 0x0000065C, 0x000000B6, 0x000006CF, 0x000000BA, 0x000000BA, 0x000000BA, 0x00000432, 0x00000494, 0x0000047D, 0x000004AB, 0x0000032B, 0x00000001, 0x00000469, 0x000001A6, 0x0000030E, 0x00001276, 0x0000026C, 0x00000344, 0x00000112, 0x00000104, 0x000001F6, 0x00000112, 0x00000132, 0x000000F4, 0x0000010C, 0x000003A7, 0x0000017D, 0x0000018D, 0x00000112, 0x00000132, 0x000007BF, 0x00000C17, 0x00000695, 0x00000256, 0x000000FD, 0x000000FD, 0x00000153, 0x00000A16, 0x00000567, 0x0000032E, 0x000002C9, 0x00000088, 0x00000155, 0x000002A0, 0x000010DD, 0x0000008E, 0x000001BC, 0x000001AD, 0x0000011B, 0x000002D0, 0x000000E7, 0x000000E7, 0x000002C0, 0x00000105, 0x0000007D, 0x0000007D, 0x00000001, 0x00000A48, 0x00000001, 0x0000007E, 0x00000C99, 0x000000C1, 0x000000BF, 0x00000063, 0x000004B6, 0x0000011B, 0x0000011B, 0x0000011B, 0x0000011B, 0x0000011B, 0x0000011B, 0x000000FA, 0x000000FA, 0x000000FA, 0x000000FA, 0x000000FA, 0x000000FA, 0x000000E7, 0x000000E7, 0x000000E7, 0x000000E7, 0x000000E7, 0x000000E7, 0x000000E7, 0x000000E7, 0x00000F3A, 0x000001F4, 0x000001F0, 0x000000DD, 0x000000DD, 0x0000008B, 0x000000C6, 0x000001A9, 0x0000040B, 0x000002DE, 0x00000116, 0x00000112, 0x00000282, 0x0000070B, 0x000000F3, 0x000002C0, 0x000000F6, 0x00000424, 0x000002FB, 0x000002FB, 0x000002FB, 0x00000187, 0x000013A2, 0x000000A8, 0x00000127, 0x00000126, 0x000000E6, 0x0000011D, 0x00000104, 0x00000104, 0x00000280, 0x0000011E, 0x00000317, 0x0000021A, 0x000001E2, 0x000002DD, 0x000013A2, 0x000000A8, 0x00000127, 0x00000126, 0x000000E6, 0x0000011D, 0x00000104, 0x00000104, 0x00000280, 0x0000011E, 0x00000317, 0x0000021A, 0x000001E2, 0x000002DD, 0x0000041F, 0x00001189, 0x000010D3, 0x00000435, 0x00000122, 0x000005C9, 0x00000F3A, 0x0000120E, 0x000000F5, 0x0000013D, 0x000000BB, 0x00000139, 0x00000304, 0x00000330, 0x0000020D, 0x000002FD, 0x000002D1, 0x000000DF, 0x000001FE, 0x00000805, 0x00000031, 0x0000040E, 0x00000139, 0x00000139, 0x000003BD, 0x00000110, 0x00000110, 0x00000594, 0x000000C6, 0x000000C6, 0x000003AD, 0x000001C1, 0x000001C1, 0x00000644, 0x000003A3, 0x000003A3, 0x000004E6, 0x00000104, 0x00000104, 0x00001220, 0x000000DD, 0x000000ED, 0x0000015A, 0x000001B7, 0x0000019F, 0x0000014F, 0x0000029E, 0x000001E2, 0x00000214, 0x00000216, 0x000001F7, 0x00000225, 0x00000218, 0x000001A7, 0x000000B6, 0x00000201, 0x00000289, 0x000001E2, 0x000001D9, 0x000001A1, 0x00000242, 0x0000023E, 0x00000202, 0x0000023F, 0x00000114, 0x0000013D, 0x00000101, 0x00000102, 0x000000F6, 0x00000116, 0x00000114, 0x00000058, 0x00000FE5, 0x00000279, 0x00000279, 0x00000305, 0x00000279, 0x00000104, 0x0000008D, 0x0000012D, 0x000002F3, 0x000002F3, 0x00000886, 0x0000008A, 0x00000260, 0x0000053D, 0x00000105, 0x0000013C, 0x0000013C, 0x00000194, 0x00000F24, 0x00000168, 0x00000168, 0x00000C48, 0x000015A0, 0x00000395, 0x00001724, 0x00000CFC, 0x0000002E, 0x00000B6B, 0x000002D3, 0x000003FA, 0x000003FC, 0x00000545, 0x00000545, 0x00000684, 0x0000131B, 0x000012E3, 0x00000125, 0x0000012D, 0x0000012B, 0x00000136, 0x00001100, 0x00000001, 0x00000F11, 0x00000158, 0x00000158, 0x0000034E, 0x00000112, 0x0000011D, 0x0000011D, 0x00000109, 0x0000020B, 0x000003AC, 0x000003E8, 0x00000289, 0x00000104, 0x00000104, 0x000000F6, 0x00000105, 0x00000194, 0x00000120, 0x0000010F, 0x00000120, 0x00000377, 0x000000F6, 0x00000001, 0x00000175, 0x000006F5, 0x0000041A, 0x000002A6, 0x00000438, 0x00000159, 0x0000018B, 0x00000140, 0x00000C48, 0x00000314, 0x0000051A, 0x00000001, 0x00000269, 0x00000116, 0x00000116, 0x00000551, 0x00000105, 0x00000105, 0x000006E4, 0x00000434, 0x0000010A, 0x0000010A, 0x000003AF, 0x000000DB, 0x000000DB, 0x000000DB, 0x000000DB, 0x00000738, 0x00000182, 0x00000773, 0x00000104, 0x000002AE, 0x00000105, 0x0000011B, 0x0000011E, 0x000001D2, 0x00000119, 0x0000011F, 0x000001A3, 0x000000DF, 0x00000119, 0x0000011C, 0x000005DF, 0x0000057D, 0x00000134, 0x00000157, 0x00000105, 0x00000120, 0x000000E7, 0x00000487, 0x00000FB8, 0x00000536, 0x0000038F, 0x00000F67, 0x00000495, 0x00000515, 0x0000033A, 0x0000045A, 0x00000143, 0x000001F0, 0x00000119, 0x000001B3, 0x000001C1, 0x00001179, 0x000001A1, 0x000002B4, 0x000002B4, 0x00000346, 0x00000171, 0x000002AD, 0x000002AD, 0x000001A3, 0x000001A3, 0x0000005C, 0x0000005C, 0x00000169, 0x00000170, 0x000002AD, 0x000002AD, 0x000001A6, 0x000001A6, 0x00000217, 0x00000077, 0x000002D1, 0x0000030A, 0x000002AD, 0x000002AD, 0x0000005C, 0x000001AA, 0x000001AA, 0x00000065, 0x00000060, 0x000001A3, 0x000001A3, 0x000000A8, 0x0000007B, 0x00000E87, 0x0000012B, 0x00000138, 0x0000038C, 0x0000010A, 0x0000010A, 0x0000012C, 0x0000012C, 0x0000054F, 0x0000010D, 0x00000111, 0x0000010D, 0x0000010D, 0x00000E7B, 0x000004FC, 0x000004FE, 0x000002D7, 0x0000068F, 0x0000018B, 0x0000018B, 0x00000001, 0x00000A22, 0x000003BF, 0x0000005F, 0x0000005E, 0x00000206, 0x00000001, 0x00000FDF, 0x00000E09, 0x00001368, 0x00001040, 0x00001186, 0x00000FBA, 0x00001555, 0x0000028A, 0x00000001, 0x00000CCA, 0x0000010E, 0x000004A8, 0x0000039A, 0x00000C1A, 0x0000013C, 0x0000031C, 0x0000035F, 0x0000048C, 0x000001F4, 0x000005FB, 0x0000064C, 0x000000F5, 0x0000056E, 0x000001AA, 0x0000019C, 0x0000082A, 0x00000554, 0x00000241, 0x0000022E, 0x0000006A, 0x00000143, 0x00000480, 0x0000042C, 0x00000263, 0x000002FB, 0x000002FB, 0x00000388, 0x000002A4, 0x000004EA, 0x000004C5, 0x00000479, 0x00000515, 0x00000431, 0x0000044B, 0x0000046F, 0x000003CC, 0x00000398, 0x0000056B, 0x000005C8, 0x000002B6, 0x000003D9, 0x0000049D, 0x00000382, 0x000002FF, 0x000001F5, 0x00000525, 0x00000EFF, 0x000000BE, 0x000000C4, 0x00000090, 0x0000010F, 0x0000010F, 0x0000010F, 0x0000010F, 0x00000104, 0x00000104, 0x00000104, 0x00000115, 0x00000115, 0x00000115, 0x00000115, 0x000003FC, 0x0000013C, 0x00000448, 0x00000733, 0x00000288, 0x00000283, 0x00000127, 0x0000085D, 0x000011CC, 0x000006AA, 0x00000429, 0x00000125, 0x00000A47, 0x00000074, 0x00000503, 0x00000062, 0x00000069, 0x00000568, 0x0000010F, 0x00000104, 0x00001257, 0x0000039D, 0x0000028D, 0x000003AA, 0x00000101, 0x000000F4, 0x000000DF, 0x0000020F, 0x00000104, 0x0000050E, 0x00000280, 0x00000280, 0x00000280, 0x00000115, 0x000002E0, 0x00000EF8, 0x000006FD, 0x000007D4, 0x000010A1, 0x00000436, 0x000001F8, 0x0000051B, 0x00000223, 0x00000FFD, 0x000005B2, 0x00000308, 0x0000020A, 0x000001CC, 0x00001228, 0x00000487, 0x00000101, 0x000001EC, 0x00000272, 0x00000080, 0x00000900, 0x0000057D, 0x00000C4D, 0x00000421, 0x00000371, 0x000001A7, 0x00000358, 0x00000325, 0x00000112, 0x000003FB, 0x000005D6, 0x00000454, 0x000008A3, 0x00000E59, 0x000001BE, 0x00000410, 0x00000403, 0x000003FA, 0x00000410, 0x000003AD, 0x00000400, 0x000002E9, 0x000001E4, 0x00000FBC, 0x00000C84, 0x00000655, 0x0000021A, 0x00000180, 0x000012F6, 0x00000D0E, 0x000001A6, 0x0000005C, 0x00000064, 0x00000159, 0x00000120, 0x00000166, 0x0000019A, 0x00000101, 0x00000213, 0x000000D7, 0x000002C9, 0x00000225, 0x00000745, 0x00000705, 0x000005D4, 0x000009BD, 0x000003B2, 0x000004B7, 0x000002F5, 0x00000118, 0x00000389, 0x0000011A, 0x000001D4, 0x000000FA, 0x00000150, 0x00000126, 0x000003E9, 0x00000105, 0x0000029B, 0x0000067A, 0x000003C1, 0x000003C1, 0x000003C1, 0x000006D8, 0x000003C1];
const demo_file_sectors = [0x00000000, 0x0000003A, 0x0000003A, 0x0000003A, 0x0000003A, 0x0000003A, 0x0000003A, 0x00000191, 0x00000191, 0x0000047D, 0x00000630, 0x00000630, 0x00000630, 0x000007EB, 0x000009AC, 0x00000B68, 0x00000D1B, 0x00000D1B, 0x00000D1B, 0x00000EBB, 0x00000EBB, 0x00000EBB, 0x00000EBB, 0x00000EBB, 0x00000EBB, 0x00000EBB, 0x00000EBB, 0x00000EBB, 0x00000EBB, 0x00001046, 0x00001046, 0x00001046, 0x00001046, 0x00001046, 0x00001046, 0x00001046, 0x00001046, 0x00001046, 0x00001046, 0x00001046, 0x00001046, 0x00001046, 0x00001046, 0x00001046, 0x00001046, 0x00001046, 0x00001046, 0x00001046, 0x00001046, 0x00001046, 0x00001046, 0x00001046, 0x00001046, 0x00001046, 0x00001046, 0x00001046, 0x00001046, 0x00001046, 0x00001046, 0x00001046, 0x00001046, 0x00001046, 0x00001046, 0x00001046, 0x00001046, 0x00001046, 0x00001046, 0x00001046, 0x00001046, 0x00001046, 0x00001046, 0x00001046, 0x00001046, 0x00001046, 0x000011F9, 0x000011F9, 0x000011F9, 0x000013AD, 0x00001564, 0x00001713, 0x000018C6, 0x000018C6, 0x000018C6, 0x00001A66, 0x00001A66, 0x00001A66, 0x00001A66, 0x00001A66, 0x00001A66, 0x00001A66, 0x00001A66, 0x00001A66, 0x00001A66, 0x00001BF1, 0x00001BF1, 0x00001BF1, 0x00001BF1, 0x00001BF1, 0x00001BF1, 0x00001BF1, 0x00001BF1, 0x00001BF1, 0x00001BF1, 0x00001BF1, 0x00001BF1, 0x00001BF1, 0x00001BF1, 0x00001BF1, 0x00001BF1, 0x00001BF1, 0x00001BF1, 0x00001BF1, 0x00001BF1, 0x00001BF1, 0x00001BF1, 0x00001BF1, 0x00001BF1, 0x00001BF1, 0x00001BF1, 0x00001BF1, 0x00001BF1, 0x00001BF1, 0x00001BF1, 0x00001BF1, 0x00001BF1, 0x00001BF1, 0x00001BF1, 0x00001BF1, 0x00001BF1, 0x00001BF1, 0x00001BF1, 0x00001BF1, 0x00001BF1, 0x00001BF1, 0x00001BF1, 0x00001BF1, 0x00001BF1, 0x00001BF1, 0x000032FB, 0x00003FFA, 0x00004447, 0x00004447, 0x00004447, 0x00004BB4, 0x00004ED5, 0x000050CA, 0x00005517, 0x00005517, 0x00005928, 0x00005928, 0x00005928, 0x00005928, 0x00005928, 0x00005928, 0x00005928, 0x00005D39, 0x00005D39, 0x00005D39, 0x00005D39, 0x00005D39, 0x00005D39, 0x00005D39, 0x00005D39, 0x00005D39, 0x00005D39, 0x00005D39, 0x00005D39, 0x00005D39, 0x00005D39, 0x00005D39, 0x00005D39, 0x00005D39, 0x00005D39, 0x00005D39, 0x00005D39, 0x00005D39, 0x00005D39, 0x00005D39, 0x00005D39, 0x00005D39, 0x00005D39, 0x00005D39, 0x00005D39, 0x00005D39, 0x00005D39, 0x00005D39, 0x00005D39, 0x00005D39, 0x00005D39, 0x00005D39, 0x00005D39, 0x00005D39, 0x00005D60, 0x00005D88, 0x00005D9E, 0x00005DB8, 0x00005DDF, 0x00005E14, 0x00005E33, 0x00005E5B, 0x00005E7B, 0x00005E90, 0x00005EB0, 0x00005ED8, 0x00005EFE, 0x00005F1D, 0x00005F39, 0x00005F64, 0x00005F7B, 0x00005F93, 0x00005FA4, 0x00005FA4, 0x00005FA4, 0x00005FA4, 0x00005FA4, 0x00005FA4, 0x00005FA4, 0x00005FA4, 0x00005FA4, 0x00005FA4, 0x00005FA4, 0x00005FA4, 0x00005FA4, 0x00005FA4, 0x00005FA4, 0x00005FA4, 0x00005FA4, 0x00005FA4, 0x00005FA4, 0x00005FA4, 0x00005FA4, 0x00005FA4, 0x00005FA4, 0x00005FA4, 0x00005FA4, 0x00005FA4, 0x00005FA4, 0x00005FA4, 0x00005FA4, 0x00005FA4, 0x00005FA4, 0x00005FA4, 0x00005FA4, 0x00005FA4, 0x00005FA4, 0x00005FA4, 0x00005FA4, 0x00005FA4, 0x00005FA4, 0x00005FA4, 0x00005FA4, 0x00005FA4, 0x00005FA4, 0x00005FA4, 0x00005FA4, 0x00005FA4, 0x00005FA4, 0x00005FA4, 0x00005FA4, 0x00005FA4, 0x00005FA4, 0x00005FA4, 0x00005FA4, 0x00005FA4, 0x00005FA4, 0x00005FA4, 0x00005FA4, 0x00005FA4, 0x00005FA4, 0x00005FA4, 0x00005FA4, 0x00005FA4, 0x00005FA4, 0x00005FA4, 0x00005FA4, 0x00005FA4, 0x00005FA4, 0x00005FA4, 0x00005FA4, 0x00005FA4, 0x00005FA4, 0x00005FA4, 0x00005FA4, 0x00006000, 0x00006014, 0x0000602B, 0x0000602B, 0x0000602B, 0x0000602B, 0x0000605F, 0x00006078, 0x00006078, 0x0000607A, 0x0000607C, 0x0000607E, 0x00006080, 0x000060B6, 0x000060E8, 0x00006119, 0x00006144, 0x0000617D, 0x00006180, 0x00006180, 0x00006180, 0x00006180, 0x00006180, 0x00006180, 0x000061B8, 0x000061EF, 0x000061EF, 0x000061EF, 0x000061EF, 0x000061EF, 0x000061EF, 0x000061EF, 0x0000621E, 0x0000621E, 0x0000621E, 0x0000621E, 0x0000621E, 0x0000621E, 0x0000621E, 0x0000621E, 0x0000621E, 0x0000621E, 0x0000621E, 0x0000621E, 0x0000621E, 0x0000621E, 0x0000621E, 0x0000621F, 0x0000621F, 0x0000621F, 0x00006220, 0x00006220, 0x00006221, 0x00006221, 0x00006221, 0x00006221, 0x00006221, 0x00006221, 0x00006221, 0x00006221, 0x00006221, 0x00006221, 0x00006221, 0x00006221, 0x00006221, 0x00006221, 0x00006221, 0x00006221, 0x00006221, 0x00006221, 0x00006221, 0x00006221, 0x00006221, 0x00006221, 0x00006221, 0x00006221, 0x00006221, 0x00006221, 0x00006221, 0x00006221, 0x00006221, 0x00006221, 0x00006221, 0x00006221, 0x00006221, 0x00006221, 0x00006221, 0x00006221, 0x00006221, 0x00006221, 0x00006221, 0x00006221, 0x00006221, 0x00006221, 0x00006221, 0x00006221, 0x00006221, 0x00006221, 0x00006221, 0x00006226, 0x0000622A, 0x0000622E, 0x00006233, 0x00006239, 0x0000623D, 0x00006253, 0x00006266, 0x00006282, 0x000062A2, 0x000062C5, 0x000062EA, 0x00006309, 0x0000632D, 0x0000634B, 0x00006368, 0x00006386, 0x000063A4, 0x000063C2, 0x000063E0, 0x000063FE, 0x00006421, 0x0000642A, 0x0000644D, 0x00006456, 0x0000645F, 0x00006468, 0x00006471, 0x0000647A, 0x00006483, 0x0000648C, 0x00006495, 0x0000649E, 0x000064A7, 0x000064B0, 0x000064B9, 0x000064EC, 0x000064EE, 0x00006718, 0x00006719, 0x00006780, 0x00006781, 0x000067E5, 0x000067E6, 0x00006A1D, 0x00006A1E, 0x00006AD1, 0x00006AD2, 0x00006B7A, 0x00006C1C, 0x00006CC8, 0x00006D70, 0x00006E14, 0x00006EC6, 0x00006F75, 0x00007035, 0x000070D9, 0x000071A9, 0x00007282, 0x00007357, 0x0000742F, 0x00007513, 0x000075EB, 0x000076DB, 0x00007776, 0x00007777, 0x00007778, 0x00007779, 0x0000777A, 0x0000777B, 0x0000777C, 0x000078D6, 0x000078D7, 0x00007921, 0x00007927, 0x000079C9, 0x000079D6, 0x00007B27, 0x00007B54, 0x00007C05, 0x00007CF0, 0x00007DAC, 0x00007E3C, 0x00007E97, 0x00007EFD, 0x00007F8B, 0x00008069, 0x00008147, 0x000081A7, 0x000081AD, 0x000081B4, 0x000081BC, 0x000081CE, 0x000081DD, 0x000081E9, 0x000081F3, 0x000081F8, 0x000081FF, 0x00008210, 0x00008226, 0x00008231, 0x00008240, 0x0000824F, 0x00008267, 0x00008272, 0x0000827D, 0x0000828C, 0x000082A2, 0x000082B1, 0x000082C0, 0x000082CD, 0x000082D2, 0x000082E5, 0x000082F0, 0x000082FE, 0x0000830D, 0x0000831D, 0x00008324, 0x00008335, 0x0000834A, 0x00008354, 0x00009CDC, 0x00009D5D, 0x00009DDE, 0x00009E5F, 0x00009EE0, 0x00009F61, 0x00009FE2, 0x0000A063, 0x0000A0E4, 0x0000A165, 0x0000A1E6, 0x0000A267, 0x0000A2E8, 0x0000A369, 0x0000A3EA, 0x0000A46B, 0x0000A4EC, 0x0000A56D, 0x0000A5AE, 0x0000A62F, 0x0000A6B0, 0x0000A731, 0x0000A7B2, 0x0000A833, 0x0000A8B4, 0x0000A935, 0x0000A9B6, 0x0000AA37, 0x0000AAB8, 0x0000AB39, 0x0000ABBA, 0x0000AC3B, 0x0000ACBC, 0x0000AD3D, 0x0000ADBE, 0x0000AE3F, 0x0000AEC0, 0x0000AF41, 0x0000AFC2, 0x0000B043, 0x0000B0C4, 0x0000B145, 0x0000B1C6, 0x0000B247, 0x0000B2C8, 0x0000B349, 0x0000B3CA, 0x0000B44B, 0x0000B4CC, 0x0000B54D, 0x0000B5CE, 0x0000B64F, 0x0000B6D0, 0x0000B751, 0x0000B7D2, 0x0000B853, 0x0000B8D4, 0x0000B955, 0x0000B9D6, 0x0000BA57, 0x0000BAD8, 0x0000BB59, 0x0000BBDA, 0x0000BC5B, 0x0000BCDC, 0x0000BD5D, 0x0000BDDE, 0x0000BE5F, 0x0000BEE0, 0x0000BF61, 0x0000BFE2, 0x0000C063, 0x0000C0E4, 0x0000C165, 0x0000C1E6, 0x0000C267, 0x0000C2E8, 0x0000C369, 0x0000C3EA, 0x0000C46B, 0x0000C4EC, 0x0000C56D, 0x0000C5EE, 0x0000C66F, 0x0000C6F0, 0x0000C771, 0x0000C7F2, 0x0000C873, 0x0000C8F4, 0x0000C975, 0x0000C9F6, 0x0000CA77, 0x0000CAF8, 0x0000CB79, 0x0000CBFA, 0x0000CC7B, 0x0000CCFC, 0x0000CD7D, 0x0000CD7D, 0x0000CD7D, 0x0000CD7D, 0x0000CD7D, 0x0000CD7D, 0x0000CD7D, 0x0000CD7D, 0x0000CD7D, 0x0000CD7D, 0x0000D2A5, 0x0000D2A6, 0x0000D2A7, 0x0000D2C4, 0x0000D46E, 0x0000D48E, 0x0000D4E1, 0x0000D5A1, 0x0000D5A2, 0x0000D5A3, 0x0000D5A7, 0x0000D5AD, 0x0000D5AE, 0x0000D5AF, 0x0000D5B0, 0x0000D5B1, 0x0000D5B2, 0x0000D5B3, 0x0000D5B4, 0x0000D616, 0x0000D697, 0x0000D718, 0x0000D79A, 0x0000D7DC, 0x0000D7DC, 0x0000D7DC, 0x0000D7DC, 0x0000D7DC, 0x0000D7DC, 0x0000D7DC, 0x0000D7DC, 0x0000D7DC, 0x0000D7DC, 0x0000D7DC, 0x0000D7DC, 0x0000D7DC, 0x0000D7DC, 0x0000D7DC, 0x0000D7DC, 0x0000D7DC, 0x0000D7DC, 0x0000D7DC, 0x0000D7DC, 0x0000D7DC, 0x0000E84E, 0x0000E84F, 0x0000E850, 0x0000E86A, 0x0000EE48, 0x0000EE63, 0x0000EE9A, 0x0000EFB1, 0x0000EFB2, 0x0000EFB6, 0x0000EFCD, 0x0000EFD3, 0x0000EFD4, 0x0000EFD6, 0x0000EFD8, 0x0000EFD9, 0x0000EFDC, 0x0000EFDD, 0x0000EFDE, 0x0000F2DD, 0x0000F2DF, 0x0000F796, 0x0000F818, 0x0000F899, 0x0000F8DB, 0x0000F8DB, 0x00010C52, 0x00010C53, 0x00010C54, 0x00010C77, 0x000112F1, 0x0001131E, 0x0001144E, 0x000117A1, 0x000117A2, 0x000117A8, 0x000117C1, 0x000117D2, 0x000117D3, 0x000117D4, 0x000117D7, 0x000117D8, 0x000117DB, 0x000117E0, 0x000117E1, 0x000117E2, 0x000117ED, 0x000117EE, 0x00011DB2, 0x00011E34, 0x00011E95, 0x00011EF6, 0x00011F78, 0x00011FDA, 0x00011FDA, 0x00011FDA, 0x00011FDA, 0x0001226A, 0x000123E9, 0x000123EA, 0x000123EB, 0x000123F8, 0x00012526, 0x00012528, 0x00012530, 0x00012541, 0x00012542, 0x00012552, 0x00012553, 0x00012554, 0x00012555, 0x00012557, 0x00012558, 0x00012559, 0x0001261E, 0x0001261F, 0x00012620, 0x00012682, 0x00012682, 0x00012682, 0x00012682, 0x00012682, 0x00012682, 0x00012682, 0x00012682, 0x00012682, 0x00012682, 0x00012876, 0x00012877, 0x00012878, 0x0001287D, 0x00012996, 0x00012997, 0x000129A7, 0x000129C0, 0x000129C1, 0x000129C3, 0x000129C5, 0x000129C7, 0x000129C8, 0x000129C9, 0x000129CA, 0x000129CB, 0x000129CD, 0x000129CE, 0x000129CF, 0x000129D0, 0x000129D6, 0x000129D7, 0x00012A18, 0x00012A79, 0x00012A79, 0x00012A79, 0x00012A79, 0x00012A79, 0x00012A79, 0x00012A79, 0x00012A79, 0x00012A79, 0x00012A79, 0x00012A79, 0x00012A79, 0x00012A79, 0x00012A79, 0x00012A79, 0x00012A79, 0x00012A79, 0x00012A79, 0x00012A79, 0x00012A79, 0x00012A79, 0x00012A79, 0x00012A79, 0x00012A79, 0x00012A79, 0x00012A79, 0x00012A79, 0x00012A79, 0x00012A79, 0x00012A79, 0x00012A79, 0x00012A79, 0x00012A79, 0x00012A79, 0x00012A79, 0x00012A79, 0x00012A79, 0x00012A79, 0x00012A79, 0x00012A79, 0x00012A79, 0x00012A79, 0x00012A79, 0x00012A79, 0x00012A79, 0x00012A79, 0x00012A79, 0x00012A79, 0x00012A79, 0x00012A79, 0x00012A79, 0x00012A79, 0x00012A79, 0x00012A79, 0x00012A79, 0x00012A79, 0x00012A79, 0x00012A79, 0x00012A79, 0x00012A79, 0x00012A79, 0x00012A79, 0x00012A79, 0x00012A79, 0x00012A79, 0x00012A79, 0x00012A79, 0x00012A79, 0x00012A79, 0x00012A79, 0x00012A79, 0x00012A79, 0x00012A79, 0x00012A79, 0x00012A79, 0x00012A79, 0x00012A79, 0x00012A79, 0x00012A79, 0x00012A79, 0x00012A79, 0x00012A79, 0x00012A79, 0x00012A79, 0x00012A79, 0x00012A79, 0x00012A79, 0x00012A79, 0x00012A79, 0x00012A79, 0x00012A79, 0x00012A79, 0x00012A79, 0x00012A79, 0x00012A79, 0x00012A79, 0x00012A79, 0x00012A79, 0x00012A79, 0x00012A79, 0x00012A79, 0x00012A79, 0x00012A79, 0x00012A79, 0x00012A79, 0x00012A79, 0x00012A79, 0x00012A79, 0x00012A79, 0x00012A79, 0x00012A79, 0x00012A79, 0x00012A79, 0x00012A79, 0x00012A79, 0x00012A79, 0x00012A79, 0x00012A79, 0x00012A79, 0x00012A79, 0x00012A79, 0x00012A79, 0x00012A79, 0x00012A79, 0x00012A79, 0x00012A79, 0x00012A79, 0x00012A79, 0x00012A79, 0x00012A79, 0x00012A79, 0x00012A79, 0x00012A79, 0x00012A79, 0x00012A79, 0x00012A79, 0x00012A79, 0x00012A79, 0x00012A79, 0x00012A79, 0x00012A79, 0x00012A79, 0x00012A79, 0x00012A79, 0x00012A79];
const demo_file_sizes = [0x0000003A, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000157, 0x00000000, 0x000002EC, 0x000001B3, 0x00000000, 0x00000000, 0x000001BB, 0x000001C1, 0x000001BC, 0x000001B3, 0x00000000, 0x00000000, 0x000001A0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x0000018B, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x000001B3, 0x00000000, 0x00000000, 0x000001B4, 0x000001B7, 0x000001AF, 0x000001B3, 0x00000000, 0x00000000, 0x000001A0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x0000018B, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x0000170A, 0x00000CFF, 0x0000044D, 0x00000000, 0x00000000, 0x0000076D, 0x00000321, 0x000001F5, 0x0000044D, 0x00000000, 0x00000411, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000411, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000027, 0x00000028, 0x00000016, 0x0000001A, 0x00000027, 0x00000035, 0x0000001F, 0x00000028, 0x00000020, 0x00000015, 0x00000020, 0x00000028, 0x00000026, 0x0000001F, 0x0000001C, 0x0000002B, 0x00000017, 0x00000018, 0x00000011, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x0000005C, 0x00000014, 0x00000017, 0x00000000, 0x00000000, 0x00000000, 0x00000034, 0x00000019, 0x00000000, 0x00000002, 0x00000002, 0x00000002, 0x00000002, 0x00000036, 0x00000032, 0x00000031, 0x0000002B, 0x00000039, 0x00000003, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000038, 0x00000037, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x0000002F, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000000, 0x00000000, 0x00000001, 0x00000000, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000005, 0x00000004, 0x00000004, 0x00000005, 0x00000006, 0x00000004, 0x00000016, 0x00000013, 0x0000001C, 0x00000020, 0x00000023, 0x00000025, 0x0000001F, 0x00000024, 0x0000001E, 0x0000001D, 0x0000001E, 0x0000001E, 0x0000001E, 0x0000001E, 0x0000001E, 0x00000023, 0x00000009, 0x00000023, 0x00000009, 0x00000009, 0x00000009, 0x00000009, 0x00000009, 0x00000009, 0x00000009, 0x00000009, 0x00000009, 0x00000009, 0x00000009, 0x00000009, 0x00000033, 0x00000002, 0x0000022A, 0x00000001, 0x00000067, 0x00000001, 0x00000064, 0x00000001, 0x00000237, 0x00000001, 0x000000B3, 0x00000001, 0x000000A8, 0x000000A2, 0x000000AC, 0x000000A8, 0x000000A4, 0x000000B2, 0x000000AF, 0x000000C0, 0x000000A4, 0x000000D0, 0x000000D9, 0x000000D5, 0x000000D8, 0x000000E4, 0x000000D8, 0x000000F0, 0x0000009B, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x0000015A, 0x00000001, 0x0000004A, 0x00000006, 0x000000A2, 0x0000000D, 0x00000151, 0x0000002D, 0x000000B1, 0x000000EB, 0x000000BC, 0x00000090, 0x0000005B, 0x00000066, 0x0000008E, 0x000000DE, 0x000000DE, 0x00000060, 0x00000006, 0x00000007, 0x00000008, 0x00000012, 0x0000000F, 0x0000000C, 0x0000000A, 0x00000005, 0x00000007, 0x00000011, 0x00000016, 0x0000000B, 0x0000000F, 0x0000000F, 0x00000018, 0x0000000B, 0x0000000B, 0x0000000F, 0x00000016, 0x0000000F, 0x0000000F, 0x0000000D, 0x00000005, 0x00000013, 0x0000000B, 0x0000000E, 0x0000000F, 0x00000010, 0x00000007, 0x00000011, 0x00000015, 0x0000000A, 0x00001988, 0x00000081, 0x00000081, 0x00000081, 0x00000081, 0x00000081, 0x00000081, 0x00000081, 0x00000081, 0x00000081, 0x00000081, 0x00000081, 0x00000081, 0x00000081, 0x00000081, 0x00000081, 0x00000081, 0x00000081, 0x00000041, 0x00000081, 0x00000081, 0x00000081, 0x00000081, 0x00000081, 0x00000081, 0x00000081, 0x00000081, 0x00000081, 0x00000081, 0x00000081, 0x00000081, 0x00000081, 0x00000081, 0x00000081, 0x00000081, 0x00000081, 0x00000081, 0x00000081, 0x00000081, 0x00000081, 0x00000081, 0x00000081, 0x00000081, 0x00000081, 0x00000081, 0x00000081, 0x00000081, 0x00000081, 0x00000081, 0x00000081, 0x00000081, 0x00000081, 0x00000081, 0x00000081, 0x00000081, 0x00000081, 0x00000081, 0x00000081, 0x00000081, 0x00000081, 0x00000081, 0x00000081, 0x00000081, 0x00000081, 0x00000081, 0x00000081, 0x00000081, 0x00000081, 0x00000081, 0x00000081, 0x00000081, 0x00000081, 0x00000081, 0x00000081, 0x00000081, 0x00000081, 0x00000081, 0x00000081, 0x00000081, 0x00000081, 0x00000081, 0x00000081, 0x00000081, 0x00000081, 0x00000081, 0x00000081, 0x00000081, 0x00000081, 0x00000081, 0x00000081, 0x00000081, 0x00000081, 0x00000081, 0x00000081, 0x00000081, 0x00000081, 0x00000081, 0x00000081, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000528, 0x00000001, 0x00000001, 0x0000001D, 0x000001AA, 0x00000020, 0x00000053, 0x000000C0, 0x00000001, 0x00000001, 0x00000004, 0x00000006, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000062, 0x00000081, 0x00000081, 0x00000082, 0x00000042, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00001072, 0x00000001, 0x00000001, 0x0000001A, 0x000005DE, 0x0000001B, 0x00000037, 0x00000117, 0x00000001, 0x00000004, 0x00000017, 0x00000006, 0x00000001, 0x00000002, 0x00000002, 0x00000001, 0x00000003, 0x00000001, 0x00000001, 0x000002FF, 0x00000002, 0x000004B7, 0x00000082, 0x00000081, 0x00000042, 0x00000000, 0x00001377, 0x00000001, 0x00000001, 0x00000023, 0x0000067A, 0x0000002D, 0x00000130, 0x00000353, 0x00000001, 0x00000006, 0x00000019, 0x00000011, 0x00000001, 0x00000001, 0x00000003, 0x00000001, 0x00000003, 0x00000005, 0x00000001, 0x00000001, 0x0000000B, 0x00000001, 0x000005C4, 0x00000082, 0x00000061, 0x00000061, 0x00000082, 0x00000062, 0x00000000, 0x00000000, 0x00000000, 0x00000290, 0x0000017F, 0x00000001, 0x00000001, 0x0000000D, 0x0000012E, 0x00000002, 0x00000008, 0x00000011, 0x00000001, 0x00000010, 0x00000001, 0x00000001, 0x00000001, 0x00000002, 0x00000001, 0x00000001, 0x000000C5, 0x00000001, 0x00000001, 0x00000062, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x000001F4, 0x00000001, 0x00000001, 0x00000005, 0x00000119, 0x00000001, 0x00000010, 0x00000019, 0x00000001, 0x00000002, 0x00000002, 0x00000002, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000002, 0x00000001, 0x00000001, 0x00000001, 0x00000006, 0x00000001, 0x00000041, 0x00000061, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000];
const dos_chars = ["\u002E", "\u263A", "\u263B", "\u2665", "\u2666", "\u2663", "\u2660", "\u2022", "\u25D8", "\u25CB", "\u25D9", "\u2642", "\u2640", "\u266A", "\u266B", "\u263C", "\u25BA", "\u25C4", "\u2195", "\u203C", "\u00B6", "\u00A7", "\u25AC", "\u21A8", "\u2191", "\u2193", "\u2192", "\u2190", "\u221F", "\u2194", "\u25B2", "\u25BC", "\u0020", "\u0021", "\u0022", "\u0023", "\u0024", "\u0025", "\u0026", "\u0027", "\u0028", "\u0029", "\u002A", "\u002B", "\u002C", "\u002D", "\u002E", "\u002F", "\u0030", "\u0031", "\u0032", "\u0033", "\u0034", "\u0035", "\u0036", "\u0037", "\u0038", "\u0039", "\u003A", "\u003B", "\u003C", "\u003D", "\u003E", "\u003F", "\u0040", "\u0041", "\u0042", "\u0043", "\u0044", "\u0045", "\u0046", "\u0047", "\u0048", "\u0049", "\u004A", "\u004B", "\u004C", "\u004D", "\u004E", "\u004F", "\u0050", "\u0051", "\u0052", "\u0053", "\u0054", "\u0055", "\u0056", "\u0057", "\u0058", "\u0059", "\u005A", "\u005B", "\u005C", "\u005D", "\u005E", "\u005F", "\u0060", "\u0061", "\u0062", "\u0063", "\u0064", "\u0065", "\u0066", "\u0067", "\u0068", "\u0069", "\u006A", "\u006B", "\u006C", "\u006D", "\u006E", "\u006F", "\u0070", "\u0071", "\u0072", "\u0073", "\u0074", "\u0075", "\u0076", "\u0077", "\u0078", "\u0079", "\u007A", "\u007B", "\u007C", "\u007D", "\u007E", "\u2302", "\u00C7", "\u00FC", "\u00E9", "\u00E2", "\u00E4", "\u00E0", "\u00E5", "\u00E7", "\u00EA", "\u00EB", "\u00E8", "\u00EF", "\u00EE", "\u00EC", "\u00C4", "\u00C5", "\u00C9", "\u00E6", "\u00C6", "\u00F4", "\u00F6", "\u00F2", "\u00FB", "\u00F9", "\u00FF", "\u00D6", "\u00DC", "\u00A2", "\u00A3", "\u00A5", "\u20A7", "\u0192", "\u00E1", "\u00ED", "\u00F3", "\u00FA", "\u00F1", "\u00D1", "\u00AA", "\u00BA", "\u00BF", "\u2310", "\u00AC", "\u00BD", "\u00BC", "\u00A1", "\u00AB", "\u00BB", "\u2591", "\u2592", "\u2593", "\u2502", "\u2524", "\u2561", "\u2562", "\u2556", "\u2555", "\u2563", "\u2551", "\u2557", "\u255D", "\u255C", "\u255B", "\u2510", "\u2514", "\u2534", "\u252C", "\u251C", "\u2500", "\u253C", "\u255E", "\u255F", "\u255A", "\u2554", "\u2569", "\u2566", "\u2560", "\u2550", "\u256C", "\u2567", "\u2568", "\u2564", "\u2565", "\u2559", "\u2558", "\u2552", "\u2553", "\u256B", "\u256A", "\u2518", "\u250C", "\u2588", "\u2584", "\u258C", "\u2590", "\u2580", "\u03B1", "\u00DF", "\u0393", "\u03C0", "\u03A3", "\u03C3", "\u00B5", "\u03C4", "\u03A6", "\u0398", "\u03A9", "\u03B4", "\u221E", "\u03C6", "\u03B5", "\u2229", "\u2261", "\u00B1", "\u2265", "\u2264", "\u2320", "\u2321", "\u00F7", "\u2248", "\u00B0", "\u2022", "\u00B7", "\u221A", "\u207F", "\u00B2", "\u25A0", "\u00A0"];
let infile;
let audio_context;
let convolver_node;
let convolver_buffer;
const note_base = 2 ** (1/12);
const note_factor = 1 / 1298141.5161388416; // this number was achieved via SCIENCE!
let file_list = [];
let dispose_old = null;
const mips_registers = ['zero','at','v0','v1','a0','a1','a2','a3','t0','t1','t2','t3','t4','t5','t6','t7','s0','s1','s2','s3','s4','s5','s6','s7','t8','t9','k0','k1','gp','sp','fp','ra'];
const mips_instructions = {
"000000????????????????????100000": {name: "add", args: "{r3}, {r1}, {r2}"},
"001000??????????????????????????": {name: "addi", args: "{r2}, {r1}, {imm}"},
"001001??????????????????????????": {name: "addiu", args: "{r2}, {r1}, {imm}"},
"000000????????????????????100001": {name: "addu", args: "{r3}, {r1}, {r2}"},
"000000????????????????????100100": {name: "and", args: "{r3}, {r1}, {r2}"},
"001100??????????????????????????": {name: "andi", args: "{r2}, {r1}, {imm}"},
"000100??????????????????????????": {name: "beq", args: "{r1}, {r2}, {b}"},
"010100??????????????????????????": {name: "beql", args: "{r1}, {r2}, {b}"},
"000001?????00001????????????????": {name: "bgez", args: "{r1}, {b}"},
"000001?????10001????????????????": {name: "bgezal", args: "{r1}, {b}"},
"000001?????10011????????????????": {name: "bgezall", args: "{r1}, {b}"},
"000001?????00011????????????????": {name: "bgezl", args: "{r1}, {b}"},
"000111??????????????????????????": {name: "bgtz", args: "{r1}, {b}"},
"010111??????????????????????????": {name: "bgtzl", args: "{r1}, {b}"},
"000110??????????????????????????": {name: "blez", args: "{r1}, {b}"},
"010110??????????????????????????": {name: "blezl", args: "{r1}, {b}"},
"000001?????00000????????????????": {name: "bltz", args: "{r1}, {b}"},
"000001?????10000????????????????": {name: "bltzal", args: "{r1}, {b}"},
"000001?????10010????????????????": {name: "bltzall", args: "{r1}, {b}"},
"000001?????00010????????????????": {name: "bltzl", args: "{r1}, {b}"},
"000101??????????????????????????": {name: "bne", args: "{r1}, {r2}, {b}"},
"010101??????????????????????????": {name: "bnel", args: "{r1}, {r2}, {b}"},
"000000????????????????????001101": {name: "break", args: "{code}"},
"000000????????????????????101100": {name: "dadd", args: "{r3}, {r1}, {r2}"},
"011000??????????????????????????": {name: "daddi", args: "{r2}, {r1}, {imm}"},
"011001??????????????????????????": {name: "daddiu", args: "{r2}, {r1}, {imm}"},
"000000????????????????????101101": {name: "daddu", args: "{r3}, {r1}, {r2}"},
"000000????????????????????011010": {name: "div", args: "{r1}, {r2}"},
"000000????????????????????011011": {name: "divu", args: "{r1}, {r2}"},
"000000????????????????????111000": {name: "dsll", args: "{r3}, {r2}, {i4}"},
"000000????????????????????111100": {name: "dsll32", args: "{r3}, {r2}, {i4}"},
"000000????????????????????010100": {name: "dsllv", args: "{r3}, {r2}, {r1}"},
"000000????????????????????111011": {name: "dsra", args: "{r3}, {r2}, {i4}"},
"000000????????????????????111111": {name: "dsra32", args: "{r3}, {r2}, {i4}"},
"000000????????????????????010111": {name: "dsrav", args: "{r3}, {r2}, {r1}"},
"000000????????????????????111010": {name: "dsrl", args: "{r3}, {r2}, {i4}"},
"000000????????????????????111110": {name: "dsrl32", args: "{r3}, {r2}, {i4}"},
"000000????????????????????010110": {name: "dsrlv", args: "{r3}, {r2}, {r1}"},
"000000????????????????????101110": {name: "dsub", args: "{r3}, {r1}, {r2}"},
"000000????????????????????101111": {name: "dsubu", args: "{r3}, {r1}, {r2}"},
"000010??????????????????????????": {name: "j", args: "{j}"},
"000011??????????????????????????": {name: "jal", args: "{j}"},
"000000????????????????????001001": {name: "jalr", args: "{r3}, {r1}"},
"000000????????????????????001000": {name: "jr", args: "{r1}"},
"100000??????????????????????????": {name: "lb", args: "{r2}, {imm}({r1})"},
"100100??????????????????????????": {name: "lbu", args: "{r2}, {imm}({r1})"},
"110111??????????????????????????": {name: "ld", args: "{r2}, {imm}({r1})"},
"011010??????????????????????????": {name: "ldl", args: "{r2}, {imm}({r1})"},
"011011??????????????????????????": {name: "ldr", args: "{r2}, {imm}({r1})"},
"100001??????????????????????????": {name: "lh", args: "{r2}, {imm}({r1})"},
"100101??????????????????????????": {name: "lhu", args: "{r2}, {imm}({r1})"},
"001111??????????????????????????": {name: "lui", args: "{r2}, {imm}"},
"100011??????????????????????????": {name: "lw", args: "{r2}, {imm}({r1})"},
"100010??????????????????????????": {name: "lwl", args: "{r2}, {imm}({r1})"},
"100110??????????????????????????": {name: "lwr", args: "{r2}, {imm}({r1})"},
"100111??????????????????????????": {name: "lwu", args: "{r2}, {imm}({r1})"},
"000000????????????????????010000": {name: "mfhi", args: "{r3}"},
"000000????????????????????010010": {name: "mflo", args: "{r3}"},
"000000????????????????????001011": {name: "movn", args: "{r3}, {r1}, {r2}"},
"000000????????????????????001010": {name: "movz", args: "{r3}, {r1}, {r2}"},
"000000????????????????????010001": {name: "mthi", args: "{r1}"},
"000000????????????????????010011": {name: "mfhi", args: "{r1}"},
"000000????????????????????011000": {name: "mult", args: "{r1}, {r2}"},
"000000????????????????????011001": {name: "multu", args: "{r1}, {r2}"},
"000000????????????????????100111": {name: "nor", args: "{r3}, {r1}, {r2}"},
"000000????????????????????100101": {name: "or", args: "{r3}, {r1}, {r2}"},
"001101??????????????????????????": {name: "ori", args: "{r2}, {r1}, {imm}"},
"110011??????????????????????????": {name: "pref", args: "{i2}, {imm}({r1})"},
"101000??????????????????????????": {name: "sb", args: "{r2}, {imm}({r1})"},
"111111??????????????????????????": {name: "sd", args: "{r2}, {imm}({r1})"},
"101100??????????????????????????": {name: "sdl", args: "{r2}, {imm}({r1})"},
"101101??????????????????????????": {name: "sdr", args: "{r2}, {imm}({r1})"},
"101001??????????????????????????": {name: "sh", args: "{r2}, {imm}({r1})"},
"000000????????????????????000000": {name: "sll", args: "{r3}, {r2}, {i4}"},
"000000????????????????????000100": {name: "sllv", args: "{r3}, {r2}, {r1}"},
"000000????????????????????101010": {name: "slt", args: "{r3}, {r1}, {r2}"},
"001010??????????????????????????": {name: "slti", args: "{r2}, {r1}, {imm}"},
"001011??????????????????????????": {name: "sltiu", args: "{r2}, {r1}, {imm}"},
"000000????????????????????101011": {name: "sltu", args: "{r3}, {r1}, {r2}"},
"000000????????????????????000011": {name: "sra", args: "{r3}, {r2}, {i4}"},
"000000????????????????????000111": {name: "srav", args: "{r3}, {r2}, {r1}"},
"000000????????????????????000010": {name: "srl", args: "{r3}, {r2}, {i4}"},
"000000????????????????????000110": {name: "srlv", args: "{r3}, {r2}, {r1}"},
"000000????????????????????100010": {name: "sub", args: "{r3}, {r1}, {r2}"},
"000000????????????????????100011": {name: "subu", args: "{r3}, {r1}, {r2}"},
"101011??????????????????????????": {name: "sw", args: "{r2}, {imm}({r1})"},
"101010??????????????????????????": {name: "swl", args: "{r2}, {imm}({r1})"},
"000000????????????????????001111": {name: "sync", args: "{i4}"},
"000000????????????????????001100": {name: "syscall", args: "{code}"},
// skip traps
"000000????????????????????100110": {name: "xor", args: "{r3}, {r1}, {r2}"},
"001110??????????????????????????": {name: "xori", args: "{r2}, {r1}, {imm}"},
// COP1 (fpu) instructions
"01000110000???????????????000101": {name: "abs.s", args: "{fr4}, {fr3}"},
"01000110000???????????????000000": {name: "add.s", args: "{fr4}, {fr3}, {fr2}"},
"01000110000???????????????011000": {name: "adda.s", args: "{fr3}, {fr2}"},
"0100010100000000????????????????": {name: "bc1f", args: "{b}"},
"0100010100000010????????????????": {name: "bc1fl", args: "{b}"},
"0100010100000001????????????????": {name: "bc1t", args: "{b}"},
"0100010100000011????????????????": {name: "bc1tl", args: "{b}"},
"0100010100000000????????????????": {name: "bc1f", args: "{b}"},
"01000110000???????????????110010": {name: "c.eq.s", args: "{fr3}, {fr2}"},
"01000110000???????????????110000": {name: "c.f.s", args: "{fr3}, {fr2}"},
"01000110000???????????????110110": {name: "c.le.s", args: "{fr3}, {fr2}"},
"01000110000???????????????110100": {name: "c.lt.s", args: "{fr3}, {fr2}"},
// Skipping cfc1 and ctc1
"01000110100???????????????100000": {name: "cvt.s.w", args: "{fr4}, {fr3}"},
"01000110000???????????????100100": {name: "cvt.w.s", args: "{fr4}, {fr3}"},
"01000110000???????????????000011": {name: "div.s", args: "{fr4}, {fr3}, {fr2}"},
"110001??????????????????????????": {name: "lwc1", args: "{fr2}, {imm}({r1})"},
"01000110000???????????????011100": {name: "madd.s", args: "{fr4}, {fr3}, {fr2}"},
"01000110000???????????????011110": {name: "madda.s", args: "{fr3}, {fr2}"},
"01000110000???????????????101000": {name: "max.s", args: "{fr4}, {fr3}, {fr2}"},
"01000100000?????????????????????": {name: "mfc1", args: "{r2}, {fr3}"},
"01000110000???????????????101001": {name: "min.s", args: "{fr4}, {fr3}, {fr2}"},
"01000110000???????????????000110": {name: "mov.s", args: "{fr4}, {fr3}"},
"01000110000???????????????011101": {name: "msub.s", args: "{fr4}, {fr3}, {fr2}"},
"01000110000???????????????011111": {name: "msuba.s", args: "{fr3}, {fr2}"},
"01000100100?????????????????????": {name: "mfc1", args: "{r2}, {fr3}"},
"01000110000???????????????000010": {name: "mul.s", args: "{fr4}, {fr3}, {fr2}"},
"01000110000???????????????011010": {name: "mula.s", args: "{fr3}, {fr2}"},
"01000110000???????????????000111": {name: "neg.s", args: "{fr4}, {fr3}"},
"01000110000???????????????010110": {name: "rsqrt.s", args: "{fr4}, {fr3}, {fr2}"},
"01000110000???????????????000100": {name: "sqrt.s", args: "{fr4}, {fr2}"},
"01000110000???????????????000001": {name: "sub.s", args: "{fr4}, {fr3}, {fr2}"},
"01000110000???????????????011001": {name: "suba.s", args: "{fr3}, {fr2}"},
"111001??????????????????????????": {name: "swc1", args: "{fr2}, {imm}({r1})"},
// Sony-specific MIPS instructions
"011100????????????????????011010": {name: "div1", args: "{r1}, {r2}"},
"011100????????????????????011011": {name: "divu1", args: "{r1}, {r2}"},
"011110??????????????????????????": {name: "lq", args: "{r2}, {imm}({r1})"},
"011100????????????????????000000": {name: "madd", args: "{r3}, {r1}, {r2}"},
"011100????????????????????100000": {name: "madd1", args: "{r3}, {r1}, {r2}"},
"011100????????????????????000001": {name: "maddu", args: "{r3}, {r1}, {r2}"},
"011100????????????????????100001": {name: "maddu1", args: "{r3}, {r1}, {r2}"},
"011100????????????????????010000": {name: "mfhi1", args: "{r3}"},
"011100????????????????????010010": {name: "mflo1", args: "{r3}"},
"000000????????????????????101000": {name: "mfsa", args: "{r3}"},
"011100????????????????????010001": {name: "mthi1", args: "{r1}"},
"011100????????????????????010011": {name: "mtlo1", args: "{r1}"}, // nice job sony docs you screwed up
"000000????????????????????101001": {name: "mtsa", args: "{r1}"},
"000001?????11000????????????????": {name: "mtsab", args: "{r1}, {imm}"},
"000001?????11001????????????????": {name: "mtsah", args: "{r1}, {imm}"},
"000000????????????????????011000": {name: "mult", args: "{r3}, {r1}, {r2}"},
"011100????????????????????011000": {name: "mult1", args: "{r3}, {r1}, {r2}"},
"000000????????????????????011001": {name: "multu", args: "{r3}, {r1}, {r2}"},
"011100????????????????????011001": {name: "multu1", args: "{r3}, {r1}, {r2}"},
"011100???????????????00101101000": {name: "pabsh", args: "{r3}, {r2}"},
"011100???????????????00001101000": {name: "pabsw", args: "{r3}, {r2}"},
"011100???????????????01000001000": {name: "paddb", args: "{r3}, {r1}, {r2}"},
"011100???????????????00100001000": {name: "paddh", args: "{r3}, {r1}, {r2}"},
"011100???????????????11000001000": {name: "paddsb", args: "{r3}, {r1}, {r2}"},
"011100???????????????10100001000": {name: "paddsh", args: "{r3}, {r1}, {r2}"},
"011100???????????????10000001000": {name: "paddsw", args: "{r3}, {r1}, {r2}"},
"011100???????????????11000101000": {name: "paddub", args: "{r3}, {r1}, {r2}"},
"011100???????????????10100101000": {name: "padduh", args: "{r3}, {r1}, {r2}"},
"011100???????????????10000101000": {name: "padduw", args: "{r3}, {r1}, {r2}"},
"011100???????????????00000001000": {name: "paddw", args: "{r3}, {r1}, {r2}"},
"011100???????????????00100101000": {name: "padsbh", args: "{r3}, {r1}, {r2}"},
"011100???????????????10010001001": {name: "pand", args: "{r3}, {r1}, {r2}"},
"011100???????????????01010101000": {name: "pceqb", args: "{r3}, {r1}, {r2}"},
"011100???????????????00110101000": {name: "pceqh", args: "{r3}, {r1}, {r2}"},
"011100???????????????00010101000": {name: "pceqw", args: "{r3}, {r1}, {r2}"},
"011100???????????????01010001000": {name: "pcgtb", args: "{r3}, {r1}, {r2}"},
"011100???????????????00110001000": {name: "pcgth", args: "{r3}, {r1}, {r2}"},
"011100???????????????00010001000": {name: "pcgtw", args: "{r3}, {r1}, {r2}"},
"011100???????????????11011101001": {name: "pcpyh", args: "{r3}, {r2}"},
"011100???????????????01110001001": {name: "pcpyld", args: "{r3}, {r1}, {r2}"},
"011100???????????????01110101001": {name: "pcpyud", args: "{r3}, {r1}, {r2}"},
"011100???????????????11101001001": {name: "pdivbw", args: "{r1}, {r2}"},
"011100???????????????01101101001": {name: "pdivuw", args: "{r1}, {r2}"},
"011100???????????????01101001001": {name: "pdivw", args: "{r1}, {r2}"},
"011100???????????????11010101001": {name: "pexch", args: "{r3}, {r2}"},
"011100???????????????11110101001": {name: "pexcw", args: "{r3}, {r2}"},
"011100???????????????11010001001": {name: "pexeh", args: "{r3}, {r2}"},
"011100???????????????11110001001": {name: "pexew", args: "{r3}, {r2}"},
"011100???????????????11110001000": {name: "pext5", args: "{r3}, {r2}"},
"011100???????????????11010001000": {name: "pextlb", args: "{r3}, {r1}, {r2}"},
"011100???????????????10110001000": {name: "pextlh", args: "{r3}, {r1}, {r2}"},
"011100???????????????10010001000": {name: "pextlw", args: "{r3}, {r1}, {r2}"},
"011100???????????????11010101000": {name: "pextub", args: "{r3}, {r1}, {r2}"},
"011100???????????????10110101000": {name: "pextuh", args: "{r3}, {r1}, {r2}"},
"011100???????????????10010101000": {name: "pextuw", args: "{r3}, {r1}, {r2}"},
"011100???????????????10001001001": {name: "phmadh", args: "{r3}, {r1}, {r2}"},
"011100???????????????10101001001": {name: "phmsbh", args: "{r3}, {r1}, {r2}"},
"011100???????????????01010101001": {name: "pinteh", args: "{r3}, {r1}, {r2}"},
"011100???????????????01010001001": {name: "pinth", args: "{r3}, {r1}, {r2}"},
"011100???????????????10000001001": {name: "pmaddh", args: "{r3}, {r1}, {r2}"},
"011100???????????????00000101001": {name: "pmadduw", args: "{r3}, {r1}, {r2}"},
"011100???????????????00000001001": {name: "pmaddw", args: "{r3}, {r1}, {r2}"},
"011100???????????????00111001000": {name: "pmaxh", args: "{r3}, {r1}, {r2}"},
"011100???????????????00011001000": {name: "pmaxw", args: "{r3}, {r1}, {r2}"},
"011100???????????????01000001001": {name: "pmfhi", args: "{r3}"},
"011100???????????????00011110000": {name: "pmfhl.lh", args: "{r3}"},
"011100???????????????00000110000": {name: "pmfhl.lw", args: "{r3}"},
"011100???????????????00100110000": {name: "pmfhl.sh", args: "{r3}"},
"011100???????????????00010110000": {name: "pmfhl.slw", args: "{r3}"},
"011100???????????????00001110000": {name: "pmfhl.uw", args: "{r3}"},
"011100???????????????01001001001": {name: "pmflo", args: "{r3}"},
"011100???????????????00111101000": {name: "pminh", args: "{r3}, {r1}, {r2}"},
"011100???????????????00011101000": {name: "pminw", args: "{r3}, {r1}, {r2}"},
"011100???????????????10100001001": {name: "psubh", args: "{r3}, {r1}, {r2}"},
"011100???????????????00100001001": {name: "pmsubw", args: "{r3}, {r1}, {r2}"},
"011100???????????????01000101001": {name: "pmthi", args: "{r1}"},
"011100???????????????00000110001": {name: "pmthl.lw", args: "{r1}"},
"011100???????????????01001101001": {name: "pmtlo", args: "{r1}"},
"011100???????????????11100001001": {name: "pmulth", args: "{r3}, {r1}, {r2}"},
"011100???????????????01100101001": {name: "pmultuw", args: "{r3}, {r1}, {r2}"},
"011100???????????????01100001001": {name: "pmultw", args: "{r3}, {r1}, {r2}"},
"011100???????????????10011101001": {name: "pnor", args: "{r3}, {r1}, {r2}"},
"011100???????????????10010101001": {name: "por", args: "{r3}, {r1}, {r2}"},
"011100???????????????11111001000": {name: "ppac5", args: "{r3}, {r2}"},
"011100???????????????11011001000": {name: "ppacb", args: "{r3}, {r1}, {r2}"},
"011100???????????????10111001000": {name: "ppach", args: "{r3}, {r1}, {r2}"},
"011100???????????????10011001000": {name: "ppacw", args: "{r3}, {r1}, {r2}"},
"011100???????????????11011001001": {name: "prevh", args: "{r3}, {r2}"},
"011100???????????????11111001001": {name: "prot3w", args: "{r3}, {r2}"},
"011100????????????????????110100": {name: "psllh", args: "{r3}, {r2}, {i4}"},
"011100???????????????00010001001": {name: "psllvw", args: "{r3}, {r1}, {r2}"},
"011100????????????????????111100": {name: "psllw", args: "{r3}, {r2}, {i4}"},
"011100????????????????????110111": {name: "psrah", args: "{r3}, {r2}, {i4}"},
"011100???????????????00011101001": {name: "psravw", args: "{r3}, {r1}, {r2}"},
"011100????????????????????111111": {name: "psraw", args: "{r3}, {r2}, {i4}"},
"011100????????????????????110110": {name: "psrlh", args: "{r3}, {r2}, {i4}"},
"011100???????????????00011001001": {name: "psrlvw", args: "{r3}, {r1}, {r2}"},
"011100????????????????????111110": {name: "psrlw", args: "{r3}, {r2}, {i4}"},
"011100???????????????01001001000": {name: "psub", args: "{r3}, {r1}, {r2}"},
"011100???????????????00101001000": {name: "psubh", args: "{r3}, {r1}, {r2}"},
"011100???????????????11001001000": {name: "psubsb", args: "{r3}, {r1}, {r2}"},
"011100???????????????10101001000": {name: "psubsh", args: "{r3}, {r1}, {r2}"},
"011100???????????????10001001000": {name: "psubsw", args: "{r3}, {r1}, {r2}"},
"011100???????????????11001101000": {name: "psubub", args: "{r3}, {r1}, {r2}"},
"011100???????????????10101101000": {name: "psubuh", args: "{r3}, {r1}, {r2}"},
"011100???????????????10001101000": {name: "psubuw", args: "{r3}, {r1}, {r2}"},
"011100???????????????00001001000": {name: "psubh", args: "{r3}, {r1}, {r2}"},
"011100???????????????10011001001": {name: "pxor", args: "{r3}, {r1}, {r2}"},
"011100???????????????11011101000": {name: "qfsrv", args: "{r3}, {r1}, {r2}"},
"011111??????????????????????????": {name: "sq", args: "{r2}, {imm}({r1})"},
}
const adsr_rates = new Uint32Array(160);
for(let i = 0; i < 160; i++) {
let shift = (i - 32) >> 2;
let rate = (i & 3) + 4;
rate = Math.floor(rate * (2 ** shift));
adsr_rates[i] = Math.min(rate, 0x3FFFFFFF);
}
async function load_gamefile() {
audio_context = new AudioContext({sampleRate: 48000}); // the PS2 SPU runs at 48 kHz
convolver_node = audio_context.createConvolver();
convolver_node.connect(audio_context.destination);
fetch(impulse_response_url).then(async (response) => {
convolver_buffer = await audio_context.decodeAudioData(await response.arrayBuffer())
convolver_node.buffer = convolver_buffer;
});
document.getElementById("loadmenu").style.display = "none";
infile = document.getElementById("fileinput").files[0];
let filelistelem = document.getElementById("filelist");
let this_sectors = file_sectors;
let this_sizes = file_sizes;
if(infile.size == 156485632) {
this_sectors = demo_file_sectors;
this_sizes = demo_file_sizes;
} else if(infile.size != 1902385152) {
this_sectors = [0];
this_sizes = [Math.ceil(infile.size / 2048)];
}
for(let i = 0; i < this_sectors.length; i++) {
let index_string = "0x"+i.toString(16).padStart(4,0);
let fileelem = document.createElement("div");
filelistelem.appendChild(fileelem);
if(this_sizes[i] == 0) {
fileelem.textContent = index_string+": Empty";
file_list.push(null);
} else {
let part_header_blob = infile.slice(this_sectors[i]*2048, this_sectors[i]*2048+48);
let part_header = new Uint8Array(await new Response(part_header_blob).arrayBuffer());
if(part_header[0] == 0x49 && part_header[1] == 0x44 && part_header[2] == 0x4D) {
fileelem.textContent = index_string+": IDM";
let part_blob = infile.slice(this_sectors[i]*2048, (this_sectors[i]+this_sizes[i])*2048);
let part = new Uint8Array(await new Response(part_blob).arrayBuffer());
let part_dv = new DataView(part.buffer);
let curr_addr = 0;
let file_entry = [];
file_list.push(file_entry);
let indent = 0;
while(curr_addr < part.length) {
if(part[curr_addr] == 0x49 && part[curr_addr+1] == 0x44 && part[curr_addr+2] == 0x4D) {
let absolute_offset = curr_addr + this_sectors[i]*2048;
let size = part_dv.getInt32(curr_addr+8, true);
let sub_blob = part_blob.slice(curr_addr, curr_addr+size);
let partelem = document.createElement("div");
filelist.appendChild(partelem);
let tc = "\xa0\xa0IDM " + part[curr_addr+3].toString(16) + " " + part[curr_addr+4].toString(16) + " " + part[curr_addr+5].toString(16) + "[" + (part[curr_addr+4] + part[curr_addr+5] * 256) + "]";
for(let i = 0; i < indent; i++) {
tc = "\xa0\xa0" + tc;
}
let this_indent = indent;
let ident = [part[curr_addr+3],part[curr_addr+4],part[curr_addr+5]];
if(ident[0] == 4 && ident[1] == 4 && ident[2] == 0) {
tc += " (Texture)";
} else if(ident[0] == 1 && ident[1] == 0 && ident[2] == 0) {
tc += " (EOF)";
if(indent > 0)
indent--;
} else if(ident[0] == 4 && ident[1] == 0x25 && ident[2] == 0) {
tc += " (Script)";
} else if(ident[0] == 1 && ident[1] == 0x13 && ident[2] == 0) {
tc += " (Zone Map)";
} else if(ident[0] == 1 && (ident[1] == 0x12 || ident[1] == 0x20 || ident[1] == 0x8) && ident[2] == 0) {
let header_size = 16 + part_dv.getInt16(curr_addr+6, true);
if(part[curr_addr+header_size] == 0x49 && part[curr_addr+header_size+1] == 0x44 && part[curr_addr+header_size+2] == 0x4D) {
size = header_size;
indent++;
}
} else if(ident[0] == 1 && ident[1] == 0xD && ident[2] == 0) {
tc += " (Model)";
} else if(ident[0] == 1 && ident[1] == 0x3 && ident[2] == 0) {
tc += " (Map Geometry)";
} else if(ident[0] == 1 && ident[1] == 0x2 && ident[2] == 0) {
tc += " (Material List)";
}
partelem.textContent = tc;
if(size <= 0) {
console.warn(size + " size at file " + i);
break;
}
curr_addr += size;
partelem.addEventListener("click", (e) => {
for(let othersel of document.querySelectorAll(".file-item-selected")) {
othersel.classList.remove("file-item-selected");
}
partelem.classList.add("file-item-selected");
set_file(sub_blob, file_entry, e.ctrlKey);
});
file_entry.push({blob: sub_blob, ident, size, indent: this_indent, offset: absolute_offset});
} else {
if(curr_addr % 2048 == 0) {
curr_addr += 2048;
} else {
curr_addr = Math.ceil(curr_addr / 2048) * 2048
}
}
}
} else {
if(part_header[24] == 0x53 && part_header[25] == 0x42 && part_header[26] == 0x6C && part_header[27] == 0x6B) {
fileelem.textContent = index_string+": Sound bank";
} else if(part_header[32] == 0x53 && part_header[33] == 0x42 && part_header[34] == 0x76 && part_header[35] == 0x32) {
fileelem.textContent = index_string+": Music file \"" + [...part_header.slice(44,48)].map((cc)=>{return String.fromCharCode(cc);}).join("") + "\"";
let part_blob = infile.slice(this_sectors[i]*2048, (this_sectors[i]+this_sizes[i])*2048);
fileelem.addEventListener("click", (e) => {
for(let othersel of document.querySelectorAll(".file-item-selected")) {
othersel.classList.remove("file-item-selected");
}
fileelem.classList.add("file-item-selected");
set_sbv2(part_blob);
});
} else if(part_header[0] == 0x56 && part_header[1] == 0x41 && part_header[2] == 0x47 && part_header[3] == 0x70) {
let title = "";
for(let i = 32; i < 48; i++) {
if(part_header[i] == 0) break;
title += String.fromCharCode(part_header[i]);
}
fileelem.textContent = index_string+": VAGp sound \"" + title + "\"";
let part_blob = infile.slice(this_sectors[i]*2048, (this_sectors[i]+this_sizes[i])*2048);
fileelem.addEventListener("click", (e) => {
for(let othersel of document.querySelectorAll(".file-item-selected")) {
othersel.classList.remove("file-item-selected");
}
fileelem.classList.add("file-item-selected");
set_vagp(part_blob);
});
} else if(part_header[0] == 0x20 && part_header[1] == 0x4B && part_header[2] == 0x50 && part_header[3] == 0x56) {
fileelem.textContent = index_string+": KPV audio";
let part_blob = infile.slice(this_sectors[i]*2048, (this_sectors[i]+this_sizes[i])*2048);
fileelem.addEventListener("click", (e) => {
for(let othersel of document.querySelectorAll(".file-item-selected")) {
othersel.classList.remove("file-item-selected");
}
fileelem.classList.add("file-item-selected");
set_kpv(part_blob);
});
} else {
fileelem.textContent = index_string+": Unknown File";
}
file_list.push(null);
}
}
}
log ("Done loading");
}
async function set_sbv2(blob) {
if(dispose_old) {
dispose_old();
dispose_old = null;
}
let file = new Uint8Array(await new Response(blob).arrayBuffer());
console.log(file.length);
let dv = new DataView(file.buffer);
let contentelem = document.getElementById("content");
contentelem.innerHTML = "";
let sbv2 = new SBv2Decoder(file);
console.log(sbv2);
let sound_start = dv.getUint32(16, true);
let sound_length = dv.getUint32(20, true);
let mmid_start = dv.getUint32(24, true);
let sbv2_start = 0x20;
let instruments_start = dv.getUint32(sbv2_start + 0x20, true) + sbv2_start;
let num_instruments = dv.getUint16(sbv2_start + 0x16, true);
let instruments = [];
let stop_playing = null;
dispose_old = ()=>{if(stop_playing) stop_playing();};
let num_midis = sbv2.tracks.length;
for(let i = (num_midis <= 1 ? 0 : 1); i < num_midis; i++) { // Yes, I'm skipping track zero. Track zero doesn't have anything useful. At least not for this thing.
let track = sbv2.tracks[i];
let tempo = track.tempo;
let ticks_per_qnote = track.ticks_per_qnote;
let data_offset = track.data_offset;
let mtext = `Track ${i}\n`;
mtext += ` Tempo: ${tempo} BPM\n`;
mtext += ` Ticks per quarter note: ${ticks_per_qnote}\n`;
let midi_elem = document.createElement("pre");
midi_elem.textContent = mtext;
contentelem.appendChild(midi_elem);
let channel_toggles = [];
let channel_labels = [];
let channel_toggles_table = document.createElement("table");
let channel_toggles_channels = document.createElement("tr");
let channel_toggles_checkboxes = document.createElement("tr");
for(let i = 0; i < 16; i++) {
let channelnum = document.createElement("td");
channelnum.textContent = i.toString(16);
channel_labels.push(channelnum);
channel_toggles_channels.appendChild(channelnum);
let channelboxcont = document.createElement("td");
channelnum.style.textAlign = "center";
let channelboxcheck = document.createElement("input");
channelboxcheck.type = "checkbox";
channelboxcheck.checked = true;
channelboxcont.appendChild(channelboxcheck);
channel_toggles_checkboxes.appendChild(channelboxcont);
channel_toggles.push(channelboxcheck);
channelboxcheck.addEventListener("dblclick", () => {
let amt_on = 0;
let amt_off = 0;
for(let toggle of channel_toggles) {
if(toggle.checked) amt_on++;
else amt_off++;
}
for(let toggle of channel_toggles) {
toggle.checked = amt_off > amt_on;
}
channelboxcheck.checked = true;
});
}
channel_toggles_table.appendChild(channel_toggles_channels);
channel_toggles_table.appendChild(channel_toggles_checkboxes);
contentelem.appendChild(channel_toggles_table);
let reverb_toggle = document.createElement("input");
reverb_toggle.type = "checkbox";
reverb_toggle.checked = true;
contentelem.appendChild(reverb_toggle);
contentelem.appendChild(document.createTextNode("Reverb"));
contentelem.appendChild(document.createElement("br"));
function calc_channel_mask() {
let mask = 0;
for(let i = 0; i < 16; i++) {
if(channel_toggles[i].checked)
mask |= (1 << i);
}
return mask;
}
let playback_display = document.createElement("pre");
let play_button = document.createElement("input");
play_button.type = "button";
play_button.value = "Play";
play_button.addEventListener("click", () => {
if(stop_playing) { stop_playing(); stop_playing = null; }
let player = new MidiPlayer(sbv2, track, audio_context);
player.channel_mask = calc_channel_mask();
player.reverb_enabled = reverb_toggle.checked;
player.play();
console.log(player);
let do_vis = () => {
if(player.curr_timeout == null) return;
for(let i = 0; i < 16; i++) {
let channel = player.channels[i];
let is_playing = false;
for(let note of channel) {
if(note) {
is_playing = true;
break;
}
}
let vis = channel_labels[i];
vis.style.backgroundColor = is_playing ? "#ccaacc" : "transparent";
}
player.channel_mask = calc_channel_mask();
player.reverb_enabled = reverb_toggle.checked;
setTimeout(do_vis, 50);
};
do_vis();
stop_playing = () => {
player.stop();
for(let vis of channel_labels) {
vis.style.backgroundColor = "transparent";
}
};
});
contentelem.appendChild(play_button);
let stop_button = document.createElement("input");
stop_button.type = "button";
stop_button.value = "Stop";
stop_button.addEventListener("click", () => {
if(stop_playing) { stop_playing(); stop_playing = null; }
});
contentelem.appendChild(stop_button);
let savewav_button = document.createElement("input");
savewav_button.type = "button";
savewav_button.value = "Save .wav (may take a while)";
savewav_button.addEventListener("click", async () => {
/*for(let chan = 0; chan < 16; chan++) {
let ctx = new OfflineAudioContext(2, (track.seconds + 5)*48000, 48000);
let player = new MidiPlayer(sbv2, track, ctx);
player.channel_mask = 1 << chan;
player.play();
let buf = await ctx.startRendering();
saveAs(new Blob([to_wav(buf)], {type:'audio/wav'}), sbv2.tag + i + "_" + chan + ".wav");
}*/
let ctx = new OfflineAudioContext(2, (track.seconds + 5)*48000, 48000);
let player = new MidiPlayer(sbv2, track, ctx);
player.channel_mask = calc_channel_mask();
player.reverb_enabled = reverb_toggle.checked;
player.play();
let buf = await ctx.startRendering();
saveAs(new Blob([to_wav(buf)], {type:'audio/wav'}), sbv2.tag + i + ".wav");
});
contentelem.appendChild(savewav_button);
let savemid_button = document.createElement("input");
savemid_button.type = "button";
savemid_button.value = "Save as .mid";
savemid_button.addEventListener("click", () => {
let outfile = new Uint8Array(100000);
let outdv = new DataView(outfile.buffer);
let current_midi_pointer = data_offset;
let o = 0;
outfile[o++] = 'M'.charCodeAt(0);
outfile[o++] = 'T'.charCodeAt(0);
outfile[o++] = 'h'.charCodeAt(0);
outfile[o++] = 'd'.charCodeAt(0);
outdv.setUint32(o, 6); o += 4;
outdv.setUint16(o, 0); o += 2;
outdv.setUint16(o, 1); o += 2;
outdv.setUint16(o, ticks_per_qnote); o += 2;
outfile[o++] = 'M'.charCodeAt(0);
outfile[o++] = 'T'.charCodeAt(0);
outfile[o++] = 'r'.charCodeAt(0);
outfile[o++] = 'k`'.charCodeAt(0);
let length_placeholder = o; o += 4;
let length_start = o;
// Write the tempo event
outfile[o++] = 0; // delta-time of 0
outfile[o++] = 0xFF; // meta event
outfile[o++] = 0x51; // set tempo
outdv.setUint32(o, 60000000 / tempo);// its a 3 byte value so I just write this as 4 bytes and overwrite the first byte with what its actually supposed to be. this is why little endian is better than big endian.
outfile[o] = 0x3;
o += 4;
let is_on_wait_byte = true;
while(current_midi_pointer < file.length) {
if(is_on_wait_byte) {
is_on_wait_byte = false;
let wait_byte = file[current_midi_pointer++];
outfile[o++] = wait_byte;
while(wait_byte & 0x80) {
wait_byte = file[current_midi_pointer++];
outfile[o++] = wait_byte;
}
} else {
is_on_wait_byte = true;
if(file[current_midi_pointer] & 0x80) {
event_type = file[current_midi_pointer];
if((event_type & 0xF0) == 0xD0) { // reee sony
outfile[o++] = 0x80 | (event_type & 0xF);
} else {
outfile[o++] = event_type;
}
current_midi_pointer++;
}
if((event_type & 0xF0) == 0xC0) { // one-byte event
outfile[o++] = file[current_midi_pointer++];
} else if([0x80, 0x90, 0xA0, 0xB0, 0xE0].includes(event_type & 0xF0)) { // two-byte events
outfile[o++] = file[current_midi_pointer++];
outfile[o++] = file[current_midi_pointer++];
} else if((event_type & 0xF0) == 0xD0) { // note off event
outfile[o++] = file[current_midi_pointer++];
outfile[o++] = 63;
} else if(event_type == 0xFF) { // Meta event
let meta_start = current_midi_pointer;
let meta_type = file[current_midi_pointer++];
let meta_length = 0;
let length_byte = file[current_midi_pointer++];
while(length_byte & 0x80) {
meta_length += length_byte & 0x7F;
meta_length <<= 7;
length_byte = file[current_midi_pointer++];
}
meta_length += length_byte;
let full_meta = file.subarray(meta_start, current_midi_pointer + meta_length);
current_midi_pointer += meta_length;
outfile.set(full_meta, o);
o += full_meta.length;
if(meta_type == 0x2F) {
break;
}
} else if(event_type == 0xF0) {
// I'd *not* include this but it'd be more difficult to splice it out so meh/
let start_sysex = current_midi_pointer;
while(file[current_midi_pointer++] != 0xF7 && current_midi_pointer < file.length);
let sysex_length = current_midi_pointer - start_sysex;
for(let i = 0; i < 4; i++) {
if(sysex_length & 0xFE00000) {
outfile[o++] = ((sysex_length >> 21) & 0x7F) | (i == 3 ? 0 : 0x80);
}
sysex_length <<= 0x7;
}
outfile.set(file.subarray(start_sysex, current_midi_pointer), o);
o += current_midi_pointer - start_sysex;
} else {
throw new Error('Unrecognized MIDI event ' + event_type.toString(16));
}
}
}
outdv.setUint32(length_placeholder, o - length_start);
outfile = outfile.subarray(0, o);
saveAs(new Blob([outfile], {type:"audio/midi"}), [...file.slice(44,48)].map((cc)=>{return String.fromCharCode(cc);}).join("") + i + '.mid');
});
contentelem.appendChild(savemid_button);
let vis_button = document.createElement("input");
vis_button.type = "button";
vis_button.value = "Save Visualisation (.ply)";
vis_button.addEventListener("click", () => {
for(let chan = 0; chan < 16; chan++) {
let total_verts = 0;
let total_faces = 0;
let verts_str = "";
let faces_str = "";
const time_scale = 0.25;
let min_note = 127;
let max_note = 0;
for(let event of track.events) {
if(event.type == "note_on") {
max_note = Math.max(max_note, event.note + 1);
min_note = Math.min(min_note, event.note);
}
}
let channel_programs = new Array(16);
for(let event of track.events) {
if(event.channel != chan) continue;
if(event.type == "program_change") {
channel_programs[event.channel] = event.program;
}
if(event.type != "note_on" || !event.note_off)
continue;
let event_length = event.note_off.seconds - event.seconds;
let region = null;
for(let r of instruments[channel_programs[event.channel] || 0].regions) {
if(event.note >= r.note_start && event.note <= r.note_end) {
region = r;
break;
}
}
if(!region) continue;
let curve = [[0,0]];
let attack_rate = (region.adsr1 >> 8) & 0x7F;
let attack_mode = region.adsr1 >> 15;
let curr_adsr_time = 0;
if(attack_mode) {
if(adsr_rates[(attack_rate ^ 0x7F) - 0x18 + 32] > 0) {
let time_a = (0x60000000 / adsr_rates[(attack_rate ^ 0x7F) - 0x18 + 32]) / 48000;
curve.push([time_a, 0.75]);
curr_adsr_time = time_a + (0x1FFFFFFF / adsr_rates[(attack_rate ^ 0x7F) - 0x10 + 32]) / 48000;
curve.push([curr_adsr_time, 1]);
}
} else {
if(adsr_rates[(attack_rate ^ 0x7F) - 0x10 + 32] > 0) {
curr_adsr_time = (0x7FFFFFFF / adsr_rates[(attack_rate ^ 0x7F) - 0x10 + 32]) / 48000;
curve.push([curr_adsr_time, 1]);
}
}
let curr_adsr_percent = 1;
let decay_rate = (region.adsr1 >> 4) & 0xF;
let sustain_level = region.adsr1 & 0xF;
let sustain_fraction = ((1/16)*(sustain_level + 1));
let decay_time_constant = 0x7FFFFFFF / adsr_rates[((decay_rate^0x1f)*4)-0xC+32] / 48000;
let decay_time = decay_time_constant * Math.log(1 / sustain_fraction)
for(let i = 0; i <= decay_time / decay_time_constant; i += 0.1) {
curve.push([curr_adsr_time+i*decay_time_constant, curr_adsr_percent * Math.E ** -i]);
}
curr_adsr_time += decay_time;
curr_adsr_percent *= sustain_fraction;
curve.push([curr_adsr_time, curr_adsr_percent]);
let sustain_mode = region.adsr2 >> 14;
let sustain_rate = (region.adsr2 >> 6) & 0x7F;
if(sustain_mode & 0x2) { // decreasing
if(sustain_mode & 0x4) { // exponential
let sustain_time_constant = 0x7FFFFFFF / adsr_rates[(sustain_rate^0x7F)-0xF + 32] / 48000;
let sustain_time = event_length - curr_adsr_time;
for(let i = 0; i <= sustain_time / sustain_time_constant + 0.1; i += 0.1) {
curve.push([curr_adsr_time+i*sustain_time_constant, curr_adsr_percent * Math.E ** -i]);
}
} else {
if(adsr_rates[(sustain_rate ^ 0x7F)-0xF + 32] > 0) {
curr_adsr_time += (0x7FFFFFFF * curr_adsr_percent / adsr_rates[(sustain_rate ^ 0x7F)-0xF + 32]) / 48000;
curve.push([curr_adsr_time, 0]);
}
}
} else if(curr_adsr_percent < 1) {
console.warn("Increasing sustain unimplemented");
}
let release_point = [event_length, 1];
for(let i = 0; i < curve.length; i++) {
let point = curve[i];
let prev_point = curve[i-1];
if(point[0] <= release_point[0]) {
release_point[1] = point[1];
}
if(prev_point && prev_point[0] < release_point[0] && point[0] > release_point[0]) {
release_point[1] = ((point[1]-prev_point[1])/(point[0]-prev_point[0])) * (release_point[0] - prev_point[0]) + prev_point[1];
}
if(point[0] >= release_point[0]) {
curve.length = i;
break;
}
}
if(release_point[1] > 0 || curve[curve.length-1][1] > 0) {
curve.push(release_point);
curr_adsr_percent = release_point[1];
curr_adsr_time = release_point[0]
let release_rate = region.adsr2 & 0x1F;
let release_mode = (region.adsr2 >> 5) & 0x1;
if(release_mode) {
let time_constant = 0x7FFFFFFF / adsr_rates[((release_rate^0x1f)*4)-0xC+32] / 48000;
for(let i = 0; i < 4; i += 0.1) {
curve.push([curr_adsr_time+i*time_constant, curr_adsr_percent * Math.E ** -i]);
}
} else {
let time_to_silence = curr_adsr_percent * 0x7FFFFFFF / (1 << (0x1f - release_rate)) / 48000;
curve.push([curr_adsr_time+time_to_silence, 0]);
}
}
// output the curve
if(curve.length >= 1) {
let color = get_map_color_float(event.channel);
for(let i = 0; i < curve.length; i++) {
let x = (event.seconds + curve[i][0]) * time_scale;
let y_scale = 1 / (max_note-min_note);
let base_y = (event.note - min_note + 0.5) * y_scale;
let y_add = curve[i][1] * event.velocity * y_scale * 0.5;
verts_str += `${x} ${base_y+y_add} ${-event_length/10} ${color[0]} ${color[1]} ${color[2]}\n`;
verts_str += `${x} ${base_y-y_add} ${-event_length/10} ${color[0]} ${color[1]} ${color[2]}\n`;
total_verts += 2;
if(i >= 1) {
faces_str += `4 ${total_verts-1} ${total_verts-2} ${total_verts-4} ${total_verts-3}\n`;
total_faces += 1;
}
}
}
}
saveAs(new Blob([`ply
format ascii 1.0
element vertex ${total_verts}
property float x
property float y
property float z
property float red
property float green
property float blue
element face ${total_faces}
property list uchar int vertex_index
end_header
${verts_str}${faces_str}`], {type:'text/plain'}), sbv2.tag + i + "_" + chan + '.ply');
}
});
contentelem.appendChild(vis_button);
contentelem.appendChild(playback_display);
}
let pre = document.createElement("pre");
pre.textContent = `Sound start: ${sound_start}
Sound length: ${sound_length}
`;
contentelem.appendChild(pre);
for(let i = 0; i < num_instruments; i++) {
let instrument_volume = file[instruments_start + (i*0x8) + 0x1];
let num_regions = file[instruments_start + (i*0x8)];
let region_offset = dv.getUint32(instruments_start + (i*0x8) + 0x4, true) + sbv2_start;
let instrument_elem = document.createElement("pre");
instrument_elem.textContent = `=== Program 0x${i.toString(16)} ===\nVolume: ${instrument_volume}`;
contentelem.appendChild(instrument_elem);
let instrument_obj = {
volume: instrument_volume / 127,
regions: []
};
instruments.push(instrument_obj);
for(let j = 0; j < num_regions; j++) {
let region_volume = file[region_offset + j*0x18 + 0x1];
let region_pitch_a = dv.getInt8(region_offset + j*0x18 + 0x2, false);
let region_pitch_b = dv.getInt8(region_offset + j*0x18 + 0x3, false);
let region_note_start = file[region_offset + j*0x18 + 0x6];
let region_note_end = file[region_offset + j*0x18 + 0x7];
let region_sample_offset = dv.getUint32(region_offset + j*0x18 + 0x10, true);
let region_adsr1 = dv.getUint16(region_offset + j*0x18 + 0xA, true);
let region_adsr2 = dv.getUint16(region_offset + j*0x18 + 0xC, true);
let region_flags = dv.getUint16(region_offset + j*0x18 + 0xE, true);
let region_obj = {
volume: region_volume / 127,
note_start: region_note_start,
note_end: region_note_end,
pitch_a: region_pitch_a,
pitch_b: region_pitch_b,
adsr1: region_adsr1,
adsr2: region_adsr2,
flags: region_flags,
sound: decode_adpcm(file, sound_start+region_sample_offset, sound_start+sound_length, 48000)
};
instrument_obj.regions.push(region_obj)
let region_elem = document.createElement("pre");
let region_text = ` ==Notes ${region_note_start}-${region_note_end}==\n`;
region_text += ` Volume: ${region_volume}\n`;
region_text += ` Pitch bytes: ${region_pitch_a} ${region_pitch_b}\n`;
region_text += ` Sample data offset: 0x${region_sample_offset.toString(16)}\n`;
region_text += ` ADSR1: 0x${region_adsr1.toString(16).padStart(4,0)}\n`;
region_text += ` ADSR2: 0x${region_adsr2.toString(16).padStart(4,0)}\n`;
region_text += ` Flags: 0x${region_flags.toString(16).padStart(4,0)}\n`;
region_elem.textContent = region_text;
contentelem.appendChild(region_elem);
let button = document.createElement("input");
button.type = "button";
button.value = "Play";
let source = null;
button.addEventListener("mousedown", () => {
let sound = region_obj.sound;
let source = audio_context.createBufferSource();
source.buffer = sound.buffer;
source.connect(audio_context.destination);
source.loop = sound.loop;
source.loopStart = sound.loop_start;
source.loopEnd = sound.loop_end;
source.playbackRate.value = handle_midi_pitch(region_pitch_a, region_pitch_b, Math.floor((region_note_start + region_note_end) / 2)) / 4096;
source.start();
let mouseup = () => {
document.removeEventListener("mouseup", mouseup);
source.stop();
};
document.addEventListener("mouseup", mouseup);
});
button.style.marginLeft = "40px";
contentelem.appendChild(button);
let savewav_button = document.createElement("input");
savewav_button.type = "button";
savewav_button.value = "Save .wav";
savewav_button.addEventListener("click", async () => {
let sound = region_obj.sound;
saveAs(new Blob([to_wav(sound.buffer)], {type:'audio/wav'}), "download.wav");
});
contentelem.appendChild(savewav_button);
}
}
}
class MidiPlayer {
constructor(sbv2, track, ctx) {
this.sbv2 = sbv2;
this.track = track;
this.ctx = ctx;
if(ctx instanceof OfflineAudioContext) {
this.convolver_node = this.ctx.createConvolver();
this.convolver_node.connect(ctx.destination);
this.convolver_node.buffer = convolver_buffer;
this.loops_left = 1;
} else {
this.convolver_node = convolver_node;
this.loops_left = Infinity;
}
this.curr_timeout = null;
this.channels = [];
for(let i = 0; i < 16; i++) {
this.channels[i] = [];
}
this.channel_programs = new Array(16);
this.channel_programs.fill(undefined);
this.channel_gains = new Array(16);
this.channel_gains_reverb = new Array(16);
for(let i = 0; i < 16; i++) {
let gain = this.channel_gains[i] = this.ctx.createGain();
gain.connect(this.ctx.destination);
let gain_reverb = this.channel_gains_reverb[i] = this.ctx.createGain();
gain_reverb.connect(this.convolver_node);
}
this.current_time = this.ctx.currentTime;