UNPKG

egg-orm-ts

Version:

Simple orm with Typeorm, for egg plugin.

364 lines 25.1 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.BaseService = void 0; const egg_1 = require("egg"); const typeorm_1 = require("typeorm"); const error_1 = require("../../lib/error"); const object_1 = require("../../lib/object"); const string_1 = require("../../lib/string"); /** * Service基类: * - 提供通用的基本业务处理方法 */ class BaseService extends egg_1.Service { constructor(_ctx) { super(_ctx); this.modelName = this.constructor.name.substring(0, this.constructor.name.length - 7); // this.entity = require('../entity/' + this.modelName); // this.entityClass = this.entity[this.modelName]; this.model = this.ctx.repo[this.modelName]; // TODO: 提示 this.repo = this.ctx.repo; this.HTTP_CODE = error_1.HTTP_CODE; this.BIZ_CODE = error_1.BIZ_CODE; this.BizError = (message, code) => { if (process.env.NODE_ENV === 'development') { message = `${this.constructor.name} error:` + message; } throw new error_1.BizError(message, code); }; // @see https://typeorm.biunav.com/zh/find-options.html#进阶选项 this.OPR = { '!=': typeorm_1.Not, '<': typeorm_1.LessThan, '<=': typeorm_1.LessThanOrEqual, '>': typeorm_1.MoreThan, '>=': typeorm_1.MoreThanOrEqual, '=': typeorm_1.Equal, '<>': typeorm_1.Between, 'not in': (val) => typeorm_1.Not(typeorm_1.In(val)), '!<>': (val, val2) => typeorm_1.Not(typeorm_1.Between(val, val2)), 'not between': (val, val2) => typeorm_1.Not(typeorm_1.Between(val, val2)), not: typeorm_1.Not, lessThan: typeorm_1.LessThan, lessThanOrEqual: typeorm_1.LessThanOrEqual, moreThan: typeorm_1.MoreThan, moreThanOrEqual: typeorm_1.MoreThanOrEqual, equal: typeorm_1.Equal, between: typeorm_1.Between, in: typeorm_1.In, any: typeorm_1.Any, isNull: typeorm_1.IsNull, iLike: typeorm_1.ILike, like: typeorm_1.Like, raw: typeorm_1.Raw, }; this.FIND_OPTIONS_KEYS = [ 'select', 'where', 'relations', 'join', 'order', 'cache', 'lock', 'withDeleted', 'loadRelationIds', 'loadEagerRelations', 'transaction', 'take', 'skip', // AntD 参数,需转换成 order 'sort', ]; } /** * Utils API */ /** * 唯一性校验 * - 必须使用 await 调用 * - 支持排除当前 id * - 至少一个属性不为空才判断重复 * @param params 校验参数对象 * @param message 提示信息(不传则使用默认值) */ async checkUnique(params, message) { const id = this.getAndDelete(params, 'id'); // 判断查询条件 if (!object_1.isEmptyObject(params)) { // 查询重复数据 const existedOne = await this.getOne(params); if (!!existedOne && id !== existedOne.id) { throw this.BizError((!message ? '请确认存在相同的数据.' : message)); } } } /** * Executes raw SQL query and returns raw database results * - !!禁止直接在 SQL 中拼接用户传入的参数,以避免 SQL 注入 * @param sql script * @param params params * @param runner params */ async query(sql, params, runner) { // return this.ctx.connection.manager.query(sql, params); return await this.ctx.connection.query(sql, params, runner); } /** * Base API * - Default api, should overwrite if need. * - Others use repo, model or manager to implement. * * FindOperatorType * @see https://typeorm.biunav.com/zh/find-options.html#进阶选项 */ async save(entity, options) { // save<T extends DeepPartial<Entity>>(entity: T, options?: SaveOptions): Promise<T & Entity>; const data = await this.model.save(entity, options); return { data, success: !!data && string_1.isValid(data.id), }; } async get(id, options) { // 避免获取不可预知的数据 if (!string_1.isValid(id)) { return null; } return await this.model.findOne(id, options); } async getOne(params, options) { if (!!options) { // findOne(conditions?: FindConditions<Entity>, options?: FindOneOptions<Entity>): Promise<Entity | undefined>; return await this.model.findOne(this.getWhere(params), options); } // findOne(options?: FindOneOptions<Entity>): Promise<Entity | undefined>; return await this.model.findOne(Object.assign({ // 转换条件 where: this.getWhere(params), // 转换排序 order: this.getOrders(params) }, this.getOptions(params))); } async getListByIds(ids, options) { return await this.model.findByIds(ids, options); } /** * Find with pagination and condition. * - cant use findAndCount for both params * - use createQueryBuilder * @param params 参数 * @param params.current 页码 * @param params.pageSize 页面条数 * @param params.sort 排序 * @param dataFunc 数据处理函数 */ async getPage(params, dataFunc) { const current = this.getAndDelete(params, 'current', 1); const pageSize = this.getAndDelete(params, 'pageSize', 10); // 查询分页 // findAndCount(options?: FindManyOptions<Entity>): Promise<[Entity[], number]>; const [data, total] = await this.model.findAndCount(Object.assign({ // 页面分页参数 take: pageSize, skip: (current - 1) * pageSize, // 转换条件 where: this.getWhere(params), // 转换排序 order: this.getOrders(params) }, this.getOptions(params))); // 数据处理 if (dataFunc) { await dataFunc(data); } return { // Optional totalPage: Math.ceil(total / pageSize), current, pageSize, // Required total, data, // AntD table required success: true, }; } /** * Update with id only (not use criteria). * @param params param * @param params.id primary key * @param params.partialEntity new data */ async updateMix(params) { const id = this.getAndDelete(params, 'id'); return await this.update(id, params); } async update(criteria, partialEntity) { return this.addSuccessFlag(await this.model.update(criteria, partialEntity)); } async delete(criteria) { return this.addSuccessFlag(await this.model.delete(criteria)); } async saveList(entities, options) { const data = await this.model.save(entities, options); return { data, success: !!data && data.length > 0, }; } /** * 查询列表 * @param params 参数 * @param dataFunc 数据处理函数 * @returns */ async getList(params, dataFunc) { const listRes = await this.model.find(Object.assign({ // 转换条件 where: this.getWhere(params), // 转换排序 order: this.getOrders(params) }, this.getOptions(params))); // 数据处理 if (dataFunc) { await dataFunc(listRes); } return listRes; } /** * Update with ids only (not use criteria). * @param params param * @param params.id primary key * @param params.partialEntity new data */ async updateListMix(params) { const ids = this.getAndDelete(params, 'ids'); return await this.updateList(ids, params); } async updateList(criteria, partialEntity) { return this.addSuccessFlag(await this.model.update(criteria, partialEntity)); } async deleteList(criteria) { return this.addSuccessFlag(await this.model.delete(criteria)); } /** * Utils function. */ /** * 转换 Find*Options * @param params 查询条件 * @returns */ getOptions(params) { const options = {}; !!params && Object.keys(params).forEach(k => { if (this.FIND_OPTIONS_KEYS.indexOf(k.trim()) !== -1 && ['where', 'order', 'sort'].indexOf(k.trim()) === -1) { options[k] = params[k]; } }); return options; } /** * 转换条件 * @param params 查询条件 * @returns */ getWhere(params) { let where = this.getAndDelete(params, 'where'); let otherCondition = params; // 合并 where 条件 where = this.combineParams(where, otherCondition); // 处理 where 条件 const newWhere = {}; !!where && Object.keys(where).forEach(k => { // 排除 findOptions 的关键字 if (this.FIND_OPTIONS_KEYS.indexOf(k.trim()) === -1) { const type = Object.prototype.toString.call(where[k]); if (!string_1.isValid(where[k])) { // 剔除空属性 delete where[k]; } else if (type === '[object Array]') { newWhere[k] = typeorm_1.In(where[k]); } else if (type === '[object Object]' && !!where[k].opr) { const opr = where[k].opr.trim(); const val = where[k].val; if ((opr.indexOf('<>') !== -1 || opr.indexOf('between') !== -1) && val.length >= 2) { newWhere[k] = this.OPR[opr](val[0], val[1]); } else if (opr === 'like' || opr === 'iLike') { newWhere[k] = this.OPR[opr]((val.indexOf('%') === -1 ? `%${val}%` : val)); } else if (opr.startsWith('not')) { newWhere[k] = typeorm_1.Not(this.OPR[opr.replace('not', '').trim()](val)); } else { newWhere[k] = this.OPR[opr](val); } } else { newWhere[k] = where[k]; } } }); return newWhere; } /** * 转换排序条件 * - 合并 order 和 sort(AntD 默认)参数 * @param params * @returns */ getOrders(params) { let order = this.getAndDelete(params, 'order'); const sort = this.getAndDelete(params, 'sort'); // 合并排序参数 order = this.combineParams(order, sort); // 处理排序参数 const newOrder = {}; !!order && Object.keys(order).forEach(k => { // 转换(直接支持 ant design table 排序参数) if (!!order[k]) { newOrder[k.trim()] = order[k].trim().toUpperCase().replace('ASCEND', 'ASC').replace('DESCEND', 'DESC'); } }); return newOrder; } // 合并参数 combineParams(first, second) { if (!second) { return first; } if (!first) { return second; } else { return Object.assign(Object.assign({}, first), second); } } /** * deal mix params * @param params 参数 */ getAndDelete(params, label, defaultValue) { if (!params || !string_1.isValid(params[label])) { return defaultValue; } const value = params[label]; delete params[label]; return value; } /** * 增加额外标志 * - 默认只判断 update or delete * @param res 响应 * @returns */ addSuccessFlag(res) { // affected: undefined, null, 0 let success = true; if (!res || !res.affected) { success = false; } return Object.assign(Object.assign({}, res), { success }); } } exports.BaseService = BaseService; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYmFzZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbImJhc2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQUEsNkJBQXVDO0FBQ3ZDLHFDQXlCaUI7QUFDakIsMkNBQWdFO0FBQ2hFLDZDQUFpRDtBQUNqRCw2Q0FBMkM7QUF1QjNDOzs7R0FHRztBQUNILE1BQU0sV0FBMEMsU0FBUSxhQUFPO0lBdUI3RCxZQUFZLElBQWE7UUFDdkIsS0FBSyxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQ1osSUFBSSxDQUFDLFNBQVMsR0FBRyxJQUFJLENBQUMsV0FBVyxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQyxFQUFFLElBQUksQ0FBQyxXQUFXLENBQUMsSUFBSSxDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUMsQ0FBQztRQUN0Rix3REFBd0Q7UUFDeEQsa0RBQWtEO1FBQ2xELElBQUksQ0FBQyxLQUFLLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxDQUFDO1FBQzNDLFdBQVc7UUFDWCxJQUFJLENBQUMsSUFBSSxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDO1FBQzFCLElBQUksQ0FBQyxTQUFTLEdBQUcsaUJBQVMsQ0FBQztRQUMzQixJQUFJLENBQUMsUUFBUSxHQUFHLGdCQUFRLENBQUM7UUFDekIsSUFBSSxDQUFDLFFBQVEsR0FBRyxDQUFDLE9BQU8sRUFBRSxJQUFJLEVBQUUsRUFBRTtZQUNoQyxJQUFJLE9BQU8sQ0FBQyxHQUFHLENBQUMsUUFBUSxLQUFLLGFBQWEsRUFBRTtnQkFDMUMsT0FBTyxHQUFHLEdBQUcsSUFBSSxDQUFDLFdBQVcsQ0FBQyxJQUFJLFNBQVMsR0FBRyxPQUFPLENBQUM7YUFDdkQ7WUFDRCxNQUFNLElBQUksZ0JBQVEsQ0FBQyxPQUFPLEVBQUUsSUFBSSxDQUFDLENBQUM7UUFDcEMsQ0FBQyxDQUFDO1FBQ0YsNERBQTREO1FBQzVELElBQUksQ0FBQyxHQUFHLEdBQUc7WUFDVCxJQUFJLEVBQUUsYUFBRztZQUNULEdBQUcsRUFBRSxrQkFBUTtZQUNiLElBQUksRUFBRSx5QkFBZTtZQUNyQixHQUFHLEVBQUUsa0JBQVE7WUFDYixJQUFJLEVBQUUseUJBQWU7WUFDckIsR0FBRyxFQUFFLGVBQUs7WUFDVixJQUFJLEVBQUUsaUJBQU87WUFDYixRQUFRLEVBQUUsQ0FBQyxHQUFRLEVBQUUsRUFBRSxDQUFDLGFBQUcsQ0FBQyxZQUFFLENBQUMsR0FBRyxDQUFDLENBQUM7WUFDcEMsS0FBSyxFQUFFLENBQUMsR0FBUSxFQUFFLElBQVMsRUFBRSxFQUFFLENBQUMsYUFBRyxDQUFDLGlCQUFPLENBQUMsR0FBRyxFQUFFLElBQUksQ0FBQyxDQUFDO1lBQ3ZELGFBQWEsRUFBRSxDQUFDLEdBQVEsRUFBRSxJQUFTLEVBQUUsRUFBRSxDQUFDLGFBQUcsQ0FBQyxpQkFBTyxDQUFDLEdBQUcsRUFBRSxJQUFJLENBQUMsQ0FBQztZQUMvRCxHQUFHLEVBQUUsYUFBRztZQUNSLFFBQVEsRUFBRSxrQkFBUTtZQUNsQixlQUFlLEVBQUUseUJBQWU7WUFDaEMsUUFBUSxFQUFFLGtCQUFRO1lBQ2xCLGVBQWUsRUFBRSx5QkFBZTtZQUNoQyxLQUFLLEVBQUUsZUFBSztZQUNaLE9BQU8sRUFBRSxpQkFBTztZQUNoQixFQUFFLEVBQUUsWUFBRTtZQUNOLEdBQUcsRUFBRSxhQUFHO1lBQ1IsTUFBTSxFQUFFLGdCQUFNO1lBQ2QsS0FBSyxFQUFFLGVBQUs7WUFDWixJQUFJLEVBQUUsY0FBSTtZQUNWLEdBQUcsRUFBRSxhQUFHO1NBQ1QsQ0FBQztRQUNGLElBQUksQ0FBQyxpQkFBaUIsR0FBRztZQUN2QixRQUFRO1lBQ1IsT0FBTztZQUNQLFdBQVc7WUFDWCxNQUFNO1lBQ04sT0FBTztZQUNQLE9BQU87WUFDUCxNQUFNO1lBQ04sYUFBYTtZQUNiLGlCQUFpQjtZQUNqQixvQkFBb0I7WUFDcEIsYUFBYTtZQUNiLE1BQU07WUFDTixNQUFNO1lBQ04scUJBQXFCO1lBQ3JCLE1BQU07U0FDUCxDQUFDO0lBQ0osQ0FBQztJQUVEOztPQUVHO0lBRUg7Ozs7Ozs7T0FPRztJQUNILEtBQUssQ0FBQyxXQUFXLENBQUMsTUFBaUUsRUFBRSxPQUFnQjtRQUNuRyxNQUFNLEVBQUUsR0FBRyxJQUFJLENBQUMsWUFBWSxDQUFDLE1BQU0sRUFBRSxJQUFJLENBQUMsQ0FBQztRQUMzQyxTQUFTO1FBQ1QsSUFBSSxDQUFDLHNCQUFhLENBQUMsTUFBTSxDQUFDLEVBQUU7WUFDMUIsU0FBUztZQUNULE1BQU0sVUFBVSxHQUFHLE1BQU0sSUFBSSxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsQ0FBQztZQUM3QyxJQUFJLENBQUMsQ0FBQyxVQUFVLElBQUksRUFBRSxLQUFLLFVBQVUsQ0FBQyxFQUFFLEVBQUU7Z0JBQ3hDLE1BQU0sSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxhQUFhLENBQUMsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUM7YUFDM0Q7U0FDRjtJQUNILENBQUM7SUFFRDs7Ozs7O09BTUc7SUFDSCxLQUFLLENBQUMsS0FBSyxDQUFDLEdBQVcsRUFBRSxNQUFjLEVBQUUsTUFBb0I7UUFDM0QseURBQXlEO1FBQ3pELE9BQU8sTUFBTSxJQUFJLENBQUMsR0FBRyxDQUFDLFVBQVUsQ0FBQyxLQUFLLENBQUMsR0FBRyxFQUFFLE1BQU0sRUFBRSxNQUFNLENBQUMsQ0FBQztJQUM5RCxDQUFDO0lBRUQ7Ozs7Ozs7T0FPRztJQUNILEtBQUssQ0FBQyxJQUFJLENBQWdDLE1BQVMsRUFBRSxPQUFxQjtRQUN4RSw4RkFBOEY7UUFDOUYsTUFBTSxJQUFJLEdBQUcsTUFBTSxJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxNQUFNLEVBQUUsT0FBTyxDQUFDLENBQUM7UUFDcEQsT0FBTztZQUNMLElBQUk7WUFDSixPQUFPLEVBQUUsQ0FBQyxDQUFDLElBQUksSUFBSSxnQkFBTyxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUM7U0FDcEMsQ0FBQztJQUNKLENBQUM7SUFFRCxLQUFLLENBQUMsR0FBRyxDQUFDLEVBQTJDLEVBQUUsT0FBZ0M7UUFDckYsY0FBYztRQUNkLElBQUksQ0FBQyxnQkFBTyxDQUFDLEVBQUUsQ0FBQyxFQUFFO1lBQ2hCLE9BQU8sSUFBSSxDQUFDO1NBQ2I7UUFDRCxPQUFPLE1BQU0sSUFBSSxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsRUFBRSxFQUFFLE9BQU8sQ0FBQyxDQUFDO0lBQy9DLENBQUM7SUFFRCxLQUFLLENBQUMsTUFBTSxDQUFDLE1BQStDLEVBQUUsT0FBZ0M7UUFDNUYsSUFBRyxDQUFDLENBQUMsT0FBTyxFQUFFO1lBQ2QsK0dBQStHO1lBQzdHLE9BQU8sTUFBTSxJQUFJLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLE1BQU0sQ0FBQyxFQUFFLE9BQU8sQ0FBQyxDQUFDO1NBQ2pFO1FBQ0QsMEVBQTBFO1FBQzFFLE9BQU8sTUFBTSxJQUFJLENBQUMsS0FBSyxDQUFDLE9BQU87WUFDN0IsT0FBTztZQUNQLEtBQUssRUFBRSxJQUFJLENBQUMsUUFBUSxDQUFDLE1BQU0sQ0FBQztZQUM1QixPQUFPO1lBQ1AsS0FBSyxFQUFFLElBQUksQ0FBQyxTQUFTLENBQUMsTUFBTSxDQUFDLElBRTFCLElBQUksQ0FBQyxVQUFVLENBQUMsTUFBTSxDQUFDLEVBQzFCLENBQUM7SUFDTCxDQUFDO0lBRUQsS0FBSyxDQUFDLFlBQVksQ0FBQyxHQUFVLEVBQUUsT0FBMEU7UUFDdkcsT0FBTyxNQUFNLElBQUksQ0FBQyxLQUFLLENBQUMsU0FBUyxDQUFDLEdBQUcsRUFBRSxPQUFPLENBQUMsQ0FBQztJQUNsRCxDQUFDO0lBRUQ7Ozs7Ozs7OztPQVNHO0lBQ0YsS0FBSyxDQUFDLE9BQU8sQ0FBQyxNQUFzQyxFQUFFLFFBQWtDO1FBQ3ZGLE1BQU0sT0FBTyxHQUFHLElBQUksQ0FBQyxZQUFZLENBQUMsTUFBTSxFQUFFLFNBQVMsRUFBRSxDQUFDLENBQUMsQ0FBQztRQUN4RCxNQUFNLFFBQVEsR0FBRyxJQUFJLENBQUMsWUFBWSxDQUFDLE1BQU0sRUFBRSxVQUFVLEVBQUUsRUFBRSxDQUFDLENBQUM7UUFDM0QsT0FBTztRQUNQLGdGQUFnRjtRQUNoRixNQUFNLENBQUUsSUFBSSxFQUFFLEtBQUssQ0FBRSxHQUFJLE1BQU0sSUFBSSxDQUFDLEtBQUssQ0FBQyxZQUFZO1lBQ3BELFNBQVM7WUFDVCxJQUFJLEVBQUUsUUFBUSxFQUNkLElBQUksRUFBRSxDQUFDLE9BQU8sR0FBRyxDQUFDLENBQUMsR0FBRyxRQUFRO1lBQzlCLE9BQU87WUFDUCxLQUFLLEVBQUUsSUFBSSxDQUFDLFFBQVEsQ0FBQyxNQUFNLENBQUM7WUFDNUIsT0FBTztZQUNQLEtBQUssRUFBRSxJQUFJLENBQUMsU0FBUyxDQUFDLE1BQU0sQ0FBQyxJQUUxQixJQUFJLENBQUMsVUFBVSxDQUFDLE1BQU0sQ0FBQyxFQUMxQixDQUFDO1FBRUgsT0FBTztRQUNQLElBQUksUUFBUSxFQUFFO1lBQ1osTUFBTSxRQUFRLENBQUMsSUFBSSxDQUFDLENBQUM7U0FDdEI7UUFFRCxPQUFPO1lBQ0wsV0FBVztZQUNYLFNBQVMsRUFBRSxJQUFJLENBQUMsSUFBSSxDQUFDLEtBQUssR0FBRyxRQUFRLENBQUM7WUFDdEMsT0FBTztZQUNQLFFBQVE7WUFDUixXQUFXO1lBQ1gsS0FBSztZQUNMLElBQUk7WUFDSixzQkFBc0I7WUFDdEIsT0FBTyxFQUFFLElBQUk7U0FDZCxDQUFDO0lBQ0osQ0FBQztJQUVEOzs7OztPQUtHO0lBQ0gsS0FBSyxDQUFDLFNBQVMsQ0FBQyxNQUFpQztRQUMvQyxNQUFNLEVBQUUsR0FBRyxJQUFJLENBQUMsWUFBWSxDQUFDLE1BQU0sRUFBRSxJQUFJLENBQUMsQ0FBQztRQUMzQyxPQUFPLE1BQU0sSUFBSSxDQUFDLE1BQU0sQ0FBQyxFQUFFLEVBQUUsTUFBTSxDQUFDLENBQUM7SUFDdkMsQ0FBQztJQUNELEtBQUssQ0FBQyxNQUFNLENBQUMsUUFBK0IsRUFBRSxhQUFrQztRQUM5RSxPQUFPLElBQUksQ0FBQyxjQUFjLENBQUMsTUFBTSxJQUFJLENBQUMsS0FBSyxDQUFDLE1BQU0sQ0FBQyxRQUFRLEVBQUUsYUFBYSxDQUFDLENBQUMsQ0FBQztJQUMvRSxDQUFDO0lBRUQsS0FBSyxDQUFDLE1BQU0sQ0FBQyxRQUErQjtRQUMxQyxPQUFPLElBQUksQ0FBQyxjQUFjLENBQUMsTUFBTSxJQUFJLENBQUMsS0FBSyxDQUFDLE1BQU0sQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDO0lBQ2hFLENBQUM7SUFFRCxLQUFLLENBQUMsUUFBUSxDQUFnQyxRQUFhLEVBQUUsT0FBcUI7UUFDaEYsTUFBTSxJQUFJLEdBQUcsTUFBTSxJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxRQUFRLEVBQUUsT0FBTyxDQUFDLENBQUM7UUFDdEQsT0FBTztZQUNMLElBQUk7WUFDSixPQUFPLEVBQUUsQ0FBQyxDQUFDLElBQUksSUFBSSxJQUFJLENBQUMsTUFBTSxHQUFHLENBQUM7U0FDbkMsQ0FBQztJQUNKLENBQUM7SUFFRDs7Ozs7T0FLRztJQUNILEtBQUssQ0FBQyxPQUFPLENBQUMsTUFBMEIsRUFBRSxRQUFrQztRQUMxRSxNQUFNLE9BQU8sR0FBRyxNQUFNLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSTtZQUNuQyxPQUFPO1lBQ1AsS0FBSyxFQUFFLElBQUksQ0FBQyxRQUFRLENBQUMsTUFBTSxDQUFDO1lBQzVCLE9BQU87WUFDUCxLQUFLLEVBQUUsSUFBSSxDQUFDLFNBQVMsQ0FBQyxNQUFNLENBQUMsSUFFMUIsSUFBSSxDQUFDLFVBQVUsQ0FBQyxNQUFNLENBQUMsRUFDMUIsQ0FBQztRQUVILE9BQU87UUFDUCxJQUFJLFFBQVEsRUFBRTtZQUNaLE1BQU0sUUFBUSxDQUFDLE9BQU8sQ0FBQyxDQUFDO1NBQ3pCO1FBQ0QsT0FBTyxPQUFPLENBQUM7SUFDakIsQ0FBQztJQUVEOzs7OztPQUtHO0lBQ0gsS0FBSyxDQUFDLGFBQWEsQ0FBQyxNQUFpQztRQUNuRCxNQUFNLEdBQUcsR0FBRyxJQUFJLENBQUMsWUFBWSxDQUFDLE1BQU0sRUFBRSxLQUFLLENBQUMsQ0FBQztRQUM3QyxPQUFPLE1BQU0sSUFBSSxDQUFDLFVBQVUsQ0FBQyxHQUFHLEVBQUUsTUFBTSxDQUFDLENBQUM7SUFDNUMsQ0FBQztJQUNELEtBQUssQ0FBQyxVQUFVLENBQUMsUUFBK0IsRUFBRSxhQUFrQztRQUNsRixPQUFPLElBQUksQ0FBQyxjQUFjLENBQUMsTUFBTSxJQUFJLENBQUMsS0FBSyxDQUFDLE1BQU0sQ0FBQyxRQUFRLEVBQUUsYUFBYSxDQUFDLENBQUMsQ0FBQztJQUMvRSxDQUFDO0lBRUQsS0FBSyxDQUFDLFVBQVUsQ0FBQyxRQUErQjtRQUM5QyxPQUFPLElBQUksQ0FBQyxjQUFjLENBQUMsTUFBTSxJQUFJLENBQUMsS0FBSyxDQUFDLE1BQU0sQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDO0lBQ2hFLENBQUM7SUFFRDs7T0FFRztJQUVIOzs7O09BSUc7SUFDSCxVQUFVLENBQUMsTUFBVztRQUNuQixNQUFNLE9BQU8sR0FBUSxFQUFFLENBQUM7UUFDekIsQ0FBQyxDQUFDLE1BQU0sSUFBSSxNQUFNLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsRUFBRTtZQUMxQyxJQUFJLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLElBQUksRUFBRSxDQUFDLEtBQUssQ0FBQyxDQUFDLElBQUksQ0FBRSxPQUFPLEVBQUUsT0FBTyxFQUFFLE1BQU0sQ0FBRSxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsSUFBSSxFQUFFLENBQUMsS0FBSyxDQUFDLENBQUMsRUFBRTtnQkFDNUcsT0FBTyxDQUFDLENBQUMsQ0FBQyxHQUFHLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQzthQUN4QjtRQUNILENBQUMsQ0FBQyxDQUFDO1FBRUgsT0FBTyxPQUFPLENBQUM7SUFDakIsQ0FBQztJQUVEOzs7O09BSUc7SUFDSCxRQUFRLENBQUMsTUFBVztRQUNsQixJQUFJLEtBQUssR0FBRyxJQUFJLENBQUMsWUFBWSxDQUFDLE1BQU0sRUFBRSxPQUFPLENBQUMsQ0FBQztRQUMvQyxJQUFJLGNBQWMsR0FBRyxNQUFNLENBQUM7UUFDNUIsY0FBYztRQUNkLEtBQUssR0FBRyxJQUFJLENBQUMsYUFBYSxDQUFDLEtBQUssRUFBRSxjQUFjLENBQUMsQ0FBQztRQUNsRCxjQUFjO1FBQ2QsTUFBTSxRQUFRLEdBQVEsRUFBRSxDQUFDO1FBQ3pCLENBQUMsQ0FBQyxLQUFLLElBQUksTUFBTSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLEVBQUU7WUFDeEMsc0JBQXNCO1lBQ3RCLElBQUksSUFBSSxDQUFDLGlCQUFpQixDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsSUFBSSxFQUFFLENBQUMsS0FBSyxDQUFDLENBQUMsRUFBRTtnQkFDbkQsTUFBTSxJQUFJLEdBQUcsTUFBTSxDQUFDLFNBQVMsQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO2dCQUN0RCxJQUFJLENBQUMsZ0JBQU8sQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRTtvQkFDdEIsUUFBUTtvQkFDUixPQUFPLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQztpQkFDakI7cUJBQU0sSUFBSSxJQUFJLEtBQUssZ0JBQWdCLEVBQUU7b0JBQ3BDLFFBQVEsQ0FBQyxDQUFDLENBQUMsR0FBRyxZQUFFLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7aUJBQzVCO3FCQUFNLElBQUksSUFBSSxLQUFLLGlCQUFpQixJQUFJLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxFQUFFO29CQUN2RCxNQUFNLEdBQUcsR0FBRyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLElBQUksRUFBRSxDQUFDO29CQUNoQyxNQUFNLEdBQUcsR0FBRyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDO29CQUN6QixJQUFJLENBQUMsR0FBRyxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsSUFBSSxHQUFHLENBQUMsT0FBTyxDQUFDLFNBQVMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLElBQUksR0FBRyxDQUFDLE1BQU0sSUFBSSxDQUFDLEVBQUU7d0JBQ2xGLFFBQVEsQ0FBQyxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztxQkFDN0M7eUJBQU0sSUFBSSxHQUFHLEtBQUssTUFBTSxJQUFJLEdBQUcsS0FBSyxPQUFPLEVBQUU7d0JBQzVDLFFBQVEsQ0FBQyxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxHQUFHLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQztxQkFDM0U7eUJBQU0sSUFBSSxHQUFHLENBQUMsVUFBVSxDQUFDLEtBQUssQ0FBQyxFQUFFO3dCQUNoQyxRQUFRLENBQUMsQ0FBQyxDQUFDLEdBQUcsYUFBRyxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLE9BQU8sQ0FBQyxLQUFLLEVBQUUsRUFBRSxDQUFDLENBQUMsSUFBSSxFQUFFLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDO3FCQUNqRTt5QkFBTTt3QkFDTCxRQUFRLENBQUMsQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQztxQkFDbEM7aUJBQ0Y7cUJBQU07b0JBQ0wsUUFBUSxDQUFDLENBQUMsQ0FBQyxHQUFHLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQztpQkFDeEI7YUFDRjtRQUNILENBQUMsQ0FBQyxDQUFDO1FBRUgsT0FBTyxRQUFRLENBQUM7SUFDbEIsQ0FBQztJQUVEOzs7OztPQUtHO0lBQ0gsU0FBUyxDQUFDLE1BQVc7UUFDbkIsSUFBSSxLQUFLLEdBQUcsSUFBSSxDQUFDLFlBQVksQ0FBQyxNQUFNLEVBQUUsT0FBTyxDQUFDLENBQUM7UUFDL0MsTUFBTSxJQUFJLEdBQUcsSUFBSSxDQUFDLFlBQVksQ0FBQyxNQUFNLEVBQUUsTUFBTSxDQUFDLENBQUM7UUFDL0MsU0FBUztRQUNULEtBQUssR0FBRyxJQUFJLENBQUMsYUFBYSxDQUFDLEtBQUssRUFBRSxJQUFJLENBQUMsQ0FBQztRQUN4QyxTQUFTO1FBQ1QsTUFBTSxRQUFRLEdBQUcsRUFBRSxDQUFDO1FBQ3BCLENBQUMsQ0FBQyxLQUFLLElBQUksTUFBTSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLEVBQUU7WUFDeEMsaUNBQWlDO1lBQ2pDLElBQUksQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsRUFBRTtnQkFDZCxRQUFRLENBQUMsQ0FBQyxDQUFDLElBQUksRUFBRSxDQUFDLEdBQUcsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksRUFBRSxDQUFDLFdBQVcsRUFBRSxDQUFDLE9BQU8sQ0FBQyxRQUFRLEVBQUUsS0FBSyxDQUFDLENBQUMsT0FBTyxDQUFDLFNBQVMsRUFBRSxNQUFNLENBQUMsQ0FBQzthQUN4RztRQUNILENBQUMsQ0FBQyxDQUFDO1FBRUgsT0FBTyxRQUFRLENBQUM7SUFDbEIsQ0FBQztJQUVELE9BQU87SUFDUCxhQUFhLENBQUMsS0FBVSxFQUFFLE1BQVc7UUFDbkMsSUFBSSxDQUFDLE1BQU0sRUFBRTtZQUNYLE9BQU8sS0FBSyxDQUFDO1NBQ2Q7UUFDRCxJQUFJLENBQUMsS0FBSyxFQUFFO1lBQ1YsT0FBTyxNQUFNLENBQUM7U0FDZjthQUFNO1lBQ0wsdUNBQVksS0FBSyxHQUFLLE1BQU0sRUFBRztTQUNoQztJQUNILENBQUM7SUFFRDs7O09BR0c7SUFDSCxZQUFZLENBQUMsTUFBVyxFQUFFLEtBQWEsRUFBRSxZQUFrQjtRQUN6RCxJQUFJLENBQUMsTUFBTSxJQUFJLENBQUMsZ0JBQU8sQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUMsRUFBRTtZQUN2QyxPQUFPLFlBQVksQ0FBQztTQUNwQjtRQUNELE1BQU0sS0FBSyxHQUFHLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUM1QixPQUFPLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUNyQixPQUFPLEtBQUssQ0FBQztJQUNmLENBQUM7SUFFRDs7Ozs7T0FLRztJQUNILGNBQWMsQ0FBQyxHQUFRO1FBQ3JCLCtCQUErQjtRQUMvQixJQUFJLE9BQU8sR0FBRyxJQUFJLENBQUM7UUFDbkIsSUFBSSxDQUFDLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxRQUFRLEVBQUU7WUFDekIsT0FBTyxHQUFHLEtBQUssQ0FBQztTQUNqQjtRQUNELHVDQUFZLEdBQUcsS0FBRSxPQUFPLElBQUc7SUFDN0IsQ0FBQztDQUVGO0FBRVEsa0NBQVcifQ==