forked from mlj/miniloguesll
-
Notifications
You must be signed in to change notification settings - Fork 0
/
miniloguesll
executable file
·470 lines (439 loc) · 24.1 KB
/
miniloguesll
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
#!/usr/bin/env ruby
require 'digest'
require 'zip'
INIT_HASH = 'f4009c8ac2495c0b908f90095931e356928b37f4f7d7bfefa460aa7b8915ab34'
UK_HASHES = %w[
0235b642aba52657f656b7cb2fd24d6bb0398333754a4120e1af361de40062b8
051025a039f1adb028f6f7ea2bce2b2787b9dbacee8a88f750eeb28a4630af4b
0946b56fe03418901785dc0704297603d0042fe931ab6e1e258d66a90f1b0ea2
0afea7279f3d38566b05d49034275e9125a2fe22300c33174de38a73df0fcd9a
0be40c4afcd41794eb6ca5530d2dd433df773b3ba654b1259db9970aaa4a4271
0c4246f4c53ba9323b07749658f3d5f509320daebeba24beedd8f0ab5d24d07b
13ce9c06a53c54cec16a009853774efc2d7c41b8e2a366ad24d2875efba0c045
1b32c41ccb07c966623fedf25523abb21e76fe802981887184566d48b54e95a1
1c0dfdd0b89dd09ff882a286dcbe9cc23f3d8a1800afabdaf383096bda50908f
220ea1d0c11e84d199feab74ac37c0a8e4e289c49e92a7a08fd8a77b9055ccd2
2325314e9901019b8642b7ef52781facd168ab055b21dc795e757cf26eee9e06
2556af10e0a8e7f74aaff8acab06b877036dc10903c38ac21d7c8fa9a5bce605
2a0d07539691fb77c3efd27ba8ba00f5315efbc1834dfa10b05ce8fad9bb26ca
2c90cfce838e3a9be09d95339cafdfac0f80e9851fda9946402535186524576e
2e98e267f2f86228f6eee05fe7c70bedb4b2c3caec53bae75e90c5d0819ff478
348ed982a5bf91ac11a7894353106acc835480dba373754d66209b77a667f170
3a000ab5ca11e5968b631ab8ab2826c2eba51aa77d178be2cb986057e29cbeb4
417ac4b7ea459c585de2b82984124cff42b724a3e19dad9c2affd9eeba3ae97b
49c6906c496fb642421cd662f69b84bbb7445866d0ef1adc0eefb9fe0653abc3
4a770fa074563fac0d125c4fe7c633366f531663eacf866989eeb7f6bf5462d1
54776ac063358f16a20d73d8c1348c4b64b694a3224185be2950f0af6ef5b17f
561e9184955ee381a2bfa2c4f5936c6d2324eff3786f94881f2a39512b89a59a
63fe8a87031e7675cc86ba0ce04c5d33baa81b112a2537d7868508bd5df8c366
641764cad555fe00dfaeec206498c0422c027f4b40e2cc300930ea7a3be7d421
67809e25f36fe38aa0c68a8a3b47d6de789a92955e795dd328b70e882f5fb278
7010c2e826a251ad2cd09b307d474f8aba45146e8944ce8d06d3b237e2fa235e
71388828275622314daf963ea2966416080d4e9abda79834c9cc6e0c89013b3d
73ae7f259fb0e68ab82f46b60cacd168b2dd0c9f78b7f97d781478f3f578fb73
73e9f1df263664cd510d4e81590762697a7425d7619292b5bf98e279019a8e58
750fbf4048cd963ee94eed995877a7c1cb47b4a39c0fa6a01ec9daa77d4d02e1
754913b9a68036a6e2614ea4d251789bc142f4c341cd5afeb26f6d5cca432a94
7a493be65f62ea83a3d2d78222da0a87288e96488d61391a42b56e7c0190946f
7a56be1744cff866668efb8960043236c8a0de7dc2f1c9d474eb9eb869c5b38c
7c1df3a78b8215c188318d3815d3b6b1b0c482af0f16f9c150fc8b57183b2475
7c27a96d309d5b2fb86d055f8ce8b63f278d46fe274ac2f72a32d8e557c9b3f8
7d5778e9710643c8eebe467da8aa035b24bc1ccb575dbbf30e840c44cc824531
7e0a32312b64a233d927f077033ea56c7aa24ab64a9280866bbedd2004e52f26
7e6706570211b8a7c756cb18fa930bae4109290d33e7e6e9a732a56bbd695cfa
82ef7a067c2e291b0ec5ad5143163735a29ef3477de100fe0c31c823b20e0b24
88681e0f820f501da39c1e302979986c5bf42baf60f35df4cec7d4e8eb718a11
8fe069f3736220465582a9176aded42af88e91729ccbaf0346b2eeb7273b1143
92148d7250754d0c10b70179f260c34d7a2dda08bba0159ce0b7572ab940b24d
9e5b003f66bc8762295c852caacf6c3eaae59c0b8372489f5078fd03061edc78
9e8fbc94efb117761abdba7e91cd0013f8c74a544c240aee9f6fd92192eca5b4
a11ffea3c15d4c41d5c2bb8568c9272b6c548491ff99c9c53c1697d98651f9cc
a308d4c0ea616b8b5b54bd73f63a19369ef6a881df98adb19a9c72b35659fb72
a4e7b8d0ccc2713ac9ee4463ff68058f865924d6cc671c0ad5359826050adb5b
ab61a8f901cfa8008203ee5b84bd87fcc2c7bba5f08ad05916db252f76f8ea8f
ae2877d2f0f4bc1542b4b4a090e95326a22dc3b7eda83146612ea419ddbec418
ae2f9fee87a085fddcf158fe3ca8871b243f6ffa35111576d8e92efafc0f6c88
b620ae35d34e89d6ed4c1623866b4dd49f929c77686dcb204f05db4486c718c8
bce2d204e712d3b9a4e35ffd2191b616c9df01a544d77763f66b169ff026b9cc
c06816187fb7926f0675dc49e7ade46cae529e929794aadd351b66c857e90cb9
c32d9474218c4d06862c05b4e83f6bacb4acd46b4cdee3757b76a31ccc1a9341
c3b1950d16c0ef12ce6141be29ab7fd4c940712e8d04a1ff2ac104d8de9c6282
c4767e6d61f7c4a20b8bde372032c130aa0ec8c245ee2e18a71d097d9f19b074
c772bbbb05079a49efba46aa4d462e88949115f2443e6550f9d8e1a0296313d7
c854158682d6f282433275fd2aec6283abe8d5b20687abae2b632ae08ddbd440
c944bbf1f718e920161c695c898c69f5a990dfec5171080b9eb15707efdaef1f
cc41e602be12ad528e188a0901f7abf4d909c2e119fedd067a3fae8cecc47406
cd0519bf95e339aafcbce79fb56166a4975049cb551e25a50208a5be091beee8
ce60e065622a423b918aa8751c53fb3fa2647349e7a77b8dd7b331f34929e3b5
d43e59a950359e22bf0c980d1af159c2dee7cbbe884e9bc7ddefd888515783e9
d58124b98c2e2f06a0a95272a3ea22790033ef3038da6576575b32ab753a5539
d6932a0f2190716f0c9e8abbfa5a10470b5c05bca7531d12e24bf974ccb36c49
d9cbd79c0bf66ba61fac14ee151cf53fecc911ff079637bb3a9f3ece31282e79
daa52d1a8b642fd0723398856e54c07c0b65de2deb6450a9929ea3aaa3a7a03f
dfd8e5338b433def0ac332571131958a9408d6320057ae9966ff58ec2823070e
e67feb8808d4a68275c7f31ce4de1a1ac1315a84d0b1c33bc7ab13d41b2ee5b8
e7e82e40c4babb97a4df67b4972e6429333ac0ddc097934ae55c6c470402521f
eb83b4e1cce133db95581242984a144e1df444b2aa3e0204aa9da55b16994630
f5910cc9716425364763d64f3d9bf4c751225fe8ff2450d6e91a169e11108315
f8f34b11c24679dcd54322202952cd0cbb1b5c6e326531b859c6458baff667f4
fb2bf4dae28280eb332cb47c5b96d93ae22683a759004af654cf81eb58369fbc
fd055a82984812d3f16b562dbfbb5e7bf86fee3e287cd2a2d2c3bffa5941766b
fdd3637ce07558e8e082cd78347ab02367e2ee211e4ccd9ceb6a8822ae60900a
].freeze
EURO_HASHES = %w[
03f450ce036bcd66b4f8e2c1f4ee8384d3a16e95173a51f6bc476f09806f94f2
0449a46b96cbfe0450abd9ce49b08e951d8dc347f1f648cabe4d164ae7d6e2e0
05511dff45ef4cc35aa1adb3d859f136840134e8780c66865b2859a01d727986
07d695a2ae782fcb4eeae5c84817a5fcb3b56cce91d4fcd2ff4e8a36ca7795bc
096c3a70792ade107257bcc1c32503a2603655379e1da3b7dd1e8598c34b8fe4
0b3c1c28d1f24fa87b1aea48a2d050e19a592c659ff8a138fcb620aa7d6a45af
0b80dba837fc74bda5d67812476114183feace0214e524f309c560787db8edb4
0c242550bc1ae5ad771113e98c8f65ba3a630914e0534542d2a6e9fcf9cbab43
0c993b8862ffae769cbca0b1e7b0c23600cafed0e25f8429fb581c95a0ebe12c
1240b3ce441d8008499f54cc61bb52c0e82046038907173184c26f56451f2f17
1575781b2ede8241eee6f6d5173ef2fa0ff1c90b8c3b66d3f45a311c1168a411
17b57957b2c66adb4c3debb985d7cdd811e35e37ea5eb990b24281e35f35f6ac
18f550fb0e15e0afd90cf6d8b3ddd57eec6075870269fa73ab3a5d1e94456270
1af71b6c2f92321dbd86f6032b11646a6fe74aa4060cca1f8d60667becb0de63
1d610a92a8b8ee4946e251554152b80d307810573f0d361bbd8b7968d4bc2129
1dae7e2846c2c601cf65f62d0f028c5676dd365e214badee51146bd73efca62d
1f24f9d30b67feddb9ad147c0f5c414fb29d3de0cd3fbce9109a1ccb8080a577
219e72609406dd5defdeee496c6385f316cecdf1f40212312dd8395c67e344fd
24a38d730be7f9ed0499cd6d152d8ad4b34ab9985fa5c46936ebfc41d6e0717b
29a0e05d9b25fd079e687bcb54f9f66f0d6873d5199888d75bd11da6b1be55a0
2d9d2c8217a2f40a4ea675752f349af4b5ac25baa127b4d104f13a6380a5122d
2e92b7b0bec57583af6cbc4e6f4256cd9337537f4a3db63cb9dd61cecb876755
31a53a8ec6a718b4fe0cb0171303a291012787fa2c3ce29d9d823d358c1c811b
33fb514abab194bd3b0b06065e9c643d17a054876a6a1d44fc09c4c0b8c3501f
357121907749a08b65ac14e1b920e8793df49cafe1cd62220d8fabc6b036e6b0
38684470feddee707c785794c0c05711cd63d178d36912af46602186254a5ab9
407bb51110085f11ec406910c7e5f930a256e23892a784f2d947cf1bf456d778
4655e82e63b69b7e4cbbc19d5cca11b8c529ca7036f72076d13cb2cefadf74e4
47c2b6d8a4e51464cc6050ef0bdd84531b3025eecc96fd51644034fc8e2f75ea
49b11f9a75d3501330953745cba82ad0f5fe6eccb792503a0ccab4b524cfbe8a
4e242cc605bd6e220de67983d748b78785b69cb8e963e2319cb87ede0307ca6b
52a6868dd2316b307081181f15d08b476edebcfcd9a3f6b598a1631c4a8d1505
544d7742ab4438d13f1dfb6e19ec840ea6620a6b92eb407ad74d9ee95e2ee546
55518565170f93096f021fbd089af241fcfd73e0e96a6e3386579666735032fe
58d49e592224cd270b37448a88064b5e49dc959bb26234e83eab0f9569b54d9b
5a20283ca583e97bf2ad8df28b1dddb813a5cd4ed388ad560775ac00d889a667
5c54d298203c3e7ccf565b9cb1cfbc1e7048561fba5c933a6208db639c6e47a6
5e35ef9ed2c545e3b66b3e86bc67ab5c57e1b2b8d158c248bbc596e2cda9759a
5fe521dbc25753322ee5ebda5517d82526119dfebbbf792a589cb69d3d936f09
62bc76d28ca5f1a598d2396759b464449a64cab69b5ddab1692d8f61f54c8cff
67b176a0f15cb14be77fbd6065d802140ff6d827e9b8a9165e15831c0032add7
67fb811bd6e4fe459ccfc3c7d689ca510529a4f45c0e7eb36aa884157c778c2b
690e6d22ff663fae38e192c004fa08890c438daa8fc7a3e9de401a47e931f321
6aa816abee10dbcfb90aa0040790a8953c7f63025426ffe5169bd18b89a1f28e
6f22624ee53abb760a94f54f72afa30eef4895c58317cecbba354c59f1c3b543
73c6f9715b4c85c65850d4c19102c12bbdac28e827af4615b4b4870c694e2234
74a750e74559e4168e7effc4ccd1fe646790f565ac6c453a21c673b3ec20f8c3
7535eae5e633c6fdefc06180148c1c76c94ffcf0cf99f4fb0627101b5f277007
7619c5023bbd31a7f036b1df3bd27f44f773395648e247a0b8415e93fb5956ff
79b1dcce1f7c5bc8d9e1f614c8ffb38855e5686cd311be43c525c7bfceb2096f
7a2fa25c645fe9ff8372105e0aedc9f71835a9af867463d8c09fe3ad7fff81b7
7c5368f510505d307f6819b0ff9b48637a8b6f92013f0c74684f66408a4dc80c
7d250ec6c5e457e143638fb33800bd83c967d401d687f7570d14fd9cc34618c9
7eca2ae8db58476f3015c1e70c68af890a7bb461dd74131269df0c1c3a1a1994
83c023b2a4cc617f26ed5ba5eacd0f999c7ab9211d88ba7822aacbc539b3b76e
85f12be1986386a0a2d4657e90d88d7173bf3f5eb4cb3721e3553b07f2490d15
86df5641a6ab320ffb882c3074642467fa6ec9adf96c0d9d38208ac2e2bb41ee
87088e8ea7d31d6fd7aeed9318bafcab000370596a00c8111151c809279910d6
8a7488de61743d20b6a4d5e7cab66192b0157ccf1fc58edd6a507bb19b61e6fa
8ca5ad65b66d323ada488402c05bbe63386f14edf2e117108cc1ff05f467345a
8e9cbdcc6e5e1ca64914e5b2b148823a508ac9f73072d1563223ab34c15f1019
90b7c851227e068336b143e3ff9fdf0ea6c65547afe2e11b10bcd6a2fd9d3a4a
929ac38341a5fcda748c78a47c937d3542dcd5d4d49d124a5065a84bbd41ea8e
946f1912479d36391c66bd3b074ef3dd13a9d36e760d2c1c742d09fa117acf48
974e53dfddd9575933df91caa8f4a1fd6c67febdecae070d046ca3f6b1305d8b
9a23013a0674933e9c7c537a2afcda709e2b943cf17d515555fc4f0b023a56b9
9e25810738f02fcddea25b6ac77c67a5087c50530d2284688b93e15f0d410938
a1a494fe51fbe50414fddb56b1f79b2cd8599c094337a48902b12b050b9f5fe5
a345a1a319b0bc1b1f98f0f69fd222266e564d2b7d1e6a5662598c57acb8a196
a39eb5cd03af8c4498780948b10ea6dcf839047e6399eafd7dd1039f34e2c0dc
a6d993dd23482633da7fb6dca5b7a56a125f96e52ab88c812c4014adfb56198d
ac70d3d16dc99cf5bc639fb521b4ff51020a0f7ad7ffb7c88a410e76c3a23685
ad858b4c5532585947c28b7f04aea0b75e9e570d6f69296fc301e5a65bb91443
ae4260103d3f2d9dc4257fa9b3cf4e4265bfc80631ef4dcd7b8c107b9af596e8
af25363853daee0b7ecf2d4741d7d8f3f9530c35778ccf685270d5d6d4e8c436
b110e7496974c9e0824c21d1b741e48806532d3cc964870e6cea599edb5240e8
b184519b2dfd5885cd771de26c5fc200c97c56ddd1f903acce42b6900d8e1940
b2dfb327feecdd54fc3898e92726b4878df0d89970c86fe6b75b5f894b1426d2
b30c1637db2bd1d78a5fbdccaa31302a1724d7a722b4d35e6d66616021664ad0
b39413a4894df285c16e847ee0198391a0e76cd881ff7b840ea92cf0c1937d7a
b397c784611f6fda2da74b2900255cf2d7a51bbf63815d92da85bd5643aee2a1
b4f300cb312bd799ac8edafe32ae5de0870458a5065fc9efb4595ce7ffa6b33b
b89c83aabaa888b597180dbdf81b2cb231885bfae3a0e63868ddd8b658d7774b
be17186f57944dc5c37fb3858e8443265c917fb7c1f5bcb68be01c516e0c240c
beeec5397da5ad3fb40483b1965cdcc25c6077650c7b04954ab11de77ac7ae14
c725293ca8870132f18bb8fcb3b5e7c69a99f3e0694aebcbb2064dfdbcce2255
c889bf3bddc1f908b286b1bf7786e61119288e5b382e581c330930f0c8fee8fa
c9449ef99d9fbe5fd87b5d7ed853ee14edaaddd2318b3f070d746bf17f908dc1
ca2e6ce5432606942e7b648d0a2d219c0e8f4518e1b4d9a21bb2c5c25ae7316a
cbf2695cfc80d9cac2b73926ad71d04efba23dfceed684f4f52b16a3bf52b2ba
d63484cc4c20641b78685c62cf89a313f756218a9d409e594fe3f1224bbd6bf3
d89f62d140b929b059a738a435a8561f826487806f38bbd4c02dc6f06a50791a
d8bbe6376f20f430a7dfd2f59459ded3bbad83d6de4cc8b5727b15922af7c238
d9473d2266c4a242e75c179d42e40bd19180d40a0c03a95034f2ec578bfd0fd3
dcd6e29f9d9d4ebaba1b964214d042f6fbabbd506b91ffbe76d8445b82c7809b
ddf612deb58b592625d9defac49fed2da48c37a3ed207cdbd0d4e0a3b3b5b62d
df49dd8e1169d92ab80a797533c71df2e45caeb8a81842a8a2423479c5cedd0c
df698f34f5d99a323a2b887d2fb8b44e2e7c66b12b5d58b1a49d85a981611087
e11142b267b1cb71fa9bfeb1458a362fd7768b52d9661dc7b2e0f3cde36f27e4
e3325277eafbabffa1d13c24cdca91aeaa59bda5c06e19cebbf142851942ca51
e340224aae3f37cda95b983921d05f329a4f64257ef3141a2e7179345bceab8e
e42f55c0525588fae56ed72c1cbaba89404668bfe963b7de30415bab2864260e
e6dde4cb79db1db09af0c54228caec2c6c6f487572df5c8e386eb751481e68b8
e8d7ff3bb233802dd471dc351c2b2dc663ce5af89a393d32a4511fe815674205
eaae9d514272ef629fd145ae7c0cf5f7e6f904f323f39294b552a311ca44a6d3
ec040cdd71a393530fa3c4c353db1ef6d84fd7e2d6804390bcbf97e85d119e81
ecae15faa5b5b02a3cb4d4b7b4547cec3aa3b33c5ac105bfdd8cff74e52a1e4c
efe7b57f3345f59c846599accc0711848b9693713ae52878af0f5971df70bdef
f3d5e36273ce9dbfed35ea07d55f6792dd9b199bee47f6be664db8b282d8e498
f6585c949abe93fed46346efde34f7dd1a41d692d2e3e3786e133ca23ffc43d7
f92626a95f09ed9aa64eb96326f4c5978af875baf30247abad5ef07d36f55f1c
fa14d03923014a6223d05563a296d391285af3d96a3c2a44269eb567c079a238
fd1bece3d0ac5c466d9496c0a4f6060db6b1e80327923f81960382958c9cd290
ffd2d1189c7e672c74a63d9f55352943ae6a806f180c30fcf645bfed81f2d1b9
].freeze
FACTORY_HASHES = %w[
0401b21534de1540a94949f979a7c9018ce1b27b7d69a31f4457869af1114932
07d872c390a2311ad728a950622777cf61eb7742d49fabeefc178d563d7dc3f3
0c612da0e0331f0b7533dacea7d104a031e24395bd75b91132f8467fe2402584
0d2101d6cb556e2c5a6da3978cb630607ec03b5441f7bba151bcc1f7f876a138
0eb6d85c249dd2a2188f36f738b7f742be072e51af68a0e7e39149b11dbc3312
11aa15d9ea8989d1de4206155b7ae6c22afed2bd4d2327c9a63465954c6eb4b3
159f3dad478ee80258b2d1f55c905b19d0086a2622c53a62f4b1c0f0f1a73c66
16a0260612ae659a83155d31a82dd96ce222959927a4381bd8373fac375c8c04
16eae5b16a917dc92b8c19eeb5b2ccbdca8811dbd1b31d8382aa4f7c87dae0df
173e3e1e6d10ab6c5c0d21b55a73bc32585cd085d1913e8b7786f6531d09a58a
17b8a6f83bcab77279ecd53d13ba6e51949a67a5ce356fbe51cd5c40f9daf7d0
1ef6f45fcc2740e3360b23eefc4f2be2b2b546a72ad9ea87269e67ac81d77876
22578b6af7bb4b18dae801f88d47cc97b9299bf355c829bf82e9737fa92d3f01
225973fdf354c8968f07970eaaaeaaf871a1b2565837b574ca1fd4efdba0f426
23a6ad0e2ffc646eeef779808c3962baa4511598cce455265b1aeb6ab7aa2c04
27b2f7784c73ebcb28e980a750d73383666e41b08a752db1e201c94910c7c5c9
2880e0eb29a639225d1446c706013dee15d4db8cfa7f295469e93c9258fff4c5
2a22d3a73d44050417465bd3ac554642a097c359a96e7a113b7794d6328532cd
2f7859d57d7490aebee513847c6dff4d5d806505af468ca3cfa2859ee8859ced
3a5c1b2472eb8169f4322ecef638e611841a7cfec6f8557d0721687d9acb83f8
3e4153d27b91dbe784200d56b490e1f3549f1a10f0e9f8f1928e26770b52887a
40179d394711f875f5ced0c050d0dcbe7f065cf5e50780857ee31968275a6141
459ea426c666dda5cdefd09267e3d11e91492f3c75fd7c5914159013006211ac
46aa83d7361928607179051cccfe6a570f814ed2f471db432d7b1ce103f91ec6
48450947690d13cdc581910bfae0d783da6a74cf2ef20975c03ec69079924047
49149a0f21f2ebdd0622585eb2b1783411d6377cf5a83f47ec56f8dae20fc79a
4979473bc5d9d1c1f2ab666f3a966a043da5225365670780e7022a5bd9d81fa0
4e12e901a34753bdeaa8ad7aa8f1d68bbbe9057c658f6575f9a6fb0e091629e8
51cbec11c2bb4965f02b1f949fd091e4b66c3733ec7e55854a9b9833be870413
572cad04d27fd09718666d355acc24e8c26b819097c1b104c8b4f1f61715f1c4
5ccb39e7aa232b4ea139712b3c3345a6dc7ab95412ca162295daceaf1beea700
5d375eb0118c0694177cb7ff8b376211bdc5372f62927b71d0136eb60f12802f
638335f8bcdd5e3260b23717f6b8077cffb09a5ae1973698671d99f6baabd050
6e3be9ce8911951b40523b07aead369d55bd35db9a38352fec70cd2788385f99
6ff5e53d644c302ebb7853cda4a3a5fa1e2637b061804b510bf103a2fd65a5bf
734783496ba1c07e3ced81083f37d2acf27b99bde6f23bcd56210358f66d08b4
764cb778011a904c71a11c87655ed2c15c863b59edd738fa6f70eb7c6ca6e46a
77f9938dc398c810d849317a091a7198e1f8b561ebdbdf1c1c07da6916570b5d
787bc24fb1ce7a8332e02475b4b038b1b9094567ec164076cf8ab3b068983eee
7be29b16bcaaeae131ac4eeb96359d7a0e254901149427201f268926722f4540
7e88a5a2f0a9a55337241e880bc24157dd4a7bdd9d599e95b9aa6e32314b7fca
81b691082fdb2c5618605236e76e60b637a655c52156c4b23ce4421fb9abafab
83d132658016019789c7256b969eff122bbd2a4921c7b2d96694d962282c496d
83d7d82d09228b009e3d8a16ceecf32489b634f2e858cd6884f2bb1c6b2b1561
85d585c085d64ef56177ad8ee76eb7bda6b6216269f0a732b5b36615e448ec9d
8c638f388f85c45e4744d6e71922218f7c4eb9347785cd0cae4c7af8bc8e27c0
8ca412b978b19a9f3162aaf64d5b79c36eb75a855e74b3d2ffbf3efa7a2a53f1
8d2829192329a23c1986a183e51cca3ed5bc15c0d4d556e9b28c3769d69d7b25
8e620316445eb17a581a77ba3a0d9497254d9d82b625f2848171786d1d70677a
8e6ff20606b81e5483275c4026a9d0020486394b514248784757f07db762177f
8faefdbf25b439715895fc5e78e2c658a2c7176987e7b68f5902ce34c32ea59e
91c2eb5bc59a841d5520e8197ba3f5006d2d9e451e564c954e262bd3e97a2542
94e5bdebe9d67111d64bbc31b0dda8cde4bc5d682c9d91e580c42b7260c21b40
952c573e7a4ae631598dc5884eb17bb7fae8eb3dd3c45c40f6815a1d2e317f11
983e113d7bcbc83d5e062607d85306922fa9571afe305f3d975d1010f5724e9c
999335050bb4ed44fba72cc15097bebe254be4c090eab99a8e920c8bba6b04a6
9b408801c57c1f2b6f0a6ca4b0c41cfff2a6fb2c57f945f5e4e1f61173d72361
9e977a4b5d6da4aa6bccb8bbecba11750c2e34c5b3fedfaacb242398ddeeb2ea
9efe7902e5dab6bd75aec69c0364d931f673160198015242aef683ac2ca3ee8e
9f1aca04a43a1092b5039563a807a494cfe1f7f70ed0080658ed006fb2145ea5
a4c54fe367d23ab1caad25a665ccbf8102a74728d7070a66dccce21f1af09038
a52a896eba90d5583e5360d8ff6cbff1468e3156722a747c9ffb20c00622aaf2
ac46bf4b08dca4e7a41131d851da3977f7bdb5f30a7031467e3dc87a12e8b413
ad26b1d339748a8b63c8e18f304e8dd47e053d06f65083fd0b5daaf6bfbc1e09
af947ec70338ea85c316129b3ef2a60ea99ee34b635e020c189b27e9373d1bfd
afd42405048c53c4999f8001fa068e9eca8eef2559ee946f54dc982a222c344c
aff16e7af4d903ed79b4aeba7be27c2abe856f78c621bb7d3748bd944bc171d7
b179990bca81a8f6aa39d3065830c5c91463dc6a6505981d1b337c8639b9f63b
b70f08767c64a77c0251a9ad5a2e8655748c6416c4b0c199231a8778a5500238
b88837c147d9f520ce665ad3f5d7ba6ed0ed6aa326fad953bacabd55cc1173f6
bdb847dcfb1cb1caf201c67632aaa03d0fcdccb1f262c7ec2b110aa41cdfee43
bdfff1511c92276f05105789ea91e393dd4a80a9b80dd95faa7e4a8248f1e6db
bef0d5e10af0c8ebabc99e1891c6ba34c069a3f9ea619f9344de1c0496afe7ad
c08e6a2451eda7ffd38b9150d005a7c890a9a465a7105dace49097a4606fef5e
c1dec43479d1a77d6d070d2cbb0faf0647efec235d0fc0e6dad69429e47e3322
c22ed70202f36ddfd38fa9b094cf35609b5d6fc6bbb116ae35a663337a995357
c78c273ef5bd043d746929c741a77009e4fa4931af654ae0e73f96670fcc0e35
c78c9e8de70129157d2370295b263ab1caf3018d09295e5a96a3a7d04a490567
c96972c9696bc21a41e874270a28750083aabe0b93a6c6aba85eb817593fba70
cad2329bcfa45710b35997d99fe7ee541fa04d6fa2049c2a3eaa8bd7330a05d5
d2b7e7c39649189dc7e53aec73b90e507c69233316d51f3a17ca04e2da4933f7
d521573d43195f77f80cd0119bd7c3fd0995ab65638469d80f0e136b0750b0a8
d813381b6f576331cfb4b65fb956c1340b2ba729c8b09224b2890e843ed0db4d
d9a95b9de17395557203fce41387b4ba47d1604982b8bb41227b2c2ef638d97f
dbdf0054f6e008a4834baeaad7dd089268f41054984901308d737b862fea732c
dc849d434fd17d226dcaf05198c47e356b9e2a5861e7d7dbd8a98c7b8e5b3d0d
e2d930c1bca23bb0cd0daddebee28945f62d951bdf8d3036c439b1ddee71aeca
e3b704825525abec74e16771f996a54a54f1c9b26c1535d64d190fb6d5df5a58
ecf58c7d08536f788cc201534823b4ab7d8bd08ad0ae9130c33877255dbd8596
ee285343693a22d66f4bd56045a17169669e77dbea40b8ccf6853ccaef1ad332
f0569700476a920477f71932d49ece588379a68858421b0eca958c75f1f628f1
f14c2f9f1f2fdbe701a746917677e9d250fb898337953f7d3f0d5ebd00fe9262
f2e35c96433eb019875807cdb6a31708d10de8b4a18b23c7c908deacdeda1818
f697d342f1a83691bdf77b95e43fd68511478931555af1fa1214aa76a06030f4
f7ea2a7d7df19da487e9d44fa73a757324e2d0353c9def22ef453b171655de37
f8a648b6becdb238be1de6765240e644af1353ff5d1f9027dbfde27aa8dcd693
f97d90e0f16e275ccd5545e36ca364e3b9ff223086b9d54e88962296e6d4757d
fad495406dec530937cc617ab8c7e4eba332a9943225fdef9ee6e3b8de31b1f4
fc76826d8802941dad142013b3a44064f51ea6a9174c45deff87b18e42fa45df
fcb3375e88ef598adf4b6227fbde3a0dfcd7c1fbfd9703840e33caa7e8b479f0
fe5ac2b041242f2c38a13abe32a06c82a7ed98747c62b2e8cecb2d9a6cdeb625
].freeze
def write_empty_prog_info(zip_file, name)
zip_file.get_output_stream(name) do |f|
f.puts '<?xml version="1.0" encoding="UTF-8"?>'
f.puts
f.puts '<xd_ProgramInformation>'
f.puts ' <Programmer></Programmer>'
f.puts ' <Comment></Comment>'
f.puts '</xd_ProgramInformation>'
end
end
def write_preset_information(zip_file, id, name, n)
zip_file.get_output_stream('PresetInformation.xml') do |f|
f.puts '<?xml version="1.0" encoding="UTF-8"?>'
f.puts
f.puts '<xd_Preset>'
f.puts " <DataID>#{id}</DataID>"
f.puts " <Name>#{name}</Name>"
f.puts ' <Author>Various</Author>'
f.puts ' <Version>1</Version>'
f.puts " <NumOfProg>#{n}</NumOfProg>"
f.puts " <Date>#{Time.now.strftime('%Y/%m/%d')}</Date>"
f.puts ' <Prefix></Prefix>'
f.puts ' <Copyright></Copyright>'
f.puts '</xd_Preset>'
end
end
def write_file_information(zip_file, n)
zip_file.get_output_stream('FileInformation.xml') do |f|
f.puts '<?xml version="1.0" encoding="UTF-8"?>'
f.puts
f.puts '<KorgMSLibrarian_Data>'
f.puts ' <Product>minilogue xd</Product>'
f.puts " <Contents NumFavoriteData=\"0\" NumProgramData=\"#{n}\" NumPresetInformation=\"1\">"
f.puts ' <PresetInformation>'
f.puts ' <File>PresetInformation.xml</File>'
f.puts ' </PresetInformation>'
(0...n).each do |i|
f.puts ' <ProgramData>'
f.puts ' <Information>Prog_%03d.prog_info</Information>' % i
f.puts ' <ProgramBinary>Prog_%03d.prog_bin</ProgramBinary>' % i
f.puts ' </ProgramData>'
end
f.puts ' </Contents>'
f.puts '</KorgMSLibrarian_Data>'
end
end
class Catalogue
attr_reader :ignored
def initialize
@i = 0
@hashes = {}
@ignored = { init: 0, euro: 0, factory: 0, uk: 0, repeated: 0 }
end
def exists?(hash)
@hashes[hash] || false
end
def add!(hash)
@hashes[hash] = true
[format('Prog_%03d.prog_bin', @i), format('Prog_%03d.prog_info', @i)].tap do
@i += 1
end
end
def ignore!(type, _hash)
@ignored[type] += 1
end
def length
@i
end
end
def extract_presets(zip_file, input_filename, catalogue)
puts "Loading #{input_filename}..."
Zip::File.open(input_filename) do |f|
(0..199).each do |i|
bin_name = "Prog_%03d.prog_bin" % i
info_name = "Prog_%03d.prog_info" % i
entry = f.glob(bin_name)
if entry.count > 0
hash = Digest::SHA256.hexdigest(entry.first.get_input_stream.read)
case hash
when FACTORY_HASHES
catalogue.ignore! :factory, hash
when UK_HASHES
catalogue.ignore! :uk, hash
when EURO_HASHES
catalogue.ignore! :euro, hash
when INIT_HASH
catalogue.ignore! :init, hash
else
if catalogue.exists?(hash)
catalogue.ignore! :repeated, hash
else
bin_entry = f.glob(bin_name).first
info_entry = f.glob(info_name).first
out_bin_name, out_info_name = catalogue.add!(hash)
zip_file.get_output_stream(out_bin_name) do |s|
s.write(bin_entry.get_input_stream.read)
end
zip_file.get_output_stream(out_info_name) do |s|
s.write(info_entry.get_input_stream.read)
end
end
end
end
end
end
end
if ARGV.length < 2
STDERR.puts "miniloguesll display_name output_file input_file(s)"
STDERR.puts
STDERR.puts "Example: miniloguesll \"My strings collection\" strings.mnlgxdlib saw1.mnlgxdprog"
exit 1
end
display_name, zip_filename, *input_filenames = ARGV
File.unlink(zip_filename) if File.exist?(zip_filename)
catalogue = Catalogue.new
Zip.default_compression = Zlib::DEFAULT_COMPRESSION
Zip::File.open(zip_filename, Zip::File::CREATE) do |f|
input_filenames.each_with_index do |input_filename, i|
case input_filename
when /\.prog_bin$/
hash = Digest::SHA256.hexdigest(File.open(input_filename).read)
bin_name, info_name = catalogue.add!(hash)
f.add(bin_name, input_filename)
write_empty_prog_info(f, info_name)
when /\.mnlgxdprog$/, /\.mnlgxdlib$/
extract_presets(f, input_filename, catalogue)
else
STDERR.puts "Don't know what to do with #{input_filename}"
end
end
write_preset_information(f, display_name, display_name, catalogue.length)
write_file_information(f, catalogue.length)
end
STDERR.puts "Ignored #{catalogue.ignored[:init]} init preset(s)" unless catalogue.ignored[:init].zero?
STDERR.puts "Ignored #{catalogue.ignored[:factory]} factory preset(s)" unless catalogue.ignored[:factory].zero?
STDERR.puts "Ignored #{catalogue.ignored[:uk]} UK Producer preset(s)" unless catalogue.ignored[:uk].zero?
STDERR.puts "Ignored #{catalogue.ignored[:euro]} Euro Producer preset(s)" unless catalogue.ignored[:euro].zero?
STDERR.puts "Ignored #{catalogue.ignored[:repeated]} repeated preset(s)" unless catalogue.ignored[:repeated].zero?