diff --git a/manifest.json b/manifest.json index 873b9ef..10f25fd 100644 --- a/manifest.json +++ b/manifest.json @@ -4,7 +4,7 @@ "name": "LLOneBot", "slug": "LLOneBot", "description": "实现 OneBot 11 和 Satori 协议,用于 QQ 机器人开发", - "version": "4.0.12", + "version": "4.0.13", "icon": "./icon.webp", "authors": [ { diff --git a/package.json b/package.json index 4291466..6b70464 100644 --- a/package.json +++ b/package.json @@ -12,7 +12,7 @@ "deploy-win": "cmd /c \"xcopy /C /S /Y dist\\* %LITELOADERQQNT_PROFILE%\\plugins\\LLOneBot\\\"", "format": "prettier -cw .", "check": "tsc", - "compile:proto": "pbjs --no-create --no-convert --no-encode --no-verify -t static-module -w es6 -p src/ntqqapi/proto -o src/ntqqapi/proto/compiled.js systemMessage.proto profileLikeTip.proto groupMemberIncrease.proto && pbts -o src/ntqqapi/proto/compiled.d.ts src/ntqqapi/proto/compiled.js" + "compile:proto": "pbjs --no-create --no-convert --no-encode --no-verify -t static-module -w es6 -p src/ntqqapi/proto -o src/ntqqapi/proto/compiled.js systemMessage.proto profileLikeTip.proto groupMemberChange.proto && pbts -o src/ntqqapi/proto/compiled.d.ts src/ntqqapi/proto/compiled.js" }, "author": "", "license": "MIT", diff --git a/src/common/config.ts b/src/common/config.ts index f7ec98e..abfab1b 100644 --- a/src/common/config.ts +++ b/src/common/config.ts @@ -44,6 +44,7 @@ export class ConfigUtil { token: '' } const defaultConfig: Config = { + enableLLOB: true, satori: satoriDefault, ob11: ob11Default, heartInterval: 60000, diff --git a/src/common/types.ts b/src/common/types.ts index 14d780e..d1b1a48 100644 --- a/src/common/types.ts +++ b/src/common/types.ts @@ -28,6 +28,7 @@ export interface SatoriConfig { } export interface Config { + enableLLOB: boolean satori: SatoriConfig ob11: OB11Config token?: string @@ -49,8 +50,6 @@ export interface Config { /** @deprecated */ wsPort?: string /** @deprecated */ - enableLLOB?: boolean - /** @deprecated */ reportSelfMessage?: boolean } diff --git a/src/main/main.ts b/src/main/main.ts index 356b81d..f60e3ee 100644 --- a/src/main/main.ts +++ b/src/main/main.ts @@ -171,7 +171,7 @@ function onLoad() { log(arg) }) - const intervalId = setInterval(() => { + const intervalId = setInterval(async () => { const self = Object.assign(selfInfo, { uin: globalThis.authData?.uin, uid: globalThis.authData?.uid, @@ -182,6 +182,16 @@ function onLoad() { log('process pid', process.pid) const config = getConfigUtil().getConfig() + + if (config.enableLLOB && (config.satori.enable || config.ob11.enable)) { + startHook() + await ctx.sleep(300) + } else { + llonebotError.otherError = 'LLOneBot 未启动' + log('LLOneBot 开关设置为关闭,不启动 LLOneBot') + return + } + ctx.plugin(Log, { enable: config.log!, filename: logFileName @@ -224,7 +234,6 @@ function onBrowserWindowCreated(window: BrowserWindow) { try { onLoad() - startHook() } catch (e) { console.log(e) } diff --git a/src/ntqqapi/api/group.ts b/src/ntqqapi/api/group.ts index c4cd7e5..cae330a 100644 --- a/src/ntqqapi/api/group.ts +++ b/src/ntqqapi/api/group.ts @@ -325,4 +325,18 @@ export class NTQQGroupApi extends Service { ) return data.infos } + + async getGroupFileCount(groupId: string) { + return await invoke( + 'nodeIKernelRichMediaService/batchGetGroupFileCount', + [{ groupIds: [groupId] }] + ) + } + + async getGroupFileSpace(groupId: string) { + return await invoke( + 'nodeIKernelRichMediaService/getGroupSpace', + [{ groupId }] + ) + } } diff --git a/src/ntqqapi/api/user.ts b/src/ntqqapi/api/user.ts index ab1abd1..6232177 100644 --- a/src/ntqqapi/api/user.ts +++ b/src/ntqqapi/api/user.ts @@ -173,7 +173,7 @@ export class NTQQUserApi extends Service { async getUinByUidV2(uid: string) { let uin = (await invoke('nodeIKernelGroupService/getUinByUids', [{ uidList: [uid] }])).uins.get(uid) - if (uin) return uin + if (uin && uin !== '0') return uin uin = (await invoke('nodeIKernelProfileService/getUinByUid', [{ callFrom: 'FriendsServiceImpl', uid: [uid] }])).get(uid) if (uin) return uin uin = (await invoke('nodeIKernelUixConvertService/getUin', [{ uids: [uid] }])).uinInfo.get(uid) diff --git a/src/ntqqapi/core.ts b/src/ntqqapi/core.ts index 347e07f..21d760c 100644 --- a/src/ntqqapi/core.ts +++ b/src/ntqqapi/core.ts @@ -47,11 +47,6 @@ class Core extends Service { } public start() { - if (!this.config.ob11.enable && !this.config.satori.enable) { - llonebotError.otherError = 'LLOneBot 未启动' - this.ctx.logger.info('LLOneBot 开关设置为关闭,不启动 LLOneBot') - return - } this.startTime = Date.now() this.registerListener() this.ctx.logger.info(`LLOneBot/${version}`) diff --git a/src/ntqqapi/native/index.ts b/src/ntqqapi/native/index.ts index 500c13f..9606ae4 100644 --- a/src/ntqqapi/native/index.ts +++ b/src/ntqqapi/native/index.ts @@ -38,7 +38,12 @@ export class Native { try { const fileName = path.basename(addon) const dest = path.join(TEMP_DIR, fileName) - await copyFile(addon, dest) + try { + await copyFile(addon, dest) + } catch (e) { + // resource busy or locked? + this.ctx.logger.warn(e) + } this.crychic = require(dest) this.crychic!.init() } catch (e) { diff --git a/src/ntqqapi/proto/compiled.d.ts b/src/ntqqapi/proto/compiled.d.ts index 3d6e972..fc0f684 100644 --- a/src/ntqqapi/proto/compiled.d.ts +++ b/src/ntqqapi/proto/compiled.d.ts @@ -461,64 +461,64 @@ export namespace SysMsg { public static getTypeUrl(typeUrlPrefix?: string): string; } - /** Properties of a GroupMemberIncrease. */ - interface IGroupMemberIncrease { + /** Properties of a GroupMemberChange. */ + interface IGroupMemberChange { - /** GroupMemberIncrease groupCode */ + /** GroupMemberChange groupCode */ groupCode?: (number|null); - /** GroupMemberIncrease memberUid */ + /** GroupMemberChange memberUid */ memberUid?: (string|null); - /** GroupMemberIncrease type */ + /** GroupMemberChange type */ type?: (number|null); - /** GroupMemberIncrease adminUid */ + /** GroupMemberChange adminUid */ adminUid?: (string|null); } - /** Represents a GroupMemberIncrease. */ - class GroupMemberIncrease implements IGroupMemberIncrease { + /** Represents a GroupMemberChange. */ + class GroupMemberChange implements IGroupMemberChange { /** - * Constructs a new GroupMemberIncrease. + * Constructs a new GroupMemberChange. * @param [properties] Properties to set */ - constructor(properties?: SysMsg.IGroupMemberIncrease); + constructor(properties?: SysMsg.IGroupMemberChange); - /** GroupMemberIncrease groupCode. */ + /** GroupMemberChange groupCode. */ public groupCode: number; - /** GroupMemberIncrease memberUid. */ + /** GroupMemberChange memberUid. */ public memberUid: string; - /** GroupMemberIncrease type. */ + /** GroupMemberChange type. */ public type: number; - /** GroupMemberIncrease adminUid. */ + /** GroupMemberChange adminUid. */ public adminUid: string; /** - * Decodes a GroupMemberIncrease message from the specified reader or buffer. + * Decodes a GroupMemberChange message from the specified reader or buffer. * @param reader Reader or buffer to decode from * @param [length] Message length if known beforehand - * @returns GroupMemberIncrease + * @returns GroupMemberChange * @throws {Error} If the payload is not a reader or valid buffer * @throws {$protobuf.util.ProtocolError} If required fields are missing */ - public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): SysMsg.GroupMemberIncrease; + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): SysMsg.GroupMemberChange; /** - * Decodes a GroupMemberIncrease message from the specified reader or buffer, length delimited. + * Decodes a GroupMemberChange message from the specified reader or buffer, length delimited. * @param reader Reader or buffer to decode from - * @returns GroupMemberIncrease + * @returns GroupMemberChange * @throws {Error} If the payload is not a reader or valid buffer * @throws {$protobuf.util.ProtocolError} If required fields are missing */ - public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): SysMsg.GroupMemberIncrease; + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): SysMsg.GroupMemberChange; /** - * Gets the default type url for GroupMemberIncrease + * Gets the default type url for GroupMemberChange * @param [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com") * @returns The default type url */ diff --git a/src/ntqqapi/proto/compiled.js b/src/ntqqapi/proto/compiled.js index 1f0f50b..b7169d8 100644 --- a/src/ntqqapi/proto/compiled.js +++ b/src/ntqqapi/proto/compiled.js @@ -1015,27 +1015,27 @@ export const SysMsg = $root.SysMsg = (() => { return ProfileLikeTip; })(); - SysMsg.GroupMemberIncrease = (function() { + SysMsg.GroupMemberChange = (function() { /** - * Properties of a GroupMemberIncrease. + * Properties of a GroupMemberChange. * @memberof SysMsg - * @interface IGroupMemberIncrease - * @property {number|null} [groupCode] GroupMemberIncrease groupCode - * @property {string|null} [memberUid] GroupMemberIncrease memberUid - * @property {number|null} [type] GroupMemberIncrease type - * @property {string|null} [adminUid] GroupMemberIncrease adminUid + * @interface IGroupMemberChange + * @property {number|null} [groupCode] GroupMemberChange groupCode + * @property {string|null} [memberUid] GroupMemberChange memberUid + * @property {number|null} [type] GroupMemberChange type + * @property {string|null} [adminUid] GroupMemberChange adminUid */ /** - * Constructs a new GroupMemberIncrease. + * Constructs a new GroupMemberChange. * @memberof SysMsg - * @classdesc Represents a GroupMemberIncrease. - * @implements IGroupMemberIncrease + * @classdesc Represents a GroupMemberChange. + * @implements IGroupMemberChange * @constructor - * @param {SysMsg.IGroupMemberIncrease=} [properties] Properties to set + * @param {SysMsg.IGroupMemberChange=} [properties] Properties to set */ - function GroupMemberIncrease(properties) { + function GroupMemberChange(properties) { if (properties) for (let keys = Object.keys(properties), i = 0; i < keys.length; ++i) if (properties[keys[i]] != null) @@ -1043,52 +1043,52 @@ export const SysMsg = $root.SysMsg = (() => { } /** - * GroupMemberIncrease groupCode. + * GroupMemberChange groupCode. * @member {number} groupCode - * @memberof SysMsg.GroupMemberIncrease + * @memberof SysMsg.GroupMemberChange * @instance */ - GroupMemberIncrease.prototype.groupCode = 0; + GroupMemberChange.prototype.groupCode = 0; /** - * GroupMemberIncrease memberUid. + * GroupMemberChange memberUid. * @member {string} memberUid - * @memberof SysMsg.GroupMemberIncrease + * @memberof SysMsg.GroupMemberChange * @instance */ - GroupMemberIncrease.prototype.memberUid = ""; + GroupMemberChange.prototype.memberUid = ""; /** - * GroupMemberIncrease type. + * GroupMemberChange type. * @member {number} type - * @memberof SysMsg.GroupMemberIncrease + * @memberof SysMsg.GroupMemberChange * @instance */ - GroupMemberIncrease.prototype.type = 0; + GroupMemberChange.prototype.type = 0; /** - * GroupMemberIncrease adminUid. + * GroupMemberChange adminUid. * @member {string} adminUid - * @memberof SysMsg.GroupMemberIncrease + * @memberof SysMsg.GroupMemberChange * @instance */ - GroupMemberIncrease.prototype.adminUid = ""; + GroupMemberChange.prototype.adminUid = ""; /** - * Decodes a GroupMemberIncrease message from the specified reader or buffer. + * Decodes a GroupMemberChange message from the specified reader or buffer. * @function decode - * @memberof SysMsg.GroupMemberIncrease + * @memberof SysMsg.GroupMemberChange * @static * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from * @param {number} [length] Message length if known beforehand - * @returns {SysMsg.GroupMemberIncrease} GroupMemberIncrease + * @returns {SysMsg.GroupMemberChange} GroupMemberChange * @throws {Error} If the payload is not a reader or valid buffer * @throws {$protobuf.util.ProtocolError} If required fields are missing */ - GroupMemberIncrease.decode = function decode(reader, length) { + GroupMemberChange.decode = function decode(reader, length) { if (!(reader instanceof $Reader)) reader = $Reader.create(reader); - let end = length === undefined ? reader.len : reader.pos + length, message = new $root.SysMsg.GroupMemberIncrease(); + let end = length === undefined ? reader.len : reader.pos + length, message = new $root.SysMsg.GroupMemberChange(); while (reader.pos < end) { let tag = reader.uint32(); switch (tag >>> 3) { @@ -1117,37 +1117,37 @@ export const SysMsg = $root.SysMsg = (() => { }; /** - * Decodes a GroupMemberIncrease message from the specified reader or buffer, length delimited. + * Decodes a GroupMemberChange message from the specified reader or buffer, length delimited. * @function decodeDelimited - * @memberof SysMsg.GroupMemberIncrease + * @memberof SysMsg.GroupMemberChange * @static * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from - * @returns {SysMsg.GroupMemberIncrease} GroupMemberIncrease + * @returns {SysMsg.GroupMemberChange} GroupMemberChange * @throws {Error} If the payload is not a reader or valid buffer * @throws {$protobuf.util.ProtocolError} If required fields are missing */ - GroupMemberIncrease.decodeDelimited = function decodeDelimited(reader) { + GroupMemberChange.decodeDelimited = function decodeDelimited(reader) { if (!(reader instanceof $Reader)) reader = new $Reader(reader); return this.decode(reader, reader.uint32()); }; /** - * Gets the default type url for GroupMemberIncrease + * Gets the default type url for GroupMemberChange * @function getTypeUrl - * @memberof SysMsg.GroupMemberIncrease + * @memberof SysMsg.GroupMemberChange * @static * @param {string} [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com") * @returns {string} The default type url */ - GroupMemberIncrease.getTypeUrl = function getTypeUrl(typeUrlPrefix) { + GroupMemberChange.getTypeUrl = function getTypeUrl(typeUrlPrefix) { if (typeUrlPrefix === undefined) { typeUrlPrefix = "type.googleapis.com"; } - return typeUrlPrefix + "/SysMsg.GroupMemberIncrease"; + return typeUrlPrefix + "/SysMsg.GroupMemberChange"; }; - return GroupMemberIncrease; + return GroupMemberChange; })(); return SysMsg; diff --git a/src/ntqqapi/proto/groupMemberIncrease.proto b/src/ntqqapi/proto/groupMemberChange.proto similarity index 53% rename from src/ntqqapi/proto/groupMemberIncrease.proto rename to src/ntqqapi/proto/groupMemberChange.proto index 8b6a0bc..dd0ed38 100644 --- a/src/ntqqapi/proto/groupMemberIncrease.proto +++ b/src/ntqqapi/proto/groupMemberChange.proto @@ -1,10 +1,9 @@ syntax = "proto3"; package SysMsg; -// GroupChange? -message GroupMemberIncrease { +message GroupMemberChange { uint32 groupCode = 1; string memberUid = 3; - uint32 type = 4; // 130:主动 131:被邀请 + uint32 type = 4; // 130:主动 131:被动 string adminUid = 5; } diff --git a/src/ntqqapi/services/NodeIKernelRichMediaService.ts b/src/ntqqapi/services/NodeIKernelRichMediaService.ts index e11a4a6..4f58c60 100644 --- a/src/ntqqapi/services/NodeIKernelRichMediaService.ts +++ b/src/ntqqapi/services/NodeIKernelRichMediaService.ts @@ -39,5 +39,21 @@ export interface NodeIKernelRichMediaService { failFileIdList: Array } }> + + batchGetGroupFileCount(groupIds: string[]): Promise + + getGroupSpace(groupId: string): Promise } diff --git a/src/ntqqapi/types/user.ts b/src/ntqqapi/types/user.ts index d33976b..efd2df6 100644 --- a/src/ntqqapi/types/user.ts +++ b/src/ntqqapi/types/user.ts @@ -1,7 +1,8 @@ export enum Sex { - male = 0, - female = 2, - unknown = 255, + Unknown = 0, + Male = 1, + Female = 2, + Hidden = 255 } export interface QQLevel { @@ -101,7 +102,7 @@ export interface BaseInfo { birthday_month: number birthday_day: number age: number - sex: number + sex: Sex eMail: string phoneNum: string categoryId: number diff --git a/src/onebot11/action/go-cqhttp/GetGroupFileSystemInfo.ts b/src/onebot11/action/go-cqhttp/GetGroupFileSystemInfo.ts new file mode 100644 index 0000000..524abf8 --- /dev/null +++ b/src/onebot11/action/go-cqhttp/GetGroupFileSystemInfo.ts @@ -0,0 +1,32 @@ +import { BaseAction, Schema } from '../BaseAction' +import { ActionName } from '../types' + +interface Payload { + group_id: number | string +} + +interface Response { + file_count: number + limit_count: number + used_space: number + total_space: number +} + +export class GetGroupFileSystemInfo extends BaseAction { + actionName = ActionName.GoCQHTTP_GetGroupFileSystemInfo + payloadSchema = Schema.object({ + group_id: Schema.union([Number, String]).required() + }) + + async _handle(payload: Payload) { + const groupId = payload.group_id.toString() + const { groupFileCounts } = await this.ctx.ntGroupApi.getGroupFileCount(groupId) + const { groupSpaceResult } = await this.ctx.ntGroupApi.getGroupFileSpace(groupId) + return { + file_count: groupFileCounts[0], + limit_count: 10000, + used_space: +groupSpaceResult.usedSpace, + total_space: +groupSpaceResult.totalSpace, + } + } +} diff --git a/src/onebot11/action/index.ts b/src/onebot11/action/index.ts index b70f836..8d46873 100644 --- a/src/onebot11/action/index.ts +++ b/src/onebot11/action/index.ts @@ -76,6 +76,7 @@ import { DeleteFriend } from './go-cqhttp/DeleteFriend' import { OCRImage } from './go-cqhttp/OCRImage' import { GroupPoke } from './llonebot/GroupPoke' import { FriendPoke } from './llonebot/FriendPoke' +import { GetGroupFileSystemInfo } from './go-cqhttp/GetGroupFileSystemInfo' export function initActionMap(adapter: Adapter) { const actionHandlers = [ @@ -157,6 +158,7 @@ export function initActionMap(adapter: Adapter) { new GetGroupNotice(adapter), new DeleteFriend(adapter), new OCRImage(adapter), + new GetGroupFileSystemInfo(adapter), ] const actionMap = new Map>() for (const action of actionHandlers) { diff --git a/src/onebot11/action/types.ts b/src/onebot11/action/types.ts index a237492..f419f28 100644 --- a/src/onebot11/action/types.ts +++ b/src/onebot11/action/types.ts @@ -89,4 +89,5 @@ export enum ActionName { GoCQHTTP_GetGroupNotice = '_get_group_notice', GoCQHTTP_DeleteFriend = 'delete_friend', GoCQHTTP_OCRImage = 'ocr_image', + GoCQHTTP_GetGroupFileSystemInfo = 'get_group_file_system_info', } diff --git a/src/onebot11/adapter.ts b/src/onebot11/adapter.ts index 85d9160..d657116 100644 --- a/src/onebot11/adapter.ts +++ b/src/onebot11/adapter.ts @@ -362,14 +362,22 @@ class OneBot11Adapter extends Service { const event = new OB11ProfileLikeEvent(detail.uin!, detail.nickname!, +times) this.dispatch(event) } else if (msgType === 33) { - const tip = SysMsg.GroupMemberIncrease.decode(sysMsg.bodyWrapper!.body!) + const tip = SysMsg.GroupMemberChange.decode(sysMsg.bodyWrapper!.body!) if (tip.type !== 130) return this.ctx.logger.info('群成员增加', tip) const memberUin = await this.ctx.ntUserApi.getUinByUid(tip.memberUid) const operatorUin = await this.ctx.ntUserApi.getUinByUid(tip.adminUid) const event = new OB11GroupIncreaseEvent(tip.groupCode, +memberUin, +operatorUin) this.dispatch(event) - } + }/* else if (msgType === 34) { + const tip = SysMsg.GroupMemberChange.decode(sysMsg.bodyWrapper!.body!) + this.ctx.logger.info('群成员减少', tip) + const memberUin = await this.ctx.ntUserApi.getUinByUid(tip.memberUid) + const operatorUin = await this.ctx.ntUserApi.getUinByUid(tip.adminUid) //0 + const subType = tip.type === 130 ? 'leave' : 'kick' + const event = new OB11GroupDecreaseEvent(tip.groupCode, +memberUin, +operatorUin, subType) + this.dispatch(event) + }*/ }) } } diff --git a/src/onebot11/entities.ts b/src/onebot11/entities.ts index 1a84606..24c9a2a 100644 --- a/src/onebot11/entities.ts +++ b/src/onebot11/entities.ts @@ -665,9 +665,10 @@ export namespace OB11Entities { export function sex(sex: Sex): OB11UserSex { const sexMap = { - [Sex.male]: OB11UserSex.Male, - [Sex.female]: OB11UserSex.Female, - [Sex.unknown]: OB11UserSex.Unknown, + [Sex.Unknown]: OB11UserSex.Unknown, + [Sex.Male]: OB11UserSex.Male, + [Sex.Female]: OB11UserSex.Female, + [Sex.Hidden]: OB11UserSex.Unknown } return sexMap[sex] ?? OB11UserSex.Unknown } @@ -697,19 +698,6 @@ export namespace OB11Entities { } } - export function stranger(user: User): OB11User { - return { - ...user, - user_id: parseInt(user.uin), - nickname: user.nick, - sex: sex(user.sex!), - age: 0, - qid: user.qid, - login_days: 0, - level: (user.qqLevel && calcQQLevel(user.qqLevel)) || 0, - } - } - export function group(group: Group): OB11Group { return { group_id: parseInt(group.groupCode), diff --git a/src/onebot11/event/notice/OB11GroupDecreaseEvent.ts b/src/onebot11/event/notice/OB11GroupDecreaseEvent.ts index 4a36195..ad85264 100644 --- a/src/onebot11/event/notice/OB11GroupDecreaseEvent.ts +++ b/src/onebot11/event/notice/OB11GroupDecreaseEvent.ts @@ -12,7 +12,7 @@ export class OB11GroupDecreaseEvent extends OB11GroupNoticeEvent { constructor(groupId: number, userId: number, operatorId: number, subType: GroupDecreaseSubType = 'leave') { super() this.group_id = groupId - this.operator_id = operatorId // 实际上不应该这么实现,但是现在还没有办法识别用户是被踢出的,还是自己主动退出的 + this.operator_id = operatorId this.user_id = userId this.sub_type = subType } diff --git a/src/renderer/index.ts b/src/renderer/index.ts index ad11311..22fc53b 100644 --- a/src/renderer/index.ts +++ b/src/renderer/index.ts @@ -43,6 +43,13 @@ async function onSettingWindowCreated(view: Element) { SettingButton('请稍候', 'llonebot-update-button', 'secondary'), ), ]), + SettingList([ + SettingItem( + '是否启用 LLOneBot,重启 QQ 后生效', + null, + SettingSwitch('enableLLOB', config.enableLLOB, { 'control-display-id': 'config-enableLLOB' }), + ) + ]), SettingList([ SettingItem( '是否启用 Satori 协议', diff --git a/src/version.ts b/src/version.ts index 5d09b2a..f4b6c49 100644 --- a/src/version.ts +++ b/src/version.ts @@ -1 +1 @@ -export const version = '4.0.12' +export const version = '4.0.13'