@dan-uni/dan-any 1.4.7 → 2.0.0

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.
Files changed (200) hide show
  1. package/README.md +87 -43
  2. package/dist/adapters.d.mts +2 -0
  3. package/dist/adapters.mjs +1 -0
  4. package/dist/chunk-0Lt9GpW0.mjs +1 -0
  5. package/dist/core/db/schema.d.mts +2 -0
  6. package/dist/core/db/schema.mjs +2 -0
  7. package/dist/core/db/schema.mjs.map +1 -0
  8. package/dist/core/db/utils.d.mts +1707 -0
  9. package/dist/core/db/utils.d.mts.map +1 -0
  10. package/dist/core/db/utils.mjs +1 -0
  11. package/dist/core-D7LMAB5h.mjs +2 -0
  12. package/dist/core-D7LMAB5h.mjs.map +1 -0
  13. package/dist/core.d.mts +2 -0
  14. package/dist/core.mjs +1 -0
  15. package/dist/db-DWWzkRBb.mjs +41 -0
  16. package/dist/db-DWWzkRBb.mjs.map +1 -0
  17. package/dist/dm-extra-DrAQCrFv.d.mts +135 -0
  18. package/dist/dm-extra-DrAQCrFv.d.mts.map +1 -0
  19. package/dist/dm-tkTdR_W6.mjs +2 -0
  20. package/dist/dm-tkTdR_W6.mjs.map +1 -0
  21. package/dist/index-vAs4qV9A.d.mts +6195 -0
  22. package/dist/index-vAs4qV9A.d.mts.map +1 -0
  23. package/dist/index.d.mts +4 -0
  24. package/dist/index.mjs +1 -0
  25. package/dist/isSame-D4G9eoE4.mjs +2 -0
  26. package/dist/isSame-D4G9eoE4.mjs.map +1 -0
  27. package/dist/plugins.d.mts +105 -0
  28. package/dist/plugins.d.mts.map +1 -0
  29. package/dist/plugins.mjs +2 -0
  30. package/dist/plugins.mjs.map +1 -0
  31. package/dist/schema-BuenbDx9.d.mts +1619 -0
  32. package/dist/schema-BuenbDx9.d.mts.map +1 -0
  33. package/dist/utils.d.mts +25 -0
  34. package/dist/utils.d.mts.map +1 -0
  35. package/dist/utils.mjs +2 -0
  36. package/dist/utils.mjs.map +1 -0
  37. package/package.json +65 -37
  38. package/.babelrc.json +0 -12
  39. package/buf.gen.yaml +0 -10
  40. package/buf.yaml +0 -12
  41. package/dist/browser/1~rslib-runtime.min.js +0 -49
  42. package/dist/browser/index.min.js +0 -13521
  43. package/dist/browser/index.min.js.LICENSE.txt +0 -17
  44. package/dist/browser/plugins/bili.min.js +0 -1
  45. package/dist/browser/plugins/index.min.js +0 -2
  46. package/dist/browser/plugins/stats.min.js +0 -10
  47. package/dist/browser/src/ass-gen/__tests__/canvas.test.d.ts +0 -1
  48. package/dist/browser/src/ass-gen/__tests__/generate.test.d.ts +0 -1
  49. package/dist/browser/src/ass-gen/ass/create.d.ts +0 -4
  50. package/dist/browser/src/ass-gen/ass/dialogue.d.ts +0 -16
  51. package/dist/browser/src/ass-gen/ass/event.d.ts +0 -2
  52. package/dist/browser/src/ass-gen/ass/info.d.ts +0 -8
  53. package/dist/browser/src/ass-gen/ass/raw.d.ts +0 -14
  54. package/dist/browser/src/ass-gen/ass/style.d.ts +0 -2
  55. package/dist/browser/src/ass-gen/config.d.ts +0 -2
  56. package/dist/browser/src/ass-gen/index.d.ts +0 -30
  57. package/dist/browser/src/ass-gen/types.d.ts +0 -71
  58. package/dist/browser/src/ass-gen/util/color.d.ts +0 -18
  59. package/dist/browser/src/ass-gen/util/danconvert.d.ts +0 -5
  60. package/dist/browser/src/ass-gen/util/index.d.ts +0 -4
  61. package/dist/browser/src/ass-gen/util/lang.d.ts +0 -3
  62. package/dist/browser/src/ass-gen/util/layout.d.ts +0 -4
  63. package/dist/browser/src/index.d.ts +0 -283
  64. package/dist/browser/src/index.test.d.ts +0 -1
  65. package/dist/browser/src/plugins/bili/dedupe.d.ts +0 -3
  66. package/dist/browser/src/plugins/bili/history-danmaku-fast-forward.d.ts +0 -18
  67. package/dist/browser/src/plugins/bili/index.d.ts +0 -2
  68. package/dist/browser/src/plugins/bili/index.test.d.ts +0 -1
  69. package/dist/browser/src/plugins/index.d.ts +0 -2
  70. package/dist/browser/src/plugins/stats/getLatestDan.d.ts +0 -6
  71. package/dist/browser/src/plugins/stats/index.d.ts +0 -1
  72. package/dist/browser/src/plugins/stats/index.test.d.ts +0 -1
  73. package/dist/browser/src/proto/gen/bilibili/community/service/dm/v1/dm_pb.d.ts +0 -3426
  74. package/dist/browser/src/proto/gen/danuni/danmaku/v1/danmaku_pb.d.ts +0 -176
  75. package/dist/browser/src/utils/dm-gen.d.ts +0 -309
  76. package/dist/browser/src/utils/dm-gen.test.d.ts +0 -1
  77. package/dist/browser/src/utils/fileParser.d.ts +0 -3
  78. package/dist/browser/src/utils/id-gen.d.ts +0 -50
  79. package/dist/browser/src/utils/platform.d.ts +0 -24
  80. package/dist/node/0~rslib-runtime.js +0 -23
  81. package/dist/node/index.js +0 -2097
  82. package/dist/node/plugins/bili.js +0 -1
  83. package/dist/node/plugins/index.js +0 -2
  84. package/dist/node/plugins/stats.js +0 -10
  85. package/dist/node/src/ass-gen/__tests__/canvas.test.d.ts +0 -1
  86. package/dist/node/src/ass-gen/__tests__/generate.test.d.ts +0 -1
  87. package/dist/node/src/ass-gen/ass/create.d.ts +0 -4
  88. package/dist/node/src/ass-gen/ass/dialogue.d.ts +0 -16
  89. package/dist/node/src/ass-gen/ass/event.d.ts +0 -2
  90. package/dist/node/src/ass-gen/ass/info.d.ts +0 -8
  91. package/dist/node/src/ass-gen/ass/raw.d.ts +0 -14
  92. package/dist/node/src/ass-gen/ass/style.d.ts +0 -2
  93. package/dist/node/src/ass-gen/config.d.ts +0 -2
  94. package/dist/node/src/ass-gen/index.d.ts +0 -30
  95. package/dist/node/src/ass-gen/types.d.ts +0 -71
  96. package/dist/node/src/ass-gen/util/color.d.ts +0 -18
  97. package/dist/node/src/ass-gen/util/danconvert.d.ts +0 -5
  98. package/dist/node/src/ass-gen/util/index.d.ts +0 -4
  99. package/dist/node/src/ass-gen/util/lang.d.ts +0 -3
  100. package/dist/node/src/ass-gen/util/layout.d.ts +0 -4
  101. package/dist/node/src/index.d.ts +0 -283
  102. package/dist/node/src/index.test.d.ts +0 -1
  103. package/dist/node/src/plugins/bili/dedupe.d.ts +0 -3
  104. package/dist/node/src/plugins/bili/history-danmaku-fast-forward.d.ts +0 -18
  105. package/dist/node/src/plugins/bili/index.d.ts +0 -2
  106. package/dist/node/src/plugins/bili/index.test.d.ts +0 -1
  107. package/dist/node/src/plugins/index.d.ts +0 -2
  108. package/dist/node/src/plugins/stats/getLatestDan.d.ts +0 -6
  109. package/dist/node/src/plugins/stats/index.d.ts +0 -1
  110. package/dist/node/src/plugins/stats/index.test.d.ts +0 -1
  111. package/dist/node/src/proto/gen/bilibili/community/service/dm/v1/dm_pb.d.ts +0 -3426
  112. package/dist/node/src/proto/gen/danuni/danmaku/v1/danmaku_pb.d.ts +0 -176
  113. package/dist/node/src/utils/dm-gen.d.ts +0 -309
  114. package/dist/node/src/utils/dm-gen.test.d.ts +0 -1
  115. package/dist/node/src/utils/fileParser.d.ts +0 -3
  116. package/dist/node/src/utils/id-gen.d.ts +0 -50
  117. package/dist/node/src/utils/platform.d.ts +0 -24
  118. package/dist/umd/index.umd.min.js +0 -32091
  119. package/dist/umd/index.umd.min.js.LICENSE.txt +0 -34
  120. package/dist/umd/plugins/bili.umd.min.js +0 -32002
  121. package/dist/umd/plugins/bili.umd.min.js.LICENSE.txt +0 -34
  122. package/dist/umd/plugins/index.umd.min.js +0 -32018
  123. package/dist/umd/plugins/index.umd.min.js.LICENSE.txt +0 -34
  124. package/dist/umd/plugins/stats.umd.min.js +0 -39
  125. package/dist/umd/src/ass-gen/__tests__/canvas.test.d.ts +0 -1
  126. package/dist/umd/src/ass-gen/__tests__/generate.test.d.ts +0 -1
  127. package/dist/umd/src/ass-gen/ass/create.d.ts +0 -4
  128. package/dist/umd/src/ass-gen/ass/dialogue.d.ts +0 -16
  129. package/dist/umd/src/ass-gen/ass/event.d.ts +0 -2
  130. package/dist/umd/src/ass-gen/ass/info.d.ts +0 -8
  131. package/dist/umd/src/ass-gen/ass/raw.d.ts +0 -14
  132. package/dist/umd/src/ass-gen/ass/style.d.ts +0 -2
  133. package/dist/umd/src/ass-gen/config.d.ts +0 -2
  134. package/dist/umd/src/ass-gen/index.d.ts +0 -30
  135. package/dist/umd/src/ass-gen/types.d.ts +0 -71
  136. package/dist/umd/src/ass-gen/util/color.d.ts +0 -18
  137. package/dist/umd/src/ass-gen/util/danconvert.d.ts +0 -5
  138. package/dist/umd/src/ass-gen/util/index.d.ts +0 -4
  139. package/dist/umd/src/ass-gen/util/lang.d.ts +0 -3
  140. package/dist/umd/src/ass-gen/util/layout.d.ts +0 -4
  141. package/dist/umd/src/index.d.ts +0 -283
  142. package/dist/umd/src/index.test.d.ts +0 -1
  143. package/dist/umd/src/plugins/bili/dedupe.d.ts +0 -3
  144. package/dist/umd/src/plugins/bili/history-danmaku-fast-forward.d.ts +0 -18
  145. package/dist/umd/src/plugins/bili/index.d.ts +0 -2
  146. package/dist/umd/src/plugins/bili/index.test.d.ts +0 -1
  147. package/dist/umd/src/plugins/index.d.ts +0 -2
  148. package/dist/umd/src/plugins/stats/getLatestDan.d.ts +0 -6
  149. package/dist/umd/src/plugins/stats/index.d.ts +0 -1
  150. package/dist/umd/src/plugins/stats/index.test.d.ts +0 -1
  151. package/dist/umd/src/proto/gen/bilibili/community/service/dm/v1/dm_pb.d.ts +0 -3426
  152. package/dist/umd/src/proto/gen/danuni/danmaku/v1/danmaku_pb.d.ts +0 -176
  153. package/dist/umd/src/utils/dm-gen.d.ts +0 -309
  154. package/dist/umd/src/utils/dm-gen.test.d.ts +0 -1
  155. package/dist/umd/src/utils/fileParser.d.ts +0 -3
  156. package/dist/umd/src/utils/id-gen.d.ts +0 -50
  157. package/dist/umd/src/utils/platform.d.ts +0 -24
  158. package/plugins/package.json +0 -6
  159. package/rslib.config.ts +0 -101
  160. package/src/ass-gen/__tests__/898651903.xml +0 -1619
  161. package/src/ass-gen/__tests__/898651903.xml.ass +0 -1516
  162. package/src/ass-gen/__tests__/canvas.test.ts +0 -15
  163. package/src/ass-gen/__tests__/generate.test.ts +0 -26
  164. package/src/ass-gen/ass/create.ts +0 -37
  165. package/src/ass-gen/ass/dialogue.ts +0 -90
  166. package/src/ass-gen/ass/event.ts +0 -57
  167. package/src/ass-gen/ass/info.ts +0 -27
  168. package/src/ass-gen/ass/raw.ts +0 -78
  169. package/src/ass-gen/ass/style.ts +0 -66
  170. package/src/ass-gen/config.ts +0 -45
  171. package/src/ass-gen/index.ts +0 -73
  172. package/src/ass-gen/types.ts +0 -76
  173. package/src/ass-gen/util/color.ts +0 -55
  174. package/src/ass-gen/util/danconvert.ts +0 -43
  175. package/src/ass-gen/util/index.ts +0 -10
  176. package/src/ass-gen/util/lang.ts +0 -35
  177. package/src/ass-gen/util/layout.ts +0 -242
  178. package/src/index.test.ts +0 -157
  179. package/src/index.ts +0 -1144
  180. package/src/plugins/bili/README.md +0 -87
  181. package/src/plugins/bili/dedupe.ts +0 -29
  182. package/src/plugins/bili/history-danmaku-fast-forward.ts +0 -86
  183. package/src/plugins/bili/index.test.ts +0 -129
  184. package/src/plugins/bili/index.ts +0 -2
  185. package/src/plugins/index.ts +0 -2
  186. package/src/plugins/stats/README.md +0 -44
  187. package/src/plugins/stats/getLatestDan.ts +0 -13
  188. package/src/plugins/stats/index.test.ts +0 -39
  189. package/src/plugins/stats/index.ts +0 -1
  190. package/src/proto/gen/bilibili/community/service/dm/v1/dm_pb.ts +0 -4072
  191. package/src/proto/gen/danuni/danmaku/v1/danmaku_pb.ts +0 -223
  192. package/src/proto/src/bilibili/community/service/dm/v1/dm.proto +0 -1095
  193. package/src/proto/src/danuni/danmaku/v1/danmaku.proto +0 -52
  194. package/src/utils/dm-gen.test.ts +0 -129
  195. package/src/utils/dm-gen.ts +0 -1078
  196. package/src/utils/fileParser.ts +0 -37
  197. package/src/utils/id-gen.ts +0 -73
  198. package/src/utils/platform.ts +0 -38
  199. package/tsconfig.json +0 -108
  200. package/types/tsconfig.tsbuildinfo +0 -1
