node-karin 0.0.3 → 0.1.1

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 (109) hide show
  1. package/LICENSE +674 -674
  2. package/README.md +57 -57
  3. package/config/defSet/App.yaml +37 -37
  4. package/config/defSet/config.yaml +43 -43
  5. package/config/defSet/group.yaml +18 -18
  6. package/config/defSet/pm2.yaml +21 -21
  7. package/config/defSet/server.yaml +42 -42
  8. package/config/view/App.yaml +74 -74
  9. package/config/view/config.yaml +100 -100
  10. package/config/view/group.yaml +62 -62
  11. package/config/view/pm2.yaml +41 -41
  12. package/config/view/redis.yaml +25 -25
  13. package/config/view/server.yaml +93 -93
  14. package/lib/adapter/onebot/onebot11.d.ts +430 -430
  15. package/lib/adapter/onebot/onebot11.js +1265 -1302
  16. package/lib/core/dir.d.ts +1 -0
  17. package/lib/core/dir.js +4 -0
  18. package/lib/core/init.js +4 -4
  19. package/lib/core/karin.d.ts +72 -72
  20. package/lib/core/karin.js +51 -51
  21. package/lib/core/listener.d.ts +121 -121
  22. package/lib/core/listener.js +178 -178
  23. package/lib/core/plugin.app.d.ts +15 -15
  24. package/lib/core/plugin.app.js +18 -18
  25. package/lib/core/plugin.d.ts +182 -182
  26. package/lib/core/plugin.js +132 -132
  27. package/lib/core/plugin.loader.d.ts +149 -149
  28. package/lib/core/plugin.loader.js +451 -451
  29. package/lib/core/server.d.ts +26 -26
  30. package/lib/core/server.js +209 -209
  31. package/lib/db/level.d.ts +20 -20
  32. package/lib/db/level.js +36 -36
  33. package/lib/db/redis.d.ts +41 -41
  34. package/lib/db/redis.js +131 -131
  35. package/lib/db/redis_level.d.ts +113 -113
  36. package/lib/db/redis_level.js +274 -274
  37. package/lib/event/event.d.ts +138 -138
  38. package/lib/event/event.handler.d.ts +29 -29
  39. package/lib/event/event.handler.js +138 -138
  40. package/lib/event/event.js +120 -120
  41. package/lib/event/message.d.ts +102 -102
  42. package/lib/event/message.handler.d.ts +25 -25
  43. package/lib/event/message.handler.js +237 -237
  44. package/lib/event/message.js +69 -69
  45. package/lib/event/notice.d.ts +49 -49
  46. package/lib/event/notice.js +14 -14
  47. package/lib/event/request.d.ts +49 -49
  48. package/lib/event/request.js +14 -14
  49. package/lib/event/review.handler.d.ts +54 -54
  50. package/lib/event/review.handler.js +374 -374
  51. package/lib/index.d.ts +24 -23
  52. package/lib/index.js +40 -40
  53. package/lib/renderer/app.d.ts +53 -53
  54. package/lib/renderer/app.js +88 -88
  55. package/lib/renderer/base.d.ts +30 -30
  56. package/lib/renderer/base.js +68 -68
  57. package/lib/renderer/client.d.ts +30 -30
  58. package/lib/renderer/client.js +155 -155
  59. package/lib/renderer/http.d.ts +19 -19
  60. package/lib/renderer/http.js +50 -50
  61. package/lib/renderer/server.d.ts +42 -42
  62. package/lib/renderer/server.js +110 -110
  63. package/lib/renderer/wormhole.d.ts +1 -1
  64. package/lib/renderer/wormhole.js +154 -154
  65. package/lib/tools/init.d.ts +2 -0
  66. package/lib/tools/init.js +31 -0
  67. package/lib/types/adapter.d.ts +575 -575
  68. package/lib/types/adapter.js +1 -1
  69. package/lib/types/config.d.ts +327 -327
  70. package/lib/types/config.js +1 -1
  71. package/lib/types/element.d.ts +576 -576
  72. package/lib/types/element.js +1 -1
  73. package/lib/types/index.d.ts +8 -8
  74. package/lib/types/index.js +8 -8
  75. package/lib/types/logger.d.ts +109 -109
  76. package/lib/types/logger.js +1 -1
  77. package/lib/types/onebots11.d.ts +1371 -1371
  78. package/lib/types/onebots11.js +1 -1
  79. package/lib/types/plugin.d.ts +282 -282
  80. package/lib/types/plugin.js +1 -1
  81. package/lib/types/render.d.ts +111 -111
  82. package/lib/types/render.js +1 -1
  83. package/lib/types/reply.d.ts +40 -40
  84. package/lib/types/reply.js +1 -1
  85. package/lib/types/types.d.ts +898 -898
  86. package/lib/types/types.js +1 -1
  87. package/lib/utils/YamlEditor.d.ts +62 -62
  88. package/lib/utils/YamlEditor.js +197 -197
  89. package/lib/utils/button.d.ts +49 -49
  90. package/lib/utils/button.js +75 -75
  91. package/lib/utils/common.d.ts +123 -123
  92. package/lib/utils/common.js +396 -396
  93. package/lib/utils/config.d.ts +72 -72
  94. package/lib/utils/config.js +259 -254
  95. package/lib/utils/exec.d.ts +22 -22
  96. package/lib/utils/exec.js +36 -36
  97. package/lib/utils/ffmpeg.d.ts +12 -12
  98. package/lib/utils/ffmpeg.js +25 -25
  99. package/lib/utils/handler.d.ts +76 -76
  100. package/lib/utils/handler.js +98 -98
  101. package/lib/utils/logger.d.ts +3 -3
  102. package/lib/utils/logger.js +104 -104
  103. package/lib/utils/segment.d.ts +276 -276
  104. package/lib/utils/segment.js +420 -420
  105. package/lib/utils/update.d.ts +69 -69
  106. package/lib/utils/update.js +145 -145
  107. package/lib/utils/updateVersion.d.ts +33 -33
  108. package/lib/utils/updateVersion.js +140 -140
  109. package/package.json +95 -91
