@xpadev-net/niconicomments 0.2.22 → 0.2.24

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/bundle.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /*!
2
- niconicomments.js v0.2.22
2
+ niconicomments.js v0.2.24
3
3
  (c) 2021 xpadev-net https://xpadev.net
4
4
  Released under the MIT License.
5
5
  */
@@ -34,1439 +34,1516 @@
34
34
  return to.concat(ar || Array.prototype.slice.call(from));
35
35
  }
36
36
 
37
- var typeGuard = {
38
- formatted: {
39
- comment: function (i) {
40
- return typeVerify(i, [
41
- "id",
42
- "vpos",
43
- "content",
44
- "date",
45
- "date_usec",
46
- "owner",
47
- "premium",
48
- "mail",
49
- "user_id",
50
- "layer",
51
- ]);
52
- },
53
- comments: function (i) {
54
- if (typeof i !== "object")
55
- return false;
56
- for (var _i = 0, _a = i; _i < _a.length; _i++) {
57
- var item = _a[_i];
58
- if (!typeGuard.formatted.comment(item))
59
- return false;
60
- }
61
- return true;
62
- },
63
- legacyComment: function (i) {
64
- return typeVerify(i, [
65
- "id",
66
- "vpos",
67
- "content",
68
- "date",
69
- "owner",
70
- "premium",
71
- "mail",
72
- ]);
73
- },
74
- legacyComments: function (i) {
75
- if (typeof i !== "object")
76
- return false;
77
- for (var _i = 0, _a = i; _i < _a.length; _i++) {
78
- var item = _a[_i];
79
- if (!typeGuard.formatted.legacyComment(item))
80
- return false;
81
- }
82
- return true;
83
- },
84
- },
85
- legacy: {
86
- rawApiResponses: function (i) {
87
- if (typeof i !== "object")
88
- return false;
89
- for (var _i = 0, _a = i; _i < _a.length; _i++) {
90
- var itemWrapper = _a[_i];
91
- for (var _b = 0, _c = Object.keys(itemWrapper); _b < _c.length; _b++) {
92
- var key = _c[_b];
93
- var item = itemWrapper[key];
94
- if (!item)
95
- continue;
96
- if (!(typeGuard.legacy.apiChat(item) ||
97
- typeGuard.legacy.apiGlobalNumRes(item) ||
98
- typeGuard.legacy.apiLeaf(item) ||
99
- typeGuard.legacy.apiPing(item) ||
100
- typeGuard.legacy.apiThread(item))) {
101
- return false;
102
- }
103
- }
104
- }
105
- return true;
106
- },
107
- apiChat: function (i) {
108
- return typeof i === "object" &&
109
- typeVerify(i, [
110
- "content",
111
- "date",
112
- "date_usec",
113
- "no",
114
- "thread",
115
- "vpos",
116
- ]);
117
- },
118
- apiGlobalNumRes: function (i) {
119
- return typeVerify(i, ["num_res", "thread"]);
120
- },
121
- apiLeaf: function (i) { return typeVerify(i, ["count", "thread"]); },
122
- apiPing: function (i) { return typeVerify(i, ["content"]); },
123
- apiThread: function (i) {
124
- return typeVerify(i, [
125
- "resultcode",
126
- "revision",
127
- "server_time",
128
- "thread",
129
- "ticket",
130
- ]);
131
- },
132
- },
133
- niconicome: {
134
- xmlDocument: function (i) {
135
- if (!i.documentElement ||
136
- i.documentElement.nodeName !== "packet")
137
- return false;
138
- if (!i.documentElement.children)
139
- return false;
140
- for (var index = 0; index < i.documentElement.children.length; index++) {
141
- var value = i.documentElement.children[index];
142
- if (!value)
143
- continue;
144
- if (index === 0) {
145
- if (value.nodeName !== "thread" ||
146
- !typeAttributeVerify(value, [
147
- "resultcode",
148
- "thread",
149
- "server_time",
150
- "last_res",
151
- "revision",
152
- ]))
153
- return false;
154
- }
155
- else {
156
- if (value.nodeName !== "chat" ||
157
- !typeAttributeVerify(value, [
158
- "thread",
159
- "no",
160
- "vpos",
161
- "date",
162
- "date_usec",
163
- "anonymity",
164
- "user_id",
165
- "mail",
166
- "leaf",
167
- "premium",
168
- "score",
169
- ]))
170
- return false;
171
- }
172
- }
173
- return true;
174
- },
175
- },
176
- legacyOwner: {
177
- comments: function (i) {
178
- if (typeof i !== "string")
179
- return false;
180
- var lists = i.split("\n");
181
- for (var _i = 0, lists_1 = lists; _i < lists_1.length; _i++) {
182
- var list = lists_1[_i];
183
- if (list.split(":").length < 3) {
184
- return false;
185
- }
186
- }
187
- return true;
188
- },
189
- },
190
- owner: {
191
- comment: function (i) {
192
- return typeVerify(i, ["time", "command", "comment"]);
193
- },
194
- comments: function (i) {
195
- if (typeof i !== "object")
196
- return false;
197
- for (var _i = 0, _a = i; _i < _a.length; _i++) {
198
- var item = _a[_i];
199
- if (!typeGuard.owner.comment(item))
200
- return false;
201
- }
202
- return true;
203
- },
204
- },
205
- v1: {
206
- comment: function (i) {
207
- return typeVerify(i, [
208
- "id",
209
- "no",
210
- "vposMs",
211
- "body",
212
- "commands",
213
- "userId",
214
- "isPremium",
215
- "score",
216
- "postedAt",
217
- "nicoruCount",
218
- "nicoruId",
219
- "source",
220
- "isMyPost",
221
- ]);
222
- },
223
- thread: function (i) {
224
- if (!typeVerify(i, ["id", "fork", "commentCount", "comments"]))
225
- return false;
226
- for (var _i = 0, _a = Object.keys(i.comments); _i < _a.length; _i++) {
227
- var item = _a[_i];
228
- if (!typeGuard.v1.comment(i.comments[item]))
229
- return false;
230
- }
231
- return true;
232
- },
233
- threads: function (i) {
234
- if (typeof i !== "object")
235
- return false;
236
- for (var _i = 0, _a = i; _i < _a.length; _i++) {
237
- var item = _a[_i];
238
- if (!typeGuard.v1.thread(item))
239
- return false;
240
- }
241
- return true;
242
- },
243
- },
244
- nicoScript: {
245
- range: {
246
- target: function (i) {
247
- return typeof i === "string" && !!i.match(/^コメ|投コメ|全$/);
248
- },
249
- },
250
- replace: {
251
- range: function (i) {
252
- return typeof i === "string" && !!i.match(/^単|全$/);
253
- },
254
- target: function (i) {
255
- return typeof i === "string" && !!i.match(/^コメ|投コメ|全|含む|含まない$/);
256
- },
257
- condition: function (i) {
258
- return typeof i === "string" && !!i.match(/^部分一致|完全一致$/);
259
- },
260
- },
261
- },
262
- comment: {
263
- font: function (i) {
264
- return typeof i === "string" && !!i.match(/^gothic|mincho|defont$/);
265
- },
266
- loc: function (i) {
267
- return typeof i === "string" && !!i.match(/^ue|naka|shita$/);
268
- },
269
- size: function (i) {
270
- return typeof i === "string" && !!i.match(/^big|medium|small$/);
271
- },
272
- },
273
- };
274
- var typeVerify = function (item, keys) {
275
- if (typeof item !== "object" || !item)
276
- return false;
277
- for (var _i = 0, keys_1 = keys; _i < keys_1.length; _i++) {
278
- var key = keys_1[_i];
279
- if (!Object.prototype.hasOwnProperty.call(item, key))
280
- return false;
281
- }
282
- return true;
283
- };
284
- var typeAttributeVerify = function (item, keys) {
285
- if (typeof item !== "object" || !item)
286
- return false;
287
- for (var _i = 0, keys_2 = keys; _i < keys_2.length; _i++) {
288
- var key = keys_2[_i];
289
- if (item.getAttribute(key) === null)
290
- return false;
291
- }
292
- return true;
37
+ var typeGuard = {
38
+ formatted: {
39
+ comment: function (i) {
40
+ return typeVerify(i, [
41
+ "id",
42
+ "vpos",
43
+ "content",
44
+ "date",
45
+ "date_usec",
46
+ "owner",
47
+ "premium",
48
+ "mail",
49
+ "user_id",
50
+ "layer",
51
+ ]);
52
+ },
53
+ comments: function (i) {
54
+ if (typeof i !== "object")
55
+ return false;
56
+ for (var _i = 0, _a = i; _i < _a.length; _i++) {
57
+ var item = _a[_i];
58
+ if (!typeGuard.formatted.comment(item))
59
+ return false;
60
+ }
61
+ return true;
62
+ },
63
+ legacyComment: function (i) {
64
+ return typeVerify(i, [
65
+ "id",
66
+ "vpos",
67
+ "content",
68
+ "date",
69
+ "owner",
70
+ "premium",
71
+ "mail",
72
+ ]);
73
+ },
74
+ legacyComments: function (i) {
75
+ if (typeof i !== "object")
76
+ return false;
77
+ for (var _i = 0, _a = i; _i < _a.length; _i++) {
78
+ var item = _a[_i];
79
+ if (!typeGuard.formatted.legacyComment(item))
80
+ return false;
81
+ }
82
+ return true;
83
+ },
84
+ },
85
+ legacy: {
86
+ rawApiResponses: function (i) {
87
+ if (typeof i !== "object")
88
+ return false;
89
+ for (var _i = 0, _a = i; _i < _a.length; _i++) {
90
+ var itemWrapper = _a[_i];
91
+ for (var _b = 0, _c = Object.keys(itemWrapper); _b < _c.length; _b++) {
92
+ var key = _c[_b];
93
+ var item = itemWrapper[key];
94
+ if (!item)
95
+ continue;
96
+ if (!(typeGuard.legacy.apiChat(item) ||
97
+ typeGuard.legacy.apiGlobalNumRes(item) ||
98
+ typeGuard.legacy.apiLeaf(item) ||
99
+ typeGuard.legacy.apiPing(item) ||
100
+ typeGuard.legacy.apiThread(item))) {
101
+ return false;
102
+ }
103
+ }
104
+ }
105
+ return true;
106
+ },
107
+ apiChat: function (i) {
108
+ return typeof i === "object" &&
109
+ typeVerify(i, ["content", "date", "no", "thread", "vpos"]);
110
+ },
111
+ apiGlobalNumRes: function (i) {
112
+ return typeVerify(i, ["num_res", "thread"]);
113
+ },
114
+ apiLeaf: function (i) { return typeVerify(i, ["count", "thread"]); },
115
+ apiPing: function (i) { return typeVerify(i, ["content"]); },
116
+ apiThread: function (i) {
117
+ return typeVerify(i, [
118
+ "resultcode",
119
+ "revision",
120
+ "server_time",
121
+ "thread",
122
+ "ticket",
123
+ ]);
124
+ },
125
+ },
126
+ niconicome: {
127
+ xmlDocument: function (i) {
128
+ if (!i.documentElement ||
129
+ i.documentElement.nodeName !== "packet")
130
+ return false;
131
+ if (!i.documentElement.children)
132
+ return false;
133
+ for (var index = 0; index < i.documentElement.children.length; index++) {
134
+ var value = i.documentElement.children[index];
135
+ if (!value)
136
+ continue;
137
+ if (index === 0) {
138
+ if (value.nodeName !== "thread" ||
139
+ !typeAttributeVerify(value, [
140
+ "resultcode",
141
+ "thread",
142
+ "server_time",
143
+ "last_res",
144
+ "revision",
145
+ ]))
146
+ return false;
147
+ }
148
+ else {
149
+ if (value.nodeName !== "chat" ||
150
+ !typeAttributeVerify(value, [
151
+ "thread",
152
+ "no",
153
+ "vpos",
154
+ "date",
155
+ "date_usec",
156
+ "anonymity",
157
+ "user_id",
158
+ "mail",
159
+ "leaf",
160
+ "premium",
161
+ "score",
162
+ ]))
163
+ return false;
164
+ }
165
+ }
166
+ return true;
167
+ },
168
+ },
169
+ legacyOwner: {
170
+ comments: function (i) {
171
+ if (typeof i !== "string")
172
+ return false;
173
+ var lists = i.split("\n");
174
+ for (var _i = 0, lists_1 = lists; _i < lists_1.length; _i++) {
175
+ var list = lists_1[_i];
176
+ if (list.split(":").length < 3) {
177
+ return false;
178
+ }
179
+ }
180
+ return true;
181
+ },
182
+ },
183
+ owner: {
184
+ comment: function (i) {
185
+ return typeVerify(i, ["time", "command", "comment"]);
186
+ },
187
+ comments: function (i) {
188
+ if (typeof i !== "object")
189
+ return false;
190
+ for (var _i = 0, _a = i; _i < _a.length; _i++) {
191
+ var item = _a[_i];
192
+ if (!typeGuard.owner.comment(item))
193
+ return false;
194
+ }
195
+ return true;
196
+ },
197
+ },
198
+ v1: {
199
+ comment: function (i) {
200
+ return typeVerify(i, [
201
+ "id",
202
+ "no",
203
+ "vposMs",
204
+ "body",
205
+ "commands",
206
+ "userId",
207
+ "isPremium",
208
+ "score",
209
+ "postedAt",
210
+ "nicoruCount",
211
+ "nicoruId",
212
+ "source",
213
+ "isMyPost",
214
+ ]);
215
+ },
216
+ thread: function (i) {
217
+ if (!typeVerify(i, ["id", "fork", "commentCount", "comments"]))
218
+ return false;
219
+ for (var _i = 0, _a = Object.keys(i.comments); _i < _a.length; _i++) {
220
+ var item = _a[_i];
221
+ if (!typeGuard.v1.comment(i.comments[item]))
222
+ return false;
223
+ }
224
+ return true;
225
+ },
226
+ threads: function (i) {
227
+ if (typeof i !== "object")
228
+ return false;
229
+ for (var _i = 0, _a = i; _i < _a.length; _i++) {
230
+ var item = _a[_i];
231
+ if (!typeGuard.v1.thread(item))
232
+ return false;
233
+ }
234
+ return true;
235
+ },
236
+ },
237
+ nicoScript: {
238
+ range: {
239
+ target: function (i) {
240
+ return typeof i === "string" && !!i.match(/^(?:コメ|投コメ|全)$/);
241
+ },
242
+ },
243
+ replace: {
244
+ range: function (i) {
245
+ return typeof i === "string" && !!i.match(/^(?:単|全)$/);
246
+ },
247
+ target: function (i) {
248
+ return typeof i === "string" &&
249
+ !!i.match(/^(?:コメ|投コメ|全|含む|含まない)$/);
250
+ },
251
+ condition: function (i) {
252
+ return typeof i === "string" && !!i.match(/^(?:部分一致|完全一致)$/);
253
+ },
254
+ },
255
+ },
256
+ comment: {
257
+ font: function (i) {
258
+ return typeof i === "string" && !!i.match(/^(?:gothic|mincho|defont)$/);
259
+ },
260
+ loc: function (i) {
261
+ return typeof i === "string" && !!i.match(/^(?:ue|naka|shita)$/);
262
+ },
263
+ size: function (i) {
264
+ return typeof i === "string" && !!i.match(/^(?:big|medium|small)$/);
265
+ },
266
+ command: {
267
+ key: function (i) {
268
+ return typeof i === "string" && !!i.match(/^(?:full|ender|_live|invisible)$/);
269
+ },
270
+ },
271
+ },
272
+ };
273
+ var typeVerify = function (item, keys) {
274
+ if (typeof item !== "object" || !item)
275
+ return false;
276
+ for (var _i = 0, keys_1 = keys; _i < keys_1.length; _i++) {
277
+ var key = keys_1[_i];
278
+ if (!Object.prototype.hasOwnProperty.call(item, key))
279
+ return false;
280
+ }
281
+ return true;
282
+ };
283
+ var typeAttributeVerify = function (item, keys) {
284
+ if (typeof item !== "object" || !item)
285
+ return false;
286
+ for (var _i = 0, keys_2 = keys; _i < keys_2.length; _i++) {
287
+ var key = keys_2[_i];
288
+ if (item.getAttribute(key) === null)
289
+ return false;
290
+ }
291
+ return true;
292
+ };
293
+
294
+ var convert2formattedComment = function (data, type) {
295
+ var result = [];
296
+ if (type === "niconicome" && typeGuard.niconicome.xmlDocument(data)) {
297
+ result = fromNiconicome(data);
298
+ }
299
+ else if (type === "formatted" && typeGuard.formatted.legacyComments(data)) {
300
+ result = fromFormatted(data);
301
+ }
302
+ else if (type === "legacy" && typeGuard.legacy.rawApiResponses(data)) {
303
+ result = fromLegacy(data);
304
+ }
305
+ else if (type === "legacyOwner" && typeGuard.legacyOwner.comments(data)) {
306
+ result = fromLegacyOwner(data);
307
+ }
308
+ else if (type === "owner" && typeGuard.owner.comments(data)) {
309
+ result = fromOwner(data);
310
+ }
311
+ else if (type === "v1" && typeGuard.v1.threads(data)) {
312
+ result = fromV1(data);
313
+ }
314
+ else {
315
+ throw new Error("unknown input format");
316
+ }
317
+ return sort(result);
318
+ };
319
+ var fromNiconicome = function (data) {
320
+ var _a;
321
+ var data_ = [], userList = [];
322
+ for (var _i = 0, _b = Array.from(data.documentElement.children); _i < _b.length; _i++) {
323
+ var item = _b[_i];
324
+ if (item.nodeName !== "chat")
325
+ continue;
326
+ var tmpParam = {
327
+ id: Number(item.getAttribute("no")),
328
+ vpos: Number(item.getAttribute("vpos")),
329
+ content: item.innerHTML,
330
+ date: Number(item.getAttribute("date")),
331
+ date_usec: Number(item.getAttribute("date_usec")),
332
+ owner: !item.getAttribute("user_id"),
333
+ premium: item.getAttribute("premium") === "1",
334
+ mail: [],
335
+ user_id: -1,
336
+ layer: -1,
337
+ };
338
+ if (item.getAttribute("mail")) {
339
+ tmpParam.mail = ((_a = item.getAttribute("mail")) === null || _a === void 0 ? void 0 : _a.split(/\s+/g)) || [];
340
+ }
341
+ if (tmpParam.content.startsWith("/") && tmpParam.owner) {
342
+ tmpParam.mail.push("invisible");
343
+ }
344
+ var userId = item.getAttribute("user_id") || "";
345
+ var isUserExist = userList.indexOf(userId);
346
+ if (isUserExist === -1) {
347
+ tmpParam.user_id = userList.length;
348
+ userList.push(userId);
349
+ }
350
+ else {
351
+ tmpParam.user_id = isUserExist;
352
+ }
353
+ data_.push(tmpParam);
354
+ }
355
+ return data_;
356
+ };
357
+ var fromFormatted = function (data) {
358
+ var tmpData = data;
359
+ if (!typeGuard.formatted.comments(data)) {
360
+ for (var _i = 0, tmpData_1 = tmpData; _i < tmpData_1.length; _i++) {
361
+ var item = tmpData_1[_i];
362
+ item.layer = -1;
363
+ item.user_id = 0;
364
+ if (!item.date_usec)
365
+ item.date_usec = 0;
366
+ }
367
+ }
368
+ return tmpData;
369
+ };
370
+ var fromLegacy = function (data) {
371
+ var data_ = [], userList = [];
372
+ for (var i = 0; i < data.length; i++) {
373
+ var val = data[i];
374
+ if (!val || !typeGuard.legacy.apiChat(val === null || val === void 0 ? void 0 : val.chat))
375
+ continue;
376
+ var value = val.chat;
377
+ if (value.deleted !== 1) {
378
+ var tmpParam = {
379
+ id: value.no,
380
+ vpos: value.vpos,
381
+ content: value.content,
382
+ date: value.date,
383
+ date_usec: value.date_usec || 0,
384
+ owner: !value.user_id,
385
+ premium: value.premium === 1,
386
+ mail: [],
387
+ user_id: -1,
388
+ layer: -1,
389
+ };
390
+ if (value.mail) {
391
+ tmpParam.mail = value.mail.split(/\s+/g);
392
+ }
393
+ if (value.content.startsWith("/") && !value.user_id) {
394
+ tmpParam.mail.push("invisible");
395
+ }
396
+ var isUserExist = userList.indexOf(value.mail);
397
+ if (isUserExist === -1) {
398
+ tmpParam.user_id = userList.length;
399
+ userList.push(value.user_id);
400
+ }
401
+ else {
402
+ tmpParam.user_id = isUserExist;
403
+ }
404
+ data_.push(tmpParam);
405
+ }
406
+ }
407
+ return data_;
408
+ };
409
+ var fromLegacyOwner = function (data) {
410
+ var data_ = [], comments = data.split("\n");
411
+ for (var i = 0; i < comments.length; i++) {
412
+ var commentData = comments[i].split(":");
413
+ if (commentData.length < 3) {
414
+ continue;
415
+ }
416
+ else if (commentData.length > 3) {
417
+ for (var j = 3; j < commentData.length; j++) {
418
+ commentData[2] += ":" + commentData[j];
419
+ }
420
+ }
421
+ var tmpParam = {
422
+ id: i,
423
+ vpos: Number(commentData[0]),
424
+ content: commentData[2] || "",
425
+ date: i,
426
+ date_usec: 0,
427
+ owner: true,
428
+ premium: true,
429
+ mail: [],
430
+ user_id: -1,
431
+ layer: -1,
432
+ };
433
+ if (commentData[1]) {
434
+ tmpParam.mail = commentData[1].split(/[\s+]/g);
435
+ }
436
+ if (tmpParam.content.startsWith("/")) {
437
+ tmpParam.mail.push("invisible");
438
+ }
439
+ data_.push(tmpParam);
440
+ }
441
+ return data_;
442
+ };
443
+ var fromOwner = function (data) {
444
+ var data_ = [];
445
+ data.forEach(function (value, index) {
446
+ var tmpParam = {
447
+ id: index,
448
+ vpos: time2vpos(value.time),
449
+ content: value.comment,
450
+ date: index,
451
+ date_usec: 0,
452
+ owner: true,
453
+ premium: true,
454
+ mail: [],
455
+ user_id: -1,
456
+ layer: -1,
457
+ };
458
+ if (value.command) {
459
+ tmpParam.mail = value.command.split(/\s+/g);
460
+ }
461
+ if (tmpParam.content.startsWith("/")) {
462
+ tmpParam.mail.push("invisible");
463
+ }
464
+ data_.push(tmpParam);
465
+ });
466
+ return data_;
467
+ };
468
+ var fromV1 = function (data) {
469
+ var data_ = [], userList = [];
470
+ for (var _i = 0, data_1 = data; _i < data_1.length; _i++) {
471
+ var item = data_1[_i];
472
+ var val = item.comments, forkName = item.fork;
473
+ for (var _a = 0, _b = Object.keys(val); _a < _b.length; _a++) {
474
+ var key = _b[_a];
475
+ var value = val[key];
476
+ if (!value)
477
+ continue;
478
+ var tmpParam = {
479
+ id: value.no,
480
+ vpos: Math.floor(value.vposMs / 10),
481
+ content: value.body,
482
+ date: date2time(value.postedAt),
483
+ date_usec: 0,
484
+ owner: forkName === "owner",
485
+ premium: value.isPremium,
486
+ mail: value.commands,
487
+ user_id: -1,
488
+ layer: -1,
489
+ };
490
+ if (tmpParam.content.startsWith("/") && tmpParam.owner) {
491
+ tmpParam.mail.push("invisible");
492
+ }
493
+ var isUserExist = userList.indexOf(value.userId);
494
+ if (isUserExist === -1) {
495
+ tmpParam.user_id = userList.length;
496
+ userList.push(value.userId);
497
+ }
498
+ else {
499
+ tmpParam.user_id = isUserExist;
500
+ }
501
+ data_.push(tmpParam);
502
+ }
503
+ }
504
+ return data_;
505
+ };
506
+ var sort = function (data) {
507
+ data.sort(function (a, b) {
508
+ if (a.vpos < b.vpos)
509
+ return -1;
510
+ if (a.vpos > b.vpos)
511
+ return 1;
512
+ if (a.date < b.date)
513
+ return -1;
514
+ if (a.date > b.date)
515
+ return 1;
516
+ if (a.date_usec < b.date_usec)
517
+ return -1;
518
+ if (a.date_usec > b.date_usec)
519
+ return 1;
520
+ return 0;
521
+ });
522
+ return data;
523
+ };
524
+ var time2vpos = function (time_str) {
525
+ var time = time_str.match(/^(?:(\d+):(\d+)\.(\d+)|(\d+):(\d+)|(\d+)\.(\d+)|(\d+))$/);
526
+ if (time) {
527
+ if (time[1] !== undefined &&
528
+ time[2] !== undefined &&
529
+ time[3] !== undefined) {
530
+ return ((Number(time[1]) * 60 + Number(time[2])) * 100 +
531
+ Number(time[3]) / Math.pow(10, time[3].length - 2));
532
+ }
533
+ else if (time[4] !== undefined && time[5] !== undefined) {
534
+ return (Number(time[4]) * 60 + Number(time[5])) * 100;
535
+ }
536
+ else if (time[6] !== undefined && time[7] !== undefined) {
537
+ return (Number(time[6]) * 100 +
538
+ Number(time[7]) / Math.pow(10, time[7].length - 2));
539
+ }
540
+ else if (time[8] !== undefined) {
541
+ return Number(time[8]) * 100;
542
+ }
543
+ }
544
+ return 0;
545
+ };
546
+ var date2time = function (date) {
547
+ return Math.floor(new Date(date).getTime() / 1000);
293
548
  };
294
549
 
295
- var convert2formattedComment = function (data, type) {
296
- var result = [];
297
- if (type === "niconicome" && typeGuard.niconicome.xmlDocument(data)) {
298
- result = fromNiconicome(data);
299
- }
300
- else if (type === "formatted" && typeGuard.formatted.legacyComments(data)) {
301
- result = fromFormatted(data);
302
- }
303
- else if (type === "legacy" && typeGuard.legacy.rawApiResponses(data)) {
304
- result = fromLegacy(data);
305
- }
306
- else if (type === "owner" && typeGuard.owner.comments(data)) {
307
- result = fromOwner(data);
308
- }
309
- else if (type === "v1" && typeGuard.v1.threads(data)) {
310
- result = fromV1(data);
311
- }
312
- else {
313
- throw new Error("unknown input format");
314
- }
315
- return sort(result);
316
- };
317
- var fromNiconicome = function (data) {
318
- var _a;
319
- var data_ = [], userList = [];
320
- for (var _i = 0, _b = Array.from(data.documentElement.children); _i < _b.length; _i++) {
321
- var item = _b[_i];
322
- if (item.nodeName !== "chat")
323
- continue;
324
- var tmpParam = {
325
- id: Number(item.getAttribute("no")),
326
- vpos: Number(item.getAttribute("vpos")),
327
- content: item.innerHTML,
328
- date: Number(item.getAttribute("date")),
329
- date_usec: Number(item.getAttribute("date_usec")),
330
- owner: !item.getAttribute("user_id"),
331
- premium: item.getAttribute("premium") === "1",
332
- mail: [],
333
- user_id: -1,
334
- layer: -1,
335
- };
336
- if (item.getAttribute("mail")) {
337
- tmpParam.mail = ((_a = item.getAttribute("mail")) === null || _a === void 0 ? void 0 : _a.split(/\s+/g)) || [];
338
- }
339
- if (tmpParam.content.startsWith("/") && tmpParam.owner) {
340
- tmpParam.mail.push("invisible");
341
- }
342
- var userId = item.getAttribute("user_id") || "";
343
- var isUserExist = userList.indexOf(userId);
344
- if (isUserExist === -1) {
345
- tmpParam.user_id = userList.length;
346
- userList.push(userId);
347
- }
348
- else {
349
- tmpParam.user_id = isUserExist;
350
- }
351
- data_.push(tmpParam);
352
- }
353
- return data_;
354
- };
355
- var fromFormatted = function (data) {
356
- var tmpData = data;
357
- if (!typeGuard.formatted.comments(data)) {
358
- for (var _i = 0, tmpData_1 = tmpData; _i < tmpData_1.length; _i++) {
359
- var item = tmpData_1[_i];
360
- item.layer = -1;
361
- item.user_id = 0;
362
- if (!item.date_usec)
363
- item.date_usec = 0;
364
- }
365
- }
366
- return tmpData;
367
- };
368
- var fromLegacy = function (data) {
369
- var data_ = [], userList = [];
370
- for (var i = 0; i < data.length; i++) {
371
- var val = data[i];
372
- if (!val || !typeGuard.legacy.apiChat(val === null || val === void 0 ? void 0 : val.chat))
373
- continue;
374
- var value = val.chat;
375
- if (value.deleted !== 1) {
376
- var tmpParam = {
377
- id: value.no,
378
- vpos: value.vpos,
379
- content: value.content,
380
- date: value.date,
381
- date_usec: value.date_usec || 0,
382
- owner: !value.user_id,
383
- premium: value.premium === 1,
384
- mail: [],
385
- user_id: -1,
386
- layer: -1,
387
- };
388
- if (value.mail) {
389
- tmpParam.mail = value.mail.split(/\s+/g);
390
- }
391
- if (value.content.startsWith("/") && !value.user_id) {
392
- tmpParam.mail.push("invisible");
393
- }
394
- var isUserExist = userList.indexOf(value.mail);
395
- if (isUserExist === -1) {
396
- tmpParam.user_id = userList.length;
397
- userList.push(value.user_id);
398
- }
399
- else {
400
- tmpParam.user_id = isUserExist;
401
- }
402
- data_.push(tmpParam);
403
- }
404
- }
405
- return data_;
406
- };
407
- var fromOwner = function (data) {
408
- var data_ = [];
409
- data.forEach(function (value, index) {
410
- var tmpParam = {
411
- id: index,
412
- vpos: time2vpos(value.time),
413
- content: value.comment,
414
- date: index,
415
- date_usec: 0,
416
- owner: true,
417
- premium: true,
418
- mail: [],
419
- user_id: -1,
420
- layer: -1,
421
- };
422
- if (value.command) {
423
- tmpParam.mail = value.command.split(/\s+/g);
424
- }
425
- if (tmpParam.content.startsWith("/")) {
426
- tmpParam.mail.push("invisible");
427
- }
428
- data_.push(tmpParam);
429
- });
430
- return data_;
431
- };
432
- var fromV1 = function (data) {
433
- var data_ = [], userList = [];
434
- for (var _i = 0, data_1 = data; _i < data_1.length; _i++) {
435
- var item = data_1[_i];
436
- var val = item.comments, forkName = item.fork;
437
- for (var _a = 0, _b = Object.keys(val); _a < _b.length; _a++) {
438
- var key = _b[_a];
439
- var value = val[key];
440
- if (!value)
441
- continue;
442
- var tmpParam = {
443
- id: value.no,
444
- vpos: Math.floor(value.vposMs / 10),
445
- content: value.body,
446
- date: date2time(value.postedAt),
447
- date_usec: 0,
448
- owner: forkName === "owner",
449
- premium: value.isPremium,
450
- mail: value.commands,
451
- user_id: -1,
452
- layer: -1,
453
- };
454
- if (tmpParam.content.startsWith("/") && tmpParam.owner) {
455
- tmpParam.mail.push("invisible");
456
- }
457
- var isUserExist = userList.indexOf(value.userId);
458
- if (isUserExist === -1) {
459
- tmpParam.user_id = userList.length;
460
- userList.push(value.userId);
461
- }
462
- else {
463
- tmpParam.user_id = isUserExist;
464
- }
465
- data_.push(tmpParam);
466
- }
467
- }
468
- return data_;
469
- };
470
- var sort = function (data) {
471
- data.sort(function (a, b) {
472
- if (a.vpos < b.vpos)
473
- return -1;
474
- if (a.vpos > b.vpos)
475
- return 1;
476
- if (a.date < b.date)
477
- return -1;
478
- if (a.date > b.date)
479
- return 1;
480
- if (a.date_usec < b.date_usec)
481
- return -1;
482
- if (a.date_usec > b.date_usec)
483
- return 1;
484
- return 0;
485
- });
486
- return data;
487
- };
488
- var time2vpos = function (time_str) {
489
- var time = time_str.match(/^(\d+):(\d+)\.(\d+)|(\d+):(\d+)|(\d+)\.(\d+)|(\d+)$/);
490
- if (time) {
491
- if (time[1] !== undefined &&
492
- time[2] !== undefined &&
493
- time[3] !== undefined) {
494
- return ((Number(time[1]) * 60 + Number(time[2])) * 100 +
495
- Number(time[3]) / Math.pow(10, time[3].length - 2));
496
- }
497
- else if (time[4] !== undefined && time[5] !== undefined) {
498
- return (Number(time[4]) * 60 + Number(time[5])) * 100;
499
- }
500
- else if (time[6] !== undefined && time[7] !== undefined) {
501
- return (Number(time[6]) * 100 +
502
- Number(time[7]) / Math.pow(10, time[7].length - 2));
503
- }
504
- else if (time[8] !== undefined) {
505
- return Number(time[8]) * 100;
506
- }
507
- }
508
- return 0;
509
- };
510
- var date2time = function (date) {
511
- return Math.floor(new Date(date).getTime() / 1000);
550
+ var colors = {
551
+ white: "#FFFFFF",
552
+ red: "#FF0000",
553
+ pink: "#FF8080",
554
+ orange: "#FFC000",
555
+ yellow: "#FFFF00",
556
+ green: "#00FF00",
557
+ cyan: "#00FFFF",
558
+ blue: "#0000FF",
559
+ purple: "#C000FF",
560
+ black: "#000000",
561
+ white2: "#CCCC99",
562
+ niconicowhite: "#CCCC99",
563
+ red2: "#CC0033",
564
+ truered: "#CC0033",
565
+ pink2: "#FF33CC",
566
+ orange2: "#FF6600",
567
+ passionorange: "#FF6600",
568
+ yellow2: "#999900",
569
+ madyellow: "#999900",
570
+ green2: "#00CC66",
571
+ elementalgreen: "#00CC66",
572
+ cyan2: "#00CCCC",
573
+ blue2: "#3399FF",
574
+ marinblue: "#3399FF",
575
+ purple2: "#6633CC",
576
+ nobleviolet: "#6633CC",
577
+ black2: "#666666",
578
+ };
579
+ var commentYPaddingTop = 0.08;
580
+ var commentYMarginBottom = 0.24;
581
+ var fontSize = {
582
+ small: {
583
+ default: 47,
584
+ resized: 26.1,
585
+ },
586
+ medium: {
587
+ default: 74,
588
+ resized: 38.7,
589
+ },
590
+ big: {
591
+ default: 110,
592
+ resized: 61,
593
+ },
594
+ };
595
+ var lineHeight = {
596
+ small: {
597
+ default: 1,
598
+ resized: 1,
599
+ },
600
+ medium: {
601
+ default: 1,
602
+ resized: 1,
603
+ },
604
+ big: {
605
+ default: 1.03,
606
+ resized: 1.01,
607
+ },
512
608
  };
609
+ var doubleResizeMaxWidth = {
610
+ full: {
611
+ legacy: 3020,
612
+ default: 3550,
613
+ },
614
+ normal: {
615
+ legacy: 2540,
616
+ default: 2650,
617
+ },
618
+ };
619
+ var defaultOptions = {
620
+ drawAllImageOnLoad: false,
621
+ format: "default",
622
+ formatted: false,
623
+ debug: false,
624
+ enableLegacyPiP: false,
625
+ keepCA: false,
626
+ showCollision: false,
627
+ showCommentCount: false,
628
+ showFPS: false,
629
+ useLegacy: false,
630
+ video: undefined,
631
+ };
632
+ var fpsInterval = 500;
633
+ var cacheAge = 2000;
634
+ var canvasWidth = 1920;
635
+ var canvasHeight = 1080;
636
+ var commentDrawRange = 1450;
637
+ var commentDrawPadding = (canvasWidth - commentDrawRange) / 2;
638
+ var collisionWidth = 40;
639
+ var collisionRange = {
640
+ left: collisionWidth,
641
+ right: canvasWidth - collisionWidth,
642
+ };
643
+ var sameCARange = 3600;
644
+ var sameCAGap = 100;
645
+ var sameCAMinScore = 10;
513
646
 
514
- var colors = {
515
- white: "#FFFFFF",
516
- red: "#FF0000",
517
- pink: "#FF8080",
518
- orange: "#FFC000",
519
- yellow: "#FFFF00",
520
- green: "#00FF00",
521
- cyan: "#00FFFF",
522
- blue: "#0000FF",
523
- purple: "#C000FF",
524
- black: "#000000",
525
- white2: "#CCCC99",
526
- niconicowhite: "#CCCC99",
527
- red2: "#CC0033",
528
- truered: "#CC0033",
529
- pink2: "#FF33CC",
530
- orange2: "#FF6600",
531
- passionorange: "#FF6600",
532
- yellow2: "#999900",
533
- madyellow: "#999900",
534
- green2: "#00CC66",
535
- elementalgreen: "#00CC66",
536
- cyan2: "#00CCCC",
537
- blue2: "#3399FF",
538
- marinblue: "#3399FF",
539
- purple2: "#6633CC",
540
- nobleviolet: "#6633CC",
541
- black2: "#666666",
542
- };
543
- var commentYPaddingTop = 0.08;
544
- var commentYMarginBottom = 0.24;
545
- var fontSize = {
546
- small: {
547
- default: 47,
548
- resized: 26.1,
549
- },
550
- medium: {
551
- default: 74,
552
- resized: 38.7,
553
- },
554
- big: {
555
- default: 110,
556
- resized: 61,
557
- },
558
- };
559
- var lineHeight = {
560
- small: {
561
- default: 1,
562
- resized: 1,
563
- },
564
- medium: {
565
- default: 1,
566
- resized: 1,
567
- },
568
- big: {
569
- default: 1.03,
570
- resized: 1.01,
571
- },
572
- };
573
- var doubleResizeMaxWidth = {
574
- full: {
575
- legacy: 3020,
576
- default: 3550,
577
- },
578
- normal: {
579
- legacy: 2540,
580
- default: 2650,
581
- },
582
- };
583
- var defaultOptions = {
584
- drawAllImageOnLoad: false,
585
- format: "default",
586
- formatted: false,
587
- debug: false,
588
- enableLegacyPiP: false,
589
- keepCA: false,
590
- showCollision: false,
591
- showCommentCount: false,
592
- showFPS: false,
593
- useLegacy: false,
594
- video: undefined,
647
+ var groupBy = function (array) {
648
+ var data = ["defont", "gothic", "mincho"].reduce(function (pv, font) {
649
+ pv[font] = {};
650
+ return pv;
651
+ }, {});
652
+ array.forEach(function (item, index) {
653
+ var value = data[item.font][item.fontSize] || [];
654
+ value.push(_assign(_assign({}, item), { index: index }));
655
+ if (value.length === 1) {
656
+ data[item.font][item.fontSize] = value;
657
+ }
658
+ });
659
+ return data;
660
+ };
661
+ var getPosY = function (currentPos, targetComment, collision, data) {
662
+ var isChanged = false, isBreak = false;
663
+ if (!collision)
664
+ return { currentPos: currentPos, isChanged: isChanged, isBreak: isBreak };
665
+ for (var _i = 0, collision_1 = collision; _i < collision_1.length; _i++) {
666
+ var index = collision_1[_i];
667
+ var collisionItem = data[index];
668
+ if (!collisionItem)
669
+ continue;
670
+ if (currentPos < collisionItem.posY + collisionItem.height &&
671
+ currentPos + targetComment.height > collisionItem.posY &&
672
+ collisionItem.owner === targetComment.owner &&
673
+ collisionItem.layer === targetComment.layer) {
674
+ if (collisionItem.posY + collisionItem.height > currentPos) {
675
+ currentPos = collisionItem.posY + collisionItem.height;
676
+ isChanged = true;
677
+ }
678
+ if (currentPos + targetComment.height > canvasHeight) {
679
+ if (canvasHeight < targetComment.height) {
680
+ if (targetComment.mail.includes("naka")) {
681
+ currentPos = (targetComment.height - canvasHeight) / -2;
682
+ }
683
+ else {
684
+ currentPos = 0;
685
+ }
686
+ }
687
+ else {
688
+ currentPos = Math.floor(Math.random() * (canvasHeight - targetComment.height));
689
+ }
690
+ isBreak = true;
691
+ break;
692
+ }
693
+ }
694
+ }
695
+ return { currentPos: currentPos, isChanged: isChanged, isBreak: isBreak };
696
+ };
697
+ var getPosX = function (width, vpos, long) {
698
+ return (commentDrawRange -
699
+ ((((width + commentDrawRange) * ((vpos + 100) / 100)) / 4) * 300) / long +
700
+ commentDrawPadding);
701
+ };
702
+ var parseFont = function (font, size, useLegacy) {
703
+ switch (font) {
704
+ case "gothic":
705
+ return "normal 400 ".concat(size, "px \"\u6E38\u30B4\u30B7\u30C3\u30AF\u4F53\", \"\u6E38\u30B4\u30B7\u30C3\u30AF\", \"Yu Gothic\", YuGothic, yugothic, YuGo-Medium");
706
+ case "mincho":
707
+ return "normal 400 ".concat(size, "px \"\u6E38\u660E\u671D\u4F53\", \"\u6E38\u660E\u671D\", \"Yu Mincho\", YuMincho, yumincho, YuMin-Medium");
708
+ default:
709
+ if (useLegacy) {
710
+ return "normal 600 ".concat(size, "px Arial, \"\uFF2D\uFF33 \uFF30\u30B4\u30B7\u30C3\u30AF\", \"MS PGothic\", MSPGothic, MS-PGothic");
711
+ }
712
+ else {
713
+ return "normal 600 ".concat(size, "px sans-serif, Arial, \"\uFF2D\uFF33 \uFF30\u30B4\u30B7\u30C3\u30AF\", \"MS PGothic\", MSPGothic, MS-PGothic");
714
+ }
715
+ }
716
+ };
717
+ var arrayPush = function (array, key, push) {
718
+ var _a;
719
+ if (!array) {
720
+ array = {};
721
+ }
722
+ if (!array[Number(key)]) {
723
+ array[Number(key)] = [];
724
+ }
725
+ (_a = array[Number(key)]) === null || _a === void 0 ? void 0 : _a.push(push);
726
+ };
727
+ var hex2rgb = function (hex) {
728
+ if (hex.slice(0, 1) === "#")
729
+ hex = hex.slice(1);
730
+ if (hex.length === 3)
731
+ hex =
732
+ hex.slice(0, 1) +
733
+ hex.slice(0, 1) +
734
+ hex.slice(1, 2) +
735
+ hex.slice(1, 2) +
736
+ hex.slice(2, 3) +
737
+ hex.slice(2, 3);
738
+ return [hex.slice(0, 2), hex.slice(2, 4), hex.slice(4, 6)].map(function (str) {
739
+ return parseInt(str, 16);
740
+ });
741
+ };
742
+ var replaceAll = function (string, target, replace) {
743
+ while (string.indexOf(target) !== -1) {
744
+ string = string.replace(target, replace);
745
+ }
746
+ return string;
747
+ };
748
+ var changeCALayer = function (rawData) {
749
+ var userList = {};
750
+ var data = [], index = {};
751
+ for (var _i = 0, rawData_1 = rawData; _i < rawData_1.length; _i++) {
752
+ var value = rawData_1[_i];
753
+ if (value.user_id === undefined || value.user_id === -1)
754
+ continue;
755
+ if (userList[value.user_id] === undefined)
756
+ userList[value.user_id] = 0;
757
+ if (value.mail.indexOf("ca") > -1 ||
758
+ value.mail.indexOf("patissier") > -1 ||
759
+ value.mail.indexOf("ender") > -1 ||
760
+ value.mail.indexOf("full") > -1) {
761
+ userList[value.user_id] += 5;
762
+ }
763
+ if ((value.content.match(/\r\n|\n|\r/g) || []).length > 2) {
764
+ userList[value.user_id] +=
765
+ (value.content.match(/\r\n|\n|\r/g) || []).length / 2;
766
+ }
767
+ var key = "".concat(value.content, "@@").concat(Array.from(new Set(__spreadArray([], value.mail, true).sort()))
768
+ .filter(function (e) { return !e.match(/@[\d.]+|184|device:.+|patissier|ca/); })
769
+ .join("")), lastComment = index[key];
770
+ if (lastComment !== undefined) {
771
+ if (value.vpos - lastComment.vpos > sameCAGap ||
772
+ Math.abs(value.date - lastComment.date) < sameCARange) {
773
+ data.push(value);
774
+ index[key] = value;
775
+ }
776
+ }
777
+ else {
778
+ data.push(value);
779
+ index[key] = value;
780
+ }
781
+ }
782
+ for (var _a = 0, data_1 = data; _a < data_1.length; _a++) {
783
+ var value = data_1[_a];
784
+ if (userList[value.user_id] || 0 >= sameCAMinScore)
785
+ value.layer = value.user_id;
786
+ }
787
+ return data;
595
788
  };
596
789
 
597
- var isDebug = false;
598
- var NiconiComments = (function () {
599
- function NiconiComments(canvas, data, initOptions) {
600
- if (initOptions === void 0) { initOptions = {}; }
601
- var _this = this;
602
- var options = Object.assign(defaultOptions, initOptions);
603
- isDebug = options.debug;
604
- var constructorStart = performance.now();
605
- this.canvas = canvas;
606
- var context = canvas.getContext("2d");
607
- if (!context)
608
- throw new Error("Fail to get CanvasRenderingContext2D");
609
- this.context = context;
610
- this.context.strokeStyle = "rgba(0,0,0,0.7)";
611
- this.context.textAlign = "start";
612
- this.context.textBaseline = "alphabetic";
613
- this.context.lineWidth = 4;
614
- var formatType = options.format;
615
- if (options.formatted) {
616
- console.warn("Deprecated: options.formatted is no longer recommended. Please use options.format");
617
- }
618
- if (formatType === "default") {
619
- formatType = options.formatted ? "formatted" : "legacy";
620
- }
621
- var parsedData = convert2formattedComment(data, formatType);
622
- this.video = options.video || undefined;
623
- this.showCollision = options.showCollision;
624
- this.showFPS = options.showFPS;
625
- this.showCommentCount = options.showCommentCount;
626
- this.enableLegacyPiP = options.enableLegacyPiP;
627
- this.keepCA = options.keepCA;
628
- this.timeline = {};
629
- this.nicoScripts = { reverse: [], default: [], replace: [], ban: [] };
630
- this.collision = ["ue", "shita", "right", "left"].reduce(function (pv, value) {
631
- pv[value] = [];
632
- return pv;
633
- }, {});
634
- this.data = [];
635
- this.lastVpos = -1;
636
- this.useLegacy = options.useLegacy;
637
- this.preRendering(parsedData, options.drawAllImageOnLoad);
638
- this.fpsCount = 0;
639
- this.fps = 0;
640
- window.setInterval(function () {
641
- _this.fps = _this.fpsCount * 2;
642
- _this.fpsCount = 0;
643
- }, 500);
644
- logger("constructor complete: ".concat(performance.now() - constructorStart, "ms"));
645
- }
646
- NiconiComments.prototype.preRendering = function (rawData, drawAll) {
647
- var _this = this;
648
- var preRenderingStart = performance.now();
649
- if (this.keepCA) {
650
- rawData = changeCALayer(rawData);
651
- }
652
- var parsedData = this.getCommentPos(this.getCommentSize(this.getFont(rawData)));
653
- this.data = this.sortComment(parsedData);
654
- if (drawAll) {
655
- parsedData.forEach(function (_, key) { return _this.getTextImage(Number(key), true); });
656
- }
657
- logger("preRendering complete: ".concat(performance.now() - preRenderingStart, "ms"));
658
- };
659
- NiconiComments.prototype.getFont = function (parsedData) {
660
- var getFontStart = performance.now();
661
- var result = [];
662
- for (var _i = 0, parsedData_1 = parsedData; _i < parsedData_1.length; _i++) {
663
- var value = parsedData_1[_i];
664
- value.content = value.content.replace(/\t/g, "\u2003\u2003");
665
- result.push(this.parseCommandAndNicoscript(value));
666
- }
667
- logger("getFont complete: ".concat(performance.now() - getFontStart, "ms"));
668
- return result;
669
- };
670
- NiconiComments.prototype.getCommentSize = function (parsedData) {
671
- var getCommentSizeStart = performance.now();
672
- var groupedData = groupBy(parsedData);
673
- var result = [];
674
- for (var _i = 0, _a = Object.keys(groupedData); _i < _a.length; _i++) {
675
- var font = _a[_i];
676
- for (var _b = 0, _c = Object.keys(groupedData[font]); _b < _c.length; _b++) {
677
- var fontSize_1 = _c[_b];
678
- var value = groupedData[font][fontSize_1];
679
- if (!value)
680
- continue;
681
- this.context.font = parseFont(font, fontSize_1, this.useLegacy);
682
- for (var _d = 0, value_1 = value; _d < value_1.length; _d++) {
683
- var comment = value_1[_d];
684
- if (comment.invisible) {
685
- continue;
686
- }
687
- var measure = this.measureText(comment);
688
- var size = parsedData[comment.index];
689
- size.height = measure.height;
690
- size.width = measure.width;
691
- size.width_max = measure.width_max;
692
- size.width_min = measure.width_min;
693
- size.lineHeight = measure.lineHeight;
694
- if (measure.resized) {
695
- size.fontSize = measure.fontSize;
696
- this.context.font = parseFont(font, fontSize_1, this.useLegacy);
697
- }
698
- result[comment.index] = size;
699
- }
700
- }
701
- }
702
- logger("getCommentSize complete: ".concat(performance.now() - getCommentSizeStart, "ms"));
703
- return result;
704
- };
705
- NiconiComments.prototype.getCommentPos = function (data) {
706
- var _this = this;
707
- var getCommentPosStart = performance.now();
708
- data.forEach(function (comment, index) {
709
- if (comment.invisible)
710
- return;
711
- for (var j = 0; j < (comment.long * 4) / 3 + 100; j++) {
712
- if (!_this.timeline[comment.vpos + j]) {
713
- _this.timeline[comment.vpos + j] = [];
714
- }
715
- if (!_this.collision.right[comment.vpos + j]) {
716
- _this.collision.right[comment.vpos + j] = [];
717
- }
718
- if (!_this.collision.left[comment.vpos + j]) {
719
- _this.collision.left[comment.vpos + j] = [];
720
- }
721
- if (!_this.collision.ue[comment.vpos + j]) {
722
- _this.collision.ue[comment.vpos + j] = [];
723
- }
724
- if (!_this.collision.shita[comment.vpos + j]) {
725
- _this.collision.shita[comment.vpos + j] = [];
726
- }
727
- }
728
- if (comment.loc === "naka") {
729
- var posY = 0, isBreak = false, isChanged = true, count = 0;
730
- var beforeVpos = Math.round(-240 / ((1680 + comment.width_max) / (comment.long + 125))) - 100;
731
- if (1080 < comment.height) {
732
- posY = (comment.height - 1080) / -2;
733
- }
734
- else {
735
- while (isChanged && count < 10) {
736
- isChanged = false;
737
- count++;
738
- for (var j = beforeVpos; j < comment.long; j++) {
739
- var vpos = comment.vpos + j;
740
- var left_pos = 1680 - ((1680 + comment.width_max) / (comment.long + 125)) * j;
741
- if (left_pos + comment.width_max >= 1880) {
742
- var result = getPosY(posY, comment, _this.collision.right[vpos], data);
743
- posY = result.currentPos;
744
- isChanged = result.isChanged;
745
- isBreak = result.isBreak;
746
- if (isBreak)
747
- break;
748
- }
749
- if (left_pos <= 40) {
750
- var result = getPosY(posY, comment, _this.collision.left[vpos], data);
751
- posY = result.currentPos;
752
- isChanged = result.isChanged;
753
- isBreak = result.isBreak;
754
- if (isBreak)
755
- break;
756
- }
757
- }
758
- if (isBreak) {
759
- break;
760
- }
761
- }
762
- }
763
- for (var j = beforeVpos; j < comment.long + 125; j++) {
764
- var vpos = comment.vpos + j;
765
- var left_pos = 1680 - ((1680 + comment.width_max) / (comment.long + 125)) * j;
766
- arrayPush(_this.timeline, vpos, index);
767
- if (left_pos + comment.width_max >= 1880) {
768
- arrayPush(_this.collision.right, vpos, index);
769
- }
770
- if (left_pos <= 40) {
771
- arrayPush(_this.collision.left, vpos, index);
772
- }
773
- }
774
- comment.posY = posY;
775
- }
776
- else {
777
- var posY = 0, isChanged = true, count = 0, collision = void 0;
778
- if (comment.loc === "ue") {
779
- collision = _this.collision.ue;
780
- }
781
- else {
782
- collision = _this.collision.shita;
783
- }
784
- while (isChanged && count < 10) {
785
- isChanged = false;
786
- count++;
787
- for (var j = 0; j < comment.long; j++) {
788
- var result = getPosY(posY, comment, collision[comment.vpos + j], data);
789
- posY = result.currentPos;
790
- isChanged = result.isChanged;
791
- if (result.isBreak)
792
- break;
793
- }
794
- }
795
- for (var j = 0; j < comment.long; j++) {
796
- var vpos = comment.vpos + j;
797
- arrayPush(_this.timeline, vpos, index);
798
- if (j > comment.long - 20)
799
- continue;
800
- if (comment.loc === "ue") {
801
- arrayPush(_this.collision.ue, vpos, index);
802
- }
803
- else {
804
- arrayPush(_this.collision.shita, vpos, index);
805
- }
806
- }
807
- comment.posY = posY;
808
- }
809
- });
810
- logger("getCommentPos complete: ".concat(performance.now() - getCommentPosStart, "ms"));
811
- return data;
812
- };
813
- NiconiComments.prototype.sortComment = function (parsedData) {
814
- var _a;
815
- var sortCommentStart = performance.now();
816
- for (var _i = 0, _b = Object.keys(this.timeline); _i < _b.length; _i++) {
817
- var vpos = _b[_i];
818
- var item = this.timeline[Number(vpos)];
819
- if (!item)
820
- continue;
821
- var owner = [], user = [];
822
- for (var _c = 0, item_1 = item; _c < item_1.length; _c++) {
823
- var index = item_1[_c];
824
- if ((_a = parsedData[index]) === null || _a === void 0 ? void 0 : _a.owner) {
825
- owner.push(index);
826
- }
827
- else {
828
- user.push(index);
829
- }
830
- }
831
- this.timeline[Number(vpos)] = owner.concat(user);
832
- }
833
- logger("parseData complete: ".concat(performance.now() - sortCommentStart, "ms"));
834
- return parsedData;
835
- };
836
- NiconiComments.prototype.measureText = function (comment) {
837
- var width_arr = [], lines = comment.content.split("\n");
838
- if (!comment.lineHeight)
839
- comment.lineHeight = lineHeight[comment.size].default;
840
- if (!comment.resized && !comment.ender) {
841
- if (comment.size === "big" && lines.length > 2) {
842
- comment.fontSize = fontSize.big.resized;
843
- comment.lineHeight = lineHeight.big.resized;
844
- comment.resized = true;
845
- comment.resizedY = true;
846
- this.context.font = parseFont(comment.font, comment.fontSize, this.useLegacy);
847
- }
848
- else if (comment.size === "medium" && lines.length > 4) {
849
- comment.fontSize = fontSize.medium.resized;
850
- comment.lineHeight = lineHeight.medium.resized;
851
- comment.resized = true;
852
- comment.resizedY = true;
853
- this.context.font = parseFont(comment.font, comment.fontSize, this.useLegacy);
854
- }
855
- else if (comment.size === "small" && lines.length > 6) {
856
- comment.fontSize = fontSize.small.resized;
857
- comment.lineHeight = lineHeight.small.resized;
858
- comment.resized = true;
859
- comment.resizedY = true;
860
- this.context.font = parseFont(comment.font, comment.fontSize, this.useLegacy);
861
- }
862
- }
863
- for (var i = 0; i < lines.length; i++) {
864
- var measure = this.context.measureText(lines[i]);
865
- width_arr.push(measure.width);
866
- }
867
- var width = width_arr.reduce(function (p, c) { return p + c; }, 0) / width_arr.length, width_max = Math.max.apply(Math, width_arr), width_min = Math.min.apply(Math, width_arr), height = comment.fontSize *
868
- comment.lineHeight *
869
- (1 + commentYPaddingTop) *
870
- lines.length +
871
- commentYMarginBottom * comment.fontSize;
872
- if (comment.loc !== "naka" && !comment.resizedY) {
873
- if ((comment.full && width_max > 1930) ||
874
- (!comment.full && width_max > 1440)) {
875
- comment.fontSize -= 2;
876
- comment.resized = true;
877
- comment.resizedX = true;
878
- this.context.font = parseFont(comment.font, comment.fontSize, this.useLegacy);
879
- return this.measureText(comment);
880
- }
881
- }
882
- else if (comment.loc !== "naka" &&
883
- comment.resizedY &&
884
- ((comment.full && width_max > 2120) ||
885
- (!comment.full && width_max > 1440)) &&
886
- !comment.resizedX) {
887
- comment.fontSize = fontSize[comment.size].default;
888
- comment.lineHeight = lineHeight[comment.size].default * 1.05;
889
- comment.resized = true;
890
- comment.resizedX = true;
891
- this.context.font = parseFont(comment.font, comment.fontSize, this.useLegacy);
892
- return this.measureText(comment);
893
- }
894
- else if (comment.loc !== "naka" && comment.resizedY && comment.resizedX) {
895
- if (comment.full &&
896
- width_max >
897
- doubleResizeMaxWidth.full[this.useLegacy ? "legacy" : "default"]) {
898
- comment.fontSize -= 1;
899
- this.context.font = parseFont(comment.font, comment.fontSize, this.useLegacy);
900
- return this.measureText(comment);
901
- }
902
- else if (!comment.full &&
903
- width_max >
904
- doubleResizeMaxWidth.normal[this.useLegacy ? "legacy" : "default"]) {
905
- comment.fontSize -= 1;
906
- this.context.font = parseFont(comment.font, comment.fontSize, this.useLegacy);
907
- return this.measureText(comment);
908
- }
909
- }
910
- return {
911
- width: width,
912
- width_max: width_max,
913
- width_min: width_min,
914
- height: height,
915
- resized: !!comment.resized,
916
- fontSize: comment.fontSize,
917
- lineHeight: comment.lineHeight,
918
- };
919
- };
920
- NiconiComments.prototype.drawText = function (comment, vpos) {
921
- var _this = this;
922
- var reverse = false;
923
- for (var _i = 0, _a = this.nicoScripts.reverse; _i < _a.length; _i++) {
924
- var range = _a[_i];
925
- if ((range.target === "コメ" && comment.owner) ||
926
- (range.target === "投コメ" && !comment.owner))
927
- break;
928
- if (range.start < vpos && vpos < range.end) {
929
- reverse = true;
930
- }
931
- }
932
- for (var _b = 0, _c = this.nicoScripts.ban; _b < _c.length; _b++) {
933
- var range = _c[_b];
934
- if (range.start < vpos && vpos < range.end)
935
- return;
936
- }
937
- var posX = (1920 - comment.width_max) / 2, posY = comment.posY;
938
- if (comment.loc === "naka") {
939
- if (reverse) {
940
- posX =
941
- 240 +
942
- ((1680 + comment.width_max) / (comment.long + 125)) *
943
- (vpos - comment.vpos + 100) -
944
- comment.width_max;
945
- }
946
- else {
947
- posX =
948
- 1680 -
949
- ((1680 + comment.width_max) / (comment.long + 125)) *
950
- (vpos - comment.vpos + 100);
951
- }
952
- }
953
- else if (comment.loc === "shita") {
954
- posY = 1080 - comment.posY - comment.height;
955
- }
956
- if (comment.image && comment.image !== true) {
957
- this.context.drawImage(comment.image, posX, posY);
958
- }
959
- if (this.showCollision) {
960
- this.context.strokeStyle = "rgba(0,255,255,1)";
961
- this.context.strokeRect(posX, posY, comment.width_max, comment.height);
962
- var lines = comment.content.split("\n");
963
- lines.forEach(function (_, index) {
964
- var linePosY = (Number(index) + 1) *
965
- (comment.fontSize * comment.lineHeight) *
966
- (1 + commentYPaddingTop);
967
- _this.context.strokeStyle = "rgba(255,255,0,0.5)";
968
- _this.context.strokeRect(posX, posY + linePosY, comment.width_max, comment.fontSize * comment.lineHeight * -1);
969
- });
970
- }
971
- if (isDebug) {
972
- var font = this.context.font;
973
- var fillStyle = this.context.fillStyle;
974
- this.context.font = parseFont("defont", 30, false);
975
- this.context.fillStyle = "#ff00ff";
976
- this.context.fillText(comment.mail.join(","), posX, posY + 30);
977
- this.context.font = font;
978
- this.context.fillStyle = fillStyle;
979
- }
980
- };
981
- NiconiComments.prototype.getTextImage = function (i, preRendering) {
982
- if (preRendering === void 0) { preRendering = false; }
983
- var value = this.data[i];
984
- if (!value || value.invisible)
985
- return;
986
- var image = document.createElement("canvas");
987
- image.width = value.width_max;
988
- image.height = value.height;
989
- var context = image.getContext("2d");
990
- if (!context)
991
- throw new Error("Fail to get CanvasRenderingContext2D");
992
- context.strokeStyle = "rgba(0,0,0,0.7)";
993
- context.textAlign = "start";
994
- context.textBaseline = "alphabetic";
995
- context.lineWidth = 4;
996
- context.font = parseFont(value.font, value.fontSize, this.useLegacy);
997
- if (value._live) {
998
- var rgb = hex2rgb(value.color);
999
- context.fillStyle = "rgba(".concat(rgb[0], ",").concat(rgb[1], ",").concat(rgb[2], ",0.5)");
1000
- }
1001
- else {
1002
- context.fillStyle = value.color;
1003
- }
1004
- if (value.color === "#000000") {
1005
- context.strokeStyle = "rgba(255,255,255,0.7)";
1006
- }
1007
- var lines = value.content.split("\n");
1008
- lines.forEach(function (line, index) {
1009
- var posY = (Number(index) + 1) *
1010
- (value.fontSize * value.lineHeight) *
1011
- (1 + commentYPaddingTop);
1012
- context.strokeText(line, 0, posY);
1013
- context.fillText(line, 0, posY);
1014
- });
1015
- value.image = image;
1016
- if (preRendering)
1017
- return;
1018
- setTimeout(function () {
1019
- if (value.image)
1020
- delete value.image;
1021
- }, 5000);
1022
- };
1023
- NiconiComments.prototype.parseCommand = function (comment) {
1024
- var metadata = comment.mail;
1025
- var result = {
1026
- loc: undefined,
1027
- size: undefined,
1028
- fontSize: undefined,
1029
- color: undefined,
1030
- font: undefined,
1031
- full: false,
1032
- ender: false,
1033
- _live: false,
1034
- invisible: false,
1035
- long: undefined,
1036
- };
1037
- var isKey = function (i) {
1038
- return typeof i === "string" && !!i.match(/^full|ender|_live|invisible$/);
1039
- };
1040
- for (var _i = 0, metadata_1 = metadata; _i < metadata_1.length; _i++) {
1041
- var command = metadata_1[_i];
1042
- command = command.toLowerCase();
1043
- var match = command.match(/^@([0-9.]+)/);
1044
- if (match && match[1]) {
1045
- result.long = Number(match[1]);
1046
- }
1047
- else if (result.loc === undefined && typeGuard.comment.loc(command)) {
1048
- result.loc = command;
1049
- }
1050
- else if (result.size === undefined && typeGuard.comment.size(command)) {
1051
- result.size = command;
1052
- result.fontSize = fontSize[command].default;
1053
- }
1054
- else {
1055
- if (result.color === undefined) {
1056
- var color = colors[command];
1057
- if (color) {
1058
- result.color = color;
1059
- continue;
1060
- }
1061
- else {
1062
- var match_1 = command.match(/#[0-9a-z]{3,6}/);
1063
- if (match_1 && match_1[0] && comment.premium) {
1064
- result.color = match_1[0].toUpperCase();
1065
- continue;
1066
- }
1067
- }
1068
- }
1069
- if (result.font === undefined && typeGuard.comment.font(command)) {
1070
- result.font = command;
1071
- }
1072
- else if (isKey(command)) {
1073
- result[command] = true;
1074
- }
1075
- }
1076
- }
1077
- return result;
1078
- };
1079
- NiconiComments.prototype.parseCommandAndNicoscript = function (comment) {
1080
- var data = this.parseCommand(comment), string = comment.content, nicoscript = string.match(/^(?:@|@)(デフォルト|置換|逆|コメント禁止|シーク禁止|ジャンプ)/);
1081
- if (nicoscript) {
1082
- var reverse = comment.content.match(/^@逆 ?(全|コメ|投コメ)?/);
1083
- var content = comment.content.split(""), result = [];
1084
- var quote = "", last_i = "", string_1 = "";
1085
- switch (nicoscript[1]) {
1086
- case "デフォルト":
1087
- this.nicoScripts.default.unshift({
1088
- start: comment.vpos,
1089
- long: data.long === undefined ? undefined : Math.floor(data.long * 100),
1090
- color: data.color,
1091
- size: data.size,
1092
- font: data.font,
1093
- loc: data.loc,
1094
- });
1095
- break;
1096
- case "逆":
1097
- if (!reverse ||
1098
- !reverse[1] ||
1099
- !typeGuard.nicoScript.range.target(reverse[1]))
1100
- break;
1101
- if (data.long === undefined) {
1102
- data.long = 30;
1103
- }
1104
- this.nicoScripts.reverse.unshift({
1105
- start: comment.vpos,
1106
- end: comment.vpos + data.long * 100,
1107
- target: reverse[1],
1108
- });
1109
- break;
1110
- case "コメント禁止":
1111
- if (data.long === undefined) {
1112
- data.long = 30;
1113
- }
1114
- this.nicoScripts.ban.unshift({
1115
- start: comment.vpos,
1116
- end: comment.vpos + data.long * 100,
1117
- });
1118
- break;
1119
- case "置換":
1120
- for (var _i = 0, _a = content.slice(4); _i < _a.length; _i++) {
1121
- var i = _a[_i];
1122
- if (i.match(/["'「]/) && quote === "") {
1123
- quote = i;
1124
- }
1125
- else if (i.match(/["']/) && quote === i && last_i !== "\\") {
1126
- result.push(replaceAll(string_1, "\\n", "\n"));
1127
- quote = "";
1128
- string_1 = "";
1129
- }
1130
- else if (i.match(/」/) && quote === "") {
1131
- result.push(string_1);
1132
- quote = "";
1133
- string_1 = "";
1134
- }
1135
- else if (quote === "" && i.match(/\s+/)) {
1136
- if (string_1) {
1137
- result.push(string_1);
1138
- string_1 = "";
1139
- }
1140
- }
1141
- else {
1142
- string_1 += i;
1143
- }
1144
- last_i = i;
1145
- }
1146
- result.push(string_1);
1147
- if (result[0] === undefined ||
1148
- result[1] === undefined ||
1149
- (result[2] !== undefined &&
1150
- !typeGuard.nicoScript.replace.range(result[2])) ||
1151
- (result[3] !== undefined &&
1152
- !typeGuard.nicoScript.replace.target(result[3])) ||
1153
- (result[4] !== undefined &&
1154
- !typeGuard.nicoScript.replace.condition(result[4])))
1155
- break;
1156
- this.nicoScripts.replace.unshift({
1157
- start: comment.vpos,
1158
- long: data.long === undefined ? undefined : Math.floor(data.long * 100),
1159
- keyword: result[0],
1160
- replace: result[1] || "",
1161
- range: result[2] || "単",
1162
- target: result[3] || "コメ",
1163
- condition: result[4] || "部分一致",
1164
- color: data.color,
1165
- size: data.size,
1166
- font: data.font,
1167
- loc: data.loc,
1168
- no: comment.id,
1169
- });
1170
- this.nicoScripts.replace.sort(function (a, b) {
1171
- if (a.start < b.start)
1172
- return -1;
1173
- if (a.start > b.start)
1174
- return 1;
1175
- if (a.no < b.no)
1176
- return -1;
1177
- if (a.no > b.no)
1178
- return 1;
1179
- return 0;
1180
- });
1181
- break;
1182
- }
1183
- data.invisible = true;
1184
- }
1185
- var color = undefined, size = undefined, font = undefined, loc = undefined;
1186
- for (var i = 0; i < this.nicoScripts.default.length; i++) {
1187
- var item = this.nicoScripts.default[i];
1188
- if (!item)
1189
- continue;
1190
- if (item.long !== undefined && item.start + item.long < comment.vpos) {
1191
- this.nicoScripts.default = this.nicoScripts.default.splice(Number(i), 1);
1192
- continue;
1193
- }
1194
- if (item.loc) {
1195
- loc = item.loc;
1196
- }
1197
- if (item.color) {
1198
- color = item.color;
1199
- }
1200
- if (item.size) {
1201
- size = item.size;
1202
- }
1203
- if (item.font) {
1204
- font = item.font;
1205
- }
1206
- if (loc && color && size && font)
1207
- break;
1208
- }
1209
- for (var i = 0; i < this.nicoScripts.replace.length; i++) {
1210
- var item = this.nicoScripts.replace[i];
1211
- if (!item)
1212
- continue;
1213
- if (item.long !== undefined && item.start + item.long < comment.vpos) {
1214
- this.nicoScripts.default = this.nicoScripts.default.splice(Number(i), 1);
1215
- continue;
1216
- }
1217
- if ((item.target === "コメ" && comment.owner) ||
1218
- (item.target === "投コメ" && !comment.owner) ||
1219
- (item.target === "含まない" && comment.owner))
1220
- continue;
1221
- if ((item.condition === "完全一致" && comment.content === item.keyword) ||
1222
- (item.condition === "部分一致" &&
1223
- comment.content.indexOf(item.keyword) !== -1)) {
1224
- if (item.range === "単") {
1225
- comment.content = replaceAll(comment.content, item.keyword, item.replace);
1226
- }
1227
- else {
1228
- comment.content = item.replace;
1229
- }
1230
- if (item.loc) {
1231
- data.loc = item.loc;
1232
- }
1233
- if (item.color) {
1234
- data.color = item.color;
1235
- }
1236
- if (item.size) {
1237
- data.size = item.size;
1238
- }
1239
- if (item.font) {
1240
- data.font = item.font;
1241
- }
1242
- }
1243
- }
1244
- if (!data.loc) {
1245
- data.loc = loc || "naka";
1246
- }
1247
- if (!data.color) {
1248
- data.color = color || "#FFFFFF";
1249
- }
1250
- if (!data.size) {
1251
- data.size = size || "medium";
1252
- data.fontSize = fontSize[data.size].default;
1253
- }
1254
- if (!data.font) {
1255
- data.font = font || "defont";
1256
- }
1257
- if (!data.long) {
1258
- data.long = 300;
1259
- }
1260
- else {
1261
- data.long = Math.floor(Number(data.long) * 100);
1262
- }
1263
- return _assign(_assign({}, comment), data);
1264
- };
1265
- NiconiComments.prototype.drawCanvas = function (vpos) {
1266
- var drawCanvasStart = performance.now();
1267
- if (this.lastVpos === vpos)
1268
- return;
1269
- this.lastVpos = vpos;
1270
- this.fpsCount++;
1271
- this.context.clearRect(0, 0, this.canvas.width, this.canvas.height);
1272
- if (this.video) {
1273
- var scale = void 0;
1274
- var height = this.canvas.height / this.video.videoHeight, width = this.canvas.width / this.video.videoWidth;
1275
- if (this.enableLegacyPiP ? height > width : height < width) {
1276
- scale = width;
1277
- }
1278
- else {
1279
- scale = height;
1280
- }
1281
- var offsetX = (this.canvas.width - this.video.videoWidth * scale) * 0.5, offsetY = (this.canvas.height - this.video.videoHeight * scale) * 0.5;
1282
- this.context.drawImage(this.video, offsetX, offsetY, this.video.videoWidth * scale, this.video.videoHeight * scale);
1283
- }
1284
- var timelineRange = this.timeline[vpos];
1285
- if (timelineRange) {
1286
- for (var _i = 0, timelineRange_1 = timelineRange; _i < timelineRange_1.length; _i++) {
1287
- var index = timelineRange_1[_i];
1288
- var comment = this.data[index];
1289
- if (!comment || comment.invisible) {
1290
- continue;
1291
- }
1292
- if (comment.image === undefined) {
1293
- this.getTextImage(index);
1294
- }
1295
- try {
1296
- this.drawText(comment, vpos);
1297
- }
1298
- catch (e) {
1299
- comment.image = false;
1300
- }
1301
- }
1302
- }
1303
- if (this.showFPS) {
1304
- this.context.font = parseFont("defont", 60, this.useLegacy);
1305
- this.context.fillStyle = "#00FF00";
1306
- this.context.strokeStyle = "rgba(0,0,0,0.7)";
1307
- this.context.strokeText("FPS:".concat(this.fps), 100, 100);
1308
- this.context.fillText("FPS:".concat(this.fps), 100, 100);
1309
- }
1310
- if (this.showCommentCount) {
1311
- this.context.font = parseFont("defont", 60, this.useLegacy);
1312
- this.context.fillStyle = "#00FF00";
1313
- this.context.strokeStyle = "rgba(0,0,0,0.7)";
1314
- if (timelineRange) {
1315
- this.context.strokeText("Count:".concat(timelineRange.length), 100, 200);
1316
- this.context.fillText("Count:".concat(timelineRange.length), 100, 200);
1317
- }
1318
- else {
1319
- this.context.strokeText("Count:0", 100, 200);
1320
- this.context.fillText("Count:0", 100, 200);
1321
- }
1322
- }
1323
- logger("drawCanvas complete: ".concat(performance.now() - drawCanvasStart, "ms"));
1324
- };
1325
- NiconiComments.prototype.clear = function () {
1326
- this.context.clearRect(0, 0, 1920, 1080);
1327
- };
1328
- return NiconiComments;
1329
- }());
1330
- var groupBy = function (array) {
1331
- var data = ["defont", "gothic", "mincho"].reduce(function (pv, font) {
1332
- pv[font] = {};
1333
- return pv;
1334
- }, {});
1335
- array.forEach(function (item, index) {
1336
- var value = data[item.font][item.fontSize] || [];
1337
- value.push(_assign(_assign({}, item), { index: index }));
1338
- if (value.length === 1) {
1339
- data[item.font][item.fontSize] = value;
1340
- }
1341
- });
1342
- return data;
1343
- };
1344
- var getPosY = function (currentPos, targetComment, collision, data) {
1345
- var isChanged = false, isBreak = false;
1346
- if (!collision)
1347
- return { currentPos: currentPos, isChanged: isChanged, isBreak: isBreak };
1348
- for (var _i = 0, collision_1 = collision; _i < collision_1.length; _i++) {
1349
- var index = collision_1[_i];
1350
- var collisionItem = data[index];
1351
- if (!collisionItem)
1352
- continue;
1353
- if (currentPos < collisionItem.posY + collisionItem.height &&
1354
- currentPos + targetComment.height > collisionItem.posY &&
1355
- collisionItem.owner === targetComment.owner &&
1356
- collisionItem.layer === targetComment.layer) {
1357
- if (collisionItem.posY + collisionItem.height > currentPos) {
1358
- currentPos = collisionItem.posY + collisionItem.height;
1359
- isChanged = true;
1360
- }
1361
- if (currentPos + targetComment.height > 1080) {
1362
- if (1080 < targetComment.height) {
1363
- if (targetComment.mail.includes("naka")) {
1364
- currentPos = (targetComment.height - 1080) / -2;
1365
- }
1366
- else {
1367
- currentPos = 0;
1368
- }
1369
- }
1370
- else {
1371
- currentPos = Math.floor(Math.random() * (1080 - targetComment.height));
1372
- }
1373
- isBreak = true;
1374
- break;
1375
- }
1376
- }
1377
- }
1378
- return { currentPos: currentPos, isChanged: isChanged, isBreak: isBreak };
1379
- };
1380
- var parseFont = function (font, size, useLegacy) {
1381
- switch (font) {
1382
- case "gothic":
1383
- return "normal 400 ".concat(size, "px \"\u6E38\u30B4\u30B7\u30C3\u30AF\u4F53\", \"\u6E38\u30B4\u30B7\u30C3\u30AF\", \"Yu Gothic\", YuGothic, yugothic, YuGo-Medium");
1384
- case "mincho":
1385
- return "normal 400 ".concat(size, "px \"\u6E38\u660E\u671D\u4F53\", \"\u6E38\u660E\u671D\", \"Yu Mincho\", YuMincho, yumincho, YuMin-Medium");
1386
- default:
1387
- if (useLegacy) {
1388
- return "normal 600 ".concat(size, "px Arial, \"\uFF2D\uFF33 \uFF30\u30B4\u30B7\u30C3\u30AF\", \"MS PGothic\", MSPGothic, MS-PGothic");
1389
- }
1390
- else {
1391
- return "normal 600 ".concat(size, "px sans-serif, Arial, \"\uFF2D\uFF33 \uFF30\u30B4\u30B7\u30C3\u30AF\", \"MS PGothic\", MSPGothic, MS-PGothic");
1392
- }
1393
- }
1394
- };
1395
- var arrayPush = function (array, key, push) {
1396
- var _a;
1397
- if (!array) {
1398
- array = {};
1399
- }
1400
- if (!array[Number(key)]) {
1401
- array[Number(key)] = [];
1402
- }
1403
- (_a = array[Number(key)]) === null || _a === void 0 ? void 0 : _a.push(push);
1404
- };
1405
- var hex2rgb = function (hex) {
1406
- if (hex.slice(0, 1) === "#")
1407
- hex = hex.slice(1);
1408
- if (hex.length === 3)
1409
- hex =
1410
- hex.slice(0, 1) +
1411
- hex.slice(0, 1) +
1412
- hex.slice(1, 2) +
1413
- hex.slice(1, 2) +
1414
- hex.slice(2, 3) +
1415
- hex.slice(2, 3);
1416
- return [hex.slice(0, 2), hex.slice(2, 4), hex.slice(4, 6)].map(function (str) {
1417
- return parseInt(str, 16);
1418
- });
1419
- };
1420
- var replaceAll = function (string, target, replace) {
1421
- while (string.indexOf(target) !== -1) {
1422
- string = string.replace(target, replace);
1423
- }
1424
- return string;
1425
- };
1426
- var logger = function (msg) {
1427
- if (isDebug)
1428
- console.debug(msg);
1429
- };
1430
- var changeCALayer = function (rawData) {
1431
- var userList = {};
1432
- var data = [], index = {};
1433
- for (var _i = 0, rawData_1 = rawData; _i < rawData_1.length; _i++) {
1434
- var value = rawData_1[_i];
1435
- if (value.user_id === undefined || value.user_id === -1)
1436
- continue;
1437
- if (userList[value.user_id] === undefined)
1438
- userList[value.user_id] = 0;
1439
- if (value.mail.indexOf("ca") > -1 ||
1440
- value.mail.indexOf("patissier") > -1 ||
1441
- value.mail.indexOf("ender") > -1 ||
1442
- value.mail.indexOf("full") > -1) {
1443
- userList[value.user_id] += 5;
1444
- }
1445
- if ((value.content.match(/\r\n|\n|\r/g) || []).length > 2) {
1446
- userList[value.user_id] +=
1447
- (value.content.match(/\r\n|\n|\r/g) || []).length / 2;
1448
- }
1449
- var key = "".concat(value.content, "@@").concat(Array.from(new Set(__spreadArray([], value.mail, true).sort()))
1450
- .filter(function (e) { return !e.match(/@[\d.]+|184|device:.+|patissier|ca/); })
1451
- .join("")), lastComment = index[key];
1452
- if (lastComment !== undefined) {
1453
- if (value.vpos - lastComment.vpos > 100 ||
1454
- Math.abs(value.date - lastComment.date) < 3600) {
1455
- data.push(value);
1456
- index[key] = value;
1457
- }
1458
- }
1459
- else {
1460
- data.push(value);
1461
- index[key] = value;
1462
- }
1463
- }
1464
- for (var _a = 0, data_1 = data; _a < data_1.length; _a++) {
1465
- var value = data_1[_a];
1466
- if (userList[value.user_id] || 0 >= 10)
1467
- value.layer = value.user_id;
1468
- }
1469
- return data;
790
+ var isDebug = false;
791
+ var NiconiComments = (function () {
792
+ function NiconiComments(canvas, data, initOptions) {
793
+ if (initOptions === void 0) { initOptions = {}; }
794
+ var _this = this;
795
+ var options = Object.assign(defaultOptions, initOptions);
796
+ isDebug = options.debug;
797
+ var constructorStart = performance.now();
798
+ this.canvas = canvas;
799
+ var context = canvas.getContext("2d");
800
+ if (!context)
801
+ throw new Error("Fail to get CanvasRenderingContext2D");
802
+ this.context = context;
803
+ this.context.strokeStyle = "rgba(0,0,0,0.7)";
804
+ this.context.textAlign = "start";
805
+ this.context.textBaseline = "alphabetic";
806
+ this.context.lineWidth = 4;
807
+ var formatType = options.format;
808
+ if (options.formatted) {
809
+ console.warn("Deprecated: options.formatted is no longer recommended. Please use options.format");
810
+ }
811
+ if (formatType === "default") {
812
+ formatType = options.formatted ? "formatted" : "legacy";
813
+ }
814
+ var parsedData = convert2formattedComment(data, formatType);
815
+ this.video = options.video || undefined;
816
+ this.showCollision = options.showCollision;
817
+ this.showFPS = options.showFPS;
818
+ this.showCommentCount = options.showCommentCount;
819
+ this.enableLegacyPiP = options.enableLegacyPiP;
820
+ this.keepCA = options.keepCA;
821
+ this.cacheIndex = {};
822
+ this.timeline = {};
823
+ this.nicoScripts = { reverse: [], default: [], replace: [], ban: [] };
824
+ this.collision = ["ue", "shita", "right", "left"].reduce(function (pv, value) {
825
+ pv[value] = [];
826
+ return pv;
827
+ }, {});
828
+ this.data = [];
829
+ this.lastVpos = -1;
830
+ this.useLegacy = options.useLegacy;
831
+ this.preRendering(parsedData, options.drawAllImageOnLoad);
832
+ this.fpsCount = 0;
833
+ this.fps = 0;
834
+ window.setInterval(function () {
835
+ _this.fps = _this.fpsCount * (1000 / fpsInterval);
836
+ _this.fpsCount = 0;
837
+ }, fpsInterval);
838
+ logger("constructor complete: ".concat(performance.now() - constructorStart, "ms"));
839
+ }
840
+ NiconiComments.prototype.preRendering = function (rawData, drawAll) {
841
+ var _this = this;
842
+ var preRenderingStart = performance.now();
843
+ if (this.keepCA) {
844
+ rawData = changeCALayer(rawData);
845
+ }
846
+ var parsedData = this.getCommentPos(this.getCommentSize(this.getFont(rawData)));
847
+ this.data = this.sortComment(parsedData);
848
+ if (drawAll) {
849
+ parsedData.forEach(function (_, key) { return _this.getTextImage(Number(key), true); });
850
+ }
851
+ logger("preRendering complete: ".concat(performance.now() - preRenderingStart, "ms"));
852
+ };
853
+ NiconiComments.prototype.getFont = function (parsedData) {
854
+ var getFontStart = performance.now();
855
+ var result = [];
856
+ for (var _i = 0, parsedData_1 = parsedData; _i < parsedData_1.length; _i++) {
857
+ var value = parsedData_1[_i];
858
+ value.content = value.content.replace(/\t/g, "\u2003\u2003");
859
+ result.push(this.parseCommandAndNicoscript(value));
860
+ }
861
+ logger("getFont complete: ".concat(performance.now() - getFontStart, "ms"));
862
+ return result;
863
+ };
864
+ NiconiComments.prototype.getCommentSize = function (parsedData) {
865
+ var getCommentSizeStart = performance.now();
866
+ var groupedData = groupBy(parsedData);
867
+ var result = [];
868
+ for (var _i = 0, _a = Object.keys(groupedData); _i < _a.length; _i++) {
869
+ var font = _a[_i];
870
+ for (var _b = 0, _c = Object.keys(groupedData[font]); _b < _c.length; _b++) {
871
+ var fontSize_1 = _c[_b];
872
+ var value = groupedData[font][fontSize_1];
873
+ if (!value)
874
+ continue;
875
+ this.context.font = parseFont(font, fontSize_1, this.useLegacy);
876
+ for (var _d = 0, value_1 = value; _d < value_1.length; _d++) {
877
+ var comment = value_1[_d];
878
+ if (comment.invisible) {
879
+ continue;
880
+ }
881
+ var measure = this.measureText(comment);
882
+ var size = parsedData[comment.index];
883
+ size.height = measure.height;
884
+ size.width = measure.width;
885
+ size.width_max = measure.width_max;
886
+ size.width_min = measure.width_min;
887
+ size.lineHeight = measure.lineHeight;
888
+ if (measure.resized) {
889
+ size.fontSize = measure.fontSize;
890
+ this.context.font = parseFont(font, fontSize_1, this.useLegacy);
891
+ }
892
+ result[comment.index] = size;
893
+ }
894
+ }
895
+ }
896
+ logger("getCommentSize complete: ".concat(performance.now() - getCommentSizeStart, "ms"));
897
+ return result;
898
+ };
899
+ NiconiComments.prototype.getCommentPos = function (data) {
900
+ var _this = this;
901
+ var getCommentPosStart = performance.now();
902
+ data.forEach(function (comment, index) {
903
+ if (comment.invisible)
904
+ return;
905
+ if (comment.loc === "naka") {
906
+ var posY = 0;
907
+ var beforeVpos = Math.round(-288 / ((1632 + comment.width_max) / (comment.long + 125))) - 100;
908
+ if (canvasHeight < comment.height) {
909
+ posY = (comment.height - canvasHeight) / -2;
910
+ }
911
+ else {
912
+ var isBreak = false, isChanged = true, count = 0;
913
+ while (isChanged && count < 10) {
914
+ isChanged = false;
915
+ count++;
916
+ for (var j = beforeVpos; j < comment.long + 125; j++) {
917
+ var vpos = comment.vpos + j;
918
+ var left_pos = getPosX(comment.width_max, j, comment.long);
919
+ if (left_pos + comment.width_max >= collisionRange.right &&
920
+ left_pos <= collisionRange.right) {
921
+ var result = getPosY(posY, comment, _this.collision.right[vpos], data);
922
+ posY = result.currentPos;
923
+ isChanged = result.isChanged;
924
+ isBreak = result.isBreak;
925
+ if (isBreak)
926
+ break;
927
+ }
928
+ if (left_pos + comment.width_max >= collisionRange.left &&
929
+ left_pos <= collisionRange.left) {
930
+ var result = getPosY(posY, comment, _this.collision.left[vpos], data);
931
+ posY = result.currentPos;
932
+ isChanged = result.isChanged;
933
+ isBreak = result.isBreak;
934
+ if (isBreak)
935
+ break;
936
+ }
937
+ }
938
+ if (isBreak) {
939
+ break;
940
+ }
941
+ }
942
+ }
943
+ for (var j = beforeVpos; j < comment.long + 125; j++) {
944
+ var vpos = comment.vpos + j;
945
+ var left_pos = getPosX(comment.width_max, j, comment.long);
946
+ arrayPush(_this.timeline, vpos, index);
947
+ if (left_pos + comment.width_max >= collisionRange.right) {
948
+ arrayPush(_this.collision.right, vpos, index);
949
+ }
950
+ if (left_pos <= collisionRange.left) {
951
+ arrayPush(_this.collision.left, vpos, index);
952
+ }
953
+ }
954
+ comment.posY = posY;
955
+ }
956
+ else {
957
+ var posY = 0, isChanged = true, count = 0, collision = void 0;
958
+ if (comment.loc === "ue") {
959
+ collision = _this.collision.ue;
960
+ }
961
+ else {
962
+ collision = _this.collision.shita;
963
+ }
964
+ while (isChanged && count < 10) {
965
+ isChanged = false;
966
+ count++;
967
+ for (var j = 0; j < comment.long; j++) {
968
+ var result = getPosY(posY, comment, collision[comment.vpos + j], data);
969
+ posY = result.currentPos;
970
+ isChanged = result.isChanged;
971
+ if (result.isBreak)
972
+ break;
973
+ }
974
+ }
975
+ for (var j = 0; j < comment.long; j++) {
976
+ var vpos = comment.vpos + j;
977
+ arrayPush(_this.timeline, vpos, index);
978
+ if (j > comment.long - 20)
979
+ continue;
980
+ if (comment.loc === "ue") {
981
+ arrayPush(_this.collision.ue, vpos, index);
982
+ }
983
+ else {
984
+ arrayPush(_this.collision.shita, vpos, index);
985
+ }
986
+ }
987
+ comment.posY = posY;
988
+ }
989
+ });
990
+ logger("getCommentPos complete: ".concat(performance.now() - getCommentPosStart, "ms"));
991
+ return data;
992
+ };
993
+ NiconiComments.prototype.sortComment = function (parsedData) {
994
+ var _a;
995
+ var sortCommentStart = performance.now();
996
+ for (var _i = 0, _b = Object.keys(this.timeline); _i < _b.length; _i++) {
997
+ var vpos = _b[_i];
998
+ var item = this.timeline[Number(vpos)];
999
+ if (!item)
1000
+ continue;
1001
+ var owner = [], user = [];
1002
+ for (var _c = 0, item_1 = item; _c < item_1.length; _c++) {
1003
+ var index = item_1[_c];
1004
+ if ((_a = parsedData[index]) === null || _a === void 0 ? void 0 : _a.owner) {
1005
+ owner.push(index);
1006
+ }
1007
+ else {
1008
+ user.push(index);
1009
+ }
1010
+ }
1011
+ this.timeline[Number(vpos)] = owner.concat(user);
1012
+ }
1013
+ logger("parseData complete: ".concat(performance.now() - sortCommentStart, "ms"));
1014
+ return parsedData;
1015
+ };
1016
+ NiconiComments.prototype.measureText = function (comment) {
1017
+ var width_arr = [], lines = comment.content.split("\n");
1018
+ if (!comment.lineHeight)
1019
+ comment.lineHeight = lineHeight[comment.size].default;
1020
+ if (!comment.resized && !comment.ender) {
1021
+ if (comment.size === "big" && lines.length > 2) {
1022
+ comment.fontSize = fontSize.big.resized;
1023
+ comment.lineHeight = lineHeight.big.resized;
1024
+ comment.resized = true;
1025
+ comment.resizedY = true;
1026
+ this.context.font = parseFont(comment.font, comment.fontSize, this.useLegacy);
1027
+ }
1028
+ else if (comment.size === "medium" && lines.length > 4) {
1029
+ comment.fontSize = fontSize.medium.resized;
1030
+ comment.lineHeight = lineHeight.medium.resized;
1031
+ comment.resized = true;
1032
+ comment.resizedY = true;
1033
+ this.context.font = parseFont(comment.font, comment.fontSize, this.useLegacy);
1034
+ }
1035
+ else if (comment.size === "small" && lines.length > 6) {
1036
+ comment.fontSize = fontSize.small.resized;
1037
+ comment.lineHeight = lineHeight.small.resized;
1038
+ comment.resized = true;
1039
+ comment.resizedY = true;
1040
+ this.context.font = parseFont(comment.font, comment.fontSize, this.useLegacy);
1041
+ }
1042
+ }
1043
+ for (var i = 0; i < lines.length; i++) {
1044
+ var measure = this.context.measureText(lines[i]);
1045
+ width_arr.push(measure.width);
1046
+ }
1047
+ var width = width_arr.reduce(function (p, c) { return p + c; }, 0) / width_arr.length;
1048
+ var width_max = Math.max.apply(Math, width_arr), width_min = Math.min.apply(Math, width_arr), height = comment.fontSize *
1049
+ comment.lineHeight *
1050
+ (1 + commentYPaddingTop) *
1051
+ lines.length +
1052
+ commentYMarginBottom * comment.fontSize;
1053
+ if (comment.loc !== "naka" && !comment.resizedY) {
1054
+ if ((comment.full && width_max > 1930) ||
1055
+ (!comment.full && width_max > 1440)) {
1056
+ while (width_max > (comment.full ? 1930 : 1440)) {
1057
+ width_max /= 1.1;
1058
+ width_max /= 1.1;
1059
+ comment.fontSize -= 2;
1060
+ }
1061
+ comment.resized = true;
1062
+ comment.resizedX = true;
1063
+ this.context.font = parseFont(comment.font, comment.fontSize, this.useLegacy);
1064
+ return this.measureText(comment);
1065
+ }
1066
+ }
1067
+ else if (comment.loc !== "naka" &&
1068
+ comment.resizedY &&
1069
+ ((comment.full && width_max > 2120) ||
1070
+ (!comment.full && width_max > 1440)) &&
1071
+ !comment.resizedX) {
1072
+ comment.fontSize = fontSize[comment.size].default;
1073
+ comment.lineHeight = lineHeight[comment.size].default * 1.05;
1074
+ comment.resized = true;
1075
+ comment.resizedX = true;
1076
+ this.context.font = parseFont(comment.font, comment.fontSize, this.useLegacy);
1077
+ return this.measureText(comment);
1078
+ }
1079
+ else if (comment.loc !== "naka" && comment.resizedY && comment.resizedX) {
1080
+ if (comment.full &&
1081
+ width_max >
1082
+ doubleResizeMaxWidth.full[this.useLegacy ? "legacy" : "default"]) {
1083
+ while (width_max >
1084
+ doubleResizeMaxWidth.full[this.useLegacy ? "legacy" : "default"]) {
1085
+ width_max /= 1.1;
1086
+ comment.fontSize -= 1;
1087
+ }
1088
+ this.context.font = parseFont(comment.font, comment.fontSize, this.useLegacy);
1089
+ return this.measureText(comment);
1090
+ }
1091
+ else if (!comment.full &&
1092
+ width_max >
1093
+ doubleResizeMaxWidth.normal[this.useLegacy ? "legacy" : "default"]) {
1094
+ while (width_max >
1095
+ doubleResizeMaxWidth.normal[this.useLegacy ? "legacy" : "default"]) {
1096
+ width_max /= 1.1;
1097
+ comment.fontSize -= 1;
1098
+ }
1099
+ this.context.font = parseFont(comment.font, comment.fontSize, this.useLegacy);
1100
+ return this.measureText(comment);
1101
+ }
1102
+ }
1103
+ return {
1104
+ width: width,
1105
+ width_max: width_max,
1106
+ width_min: width_min,
1107
+ height: height,
1108
+ resized: !!comment.resized,
1109
+ fontSize: comment.fontSize,
1110
+ lineHeight: comment.lineHeight,
1111
+ };
1112
+ };
1113
+ NiconiComments.prototype.drawText = function (comment, vpos) {
1114
+ var _this = this;
1115
+ var reverse = false;
1116
+ for (var _i = 0, _a = this.nicoScripts.reverse; _i < _a.length; _i++) {
1117
+ var range = _a[_i];
1118
+ if ((range.target === "コメ" && comment.owner) ||
1119
+ (range.target === "投コメ" && !comment.owner))
1120
+ break;
1121
+ if (range.start < vpos && vpos < range.end) {
1122
+ reverse = true;
1123
+ }
1124
+ }
1125
+ for (var _b = 0, _c = this.nicoScripts.ban; _b < _c.length; _b++) {
1126
+ var range = _c[_b];
1127
+ if (range.start < vpos && vpos < range.end)
1128
+ return;
1129
+ }
1130
+ var posX = (canvasWidth - comment.width_max) / 2, posY = comment.posY;
1131
+ if (comment.loc === "naka") {
1132
+ if (reverse) {
1133
+ posX =
1134
+ canvasWidth +
1135
+ comment.width_max -
1136
+ getPosX(comment.width_max, vpos - comment.vpos, comment.long);
1137
+ }
1138
+ else {
1139
+ posX = getPosX(comment.width_max, vpos - comment.vpos, comment.long);
1140
+ }
1141
+ if (posX > canvasWidth || posX + comment.width_max < 0) {
1142
+ return;
1143
+ }
1144
+ }
1145
+ else if (comment.loc === "shita") {
1146
+ posY = canvasHeight - comment.posY - comment.height;
1147
+ }
1148
+ if (comment.image && comment.image !== true) {
1149
+ this.context.drawImage(comment.image, posX, posY);
1150
+ }
1151
+ if (this.showCollision) {
1152
+ this.context.strokeStyle = "rgba(0,255,255,1)";
1153
+ this.context.strokeRect(posX, posY, comment.width_max, comment.height);
1154
+ var lines = comment.content.split("\n");
1155
+ lines.forEach(function (_, index) {
1156
+ var linePosY = (Number(index) + 1) *
1157
+ (comment.fontSize * comment.lineHeight) *
1158
+ (1 + commentYPaddingTop);
1159
+ _this.context.strokeStyle = "rgba(255,255,0,0.5)";
1160
+ _this.context.strokeRect(posX, posY + linePosY, comment.width_max, comment.fontSize * comment.lineHeight * -1);
1161
+ });
1162
+ }
1163
+ if (isDebug) {
1164
+ var font = this.context.font;
1165
+ var fillStyle = this.context.fillStyle;
1166
+ this.context.font = parseFont("defont", 30, false);
1167
+ this.context.fillStyle = "#ff00ff";
1168
+ this.context.fillText(comment.mail.join(","), posX, posY + 30);
1169
+ this.context.font = font;
1170
+ this.context.fillStyle = fillStyle;
1171
+ }
1172
+ };
1173
+ NiconiComments.prototype.getTextImage = function (i, preRendering) {
1174
+ var _this = this;
1175
+ var _a;
1176
+ if (preRendering === void 0) { preRendering = false; }
1177
+ var value = this.data[i];
1178
+ if (!value || value.invisible)
1179
+ return;
1180
+ var cacheKey = value.content + "@@@" + __spreadArray([], value.mail, true).sort().join(","), cache = this.cacheIndex[cacheKey];
1181
+ if (cache) {
1182
+ var image_1 = (_a = this.data[cache]) === null || _a === void 0 ? void 0 : _a.image;
1183
+ if (image_1) {
1184
+ this.cacheIndex[cacheKey] = i;
1185
+ value.image = image_1;
1186
+ setTimeout(function () {
1187
+ if (value.image) {
1188
+ delete value.image;
1189
+ }
1190
+ if (_this.cacheIndex[cacheKey] === i) {
1191
+ delete _this.cacheIndex[cacheKey];
1192
+ }
1193
+ }, value.long * 10 + cacheAge);
1194
+ return;
1195
+ }
1196
+ }
1197
+ var image = document.createElement("canvas");
1198
+ image.width = value.width_max;
1199
+ image.height = value.height;
1200
+ var context = image.getContext("2d");
1201
+ if (!context)
1202
+ throw new Error("Fail to get CanvasRenderingContext2D");
1203
+ context.strokeStyle = "rgba(0,0,0,0.7)";
1204
+ context.textAlign = "start";
1205
+ context.textBaseline = "alphabetic";
1206
+ context.lineWidth = 4;
1207
+ context.font = parseFont(value.font, value.fontSize, this.useLegacy);
1208
+ if (value._live) {
1209
+ var rgb = hex2rgb(value.color);
1210
+ context.fillStyle = "rgba(".concat(rgb[0], ",").concat(rgb[1], ",").concat(rgb[2], ",0.5)");
1211
+ }
1212
+ else {
1213
+ context.fillStyle = value.color;
1214
+ }
1215
+ if (value.color === "#000000") {
1216
+ context.strokeStyle = "rgba(255,255,255,0.7)";
1217
+ }
1218
+ var lines = value.content.split("\n");
1219
+ lines.forEach(function (line, index) {
1220
+ var posY = (index + 1) *
1221
+ (value.fontSize * value.lineHeight) *
1222
+ (1 + commentYPaddingTop);
1223
+ context.strokeText(line, 0, posY);
1224
+ context.fillText(line, 0, posY);
1225
+ });
1226
+ value.image = image;
1227
+ this.cacheIndex[cacheKey] = i;
1228
+ if (preRendering)
1229
+ return;
1230
+ setTimeout(function () {
1231
+ if (value.image) {
1232
+ delete value.image;
1233
+ }
1234
+ if (_this.cacheIndex[cacheKey] === i) {
1235
+ delete _this.cacheIndex[cacheKey];
1236
+ }
1237
+ }, value.long * 10 + cacheAge);
1238
+ };
1239
+ NiconiComments.prototype.parseCommand = function (comment) {
1240
+ var metadata = comment.mail;
1241
+ var result = {
1242
+ loc: undefined,
1243
+ size: undefined,
1244
+ fontSize: undefined,
1245
+ color: undefined,
1246
+ font: undefined,
1247
+ full: false,
1248
+ ender: false,
1249
+ _live: false,
1250
+ invisible: false,
1251
+ long: undefined,
1252
+ };
1253
+ for (var _i = 0, metadata_1 = metadata; _i < metadata_1.length; _i++) {
1254
+ var command = metadata_1[_i];
1255
+ command = command.toLowerCase();
1256
+ var match = command.match(/^@([0-9.]+)/);
1257
+ if (match && match[1]) {
1258
+ result.long = Number(match[1]);
1259
+ }
1260
+ else if (result.loc === undefined && typeGuard.comment.loc(command)) {
1261
+ result.loc = command;
1262
+ }
1263
+ else if (result.size === undefined && typeGuard.comment.size(command)) {
1264
+ result.size = command;
1265
+ result.fontSize = fontSize[command].default;
1266
+ }
1267
+ else {
1268
+ if (result.color === undefined) {
1269
+ var color = colors[command];
1270
+ if (color) {
1271
+ result.color = color;
1272
+ continue;
1273
+ }
1274
+ else {
1275
+ var match_1 = command.match(/#[0-9a-z]{3,6}/);
1276
+ if (match_1 && match_1[0] && comment.premium) {
1277
+ result.color = match_1[0].toUpperCase();
1278
+ continue;
1279
+ }
1280
+ }
1281
+ }
1282
+ if (result.font === undefined && typeGuard.comment.font(command)) {
1283
+ result.font = command;
1284
+ }
1285
+ else if (typeGuard.comment.command.key(command)) {
1286
+ result[command] = true;
1287
+ }
1288
+ }
1289
+ }
1290
+ return result;
1291
+ };
1292
+ NiconiComments.prototype.parseCommandAndNicoscript = function (comment) {
1293
+ var data = this.parseCommand(comment), string = comment.content, nicoscript = string.match(/^(?:@|@)(デフォルト|置換|逆|コメント禁止|シーク禁止|ジャンプ)/);
1294
+ if (nicoscript) {
1295
+ var reverse = comment.content.match(/^@逆 ?(全|コメ|投コメ)?/);
1296
+ var content = comment.content.split(""), result = [];
1297
+ var quote = "", last_i = "", string_1 = "";
1298
+ switch (nicoscript[1]) {
1299
+ case "デフォルト":
1300
+ this.nicoScripts.default.unshift({
1301
+ start: comment.vpos,
1302
+ long: data.long === undefined ? undefined : Math.floor(data.long * 100),
1303
+ color: data.color,
1304
+ size: data.size,
1305
+ font: data.font,
1306
+ loc: data.loc,
1307
+ });
1308
+ break;
1309
+ case "逆":
1310
+ if (!reverse ||
1311
+ !reverse[1] ||
1312
+ !typeGuard.nicoScript.range.target(reverse[1]))
1313
+ break;
1314
+ if (data.long === undefined) {
1315
+ data.long = 30;
1316
+ }
1317
+ this.nicoScripts.reverse.unshift({
1318
+ start: comment.vpos,
1319
+ end: comment.vpos + data.long * 100,
1320
+ target: reverse[1],
1321
+ });
1322
+ break;
1323
+ case "コメント禁止":
1324
+ if (data.long === undefined) {
1325
+ data.long = 30;
1326
+ }
1327
+ this.nicoScripts.ban.unshift({
1328
+ start: comment.vpos,
1329
+ end: comment.vpos + data.long * 100,
1330
+ });
1331
+ break;
1332
+ case "置換":
1333
+ for (var _i = 0, _a = content.slice(4); _i < _a.length; _i++) {
1334
+ var i = _a[_i];
1335
+ if (i.match(/["'「]/) && quote === "") {
1336
+ quote = i;
1337
+ }
1338
+ else if (i.match(/["']/) && quote === i && last_i !== "\\") {
1339
+ result.push(replaceAll(string_1, "\\n", "\n"));
1340
+ quote = "";
1341
+ string_1 = "";
1342
+ }
1343
+ else if (i.match(/」/) && quote === "「") {
1344
+ result.push(string_1);
1345
+ quote = "";
1346
+ string_1 = "";
1347
+ }
1348
+ else if (quote === "" && i.match(/\s+/)) {
1349
+ if (string_1) {
1350
+ result.push(string_1);
1351
+ string_1 = "";
1352
+ }
1353
+ }
1354
+ else {
1355
+ string_1 += i;
1356
+ }
1357
+ last_i = i;
1358
+ }
1359
+ result.push(string_1);
1360
+ if (result[0] === undefined ||
1361
+ result[1] === undefined ||
1362
+ (result[2] !== undefined &&
1363
+ !typeGuard.nicoScript.replace.range(result[2])) ||
1364
+ (result[3] !== undefined &&
1365
+ !typeGuard.nicoScript.replace.target(result[3])) ||
1366
+ (result[4] !== undefined &&
1367
+ !typeGuard.nicoScript.replace.condition(result[4])))
1368
+ break;
1369
+ this.nicoScripts.replace.unshift({
1370
+ start: comment.vpos,
1371
+ long: data.long === undefined ? undefined : Math.floor(data.long * 100),
1372
+ keyword: result[0],
1373
+ replace: result[1] || "",
1374
+ range: result[2] || "単",
1375
+ target: result[3] || "コメ",
1376
+ condition: result[4] || "部分一致",
1377
+ color: data.color,
1378
+ size: data.size,
1379
+ font: data.font,
1380
+ loc: data.loc,
1381
+ no: comment.id,
1382
+ });
1383
+ this.nicoScripts.replace.sort(function (a, b) {
1384
+ if (a.start < b.start)
1385
+ return -1;
1386
+ if (a.start > b.start)
1387
+ return 1;
1388
+ if (a.no < b.no)
1389
+ return -1;
1390
+ if (a.no > b.no)
1391
+ return 1;
1392
+ return 0;
1393
+ });
1394
+ break;
1395
+ }
1396
+ data.invisible = true;
1397
+ }
1398
+ var color = undefined, size = undefined, font = undefined, loc = undefined;
1399
+ for (var i = 0; i < this.nicoScripts.default.length; i++) {
1400
+ var item = this.nicoScripts.default[i];
1401
+ if (!item)
1402
+ continue;
1403
+ if (item.long !== undefined && item.start + item.long < comment.vpos) {
1404
+ this.nicoScripts.default = this.nicoScripts.default.splice(Number(i), 1);
1405
+ continue;
1406
+ }
1407
+ if (item.loc) {
1408
+ loc = item.loc;
1409
+ }
1410
+ if (item.color) {
1411
+ color = item.color;
1412
+ }
1413
+ if (item.size) {
1414
+ size = item.size;
1415
+ }
1416
+ if (item.font) {
1417
+ font = item.font;
1418
+ }
1419
+ if (loc && color && size && font)
1420
+ break;
1421
+ }
1422
+ for (var i = 0; i < this.nicoScripts.replace.length; i++) {
1423
+ var item = this.nicoScripts.replace[i];
1424
+ if (!item)
1425
+ continue;
1426
+ if (item.long !== undefined && item.start + item.long < comment.vpos) {
1427
+ this.nicoScripts.default = this.nicoScripts.default.splice(Number(i), 1);
1428
+ continue;
1429
+ }
1430
+ if ((item.target === "コメ" && comment.owner) ||
1431
+ (item.target === "投コメ" && !comment.owner) ||
1432
+ (item.target === "含まない" && comment.owner))
1433
+ continue;
1434
+ if ((item.condition === "完全一致" && comment.content === item.keyword) ||
1435
+ (item.condition === "部分一致" &&
1436
+ comment.content.indexOf(item.keyword) !== -1)) {
1437
+ if (item.range === "単") {
1438
+ comment.content = replaceAll(comment.content, item.keyword, item.replace);
1439
+ }
1440
+ else {
1441
+ comment.content = item.replace;
1442
+ }
1443
+ if (item.loc) {
1444
+ data.loc = item.loc;
1445
+ }
1446
+ if (item.color) {
1447
+ data.color = item.color;
1448
+ }
1449
+ if (item.size) {
1450
+ data.size = item.size;
1451
+ }
1452
+ if (item.font) {
1453
+ data.font = item.font;
1454
+ }
1455
+ }
1456
+ }
1457
+ if (!data.loc) {
1458
+ data.loc = loc || "naka";
1459
+ }
1460
+ if (!data.color) {
1461
+ data.color = color || "#FFFFFF";
1462
+ }
1463
+ if (!data.size) {
1464
+ data.size = size || "medium";
1465
+ data.fontSize = fontSize[data.size].default;
1466
+ }
1467
+ if (!data.font) {
1468
+ data.font = font || "defont";
1469
+ }
1470
+ if (!data.long) {
1471
+ data.long = 300;
1472
+ }
1473
+ else {
1474
+ data.long = Math.floor(Number(data.long) * 100);
1475
+ }
1476
+ return _assign(_assign({}, comment), data);
1477
+ };
1478
+ NiconiComments.prototype.drawCanvas = function (vpos, forceRendering) {
1479
+ if (forceRendering === void 0) { forceRendering = false; }
1480
+ var drawCanvasStart = performance.now();
1481
+ if (this.lastVpos === vpos && !forceRendering)
1482
+ return;
1483
+ this.lastVpos = vpos;
1484
+ this.fpsCount++;
1485
+ this.context.clearRect(0, 0, this.canvas.width, this.canvas.height);
1486
+ if (this.video) {
1487
+ var scale = void 0;
1488
+ var height = this.canvas.height / this.video.videoHeight, width = this.canvas.width / this.video.videoWidth;
1489
+ if (this.enableLegacyPiP ? height > width : height < width) {
1490
+ scale = width;
1491
+ }
1492
+ else {
1493
+ scale = height;
1494
+ }
1495
+ var offsetX = (this.canvas.width - this.video.videoWidth * scale) * 0.5, offsetY = (this.canvas.height - this.video.videoHeight * scale) * 0.5;
1496
+ this.context.drawImage(this.video, offsetX, offsetY, this.video.videoWidth * scale, this.video.videoHeight * scale);
1497
+ }
1498
+ var timelineRange = this.timeline[vpos];
1499
+ if (timelineRange) {
1500
+ for (var _i = 0, timelineRange_1 = timelineRange; _i < timelineRange_1.length; _i++) {
1501
+ var index = timelineRange_1[_i];
1502
+ var comment = this.data[index];
1503
+ if (!comment || comment.invisible) {
1504
+ continue;
1505
+ }
1506
+ if (comment.image === undefined) {
1507
+ this.getTextImage(index);
1508
+ }
1509
+ try {
1510
+ this.drawText(comment, vpos);
1511
+ }
1512
+ catch (e) {
1513
+ comment.image = false;
1514
+ }
1515
+ }
1516
+ }
1517
+ if (this.showFPS) {
1518
+ this.context.font = parseFont("defont", 60, this.useLegacy);
1519
+ this.context.fillStyle = "#00FF00";
1520
+ this.context.strokeStyle = "rgba(0,0,0,0.7)";
1521
+ this.context.strokeText("FPS:".concat(this.fps), 100, 100);
1522
+ this.context.fillText("FPS:".concat(this.fps), 100, 100);
1523
+ }
1524
+ if (this.showCommentCount) {
1525
+ this.context.font = parseFont("defont", 60, this.useLegacy);
1526
+ this.context.fillStyle = "#00FF00";
1527
+ this.context.strokeStyle = "rgba(0,0,0,0.7)";
1528
+ if (timelineRange) {
1529
+ this.context.strokeText("Count:".concat(timelineRange.length), 100, 200);
1530
+ this.context.fillText("Count:".concat(timelineRange.length), 100, 200);
1531
+ }
1532
+ else {
1533
+ this.context.strokeText("Count:0", 100, 200);
1534
+ this.context.fillText("Count:0", 100, 200);
1535
+ }
1536
+ }
1537
+ logger("drawCanvas complete: ".concat(performance.now() - drawCanvasStart, "ms"));
1538
+ };
1539
+ NiconiComments.prototype.clear = function () {
1540
+ this.context.clearRect(0, 0, canvasWidth, canvasHeight);
1541
+ };
1542
+ return NiconiComments;
1543
+ }());
1544
+ var logger = function (msg) {
1545
+ if (isDebug)
1546
+ console.debug(msg);
1470
1547
  };
1471
1548
 
1472
1549
  return NiconiComments;