@vnpn/lucky-canvas-core 1.7.26

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.
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.esm.js","sources":["../src/utils/polyfill.js","../src/utils/index.ts","../src/observer/dep.ts","../src/observer/utils.ts","../src/observer/array.ts","../src/observer/index.ts","../src/observer/watcher.ts","../src/lib/lucky.ts","../src/utils/math.ts","../src/utils/tween.ts","../src/lib/wheel.ts","../src/lib/grid.ts","../src/lib/slot.ts","../src/utils/image.ts"],"sourcesContent":["/**\n * 由于部分低版本下的某些 app 可能会缺少某些原型方法, 这里增加兼容\n */\n\n// ie11 不兼容 includes 方法\nif (!Array.prototype.includes) {\n Object.defineProperty(Array.prototype, 'includes', {\n value: function(valueToFind, fromIndex) {\n\n if (this == null) {\n throw new TypeError('\"this\" is null or not defined');\n }\n\n // 1. Let O be ? ToObject(this value).\n var o = Object(this);\n\n // 2. Let len be ? ToLength(? Get(O, \"length\")).\n var len = o.length >>> 0;\n\n // 3. If len is 0, return false.\n if (len === 0) {\n return false;\n }\n\n // 4. Let n be ? ToInteger(fromIndex).\n // (If fromIndex is undefined, this step produces the value 0.)\n var n = fromIndex | 0;\n\n // 5. If n ≥ 0, then\n // a. Let k be n.\n // 6. Else n < 0,\n // a. Let k be len + n.\n // b. If k < 0, let k be 0.\n var k = Math.max(n >= 0 ? n : len - Math.abs(n), 0);\n\n function sameValueZero(x, y) {\n return x === y || (typeof x === 'number' && typeof y === 'number' && isNaN(x) && isNaN(y));\n }\n\n // 7. Repeat, while k < len\n while (k < len) {\n // a. Let elementK be the result of ? Get(O, ! ToString(k)).\n // b. If SameValueZero(valueToFind, elementK) is true, return true.\n if (sameValueZero(o[k], valueToFind)) {\n return true;\n }\n // c. Increase k by 1.\n k++;\n }\n\n // 8. Return false\n return false;\n }\n });\n}\n\n// vivo x7 下网易云游戏 app 缺少 includes 方法\nif (!String.prototype.includes) {\n String.prototype.includes = function(search, start) {\n 'use strict';\n if (typeof start !== 'number') {\n start = 0;\n }\n if (start + search.length > this.length) {\n return false;\n } else {\n return this.indexOf(search, start) !== -1;\n }\n };\n}\n\n// vivo x7 下网易云游戏 app 缺少 find 方法\nif (!Array.prototype.find) {\n Object.defineProperty(Array.prototype, 'find', {\n value: function(predicate) {\n // 1. Let O be ? ToObject(this value).\n if (this == null) {\n throw new TypeError('\"this\" is null or not defined');\n }\n var o = Object(this);\n // 2. Let len be ? ToLength(? Get(O, \"length\")).\n var len = o.length >>> 0;\n // 3. If IsCallable(predicate) is false, throw a TypeError exception.\n if (typeof predicate !== 'function') {\n throw new TypeError('predicate must be a function');\n }\n // 4. If thisArg was supplied, let T be thisArg; else let T be undefined.\n var thisArg = arguments[1];\n // 5. Let k be 0.\n var k = 0;\n // 6. Repeat, while k < len\n while (k < len) {\n // a. Let Pk be ! ToString(k).\n // b. Let kValue be ? Get(O, Pk).\n // c. Let testResult be ToBoolean(? Call(predicate, T, « kValue, k, O »)).\n // d. If testResult is true, return kValue.\n var kValue = o[k];\n if (predicate.call(thisArg, kValue, k, o)) {\n return kValue;\n }\n // e. Increase k by 1.\n k++;\n }\n // 7. Return undefined.\n return void 0;\n }\n });\n}\n","/**\n * 判断是否是期望的类型\n * @param { unknown } param 将要判断的变量\n * @param { ...string } types 期望的类型\n * @return { boolean } 返回期望是否正确\n */\nexport const isExpectType = (param: unknown, ...types: string[]): boolean => {\n return types.some(type => Object.prototype.toString.call(param).slice(8, -1).toLowerCase() === type)\n}\n\nexport const get = (data: object, strKeys: string) => {\n const keys = strKeys.split('.')\n for (let key of keys) {\n const res = data[key]\n if (!isExpectType(res, 'object', 'array')) return res\n data = res\n }\n return data\n}\n\nexport const has = (data: object, key: string | number): boolean => {\n return Object.prototype.hasOwnProperty.call(data, key)\n}\n\n/**\n * 移除\\n\n * @param { string } str 将要处理的字符串\n * @return { string } 返回新的字符串\n */\nexport const removeEnter = (str: string): string => {\n return [].filter.call(str, s => s !== '\\n').join('')\n}\n\n/**\n * 把任何数据类型转成数字\n * @param num \n */\nexport const getNumber = (num: unknown): number => {\n if (num === null) return 0\n if (typeof num === 'object') return NaN\n if (typeof num === 'number') return num\n if (typeof num === 'string') {\n if (num[num.length - 1] === '%') {\n return Number(num.slice(0, -1)) / 100\n }\n return Number(num)\n }\n return NaN\n}\n\n/**\n * 判断颜色是否有效 (透明色 === 无效)\n * @param color 颜色\n */\nexport const hasBackground = (color: string | undefined | null): boolean => {\n if (typeof color !== 'string') return false\n color = color.toLocaleLowerCase().trim()\n if (color === 'transparent') return false\n if (/^rgba/.test(color)) {\n const alpha = /([^\\s,]+)\\)$/.exec(color)\n if (getNumber(alpha) === 0) return false\n }\n return true\n}\n\n/**\n * 通过padding计算\n * @return { object } block 边框信息\n */\nexport const computePadding = (\n block: { padding?: string },\n getLength: Function\n): [number, number, number, number] => {\n let padding = block.padding?.split(' ').map(n => getLength(n)) || [0],\n paddingTop = 0,\n paddingBottom = 0,\n paddingLeft = 0,\n paddingRight = 0\n switch (padding.length) {\n case 1:\n paddingTop = paddingBottom = paddingLeft = paddingRight = padding[0]\n break\n case 2:\n paddingTop = paddingBottom = padding[0]\n paddingLeft = paddingRight = padding[1]\n break\n case 3:\n paddingTop = padding[0]\n paddingLeft = paddingRight = padding[1]\n paddingBottom = padding[2]\n break\n default:\n paddingTop = padding[0]\n paddingBottom = padding[1]\n paddingLeft = padding[2]\n paddingRight = padding[3]\n }\n // 检查是否单独传入值, 并且不是0\n const res = { paddingTop, paddingBottom, paddingLeft, paddingRight }\n for (let key in res) {\n // 是否含有这个属性, 并且是数字或字符串\n res[key] = has(block, key) && isExpectType(block[key], 'string', 'number')\n ? getLength(block[key])\n : res[key]\n }\n return [paddingTop, paddingBottom, paddingLeft, paddingRight]\n}\n\n/**\n * 节流函数\n * @param fn 将要处理的函数\n * @param wait 时间, 单位为毫秒\n * @returns 包装好的节流函数\n */\nexport const throttle = (fn: Function, wait = 300) => {\n let timeId = null as any\n return function (this: any, ...args: any[]) {\n if (timeId) return\n timeId = setTimeout(() => {\n fn.apply(this, args)\n clearTimeout(timeId)\n timeId = null\n }, wait)\n }\n}\n\n/**\n * 通过概率计算出一个奖品索引\n * @param { Array<number | undefined> } rangeArr 概率\n * @returns { number } 中奖索引\n */\nexport const computeRange = (rangeArr: Array<number | undefined>): number => {\n const ascendingArr: number[] = []\n // 额外增加 map 来优化 ts 的类型推断\n const sum = rangeArr.map(num => Number(num)).reduce((prev, curr) => {\n if (curr > 0) { // 大于0\n const res = prev + curr\n ascendingArr.push(res)\n return res\n } else { // 小于等于0或NaN\n ascendingArr.push(NaN)\n return prev\n }\n }, 0)\n const random = Math.random() * sum\n return ascendingArr.findIndex(num => random <= num)\n}\n\n/**\n * 根据宽度分割字符串, 来达到换行的效果\n * @param text \n * @param maxWidth \n * @returns \n */\nexport const splitText = (\n ctx: CanvasRenderingContext2D,\n text: string,\n getWidth: (lines: string[]) => number,\n lineClamp: number = Infinity\n): string[] => {\n // 如果 lineClamp 设置不正确, 则忽略该属性\n if (lineClamp <= 0) lineClamp = Infinity\n let str = ''\n const lines = []\n const EndWidth = ctx.measureText('...').width\n for (let i = 0; i < text.length; i++) {\n str += text[i]\n let currWidth = ctx.measureText(str).width\n const maxWidth = getWidth(lines)\n // 如果正在计算最后一行, 则加上三个小点的宽度\n if (lineClamp === lines.length + 1) currWidth += EndWidth\n // 如果已经没有宽度了, 就没有必要再计算了\n if (maxWidth < 0) return lines\n // 如果当前一行的宽度不够了, 则处理下一行\n if (currWidth > maxWidth) {\n lines.push(str.slice(0, -1))\n str = text[i]\n }\n // 如果现在是最后一行, 则加上三个小点并跳出\n if (lineClamp === lines.length) {\n lines[lines.length - 1] += '...'\n return lines\n }\n }\n if (str) lines.push(str)\n if (!lines.length) lines.push(text)\n return lines\n}\n\n// 获取一个重新排序的数组\nexport const getSortedArrayByIndex = <T>(arr: T[], order: number[]): T[] => {\n const map: { [key: number]: T } = {}, res = []\n for (let i = 0; i < arr.length; i++) {\n map[i] = arr[i]\n }\n for (let i = 0; i < order.length; i++) {\n const curr = map[order[i]]\n if (curr) (res[i] = curr)\n }\n return res\n}\n","import Watcher from './watcher'\n\nexport default class Dep {\n static target: Watcher | null\n private subs: Array<Watcher>\n\n /**\n * 订阅中心构造器\n */\n constructor () {\n this.subs = []\n }\n\n /**\n * 收集依赖\n * @param {*} sub \n */\n public addSub (sub: Watcher) {\n // 此处临时使用includes防重复添加\n if (!this.subs.includes(sub)) {\n this.subs.push(sub)\n }\n }\n\n /**\n * 派发更新\n */\n public notify () {\n this.subs.forEach(sub => {\n sub.update()\n })\n }\n}\n","\nimport { isExpectType } from '../utils'\n\nexport const hasProto = '__proto__' in {}\n\nexport function def (obj: object, key: string | number, val: any, enumerable?: boolean) {\n Object.defineProperty(obj, key, {\n value: val,\n enumerable: !!enumerable,\n writable: true,\n configurable: true\n })\n}\n\nexport function parsePath (path: string) {\n path += '.'\n let segments: string[] = [], segment = ''\n for (let i = 0; i < path.length; i++) {\n let curr = path[i]\n if (/\\[|\\./.test(curr)) {\n segments.push(segment)\n segment = ''\n } else if (/\\W/.test(curr)) {\n continue\n } else {\n segment += curr\n }\n }\n return function (data: object | any[]) {\n return segments.reduce((data, key) => {\n return data[key]\n }, data)\n }\n}\n\nexport function traverse (value: any) {\n // const seenObjects = new Set()\n const dfs = (data: any) => {\n if (!isExpectType(data, 'array', 'object')) return\n Object.keys(data).forEach(key => {\n const value = data[key]\n dfs(value)\n })\n }\n dfs(value)\n // seenObjects.clear()\n}","/**\n * 重写数组的原型方法\n */\nconst oldArrayProto = Array.prototype\nconst newArrayProto = Object.create(oldArrayProto)\nconst methods = ['push', 'pop', 'shift', 'unshift', 'sort', 'splice', 'reverse']\nmethods.forEach(method => {\n newArrayProto[method] = function (...args: any[]) {\n const res = oldArrayProto[method].apply(this, args)\n const luckyOb = this['__luckyOb__']\n if (['push', 'unshift', 'splice'].includes(method)) luckyOb.walk(this)\n luckyOb.dep.notify()\n return res\n }\n})\n\nexport { newArrayProto }\n","import Dep from './dep'\nimport { hasProto, def } from './utils'\nimport { newArrayProto } from './array'\n\nexport default class Observer {\n value: any\n dep: Dep\n\n /**\n * 观察者构造器\n * @param value \n */\n constructor (value: any) {\n // this.value = value\n this.dep = new Dep()\n // 将响应式对象代理到当前value上面, 并且将当前的enumerable设置为false\n def(value, '__luckyOb__', this)\n if (Array.isArray(value)) { // 如果是数组, 则重写原型方法\n if (hasProto) {\n value['__proto__'] = newArrayProto\n } else {\n Object.getOwnPropertyNames(newArrayProto).forEach(key => {\n def(value, key, newArrayProto[key])\n })\n }\n }\n this.walk(value)\n }\n\n walk (data: object | any[]) {\n Object.keys(data).forEach(key => {\n defineReactive(data, key, data[key])\n })\n }\n}\n\n/**\n * 处理响应式\n * @param { Object | Array } data\n */\nexport function observe (data: any): Observer | void {\n if (!data || typeof data !== 'object') return\n let luckyOb: Observer | void\n if ('__luckyOb__' in data) {\n luckyOb = data['__luckyOb__']\n } else {\n luckyOb = new Observer(data)\n }\n return luckyOb\n}\n\n/**\n * 重写 setter / getter\n * @param {*} data \n * @param {*} key \n * @param {*} val \n */\nexport function defineReactive (data: any, key: string | number, val: any) {\n const dep = new Dep()\n const property = Object.getOwnPropertyDescriptor(data, key)\n if (property && property.configurable === false) {\n return\n }\n const getter = property && property.get\n const setter = property && property.set\n if ((!getter || setter) && arguments.length === 2) {\n val = data[key]\n }\n let childOb = observe(val)\n Object.defineProperty(data, key, {\n get: () => {\n const value = getter ? getter.call(data) : val\n if (Dep.target) {\n dep.addSub(Dep.target)\n if (childOb) {\n childOb.dep.addSub(Dep.target)\n }\n }\n return value\n },\n set: (newVal) => {\n if (newVal === val) return\n val = newVal\n if (getter && !setter) return\n if (setter) {\n setter.call(data, newVal)\n } else {\n val = newVal\n }\n childOb = observe(newVal)\n dep.notify()\n }\n })\n}\n","import Lucky from '../lib/lucky'\nimport Dep from './dep'\nimport { parsePath, traverse } from './utils'\n\nexport interface WatchOptType {\n handler?: () => Function\n immediate?: boolean\n deep?: boolean\n}\n\nlet uid = 0\nexport default class Watcher {\n id: number\n $lucky: Lucky\n expr: string | Function\n cb: Function\n deep: boolean\n getter: Function\n value: any\n\n /**\n * 观察者构造器\n * @param {*} $lucky \n * @param {*} expr \n * @param {*} cb \n */\n constructor ($lucky: Lucky, expr: string | Function, cb: Function, options: WatchOptType = {}) {\n this.id = uid++\n this.$lucky = $lucky\n this.expr = expr\n this.deep = !!options.deep\n if (typeof expr === 'function') {\n this.getter = expr\n } else {\n this.getter = parsePath(expr)\n }\n this.cb = cb\n this.value = this.get()\n }\n\n /**\n * 根据表达式获取新值\n */\n get () {\n Dep.target = this\n const value = this.getter.call(this.$lucky, this.$lucky)\n // 处理深度监听\n if (this.deep) {\n traverse(value)\n }\n Dep.target = null\n return value\n }\n\n /**\n * 触发 watcher 更新\n */\n update () {\n // get获取新值\n const newVal = this.get()\n // 读取之前存储的旧值\n const oldVal = this.value\n this.value = newVal\n // 触发 watch 回调\n this.cb.call(this.$lucky, newVal, oldVal)\n }\n}\n","import '../utils/polyfill'\nimport { has, isExpectType, throttle } from '../utils/index'\nimport { name, version } from '../../package.json'\nimport { ConfigType, UserConfigType, ImgItemType, ImgType, Tuple } from '../types/index'\nimport { defineReactive } from '../observer'\nimport Watcher, { WatchOptType } from '../observer/watcher'\n\nexport default class Lucky {\n static version: string = version\n protected readonly version: string = version\n protected readonly config: ConfigType\n protected readonly ctx: CanvasRenderingContext2D\n protected htmlFontSize: number = 16\n protected rAF: Function = function () {}\n protected boxWidth: number = 0\n protected boxHeight: number = 0\n protected data: {\n width: string | number,\n height: string | number\n }\n\n /**\n * 公共构造器\n * @param config\n */\n constructor (\n config: string | HTMLDivElement | UserConfigType,\n data: {\n width: string | number,\n height: string | number\n }\n ) {\n // 兼容代码开始: 为了处理 v1.0.6 版本在这里传入了一个 dom\n if (typeof config === 'string') config = { el: config } as UserConfigType\n else if (config.nodeType === 1) config = { el: '', divElement: config } as UserConfigType\n // 这里先野蛮的处理, 等待后续优化, 对外暴露的类型是UserConfigType, 但内部期望是ConfigType\n config = config as UserConfigType\n this.config = config as ConfigType\n this.data = data\n // 开始初始化\n if (!config.flag) config.flag = 'WEB'\n if (config.el) config.divElement = document.querySelector(config.el) as HTMLDivElement\n // 如果存在父盒子, 就创建canvas标签\n if (config.divElement) {\n // 无论盒子内有没有canvas都执行覆盖逻辑\n config.canvasElement = document.createElement('canvas')\n config.divElement.appendChild(config.canvasElement)\n }\n // 获取 canvas 上下文\n if (config.canvasElement) {\n config.ctx = config.canvasElement.getContext('2d')!\n // 添加版本信息到标签上, 方便定位版本问题\n config.canvasElement.setAttribute('package', `${name}@${version}`)\n config.canvasElement.addEventListener('click', e => this.handleClick(e))\n }\n this.ctx = config.ctx as CanvasRenderingContext2D\n // 初始化 window 方法\n this.initWindowFunction()\n // 如果最后得不到 canvas 上下文那就无法进行绘制\n if (!this.config.ctx) {\n console.error('无法获取到 CanvasContext2D')\n }\n // 监听 window 触发 resize 时重置\n if (window && typeof window.addEventListener === 'function') {\n window.addEventListener('resize', throttle(() => this.resize(), 300))\n }\n // 监听异步设置 html 的 fontSize 并重新绘制\n if (window && typeof window.MutationObserver === 'function') {\n new window.MutationObserver(() => {\n this.resize()\n }).observe(document.documentElement, { attributes: true })\n }\n }\n\n /**\n * 初始化组件大小/单位\n */\n protected resize(): void {\n this.config.beforeResize?.()\n // 先初始化 fontSize 以防后面有 rem 单位\n this.setHTMLFontSize()\n // 拿到 config 即可设置 dpr\n this.setDpr()\n // 初始化宽高\n this.resetWidthAndHeight()\n // 根据 dpr 来缩放 canvas\n this.zoomCanvas()\n }\n\n /**\n * 初始化方法\n */\n protected initLucky () {\n this.resize()\n if (!this.boxWidth || !this.boxHeight) {\n return console.error('无法获取到宽度或高度')\n }\n }\n\n /**\n * 鼠标点击事件\n * @param e 事件参数\n */\n protected handleClick (e: MouseEvent): void {}\n\n /**\n * 根标签的字体大小\n */\n protected setHTMLFontSize (): void {\n if (!window || !window.getComputedStyle) return\n this.htmlFontSize = +window.getComputedStyle(document.documentElement).fontSize.slice(0, -2)\n }\n\n // 清空画布\n public clearCanvas (): void {\n const [width, height] = [this.boxWidth, this.boxHeight]\n this.ctx.clearRect(-width, -height, width * 2, height * 2)\n }\n\n /**\n * 设备像素比\n * window 环境下自动获取, 其余环境手动传入\n */\n protected setDpr (): void {\n const { config } = this\n if (config.dpr) {\n // 优先使用 config 传入的 dpr\n } else if (window) {\n window['dpr'] = config.dpr = window.devicePixelRatio || 1\n } else if (!config.dpr) {\n console.error(config, '未传入 dpr 可能会导致绘制异常')\n }\n }\n\n /**\n * 重置盒子和canvas的宽高\n */\n private resetWidthAndHeight (): void {\n const { config, data } = this\n // 如果是浏览器环境并且存在盒子\n let boxWidth = 0, boxHeight = 0\n if (config.divElement) {\n boxWidth = config.divElement.offsetWidth\n boxHeight = config.divElement.offsetHeight\n }\n // 先从 data 里取宽高, 如果 config 上面没有, 就从 style 上面取\n this.boxWidth = this.getLength(data.width || config['width']) || boxWidth\n this.boxHeight = this.getLength(data.height || config['height']) || boxHeight\n // 重新把宽高赋给盒子\n if (config.divElement) {\n config.divElement.style.overflow = 'hidden'\n config.divElement.style.width = this.boxWidth + 'px'\n config.divElement.style.height = this.boxHeight + 'px'\n }\n }\n\n /**\n * 根据 dpr 缩放 canvas 并处理位移\n */\n protected zoomCanvas (): void {\n const { config, ctx } = this\n const { canvasElement, dpr } = config\n const [width, height] = [this.boxWidth * dpr, this.boxHeight * dpr]\n if (!canvasElement) return\n canvasElement.width = width\n canvasElement.height = height\n canvasElement.style.width = `${width}px`\n canvasElement.style.height = `${height}px`\n canvasElement.style['transform-origin'] = 'left top'\n canvasElement.style.transform = `scale(${1 / dpr})`\n ctx.scale(dpr, dpr)\n }\n\n /**\n * 从 window 对象上获取一些方法\n */\n private initWindowFunction (): void {\n const { config } = this\n if (window) {\n this.rAF = window.requestAnimationFrame ||\n window['webkitRequestAnimationFrame'] ||\n window['mozRequestAnimationFrame'] ||\n function (callback: Function) {\n window.setTimeout(callback, 1000 / 60)\n }\n config.setTimeout = window.setTimeout\n config.setInterval = window.setInterval\n config.clearTimeout = window.clearTimeout\n config.clearInterval = window.clearInterval\n return\n }\n if (config.rAF) {\n // 优先使用帧动画\n this.rAF = config.rAF\n } else if (config.setTimeout) {\n // 其次使用定时器\n const timeout = config.setTimeout\n this.rAF = (callback: Function): number => timeout(callback, 16.7)\n } else {\n // 如果config里面没有提供, 那就假设全局方法存在setTimeout\n this.rAF = (callback: Function): number => setTimeout(callback, 16.7)\n }\n }\n\n public isWeb () {\n return ['WEB', 'UNI-H5', 'TARO-H5'].includes(this.config.flag)\n }\n\n /**\n * 异步加载图片并返回图片的几何信息\n * @param src 图片路径\n * @param info 图片信息\n */\n protected loadImg (\n src: string,\n info: ImgItemType,\n resolveName = '$resolve'\n ): Promise<ImgType> {\n return new Promise((resolve, reject) => {\n if (!src) reject(`=> '${info.src}' 不能为空或不合法`)\n if (this.config.flag === 'WEB') {\n let imgObj = new Image()\n imgObj['crossorigin'] = 'anonymous'\n imgObj.onload = () => resolve(imgObj)\n imgObj.onerror = () => reject(`=> '${info.src}' 图片加载失败`)\n imgObj.src = src\n } else {\n // 其余平台向外暴露, 交给外部自行处理\n info[resolveName] = resolve\n info['$reject'] = reject\n return\n }\n })\n }\n\n /**\n * 公共绘制图片的方法\n * @param imgObj 图片对象\n * @param rectInfo: [x轴位置, y轴位置, 渲染宽度, 渲染高度] \n */\n protected drawImage(\n ctx: CanvasRenderingContext2D,\n imgObj: ImgType,\n ...rectInfo: [...Tuple<number, 4>, ...Partial<Tuple<number, 4>>]\n ): void {\n let drawImg\n const { flag, dpr } = this.config\n if (['WEB', 'MP-WX'].includes(flag)) {\n // 浏览器和新版小程序中直接绘制即可\n drawImg = imgObj\n } else if (['UNI-H5', 'UNI-MP', 'TARO-H5', 'TARO-MP'].includes(flag)) {\n // 旧版本的小程序需要绘制 path, 这里特殊处理一下\n type OldImageType = ImgType & { path: CanvasImageSource }\n drawImg = (imgObj as OldImageType).path\n } else {\n // 如果传入了未知的标识\n return console.error('意料之外的 flag, 该平台尚未兼容!')\n }\n const miniProgramOffCtx = (drawImg['canvas'] || drawImg).getContext?.('2d')\n if (miniProgramOffCtx && !this.isWeb()) {\n rectInfo = rectInfo.map(val => val! * dpr) as Tuple<number, 8>\n const temp = miniProgramOffCtx.getImageData(...rectInfo.slice(0, 4))\n ctx.putImageData(temp, ...(rectInfo.slice(4, 6) as Tuple<number, 2>))\n } else {\n if (rectInfo.length === 8) {\n rectInfo = rectInfo.map((val, index) => index < 4 ? val! * dpr : val) as Tuple<number, 8>\n }\n // 尝试捕获错误\n try {\n ctx.drawImage(drawImg, ...rectInfo as Tuple<number, 8>)\n } catch (err) {\n /**\n * TODO: safari浏览器下, init() 会出现奇怪的报错\n * IndexSizeError: The index is not in the allowed range\n * 但是这个报错并不影响实际的绘制, 目前先放一放, 等待有缘人\n */\n // console.log(err)\n }\n }\n }\n\n /**\n * 计算图片的渲染宽高\n * @param imgObj 图片标签元素\n * @param imgInfo 图片信息\n * @param maxWidth 最大宽度\n * @param maxHeight 最大高度\n * @return [渲染宽度, 渲染高度]\n */\n protected computedWidthAndHeight (\n imgObj: ImgType,\n imgInfo: ImgItemType,\n maxWidth: number,\n maxHeight: number\n ): [number, number] {\n // 根据配置的样式计算图片的真实宽高\n if (!imgInfo.width && !imgInfo.height) {\n // 如果没有配置宽高, 则使用图片本身的宽高\n return [imgObj.width, imgObj.height]\n } else if (imgInfo.width && !imgInfo.height) {\n // 如果只填写了宽度, 没填写高度\n let trueWidth = this.getLength(imgInfo.width, maxWidth)\n // 那高度就随着宽度进行等比缩放\n return [trueWidth, imgObj.height * (trueWidth / imgObj.width)]\n } else if (!imgInfo.width && imgInfo.height) {\n // 如果只填写了宽度, 没填写高度\n let trueHeight = this.getLength(imgInfo.height, maxHeight)\n // 那宽度就随着高度进行等比缩放\n return [imgObj.width * (trueHeight / imgObj.height), trueHeight]\n }\n // 如果宽度和高度都填写了, 就如实计算\n return [\n this.getLength(imgInfo.width, maxWidth),\n this.getLength(imgInfo.height, maxHeight)\n ]\n }\n\n /**\n * 转换单位\n * @param { string } value 将要转换的值\n * @param { number } denominator 分子\n * @return { number } 返回新的字符串\n */\n protected changeUnits (value: string, denominator = 1): number {\n const { config } = this\n return Number(value.replace(/^([-]*[0-9.]*)([a-z%]*)$/, (val, num, unit) => {\n const handleCssUnit = {\n '%': (n: number) => n * (denominator / 100),\n 'px': (n: number) => n * 1,\n 'rem': (n: number) => n * this.htmlFontSize,\n 'vw': (n: number) => n / 100 * window.innerWidth,\n }[unit]\n if (handleCssUnit) return handleCssUnit(num)\n // 如果找不到默认单位, 就交给外面处理\n const otherHandleCssUnit = config.handleCssUnit || config['unitFunc']\n return otherHandleCssUnit ? otherHandleCssUnit(num, unit) : num\n }))\n }\n\n /**\n * 获取长度\n * @param length 将要转换的长度\n * @param maxLength 最大长度\n * @return 返回长度\n */\n protected getLength (length: string | number | undefined, maxLength?: number): number {\n if (isExpectType(length, 'number')) return length as number\n if (isExpectType(length, 'string')) return this.changeUnits(length as string, maxLength)\n return 0\n }\n\n /**\n * 获取相对(居中)X坐标\n * @param width\n * @param col\n */\n protected getOffsetX (width: number, maxWidth: number = 0): number {\n return (maxWidth - width) / 2\n }\n\n protected getOffscreenCanvas (width: number, height: number): {\n _offscreenCanvas: HTMLCanvasElement,\n _ctx: CanvasRenderingContext2D\n } | void {\n if (!this['_offscreenCanvas']) {\n if (window && window.document && this.config.flag === 'WEB') {\n this['_offscreenCanvas'] = document.createElement('canvas')\n } else {\n this['_offscreenCanvas'] = this.config['offscreenCanvas']\n }\n if (!this['_offscreenCanvas']) return console.error('离屏 Canvas 无法渲染!')\n }\n const dpr = this.config.dpr\n const _offscreenCanvas = this['_offscreenCanvas'] as HTMLCanvasElement\n _offscreenCanvas.width = (width || 300) * dpr\n _offscreenCanvas.height = (height || 150) * dpr\n const _ctx = _offscreenCanvas.getContext('2d')!\n _ctx.clearRect(0, 0, width, height)\n _ctx.scale(dpr, dpr)\n _ctx['dpr'] = dpr\n return { _offscreenCanvas, _ctx }\n }\n\n /**\n * 添加一个新的响应式数据 (临时)\n * @param data 数据\n * @param key 属性\n * @param value 新值\n */\n public $set (data: object, key: string | number, value: any) {\n if (!data || typeof data !== 'object') return\n defineReactive(data, key, value)\n }\n\n /**\n * 添加一个属性计算 (临时)\n * @param data 源数据\n * @param key 属性名\n * @param callback 回调函数\n */\n protected $computed (data: object, key: string, callback: Function) {\n Object.defineProperty(data, key, {\n get: () => {\n return callback.call(this)\n }\n })\n }\n\n /**\n * 添加一个观察者 create user watcher\n * @param expr 表达式\n * @param handler 回调函数\n * @param watchOpt 配置参数\n * @return 卸载当前观察者的函数 (暂未返回)\n */\n protected $watch (\n expr: string | Function,\n handler: Function | WatchOptType,\n watchOpt: WatchOptType = {}\n ): Function {\n if (typeof handler === 'object') {\n watchOpt = handler\n handler = watchOpt.handler!\n }\n // 创建 user watcher\n const watcher = new Watcher(this, expr, handler, watchOpt)\n // 判断是否需要初始化时触发回调\n if (watchOpt.immediate) {\n handler.call(this, watcher.value)\n }\n // 返回一个卸载当前观察者的函数\n return function unWatchFn () {}\n }\n}\n","/**\n * 转换为运算角度\n * @param { number } deg 数学角度\n * @return { number } 运算角度\n */\nexport const getAngle = (deg: number): number => {\n return Math.PI / 180 * deg\n}\n\n/**\n * 根据角度计算圆上的点\n * @param { number } deg 运算角度\n * @param { number } r 半径\n * @return { Array<number> } 坐标[x, y]\n */\nexport const getArcPointerByDeg = (deg: number, r: number): [number, number] => {\n return [+(Math.cos(deg) * r).toFixed(8), +(Math.sin(deg) * r).toFixed(8)]\n}\n\n/**\n * 根据点计算切线方程\n * @param { number } x 横坐标\n * @param { number } y 纵坐标\n * @return { Array<number> } [斜率, 常数]\n */\nexport const getTangentByPointer = (x: number, y: number): Array<number> => {\n let k = - x / y\n let b = -k * x + y\n return [k, b]\n}\n\n// 使用 arc 绘制扇形\nexport const fanShapedByArc = (\n ctx: CanvasRenderingContext2D,\n minRadius: number,\n maxRadius: number,\n start: number,\n end: number,\n gutter: number,\n): void => {\n ctx.beginPath()\n let maxGutter = getAngle(90 / Math.PI / maxRadius * gutter)\n let minGutter = getAngle(90 / Math.PI / minRadius * gutter)\n let maxStart = start + maxGutter\n let maxEnd = end - maxGutter\n let minStart = start + minGutter\n let minEnd = end - minGutter\n ctx.arc(0, 0, maxRadius, maxStart, maxEnd, false)\n // 如果 getter 比按钮短就绘制圆弧, 反之计算新的坐标点\n // if (minEnd > minStart) {\n // ctx.arc(0, 0, minRadius, minEnd, minStart, true)\n // } else {\n ctx.lineTo(\n ...getArcPointerByDeg(\n (start + end) / 2,\n gutter / 2 / Math.abs(Math.sin((start - end) / 2))\n )\n )\n // }\n ctx.closePath()\n}\n\n// 使用 arc 绘制圆角矩形\nexport const roundRectByArc = (\n ctx: CanvasRenderingContext2D,\n ...[x, y, w, h, r]: number[]\n) => {\n const min = Math.min(w, h), PI = Math.PI\n if (r > min / 2) r = min / 2\n ctx.beginPath()\n ctx.moveTo(x + r, y)\n ctx.lineTo(x + r, y)\n ctx.lineTo(x + w - r, y)\n ctx.arc(x + w - r, y + r, r, -PI / 2, 0)\n ctx.lineTo(x + w, y + h - r)\n ctx.arc(x + w - r, y + h - r, r, 0, PI / 2)\n ctx.lineTo(x + r, y + h)\n ctx.arc(x + r, y + h - r, r, PI / 2, PI)\n ctx.lineTo(x, y + r)\n ctx.arc(x + r, y + r, r, PI, -PI / 2)\n ctx.closePath()\n}\n\n/**\n * 创建线性渐变色\n */\nexport const getLinearGradient = (\n ctx: CanvasRenderingContext2D,\n x: number,\n y: number,\n w: number,\n h: number,\n background: string\n) => {\n const context = (/linear-gradient\\((.+)\\)/.exec(background) as Array<any>)[1]\n .split(',') // 根据逗号分割\n .map((text: string) => text.trim()) // 去除两边空格\n let deg = context.shift(), direction: [number, number, number, number] = [0, 0, 0, 0]\n // 通过起始点和角度计算渐变终点的坐标点, 这里感谢泽宇大神提醒我使用勾股定理....\n if (deg.includes('deg')) {\n deg = deg.slice(0, -3) % 360\n // 根据4个象限定义起点坐标, 根据45度划分8个区域计算终点坐标\n const getLenOfTanDeg = (deg: number) => Math.tan(deg / 180 * Math.PI)\n if (deg >= 0 && deg < 45) direction = [x, y + h, x + w, y + h - w * getLenOfTanDeg(deg - 0)]\n else if (deg >= 45 && deg < 90) direction = [x, y + h, (x + w) - h * getLenOfTanDeg(deg - 45), y]\n else if (deg >= 90 && deg < 135) direction = [x + w, y + h, (x + w) - h * getLenOfTanDeg(deg - 90), y]\n else if (deg >= 135 && deg < 180) direction = [x + w, y + h, x, y + w * getLenOfTanDeg(deg - 135)]\n else if (deg >= 180 && deg < 225) direction = [x + w, y, x, y + w * getLenOfTanDeg(deg - 180)]\n else if (deg >= 225 && deg < 270) direction = [x + w, y, x + h * getLenOfTanDeg(deg - 225), y + h]\n else if (deg >= 270 && deg < 315) direction = [x, y, x + h * getLenOfTanDeg(deg - 270), y + h]\n else if (deg >= 315 && deg < 360) direction = [x, y, x + w, y + h - w * getLenOfTanDeg(deg - 315)]\n }\n // 创建四个简单的方向坐标\n else if (deg.includes('top')) direction = [x, y + h, x, y]\n else if (deg.includes('bottom')) direction = [x, y, x, y + h]\n else if (deg.includes('left')) direction = [x + w, y, x, y]\n else if (deg.includes('right')) direction = [x, y, x + w, y]\n // 创建线性渐变必须使用整数坐标\n const gradient = ctx.createLinearGradient(...(direction.map(n => n >> 0) as typeof direction))\n // 这里后期重构, 先用any代替\n return context.reduce((gradient: any, item: any, index: any) => {\n const info = item.split(' ')\n if (info.length === 1) gradient.addColorStop(index, info[0])\n else if (info.length === 2) gradient.addColorStop(...info)\n return gradient\n }, gradient)\n}\n\n// // 根据三点画圆弧\n// export const drawRadian = (\n// ctx: CanvasRenderingContext2D,\n// r: number,\n// start: number,\n// end: number,\n// direction: boolean = true\n// ) => {\n// // 如果角度大于等于180度, 则分两次绘制, 因为 arcTo 无法绘制180度的圆弧\n// if (Math.abs(end - start).toFixed(8) >= getAngle(180).toFixed(8)) {\n// let middle = (end + start) / 2\n// if (direction) {\n// drawRadian(ctx, r, start, middle, direction)\n// drawRadian(ctx, r, middle, end, direction)\n// } else {\n// drawRadian(ctx, r, middle, end, direction)\n// drawRadian(ctx, r, start, middle, direction)\n// }\n// return false\n// }\n// // 如果方法相反, 则交换起点和终点\n// if (!direction) [start, end] = [end, start]\n// const [x1, y1] = getArcPointerByDeg(start, r)\n// const [x2, y2] = getArcPointerByDeg(end, r)\n// const [k1, b1] = getTangentByPointer(x1, y1)\n// const [k2, b2] = getTangentByPointer(x2, y2)\n// // 计算两条切线的交点\n// let x0 = (b2 - b1) / (k1 - k2)\n// let y0 = (k2 * b1 - k1 * b2) / (k2 - k1)\n// // 如果有任何一条切线垂直于x轴, 则斜率不存在\n// if (isNaN(x0)) {\n// Math.abs(x1) === +r.toFixed(8) && (x0 = x1)\n// Math.abs(x2) === +r.toFixed(8) && (x0 = x2)\n// }\n// if (k1 === Infinity || k1 === -Infinity) {\n// y0 = k2 * x0 + b2\n// }\n// else if (k2 === Infinity || k2 === -Infinity) {\n// y0 = k1 * x0 + b1\n// }\n// ctx.lineTo(x1, y1)\n// // 微信小程序下 arcTo 在安卓真机下绘制有 bug\n// ctx.arcTo(x0, y0, x2, y2, r)\n// }\n\n// // 使用 arcTo 绘制扇形 (弃用)\n// export const drawSectorByArcTo = (\n// ctx: CanvasRenderingContext2D,\n// minRadius: number,\n// maxRadius: number,\n// start: number,\n// end: number,\n// gutter: number,\n// ) => {\n// if (!minRadius) minRadius = gutter\n// // 内外圆弧分别进行等边缩放\n// let maxGutter = getAngle(90 / Math.PI / maxRadius * gutter)\n// let minGutter = getAngle(90 / Math.PI / minRadius * gutter)\n// let maxStart = start + maxGutter\n// let maxEnd = end - maxGutter\n// let minStart = start + minGutter\n// let minEnd = end - minGutter\n// ctx.beginPath()\n// ctx.moveTo(...getArcPointerByDeg(maxStart, maxRadius))\n// drawRadian(ctx, maxRadius, maxStart, maxEnd, true)\n// // 如果 getter 比按钮短就绘制圆弧, 反之计算新的坐标点\n// if (minEnd > minStart) {\n// drawRadian(ctx, minRadius, minStart, minEnd, false)\n// } else {\n// ctx.lineTo(\n// ...getArcPointerByDeg(\n// (start + end) / 2,\n// gutter / 2 / Math.abs(Math.sin((start - end) / 2))\n// )\n// )\n// }\n// ctx.closePath()\n// }\n\n// // 使用 arcTo 绘制圆角矩形 (弃用)\n// export const roundRectByArcTo = (\n// ctx: CanvasRenderingContext2D,\n// ...[x, y, w, h, r]: number[]\n// ) => {\n// let min = Math.min(w, h)\n// if (r > min / 2) r = min / 2\n// ctx.beginPath()\n// ctx.moveTo(x + r, y)\n// ctx.lineTo(x + r, y)\n// ctx.lineTo(x + w - r, y)\n// ctx.arcTo(x + w, y, x + w, y + r, r)\n// ctx.lineTo(x + w, y + h - r)\n// ctx.arcTo(x + w, y + h, x + w - r, y + h, r)\n// ctx.lineTo(x + r, y + h)\n// ctx.arcTo(x, y + h, x, y + h - r, r)\n// ctx.lineTo(x, y + r)\n// ctx.arcTo(x, y, x + r, y, r)\n// }\n","/**\n * 缓动函数\n * t: current time(当前时间)\n * b: beginning value(初始值)\n * c: change in value(变化量)\n * d: duration(持续时间)\n * \n * 感谢张鑫旭大佬 https://github.com/zhangxinxu/Tween\n */\n\ninterface SpeedType {\n easeIn: (...arr: number[]) => number\n easeOut: (...arr: number[]) => number\n}\n\n// 二次方的缓动\nexport const quad: SpeedType = {\n easeIn: function (t, b, c, d) {\n if (t >= d) t = d\n return c * (t /= d) * t + b\n },\n easeOut: function (t, b, c, d) {\n if (t >= d) t = d\n return -c * (t /= d) * (t - 2) + b\n }\n}\n\n// 三次方的缓动\nexport const cubic: SpeedType = {\n easeIn: function (t, b, c, d) {\n if (t >= d) t = d\n return c * (t /= d) * t * t + b\n },\n easeOut: function (t, b, c, d) {\n if (t >= d) t = d\n return c * ((t = t / d - 1) * t * t + 1) + b\n }\n}\n\n// 四次方的缓动\nexport const quart: SpeedType = {\n easeIn: function (t, b, c, d) {\n if (t >= d) t = d\n return c * (t /= d) * t * t * t + b\n },\n easeOut: function (t, b, c, d) {\n if (t >= d) t = d\n return -c * ((t = t / d - 1) * t * t * t - 1) + b\n }\n}\n\n// 五次方的缓动\nexport const quint: SpeedType = {\n easeIn: function (t, b, c, d) {\n if (t >= d) t = d\n return c * (t /= d) * t * t * t * t + b\n },\n easeOut: function (t, b, c, d) {\n if (t >= d) t = d\n return c * ((t = t / d - 1) * t * t * t * t + 1) + b\n }\n}\n\n// 正弦曲线的缓动\nexport const sine: SpeedType = {\n easeIn: function (t, b, c, d) {\n if (t >= d) t = d\n return -c * Math.cos(t / d * (Math.PI / 2)) + c + b\n },\n easeOut: function (t, b, c, d) {\n if (t >= d) t = d\n return c * Math.sin(t / d * (Math.PI / 2)) + b\n }\n}\n\n// 指数曲线的缓动\nexport const expo: SpeedType = {\n easeIn: function (t, b, c, d) {\n if (t >= d) t = d\n return (t == 0) ? b : c * Math.pow(2, 10 * (t / d - 1)) + b\n },\n easeOut: function (t, b, c, d) {\n if (t >= d) t = d\n return (t == d) ? b + c : c * (-Math.pow(2, -10 * t / d) + 1) + b\n }\n}\n\n// 圆形曲线的缓动\nexport const circ: SpeedType = {\n easeIn: function (t, b, c, d) {\n if (t >= d) t = d\n return -c * (Math.sqrt(1 - (t /= d) * t) - 1) + b\n },\n easeOut: function (t, b, c, d) {\n if (t >= d) t = d\n return c * Math.sqrt(1 - (t = t / d - 1) * t) + b\n }\n}\n","import Lucky from './lucky'\nimport { UserConfigType, FontItemType, ImgType } from '../types/index'\nimport LuckyWheelConfig, {\n BlockType,\n PrizeType,\n ButtonType,\n DefaultConfigType,\n DefaultStyleType,\n StartCallbackType,\n EndCallbackType\n} from '../types/wheel'\nimport {\n removeEnter,\n hasBackground,\n computeRange,\n splitText,\n has,\n} from '../utils/index'\nimport { getAngle, fanShapedByArc } from '../utils/math'\nimport { quad } from '../utils/tween'\n\nexport default class LuckyWheel extends Lucky {\n private blocks: Array<BlockType> = []\n private prizes: Array<PrizeType> = []\n private buttons: Array<ButtonType> = []\n private defaultConfig: DefaultConfigType = {}\n private defaultStyle: DefaultStyleType = {}\n private _defaultConfig: Required<DefaultConfigType> = {} as Required<DefaultConfigType>\n private _defaultStyle: Required<DefaultStyleType> = {} as Required<DefaultStyleType>\n private startCallback?: StartCallbackType\n private endCallback?: EndCallbackType\n private Radius = 0 // 大转盘半径\n private prizeRadius = 0 // 奖品区域半径\n private prizeDeg = 0 // 奖品数学角度\n private prizeAng = 0 // 奖品运算角度\n private rotateDeg = 0 // 转盘旋转角度\n private maxBtnRadius = 0 // 最大按钮半径\n private startTime = 0 // 开始时间戳\n private endTime = 0 // 停止时间戳\n private stopDeg = 0 // 刻舟求剑\n private endDeg = 0 // 停止角度\n private FPS = 16.6 // 屏幕刷新率\n /**\n * 游戏当前的阶段\n * step = 0 时, 游戏尚未开始\n * step = 1 时, 此时处于加速阶段\n * step = 2 时, 此时处于匀速阶段\n * step = 3 时, 此时处于减速阶段\n */\n private step: 0 | 1 | 2 | 3 = 0\n /**\n * 中奖索引\n * prizeFlag = undefined 时, 处于开始抽奖阶段, 正常旋转\n * prizeFlag >= 0 时, 说明stop方法被调用, 并且传入了中奖索引\n * prizeFlag === -1 时, 说明stop方法被调用, 并且传入了负值, 本次抽奖无效\n */\n private prizeFlag: number | undefined\n private ImageCache = new Map()\n\n /**\n * 大转盘构造器\n * @param config 配置项\n * @param data 抽奖数据\n */\n constructor (config: UserConfigType, data: LuckyWheelConfig) {\n super(config, {\n width: data.width,\n height: data.height\n })\n this.initData(data)\n this.initWatch()\n this.initComputed()\n // 创建前回调函数\n config.beforeCreate?.call(this)\n // 首次初始化\n this.init()\n }\n\n protected resize(): void {\n super.resize()\n this.Radius = Math.min(this.boxWidth, this.boxHeight) / 2\n this.ctx.translate(this.Radius, this.Radius)\n this.draw()\n this.config.afterResize?.()\n }\n\n protected initLucky (): void {\n this.Radius = 0\n this.prizeRadius = 0\n this.prizeDeg = 0\n this.prizeAng = 0\n this.rotateDeg = 0\n this.maxBtnRadius = 0\n this.startTime = 0\n this.endTime = 0\n this.stopDeg = 0\n this.endDeg = 0\n this.FPS = 16.6\n this.prizeFlag = -1\n this.step = 0\n super.initLucky()\n }\n\n /**\n * 初始化数据\n * @param data\n */\n private initData (data: LuckyWheelConfig): void {\n this.$set(this, 'width', data.width)\n this.$set(this, 'height', data.height)\n this.$set(this, 'blocks', data.blocks || [])\n this.$set(this, 'prizes', data.prizes || [])\n this.$set(this, 'buttons', data.buttons || [])\n this.$set(this, 'defaultConfig', data.defaultConfig || {})\n this.$set(this, 'defaultStyle', data.defaultStyle || {})\n this.$set(this, 'startCallback', data.start)\n this.$set(this, 'endCallback', data.end)\n }\n\n /**\n * 初始化属性计算\n */\n private initComputed () {\n // 默认配置\n this.$computed(this, '_defaultConfig', () => {\n const config = {\n gutter: '0px',\n offsetDegree: 0,\n speed: 20,\n speedFunction: 'quad',\n accelerationTime: 2500,\n decelerationTime: 2500,\n stopRange: 0,\n ...this.defaultConfig\n }\n return config\n })\n // 默认样式\n this.$computed(this, '_defaultStyle', () => {\n const style = {\n fontSize: '18px',\n fontColor: '#000',\n fontStyle: 'sans-serif',\n fontWeight: '400',\n background: 'rgba(0,0,0,0)',\n wordWrap: true,\n lengthLimit: '90%',\n ...this.defaultStyle\n }\n return style\n })\n }\n\n /**\n * 初始化观察者\n */\n private initWatch () {\n // 重置宽度\n this.$watch('width', (newVal: string | number) => {\n this.data.width = newVal\n this.resize()\n })\n // 重置高度\n this.$watch('height', (newVal: string | number) => {\n this.data.height = newVal\n this.resize()\n })\n // 观察 blocks 变化收集图片\n this.$watch('blocks', (newData: Array<BlockType>) => {\n this.initImageCache()\n }, { deep: true })\n // 观察 prizes 变化收集图片\n this.$watch('prizes', (newData: Array<PrizeType>) => {\n this.initImageCache()\n }, { deep: true })\n // 观察 buttons 变化收集图片\n this.$watch('buttons', (newData: Array<ButtonType>) => {\n this.initImageCache()\n }, { deep: true })\n this.$watch('defaultConfig', () => this.draw(), { deep: true })\n this.$watch('defaultStyle', () => this.draw(), { deep: true })\n this.$watch('startCallback', () => this.init())\n this.$watch('endCallback', () => this.init())\n }\n\n /**\n * 初始化 canvas 抽奖\n */\n public async init (): Promise<void> {\n this.initLucky()\n const { config } = this\n // 初始化前回调函数\n config.beforeInit?.call(this)\n this.draw() // 先画一次, 防止闪烁\n this.draw() // 再画一次, 拿到正确的按钮轮廓\n // 异步加载图片\n await this.initImageCache()\n // 初始化后回调函数\n config.afterInit?.call(this)\n }\n\n private initImageCache (): Promise<void> {\n return new Promise((resolve) => {\n const willUpdateImgs = {\n blocks: this.blocks.map(block => block.imgs),\n prizes: this.prizes.map(prize => prize.imgs),\n buttons: this.buttons.map(btn => btn.imgs),\n }\n ;(<(keyof typeof willUpdateImgs)[]>Object.keys(willUpdateImgs)).forEach(imgName => {\n const willUpdate = willUpdateImgs[imgName]\n // 循环遍历所有图片\n const allPromise: Promise<void>[] = []\n willUpdate && willUpdate.forEach((imgs, cellIndex) => {\n imgs && imgs.forEach((imgInfo, imgIndex) => {\n allPromise.push(this.loadAndCacheImg(imgName, cellIndex, imgIndex))\n })\n })\n Promise.all(allPromise).then(() => {\n this.draw()\n resolve()\n })\n })\n })\n }\n\n /**\n * canvas点击事件\n * @param e 事件参数\n */\n protected handleClick (e: MouseEvent): void {\n const { ctx } = this\n ctx.beginPath()\n ctx.arc(0, 0, this.maxBtnRadius, 0, Math.PI * 2, false)\n if (!ctx.isPointInPath(e.offsetX, e.offsetY)) return\n if (this.step !== 0) return\n this.startCallback?.(e)\n }\n\n /**\n * 根据索引单独加载指定图片并缓存\n * @param cellName 模块名称\n * @param cellIndex 模块索引\n * @param imgName 模块对应的图片缓存\n * @param imgIndex 图片索引\n */\n private async loadAndCacheImg (\n cellName: 'blocks' | 'prizes' | 'buttons',\n cellIndex: number,\n imgIndex: number,\n ): Promise<void> {\n return new Promise((resolve, reject) => {\n // 获取图片信息\n const cell: BlockType | PrizeType | ButtonType = this[cellName][cellIndex]\n if (!cell || !cell.imgs) return\n const imgInfo = cell.imgs[imgIndex]\n if (!imgInfo) return\n // 异步加载图片\n this.loadImg(imgInfo.src, imgInfo).then(async currImg => {\n if (typeof imgInfo.formatter === 'function') {\n currImg = await Promise.resolve(imgInfo.formatter.call(this, currImg))\n }\n this.ImageCache.set(imgInfo['src'], currImg)\n resolve()\n }).catch(err => {\n console.error(`${cellName}[${cellIndex}].imgs[${imgIndex}] ${err}`)\n reject()\n })\n })\n }\n\n private drawBlock (radius: number, block: BlockType, blockIndex: number): void {\n const { ctx } = this\n if (hasBackground(block.background)) {\n ctx.beginPath()\n ctx.fillStyle = block.background!\n ctx.arc(0, 0, radius, 0, Math.PI * 2, false)\n ctx.fill()\n }\n block.imgs && block.imgs.forEach((imgInfo, imgIndex) => {\n const blockImg = this.ImageCache.get(imgInfo.src)\n if (!blockImg) return\n // 绘制图片\n const [trueWidth, trueHeight] = this.computedWidthAndHeight(blockImg, imgInfo, radius * 2, radius * 2)\n const [xAxis, yAxis] = [this.getOffsetX(trueWidth) + this.getLength(imgInfo.left, radius * 2), this.getLength(imgInfo.top, radius * 2) - radius]\n ctx.save()\n imgInfo.rotate && ctx.rotate(getAngle(this.rotateDeg))\n this.drawImage(ctx, blockImg, xAxis, yAxis, trueWidth, trueHeight)\n ctx.restore()\n })\n }\n\n /**\n * 开始绘制\n */\n protected draw (): void {\n const { config, ctx, _defaultConfig, _defaultStyle } = this\n // 触发绘制前回调\n config.beforeDraw?.call(this, ctx)\n // 清空画布\n ctx.clearRect(-this.Radius, -this.Radius, this.Radius * 2, this.Radius * 2)\n // 计算 padding 并绘制 blocks 边框\n this.prizeRadius = this.blocks.reduce((radius, block, blockIndex) => {\n this.drawBlock(radius, block, blockIndex)\n return radius - this.getLength(block.padding && block.padding.split(' ')[0])\n }, this.Radius)\n // 计算起始弧度\n this.prizeDeg = 360 / this.prizes.length\n this.prizeAng = getAngle(this.prizeDeg)\n const shortSide = this.prizeRadius * Math.sin(this.prizeAng / 2) * 2\n // 起始角度调整到正上方, 并且减去半个扇形角度\n let start = getAngle(this.rotateDeg - 90 + this.prizeDeg / 2 + _defaultConfig.offsetDegree)\n // 计算文字横坐标\n const getFontX = (font: FontItemType, line: string) => {\n return this.getOffsetX(ctx.measureText(line).width) + this.getLength(font.left, shortSide)\n }\n // 计算文字纵坐标\n const getFontY = (font: FontItemType, height: number, lineIndex: number) => {\n // 优先使用字体行高, 要么使用默认行高, 其次使用字体大小, 否则使用默认字体大小\n const lineHeight = font.lineHeight || _defaultStyle.lineHeight || font.fontSize || _defaultStyle.fontSize\n return this.getLength(font.top, height) + (lineIndex + 1) * this.getLength(lineHeight)\n }\n ctx.save()\n // 绘制prizes奖品区域\n this.prizes.forEach((prize, prizeIndex) => {\n // 计算当前奖品区域中间坐标点\n let currMiddleDeg = start + prizeIndex * this.prizeAng\n // 奖品区域可见高度\n let prizeHeight = this.prizeRadius - this.maxBtnRadius\n // 绘制背景\n const background = prize.background || _defaultStyle.background\n if (hasBackground(background)) {\n ctx.fillStyle = background\n fanShapedByArc(\n ctx, this.maxBtnRadius, this.prizeRadius,\n currMiddleDeg - this.prizeAng / 2,\n currMiddleDeg + this.prizeAng / 2,\n this.getLength(_defaultConfig.gutter),\n )\n ctx.fill()\n }\n // 计算临时坐标并旋转文字\n let x = Math.cos(currMiddleDeg) * this.prizeRadius\n let y = Math.sin(currMiddleDeg) * this.prizeRadius\n ctx.translate(x, y)\n ctx.rotate(currMiddleDeg + getAngle(90))\n // 绘制图片\n prize.imgs && prize.imgs.forEach((imgInfo, imgIndex) => {\n const prizeImg = this.ImageCache.get(imgInfo.src)\n if (!prizeImg) return\n const [trueWidth, trueHeight] = this.computedWidthAndHeight(\n prizeImg,\n imgInfo,\n this.prizeAng * this.prizeRadius,\n prizeHeight\n )\n const [xAxis, yAxis] = [\n this.getOffsetX(trueWidth) + this.getLength(imgInfo.left, shortSide),\n this.getLength(imgInfo.top, prizeHeight)\n ]\n this.drawImage(ctx, prizeImg, xAxis, yAxis, trueWidth, trueHeight)\n })\n // 逐行绘制文字\n prize.fonts && prize.fonts.forEach(font => {\n const fontColor = font.fontColor || _defaultStyle.fontColor\n const fontWeight = font.fontWeight || _defaultStyle.fontWeight\n const fontSize = this.getLength(font.fontSize || _defaultStyle.fontSize)\n const fontStyle = font.fontStyle || _defaultStyle.fontStyle\n const wordWrap = has(font, 'wordWrap') ? font.wordWrap : _defaultStyle.wordWrap\n const lengthLimit = font.lengthLimit || _defaultStyle.lengthLimit\n const lineClamp = font.lineClamp || _defaultStyle.lineClamp\n ctx.fillStyle = fontColor\n ctx.font = `${fontWeight} ${fontSize >> 0}px ${fontStyle}`\n let lines = [], text = String(font.text)\n if (wordWrap) {\n lines = splitText(ctx, removeEnter(text), (lines) => {\n // 三角形临边\n const adjacentSide = this.prizeRadius - getFontY(font, prizeHeight, lines.length)\n // 三角形短边\n const shortSide = adjacentSide * Math.tan(this.prizeAng / 2)\n // 最大宽度\n let maxWidth = shortSide * 2 - this.getLength(_defaultConfig.gutter)\n return this.getLength(lengthLimit, maxWidth)\n }, lineClamp)\n } else {\n lines = text.split('\\n')\n }\n lines.filter(line => !!line).forEach((line, lineIndex) => {\n ctx.fillText(line, getFontX(font, line), getFontY(font, prizeHeight, lineIndex))\n })\n })\n // 修正旋转角度和原点坐标\n ctx.rotate(getAngle(360) - currMiddleDeg - getAngle(90))\n ctx.translate(-x, -y)\n })\n ctx.restore()\n // 绘制按钮\n this.buttons.forEach((btn, btnIndex) => {\n let radius = this.getLength(btn.radius, this.prizeRadius)\n // 绘制背景颜色\n this.maxBtnRadius = Math.max(this.maxBtnRadius, radius)\n if (hasBackground(btn.background)) {\n ctx.beginPath()\n ctx.fillStyle = btn.background as string\n ctx.arc(0, 0, radius, 0, Math.PI * 2, false)\n ctx.fill()\n }\n // 绘制指针\n if (btn.pointer && hasBackground(btn.background)) {\n ctx.beginPath()\n ctx.fillStyle = btn.background as string\n ctx.moveTo(-radius, 0)\n ctx.lineTo(radius, 0)\n ctx.lineTo(0, -radius * 2)\n ctx.closePath()\n ctx.fill()\n }\n // 绘制按钮图片\n btn.imgs && btn.imgs.forEach((imgInfo, imgIndex) => {\n const btnImg = this.ImageCache.get(imgInfo.src)\n if (!btnImg) return\n const [trueWidth, trueHeight] = this.computedWidthAndHeight(btnImg, imgInfo, radius * 2, radius * 2)\n const [xAxis, yAxis] = [this.getOffsetX(trueWidth) + this.getLength(imgInfo.left, radius), this.getLength(imgInfo.top, radius)]\n this.drawImage(ctx, btnImg, xAxis, yAxis, trueWidth, trueHeight)\n })\n // 绘制按钮文字\n btn.fonts && btn.fonts.forEach(font => {\n let fontColor = font.fontColor || _defaultStyle.fontColor\n let fontWeight = font.fontWeight || _defaultStyle.fontWeight\n let fontSize = this.getLength(font.fontSize || _defaultStyle.fontSize)\n let fontStyle = font.fontStyle || _defaultStyle.fontStyle\n ctx.fillStyle = fontColor\n ctx.font = `${fontWeight} ${fontSize >> 0}px ${fontStyle}`\n String(font.text).split('\\n').forEach((line, lineIndex) => {\n ctx.fillText(line, getFontX(font, line), getFontY(font, radius, lineIndex))\n })\n })\n })\n // 触发绘制后回调\n config.afterDraw?.call(this, ctx)\n }\n\n /**\n * 刻舟求剑\n */\n private carveOnGunwaleOfAMovingBoat (): void {\n const { _defaultConfig, prizeFlag, prizeDeg, rotateDeg } = this\n this.endTime = Date.now()\n const stopDeg = this.stopDeg = rotateDeg\n const speed = _defaultConfig.speed\n const stopRange = (Math.random() * prizeDeg - prizeDeg / 2) * this.getLength(_defaultConfig.stopRange)\n let i = 0, prevSpeed = 0, prevDeg = 0\n while (++i) {\n const endDeg = 360 * i - prizeFlag! * prizeDeg - rotateDeg - _defaultConfig.offsetDegree + stopRange - prizeDeg / 2\n let currSpeed = quad.easeOut(this.FPS, stopDeg, endDeg, _defaultConfig.decelerationTime) - stopDeg\n if (currSpeed > speed) {\n this.endDeg = (speed - prevSpeed > currSpeed - speed) ? endDeg : prevDeg\n break\n }\n prevDeg = endDeg\n prevSpeed = currSpeed\n }\n }\n\n /**\n * 对外暴露: 开始抽奖方法\n */\n public play (): void {\n if (this.step !== 0) return\n // 记录游戏开始时间\n this.startTime = Date.now()\n // 重置中奖索引\n this.prizeFlag = void 0\n // 加速阶段\n this.step = 1\n // 触发回调\n this.config.afterStart?.()\n // 开始游戏\n this.run()\n }\n\n /**\n * 对外暴露: 缓慢停止方法\n * @param index 中奖索引\n */\n public stop (index?: number): void {\n if (this.step === 0 || this.step === 3) return\n // 如果没有传递中奖索引, 则通过range属性计算一个\n if (!index && index !== 0) {\n const rangeArr = this.prizes.map(item => item.range)\n index = computeRange(rangeArr)\n }\n // 如果index是负数则停止游戏, 反之则传递中奖索引\n if (index < 0) {\n this.step = 0\n this.prizeFlag = -1\n } else {\n this.step = 2\n this.prizeFlag = index % this.prizes.length\n }\n }\n\n /**\n * 实际开始执行方法\n * @param num 记录帧动画执行多少次\n */\n private run (num: number = 0): void {\n const { rAF, step, prizeFlag, _defaultConfig } = this\n const { accelerationTime, decelerationTime, speed } = _defaultConfig\n // 游戏结束\n if (step === 0) {\n this.endCallback?.(this.prizes.find((prize, index) => index === prizeFlag) || {})\n return\n }\n // 如果等于 -1 就直接停止游戏\n if (prizeFlag === -1) return\n // 计算结束位置\n if (step === 3 && !this.endDeg) this.carveOnGunwaleOfAMovingBoat()\n // 计算时间间隔\n const startInterval = Date.now() - this.startTime\n const endInterval = Date.now() - this.endTime\n let rotateDeg = this.rotateDeg\n // \n if (step === 1 || startInterval < accelerationTime) { // 加速阶段\n // 记录帧率\n this.FPS = startInterval / num\n const currSpeed = quad.easeIn(startInterval, 0, speed, accelerationTime)\n // 加速到峰值后, 进入匀速阶段\n if (currSpeed === speed) {\n this.step = 2\n }\n rotateDeg = rotateDeg + currSpeed % 360\n } else if (step === 2) { // 匀速阶段\n // 速度保持不变\n rotateDeg = rotateDeg + speed % 360\n // 如果 prizeFlag 有值, 则进入减速阶段\n if (prizeFlag !== void 0 && prizeFlag >= 0) {\n this.step = 3\n // 清空上一次的位置信息\n this.stopDeg = 0\n this.endDeg = 0\n }\n } else if (step === 3) { // 减速阶段\n // 开始缓慢停止\n rotateDeg = quad.easeOut(endInterval, this.stopDeg, this.endDeg, decelerationTime)\n if (endInterval >= decelerationTime) {\n this.step = 0\n }\n } else {\n // 出现异常\n this.stop(-1)\n }\n this.rotateDeg = rotateDeg\n this.draw()\n rAF(this.run.bind(this, num + 1))\n }\n\n /**\n * 换算渲染坐标\n * @param x\n * @param y\n */\n protected conversionAxis (x: number, y: number): [number, number] {\n const { config } = this\n return [x / config.dpr - this.Radius, y / config.dpr - this.Radius]\n }\n}\n","import Lucky from './lucky'\nimport { UserConfigType, ImgType } from '../types/index'\nimport LuckyGridConfig, {\n BlockType,\n PrizeType,\n ButtonType,\n CellFontType,\n CellImgType,\n RowsType,\n ColsType,\n CellType,\n DefaultConfigType,\n DefaultStyleType,\n ActiveStyleType,\n StartCallbackType,\n EndCallbackType,\n} from '../types/grid'\nimport {\n has,\n isExpectType,\n removeEnter,\n computePadding,\n hasBackground,\n computeRange,\n splitText\n} from '../utils/index'\nimport { roundRectByArc, getLinearGradient } from '../utils/math'\nimport { quad } from '../utils/tween'\n\nexport default class LuckyGrid extends Lucky {\n private rows: RowsType = 3\n private cols: ColsType = 3\n private blocks: Array<BlockType> = []\n private prizes: Array<PrizeType> = []\n private buttons: Array<ButtonType> = []\n private button?: ButtonType\n private defaultConfig: DefaultConfigType = {}\n private defaultStyle: DefaultStyleType = {}\n private activeStyle: ActiveStyleType = {}\n private _defaultConfig: Required<DefaultConfigType> = {} as Required<DefaultConfigType>\n private _defaultStyle: Required<DefaultStyleType> = {} as Required<DefaultStyleType>\n private _activeStyle: Required<ActiveStyleType> = {} as Required<ActiveStyleType>\n private startCallback?: StartCallbackType\n private endCallback?: EndCallbackType\n private cellWidth = 0 // 格子宽度\n private cellHeight = 0 // 格子高度\n private startTime = 0 // 开始时间戳\n private endTime = 0 // 结束时间戳\n private currIndex = 0 // 当前index累加\n private stopIndex = 0 // 刻舟求剑\n private endIndex = 0 // 停止索引\n private demo = false // 是否自动游走\n private timer = 0 // 游走定时器\n private FPS = 16.6 // 屏幕刷新率\n /**\n * 游戏当前的阶段\n * step = 0 时, 游戏尚未开始\n * step = 1 时, 此时处于加速阶段\n * step = 2 时, 此时处于匀速阶段\n * step = 3 时, 此时处于减速阶段\n */\n private step: 0 | 1 | 2 | 3 = 0\n /**\n * 中奖索引\n * prizeFlag = undefined 时, 处于开始抽奖阶段, 正常旋转\n * prizeFlag >= 0 时, 说明stop方法被调用, 并且传入了中奖索引\n * prizeFlag === -1 时, 说明stop方法被调用, 并且传入了负值, 本次抽奖无效\n */\n private prizeFlag: number | undefined = -1\n // 所有格子\n private cells: CellType<CellFontType, CellImgType>[] = []\n // 奖品区域几何信息\n private prizeArea: { x: number, y: number, w: number, h: number } | undefined\n // 图片缓存\n private ImageCache = new Map()\n\n /**\n * 九宫格构造器\n * @param config 配置项\n * @param data 抽奖数据\n */\n constructor (config: UserConfigType, data: LuckyGridConfig) {\n super(config, {\n width: data.width,\n height: data.height\n })\n this.initData(data)\n this.initWatch()\n this.initComputed()\n // 创建前回调函数\n config.beforeCreate?.call(this)\n // 首次初始化\n this.init()\n }\n\n protected resize(): void {\n super.resize()\n this.draw()\n this.config.afterResize?.()\n }\n\n protected initLucky (): void {\n this.cellWidth = 0\n this.cellHeight = 0\n this.startTime = 0\n this.endTime = 0\n this.currIndex = 0\n this.stopIndex = 0\n this.endIndex = 0\n this.demo = false\n this.timer = 0\n this.FPS = 16.6\n this.prizeFlag = -1\n this.step = 0\n super.initLucky()\n }\n\n /**\n * 初始化数据\n * @param data\n */\n private initData (data: LuckyGridConfig): void {\n this.$set(this, 'width', data.width)\n this.$set(this, 'height', data.height)\n this.$set(this, 'rows', Number(data.rows) || 3)\n this.$set(this, 'cols', Number(data.cols) || 3)\n this.$set(this, 'blocks', data.blocks || [])\n this.$set(this, 'prizes', data.prizes || [])\n this.$set(this, 'buttons', data.buttons || [])\n // 临时过渡代码, 升级到2.x即可删除\n this.$set(this, 'button', data.button)\n this.$set(this, 'defaultConfig', data.defaultConfig || {})\n this.$set(this, 'defaultStyle', data.defaultStyle || {})\n this.$set(this, 'activeStyle', data.activeStyle || {})\n this.$set(this, 'startCallback', data.start)\n this.$set(this, 'endCallback', data.end)\n }\n\n /**\n * 初始化属性计算\n */\n private initComputed (): void {\n // 默认配置\n this.$computed(this, '_defaultConfig', () => {\n const config = {\n gutter: 5,\n speed: 20,\n accelerationTime: 2500,\n decelerationTime: 2500,\n ...this.defaultConfig\n }\n config.gutter = this.getLength(config.gutter)\n config.speed = config.speed / 40\n return config\n })\n // 默认样式\n this.$computed(this, '_defaultStyle', () => {\n return {\n borderRadius: 20,\n fontColor: '#000',\n fontSize: '18px',\n fontStyle: 'sans-serif',\n fontWeight: '400',\n background: 'rgba(0,0,0,0)',\n shadow: '',\n wordWrap: true,\n lengthLimit: '90%',\n ...this.defaultStyle\n }\n })\n // 中奖样式\n this.$computed(this, '_activeStyle', () => {\n return {\n background: '#ffce98',\n shadow: '',\n ...this.activeStyle\n }\n })\n }\n\n /**\n * 初始化观察者\n */\n private initWatch (): void {\n // 重置宽度\n this.$watch('width', (newVal: string | number) => {\n this.data.width = newVal\n this.resize()\n })\n // 重置高度\n this.$watch('height', (newVal: string | number) => {\n this.data.height = newVal\n this.resize()\n })\n // 监听 blocks 数据的变化\n this.$watch('blocks', (newData: Array<BlockType>) => {\n this.initImageCache()\n }, { deep: true })\n // 监听 prizes 数据的变化\n this.$watch('prizes', (newData: Array<PrizeType>) => {\n this.initImageCache()\n }, { deep: true })\n // 监听 button 数据的变化\n this.$watch('buttons', (newData: Array<ButtonType>) => {\n this.initImageCache()\n }, { deep: true })\n this.$watch('rows', () => this.init())\n this.$watch('cols', () => this.init())\n this.$watch('defaultConfig', () => this.draw(), { deep: true })\n this.$watch('defaultStyle', () => this.draw(), { deep: true })\n this.$watch('activeStyle', () => this.draw(), { deep: true })\n this.$watch('startCallback', () => this.init())\n this.$watch('endCallback', () => this.init())\n }\n\n /**\n * 初始化 canvas 抽奖\n */\n public async init (): Promise<void> {\n this.initLucky()\n const { config } = this\n // 初始化前回调函数\n config.beforeInit?.call(this)\n // 先画一次防止闪烁\n this.draw()\n // 异步加载图片\n await this.initImageCache()\n // 初始化后回调函数\n config.afterInit?.call(this)\n }\n\n private initImageCache (): Promise<void> {\n return new Promise((resolve) => {\n const btnImgs = this.buttons.map(btn => btn.imgs)\n if (this.button) btnImgs.push(this.button.imgs)\n const willUpdateImgs = {\n blocks: this.blocks.map(block => block.imgs),\n prizes: this.prizes.map(prize => prize.imgs),\n buttons: btnImgs,\n }\n ;(<(keyof typeof willUpdateImgs)[]>Object.keys(willUpdateImgs)).forEach(imgName => {\n const willUpdate = willUpdateImgs[imgName]\n // 循环遍历所有图片\n const allPromise: Promise<void>[] = []\n willUpdate && willUpdate.forEach((imgs, cellIndex) => {\n imgs && imgs.forEach((imgInfo, imgIndex) => {\n allPromise.push(this.loadAndCacheImg(imgName, cellIndex, imgIndex))\n })\n })\n Promise.all(allPromise).then(() => {\n this.draw()\n resolve()\n })\n })\n })\n }\n\n /**\n * canvas点击事件\n * @param e 事件参数\n */\n protected handleClick (e: MouseEvent): void {\n const { ctx } = this\n ;[\n ...this.buttons,\n this.button\n ].forEach(btn => {\n if (!btn) return\n const [x, y, width, height] = this.getGeometricProperty([\n btn.x, btn.y, btn.col || 1, btn.row || 1\n ])\n ctx.beginPath()\n ctx.rect(x, y, width, height)\n if (!ctx.isPointInPath(e.offsetX, e.offsetY)) return\n if (this.step !== 0) return\n // 如果btn里有单独的回调方法, 优先触发\n if (typeof btn.callback === 'function') btn.callback.call(this, btn)\n // 最后触发公共回调\n this.startCallback?.(e, btn)\n })\n }\n\n /**\n * 根据索引单独加载指定图片并缓存\n * @param cellName 模块名称\n * @param cellIndex 模块索引\n * @param imgName 模块对应的图片缓存\n * @param imgIndex 图片索引\n */\n private async loadAndCacheImg (\n cellName: 'blocks' | 'prizes' | 'buttons',\n cellIndex: number,\n imgIndex: number\n ): Promise<void> {\n return new Promise((resolve, reject) => {\n let cell: BlockType | PrizeType | ButtonType = this[cellName][cellIndex]\n // 临时过渡代码, 升级到2.x即可删除\n if (cellName === 'buttons' && !this.buttons.length && this.button) {\n cell = this.button\n }\n if (!cell || !cell.imgs) return\n const imgInfo = cell.imgs[imgIndex]\n if (!imgInfo) return\n // 异步加载图片\n const request = [\n this.loadImg(imgInfo.src, imgInfo),\n imgInfo['activeSrc'] && this.loadImg(imgInfo['activeSrc'], imgInfo, '$activeResolve')\n ]\n Promise.all(request).then(async ([defaultImg, activeImg]) => {\n const formatter = imgInfo.formatter\n // 对图片进行处理\n if (typeof formatter === 'function') {\n defaultImg = await Promise.resolve(formatter.call(this, defaultImg))\n if (activeImg) {\n activeImg = await Promise.resolve(formatter.call(this, activeImg))\n }\n }\n this.ImageCache.set(imgInfo['src'], defaultImg)\n activeImg && this.ImageCache.set(imgInfo['activeSrc'], activeImg)\n resolve()\n }).catch(err => {\n console.error(`${cellName}[${cellIndex}].imgs[${imgIndex}] ${err}`)\n reject()\n })\n })\n }\n\n /**\n * 绘制九宫格抽奖\n */\n protected draw (): void {\n const { config, ctx, _defaultConfig, _defaultStyle, _activeStyle } = this\n // 触发绘制前回调\n config.beforeDraw?.call(this, ctx)\n // 清空画布\n ctx.clearRect(0, 0, this.boxWidth, this.boxHeight)\n // 合并奖品和按钮\n this.cells = [\n ...this.prizes,\n ...this.buttons\n ]\n if (this.button) this.cells.push(this.button)\n this.cells.forEach(cell => {\n cell.col = cell.col || 1\n cell.row = cell.row || 1\n })\n // 计算获取奖品区域的几何信息\n this.prizeArea = this.blocks.reduce(({x, y, w, h}, block, blockIndex) => {\n const [paddingTop, paddingBottom, paddingLeft, paddingRight] = computePadding(block, this.getLength.bind(this))\n const r = block.borderRadius ? this.getLength(block.borderRadius) : 0\n // 绘制边框\n const background = block.background\n if (hasBackground(background)) {\n ctx.fillStyle = this.handleBackground(x, y, w, h, background!)\n roundRectByArc(ctx, x, y, w, h, r)\n ctx.fill()\n }\n // 绘制图片\n block.imgs && block.imgs.forEach((imgInfo, imgIndex) => {\n const blockImg = this.ImageCache.get(imgInfo.src)\n if (!blockImg) return\n // 绘制图片\n const [trueWidth, trueHeight] = this.computedWidthAndHeight(blockImg, imgInfo, w, h)\n const [xAxis, yAxis] = [\n this.getOffsetX(trueWidth, w) + this.getLength(imgInfo.left, w),\n this.getLength(imgInfo.top, h)\n ]\n this.drawImage(ctx, blockImg, x + xAxis, y + yAxis, trueWidth, trueHeight)\n })\n return {\n x: x + paddingLeft,\n y: y + paddingTop,\n w: w - paddingLeft - paddingRight,\n h: h - paddingTop - paddingBottom\n }\n }, { x: 0, y: 0, w: this.boxWidth, h: this.boxHeight })\n // 计算单一奖品格子的宽度和高度\n this.cellWidth = (this.prizeArea.w - _defaultConfig.gutter * (this.cols - 1)) / this.cols\n this.cellHeight = (this.prizeArea.h - _defaultConfig.gutter * (this.rows - 1)) / this.rows\n // 绘制所有格子\n this.cells.forEach((cell, cellIndex) => {\n let [x, y, width, height] = this.getGeometricProperty([cell.x, cell.y, cell.col!, cell.row!])\n // 默认不显示中奖标识\n let isActive = false\n // 只要 prizeFlag 不是负数, 就显示中奖标识\n if (this.prizeFlag === void 0 || this.prizeFlag > -1) {\n isActive = cellIndex === this.currIndex % this.prizes.length >> 0\n }\n // 绘制背景色\n const background = isActive ? _activeStyle.background : (cell.background || _defaultStyle.background)\n if (hasBackground(background)) {\n // 处理阴影 (暂时先用any, 这里后续要优化)\n const shadow: any = (\n isActive ? _activeStyle.shadow : (cell.shadow || _defaultStyle.shadow)\n )\n .replace(/px/g, '') // 清空px字符串\n .split(',')[0].split(' ') // 防止有人声明多个阴影, 截取第一个阴影\n .map((n, i) => i < 3 ? Number(n) : n) // 把数组的前三个值*像素比\n // 绘制阴影\n if (shadow.length === 4) {\n ctx.shadowColor = shadow[3]\n ctx.shadowOffsetX = shadow[0] * config.dpr\n ctx.shadowOffsetY = shadow[1] * config.dpr\n ctx.shadowBlur = shadow[2]\n // 修正(格子+阴影)的位置, 这里使用逗号运算符\n shadow[0] > 0 ? (width -= shadow[0]) : (width += shadow[0], x -= shadow[0])\n shadow[1] > 0 ? (height -= shadow[1]) : (height += shadow[1], y -= shadow[1])\n }\n // 绘制背景\n ctx.fillStyle = this.handleBackground(x, y, width, height, background)\n const borderRadius = this.getLength(cell.borderRadius ? cell.borderRadius : _defaultStyle.borderRadius)\n roundRectByArc(ctx, x, y, width, height, borderRadius)\n ctx.fill()\n // 清空阴影\n ctx.shadowColor = 'rgba(0, 0, 0, 0)'\n ctx.shadowOffsetX = 0\n ctx.shadowOffsetY = 0\n ctx.shadowBlur = 0\n }\n // 修正图片缓存\n let cellName = 'prizes'\n if (cellIndex >= this.prizes.length) {\n cellName = 'buttons'\n cellIndex -= this.prizes.length\n }\n // 绘制图片\n cell.imgs && cell.imgs.forEach((imgInfo, imgIndex) => {\n const cellImg = this.ImageCache.get(imgInfo.src)\n const activeImg = this.ImageCache.get(imgInfo['activeSrc'])\n if (!cellImg) return\n const renderImg = (isActive && activeImg) || cellImg\n if (!renderImg) return\n const [trueWidth, trueHeight] = this.computedWidthAndHeight(renderImg, imgInfo, width, height)\n const [xAxis, yAxis] = [\n x + this.getOffsetX(trueWidth, width) + this.getLength(imgInfo.left, width),\n y + this.getLength(imgInfo.top, height)\n ]\n this.drawImage(ctx, renderImg, xAxis, yAxis, trueWidth, trueHeight)\n })\n // 绘制文字\n cell.fonts && cell.fonts.forEach(font => {\n // 字体样式\n const style = isActive && _activeStyle.fontStyle\n ? _activeStyle.fontStyle\n : (font.fontStyle || _defaultStyle.fontStyle)\n // 字体加粗\n const fontWeight = isActive && _activeStyle.fontWeight\n ? _activeStyle.fontWeight\n : (font.fontWeight || _defaultStyle.fontWeight)\n // 字体大小\n const size = isActive && _activeStyle.fontSize\n ? this.getLength(_activeStyle.fontSize)\n : this.getLength(font.fontSize || _defaultStyle.fontSize)\n // 字体行高\n const lineHeight = isActive && _activeStyle.lineHeight\n ? _activeStyle.lineHeight\n : font.lineHeight || _defaultStyle.lineHeight || font.fontSize || _defaultStyle.fontSize\n const wordWrap = has(font, 'wordWrap') ? font.wordWrap : _defaultStyle.wordWrap\n const lengthLimit = font.lengthLimit || _defaultStyle.lengthLimit\n const lineClamp = font.lineClamp || _defaultStyle.lineClamp\n ctx.font = `${fontWeight} ${size >> 0}px ${style}`\n ctx.fillStyle = (isActive && _activeStyle.fontColor) ? _activeStyle.fontColor : (font.fontColor || _defaultStyle.fontColor)\n let lines = [], text = String(font.text)\n // 计算文字换行\n if (wordWrap) {\n // 最大宽度\n let maxWidth = this.getLength(lengthLimit, width)\n lines = splitText(ctx, removeEnter(text), () => maxWidth, lineClamp)\n } else {\n lines = text.split('\\n')\n }\n lines.forEach((line, lineIndex) => {\n ctx.fillText(\n line,\n x + this.getOffsetX(ctx.measureText(line).width, width) + this.getLength(font.left, width),\n y + this.getLength(font.top, height) + (lineIndex + 1) * this.getLength(lineHeight)\n )\n })\n })\n })\n // 触发绘制后回调\n config.afterDraw?.call(this, ctx)\n }\n\n /**\n * 处理背景色\n * @param x\n * @param y\n * @param width\n * @param height\n * @param background\n * @param isActive\n */\n private handleBackground (\n x: number,\n y: number,\n width: number,\n height: number,\n background: string,\n ) {\n const { ctx } = this\n // 处理线性渐变\n if (background.includes('linear-gradient')) {\n background = getLinearGradient(ctx, x, y, width, height, background)\n }\n return background\n }\n\n /**\n * 刻舟求剑\n */\n private carveOnGunwaleOfAMovingBoat (): void {\n const { _defaultConfig, prizeFlag, currIndex } = this\n this.endTime = Date.now()\n const stopIndex = this.stopIndex = currIndex\n const speed = _defaultConfig.speed\n let i = 0, prevSpeed = 0, prevIndex = 0\n while (++i) {\n const endIndex = this.prizes.length * i + prizeFlag! - (stopIndex)\n const currSpeed = quad.easeOut(this.FPS, stopIndex, endIndex, _defaultConfig.decelerationTime) - stopIndex\n if (currSpeed > speed) {\n this.endIndex = (speed - prevSpeed > currSpeed - speed) ? endIndex : prevIndex\n break\n }\n prevIndex = endIndex\n prevSpeed = currSpeed\n }\n }\n\n /**\n * 对外暴露: 开始抽奖方法\n */\n public play (): void {\n if (this.step !== 0) return\n // 记录游戏开始的时间\n this.startTime = Date.now()\n // 重置中奖索引\n this.prizeFlag = void 0\n // 开始加速\n this.step = 1\n // 触发回调\n this.config.afterStart?.()\n // 开始运行\n this.run()\n }\n\n /**\n * 对外暴露: 缓慢停止方法\n * @param index 中奖索引\n */\n public stop (index?: number): void {\n if (this.step === 0 || this.step === 3) return\n // 如果没有传递中奖索引, 则通过range属性计算一个\n if (!index && index !== 0) {\n const rangeArr = this.prizes.map(item => item.range)\n index = computeRange(rangeArr)\n }\n // 如果index是负数则停止游戏, 反之则传递中奖索引\n if (index < 0) {\n this.step = 0\n this.prizeFlag = -1\n } else {\n this.step = 2\n this.prizeFlag = index % this.prizes.length\n }\n }\n\n /**\n * 实际开始执行方法\n * @param num 记录帧动画执行多少次\n */\n private run (num: number = 0): void {\n const { rAF, step, prizes, prizeFlag, _defaultConfig } = this\n const { accelerationTime, decelerationTime, speed } = _defaultConfig\n // 结束游戏\n if (step === 0) {\n this.endCallback?.(this.prizes.find((prize, index) => index === prizeFlag) || {})\n return\n }\n // 如果等于 -1 就直接停止游戏\n if (prizeFlag === -1) return\n // 计算结束位置\n if (step === 3 && !this.endIndex) this.carveOnGunwaleOfAMovingBoat()\n // 计算时间间隔\n const startInterval = Date.now() - this.startTime\n const endInterval = Date.now() - this.endTime\n let currIndex = this.currIndex\n // \n if (step === 1 || startInterval < accelerationTime) { // 加速阶段\n // 记录帧率\n this.FPS = startInterval / num\n const currSpeed = quad.easeIn(startInterval, 0.1, speed - 0.1, accelerationTime)\n // 加速到峰值后, 进入匀速阶段\n if (currSpeed === speed) {\n this.step = 2\n }\n currIndex = currIndex + currSpeed % prizes.length\n } else if (step === 2) { // 匀速阶段\n // 速度保持不变\n currIndex = currIndex + speed % prizes.length\n // 如果 prizeFlag 有值, 则进入减速阶段\n if (prizeFlag !== void 0 && prizeFlag >= 0) {\n this.step = 3\n // 清空上一次的位置信息\n this.stopIndex = 0\n this.endIndex = 0\n }\n } else if (step === 3) { // 减速阶段\n // 开始缓慢停止\n currIndex = quad.easeOut(endInterval, this.stopIndex, this.endIndex, decelerationTime)\n if (endInterval >= decelerationTime) {\n this.step = 0\n }\n } else {\n // 出现异常\n this.stop(-1)\n }\n this.currIndex = currIndex\n this.draw()\n rAF(this.run.bind(this, num + 1))\n }\n\n /**\n * 计算奖品格子的几何属性\n * @param { array } [...矩阵坐标, col, row]\n * @return { array } [...真实坐标, width, height]\n */\n private getGeometricProperty ([x, y, col = 1, row = 1]: number[]) {\n const { cellWidth, cellHeight } = this\n const gutter = this._defaultConfig.gutter\n let res = [\n this.prizeArea!.x + (cellWidth + gutter) * x,\n this.prizeArea!.y + (cellHeight + gutter) * y\n ]\n col && row && res.push(\n cellWidth * col + gutter * (col - 1),\n cellHeight * row + gutter * (row - 1),\n )\n return res\n }\n\n /**\n * 换算渲染坐标\n * @param x\n * @param y\n */\n protected conversionAxis (x: number, y: number): [number, number] {\n const { config } = this\n return [x / config.dpr, y / config.dpr]\n }\n}\n","import Lucky from './lucky'\nimport { UserConfigType, ImgType, ImgItemType, Tuple } from '../types/index'\nimport SlotMachineConfig, {\n BlockType,\n PrizeType,\n SlotType,\n DefaultConfigType,\n DefaultStyleType,\n EndCallbackType,\n} from '../types/slot'\nimport {\n get,\n has,\n isExpectType,\n removeEnter,\n computePadding,\n hasBackground,\n computeRange,\n splitText,\n getSortedArrayByIndex,\n} from '../utils/index'\nimport { roundRectByArc } from '../utils/math'\nimport { quad } from '../utils/tween'\n\nexport default class SlotMachine extends Lucky {\n // 背景\n private blocks: Array<BlockType> = []\n // 奖品列表\n private prizes: Array<PrizeType> = []\n // 插槽列表\n private slots: Array<SlotType> = []\n // 默认配置\n private defaultConfig: DefaultConfigType = {}\n private _defaultConfig: Required<DefaultConfigType> =\n {} as Required<DefaultConfigType>\n // 默认样式\n private defaultStyle: DefaultStyleType = {}\n private _defaultStyle: Required<DefaultStyleType> =\n {} as Required<DefaultStyleType>\n private endCallback: EndCallbackType = () => {}\n // 离屏canvas\n private _offscreenCanvas?: HTMLCanvasElement\n private cellWidth = 0 // 格子宽度\n private cellHeight = 0 // 格子高度\n private cellAndSpacing = 0 // 格子+间距\n private widthAndSpacing = 0 // 格子宽度+列间距\n private heightAndSpacing = 0 // 格子高度+行间距\n private FPS = 16.6 // 屏幕刷新率\n private scroll: number[] = [] // 滚动的长度\n private stopScroll: number[] = [] // 刻舟求剑\n private endScroll: number[] = [] // 最终停止的长度\n private startTime = 0 // 开始游戏的时间\n private endTime: number[] = [] // 每一列开始停止的时间\n private slotStep: Array<0 | 1 | 2 | 3> = []\n // 默认顺序由 prizes 生成\n private defaultOrder: number[] = []\n /**\n * 游戏当前的整体阶段\n * step = 0 时, 游戏尚未开始\n * step = 1 时, 此时处于加速阶段\n * step = 2 时, 此时处于运行阶段\n */\n private step: 0 | 1 | 2 = 0\n /**\n * 中奖索引\n * prizeFlag = undefined 时, 处于开始抽奖阶段, 正常旋转\n * prizeFlag >= 0 时, 说明stop方法被调用, 并且传入了中奖索引\n * prizeFlag === -1 时, 说明stop方法被调用, 并且传入了负值, 本次抽奖无效\n */\n private prizeFlag: Array<number | undefined> | undefined = void 0\n // 奖品区域几何信息\n private prizeArea?: { x: number; y: number; w: number; h: number }\n // 图片缓存\n private ImageCache = new Map()\n\n /**\n * 老虎机构造器\n * @param config 配置项\n * @param data 抽奖数据\n */\n constructor(config: UserConfigType, data: SlotMachineConfig) {\n super(config, {\n width: data.width,\n height: data.height,\n })\n this.initData(data)\n this.initWatch()\n this.initComputed()\n // 创建前回调函数\n config.beforeCreate?.call(this)\n // 首次初始化\n this.init()\n }\n\n protected resize(): void {\n super.resize()\n this.redrawOffscreenCanvas()\n this.config.afterResize?.()\n }\n\n protected initLucky(): void {\n this.cellWidth = 0\n this.cellHeight = 0\n this.cellAndSpacing = 0\n this.widthAndSpacing = 0\n this.heightAndSpacing = 0\n this.FPS = 16.6\n this.scroll = []\n this.stopScroll = []\n this.endScroll = []\n this.startTime = 0\n this.endTime = []\n this.slotStep = []\n this.prizeFlag = void 0\n this.step = 0\n super.initLucky()\n }\n\n /**\n * 初始化数据\n * @param data\n */\n private initData(data: SlotMachineConfig): void {\n this.$set(this, 'width', data.width)\n this.$set(this, 'height', data.height)\n this.$set(this, 'blocks', data.blocks || [])\n this.$set(this, 'prizes', data.prizes || [])\n this.$set(this, 'slots', data.slots || [])\n this.$set(this, 'defaultConfig', data.defaultConfig || {})\n this.$set(this, 'defaultStyle', data.defaultStyle || {})\n this.$set(this, 'endCallback', data.end)\n }\n\n /**\n * 初始化属性计算\n */\n private initComputed(): void {\n // 默认配置\n this.$computed(this, '_defaultConfig', () => {\n const config = {\n mode: 'vertical',\n rowSpacing: 0,\n colSpacing: 5,\n speed: 20,\n direction: 1,\n accelerationTime: 2500,\n decelerationTime: 2500,\n ...this.defaultConfig,\n }\n config.rowSpacing = this.getLength(config.rowSpacing)\n config.colSpacing = this.getLength(config.colSpacing)\n return config\n })\n // 默认样式\n this.$computed(this, '_defaultStyle', () => {\n return {\n borderRadius: 0,\n fontColor: '#000',\n fontSize: '18px',\n fontStyle: 'sans-serif',\n fontWeight: '400',\n background: 'rgba(0,0,0,0)',\n wordWrap: true,\n lengthLimit: '90%',\n ...this.defaultStyle,\n }\n })\n }\n\n /**\n * 初始化观察者\n */\n private initWatch(): void {\n // 重置宽度\n this.$watch('width', (newVal: string | number) => {\n this.data.width = newVal\n this.resize()\n })\n // 重置高度\n this.$watch('height', (newVal: string | number) => {\n this.data.height = newVal\n this.resize()\n })\n // 监听 blocks 数据的变化\n this.$watch(\n 'blocks',\n (newData: Array<BlockType>) => {\n this.initImageCache()\n },\n { deep: true },\n )\n // 监听 prizes 数据的变化\n this.$watch(\n 'prizes',\n (newData: Array<PrizeType>) => {\n this.initImageCache()\n },\n { deep: true },\n )\n // 监听 prizes 数据的变化\n this.$watch(\n 'slots',\n (newData: Array<PrizeType>) => {\n this.redrawOffscreenCanvas()\n },\n { deep: true },\n )\n this.$watch('defaultConfig', () => this.redrawOffscreenCanvas(), {\n deep: true,\n })\n this.$watch('defaultStyle', () => this.redrawOffscreenCanvas(), {\n deep: true,\n })\n this.$watch('endCallback', () => this.init())\n }\n\n /**\n * 初始化 canvas 抽奖\n */\n public async init(): Promise<void> {\n this.initLucky()\n const { config } = this\n // 初始化前回调函数\n config.beforeInit?.call(this)\n // 先绘制一次\n this.drawOffscreenCanvas()\n this.draw()\n // 异步加载图片\n await this.initImageCache()\n // 初始化后回调函数\n config.afterInit?.call(this)\n }\n\n private redrawOffscreenCanvas(): void {\n this.drawOffscreenCanvas()\n this.draw()\n }\n\n private initImageCache(): Promise<void> {\n return new Promise((resolve) => {\n const willUpdateImgs = {\n blocks: this.blocks.map((block) => block.imgs),\n prizes: this.prizes.map((prize) => prize.imgs),\n }\n ;(<(keyof typeof willUpdateImgs)[]>Object.keys(willUpdateImgs)).forEach(\n (imgName) => {\n const willUpdate = willUpdateImgs[imgName]\n // 循环遍历所有图片\n const allPromise: Promise<void>[] = []\n willUpdate &&\n willUpdate.forEach((imgs, cellIndex) => {\n imgs &&\n imgs.forEach((imgInfo, imgIndex) => {\n allPromise.push(\n this.loadAndCacheImg(imgName, cellIndex, imgIndex),\n )\n })\n })\n Promise.all(allPromise).then(() => {\n this.drawOffscreenCanvas()\n this.draw()\n resolve()\n })\n },\n )\n })\n }\n\n /**\n * 根据索引单独加载指定图片并缓存\n * @param cellName 模块名称\n * @param cellIndex 模块索引\n * @param imgName 模块对应的图片缓存\n * @param imgIndex 图片索引\n */\n private async loadAndCacheImg(\n cellName: 'blocks' | 'prizes',\n cellIndex: number,\n imgIndex: number,\n ): Promise<void> {\n return new Promise((resolve, reject) => {\n let cell: BlockType | PrizeType = this[cellName][cellIndex]\n if (!cell || !cell.imgs) return\n const imgInfo = cell.imgs[imgIndex]\n if (!imgInfo) return\n // 异步加载图片\n this.loadImg(imgInfo.src, imgInfo)\n .then(async (currImg) => {\n if (typeof imgInfo.formatter === 'function') {\n currImg = await Promise.resolve(\n imgInfo.formatter.call(this, currImg),\n )\n }\n this.ImageCache.set(imgInfo['src'], currImg)\n resolve()\n })\n .catch((err) => {\n console.error(`${cellName}[${cellIndex}].imgs[${imgIndex}] ${err}`)\n reject()\n })\n })\n }\n\n /**\n * 绘制离屏canvas\n */\n protected drawOffscreenCanvas(): void {\n const { _defaultConfig, _defaultStyle } = this\n const { w, h } = this.drawBlocks()!\n // 计算单一奖品格子的宽度和高度\n const prizesLen = this.prizes.length\n const { cellWidth, cellHeight, widthAndSpacing, heightAndSpacing } =\n this.displacementWidthOrHeight()\n this.defaultOrder = new Array(prizesLen).fill(void 0).map((v, i) => i)\n let maxOrderLen = 0,\n maxOffWidth = 0,\n maxOffHeight = 0\n this.slots.forEach((slot, slotIndex) => {\n // 初始化 scroll 的值\n if (this.scroll[slotIndex] === void 0) this.scroll[slotIndex] = 0\n // 如果没有order属性, 就填充prizes\n const order = slot.order || this.defaultOrder\n // 计算最大值\n const currLen = order.length\n maxOrderLen = Math.max(maxOrderLen, currLen)\n maxOffWidth = Math.max(maxOffWidth, w + widthAndSpacing * currLen)\n maxOffHeight = Math.max(maxOffHeight, h + heightAndSpacing * currLen)\n })\n // 创建一个离屏Canvas来存储画布的内容\n const { _offscreenCanvas, _ctx } = this.getOffscreenCanvas(\n maxOffWidth,\n maxOffHeight,\n )!\n this._offscreenCanvas = _offscreenCanvas\n // 绘制插槽\n this.slots.forEach((slot, slotIndex) => {\n const cellX = cellWidth * slotIndex\n const cellY = cellHeight * slotIndex\n let lengthOfCopy = 0\n // 绘制奖品\n const newPrizes = getSortedArrayByIndex(\n this.prizes,\n slot.order || this.defaultOrder,\n )\n // 如果没有奖品则打断逻辑\n if (!newPrizes.length) return\n newPrizes.forEach((cell, cellIndex) => {\n if (!cell) return\n const prizesX =\n widthAndSpacing * cellIndex + _defaultConfig.colSpacing / 2\n const prizesY =\n heightAndSpacing * cellIndex + _defaultConfig.rowSpacing / 2\n const [_x, _y, spacing] = this.displacement(\n [cellX, prizesY, heightAndSpacing],\n [prizesX, cellY, widthAndSpacing],\n )\n lengthOfCopy += spacing\n // 绘制背景\n const background = cell.background || _defaultStyle.background\n if (hasBackground(background)) {\n const borderRadius = this.getLength(\n has(cell, 'borderRadius')\n ? cell.borderRadius\n : _defaultStyle.borderRadius,\n )\n roundRectByArc(_ctx, _x, _y, cellWidth, cellWidth, borderRadius)\n _ctx.fillStyle = background\n _ctx.fill()\n }\n // 绘制图片\n cell.imgs &&\n cell.imgs.forEach((imgInfo, imgIndex) => {\n const cellImg = this.ImageCache.get(imgInfo.src)\n if (!cellImg) return\n const [trueWidth, trueHeight] = this.computedWidthAndHeight(\n cellImg,\n imgInfo,\n cellWidth,\n cellHeight,\n )\n const [xAxis, yAxis] = [\n _x +\n this.getOffsetX(trueWidth, cellWidth) +\n this.getLength(imgInfo.left, cellWidth),\n _y + this.getLength(imgInfo.top, cellHeight),\n ]\n this.drawImage(_ctx, cellImg, xAxis, yAxis, trueWidth, trueHeight)\n })\n // 绘制文字\n cell.fonts &&\n cell.fonts.forEach((font) => {\n // 字体样式\n const style = font.fontStyle || _defaultStyle.fontStyle\n // 字体加粗\n const fontWeight = font.fontWeight || _defaultStyle.fontWeight\n // 字体大小\n const size = this.getLength(font.fontSize || _defaultStyle.fontSize)\n // 字体行高\n const lineHeight =\n font.lineHeight ||\n _defaultStyle.lineHeight ||\n font.fontSize ||\n _defaultStyle.fontSize\n const wordWrap = has(font, 'wordWrap')\n ? font.wordWrap\n : _defaultStyle.wordWrap\n const lengthLimit = font.lengthLimit || _defaultStyle.lengthLimit\n const lineClamp = font.lineClamp || _defaultStyle.lineClamp\n _ctx.font = `${fontWeight} ${size >> 0}px ${style}`\n _ctx.fillStyle = font.fontColor || _defaultStyle.fontColor\n let lines = [],\n text = String(font.text)\n // 计算文字换行\n if (wordWrap) {\n // 最大宽度\n let maxWidth = this.getLength(lengthLimit, cellWidth)\n lines = splitText(\n _ctx,\n removeEnter(text),\n () => maxWidth,\n lineClamp,\n )\n } else {\n lines = text.split('\\n')\n }\n lines.forEach((line, lineIndex) => {\n _ctx.fillText(\n line,\n _x +\n this.getOffsetX(_ctx.measureText(line).width, cellWidth) +\n this.getLength(font.left, cellWidth),\n _y +\n this.getLength(font.top, cellHeight) +\n (lineIndex + 1) * this.getLength(lineHeight),\n )\n })\n })\n })\n const [_x, _y, _w, _h] = this.displacement(\n [cellX, 0, cellWidth, lengthOfCopy],\n [0, cellY, lengthOfCopy, cellHeight],\n )\n let drawLen = lengthOfCopy\n while (drawLen < maxOffHeight + lengthOfCopy) {\n const [drawX, drawY] = this.displacement([_x, drawLen], [drawLen, _y])\n this.drawImage(\n _ctx,\n _offscreenCanvas,\n _x,\n _y,\n _w,\n _h,\n drawX,\n drawY,\n _w,\n _h,\n )\n drawLen += lengthOfCopy\n }\n })\n }\n\n /**\n * 绘制背景区域\n */\n protected drawBlocks(): SlotMachine['prizeArea'] {\n const { config, ctx, _defaultConfig, _defaultStyle } = this\n // 绘制背景区域, 并计算奖品区域\n return (this.prizeArea = this.blocks.reduce(\n ({ x, y, w, h }, block, blockIndex) => {\n const [paddingTop, paddingBottom, paddingLeft, paddingRight] =\n computePadding(block, this.getLength.bind(this))\n const r = block.borderRadius ? this.getLength(block.borderRadius) : 0\n // 绘制边框\n const background = block.background || _defaultStyle.background\n if (hasBackground(background)) {\n roundRectByArc(ctx, x, y, w, h, r)\n ctx.fillStyle = background\n ctx.fill()\n }\n // 绘制图片\n block.imgs &&\n block.imgs.forEach((imgInfo, imgIndex) => {\n const blockImg = this.ImageCache.get(imgInfo.src)\n if (!blockImg) return\n // 绘制图片\n const [trueWidth, trueHeight] = this.computedWidthAndHeight(\n blockImg,\n imgInfo,\n w,\n h,\n )\n const [xAxis, yAxis] = [\n this.getOffsetX(trueWidth, w) + this.getLength(imgInfo.left, w),\n this.getLength(imgInfo.top, h),\n ]\n this.drawImage(\n ctx,\n blockImg,\n x + xAxis,\n y + yAxis,\n trueWidth,\n trueHeight,\n )\n })\n return {\n x: x + paddingLeft,\n y: y + paddingTop,\n w: w - paddingLeft - paddingRight,\n h: h - paddingTop - paddingBottom,\n }\n },\n { x: 0, y: 0, w: this.boxWidth, h: this.boxHeight },\n ))\n }\n\n /**\n * 绘制老虎机抽奖\n */\n protected draw(): void {\n const { config, ctx, _defaultConfig, _defaultStyle } = this\n // 触发绘制前回调\n config.beforeDraw?.call(this, ctx)\n // 清空画布\n ctx.clearRect(0, 0, this.boxWidth, this.boxHeight)\n // 绘制背景\n const { x, y, w, h } = this.drawBlocks()!\n // 绘制插槽\n if (!this._offscreenCanvas) return\n const {\n cellWidth,\n cellHeight,\n cellAndSpacing,\n widthAndSpacing,\n heightAndSpacing,\n } = this\n this.slots.forEach((slot, slotIndex) => {\n const order = slot.order || this.defaultOrder\n // 绘制临界点\n const _p = cellAndSpacing * order.length\n // 调整奖品垂直居中\n const start = this.displacement(\n -(h - heightAndSpacing) / 2,\n -(w - widthAndSpacing) / 2,\n )\n let scroll = this.scroll[slotIndex] + start\n // scroll 会无限累加 1 / -1\n if (scroll < 0) {\n scroll = (scroll % _p) + _p\n }\n if (scroll > _p) {\n scroll = scroll % _p\n }\n const [sx, sy, sw, sh] = this.displacement(\n [cellWidth * slotIndex, scroll, cellWidth, h],\n [scroll, cellHeight * slotIndex, w, cellHeight],\n )\n const [dx, dy, dw, dh] = this.displacement(\n [x + widthAndSpacing * slotIndex, y, cellWidth, h],\n [x, y + heightAndSpacing * slotIndex, w, cellHeight],\n )\n this.drawImage(\n ctx,\n this._offscreenCanvas!,\n sx,\n sy,\n sw,\n sh,\n dx,\n dy,\n dw,\n dh,\n )\n })\n }\n\n /**\n * 刻舟求剑\n */\n private carveOnGunwaleOfAMovingBoat(slotIndex: number): void {\n const { _defaultConfig, prizeFlag, cellAndSpacing } = this\n const slot = this.slots[slotIndex]\n const order = slot.order || this.defaultOrder\n if (!order.length || prizeFlag === void 0) return\n const speed = Math.abs(slot.speed || _defaultConfig.speed)\n const direction = slot.direction || _defaultConfig.direction\n const orderIndex = order.findIndex(\n (prizeIndex) => prizeIndex === prizeFlag[slotIndex],\n )\n const _p = cellAndSpacing * order.length\n const stopScroll = (this.stopScroll[slotIndex] = this.scroll[slotIndex])\n this.endTime[slotIndex] = Date.now()\n let i = 0\n while (++i) {\n const endScroll =\n cellAndSpacing * orderIndex + _p * i * direction - stopScroll\n const currSpeed =\n quad.easeOut(\n this.FPS,\n stopScroll,\n endScroll,\n _defaultConfig.decelerationTime,\n ) - stopScroll\n if (Math.abs(currSpeed) > speed) {\n this.endScroll[slotIndex] = endScroll\n break\n }\n }\n }\n\n private hasAllPrizeFlag(): boolean {\n return !!this.prizeFlag?.length && this.prizeFlag.every((flag) => flag !== void 0)\n }\n\n private isAllSlotStopped(): boolean {\n return this.slots.every((slot, slotIndex) => {\n const order = slot.order || this.defaultOrder\n return !order.length || this.slotStep[slotIndex] === 0\n })\n }\n\n private getEndPrize(): PrizeType | undefined {\n if (!this.hasAllPrizeFlag()) return void 0\n const prizeFlag = this.prizeFlag as number[]\n let flag = prizeFlag[0]\n for (let i = 0; i < this.slots.length; i++) {\n const slot = this.slots[i]\n const currFlag = prizeFlag[i]\n const order = slot.order || this.defaultOrder\n if (!order?.includes(currFlag) || flag !== currFlag) {\n flag = -1\n break\n }\n }\n return this.prizes.find((prize, index) => index === flag) || void 0\n }\n\n /**\n * 对外暴露: 开始抽奖方法\n */\n public play(): void {\n if (this.step !== 0) return\n // 记录开始游戏的时间\n this.startTime = Date.now()\n // 清空中奖索引\n this.prizeFlag = void 0\n this.stopScroll = []\n this.endScroll = []\n this.endTime = []\n this.slotStep = this.slots.map((slot) => {\n const order = slot.order || this.defaultOrder\n return order.length ? 1 : 0\n })\n // 开始加速\n this.step = 1\n // 触发回调\n this.config.afterStart?.()\n // 开始渲染\n this.run()\n }\n\n public stop(index: number | number[], slotIndex?: number): void {\n if (this.step === 0) return\n // 设置中奖索引\n if (typeof slotIndex === 'number') {\n if (!Number.isInteger(slotIndex) || slotIndex < 0 || slotIndex >= this.slots.length) {\n return console.error(`stop(${index}, ${slotIndex}) slotIndex 超出范围`)\n }\n if (typeof index !== 'number') {\n return console.error(`stop(${JSON.stringify(index)}, ${slotIndex}) 参数类型不正确`)\n }\n if (this.prizeFlag === void 0 || !this.prizeFlag.length) {\n this.prizeFlag = new Array(this.slots.length).fill(void 0)\n }\n this.prizeFlag[slotIndex] = index\n } else if (typeof index === 'number') {\n this.prizeFlag = new Array(this.slots.length).fill(index)\n } else if (isExpectType(index, 'array')) {\n if (index.length === this.slots.length) {\n this.prizeFlag = index\n } else {\n this.stop(-1)\n return console.error(`stop([${index}]) 参数长度的不正确`)\n }\n } else {\n this.stop(-1)\n return console.error(`stop() 无法识别的参数类型 ${typeof index}`)\n }\n // 如果包含负数则停止游戏, 反之则继续游戏\n if (this.prizeFlag?.includes(-1)) {\n this.prizeFlag = []\n this.slotStep = this.slotStep.map(() => 0)\n // 停止游戏\n this.step = 0\n } else {\n // 进入匀速\n this.step = 2\n }\n }\n\n /**\n * 让游戏动起来\n * @param num 记录帧动画执行多少次\n */\n private run(num: number = 0): void {\n const { rAF, _defaultConfig, cellAndSpacing, slots } = this\n const { accelerationTime, decelerationTime } = _defaultConfig\n const prizeFlag = this.prizeFlag\n if (this.step === 0) {\n if (this.hasAllPrizeFlag() && this.isAllSlotStopped()) {\n this.endCallback?.(this.getEndPrize())\n }\n return\n }\n // 如果长度为 0 就直接停止游戏\n if (prizeFlag !== void 0 && !prizeFlag.length) return\n // 计算时间间隔\n const startInterval = Date.now() - this.startTime\n if (startInterval >= accelerationTime && this.step === 1) {\n this.step = 2\n }\n // 分别计算对应插槽的加速度\n slots.forEach((slot, slotIndex) => {\n const order = slot.order || this.defaultOrder\n if (!order || !order.length) return\n const _p = cellAndSpacing * order.length\n const speed = Math.abs(slot.speed || _defaultConfig.speed)\n const direction = slot.direction || _defaultConfig.direction\n const slotStep = this.slotStep[slotIndex] || 0\n let scroll = 0,\n prevScroll = this.scroll[slotIndex]\n if (!slotStep) return\n if (slotStep === 1 || startInterval < accelerationTime) {\n // 加速阶段\n // 记录帧率\n this.FPS = startInterval / num\n const currSpeed = quad.easeIn(startInterval, 0, speed, accelerationTime)\n // 加速到最大速度后, 即可进入匀速阶段\n if (currSpeed === speed) {\n this.slotStep[slotIndex] = 2\n }\n scroll = (prevScroll + currSpeed * direction) % _p\n } else if (slotStep === 2) {\n // 匀速阶段\n // 速度保持不变\n scroll = (prevScroll + speed * direction) % _p\n // 当前列已经拿到中奖索引, 则单独进入减速阶段\n if (prizeFlag?.[slotIndex] !== void 0) {\n this.slotStep[slotIndex] = 3\n this.scroll[slotIndex] = scroll\n this.carveOnGunwaleOfAMovingBoat(slotIndex)\n }\n } else if (slotStep === 3) {\n // 减速阶段\n // 开始缓慢停止\n const stopScroll = this.stopScroll[slotIndex]\n const endScroll = this.endScroll[slotIndex]\n const endInterval = Date.now() - this.endTime[slotIndex]\n scroll = quad.easeOut(\n endInterval,\n stopScroll,\n endScroll,\n decelerationTime,\n )\n if (endInterval >= decelerationTime) {\n scroll = stopScroll + endScroll\n this.slotStep[slotIndex] = 0\n }\n }\n this.scroll[slotIndex] = scroll\n })\n this.draw()\n if (this.isAllSlotStopped()) {\n this.step = 0\n if (this.hasAllPrizeFlag()) {\n this.endCallback?.(this.getEndPrize())\n }\n return\n }\n rAF(this.run.bind(this, num + 1))\n }\n\n // 根据mode置换数值\n private displacement<T>(a: T, b: T): T {\n return this._defaultConfig.mode === 'horizontal' ? b : a\n }\n\n // 根据mode计算宽高\n private displacementWidthOrHeight() {\n const mode = this._defaultConfig.mode\n const slotsLen = this.slots.length\n const { colSpacing, rowSpacing } = this._defaultConfig\n const { x, y, w, h } = this.prizeArea || this.drawBlocks()!\n let cellWidth = 0,\n cellHeight = 0,\n widthAndSpacing = 0,\n heightAndSpacing = 0\n if (mode === 'horizontal') {\n cellHeight = this.cellHeight =\n (h - rowSpacing * (slotsLen - 1)) / slotsLen\n cellWidth = this.cellWidth = cellHeight\n } else {\n cellWidth = this.cellWidth = (w - colSpacing * (slotsLen - 1)) / slotsLen\n cellHeight = this.cellHeight = cellWidth\n }\n widthAndSpacing = this.widthAndSpacing = this.cellWidth + colSpacing\n heightAndSpacing = this.heightAndSpacing = this.cellHeight + rowSpacing\n if (mode === 'horizontal') {\n this.cellAndSpacing = widthAndSpacing\n } else {\n this.cellAndSpacing = heightAndSpacing\n }\n return {\n cellWidth,\n cellHeight,\n widthAndSpacing,\n heightAndSpacing,\n }\n }\n}\n","import { ImgType } from '../types/index'\nimport { roundRectByArc } from './math'\n\n/**\n * 根据路径获取图片对象\n * @param { string } src 图片路径\n * @returns { Promise<HTMLImageElement> } 图片标签\n */\nexport const getImage = (src: string): Promise<ImgType> => {\n return new Promise((resolve, reject) => {\n const img = new Image()\n img.onload = () => resolve(img)\n img.onerror = err => reject(err)\n img.src = src\n })\n}\n\n/**\n * 切割圆角\n * @param img 将要裁剪的图片对象\n * @param radius 裁剪的圆角半径\n * @returns 返回一个离屏 canvas 用于渲染\n */\nexport const cutRound = (img: ImgType, radius: number): ImgType => {\n const canvas = document.createElement('canvas')\n const ctx = canvas.getContext('2d')!\n const { width, height } = img\n canvas.width = width\n canvas.height = height\n roundRectByArc(ctx, 0, 0, width, height, radius)\n ctx.clip()\n ctx.drawImage(img, 0, 0, width, height)\n return canvas\n}\n\n/**\n * 透明度\n * @param img 将要处理的图片对象\n * @param opacity 透明度\n * @returns 返回一个离屏 canvas 用于渲染\n */\nexport const opacity = (\n img: ImgType,\n opacity: number\n): ImgType => {\n const canvas = document.createElement('canvas')\n const ctx = canvas.getContext('2d')!\n const { width, height } = img\n canvas.width = width\n canvas.height = height\n // 绘制图片, 部分浏览器不支持 filter 属性, 需要处理兼容\n if (typeof ctx.filter === 'string') {\n ctx.filter = `opacity(${opacity * 100}%)`\n ctx.drawImage(img, 0, 0, width, height)\n } else {\n ctx.drawImage(img, 0, 0, width, height)\n const imageData = ctx.getImageData(0, 0, width, height)\n const { data } = imageData\n const len = data.length\n for (let i = 0; i < len; i += 4) {\n const alpha = data[i + 3]\n if (alpha !== 0) data[i + 3] = alpha * opacity\n }\n ctx.putImageData(imageData, 0, 0)\n }\n return canvas\n}\n\n/**\n * 权重矩阵\n * @param radius 模糊半径\n * @param sigma \n * @returns 返回一个权重和为1的矩阵\n */\nconst getMatrix = (radius: number, sigma?: number): number[] => {\n sigma = sigma || radius / 3\n const r = Math.ceil(radius)\n const sigma_2 = sigma * sigma\n const sigma2_2 = 2 * sigma_2\n const denominator = 1 / (2 * Math.PI * sigma_2)\n const matrix = []\n let total = 0\n // 计算权重矩阵\n for (let x = -r; x <= r; x++) {\n for (let y = -r; y <= r; y++) {\n // 套用二维高斯函数得到每个点的权重\n const res = denominator * Math.exp(-(x * x + y * y) / sigma2_2)\n matrix.push(res)\n total += res\n }\n }\n // 让矩阵中所有权重的和等于1\n for (let i = 0; i < matrix.length; i++) {\n matrix[i] /= total\n }\n return matrix\n}\n\n/**\n * 高斯模糊\n * @param img 将要处理的图片对象\n * @param radius 模糊半径\n * @returns 返回一个离屏 canvas 用于渲染\n */\nexport const blur = (\n img: ImgType,\n radius: number\n): ImgType => {\n const canvas = document.createElement('canvas')\n const ctx = canvas.getContext('2d')!\n const { width, height } = img\n // 设置图片宽高\n canvas.width = width\n canvas.height = height\n ctx.drawImage(img, 0, 0, width, height)\n const ImageData = ctx.getImageData(0, 0, width, height)\n const { data } = ImageData\n const matrix = getMatrix(radius)\n const r = Math.ceil(radius)\n const w = width * 4\n const cols = r * 2 + 1\n const len = data.length, matrixLen = matrix.length\n for (let i = 0; i < len; i += 4) {\n // 处理\n }\n console.log(ImageData)\n ctx.putImageData(ImageData, 0, 0)\n return canvas\n}\n\nexport const getBase64Image = () => {\n\n}\n"],"names":["Array","prototype","includes","Object","defineProperty","value","valueToFind","fromIndex","this","TypeError","o","len","length","n","k","Math","max","abs","sameValueZero","x","y","isNaN","String","search","start","indexOf","find","predicate","thisArg","arguments","kValue","call","isExpectType","param","types","some","type","toString","slice","toLowerCase","has","data","key","hasOwnProperty","removeEnter","str","filter","s","join","hasBackground","color","toLocaleLowerCase","trim","test","alpha","exec","num","NaN","Number","computePadding","block","getLength","_a","padding","split","map","paddingTop","paddingBottom","paddingLeft","paddingRight","res","throttle","fn","wait","timeId","args","setTimeout","apply","clearTimeout","computeRange","rangeArr","ascendingArr","sum","reduce","prev","curr","push","random","findIndex","splitText","ctx","text","getWidth","lineClamp","Infinity","lines","EndWidth","measureText","width","i","currWidth","maxWidth","Dep","constructor","__publicField","subs","addSub","sub","notify","forEach","update","hasProto","def","obj","val","enumerable","writable","configurable","oldArrayProto","newArrayProto","create","method","luckyOb","walk","dep","Observer","isArray","getOwnPropertyNames","keys","defineReactive","observe","property","getOwnPropertyDescriptor","getter","get","setter","set","childOb","target","newVal","uid","Watcher","$lucky","expr","cb","options","id","deep","path","segments","segment","parsePath","dfs","traverse","oldVal","Lucky","config","version","el","nodeType","divElement","flag","document","querySelector","canvasElement","createElement","appendChild","getContext","setAttribute","addEventListener","handleClick","e","initWindowFunction","console","error","window","resize","MutationObserver","documentElement","attributes","_b","beforeResize","setHTMLFontSize","setDpr","resetWidthAndHeight","zoomCanvas","initLucky","boxWidth","boxHeight","getComputedStyle","htmlFontSize","fontSize","clearCanvas","height","clearRect","dpr","devicePixelRatio","offsetWidth","offsetHeight","style","overflow","transform","scale","rAF","requestAnimationFrame","callback","setInterval","clearInterval","timeout","isWeb","loadImg","src","info","resolveName","Promise","resolve","reject","imgObj","Image","onload","onerror","drawImage","rectInfo","drawImg","miniProgramOffCtx","temp","getImageData","putImageData","index","err","computedWidthAndHeight","imgInfo","maxHeight","trueWidth","trueHeight","changeUnits","denominator","replace","unit","handleCssUnit","px","rem","vw","innerWidth","otherHandleCssUnit","maxLength","getOffsetX","getOffscreenCanvas","_offscreenCanvas","_ctx","$set","$computed","$watch","handler","watchOpt","watcher","immediate","getAngle","deg","PI","fanShapedByArc","minRadius","maxRadius","end","gutter","beginPath","maxGutter","maxStart","maxEnd","r","arc","lineTo","sin","cos","toFixed","closePath","roundRectByArc","w","h","min","moveTo","quad","t","b","c","d","LuckyWheel","super","Map","initData","initWatch","initComputed","beforeCreate","init","Radius","translate","draw","afterResize","prizeRadius","prizeDeg","prizeAng","rotateDeg","maxBtnRadius","startTime","endTime","stopDeg","endDeg","FPS","prizeFlag","step","blocks","prizes","buttons","defaultConfig","defaultStyle","__spreadValues","offsetDegree","speed","speedFunction","accelerationTime","decelerationTime","stopRange","fontColor","fontStyle","fontWeight","background","wordWrap","lengthLimit","newData","initImageCache","__async","beforeInit","afterInit","willUpdateImgs","imgs","prize","btn","imgName","willUpdate","allPromise","cellIndex","imgIndex","loadAndCacheImg","all","then","isPointInPath","offsetX","offsetY","startCallback","cellName","cell","currImg","formatter","ImageCache","catch","drawBlock","radius","blockIndex","fillStyle","fill","blockImg","xAxis","yAxis","left","top","save","rotate","restore","_defaultConfig","_defaultStyle","beforeDraw","shortSide","getFontX","font","line","getFontY","lineIndex","lineHeight","prizeIndex","currMiddleDeg","prizeHeight","prizeImg","fonts","tan","fillText","btnIndex","pointer","btnImg","afterDraw","carveOnGunwaleOfAMovingBoat","Date","now","prevSpeed","prevDeg","currSpeed","play","afterStart","run","stop","item","range","endCallback","startInterval","endInterval","bind","conversionAxis","LuckyGrid","cellWidth","cellHeight","currIndex","stopIndex","endIndex","demo","timer","rows","cols","button","activeStyle","borderRadius","shadow","btnImgs","getGeometricProperty","col","row","rect","request","_0","defaultImg","activeImg","_activeStyle","cells","prizeArea","handleBackground","isActive","shadowColor","shadowOffsetX","shadowOffsetY","shadowBlur","cellImg","renderImg","size","context","shift","direction","getLenOfTanDeg","gradient","createLinearGradient","addColorStop","getLinearGradient","prevIndex","SlotMachine","redrawOffscreenCanvas","cellAndSpacing","widthAndSpacing","heightAndSpacing","scroll","stopScroll","endScroll","slotStep","slots","mode","rowSpacing","colSpacing","drawOffscreenCanvas","drawBlocks","prizesLen","displacementWidthOrHeight","defaultOrder","v","maxOffWidth","maxOffHeight","slot","slotIndex","currLen","order","cellX","cellY","lengthOfCopy","newPrizes","arr","getSortedArrayByIndex","prizesX","prizesY","_x","_y","spacing","displacement","_w","_h","drawLen","drawX","drawY","_p","sx","sy","sw","sh","dx","dy","dw","dh","orderIndex","hasAllPrizeFlag","every","isAllSlotStopped","getEndPrize","currFlag","isInteger","JSON","stringify","prevScroll","a","slotsLen","cutRound","img","canvas","clip","opacity","imageData"],"mappings":"AAKKA,MAAMC,UAAUC,UACZC,OAAAC,eAAeJ,MAAMC,UAAW,WAAY,CACjDI,MAAO,SAASC,EAAaC,GAE3B,GAAY,MAARC,KACI,MAAA,IAAIC,UAAU,iCAIlB,IAAAC,EAAIP,OAAOK,MAGXG,EAAMD,EAAEE,SAAW,EAGvB,GAAY,IAARD,EACK,OAAA,EAKT,IAAIE,EAAgB,EAAZN,EAOJO,EAAIC,KAAKC,IAAIH,GAAK,EAAIA,EAAIF,EAAMI,KAAKE,IAAIJ,GAAI,GAExC,SAAAK,EAAcC,EAAGC,GACxB,OAAOD,IAAMC,GAAmB,iBAAND,GAA+B,iBAANC,GAAkBC,MAAMF,IAAME,MAAMD,EACzF,CAGA,KAAON,EAAIH,GAAK,CAGd,GAAIO,EAAcR,EAAEI,GAAIR,GACf,OAAA,EAGTQ,GACF,CAGO,OAAA,CACT,IAKCQ,OAAOrB,UAAUC,WACpBoB,OAAOrB,UAAUC,SAAW,SAASqB,EAAQC,GAK3C,MAHqB,iBAAVA,IACDA,EAAA,KAENA,EAAQD,EAAOX,OAASJ,KAAKI,UAGQ,IAAhCJ,KAAKiB,QAAQF,EAAQC,KAM7BxB,MAAMC,UAAUyB,MACZvB,OAAAC,eAAeJ,MAAMC,UAAW,OAAQ,CAC7CI,MAAO,SAASsB,GAEd,GAAY,MAARnB,KACI,MAAA,IAAIC,UAAU,iCAElB,IAAAC,EAAIP,OAAOK,MAEXG,EAAMD,EAAEE,SAAW,EAEnB,GAAqB,mBAAde,EACH,MAAA,IAAIlB,UAAU,gCAOtB,IAJI,IAAAmB,EAAUC,UAAU,GAEpBf,EAAI,EAEDA,EAAIH,GAAK,CAKV,IAAAmB,EAASpB,EAAEI,GACf,GAAIa,EAAUI,KAAKH,EAASE,EAAQhB,EAAGJ,GAC9B,OAAAoB,EAGThB,GACF,CAGF,ICnGS,MAAAkB,EAAe,CAACC,KAAmBC,IACvCA,EAAMC,KAAaC,GAAAjC,OAAOF,UAAUoC,SAASN,KAAKE,GAAOK,MAAM,GAAG,GAAIC,gBAAkBH,GAapFI,EAAM,CAACC,EAAcC,IACzBvC,OAAOF,UAAU0C,eAAeZ,KAAKU,EAAMC,GAQvCE,EAAeC,GACnB,GAAGC,OAAOf,KAAKc,KAAgB,OAANE,GAAYC,KAAK,IAwBtCC,EAAiBC,IACxB,GAAiB,iBAAVA,EAA2B,OAAA,EAElC,GAAU,iBADNA,EAAAA,EAAMC,oBAAoBC,QACE,OAAA,EAChC,GAAA,QAAQC,KAAKH,GAAQ,CACjB,MAAAI,EAAQ,eAAeC,KAAKL,GAClC,GAAyB,KAtBf,QADYM,EAuBRF,GAtBS,EACN,iBAARE,EAAyBC,IACjB,iBAARD,EAAyBA,EACjB,iBAARA,EACmB,MAAxBA,EAAIA,EAAI5C,OAAS,GACZ8C,OAAOF,EAAIlB,MAAM,GAAG,IAAO,IAE7BoB,OAAOF,GAETC,KAa8B,OAAA,CACrC,CAxBuB,IAACD,EAyBjB,OAAA,GAOIG,EAAiB,CAC5BC,EACAC,KAvEF,IAAAC,EAyEM,IAAAC,GAAU,OAAAD,IAAMC,cAAN,EAAAD,EAAeE,MAAM,KAAKC,OAASJ,EAAUhD,MAAO,CAAC,GACjEqD,EAAa,EACbC,EAAgB,EAChBC,EAAc,EACdC,EAAe,EACjB,OAAQN,EAAQnD,QACd,KAAK,EACHsD,EAAaC,EAAgBC,EAAcC,EAAeN,EAAQ,GAClE,MACF,KAAK,EACUG,EAAAC,EAAgBJ,EAAQ,GACvBK,EAAAC,EAAeN,EAAQ,GACrC,MACF,KAAK,EACHG,EAAaH,EAAQ,GACPK,EAAAC,EAAeN,EAAQ,GACrCI,EAAgBJ,EAAQ,GACxB,MACF,QACEG,EAAaH,EAAQ,GACrBI,EAAgBJ,EAAQ,GACxBK,EAAcL,EAAQ,GACtBM,EAAeN,EAAQ,GAG3B,MAAMO,EAAM,CAAEJ,aAAYC,gBAAeC,cAAaC,gBACtD,IAAA,IAAS3B,KAAO4B,EAEdA,EAAI5B,GAAOF,EAAIoB,EAAOlB,IAAQV,EAAa4B,EAAMlB,GAAM,SAAU,UAC7DmB,EAAUD,EAAMlB,IAChB4B,EAAI5B,GAEV,MAAO,CAACwB,EAAYC,EAAeC,EAAaC,IASrCE,EAAW,CAACC,EAAcC,EAAO,OAC5C,IAAIC,EAAS,KACb,OAAO,YAAwBC,GACzBD,IACJA,EAASE,WAAW,KACfJ,EAAAK,MAAMrE,KAAMmE,GACfG,aAAaJ,GACJA,EAAA,MACRD,GAAI,GASEM,EAAgBC,IAC3B,MAAMC,EAAyB,GAEzBC,EAAMF,EAASf,IAAWT,GAAAE,OAAOF,IAAM2B,OAAO,CAACC,EAAMC,KACzD,GAAIA,EAAO,EAAG,CACZ,MAAMf,EAAMc,EAAOC,EAEZ,OADPJ,EAAaK,KAAKhB,GACXA,CAAA,CAGA,OADPW,EAAaK,KAAK7B,KACX2B,GAER,GACGG,EAASxE,KAAKwE,SAAWL,EAC/B,OAAOD,EAAaO,UAAiBhC,GAAA+B,GAAU/B,IASpCiC,EAAY,CACvBC,EACAC,EACAC,EACAC,EAAoBC,OAGhBD,GAAa,IAAeA,EAAAC,KAChC,IAAIjD,EAAM,GACV,MAAMkD,EAAQ,GACRC,EAAWN,EAAIO,YAAY,OAAOC,MACxC,IAAA,IAASC,EAAI,EAAGA,EAAIR,EAAK/E,OAAQuF,IAAK,CACpCtD,GAAO8C,EAAKQ,GACZ,IAAIC,EAAYV,EAAIO,YAAYpD,GAAKqD,MAC/B,MAAAG,EAAWT,EAASG,GAItB,GAFAF,IAAcE,EAAMnF,OAAS,IAAgBwF,GAAAJ,GAE7CK,EAAW,EAAU,OAAAN,EAOrB,GALAK,EAAYC,IACdN,EAAMT,KAAKzC,EAAIP,MAAM,OACrBO,EAAM8C,EAAKQ,IAGTN,IAAcE,EAAMnF,OAEf,OADDmF,EAAAA,EAAMnF,OAAS,IAAM,MACpBmF,CAEX,CAGO,OAFHlD,GAAWkD,EAAAT,KAAKzC,GACfkD,EAAMnF,QAAQmF,EAAMT,KAAKK,GACvBI,wKCxLT,MAAqBO,EAOnB,WAAAC,GALQC,EAAAhG,KAAA,QAMNA,KAAKiG,KAAO,EACd,CAMO,MAAAC,CAAQC,GAERnG,KAAKiG,KAAKvG,SAASyG,IACjBnG,KAAAiG,KAAKnB,KAAKqB,EAEnB,CAKO,MAAAC,GACApG,KAAAiG,KAAKI,QAAeF,IACvBA,EAAIG,UAER,EA5BAN,EADmBF,EACZ,UCAI,MAAAS,EAAW,aAAe,GAEhC,SAASC,EAAKC,EAAavE,EAAsBwE,EAAUC,GACzDhH,OAAAC,eAAe6G,EAAKvE,EAAK,CAC9BrC,MAAO6G,EACPC,aAAcA,EACdC,UAAU,EACVC,cAAc,GAElB,CCTA,MAAMC,EAAgBtH,MAAMC,UACtBsH,EAAgBpH,OAAOqH,OAAOF,GACpB,CAAC,OAAQ,MAAO,QAAS,UAAW,OAAQ,SAAU,WAC9DT,QAAkBY,IACVF,EAAAE,GAAU,YAAa9C,GACnC,MAAML,EAAMgD,EAAcG,GAAQ5C,MAAMrE,KAAMmE,GACxC+C,EAAUlH,KAAkB,YAG3B,MAFH,CAAC,OAAQ,UAAW,UAAUN,SAASuH,IAAiBC,EAAAC,KAAKnH,MACjEkH,EAAQE,IAAIhB,SACLtC,CAAA,8JCRX,MAAqBuD,EAQnB,WAAAtB,CAAalG,GAPbmG,EAAAhG,KAAA,SACAgG,EAAAhG,KAAA,OAQOA,KAAAoH,IAAM,IAAItB,EAEXU,EAAA3G,EAAO,cAAeG,MACtBR,MAAM8H,QAAQzH,KACZ0G,EACF1G,EAAiB,UAAIkH,EAErBpH,OAAO4H,oBAAoBR,GAAeV,QAAenE,IACvDsE,EAAI3G,EAAOqC,EAAK6E,EAAc7E,OAIpClC,KAAKmH,KAAKtH,EACZ,CAEA,IAAAsH,CAAMlF,GACJtC,OAAO6H,KAAKvF,GAAMoE,QAAenE,IAC/BuF,EAAexF,EAAMC,EAAKD,EAAKC,KAEnC,EAOK,SAASwF,EAASzF,GACvB,IAAKA,GAAwB,iBAATA,EAAmB,OACnC,IAAAiF,EAMG,OAJLA,EADE,gBAAiBjF,EACTA,EAAkB,YAElB,IAAIoF,EAASpF,GAElBiF,CACT,CAQgB,SAAAO,EAAgBxF,EAAWC,EAAsBwE,GACzD,MAAAU,EAAM,IAAItB,EACV6B,EAAWhI,OAAOiI,yBAAyB3F,EAAMC,GACnD,GAAAyF,IAAsC,IAA1BA,EAASd,aACvB,OAEI,MAAAgB,EAASF,GAAYA,EAASG,IAC9BC,EAASJ,GAAYA,EAASK,IAC9BH,IAAUE,GAAgC,IAArB1G,UAAUjB,SACnCsG,EAAMzE,EAAKC,IAET,IAAA+F,EAAUP,EAAQhB,GACf/G,OAAAC,eAAeqC,EAAMC,EAAK,CAC/B4F,IAAK,KACH,MAAMjI,EAAQgI,EAASA,EAAOtG,KAAKU,GAAQyE,EAOpC,OANHZ,EAAIoC,SACFd,EAAAlB,OAAOJ,EAAIoC,QACXD,GACMA,EAAAb,IAAIlB,OAAOJ,EAAIoC,SAGpBrI,GAETmI,IAAMG,IACAA,IAAWzB,IACTA,EAAAyB,EACFN,IAAWE,IACXA,EACKA,EAAAxG,KAAKU,EAAMkG,GAEZzB,EAAAyB,EAERF,EAAUP,EAAQS,GAClBf,EAAIhB,aAGV,2JCnFA,IAAIgC,EAAM,EACV,MAAqBC,EAenB,WAAAtC,CAAauC,EAAeC,EAAyBC,EAAcC,EAAwB,CAAA,GAd3FzC,EAAAhG,KAAA,MACAgG,EAAAhG,KAAA,UACAgG,EAAAhG,KAAA,QACAgG,EAAAhG,KAAA,MACAgG,EAAAhG,KAAA,QACAgG,EAAAhG,KAAA,UACAgG,EAAAhG,KAAA,SASEA,KAAK0I,GAAKN,IACVpI,KAAKsI,OAASA,EACdtI,KAAKuI,KAAOA,EACPvI,KAAA2I,OAASF,EAAQE,KAEpB3I,KAAK6H,OADa,mBAATU,EACKA,EHlBb,SAAoBK,GACjBA,GAAA,IACJ,IAAAC,EAAqB,GAAIC,EAAU,GACvC,IAAA,IAASnD,EAAI,EAAGA,EAAIiD,EAAKxI,OAAQuF,IAAK,CAChC,IAAAd,EAAO+D,EAAKjD,GACZ,GAAA,QAAQ9C,KAAKgC,GACfgE,EAAS/D,KAAKgE,GACJA,EAAA,OACD,IAAA,KAAKjG,KAAKgC,GACnB,SAEWiE,GAAAjE,CACb,CACF,CACA,OAAO,SAAU5C,GACf,OAAO4G,EAASlE,OAAO,CAAC1C,EAAMC,IACrBD,EAAKC,GACXD,EAAI,CAEX,CGCoB8G,CAAUR,GAE1BvI,KAAKwI,GAAKA,EACLxI,KAAAH,MAAQG,KAAK8H,KACpB,CAKA,GAAAA,GACEhC,EAAIoC,OAASlI,KACb,MAAMH,EAAQG,KAAK6H,OAAOtG,KAAKvB,KAAKsI,OAAQtI,KAAKsI,QAM1C,OAJHtI,KAAK2I,MHZN,SAAmB9I,GAElB,MAAAmJ,EAAO/G,IACNT,EAAaS,EAAM,QAAS,WACjCtC,OAAO6H,KAAKvF,GAAMoE,QAAenE,IACzBrC,MAAAA,EAAQoC,EAAKC,GACnB8G,EAAInJ,MAGRmJ,EAAInJ,EAEN,CGEMoJ,CAASpJ,GAEXiG,EAAIoC,OAAS,KACNrI,CACT,CAKA,MAAAyG,GAEQ,MAAA6B,EAASnI,KAAK8H,MAEdoB,EAASlJ,KAAKH,MACpBG,KAAKH,MAAQsI,EAEbnI,KAAKwI,GAAGjH,KAAKvB,KAAKsI,OAAQH,EAAQe,EACpC,4JC1DF,MAAqBC,EAkBnB,WAAApD,CACEqD,EACAnH,GAlBF+D,EAAAhG,KAAmB,UAAkBqJ,GAClBrD,EAAAhG,KAAA,UACAgG,EAAAhG,KAAA,OACnBgG,EAAAhG,KAAU,eAAuB,IACjCgG,EAAAhG,KAAU,MAAgB,WAAY,GACtCgG,EAAAhG,KAAU,WAAmB,GAC7BgG,EAAAhG,KAAU,YAAoB,GACpBgG,EAAAhG,KAAA,QAiBc,iBAAXoJ,EAA8BA,EAAA,CAAEE,GAAIF,GAClB,IAApBA,EAAOG,WAAgBH,EAAS,CAAEE,GAAI,GAAIE,WAAYJ,IAG/DpJ,KAAKoJ,OAASA,EACdpJ,KAAKiC,KAAOA,EAEPmH,EAAOK,OAAML,EAAOK,KAAO,OAC5BL,EAAOE,KAAIF,EAAOI,WAAaE,SAASC,cAAcP,EAAOE,KAE7DF,EAAOI,aAEFJ,EAAAQ,cAAgBF,SAASG,cAAc,UACvCT,EAAAI,WAAWM,YAAYV,EAAOQ,gBAGnCR,EAAOQ,gBACTR,EAAOlE,IAAMkE,EAAOQ,cAAcG,WAAW,MAE7CX,EAAOQ,cAAcI,aAAa,UAAW,2BAAWX,KACxDD,EAAOQ,cAAcK,iBAAiB,WAAcjK,KAAKkK,YAAYC,KAEvEnK,KAAKkF,IAAMkE,EAAOlE,IAElBlF,KAAKoK,qBAEApK,KAAKoJ,OAAOlE,KACfmF,QAAQC,MAAM,yBAGZC,QAA6C,mBAA5BA,OAAON,kBACnBM,OAAAN,iBAAiB,SAAUlG,EAAS,IAAM/D,KAAKwK,SAAU,MAG9DD,QAA6C,mBAA5BA,OAAOE,kBACtB,IAAAF,OAAOE,iBAAiB,KAC1BzK,KAAKwK,WACJ9C,QAAQgC,SAASgB,gBAAiB,CAAEC,YAAY,GAEvD,CAKU,MAAAH,GA7EZ,IAAAlH,EAAAsH,EA8EI,OAAAA,GAAAtH,EAAAtD,KAAKoJ,QAAOyB,eAAZD,EAAArJ,KAAA+B,GAEAtD,KAAK8K,kBAEL9K,KAAK+K,SAEL/K,KAAKgL,sBAELhL,KAAKiL,YACP,CAKU,SAAAC,GAER,GADAlL,KAAKwK,UACAxK,KAAKmL,WAAanL,KAAKoL,UACnB,OAAAf,QAAQC,MAAM,aAEzB,CAMU,WAAAJ,CAAaC,GAAsB,CAKnC,eAAAW,GACLP,QAAWA,OAAOc,mBAChBrL,KAAAsL,cAAgBf,OAAOc,iBAAiB3B,SAASgB,iBAAiBa,SAASzJ,MAAM,GAAK,GAC7F,CAGO,WAAA0J,GACC,MAAC9F,EAAO+F,GAAU,CAACzL,KAAKmL,SAAUnL,KAAKoL,WACxCpL,KAAAkF,IAAIwG,WAAWhG,GAAQ+F,EAAgB,EAAR/F,EAAoB,EAAT+F,EACjD,CAMU,MAAAV,GACF,MAAA3B,OAAEA,GAAWpJ,KACfoJ,EAAOuC,MAEApB,OACTA,OAAY,IAAInB,EAAOuC,IAAMpB,OAAOqB,kBAAoB,EAC9CxC,EAAOuC,KACTtB,QAAAC,MAAMlB,EAAQ,qBAE1B,CAKQ,mBAAA4B,GACA,MAAA5B,OAAEA,EAAQnH,KAAAA,GAASjC,KAErB,IAAAmL,EAAW,EAAGC,EAAY,EAC1BhC,EAAOI,aACT2B,EAAW/B,EAAOI,WAAWqC,YAC7BT,EAAYhC,EAAOI,WAAWsC,cAG3B9L,KAAAmL,SAAWnL,KAAKqD,UAAUpB,EAAKyD,OAAS0D,EAAc,QAAM+B,EAC5DnL,KAAAoL,UAAYpL,KAAKqD,UAAUpB,EAAKwJ,QAAUrC,EAAe,SAAMgC,EAEhEhC,EAAOI,aACFJ,EAAAI,WAAWuC,MAAMC,SAAW,SACnC5C,EAAOI,WAAWuC,MAAMrG,MAAQ1F,KAAKmL,SAAW,KAChD/B,EAAOI,WAAWuC,MAAMN,OAASzL,KAAKoL,UAAY,KAEtD,CAKU,UAAAH,GACF,MAAA7B,OAAEA,EAAQlE,IAAAA,GAAQlF,MAClB4J,cAAEA,EAAe+B,IAAAA,GAAQvC,GACxB1D,EAAO+F,GAAU,CAACzL,KAAKmL,SAAWQ,EAAK3L,KAAKoL,UAAYO,GAC1D/B,IACLA,EAAclE,MAAQA,EACtBkE,EAAc6B,OAASA,EACT7B,EAAAmC,MAAMrG,MAAQ,GAAGA,MACjBkE,EAAAmC,MAAMN,OAAS,GAAGA,MAClB7B,EAAAmC,MAAM,oBAAsB,WAC1CnC,EAAcmC,MAAME,UAAY,SAAS,EAAIN,KACzCzG,EAAAgH,MAAMP,EAAKA,GACjB,CAKQ,kBAAAvB,GACA,MAAAhB,OAAEA,GAAWpJ,KACnB,GAAIuK,OAWF,OAVKvK,KAAAmM,IAAM5B,OAAO6B,uBAChB7B,OAAoC,6BACpCA,OAAiC,0BACjC,SAAU8B,GACD9B,OAAAnG,WAAWiI,EAAU,IAAO,GAAE,EAEzCjD,EAAOhF,WAAamG,OAAOnG,WAC3BgF,EAAOkD,YAAc/B,OAAO+B,YAC5BlD,EAAO9E,aAAeiG,OAAOjG,kBAC7B8E,EAAOmD,cAAgBhC,OAAOgC,eAGhC,GAAInD,EAAO+C,IAETnM,KAAKmM,IAAM/C,EAAO+C,SACpB,GAAW/C,EAAOhF,WAAY,CAE5B,MAAMoI,EAAUpD,EAAOhF,WACvBpE,KAAKmM,IAAOE,GAA+BG,EAAQH,EAAU,KAAI,MAGjErM,KAAKmM,IAAOE,GAA+BjI,WAAWiI,EAAU,KAEpE,CAEO,KAAAI,GACE,MAAA,CAAC,MAAO,SAAU,WAAW/M,SAASM,KAAKoJ,OAAOK,KAC3D,CAOU,OAAAiD,CACRC,EACAC,EACAC,EAAc,YAEd,OAAO,IAAIC,QAAQ,CAACC,EAASC,KAEvB,GADCL,GAAKK,EAAO,OAAOJ,EAAKD,iBACJ,QAArB3M,KAAKoJ,OAAOK,KAUd,OAFAmD,EAAKC,GAAeE,OACpBH,EAAc,QAAII,GATY,CAC1B,IAAAC,EAAS,IAAIC,MACjBD,EAAoB,YAAI,YACjBA,EAAAE,OAAS,IAAMJ,EAAQE,GAC9BA,EAAOG,QAAU,IAAMJ,EAAO,OAAOJ,EAAKD,eAC1CM,EAAON,IAAMA,CAAA,GAQnB,CAOU,SAAAU,CACRnI,EACA+H,KACGK,GAnPP,IAAAhK,EAAAsH,EAqPQ,IAAA2C,EACJ,MAAM9D,KAAEA,EAAAkC,IAAMA,GAAQ3L,KAAKoJ,OAC3B,GAAI,CAAC,MAAO,SAAS1J,SAAS+J,GAElB8D,EAAAN,MACZ,KAAW,CAAC,SAAU,SAAU,UAAW,WAAWvN,SAAS+J,GAMtD,OAAAY,QAAQC,MAAM,wBAHrBiD,EAAWN,EAAwBrE,IAIrC,CACA,MAAM4E,EAAqB,OAAA5C,GAAQtH,EAAAiK,EAAQ,QAAKA,GAASxD,iBAAa,EAAAa,EAAArJ,KAAA+B,EAAA,MACtE,GAAIkK,IAAsBxN,KAAKyM,QAAS,CACtCa,EAAWA,EAAS7J,IAAWiD,GAAAA,EAAOiF,GAChC,MAAA8B,EAAOD,EAAkBE,gBAAgBJ,EAASxL,MAAM,EAAG,IACjEoD,EAAIyI,aAAaF,KAAUH,EAASxL,MAAM,EAAG,GAAuB,KAC/D,CACmB,IAApBwL,EAASlN,SACAkN,EAAAA,EAAS7J,IAAI,CAACiD,EAAKkH,IAAUA,EAAQ,EAAIlH,EAAOiF,EAAMjF,IAG/D,IACExB,EAAAmI,UAAUE,KAAYD,SACnBO,GAOT,CACF,CACF,CAUU,sBAAAC,CACRb,EACAc,EACAlI,EACAmI,GAGA,IAAKD,EAAQrI,QAAUqI,EAAQtC,OAE7B,MAAO,CAACwB,EAAOvH,MAAOuH,EAAOxB,QACpB,GAAAsC,EAAQrI,QAAUqI,EAAQtC,OAAQ,CAE3C,IAAIwC,EAAYjO,KAAKqD,UAAU0K,EAAQrI,MAAOG,GAE9C,MAAO,CAACoI,EAAWhB,EAAOxB,QAAUwC,EAAYhB,EAAOvH,OAC9C,CAAA,IAACqI,EAAQrI,OAASqI,EAAQtC,OAAQ,CAE3C,IAAIyC,EAAalO,KAAKqD,UAAU0K,EAAQtC,OAAQuC,GAEhD,MAAO,CAACf,EAAOvH,OAASwI,EAAajB,EAAOxB,QAASyC,EACvD,CAEO,MAAA,CACLlO,KAAKqD,UAAU0K,EAAQrI,MAAOG,GAC9B7F,KAAKqD,UAAU0K,EAAQtC,OAAQuC,GAEnC,CAQU,WAAAG,CAAatO,EAAeuO,EAAc,GAC5C,MAAAhF,OAAEA,GAAWpJ,KACnB,OAAOkD,OAAOrD,EAAMwO,QAAQ,2BAA4B,CAAC3H,EAAK1D,EAAKsL,KACjE,MAAMC,EAAgB,CACpB,IAAMlO,GAAcA,GAAK+N,EAAc,KACvCI,GAAOnO,GAAkB,EAAJA,EACrBoO,IAAQpO,GAAcA,EAAIL,KAAKsL,aAC/BoD,GAAOrO,GAAcA,EAAI,IAAMkK,OAAOoE,YACtCL,GACE,GAAAC,EAAsB,OAAAA,EAAcvL,GAExC,MAAM4L,EAAqBxF,EAAOmF,eAAiBnF,EAAiB,SACpE,OAAOwF,EAAqBA,EAAmB5L,EAAKsL,GAAQtL,IAEhE,CAQU,SAAAK,CAAWjD,EAAqCyO,GACxD,OAAIrN,EAAapB,EAAQ,UAAkBA,EACvCoB,EAAapB,EAAQ,UAAkBJ,KAAKmO,YAAY/N,EAAkByO,GACvE,CACT,CAOU,UAAAC,CAAYpJ,EAAeG,EAAmB,GACtD,OAAQA,EAAWH,GAAS,CAC9B,CAEU,kBAAAqJ,CAAoBrJ,EAAe+F,GAIvC,IAACzL,KAAuB,mBACtBuK,QAAUA,OAAOb,UAAiC,QAArB1J,KAAKoJ,OAAOK,KAC3CzJ,KAAuB,iBAAI0J,SAASG,cAAc,UAElD7J,KAAuB,iBAAIA,KAAKoJ,OAAwB,iBAErDpJ,KAAuB,kBAAU,OAAAqK,QAAQC,MAAM,mBAEhD,MAAAqB,EAAM3L,KAAKoJ,OAAOuC,IAClBqD,EAAmBhP,KAAuB,iBAC/BgP,EAAAtJ,OAASA,GAAS,KAAOiG,EACzBqD,EAAAvD,QAAUA,GAAU,KAAOE,EACtC,MAAAsD,EAAOD,EAAiBjF,WAAW,MAIlC,OAHPkF,EAAKvD,UAAU,EAAG,EAAGhG,EAAO+F,GACvBwD,EAAA/C,MAAMP,EAAKA,GAChBsD,EAAU,IAAItD,EACP,CAAEqD,mBAAkBC,OAC7B,CAQO,IAAAC,CAAMjN,EAAcC,EAAsBrC,GAC1CoC,GAAwB,iBAATA,GACLwF,EAAAxF,EAAMC,EAAKrC,EAC5B,CAQU,SAAAsP,CAAWlN,EAAcC,EAAamK,GACvC1M,OAAAC,eAAeqC,EAAMC,EAAK,CAC/B4F,IAAK,IACIuE,EAAS9K,KAAKvB,OAG3B,CASU,MAAAoP,CACR7G,EACA8G,EACAC,EAAyB,CAAA,GAEF,iBAAZD,IAETA,GADWC,EAAAD,GACQA,SAGrB,MAAME,EAAU,IAAIlH,EAAQrI,KAAMuI,EAAM8G,EAASC,GAMjD,OAJIA,EAASE,WACHH,EAAA9N,KAAKvB,KAAMuP,EAAQ1P,OAGtB,WAAsB,CAC/B,EAxaAmG,EADmBmD,EACZ,UAAkBE,GCHd,MAAAoG,EAAYC,GAChBnP,KAAKoP,GAAK,IAAMD,EA0BZE,EAAiB,CAC5B1K,EACA2K,EACAC,EACA9O,EACA+O,EACAC,KAEA9K,EAAI+K,YACJ,IAAIC,EAAYT,EAAS,GAAKlP,KAAKoP,GAAKG,EAAYE,GAEhDG,EAAWnP,EAAQkP,EACnBE,EAASL,EAAMG,EA7Ba,IAACR,EAAaW,EAgC9CnL,EAAIoL,IAAI,EAAG,EAAGR,EAAWK,EAAUC,GAAQ,GAKrClL,EAAAqL,WArC2Bb,GAuC1B1O,EAAQ+O,GAAO,EAvCwBM,EAwCxCL,EAAS,EAAIzP,KAAKE,IAAIF,KAAKiQ,KAAKxP,EAAQ+O,GAAO,IAvC9C,GAAGxP,KAAKkQ,IAAIf,GAAOW,GAAGK,QAAQ,KAAMnQ,KAAKiQ,IAAId,GAAOW,GAAGK,QAAQ,MA2CtExL,EAAIyL,aAIOC,EAAiB,CAC5B1L,MACIvE,EAAGC,EAAGiQ,EAAGC,EAAGT,MAEhB,MAAMU,EAAMxQ,KAAKwQ,IAAIF,EAAGC,GAAInB,EAAKpP,KAAKoP,GAClCU,EAAIU,EAAM,IAAGV,EAAIU,EAAM,GAC3B7L,EAAI+K,YACA/K,EAAA8L,OAAOrQ,EAAI0P,EAAGzP,GACdsE,EAAAqL,OAAO5P,EAAI0P,EAAGzP,GAClBsE,EAAIqL,OAAO5P,EAAIkQ,EAAIR,EAAGzP,GAClBsE,EAAAoL,IAAI3P,EAAIkQ,EAAIR,EAAGzP,EAAIyP,EAAGA,GAAIV,EAAK,EAAG,GACtCzK,EAAIqL,OAAO5P,EAAIkQ,EAAGjQ,EAAIkQ,EAAIT,GACtBnL,EAAAoL,IAAI3P,EAAIkQ,EAAIR,EAAGzP,EAAIkQ,EAAIT,EAAGA,EAAG,EAAGV,EAAK,GACzCzK,EAAIqL,OAAO5P,EAAI0P,EAAGzP,EAAIkQ,GAClB5L,EAAAoL,IAAI3P,EAAI0P,EAAGzP,EAAIkQ,EAAIT,EAAGA,EAAGV,EAAK,EAAGA,GACjCzK,EAAAqL,OAAO5P,EAAGC,EAAIyP,GACdnL,EAAAoL,IAAI3P,EAAI0P,EAAGzP,EAAIyP,EAAGA,EAAGV,GAAKA,EAAK,GACnCzK,EAAIyL,aChEOM,EACH,SAAUC,EAAGC,EAAGC,EAAGC,GAElB,OADHH,GAAKG,IAAOH,EAAAG,GACTD,GAAKF,GAAKG,GAAKH,EAAIC,CAC5B,EAJWF,EAKF,SAAUC,EAAGC,EAAGC,EAAGC,GAE1B,OADIH,GAAKG,IAAOH,EAAAG,IACRD,GAAKF,GAAKG,IAAMH,EAAI,GAAKC,CACnC,okBCHF,MAAqBG,UAAmBnI,EA2CtC,WAAApD,CAAaqD,EAAwBnH,GAhEvC,IAAAqB,EAiEIiO,MAAMnI,EAAQ,CACZ1D,MAAOzD,EAAKyD,MACZ+F,OAAQxJ,EAAKwJ,SA7CjBzF,EAAAhG,KAAQ,SAA2B,IACnCgG,EAAAhG,KAAQ,SAA2B,IACnCgG,EAAAhG,KAAQ,UAA6B,IACrCgG,EAAAhG,KAAQ,gBAAmC,CAAA,GAC3CgG,EAAAhG,KAAQ,eAAiC,CAAA,GACzCgG,EAAAhG,KAAQ,iBAA8C,CAAA,GACtDgG,EAAAhG,KAAQ,gBAA4C,CAAA,GAC5CgG,EAAAhG,KAAA,iBACAgG,EAAAhG,KAAA,eACRgG,EAAAhG,KAAQ,SAAS,GACjBgG,EAAAhG,KAAQ,cAAc,GACtBgG,EAAAhG,KAAQ,WAAW,GACnBgG,EAAAhG,KAAQ,WAAW,GACnBgG,EAAAhG,KAAQ,YAAY,GACpBgG,EAAAhG,KAAQ,eAAe,GACvBgG,EAAAhG,KAAQ,YAAY,GACpBgG,EAAAhG,KAAQ,UAAU,GAClBgG,EAAAhG,KAAQ,UAAU,GAClBgG,EAAAhG,KAAQ,SAAS,GACjBgG,EAAAhG,KAAQ,MAAM,MAQdgG,EAAAhG,KAAQ,OAAsB,GAOtBgG,EAAAhG,KAAA,aACAgG,EAAAhG,KAAA,iBAAiBwR,KAYvBxR,KAAKyR,SAASxP,GACdjC,KAAK0R,YACL1R,KAAK2R,eAEL,OAAOrO,EAAA8F,EAAAwI,iBAAcrQ,KAAKvB,MAE1BA,KAAK6R,MACP,CAEU,MAAArH,GA9EZ,IAAAlH,EAAAsH,EA+EI2G,MAAM/G,SACNxK,KAAK8R,OAASvR,KAAKwQ,IAAI/Q,KAAKmL,SAAUnL,KAAKoL,WAAa,EACxDpL,KAAKkF,IAAI6M,UAAU/R,KAAK8R,OAAQ9R,KAAK8R,QACrC9R,KAAKgS,OACL,OAAApH,GAAAtH,EAAAtD,KAAKoJ,QAAO6I,cAAZrH,EAAArJ,KAAA+B,EACF,CAEU,SAAA4H,GACRlL,KAAK8R,OAAS,EACd9R,KAAKkS,YAAc,EACnBlS,KAAKmS,SAAW,EAChBnS,KAAKoS,SAAW,EAChBpS,KAAKqS,UAAY,EACjBrS,KAAKsS,aAAe,EACpBtS,KAAKuS,UAAY,EACjBvS,KAAKwS,QAAU,EACfxS,KAAKyS,QAAU,EACfzS,KAAK0S,OAAS,EACd1S,KAAK2S,IAAM,KACX3S,KAAK4S,WAAY,EACjB5S,KAAK6S,KAAO,EACZtB,MAAMrG,WACR,CAMQ,QAAAuG,CAAUxP,GAChBjC,KAAKkP,KAAKlP,KAAM,QAASiC,EAAKyD,OAC9B1F,KAAKkP,KAAKlP,KAAM,SAAUiC,EAAKwJ,QAC/BzL,KAAKkP,KAAKlP,KAAM,SAAUiC,EAAK6Q,QAAU,IACzC9S,KAAKkP,KAAKlP,KAAM,SAAUiC,EAAK8Q,QAAU,IACzC/S,KAAKkP,KAAKlP,KAAM,UAAWiC,EAAK+Q,SAAW,IAC3ChT,KAAKkP,KAAKlP,KAAM,gBAAiBiC,EAAKgR,eAAiB,CAAA,GACvDjT,KAAKkP,KAAKlP,KAAM,eAAgBiC,EAAKiR,cAAgB,CAAA,GACrDlT,KAAKkP,KAAKlP,KAAM,gBAAiBiC,EAAKjB,OACtChB,KAAKkP,KAAKlP,KAAM,cAAeiC,EAAK8N,IACtC,CAKQ,YAAA4B,GAED3R,KAAAmP,UAAUnP,KAAM,iBAAkB,IACtBmT,EAAA,CACbnD,OAAQ,MACRoD,aAAc,EACdC,MAAO,GACPC,cAAe,OACfC,iBAAkB,KAClBC,iBAAkB,KAClBC,UAAW,GACRzT,KAAKiT,gBAKPjT,KAAAmP,UAAUnP,KAAM,gBAAiB,IACtBmT,EAAA,CACZ5H,SAAU,OACVmI,UAAW,OACXC,UAAW,aACXC,WAAY,MACZC,WAAY,gBACZC,UAAU,EACVC,YAAa,OACV/T,KAAKkT,cAId,CAKQ,SAAAxB,GAED1R,KAAAoP,OAAO,QAAUjH,IACpBnI,KAAKiC,KAAKyD,MAAQyC,EAClBnI,KAAKwK,WAGFxK,KAAAoP,OAAO,SAAWjH,IACrBnI,KAAKiC,KAAKwJ,OAAStD,EACnBnI,KAAKwK,WAGFxK,KAAAoP,OAAO,SAAW4E,IACrBhU,KAAKiU,kBACJ,CAAEtL,MAAM,IAEN3I,KAAAoP,OAAO,SAAW4E,IACrBhU,KAAKiU,kBACJ,CAAEtL,MAAM,IAEN3I,KAAAoP,OAAO,UAAY4E,IACtBhU,KAAKiU,kBACJ,CAAEtL,MAAM,IACN3I,KAAAoP,OAAO,gBAAiB,IAAMpP,KAAKgS,OAAQ,CAAErJ,MAAM,IACnD3I,KAAAoP,OAAO,eAAgB,IAAMpP,KAAKgS,OAAQ,CAAErJ,MAAM,IACvD3I,KAAKoP,OAAO,gBAAiB,IAAMpP,KAAK6R,QACxC7R,KAAKoP,OAAO,cAAe,IAAMpP,KAAK6R,OACxC,CAKa,IAAAA,GAAuB,OAAAqC,EAAAlU,KAAA,KAAA,YA5LtC,IAAAsD,EAAAsH,EA6LI5K,KAAKkL,YACC,MAAA9B,OAAEA,GAAWpJ,KAEnB,OAAOsD,EAAA8F,EAAA+K,eAAY5S,KAAKvB,MACxBA,KAAKgS,OACLhS,KAAKgS,aAEChS,KAAKiU,iBAEX,OAAOrJ,EAAAxB,EAAAgL,cAAW7S,KAAKvB,KAAA,EACzB,CAEQ,cAAAiU,GACC,OAAA,IAAInH,QAASC,IAClB,MAAMsH,EAAiB,CACrBvB,OAAQ9S,KAAK8S,OAAOrP,IAAIL,GAASA,EAAMkR,MACvCvB,OAAQ/S,KAAK+S,OAAOtP,IAAI8Q,GAASA,EAAMD,MACvCtB,QAAShT,KAAKgT,QAAQvP,IAAI+Q,GAAOA,EAAIF,OAEJ3U,OAAO6H,KAAK6M,GAAiBhO,QAAmBoO,IAC3E,MAAAC,EAAaL,EAAeI,GAE5BE,EAA8B,GACpCD,GAAcA,EAAWrO,QAAQ,CAACiO,EAAMM,KACtCN,GAAQA,EAAKjO,QAAQ,CAAC0H,EAAS8G,KAC7BF,EAAW7P,KAAK9E,KAAK8U,gBAAgBL,EAASG,EAAWC,QAG7D/H,QAAQiI,IAAIJ,GAAYK,KAAK,KAC3BhV,KAAKgS,OACGjF,SAIhB,CAMU,WAAA7C,CAAaC,GArOzB,IAAA7G,EAsOU,MAAA4B,IAAEA,GAAQlF,KAChBkF,EAAI+K,YACA/K,EAAAoL,IAAI,EAAG,EAAGtQ,KAAKsS,aAAc,EAAa,EAAV/R,KAAKoP,IAAQ,GAC5CzK,EAAI+P,cAAc9K,EAAE+K,QAAS/K,EAAEgL,UAClB,IAAdnV,KAAK6S,OACT,OAAAvP,EAAAtD,KAAKoV,gBAAgB9R,EAAA/B,KAAAvB,KAAAmK,GACvB,CASc,eAAA2K,CACZO,EACAT,EACAC,GACe,OAAAX,EAAAlU,KAAA,KAAA,YACf,OAAO,IAAI8M,QAAQ,CAACC,EAASC,KAE3B,MAAMsI,EAA2CtV,KAAKqV,GAAUT,GAChE,IAAKU,IAASA,EAAKhB,KAAM,OACnB,MAAAvG,EAAUuH,EAAKhB,KAAKO,GACrB9G,GAEL/N,KAAK0M,QAAQqB,EAAQpB,IAAKoB,GAASiH,KAAWO,GAAWrB,EAAAlU,KAAA,KAAA,YACtB,mBAAtB+N,EAAQyH,YACPD,QAAMzI,QAAQC,QAAQgB,EAAQyH,UAAUjU,KAAKvB,KAAMuV,KAE/DvV,KAAKyV,WAAWzN,IAAI+F,EAAa,IAAGwH,GAC5BxI,GAAA,IACP2I,MAAa7H,IACNxD,QAAAC,MAAM,GAAG+K,KAAYT,WAAmBC,MAAahH,KACtDb,OAEV,EACH,CAEQ,SAAA2I,CAAWC,EAAgBxS,EAAkByS,GAC7C,MAAA3Q,IAAEA,GAAQlF,KACZyC,EAAcW,EAAMyQ,cACtB3O,EAAI+K,YACJ/K,EAAI4Q,UAAY1S,EAAMyQ,WAClB3O,EAAAoL,IAAI,EAAG,EAAGsF,EAAQ,EAAa,EAAVrV,KAAKoP,IAAQ,GACtCzK,EAAI6Q,QAEN3S,EAAMkR,MAAQlR,EAAMkR,KAAKjO,QAAQ,CAAC0H,EAAS8G,KACzC,MAAMmB,EAAWhW,KAAKyV,WAAW3N,IAAIiG,EAAQpB,KAC7C,IAAKqJ,EAAU,OAET,MAAC/H,EAAWC,GAAclO,KAAK8N,uBAAuBkI,EAAUjI,EAAkB,EAAT6H,EAAqB,EAATA,IACpFK,EAAOC,GAAS,CAAClW,KAAK8O,WAAWb,GAAajO,KAAKqD,UAAU0K,EAAQoI,KAAe,EAATP,GAAa5V,KAAKqD,UAAU0K,EAAQqI,IAAc,EAATR,GAAcA,GACzI1Q,EAAImR,OACJtI,EAAQuI,QAAUpR,EAAIoR,OAAO7G,EAASzP,KAAKqS,YAC3CrS,KAAKqN,UAAUnI,EAAK8Q,EAAUC,EAAOC,EAAOjI,EAAWC,GACvDhJ,EAAIqR,WAER,CAKU,IAAAvE,GAtSZ,IAAA1O,EAAAsH,EAuSI,MAAMxB,OAAEA,EAAAlE,IAAQA,EAAKsR,eAAAA,EAAAC,cAAgBA,GAAkBzW,KAEvD,OAAOsD,EAAA8F,EAAAsN,aAAYpT,EAAA/B,KAAKvB,KAAMkF,GAE9BA,EAAIwG,WAAW1L,KAAK8R,QAAS9R,KAAK8R,OAAsB,EAAd9R,KAAK8R,OAA0B,EAAd9R,KAAK8R,QAEhE9R,KAAKkS,YAAclS,KAAK8S,OAAOnO,OAAO,CAACiR,EAAQxS,EAAOyS,KAC/C7V,KAAA2V,UAAUC,EAAQxS,EAAOyS,GACvBD,EAAS5V,KAAKqD,UAAUD,EAAMG,SAAWH,EAAMG,QAAQC,MAAM,KAAK,KACxExD,KAAK8R,QAEH9R,KAAAmS,SAAW,IAAMnS,KAAK+S,OAAO3S,OAC7BJ,KAAAoS,SAAW3C,EAASzP,KAAKmS,UACxB,MAAAwE,EAAY3W,KAAKkS,YAAc3R,KAAKiQ,IAAIxQ,KAAKoS,SAAW,GAAK,EAE/D,IAAApR,EAAQyO,EAASzP,KAAKqS,UAAY,GAAKrS,KAAKmS,SAAW,EAAIqE,EAAepD,cAExE,MAAAwD,EAAW,CAACC,EAAoBC,IAC7B9W,KAAK8O,WAAW5J,EAAIO,YAAYqR,GAAMpR,OAAS1F,KAAKqD,UAAUwT,EAAKV,KAAMQ,GAG5EI,EAAW,CAACF,EAAoBpL,EAAgBuL,KAEpD,MAAMC,EAAaJ,EAAKI,YAAcR,EAAcQ,YAAcJ,EAAKtL,UAAYkL,EAAclL,SAC1F,OAAAvL,KAAKqD,UAAUwT,EAAKT,IAAK3K,IAAWuL,EAAY,GAAKhX,KAAKqD,UAAU4T,IAE7E/R,EAAImR,OAEJrW,KAAK+S,OAAO1M,QAAQ,CAACkO,EAAO2C,KAEtB,IAAAC,EAAgBnW,EAAQkW,EAAalX,KAAKoS,SAE1CgF,EAAcpX,KAAKkS,YAAclS,KAAKsS,aAEpC,MAAAuB,EAAaU,EAAMV,YAAc4C,EAAc5C,WACjDpR,EAAcoR,KAChB3O,EAAI4Q,UAAYjC,EAChBjE,EACE1K,EAAKlF,KAAKsS,aAActS,KAAKkS,YAC7BiF,EAAgBnX,KAAKoS,SAAW,EAChC+E,EAAgBnX,KAAKoS,SAAW,EAChCpS,KAAKqD,UAAUmT,EAAexG,SAEhC9K,EAAI6Q,QAGN,IAAIpV,EAAIJ,KAAKkQ,IAAI0G,GAAiBnX,KAAKkS,YACnCtR,EAAIL,KAAKiQ,IAAI2G,GAAiBnX,KAAKkS,YACnChN,EAAA6M,UAAUpR,EAAGC,GACjBsE,EAAIoR,OAAOa,EAAgB1H,EAAS,KAEpC8E,EAAMD,MAAQC,EAAMD,KAAKjO,QAAQ,CAAC0H,EAAS8G,KACzC,MAAMwC,EAAWrX,KAAKyV,WAAW3N,IAAIiG,EAAQpB,KAC7C,IAAK0K,EAAU,OACf,MAAOpJ,EAAWC,GAAclO,KAAK8N,uBACnCuJ,EACAtJ,EACA/N,KAAKoS,SAAWpS,KAAKkS,YACrBkF,IAEKnB,EAAOC,GAAS,CACrBlW,KAAK8O,WAAWb,GAAajO,KAAKqD,UAAU0K,EAAQoI,KAAMQ,GAC1D3W,KAAKqD,UAAU0K,EAAQqI,IAAKgB,IAE9BpX,KAAKqN,UAAUnI,EAAKmS,EAAUpB,EAAOC,EAAOjI,EAAWC,KAGzDqG,EAAM+C,OAAS/C,EAAM+C,MAAMjR,QAAgBwQ,IACnC,MAAAnD,EAAYmD,EAAKnD,WAAa+C,EAAc/C,UAC5CE,EAAaiD,EAAKjD,YAAc6C,EAAc7C,WAC9CrI,EAAWvL,KAAKqD,UAAUwT,EAAKtL,UAAYkL,EAAclL,UACzDoI,EAAYkD,EAAKlD,WAAa8C,EAAc9C,UAC5CG,EAAW9R,EAAI6U,EAAM,YAAcA,EAAK/C,SAAW2C,EAAc3C,SACjEC,EAAc8C,EAAK9C,aAAe0C,EAAc1C,YAChD1O,EAAYwR,EAAKxR,WAAaoR,EAAcpR,UAClDH,EAAI4Q,UAAYpC,EAChBxO,EAAI2R,KAAO,GAAGjD,KAAcrI,EAAY,OAAOoI,IAC/C,IAAIpO,EAAQ,GAAIJ,EAAOrE,OAAO+V,EAAK1R,MAEjCI,EADEuO,EACM7O,EAAUC,EAAK9C,EAAY+C,GAAQI,IAMzC,IAAIM,EAAuB,IAJN7F,KAAKkS,YAAc6E,EAASF,EAAMO,EAAa7R,EAAMnF,SAEzCG,KAAKgX,IAAIvX,KAAKoS,SAAW,IAE3BpS,KAAKqD,UAAUmT,EAAexG,QACtD,OAAAhQ,KAAKqD,UAAU0Q,EAAalO,IAClCR,GAEKF,EAAK3B,MAAM,MAEf+B,EAAAjD,YAAiBwU,GAAMzQ,QAAQ,CAACyQ,EAAME,KACtC9R,EAAAsS,SAASV,EAAMF,EAASC,EAAMC,GAAOC,EAASF,EAAMO,EAAaJ,QAIzE9R,EAAIoR,OAAO7G,EAAS,KAAO0H,EAAgB1H,EAAS,KACpDvK,EAAI6M,WAAWpR,GAAIC,KAErBsE,EAAIqR,UAEJvW,KAAKgT,QAAQ3M,QAAQ,CAACmO,EAAKiD,KACzB,IAAI7B,EAAS5V,KAAKqD,UAAUmR,EAAIoB,OAAQ5V,KAAKkS,aAE7ClS,KAAKsS,aAAe/R,KAAKC,IAAIR,KAAKsS,aAAcsD,GAC5CnT,EAAc+R,EAAIX,cACpB3O,EAAI+K,YACJ/K,EAAI4Q,UAAYtB,EAAIX,WAChB3O,EAAAoL,IAAI,EAAG,EAAGsF,EAAQ,EAAa,EAAVrV,KAAKoP,IAAQ,GACtCzK,EAAI6Q,QAGFvB,EAAIkD,SAAWjV,EAAc+R,EAAIX,cACnC3O,EAAI+K,YACJ/K,EAAI4Q,UAAYtB,EAAIX,WAChB3O,EAAA8L,QAAQ4E,EAAQ,GAChB1Q,EAAAqL,OAAOqF,EAAQ,GACnB1Q,EAAIqL,OAAO,EAAa,GAATqF,GACf1Q,EAAIyL,YACJzL,EAAI6Q,QAGNvB,EAAIF,MAAQE,EAAIF,KAAKjO,QAAQ,CAAC0H,EAAS8G,KACrC,MAAM8C,EAAS3X,KAAKyV,WAAW3N,IAAIiG,EAAQpB,KAC3C,IAAKgL,EAAQ,OACP,MAAC1J,EAAWC,GAAclO,KAAK8N,uBAAuB6J,EAAQ5J,EAAkB,EAAT6H,EAAqB,EAATA,IAClFK,EAAOC,GAAS,CAAClW,KAAK8O,WAAWb,GAAajO,KAAKqD,UAAU0K,EAAQoI,KAAMP,GAAS5V,KAAKqD,UAAU0K,EAAQqI,IAAKR,IACvH5V,KAAKqN,UAAUnI,EAAKyS,EAAQ1B,EAAOC,EAAOjI,EAAWC,KAGvDsG,EAAI8C,OAAS9C,EAAI8C,MAAMjR,QAAgBwQ,IACjC,IAAAnD,EAAYmD,EAAKnD,WAAa+C,EAAc/C,UAC5CE,EAAaiD,EAAKjD,YAAc6C,EAAc7C,WAC9CrI,EAAWvL,KAAKqD,UAAUwT,EAAKtL,UAAYkL,EAAclL,UACzDoI,EAAYkD,EAAKlD,WAAa8C,EAAc9C,UAChDzO,EAAI4Q,UAAYpC,EAChBxO,EAAI2R,KAAO,GAAGjD,KAAcrI,EAAY,OAAOoI,IACxC7S,OAAA+V,EAAK1R,MAAM3B,MAAM,MAAM6C,QAAQ,CAACyQ,EAAME,KACvC9R,EAAAsS,SAASV,EAAMF,EAASC,EAAMC,GAAOC,EAASF,EAAMjB,EAAQoB,UAKtE,OAAOpM,EAAAxB,EAAAwO,YAAWhN,EAAArJ,KAAKvB,KAAMkF,EAC/B,CAKQ,2BAAA2S,GACN,MAAMrB,eAAEA,EAAA5D,UAAgBA,EAAWT,SAAAA,EAAAE,UAAUA,GAAcrS,KACtDA,KAAAwS,QAAUsF,KAAKC,MACd,MAAAtF,EAAUzS,KAAKyS,QAAUJ,EACzBgB,EAAQmD,EAAenD,MACvBI,GAAalT,KAAKwE,SAAWoN,EAAWA,EAAW,GAAKnS,KAAKqD,UAAUmT,EAAe/C,WAC5F,IAAI9N,EAAI,EAAGqS,EAAY,EAAGC,EAAU,EACpC,OAAStS,GAAG,CACJ,MAAA+M,EAAS,IAAM/M,EAAIiN,EAAaT,EAAWE,EAAYmE,EAAepD,aAAeK,EAAYtB,EAAW,EAC9G,IAAA+F,EAAYjH,EAAajR,KAAK2S,IAAKF,EAASC,EAAQ8D,EAAehD,kBAAoBf,EAC3F,GAAIyF,EAAY7E,EAAO,CACrBrT,KAAK0S,OAAUW,EAAQ2E,EAAYE,EAAY7E,EAASX,EAASuF,EACjE,KACF,CACUA,EAAAvF,EACEsF,EAAAE,CACd,CACF,CAKO,IAAAC,GAldT,IAAA7U,EAAAsH,EAmdsB,IAAd5K,KAAK6S,OAEJ7S,KAAAuS,UAAYuF,KAAKC,MAEtB/X,KAAK4S,eAAY,EAEjB5S,KAAK6S,KAAO,EAEZ,OAAAjI,GAAAtH,EAAAtD,KAAKoJ,QAAOgP,aAAZxN,EAAArJ,KAAA+B,GAEAtD,KAAKqY,MACP,CAMO,IAAAC,CAAM1K,GACX,GAAkB,IAAd5N,KAAK6S,MAA4B,IAAd7S,KAAK6S,KAA5B,CAEI,IAACjF,GAAmB,IAAVA,EAAa,CACzB,MAAMpJ,EAAWxE,KAAK+S,OAAOtP,IAAI8U,GAAQA,EAAKC,OAC9C5K,EAAQrJ,EAAaC,EACvB,CAEIoJ,EAAQ,GACV5N,KAAK6S,KAAO,EACZ7S,KAAK4S,WAAY,IAEjB5S,KAAK6S,KAAO,EACP7S,KAAA4S,UAAYhF,EAAQ5N,KAAK+S,OAAO3S,OAZC,CAc1C,CAMQ,GAAAiY,CAAKrV,EAAc,GAzf7B,IAAAM,EA0fI,MAAM6I,IAAEA,EAAA0G,KAAKA,EAAMD,UAAAA,EAAA4D,eAAWA,GAAmBxW,MAC3CuT,iBAAEA,EAAAC,iBAAkBA,EAAkBH,MAAAA,GAAUmD,EAEtD,GAAa,IAAT3D,EAEF,YADA,OAAKvP,EAAAtD,KAAAyY,cAAcnV,EAAA/B,KAAAvB,KAAAA,KAAK+S,OAAO7R,KAAK,CAACqT,EAAO3G,IAAUA,IAAUgF,IAAc,CAAA,IAIhF,IAAsB,IAAlBA,EAAkB,OAET,IAATC,GAAe7S,KAAK0S,aAAamF,8BAErC,MAAMa,EAAgBZ,KAAKC,MAAQ/X,KAAKuS,UAClCoG,EAAcb,KAAKC,MAAQ/X,KAAKwS,QACtC,IAAIH,EAAYrS,KAAKqS,UAEjB,GAAS,IAATQ,GAAc6F,EAAgBnF,EAAkB,CAElDvT,KAAK2S,IAAM+F,EAAgB1V,EAC3B,MAAMkV,EAAYjH,EAAYyH,EAAe,EAAGrF,EAAOE,GAEnD2E,IAAc7E,IAChBrT,KAAK6S,KAAO,GAEdR,GAAwB6F,EAAY,GAAA,MAClB,IAATrF,GAETR,GAAwBgB,EAAQ,SAEJ,IAAxBT,GAAwBA,GAAa,IACvC5S,KAAK6S,KAAO,EAEZ7S,KAAKyS,QAAU,EACfzS,KAAK0S,OAAS,IAEE,IAATG,GAETR,EAAYpB,EAAa0H,EAAa3Y,KAAKyS,QAASzS,KAAK0S,OAAQc,GAC7DmF,GAAenF,IACjBxT,KAAK6S,KAAO,IAId7S,KAAKsY,MAAO,GAEdtY,KAAKqS,UAAYA,EACjBrS,KAAKgS,OACL7F,EAAInM,KAAKqY,IAAIO,KAAK5Y,KAAMgD,EAAM,GAChC,CAOU,cAAA6V,CAAgBlY,EAAWC,GAC7B,MAAAwI,OAAEA,GAAWpJ,KACZ,MAAA,CAACW,EAAIyI,EAAOuC,IAAM3L,KAAK8R,OAAQlR,EAAIwI,EAAOuC,IAAM3L,KAAK8R,OAC9D,okBCvhBF,MAAqBgH,UAAkB3P,EAoDrC,WAAApD,CAAaqD,EAAwBnH,GAjFvC,IAAAqB,EAkFIiO,MAAMnI,EAAQ,CACZ1D,MAAOzD,EAAKyD,MACZ+F,OAAQxJ,EAAKwJ,SAtDjBzF,EAAAhG,KAAQ,OAAiB,GACzBgG,EAAAhG,KAAQ,OAAiB,GACzBgG,EAAAhG,KAAQ,SAA2B,IACnCgG,EAAAhG,KAAQ,SAA2B,IACnCgG,EAAAhG,KAAQ,UAA6B,IAC7BgG,EAAAhG,KAAA,UACRgG,EAAAhG,KAAQ,gBAAmC,CAAA,GAC3CgG,EAAAhG,KAAQ,eAAiC,CAAA,GACzCgG,EAAAhG,KAAQ,cAA+B,CAAA,GACvCgG,EAAAhG,KAAQ,iBAA8C,CAAA,GACtDgG,EAAAhG,KAAQ,gBAA4C,CAAA,GACpDgG,EAAAhG,KAAQ,eAA0C,CAAA,GAC1CgG,EAAAhG,KAAA,iBACAgG,EAAAhG,KAAA,eACRgG,EAAAhG,KAAQ,YAAY,GACpBgG,EAAAhG,KAAQ,aAAa,GACrBgG,EAAAhG,KAAQ,YAAY,GACpBgG,EAAAhG,KAAQ,UAAU,GAClBgG,EAAAhG,KAAQ,YAAY,GACpBgG,EAAAhG,KAAQ,YAAY,GACpBgG,EAAAhG,KAAQ,WAAW,GACnBgG,EAAAhG,KAAQ,QAAO,GACfgG,EAAAhG,KAAQ,QAAQ,GAChBgG,EAAAhG,KAAQ,MAAM,MAQdgG,EAAAhG,KAAQ,OAAsB,GAO9BgG,EAAAhG,KAAQ,aAAgC,GAExCgG,EAAAhG,KAAQ,QAA+C,IAE/CgG,EAAAhG,KAAA,aAEAgG,EAAAhG,KAAA,iBAAiBwR,KAYvBxR,KAAKyR,SAASxP,GACdjC,KAAK0R,YACL1R,KAAK2R,eAEL,OAAOrO,EAAA8F,EAAAwI,iBAAcrQ,KAAKvB,MAE1BA,KAAK6R,MACP,CAEU,MAAArH,GA/FZ,IAAAlH,EAAAsH,EAgGI2G,MAAM/G,SACNxK,KAAKgS,OACL,OAAApH,GAAAtH,EAAAtD,KAAKoJ,QAAO6I,cAAZrH,EAAArJ,KAAA+B,EACF,CAEU,SAAA4H,GACRlL,KAAK+Y,UAAY,EACjB/Y,KAAKgZ,WAAa,EAClBhZ,KAAKuS,UAAY,EACjBvS,KAAKwS,QAAU,EACfxS,KAAKiZ,UAAY,EACjBjZ,KAAKkZ,UAAY,EACjBlZ,KAAKmZ,SAAW,EAChBnZ,KAAKoZ,MAAO,EACZpZ,KAAKqZ,MAAQ,EACbrZ,KAAK2S,IAAM,KACX3S,KAAK4S,WAAY,EACjB5S,KAAK6S,KAAO,EACZtB,MAAMrG,WACR,CAMQ,QAAAuG,CAAUxP,GAChBjC,KAAKkP,KAAKlP,KAAM,QAASiC,EAAKyD,OAC9B1F,KAAKkP,KAAKlP,KAAM,SAAUiC,EAAKwJ,QAC/BzL,KAAKkP,KAAKlP,KAAM,OAAQkD,OAAOjB,EAAKqX,OAAS,GAC7CtZ,KAAKkP,KAAKlP,KAAM,OAAQkD,OAAOjB,EAAKsX,OAAS,GAC7CvZ,KAAKkP,KAAKlP,KAAM,SAAUiC,EAAK6Q,QAAU,IACzC9S,KAAKkP,KAAKlP,KAAM,SAAUiC,EAAK8Q,QAAU,IACzC/S,KAAKkP,KAAKlP,KAAM,UAAWiC,EAAK+Q,SAAW,IAE3ChT,KAAKkP,KAAKlP,KAAM,SAAUiC,EAAKuX,QAC/BxZ,KAAKkP,KAAKlP,KAAM,gBAAiBiC,EAAKgR,eAAiB,CAAA,GACvDjT,KAAKkP,KAAKlP,KAAM,eAAgBiC,EAAKiR,cAAgB,CAAA,GACrDlT,KAAKkP,KAAKlP,KAAM,cAAeiC,EAAKwX,aAAe,CAAA,GACnDzZ,KAAKkP,KAAKlP,KAAM,gBAAiBiC,EAAKjB,OACtChB,KAAKkP,KAAKlP,KAAM,cAAeiC,EAAK8N,IACtC,CAKQ,YAAA4B,GAED3R,KAAAmP,UAAUnP,KAAM,iBAAkB,KACrC,MAAMoJ,EAAS+J,EAAA,CACbnD,OAAQ,EACRqD,MAAO,GACPE,iBAAkB,KAClBC,iBAAkB,MACfxT,KAAKiT,eAIH,OAFP7J,EAAO4G,OAAShQ,KAAKqD,UAAU+F,EAAO4G,QAC/B5G,EAAAiK,MAAQjK,EAAOiK,MAAQ,GACvBjK,IAGJpJ,KAAAmP,UAAUnP,KAAM,gBAAiB,IAC7BmT,EAAA,CACLuG,aAAc,GACdhG,UAAW,OACXnI,SAAU,OACVoI,UAAW,aACXC,WAAY,MACZC,WAAY,gBACZ8F,OAAQ,GACR7F,UAAU,EACVC,YAAa,OACV/T,KAAKkT,eAIPlT,KAAAmP,UAAUnP,KAAM,eAAgB,IAC5BmT,EAAA,CACLU,WAAY,UACZ8F,OAAQ,IACL3Z,KAAKyZ,aAGd,CAKQ,SAAA/H,GAED1R,KAAAoP,OAAO,QAAUjH,IACpBnI,KAAKiC,KAAKyD,MAAQyC,EAClBnI,KAAKwK,WAGFxK,KAAAoP,OAAO,SAAWjH,IACrBnI,KAAKiC,KAAKwJ,OAAStD,EACnBnI,KAAKwK,WAGFxK,KAAAoP,OAAO,SAAW4E,IACrBhU,KAAKiU,kBACJ,CAAEtL,MAAM,IAEN3I,KAAAoP,OAAO,SAAW4E,IACrBhU,KAAKiU,kBACJ,CAAEtL,MAAM,IAEN3I,KAAAoP,OAAO,UAAY4E,IACtBhU,KAAKiU,kBACJ,CAAEtL,MAAM,IACX3I,KAAKoP,OAAO,OAAQ,IAAMpP,KAAK6R,QAC/B7R,KAAKoP,OAAO,OAAQ,IAAMpP,KAAK6R,QAC1B7R,KAAAoP,OAAO,gBAAiB,IAAMpP,KAAKgS,OAAQ,CAAErJ,MAAM,IACnD3I,KAAAoP,OAAO,eAAgB,IAAMpP,KAAKgS,OAAQ,CAAErJ,MAAM,IAClD3I,KAAAoP,OAAO,cAAe,IAAMpP,KAAKgS,OAAQ,CAAErJ,MAAM,IACtD3I,KAAKoP,OAAO,gBAAiB,IAAMpP,KAAK6R,QACxC7R,KAAKoP,OAAO,cAAe,IAAMpP,KAAK6R,OACxC,CAKa,IAAAA,GAAuB,OAAAqC,EAAAlU,KAAA,KAAA,YA1NtC,IAAAsD,EAAAsH,EA2NI5K,KAAKkL,YACC,MAAA9B,OAAEA,GAAWpJ,KAEnB,OAAOsD,EAAA8F,EAAA+K,eAAY5S,KAAKvB,MAExBA,KAAKgS,aAEChS,KAAKiU,iBAEX,OAAOrJ,EAAAxB,EAAAgL,cAAW7S,KAAKvB,KAAA,EACzB,CAEQ,cAAAiU,GACC,OAAA,IAAInH,QAASC,IAClB,MAAM6M,EAAU5Z,KAAKgT,QAAQvP,IAAI+Q,GAAOA,EAAIF,MACxCtU,KAAKwZ,QAAQI,EAAQ9U,KAAK9E,KAAKwZ,OAAOlF,MAC1C,MAAMD,EAAiB,CACrBvB,OAAQ9S,KAAK8S,OAAOrP,IAAIL,GAASA,EAAMkR,MACvCvB,OAAQ/S,KAAK+S,OAAOtP,IAAI8Q,GAASA,EAAMD,MACvCtB,QAAS4G,GAEwBja,OAAO6H,KAAK6M,GAAiBhO,QAAmBoO,IAC3E,MAAAC,EAAaL,EAAeI,GAE5BE,EAA8B,GACpCD,GAAcA,EAAWrO,QAAQ,CAACiO,EAAMM,KACtCN,GAAQA,EAAKjO,QAAQ,CAAC0H,EAAS8G,KAC7BF,EAAW7P,KAAK9E,KAAK8U,gBAAgBL,EAASG,EAAWC,QAG7D/H,QAAQiI,IAAIJ,GAAYK,KAAK,KAC3BhV,KAAKgS,OACGjF,SAIhB,CAMU,WAAA7C,CAAaC,GACf,MAAAjF,IAAEA,GAAQlF,KACf,IACIA,KAAKgT,QACRhT,KAAKwZ,QACLnT,QAAemO,IA1QrB,IAAAlR,EA2QM,IAAKkR,EAAK,OACV,MAAO7T,EAAGC,EAAG8E,EAAO+F,GAAUzL,KAAK6Z,qBAAqB,CACtDrF,EAAI7T,EAAG6T,EAAI5T,EAAG4T,EAAIsF,KAAO,EAAGtF,EAAIuF,KAAO,IAEzC7U,EAAI+K,YACJ/K,EAAI8U,KAAKrZ,EAAGC,EAAG8E,EAAO+F,GACjBvG,EAAI+P,cAAc9K,EAAE+K,QAAS/K,EAAEgL,UAClB,IAAdnV,KAAK6S,OAEmB,mBAAjB2B,EAAInI,YAA6BA,SAAS9K,KAAKvB,KAAMwU,GAEhE,OAAKlR,EAAAtD,KAAAoV,4BAAgBjL,EAAGqK,KAE5B,CASc,eAAAM,CACZO,EACAT,EACAC,GACe,OAAAX,EAAAlU,KAAA,KAAA,YACf,OAAO,IAAI8M,QAAQ,CAACC,EAASC,KAC3B,IAAIsI,EAA2CtV,KAAKqV,GAAUT,GAK9D,GAHiB,YAAbS,IAA2BrV,KAAKgT,QAAQ5S,QAAUJ,KAAKwZ,SACzDlE,EAAOtV,KAAKwZ,SAETlE,IAASA,EAAKhB,KAAM,OACnB,MAAAvG,EAAUuH,EAAKhB,KAAKO,GAC1B,IAAK9G,EAAS,OAEd,MAAMkM,EAAU,CACdja,KAAK0M,QAAQqB,EAAQpB,IAAKoB,GAC1BA,EAAmB,WAAK/N,KAAK0M,QAAQqB,EAAmB,UAAGA,EAAS,mBAEtEjB,QAAQiI,IAAIkF,GAASjF,KAAYkF,GAA4BhG,EAA5BlU,KAAA,CAAAka,GAA4B,WAA3BC,EAAYC,IAC5C,MAAM5E,EAAYzH,EAAQyH,UAED,mBAAdA,IACT2E,QAAmBrN,QAAQC,QAAQyI,EAAUjU,KAAKvB,KAAMma,IACpDC,IACFA,QAAkBtN,QAAQC,QAAQyI,EAAUjU,KAAKvB,KAAMoa,MAG3Dpa,KAAKyV,WAAWzN,IAAI+F,EAAa,IAAGoM,GACpCC,GAAapa,KAAKyV,WAAWzN,IAAI+F,EAAmB,UAAGqM,GAC/CrN,GAAA,IACP2I,MAAa7H,IACNxD,QAAAC,MAAM,GAAG+K,KAAYT,WAAmBC,MAAahH,KACtDb,OAEV,EACH,CAKU,IAAAgF,GA1UZ,IAAA1O,EAAAsH,EA2UI,MAAMxB,OAAEA,EAAQlE,IAAAA,EAAAsR,eAAKA,EAAgBC,cAAAA,EAAA4D,aAAeA,GAAiBra,KAErE,OAAOsD,EAAA8F,EAAAsN,aAAYpT,EAAA/B,KAAKvB,KAAMkF,GAE9BA,EAAIwG,UAAU,EAAG,EAAG1L,KAAKmL,SAAUnL,KAAKoL,WAExCpL,KAAKsa,MAAQ,IACRta,KAAK+S,UACL/S,KAAKgT,SAENhT,KAAKwZ,QAAQxZ,KAAKsa,MAAMxV,KAAK9E,KAAKwZ,QACjCxZ,KAAAsa,MAAMjU,QAAgBiP,IACpBA,EAAAwE,IAAMxE,EAAKwE,KAAO,EAClBxE,EAAAyE,IAAMzE,EAAKyE,KAAO,IAGzB/Z,KAAKua,UAAYva,KAAK8S,OAAOnO,OAAO,EAAEhE,IAAGC,IAAGiQ,IAAGC,KAAI1N,EAAOyS,KACxD,MAAOnS,EAAYC,EAAeC,EAAaC,GAAgBV,EAAeC,EAAOpD,KAAKqD,UAAUuV,KAAK5Y,OACnGqQ,EAAIjN,EAAMsW,aAAe1Z,KAAKqD,UAAUD,EAAMsW,cAAgB,EAE9D7F,EAAazQ,EAAMyQ,WAkBlB,OAjBHpR,EAAcoR,KAChB3O,EAAI4Q,UAAY9V,KAAKwa,iBAAiB7Z,EAAGC,EAAGiQ,EAAGC,EAAG+C,GAClDjD,EAAe1L,EAAKvE,EAAGC,EAAGiQ,EAAGC,EAAGT,GAChCnL,EAAI6Q,QAGN3S,EAAMkR,MAAQlR,EAAMkR,KAAKjO,QAAQ,CAAC0H,EAAS8G,KACzC,MAAMmB,EAAWhW,KAAKyV,WAAW3N,IAAIiG,EAAQpB,KAC7C,IAAKqJ,EAAU,OAET,MAAC/H,EAAWC,GAAclO,KAAK8N,uBAAuBkI,EAAUjI,EAAS8C,EAAGC,IAC3EmF,EAAOC,GAAS,CACrBlW,KAAK8O,WAAWb,EAAW4C,GAAK7Q,KAAKqD,UAAU0K,EAAQoI,KAAMtF,GAC7D7Q,KAAKqD,UAAU0K,EAAQqI,IAAKtF,IAEzB9Q,KAAAqN,UAAUnI,EAAK8Q,EAAUrV,EAAIsV,EAAOrV,EAAIsV,EAAOjI,EAAWC,KAE1D,CACLvN,EAAGA,EAAIiD,EACPhD,EAAGA,EAAI8C,EACPmN,EAAGA,EAAIjN,EAAcC,EACrBiN,EAAGA,EAAIpN,EAAaC,IAErB,CAAEhD,EAAG,EAAGC,EAAG,EAAGiQ,EAAG7Q,KAAKmL,SAAU2F,EAAG9Q,KAAKoL,YAEtCpL,KAAA+Y,WAAa/Y,KAAKua,UAAU1J,EAAI2F,EAAexG,QAAUhQ,KAAKuZ,KAAO,IAAMvZ,KAAKuZ,KAChFvZ,KAAAgZ,YAAchZ,KAAKua,UAAUzJ,EAAI0F,EAAexG,QAAUhQ,KAAKsZ,KAAO,IAAMtZ,KAAKsZ,KAEtFtZ,KAAKsa,MAAMjU,QAAQ,CAACiP,EAAMV,KACxB,IAAKjU,EAAGC,EAAG8E,EAAO+F,GAAUzL,KAAK6Z,qBAAqB,CAACvE,EAAK3U,EAAG2U,EAAK1U,EAAG0U,EAAKwE,IAAMxE,EAAKyE,MAEnFU,GAAW,QAEkB,IAA7Bza,KAAK4S,WAAwB5S,KAAK4S,WAAgB,KACpD6H,EAAW7F,KAAc5U,KAAKiZ,UAAYjZ,KAAK+S,OAAO3S,OAAU,IAGlE,MAAMyT,EAAa4G,EAAWJ,EAAaxG,WAAcyB,EAAKzB,YAAc4C,EAAc5C,WACtF,GAAApR,EAAcoR,GAAa,CAE7B,MAAM8F,GACJc,EAAWJ,EAAaV,OAAUrE,EAAKqE,QAAUlD,EAAckD,QAE9DtL,QAAQ,MAAO,IACf7K,MAAM,KAAK,GAAGA,MAAM,KACpBC,IAAI,CAACpD,EAAGsF,IAAMA,EAAI,EAAIzC,OAAO7C,GAAKA,GAEf,IAAlBsZ,EAAOvZ,SACL8E,EAAAwV,YAAcf,EAAO,GACzBzU,EAAIyV,cAAgBhB,EAAO,GAAKvQ,EAAOuC,IACvCzG,EAAI0V,cAAgBjB,EAAO,GAAKvQ,EAAOuC,IACnCzG,EAAA2V,WAAalB,EAAO,GAExBA,EAAO,GAAK,EAAKjU,GAASiU,EAAO,IAAOjU,GAASiU,EAAO,GAAIhZ,GAAKgZ,EAAO,IACxEA,EAAO,GAAK,EAAKlO,GAAUkO,EAAO,IAAOlO,GAAUkO,EAAO,GAAI/Y,GAAK+Y,EAAO,KAG5EzU,EAAI4Q,UAAY9V,KAAKwa,iBAAiB7Z,EAAGC,EAAG8E,EAAO+F,EAAQoI,GACrD,MAAA6F,EAAe1Z,KAAKqD,UAAUiS,EAAKoE,aAAepE,EAAKoE,aAAejD,EAAciD,cAC1F9I,EAAe1L,EAAKvE,EAAGC,EAAG8E,EAAO+F,EAAQiO,GACzCxU,EAAI6Q,OAEJ7Q,EAAIwV,YAAc,mBAClBxV,EAAIyV,cAAgB,EACpBzV,EAAI0V,cAAgB,EACpB1V,EAAI2V,WAAa,CACnB,CAGIjG,GAAa5U,KAAK+S,OAAO3S,SAE3BwU,GAAa5U,KAAK+S,OAAO3S,QAG3BkV,EAAKhB,MAAQgB,EAAKhB,KAAKjO,QAAQ,CAAC0H,EAAS8G,KACvC,MAAMiG,EAAU9a,KAAKyV,WAAW3N,IAAIiG,EAAQpB,KACtCyN,EAAYpa,KAAKyV,WAAW3N,IAAIiG,EAAmB,WACzD,IAAK+M,EAAS,OACR,MAAAC,EAAaN,GAAYL,GAAcU,EAC7C,IAAKC,EAAW,OACV,MAAC9M,EAAWC,GAAclO,KAAK8N,uBAAuBiN,EAAWhN,EAASrI,EAAO+F,IAChFwK,EAAOC,GAAS,CACrBvV,EAAIX,KAAK8O,WAAWb,EAAWvI,GAAS1F,KAAKqD,UAAU0K,EAAQoI,KAAMzQ,GACrE9E,EAAIZ,KAAKqD,UAAU0K,EAAQqI,IAAK3K,IAElCzL,KAAKqN,UAAUnI,EAAK6V,EAAW9E,EAAOC,EAAOjI,EAAWC,KAG1DoH,EAAKgC,OAAShC,EAAKgC,MAAMjR,QAAgBwQ,IAEjC,MAAA9K,EAAQ0O,GAAYJ,EAAa1G,UACnC0G,EAAa1G,UACZkD,EAAKlD,WAAa8C,EAAc9C,UAE/BC,EAAa6G,GAAYJ,EAAazG,WACxCyG,EAAazG,WACZiD,EAAKjD,YAAc6C,EAAc7C,WAEhCoH,EAAOP,GAAYJ,EAAa9O,SAClCvL,KAAKqD,UAAUgX,EAAa9O,UAC5BvL,KAAKqD,UAAUwT,EAAKtL,UAAYkL,EAAclL,UAE5C0L,EAAawD,GAAYJ,EAAapD,WACxCoD,EAAapD,WACbJ,EAAKI,YAAcR,EAAcQ,YAAcJ,EAAKtL,UAAYkL,EAAclL,SAC5EuI,EAAW9R,EAAI6U,EAAM,YAAcA,EAAK/C,SAAW2C,EAAc3C,SACjEC,EAAc8C,EAAK9C,aAAe0C,EAAc1C,YAChD1O,EAAYwR,EAAKxR,WAAaoR,EAAcpR,UAClDH,EAAI2R,KAAO,GAAGjD,KAAcoH,EAAQ,OAAOjP,IACvC7G,EAAA4Q,UAAa2E,GAAYJ,EAAa3G,UAAa2G,EAAa3G,UAAamD,EAAKnD,WAAa+C,EAAc/C,UACjH,IAAInO,EAAQ,GAAIJ,EAAOrE,OAAO+V,EAAK1R,MAEnC,GAAI2O,EAAU,CAEZ,IAAIjO,EAAW7F,KAAKqD,UAAU0Q,EAAarO,GAC3CH,EAAQN,EAAUC,EAAK9C,EAAY+C,GAAO,IAAMU,EAAUR,EAAS,MAE3DE,EAAAJ,EAAK3B,MAAM,MAEf+B,EAAAc,QAAQ,CAACyQ,EAAME,KACf9R,EAAAsS,SACFV,EACAnW,EAAIX,KAAK8O,WAAW5J,EAAIO,YAAYqR,GAAMpR,MAAOA,GAAS1F,KAAKqD,UAAUwT,EAAKV,KAAMzQ,GACpF9E,EAAIZ,KAAKqD,UAAUwT,EAAKT,IAAK3K,IAAWuL,EAAY,GAAKhX,KAAKqD,UAAU4T,UAMhF,OAAOrM,EAAAxB,EAAAwO,YAAWhN,EAAArJ,KAAKvB,KAAMkF,EAC/B,CAWQ,gBAAAsV,CACN7Z,EACAC,EACA8E,EACA+F,EACAoI,GAEM,MAAA3O,IAAEA,GAAQlF,KAKT,OAHH6T,EAAWnU,SAAS,qBACtBmU,EHja2B,EAC/B3O,EACAvE,EACAC,EACAiQ,EACAC,EACA+C,KAEA,MAAMoH,EAAW,0BAA0BlY,KAAK8Q,GAA2B,GACxErQ,MAAM,KACNC,IAAK0B,GAAiBA,EAAKvC,QAC1B,IAAA8M,EAAMuL,EAAQC,QAASC,EAA8C,CAAC,EAAG,EAAG,EAAG,GAE/E,GAAAzL,EAAIhQ,SAAS,OAAQ,CACvBgQ,EAAMA,EAAI5N,MAAM,GAAG,GAAM,IAEnB,MAAAsZ,EAAkB1L,GAAgBnP,KAAKgX,IAAI7H,EAAM,IAAMnP,KAAKoP,IAC9DD,GAAO,GAAKA,EAAM,GAAIyL,EAAY,CAACxa,EAAGC,EAAIkQ,EAAGnQ,EAAIkQ,EAAGjQ,EAAIkQ,EAAID,EAAIuK,EAAe1L,EAAM,IAChFA,GAAO,IAAMA,EAAM,GAAIyL,EAAY,CAACxa,EAAGC,EAAIkQ,EAAInQ,EAAIkQ,EAAKC,EAAIsK,EAAe1L,EAAM,IAAK9O,GACtF8O,GAAO,IAAMA,EAAM,IAAKyL,EAAY,CAACxa,EAAIkQ,EAAGjQ,EAAIkQ,EAAInQ,EAAIkQ,EAAKC,EAAIsK,EAAe1L,EAAM,IAAK9O,GAC3F8O,GAAO,KAAOA,EAAM,IAAKyL,EAAY,CAACxa,EAAIkQ,EAAGjQ,EAAIkQ,EAAGnQ,EAAGC,EAAIiQ,EAAIuK,EAAe1L,EAAM,MACpFA,GAAO,KAAOA,EAAM,MAAiB,CAAC/O,EAAIkQ,EAAGjQ,EAAGD,EAAGC,EAAIiQ,EAAIuK,EAAe1L,EAAM,MAChFA,GAAO,KAAOA,EAAM,IAAKyL,EAAY,CAACxa,EAAIkQ,EAAGjQ,EAAGD,EAAImQ,EAAIsK,EAAe1L,EAAM,KAAM9O,EAAIkQ,GACvFpB,GAAO,KAAOA,EAAM,MAAiB,CAAC/O,EAAGC,EAAGD,EAAImQ,EAAIsK,EAAe1L,EAAM,KAAM9O,EAAIkQ,GACnFpB,GAAO,KAAOA,EAAM,MAAKyL,EAAY,CAACxa,EAAGC,EAAGD,EAAIkQ,EAAGjQ,EAAIkQ,EAAID,EAAIuK,EAAe1L,EAAM,MAC/F,MAESA,EAAIhQ,SAAS,OAAoByb,EAAA,CAACxa,EAAGC,EAAIkQ,EAAGnQ,EAAGC,GAC/C8O,EAAIhQ,SAAS,UAAWyb,EAAY,CAACxa,EAAGC,EAAGD,EAAGC,EAAIkQ,GAClDpB,EAAIhQ,SAAS,QAASyb,EAAY,CAACxa,EAAIkQ,EAAGjQ,EAAGD,EAAGC,GAChD8O,EAAIhQ,SAAS,WAAUyb,EAAY,CAACxa,EAAGC,EAAGD,EAAIkQ,EAAGjQ,IAEpD,MAAAya,EAAWnW,EAAIoW,wBAAyBH,EAAU1X,IAAIpD,GAAU,EAALA,IAEjE,OAAO4a,EAAQtW,OAAO,CAAC0W,EAAe9C,EAAW3K,KACzC,MAAAhB,EAAO2L,EAAK/U,MAAM,KAGjB6X,OAFa,IAAhBzO,EAAKxM,OAAcib,EAASE,aAAa3N,EAAOhB,EAAK,IAChC,IAAhBA,EAAKxM,QAAcib,EAASE,gBAAgB3O,GAC9CyO,GACNA,IG0XcG,CAAkBtW,EAAKvE,EAAGC,EAAG8E,EAAO+F,EAAQoI,IAEpDA,CACT,CAKQ,2BAAAgE,GACN,MAAMrB,eAAEA,EAAA5D,UAAgBA,EAAWqG,UAAAA,GAAcjZ,KAC5CA,KAAAwS,QAAUsF,KAAKC,MACd,MAAAmB,EAAYlZ,KAAKkZ,UAAYD,EAC7B5F,EAAQmD,EAAenD,MAC7B,IAAI1N,EAAI,EAAGqS,EAAY,EAAGyD,EAAY,EACtC,OAAS9V,GAAG,CACV,MAAMwT,EAAWnZ,KAAK+S,OAAO3S,OAASuF,EAAIiN,EAAcsG,EAClDhB,EAAYjH,EAAajR,KAAK2S,IAAKuG,EAAWC,EAAU3C,EAAehD,kBAAoB0F,EACjG,GAAIhB,EAAY7E,EAAO,CACrBrT,KAAKmZ,SAAY9F,EAAQ2E,EAAYE,EAAY7E,EAAS8F,EAAWsC,EACrE,KACF,CACYA,EAAAtC,EACAnB,EAAAE,CACd,CACF,CAKO,IAAAC,GAphBT,IAAA7U,EAAAsH,EAqhBsB,IAAd5K,KAAK6S,OAEJ7S,KAAAuS,UAAYuF,KAAKC,MAEtB/X,KAAK4S,eAAY,EAEjB5S,KAAK6S,KAAO,EAEZ,OAAAjI,GAAAtH,EAAAtD,KAAKoJ,QAAOgP,aAAZxN,EAAArJ,KAAA+B,GAEAtD,KAAKqY,MACP,CAMO,IAAAC,CAAM1K,GACX,GAAkB,IAAd5N,KAAK6S,MAA4B,IAAd7S,KAAK6S,KAA5B,CAEI,IAACjF,GAAmB,IAAVA,EAAa,CACzB,MAAMpJ,EAAWxE,KAAK+S,OAAOtP,IAAI8U,GAAQA,EAAKC,OAC9C5K,EAAQrJ,EAAaC,EACvB,CAEIoJ,EAAQ,GACV5N,KAAK6S,KAAO,EACZ7S,KAAK4S,WAAY,IAEjB5S,KAAK6S,KAAO,EACP7S,KAAA4S,UAAYhF,EAAQ5N,KAAK+S,OAAO3S,OAZC,CAc1C,CAMQ,GAAAiY,CAAKrV,EAAc,GA3jB7B,IAAAM,EA4jBI,MAAM6I,IAAEA,EAAK0G,KAAAA,EAAAE,OAAMA,EAAQH,UAAAA,EAAA4D,eAAWA,GAAmBxW,MACnDuT,iBAAEA,EAAAC,iBAAkBA,EAAkBH,MAAAA,GAAUmD,EAEtD,GAAa,IAAT3D,EAEF,YADA,OAAKvP,EAAAtD,KAAAyY,cAAcnV,EAAA/B,KAAAvB,KAAAA,KAAK+S,OAAO7R,KAAK,CAACqT,EAAO3G,IAAUA,IAAUgF,IAAc,CAAA,IAIhF,IAAsB,IAAlBA,EAAkB,OAET,IAATC,GAAe7S,KAAKmZ,eAAetB,8BAEvC,MAAMa,EAAgBZ,KAAKC,MAAQ/X,KAAKuS,UAClCoG,EAAcb,KAAKC,MAAQ/X,KAAKwS,QACtC,IAAIyG,EAAYjZ,KAAKiZ,UAEjB,GAAS,IAATpG,GAAc6F,EAAgBnF,EAAkB,CAElDvT,KAAK2S,IAAM+F,EAAgB1V,EAC3B,MAAMkV,EAAYjH,EAAYyH,EAAe,GAAKrF,EAAQ,GAAKE,GAE3D2E,IAAc7E,IAChBrT,KAAK6S,KAAO,GAEFoG,GAAYf,EAAYnF,EAAO3S,MAAA,MACzB,IAATyS,GAEGoG,GAAY5F,EAAQN,EAAO3S,YAEX,IAAxBwS,GAAwBA,GAAa,IACvC5S,KAAK6S,KAAO,EAEZ7S,KAAKkZ,UAAY,EACjBlZ,KAAKmZ,SAAW,IAEA,IAATtG,GAEToG,EAAYhI,EAAa0H,EAAa3Y,KAAKkZ,UAAWlZ,KAAKmZ,SAAU3F,GACjEmF,GAAenF,IACjBxT,KAAK6S,KAAO,IAId7S,KAAKsY,MAAO,GAEdtY,KAAKiZ,UAAYA,EACjBjZ,KAAKgS,OACL7F,EAAInM,KAAKqY,IAAIO,KAAK5Y,KAAMgD,EAAM,GAChC,CAOQ,oBAAA6W,EAAuBlZ,EAAGC,EAAGkZ,EAAM,EAAGC,EAAM,IAC5C,MAAAhB,UAAEA,EAAWC,WAAAA,GAAehZ,KAC5BgQ,EAAShQ,KAAKwW,eAAexG,OACnC,IAAIlM,EAAM,CACR9D,KAAKua,UAAW5Z,GAAKoY,EAAY/I,GAAUrP,EAC3CX,KAAKua,UAAW3Z,GAAKoY,EAAahJ,GAAUpP,GAMvC,OAJPkZ,GAAOC,GAAOjW,EAAIgB,KAChBiU,EAAYe,EAAM9J,GAAU8J,EAAM,GAClCd,EAAae,EAAM/J,GAAU+J,EAAM,IAE9BjW,CACT,CAOU,cAAA+U,CAAgBlY,EAAWC,GAC7B,MAAAwI,OAAEA,GAAWpJ,KACnB,MAAO,CAACW,EAAIyI,EAAOuC,IAAK/K,EAAIwI,EAAOuC,IACrC,6kBCjnBF,MAAqB+P,WAAoBvS,EAwDvC,WAAApD,CAAYqD,EAAwBnH,GAhFtC,IAAAqB,EAiFIiO,MAAMnI,EAAQ,CACZ1D,MAAOzD,EAAKyD,MACZ+F,OAAQxJ,EAAKwJ,SAzDjBzF,GAAAhG,KAAQ,SAA2B,IAEnCgG,GAAAhG,KAAQ,SAA2B,IAEnCgG,GAAAhG,KAAQ,QAAyB,IAEjCgG,GAAAhG,KAAQ,gBAAmC,CAAA,GAC3CgG,GAAAhG,KAAQ,iBACN,CAAA,GAEFgG,GAAAhG,KAAQ,eAAiC,CAAA,GACzCgG,GAAAhG,KAAQ,gBACN,CAAA,GACFgG,GAAAhG,KAAQ,cAA+B,QAE/BgG,GAAAhG,KAAA,oBACRgG,GAAAhG,KAAQ,YAAY,GACpBgG,GAAAhG,KAAQ,aAAa,GACrBgG,GAAAhG,KAAQ,iBAAiB,GACzBgG,GAAAhG,KAAQ,kBAAkB,GAC1BgG,GAAAhG,KAAQ,mBAAmB,GAC3BgG,GAAAhG,KAAQ,MAAM,MACdgG,GAAAhG,KAAQ,SAAmB,IAC3BgG,GAAAhG,KAAQ,aAAuB,IAC/BgG,GAAAhG,KAAQ,YAAsB,IAC9BgG,GAAAhG,KAAQ,YAAY,GACpBgG,GAAAhG,KAAQ,UAAoB,IAC5BgG,GAAAhG,KAAQ,WAAiC,IAEzCgG,GAAAhG,KAAQ,eAAyB,IAOjCgG,GAAAhG,KAAQ,OAAkB,GAOlBgG,GAAAhG,KAAA,aAEAgG,GAAAhG,KAAA,aAEAgG,GAAAhG,KAAA,iBAAiBwR,KAYvBxR,KAAKyR,SAASxP,GACdjC,KAAK0R,YACL1R,KAAK2R,eAEL,OAAOrO,EAAA8F,EAAAwI,iBAAcrQ,KAAKvB,MAE1BA,KAAK6R,MACP,CAEU,MAAArH,GA9FZ,IAAAlH,EAAAsH,EA+FI2G,MAAM/G,SACNxK,KAAK2b,wBACL,OAAA/Q,GAAAtH,EAAAtD,KAAKoJ,QAAO6I,cAAZrH,EAAArJ,KAAA+B,EACF,CAEU,SAAA4H,GACRlL,KAAK+Y,UAAY,EACjB/Y,KAAKgZ,WAAa,EAClBhZ,KAAK4b,eAAiB,EACtB5b,KAAK6b,gBAAkB,EACvB7b,KAAK8b,iBAAmB,EACxB9b,KAAK2S,IAAM,KACX3S,KAAK+b,OAAS,GACd/b,KAAKgc,WAAa,GAClBhc,KAAKic,UAAY,GACjBjc,KAAKuS,UAAY,EACjBvS,KAAKwS,QAAU,GACfxS,KAAKkc,SAAW,GAChBlc,KAAK4S,eAAY,EACjB5S,KAAK6S,KAAO,EACZtB,MAAMrG,WACR,CAMQ,QAAAuG,CAASxP,GACfjC,KAAKkP,KAAKlP,KAAM,QAASiC,EAAKyD,OAC9B1F,KAAKkP,KAAKlP,KAAM,SAAUiC,EAAKwJ,QAC/BzL,KAAKkP,KAAKlP,KAAM,SAAUiC,EAAK6Q,QAAU,IACzC9S,KAAKkP,KAAKlP,KAAM,SAAUiC,EAAK8Q,QAAU,IACzC/S,KAAKkP,KAAKlP,KAAM,QAASiC,EAAKka,OAAS,IACvCnc,KAAKkP,KAAKlP,KAAM,gBAAiBiC,EAAKgR,eAAiB,CAAA,GACvDjT,KAAKkP,KAAKlP,KAAM,eAAgBiC,EAAKiR,cAAgB,CAAA,GACrDlT,KAAKkP,KAAKlP,KAAM,cAAeiC,EAAK8N,IACtC,CAKQ,YAAA4B,GAED3R,KAAAmP,UAAUnP,KAAM,iBAAkB,KACrC,MAAMoJ,EAAS+J,GAAA,CACbiJ,KAAM,WACNC,WAAY,EACZC,WAAY,EACZjJ,MAAO,GACP8H,UAAW,EACX5H,iBAAkB,KAClBC,iBAAkB,MACfxT,KAAKiT,eAIH,OAFP7J,EAAOiT,WAAarc,KAAKqD,UAAU+F,EAAOiT,YAC1CjT,EAAOkT,WAAatc,KAAKqD,UAAU+F,EAAOkT,YACnClT,IAGJpJ,KAAAmP,UAAUnP,KAAM,gBAAiB,IAC7BmT,GAAA,CACLuG,aAAc,EACdhG,UAAW,OACXnI,SAAU,OACVoI,UAAW,aACXC,WAAY,MACZC,WAAY,gBACZC,UAAU,EACVC,YAAa,OACV/T,KAAKkT,cAGd,CAKQ,SAAAxB,GAED1R,KAAAoP,OAAO,QAAUjH,IACpBnI,KAAKiC,KAAKyD,MAAQyC,EAClBnI,KAAKwK,WAGFxK,KAAAoP,OAAO,SAAWjH,IACrBnI,KAAKiC,KAAKwJ,OAAStD,EACnBnI,KAAKwK,WAGFxK,KAAAoP,OACH,SACC4E,IACChU,KAAKiU,kBAEP,CAAEtL,MAAM,IAGL3I,KAAAoP,OACH,SACC4E,IACChU,KAAKiU,kBAEP,CAAEtL,MAAM,IAGL3I,KAAAoP,OACH,QACC4E,IACChU,KAAK2b,yBAEP,CAAEhT,MAAM,IAEV3I,KAAKoP,OAAO,gBAAiB,IAAMpP,KAAK2b,wBAAyB,CAC/DhT,MAAM,IAER3I,KAAKoP,OAAO,eAAgB,IAAMpP,KAAK2b,wBAAyB,CAC9DhT,MAAM,IAER3I,KAAKoP,OAAO,cAAe,IAAMpP,KAAK6R,OACxC,CAKa,IAAAA,GAAsB,OAAAqC,GAAAlU,KAAA,KAAA,YA3NrC,IAAAsD,EAAAsH,EA4NI5K,KAAKkL,YACC,MAAA9B,OAAEA,GAAWpJ,KAEnB,OAAOsD,EAAA8F,EAAA+K,eAAY5S,KAAKvB,MAExBA,KAAKuc,sBACLvc,KAAKgS,aAEChS,KAAKiU,iBAEX,OAAOrJ,EAAAxB,EAAAgL,cAAW7S,KAAKvB,KAAA,EACzB,CAEQ,qBAAA2b,GACN3b,KAAKuc,sBACLvc,KAAKgS,MACP,CAEQ,cAAAiC,GACC,OAAA,IAAInH,QAASC,IAClB,MAAMsH,EAAiB,CACrBvB,OAAQ9S,KAAK8S,OAAOrP,IAAKL,GAAUA,EAAMkR,MACzCvB,OAAQ/S,KAAK+S,OAAOtP,IAAK8Q,GAAUA,EAAMD,OAER3U,OAAO6H,KAAK6M,GAAiBhO,QAC7DoO,IACO,MAAAC,EAAaL,EAAeI,GAE5BE,EAA8B,GACpCD,GACEA,EAAWrO,QAAQ,CAACiO,EAAMM,KACxBN,GACEA,EAAKjO,QAAQ,CAAC0H,EAAS8G,KACVF,EAAA7P,KACT9E,KAAK8U,gBAAgBL,EAASG,EAAWC,QAInD/H,QAAQiI,IAAIJ,GAAYK,KAAK,KAC3BhV,KAAKuc,sBACLvc,KAAKgS,OACGjF,SAKlB,CASc,eAAA+H,CACZO,EACAT,EACAC,GACe,OAAAX,GAAAlU,KAAA,KAAA,YACf,OAAO,IAAI8M,QAAQ,CAACC,EAASC,KAC3B,IAAIsI,EAA8BtV,KAAKqV,GAAUT,GACjD,IAAKU,IAASA,EAAKhB,KAAM,OACnB,MAAAvG,EAAUuH,EAAKhB,KAAKO,GACrB9G,GAEL/N,KAAK0M,QAAQqB,EAAQpB,IAAKoB,GACvBiH,KAAYO,GAAYrB,GAAAlU,KAAA,KAAA,YACU,mBAAtB+N,EAAQyH,YACjBD,QAAgBzI,QAAQC,QACtBgB,EAAQyH,UAAUjU,KAAKvB,KAAMuV,KAGjCvV,KAAKyV,WAAWzN,IAAI+F,EAAa,IAAGwH,GAC5BxI,GAAA,IAET2I,MAAO7H,IACExD,QAAAC,MAAM,GAAG+K,KAAYT,WAAmBC,MAAahH,KACtDb,OAEZ,EACH,CAKU,mBAAAuP,GACF,MAAA/F,eAAEA,EAAgBC,cAAAA,GAAkBzW,MACpC6Q,EAAEA,EAAAC,EAAGA,GAAM9Q,KAAKwc,aAEhBC,EAAYzc,KAAK+S,OAAO3S,QACxB2Y,UAAEA,EAAWC,WAAAA,EAAA6C,gBAAYA,mBAAiBC,GAC9C9b,KAAK0c,4BACP1c,KAAK2c,aAAe,IAAInd,MAAMid,GAAW1G,UAAW,GAAEtS,IAAI,CAACmZ,EAAGjX,IAAMA,GACpE,IACEkX,EAAc,EACdC,EAAe,EACjB9c,KAAKmc,MAAM9V,QAAQ,CAAC0W,EAAMC,cAEpBhd,KAAK+b,OAAOiB,KAA4Bhd,KAAA+b,OAAOiB,GAAa,GAE1D,MAEAC,GAFQF,EAAKG,OAASld,KAAK2c,cAEXvc,OAEtByc,EAActc,KAAKC,IAAIqc,EAAahM,EAAIgL,EAAkBoB,GAC1DH,EAAevc,KAAKC,IAAIsc,EAAchM,EAAIgL,EAAmBmB,KAG/D,MAAMjO,iBAAEA,EAAAC,KAAkBA,GAASjP,KAAK+O,mBACtC8N,EACAC,GAEF9c,KAAKgP,iBAAmBA,EAExBhP,KAAKmc,MAAM9V,QAAQ,CAAC0W,EAAMC,KACxB,MAAMG,EAAQpE,EAAYiE,EACpBI,EAAQpE,EAAagE,EAC3B,IAAIK,EAAe,EAEnB,MAAMC,EXtJyB,EAAIC,EAAUL,KACjD,MAAMzZ,EAA4B,CAAA,EAAIK,EAAM,GAC5C,IAAA,IAAS6B,EAAI,EAAGA,EAAI4X,EAAInd,OAAQuF,IAC1BlC,EAAAkC,GAAK4X,EAAI5X,GAEf,IAAA,IAASA,EAAI,EAAGA,EAAIuX,EAAM9c,OAAQuF,IAAK,CACrC,MAAMd,EAAOpB,EAAIyZ,EAAMvX,IACnBd,IAAOf,EAAI6B,GAAKd,EACtB,CACO,OAAAf,GW6Ie0Z,CAChBxd,KAAK+S,OACLgK,EAAKG,OAASld,KAAK2c,cAGjB,IAACW,EAAUld,OAAQ,OACbkd,EAAAjX,QAAQ,CAACiP,EAAMV,KACvB,IAAKU,EAAM,OACX,MAAMmI,EACJ5B,EAAkBjH,EAAY4B,EAAe8F,WAAa,EACtDoB,EACJ5B,EAAmBlH,EAAY4B,EAAe6F,WAAa,GACtDsB,EAAIC,EAAIC,GAAW7d,KAAK8d,aAC7B,CAACX,EAAOO,EAAS5B,GACjB,CAAC2B,EAASL,EAAOvB,IAEHwB,GAAAQ,EAEV,MAAAhK,EAAayB,EAAKzB,YAAc4C,EAAc5C,WAChD,GAAApR,EAAcoR,GAAa,CAC7B,MAAM6F,EAAe1Z,KAAKqD,UACxBrB,EAAIsT,EAAM,gBACNA,EAAKoE,aACLjD,EAAciD,cAEpB9I,EAAe3B,EAAM0O,EAAIC,EAAI7E,EAAWA,EAAWW,GACnDzK,EAAK6G,UAAYjC,EACjB5E,EAAK8G,MACP,CAEAT,EAAKhB,MACHgB,EAAKhB,KAAKjO,QAAQ,CAAC0H,EAAS8G,KAC1B,MAAMiG,EAAU9a,KAAKyV,WAAW3N,IAAIiG,EAAQpB,KAC5C,IAAKmO,EAAS,OACd,MAAO7M,EAAWC,GAAclO,KAAK8N,uBACnCgN,EACA/M,EACAgL,EACAC,IAEK/C,EAAOC,GAAS,CACrByH,EACE3d,KAAK8O,WAAWb,EAAW8K,GAC3B/Y,KAAKqD,UAAU0K,EAAQoI,KAAM4C,GAC/B6E,EAAK5d,KAAKqD,UAAU0K,EAAQqI,IAAK4C,IAEnChZ,KAAKqN,UAAU4B,EAAM6L,EAAS7E,EAAOC,EAAOjI,EAAWC,KAG3DoH,EAAKgC,OACHhC,EAAKgC,MAAMjR,QAASwQ,IAEZ,MAAA9K,EAAQ8K,EAAKlD,WAAa8C,EAAc9C,UAExCC,EAAaiD,EAAKjD,YAAc6C,EAAc7C,WAE9CoH,EAAOhb,KAAKqD,UAAUwT,EAAKtL,UAAYkL,EAAclL,UAErD0L,EACJJ,EAAKI,YACLR,EAAcQ,YACdJ,EAAKtL,UACLkL,EAAclL,SACVuI,EAAW9R,EAAI6U,EAAM,YACvBA,EAAK/C,SACL2C,EAAc3C,SACZC,EAAc8C,EAAK9C,aAAe0C,EAAc1C,YAChD1O,EAAYwR,EAAKxR,WAAaoR,EAAcpR,UAClD4J,EAAK4H,KAAO,GAAGjD,KAAcoH,EAAQ,OAAOjP,IACvCkD,EAAA6G,UAAYe,EAAKnD,WAAa+C,EAAc/C,UACjD,IAAInO,EAAQ,GACVJ,EAAOrE,OAAO+V,EAAK1R,MAErB,GAAI2O,EAAU,CAEZ,IAAIjO,EAAW7F,KAAKqD,UAAU0Q,EAAagF,GACnCxT,EAAAN,EACNgK,EACA7M,EAAY+C,GACZ,IAAMU,EACNR,EACF,MAEQE,EAAAJ,EAAK3B,MAAM,MAEf+B,EAAAc,QAAQ,CAACyQ,EAAME,KACd/H,EAAAuI,SACHV,EACA6G,EACE3d,KAAK8O,WAAWG,EAAKxJ,YAAYqR,GAAMpR,MAAOqT,GAC9C/Y,KAAKqD,UAAUwT,EAAKV,KAAM4C,GAC5B6E,EACE5d,KAAKqD,UAAUwT,EAAKT,IAAK4C,IACxBhC,EAAY,GAAKhX,KAAKqD,UAAU4T,UAK7C,MAAO0G,EAAIC,EAAIG,EAAIC,GAAMhe,KAAK8d,aAC5B,CAACX,EAAO,EAAGpE,EAAWsE,GACtB,CAAC,EAAGD,EAAOC,EAAcrE,IAE3B,IAAIiF,EAAUZ,EACP,KAAAY,EAAUnB,EAAeO,GAAc,CAC5C,MAAOa,EAAOC,GAASne,KAAK8d,aAAa,CAACH,EAAIM,GAAU,CAACA,EAASL,IAC7D5d,KAAAqN,UACH4B,EACAD,EACA2O,EACAC,EACAG,EACAC,EACAE,EACAC,EACAJ,EACAC,GAESC,GAAAZ,CACb,GAEJ,CAKU,UAAAb,GACR,MAAMpT,OAAEA,EAAAlE,IAAQA,EAAKsR,eAAAA,EAAAC,cAAgBA,GAAkBzW,KAE/C,OAAAA,KAAKua,UAAYva,KAAK8S,OAAOnO,OACnC,EAAGhE,IAAGC,IAAGiQ,IAAGC,KAAK1N,EAAOyS,KACtB,MAAOnS,EAAYC,EAAeC,EAAaC,GAC7CV,EAAeC,EAAOpD,KAAKqD,UAAUuV,KAAK5Y,OACtCqQ,EAAIjN,EAAMsW,aAAe1Z,KAAKqD,UAAUD,EAAMsW,cAAgB,EAE9D7F,EAAazQ,EAAMyQ,YAAc4C,EAAc5C,WA+B9C,OA9BHpR,EAAcoR,KAChBjD,EAAe1L,EAAKvE,EAAGC,EAAGiQ,EAAGC,EAAGT,GAChCnL,EAAI4Q,UAAYjC,EAChB3O,EAAI6Q,QAGN3S,EAAMkR,MACJlR,EAAMkR,KAAKjO,QAAQ,CAAC0H,EAAS8G,KAC3B,MAAMmB,EAAWhW,KAAKyV,WAAW3N,IAAIiG,EAAQpB,KAC7C,IAAKqJ,EAAU,OAEf,MAAO/H,EAAWC,GAAclO,KAAK8N,uBACnCkI,EACAjI,EACA8C,EACAC,IAEKmF,EAAOC,GAAS,CACrBlW,KAAK8O,WAAWb,EAAW4C,GAAK7Q,KAAKqD,UAAU0K,EAAQoI,KAAMtF,GAC7D7Q,KAAKqD,UAAU0K,EAAQqI,IAAKtF,IAEzB9Q,KAAAqN,UACHnI,EACA8Q,EACArV,EAAIsV,EACJrV,EAAIsV,EACJjI,EACAC,KAGC,CACLvN,EAAGA,EAAIiD,EACPhD,EAAGA,EAAI8C,EACPmN,EAAGA,EAAIjN,EAAcC,EACrBiN,EAAGA,EAAIpN,EAAaC,IAGxB,CAAEhD,EAAG,EAAGC,EAAG,EAAGiQ,EAAG7Q,KAAKmL,SAAU2F,EAAG9Q,KAAKoL,WAE5C,CAKU,IAAA4G,GAvgBZ,IAAA1O,EAwgBI,MAAM8F,OAAEA,EAAAlE,IAAQA,EAAKsR,eAAAA,EAAAC,cAAgBA,GAAkBzW,KAEvD,OAAOsD,EAAA8F,EAAAsN,aAAYpT,EAAA/B,KAAKvB,KAAMkF,GAE9BA,EAAIwG,UAAU,EAAG,EAAG1L,KAAKmL,SAAUnL,KAAKoL,WAExC,MAAMzK,EAAEA,EAAGC,EAAAA,EAAAiQ,EAAGA,IAAGC,GAAM9Q,KAAKwc,aAExB,IAACxc,KAAKgP,iBAAkB,OACtB,MAAA+J,UACJA,EAAAC,WACAA,EAAA4C,eACAA,EAAAC,gBACAA,EAAAC,iBACAA,GACE9b,KACJA,KAAKmc,MAAM9V,QAAQ,CAAC0W,EAAMC,KAClB,MAAAE,EAAQH,EAAKG,OAASld,KAAK2c,aAE3ByB,EAAKxC,EAAiBsB,EAAM9c,OAE5BY,EAAQhB,KAAK8d,eACfhN,EAAIgL,GAAoB,IACxBjL,EAAIgL,GAAmB,GAE3B,IAAIE,EAAS/b,KAAK+b,OAAOiB,GAAahc,EAElC+a,EAAS,IACXA,EAAUA,EAASqC,EAAMA,GAEvBrC,EAASqC,IACXrC,GAAkBqC,GAEpB,MAAOC,EAAIC,EAAIC,EAAIC,GAAMxe,KAAK8d,aAC5B,CAAC/E,EAAYiE,EAAWjB,EAAQhD,EAAWjI,GAC3C,CAACiL,EAAQ/C,EAAagE,EAAWnM,EAAGmI,KAE/ByF,EAAIC,EAAIC,EAAIC,GAAM5e,KAAK8d,aAC5B,CAACnd,EAAIkb,EAAkBmB,EAAWpc,EAAGmY,EAAWjI,GAChD,CAACnQ,EAAGC,EAAIkb,EAAmBkB,EAAWnM,EAAGmI,IAEtChZ,KAAAqN,UACHnI,EACAlF,KAAKgP,iBACLqP,EACAC,EACAC,EACAC,EACAC,EACAC,EACAC,EACAC,IAGN,CAKQ,2BAAA/G,CAA4BmF,GAClC,MAAMxG,eAAEA,EAAA5D,UAAgBA,EAAWgJ,eAAAA,GAAmB5b,KAChD+c,EAAO/c,KAAKmc,MAAMa,GAClBE,EAAQH,EAAKG,OAASld,KAAK2c,aACjC,IAAKO,EAAM9c,aAAgC,IAAtBwS,EAAsB,OAC3C,MAAMS,EAAQ9S,KAAKE,IAAIsc,EAAK1J,OAASmD,EAAenD,OAC9C8H,EAAY4B,EAAK5B,WAAa3E,EAAe2E,UAC7C0D,EAAa3B,EAAMlY,UACtBkS,GAAeA,IAAetE,EAAUoK,IAErCoB,EAAKxC,EAAiBsB,EAAM9c,OAC5B4b,EAAchc,KAAKgc,WAAWgB,GAAahd,KAAK+b,OAAOiB,GAC7Dhd,KAAKwS,QAAQwK,GAAalF,KAAKC,MAC/B,IAAIpS,EAAI,EACR,OAASA,GAAG,CACV,MAAMsW,EACJL,EAAiBiD,EAAaT,EAAKzY,EAAIwV,EAAYa,EAC/C9D,EACJjH,EACEjR,KAAK2S,IACLqJ,EACAC,EACAzF,EAAehD,kBACbwI,EACN,GAAIzb,KAAKE,IAAIyX,GAAa7E,EAAO,CAC1BrT,KAAAic,UAAUe,GAAaf,EAC5B,KACF,CACF,CACF,CAEQ,eAAA6C,GAlmBV,IAAAxb,EAmmBI,SAAS,OAAAA,EAAKtD,KAAA4S,gBAAW,EAAAtP,EAAAlD,SAAUJ,KAAK4S,UAAUmM,MAAOtV,QAAwB,IAAfA,EACpE,CAEQ,gBAAAuV,GACN,OAAOhf,KAAKmc,MAAM4C,MAAM,CAAChC,EAAMC,MACfD,EAAKG,OAASld,KAAK2c,cACnBvc,QAAuC,IAA7BJ,KAAKkc,SAASc,GAE1C,CAEQ,WAAAiC,GACN,IAAKjf,KAAK8e,kBAA0B,OACpC,MAAMlM,EAAY5S,KAAK4S,UACnB,IAAAnJ,EAAOmJ,EAAU,GACrB,IAAA,IAASjN,EAAI,EAAGA,EAAI3F,KAAKmc,MAAM/b,OAAQuF,IAAK,CACpC,MAAAoX,EAAO/c,KAAKmc,MAAMxW,GAClBuZ,EAAWtM,EAAUjN,GACrBuX,EAAQH,EAAKG,OAASld,KAAK2c,aACjC,KAAK,MAAAO,OAAA,EAAAA,EAAOxd,SAASwf,KAAazV,IAASyV,EAAU,CAC5CzV,GAAA,EACP,KACF,CACF,CACO,OAAAzJ,KAAK+S,OAAO7R,KAAK,CAACqT,EAAO3G,IAAUA,IAAUnE,SAAS,CAC/D,CAKO,IAAA0O,GAhoBT,IAAA7U,EAAAsH,EAioBsB,IAAd5K,KAAK6S,OAEJ7S,KAAAuS,UAAYuF,KAAKC,MAEtB/X,KAAK4S,eAAY,EACjB5S,KAAKgc,WAAa,GAClBhc,KAAKic,UAAY,GACjBjc,KAAKwS,QAAU,GACfxS,KAAKkc,SAAWlc,KAAKmc,MAAM1Y,IAAKsZ,IAChBA,EAAKG,OAASld,KAAK2c,cACpBvc,OAAS,EAAI,GAG5BJ,KAAK6S,KAAO,EAEZ,OAAAjI,GAAAtH,EAAAtD,KAAKoJ,QAAOgP,aAAZxN,EAAArJ,KAAA+B,GAEAtD,KAAKqY,MACP,CAEO,IAAAC,CAAK1K,EAA0BoP,GArpBxC,IAAA1Z,EAspBQ,GAAc,IAAdtD,KAAK6S,KAAL,CAEA,GAAqB,iBAAdmK,EAAwB,CAC7B,IAAC9Z,OAAOic,UAAUnC,IAAcA,EAAY,GAAKA,GAAahd,KAAKmc,MAAM/b,OAC3E,OAAOiK,QAAQC,MAAM,QAAQsD,MAAUoP,qBAErC,GAAiB,iBAAVpP,EACF,OAAAvD,QAAQC,MAAM,QAAQ8U,KAAKC,UAAUzR,OAAWoP,mBAElC,IAAnBhd,KAAK4S,WAAyB5S,KAAK4S,UAAUxS,SAC1CJ,KAAA4S,UAAY,IAAIpT,MAAMQ,KAAKmc,MAAM/b,QAAQ2V,UAAW,IAEtD/V,KAAA4S,UAAUoK,GAAapP,CAAA,MAC9B,GAA4B,iBAAVA,EACX5N,KAAA4S,UAAY,IAAIpT,MAAMQ,KAAKmc,MAAM/b,QAAQ2V,KAAKnI,OAC1C,KAAApM,EAAaoM,EAAO,SAS7B,OADA5N,KAAKsY,MAAO,GACLjO,QAAQC,MAAM,2BAA2BsD,GARhD,GAAIA,EAAMxN,SAAWJ,KAAKmc,MAAM/b,OAI9B,OADAJ,KAAKsY,MAAO,GACLjO,QAAQC,MAAM,SAASsD,gBAH9B5N,KAAK4S,UAAYhF,CAQrB,EAEI,OAAAtK,EAAKtD,KAAA4S,gBAAW,EAAAtP,EAAA5D,UAAc,KAChCM,KAAK4S,UAAY,GACjB5S,KAAKkc,SAAWlc,KAAKkc,SAASzY,IAAI,IAAM,GAExCzD,KAAK6S,KAAO,GAGZ7S,KAAK6S,KAAO,CAlCO,CAoCvB,CAMQ,GAAAwF,CAAIrV,EAAc,GAhsB5B,IAAAM,EAAAsH,EAisBI,MAAMuB,IAAEA,EAAAqK,eAAKA,EAAgBoF,eAAAA,EAAAO,MAAgBA,GAAUnc,MACjDuT,iBAAEA,EAAkBC,iBAAAA,GAAqBgD,EACzC5D,EAAY5S,KAAK4S,UACnB,GAAc,IAAd5S,KAAK6S,KAIP,YAHI7S,KAAK8e,mBAAqB9e,KAAKgf,qBACjC,OAAK1b,EAAAtD,KAAAyY,cAAcnV,EAAA/B,KAAAvB,KAAAA,KAAKif,iBAK5B,QAAkB,IAAdrM,IAAyBA,EAAUxS,OAAQ,OAE/C,MAAMsY,EAAgBZ,KAAKC,MAAQ/X,KAAKuS,UAuDpC,GAtDAmG,GAAiBnF,GAAkC,IAAdvT,KAAK6S,OAC5C7S,KAAK6S,KAAO,GAGRsJ,EAAA9V,QAAQ,CAAC0W,EAAMC,KACb,MAAAE,EAAQH,EAAKG,OAASld,KAAK2c,aACjC,IAAKO,IAAUA,EAAM9c,OAAQ,OACvB,MAAAge,EAAKxC,EAAiBsB,EAAM9c,OAC5BiT,EAAQ9S,KAAKE,IAAIsc,EAAK1J,OAASmD,EAAenD,OAC9C8H,EAAY4B,EAAK5B,WAAa3E,EAAe2E,UAC7Ce,EAAWlc,KAAKkc,SAASc,IAAc,EAC7C,IAAIjB,EAAS,EACXuD,EAAatf,KAAK+b,OAAOiB,GAC3B,GAAKd,EAAL,CACI,GAAa,IAAbA,GAAkBxD,EAAgBnF,EAAkB,CAGtDvT,KAAK2S,IAAM+F,EAAgB1V,EAC3B,MAAMkV,EAAYjH,EAAYyH,EAAe,EAAGrF,EAAOE,GAEnD2E,IAAc7E,IACXrT,KAAAkc,SAASc,GAAa,GAEnBjB,GAAAuD,EAAapH,EAAYiD,GAAaiD,CAAA,MAClD,GAAwB,IAAblC,EAGCH,GAAAuD,EAAajM,EAAQ8H,GAAaiD,OAEL,KAAnC,MAAAxL,OAAA,EAAAA,EAAYoK,MACThd,KAAAkc,SAASc,GAAa,EACtBhd,KAAA+b,OAAOiB,GAAajB,EACzB/b,KAAK6X,4BAA4BmF,SAErC,GAAwB,IAAbd,EAAgB,CAGnB,MAAAF,EAAahc,KAAKgc,WAAWgB,GAC7Bf,EAAYjc,KAAKic,UAAUe,GAC3BrE,EAAcb,KAAKC,MAAQ/X,KAAKwS,QAAQwK,GAC9CjB,EAAS9K,EACP0H,EACAqD,EACAC,EACAzI,GAEEmF,GAAenF,IACjBuI,EAASC,EAAaC,EACjBjc,KAAAkc,SAASc,GAAa,EAE/B,CACKhd,KAAA+b,OAAOiB,GAAajB,CAtCV,IAwCjB/b,KAAKgS,OACDhS,KAAKgf,mBAKP,OAJAhf,KAAK6S,KAAO,OACR7S,KAAK8e,oBACP,OAAKlU,EAAA5K,KAAAyY,cAAc7N,EAAArJ,KAAAvB,KAAAA,KAAKif,iBAI5B9S,EAAInM,KAAKqY,IAAIO,KAAK5Y,KAAMgD,EAAM,GAChC,CAGQ,YAAA8a,CAAgByB,EAAMpO,GAC5B,MAAoC,eAA7BnR,KAAKwW,eAAe4F,KAAwBjL,EAAIoO,CACzD,CAGQ,yBAAA7C,GACA,MAAAN,EAAOpc,KAAKwW,eAAe4F,KAC3BoD,EAAWxf,KAAKmc,MAAM/b,QACtBkc,WAAEA,EAAAD,WAAYA,GAAerc,KAAKwW,gBAClC7V,EAAEA,IAAGC,EAAGiQ,EAAAA,EAAAC,EAAGA,GAAM9Q,KAAKua,WAAava,KAAKwc,aAC9C,IAAIzD,EAAY,EACdC,EAAa,EACb6C,EAAkB,EAClBC,EAAmB,EAgBd,MAfM,eAATM,GACFpD,EAAahZ,KAAKgZ,YACflI,EAAIuL,GAAcmD,EAAW,IAAMA,EACtCzG,EAAY/Y,KAAK+Y,UAAYC,IAE7BD,EAAY/Y,KAAK+Y,WAAalI,EAAIyL,GAAckD,EAAW,IAAMA,EACjExG,EAAahZ,KAAKgZ,WAAaD,GAEf8C,EAAA7b,KAAK6b,gBAAkB7b,KAAK+Y,UAAYuD,EACvCR,EAAA9b,KAAK8b,iBAAmB9b,KAAKgZ,WAAaqD,EAE3Drc,KAAK4b,eADM,eAATQ,EACoBP,EAEAC,EAEjB,CACL/C,YACAC,aACA6C,kBACAC,mBAEJ,EC3xBW,MAAA2D,GAAW,CAACC,EAAc9J,KAC/B,MAAA+J,EAASjW,SAASG,cAAc,UAChC3E,EAAMya,EAAO5V,WAAW,OACxBrE,MAAEA,EAAO+F,OAAAA,GAAWiU,EAMnB,OALPC,EAAOja,MAAQA,EACfia,EAAOlU,OAASA,EAChBmF,EAAe1L,EAAK,EAAG,EAAGQ,EAAO+F,EAAQmK,GACzC1Q,EAAI0a,OACJ1a,EAAImI,UAAUqS,EAAK,EAAG,EAAGha,EAAO+F,GACzBkU,GASIE,GAAU,CACrBH,EACAG,KAEM,MAAAF,EAASjW,SAASG,cAAc,UAChC3E,EAAMya,EAAO5V,WAAW,OACxBrE,MAAEA,EAAO+F,OAAAA,GAAWiU,EAItB,GAHJC,EAAOja,MAAQA,EACfia,EAAOlU,OAASA,EAEU,iBAAfvG,EAAI5C,OACT4C,EAAA5C,OAAS,WAAqB,IAAVud,MACxB3a,EAAImI,UAAUqS,EAAK,EAAG,EAAGha,EAAO+F,OAC3B,CACLvG,EAAImI,UAAUqS,EAAK,EAAG,EAAGha,EAAO+F,GAChC,MAAMqU,EAAY5a,EAAIwI,aAAa,EAAG,EAAGhI,EAAO+F,IAC1CxJ,KAAEA,GAAS6d,EACX3f,EAAM8B,EAAK7B,OACjB,IAAA,IAASuF,EAAI,EAAGA,EAAIxF,EAAKwF,GAAK,EAAG,CACzB,MAAA7C,EAAQb,EAAK0D,EAAI,GACT,IAAV7C,IAAab,EAAK0D,EAAI,GAAK7C,EAAQ+c,EACzC,CACI3a,EAAAyI,aAAamS,EAAW,EAAG,EACjC,CACO,OAAAH"}
@@ -0,0 +1 @@
1
+ !function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports):"function"==typeof define&&define.amd?define(["exports"],e):e((t="undefined"!=typeof globalThis?globalThis:t||self).LuckyCanvas={})}(this,function(t){"use strict";Array.prototype.includes||Object.defineProperty(Array.prototype,"includes",{value:function(t,e){if(null==this)throw new TypeError('"this" is null or not defined');var i=Object(this),s=i.length>>>0;if(0===s)return!1;var h=0|e,n=Math.max(h>=0?h:s-Math.abs(h),0);function r(t,e){return t===e||"number"==typeof t&&"number"==typeof e&&isNaN(t)&&isNaN(e)}for(;n<s;){if(r(i[n],t))return!0;n++}return!1}}),String.prototype.includes||(String.prototype.includes=function(t,e){return"number"!=typeof e&&(e=0),!(e+t.length>this.length)&&-1!==this.indexOf(t,e)}),Array.prototype.find||Object.defineProperty(Array.prototype,"find",{value:function(t){if(null==this)throw new TypeError('"this" is null or not defined');var e=Object(this),i=e.length>>>0;if("function"!=typeof t)throw new TypeError("predicate must be a function");for(var s=arguments[1],h=0;h<i;){var n=e[h];if(t.call(s,n,h,e))return n;h++}}});const e=(t,...e)=>e.some(e=>Object.prototype.toString.call(t).slice(8,-1).toLowerCase()===e),i=(t,e)=>Object.prototype.hasOwnProperty.call(t,e),s=t=>[].filter.call(t,t=>"\n"!==t).join(""),h=t=>{if("string"!=typeof t)return!1;if("transparent"===(t=t.toLocaleLowerCase().trim()))return!1;if(/^rgba/.test(t)){const i=/([^\s,]+)\)$/.exec(t);if(0===(null===(e=i)?0:"object"==typeof e?NaN:"number"==typeof e?e:"string"==typeof e?"%"===e[e.length-1]?Number(e.slice(0,-1))/100:Number(e):NaN))return!1}var e;return!0},n=(t,s)=>{var h;let n=(null==(h=t.padding)?void 0:h.split(" ").map(t=>s(t)))||[0],r=0,o=0,a=0,l=0;switch(n.length){case 1:r=o=a=l=n[0];break;case 2:r=o=n[0],a=l=n[1];break;case 3:r=n[0],a=l=n[1],o=n[2];break;default:r=n[0],o=n[1],a=n[2],l=n[3]}const c={paddingTop:r,paddingBottom:o,paddingLeft:a,paddingRight:l};for(let h in c)c[h]=i(t,h)&&e(t[h],"string","number")?s(t[h]):c[h];return[r,o,a,l]},r=(t,e=300)=>{let i=null;return function(...s){i||(i=setTimeout(()=>{t.apply(this,s),clearTimeout(i),i=null},e))}},o=t=>{const e=[],i=t.map(t=>Number(t)).reduce((t,i)=>{if(i>0){const s=t+i;return e.push(s),s}return e.push(NaN),t},0),s=Math.random()*i;return e.findIndex(t=>s<=t)},a=(t,e,i,s=1/0)=>{s<=0&&(s=1/0);let h="";const n=[],r=t.measureText("...").width;for(let o=0;o<e.length;o++){h+=e[o];let a=t.measureText(h).width;const l=i(n);if(s===n.length+1&&(a+=r),l<0)return n;if(a>l&&(n.push(h.slice(0,-1)),h=e[o]),s===n.length)return n[n.length-1]+="...",n}return h&&n.push(h),n.length||n.push(e),n};var l="1.7.26",c=Object.defineProperty,d=(t,e,i)=>((t,e,i)=>e in t?c(t,e,{enumerable:!0,configurable:!0,writable:!0,value:i}):t[e]=i)(t,"symbol"!=typeof e?e+"":e,i);class g{constructor(){d(this,"subs"),this.subs=[]}addSub(t){this.subs.includes(t)||this.subs.push(t)}notify(){this.subs.forEach(t=>{t.update()})}}d(g,"target");const f="__proto__"in{};function u(t,e,i,s){Object.defineProperty(t,e,{value:i,enumerable:!!s,writable:!0,configurable:!0})}const p=Array.prototype,m=Object.create(p);["push","pop","shift","unshift","sort","splice","reverse"].forEach(t=>{m[t]=function(...e){const i=p[t].apply(this,e),s=this.__luckyOb__;return["push","unshift","splice"].includes(t)&&s.walk(this),s.dep.notify(),i}});var w=Object.defineProperty,b=(t,e,i)=>((t,e,i)=>e in t?w(t,e,{enumerable:!0,configurable:!0,writable:!0,value:i}):t[e]=i)(t,"symbol"!=typeof e?e+"":e,i);class y{constructor(t){b(this,"value"),b(this,"dep"),this.dep=new g,u(t,"__luckyOb__",this),Array.isArray(t)&&(f?t.__proto__=m:Object.getOwnPropertyNames(m).forEach(e=>{u(t,e,m[e])})),this.walk(t)}walk(t){Object.keys(t).forEach(e=>{S(t,e,t[e])})}}function v(t){if(!t||"object"!=typeof t)return;let e;return e="__luckyOb__"in t?t.__luckyOb__:new y(t),e}function S(t,e,i){const s=new g,h=Object.getOwnPropertyDescriptor(t,e);if(h&&!1===h.configurable)return;const n=h&&h.get,r=h&&h.set;n&&!r||2!==arguments.length||(i=t[e]);let o=v(i);Object.defineProperty(t,e,{get:()=>{const e=n?n.call(t):i;return g.target&&(s.addSub(g.target),o&&o.dep.addSub(g.target)),e},set:e=>{e!==i&&(i=e,n&&!r||(r?r.call(t,e):i=e,o=v(e),s.notify()))}})}var C=Object.defineProperty,z=(t,e,i)=>((t,e,i)=>e in t?C(t,e,{enumerable:!0,configurable:!0,writable:!0,value:i}):t[e]=i)(t,"symbol"!=typeof e?e+"":e,i);let x=0;class k{constructor(t,e,i,s={}){z(this,"id"),z(this,"$lucky"),z(this,"expr"),z(this,"cb"),z(this,"deep"),z(this,"getter"),z(this,"value"),this.id=x++,this.$lucky=t,this.expr=e,this.deep=!!s.deep,this.getter="function"==typeof e?e:function(t){t+=".";let e=[],i="";for(let s=0;s<t.length;s++){let h=t[s];if(/\[|\./.test(h))e.push(i),i="";else{if(/\W/.test(h))continue;i+=h}}return function(t){return e.reduce((t,e)=>t[e],t)}}(e),this.cb=i,this.value=this.get()}get(){g.target=this;const t=this.getter.call(this.$lucky,this.$lucky);return this.deep&&function(t){const i=t=>{e(t,"array","object")&&Object.keys(t).forEach(e=>{const s=t[e];i(s)})};i(t)}(t),g.target=null,t}update(){const t=this.get(),e=this.value;this.value=t,this.cb.call(this.$lucky,t,e)}}var $=Object.defineProperty,I=(t,e,i)=>((t,e,i)=>e in t?$(t,e,{enumerable:!0,configurable:!0,writable:!0,value:i}):t[e]=i)(t,"symbol"!=typeof e?e+"":e,i);class O{constructor(t,e){I(this,"version",l),I(this,"config"),I(this,"ctx"),I(this,"htmlFontSize",16),I(this,"rAF",function(){}),I(this,"boxWidth",0),I(this,"boxHeight",0),I(this,"data"),"string"==typeof t?t={el:t}:1===t.nodeType&&(t={el:"",divElement:t}),this.config=t,this.data=e,t.flag||(t.flag="WEB"),t.el&&(t.divElement=document.querySelector(t.el)),t.divElement&&(t.canvasElement=document.createElement("canvas"),t.divElement.appendChild(t.canvasElement)),t.canvasElement&&(t.ctx=t.canvasElement.getContext("2d"),t.canvasElement.setAttribute("package",`@vnpn/lucky-canvas-core@${l}`),t.canvasElement.addEventListener("click",t=>this.handleClick(t))),this.ctx=t.ctx,this.initWindowFunction(),this.config.ctx||console.error("无法获取到 CanvasContext2D"),window&&"function"==typeof window.addEventListener&&window.addEventListener("resize",r(()=>this.resize(),300)),window&&"function"==typeof window.MutationObserver&&new window.MutationObserver(()=>{this.resize()}).observe(document.documentElement,{attributes:!0})}resize(){var t,e;null==(e=(t=this.config).beforeResize)||e.call(t),this.setHTMLFontSize(),this.setDpr(),this.resetWidthAndHeight(),this.zoomCanvas()}initLucky(){if(this.resize(),!this.boxWidth||!this.boxHeight)return console.error("无法获取到宽度或高度")}handleClick(t){}setHTMLFontSize(){window&&window.getComputedStyle&&(this.htmlFontSize=+window.getComputedStyle(document.documentElement).fontSize.slice(0,-2))}clearCanvas(){const[t,e]=[this.boxWidth,this.boxHeight];this.ctx.clearRect(-t,-e,2*t,2*e)}setDpr(){const{config:t}=this;t.dpr||(window?window.dpr=t.dpr=window.devicePixelRatio||1:t.dpr||console.error(t,"未传入 dpr 可能会导致绘制异常"))}resetWidthAndHeight(){const{config:t,data:e}=this;let i=0,s=0;t.divElement&&(i=t.divElement.offsetWidth,s=t.divElement.offsetHeight),this.boxWidth=this.getLength(e.width||t.width)||i,this.boxHeight=this.getLength(e.height||t.height)||s,t.divElement&&(t.divElement.style.overflow="hidden",t.divElement.style.width=this.boxWidth+"px",t.divElement.style.height=this.boxHeight+"px")}zoomCanvas(){const{config:t,ctx:e}=this,{canvasElement:i,dpr:s}=t,[h,n]=[this.boxWidth*s,this.boxHeight*s];i&&(i.width=h,i.height=n,i.style.width=`${h}px`,i.style.height=`${n}px`,i.style["transform-origin"]="left top",i.style.transform=`scale(${1/s})`,e.scale(s,s))}initWindowFunction(){const{config:t}=this;if(window)return this.rAF=window.requestAnimationFrame||window.webkitRequestAnimationFrame||window.mozRequestAnimationFrame||function(t){window.setTimeout(t,1e3/60)},t.setTimeout=window.setTimeout,t.setInterval=window.setInterval,t.clearTimeout=window.clearTimeout,void(t.clearInterval=window.clearInterval);if(t.rAF)this.rAF=t.rAF;else if(t.setTimeout){const e=t.setTimeout;this.rAF=t=>e(t,16.7)}else this.rAF=t=>setTimeout(t,16.7)}isWeb(){return["WEB","UNI-H5","TARO-H5"].includes(this.config.flag)}loadImg(t,e,i="$resolve"){return new Promise((s,h)=>{if(t||h(`=> '${e.src}' 不能为空或不合法`),"WEB"!==this.config.flag)return e[i]=s,void(e.$reject=h);{let i=new Image;i.crossorigin="anonymous",i.onload=()=>s(i),i.onerror=()=>h(`=> '${e.src}' 图片加载失败`),i.src=t}})}drawImage(t,e,...i){var s,h;let n;const{flag:r,dpr:o}=this.config;if(["WEB","MP-WX"].includes(r))n=e;else{if(!["UNI-H5","UNI-MP","TARO-H5","TARO-MP"].includes(r))return console.error("意料之外的 flag, 该平台尚未兼容!");n=e.path}const a=null==(h=(s=n.canvas||n).getContext)?void 0:h.call(s,"2d");if(a&&!this.isWeb()){i=i.map(t=>t*o);const e=a.getImageData(...i.slice(0,4));t.putImageData(e,...i.slice(4,6))}else{8===i.length&&(i=i.map((t,e)=>e<4?t*o:t));try{t.drawImage(n,...i)}catch(t){}}}computedWidthAndHeight(t,e,i,s){if(!e.width&&!e.height)return[t.width,t.height];if(e.width&&!e.height){let s=this.getLength(e.width,i);return[s,t.height*(s/t.width)]}if(!e.width&&e.height){let i=this.getLength(e.height,s);return[t.width*(i/t.height),i]}return[this.getLength(e.width,i),this.getLength(e.height,s)]}changeUnits(t,e=1){const{config:i}=this;return Number(t.replace(/^([-]*[0-9.]*)([a-z%]*)$/,(t,s,h)=>{const n={"%":t=>t*(e/100),px:t=>1*t,rem:t=>t*this.htmlFontSize,vw:t=>t/100*window.innerWidth}[h];if(n)return n(s);const r=i.handleCssUnit||i.unitFunc;return r?r(s,h):s}))}getLength(t,i){return e(t,"number")?t:e(t,"string")?this.changeUnits(t,i):0}getOffsetX(t,e=0){return(e-t)/2}getOffscreenCanvas(t,e){if(!this._offscreenCanvas&&(window&&window.document&&"WEB"===this.config.flag?this._offscreenCanvas=document.createElement("canvas"):this._offscreenCanvas=this.config.offscreenCanvas,!this._offscreenCanvas))return console.error("离屏 Canvas 无法渲染!");const i=this.config.dpr,s=this._offscreenCanvas;s.width=(t||300)*i,s.height=(e||150)*i;const h=s.getContext("2d");return h.clearRect(0,0,t,e),h.scale(i,i),h.dpr=i,{_offscreenCanvas:s,_ctx:h}}$set(t,e,i){t&&"object"==typeof t&&S(t,e,i)}$computed(t,e,i){Object.defineProperty(t,e,{get:()=>i.call(this)})}$watch(t,e,i={}){"object"==typeof e&&(e=(i=e).handler);const s=new k(this,t,e,i);return i.immediate&&e.call(this,s.value),function(){}}}I(O,"version",l);const A=t=>Math.PI/180*t,P=(t,e,i,s,h,n)=>{t.beginPath();let r=A(90/Math.PI/i*n),o=s+r,a=h-r;var l,c;t.arc(0,0,i,o,a,!1),t.lineTo(...(l=(s+h)/2,c=n/2/Math.abs(Math.sin((s-h)/2)),[+(Math.cos(l)*c).toFixed(8),+(Math.sin(l)*c).toFixed(8)])),t.closePath()},L=(t,...[e,i,s,h,n])=>{const r=Math.min(s,h),o=Math.PI;n>r/2&&(n=r/2),t.beginPath(),t.moveTo(e+n,i),t.lineTo(e+n,i),t.lineTo(e+s-n,i),t.arc(e+s-n,i+n,n,-o/2,0),t.lineTo(e+s,i+h-n),t.arc(e+s-n,i+h-n,n,0,o/2),t.lineTo(e+n,i+h),t.arc(e+n,i+h-n,n,o/2,o),t.lineTo(e,i+n),t.arc(e+n,i+n,n,o,-o/2),t.closePath()},T=function(t,e,i,s){return t>=s&&(t=s),i*(t/=s)*t+e},E=function(t,e,i,s){return t>=s&&(t=s),-i*(t/=s)*(t-2)+e};var W=Object.defineProperty,_=Object.getOwnPropertySymbols,F=Object.prototype.hasOwnProperty,R=Object.prototype.propertyIsEnumerable,D=(t,e,i)=>e in t?W(t,e,{enumerable:!0,configurable:!0,writable:!0,value:i}):t[e]=i,H=(t,e)=>{for(var i in e||(e={}))F.call(e,i)&&D(t,i,e[i]);if(_)for(var i of _(e))R.call(e,i)&&D(t,i,e[i]);return t},M=(t,e,i)=>D(t,"symbol"!=typeof e?e+"":e,i),j=(t,e,i)=>new Promise((s,h)=>{var n=t=>{try{o(i.next(t))}catch(t){h(t)}},r=t=>{try{o(i.throw(t))}catch(t){h(t)}},o=t=>t.done?s(t.value):Promise.resolve(t.value).then(n,r);o((i=i.apply(t,e)).next())});var B=Object.defineProperty,N=Object.getOwnPropertySymbols,X=Object.prototype.hasOwnProperty,G=Object.prototype.propertyIsEnumerable,U=(t,e,i)=>e in t?B(t,e,{enumerable:!0,configurable:!0,writable:!0,value:i}):t[e]=i,q=(t,e)=>{for(var i in e||(e={}))X.call(e,i)&&U(t,i,e[i]);if(N)for(var i of N(e))G.call(e,i)&&U(t,i,e[i]);return t},Y=(t,e,i)=>U(t,"symbol"!=typeof e?e+"":e,i),J=(t,e,i)=>new Promise((s,h)=>{var n=t=>{try{o(i.next(t))}catch(t){h(t)}},r=t=>{try{o(i.throw(t))}catch(t){h(t)}},o=t=>t.done?s(t.value):Promise.resolve(t.value).then(n,r);o((i=i.apply(t,e)).next())});var K=Object.defineProperty,Q=Object.getOwnPropertySymbols,V=Object.prototype.hasOwnProperty,Z=Object.prototype.propertyIsEnumerable,tt=(t,e,i)=>e in t?K(t,e,{enumerable:!0,configurable:!0,writable:!0,value:i}):t[e]=i,et=(t,e)=>{for(var i in e||(e={}))V.call(e,i)&&tt(t,i,e[i]);if(Q)for(var i of Q(e))Z.call(e,i)&&tt(t,i,e[i]);return t},it=(t,e,i)=>tt(t,"symbol"!=typeof e?e+"":e,i),st=(t,e,i)=>new Promise((s,h)=>{var n=t=>{try{o(i.next(t))}catch(t){h(t)}},r=t=>{try{o(i.throw(t))}catch(t){h(t)}},o=t=>t.done?s(t.value):Promise.resolve(t.value).then(n,r);o((i=i.apply(t,e)).next())});t.LuckyGrid=class extends O{constructor(t,e){var i;super(t,{width:e.width,height:e.height}),Y(this,"rows",3),Y(this,"cols",3),Y(this,"blocks",[]),Y(this,"prizes",[]),Y(this,"buttons",[]),Y(this,"button"),Y(this,"defaultConfig",{}),Y(this,"defaultStyle",{}),Y(this,"activeStyle",{}),Y(this,"_defaultConfig",{}),Y(this,"_defaultStyle",{}),Y(this,"_activeStyle",{}),Y(this,"startCallback"),Y(this,"endCallback"),Y(this,"cellWidth",0),Y(this,"cellHeight",0),Y(this,"startTime",0),Y(this,"endTime",0),Y(this,"currIndex",0),Y(this,"stopIndex",0),Y(this,"endIndex",0),Y(this,"demo",!1),Y(this,"timer",0),Y(this,"FPS",16.6),Y(this,"step",0),Y(this,"prizeFlag",-1),Y(this,"cells",[]),Y(this,"prizeArea"),Y(this,"ImageCache",new Map),this.initData(e),this.initWatch(),this.initComputed(),null==(i=t.beforeCreate)||i.call(this),this.init()}resize(){var t,e;super.resize(),this.draw(),null==(e=(t=this.config).afterResize)||e.call(t)}initLucky(){this.cellWidth=0,this.cellHeight=0,this.startTime=0,this.endTime=0,this.currIndex=0,this.stopIndex=0,this.endIndex=0,this.demo=!1,this.timer=0,this.FPS=16.6,this.prizeFlag=-1,this.step=0,super.initLucky()}initData(t){this.$set(this,"width",t.width),this.$set(this,"height",t.height),this.$set(this,"rows",Number(t.rows)||3),this.$set(this,"cols",Number(t.cols)||3),this.$set(this,"blocks",t.blocks||[]),this.$set(this,"prizes",t.prizes||[]),this.$set(this,"buttons",t.buttons||[]),this.$set(this,"button",t.button),this.$set(this,"defaultConfig",t.defaultConfig||{}),this.$set(this,"defaultStyle",t.defaultStyle||{}),this.$set(this,"activeStyle",t.activeStyle||{}),this.$set(this,"startCallback",t.start),this.$set(this,"endCallback",t.end)}initComputed(){this.$computed(this,"_defaultConfig",()=>{const t=q({gutter:5,speed:20,accelerationTime:2500,decelerationTime:2500},this.defaultConfig);return t.gutter=this.getLength(t.gutter),t.speed=t.speed/40,t}),this.$computed(this,"_defaultStyle",()=>q({borderRadius:20,fontColor:"#000",fontSize:"18px",fontStyle:"sans-serif",fontWeight:"400",background:"rgba(0,0,0,0)",shadow:"",wordWrap:!0,lengthLimit:"90%"},this.defaultStyle)),this.$computed(this,"_activeStyle",()=>q({background:"#ffce98",shadow:""},this.activeStyle))}initWatch(){this.$watch("width",t=>{this.data.width=t,this.resize()}),this.$watch("height",t=>{this.data.height=t,this.resize()}),this.$watch("blocks",t=>{this.initImageCache()},{deep:!0}),this.$watch("prizes",t=>{this.initImageCache()},{deep:!0}),this.$watch("buttons",t=>{this.initImageCache()},{deep:!0}),this.$watch("rows",()=>this.init()),this.$watch("cols",()=>this.init()),this.$watch("defaultConfig",()=>this.draw(),{deep:!0}),this.$watch("defaultStyle",()=>this.draw(),{deep:!0}),this.$watch("activeStyle",()=>this.draw(),{deep:!0}),this.$watch("startCallback",()=>this.init()),this.$watch("endCallback",()=>this.init())}init(){return J(this,null,function*(){var t,e;this.initLucky();const{config:i}=this;null==(t=i.beforeInit)||t.call(this),this.draw(),yield this.initImageCache(),null==(e=i.afterInit)||e.call(this)})}initImageCache(){return new Promise(t=>{const e=this.buttons.map(t=>t.imgs);this.button&&e.push(this.button.imgs);const i={blocks:this.blocks.map(t=>t.imgs),prizes:this.prizes.map(t=>t.imgs),buttons:e};Object.keys(i).forEach(e=>{const s=i[e],h=[];s&&s.forEach((t,i)=>{t&&t.forEach((t,s)=>{h.push(this.loadAndCacheImg(e,i,s))})}),Promise.all(h).then(()=>{this.draw(),t()})})})}handleClick(t){const{ctx:e}=this;[...this.buttons,this.button].forEach(i=>{var s;if(!i)return;const[h,n,r,o]=this.getGeometricProperty([i.x,i.y,i.col||1,i.row||1]);e.beginPath(),e.rect(h,n,r,o),e.isPointInPath(t.offsetX,t.offsetY)&&0===this.step&&("function"==typeof i.callback&&i.callback.call(this,i),null==(s=this.startCallback)||s.call(this,t,i))})}loadAndCacheImg(t,e,i){return J(this,null,function*(){return new Promise((s,h)=>{let n=this[t][e];if("buttons"===t&&!this.buttons.length&&this.button&&(n=this.button),!n||!n.imgs)return;const r=n.imgs[i];if(!r)return;const o=[this.loadImg(r.src,r),r.activeSrc&&this.loadImg(r.activeSrc,r,"$activeResolve")];Promise.all(o).then(t=>J(this,[t],function*([t,e]){const i=r.formatter;"function"==typeof i&&(t=yield Promise.resolve(i.call(this,t)),e&&(e=yield Promise.resolve(i.call(this,e)))),this.ImageCache.set(r.src,t),e&&this.ImageCache.set(r.activeSrc,e),s()})).catch(s=>{console.error(`${t}[${e}].imgs[${i}] ${s}`),h()})})})}draw(){var t,e;const{config:r,ctx:o,_defaultConfig:l,_defaultStyle:c,_activeStyle:d}=this;null==(t=r.beforeDraw)||t.call(this,o),o.clearRect(0,0,this.boxWidth,this.boxHeight),this.cells=[...this.prizes,...this.buttons],this.button&&this.cells.push(this.button),this.cells.forEach(t=>{t.col=t.col||1,t.row=t.row||1}),this.prizeArea=this.blocks.reduce(({x:t,y:e,w:i,h:s},r,a)=>{const[l,c,d,g]=n(r,this.getLength.bind(this)),f=r.borderRadius?this.getLength(r.borderRadius):0,u=r.background;return h(u)&&(o.fillStyle=this.handleBackground(t,e,i,s,u),L(o,t,e,i,s,f),o.fill()),r.imgs&&r.imgs.forEach((h,n)=>{const r=this.ImageCache.get(h.src);if(!r)return;const[a,l]=this.computedWidthAndHeight(r,h,i,s),[c,d]=[this.getOffsetX(a,i)+this.getLength(h.left,i),this.getLength(h.top,s)];this.drawImage(o,r,t+c,e+d,a,l)}),{x:t+d,y:e+l,w:i-d-g,h:s-l-c}},{x:0,y:0,w:this.boxWidth,h:this.boxHeight}),this.cellWidth=(this.prizeArea.w-l.gutter*(this.cols-1))/this.cols,this.cellHeight=(this.prizeArea.h-l.gutter*(this.rows-1))/this.rows,this.cells.forEach((t,e)=>{let[n,l,g,f]=this.getGeometricProperty([t.x,t.y,t.col,t.row]),u=!1;(void 0===this.prizeFlag||this.prizeFlag>-1)&&(u=e===(this.currIndex%this.prizes.length|0));const p=u?d.background:t.background||c.background;if(h(p)){const e=(u?d.shadow:t.shadow||c.shadow).replace(/px/g,"").split(",")[0].split(" ").map((t,e)=>e<3?Number(t):t);4===e.length&&(o.shadowColor=e[3],o.shadowOffsetX=e[0]*r.dpr,o.shadowOffsetY=e[1]*r.dpr,o.shadowBlur=e[2],e[0]>0?g-=e[0]:(g+=e[0],n-=e[0]),e[1]>0?f-=e[1]:(f+=e[1],l-=e[1])),o.fillStyle=this.handleBackground(n,l,g,f,p);const i=this.getLength(t.borderRadius?t.borderRadius:c.borderRadius);L(o,n,l,g,f,i),o.fill(),o.shadowColor="rgba(0, 0, 0, 0)",o.shadowOffsetX=0,o.shadowOffsetY=0,o.shadowBlur=0}e>=this.prizes.length&&(e-=this.prizes.length),t.imgs&&t.imgs.forEach((t,e)=>{const i=this.ImageCache.get(t.src),s=this.ImageCache.get(t.activeSrc);if(!i)return;const h=u&&s||i;if(!h)return;const[r,a]=this.computedWidthAndHeight(h,t,g,f),[c,d]=[n+this.getOffsetX(r,g)+this.getLength(t.left,g),l+this.getLength(t.top,f)];this.drawImage(o,h,c,d,r,a)}),t.fonts&&t.fonts.forEach(t=>{const e=u&&d.fontStyle?d.fontStyle:t.fontStyle||c.fontStyle,h=u&&d.fontWeight?d.fontWeight:t.fontWeight||c.fontWeight,r=u&&d.fontSize?this.getLength(d.fontSize):this.getLength(t.fontSize||c.fontSize),p=u&&d.lineHeight?d.lineHeight:t.lineHeight||c.lineHeight||t.fontSize||c.fontSize,m=i(t,"wordWrap")?t.wordWrap:c.wordWrap,w=t.lengthLimit||c.lengthLimit,b=t.lineClamp||c.lineClamp;o.font=`${h} ${r|0}px ${e}`,o.fillStyle=u&&d.fontColor?d.fontColor:t.fontColor||c.fontColor;let y=[],v=String(t.text);if(m){let t=this.getLength(w,g);y=a(o,s(v),()=>t,b)}else y=v.split("\n");y.forEach((e,i)=>{o.fillText(e,n+this.getOffsetX(o.measureText(e).width,g)+this.getLength(t.left,g),l+this.getLength(t.top,f)+(i+1)*this.getLength(p))})})}),null==(e=r.afterDraw)||e.call(this,o)}handleBackground(t,e,i,s,h){const{ctx:n}=this;return h.includes("linear-gradient")&&(h=((t,e,i,s,h,n)=>{const r=/linear-gradient\((.+)\)/.exec(n)[1].split(",").map(t=>t.trim());let o=r.shift(),a=[0,0,0,0];if(o.includes("deg")){o=o.slice(0,-3)%360;const t=t=>Math.tan(t/180*Math.PI);o>=0&&o<45?a=[e,i+h,e+s,i+h-s*t(o-0)]:o>=45&&o<90?a=[e,i+h,e+s-h*t(o-45),i]:o>=90&&o<135?a=[e+s,i+h,e+s-h*t(o-90),i]:o>=135&&o<180?a=[e+s,i+h,e,i+s*t(o-135)]:o>=180&&o<225?a=[e+s,i,e,i+s*t(o-180)]:o>=225&&o<270?a=[e+s,i,e+h*t(o-225),i+h]:o>=270&&o<315?a=[e,i,e+h*t(o-270),i+h]:o>=315&&o<360&&(a=[e,i,e+s,i+h-s*t(o-315)])}else o.includes("top")?a=[e,i+h,e,i]:o.includes("bottom")?a=[e,i,e,i+h]:o.includes("left")?a=[e+s,i,e,i]:o.includes("right")&&(a=[e,i,e+s,i]);const l=t.createLinearGradient(...a.map(t=>0|t));return r.reduce((t,e,i)=>{const s=e.split(" ");return 1===s.length?t.addColorStop(i,s[0]):2===s.length&&t.addColorStop(...s),t},l)})(n,t,e,i,s,h)),h}carveOnGunwaleOfAMovingBoat(){const{_defaultConfig:t,prizeFlag:e,currIndex:i}=this;this.endTime=Date.now();const s=this.stopIndex=i,h=t.speed;let n=0,r=0,o=0;for(;++n;){const i=this.prizes.length*n+e-s,a=E(this.FPS,s,i,t.decelerationTime)-s;if(a>h){this.endIndex=h-r>a-h?i:o;break}o=i,r=a}}play(){var t,e;0===this.step&&(this.startTime=Date.now(),this.prizeFlag=void 0,this.step=1,null==(e=(t=this.config).afterStart)||e.call(t),this.run())}stop(t){if(0!==this.step&&3!==this.step){if(!t&&0!==t){const e=this.prizes.map(t=>t.range);t=o(e)}t<0?(this.step=0,this.prizeFlag=-1):(this.step=2,this.prizeFlag=t%this.prizes.length)}}run(t=0){var e;const{rAF:i,step:s,prizes:h,prizeFlag:n,_defaultConfig:r}=this,{accelerationTime:o,decelerationTime:a,speed:l}=r;if(0===s)return void(null==(e=this.endCallback)||e.call(this,this.prizes.find((t,e)=>e===n)||{}));if(-1===n)return;3!==s||this.endIndex||this.carveOnGunwaleOfAMovingBoat();const c=Date.now()-this.startTime,d=Date.now()-this.endTime;let g=this.currIndex;if(1===s||c<o){this.FPS=c/t;const e=T(c,.1,l-.1,o);e===l&&(this.step=2),g+=e%h.length}else 2===s?(g+=l%h.length,void 0!==n&&n>=0&&(this.step=3,this.stopIndex=0,this.endIndex=0)):3===s?(g=E(d,this.stopIndex,this.endIndex,a),d>=a&&(this.step=0)):this.stop(-1);this.currIndex=g,this.draw(),i(this.run.bind(this,t+1))}getGeometricProperty([t,e,i=1,s=1]){const{cellWidth:h,cellHeight:n}=this,r=this._defaultConfig.gutter;let o=[this.prizeArea.x+(h+r)*t,this.prizeArea.y+(n+r)*e];return i&&s&&o.push(h*i+r*(i-1),n*s+r*(s-1)),o}conversionAxis(t,e){const{config:i}=this;return[t/i.dpr,e/i.dpr]}},t.LuckyWheel=class extends O{constructor(t,e){var i;super(t,{width:e.width,height:e.height}),M(this,"blocks",[]),M(this,"prizes",[]),M(this,"buttons",[]),M(this,"defaultConfig",{}),M(this,"defaultStyle",{}),M(this,"_defaultConfig",{}),M(this,"_defaultStyle",{}),M(this,"startCallback"),M(this,"endCallback"),M(this,"Radius",0),M(this,"prizeRadius",0),M(this,"prizeDeg",0),M(this,"prizeAng",0),M(this,"rotateDeg",0),M(this,"maxBtnRadius",0),M(this,"startTime",0),M(this,"endTime",0),M(this,"stopDeg",0),M(this,"endDeg",0),M(this,"FPS",16.6),M(this,"step",0),M(this,"prizeFlag"),M(this,"ImageCache",new Map),this.initData(e),this.initWatch(),this.initComputed(),null==(i=t.beforeCreate)||i.call(this),this.init()}resize(){var t,e;super.resize(),this.Radius=Math.min(this.boxWidth,this.boxHeight)/2,this.ctx.translate(this.Radius,this.Radius),this.draw(),null==(e=(t=this.config).afterResize)||e.call(t)}initLucky(){this.Radius=0,this.prizeRadius=0,this.prizeDeg=0,this.prizeAng=0,this.rotateDeg=0,this.maxBtnRadius=0,this.startTime=0,this.endTime=0,this.stopDeg=0,this.endDeg=0,this.FPS=16.6,this.prizeFlag=-1,this.step=0,super.initLucky()}initData(t){this.$set(this,"width",t.width),this.$set(this,"height",t.height),this.$set(this,"blocks",t.blocks||[]),this.$set(this,"prizes",t.prizes||[]),this.$set(this,"buttons",t.buttons||[]),this.$set(this,"defaultConfig",t.defaultConfig||{}),this.$set(this,"defaultStyle",t.defaultStyle||{}),this.$set(this,"startCallback",t.start),this.$set(this,"endCallback",t.end)}initComputed(){this.$computed(this,"_defaultConfig",()=>H({gutter:"0px",offsetDegree:0,speed:20,speedFunction:"quad",accelerationTime:2500,decelerationTime:2500,stopRange:0},this.defaultConfig)),this.$computed(this,"_defaultStyle",()=>H({fontSize:"18px",fontColor:"#000",fontStyle:"sans-serif",fontWeight:"400",background:"rgba(0,0,0,0)",wordWrap:!0,lengthLimit:"90%"},this.defaultStyle))}initWatch(){this.$watch("width",t=>{this.data.width=t,this.resize()}),this.$watch("height",t=>{this.data.height=t,this.resize()}),this.$watch("blocks",t=>{this.initImageCache()},{deep:!0}),this.$watch("prizes",t=>{this.initImageCache()},{deep:!0}),this.$watch("buttons",t=>{this.initImageCache()},{deep:!0}),this.$watch("defaultConfig",()=>this.draw(),{deep:!0}),this.$watch("defaultStyle",()=>this.draw(),{deep:!0}),this.$watch("startCallback",()=>this.init()),this.$watch("endCallback",()=>this.init())}init(){return j(this,null,function*(){var t,e;this.initLucky();const{config:i}=this;null==(t=i.beforeInit)||t.call(this),this.draw(),this.draw(),yield this.initImageCache(),null==(e=i.afterInit)||e.call(this)})}initImageCache(){return new Promise(t=>{const e={blocks:this.blocks.map(t=>t.imgs),prizes:this.prizes.map(t=>t.imgs),buttons:this.buttons.map(t=>t.imgs)};Object.keys(e).forEach(i=>{const s=e[i],h=[];s&&s.forEach((t,e)=>{t&&t.forEach((t,s)=>{h.push(this.loadAndCacheImg(i,e,s))})}),Promise.all(h).then(()=>{this.draw(),t()})})})}handleClick(t){var e;const{ctx:i}=this;i.beginPath(),i.arc(0,0,this.maxBtnRadius,0,2*Math.PI,!1),i.isPointInPath(t.offsetX,t.offsetY)&&0===this.step&&(null==(e=this.startCallback)||e.call(this,t))}loadAndCacheImg(t,e,i){return j(this,null,function*(){return new Promise((s,h)=>{const n=this[t][e];if(!n||!n.imgs)return;const r=n.imgs[i];r&&this.loadImg(r.src,r).then(t=>j(this,null,function*(){"function"==typeof r.formatter&&(t=yield Promise.resolve(r.formatter.call(this,t))),this.ImageCache.set(r.src,t),s()})).catch(s=>{console.error(`${t}[${e}].imgs[${i}] ${s}`),h()})})})}drawBlock(t,e,i){const{ctx:s}=this;h(e.background)&&(s.beginPath(),s.fillStyle=e.background,s.arc(0,0,t,0,2*Math.PI,!1),s.fill()),e.imgs&&e.imgs.forEach((e,i)=>{const h=this.ImageCache.get(e.src);if(!h)return;const[n,r]=this.computedWidthAndHeight(h,e,2*t,2*t),[o,a]=[this.getOffsetX(n)+this.getLength(e.left,2*t),this.getLength(e.top,2*t)-t];s.save(),e.rotate&&s.rotate(A(this.rotateDeg)),this.drawImage(s,h,o,a,n,r),s.restore()})}draw(){var t,e;const{config:n,ctx:r,_defaultConfig:o,_defaultStyle:l}=this;null==(t=n.beforeDraw)||t.call(this,r),r.clearRect(-this.Radius,-this.Radius,2*this.Radius,2*this.Radius),this.prizeRadius=this.blocks.reduce((t,e,i)=>(this.drawBlock(t,e,i),t-this.getLength(e.padding&&e.padding.split(" ")[0])),this.Radius),this.prizeDeg=360/this.prizes.length,this.prizeAng=A(this.prizeDeg);const c=this.prizeRadius*Math.sin(this.prizeAng/2)*2;let d=A(this.rotateDeg-90+this.prizeDeg/2+o.offsetDegree);const g=(t,e)=>this.getOffsetX(r.measureText(e).width)+this.getLength(t.left,c),f=(t,e,i)=>{const s=t.lineHeight||l.lineHeight||t.fontSize||l.fontSize;return this.getLength(t.top,e)+(i+1)*this.getLength(s)};r.save(),this.prizes.forEach((t,e)=>{let n=d+e*this.prizeAng,u=this.prizeRadius-this.maxBtnRadius;const p=t.background||l.background;h(p)&&(r.fillStyle=p,P(r,this.maxBtnRadius,this.prizeRadius,n-this.prizeAng/2,n+this.prizeAng/2,this.getLength(o.gutter)),r.fill());let m=Math.cos(n)*this.prizeRadius,w=Math.sin(n)*this.prizeRadius;r.translate(m,w),r.rotate(n+A(90)),t.imgs&&t.imgs.forEach((t,e)=>{const i=this.ImageCache.get(t.src);if(!i)return;const[s,h]=this.computedWidthAndHeight(i,t,this.prizeAng*this.prizeRadius,u),[n,o]=[this.getOffsetX(s)+this.getLength(t.left,c),this.getLength(t.top,u)];this.drawImage(r,i,n,o,s,h)}),t.fonts&&t.fonts.forEach(t=>{const e=t.fontColor||l.fontColor,h=t.fontWeight||l.fontWeight,n=this.getLength(t.fontSize||l.fontSize),c=t.fontStyle||l.fontStyle,d=i(t,"wordWrap")?t.wordWrap:l.wordWrap,p=t.lengthLimit||l.lengthLimit,m=t.lineClamp||l.lineClamp;r.fillStyle=e,r.font=`${h} ${n|0}px ${c}`;let w=[],b=String(t.text);w=d?a(r,s(b),e=>{let i=2*((this.prizeRadius-f(t,u,e.length))*Math.tan(this.prizeAng/2))-this.getLength(o.gutter);return this.getLength(p,i)},m):b.split("\n"),w.filter(t=>!!t).forEach((e,i)=>{r.fillText(e,g(t,e),f(t,u,i))})}),r.rotate(A(360)-n-A(90)),r.translate(-m,-w)}),r.restore(),this.buttons.forEach((t,e)=>{let i=this.getLength(t.radius,this.prizeRadius);this.maxBtnRadius=Math.max(this.maxBtnRadius,i),h(t.background)&&(r.beginPath(),r.fillStyle=t.background,r.arc(0,0,i,0,2*Math.PI,!1),r.fill()),t.pointer&&h(t.background)&&(r.beginPath(),r.fillStyle=t.background,r.moveTo(-i,0),r.lineTo(i,0),r.lineTo(0,2*-i),r.closePath(),r.fill()),t.imgs&&t.imgs.forEach((t,e)=>{const s=this.ImageCache.get(t.src);if(!s)return;const[h,n]=this.computedWidthAndHeight(s,t,2*i,2*i),[o,a]=[this.getOffsetX(h)+this.getLength(t.left,i),this.getLength(t.top,i)];this.drawImage(r,s,o,a,h,n)}),t.fonts&&t.fonts.forEach(t=>{let e=t.fontColor||l.fontColor,s=t.fontWeight||l.fontWeight,h=this.getLength(t.fontSize||l.fontSize),n=t.fontStyle||l.fontStyle;r.fillStyle=e,r.font=`${s} ${h|0}px ${n}`,String(t.text).split("\n").forEach((e,s)=>{r.fillText(e,g(t,e),f(t,i,s))})})}),null==(e=n.afterDraw)||e.call(this,r)}carveOnGunwaleOfAMovingBoat(){const{_defaultConfig:t,prizeFlag:e,prizeDeg:i,rotateDeg:s}=this;this.endTime=Date.now();const h=this.stopDeg=s,n=t.speed,r=(Math.random()*i-i/2)*this.getLength(t.stopRange);let o=0,a=0,l=0;for(;++o;){const c=360*o-e*i-s-t.offsetDegree+r-i/2;let d=E(this.FPS,h,c,t.decelerationTime)-h;if(d>n){this.endDeg=n-a>d-n?c:l;break}l=c,a=d}}play(){var t,e;0===this.step&&(this.startTime=Date.now(),this.prizeFlag=void 0,this.step=1,null==(e=(t=this.config).afterStart)||e.call(t),this.run())}stop(t){if(0!==this.step&&3!==this.step){if(!t&&0!==t){const e=this.prizes.map(t=>t.range);t=o(e)}t<0?(this.step=0,this.prizeFlag=-1):(this.step=2,this.prizeFlag=t%this.prizes.length)}}run(t=0){var e;const{rAF:i,step:s,prizeFlag:h,_defaultConfig:n}=this,{accelerationTime:r,decelerationTime:o,speed:a}=n;if(0===s)return void(null==(e=this.endCallback)||e.call(this,this.prizes.find((t,e)=>e===h)||{}));if(-1===h)return;3!==s||this.endDeg||this.carveOnGunwaleOfAMovingBoat();const l=Date.now()-this.startTime,c=Date.now()-this.endTime;let d=this.rotateDeg;if(1===s||l<r){this.FPS=l/t;const e=T(l,0,a,r);e===a&&(this.step=2),d+=e%360}else 2===s?(d+=a%360,void 0!==h&&h>=0&&(this.step=3,this.stopDeg=0,this.endDeg=0)):3===s?(d=E(c,this.stopDeg,this.endDeg,o),c>=o&&(this.step=0)):this.stop(-1);this.rotateDeg=d,this.draw(),i(this.run.bind(this,t+1))}conversionAxis(t,e){const{config:i}=this;return[t/i.dpr-this.Radius,e/i.dpr-this.Radius]}},t.SlotMachine=class extends O{constructor(t,e){var i;super(t,{width:e.width,height:e.height}),it(this,"blocks",[]),it(this,"prizes",[]),it(this,"slots",[]),it(this,"defaultConfig",{}),it(this,"_defaultConfig",{}),it(this,"defaultStyle",{}),it(this,"_defaultStyle",{}),it(this,"endCallback",()=>{}),it(this,"_offscreenCanvas"),it(this,"cellWidth",0),it(this,"cellHeight",0),it(this,"cellAndSpacing",0),it(this,"widthAndSpacing",0),it(this,"heightAndSpacing",0),it(this,"FPS",16.6),it(this,"scroll",[]),it(this,"stopScroll",[]),it(this,"endScroll",[]),it(this,"startTime",0),it(this,"endTime",[]),it(this,"slotStep",[]),it(this,"defaultOrder",[]),it(this,"step",0),it(this,"prizeFlag"),it(this,"prizeArea"),it(this,"ImageCache",new Map),this.initData(e),this.initWatch(),this.initComputed(),null==(i=t.beforeCreate)||i.call(this),this.init()}resize(){var t,e;super.resize(),this.redrawOffscreenCanvas(),null==(e=(t=this.config).afterResize)||e.call(t)}initLucky(){this.cellWidth=0,this.cellHeight=0,this.cellAndSpacing=0,this.widthAndSpacing=0,this.heightAndSpacing=0,this.FPS=16.6,this.scroll=[],this.stopScroll=[],this.endScroll=[],this.startTime=0,this.endTime=[],this.slotStep=[],this.prizeFlag=void 0,this.step=0,super.initLucky()}initData(t){this.$set(this,"width",t.width),this.$set(this,"height",t.height),this.$set(this,"blocks",t.blocks||[]),this.$set(this,"prizes",t.prizes||[]),this.$set(this,"slots",t.slots||[]),this.$set(this,"defaultConfig",t.defaultConfig||{}),this.$set(this,"defaultStyle",t.defaultStyle||{}),this.$set(this,"endCallback",t.end)}initComputed(){this.$computed(this,"_defaultConfig",()=>{const t=et({mode:"vertical",rowSpacing:0,colSpacing:5,speed:20,direction:1,accelerationTime:2500,decelerationTime:2500},this.defaultConfig);return t.rowSpacing=this.getLength(t.rowSpacing),t.colSpacing=this.getLength(t.colSpacing),t}),this.$computed(this,"_defaultStyle",()=>et({borderRadius:0,fontColor:"#000",fontSize:"18px",fontStyle:"sans-serif",fontWeight:"400",background:"rgba(0,0,0,0)",wordWrap:!0,lengthLimit:"90%"},this.defaultStyle))}initWatch(){this.$watch("width",t=>{this.data.width=t,this.resize()}),this.$watch("height",t=>{this.data.height=t,this.resize()}),this.$watch("blocks",t=>{this.initImageCache()},{deep:!0}),this.$watch("prizes",t=>{this.initImageCache()},{deep:!0}),this.$watch("slots",t=>{this.redrawOffscreenCanvas()},{deep:!0}),this.$watch("defaultConfig",()=>this.redrawOffscreenCanvas(),{deep:!0}),this.$watch("defaultStyle",()=>this.redrawOffscreenCanvas(),{deep:!0}),this.$watch("endCallback",()=>this.init())}init(){return st(this,null,function*(){var t,e;this.initLucky();const{config:i}=this;null==(t=i.beforeInit)||t.call(this),this.drawOffscreenCanvas(),this.draw(),yield this.initImageCache(),null==(e=i.afterInit)||e.call(this)})}redrawOffscreenCanvas(){this.drawOffscreenCanvas(),this.draw()}initImageCache(){return new Promise(t=>{const e={blocks:this.blocks.map(t=>t.imgs),prizes:this.prizes.map(t=>t.imgs)};Object.keys(e).forEach(i=>{const s=e[i],h=[];s&&s.forEach((t,e)=>{t&&t.forEach((t,s)=>{h.push(this.loadAndCacheImg(i,e,s))})}),Promise.all(h).then(()=>{this.drawOffscreenCanvas(),this.draw(),t()})})})}loadAndCacheImg(t,e,i){return st(this,null,function*(){return new Promise((s,h)=>{let n=this[t][e];if(!n||!n.imgs)return;const r=n.imgs[i];r&&this.loadImg(r.src,r).then(t=>st(this,null,function*(){"function"==typeof r.formatter&&(t=yield Promise.resolve(r.formatter.call(this,t))),this.ImageCache.set(r.src,t),s()})).catch(s=>{console.error(`${t}[${e}].imgs[${i}] ${s}`),h()})})})}drawOffscreenCanvas(){const{_defaultConfig:t,_defaultStyle:e}=this,{w:n,h:r}=this.drawBlocks(),o=this.prizes.length,{cellWidth:l,cellHeight:c,widthAndSpacing:d,heightAndSpacing:g}=this.displacementWidthOrHeight();this.defaultOrder=new Array(o).fill(void 0).map((t,e)=>e);let f=0,u=0;this.slots.forEach((t,e)=>{void 0===this.scroll[e]&&(this.scroll[e]=0);const i=(t.order||this.defaultOrder).length;f=Math.max(f,n+d*i),u=Math.max(u,r+g*i)});const{_offscreenCanvas:p,_ctx:m}=this.getOffscreenCanvas(f,u);this._offscreenCanvas=p,this.slots.forEach((n,r)=>{const o=l*r,f=c*r;let w=0;const b=((t,e)=>{const i={},s=[];for(let e=0;e<t.length;e++)i[e]=t[e];for(let t=0;t<e.length;t++){const h=i[e[t]];h&&(s[t]=h)}return s})(this.prizes,n.order||this.defaultOrder);if(!b.length)return;b.forEach((n,r)=>{if(!n)return;const u=d*r+t.colSpacing/2,p=g*r+t.rowSpacing/2,[b,y,v]=this.displacement([o,p,g],[u,f,d]);w+=v;const S=n.background||e.background;if(h(S)){const t=this.getLength(i(n,"borderRadius")?n.borderRadius:e.borderRadius);L(m,b,y,l,l,t),m.fillStyle=S,m.fill()}n.imgs&&n.imgs.forEach((t,e)=>{const i=this.ImageCache.get(t.src);if(!i)return;const[s,h]=this.computedWidthAndHeight(i,t,l,c),[n,r]=[b+this.getOffsetX(s,l)+this.getLength(t.left,l),y+this.getLength(t.top,c)];this.drawImage(m,i,n,r,s,h)}),n.fonts&&n.fonts.forEach(t=>{const h=t.fontStyle||e.fontStyle,n=t.fontWeight||e.fontWeight,r=this.getLength(t.fontSize||e.fontSize),o=t.lineHeight||e.lineHeight||t.fontSize||e.fontSize,d=i(t,"wordWrap")?t.wordWrap:e.wordWrap,g=t.lengthLimit||e.lengthLimit,f=t.lineClamp||e.lineClamp;m.font=`${n} ${r|0}px ${h}`,m.fillStyle=t.fontColor||e.fontColor;let u=[],p=String(t.text);if(d){let t=this.getLength(g,l);u=a(m,s(p),()=>t,f)}else u=p.split("\n");u.forEach((e,i)=>{m.fillText(e,b+this.getOffsetX(m.measureText(e).width,l)+this.getLength(t.left,l),y+this.getLength(t.top,c)+(i+1)*this.getLength(o))})})});const[y,v,S,C]=this.displacement([o,0,l,w],[0,f,w,c]);let z=w;for(;z<u+w;){const[t,e]=this.displacement([y,z],[z,v]);this.drawImage(m,p,y,v,S,C,t,e,S,C),z+=w}})}drawBlocks(){const{config:t,ctx:e,_defaultConfig:i,_defaultStyle:s}=this;return this.prizeArea=this.blocks.reduce(({x:t,y:i,w:r,h:o},a,l)=>{const[c,d,g,f]=n(a,this.getLength.bind(this)),u=a.borderRadius?this.getLength(a.borderRadius):0,p=a.background||s.background;return h(p)&&(L(e,t,i,r,o,u),e.fillStyle=p,e.fill()),a.imgs&&a.imgs.forEach((s,h)=>{const n=this.ImageCache.get(s.src);if(!n)return;const[a,l]=this.computedWidthAndHeight(n,s,r,o),[c,d]=[this.getOffsetX(a,r)+this.getLength(s.left,r),this.getLength(s.top,o)];this.drawImage(e,n,t+c,i+d,a,l)}),{x:t+g,y:i+c,w:r-g-f,h:o-c-d}},{x:0,y:0,w:this.boxWidth,h:this.boxHeight})}draw(){var t;const{config:e,ctx:i,_defaultConfig:s,_defaultStyle:h}=this;null==(t=e.beforeDraw)||t.call(this,i),i.clearRect(0,0,this.boxWidth,this.boxHeight);const{x:n,y:r,w:o,h:a}=this.drawBlocks();if(!this._offscreenCanvas)return;const{cellWidth:l,cellHeight:c,cellAndSpacing:d,widthAndSpacing:g,heightAndSpacing:f}=this;this.slots.forEach((t,e)=>{const s=t.order||this.defaultOrder,h=d*s.length,u=this.displacement(-(a-f)/2,-(o-g)/2);let p=this.scroll[e]+u;p<0&&(p=p%h+h),p>h&&(p%=h);const[m,w,b,y]=this.displacement([l*e,p,l,a],[p,c*e,o,c]),[v,S,C,z]=this.displacement([n+g*e,r,l,a],[n,r+f*e,o,c]);this.drawImage(i,this._offscreenCanvas,m,w,b,y,v,S,C,z)})}carveOnGunwaleOfAMovingBoat(t){const{_defaultConfig:e,prizeFlag:i,cellAndSpacing:s}=this,h=this.slots[t],n=h.order||this.defaultOrder;if(!n.length||void 0===i)return;const r=Math.abs(h.speed||e.speed),o=h.direction||e.direction,a=n.findIndex(e=>e===i[t]),l=s*n.length,c=this.stopScroll[t]=this.scroll[t];this.endTime[t]=Date.now();let d=0;for(;++d;){const i=s*a+l*d*o-c,h=E(this.FPS,c,i,e.decelerationTime)-c;if(Math.abs(h)>r){this.endScroll[t]=i;break}}}hasAllPrizeFlag(){var t;return!!(null==(t=this.prizeFlag)?void 0:t.length)&&this.prizeFlag.every(t=>void 0!==t)}isAllSlotStopped(){return this.slots.every((t,e)=>!(t.order||this.defaultOrder).length||0===this.slotStep[e])}getEndPrize(){if(!this.hasAllPrizeFlag())return;const t=this.prizeFlag;let e=t[0];for(let i=0;i<this.slots.length;i++){const s=this.slots[i],h=t[i],n=s.order||this.defaultOrder;if(!(null==n?void 0:n.includes(h))||e!==h){e=-1;break}}return this.prizes.find((t,i)=>i===e)||void 0}play(){var t,e;0===this.step&&(this.startTime=Date.now(),this.prizeFlag=void 0,this.stopScroll=[],this.endScroll=[],this.endTime=[],this.slotStep=this.slots.map(t=>(t.order||this.defaultOrder).length?1:0),this.step=1,null==(e=(t=this.config).afterStart)||e.call(t),this.run())}stop(t,i){var s;if(0!==this.step){if("number"==typeof i){if(!Number.isInteger(i)||i<0||i>=this.slots.length)return console.error(`stop(${t}, ${i}) slotIndex 超出范围`);if("number"!=typeof t)return console.error(`stop(${JSON.stringify(t)}, ${i}) 参数类型不正确`);void 0!==this.prizeFlag&&this.prizeFlag.length||(this.prizeFlag=new Array(this.slots.length).fill(void 0)),this.prizeFlag[i]=t}else if("number"==typeof t)this.prizeFlag=new Array(this.slots.length).fill(t);else{if(!e(t,"array"))return this.stop(-1),console.error("stop() 无法识别的参数类型 "+typeof t);if(t.length!==this.slots.length)return this.stop(-1),console.error(`stop([${t}]) 参数长度的不正确`);this.prizeFlag=t}(null==(s=this.prizeFlag)?void 0:s.includes(-1))?(this.prizeFlag=[],this.slotStep=this.slotStep.map(()=>0),this.step=0):this.step=2}}run(t=0){var e,i;const{rAF:s,_defaultConfig:h,cellAndSpacing:n,slots:r}=this,{accelerationTime:o,decelerationTime:a}=h,l=this.prizeFlag;if(0===this.step)return void(this.hasAllPrizeFlag()&&this.isAllSlotStopped()&&(null==(e=this.endCallback)||e.call(this,this.getEndPrize())));if(void 0!==l&&!l.length)return;const c=Date.now()-this.startTime;if(c>=o&&1===this.step&&(this.step=2),r.forEach((e,i)=>{const s=e.order||this.defaultOrder;if(!s||!s.length)return;const r=n*s.length,d=Math.abs(e.speed||h.speed),g=e.direction||h.direction,f=this.slotStep[i]||0;let u=0,p=this.scroll[i];if(f){if(1===f||c<o){this.FPS=c/t;const e=T(c,0,d,o);e===d&&(this.slotStep[i]=2),u=(p+e*g)%r}else if(2===f)u=(p+d*g)%r,void 0!==(null==l?void 0:l[i])&&(this.slotStep[i]=3,this.scroll[i]=u,this.carveOnGunwaleOfAMovingBoat(i));else if(3===f){const t=this.stopScroll[i],e=this.endScroll[i],s=Date.now()-this.endTime[i];u=E(s,t,e,a),s>=a&&(u=t+e,this.slotStep[i]=0)}this.scroll[i]=u}}),this.draw(),this.isAllSlotStopped())return this.step=0,void(this.hasAllPrizeFlag()&&(null==(i=this.endCallback)||i.call(this,this.getEndPrize())));s(this.run.bind(this,t+1))}displacement(t,e){return"horizontal"===this._defaultConfig.mode?e:t}displacementWidthOrHeight(){const t=this._defaultConfig.mode,e=this.slots.length,{colSpacing:i,rowSpacing:s}=this._defaultConfig,{x:h,y:n,w:r,h:o}=this.prizeArea||this.drawBlocks();let a=0,l=0,c=0,d=0;return"horizontal"===t?(l=this.cellHeight=(o-s*(e-1))/e,a=this.cellWidth=l):(a=this.cellWidth=(r-i*(e-1))/e,l=this.cellHeight=a),c=this.widthAndSpacing=this.cellWidth+i,d=this.heightAndSpacing=this.cellHeight+s,this.cellAndSpacing="horizontal"===t?c:d,{cellWidth:a,cellHeight:l,widthAndSpacing:c,heightAndSpacing:d}}},t.cutRound=(t,e)=>{const i=document.createElement("canvas"),s=i.getContext("2d"),{width:h,height:n}=t;return i.width=h,i.height=n,L(s,0,0,h,n,e),s.clip(),s.drawImage(t,0,0,h,n),i},t.opacity=(t,e)=>{const i=document.createElement("canvas"),s=i.getContext("2d"),{width:h,height:n}=t;if(i.width=h,i.height=n,"string"==typeof s.filter)s.filter=`opacity(${100*e}%)`,s.drawImage(t,0,0,h,n);else{s.drawImage(t,0,0,h,n);const i=s.getImageData(0,0,h,n),{data:r}=i,o=r.length;for(let t=0;t<o;t+=4){const i=r[t+3];0!==i&&(r[t+3]=i*e)}s.putImageData(i,0,0)}return i},Object.defineProperty(t,"__esModule",{value:!0})});