{"version":3,"sources":["jsdelivr-header.js","/npm/@graphi/mockjs@1.0.0/src/index.js"],"names":[],"mappings":"AAAA;AACA;AACA;AACA;AACA;AACA;AACA,AC2BA,IAAI,SAAW,QAAQ,cACnB,KAAO,QAAQ,UACf,OAAS,QAAQ,YACjB,OAAS,QAAQ,aACjB,GAAK,QAAQ,YAEb,KAAO,CACP,OAAQ,KAAK,OAejB,IAAW,SAAS,EAAU,EAAM,GAEhC,EAAe,MAAR,EAAoB,GAAM,EAAO,GAGxC,EAAU,CAEF,MAHR,EAAU,GAAW,CAAC,GAGA,MAAQ,CAAC,SAAS,MAChC,aAAc,EAAQ,cAAgB,CAAC,SAAS,QAEhD,eAAgB,EAAQ,eAExB,uBAAwB,EAAQ,wBAA0B,EAE1D,KAAM,EAAQ,MAAQ,EAAQ,eAE9B,aAAc,EAAQ,cAAgB,EAAQ,wBAA0B,GAIhF,IAEI,EAFA,EAAO,OAAO,MAAM,GACpB,EAAO,KAAK,KAAK,GAGrB,OAAI,KAAK,IACL,EAAO,KAAK,GAAM,CAEd,KAAM,EAEN,SAAU,EAEV,KAAM,EAEN,WAAY,EAAO,EAAK,QAAQ,SAAS,OAAQ,MAAQ,EAGzD,KAAM,EAEN,QAAS,IAGR,EAAQ,OAAM,EAAQ,KAAO,GAC3B,GAGJ,CACX,GAEA,KAAK,OAAO,CACR,MAAO,SAAS,GACZ,IACI,EAAG,EADH,EAAS,GAMb,GAAgC,IAA5B,EAAQ,SAAS,OAAc,OAAO,EAG1C,GAAK,EAAQ,KAAK,WAmBd,GAAyB,IAArB,EAAQ,KAAK,UAAkC,IAArB,EAAQ,KAAK,IAEvC,EAAQ,QAAQ,KAAK,KAAK,EAAQ,MAClC,EAAQ,QAAQ,aAAa,KAAK,EAAQ,MAC1C,EAAS,OAAO,KACZ,KAAK,IAAI,EAAQ,cAAU,EAAW,CAClC,KAAM,EAAQ,QAAQ,KACtB,aAAc,EAAQ,QAAQ,aAC9B,eAAgB,EAChB,uBAAwB,EAAQ,SAChC,KAAM,EAAQ,QAAQ,MAAQ,EAC9B,aAAc,EAAQ,QAAQ,cAAgB,EAAQ,YAG9D,EAAQ,QAAQ,KAAK,MACrB,EAAQ,QAAQ,aAAa,WAG7B,GAAI,EAAQ,KAAK,WAAW,GACxB,EAAQ,SAAS,cAAgB,EAAQ,SAAS,eAAiB,EAEnE,EAAQ,QAAQ,KAAK,KAAK,EAAQ,MAClC,EAAQ,QAAQ,aAAa,KAAK,EAAQ,MAC1C,EAAS,KAAK,IAAI,EAAQ,cAAU,EAAW,CAC3C,KAAM,EAAQ,QAAQ,KACtB,aAAc,EAAQ,QAAQ,aAC9B,eAAgB,EAChB,uBAAwB,EAAQ,SAChC,KAAM,EAAQ,QAAQ,MAAQ,EAC9B,aAAc,EAAQ,QAAQ,cAAgB,EAAQ,WAEtD,EAAQ,SAAS,cAAgB,EAAQ,SAAS,QAGtD,EAAQ,SAAS,gBAAkB,EAAQ,KAAK,WAAW,GAE3D,EAAQ,QAAQ,KAAK,MACrB,EAAQ,QAAQ,aAAa,WAI7B,IAAK,EAAI,EAAG,EAAI,EAAQ,KAAK,MAAO,IAEhC,IAAK,EAAK,EAAG,EAAK,EAAQ,SAAS,OAAQ,IACvC,EAAQ,QAAQ,KAAK,KAAK,EAAO,QACjC,EAAQ,QAAQ,aAAa,KAAK,GAClC,EAAO,KACH,KAAK,IAAI,EAAQ,SAAS,GAAK,EAAO,OAAQ,CAC1C,KAAM,EAAQ,QAAQ,KACtB,aAAc,EAAQ,QAAQ,aAC9B,eAAgB,EAChB,uBAAwB,EAAQ,SAChC,KAAM,EAAQ,QAAQ,MAAQ,EAC9B,aAAc,EAAQ,QAAQ,cAAgB,EAAQ,YAG9D,EAAQ,QAAQ,KAAK,MACrB,EAAQ,QAAQ,aAAa,WA3E7C,IAAK,EAAI,EAAG,EAAI,EAAQ,SAAS,OAAQ,IACrC,EAAQ,QAAQ,KAAK,KAAK,GAC1B,EAAQ,QAAQ,aAAa,KAAK,GAClC,EAAO,KACH,KAAK,IAAI,EAAQ,SAAS,GAAI,EAAG,CAC7B,KAAM,EAAQ,QAAQ,KACtB,aAAc,EAAQ,QAAQ,aAC9B,eAAgB,EAChB,uBAAwB,EAAQ,SAChC,KAAM,EAAQ,QAAQ,MAAQ,EAC9B,aAAc,EAAQ,QAAQ,cAAgB,EAAQ,YAG9D,EAAQ,QAAQ,KAAK,MACrB,EAAQ,QAAQ,aAAa,MAmErC,OAAO,CACX,EACA,OAAQ,SAAS,GACb,IACI,EAAM,EAAQ,EAAK,EAAW,EAAK,EADnC,EAAS,CAAC,EAKd,GAAwB,MAApB,EAAQ,KAAK,IAIb,IAHA,EAAO,KAAK,KAAK,EAAQ,UAEzB,GADA,EAAO,OAAO,QAAQ,IACV,MAAM,EAAG,EAAQ,KAAK,OAC7B,EAAI,EAAG,EAAI,EAAK,OAAQ,IAEzB,GADA,EAAM,EAAK,IACK,QAAQ,SAAS,OAAQ,MACzC,EAAQ,QAAQ,KAAK,KAAK,GAC1B,EAAQ,QAAQ,aAAa,KAAK,GAClC,EAAO,GAAa,KAAK,IAAI,EAAQ,SAAS,GAAM,EAAK,CACrD,KAAM,EAAQ,QAAQ,KACtB,aAAc,EAAQ,QAAQ,aAC9B,eAAgB,EAChB,uBAAwB,EAAQ,SAChC,KAAM,EAAQ,QAAQ,MAAQ,EAC9B,aAAc,EAAQ,QAAQ,cAAgB,EAAQ,WAE1D,EAAQ,QAAQ,KAAK,MACrB,EAAQ,QAAQ,aAAa,UAG9B,CAIH,IAAK,KAFL,EAAO,GACP,EAAS,GACG,EAAQ,UACkB,mBAA1B,EAAQ,SAAS,GAAsB,EAAS,GAAM,KAAK,GAgBvE,IAdA,EAAO,EAAK,OAAO,GAcd,EAAI,EAAG,EAAI,EAAK,OAAQ,IAEzB,GADA,EAAM,EAAK,IACK,QAAQ,SAAS,OAAQ,MACzC,EAAQ,QAAQ,KAAK,KAAK,GAC1B,EAAQ,QAAQ,aAAa,KAAK,GAClC,EAAO,GAAa,KAAK,IAAI,EAAQ,SAAS,GAAM,EAAK,CACrD,KAAM,EAAQ,QAAQ,KACtB,aAAc,EAAQ,QAAQ,aAC9B,eAAgB,EAChB,uBAAwB,EAAQ,SAChC,KAAM,EAAQ,QAAQ,MAAQ,EAC9B,aAAc,EAAQ,QAAQ,cAAgB,EAAQ,WAE1D,EAAQ,QAAQ,KAAK,MACrB,EAAQ,QAAQ,aAAa,OAE7B,EAAM,EAAI,MAAM,SAAS,UACd,EAAI,IAA2C,WAArC,KAAK,KAAK,EAAQ,SAAS,MAC5C,EAAQ,SAAS,IAAQ,SAAS,EAAI,GAAI,IAGtD,CACA,OAAO,CACX,EACA,OAAQ,SAAS,GACb,IAAI,EAAQ,EACZ,GAAI,EAAQ,KAAK,QAAS,CAStB,IARA,EAAQ,UAAY,IACpB,EAAQ,EAAQ,SAAS,MAAM,MAKzB,GAAK,EAAQ,KAAK,MAAQ,EAAQ,KAAK,MAAQ,EAAM,GAC3D,EAAM,IAAM,EAAM,IAAM,IAAI,MAAM,EAAG,EAAQ,KAAK,QAC3C,EAAM,GAAG,OAAS,EAAQ,KAAK,QAClC,EAAM,IAED,EAAM,GAAG,OAAS,EAAQ,KAAK,OAAS,EAAK,OAAO,UAAU,UAAY,OAAO,UAAU,aAGpG,EAAS,WAAW,EAAM,KAAK,KAAM,GACzC,MAEI,EAAS,EAAQ,KAAK,QAAU,EAAQ,KAAK,WAAW,GAAK,EAAQ,KAAK,MAAQ,EAAQ,SAE9F,OAAO,CACX,EACA,QAAS,SAAS,GAKd,OADS,EAAQ,KAAK,WAAa,OAAO,KAAK,EAAQ,KAAK,IAAK,EAAQ,KAAK,IAAK,EAAQ,UAAY,EAAQ,QAEnH,EACA,OAAQ,SAAS,GACb,IACI,EAAG,EAAc,EAAI,EADrB,EAAS,GAEb,GAAI,EAAQ,SAAS,OAAQ,CASzB,IAL0B,MAAtB,EAAQ,KAAK,QACb,GAAU,EAAQ,UAIjB,EAAI,EAAG,EAAI,EAAQ,KAAK,MAAO,IAChC,GAAU,EAAQ,SAItB,IADA,EAAe,EAAO,MAAM,SAAS,iBAAmB,GACnD,EAAI,EAAG,EAAI,EAAa,OAAQ,IAIjC,GAHA,EAAK,EAAa,GAGd,MAAM,KAAK,GACX,EAAa,OAAO,IAAK,OAD7B,CAQA,GAHA,EAAO,KAAK,YAAY,EAAI,EAAQ,QAAQ,eAAgB,EAAQ,QAAQ,uBAAwB,GAGxE,IAAxB,EAAa,QAAgB,IAAO,UAAiB,UAAgB,EAAQ,CAC7E,EAAS,EACT,KAYJ,CACA,EAAS,EAAO,QAAQ,EAAI,EApB5B,CAuBR,MAGI,EAAS,EAAQ,KAAK,MAAQ,OAAO,OAAO,EAAQ,KAAK,OAAS,EAAQ,SAE9E,OAAO,CACX,EACA,SAAY,SAAS,GAEjB,OAAO,EAAQ,SAAS,KAAK,EAAQ,QAAQ,eAAgB,EACjE,EACA,OAAU,SAAS,GACf,IAAI,EAAS,GAIa,MAAtB,EAAQ,KAAK,QACb,GAAU,EAAQ,SAAS,QAI/B,IAAK,IAAI,EAAI,EAAG,EAAI,EAAQ,KAAK,MAAO,IACpC,GAAU,EAAQ,SAAS,OAG/B,OAAO,GAAG,QAAQ,IACd,GAAG,OAAO,MACN,GAGZ,IAGJ,KAAK,OAAO,CACR,KAAM,WACF,IAAI,EAAK,CAAC,EACV,IAAK,IAAI,KAAO,OAAQ,EAAG,EAAI,eAAiB,EAChD,OAAO,CACX,EAEA,YAAa,SAAS,YAAa,IAAK,gBAAiB,SAGrD,SAAS,eAAe,KAAK,IAC7B,IAAI,MAAQ,SAAS,eAAe,KAAK,aACrC,IAAM,OAAS,MAAM,GACrB,KAAO,KAAO,IAAI,cAClB,KAAO,KAAK,OAAO,MACnB,OAAS,OAAS,MAAM,IAAM,GAC9B,UAAY,KAAK,iBAAiB,KAGtC,IAQI,OAAS,KAAK,wDAA0D,OAAS,IACrF,CAAE,MAAO,GAKL,OAAS,MAAM,GAAG,MAAM,OAC5B,CAGA,GAAI,KAAQ,OAAO,IAAM,OAAO,IAAI,KAOpC,GACsB,MAAlB,IAAI,OAAO,IACX,UAAU,OAAS,EACrB,OAAO,KAAK,kBAAkB,IAAK,SAGrC,GAAI,iBAC4B,iBAApB,iBACP,OAAO,iBACP,cAAgB,gBAAgB,KAOjC,OAJA,gBAAgB,KAAO,KAAK,IAAI,gBAAgB,KAAM,IAAK,CACvD,eAAgB,IAChB,uBAAwB,kBAErB,gBAAgB,KAI3B,KAAM,OAAO,WAAa,QAAQ,WAAa,QAAQ,QAAS,OAAO,YAGvE,IAAK,IAAI,EAAI,EAAG,EAAI,OAAO,OAAQ,IAC/B,SAAS,eAAe,KAAK,IACzB,SAAS,eAAe,KAAK,OAAO,MACpC,OAAO,GAAK,KAAK,YAAY,OAAO,GAAI,IAAK,gBAAiB,UAItE,IAAI,OAAS,OAAO,MAAQ,OAAO,OAAS,OAAO,MACnD,OAAQ,KAAK,KAAK,SACd,IAAK,QAED,OAAO,OAAO,KAAK,QACvB,IAAK,WAED,OAAO,QAAU,QACjB,IAAI,GAAK,OAAO,MAAM,OAAQ,QAG9B,YAFW,IAAP,KAAkB,GAAK,WACpB,OAAO,QACP,GAEnB,EACA,kBAAmB,SAAS,EAAK,GAC7B,IAAI,EAAc,EACd,EAAe,KAAK,iBAAiB,GACrC,EAAoB,GAGF,MAAlB,EAAI,OAAO,GACX,EAAoB,CAAC,EAAQ,QAAQ,KAAK,IAAI,OAC1C,KAAK,cAAc,IAInB,EAAa,OAAS,KACtB,EAAoB,EAAQ,QAAQ,KAAK,MAAM,IAC7B,MAClB,EAAoB,KAAK,cACrB,EAAkB,OAAO,KAMrC,IACI,EAAM,EAAa,EAAa,OAAS,GAGzC,IAFA,IAAI,EAAiB,EAAQ,QAAQ,KACjC,EAAyB,EAAQ,QAAQ,aACpC,EAAI,EAAG,EAAI,EAAkB,OAAS,EAAG,IAC9C,EAAiB,EAAe,EAAkB,IAClD,EAAyB,EAAuB,EAAkB,IAGtE,GAAI,GAAmB,KAAO,EAAiB,OAAO,EAAe,GAGrE,GAAI,GACmC,iBAA3B,GACP,KAAO,GACP,IAAgB,EAAuB,GAOxC,OAJA,EAAuB,GAAO,KAAK,IAAI,EAAuB,GAAM,EAAK,CACrE,eAAgB,EAChB,uBAAwB,IAErB,EAAuB,EAEtC,CAAE,MAAM,GAAO,CAEf,MAAO,IAAM,EAAa,KAAK,IACnC,EAEA,cAAe,SAAS,GAEpB,IADA,IAAI,EAAe,GACV,EAAI,EAAG,EAAI,EAAU,OAAQ,IAClC,OAAQ,EAAU,IACd,IAAK,KACD,EAAa,MACb,MACJ,IAAK,IACD,MACJ,QACI,EAAa,KAAK,EAAU,IAGxC,OAAO,CACX,EACA,iBAAkB,SAAS,GACvB,IAAI,EAAQ,EAAK,MAAM,OAGvB,OAFK,EAAM,EAAM,OAAS,KAAI,EAAQ,EAAM,MAAM,GAAI,IACjD,EAAM,KAAI,EAAQ,EAAM,MAAM,IAC5B,CACX,IAGJ,KAAK,KAAO,KAAK,IAEjB,OAAO,QAAU","file":"/npm/@graphi/mockjs@1.0.0/src/index.js","sourceRoot":"","sourcesContent":["/**\n * Minified by jsDelivr using Terser v5.39.0.\n * Original file: /npm/@graphi/mockjs@1.0.0/src/index.js\n *\n * Do NOT use SRI with dynamically generated files! More information: https://www.jsdelivr.com/using-sri-with-dynamic-files\n */\n","/* \n    ## Handler\n\n    处理数据模板。\n    \n    * Handler.gen( template, name?, context? )\n\n        入口方法。\n\n    * Data Template Definition, DTD\n        \n        处理数据模板定义。\n\n        * Handler.array( options )\n        * Handler.object( options )\n        * Handler.number( options )\n        * Handler.boolean( options )\n        * Handler.string( options )\n        * Handler.function( options )\n        * Handler.regexp( options )\n        \n        处理路径（相对和绝对）。\n\n        * Handler.getValueByKeyPath( key, options )\n\n    * Data Placeholder Definition, DPD\n\n        处理数据占位符定义\n\n        * Handler.placeholder( placeholder, context, templateContext, options )\n\n*/\n\nvar Constant = require('./constant')\nvar Util = require('./util')\nvar Parser = require('./parser')\nvar Random = require('./random/')\nvar RE = require('./regexp')\n\nvar Mock = {\n    extend: Util.extend\n}\n\n/*\n    template        属性值（即数据模板）\n    name            属性名\n    context         数据上下文，生成后的数据\n    templateContext 模板上下文，\n\n    Handle.gen(template, name, options)\n    context\n        currentContext, templateCurrentContext, \n        path, templatePath\n        root, templateRoot\n*/\nMock.gen = function(template, name, context) {\n    /* jshint -W041 */\n    name = name == undefined ? '' : (name + '')\n\n    context = context || {}\n    context = {\n            // 当前访问路径，只有属性名，不包括生成规则\n            path: context.path || [Constant.GUID],\n            templatePath: context.templatePath || [Constant.GUID++],\n            // 最终属性值的上下文\n            currentContext: context.currentContext,\n            // 属性值模板的上下文\n            templateCurrentContext: context.templateCurrentContext || template,\n            // 最终值的根\n            root: context.root || context.currentContext,\n            // 模板的根\n            templateRoot: context.templateRoot || context.templateCurrentContext || template\n        }\n        // console.log('path:', context.path.join('.'), template)\n\n    var rule = Parser.parse(name)\n    var type = Util.type(template)\n    var data\n\n    if (Mock[type]) {\n        data = Mock[type]({\n            // 属性值类型\n            type: type,\n            // 属性值模板\n            template: template,\n            // 属性名 + 生成规则\n            name: name,\n            // 属性名\n            parsedName: name ? name.replace(Constant.RE_KEY, '$1') : name,\n\n            // 解析后的生成规则\n            rule: rule,\n            // 相关上下文\n            context: context\n        })\n\n        if (!context.root) context.root = data\n        return data\n    }\n\n    return template\n}\n\nMock.extend({\n    array: function(options) {\n        var result = [],\n            i, ii;\n\n        // 'name|1': []\n        // 'name|count': []\n        // 'name|min-max': []\n        if (options.template.length === 0) return result\n\n        // 'arr': [{ 'email': '@EMAIL' }, { 'email': '@EMAIL' }]\n        if (!options.rule.parameters) {\n            for (i = 0; i < options.template.length; i++) {\n                options.context.path.push(i)\n                options.context.templatePath.push(i)\n                result.push(\n                    Mock.gen(options.template[i], i, {\n                        path: options.context.path,\n                        templatePath: options.context.templatePath,\n                        currentContext: result,\n                        templateCurrentContext: options.template,\n                        root: options.context.root || result,\n                        templateRoot: options.context.templateRoot || options.template\n                    })\n                )\n                options.context.path.pop()\n                options.context.templatePath.pop()\n            }\n        } else {\n            // 'method|1': ['GET', 'POST', 'HEAD', 'DELETE']\n            if (options.rule.min === 1 && options.rule.max === undefined) {\n                // fix #17\n                options.context.path.push(options.name)\n                options.context.templatePath.push(options.name)\n                result = Random.pick(\n                    Mock.gen(options.template, undefined, {\n                        path: options.context.path,\n                        templatePath: options.context.templatePath,\n                        currentContext: result,\n                        templateCurrentContext: options.template,\n                        root: options.context.root || result,\n                        templateRoot: options.context.templateRoot || options.template\n                    })\n                )\n                options.context.path.pop()\n                options.context.templatePath.pop()\n            } else {\n                // 'data|+1': [{}, {}]\n                if (options.rule.parameters[2]) {\n                    options.template.__order_index = options.template.__order_index || 0\n\n                    options.context.path.push(options.name)\n                    options.context.templatePath.push(options.name)\n                    result = Mock.gen(options.template, undefined, {\n                        path: options.context.path,\n                        templatePath: options.context.templatePath,\n                        currentContext: result,\n                        templateCurrentContext: options.template,\n                        root: options.context.root || result,\n                        templateRoot: options.context.templateRoot || options.template\n                    })[\n                        options.template.__order_index % options.template.length\n                    ]\n\n                    options.template.__order_index += +options.rule.parameters[2]\n\n                    options.context.path.pop()\n                    options.context.templatePath.pop()\n\n                } else {\n                    // 'data|1-10': [{}]\n                    for (i = 0; i < options.rule.count; i++) {\n                        // 'data|1-10': [{}, {}]\n                        for (ii = 0; ii < options.template.length; ii++) {\n                            options.context.path.push(result.length)\n                            options.context.templatePath.push(ii)\n                            result.push(\n                                Mock.gen(options.template[ii], result.length, {\n                                    path: options.context.path,\n                                    templatePath: options.context.templatePath,\n                                    currentContext: result,\n                                    templateCurrentContext: options.template,\n                                    root: options.context.root || result,\n                                    templateRoot: options.context.templateRoot || options.template\n                                })\n                            )\n                            options.context.path.pop()\n                            options.context.templatePath.pop()\n                        }\n                    }\n                }\n            }\n        }\n        return result\n    },\n    object: function(options) {\n        var result = {},\n            keys, fnKeys, key, parsedKey, inc, i;\n\n        // 'obj|min-max': {}\n        /* jshint -W041 */\n        if (options.rule.min != undefined) {\n            keys = Util.keys(options.template)\n            keys = Random.shuffle(keys)\n            keys = keys.slice(0, options.rule.count)\n            for (i = 0; i < keys.length; i++) {\n                key = keys[i]\n                parsedKey = key.replace(Constant.RE_KEY, '$1')\n                options.context.path.push(parsedKey)\n                options.context.templatePath.push(key)\n                result[parsedKey] = Mock.gen(options.template[key], key, {\n                    path: options.context.path,\n                    templatePath: options.context.templatePath,\n                    currentContext: result,\n                    templateCurrentContext: options.template,\n                    root: options.context.root || result,\n                    templateRoot: options.context.templateRoot || options.template\n                })\n                options.context.path.pop()\n                options.context.templatePath.pop()\n            }\n\n        } else {\n            // 'obj': {}\n            keys = []\n            fnKeys = [] // #25 改变了非函数属性的顺序，查找起来不方便\n            for (key in options.template) {\n                (typeof options.template[key] === 'function' ? fnKeys : keys).push(key)\n            }\n            keys = keys.concat(fnKeys)\n\n            /*\n                会改变非函数属性的顺序\n                keys = Util.keys(options.template)\n                keys.sort(function(a, b) {\n                    var afn = typeof options.template[a] === 'function'\n                    var bfn = typeof options.template[b] === 'function'\n                    if (afn === bfn) return 0\n                    if (afn && !bfn) return 1\n                    if (!afn && bfn) return -1\n                })\n            */\n\n            for (i = 0; i < keys.length; i++) {\n                key = keys[i]\n                parsedKey = key.replace(Constant.RE_KEY, '$1')\n                options.context.path.push(parsedKey)\n                options.context.templatePath.push(key)\n                result[parsedKey] = Mock.gen(options.template[key], key, {\n                    path: options.context.path,\n                    templatePath: options.context.templatePath,\n                    currentContext: result,\n                    templateCurrentContext: options.template,\n                    root: options.context.root || result,\n                    templateRoot: options.context.templateRoot || options.template\n                })\n                options.context.path.pop()\n                options.context.templatePath.pop()\n                    // 'id|+1': 1\n                inc = key.match(Constant.RE_KEY)\n                if (inc && inc[2] && Util.type(options.template[key]) === 'number') {\n                    options.template[key] += parseInt(inc[2], 10)\n                }\n            }\n        }\n        return result\n    },\n    number: function(options) {\n        var result, parts;\n        if (options.rule.decimal) { // float\n            options.template += ''\n            parts = options.template.split('.')\n                // 'float1|.1-10': 10,\n                // 'float2|1-100.1-10': 1,\n                // 'float3|999.1-10': 1,\n                // 'float4|.3-10': 123.123,\n            parts[0] = options.rule.range ? options.rule.count : parts[0]\n            parts[1] = (parts[1] || '').slice(0, options.rule.dcount)\n            while (parts[1].length < options.rule.dcount) {\n                parts[1] += (\n                    // 最后一位不能为 0：如果最后一位为 0，会被 JS 引擎忽略掉。\n                    (parts[1].length < options.rule.dcount - 1) ? Random.character('number') : Random.character('123456789')\n                )\n            }\n            result = parseFloat(parts.join('.'), 10)\n        } else { // integer\n            // 'grade1|1-100': 1,\n            result = options.rule.range && !options.rule.parameters[2] ? options.rule.count : options.template\n        }\n        return result\n    },\n    boolean: function(options) {\n        var result;\n        // 'prop|multiple': false, 当前值是相反值的概率倍数\n        // 'prop|probability-probability': false, 当前值与相反值的概率\n        result = options.rule.parameters ? Random.bool(options.rule.min, options.rule.max, options.template) : options.template\n        return result\n    },\n    string: function(options) {\n        var result = '',\n            i, placeholders, ph, phed;\n        if (options.template.length) {\n\n            //  'foo': '★',\n            /* jshint -W041 */\n            if (options.rule.count == undefined) {\n                result += options.template\n            }\n\n            // 'star|1-5': '★',\n            for (i = 0; i < options.rule.count; i++) {\n                result += options.template\n            }\n            // 'email|1-10': '@EMAIL, ',\n            placeholders = result.match(Constant.RE_PLACEHOLDER) || [] // A-Z_0-9 > \\w_\n            for (i = 0; i < placeholders.length; i++) {\n                ph = placeholders[i]\n\n                // 遇到转义斜杠，不需要解析占位符\n                if (/^\\\\/.test(ph)) {\n                    placeholders.splice(i--, 1)\n                    continue\n                }\n\n                phed = Mock.placeholder(ph, options.context.currentContext, options.context.templateCurrentContext, options)\n\n                // 只有一个占位符，并且没有其他字符\n                if (placeholders.length === 1 && ph === result && typeof phed !== typeof result) { // \n                    result = phed\n                    break\n\n                    if (Util.isNumeric(phed)) {\n                        result = parseFloat(phed, 10)\n                        break\n                    }\n                    if (/^(true|false)$/.test(phed)) {\n                        result = phed === 'true' ? true :\n                            phed === 'false' ? false :\n                            phed // 已经是布尔值\n                        break\n                    }\n                }\n                result = result.replace(ph, phed)\n            }\n\n        } else {\n            // 'ASCII|1-10': '',\n            // 'ASCII': '',\n            result = options.rule.range ? Random.string(options.rule.count) : options.template\n        }\n        return result\n    },\n    'function': function(options) {\n        // ( context, options )\n        return options.template.call(options.context.currentContext, options)\n    },\n    'regexp': function(options) {\n        var source = ''\n\n        // 'name': /regexp/,\n        /* jshint -W041 */\n        if (options.rule.count == undefined) {\n            source += options.template.source // regexp.source\n        }\n\n        // 'name|1-5': /regexp/,\n        for (var i = 0; i < options.rule.count; i++) {\n            source += options.template.source\n        }\n\n        return RE.Handler.gen(\n            RE.Parser.parse(\n                source\n            )\n        )\n    }\n})\n\nMock.extend({\n    _all: function() {\n        var re = {};\n        for (var key in Random) re[key.toLowerCase()] = key\n        return re\n    },\n    // 处理占位符，转换为最终值\n    placeholder: function(placeholder, obj, templateContext, options) {\n        // console.log(options.context.path)\n        // 1 key, 2 params\n        Constant.RE_PLACEHOLDER.exec('')\n        var parts = Constant.RE_PLACEHOLDER.exec(placeholder),\n            key = parts && parts[1],\n            lkey = key && key.toLowerCase(),\n            okey = this._all()[lkey],\n            params = parts && parts[2] || ''\n        var pathParts = this.splitPathToArray(key)\n\n        // 解析占位符的参数\n        try {\n            // 1. 尝试保持参数的类型\n            /*\n                #24 [Window Firefox 30.0 引用 占位符 抛错](https://github.com/nuysoft/Mock/issues/24)\n                [BX9056: 各浏览器下 window.eval 方法的执行上下文存在差异](http://www.w3help.org/zh-cn/causes/BX9056)\n                应该属于 Window Firefox 30.0 的 BUG\n            */\n            /* jshint -W061 */\n            params = eval('(function(){ return [].splice.call(arguments, 0 ) })(' + params + ')')\n        } catch (error) {\n            // 2. 如果失败，只能解析为字符串\n            // console.error(error)\n            // if (error instanceof ReferenceError) params = parts[2].split(/,\\s*/);\n            // else throw error\n            params = parts[2].split(/,\\s*/)\n        }\n\n        // 占位符优先引用数据模板中的属性\n        if (obj && (key in obj)) return obj[key]\n\n        // @index @key\n        // if (Constant.RE_INDEX.test(key)) return +options.name\n        // if (Constant.RE_KEY.test(key)) return options.name\n\n        // 绝对路径 or 相对路径\n        if (\n            key.charAt(0) === '/' ||\n            pathParts.length > 1\n        ) return this.getValueByKeyPath(key, options)\n\n        // 递归引用数据模板中的属性\n        if (templateContext &&\n            (typeof templateContext === 'object') &&\n            (key in templateContext) &&\n            (placeholder !== templateContext[key]) // fix #15 避免自己依赖自己\n        ) {\n            // 先计算被引用的属性值\n            templateContext[key] = Mock.gen(templateContext[key], key, {\n                currentContext: obj,\n                templateCurrentContext: templateContext\n            })\n            return templateContext[key]\n        }\n\n        // 如果未找到，则原样返回\n        if (!(key in Random) && !(lkey in Random) && !(okey in Random)) return placeholder\n\n        // 递归解析参数中的占位符\n        for (var i = 0; i < params.length; i++) {\n            Constant.RE_PLACEHOLDER.exec('')\n            if (Constant.RE_PLACEHOLDER.test(params[i])) {\n                params[i] = Mock.placeholder(params[i], obj, templateContext, options)\n            }\n        }\n\n        var handle = Random[key] || Random[lkey] || Random[okey]\n        switch (Util.type(handle)) {\n            case 'array':\n                // 自动从数组中取一个，例如 @areas\n                return Random.pick(handle)\n            case 'function':\n                // 执行占位符方法（大多数情况）\n                handle.options = options\n                var re = handle.apply(Random, params)\n                if (re === undefined) re = '' // 因为是在字符串中，所以默认为空字符串。\n                delete handle.options\n                return re\n        }\n    },\n    getValueByKeyPath: function(key, options) {\n        var originalKey = key\n        var keyPathParts = this.splitPathToArray(key)\n        var absolutePathParts = []\n\n        // 绝对路径\n        if (key.charAt(0) === '/') {\n            absolutePathParts = [options.context.path[0]].concat(\n                this.normalizePath(keyPathParts)\n            )\n        } else {\n            // 相对路径\n            if (keyPathParts.length > 1) {\n                absolutePathParts = options.context.path.slice(0)\n                absolutePathParts.pop()\n                absolutePathParts = this.normalizePath(\n                    absolutePathParts.concat(keyPathParts)\n                )\n\n            }\n        }\n\n        try {\n            key = keyPathParts[keyPathParts.length - 1]\n            var currentContext = options.context.root\n            var templateCurrentContext = options.context.templateRoot\n            for (var i = 1; i < absolutePathParts.length - 1; i++) {\n                currentContext = currentContext[absolutePathParts[i]]\n                templateCurrentContext = templateCurrentContext[absolutePathParts[i]]\n            }\n            // 引用的值已经计算好\n            if (currentContext && (key in currentContext)) return currentContext[key]\n    \n            // 尚未计算，递归引用数据模板中的属性\n            if (templateCurrentContext &&\n                (typeof templateCurrentContext === 'object') &&\n                (key in templateCurrentContext) &&\n                (originalKey !== templateCurrentContext[key]) // fix #15 避免自己依赖自己\n            ) {\n                // 先计算被引用的属性值\n                templateCurrentContext[key] = Mock.gen(templateCurrentContext[key], key, {\n                    currentContext: currentContext,\n                    templateCurrentContext: templateCurrentContext\n                })\n                return templateCurrentContext[key]\n            }\n        } catch(err) { }\n\n        return '@' + keyPathParts.join('/')\n    },\n    // https://github.com/kissyteam/kissy/blob/master/src/path/src/path.js\n    normalizePath: function(pathParts) {\n        var newPathParts = []\n        for (var i = 0; i < pathParts.length; i++) {\n            switch (pathParts[i]) {\n                case '..':\n                    newPathParts.pop()\n                    break\n                case '.':\n                    break\n                default:\n                    newPathParts.push(pathParts[i])\n            }\n        }\n        return newPathParts\n    },\n    splitPathToArray: function(path) {\n        var parts = path.split(/\\/+/);\n        if (!parts[parts.length - 1]) parts = parts.slice(0, -1)\n        if (!parts[0]) parts = parts.slice(1)\n        return parts;\n    }\n})\n\nMock.mock = Mock.gen\n\nmodule.exports = Mock"]}