@@ -1,290 +1,290 @@
1
- import { Level } from 'level'
2
- export default class RedisLevel {
3
- #level
4
- #expireMap
5
- id
6
- constructor () {
7
- const path = process.cwd() + '/data/db/RedisLevel'
8
- this.#level = new Level(path, { valueEncoding: 'json' })
9
- /**
10
- * @type {'RedisLevel'} 唯一标识符 用于区分不同的数据库
11
- */
12
- this.id = 'RedisLevel'
13
- /**
14
- * 过期时间映射表
15
- * @type {Map<string, number>} 键: 值 (过期时间)
16
- */
17
- this.#expireMap = new Map()
18
- /**
19
- * 开启过期时间处理
20
- */
21
- this.#expireHandle()
1
+ import { Level } from 'level'
2
+ export default class RedisLevel {
3
+ #level
4
+ #expireMap
5
+ id
6
+ constructor () {
7
+ const path = process.cwd() + '/data/db/RedisLevel'
8
+ this.#level = new Level(path, { valueEncoding: 'json' })
9
+ /**
10
+ * @type {'RedisLevel'} 唯一标识符 用于区分不同的数据库
11
+ */
12
+ this.id = 'RedisLevel'
13
+ /**
14
+ * 过期时间映射表
15
+ * @type {Map<string, number>} 键: 值 (过期时间)
16
+ */
17
+ this.#expireMap = new Map()
18
+ /**
19
+ * 开启过期时间处理
20
+ */
21
+ this.#expireHandle()
22
22
  }
23
-
24
- /**
25
- * 过期时间处理 每分钟检查一次
26
- */
27
- async #expireHandle () {
28
- setInterval(async () => {
29
- const now = Date.now()
30
- // 获取代理对象的键值对数组
31
- const entries = Array.from(this.#expireMap.entries())
32
- for (const [key, expire] of entries) {
33
- if (expire < now) {
34
- await this.#level.del(key)
35
- this.#expireMap.delete(key) // 通过代理的方式删除键值对
36
- }
37
- }
38
- }, 60000)
39
- /**
40
- * 对expireMap进行代理 实现持久化 每次触发都保存到数据库
41
- */
42
- const handler = {
43
- get: function (target, prop, receiver) {
44
- if (prop === 'get' || prop === 'entries') {
45
- return function (...args) {
46
- const reflect = Reflect.get(target, prop).apply(target, args)
47
- return typeof reflect === 'function' ? reflect.bind(target) : reflect
48
- }
49
- }
50
- const reflect = Reflect.get(target, prop, receiver)
51
- return typeof reflect === 'function' ? reflect.bind(target) : reflect
52
- },
53
- set: function (target, key, value) {
54
- target.set(key, value)
55
- // 修改后持久化到数据库
56
- const reflect = Reflect.set(target, key, value)
57
- return typeof reflect === 'function' ? reflect.bind(target) : reflect
58
- },
59
- deleteProperty: function (target, key) {
60
- Reflect.deleteProperty(target, key)
61
- // 删除后持久化到数据库
62
- const reflect = Reflect.deleteProperty(target, key)
63
- return typeof reflect === 'function' ? reflect.bind(target) : reflect
64
- },
65
- }
66
- this.#expireMap = new Proxy(this.#expireMap, handler)
23
+
24
+ /**
25
+ * 过期时间处理 每分钟检查一次
26
+ */
27
+ async #expireHandle () {
28
+ setInterval(async () => {
29
+ const now = Date.now()
30
+ // 获取代理对象的键值对数组
31
+ const entries = Array.from(this.#expireMap.entries())
32
+ for (const [key, expire] of entries) {
33
+ if (expire < now) {
34
+ await this.#level.del(key)
35
+ this.#expireMap.delete(key) // 通过代理的方式删除键值对
36
+ }
37
+ }
38
+ }, 60000)
39
+ /**
40
+ * 对expireMap进行代理 实现持久化 每次触发都保存到数据库
41
+ */
42
+ const handler = {
43
+ get: function (target, prop, receiver) {
44
+ if (prop === 'get' || prop === 'entries') {
45
+ return function (...args) {
46
+ const reflect = Reflect.get(target, prop).apply(target, args)
47
+ return typeof reflect === 'function' ? reflect.bind(target) : reflect
48
+ }
49
+ }
50
+ const reflect = Reflect.get(target, prop, receiver)
51
+ return typeof reflect === 'function' ? reflect.bind(target) : reflect
52
+ },
53
+ set: function (target, key, value) {
54
+ target.set(key, value)
55
+ // 修改后持久化到数据库
56
+ const reflect = Reflect.set(target, key, value)
57
+ return typeof reflect === 'function' ? reflect.bind(target) : reflect
58
+ },
59
+ deleteProperty: function (target, key) {
60
+ Reflect.deleteProperty(target, key)
61
+ // 删除后持久化到数据库
62
+ const reflect = Reflect.deleteProperty(target, key)
63
+ return typeof reflect === 'function' ? reflect.bind(target) : reflect
64
+ },
65
+ }
66
+ this.#expireMap = new Proxy(this.#expireMap, handler)
67
67
  }
68
-
69
- /**
70
- * get 获取数据
71
- * @param {string} key 键
72
- * @returns {Promise<string>|Error} 数据
73
- */
74
- async get (key) {
75
- try {
76
- /** 先查过期时间 */
77
- const expire = this.#expireMap.get(key)
78
- if (expire && expire < Date.now()) {
79
- await this.#level.del(key)
80
- this.#expireMap.delete(key)
81
- return null
82
- }
83
- return await this.#level.get(key)
84
- } catch (error) {
85
- if (error.notFound) { return null }
86
- throw error
87
- }
68
+
69
+ /**
70
+ * get 获取数据
71
+ * @param {string} key 键
72
+ * @returns {Promise<string>|Error} 数据
73
+ */
74
+ async get (key) {
75
+ try {
76
+ /** 先查过期时间 */
77
+ const expire = this.#expireMap.get(key)
78
+ if (expire && expire < Date.now()) {
79
+ await this.#level.del(key)
80
+ this.#expireMap.delete(key)
81
+ return null
82
+ }
83
+ return await this.#level.get(key)
84
+ } catch (error) {
85
+ if (error.notFound) { return null }
86
+ throw error
87
+ }
88
88
  }
89
-
90
- /**
91
- * set 设置数据
92
- * @param {string} key 键
93
- * @param {string} value 值
94
- * @param {object} [options] 选项
95
- * @param [options.EX] 过期时间 单位秒
96
- * @returns {Promise<void>|Error}
97
- */
98
- async set (key, value, options) {
99
- if (options && options.EX) {
100
- this.#expireMap.set(key, Date.now() + options.EX * 1000)
101
- }
102
- return await this.#level.put(key, value)
89
+
90
+ /**
91
+ * set 设置数据
92
+ * @param {string} key 键
93
+ * @param {string} value 值
94
+ * @param {object} [options] 选项
95
+ * @param [options.EX] 过期时间 单位秒
96
+ * @returns {Promise<void>|Error}
97
+ */
98
+ async set (key, value, options) {
99
+ if (options && options.EX) {
100
+ this.#expireMap.set(key, Date.now() + options.EX * 1000)
101
+ }
102
+ return await this.#level.put(key, value)
103
103
  }
104
-
105
- /**
106
- * del 删除数据
107
- * @param {string} key 键
108
- * @returns {Promise<void>|Error}
109
- */
110
- async del (key) {
111
- this.#expireMap.delete(key)
112
- return await this.#level.del(key)
104
+
105
+ /**
106
+ * del 删除数据
107
+ * @param {string} key 键
108
+ * @returns {Promise<void>|Error}
109
+ */
110
+ async del (key) {
111
+ this.#expireMap.delete(key)
112
+ return await this.#level.del(key)
113
113
  }
114
-
115
- /**
116
- * keys 获取所有键
117
- * @param {string} [prefix] 前缀
118
- * @returns {Promise<string[]>|Error} 键列表
119
- */
120
- async keys (prefix = '') {
121
- const keys = []
122
- for await (const key of this.#level.keys({ gte: prefix, lt: prefix + '\xFF' })) {
123
- // Check if the key has expired
124
- const expire = this.#expireMap.get(key)
125
- if (expire && expire < Date.now()) {
126
- await this.#level.del(key)
127
- this.#expireMap.delete(key)
128
- } else {
129
- keys.push(key)
130
- }
131
- }
132
- return keys
114
+
115
+ /**
116
+ * keys 获取所有键
117
+ * @param {string} [prefix] 前缀
118
+ * @returns {Promise<string[]>|Error} 键列表
119
+ */
120
+ async keys (prefix = '') {
121
+ const keys = []
122
+ for await (const key of this.#level.keys({ gte: prefix, lt: prefix + '\xFF' })) {
123
+ // Check if the key has expired
124
+ const expire = this.#expireMap.get(key)
125
+ if (expire && expire < Date.now()) {
126
+ await this.#level.del(key)
127
+ this.#expireMap.delete(key)
128
+ } else {
129
+ keys.push(key)
130
+ }
131
+ }
132
+ return keys
133
133
  }
134
-
135
- /**
136
- * incr 递增数据
137
- * @param {string} key 键
138
- * @returns {Promise<number>|Error}
139
- */
140
- async incr (key) {
141
- let value = Number(await this.get(key))
142
- if (value === null) {
143
- value = 0
144
- } else {
145
- value = Number(value)
146
- if (isNaN(value)) { throw new Error('Value is not a number') }
147
- }
148
- value += 1
149
- await this.set(key, value.toString())
150
- return value
134
+
135
+ /**
136
+ * incr 递增数据
137
+ * @param {string} key 键
138
+ * @returns {Promise<number>|Error}
139
+ */
140
+ async incr (key) {
141
+ let value = Number(await this.get(key))
142
+ if (value === null) {
143
+ value = 0
144
+ } else {
145
+ value = Number(value)
146
+ if (isNaN(value)) { throw new Error('Value is not a number') }
147
+ }
148
+ value += 1
149
+ await this.set(key, value.toString())
150
+ return value
151
151
  }
152
-
153
- /**
154
- * decr 递减数据
155
- * @param {string} key 键
156
- * @returns {Promise<number>|Error}
157
- */
158
- async decr (key) {
159
- let value = Number(await this.get(key))
160
- if (value === null) {
161
- value = 0
162
- } else {
163
- value = Number(value)
164
- if (isNaN(value)) { throw new Error('Value is not a number') }
165
- }
166
- value -= 1
167
- await this.set(key, value.toString())
168
- return value
152
+
153
+ /**
154
+ * decr 递减数据
155
+ * @param {string} key 键
156
+ * @returns {Promise<number>|Error}
157
+ */
158
+ async decr (key) {
159
+ let value = Number(await this.get(key))
160
+ if (value === null) {
161
+ value = 0
162
+ } else {
163
+ value = Number(value)
164
+ if (isNaN(value)) { throw new Error('Value is not a number') }
165
+ }
166
+ value -= 1
167
+ await this.set(key, value.toString())
168
+ return value
169
169
  }
170
-
171
- /**
172
- * expire 设置过期时间
173
- * @param {string} key 键
174
- * @param seconds 过期时间 单位秒
175
- * @returns {Promise<number>|Error}
176
- */
177
- async expire (key, seconds) {
178
- this.#expireMap.set(key, Date.now() + seconds * 1000)
179
- return seconds
170
+
171
+ /**
172
+ * expire 设置过期时间
173
+ * @param {string} key 键
174
+ * @param seconds 过期时间 单位秒
175
+ * @returns {Promise<number>|Error}
176
+ */
177
+ async expire (key, seconds) {
178
+ this.#expireMap.set(key, Date.now() + seconds * 1000)
179
+ return seconds
180
180
  }
181
-
182
- /**
183
- * ttl 获取过期时间
184
- * @param {string} key 键
185
- * @returns {Promise<number>|Error}
186
- */
187
- async ttl (key) {
188
- const expire = this.#expireMap.get(key)
189
- if (expire) {
190
- return Math.ceil((expire - Date.now()) / 1000)
191
- }
192
- return -2
181
+
182
+ /**
183
+ * ttl 获取过期时间
184
+ * @param {string} key 键
185
+ * @returns {Promise<number>|Error}
186
+ */
187
+ async ttl (key) {
188
+ const expire = this.#expireMap.get(key)
189
+ if (expire) {
190
+ return Math.ceil((expire - Date.now()) / 1000)
191
+ }
192
+ return -2
193
193
  }
194
-
195
- /**
196
- * setEx 设置数据并设置过期时间
197
- * @param {string} key 键
198
- * @param seconds 过期时间 单位秒
199
- * @param {string} value 值
200
- * @returns {Promise<void>|Error}
201
- */
202
- async setEx (key, seconds, value) {
203
- this.#expireMap.set(key, Date.now() + seconds * 1000)
204
- return await this.#level.put(key, value)
194
+
195
+ /**
196
+ * setEx 设置数据并设置过期时间
197
+ * @param {string} key 键
198
+ * @param seconds 过期时间 单位秒
199
+ * @param {string} value 值
200
+ * @returns {Promise<void>|Error}
201
+ */
202
+ async setEx (key, seconds, value) {
203
+ this.#expireMap.set(key, Date.now() + seconds * 1000)
204
+ return await this.#level.put(key, value)
205
205
  }
206
-
207
- /**
208
- * exists 判断键是否存在
209
- * @param {string} key 键
210
- * @returns {Promise<number>|Error}
211
- */
212
- async exists (key) {
213
- const value = await this.get(key)
214
- return value === null ? 0 : 1
206
+
207
+ /**
208
+ * exists 判断键是否存在
209
+ * @param {string} key 键
210
+ * @returns {Promise<number>|Error}
211
+ */
212
+ async exists (key) {
213
+ const value = await this.get(key)
214
+ return value === null ? 0 : 1
215
215
  }
216
-
217
- /**
218
- * zAdd 有序集合添加元素
219
- * @param {string} key 键
220
- * @param {object} data 数据
221
- * @param data.score 分数
222
- * @param {string} data.value 值
223
- */
224
- async zAdd (key, { score, value }) {
225
- const set = await this.get(key)
226
- const arr = (set ? JSON.parse(set) : [])
227
- arr.push({ score, value })
228
- arr.sort((a, b) => a.score - b.score)
229
- await this.set(key, JSON.stringify(arr))
216
+
217
+ /**
218
+ * zAdd 有序集合添加元素
219
+ * @param {string} key 键
220
+ * @param {object} data 数据
221
+ * @param data.score 分数
222
+ * @param {string} data.value 值
223
+ */
224
+ async zAdd (key, { score, value }) {
225
+ const set = await this.get(key)
226
+ const arr = (set ? JSON.parse(set) : [])
227
+ arr.push({ score, value })
228
+ arr.sort((a, b) => a.score - b.score)
229
+ await this.set(key, JSON.stringify(arr))
230
230
  }
231
-
232
- /**
233
- * zRem 有序集合删除元素
234
- * @param {string} key 键
235
- * @param {string} value 值
236
- */
237
- async zRem (key, value) {
238
- const set = await this.get(key)
239
- if (set === null) { return }
240
- let arr = JSON.parse(set)
241
- arr = arr.filter((item) => item.value !== value)
242
- await this.set(key, JSON.stringify(arr))
231
+
232
+ /**
233
+ * zRem 有序集合删除元素
234
+ * @param {string} key 键
235
+ * @param {string} value 值
236
+ */
237
+ async zRem (key, value) {
238
+ const set = await this.get(key)
239
+ if (set === null) { return }
240
+ let arr = JSON.parse(set)
241
+ arr = arr.filter((item) => item.value !== value)
242
+ await this.set(key, JSON.stringify(arr))
243
243
  }
244
-
245
- /**
246
- * zIncrBy 有序集合分数递增
247
- * @param {string} key 键
248
- * @param increment 递增值
249
- * @param {string} value 值
250
- * @returns {Promise<number>|Error}
251
- */
252
- async zIncrBy (key, increment, value) {
253
- const set = await this.get(key)
254
- if (set === null) { throw new Error('Set does not exist') }
255
- const arr = JSON.parse(set)
256
- const item = arr.find((item) => item.value === value)
257
- if (item) { item.score += increment }
258
- arr.sort((a, b) => a.score - b.score)
259
- await this.set(key, JSON.stringify(arr))
260
- return item.score
244
+
245
+ /**
246
+ * zIncrBy 有序集合分数递增
247
+ * @param {string} key 键
248
+ * @param increment 递增值
249
+ * @param {string} value 值
250
+ * @returns {Promise<number>|Error}
251
+ */
252
+ async zIncrBy (key, increment, value) {
253
+ const set = await this.get(key)
254
+ if (set === null) { throw new Error('Set does not exist') }
255
+ const arr = JSON.parse(set)
256
+ const item = arr.find((item) => item.value === value)
257
+ if (item) { item.score += increment }
258
+ arr.sort((a, b) => a.score - b.score)
259
+ await this.set(key, JSON.stringify(arr))
260
+ return item.score
261
261
  }
262
-
263
- /**
264
- * zRangeByScore 有序集合根据分数范围获取元素
265
- * @param {string} key 键
266
- * @param min 最小分数
267
- * @param max 最大分数
268
- * @returns {Promise<string[]>|Error}
269
- */
270
- async zRangeByScore (key, min, max) {
271
- const set = await this.get(key)
272
- if (set === null) { return [] }
273
- const arr = JSON.parse(set)
274
- return arr.filter((item) => item.score >= min && item.score <= max).map((item) => item.value)
262
+
263
+ /**
264
+ * zRangeByScore 有序集合根据分数范围获取元素
265
+ * @param {string} key 键
266
+ * @param min 最小分数
267
+ * @param max 最大分数
268
+ * @returns {Promise<string[]>|Error}
269
+ */
270
+ async zRangeByScore (key, min, max) {
271
+ const set = await this.get(key)
272
+ if (set === null) { return [] }
273
+ const arr = JSON.parse(set)
274
+ return arr.filter((item) => item.score >= min && item.score <= max).map((item) => item.value)
275
275
  }
276
-
277
- /**
278
- * zScore 有序集合获取元素分数
279
- * @param {string} key 键
280
- * @param {string} value 值
281
- * @returns {Promise<number>|Error}
282
- */
283
- async zScore (key, value) {
284
- const set = await this.get(key)
285
- if (set === null) { return null }
286
- const arr = JSON.parse(set)
287
- const item = arr.find((item) => item.value === value)
288
- return item ? item.score : null
289
- }
290
- }
276
+
277
+ /**
278
+ * zScore 有序集合获取元素分数
279
+ * @param {string} key 键
280
+ * @param {string} value 值
281
+ * @returns {Promise<number>|Error}
282
+ */
283
+ async zScore (key, value) {
284
+ const set = await this.get(key)
285
+ if (set === null) { return null }
286
+ const arr = JSON.parse(set)
287
+ const item = arr.find((item) => item.value === value)
288
+ return item ? item.score : null
289
+ }
290
+ }