@@ -1,2097 +0,0 @@
1
- import { __webpack_require__ } from "./0~rslib-runtime.js";
2
- import "reflect-metadata/lite";
3
- import { IsDate, IsEmail, IsEnum, IsInt, IsNotEmpty, IsNumber, IsOptional, IsString, Max, Min, isEmail, isJSON, isString, validateOrReject } from "class-validator";
4
- import { XMLBuilder, XMLParser } from "fast-xml-parser";
5
- import json_bigint from "json-bigint";
6
- import { create, fromBinary, toBinary } from "@bufbuild/protobuf";
7
- import { file_google_protobuf_timestamp, timestampDate, timestampFromDate, timestampNow } from "@bufbuild/protobuf/wkt";
8
- import { Expose, plainToInstance } from "class-transformer";
9
- import hh_mm_ss from "hh-mm-ss";
10
- import jssha from "jssha";
11
- import { brotliCompressSync, brotliDecompressSync, gunzipSync, gzipSync } from "node:zlib";
12
- import { fileDesc, messageDesc as codegenv2_messageDesc } from "@bufbuild/protobuf/codegenv2";
13
- import { DateTime } from "luxon";
14
- import "./plugins/stats.js";
15
- import * as __rspack_external_base16384 from "base16384";
16
- var dedupe_namespaceObject = {};
17
- __webpack_require__.r(dedupe_namespaceObject);
18
- __webpack_require__.d(dedupe_namespaceObject, {
19
- bili_dedupe: ()=>bili_dedupe,
20
- to_bili_deduped: ()=>to_bili_deduped
21
- });
22
- var bili_namespaceObject = {};
23
- __webpack_require__.r(bili_namespaceObject);
24
- __webpack_require__.d(bili_namespaceObject, {
25
- bili_dedupe: ()=>dedupe_namespaceObject,
26
- bili_history_fast_forward: ()=>bili_history_fast_forward
27
- });
28
- var plugins_namespaceObject = {};
29
- __webpack_require__.r(plugins_namespaceObject);
30
- __webpack_require__.d(plugins_namespaceObject, {
31
- bili: ()=>bili_namespaceObject,
32
- stats: ()=>stats_namespaceObject
33
- });
34
- var dm_gen_namespaceObject = {};
35
- __webpack_require__.r(dm_gen_namespaceObject);
36
- __webpack_require__.d(dm_gen_namespaceObject, {
37
- DMAttr: ()=>dm_gen_DMAttr,
38
- ExtraDanUniChapterAction: ()=>dm_gen_ExtraDanUniChapterAction,
39
- ExtraDanUniChapterType: ()=>dm_gen_ExtraDanUniChapterType,
40
- Modes: ()=>dm_gen_Modes,
41
- Pools: ()=>dm_gen_Pools,
42
- UniDM: ()=>UniDM
43
- });
44
- var id_gen_namespaceObject = {};
45
- __webpack_require__.r(id_gen_namespaceObject);
46
- __webpack_require__.d(id_gen_namespaceObject, {
47
- UniID: ()=>id_gen_UniID,
48
- createDMID: ()=>createDMID
49
- });
50
- var platform_namespaceObject = {};
51
- __webpack_require__.r(platform_namespaceObject);
52
- __webpack_require__.d(platform_namespaceObject, {
53
- PlatformDanmakuOnlySource: ()=>platform_PlatformDanmakuOnlySource,
54
- PlatformDanmakuOnlySources: ()=>PlatformDanmakuOnlySources,
55
- PlatformDanmakuSources: ()=>PlatformDanmakuSources,
56
- PlatformInfoSource: ()=>platform_PlatformInfoSource,
57
- PlatformInfoSources: ()=>PlatformInfoSources,
58
- PlatformSources: ()=>PlatformSources,
59
- PlatformVideoSource: ()=>platform_PlatformVideoSource,
60
- PlatformVideoSources: ()=>PlatformVideoSources
61
- });
62
- var package_namespaceObject = JSON.parse('{"UU":"@dan-uni/dan-any","rE":"1.4.7","TB":"https://github.com/ani-uni/danuni/tree/master/packages/dan-any#readme"}');
63
- const color_pad = (s)=>s.length < 2 ? `0${s}` : s;
64
- const decimalToHex = (n)=>color_pad(n.toString(16));
65
- const isDarkColor = ({ r, g, b })=>0.299 * r + 0.587 * g + 0.114 * b < 0x30;
66
- const WHITE = {
67
- r: 255,
68
- g: 255,
69
- b: 255
70
- };
71
- const BLACK = {
72
- r: 0,
73
- g: 0,
74
- b: 0
75
- };
76
- const hexColorToRGB = (hex)=>{
77
- if (0 === hex.indexOf('#')) hex = hex.slice(1);
78
- const [r, g, b] = 3 === hex.length ? hex.split('').map((c)=>c + c) : hex.match(/../g) || [];
79
- return {
80
- r: Number.parseInt(r, 16),
81
- g: Number.parseInt(g, 16),
82
- b: Number.parseInt(b, 16)
83
- };
84
- };
85
- const formatColor = ({ r, g, b }, opacity)=>{
86
- const color = [
87
- b,
88
- g,
89
- r
90
- ];
91
- if (void 0 !== opacity) {
92
- const alpha = Math.round((1 - opacity) * 255);
93
- color.unshift(alpha);
94
- }
95
- return `&H${color.map(decimalToHex).join('').toUpperCase()}`;
96
- };
97
- const getDecoratingColor = (color)=>isDarkColor(color) ? WHITE : BLACK;
98
- const isWhite = (color)=>255 === color.r && 255 === color.g && 255 === color.b;
99
- var platform_PlatformInfoSource = /*#__PURE__*/ function(PlatformInfoSource) {
100
- PlatformInfoSource["Bangumi"] = "bgm";
101
- PlatformInfoSource["TMDB"] = "tmdb";
102
- return PlatformInfoSource;
103
- }({});
104
- const PlatformInfoSources = Object.values(platform_PlatformInfoSource);
105
- var platform_PlatformVideoSource = /*#__PURE__*/ function(PlatformVideoSource) {
106
- PlatformVideoSource["Acfun"] = "acfun";
107
- PlatformVideoSource["Baha"] = "baha";
108
- PlatformVideoSource["Bilibili"] = "bili";
109
- PlatformVideoSource["BilibiliGlobal"] = "bglobal";
110
- PlatformVideoSource["Iqiyi"] = "iqiyi";
111
- PlatformVideoSource["Tencent"] = "tencent";
112
- PlatformVideoSource["Youku"] = "youku";
113
- return PlatformVideoSource;
114
- }({});
115
- const PlatformVideoSources = Object.values(platform_PlatformVideoSource);
116
- var platform_PlatformDanmakuOnlySource = /*#__PURE__*/ function(PlatformDanmakuOnlySource) {
117
- PlatformDanmakuOnlySource["DanDanPlay"] = "ddplay";
118
- PlatformDanmakuOnlySource["TuCao"] = "tucao";
119
- return PlatformDanmakuOnlySource;
120
- }({});
121
- const PlatformDanmakuOnlySources = Object.values(platform_PlatformDanmakuOnlySource);
122
- const PlatformDanmakuSources = [
123
- ...PlatformVideoSources,
124
- ...PlatformDanmakuOnlySources
125
- ];
126
- const PlatformSources = [
127
- ...PlatformInfoSources,
128
- ...PlatformDanmakuSources
129
- ];
130
- class id_gen_UniID {
131
- constructor(id, domain){
132
- this.id = id;
133
- this.domain = domain;
134
- }
135
- static fromString(str) {
136
- const [id, domain] = str.split('@');
137
- return new id_gen_UniID(id, domain);
138
- }
139
- toString() {
140
- return `${this.id}@${this.domain}`;
141
- }
142
- static fromNull(domain) {
143
- return new id_gen_UniID('runtime' === domain ? 'runtime' : 'anonymous', domain || 'danuni');
144
- }
145
- static fromBili({ cid, mid, midHash }) {
146
- if (cid) return new id_gen_UniID(cid.toString(), platform_PlatformVideoSource.Bilibili);
147
- if (mid) return new id_gen_UniID(mid.toString(), platform_PlatformVideoSource.Bilibili);
148
- if (midHash) return new id_gen_UniID(midHash, platform_PlatformVideoSource.Bilibili);
149
- return this.fromNull(platform_PlatformVideoSource.Bilibili);
150
- }
151
- static fromUnknown(id, domain) {
152
- if (id) return new id_gen_UniID(id, domain);
153
- return this.fromNull(domain);
154
- }
155
- }
156
- function createDMID(dan, slice = 8) {
157
- return new jssha('SHA3-256', 'TEXT').update(`${dan.content}|${dan.mode}|${dan.pool}|${dan.platform}|${dan.extraStr}|${dan.senderID}|${UniDM.transCtime(dan.ctime).toISOString()}`).getHash('HEX').slice(0, slice);
158
- }
159
- function _ts_decorate(decorators, target, key, desc) {
160
- var c = arguments.length, r = c < 3 ? target : null === desc ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
161
- if ("object" == typeof Reflect && "function" == typeof Reflect.decorate) r = Reflect.decorate(decorators, target, key, desc);
162
- else for(var i = decorators.length - 1; i >= 0; i--)if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
163
- return c > 3 && r && Object.defineProperty(target, key, r), r;
164
- }
165
- function _ts_metadata(k, v) {
166
- if ("object" == typeof Reflect && "function" == typeof Reflect.metadata) return Reflect.metadata(k, v);
167
- }
168
- const dm_gen_JSON = json_bigint({
169
- useNativeBigInt: true
170
- });
171
- function cleanEmptyObjects(obj) {
172
- if (null === obj || 'object' != typeof obj) return obj;
173
- if (Array.isArray(obj)) return obj;
174
- const cleaned = {};
175
- for (const [key, value] of Object.entries(obj)){
176
- const cleanedValue = cleanEmptyObjects(value);
177
- if (void 0 !== cleanedValue && ('object' != typeof cleanedValue || 0 !== Object.keys(cleanedValue).length)) cleaned[key] = cleanedValue;
178
- }
179
- return Object.keys(cleaned).length > 0 ? cleaned : {};
180
- }
181
- class SetBin {
182
- constructor(bin){
183
- this.bin = bin;
184
- }
185
- set1(bit) {
186
- this.bin |= 1 << bit;
187
- }
188
- set0(bit) {
189
- this.bin &= ~(1 << bit);
190
- }
191
- }
192
- const toBits = (number)=>{
193
- const bits = [];
194
- do {
195
- bits.unshift(!!(1 & number));
196
- number >>= 1;
197
- }while (number);
198
- return bits.toReversed();
199
- };
200
- var dm_gen_DMAttr = /*#__PURE__*/ function(DMAttr) {
201
- DMAttr["Protect"] = "Protect";
202
- DMAttr["FromLive"] = "FromLive";
203
- DMAttr["HighLike"] = "HighLike";
204
- DMAttr["Compatible"] = "Compatible";
205
- DMAttr["Reported"] = "Reported";
206
- DMAttr["Unchecked"] = "Unchecked";
207
- DMAttr["HasEvent"] = "HasEvent";
208
- DMAttr["Hide"] = "Hide";
209
- return DMAttr;
210
- }({});
211
- const DMAttrUtils = {
212
- fromBin (bin = 0, format) {
213
- const array = toBits(bin);
214
- const attr = [];
215
- if ('bili' === format) {
216
- if (array[0]) attr.push("Protect");
217
- if (array[1]) attr.push("FromLive");
218
- if (array[2]) attr.push("HighLike");
219
- }
220
- return attr;
221
- },
222
- toBin (attr = [], format) {
223
- const bin = new SetBin(0);
224
- if ('bili' === format) {
225
- if (attr.includes("Protect")) bin.set1(0);
226
- if (attr.includes("FromLive")) bin.set1(1);
227
- if (attr.includes("HighLike")) bin.set1(2);
228
- }
229
- return bin.bin;
230
- }
231
- };
232
- var dm_gen_ExtraDanUniChapterType = /*#__PURE__*/ function(ExtraDanUniChapterType) {
233
- ExtraDanUniChapterType["Chapter"] = "ch";
234
- ExtraDanUniChapterType["Review"] = "rev";
235
- ExtraDanUniChapterType["OP"] = "op";
236
- ExtraDanUniChapterType["Intermission"] = "int";
237
- ExtraDanUniChapterType["ED"] = "ed";
238
- ExtraDanUniChapterType["Preview"] = "prvw";
239
- ExtraDanUniChapterType["Cut"] = "cut";
240
- ExtraDanUniChapterType["Duplicate"] = "dup";
241
- ExtraDanUniChapterType["AdBiz"] = "biz";
242
- ExtraDanUniChapterType["AdUnpaid"] = "promo";
243
- return ExtraDanUniChapterType;
244
- }({});
245
- const ExtraDanUniChapterTypeDict = {
246
- chs: {
247
- ch: '其它片段',
248
- rev: '回顾',
249
- op: '片头',
250
- int: '中场',
251
- ed: '片尾',
252
- prvw: '预告',
253
- cut: '删减',
254
- dup: '补档',
255
- biz: '商业广告',
256
- promo: '推广'
257
- }
258
- };
259
- var dm_gen_ExtraDanUniChapterAction = /*#__PURE__*/ function(ExtraDanUniChapterAction) {
260
- ExtraDanUniChapterAction[ExtraDanUniChapterAction["Disabled"] = -1] = "Disabled";
261
- ExtraDanUniChapterAction[ExtraDanUniChapterAction["ShowOverlay"] = 0] = "ShowOverlay";
262
- ExtraDanUniChapterAction[ExtraDanUniChapterAction["ManualSkip"] = 1] = "ManualSkip";
263
- ExtraDanUniChapterAction[ExtraDanUniChapterAction["AutoSkip"] = 2] = "AutoSkip";
264
- return ExtraDanUniChapterAction;
265
- }({});
266
- var dm_gen_Modes = /*#__PURE__*/ function(Modes) {
267
- Modes[Modes["Normal"] = 0] = "Normal";
268
- Modes[Modes["Bottom"] = 1] = "Bottom";
269
- Modes[Modes["Top"] = 2] = "Top";
270
- Modes[Modes["Reverse"] = 3] = "Reverse";
271
- Modes[Modes["Ext"] = 4] = "Ext";
272
- return Modes;
273
- }({});
274
- var dm_gen_Pools = /*#__PURE__*/ function(Pools) {
275
- Pools[Pools["Def"] = 0] = "Def";
276
- Pools[Pools["Sub"] = 1] = "Sub";
277
- Pools[Pools["Adv"] = 2] = "Adv";
278
- Pools[Pools["Ix"] = 3] = "Ix";
279
- return Pools;
280
- }({});
281
- class UniDM {
282
- init(options) {
283
- this.options = options || this.options;
284
- const def = new UniDM();
285
- if (void 0 === this.options.dmid || true === this.options.dmid) this.options.dmid = createDMID;
286
- this.content = String(this.content);
287
- this.ctime = UniDM.transCtime(this.ctime);
288
- if (!this.SOID) this.SOID = def.SOID;
289
- if (!this.progress) this.progress = def.progress;
290
- if (!this.mode) this.mode = def.mode;
291
- if (!this.fontsize) this.fontsize = def.fontsize;
292
- if (!this.color) this.color = def.color;
293
- if (!this.senderID) this.senderID = def.senderID;
294
- if (!this.content) this.content = def.content;
295
- if (!this.ctime) this.ctime = def.ctime;
296
- if (!this.weight) this.weight = def.weight;
297
- if (!this.pool) this.pool = def.pool;
298
- if (!this.attr) this.attr = def.attr;
299
- if (!this.DMID && false !== this.options.dmid) this.DMID = this.toDMID();
300
- this.progress = Number.parseFloat(this.progress.toFixed(3));
301
- if (this.extraStr) this.extraStr = dm_gen_JSON.stringify(cleanEmptyObjects(dm_gen_JSON.parse(this.extraStr)));
302
- if ('{}' === this.extraStr) this.extraStr = void 0;
303
- else if (4 !== this.mode) {
304
- const checkExtraBili = (obj)=>obj ? [
305
- 'adv',
306
- 'bas',
307
- 'code',
308
- 'command'
309
- ].some((k)=>obj[k]) : false;
310
- if (this.extra.artplayer || this.extra.danuni?.chapter || checkExtraBili(this.extra.bili)) this.mode = 4;
311
- }
312
- return this;
313
- }
314
- async validate() {
315
- return validateOrReject(this);
316
- }
317
- static create(pjson, options) {
318
- return pjson ? plainToInstance(UniDM, pjson.extra ? {
319
- ...pjson,
320
- extraStr: pjson.extra ? dm_gen_JSON.stringify(pjson.extra) : pjson.extraStr
321
- } : pjson, {
322
- excludeExtraneousValues: true
323
- }).init(options) : new UniDM();
324
- }
325
- get extra() {
326
- const extra = dm_gen_JSON.parse(this.extraStr || '{}');
327
- return extra;
328
- }
329
- get isFrom3rdPlatform() {
330
- if (this.platform && PlatformDanmakuSources.includes(this.platform)) return true;
331
- return false;
332
- }
333
- toDMID() {
334
- if (false === this.options.dmid) return;
335
- if (true === this.options.dmid) return createDMID(this);
336
- if ('number' == typeof this.options.dmid) return createDMID(this, this.options.dmid);
337
- return this.options.dmid(this);
338
- }
339
- isSameAs(dan, options) {
340
- if (this === dan) return true;
341
- if (4 === this.mode || 4 === dan.mode) return false;
342
- if (!options?.skipDanuniMerge && (this.extra.danuni?.merge || dan.extra.danuni?.merge)) return false;
343
- if (this.extra.bili?.dmid && dan.extra.bili?.dmid) {
344
- if (this.extra.bili.dmid && !dan.extra.bili.dmid || !this.extra.bili.dmid && dan.extra.bili.dmid) return false;
345
- if (this.extra.bili.dmid === dan.extra.bili.dmid) return true;
346
- return false;
347
- }
348
- if (this.extra.artplayer && !dan.extra.artplayer || !this.extra.artplayer && dan.extra.artplayer) return false;
349
- if (this.extra.artplayer && dan.extra.artplayer && (this.extra.artplayer.border !== dan.extra.artplayer.border || dm_gen_JSON.stringify(this.extra.artplayer.style) !== dm_gen_JSON.stringify(dan.extra.artplayer.style))) return false;
350
- const isSame = (k)=>this[k] === dan[k];
351
- const checks = [
352
- 'SOID',
353
- 'content',
354
- 'mode',
355
- 'pool',
356
- 'platform'
357
- ].every((k)=>isSame(k));
358
- return checks;
359
- }
360
- minify() {
361
- const def = new UniDM();
362
- const result = {
363
- SOID: this.SOID
364
- };
365
- if (this.progress !== def.progress) result.progress = this.progress;
366
- if (this.mode !== def.mode) result.mode = this.mode;
367
- if (this.fontsize !== def.fontsize) result.fontsize = this.fontsize;
368
- if (this.color !== def.color) result.color = this.color;
369
- if (this.senderID !== def.senderID) result.senderID = this.senderID;
370
- if (this.content !== def.content) result.content = this.content;
371
- if (this.weight !== def.weight) result.weight = this.weight;
372
- if (this.pool !== def.pool) result.pool = this.pool;
373
- if (this.attr.length > 0) result.attr = this.attr;
374
- if (void 0 !== this.platform) result.platform = this.platform;
375
- if (this.extraStr && '{}' !== this.extraStr) result.extraStr = this.extraStr;
376
- if (void 0 !== this.DMID && this.options.dmid) result.DMID = this.DMID;
377
- return result;
378
- }
379
- downgradeAdvcancedDan({ include, exclude, cleanExtra = false } = {}) {
380
- if (!this.extra) return this;
381
- {
382
- if (!include) include = [];
383
- if (!exclude) exclude = [];
384
- const check = (k)=>include?.includes(k) || !exclude?.includes(k);
385
- const clone = UniDM.create(this);
386
- clone.mode = 2;
387
- if (check('danuni') && clone.extra.danuni) {
388
- const danuni = clone.extra.danuni;
389
- if (danuni.merge) {
390
- const merge = danuni.merge;
391
- clone.content = `${this.content} x${merge.count}`;
392
- } else if (danuni.chapter) {
393
- const chapter = danuni.chapter;
394
- if ("cut" === chapter.type) clone.content = `[提示]${clone.platform}源${ExtraDanUniChapterTypeDict.chs[chapter.type]}了${chapter.duration}秒`;
395
- else if ("dup" === chapter.type) clone.content = `[提示(${ExtraDanUniChapterTypeDict.chs[chapter.type]})]${clone.platform}源-${chapter.duration}秒`;
396
- else clone.content = `[空降(${ExtraDanUniChapterTypeDict.chs[chapter.type]})]${hh_mm_ss.fromS(clone.progress + chapter.duration)}`;
397
- }
398
- } else if (check('bili') && clone.extra.bili) {
399
- const bili = clone.extra.bili;
400
- if (7 === bili.mode && bili.adv) clone.content = `[B站高级弹幕]${dm_gen_JSON.parse(bili.adv)[4] || ''}`;
401
- else if (bili.command) {
402
- const command = bili.command;
403
- clone.content = `[B站指令弹幕]${command.content}`;
404
- clone.fontsize = 36;
405
- }
406
- }
407
- clone.senderID = 'compat[bot]@dan-any';
408
- clone.attr.push("Compatible");
409
- if (cleanExtra) clone.extraStr = void 0;
410
- return clone;
411
- }
412
- }
413
- static transCtime(oriCtime, tsUnit) {
414
- function isMsTs(ts) {
415
- if ('ms' === tsUnit) return true;
416
- if ('s' === tsUnit) return false;
417
- return ts < 100000000;
418
- }
419
- if ('number' == typeof oriCtime || 'bigint' == typeof oriCtime) if (isMsTs(oriCtime)) return new Date(Number(oriCtime));
420
- else return new Date(1000 * Number(oriCtime));
421
- if ('string' != typeof oriCtime) return oriCtime;
422
- if (/^\d+n$/.test(oriCtime)) return new Date(Number(oriCtime.slice(0, -1)));
423
- return new Date(oriCtime);
424
- }
425
- static transMode(oriMode, fmt) {
426
- let mode = 0;
427
- switch(fmt){
428
- case 'bili':
429
- switch(oriMode){
430
- case 4:
431
- mode = 1;
432
- break;
433
- case 5:
434
- mode = 2;
435
- break;
436
- case 6:
437
- mode = 3;
438
- break;
439
- case 7:
440
- mode = 4;
441
- break;
442
- case 8:
443
- mode = 4;
444
- break;
445
- case 9:
446
- mode = 4;
447
- break;
448
- }
449
- break;
450
- case 'dplayer':
451
- if (1 === oriMode) mode = 2;
452
- else if (2 === oriMode) mode = 1;
453
- break;
454
- case 'artplayer':
455
- if (1 === oriMode) mode = 2;
456
- else if (2 === oriMode) mode = 1;
457
- break;
458
- case 'ddplay':
459
- mode = this.transMode(oriMode, 'bili');
460
- break;
461
- default:
462
- mode = 0;
463
- break;
464
- }
465
- return mode;
466
- }
467
- static parseBiliSingle(p, c) {
468
- const p_arr = p.split(',');
469
- return {
470
- content: c,
471
- progress: Number.parseFloat(p_arr[0]),
472
- mode: Number.parseInt(p_arr[1]),
473
- fontsize: Number.parseInt(p_arr[2]),
474
- color: Number.parseInt(p_arr[3]),
475
- ctime: BigInt(p_arr[4]),
476
- pool: Number.parseInt(p_arr[5]),
477
- midHash: p_arr[6],
478
- id: BigInt(p_arr[7]),
479
- weight: Number.parseInt(p_arr[8])
480
- };
481
- }
482
- static fromBili(args, cid, options, recSOID) {
483
- if (args.oid && !cid) cid = args.oid;
484
- const SOID = recSOID || `def_${platform_PlatformVideoSource.Bilibili}+${id_gen_UniID.fromBili({
485
- cid
486
- })}`;
487
- const senderID = isEmail(args.midHash, {
488
- require_tld: false
489
- }) ? args.midHash : id_gen_UniID.fromBili({
490
- midHash: args.midHash
491
- });
492
- let mode;
493
- const pool = args.pool;
494
- const extra = {
495
- bili: {
496
- mode: args.mode,
497
- pool: args.pool,
498
- dmid: args.id,
499
- attr: args.attr,
500
- mid: args.mid
501
- }
502
- };
503
- switch(args.mode){
504
- case 4:
505
- mode = 1;
506
- break;
507
- case 5:
508
- mode = 2;
509
- break;
510
- case 6:
511
- mode = 3;
512
- break;
513
- case 7:
514
- mode = 4;
515
- extra.bili.adv = args.content;
516
- break;
517
- case 8:
518
- mode = 4;
519
- extra.bili.code = args.content;
520
- break;
521
- case 9:
522
- mode = 4;
523
- extra.bili.bas = args.content;
524
- break;
525
- default:
526
- mode = 0;
527
- break;
528
- }
529
- return this.create({
530
- ...args,
531
- SOID,
532
- mode,
533
- senderID: senderID.toString(),
534
- ctime: this.transCtime(args.ctime, 's'),
535
- weight: args.weight || (3 === pool ? 1 : 0),
536
- pool,
537
- attr: DMAttrUtils.fromBin(args.attr, platform_PlatformVideoSource.Bilibili),
538
- platform: platform_PlatformVideoSource.Bilibili,
539
- extra
540
- }, options);
541
- }
542
- toBiliXML(options) {
543
- if (options?.skipBiliCommand && this.extra.bili?.command) return null;
544
- const recMode = (mode, extra)=>{
545
- switch(mode){
546
- case 0:
547
- return 1;
548
- case 1:
549
- return 4;
550
- case 2:
551
- return 5;
552
- case 3:
553
- return 6;
554
- case 4:
555
- if (!extra) return 1;
556
- if (extra.adv) return 7;
557
- if (extra.code) return 8;
558
- else if (extra.bas) return 9;
559
- else return 1;
560
- default:
561
- return 1;
562
- }
563
- };
564
- const rMode = this.extra.bili?.mode || recMode(this.mode, this.extra?.bili);
565
- let content;
566
- switch(rMode){
567
- case 7:
568
- content = this.extra?.bili?.adv;
569
- break;
570
- case 8:
571
- content = this.extra?.bili?.code;
572
- break;
573
- case 9:
574
- content = this.extra?.bili?.bas;
575
- break;
576
- default:
577
- content = this.content;
578
- break;
579
- }
580
- return {
581
- '#text': content ?? this.content,
582
- '@_p': [
583
- this.progress,
584
- rMode,
585
- this.fontsize,
586
- this.color,
587
- this.ctime.getTime() / 1000,
588
- this.extra.bili?.pool || this.pool,
589
- options?.avoidSenderIDWithAt ? this.senderID.replaceAll(`@${platform_PlatformVideoSource.Bilibili}`, '') : this.senderID,
590
- this.extra.bili?.dmid || this.DMID || this.toDMID(),
591
- this.weight
592
- ].join(',')
593
- };
594
- }
595
- static fromBiliCommand(args, cid, options) {
596
- if (args.oid && !cid) cid = args.oid;
597
- const SOID = `def_${platform_PlatformVideoSource.Bilibili}+${id_gen_UniID.fromBili({
598
- cid
599
- })}`;
600
- const senderID = id_gen_UniID.fromBili({
601
- mid: args.mid
602
- });
603
- return this.create({
604
- ...args,
605
- SOID,
606
- mode: 4,
607
- senderID: senderID.toString(),
608
- ctime: new Date(`${args.ctime} GMT+0800`),
609
- weight: 11,
610
- pool: 2,
611
- attr: [
612
- "Protect"
613
- ],
614
- platform: platform_PlatformVideoSource.Bilibili,
615
- extra: {
616
- bili: {
617
- dmid: args.id,
618
- attr: args.attr,
619
- mid: args.mid,
620
- command: args
621
- }
622
- }
623
- }, options);
624
- }
625
- static fromDplayer(args, playerID, domain, options) {
626
- const SOID = id_gen_UniID.fromUnknown(playerID, domain);
627
- const senderID = id_gen_UniID.fromUnknown(args.midHash, domain);
628
- return this.create({
629
- ...args,
630
- SOID: SOID.toString(),
631
- mode: this.transMode(args.mode, 'dplayer'),
632
- senderID: senderID.toString(),
633
- platform: domain
634
- }, options);
635
- }
636
- toDplayer() {
637
- let mode = 0;
638
- if (2 === this.mode) mode = 1;
639
- else if (1 === this.mode) mode = 2;
640
- return {
641
- mode,
642
- progress: this.progress,
643
- color: this.color,
644
- midHash: this.senderID,
645
- content: this.content
646
- };
647
- }
648
- static fromArtplayer(args, playerID, domain, options) {
649
- const SOID = id_gen_UniID.fromUnknown(playerID, domain);
650
- const senderID = id_gen_UniID.fromUnknown('', domain);
651
- let extra = args.border ? {
652
- artplayer: {
653
- border: args.border,
654
- style: {}
655
- }
656
- } : void 0;
657
- if (args.style) extra = extra ? {
658
- ...extra,
659
- artplayer: {
660
- ...extra.artplayer,
661
- style: args.style
662
- }
663
- } : {
664
- artplayer: {
665
- style: args.style
666
- }
667
- };
668
- return this.create({
669
- ...args,
670
- SOID: SOID.toString(),
671
- mode: this.transMode(args.mode, 'artplayer'),
672
- senderID: senderID.toString(),
673
- platform: domain,
674
- extra
675
- }, options);
676
- }
677
- toArtplayer() {
678
- let mode = 0;
679
- if (2 === this.mode) mode = 1;
680
- else if (1 === this.mode) mode = 2;
681
- return {
682
- progress: this.progress,
683
- mode,
684
- color: this.color,
685
- content: this.content,
686
- border: this.extra.artplayer?.border,
687
- style: this.extra.artplayer?.style
688
- };
689
- }
690
- static fromDDPlay(args, episodeId, domain = platform_PlatformDanmakuOnlySource.DanDanPlay, options) {
691
- const SOID = id_gen_UniID.fromUnknown(`def_${platform_PlatformDanmakuOnlySource.DanDanPlay}+${episodeId}`, domain);
692
- return this.create({
693
- ...args,
694
- SOID: SOID.toString(),
695
- mode: this.transMode(args.mode, 'ddplay'),
696
- senderID: args.uid,
697
- content: args.m,
698
- platform: domain,
699
- DMID: args.cid.toString()
700
- }, options);
701
- }
702
- toDDPlay() {
703
- let mode = 1;
704
- if (2 === this.mode) mode = 5;
705
- else if (1 === this.mode) mode = 4;
706
- return {
707
- progress: this.progress,
708
- mode,
709
- color: this.color,
710
- uid: this.senderID,
711
- m: this.content,
712
- cid: this.DMID ? BigInt(`0x${Buffer.from(this.DMID).toString('hex')}`) : 0n
713
- };
714
- }
715
- constructor(){
716
- this.SOID = id_gen_UniID.fromNull().toString();
717
- this.progress = 0;
718
- this.mode = 0;
719
- this.fontsize = 25;
720
- this.color = 16777215;
721
- this.senderID = id_gen_UniID.fromNull().toString();
722
- this.content = '';
723
- this.ctime = new Date();
724
- this.weight = 0;
725
- this.pool = 0;
726
- this.attr = [];
727
- this.options = {
728
- dmid: createDMID
729
- };
730
- }
731
- }
732
- _ts_decorate([
733
- IsEmail({
734
- require_tld: false
735
- }),
736
- IsString(),
737
- IsNotEmpty(),
738
- Expose(),
739
- _ts_metadata("design:type", String)
740
- ], UniDM.prototype, "SOID", void 0);
741
- _ts_decorate([
742
- Min(0),
743
- IsNumber(),
744
- IsNotEmpty(),
745
- Expose(),
746
- _ts_metadata("design:type", Number)
747
- ], UniDM.prototype, "progress", void 0);
748
- _ts_decorate([
749
- IsEnum(dm_gen_Modes),
750
- IsNotEmpty(),
751
- Expose(),
752
- _ts_metadata("design:type", Number)
753
- ], UniDM.prototype, "mode", void 0);
754
- _ts_decorate([
755
- Max(64),
756
- Min(12),
757
- IsNumber(),
758
- IsNotEmpty(),
759
- Expose(),
760
- _ts_metadata("design:type", Number)
761
- ], UniDM.prototype, "fontsize", void 0);
762
- _ts_decorate([
763
- IsNumber(),
764
- IsNotEmpty(),
765
- Expose(),
766
- _ts_metadata("design:type", Number)
767
- ], UniDM.prototype, "color", void 0);
768
- _ts_decorate([
769
- IsEmail({
770
- require_tld: false
771
- }),
772
- IsString(),
773
- IsNotEmpty(),
774
- Expose(),
775
- _ts_metadata("design:type", String)
776
- ], UniDM.prototype, "senderID", void 0);
777
- _ts_decorate([
778
- IsString(),
779
- IsNotEmpty(),
780
- Expose(),
781
- _ts_metadata("design:type", String)
782
- ], UniDM.prototype, "content", void 0);
783
- _ts_decorate([
784
- IsDate(),
785
- IsNotEmpty(),
786
- Expose(),
787
- _ts_metadata("design:type", "u" < typeof Date ? Object : Date)
788
- ], UniDM.prototype, "ctime", void 0);
789
- _ts_decorate([
790
- Max(11),
791
- Min(0),
792
- IsInt(),
793
- IsNotEmpty(),
794
- Expose(),
795
- _ts_metadata("design:type", Number)
796
- ], UniDM.prototype, "weight", void 0);
797
- _ts_decorate([
798
- IsEnum(dm_gen_Pools),
799
- IsNotEmpty(),
800
- Expose(),
801
- _ts_metadata("design:type", Number)
802
- ], UniDM.prototype, "pool", void 0);
803
- _ts_decorate([
804
- IsEnum(dm_gen_DMAttr, {
805
- each: true
806
- }),
807
- IsNotEmpty(),
808
- Expose(),
809
- _ts_metadata("design:type", Array)
810
- ], UniDM.prototype, "attr", void 0);
811
- _ts_decorate([
812
- IsString(),
813
- IsOptional(),
814
- Expose(),
815
- _ts_metadata("design:type", Object)
816
- ], UniDM.prototype, "platform", void 0);
817
- _ts_decorate([
818
- IsString(),
819
- IsOptional(),
820
- Expose(),
821
- _ts_metadata("design:type", String)
822
- ], UniDM.prototype, "extraStr", void 0);
823
- _ts_decorate([
824
- IsString(),
825
- IsOptional(),
826
- Expose(),
827
- _ts_metadata("design:type", String)
828
- ], UniDM.prototype, "DMID", void 0);
829
- _ts_decorate([
830
- Expose(),
831
- _ts_metadata("design:type", Function),
832
- _ts_metadata("design:paramtypes", [
833
- "u" < typeof Options ? Object : Options
834
- ]),
835
- _ts_metadata("design:returntype", void 0)
836
- ], UniDM.prototype, "init", null);
837
- _ts_decorate([
838
- Expose(),
839
- _ts_metadata("design:type", Function),
840
- _ts_metadata("design:paramtypes", []),
841
- _ts_metadata("design:returntype", Promise)
842
- ], UniDM.prototype, "validate", null);
843
- _ts_decorate([
844
- Expose(),
845
- _ts_metadata("design:type", "u" < typeof Extra ? Object : Extra),
846
- _ts_metadata("design:paramtypes", [])
847
- ], UniDM.prototype, "extra", null);
848
- _ts_decorate([
849
- Expose(),
850
- _ts_metadata("design:type", void 0),
851
- _ts_metadata("design:paramtypes", [])
852
- ], UniDM.prototype, "isFrom3rdPlatform", null);
853
- _ts_decorate([
854
- Expose(),
855
- _ts_metadata("design:type", Function),
856
- _ts_metadata("design:paramtypes", []),
857
- _ts_metadata("design:returntype", void 0)
858
- ], UniDM.prototype, "toDMID", null);
859
- _ts_decorate([
860
- Expose(),
861
- _ts_metadata("design:type", Function),
862
- _ts_metadata("design:paramtypes", [
863
- Object,
864
- Object
865
- ]),
866
- _ts_metadata("design:returntype", Boolean)
867
- ], UniDM.prototype, "isSameAs", null);
868
- _ts_decorate([
869
- Expose(),
870
- _ts_metadata("design:type", Function),
871
- _ts_metadata("design:paramtypes", []),
872
- _ts_metadata("design:returntype", void 0)
873
- ], UniDM.prototype, "minify", null);
874
- _ts_decorate([
875
- Expose(),
876
- _ts_metadata("design:type", Function),
877
- _ts_metadata("design:paramtypes", [
878
- Object
879
- ]),
880
- _ts_metadata("design:returntype", void 0)
881
- ], UniDM.prototype, "downgradeAdvcancedDan", null);
882
- _ts_decorate([
883
- Expose(),
884
- _ts_metadata("design:type", Function),
885
- _ts_metadata("design:paramtypes", [
886
- Object
887
- ]),
888
- _ts_metadata("design:returntype", void 0)
889
- ], UniDM.prototype, "toBiliXML", null);
890
- _ts_decorate([
891
- Expose(),
892
- _ts_metadata("design:type", Function),
893
- _ts_metadata("design:paramtypes", []),
894
- _ts_metadata("design:returntype", "u" < typeof DMDplayer ? Object : DMDplayer)
895
- ], UniDM.prototype, "toDplayer", null);
896
- _ts_decorate([
897
- Expose(),
898
- _ts_metadata("design:type", Function),
899
- _ts_metadata("design:paramtypes", []),
900
- _ts_metadata("design:returntype", "u" < typeof DMArtplayer ? Object : DMArtplayer)
901
- ], UniDM.prototype, "toArtplayer", null);
902
- _ts_decorate([
903
- Expose(),
904
- _ts_metadata("design:type", Function),
905
- _ts_metadata("design:paramtypes", []),
906
- _ts_metadata("design:returntype", "u" < typeof DMDDPlay ? Object : DMDDPlay)
907
- ], UniDM.prototype, "toDDPlay", null);
908
- const DanmakuType = {
909
- SCROLL: 1,
910
- BOTTOM: 2,
911
- TOP: 3
912
- };
913
- const FontSize = {
914
- SMALL: 0,
915
- NORMAL: 1,
916
- LARGE: 2
917
- };
918
- function decimalToRGB888(decimal) {
919
- const r = decimal >> 16 & 0xff;
920
- const g = decimal >> 8 & 0xff;
921
- const b = 0xff & decimal;
922
- return {
923
- r,
924
- g,
925
- b
926
- };
927
- }
928
- function UniPool2DanmakuLists(UP) {
929
- const dans = UP.dans;
930
- let type = DanmakuType.SCROLL;
931
- return dans.map((d)=>{
932
- if (d.mode === dm_gen_Modes.Bottom) type = DanmakuType.BOTTOM;
933
- else if (d.mode === dm_gen_Modes.Top) type = DanmakuType.TOP;
934
- return {
935
- time: d.progress,
936
- type,
937
- fontSizeType: d.fontsize,
938
- content: d.content,
939
- color: decimalToRGB888(d.color),
940
- extra: d
941
- };
942
- });
943
- }
944
- function DanmakuList2UniPool(d, options) {
945
- return new UniPool(d.map((d)=>UniDM.create(d.extra)), options);
946
- }
947
- const lang_assign = (source, ...targets)=>{
948
- for (const target of targets)for (const key of Object.keys(target))source[key] = target[key];
949
- return source;
950
- };
951
- const arrayOfLength = (length, defaultValue)=>{
952
- const array = new Array(length);
953
- for(let i = 0; i < length; i++)array[i] = defaultValue;
954
- return array;
955
- };
956
- const computeScrollInTime = (rectWidth, screenWidth, scrollTime)=>{
957
- const speed = (screenWidth + rectWidth) / scrollTime;
958
- return rectWidth / speed;
959
- };
960
- const computeScrollOverTime = (rectWidth, screenWidth, scrollTime)=>{
961
- const speed = (screenWidth + rectWidth) / scrollTime;
962
- return screenWidth / speed;
963
- };
964
- const splitGrids = ({ fontSize, padding, playResY, bottomSpace })=>{
965
- const defaultFontSize = fontSize[FontSize.NORMAL];
966
- const paddingTop = padding[0];
967
- const paddingBottom = padding[2];
968
- const linesCount = Math.floor((playResY - bottomSpace) / (defaultFontSize + paddingTop + paddingBottom));
969
- return {
970
- 1: arrayOfLength(linesCount, {
971
- start: 0,
972
- end: 0,
973
- width: 0
974
- }),
975
- 3: arrayOfLength(linesCount, 0),
976
- 2: arrayOfLength(linesCount, 0)
977
- };
978
- };
979
- const measureTextWidthConstructor = (canvasContext)=>{
980
- const supportTextMeasure = !!canvasContext.measureText('中');
981
- if (supportTextMeasure) return (fontName, fontSize, bold, text)=>{
982
- canvasContext.font = `${bold ? 'bold' : 'normal'} ${fontSize}px ${fontName}`;
983
- const textWidth = canvasContext.measureText(text).width;
984
- return Math.round(textWidth);
985
- };
986
- console.warn('[Warn] node-canvas is installed without text measure support, layout may not be correct');
987
- return (_fontName, fontSize, _bold, text)=>text.length * fontSize;
988
- };
989
- const resolveAvailableFixGrid = (grids, time)=>{
990
- for (const [i, grid] of grids.entries())if (grid <= time) return i;
991
- return -1;
992
- };
993
- const resolveAvailableScrollGrid = (grids, rectWidth, screenWidth, time, duration)=>{
994
- for (const [i, previous] of grids.entries()){
995
- const previousInTime = previous.start + computeScrollInTime(previous.width, screenWidth, duration);
996
- const currentOverTime = time + computeScrollOverTime(rectWidth, screenWidth, duration);
997
- if (time >= previousInTime && currentOverTime >= previous.end) return i;
998
- }
999
- return -1;
1000
- };
1001
- const initializeLayout = (config, canvasCtx)=>{
1002
- const { playResX, playResY, fontName, fontSize, bold, padding, scrollTime, fixTime, bottomSpace } = config;
1003
- const [paddingTop, paddingRight, paddingBottom, paddingLeft] = padding;
1004
- const defaultFontSize = fontSize[FontSize.NORMAL];
1005
- const grids = splitGrids(config);
1006
- const gridHeight = defaultFontSize + paddingTop + paddingBottom;
1007
- return (danmaku)=>{
1008
- const targetGrids = grids[danmaku.type];
1009
- const danmakuFontSize = fontSize[danmaku.fontSizeType];
1010
- const rectWidth = measureTextWidthConstructor(canvasCtx)(fontName, danmakuFontSize, bold, danmaku.content) + paddingLeft + paddingRight;
1011
- const verticalOffset = paddingTop + Math.round((defaultFontSize - danmakuFontSize) / 2);
1012
- if (danmaku.type === DanmakuType.SCROLL) {
1013
- const scrollGrids = targetGrids;
1014
- const gridNumber = resolveAvailableScrollGrid(scrollGrids, rectWidth, playResX, danmaku.time, scrollTime);
1015
- if (gridNumber < 0) return null;
1016
- targetGrids[gridNumber] = {
1017
- width: rectWidth,
1018
- start: danmaku.time,
1019
- end: danmaku.time + scrollTime
1020
- };
1021
- const top = gridNumber * gridHeight + verticalOffset;
1022
- const start = playResX + paddingLeft;
1023
- const end = -rectWidth;
1024
- return {
1025
- ...danmaku,
1026
- top,
1027
- start,
1028
- end
1029
- };
1030
- }
1031
- {
1032
- const gridNumber = resolveAvailableFixGrid(targetGrids, danmaku.time);
1033
- if (gridNumber < 0) return null;
1034
- if (danmaku.type === DanmakuType.TOP) {
1035
- targetGrids[gridNumber] = danmaku.time + fixTime;
1036
- const top = gridNumber * gridHeight + verticalOffset;
1037
- const left = Math.round(playResX / 2);
1038
- return {
1039
- ...danmaku,
1040
- top,
1041
- left
1042
- };
1043
- }
1044
- targetGrids[gridNumber] = danmaku.time + fixTime;
1045
- const top = playResY - bottomSpace - gridHeight * gridNumber - gridHeight + verticalOffset;
1046
- const left = Math.round(playResX / 2);
1047
- return {
1048
- ...danmaku,
1049
- top,
1050
- left
1051
- };
1052
- }
1053
- };
1054
- };
1055
- const layoutDanmaku = (inputList, config, canvasCtx)=>{
1056
- const list = [
1057
- ...UniPool2DanmakuLists(inputList)
1058
- ].toSorted((x, y)=>x.time - y.time);
1059
- const layout = initializeLayout(config, canvasCtx);
1060
- return DanmakuList2UniPool(list.map(layout).filter((danmaku)=>!!danmaku));
1061
- };
1062
- const formatTime = (seconds)=>{
1063
- const div = (i, j)=>Math.floor(i / j);
1064
- const pad = (n)=>n < 10 ? `0${n}` : String(n);
1065
- const integer = Math.floor(seconds);
1066
- const hour = div(integer, 3600);
1067
- const minute = div(integer, 60) % 60;
1068
- const second = integer % 60;
1069
- const minorSecond = Math.floor((seconds - integer) * 100);
1070
- return `${hour}:${pad(minute)}:${pad(second)}.${minorSecond}`;
1071
- };
1072
- const encode = (text)=>text.toString().replaceAll('{', '{').replaceAll('}', '}').replaceAll(/\r|\n/g, '');
1073
- const scrollCommand = ({ start, end, top })=>String.raw`\move(${start},${top},${end},${top})`;
1074
- const fixCommand = ({ top, left })=>String.raw`\an8\pos(${left},${top})`;
1075
- const colorCommand = (color)=>String.raw`\c${formatColor(color)}`;
1076
- const borderColorCommand = (color)=>String.raw`\3c${formatColor(color)}`;
1077
- const dialogue = (danmaku, config)=>{
1078
- const { fontSizeType, content, time } = danmaku;
1079
- const { scrollTime, fixTime } = config;
1080
- const commands = [
1081
- danmaku.type === DanmakuType.SCROLL ? scrollCommand({
1082
- start: danmaku.start,
1083
- end: danmaku.end,
1084
- top: danmaku.top
1085
- }) : fixCommand({
1086
- top: danmaku.top,
1087
- left: danmaku.left
1088
- }),
1089
- isWhite(danmaku.color) ? '' : colorCommand(danmaku.color),
1090
- isWhite(danmaku.color) ? '' : borderColorCommand(getDecoratingColor(danmaku.color))
1091
- ];
1092
- const fields = [
1093
- 0,
1094
- formatTime(time),
1095
- formatTime(time + (danmaku.type === DanmakuType.SCROLL ? scrollTime : fixTime)),
1096
- `F${fontSizeType}`,
1097
- '',
1098
- '0000',
1099
- '0000',
1100
- '0000',
1101
- '',
1102
- `{${commands.join('')}}${encode(content)}`
1103
- ];
1104
- return `Dialogue: ${fields.join(',')}`;
1105
- };
1106
- const calculateDanmakuPosition = (danmaku, config)=>{
1107
- const { playResX, playResY, scrollTime, fixTime } = config;
1108
- switch(danmaku.type){
1109
- case DanmakuType.SCROLL:
1110
- {
1111
- const start = playResX;
1112
- const end = -playResX / 10;
1113
- const top = danmaku.fontSizeType * playResY / 20;
1114
- return {
1115
- ...danmaku,
1116
- start,
1117
- end,
1118
- top,
1119
- left: 0,
1120
- duration: scrollTime
1121
- };
1122
- }
1123
- case DanmakuType.TOP:
1124
- case DanmakuType.BOTTOM:
1125
- {
1126
- const left = playResX / 2;
1127
- const top = danmaku.type === DanmakuType.TOP ? danmaku.fontSizeType * playResY / 20 : playResY - config.bottomSpace - danmaku.fontSizeType * playResY / 20;
1128
- return {
1129
- ...danmaku,
1130
- start: 0,
1131
- end: 0,
1132
- top,
1133
- left,
1134
- duration: fixTime
1135
- };
1136
- }
1137
- default:
1138
- throw new Error(`Unknown danmaku type: ${danmaku.type}`);
1139
- }
1140
- };
1141
- const event_event = (list, config)=>{
1142
- const content = [
1143
- '[Events]',
1144
- 'Format: Layer, Start, End, Style, Name, MarginL, MarginR, MarginV, Effect, Text',
1145
- ...list.map((danmaku)=>{
1146
- const positionedDanmaku = calculateDanmakuPosition(danmaku, config);
1147
- return dialogue(positionedDanmaku, config);
1148
- })
1149
- ];
1150
- return content.join('\n');
1151
- };
1152
- const info_info = ({ playResX, playResY }, { filename, title })=>{
1153
- const content = [
1154
- '[Script Info]',
1155
- `Title: ${title}`,
1156
- `Original Script: 根据 ${filename} 的弹幕信息,由 ${package_namespaceObject.TB} 生成`,
1157
- 'ScriptType: v4.00+',
1158
- 'Collisions: Reverse',
1159
- `PlayResX: ${playResX}`,
1160
- `PlayResY: ${playResY}`,
1161
- 'Timer: 100.0000'
1162
- ];
1163
- return content.join('\n');
1164
- };
1165
- const compressTypes = new Set([
1166
- 'brotli',
1167
- 'gzip'
1168
- ]);
1169
- const baseTypes = new Set([
1170
- 'base64',
1171
- 'base18384'
1172
- ]);
1173
- function fromUint16Array(array) {
1174
- let result = '';
1175
- for (const element of array)result += String.fromCodePoint(element);
1176
- return result;
1177
- }
1178
- function raw_raw(list, config, context, compressType = 'brotli', baseType = 'base18384') {
1179
- const raw1 = {
1180
- list,
1181
- config,
1182
- context
1183
- };
1184
- const rawText = JSON.stringify(raw1);
1185
- let compress;
1186
- compress = 'brotli' === compressType ? brotliCompressSync(rawText) : gzipSync(rawText);
1187
- return `;RawCompressType: ${compressType}\n;RawBaseType: ${baseType}\n;Raw: ${'base64' === baseType ? compress.toString('base64') : fromUint16Array(__rspack_external_base16384.encode(compress))}`;
1188
- }
1189
- function deRaw(ass) {
1190
- const arr = ass.split('\n');
1191
- const lineCompressType = arr.find((line)=>line.startsWith(';RawCompressType:'));
1192
- const lineBaseType = arr.find((line)=>line.startsWith(';RawBaseType:'));
1193
- const lineRaw = arr.find((line)=>line.startsWith(';Raw:'));
1194
- if (!lineCompressType || !lineBaseType || !lineRaw) return;
1195
- {
1196
- let compressType = lineCompressType.replace(';RawCompressType: ', '').trim();
1197
- let baseType = lineBaseType.replace(';RawBaseType: ', '').trim();
1198
- if (!compressTypes.has(compressType)) compressType = 'gzip';
1199
- if (!baseTypes.has(baseType)) baseType = 'base64';
1200
- const text = lineRaw.replace(';Raw: ', '').trim();
1201
- const buffer = 'base64' === baseType ? Buffer.from(text, 'base64') : Buffer.from(__rspack_external_base16384.decode(Buffer.from(text, 'utf8').toString('utf8')));
1202
- let decompress;
1203
- decompress = 'brotli' === compressType ? brotliDecompressSync(buffer) : gunzipSync(buffer);
1204
- try {
1205
- return JSON.parse(decompress.toString('utf8'));
1206
- } catch {
1207
- return;
1208
- }
1209
- }
1210
- }
1211
- const style = ({ fontName, fontSize, color: configColor, outlineColor, backColor, bold, outline, shadow, opacity })=>{
1212
- const fields = [
1213
- 'Name',
1214
- 'Fontname',
1215
- 'Fontsize',
1216
- 'PrimaryColour',
1217
- 'SecondaryColour',
1218
- 'OutlineColour',
1219
- 'BackColour',
1220
- 'Bold',
1221
- 'Italic',
1222
- 'Underline',
1223
- 'StrikeOut',
1224
- 'ScaleX',
1225
- 'ScaleY',
1226
- 'Spacing',
1227
- 'Angle',
1228
- 'BorderStyle',
1229
- 'Outline',
1230
- 'Shadow',
1231
- 'Alignment',
1232
- 'MarginL',
1233
- 'MarginR',
1234
- 'MarginV',
1235
- 'Encoding'
1236
- ];
1237
- const primaryColorValue = formatColor(hexColorToRGB(configColor), opacity);
1238
- const secondaryColor = getDecoratingColor(hexColorToRGB(configColor));
1239
- const outlineColorValue = formatColor(outlineColor ? hexColorToRGB(outlineColor) : secondaryColor, opacity);
1240
- const backColorValue = formatColor(backColor ? hexColorToRGB(backColor) : secondaryColor, opacity);
1241
- const colorStyle = `${primaryColorValue},${primaryColorValue},${outlineColorValue},${backColorValue}`;
1242
- const boldValue = bold ? '1' : '0';
1243
- const fontStyle = `${boldValue},0,0,0,100,100,0,0,1,${outline},${shadow},7,0,0,0,0`;
1244
- const fontDeclaration = (size, i)=>`Style: F${i},${fontName},${size},${colorStyle},${fontStyle}`;
1245
- const content = [
1246
- '[V4+ Styles]',
1247
- `Format: ${fields.join(',')}`,
1248
- ...fontSize.map(fontDeclaration)
1249
- ];
1250
- return content.join('\n');
1251
- };
1252
- const default_context = {
1253
- filename: 'unknown',
1254
- title: 'unknown'
1255
- };
1256
- const create_ass = (list, rawList, config, context = default_context, rawConfig)=>{
1257
- const Elist = UniPool2DanmakuLists(list);
1258
- const ErawList = UniPool2DanmakuLists(rawList);
1259
- const content = [
1260
- info_info(config, context),
1261
- style(config),
1262
- event_event(Elist, config)
1263
- ];
1264
- if (config.includeRaw) content.push(raw_raw(ErawList, config, context, rawConfig?.compressType, rawConfig?.baseType));
1265
- return `${content.join('\n\n')}\n`;
1266
- };
1267
- const getConfig = (overrides = {})=>{
1268
- const defaults = {
1269
- fontSize: [
1270
- 25,
1271
- 25,
1272
- 36
1273
- ],
1274
- fontName: 'SimHei',
1275
- color: '#ffffff',
1276
- outlineColor: void 0,
1277
- backColor: void 0,
1278
- outline: 2,
1279
- shadow: 0,
1280
- bold: false,
1281
- padding: [
1282
- 2,
1283
- 2,
1284
- 2,
1285
- 2
1286
- ],
1287
- playResX: 1920,
1288
- playResY: 1080,
1289
- scrollTime: 8,
1290
- fixTime: 4,
1291
- opacity: 0.6,
1292
- bottomSpace: 60,
1293
- includeRaw: true,
1294
- mergeIn: -1
1295
- };
1296
- const config = lang_assign(defaults, overrides);
1297
- config.color = formatColor(hexColorToRGB(config.color));
1298
- config.outlineColor = config.outlineColor && formatColor(hexColorToRGB(config.outlineColor));
1299
- config.backColor = config.backColor && formatColor(hexColorToRGB(config.backColor));
1300
- return config;
1301
- };
1302
- function generateASS(danmaku, options, canvasCtx) {
1303
- const config = getConfig(options.substyle);
1304
- const mergedList = danmaku.merge(config.mergeIn);
1305
- const layoutList = layoutDanmaku(mergedList, config, canvasCtx);
1306
- const content = create_ass(layoutList, danmaku, config, {
1307
- filename: options?.filename || 'unknown',
1308
- title: options?.title || 'unknown'
1309
- }, options.raw);
1310
- return content;
1311
- }
1312
- function parseAssRawField(ass, options) {
1313
- const raw = deRaw(ass);
1314
- if (raw) return DanmakuList2UniPool(raw.list, options);
1315
- return UniPool.create();
1316
- }
1317
- const file_bilibili_community_service_dm_v1_dm = /*@__PURE__*/ fileDesc("CiliaWxpYmlsaS9jb21tdW5pdHkvc2VydmljZS9kbS92MS9kbS5wcm90bxIgYmlsaWJpbGkuY29tbXVuaXR5LnNlcnZpY2UuZG0udjEiZAoGQXZhdGFyEgoKAmlkGAEgASgJEgsKA3VybBgCIAEoCRJBCgthdmF0YXJfdHlwZRgDIAEoDjIsLmJpbGliaWxpLmNvbW11bml0eS5zZXJ2aWNlLmRtLnYxLkF2YXRhclR5cGUiIwoGQnViYmxlEgwKBHRleHQYASABKAkSCwoDdXJsGAIgASgJIsYBCghCdWJibGVWMhIMCgR0ZXh0GAEgASgJEgsKA3VybBgCIAEoCRJBCgtidWJibGVfdHlwZRgDIAEoDjIsLmJpbGliaWxpLmNvbW11bml0eS5zZXJ2aWNlLmRtLnYxLkJ1YmJsZVR5cGUSFQoNZXhwb3N1cmVfb25jZRgEIAEoCBJFCg1leHBvc3VyZV90eXBlGAUgASgOMi4uYmlsaWJpbGkuY29tbXVuaXR5LnNlcnZpY2UuZG0udjEuRXhwb3N1cmVUeXBlIlsKBkJ1dHRvbhIMCgR0ZXh0GAEgASgJEkMKBmFjdGlvbhgCIAEoDjIzLmJpbGliaWxpLmNvbW11bml0eS5zZXJ2aWNlLmRtLnYxLlRvYXN0RnVuY3Rpb25UeXBlIlgKDkJ1enp3b3JkQ29uZmlnEkYKCGtleXdvcmRzGAEgAygLMjQuYmlsaWJpbGkuY29tbXVuaXR5LnNlcnZpY2UuZG0udjEuQnV6endvcmRTaG93Q29uZmlnIngKEkJ1enp3b3JkU2hvd0NvbmZpZxIMCgRuYW1lGAEgASgJEg4KBnNjaGVtYRgCIAEoCRIOCgZzb3VyY2UYAyABKAUSCgoCaWQYBCABKAMSEwoLYnV6endvcmRfaWQYBSABKAMSEwoLc2NoZW1hX3R5cGUYBiABKAUiewoIQ2hlY2tCb3gSDAoEdGV4dBgBIAEoCRI8CgR0eXBlGAIgASgOMi4uYmlsaWJpbGkuY29tbXVuaXR5LnNlcnZpY2UuZG0udjEuQ2hlY2tib3hUeXBlEhUKDWRlZmF1bHRfdmFsdWUYAyABKAgSDAoEc2hvdxgEIAEoCCJvCgpDaGVja0JveFYyEgwKBHRleHQYASABKAkSPAoEdHlwZRgCIAEoDjIuLmJpbGliaWxpLmNvbW11bml0eS5zZXJ2aWNlLmRtLnYxLkNoZWNrYm94VHlwZRIVCg1kZWZhdWx0X3ZhbHVlGAMgASgIIoICCgtDbGlja0J1dHRvbhIVCg1wb3J0cmFpdF90ZXh0GAEgAygJEhYKDmxhbmRzY2FwZV90ZXh0GAIgAygJEhsKE3BvcnRyYWl0X3RleHRfZm9jdXMYAyADKAkSHAoUbGFuZHNjYXBlX3RleHRfZm9jdXMYBCADKAkSQQoLcmVuZGVyX3R5cGUYBSABKA4yLC5iaWxpYmlsaS5jb21tdW5pdHkuc2VydmljZS5kbS52MS5SZW5kZXJUeXBlEgwKBHNob3cYBiABKAgSOAoGYnViYmxlGAcgASgLMiguYmlsaWJpbGkuY29tbXVuaXR5LnNlcnZpY2UuZG0udjEuQnViYmxlIrMCCg1DbGlja0J1dHRvblYyEhUKDXBvcnRyYWl0X3RleHQYASADKAkSFgoObGFuZHNjYXBlX3RleHQYAiADKAkSGwoTcG9ydHJhaXRfdGV4dF9mb2N1cxgDIAMoCRIcChRsYW5kc2NhcGVfdGV4dF9mb2N1cxgEIAMoCRJBCgtyZW5kZXJfdHlwZRgFIAEoDjIsLmJpbGliaWxpLmNvbW11bml0eS5zZXJ2aWNlLmRtLnYxLlJlbmRlclR5cGUSFwoPdGV4dF9pbnB1dF9wb3N0GAYgASgIEhUKDWV4cG9zdXJlX29uY2UYByABKAgSRQoNZXhwb3N1cmVfdHlwZRgIIAEoDjIuLmJpbGliaWxpLmNvbW11bml0eS5zZXJ2aWNlLmRtLnYxLkV4cG9zdXJlVHlwZSJLCgdDb21tYW5kEkAKC2NvbW1hbmRfZG1zGAEgAygLMisuYmlsaWJpbGkuY29tbXVuaXR5LnNlcnZpY2UuZG0udjEuQ29tbWFuZERtIuYBCglDb21tYW5kRG0SCgoCaWQYASABKAMSCwoDb2lkGAIgASgDEgsKA21pZBgDIAEoAxIPCgdjb21tYW5kGAQgASgJEg8KB2NvbnRlbnQYBSABKAkSEAoIcHJvZ3Jlc3MYBiABKAUSDQoFY3RpbWUYByABKAkSDQoFbXRpbWUYCCABKAkSDQoFZXh0cmEYCSABKAkSDQoFaWRTdHIYCiABKAkSDAoEdHlwZRgLIAEoBRITCgthdXRvX2NyZWF0ZRgMIAEoCBISCgpjb3VudF9kb3duGA0gASgFEgwKBGF0dHIYDiABKAUiUAoNRGFubWFrdUFJRmxhZxI/CghkbV9mbGFncxgBIAMoCzItLmJpbGliaWxpLmNvbW11bml0eS5zZXJ2aWNlLmRtLnYxLkRhbm1ha3VGbGFnIosDCgtEYW5tYWt1RWxlbRIKCgJpZBgBIAEoAxIQCghwcm9ncmVzcxgCIAEoBRIMCgRtb2RlGAMgASgFEhAKCGZvbnRzaXplGAQgASgFEj8KBWNvbG9yGAUgASgOMjAuYmlsaWJpbGkuY29tbXVuaXR5LnNlcnZpY2UuZG0udjEuRG1Db2xvcmZ1bFR5cGUSEAoIbWlkX2hhc2gYBiABKAkSDwoHY29udGVudBgHIAEoCRINCgVjdGltZRgIIAEoAxIOCgZ3ZWlnaHQYCSABKAUSDgoGYWN0aW9uGAogASgJEgwKBHBvb2wYCyABKAUSDgoGaWRfc3RyGAwgASgJEgwKBGF0dHIYDSABKAUSEQoJYW5pbWF0aW9uGBYgASgJEg0KBWV4dHJhGBcgASgJEkIKCGNvbG9yZnVsGBggASgOMjAuYmlsaWJpbGkuY29tbXVuaXR5LnNlcnZpY2UuZG0udjEuRG1Db2xvcmZ1bFR5cGUSDAoEdHlwZRgZIAEoBRILCgNvaWQYGiABKAMiKQoLRGFubWFrdUZsYWcSDAoEZG1pZBgBIAEoAxIMCgRmbGFnGAIgASgFIksKEURhbm1ha3VGbGFnQ29uZmlnEhAKCHJlY19mbGFnGAEgASgFEhAKCHJlY190ZXh0GAIgASgJEhIKCnJlY19zd2l0Y2gYAyABKAUiiwcKGERhbm11RGVmYXVsdFBsYXllckNvbmZpZxIpCiFwbGF5ZXJfZGFubWFrdV91c2VfZGVmYXVsdF9jb25maWcYASABKAgSLAokcGxheWVyX2Rhbm1ha3VfYWlfcmVjb21tZW5kZWRfc3dpdGNoGAQgASgIEisKI3BsYXllcl9kYW5tYWt1X2FpX3JlY29tbWVuZGVkX2xldmVsGAUgASgFEh8KF3BsYXllcl9kYW5tYWt1X2Jsb2NrdG9wGAYgASgIEiIKGnBsYXllcl9kYW5tYWt1X2Jsb2Nrc2Nyb2xsGAcgASgIEiIKGnBsYXllcl9kYW5tYWt1X2Jsb2NrYm90dG9tGAggASgIEiQKHHBsYXllcl9kYW5tYWt1X2Jsb2NrY29sb3JmdWwYCSABKAgSIgoacGxheWVyX2Rhbm1ha3VfYmxvY2tyZXBlYXQYCiABKAgSIwobcGxheWVyX2Rhbm1ha3VfYmxvY2tzcGVjaWFsGAsgASgIEh4KFnBsYXllcl9kYW5tYWt1X29wYWNpdHkYDCABKAISJAoccGxheWVyX2Rhbm1ha3Vfc2NhbGluZ2ZhY3RvchgNIAEoAhIdChVwbGF5ZXJfZGFubWFrdV9kb21haW4YDiABKAISHAoUcGxheWVyX2Rhbm1ha3Vfc3BlZWQYDyABKAUSJAocaW5saW5lX3BsYXllcl9kYW5tYWt1X3N3aXRjaBgQIAEoCBIpCiFwbGF5ZXJfZGFubWFrdV9zZW5pb3JfbW9kZV9zd2l0Y2gYESABKAUSLgomcGxheWVyX2Rhbm1ha3VfYWlfcmVjb21tZW5kZWRfbGV2ZWxfdjIYEiABKAUSmAEKKnBsYXllcl9kYW5tYWt1X2FpX3JlY29tbWVuZGVkX2xldmVsX3YyX21hcBgTIAMoCzJkLmJpbGliaWxpLmNvbW11bml0eS5zZXJ2aWNlLmRtLnYxLkRhbm11RGVmYXVsdFBsYXllckNvbmZpZy5QbGF5ZXJEYW5tYWt1QWlSZWNvbW1lbmRlZExldmVsVjJNYXBFbnRyeRIlCh1wbGF5ZXJfZGFubWFrdV9lbmFibGVfaGVyZF9kbRgUIAEoCBpLCilQbGF5ZXJEYW5tYWt1QWlSZWNvbW1lbmRlZExldmVsVjJNYXBFbnRyeRILCgNrZXkYASABKAUSDQoFdmFsdWUYAiABKAU6AjgBIuwJChFEYW5tdVBsYXllckNvbmZpZxIdChVwbGF5ZXJfZGFubWFrdV9zd2l0Y2gYASABKAgSIgoacGxheWVyX2Rhbm1ha3Vfc3dpdGNoX3NhdmUYAiABKAgSKQohcGxheWVyX2Rhbm1ha3VfdXNlX2RlZmF1bHRfY29uZmlnGAMgASgIEiwKJHBsYXllcl9kYW5tYWt1X2FpX3JlY29tbWVuZGVkX3N3aXRjaBgEIAEoCBIrCiNwbGF5ZXJfZGFubWFrdV9haV9yZWNvbW1lbmRlZF9sZXZlbBgFIAEoBRIfChdwbGF5ZXJfZGFubWFrdV9ibG9ja3RvcBgGIAEoCBIiChpwbGF5ZXJfZGFubWFrdV9ibG9ja3Njcm9sbBgHIAEoCBIiChpwbGF5ZXJfZGFubWFrdV9ibG9ja2JvdHRvbRgIIAEoCBIkChxwbGF5ZXJfZGFubWFrdV9ibG9ja2NvbG9yZnVsGAkgASgIEiIKGnBsYXllcl9kYW5tYWt1X2Jsb2NrcmVwZWF0GAogASgIEiMKG3BsYXllcl9kYW5tYWt1X2Jsb2Nrc3BlY2lhbBgLIAEoCBIeChZwbGF5ZXJfZGFubWFrdV9vcGFjaXR5GAwgASgCEiQKHHBsYXllcl9kYW5tYWt1X3NjYWxpbmdmYWN0b3IYDSABKAISHQoVcGxheWVyX2Rhbm1ha3VfZG9tYWluGA4gASgCEhwKFHBsYXllcl9kYW5tYWt1X3NwZWVkGA8gASgFEiYKHnBsYXllcl9kYW5tYWt1X2VuYWJsZWJsb2NrbGlzdBgQIAEoCBIkChxpbmxpbmVfcGxheWVyX2Rhbm1ha3Vfc3dpdGNoGBEgASgIEiQKHGlubGluZV9wbGF5ZXJfZGFubWFrdV9jb25maWcYEiABKAUSJgoecGxheWVyX2Rhbm1ha3VfaW9zX3N3aXRjaF9zYXZlGBMgASgFEikKIXBsYXllcl9kYW5tYWt1X3Nlbmlvcl9tb2RlX3N3aXRjaBgUIAEoBRIuCiZwbGF5ZXJfZGFubWFrdV9haV9yZWNvbW1lbmRlZF9sZXZlbF92MhgVIAEoBRKRAQoqcGxheWVyX2Rhbm1ha3VfYWlfcmVjb21tZW5kZWRfbGV2ZWxfdjJfbWFwGBYgAygLMl0uYmlsaWJpbGkuY29tbXVuaXR5LnNlcnZpY2UuZG0udjEuRGFubXVQbGF5ZXJDb25maWcuUGxheWVyRGFubWFrdUFpUmVjb21tZW5kZWRMZXZlbFYyTWFwRW50cnkSJQodcGxheWVyX2Rhbm1ha3VfZW5hYmxlX2hlcmRfZG0YFyABKAgSJgoecGxheWVyX2Rhbm1ha3VfYmxvY2t0b3BfYm90dG9tGBggASgIEiAKGHBsYXllcl9kYW5tYWt1X2RvbWFpbl92MhgZIAEoBRIeChZwbGF5ZXJfZGFubWFrdV9kZW5zaXR5GBogASgFEiUKHXBsYXllcl9kYW5tYWt1X3N1YnRpdGxlX3Byb29mGBsgASgIEiMKG3BsYXllcl9kYW5tYWt1X3Blb3BsZV9wcm9vZhgcIAEoCBpLCilQbGF5ZXJEYW5tYWt1QWlSZWNvbW1lbmRlZExldmVsVjJNYXBFbnRyeRILCgNrZXkYASABKAUSDQoFdmFsdWUYAiABKAU6AjgBIjAKFkRhbm11UGxheWVyQ29uZmlnUGFuZWwSFgoOc2VsZWN0aW9uX3RleHQYASABKAkiSwoYRGFubXVQbGF5ZXJEeW5hbWljQ29uZmlnEhAKCHByb2dyZXNzGAEgASgFEh0KFXBsYXllcl9kYW5tYWt1X2RvbWFpbhgOIAEoAiKQAwoVRGFubXVQbGF5ZXJWaWV3Q29uZmlnEmEKHWRhbm11a3VfZGVmYXVsdF9wbGF5ZXJfY29uZmlnGAEgASgLMjouYmlsaWJpbGkuY29tbXVuaXR5LnNlcnZpY2UuZG0udjEuRGFubXVEZWZhdWx0UGxheWVyQ29uZmlnElIKFWRhbm11a3VfcGxheWVyX2NvbmZpZxgCIAEoCzIzLmJpbGliaWxpLmNvbW11bml0eS5zZXJ2aWNlLmRtLnYxLkRhbm11UGxheWVyQ29uZmlnEmEKHWRhbm11a3VfcGxheWVyX2R5bmFtaWNfY29uZmlnGAMgAygLMjouYmlsaWJpbGkuY29tbXVuaXR5LnNlcnZpY2UuZG0udjEuRGFubXVQbGF5ZXJEeW5hbWljQ29uZmlnEl0KG2Rhbm11a3VfcGxheWVyX2NvbmZpZ19wYW5lbBgEIAEoCzI4LmJpbGliaWxpLmNvbW11bml0eS5zZXJ2aWNlLmRtLnYxLkRhbm11UGxheWVyQ29uZmlnUGFuZWwimQUKFERhbm11V2ViUGxheWVyQ29uZmlnEhEKCWRtX3N3aXRjaBgBIAEoCBIRCglhaV9zd2l0Y2gYAiABKAgSEAoIYWlfbGV2ZWwYAyABKAUSEAoIYmxvY2t0b3AYBCABKAgSEwoLYmxvY2tzY3JvbGwYBSABKAgSEwoLYmxvY2tib3R0b20YBiABKAgSEgoKYmxvY2tjb2xvchgHIAEoCBIUCgxibG9ja3NwZWNpYWwYCCABKAgSFAoMcHJldmVudHNoYWRlGAkgASgIEg0KBWRtYXNrGAogASgIEg8KB29wYWNpdHkYCyABKAISDgoGZG1hcmVhGAwgASgFEhEKCXNwZWVkcGx1cxgNIAEoAhIQCghmb250c2l6ZRgOIAEoAhISCgpzY3JlZW5zeW5jGA8gASgIEhEKCXNwZWVkc3luYxgQIAEoCBISCgpmb250ZmFtaWx5GBEgASgJEgwKBGJvbGQYEiABKAgSEgoKZm9udGJvcmRlchgTIAEoBRIRCglkcmF3X3R5cGUYFCABKAkSGgoSc2VuaW9yX21vZGVfc3dpdGNoGBUgASgFEhMKC2FpX2xldmVsX3YyGBYgASgFEmEKD2FpX2xldmVsX3YyX21hcBgXIAMoCzJILmJpbGliaWxpLmNvbW11bml0eS5zZXJ2aWNlLmRtLnYxLkRhbm11V2ViUGxheWVyQ29uZmlnLkFpTGV2ZWxWMk1hcEVudHJ5EhcKD2Jsb2NrdG9wX2JvdHRvbRgYIAEoCBISCgpkbV9hcmVhX3YyGBkgASgFEhIKCmRtX2RlbnNpdHkYGiABKAUaMwoRQWlMZXZlbFYyTWFwRW50cnkSCwoDa2V5GAEgASgFEg0KBXZhbHVlGAIgASgFOgI4ASJZCgpEbUNvbG9yZnVsEj4KBHR5cGUYASABKA4yMC5iaWxpYmlsaS5jb21tdW5pdHkuc2VydmljZS5kbS52MS5EbUNvbG9yZnVsVHlwZRILCgNzcmMYAiABKAkiUAoPRG1FeHBvUmVwb3J0UmVxEhIKCnNlc3Npb25faWQYASABKAkSCwoDb2lkGAIgASgDEg0KBWRtaWRzGAMgASgMEg0KBXNwbWlkGAQgASgJIhEKD0RtRXhwb1JlcG9ydFJlcyJtCgpEbUhlcmRWaWV3EhsKE2Rpc3BsYXlfaGVyZF9kbV9udW0YASABKAUSQgoIaGVyZF9kbXMYAiADKAsyMC5iaWxpYmlsaS5jb21tdW5pdHkuc2VydmljZS5kbS52MS5WaWV3SGVyZERtRWxlbSKWAgoKRG1NYXNrV2FsbBINCgVzdGFydBgBIAEoAxILCgNlbmQYAiABKAMSDwoHY29udGVudBgDIAEoCRJNCgxjb250ZW50X3R5cGUYBCABKA4yNy5iaWxpYmlsaS5jb21tdW5pdHkuc2VydmljZS5kbS52MS5EbU1hc2tXYWxsQ29udGVudFR5cGUSRQoIYml6X3R5cGUYBSABKA4yMy5iaWxpYmlsaS5jb21tdW5pdHkuc2VydmljZS5kbS52MS5EbU1hc2tXYWxsQml6VHlwZRJFCghjb250ZW50cxgGIAMoCzIzLmJpbGliaWxpLmNvbW11bml0eS5zZXJ2aWNlLmRtLnYxLkRtTWFza1dhbGxDb250ZW50ImsKEURtTWFza1dhbGxDb250ZW50EkUKBHR5cGUYASABKA4yNy5iaWxpYmlsaS5jb21tdW5pdHkuc2VydmljZS5kbS52MS5EbU1hc2tXYWxsQ29udGVudFR5cGUSDwoHY29udGVudBgCIAEoCSLNEAoRRG1QbGF5ZXJDb25maWdSZXESCgoCdHMYASABKAMSRQoGc3dpdGNoGAIgASgLMjUuYmlsaWJpbGkuY29tbXVuaXR5LnNlcnZpY2UuZG0udjEuUGxheWVyRGFubWFrdVN3aXRjaBJOCgtzd2l0Y2hfc2F2ZRgDIAEoCzI5LmJpbGliaWxpLmNvbW11bml0eS5zZXJ2aWNlLmRtLnYxLlBsYXllckRhbm1ha3VTd2l0Y2hTYXZlElsKEnVzZV9kZWZhdWx0X2NvbmZpZxgEIAEoCzI/LmJpbGliaWxpLmNvbW11bml0eS5zZXJ2aWNlLmRtLnYxLlBsYXllckRhbm1ha3VVc2VEZWZhdWx0Q29uZmlnEmEKFWFpX3JlY29tbWVuZGVkX3N3aXRjaBgFIAEoCzJCLmJpbGliaWxpLmNvbW11bml0eS5zZXJ2aWNlLmRtLnYxLlBsYXllckRhbm1ha3VBaVJlY29tbWVuZGVkU3dpdGNoEl8KFGFpX3JlY29tbWVuZGVkX2xldmVsGAYgASgLMkEuYmlsaWJpbGkuY29tbXVuaXR5LnNlcnZpY2UuZG0udjEuUGxheWVyRGFubWFrdUFpUmVjb21tZW5kZWRMZXZlbBJJCghibG9ja3RvcBgHIAEoCzI3LmJpbGliaWxpLmNvbW11bml0eS5zZXJ2aWNlLmRtLnYxLlBsYXllckRhbm1ha3VCbG9ja3RvcBJPCgtibG9ja3Njcm9sbBgIIAEoCzI6LmJpbGliaWxpLmNvbW11bml0eS5zZXJ2aWNlLmRtLnYxLlBsYXllckRhbm1ha3VCbG9ja3Njcm9sbBJPCgtibG9ja2JvdHRvbRgJIAEoCzI6LmJpbGliaWxpLmNvbW11bml0eS5zZXJ2aWNlLmRtLnYxLlBsYXllckRhbm1ha3VCbG9ja2JvdHRvbRJTCg1ibG9ja2NvbG9yZnVsGAogASgLMjwuYmlsaWJpbGkuY29tbXVuaXR5LnNlcnZpY2UuZG0udjEuUGxheWVyRGFubWFrdUJsb2NrY29sb3JmdWwSTwoLYmxvY2tyZXBlYXQYCyABKAsyOi5iaWxpYmlsaS5jb21tdW5pdHkuc2VydmljZS5kbS52MS5QbGF5ZXJEYW5tYWt1QmxvY2tyZXBlYXQSUQoMYmxvY2tzcGVjaWFsGAwgASgLMjsuYmlsaWJpbGkuY29tbXVuaXR5LnNlcnZpY2UuZG0udjEuUGxheWVyRGFubWFrdUJsb2Nrc3BlY2lhbBJHCgdvcGFjaXR5GA0gASgLMjYuYmlsaWJpbGkuY29tbXVuaXR5LnNlcnZpY2UuZG0udjEuUGxheWVyRGFubWFrdU9wYWNpdHkSUwoNc2NhbGluZ2ZhY3RvchgOIAEoCzI8LmJpbGliaWxpLmNvbW11bml0eS5zZXJ2aWNlLmRtLnYxLlBsYXllckRhbm1ha3VTY2FsaW5nZmFjdG9yEkUKBmRvbWFpbhgPIAEoCzI1LmJpbGliaWxpLmNvbW11bml0eS5zZXJ2aWNlLmRtLnYxLlBsYXllckRhbm1ha3VEb21haW4SQwoFc3BlZWQYECABKAsyNC5iaWxpYmlsaS5jb21tdW5pdHkuc2VydmljZS5kbS52MS5QbGF5ZXJEYW5tYWt1U3BlZWQSVwoPZW5hYmxlYmxvY2tsaXN0GBEgASgLMj4uYmlsaWJpbGkuY29tbXVuaXR5LnNlcnZpY2UuZG0udjEuUGxheWVyRGFubWFrdUVuYWJsZWJsb2NrbGlzdBJeChlpbmxpbmVQbGF5ZXJEYW5tYWt1U3dpdGNoGBIgASgLMjsuYmlsaWJpbGkuY29tbXVuaXR5LnNlcnZpY2UuZG0udjEuSW5saW5lUGxheWVyRGFubWFrdVN3aXRjaBJbChJzZW5pb3JfbW9kZV9zd2l0Y2gYEyABKAsyPy5iaWxpYmlsaS5jb21tdW5pdHkuc2VydmljZS5kbS52MS5QbGF5ZXJEYW5tYWt1U2VuaW9yTW9kZVN3aXRjaBJkChdhaV9yZWNvbW1lbmRlZF9sZXZlbF92MhgUIAEoCzJDLmJpbGliaWxpLmNvbW11bml0eS5zZXJ2aWNlLmRtLnYxLlBsYXllckRhbm1ha3VBaVJlY29tbWVuZGVkTGV2ZWxWMhJTCg5lbmFibGVfaGVyZF9kbRgVIAEoCzI7LmJpbGliaWxpLmNvbW11bml0eS5zZXJ2aWNlLmRtLnYxLlBsYXllckRhbm1ha3VFbmFibGVIZXJkRG0SVgoPYmxvY2t0b3BfYm90dG9tGBYgASgLMj0uYmlsaWJpbGkuY29tbXVuaXR5LnNlcnZpY2UuZG0udjEuUGxheWVyRGFubWFrdUJsb2NrdG9wQm90dG9tEkoKCWRvbWFpbl92MhgXIAEoCzI3LmJpbGliaWxpLmNvbW11bml0eS5zZXJ2aWNlLmRtLnYxLlBsYXllckRhbm1ha3VEb21haW5WMhJHCgdkZW5zaXR5GBggASgLMjYuYmlsaWJpbGkuY29tbXVuaXR5LnNlcnZpY2UuZG0udjEuUGxheWVyRGFubWFrdURlbnNpdHkSVAoOc3VidGl0bGVfcHJvb2YYGSABKAsyPC5iaWxpYmlsaS5jb21tdW5pdHkuc2VydmljZS5kbS52MS5QbGF5ZXJEYW5tYWt1U3VidGl0bGVQcm9vZhJQCgxwZW9wbGVfcHJvb2YYGiABKAsyOi5iaWxpYmlsaS5jb21tdW5pdHkuc2VydmljZS5kbS52MS5QbGF5ZXJEYW5tYWt1UGVvcGxlUHJvb2YiLwoLRG1TZWdDb25maWcSEQoJcGFnZV9zaXplGAEgASgDEg0KBXRvdGFsGAIgASgDIpECChBEbVNlZ01vYmlsZVJlcGx5EjwKBWVsZW1zGAEgAygLMi0uYmlsaWJpbGkuY29tbXVuaXR5LnNlcnZpY2UuZG0udjEuRGFubWFrdUVsZW0SDQoFc3RhdGUYAiABKAUSQAoHYWlfZmxhZxgDIAEoCzIvLmJpbGliaWxpLmNvbW11bml0eS5zZXJ2aWNlLmRtLnYxLkRhbm1ha3VBSUZsYWcSFQoNc2VnbWVudF9ydWxlcxgEIAMoAxJCCgxjb2xvcmZ1bF9zcmMYBSADKAsyLC5iaWxpYmlsaS5jb21tdW5pdHkuc2VydmljZS5kbS52MS5EbUNvbG9yZnVsEhMKC2NvbnRleHRfc3JjGAYgASgJIsoBCg5EbVNlZ01vYmlsZVJlcRILCgNwaWQYASABKAMSCwoDb2lkGAIgASgDEgwKBHR5cGUYAyABKAUSFQoNc2VnbWVudF9pbmRleBgEIAEoAxIWCg50ZWVuYWdlcnNfbW9kZRgFIAEoBRIKCgJwcxgGIAEoAxIKCgJwZRgHIAEoAxIRCglwdWxsX21vZGUYCCABKAUSEgoKZnJvbV9zY2VuZRgJIAEoBRINCgVzcG1pZBgKIAEoCRITCgtjb250ZXh0X2V4dBgLIAEoCSJcCg1EbVNlZ090dFJlcGx5EjwKBWVsZW1zGAEgAygLMi0uYmlsaWJpbGkuY29tbXVuaXR5LnNlcnZpY2UuZG0udjEuRGFubWFrdUVsZW0SDQoFc3RhdGUYAiABKAUiTAoLRG1TZWdPdHRSZXESCwoDcGlkGAEgASgDEgsKA29pZBgCIAEoAxIMCgR0eXBlGAMgASgFEhUKDXNlZ21lbnRfaW5kZXgYBCABKAMiXQoNRG1TZWdTREtSZXBseRIOCgZjbG9zZWQYASABKAgSPAoFZWxlbXMYAiADKAsyLS5iaWxpYmlsaS5jb21tdW5pdHkuc2VydmljZS5kbS52MS5EYW5tYWt1RWxlbSJMCgtEbVNlZ1NES1JlcRILCgNwaWQYASABKAMSCwoDb2lkGAIgASgDEgwKBHR5cGUYAyABKAUSFQoNc2VnbWVudF9pbmRleBgEIAEoAyJ3CglEbVN1YlZpZXcSDAoEdHlwZRgBIAEoBRILCgNvaWQYAiABKAMSCwoDcGlkGAMgASgDEkIKC3Bvc3RfcGFuZWwyGAQgAygLMi0uYmlsaWJpbGkuY29tbXVuaXR5LnNlcnZpY2UuZG0udjEuUG9zdFBhbmVsVjIioQkKC0RtVmlld1JlcGx5Eg4KBmNsb3NlZBgBIAEoCBI5CgRtYXNrGAIgASgLMisuYmlsaWJpbGkuY29tbXVuaXR5LnNlcnZpY2UuZG0udjEuVmlkZW9NYXNrEkEKCHN1YnRpdGxlGAMgASgLMi8uYmlsaWJpbGkuY29tbXVuaXR5LnNlcnZpY2UuZG0udjEuVmlkZW9TdWJ0aXRsZRITCgtzcGVjaWFsX2RtcxgEIAMoCRJECgdhaV9mbGFnGAUgASgLMjMuYmlsaWJpbGkuY29tbXVuaXR5LnNlcnZpY2UuZG0udjEuRGFubWFrdUZsYWdDb25maWcSTgoNcGxheWVyX2NvbmZpZxgGIAEoCzI3LmJpbGliaWxpLmNvbW11bml0eS5zZXJ2aWNlLmRtLnYxLkRhbm11UGxheWVyVmlld0NvbmZpZxIWCg5zZW5kX2JveF9zdHlsZRgHIAEoBRINCgVhbGxvdxgIIAEoCBIRCgljaGVja19ib3gYCSABKAgSGgoSY2hlY2tfYm94X3Nob3dfbXNnGAogASgJEhgKEHRleHRfcGxhY2Vob2xkZXIYCyABKAkSGQoRaW5wdXRfcGxhY2Vob2xkZXIYDCABKAkSHQoVcmVwb3J0X2ZpbHRlcl9jb250ZW50GA0gAygJEkEKC2V4cG9fcmVwb3J0GA4gASgLMiwuYmlsaWJpbGkuY29tbXVuaXR5LnNlcnZpY2UuZG0udjEuRXhwb1JlcG9ydBJJCg9idXp6d29yZF9jb25maWcYDyABKAsyMC5iaWxpYmlsaS5jb21tdW5pdHkuc2VydmljZS5kbS52MS5CdXp6d29yZENvbmZpZxJCCgtleHByZXNzaW9ucxgQIAMoCzItLmJpbGliaWxpLmNvbW11bml0eS5zZXJ2aWNlLmRtLnYxLkV4cHJlc3Npb25zEj8KCnBvc3RfcGFuZWwYESADKAsyKy5iaWxpYmlsaS5jb21tdW5pdHkuc2VydmljZS5kbS52MS5Qb3N0UGFuZWwSFQoNYWN0aXZpdHlfbWV0YRgSIAMoCRJCCgtwb3N0X3BhbmVsMhgTIAMoCzItLmJpbGliaWxpLmNvbW11bml0eS5zZXJ2aWNlLmRtLnYxLlBvc3RQYW5lbFYyEkIKDGRtX21hc2tfd2FsbBgUIAMoCzIsLmJpbGliaWxpLmNvbW11bml0eS5zZXJ2aWNlLmRtLnYxLkRtTWFza1dhbGwSPQoHZG1faGVyZBgVIAEoCzIsLmJpbGliaWxpLmNvbW11bml0eS5zZXJ2aWNlLmRtLnYxLkRtSGVyZFZpZXcSOgoHY29tbWFuZBgWIAEoCzIpLmJpbGliaWxpLmNvbW11bml0eS5zZXJ2aWNlLmRtLnYxLkNvbW1hbmQSCgoCa3YYFyABKAkSPgoJc3ViX3ZpZXdzGBggAygLMisuYmlsaWJpbGkuY29tbXVuaXR5LnNlcnZpY2UuZG0udjEuRG1TdWJWaWV3EjYKA3FvZRgZIAEoCzIpLmJpbGliaWxpLmNvbW11bml0eS5zZXJ2aWNlLmRtLnYxLlFvZUluZm8ibQoJRG1WaWV3UmVxEgsKA3BpZBgBIAEoAxILCgNvaWQYAiABKAMSDAoEdHlwZRgDIAEoBRINCgVzcG1pZBgEIAEoCRIUCgxpc19oYXJkX2Jvb3QYBSABKAUSEwoLY29udGV4dF9leHQYBiABKAkigQYKDkRtV2ViVmlld1JlcGx5Eg0KBXN0YXRlGAEgASgFEgwKBHRleHQYAiABKAkSEQoJdGV4dF9zaWRlGAMgASgJEj0KBmRtX3NnZRgEIAEoCzItLmJpbGliaWxpLmNvbW11bml0eS5zZXJ2aWNlLmRtLnYxLkRtU2VnQ29uZmlnEkEKBGZsYWcYBSABKAsyMy5iaWxpYmlsaS5jb21tdW5pdHkuc2VydmljZS5kbS52MS5EYW5tYWt1RmxhZ0NvbmZpZxITCgtzcGVjaWFsX2RtcxgGIAMoCRIRCgljaGVja19ib3gYByABKAgSDQoFY291bnQYCCABKAMSQAoLY29tbWFuZF9kbXMYCSADKAsyKy5iaWxpYmlsaS5jb21tdW5pdHkuc2VydmljZS5kbS52MS5Db21tYW5kRG0STQoNcGxheWVyX2NvbmZpZxgKIAEoCzI2LmJpbGliaWxpLmNvbW11bml0eS5zZXJ2aWNlLmRtLnYxLkRhbm11V2ViUGxheWVyQ29uZmlnEh0KFXJlcG9ydF9maWx0ZXJfY29udGVudBgLIAMoCRJCCgtleHByZXNzaW9ucxgMIAMoCzItLmJpbGliaWxpLmNvbW11bml0eS5zZXJ2aWNlLmRtLnYxLkV4cHJlc3Npb25zEj8KCnBvc3RfcGFuZWwYDSADKAsyKy5iaWxpYmlsaS5jb21tdW5pdHkuc2VydmljZS5kbS52MS5Qb3N0UGFuZWwSFQoNYWN0aXZpdHlfbWV0YRgOIAMoCRJCCgtwb3N0X3BhbmVsMhgPIAMoCzItLmJpbGliaWxpLmNvbW11bml0eS5zZXJ2aWNlLmRtLnYxLlBvc3RQYW5lbFYyEj4KCXN1Yl92aWV3cxgQIAMoCzIrLmJpbGliaWxpLmNvbW11bml0eS5zZXJ2aWNlLmRtLnYxLkRtU3ViVmlldxI2CgNxb2UYESABKAsyKS5iaWxpYmlsaS5jb21tdW5pdHkuc2VydmljZS5kbS52MS5Rb2VJbmZvIioKCkV4cG9SZXBvcnQSHAoUc2hvdWxkX3JlcG9ydF9hdF9lbmQYASABKAgiZAoKRXhwcmVzc2lvbhIPCgdrZXl3b3JkGAEgAygJEgsKA3VybBgCIAEoCRI4CgZwZXJpb2QYAyADKAsyKC5iaWxpYmlsaS5jb21tdW5pdHkuc2VydmljZS5kbS52MS5QZXJpb2QiSQoLRXhwcmVzc2lvbnMSOgoEZGF0YRgBIAMoCzIsLmJpbGliaWxpLmNvbW11bml0eS5zZXJ2aWNlLmRtLnYxLkV4cHJlc3Npb24iKgoZSW5saW5lUGxheWVyRGFubWFrdVN3aXRjaBINCgV2YWx1ZRgBIAEoCCInCgVMYWJlbBINCgV0aXRsZRgBIAEoCRIPCgdjb250ZW50GAIgAygJIocBCgdMYWJlbFYyEg0KBXRpdGxlGAEgASgJEg8KB2NvbnRlbnQYAiADKAkSFQoNZXhwb3N1cmVfb25jZRgDIAEoCBJFCg1leHBvc3VyZV90eXBlGAQgASgOMi4uYmlsaWJpbGkuY29tbXVuaXR5LnNlcnZpY2UuZG0udjEuRXhwb3N1cmVUeXBlIiQKBlBlcmlvZBINCgVzdGFydBgBIAEoAxILCgNlbmQYAiABKAMiMAofUGxheWVyRGFubWFrdUFpUmVjb21tZW5kZWRMZXZlbBINCgV2YWx1ZRgBIAEoBSIyCiFQbGF5ZXJEYW5tYWt1QWlSZWNvbW1lbmRlZExldmVsVjISDQoFdmFsdWUYASABKAUiMQogUGxheWVyRGFubWFrdUFpUmVjb21tZW5kZWRTd2l0Y2gSDQoFdmFsdWUYASABKAgiKQoYUGxheWVyRGFubWFrdUJsb2NrYm90dG9tEg0KBXZhbHVlGAEgASgIIisKGlBsYXllckRhbm1ha3VCbG9ja2NvbG9yZnVsEg0KBXZhbHVlGAEgASgIIikKGFBsYXllckRhbm1ha3VCbG9ja3JlcGVhdBINCgV2YWx1ZRgBIAEoCCIpChhQbGF5ZXJEYW5tYWt1QmxvY2tzY3JvbGwSDQoFdmFsdWUYASABKAgiKgoZUGxheWVyRGFubWFrdUJsb2Nrc3BlY2lhbBINCgV2YWx1ZRgBIAEoCCImChVQbGF5ZXJEYW5tYWt1QmxvY2t0b3ASDQoFdmFsdWUYASABKAgiLAobUGxheWVyRGFubWFrdUJsb2NrdG9wQm90dG9tEg0KBXZhbHVlGAEgASgIIiUKFFBsYXllckRhbm1ha3VEZW5zaXR5Eg0KBXZhbHVlGAEgASgFIiQKE1BsYXllckRhbm1ha3VEb21haW4SDQoFdmFsdWUYASABKAIiJgoVUGxheWVyRGFubWFrdURvbWFpblYyEg0KBXZhbHVlGAEgASgFIioKGVBsYXllckRhbm1ha3VFbmFibGVIZXJkRG0SDQoFdmFsdWUYASABKAgiLQocUGxheWVyRGFubWFrdUVuYWJsZWJsb2NrbGlzdBINCgV2YWx1ZRgBIAEoCCIlChRQbGF5ZXJEYW5tYWt1T3BhY2l0eRINCgV2YWx1ZRgBIAEoAiIpChhQbGF5ZXJEYW5tYWt1UGVvcGxlUHJvb2YSDQoFdmFsdWUYASABKAgiKwoaUGxheWVyRGFubWFrdVNjYWxpbmdmYWN0b3ISDQoFdmFsdWUYASABKAIiLgodUGxheWVyRGFubWFrdVNlbmlvck1vZGVTd2l0Y2gSDQoFdmFsdWUYASABKAUiIwoSUGxheWVyRGFubWFrdVNwZWVkEg0KBXZhbHVlGAEgASgFIisKGlBsYXllckRhbm1ha3VTdWJ0aXRsZVByb29mEg0KBXZhbHVlGAEgASgIIjgKE1BsYXllckRhbm1ha3VTd2l0Y2gSDQoFdmFsdWUYASABKAgSEgoKY2FuX2lnbm9yZRgCIAEoCCIoChdQbGF5ZXJEYW5tYWt1U3dpdGNoU2F2ZRINCgV2YWx1ZRgBIAEoCCIuCh1QbGF5ZXJEYW5tYWt1VXNlRGVmYXVsdENvbmZpZxINCgV2YWx1ZRgBIAEoCCKMAwoJUG9zdFBhbmVsEg0KBXN0YXJ0GAEgASgDEgsKA2VuZBgCIAEoAxIQCghwcmlvcml0eRgDIAEoAxIOCgZiaXpfaWQYBCABKAMSRAoIYml6X3R5cGUYBSABKA4yMi5iaWxpYmlsaS5jb21tdW5pdHkuc2VydmljZS5kbS52MS5Qb3N0UGFuZWxCaXpUeXBlEkMKDGNsaWNrX2J1dHRvbhgGIAEoCzItLmJpbGliaWxpLmNvbW11bml0eS5zZXJ2aWNlLmRtLnYxLkNsaWNrQnV0dG9uEj8KCnRleHRfaW5wdXQYByABKAsyKy5iaWxpYmlsaS5jb21tdW5pdHkuc2VydmljZS5kbS52MS5UZXh0SW5wdXQSPQoJY2hlY2tfYm94GAggASgLMiouYmlsaWJpbGkuY29tbXVuaXR5LnNlcnZpY2UuZG0udjEuQ2hlY2tCb3gSNgoFdG9hc3QYCSABKAsyJy5iaWxpYmlsaS5jb21tdW5pdHkuc2VydmljZS5kbS52MS5Ub2FzdCKtBAoLUG9zdFBhbmVsVjISDQoFc3RhcnQYASABKAMSCwoDZW5kGAIgASgDEkQKCGJpel90eXBlGAMgASgOMjIuYmlsaWJpbGkuY29tbXVuaXR5LnNlcnZpY2UuZG0udjEuUG9zdFBhbmVsQml6VHlwZRJFCgxjbGlja19idXR0b24YBCABKAsyLy5iaWxpYmlsaS5jb21tdW5pdHkuc2VydmljZS5kbS52MS5DbGlja0J1dHRvblYyEkEKCnRleHRfaW5wdXQYBSABKAsyLS5iaWxpYmlsaS5jb21tdW5pdHkuc2VydmljZS5kbS52MS5UZXh0SW5wdXRWMhI/CgljaGVja19ib3gYBiABKAsyLC5iaWxpYmlsaS5jb21tdW5pdHkuc2VydmljZS5kbS52MS5DaGVja0JveFYyEjgKBXRvYXN0GAcgASgLMikuYmlsaWJpbGkuY29tbXVuaXR5LnNlcnZpY2UuZG0udjEuVG9hc3RWMhI6CgZidWJibGUYCCABKAsyKi5iaWxpYmlsaS5jb21tdW5pdHkuc2VydmljZS5kbS52MS5CdWJibGVWMhI4CgVsYWJlbBgJIAEoCzIpLmJpbGliaWxpLmNvbW11bml0eS5zZXJ2aWNlLmRtLnYxLkxhYmVsVjISQQoLcG9zdF9zdGF0dXMYCiABKA4yLC5iaWxpYmlsaS5jb21tdW5pdHkuc2VydmljZS5kbS52MS5Qb3N0U3RhdHVzIhcKB1FvZUluZm8SDAoEaW5mbxgBIAEoCSIpCghSZXNwb25zZRIMCgRjb2RlGAEgASgFEg8KB21lc3NhZ2UYAiABKAki+QIKDFN1YnRpdGxlSXRlbRIKCgJpZBgBIAEoAxIOCgZpZF9zdHIYAiABKAkSCwoDbGFuGAMgASgJEg8KB2xhbl9kb2MYBCABKAkSFAoMc3VidGl0bGVfdXJsGAUgASgJEjoKBmF1dGhvchgGIAEoCzIqLmJpbGliaWxpLmNvbW11bml0eS5zZXJ2aWNlLmRtLnYxLlVzZXJJbmZvEjwKBHR5cGUYByABKA4yLi5iaWxpYmlsaS5jb21tdW5pdHkuc2VydmljZS5kbS52MS5TdWJ0aXRsZVR5cGUSFQoNbGFuX2RvY19icmllZhgIIAEoCRJBCgdhaV90eXBlGAkgASgOMjAuYmlsaWJpbGkuY29tbXVuaXR5LnNlcnZpY2UuZG0udjEuU3VidGl0bGVBaVR5cGUSRQoJYWlfc3RhdHVzGAogASgOMjIuYmlsaWJpbGkuY29tbXVuaXR5LnNlcnZpY2UuZG0udjEuU3VidGl0bGVBaVN0YXR1cyLoAgoJVGV4dElucHV0EhwKFHBvcnRyYWl0X3BsYWNlaG9sZGVyGAEgAygJEh0KFWxhbmRzY2FwZV9wbGFjZWhvbGRlchgCIAMoCRJBCgtyZW5kZXJfdHlwZRgDIAEoDjIsLmJpbGliaWxpLmNvbW11bml0eS5zZXJ2aWNlLmRtLnYxLlJlbmRlclR5cGUSGAoQcGxhY2Vob2xkZXJfcG9zdBgEIAEoCBIMCgRzaG93GAUgASgIEjgKBmF2YXRhchgGIAMoCzIoLmJpbGliaWxpLmNvbW11bml0eS5zZXJ2aWNlLmRtLnYxLkF2YXRhchJBCgtwb3N0X3N0YXR1cxgHIAEoDjIsLmJpbGliaWxpLmNvbW11bml0eS5zZXJ2aWNlLmRtLnYxLlBvc3RTdGF0dXMSNgoFbGFiZWwYCCABKAsyJy5iaWxpYmlsaS5jb21tdW5pdHkuc2VydmljZS5kbS52MS5MYWJlbCL7AQoLVGV4dElucHV0VjISHAoUcG9ydHJhaXRfcGxhY2Vob2xkZXIYASADKAkSHQoVbGFuZHNjYXBlX3BsYWNlaG9sZGVyGAIgAygJEkEKC3JlbmRlcl90eXBlGAMgASgOMiwuYmlsaWJpbGkuY29tbXVuaXR5LnNlcnZpY2UuZG0udjEuUmVuZGVyVHlwZRIYChBwbGFjZWhvbGRlcl9wb3N0GAQgASgIEjgKBmF2YXRhchgFIAMoCzIoLmJpbGliaWxpLmNvbW11bml0eS5zZXJ2aWNlLmRtLnYxLkF2YXRhchIYChB0ZXh0X2lucHV0X2xpbWl0GAYgASgFIm8KBVRvYXN0EgwKBHRleHQYASABKAkSEAoIZHVyYXRpb24YAiABKAUSDAoEc2hvdxgDIAEoCBI4CgZidXR0b24YBCABKAsyKC5iaWxpYmlsaS5jb21tdW5pdHkuc2VydmljZS5kbS52MS5CdXR0b24iYgoNVG9hc3RCdXR0b25WMhIMCgR0ZXh0GAEgASgJEkMKBmFjdGlvbhgCIAEoDjIzLmJpbGliaWxpLmNvbW11bml0eS5zZXJ2aWNlLmRtLnYxLlRvYXN0RnVuY3Rpb25UeXBlInMKB1RvYXN0VjISDAoEdGV4dBgBIAEoCRIQCghkdXJhdGlvbhgCIAEoBRJICg90b2FzdF9idXR0b25fdjIYAyABKAsyLy5iaWxpYmlsaS5jb21tdW5pdHkuc2VydmljZS5kbS52MS5Ub2FzdEJ1dHRvblYyIlwKCFVzZXJJbmZvEgsKA21pZBgBIAEoAxIMCgRuYW1lGAIgASgJEgsKA3NleBgDIAEoCRIMCgRmYWNlGAQgASgJEgwKBHNpZ24YBSABKAkSDAoEcmFuaxgGIAEoBSJTCglWaWRlb01hc2sSCwoDY2lkGAEgASgDEgwKBHBsYXQYAiABKAUSCwoDZnBzGAMgASgFEgwKBHRpbWUYBCABKAMSEAoIbWFza191cmwYBSABKAkicAoNVmlkZW9TdWJ0aXRsZRILCgNsYW4YASABKAkSDwoHbGFuX2RvYxgCIAEoCRJBCglzdWJ0aXRsZXMYAyADKAsyLi5iaWxpYmlsaS5jb21tdW5pdHkuc2VydmljZS5kbS52MS5TdWJ0aXRsZUl0ZW0ikgEKDlZpZXdIZXJkRG1FbGVtEhAKCGhlcmRfbXNnGAEgASgJEhYKDmhlcmRfc3RhcnRfY250GAIgASgFEhQKDGhlcmRfZW5kX2NudBgDIAEoBRISCgpyZWdleF9ydWxlGAQgASgJEhYKDnN0YXJ0X3Byb2dyZXNzGAUgASgFEhQKDGVuZF9wcm9ncmVzcxgGIAEoBSozCgpBdmF0YXJUeXBlEhIKDkF2YXRhclR5cGVOb25lEAASEQoNQXZhdGFyVHlwZU5GVBABKlkKCkJ1YmJsZVR5cGUSEgoOQnViYmxlVHlwZU5vbmUQABIZChVCdWJibGVUeXBlQ2xpY2tCdXR0b24QARIcChhCdWJibGVUeXBlRG1TZXR0aW5nUGFuZWwQAipYCgxDaGVja2JveFR5cGUSFAoQQ2hlY2tib3hUeXBlTm9uZRAAEhkKFUNoZWNrYm94VHlwZUVuY291cmFnZRABEhcKE0NoZWNrYm94VHlwZUNvbG9yRE0QAio1Cg5EbUNvbG9yZnVsVHlwZRIMCghOb25lVHlwZRAAEhUKD1ZpcEdyYWR1YWxDb2xvchDh1AMqYAoRRG1NYXNrV2FsbEJpelR5cGUSCwoHVW5rbm93bhAAEgcKA09HVhABEgoKBkJpelBpYxACEggKBE11dGUQAxIKCgZSZWNvcmQQBBIJCgVDbG91ZBAFEggKBEFJR0MQBip2ChVEbU1hc2tXYWxsQ29udGVudFR5cGUSIAocRG1NYXNrV2FsbENvbnRlbnRUeXBlVW5rbm93bhAAEh0KGURtTWFza1dhbGxDb250ZW50VHlwZVRleHQQARIcChhEbU1hc2tXYWxsQ29udGVudFR5cGVQaWMQAio8CgxFeHBvc3VyZVR5cGUSFAoQRXhwb3N1cmVUeXBlTm9uZRAAEhYKEkV4cG9zdXJlVHlwZURNU2VuZBABKoMCChBQb3N0UGFuZWxCaXpUeXBlEhgKFFBvc3RQYW5lbEJpelR5cGVOb25lEAASHQoZUG9zdFBhbmVsQml6VHlwZUVuY291cmFnZRABEhsKF1Bvc3RQYW5lbEJpelR5cGVDb2xvckRNEAISGQoVUG9zdFBhbmVsQml6VHlwZU5GVERNEAMSHQoZUG9zdFBhbmVsQml6VHlwZUZyYWdDbG9zZRAEEh0KGVBvc3RQYW5lbEJpelR5cGVSZWNvbW1lbmQQBRIcChhQb3N0UGFuZWxCaXpUeXBlUGxvdExlYWsQBhIiCh5Qb3N0UGFuZWxCaXpUeXBlQW50aUhhcmFzc21lbnQQByo4CgpQb3N0U3RhdHVzEhQKEFBvc3RTdGF0dXNOb3JtYWwQABIUChBQb3N0U3RhdHVzQ2xvc2VkEAEqTgoKUmVuZGVyVHlwZRISCg5SZW5kZXJUeXBlTm9uZRAAEhQKEFJlbmRlclR5cGVTaW5nbGUQARIWChJSZW5kZXJUeXBlUm90YXRpb24QAio2ChBTdWJ0aXRsZUFpU3RhdHVzEggKBE5vbmUQABIMCghFeHBvc3VyZRABEgoKBkFzc2lzdBACKisKDlN1YnRpdGxlQWlUeXBlEgoKBk5vcm1hbBAAEg0KCVRyYW5zbGF0ZRABKh4KDFN1YnRpdGxlVHlwZRIGCgJDQxAAEgYKAkFJEAEqTgoRVG9hc3RGdW5jdGlvblR5cGUSGQoVVG9hc3RGdW5jdGlvblR5cGVOb25lEAASHgoaVG9hc3RGdW5jdGlvblR5cGVQb3N0UGFuZWwQATKgBQoCRE0ScwoLRG1TZWdNb2JpbGUSMC5iaWxpYmlsaS5jb21tdW5pdHkuc2VydmljZS5kbS52MS5EbVNlZ01vYmlsZVJlcRoyLmJpbGliaWxpLmNvbW11bml0eS5zZXJ2aWNlLmRtLnYxLkRtU2VnTW9iaWxlUmVwbHkSZAoGRG1WaWV3EisuYmlsaWJpbGkuY29tbXVuaXR5LnNlcnZpY2UuZG0udjEuRG1WaWV3UmVxGi0uYmlsaWJpbGkuY29tbXVuaXR5LnNlcnZpY2UuZG0udjEuRG1WaWV3UmVwbHkScQoORG1QbGF5ZXJDb25maWcSMy5iaWxpYmlsaS5jb21tdW5pdHkuc2VydmljZS5kbS52MS5EbVBsYXllckNvbmZpZ1JlcRoqLmJpbGliaWxpLmNvbW11bml0eS5zZXJ2aWNlLmRtLnYxLlJlc3BvbnNlEmoKCERtU2VnT3R0Ei0uYmlsaWJpbGkuY29tbXVuaXR5LnNlcnZpY2UuZG0udjEuRG1TZWdPdHRSZXEaLy5iaWxpYmlsaS5jb21tdW5pdHkuc2VydmljZS5kbS52MS5EbVNlZ090dFJlcGx5EmoKCERtU2VnU0RLEi0uYmlsaWJpbGkuY29tbXVuaXR5LnNlcnZpY2UuZG0udjEuRG1TZWdTREtSZXEaLy5iaWxpYmlsaS5jb21tdW5pdHkuc2VydmljZS5kbS52MS5EbVNlZ1NES1JlcGx5EnQKDERtRXhwb1JlcG9ydBIxLmJpbGliaWxpLmNvbW11bml0eS5zZXJ2aWNlLmRtLnYxLkRtRXhwb1JlcG9ydFJlcRoxLmJpbGliaWxpLmNvbW11bml0eS5zZXJ2aWNlLmRtLnYxLkRtRXhwb1JlcG9ydFJlc0LUAQokY29tLmJpbGliaWxpLmNvbW11bml0eS5zZXJ2aWNlLmRtLnYxQgdEbVByb3RvUAGiAgRCQ1NEqgIgQmlsaWJpbGkuQ29tbXVuaXR5LlNlcnZpY2UuRG0uVjHKAiBCaWxpYmlsaVxDb21tdW5pdHlcU2VydmljZVxEbVxWMeICLEJpbGliaWxpXENvbW11bml0eVxTZXJ2aWNlXERtXFYxXEdQQk1ldGFkYXRh6gIkQmlsaWJpbGk6OkNvbW11bml0eTo6U2VydmljZTo6RG06OlYxYgZwcm90bzM");
1318
- const DmSegMobileReplySchema = /*@__PURE__*/ codegenv2_messageDesc(file_bilibili_community_service_dm_v1_dm, 30);
1319
- const DmWebViewReplySchema = /*@__PURE__*/ codegenv2_messageDesc(file_bilibili_community_service_dm_v1_dm, 39);
1320
- const file_danuni_danmaku_v1_danmaku = /*@__PURE__*/ fileDesc("Ch9kYW51bmkvZGFubWFrdS92MS9kYW5tYWt1LnByb3RvEhFkYW51bmkuZGFubWFrdS52MSI2Cg5MaXN0RGFuUmVxdWVzdBIKCgJpZBgBIAEoCRIQCgNzZWcYAiABKAVIAIgBAUIGCgRfc2VnIusCCgdEYW5tYWt1EhIKBHNvaWQYASABKAlSBFNPSUQSEgoEZG1pZBgCIAEoCVIERE1JRBIQCghwcm9ncmVzcxgDIAEoBRIlCgRtb2RlGAQgASgOMhcuZGFudW5pLmRhbm1ha3UudjEuTW9kZRIQCghmb250c2l6ZRgFIAEoBRINCgVjb2xvchgGIAEoBRIbCglzZW5kZXJfaWQYByABKAlSCHNlbmRlcklEEg8KB2NvbnRlbnQYCCABKAkSKQoFY3RpbWUYCSABKAsyGi5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wEg4KBndlaWdodBgKIAEoBRIlCgRwb29sGAsgASgOMhcuZGFudW5pLmRhbm1ha3UudjEuUG9vbBIMCgRhdHRyGAwgAygJEhUKCHBsYXRmb3JtGA0gASgJSACIAQESEgoFZXh0cmEYDiABKAlIAYgBAUILCglfcGxhdGZvcm1CCAoGX2V4dHJhIj8KD0xpc3REYW5SZXNwb25zZRIsCghkYW5tYWt1cxgBIAMoCzIaLmRhbnVuaS5kYW5tYWt1LnYxLkRhbm1ha3UqYgoETW9kZRIbChdNT0RFX05PUk1BTF9VTlNQRUNJRklFRBAAEg8KC01PREVfQk9UVE9NEAESDAoITU9ERV9UT1AQAhIQCgxNT0RFX1JFVkVSU0UQAxIMCghNT0RFX0VYVBAEKkkKBFBvb2wSGAoUUE9PTF9ERUZfVU5TUEVDSUZJRUQQABIMCghQT09MX1NVQhABEgwKCFBPT0xfQURWEAISCwoHUE9PTF9JWBADMmQKDkRhbm1ha3VTZXJ2aWNlElIKB0xpc3REYW4SIS5kYW51bmkuZGFubWFrdS52MS5MaXN0RGFuUmVxdWVzdBoiLmRhbnVuaS5kYW5tYWt1LnYxLkxpc3REYW5SZXNwb25zZSIAQosBChVjb20uZGFudW5pLmRhbm1ha3UudjFCDERhbm1ha3VQcm90b1ABogIDRERYqgIRRGFudW5pLkRhbm1ha3UuVjHKAhFEYW51bmlcRGFubWFrdVxWMeICHURhbnVuaVxEYW5tYWt1XFYxXEdQQk1ldGFkYXRh6gITRGFudW5pOjpEYW5tYWt1OjpWMWIGcHJvdG8z", [
1321
- file_google_protobuf_timestamp
1322
- ]);
1323
- const ListDanResponseSchema = /*@__PURE__*/ codegenv2_messageDesc(file_danuni_danmaku_v1_danmaku, 2);
1324
- function fileParser(file, mod) {
1325
- const isBinary = file instanceof ArrayBuffer || file instanceof Uint8Array;
1326
- switch(mod){
1327
- case 'bin':
1328
- if (isBinary) return file;
1329
- throw new TypeError('Expected binary data for mod "bin"');
1330
- case 'string':
1331
- if ('string' == typeof file) return file;
1332
- if (isBinary) return new TextDecoder().decode(file);
1333
- throw new TypeError('Expected binary data or string for mod "string"');
1334
- case 'json':
1335
- {
1336
- if ('object' == typeof file && null !== file && !isBinary) return file;
1337
- if ('string' != typeof file && !isBinary) throw new TypeError('Expected object, JSON string, or binary data for mod "json"');
1338
- const str = 'string' == typeof file ? file : new TextDecoder().decode(file);
1339
- try {
1340
- return JSON.parse(str);
1341
- } catch {
1342
- throw new Error('Invalid JSON string');
1343
- }
1344
- }
1345
- default:
1346
- throw new Error(`Unsupported mod "${mod}"`);
1347
- }
1348
- }
1349
- function main(that) {
1350
- that.dans.forEach((d)=>{
1351
- if (d.platform !== platform_PlatformVideoSource.Bilibili) throw new Error('bili-dedupe: 仅支持B站(主站)的弹幕');
1352
- if (!d.extra.bili?.dmid && !d.extra.bili?.command?.id) throw new Error('bili-dedupe: 弹幕缺少bili extra dmid字段');
1353
- });
1354
- const map = new Map();
1355
- that.dans.forEach((d)=>map.set(d.extra.bili.dmid, d));
1356
- return map;
1357
- }
1358
- function to_bili_deduped(that) {
1359
- const map = main(that);
1360
- return new UniPool([
1361
- ...map.values()
1362
- ], that.options, that.info);
1363
- }
1364
- function bili_dedupe(that) {
1365
- const map = main(that);
1366
- that.dans = [
1367
- ...map.values()
1368
- ];
1369
- }
1370
- function history_danmaku_fast_forward_main(that, query_history_date) {
1371
- const qhd = DateTime.fromFormat(query_history_date, 'yyyy-MM-dd', {
1372
- zone: 'Asia/Shanghai'
1373
- }).setZone('Asia/Shanghai');
1374
- if (!qhd.isValid) throw new Error('Invalid query_history_date');
1375
- const s = qhd.startOf('day');
1376
- const before = that.dans.filter((d)=>d.ctime < s.toJSDate());
1377
- if (0 === before.length) return {
1378
- earliest: null,
1379
- FastForward: [],
1380
- skip: [],
1381
- SpecificDate: qhd.toFormat('yyyy-MM-dd')
1382
- };
1383
- const earliestCtime = before.toSorted((a, b)=>a.ctime.getTime() - b.ctime.getTime())[0].ctime;
1384
- const earliestDate = DateTime.fromJSDate(earliestCtime).setZone('Asia/Shanghai').startOf('day');
1385
- const datesWithDanmaku = new Set();
1386
- for (const dan of before){
1387
- const dateStr = DateTime.fromJSDate(dan.ctime).setZone('Asia/Shanghai').toFormat('yyyy-MM-dd');
1388
- datesWithDanmaku.add(dateStr);
1389
- }
1390
- let current = earliestDate;
1391
- const allDates = [];
1392
- while(current < s){
1393
- allDates.push(current.toFormat('yyyy-MM-dd'));
1394
- current = current.plus({
1395
- days: 1
1396
- });
1397
- }
1398
- const FastForward = allDates.filter((d)=>datesWithDanmaku.has(d));
1399
- const skip = allDates.filter((d)=>!datesWithDanmaku.has(d));
1400
- return {
1401
- earliest: earliestDate.toFormat('yyyy-MM-dd'),
1402
- FastForward,
1403
- skip,
1404
- SpecificDate: qhd.toFormat('yyyy-MM-dd')
1405
- };
1406
- }
1407
- function bili_history_fast_forward(query_history_date) {
1408
- return (that)=>history_danmaku_fast_forward_main(that, query_history_date);
1409
- }
1410
- const src_JSON = json_bigint({
1411
- useNativeBigInt: true
1412
- });
1413
- const DanUniConvertTipTemplate = {
1414
- meassage: 'Converted by DanUni!',
1415
- version: `JS/TS ${package_namespaceObject.UU} (v${package_namespaceObject.rE})`
1416
- };
1417
- var src_DM_format = /*#__PURE__*/ function(DM_format) {
1418
- DM_format["DanuniJson"] = "danuni.json";
1419
- DM_format["DanuniMinJson"] = "danuni.min.json";
1420
- DM_format["DanuniPbBin"] = "danuni.binpb";
1421
- DM_format["BiliXml"] = "bili.xml";
1422
- DM_format["BiliPbBin"] = "bili.binpb";
1423
- DM_format["BiliCmdPbBin"] = "bili.cmd.binpb";
1424
- DM_format["BiliUpJson"] = "bili.up.json";
1425
- DM_format["DplayerJson"] = "dplayer.json";
1426
- DM_format["ArtplayerJson"] = "artplayer.json";
1427
- DM_format["DDPlayJson"] = "ddplay.json";
1428
- DM_format["CommonAss"] = "common.ass";
1429
- return DM_format;
1430
- }({});
1431
- const convert2Formats = [
1432
- "danuni.json",
1433
- "danuni.min.json",
1434
- "danuni.binpb",
1435
- "bili.xml",
1436
- "dplayer.json",
1437
- "artplayer.json",
1438
- "ddplay.json"
1439
- ];
1440
- class UniPool {
1441
- constructor(dans, options = {}, info = {
1442
- fromConverted: false
1443
- }){
1444
- this.dans = dans;
1445
- this.options = options;
1446
- this.info = info;
1447
- if (false !== options.dedupe) options.dedupe = true;
1448
- if (this.options.dedupe) this.dedupe();
1449
- }
1450
- pipe(fn) {
1451
- return fn(this);
1452
- }
1453
- get shared() {
1454
- if (0 === this.dans.length) return {};
1455
- const keys = [
1456
- 'SOID',
1457
- 'senderID',
1458
- 'platform',
1459
- 'pool',
1460
- 'mode',
1461
- 'color'
1462
- ];
1463
- const result = {};
1464
- for (const key of keys){
1465
- const sharedVal = this.getShared(key);
1466
- if (void 0 !== sharedVal) result[key] = sharedVal;
1467
- }
1468
- return result;
1469
- }
1470
- getShared(key) {
1471
- if (0 === this.dans.length) return;
1472
- const firstVal = this.dans[0][key];
1473
- for(let i = 1; i < this.dans.length; i++)if (this.dans[i][key] !== firstVal) return;
1474
- return firstVal;
1475
- }
1476
- getStat(key) {
1477
- const statMap = new Map();
1478
- for (const dan of this.dans){
1479
- const val = dan[key];
1480
- statMap.set(val, (statMap.get(val) || 0) + 1);
1481
- }
1482
- return statMap;
1483
- }
1484
- getMost(key) {
1485
- const stats = this.getStat(key);
1486
- if (0 === stats.size) return {
1487
- val: void 0,
1488
- count: 0
1489
- };
1490
- let mostVal;
1491
- let maxCount = 0;
1492
- for (const [val, count] of stats.entries())if (count > maxCount) {
1493
- maxCount = count;
1494
- mostVal = val;
1495
- }
1496
- return {
1497
- val: mostVal,
1498
- count: maxCount
1499
- };
1500
- }
1501
- get most() {
1502
- const keys = [
1503
- 'mode',
1504
- 'fontsize',
1505
- 'color',
1506
- 'senderID',
1507
- 'content',
1508
- 'weight',
1509
- 'pool',
1510
- 'platform'
1511
- ];
1512
- const statMaps = new Map();
1513
- for (const dan of this.dans)for (const key of keys){
1514
- if (!statMaps.has(key)) statMaps.set(key, new Map());
1515
- const statMap = statMaps.get(key);
1516
- const val = dan[key];
1517
- statMap.set(val, (statMap.get(val) || 0) + 1);
1518
- }
1519
- const result = {};
1520
- for (const key of keys){
1521
- const statMap = statMaps.get(key);
1522
- let mostVal;
1523
- let maxCount = 0;
1524
- for (const [val, count] of statMap.entries())if (count > maxCount) {
1525
- maxCount = count;
1526
- mostVal = val;
1527
- }
1528
- result[key] = mostVal;
1529
- }
1530
- return {
1531
- mode: result.mode,
1532
- fontsize: result.fontsize,
1533
- color: result.color,
1534
- senderID: result.senderID,
1535
- content: result.content,
1536
- weight: result.weight,
1537
- pool: result.pool,
1538
- platform: result.platform
1539
- };
1540
- }
1541
- static create(options) {
1542
- return new UniPool([], options);
1543
- }
1544
- assign(dans) {
1545
- if (dans instanceof UniPool) return new UniPool([
1546
- ...this.dans,
1547
- ...dans.dans
1548
- ], {
1549
- ...this.options,
1550
- ...dans.options
1551
- }, {
1552
- ...this.info,
1553
- ...dans.info
1554
- });
1555
- if (dans instanceof UniDM) return new UniPool([
1556
- ...this.dans,
1557
- dans
1558
- ], this.options, this.info);
1559
- if (Array.isArray(dans) && dans.every((d)=>d instanceof UniDM)) return new UniPool([
1560
- ...this.dans,
1561
- ...dans
1562
- ], this.options, this.info);
1563
- return this;
1564
- }
1565
- split(key) {
1566
- if (this.getShared(key)) return [
1567
- this
1568
- ];
1569
- const set = new Set(this.dans.map((d)=>d[key]));
1570
- return [
1571
- ...set
1572
- ].map((v)=>new UniPool(this.dans.filter((d)=>d[key] === v), {
1573
- ...this.options,
1574
- dedupe: false
1575
- }, this.info));
1576
- }
1577
- dedupe() {
1578
- if (false !== this.options.dmid) {
1579
- const map = new Map();
1580
- this.dans.forEach((d)=>map.set(d.DMID || d.toDMID(), d));
1581
- this.dans = [
1582
- ...map.values()
1583
- ];
1584
- }
1585
- this.options.dedupe = false;
1586
- }
1587
- merge(lifetime = 0) {
1588
- if (!this.getShared('SOID')) {
1589
- console.error("本功能仅支持同弹幕库内使用,可先 .split('SOID') 在分别使用");
1590
- return this;
1591
- }
1592
- if (lifetime <= 0) return this;
1593
- const result = [];
1594
- const cache = {};
1595
- const mergeObj = {};
1596
- for (const danmaku of this.dans){
1597
- const key = `${danmaku.content}|${danmaku.mode}|${danmaku.pool}|${danmaku.platform}`;
1598
- const cached = cache[key];
1599
- if (cached && danmaku.progress - cached.progress <= lifetime && danmaku.isSameAs(cached, {
1600
- skipDanuniMerge: true
1601
- })) {
1602
- mergeObj[key].senders.push(danmaku.senderID);
1603
- mergeObj[key].count = mergeObj[key].senders.length;
1604
- mergeObj[key].taolu_count = mergeObj[key].count;
1605
- mergeObj[key].taolu_senders = mergeObj[key].senders;
1606
- mergeObj[key].duration = Number.parseFloat((danmaku.progress - cached.progress).toFixed(3));
1607
- cache[key] = danmaku;
1608
- } else {
1609
- mergeObj[key] = {
1610
- count: 1,
1611
- duration: 0,
1612
- senders: [
1613
- danmaku.senderID
1614
- ],
1615
- taolu_count: 1,
1616
- taolu_senders: [
1617
- danmaku.senderID
1618
- ]
1619
- };
1620
- cache[key] = danmaku;
1621
- result.push(danmaku);
1622
- }
1623
- }
1624
- for (const danmaku of result){
1625
- const key = `${danmaku.content}|${danmaku.mode}|${danmaku.pool}|${danmaku.platform}`;
1626
- const mergeData = mergeObj[key];
1627
- const extra = danmaku.extra;
1628
- if (mergeData.count > 1) {
1629
- danmaku.senderID = 'merge[bot]@dan-any';
1630
- if (danmaku.attr) {
1631
- if (!danmaku.attr.includes(dm_gen_DMAttr.Protect)) danmaku.attr.push(dm_gen_DMAttr.Protect);
1632
- } else danmaku.attr = [
1633
- dm_gen_DMAttr.Protect
1634
- ];
1635
- extra.danuni = extra.danuni || {};
1636
- extra.danuni.merge = mergeData;
1637
- danmaku.extraStr = src_JSON.stringify(extra);
1638
- } else {
1639
- if (extra.danuni?.merge) {
1640
- delete extra.danuni.merge;
1641
- if (0 === Object.keys(extra.danuni).length) delete extra.danuni;
1642
- }
1643
- danmaku.extraStr = Object.keys(extra).length > 0 ? src_JSON.stringify(extra) : void 0;
1644
- }
1645
- }
1646
- return new UniPool(result, this.options, this.info);
1647
- }
1648
- static import(file, options, mod) {
1649
- const handlers = {
1650
- ["danuni.json"]: (json)=>({
1651
- pool: new UniPool(json, options),
1652
- fmt: "danuni.json"
1653
- }),
1654
- ["danuni.min.json"]: (json)=>({
1655
- pool: this.fromMin(json, options),
1656
- fmt: "danuni.min.json"
1657
- }),
1658
- ["danuni.binpb"]: (file)=>({
1659
- pool: this.fromPb(file),
1660
- fmt: "danuni.binpb"
1661
- }),
1662
- ["bili.xml"]: (file)=>({
1663
- pool: this.fromBiliXML(file, options),
1664
- fmt: "bili.xml"
1665
- }),
1666
- ["bili.binpb"]: (file)=>({
1667
- pool: this.fromBiliGrpc(file),
1668
- fmt: "bili.binpb"
1669
- }),
1670
- ["bili.cmd.binpb"]: (file)=>({
1671
- pool: this.fromBiliCommandGrpc(file),
1672
- fmt: "bili.cmd.binpb"
1673
- }),
1674
- ["bili.up.json"]: (json)=>({
1675
- pool: this.fromBiliUp(json, options),
1676
- fmt: "bili.up.json"
1677
- }),
1678
- ["dplayer.json"]: (json)=>({
1679
- pool: this.fromDplayer(json, json.danuni?.data ?? '', void 0, options),
1680
- fmt: "dplayer.json"
1681
- }),
1682
- ["artplayer.json"]: (json)=>({
1683
- pool: this.fromArtplayer(json, json.danuni?.data ?? '', void 0, options),
1684
- fmt: "artplayer.json"
1685
- }),
1686
- ["ddplay.json"]: (json)=>({
1687
- pool: this.fromDDPlay(json, json.danuni?.data ?? '', options),
1688
- fmt: "ddplay.json"
1689
- }),
1690
- ["common.ass"]: (file)=>({
1691
- pool: this.fromASS(file, options),
1692
- fmt: "common.ass"
1693
- })
1694
- };
1695
- if ('string' == typeof mod) {
1696
- const fn = mod;
1697
- try {
1698
- if (fn.endsWith("danuni.json")) return handlers["danuni.json"](fileParser(file, 'json'));
1699
- if (fn.endsWith("danuni.min.json")) return handlers["danuni.min.json"](fileParser(file, 'json'));
1700
- if (fn.endsWith("danuni.binpb")) return handlers["danuni.binpb"](fileParser(file, 'bin'));
1701
- else if (fn.endsWith("bili.xml")) return handlers["bili.xml"](fileParser(file, 'string'));
1702
- else if (fn.endsWith("bili.binpb")) return handlers["bili.binpb"](fileParser(file, 'bin'));
1703
- else if (fn.endsWith("bili.cmd.binpb")) return handlers["bili.cmd.binpb"](fileParser(file, 'bin'));
1704
- else if (fn.endsWith("bili.up.json")) return handlers["bili.up.json"](fileParser(file, 'json'));
1705
- else if (fn.endsWith("dplayer.json")) return handlers["dplayer.json"](fileParser(file, 'json'));
1706
- else if (fn.endsWith("artplayer.json")) return handlers["artplayer.json"](fileParser(file, 'json'));
1707
- else if (fn.endsWith("ddplay.json")) return handlers["ddplay.json"](fileParser(file, 'json'));
1708
- else if (fn.endsWith("common.ass")) return handlers["common.ass"](fileParser(file, 'string'));
1709
- } catch {}
1710
- const ext = fn.split('.').pop()?.toLowerCase();
1711
- if (ext) {
1712
- if ('json' === ext) mod = [
1713
- 'json'
1714
- ];
1715
- else if ([
1716
- 'xml',
1717
- 'ass'
1718
- ].includes(ext)) mod = [
1719
- 'str'
1720
- ];
1721
- else if ([
1722
- 'binpb',
1723
- 'bin',
1724
- 'so'
1725
- ].includes(ext)) mod = [
1726
- 'bin'
1727
- ];
1728
- }
1729
- }
1730
- if (!mod) mod = [
1731
- 'json',
1732
- 'str',
1733
- 'bin'
1734
- ];
1735
- const err = '无法识别该文件,请手动指定格式!';
1736
- const parseJSON = (json)=>{
1737
- try {
1738
- if (Array.isArray(json) && json.every((d)=>d.SOID)) return handlers["danuni.min.json"](json);
1739
- if (json.danmuku && json.danmuku.every((d)=>d.text)) return handlers["artplayer.json"](json);
1740
- if (json.count && json.comments && Array.isArray(json.comments) && json.comments.every((d)=>d.m)) return handlers["ddplay.json"](json);
1741
- else if (0 == json.code && json.data && Array.isArray(json.data) && json.data.every((d)=>Array.isArray(d))) return handlers["dplayer.json"](json);
1742
- else if (0 == json.code && '0' == json.message && json.data && json.data.page && json.data.result && Array.isArray(json.data.result) && json.data.result.every((d)=>d.id && d.oid)) return handlers["bili.up.json"](json);
1743
- } catch {}
1744
- };
1745
- const parseStr = (file)=>{
1746
- if (mod.includes('json')) try {
1747
- if (isJSON(file)) {
1748
- const json = src_JSON.parse(file);
1749
- return parseJSON(json);
1750
- }
1751
- } catch {}
1752
- if (mod.includes('str')) {
1753
- try {
1754
- const xmlParser = new XMLParser({
1755
- ignoreAttributes: false
1756
- });
1757
- const xml = xmlParser.parse(file);
1758
- if (xml?.i?.d) return handlers["bili.xml"](file);
1759
- } catch {}
1760
- try {
1761
- return handlers["common.ass"](file);
1762
- } catch {}
1763
- }
1764
- };
1765
- let errmesg;
1766
- if ('object' == typeof file || Array.isArray(file)) {
1767
- if (file instanceof ArrayBuffer || file instanceof Uint8Array) {
1768
- if (mod.includes('bin')) {
1769
- try {
1770
- return handlers["danuni.binpb"](file);
1771
- } catch {}
1772
- try {
1773
- return handlers["bili.binpb"](file);
1774
- } catch {}
1775
- try {
1776
- return handlers["bili.cmd.binpb"](file);
1777
- } catch {}
1778
- }
1779
- try {
1780
- const fileStr = new TextDecoder().decode(file);
1781
- const prStr = parseStr(fileStr);
1782
- if (prStr) return prStr;
1783
- errmesg = `${err}(定位: bin->string)`;
1784
- } catch {}
1785
- } else if (mod.includes('json')) {
1786
- const prJSON = parseJSON(file);
1787
- if (!prJSON) throw new Error(`${err}(定位: json)`);
1788
- return prJSON;
1789
- }
1790
- } else if (isString(file)) {
1791
- const prStr = parseStr(file);
1792
- if (!prStr) throw new Error(`${err}(定位: string)`);
1793
- return prStr;
1794
- }
1795
- throw new Error(errmesg ?? err);
1796
- }
1797
- convert2(format, file_wrapper = false, continue_on_error = false) {
1798
- switch(format){
1799
- case "danuni.json":
1800
- if (file_wrapper) return new File([
1801
- src_JSON.stringify(this.dans)
1802
- ], "danuni.json", {
1803
- type: 'application/json'
1804
- });
1805
- return this.dans;
1806
- case "danuni.min.json":
1807
- if (file_wrapper) return new File([
1808
- src_JSON.stringify(this.minify())
1809
- ], "danuni.min.json", {
1810
- type: 'application/json'
1811
- });
1812
- return this.minify();
1813
- case "danuni.binpb":
1814
- if (file_wrapper) return new File([
1815
- this.toPb()
1816
- ], "danuni.binpb", {
1817
- type: 'application/protobuf'
1818
- });
1819
- return this.toPb();
1820
- case "bili.xml":
1821
- if (file_wrapper) return new File([
1822
- this.toBiliXML()
1823
- ], "bili.xml", {
1824
- type: 'application/xml'
1825
- });
1826
- return this.toBiliXML();
1827
- case "dplayer.json":
1828
- if (file_wrapper) return new File([
1829
- src_JSON.stringify(this.toDplayer())
1830
- ], "dplayer.json", {
1831
- type: 'application/json'
1832
- });
1833
- return this.toDplayer();
1834
- case "artplayer.json":
1835
- if (file_wrapper) return new File([
1836
- src_JSON.stringify(this.toArtplayer())
1837
- ], "artplayer.json", {
1838
- type: 'application/json'
1839
- });
1840
- return this.toArtplayer();
1841
- case "ddplay.json":
1842
- if (file_wrapper) return new File([
1843
- src_JSON.stringify(this.toDDPlay())
1844
- ], "ddplay.json", {
1845
- type: 'application/json'
1846
- });
1847
- return this.toDDPlay();
1848
- default:
1849
- {
1850
- const message = '(err) Unknown format or unsupported now!';
1851
- if (continue_on_error) return message;
1852
- throw new Error(message);
1853
- }
1854
- }
1855
- }
1856
- minify() {
1857
- return this.dans.map((d)=>d.minify());
1858
- }
1859
- static fromMin(json, options) {
1860
- return new UniPool(json.map((d)=>UniDM.create(d, options)));
1861
- }
1862
- static fromPb(bin, options) {
1863
- const data = fromBinary(ListDanResponseSchema, new Uint8Array(bin));
1864
- return new UniPool(data.danmakus.map((d)=>UniDM.create({
1865
- ...d,
1866
- SOID: d.soid,
1867
- DMID: d.dmid,
1868
- progress: d.progress / 1000,
1869
- mode: d.mode,
1870
- senderID: d.senderId,
1871
- ctime: timestampDate(d.ctime || timestampNow()),
1872
- pool: d.pool,
1873
- attr: d.attr,
1874
- extra: void 0,
1875
- extraStr: d.extra
1876
- }, options)), options);
1877
- }
1878
- toPb() {
1879
- return toBinary(ListDanResponseSchema, create(ListDanResponseSchema, {
1880
- danmakus: this.dans.map((d)=>({
1881
- soid: d.SOID,
1882
- dmid: d.DMID ?? '',
1883
- progress: Math.round(1000 * d.progress),
1884
- mode: d.mode,
1885
- fontsize: d.fontsize,
1886
- color: d.color,
1887
- senderId: d.senderID,
1888
- content: d.content,
1889
- ctime: timestampFromDate(d.ctime),
1890
- weight: d.weight,
1891
- pool: d.pool,
1892
- attr: d.attr,
1893
- platform: d.platform,
1894
- extra: d.extraStr
1895
- }))
1896
- }));
1897
- }
1898
- static fromBiliXML(xml, options) {
1899
- const parser = new XMLParser({
1900
- ignoreAttributes: false,
1901
- isArray: (_name, jpath, _isLeafNode, _isAttribute)=>{
1902
- if ('i.d' === jpath) return true;
1903
- return false;
1904
- }
1905
- });
1906
- const oriData = parser.parse(xml);
1907
- const dans = oriData.i.d;
1908
- const fromConverted = !!oriData.i.danuni;
1909
- const cid = BigInt(oriData.i.chatid);
1910
- return new UniPool(dans.map((d)=>UniDM.fromBili(UniDM.parseBiliSingle(d['@_p'], d['#text']), cid, options, fromConverted ? oriData.i.danuni?.data : void 0)).filter((d)=>null !== d), options, {
1911
- fromConverted
1912
- });
1913
- }
1914
- toBiliXML(options) {
1915
- const genCID = (id)=>{
1916
- if (!id) return options?.cid || id_gen_UniID.fromNull().toString();
1917
- {
1918
- const UniID = id_gen_UniID.fromString(id);
1919
- if (UniID.domain === platform_PlatformVideoSource.Bilibili) {
1920
- const cid = UniID.id.replaceAll(`def_${platform_PlatformVideoSource.Bilibili}+`, '');
1921
- if (cid) return cid;
1922
- }
1923
- return options?.cid || id;
1924
- }
1925
- };
1926
- if (options?.avoidSenderIDWithAt) {
1927
- const ok = this.dans.every((d)=>d.senderID.endsWith(`@${platform_PlatformVideoSource.Bilibili}`));
1928
- if (!ok) throw new Error('存在其他来源的senderID,请关闭该功能再试!');
1929
- }
1930
- let ds = this.dans.map((dan)=>dan.toBiliXML(options));
1931
- if (options?.skipBiliCommand) ds = ds.filter((d)=>null !== d);
1932
- const builder = new XMLBuilder({
1933
- ignoreAttributes: false
1934
- });
1935
- return builder.build({
1936
- '?xml': {
1937
- '@_version': '1.0',
1938
- '@_encoding': 'UTF-8'
1939
- },
1940
- i: {
1941
- chatserver: 'chat.bilibili.com',
1942
- chatid: genCID(this.dans[0]?.SOID),
1943
- mission: 0,
1944
- maxlimit: this.dans.length,
1945
- state: 0,
1946
- real_name: 0,
1947
- source: 'k-v',
1948
- danuni: {
1949
- ...DanUniConvertTipTemplate,
1950
- data: this.getShared('SOID')
1951
- },
1952
- d: ds
1953
- }
1954
- });
1955
- }
1956
- static fromBiliGrpc(bin, options) {
1957
- const data = fromBinary(DmSegMobileReplySchema, new Uint8Array(bin));
1958
- const json = data.elems;
1959
- return new UniPool(json.map((d)=>UniDM.fromBili({
1960
- ...d,
1961
- progress: d.progress / 1000
1962
- }, d.oid, options)), options);
1963
- }
1964
- static fromBiliCommandGrpc(bin, options) {
1965
- const data = fromBinary(DmWebViewReplySchema, new Uint8Array(bin));
1966
- const json = data.commandDms;
1967
- return new UniPool(json.map((d)=>UniDM.fromBiliCommand(d, d.oid, options)), options);
1968
- }
1969
- static fromBiliUp(json, options) {
1970
- return new UniPool(json.data.result.map((d)=>{
1971
- const attrBin = d.attrs ? d.attrs.split(',').map(Number).reduce((bin, bitPosition)=>bin | 1 << bitPosition - 1, 0) : 0;
1972
- return UniDM.fromBili({
1973
- id: BigInt(d.id_str || d.id),
1974
- progress: d.progress / 1000,
1975
- mode: d.mode,
1976
- fontsize: d.fontsize,
1977
- color: Number.parseInt(d.color, 16),
1978
- mid: d.mid,
1979
- midHash: d.mid_hash,
1980
- content: d.msg,
1981
- ctime: BigInt(d.ctime),
1982
- pool: d.pool,
1983
- attr: attrBin,
1984
- oid: BigInt(d.oid)
1985
- }, BigInt(d.oid), options);
1986
- }), options);
1987
- }
1988
- static fromDplayer(json, playerID, domain = 'other', options) {
1989
- return new UniPool(json.data.map((d)=>UniDM.fromDplayer({
1990
- content: d[4],
1991
- progress: d[0],
1992
- mode: d[1],
1993
- color: d[2],
1994
- midHash: d[3]
1995
- }, playerID, domain, options)), options, {
1996
- fromConverted: !!json.danuni
1997
- });
1998
- }
1999
- toDplayer() {
2000
- return {
2001
- code: 0,
2002
- danuni: {
2003
- ...DanUniConvertTipTemplate,
2004
- data: this.dans[0]?.SOID.split('@')[0]
2005
- },
2006
- data: this.dans.map((dan)=>{
2007
- const d = dan.toDplayer();
2008
- return [
2009
- d.progress,
2010
- d.mode,
2011
- d.color,
2012
- d.midHash,
2013
- d.content
2014
- ];
2015
- })
2016
- };
2017
- }
2018
- static fromArtplayer(json, playerID, domain = 'other', options) {
2019
- return new UniPool(json.danmuku.map((d)=>UniDM.fromArtplayer({
2020
- content: d.text,
2021
- progress: d.time || 0,
2022
- mode: d.mode || 0,
2023
- color: Number((d.color || 'FFFFFF').replace('#', '0x')),
2024
- style: d.style
2025
- }, playerID, domain, options)), options, {
2026
- fromConverted: !!json.danuni
2027
- });
2028
- }
2029
- toArtplayer() {
2030
- return {
2031
- danuni: {
2032
- ...DanUniConvertTipTemplate,
2033
- data: this.dans[0]?.SOID.split('@')[0]
2034
- },
2035
- danmuku: this.dans.map((dan)=>{
2036
- const d = dan.toArtplayer();
2037
- return {
2038
- text: d.content,
2039
- time: d.progress,
2040
- mode: d.mode,
2041
- color: `#${d.color.toString(16).toUpperCase() || 'FFFFFF'}`,
2042
- border: d.border,
2043
- style: d.style
2044
- };
2045
- })
2046
- };
2047
- }
2048
- static fromDDPlay(json, episodeId, options) {
2049
- return new UniPool(json.comments.map((d)=>{
2050
- const p_arr = d.p.split(',');
2051
- return UniDM.fromDDPlay({
2052
- cid: d.cid,
2053
- color: Number.parseInt(p_arr[2]),
2054
- m: d.m,
2055
- mode: Number.parseInt(p_arr[1]),
2056
- progress: Number.parseFloat(p_arr[0]),
2057
- uid: p_arr[3]
2058
- }, episodeId, void 0, options);
2059
- }), options, {
2060
- fromConverted: !!json.danuni
2061
- });
2062
- }
2063
- toDDPlay() {
2064
- const episodeId = this.dans[0]?.SOID.split('@')[0].replaceAll(`def_${platform_PlatformDanmakuOnlySource.DanDanPlay}+`, '');
2065
- return {
2066
- danuni: {
2067
- ...DanUniConvertTipTemplate,
2068
- data: episodeId
2069
- },
2070
- count: this.dans.length,
2071
- comments: this.dans.map((dan)=>{
2072
- const d = dan.toDDPlay();
2073
- return {
2074
- cid: d.cid,
2075
- p: `${d.progress},${d.mode},${d.color},${d.uid}`,
2076
- m: d.m
2077
- };
2078
- })
2079
- };
2080
- }
2081
- static fromASS(ass, options) {
2082
- return parseAssRawField(ass, options);
2083
- }
2084
- toASS(canvasCtx, options) {
2085
- const defaultOptions = {
2086
- substyle: {}
2087
- };
2088
- const finalOptions = options ?? defaultOptions;
2089
- const fn = this.getShared('SOID');
2090
- return generateASS(this, {
2091
- filename: fn,
2092
- title: fn,
2093
- ...finalOptions
2094
- }, canvasCtx);
2095
- }
2096
- }
2097
- export { UniDM, UniPool, bili_history_fast_forward, bili_namespaceObject as bili, convert2Formats, dedupe_namespaceObject as bili_dedupe, dm_gen_namespaceObject as UniDMTools, id_gen_namespaceObject as UniIDTools, platform_namespaceObject as platform, plugins_namespaceObject as plugins, src_DM_format as DM_format };