├── configs ├── api_cfg.js ├── build │ ├── webpack.development.js │ ├── webpack.production.js │ └── webpack.base.js └── site_cfg.js ├── models └── .gitkeep ├── controllers └── index.js ├── middlewares └── .gitkeep ├── public └── src │ ├── styles │ ├── main.scss │ └── icon.scss │ ├── scripts │ └── common │ │ └── index.js │ ├── fonts │ ├── iconfont.eot │ ├── iconfont.ttf │ ├── iconfont.woff │ └── iconfont.svg │ └── js │ ├── core.js.map │ ├── core.js │ ├── common.js.map │ └── common.js ├── views └── dev │ ├── home │ └── index.html │ └── layouts │ └── main.html ├── routers ├── index.js └── home.js ├── test └── test.js ├── kits ├── cache_kit.js ├── logger_kit.js └── api_kit.js ├── .eslintrc.js ├── .jsbeautifyrc ├── README.md ├── .gitignore ├── app.js ├── package.json └── gulpfile.js /configs/api_cfg.js: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /models/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /controllers/index.js: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /middlewares/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /public/src/styles/main.scss: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /public/src/scripts/common/index.js: -------------------------------------------------------------------------------- 1 | const $ = require('zepto'); 2 | -------------------------------------------------------------------------------- /views/dev/home/index.html: -------------------------------------------------------------------------------- 1 | {% extends 'layouts/main.html' %} 2 | 3 | {% block body %} 4 | 测试 5 | {% endblock %} -------------------------------------------------------------------------------- /public/src/fonts/iconfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jaylinwang/koa-skeleton/HEAD/public/src/fonts/iconfont.eot -------------------------------------------------------------------------------- /public/src/fonts/iconfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jaylinwang/koa-skeleton/HEAD/public/src/fonts/iconfont.ttf -------------------------------------------------------------------------------- /public/src/fonts/iconfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jaylinwang/koa-skeleton/HEAD/public/src/fonts/iconfont.woff -------------------------------------------------------------------------------- /configs/build/webpack.development.js: -------------------------------------------------------------------------------- 1 | const merge = require('webpack-merge'); 2 | const webpackBaseCfg = require('./webpack.base'); 3 | 4 | module.exports = merge(webpackBaseCfg, { 5 | cache: true, 6 | devtool: '#source-map', 7 | }); 8 | -------------------------------------------------------------------------------- /routers/index.js: -------------------------------------------------------------------------------- 1 | const Router = require('koa-router'); 2 | const homeRouter = require('./home'); 3 | 4 | const router = new Router(); 5 | 6 | router.use('/', homeRouter.routes(), homeRouter.allowedMethods()); 7 | 8 | module.exports = router; 9 | -------------------------------------------------------------------------------- /routers/home.js: -------------------------------------------------------------------------------- 1 | const Router = require('koa-router'); 2 | 3 | const router = new Router(); 4 | 5 | router.get('/', (ctx, next) => { 6 | return next().then(() => { 7 | // ctx.body = 'home'; 8 | return ctx.render('home/index'); 9 | }); 10 | }); 11 | 12 | module.exports = router; 13 | -------------------------------------------------------------------------------- /test/test.js: -------------------------------------------------------------------------------- 1 | import test from 'ava'; 2 | 3 | const apiKit = require('../kits/api_kit'); 4 | 5 | test('api_request', t => { 6 | const promise = apiKit.post('http://ht.p.jx-cloud.cc:3032/api/pub/live/getLatestCourses'); 7 | return promise.then(body => { 8 | t.deepEqual({ 9 | ret: -212, 10 | message: 'invalid client_id', 11 | }, body); 12 | }); 13 | }); 14 | -------------------------------------------------------------------------------- /configs/build/webpack.production.js: -------------------------------------------------------------------------------- 1 | const webpack = require('webpack'); 2 | const merge = require('webpack-merge'); 3 | const webpackBaseCfg = require('./webpack.base'); 4 | 5 | module.exports = merge(webpackBaseCfg, { 6 | cache: true, 7 | devtool: '#source-map', 8 | plugins: [ 9 | new webpack.optimize.UglifyJsPlugin({ 10 | compress: { 11 | warnings: false, 12 | }, 13 | }), 14 | ], 15 | }); 16 | -------------------------------------------------------------------------------- /views/dev/layouts/main.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | {{brandName}} 7 | 8 | {% block style %} 9 | 10 | {% endblock %} 11 | 12 | 13 | 14 | {% block body %} 15 | 16 | {% endblock %} 17 | 18 | {% block script %} 19 | 20 | {% endblock %} 21 | 22 | 23 | -------------------------------------------------------------------------------- /kits/cache_kit.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const bunyan = require('bunyan'); 4 | const Redis = require('ioredis'); 5 | 6 | const logger = bunyan.createLogger({ 7 | name: 'api request', 8 | }); 9 | 10 | module.exports = (opts) => { 11 | const redis = new Redis(opts); 12 | redis.on('error', (err) => { 13 | if (err) { 14 | logger.error('connect to redis error, check your redis config', err); 15 | process.exit(1); 16 | } 17 | }); 18 | return redis; 19 | }; 20 | -------------------------------------------------------------------------------- /.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | "extends": "airbnb", 3 | "rules": { 4 | strict: "off", 5 | "indent": [ 6 | "error", 7 | 4, { 8 | "SwitchCase": 1 9 | } 10 | ], 11 | "max-len": ["error", 120, 4], 12 | "func-names": ["error", "never"], 13 | "import/no-extraneous-dependencies": ["error", { 14 | "devDependencies": true, 15 | "optionalDependencies": false, 16 | "peerDependencies": false 17 | }] 18 | } 19 | }; 20 | -------------------------------------------------------------------------------- /kits/logger_kit.js: -------------------------------------------------------------------------------- 1 | const bunyan = require('bunyan'); 2 | 3 | function reqSerializer(req) { 4 | return { 5 | method: req.method, 6 | url: req.uri.href, 7 | headers: req.headers, 8 | body: req.body, 9 | }; 10 | } 11 | 12 | const logger = bunyan.createLogger({ 13 | name: 'hiteacher', 14 | streams: [{ 15 | level: 'info', 16 | stream: process.stdout, 17 | }, { 18 | level: 'error', 19 | stream: process.stdout, 20 | }], 21 | serializers: { 22 | req: reqSerializer, 23 | }, 24 | }); 25 | 26 | module.exports = logger; 27 | -------------------------------------------------------------------------------- /.jsbeautifyrc: -------------------------------------------------------------------------------- 1 | { 2 | "indent_size": 4, 3 | "indent_char": " ", 4 | "eol": "\n", 5 | "indent_level": 0, 6 | "indent_with_tabs": false, 7 | "preserve_newlines": true, 8 | "max_preserve_newlines": 10, 9 | "jslint_happy": true, 10 | "space_after_anon_function": false, 11 | "brace_style": "collapse", 12 | "keep_array_indentation": false, 13 | "keep_function_indentation": false, 14 | "space_before_conditional": true, 15 | "break_chained_methods": false, 16 | "eval_code": false, 17 | "unescape_strings": false, 18 | "wrap_line_length": 0, 19 | "wrap_attributes": "auto", 20 | "wrap_attributes_indent_size": 4, 21 | "end_with_newline": true 22 | } 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # koa-skeleton 2 | 3 | ## 项目描述 4 | 5 | 基于koa2的web项目架子,自娱自乐,仅供参考,欢迎指正 :) 6 | 7 | ## 目录结构 8 | 9 | `+`表示一级目录,`++`表示二级目录,`+++`表示三级级目录, 10 | 11 | ``` 12 | + configs(项目配置文件目录) 13 | ++ build(项目编译相关配置) * 14 | 15 | + controllers(项目业务控制代码目录) 16 | 17 | + kits(常用工具包) 18 | 19 | + middlewares(项目中间件) 20 | 21 | + models(业务数据对象,可以是操作数据库,可以是来源于调用api) 22 | 23 | + public(静态资源目录) 24 | ++ src(项目静态资源源文件) 25 | +++ fonts(字体文件) 26 | +++ iamges(图片) 27 | +++ styles(未编译样式脚本,本项目使用sass) 28 | +++ scripts(未编译js脚本,本项目部分使用es6) 29 | ++ publish(项目静态资源发布文件,发布自动生成) 30 | 31 | + routers(路由配置文件目录) 32 | 33 | + test(项目相关测试文件) 34 | 35 | + views(项目视图目录) 36 | ++ dev(开发视图文件) 37 | ++ pro(发布视图文件,发布自动生成) 38 | 39 | + app.js(项目入口) 40 | 41 | ``` 42 | 43 | ## License 44 | 45 | MIT - [@jaylinwang](https://github.com/jaylinwang) 46 | 47 | -------------------------------------------------------------------------------- /public/src/styles/icon.scss: -------------------------------------------------------------------------------- 1 | @font-face {font-family: "iconfont"; 2 | src: url('../fonts/iconfont.eot?t=1472017686'); /* IE9*/ 3 | src: url('../fonts/iconfont.eot?t=1472017686#iefix') format('embedded-opentype'), /* IE6-IE8 */ 4 | url('../fonts/iconfont.woff?t=1472017686') format('woff'), /* chrome, firefox */ 5 | url('../fonts/iconfont.ttf?t=1472017686') format('truetype'), /* chrome, firefox, opera, Safari, Android, iOS 4.2+*/ 6 | url('../fonts/iconfont.svg?t=1472017686#iconfont') format('svg'); /* iOS 4.1- */ 7 | } 8 | 9 | .iconfont { 10 | font-family:"iconfont" !important; 11 | font-size:16px; 12 | font-style:normal; 13 | -webkit-font-smoothing: antialiased; 14 | -webkit-text-stroke-width: 0.2px; 15 | -moz-osx-font-smoothing: grayscale; 16 | } 17 | .icon-scan:before { content: "\e601"; } 18 | .icon-jiudianxinxi:before { content: "\e602"; } 19 | .icon-jingdian2:before { content: "\e600"; } 20 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Created by .ignore support plugin (hsz.mobi) 2 | ### Node template 3 | # Logs 4 | logs 5 | *.log 6 | npm-debug.log* 7 | 8 | # Runtime data 9 | pids 10 | *.pid 11 | *.seed 12 | 13 | # Directory for instrumented libs generated by jscoverage/JSCover 14 | lib-cov 15 | 16 | # Coverage directory used by tools like istanbul 17 | coverage 18 | 19 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 20 | .grunt 21 | 22 | # node-waf configuration 23 | .lock-wscript 24 | 25 | # Compiled binary addons (http://nodejs.org/api/addons.html) 26 | public/build 27 | public/publish 28 | public/temp/upload_* 29 | public/temp/avatar_* 30 | 31 | # Dependency directory 32 | # https://docs.npmjs.com/misc/faq#should-i-check-my-node-modules-folder-into-git 33 | node_modules 34 | ### Example user template template 35 | ### Example user template 36 | 37 | # IntelliJ project files 38 | .idea 39 | *.iml 40 | out 41 | gen 42 | 43 | .DS_Store 44 | typings -------------------------------------------------------------------------------- /app.js: -------------------------------------------------------------------------------- 1 | const Koa = require('koa'); 2 | const views = require('koa-views'); 3 | const nunjucks = require('nunjucks'); 4 | const session = require('koa-generic-session'); 5 | const redisStore = require('koa-redis'); 6 | const convert = require('koa-convert'); 7 | const csrf = require('koa-csrf'); 8 | 9 | const logger = require('./kits/logger_kit'); 10 | const routers = require('./routers'); 11 | const siteCfg = require('./configs/site_cfg'); 12 | 13 | const app = new Koa(); 14 | 15 | app.use(convert(session({ 16 | store: redisStore(siteCfg.redis), 17 | }))); 18 | 19 | app.use(convert(csrf())); 20 | 21 | app.use(views(siteCfg.view_path, { 22 | map: { 23 | html: 'nunjucks', 24 | }, 25 | })); 26 | 27 | // nunjucks配置 28 | nunjucks.configure(siteCfg.view_path); 29 | 30 | app.use(routers.routes()); 31 | 32 | app.listen(siteCfg.port, () => { 33 | logger.info({ 34 | port: siteCfg.port, 35 | env: app.env, 36 | }, '服务器启动信息'); 37 | }); 38 | -------------------------------------------------------------------------------- /configs/build/webpack.base.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | const webpack = require('webpack'); 3 | const CommonsChunkPlugin = require('webpack/lib/optimize/CommonsChunkPlugin'); 4 | // const npmRoot = path.resolve(process.cwd(), 'node_modules'); 5 | 6 | module.exports = { 7 | context: path.resolve(process.cwd(), 'public/src'), 8 | entry: { 9 | common: ['./scripts/common/index'], 10 | }, 11 | output: { 12 | path: path.join(process.cwd(), 'public/src/js/'), 13 | publicPath: 'src/js/', 14 | filename: '[name].js', 15 | }, 16 | resolve: { 17 | alias: {}, 18 | }, 19 | module: { 20 | loaders: [{ 21 | test: /\.css$/, 22 | loaders: ['style', 'css'], 23 | }, { 24 | test: /\.(woff2?|svg)$/, 25 | loader: 'url?limit=10000', 26 | }, { 27 | test: /\.(ttf|eot)$/, 28 | loader: 'file', 29 | }, { 30 | test: /\.js$/, 31 | exclude: /node_modules/, 32 | loader: 'babel', 33 | query: { 34 | presets: ['es2015'], 35 | }, 36 | }], 37 | }, 38 | plugins: [ 39 | new CommonsChunkPlugin({ 40 | name: 'core', 41 | filename: 'core.js', 42 | }), 43 | new webpack.ProvidePlugin({}), 44 | ], 45 | }; 46 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "koa-skeleton", 3 | "version": "0.1.0", 4 | "description": "koa-skeleton", 5 | "main": "app.js", 6 | "scripts": { 7 | "test": "ava", 8 | "wechat-dev": "gulp dev:wechat --use-strict" 9 | }, 10 | "repository": { 11 | "type": "git", 12 | "url": "https://github.com/jaylinwang/koa-skeleton.git" 13 | }, 14 | "keywords": [ 15 | "koa-skeleton" 16 | ], 17 | "author": "JaylinWang", 18 | "license": "MIT", 19 | "dependencies": { 20 | "ava": "^0.16.0", 21 | "bluebird": "^3.4.1", 22 | "bunyan": "^1.8.1", 23 | "ioredis": "^2.3.0", 24 | "koa": "^2.0.0-alpha.5", 25 | "koa-convert": "^1.2.0", 26 | "koa-csrf": "^2.5.0", 27 | "koa-generic-session": "^1.11.3", 28 | "koa-redis": "^2.1.2", 29 | "koa-router": "^7.0.1", 30 | "koa-views": "^5.0.2", 31 | "lodash": "^4.15.0", 32 | "nunjucks": "^2.4.2", 33 | "request": "^2.74.0", 34 | "requestretry": "^1.10.0", 35 | "zepto": "^1.2.0" 36 | }, 37 | "devDependencies": { 38 | "ava": "^0.16.0", 39 | "babel-core": "^6.13.2", 40 | "babel-loader": "^6.2.5", 41 | "babel-preset-es2015": "^6.13.2", 42 | "css-loader": "^0.24.0", 43 | "del": "^2.2.2", 44 | "eslint": "^3.3.1", 45 | "eslint-config-airbnb": "^10.0.1", 46 | "eslint-plugin-import": "^1.14.0", 47 | "eslint-plugin-jsx-a11y": "^2.1.0", 48 | "eslint-plugin-react": "^6.1.2", 49 | "file-loader": "^0.9.0", 50 | "gulp": "^3.9.1", 51 | "gulp-base64": "^0.1.3", 52 | "gulp-nodemon": "^2.1.0", 53 | "gulp-plumber": "^1.1.0", 54 | "gulp-rev": "^7.1.2", 55 | "gulp-rev-replace": "^0.4.3", 56 | "gulp-sass": "^2.3.2", 57 | "gulp-sequence": "^0.4.5", 58 | "gulp-util": "^3.0.7", 59 | "style-loader": "^0.13.1", 60 | "webpack": "^1.13.2", 61 | "webpack-merge": "^0.14.1" 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /kits/api_kit.js: -------------------------------------------------------------------------------- 1 | const bunyan = require('bunyan'); 2 | const Promise = require('bluebird'); 3 | 4 | const logger = bunyan.createLogger({ 5 | name: 'api request', 6 | }); 7 | 8 | const baseRequest = require('requestretry').defaults({ 9 | gzip: true, 10 | encoding: 'utf8', 11 | headers: { 12 | 'User-Agent': 'request from node', 13 | }, 14 | maxAttempts: 3, // 最大尝试次数 15 | retryDelay: 3000, // 每次重试间隔时间 16 | fullResponse: true, 17 | promiseFactory: (resolver) => new Promise(resolver), 18 | }); 19 | 20 | /** 21 | * api请求 22 | * @param {string} url 23 | * @param {Object} data 24 | * @param {Object} options 25 | */ 26 | const request = function (url, data, options) { 27 | const mData = Object.assign({}, data || {}); 28 | const mOptions = Object.assign({ 29 | url, 30 | form: mData, 31 | }, options || {}); 32 | const beginDate = new Date(); 33 | return baseRequest(mOptions).then((response) => { 34 | const time = new Date() - beginDate; 35 | logger.info(`request <${url}> cost ${time}`); 36 | try { 37 | const body = JSON.parse(response.body); 38 | if (body.ret !== -500 && body.ret !== -404) { 39 | return body; 40 | } 41 | logger.error({ 42 | error: body, 43 | }, 'API请求错误'); 44 | throw new Error('API请求错误'); 45 | } catch (error) { 46 | throw new Error('API返回一个非json数据'); 47 | } 48 | }).catch((error) => { 49 | logger.error({ 50 | error, 51 | }); 52 | }); 53 | }; 54 | 55 | /** 56 | * api post请求 57 | * @param {string} url 58 | * @param {Object} data 59 | * @param {Object} options 60 | */ 61 | const post = function (url, data, options) { 62 | Object.assign({ 63 | method: 'POST', 64 | }, options || {}); 65 | 66 | return request(url, data, options); 67 | }; 68 | 69 | /** 70 | * api get请求 71 | * @param {string} url 72 | * @param {Object} data 73 | * @param {Object} options 74 | */ 75 | const get = function (url, data, options) { 76 | Object.assign({ 77 | method: 'GET', 78 | }, options || {}); 79 | return request(url, data, options); 80 | }; 81 | 82 | exports.get = get; 83 | exports.post = post; 84 | -------------------------------------------------------------------------------- /configs/site_cfg.js: -------------------------------------------------------------------------------- 1 | const config = { 2 | /** 3 | * 程序运行端口 4 | */ 5 | port: 3000, 6 | 7 | /** 8 | * 静态资源路径 9 | */ 10 | resource_url: '/build', 11 | 12 | /** 13 | * 视图路径 14 | */ 15 | view_path: `${process.cwd()}/views/dev`, 16 | 17 | /** 18 | * redis 19 | */ 20 | redis: { 21 | host: '', 22 | port: 6379, 23 | prefix: 'jaylinwang_session_', 24 | pass: '', 25 | db: 7, 26 | ttl: 60 * 60 * 2, 27 | }, 28 | 29 | /** 30 | * session secret setting 31 | */ 32 | session_secret: 'jaylinwang_secret', 33 | 34 | /** 35 | * auth_cookie_name setting 36 | */ 37 | auth_cookie_name: 'sunny', 38 | 39 | /** 40 | * 执行上下文 41 | */ 42 | scope: 'wechat', 43 | 44 | /** 45 | * 站点地址 46 | */ 47 | site_url: 'http://172.16.1.224:4000', 48 | }; 49 | 50 | //= ================================================ 51 | // # 微信环境配置 52 | //= ================================================ 53 | 54 | // 微信上下文 55 | // 56 | if (process.env.NODE_ENV === 'wechat-dev' || 57 | process.env.NODE_ENV === 'wechat-preprod' || 58 | process.env.NODE_ENV === 'wechat-prod') { 59 | config.scope = 'wechat'; 60 | config.port = 4000; 61 | config.session_secret = 'jaylinwang_wechat_secret'; 62 | config.auth_cookie_name = 'jaylinwang_wechat'; 63 | config.site_url = 'http://172.16.1.224:4000'; 64 | } 65 | 66 | // 预生产环境 67 | // 68 | if (process.env.NODE_ENV === 'wechat-preprod') { 69 | config.resource_url = ''; 70 | config.site_url = 'http://w.jx-cloud.cc'; 71 | config.view_path = `${process.cwd()}/views/pro`; 72 | } 73 | 74 | // 生产环境 75 | if (process.env.NODE_ENV === 'wechat-prod') { 76 | config.resource_url = ''; 77 | config.site_url = 'http://jaylinwang_wechat.com.cn'; 78 | config.view_path = `${process.cwd()}/views/pro`; 79 | config.redis = { 80 | // # 内网 81 | host: '', 82 | // # 外网 83 | // host: '120.24.44.32', 84 | port: 6379, 85 | pass: '', 86 | db: 7, 87 | prefix: 'jaylinwang_wechat_session_', 88 | ttl: 60 * 60 * 2, 89 | }; 90 | } 91 | 92 | //= ================================================ 93 | // # 手机网站环境配置 94 | //= ================================================ 95 | 96 | // wap上下文 97 | if (process.env.NODE_ENV === 'wap-dev' || 98 | process.env.NODE_ENV === 'wap-preprod' || 99 | process.env.NODE_ENV === 'wap-prod') { 100 | config.scope = 'wap'; 101 | config.port = 5000; 102 | config.session_secret = 'jaylinwang_wap_secret'; 103 | config.auth_cookie_name = 'jaylinwang_wap'; 104 | config.site_url = 'http://192.168.100.201:5000'; 105 | } 106 | 107 | // 预生产环境 108 | if (process.env.NODE_ENV === 'wap-preprod') { 109 | config.resource_url = 'http://s.jxcstatic.com/wapstatics'; 110 | config.site_url = 'http://w.jx-cloud.cc'; 111 | config.view_path = `${process.cwd()}/views/pro`; 112 | } 113 | 114 | // 生产环境 115 | if (process.env.NODE_ENV === 'wap-prod') { 116 | config.resource_url = ''; 117 | config.site_url = ''; 118 | config.view_path = `${process.cwd()}/views/pro`; 119 | config.redis = { 120 | // # 内网 121 | host: '', 122 | // # 外网 123 | // host: '120.24.44.32', 124 | port: 6379, 125 | pass: '', 126 | db: 7, 127 | prefix: 'jaylinwang_wap_session_', 128 | ttl: 60 * 60 * 2, 129 | }; 130 | } 131 | 132 | module.exports = config; 133 | -------------------------------------------------------------------------------- /public/src/js/core.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"sources":["webpack:///webpack/bootstrap bffe3e89f13bb53bed3a"],"names":[],"mappings":";AAAA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAQ,oBAAoB;AAC5B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA,uBAAe;AACf;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,YAAI;AACJ;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,wEAAgE,aAAa;AAC7E;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA","file":"core.js","sourcesContent":[" \t// install a JSONP callback for chunk loading\n \tvar parentJsonpFunction = window[\"webpackJsonp\"];\n \twindow[\"webpackJsonp\"] = function webpackJsonpCallback(chunkIds, moreModules) {\n \t\t// add \"moreModules\" to the modules object,\n \t\t// then flag all \"chunkIds\" as loaded and fire callback\n \t\tvar moduleId, chunkId, i = 0, callbacks = [];\n \t\tfor(;i < chunkIds.length; i++) {\n \t\t\tchunkId = chunkIds[i];\n \t\t\tif(installedChunks[chunkId])\n \t\t\t\tcallbacks.push.apply(callbacks, installedChunks[chunkId]);\n \t\t\tinstalledChunks[chunkId] = 0;\n \t\t}\n \t\tfor(moduleId in moreModules) {\n \t\t\tmodules[moduleId] = moreModules[moduleId];\n \t\t}\n \t\tif(parentJsonpFunction) parentJsonpFunction(chunkIds, moreModules);\n \t\twhile(callbacks.length)\n \t\t\tcallbacks.shift().call(null, __webpack_require__);\n \t\tif(moreModules[0]) {\n \t\t\tinstalledModules[0] = 0;\n \t\t\treturn __webpack_require__(0);\n \t\t}\n \t};\n\n \t// The module cache\n \tvar installedModules = {};\n\n \t// object to store loaded and loading chunks\n \t// \"0\" means \"already loaded\"\n \t// Array means \"loading\", array contains callbacks\n \tvar installedChunks = {\n \t\t1:0\n \t};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId])\n \t\t\treturn installedModules[moduleId].exports;\n\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\texports: {},\n \t\t\tid: moduleId,\n \t\t\tloaded: false\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.loaded = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n \t// This file contains only the entry chunk.\n \t// The chunk loading function for additional chunks\n \t__webpack_require__.e = function requireEnsure(chunkId, callback) {\n \t\t// \"0\" is the signal for \"already loaded\"\n \t\tif(installedChunks[chunkId] === 0)\n \t\t\treturn callback.call(null, __webpack_require__);\n\n \t\t// an array means \"currently loading\".\n \t\tif(installedChunks[chunkId] !== undefined) {\n \t\t\tinstalledChunks[chunkId].push(callback);\n \t\t} else {\n \t\t\t// start chunk loading\n \t\t\tinstalledChunks[chunkId] = [callback];\n \t\t\tvar head = document.getElementsByTagName('head')[0];\n \t\t\tvar script = document.createElement('script');\n \t\t\tscript.type = 'text/javascript';\n \t\t\tscript.charset = 'utf-8';\n \t\t\tscript.async = true;\n\n \t\t\tscript.src = __webpack_require__.p + \"\" + chunkId + \".\" + ({\"0\":\"common\"}[chunkId]||chunkId) + \".js\";\n \t\t\thead.appendChild(script);\n \t\t}\n \t};\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"src/js/\";\n\n\n\n/** WEBPACK FOOTER **\n ** webpack/bootstrap bffe3e89f13bb53bed3a\n **/"],"sourceRoot":""} -------------------------------------------------------------------------------- /public/src/js/core.js: -------------------------------------------------------------------------------- 1 | /******/ (function(modules) { // webpackBootstrap 2 | /******/ // install a JSONP callback for chunk loading 3 | /******/ var parentJsonpFunction = window["webpackJsonp"]; 4 | /******/ window["webpackJsonp"] = function webpackJsonpCallback(chunkIds, moreModules) { 5 | /******/ // add "moreModules" to the modules object, 6 | /******/ // then flag all "chunkIds" as loaded and fire callback 7 | /******/ var moduleId, chunkId, i = 0, callbacks = []; 8 | /******/ for(;i < chunkIds.length; i++) { 9 | /******/ chunkId = chunkIds[i]; 10 | /******/ if(installedChunks[chunkId]) 11 | /******/ callbacks.push.apply(callbacks, installedChunks[chunkId]); 12 | /******/ installedChunks[chunkId] = 0; 13 | /******/ } 14 | /******/ for(moduleId in moreModules) { 15 | /******/ modules[moduleId] = moreModules[moduleId]; 16 | /******/ } 17 | /******/ if(parentJsonpFunction) parentJsonpFunction(chunkIds, moreModules); 18 | /******/ while(callbacks.length) 19 | /******/ callbacks.shift().call(null, __webpack_require__); 20 | /******/ if(moreModules[0]) { 21 | /******/ installedModules[0] = 0; 22 | /******/ return __webpack_require__(0); 23 | /******/ } 24 | /******/ }; 25 | /******/ 26 | /******/ // The module cache 27 | /******/ var installedModules = {}; 28 | /******/ 29 | /******/ // object to store loaded and loading chunks 30 | /******/ // "0" means "already loaded" 31 | /******/ // Array means "loading", array contains callbacks 32 | /******/ var installedChunks = { 33 | /******/ 1:0 34 | /******/ }; 35 | /******/ 36 | /******/ // The require function 37 | /******/ function __webpack_require__(moduleId) { 38 | /******/ 39 | /******/ // Check if module is in cache 40 | /******/ if(installedModules[moduleId]) 41 | /******/ return installedModules[moduleId].exports; 42 | /******/ 43 | /******/ // Create a new module (and put it into the cache) 44 | /******/ var module = installedModules[moduleId] = { 45 | /******/ exports: {}, 46 | /******/ id: moduleId, 47 | /******/ loaded: false 48 | /******/ }; 49 | /******/ 50 | /******/ // Execute the module function 51 | /******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); 52 | /******/ 53 | /******/ // Flag the module as loaded 54 | /******/ module.loaded = true; 55 | /******/ 56 | /******/ // Return the exports of the module 57 | /******/ return module.exports; 58 | /******/ } 59 | /******/ 60 | /******/ // This file contains only the entry chunk. 61 | /******/ // The chunk loading function for additional chunks 62 | /******/ __webpack_require__.e = function requireEnsure(chunkId, callback) { 63 | /******/ // "0" is the signal for "already loaded" 64 | /******/ if(installedChunks[chunkId] === 0) 65 | /******/ return callback.call(null, __webpack_require__); 66 | /******/ 67 | /******/ // an array means "currently loading". 68 | /******/ if(installedChunks[chunkId] !== undefined) { 69 | /******/ installedChunks[chunkId].push(callback); 70 | /******/ } else { 71 | /******/ // start chunk loading 72 | /******/ installedChunks[chunkId] = [callback]; 73 | /******/ var head = document.getElementsByTagName('head')[0]; 74 | /******/ var script = document.createElement('script'); 75 | /******/ script.type = 'text/javascript'; 76 | /******/ script.charset = 'utf-8'; 77 | /******/ script.async = true; 78 | /******/ 79 | /******/ script.src = __webpack_require__.p + "" + chunkId + "." + ({"0":"common"}[chunkId]||chunkId) + ".js"; 80 | /******/ head.appendChild(script); 81 | /******/ } 82 | /******/ }; 83 | /******/ 84 | /******/ // expose the modules object (__webpack_modules__) 85 | /******/ __webpack_require__.m = modules; 86 | /******/ 87 | /******/ // expose the module cache 88 | /******/ __webpack_require__.c = installedModules; 89 | /******/ 90 | /******/ // __webpack_public_path__ 91 | /******/ __webpack_require__.p = "src/js/"; 92 | /******/ }) 93 | /************************************************************************/ 94 | /******/ ([]); 95 | //# sourceMappingURL=core.js.map -------------------------------------------------------------------------------- /public/src/fonts/iconfont.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Created by FontForge 20120731 at Wed Aug 24 13:48:06 2016 6 | By admin 7 | 8 | 9 | 10 | 24 | 26 | 28 | 30 | 32 | 36 | 40 | 45 | 49 | 50 | 51 | -------------------------------------------------------------------------------- /gulpfile.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const gulp = require('gulp'); 4 | const gutil = require('gulp-util'); 5 | const nodemon = require('gulp-nodemon'); 6 | const webpack = require('webpack'); 7 | const sass = require('gulp-sass'); 8 | const base64 = require('gulp-base64'); 9 | const rev = require('gulp-rev'); 10 | const revReplace = require('gulp-rev-replace'); 11 | const gulpSequence = require('gulp-sequence'); 12 | const plumber = require('gulp-plumber'); 13 | const del = require('del'); 14 | 15 | const webpackDevCfg = require('./configs/build/webpack.development'); 16 | const webpackProdCfg = require('./configs/build/webpack.production'); 17 | 18 | //= ===================================================== 19 | // # 公共操作 20 | // ## sass编译 21 | // ## 删除不想干文件 22 | //= ====================================================== 23 | 24 | // 压缩合并css, css中既有自己写的.scss, 也有引入第三方库的.css 25 | gulp.task('build:sass', () => { 26 | gulp.src(['public/src/styles/*.scss']) 27 | .pipe(plumber()) 28 | .pipe(sass({ 29 | outputStyle: 'compressed', 30 | })) 31 | .pipe(base64()) 32 | .pipe(gulp.dest('./public/src/css')); 33 | }); 34 | 35 | // 删除目录 36 | gulp.task('clean', () => { 37 | del(['public/publish/**/*']).then(paths => { 38 | gutil.log('Deleted files and folders:\n', paths.join('\n')); 39 | }); 40 | }); 41 | 42 | //= =========================================== 43 | // # 开发相关操作 44 | // ## 编译js 45 | // ## 监听文件变化 46 | // ## nodemon模式启动 47 | //= =========================================== 48 | 49 | // 开发环境中编译js 50 | gulp.task('build:js-dev', () => { 51 | webpack(webpackDevCfg, (err, stats) => { 52 | if (err) { 53 | throw new gutil.PluginError('webpack', err); 54 | } 55 | gutil.log('[webpack]', stats.toString({ 56 | colors: true, 57 | })); 58 | }); 59 | }); 60 | 61 | // 监听src下文件变化 62 | gulp.task('watch', () => { 63 | gulp.watch(['public/src/styles/**/*.scss'], ['build:sass']); 64 | gulp.watch('public/src/styles/**/*.js', ['build:js-dev']); 65 | }); 66 | 67 | // nodemon setting 68 | gulp.task('nodemon:wap-dev', () => { 69 | nodemon({ 70 | script: 'app.js', 71 | ext: 'js html', 72 | // ignore: ['public/**/*'], 73 | env: { 74 | NODE_ENV: 'wap-dev', 75 | }, 76 | }); 77 | }); 78 | gulp.task('nodemon:wechat-dev', () => { 79 | nodemon({ 80 | script: 'app.js', 81 | ext: 'js html', 82 | env: { 83 | NODE_ENV: 'wechat-dev', 84 | }, 85 | }); 86 | }); 87 | 88 | // 开发任务入口 89 | gulp.task('dev:wechat', gulpSequence( 90 | ['build:sass', 'build:js-dev'], 91 | 'watch', 92 | 'nodemon:wechat-dev' 93 | )); 94 | 95 | gulp.task('dev:wap', gulpSequence( 96 | ['build:sass', 'build:js-dev'], 97 | 'watch', 98 | 'nodemon:wap-dev' 99 | )); 100 | 101 | //= =========================================== 102 | // # 发布到线上环境操作 103 | // ## 编译js 104 | // ## 文件md5后缀及文件中文件引入替换 105 | // ## 监听文件变化 106 | // ## nodemon模式启动 107 | //= =========================================== 108 | 109 | // # 生产环境中编译js 110 | gulp.task('build:js-pro', (cb) => { 111 | webpack(webpackProdCfg, (err, stats) => { 112 | if (err) { 113 | throw new gutil.PluginError('webpack', err); 114 | } 115 | gutil.log('[webpack]', stats.toString({ 116 | colors: true, 117 | })); 118 | cb(); 119 | }); 120 | }); 121 | 122 | // publish setting 123 | gulp.task('revision', () => { 124 | gulp.src(['public/src/**/*']) 125 | .pipe(plumber()) 126 | .pipe(rev()) 127 | .pipe(gulp.dest('public/publish')) 128 | .pipe(rev.manifest()) 129 | .pipe(gulp.dest('public/publish')); 130 | }); 131 | gulp.task('revreplace', () => { 132 | const manifest = gulp.src('public/publish/rev-manifest.json'); 133 | return gulp.src('views/dev/**/*.html') 134 | .pipe(revReplace({ 135 | manifest, 136 | })) 137 | .pipe(gulp.dest('views/prod')); 138 | }); 139 | 140 | // nodemon setting 141 | gulp.task('nodemon:wap-preprod', () => { 142 | nodemon({ 143 | script: 'app.js', 144 | ext: 'js hbs', 145 | ignore: [ 146 | 'public/**/*', 'views/**/*', 147 | ], 148 | env: { 149 | NODE_ENV: 'wap-preprod', 150 | }, 151 | }); 152 | }); 153 | gulp.task('nodemon:wechat-preprod', () => { 154 | nodemon({ 155 | script: 'app.js', 156 | ext: 'js hbs', 157 | ignore: [ 158 | 'public/**/*', 'views/**/*', 159 | ], 160 | env: { 161 | NODE_ENV: 'wechat-preprod', 162 | }, 163 | }); 164 | }); 165 | 166 | // 发布任务入口 167 | gulp.task('publish:wechat', gulpSequence( 168 | 'clean', ['build:sass', 'build:js-pro'], 169 | 'revision', 170 | 'revreplace', 171 | 'nodemon:wechat-preprod' 172 | )); 173 | gulp.task('publish:wap', gulpSequence( 174 | 'clean', ['build:sass', 'build:js-pro'], 175 | 'revision', 176 | 'revreplace', 177 | 'nodemon:wap-preprod' 178 | )); 179 | -------------------------------------------------------------------------------- /public/src/js/common.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"sources":["webpack:///./scripts/common/index.js","webpack:////Users/jaylinwang/Workspace/Mine/sunny-wechat/~/zepto/dist/zepto.js"],"names":[],"mappings":";;;;;;;;;;;;;AAAA,KAAM,IAAI,oBAAQ,CAAR,CAAV,C;;;;;;ACAA;AACA;AACA;AACA,mDAAuB,yBAAyB;AAChD;AACA;AACA,EAAC;AACD;AACA;AACA;AACA,wBAAuB,iBAAiB;AACxC,kBAAiB,4GAA4G;AAC7H;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA,oBAAmB;AACnB;AACA,eAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA,wBAAuB;;AAEvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA,+BAA8B;AAC9B,+BAA8B;AAC9B,+BAA8B;AAC9B,+BAA8B;AAC9B;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA,4BAA2B,0CAA0C,sBAAsB;AAC3F,4BAA2B;AAC3B,4BAA2B,oDAAoD,sCAAsC;AACrH;AACA;AACA;AACA;AACA;AACA;AACA;AACA,0BAAyB,+CAA+C,oCAAoC;;AAE5G;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,gDAA+C,sCAAsC;AACrF;;AAEA;AACA;AACA,gBAAe,SAAS;AACxB;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,QAAO;AACP;;AAEA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gCAA+B,4BAA4B;AAC3D;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAiB;AACjB;AACA;AACA,MAAK;AACL;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA,gBAAe;AACf,aAAY;AACZ;;AAEA;AACA;AACA;AACA,kBAAiB,qBAAqB;AACtC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,kBAAiB,qBAAqB;AACtC;AACA,MAAK;AACL;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA,IAAG;;AAEH;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAiB,sBAAsB;AACvC;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA,4CAA2C,4BAA4B;AACvE,MAAK;AACL;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA,qEAAoE,cAAc;AAClF;AACA,MAAK;AACL;AACA;AACA,MAAK;AACL,yBAAwB,oBAAoB;AAC5C;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;AACA,QAAO;AACP,MAAK;AACL;AACA;AACA;AACA,QAAO;AACP;AACA,MAAK;AACL;AACA;AACA;AACA;AACA,QAAO;AACP,MAAK;AACL;AACA;AACA,MAAK;AACL;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;AACA;AACA,QAAO;AACP,MAAK;AACL;AACA;AACA,MAAK;AACL;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;AACX,UAAS;AACT;AACA,yCAAwC,mCAAmC;AAC3E;AACA,MAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA,MAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA,MAAK;AACL;AACA;AACA,MAAK;AACL;AACA,2CAA0C,wBAAwB;AAClE,MAAK;AACL;AACA,mCAAkC,6DAA6D;AAC/F,MAAK;AACL;AACA;AACA,qEAAoE,oBAAoB;AACxF,QAAO;AACP,MAAK;AACL;AACA,mCAAkC,sBAAsB;AACxD,MAAK;AACL;AACA;AACA,uCAAsC,sBAAsB;AAC5D,MAAK;AACL;AACA;AACA;AACA;AACA;AACA,QAAO;AACP,MAAK;AACL;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP,MAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP,MAAK;AACL;AACA;AACA;AACA,QAAO;AACP;AACA,MAAK;AACL;AACA,kCAAiC,8BAA8B;AAC/D,MAAK;AACL;AACA;AACA,MAAK;AACL;AACA;AACA;AACA,UAAS;AACT,QAAO;AACP,MAAK;AACL,8BAA6B,yEAAyE;AACtG,8BAA6B,qEAAqE;AAClG;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA,MAAK;AACL;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA,MAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT,MAAK;AACL;AACA,mCAAkC;AAClC;AACA,QAAO,QAAQ;AACf,MAAK;AACL;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA,MAAK;AACL;AACA;AACA,mCAAkC,oBAAoB;AACtD,MAAK;AACL;AACA;;AAEA;AACA;AACA;;AAEA;AACA,MAAK;AACL;AACA;AACA;AACA;AACA;AACA,UAAS;AACT,QAAO;AACP;AACA,wDAAuD,uBAAuB;AAC9E;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,QAAO;AACP;AACA;AACA,iBAAgB;AAChB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA,YAAW;AACX;AACA;AACA;;AAEA;AACA;AACA;AACA,gCAA+B,iDAAiD;AAChF;AACA;AACA,QAAO;AACP;AACA;AACA,kCAAiC,4CAA4C;AAC7E;AACA,8EAA6E;AAC7E;;AAEA,mCAAkC,yBAAyB,SAAS;AACpE,MAAK;AACL;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;AACA,QAAO;AACP,MAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA,QAAO;AACP,MAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA,QAAO;AACP,MAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT,QAAO;AACP,MAAK;AACL;AACA;AACA;AACA;AACA;AACA,oBAAmB,yBAAyB;AAC5C,oBAAmB,qCAAqC;AACxD,MAAK;AACL;AACA;AACA;AACA;AACA;AACA,oBAAmB,0BAA0B;AAC7C,oBAAmB,qCAAqC;AACxD,MAAK;AACL;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,qEAAoE,kBAAkB;;AAEtF;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;;AAEA;AACA;;AAEA;AACA,IAAG;AACH;AACA,0CAAyC,4BAA4B;;AAErE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA,IAAG;;AAEH;AACA;AACA,kDAAiD,SAAS;AAC1D;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAe;AACf;AACA;AACA;AACA;AACA,YAAW;AACX;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;AACX,UAAS;AACT,QAAO;AACP;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;;AAEA;AACA,EAAC;;AAED;AACA;;AAEA,EAAC;AACD;AACA;AACA;AACA,gCAA+B,gCAAgC;AAC/D,oBAAmB;AACnB,uBAAsB;AACtB;AACA,gBAAe,qCAAqC;AACpD,gBAAe;;AAEf;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA,aAAY;AACZ;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;AACA,QAAO;AACP,MAAK;AACL;;AAEA,cAAa;;AAEb;AACA;AACA;AACA,gCAA+B;AAC/B;AACA;AACA,MAAK;AACL;AACA;AACA;AACA,QAAO;AACP;AACA;AACA,MAAK;AACL;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,+BAA8B,YAAY;AAC1C,gCAA+B,aAAa;AAC5C;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;;AAEP;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,uBAAsB;AACtB;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,2CAA0C,yCAAyC;AACnF;AACA;AACA;;AAEA;AACA,MAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA,MAAK;AACL;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP,MAAK;AACL;AACA;;AAEA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAG;;AAEH;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,EAAC;;AAED,EAAC;AACD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP,cAAa,eAAe;;AAE5B;;AAEA;AACA;AACA;;AAEA;AACA;AACA,QAAO;AACP;AACA;;AAEA;AACA;AACA;;AAEA;AACA,MAAK;;AAEL;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA,MAAK;;AAEL;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,mCAAkC;AAClC;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,8CAA6C,IAAI;AACjD;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,+BAA8B,eAAe;AAC7C;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,oBAAmB,EAAE;AACrB,4CAA2C,8CAA8C;AACzF;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAa,YAAY;;AAEzB;AACA;;AAEA;AACA,UAAS;AACT;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA,QAAO;;AAEP;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,EAAC;;AAED,EAAC;AACD;AACA;AACA;AACA;AACA,sBAAqB,2BAA2B;AAChD;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;;AAEA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,EAAC;;AAED,EAAC;AACD;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;AACA;AACA;AACA,EAAC;AACD;AACA,EAAC","file":"common.js","sourcesContent":["const $ = require('zepto');\n\n\n\n/** WEBPACK FOOTER **\n ** ./scripts/common/index.js\n **/","/* Zepto v1.2.0 - zepto event ajax form ie - zeptojs.com/license */\n(function(global, factory) {\n if (typeof define === 'function' && define.amd)\n define(function() { return factory(global) })\n else\n factory(global)\n}(this, function(window) {\n var Zepto = (function() {\n var undefined, key, $, classList, emptyArray = [], concat = emptyArray.concat, filter = emptyArray.filter, slice = emptyArray.slice,\n document = window.document,\n elementDisplay = {}, classCache = {},\n cssNumber = { 'column-count': 1, 'columns': 1, 'font-weight': 1, 'line-height': 1,'opacity': 1, 'z-index': 1, 'zoom': 1 },\n fragmentRE = /^\\s*<(\\w+|!)[^>]*>/,\n singleTagRE = /^<(\\w+)\\s*\\/?>(?:<\\/\\1>|)$/,\n tagExpanderRE = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\\w:]+)[^>]*)\\/>/ig,\n rootNodeRE = /^(?:body|html)$/i,\n capitalRE = /([A-Z])/g,\n\n // special attributes that should be get/set via method calls\n methodAttributes = ['val', 'css', 'html', 'text', 'data', 'width', 'height', 'offset'],\n\n adjacencyOperators = [ 'after', 'prepend', 'before', 'append' ],\n table = document.createElement('table'),\n tableRow = document.createElement('tr'),\n containers = {\n 'tr': document.createElement('tbody'),\n 'tbody': table, 'thead': table, 'tfoot': table,\n 'td': tableRow, 'th': tableRow,\n '*': document.createElement('div')\n },\n readyRE = /complete|loaded|interactive/,\n simpleSelectorRE = /^[\\w-]*$/,\n class2type = {},\n toString = class2type.toString,\n zepto = {},\n camelize, uniq,\n tempParent = document.createElement('div'),\n propMap = {\n 'tabindex': 'tabIndex',\n 'readonly': 'readOnly',\n 'for': 'htmlFor',\n 'class': 'className',\n 'maxlength': 'maxLength',\n 'cellspacing': 'cellSpacing',\n 'cellpadding': 'cellPadding',\n 'rowspan': 'rowSpan',\n 'colspan': 'colSpan',\n 'usemap': 'useMap',\n 'frameborder': 'frameBorder',\n 'contenteditable': 'contentEditable'\n },\n isArray = Array.isArray ||\n function(object){ return object instanceof Array }\n\n zepto.matches = function(element, selector) {\n if (!selector || !element || element.nodeType !== 1) return false\n var matchesSelector = element.matches || element.webkitMatchesSelector ||\n element.mozMatchesSelector || element.oMatchesSelector ||\n element.matchesSelector\n if (matchesSelector) return matchesSelector.call(element, selector)\n // fall back to performing a selector:\n var match, parent = element.parentNode, temp = !parent\n if (temp) (parent = tempParent).appendChild(element)\n match = ~zepto.qsa(parent, selector).indexOf(element)\n temp && tempParent.removeChild(element)\n return match\n }\n\n function type(obj) {\n return obj == null ? String(obj) :\n class2type[toString.call(obj)] || \"object\"\n }\n\n function isFunction(value) { return type(value) == \"function\" }\n function isWindow(obj) { return obj != null && obj == obj.window }\n function isDocument(obj) { return obj != null && obj.nodeType == obj.DOCUMENT_NODE }\n function isObject(obj) { return type(obj) == \"object\" }\n function isPlainObject(obj) {\n return isObject(obj) && !isWindow(obj) && Object.getPrototypeOf(obj) == Object.prototype\n }\n\n function likeArray(obj) {\n var length = !!obj && 'length' in obj && obj.length,\n type = $.type(obj)\n\n return 'function' != type && !isWindow(obj) && (\n 'array' == type || length === 0 ||\n (typeof length == 'number' && length > 0 && (length - 1) in obj)\n )\n }\n\n function compact(array) { return filter.call(array, function(item){ return item != null }) }\n function flatten(array) { return array.length > 0 ? $.fn.concat.apply([], array) : array }\n camelize = function(str){ return str.replace(/-+(.)?/g, function(match, chr){ return chr ? chr.toUpperCase() : '' }) }\n function dasherize(str) {\n return str.replace(/::/g, '/')\n .replace(/([A-Z]+)([A-Z][a-z])/g, '$1_$2')\n .replace(/([a-z\\d])([A-Z])/g, '$1_$2')\n .replace(/_/g, '-')\n .toLowerCase()\n }\n uniq = function(array){ return filter.call(array, function(item, idx){ return array.indexOf(item) == idx }) }\n\n function classRE(name) {\n return name in classCache ?\n classCache[name] : (classCache[name] = new RegExp('(^|\\\\s)' + name + '(\\\\s|$)'))\n }\n\n function maybeAddPx(name, value) {\n return (typeof value == \"number\" && !cssNumber[dasherize(name)]) ? value + \"px\" : value\n }\n\n function defaultDisplay(nodeName) {\n var element, display\n if (!elementDisplay[nodeName]) {\n element = document.createElement(nodeName)\n document.body.appendChild(element)\n display = getComputedStyle(element, '').getPropertyValue(\"display\")\n element.parentNode.removeChild(element)\n display == \"none\" && (display = \"block\")\n elementDisplay[nodeName] = display\n }\n return elementDisplay[nodeName]\n }\n\n function children(element) {\n return 'children' in element ?\n slice.call(element.children) :\n $.map(element.childNodes, function(node){ if (node.nodeType == 1) return node })\n }\n\n function Z(dom, selector) {\n var i, len = dom ? dom.length : 0\n for (i = 0; i < len; i++) this[i] = dom[i]\n this.length = len\n this.selector = selector || ''\n }\n\n // `$.zepto.fragment` takes a html string and an optional tag name\n // to generate DOM nodes from the given html string.\n // The generated DOM nodes are returned as an array.\n // This function can be overridden in plugins for example to make\n // it compatible with browsers that don't support the DOM fully.\n zepto.fragment = function(html, name, properties) {\n var dom, nodes, container\n\n // A special case optimization for a single tag\n if (singleTagRE.test(html)) dom = $(document.createElement(RegExp.$1))\n\n if (!dom) {\n if (html.replace) html = html.replace(tagExpanderRE, \"<$1>\")\n if (name === undefined) name = fragmentRE.test(html) && RegExp.$1\n if (!(name in containers)) name = '*'\n\n container = containers[name]\n container.innerHTML = '' + html\n dom = $.each(slice.call(container.childNodes), function(){\n container.removeChild(this)\n })\n }\n\n if (isPlainObject(properties)) {\n nodes = $(dom)\n $.each(properties, function(key, value) {\n if (methodAttributes.indexOf(key) > -1) nodes[key](value)\n else nodes.attr(key, value)\n })\n }\n\n return dom\n }\n\n // `$.zepto.Z` swaps out the prototype of the given `dom` array\n // of nodes with `$.fn` and thus supplying all the Zepto functions\n // to the array. This method can be overridden in plugins.\n zepto.Z = function(dom, selector) {\n return new Z(dom, selector)\n }\n\n // `$.zepto.isZ` should return `true` if the given object is a Zepto\n // collection. This method can be overridden in plugins.\n zepto.isZ = function(object) {\n return object instanceof zepto.Z\n }\n\n // `$.zepto.init` is Zepto's counterpart to jQuery's `$.fn.init` and\n // takes a CSS selector and an optional context (and handles various\n // special cases).\n // This method can be overridden in plugins.\n zepto.init = function(selector, context) {\n var dom\n // If nothing given, return an empty Zepto collection\n if (!selector) return zepto.Z()\n // Optimize for string selectors\n else if (typeof selector == 'string') {\n selector = selector.trim()\n // If it's a html fragment, create nodes from it\n // Note: In both Chrome 21 and Firefox 15, DOM error 12\n // is thrown if the fragment doesn't begin with <\n if (selector[0] == '<' && fragmentRE.test(selector))\n dom = zepto.fragment(selector, RegExp.$1, context), selector = null\n // If there's a context, create a collection on that context first, and select\n // nodes from there\n else if (context !== undefined) return $(context).find(selector)\n // If it's a CSS selector, use it to select nodes.\n else dom = zepto.qsa(document, selector)\n }\n // If a function is given, call it when the DOM is ready\n else if (isFunction(selector)) return $(document).ready(selector)\n // If a Zepto collection is given, just return it\n else if (zepto.isZ(selector)) return selector\n else {\n // normalize array if an array of nodes is given\n if (isArray(selector)) dom = compact(selector)\n // Wrap DOM nodes.\n else if (isObject(selector))\n dom = [selector], selector = null\n // If it's a html fragment, create nodes from it\n else if (fragmentRE.test(selector))\n dom = zepto.fragment(selector.trim(), RegExp.$1, context), selector = null\n // If there's a context, create a collection on that context first, and select\n // nodes from there\n else if (context !== undefined) return $(context).find(selector)\n // And last but no least, if it's a CSS selector, use it to select nodes.\n else dom = zepto.qsa(document, selector)\n }\n // create a new Zepto collection from the nodes found\n return zepto.Z(dom, selector)\n }\n\n // `$` will be the base `Zepto` object. When calling this\n // function just call `$.zepto.init, which makes the implementation\n // details of selecting nodes and creating Zepto collections\n // patchable in plugins.\n $ = function(selector, context){\n return zepto.init(selector, context)\n }\n\n function extend(target, source, deep) {\n for (key in source)\n if (deep && (isPlainObject(source[key]) || isArray(source[key]))) {\n if (isPlainObject(source[key]) && !isPlainObject(target[key]))\n target[key] = {}\n if (isArray(source[key]) && !isArray(target[key]))\n target[key] = []\n extend(target[key], source[key], deep)\n }\n else if (source[key] !== undefined) target[key] = source[key]\n }\n\n // Copy all but undefined properties from one or more\n // objects to the `target` object.\n $.extend = function(target){\n var deep, args = slice.call(arguments, 1)\n if (typeof target == 'boolean') {\n deep = target\n target = args.shift()\n }\n args.forEach(function(arg){ extend(target, arg, deep) })\n return target\n }\n\n // `$.zepto.qsa` is Zepto's CSS selector implementation which\n // uses `document.querySelectorAll` and optimizes for some special cases, like `#id`.\n // This method can be overridden in plugins.\n zepto.qsa = function(element, selector){\n var found,\n maybeID = selector[0] == '#',\n maybeClass = !maybeID && selector[0] == '.',\n nameOnly = maybeID || maybeClass ? selector.slice(1) : selector, // Ensure that a 1 char tag name still gets checked\n isSimple = simpleSelectorRE.test(nameOnly)\n return (element.getElementById && isSimple && maybeID) ? // Safari DocumentFragment doesn't have getElementById\n ( (found = element.getElementById(nameOnly)) ? [found] : [] ) :\n (element.nodeType !== 1 && element.nodeType !== 9 && element.nodeType !== 11) ? [] :\n slice.call(\n isSimple && !maybeID && element.getElementsByClassName ? // DocumentFragment doesn't have getElementsByClassName/TagName\n maybeClass ? element.getElementsByClassName(nameOnly) : // If it's simple, it could be a class\n element.getElementsByTagName(selector) : // Or a tag\n element.querySelectorAll(selector) // Or it's not simple, and we need to query all\n )\n }\n\n function filtered(nodes, selector) {\n return selector == null ? $(nodes) : $(nodes).filter(selector)\n }\n\n $.contains = document.documentElement.contains ?\n function(parent, node) {\n return parent !== node && parent.contains(node)\n } :\n function(parent, node) {\n while (node && (node = node.parentNode))\n if (node === parent) return true\n return false\n }\n\n function funcArg(context, arg, idx, payload) {\n return isFunction(arg) ? arg.call(context, idx, payload) : arg\n }\n\n function setAttribute(node, name, value) {\n value == null ? node.removeAttribute(name) : node.setAttribute(name, value)\n }\n\n // access className property while respecting SVGAnimatedString\n function className(node, value){\n var klass = node.className || '',\n svg = klass && klass.baseVal !== undefined\n\n if (value === undefined) return svg ? klass.baseVal : klass\n svg ? (klass.baseVal = value) : (node.className = value)\n }\n\n // \"true\" => true\n // \"false\" => false\n // \"null\" => null\n // \"42\" => 42\n // \"42.5\" => 42.5\n // \"08\" => \"08\"\n // JSON => parse if valid\n // String => self\n function deserializeValue(value) {\n try {\n return value ?\n value == \"true\" ||\n ( value == \"false\" ? false :\n value == \"null\" ? null :\n +value + \"\" == value ? +value :\n /^[\\[\\{]/.test(value) ? $.parseJSON(value) :\n value )\n : value\n } catch(e) {\n return value\n }\n }\n\n $.type = type\n $.isFunction = isFunction\n $.isWindow = isWindow\n $.isArray = isArray\n $.isPlainObject = isPlainObject\n\n $.isEmptyObject = function(obj) {\n var name\n for (name in obj) return false\n return true\n }\n\n $.isNumeric = function(val) {\n var num = Number(val), type = typeof val\n return val != null && type != 'boolean' &&\n (type != 'string' || val.length) &&\n !isNaN(num) && isFinite(num) || false\n }\n\n $.inArray = function(elem, array, i){\n return emptyArray.indexOf.call(array, elem, i)\n }\n\n $.camelCase = camelize\n $.trim = function(str) {\n return str == null ? \"\" : String.prototype.trim.call(str)\n }\n\n // plugin compatibility\n $.uuid = 0\n $.support = { }\n $.expr = { }\n $.noop = function() {}\n\n $.map = function(elements, callback){\n var value, values = [], i, key\n if (likeArray(elements))\n for (i = 0; i < elements.length; i++) {\n value = callback(elements[i], i)\n if (value != null) values.push(value)\n }\n else\n for (key in elements) {\n value = callback(elements[key], key)\n if (value != null) values.push(value)\n }\n return flatten(values)\n }\n\n $.each = function(elements, callback){\n var i, key\n if (likeArray(elements)) {\n for (i = 0; i < elements.length; i++)\n if (callback.call(elements[i], i, elements[i]) === false) return elements\n } else {\n for (key in elements)\n if (callback.call(elements[key], key, elements[key]) === false) return elements\n }\n\n return elements\n }\n\n $.grep = function(elements, callback){\n return filter.call(elements, callback)\n }\n\n if (window.JSON) $.parseJSON = JSON.parse\n\n // Populate the class2type map\n $.each(\"Boolean Number String Function Array Date RegExp Object Error\".split(\" \"), function(i, name) {\n class2type[ \"[object \" + name + \"]\" ] = name.toLowerCase()\n })\n\n // Define methods that will be available on all\n // Zepto collections\n $.fn = {\n constructor: zepto.Z,\n length: 0,\n\n // Because a collection acts like an array\n // copy over these useful array functions.\n forEach: emptyArray.forEach,\n reduce: emptyArray.reduce,\n push: emptyArray.push,\n sort: emptyArray.sort,\n splice: emptyArray.splice,\n indexOf: emptyArray.indexOf,\n concat: function(){\n var i, value, args = []\n for (i = 0; i < arguments.length; i++) {\n value = arguments[i]\n args[i] = zepto.isZ(value) ? value.toArray() : value\n }\n return concat.apply(zepto.isZ(this) ? this.toArray() : this, args)\n },\n\n // `map` and `slice` in the jQuery API work differently\n // from their array counterparts\n map: function(fn){\n return $($.map(this, function(el, i){ return fn.call(el, i, el) }))\n },\n slice: function(){\n return $(slice.apply(this, arguments))\n },\n\n ready: function(callback){\n // need to check if document.body exists for IE as that browser reports\n // document ready when it hasn't yet created the body element\n if (readyRE.test(document.readyState) && document.body) callback($)\n else document.addEventListener('DOMContentLoaded', function(){ callback($) }, false)\n return this\n },\n get: function(idx){\n return idx === undefined ? slice.call(this) : this[idx >= 0 ? idx : idx + this.length]\n },\n toArray: function(){ return this.get() },\n size: function(){\n return this.length\n },\n remove: function(){\n return this.each(function(){\n if (this.parentNode != null)\n this.parentNode.removeChild(this)\n })\n },\n each: function(callback){\n emptyArray.every.call(this, function(el, idx){\n return callback.call(el, idx, el) !== false\n })\n return this\n },\n filter: function(selector){\n if (isFunction(selector)) return this.not(this.not(selector))\n return $(filter.call(this, function(element){\n return zepto.matches(element, selector)\n }))\n },\n add: function(selector,context){\n return $(uniq(this.concat($(selector,context))))\n },\n is: function(selector){\n return this.length > 0 && zepto.matches(this[0], selector)\n },\n not: function(selector){\n var nodes=[]\n if (isFunction(selector) && selector.call !== undefined)\n this.each(function(idx){\n if (!selector.call(this,idx)) nodes.push(this)\n })\n else {\n var excludes = typeof selector == 'string' ? this.filter(selector) :\n (likeArray(selector) && isFunction(selector.item)) ? slice.call(selector) : $(selector)\n this.forEach(function(el){\n if (excludes.indexOf(el) < 0) nodes.push(el)\n })\n }\n return $(nodes)\n },\n has: function(selector){\n return this.filter(function(){\n return isObject(selector) ?\n $.contains(this, selector) :\n $(this).find(selector).size()\n })\n },\n eq: function(idx){\n return idx === -1 ? this.slice(idx) : this.slice(idx, + idx + 1)\n },\n first: function(){\n var el = this[0]\n return el && !isObject(el) ? el : $(el)\n },\n last: function(){\n var el = this[this.length - 1]\n return el && !isObject(el) ? el : $(el)\n },\n find: function(selector){\n var result, $this = this\n if (!selector) result = $()\n else if (typeof selector == 'object')\n result = $(selector).filter(function(){\n var node = this\n return emptyArray.some.call($this, function(parent){\n return $.contains(parent, node)\n })\n })\n else if (this.length == 1) result = $(zepto.qsa(this[0], selector))\n else result = this.map(function(){ return zepto.qsa(this, selector) })\n return result\n },\n closest: function(selector, context){\n var nodes = [], collection = typeof selector == 'object' && $(selector)\n this.each(function(_, node){\n while (node && !(collection ? collection.indexOf(node) >= 0 : zepto.matches(node, selector)))\n node = node !== context && !isDocument(node) && node.parentNode\n if (node && nodes.indexOf(node) < 0) nodes.push(node)\n })\n return $(nodes)\n },\n parents: function(selector){\n var ancestors = [], nodes = this\n while (nodes.length > 0)\n nodes = $.map(nodes, function(node){\n if ((node = node.parentNode) && !isDocument(node) && ancestors.indexOf(node) < 0) {\n ancestors.push(node)\n return node\n }\n })\n return filtered(ancestors, selector)\n },\n parent: function(selector){\n return filtered(uniq(this.pluck('parentNode')), selector)\n },\n children: function(selector){\n return filtered(this.map(function(){ return children(this) }), selector)\n },\n contents: function() {\n return this.map(function() { return this.contentDocument || slice.call(this.childNodes) })\n },\n siblings: function(selector){\n return filtered(this.map(function(i, el){\n return filter.call(children(el.parentNode), function(child){ return child!==el })\n }), selector)\n },\n empty: function(){\n return this.each(function(){ this.innerHTML = '' })\n },\n // `pluck` is borrowed from Prototype.js\n pluck: function(property){\n return $.map(this, function(el){ return el[property] })\n },\n show: function(){\n return this.each(function(){\n this.style.display == \"none\" && (this.style.display = '')\n if (getComputedStyle(this, '').getPropertyValue(\"display\") == \"none\")\n this.style.display = defaultDisplay(this.nodeName)\n })\n },\n replaceWith: function(newContent){\n return this.before(newContent).remove()\n },\n wrap: function(structure){\n var func = isFunction(structure)\n if (this[0] && !func)\n var dom = $(structure).get(0),\n clone = dom.parentNode || this.length > 1\n\n return this.each(function(index){\n $(this).wrapAll(\n func ? structure.call(this, index) :\n clone ? dom.cloneNode(true) : dom\n )\n })\n },\n wrapAll: function(structure){\n if (this[0]) {\n $(this[0]).before(structure = $(structure))\n var children\n // drill down to the inmost element\n while ((children = structure.children()).length) structure = children.first()\n $(structure).append(this)\n }\n return this\n },\n wrapInner: function(structure){\n var func = isFunction(structure)\n return this.each(function(index){\n var self = $(this), contents = self.contents(),\n dom = func ? structure.call(this, index) : structure\n contents.length ? contents.wrapAll(dom) : self.append(dom)\n })\n },\n unwrap: function(){\n this.parent().each(function(){\n $(this).replaceWith($(this).children())\n })\n return this\n },\n clone: function(){\n return this.map(function(){ return this.cloneNode(true) })\n },\n hide: function(){\n return this.css(\"display\", \"none\")\n },\n toggle: function(setting){\n return this.each(function(){\n var el = $(this)\n ;(setting === undefined ? el.css(\"display\") == \"none\" : setting) ? el.show() : el.hide()\n })\n },\n prev: function(selector){ return $(this.pluck('previousElementSibling')).filter(selector || '*') },\n next: function(selector){ return $(this.pluck('nextElementSibling')).filter(selector || '*') },\n html: function(html){\n return 0 in arguments ?\n this.each(function(idx){\n var originHtml = this.innerHTML\n $(this).empty().append( funcArg(this, html, idx, originHtml) )\n }) :\n (0 in this ? this[0].innerHTML : null)\n },\n text: function(text){\n return 0 in arguments ?\n this.each(function(idx){\n var newText = funcArg(this, text, idx, this.textContent)\n this.textContent = newText == null ? '' : ''+newText\n }) :\n (0 in this ? this.pluck('textContent').join(\"\") : null)\n },\n attr: function(name, value){\n var result\n return (typeof name == 'string' && !(1 in arguments)) ?\n (0 in this && this[0].nodeType == 1 && (result = this[0].getAttribute(name)) != null ? result : undefined) :\n this.each(function(idx){\n if (this.nodeType !== 1) return\n if (isObject(name)) for (key in name) setAttribute(this, key, name[key])\n else setAttribute(this, name, funcArg(this, value, idx, this.getAttribute(name)))\n })\n },\n removeAttr: function(name){\n return this.each(function(){ this.nodeType === 1 && name.split(' ').forEach(function(attribute){\n setAttribute(this, attribute)\n }, this)})\n },\n prop: function(name, value){\n name = propMap[name] || name\n return (1 in arguments) ?\n this.each(function(idx){\n this[name] = funcArg(this, value, idx, this[name])\n }) :\n (this[0] && this[0][name])\n },\n removeProp: function(name){\n name = propMap[name] || name\n return this.each(function(){ delete this[name] })\n },\n data: function(name, value){\n var attrName = 'data-' + name.replace(capitalRE, '-$1').toLowerCase()\n\n var data = (1 in arguments) ?\n this.attr(attrName, value) :\n this.attr(attrName)\n\n return data !== null ? deserializeValue(data) : undefined\n },\n val: function(value){\n if (0 in arguments) {\n if (value == null) value = \"\"\n return this.each(function(idx){\n this.value = funcArg(this, value, idx, this.value)\n })\n } else {\n return this[0] && (this[0].multiple ?\n $(this[0]).find('option').filter(function(){ return this.selected }).pluck('value') :\n this[0].value)\n }\n },\n offset: function(coordinates){\n if (coordinates) return this.each(function(index){\n var $this = $(this),\n coords = funcArg(this, coordinates, index, $this.offset()),\n parentOffset = $this.offsetParent().offset(),\n props = {\n top: coords.top - parentOffset.top,\n left: coords.left - parentOffset.left\n }\n\n if ($this.css('position') == 'static') props['position'] = 'relative'\n $this.css(props)\n })\n if (!this.length) return null\n if (document.documentElement !== this[0] && !$.contains(document.documentElement, this[0]))\n return {top: 0, left: 0}\n var obj = this[0].getBoundingClientRect()\n return {\n left: obj.left + window.pageXOffset,\n top: obj.top + window.pageYOffset,\n width: Math.round(obj.width),\n height: Math.round(obj.height)\n }\n },\n css: function(property, value){\n if (arguments.length < 2) {\n var element = this[0]\n if (typeof property == 'string') {\n if (!element) return\n return element.style[camelize(property)] || getComputedStyle(element, '').getPropertyValue(property)\n } else if (isArray(property)) {\n if (!element) return\n var props = {}\n var computedStyle = getComputedStyle(element, '')\n $.each(property, function(_, prop){\n props[prop] = (element.style[camelize(prop)] || computedStyle.getPropertyValue(prop))\n })\n return props\n }\n }\n\n var css = ''\n if (type(property) == 'string') {\n if (!value && value !== 0)\n this.each(function(){ this.style.removeProperty(dasherize(property)) })\n else\n css = dasherize(property) + \":\" + maybeAddPx(property, value)\n } else {\n for (key in property)\n if (!property[key] && property[key] !== 0)\n this.each(function(){ this.style.removeProperty(dasherize(key)) })\n else\n css += dasherize(key) + ':' + maybeAddPx(key, property[key]) + ';'\n }\n\n return this.each(function(){ this.style.cssText += ';' + css })\n },\n index: function(element){\n return element ? this.indexOf($(element)[0]) : this.parent().children().indexOf(this[0])\n },\n hasClass: function(name){\n if (!name) return false\n return emptyArray.some.call(this, function(el){\n return this.test(className(el))\n }, classRE(name))\n },\n addClass: function(name){\n if (!name) return this\n return this.each(function(idx){\n if (!('className' in this)) return\n classList = []\n var cls = className(this), newName = funcArg(this, name, idx, cls)\n newName.split(/\\s+/g).forEach(function(klass){\n if (!$(this).hasClass(klass)) classList.push(klass)\n }, this)\n classList.length && className(this, cls + (cls ? \" \" : \"\") + classList.join(\" \"))\n })\n },\n removeClass: function(name){\n return this.each(function(idx){\n if (!('className' in this)) return\n if (name === undefined) return className(this, '')\n classList = className(this)\n funcArg(this, name, idx, classList).split(/\\s+/g).forEach(function(klass){\n classList = classList.replace(classRE(klass), \" \")\n })\n className(this, classList.trim())\n })\n },\n toggleClass: function(name, when){\n if (!name) return this\n return this.each(function(idx){\n var $this = $(this), names = funcArg(this, name, idx, className(this))\n names.split(/\\s+/g).forEach(function(klass){\n (when === undefined ? !$this.hasClass(klass) : when) ?\n $this.addClass(klass) : $this.removeClass(klass)\n })\n })\n },\n scrollTop: function(value){\n if (!this.length) return\n var hasScrollTop = 'scrollTop' in this[0]\n if (value === undefined) return hasScrollTop ? this[0].scrollTop : this[0].pageYOffset\n return this.each(hasScrollTop ?\n function(){ this.scrollTop = value } :\n function(){ this.scrollTo(this.scrollX, value) })\n },\n scrollLeft: function(value){\n if (!this.length) return\n var hasScrollLeft = 'scrollLeft' in this[0]\n if (value === undefined) return hasScrollLeft ? this[0].scrollLeft : this[0].pageXOffset\n return this.each(hasScrollLeft ?\n function(){ this.scrollLeft = value } :\n function(){ this.scrollTo(value, this.scrollY) })\n },\n position: function() {\n if (!this.length) return\n\n var elem = this[0],\n // Get *real* offsetParent\n offsetParent = this.offsetParent(),\n // Get correct offsets\n offset = this.offset(),\n parentOffset = rootNodeRE.test(offsetParent[0].nodeName) ? { top: 0, left: 0 } : offsetParent.offset()\n\n // Subtract element margins\n // note: when an element has margin: auto the offsetLeft and marginLeft\n // are the same in Safari causing offset.left to incorrectly be 0\n offset.top -= parseFloat( $(elem).css('margin-top') ) || 0\n offset.left -= parseFloat( $(elem).css('margin-left') ) || 0\n\n // Add offsetParent borders\n parentOffset.top += parseFloat( $(offsetParent[0]).css('border-top-width') ) || 0\n parentOffset.left += parseFloat( $(offsetParent[0]).css('border-left-width') ) || 0\n\n // Subtract the two offsets\n return {\n top: offset.top - parentOffset.top,\n left: offset.left - parentOffset.left\n }\n },\n offsetParent: function() {\n return this.map(function(){\n var parent = this.offsetParent || document.body\n while (parent && !rootNodeRE.test(parent.nodeName) && $(parent).css(\"position\") == \"static\")\n parent = parent.offsetParent\n return parent\n })\n }\n }\n\n // for now\n $.fn.detach = $.fn.remove\n\n // Generate the `width` and `height` functions\n ;['width', 'height'].forEach(function(dimension){\n var dimensionProperty =\n dimension.replace(/./, function(m){ return m[0].toUpperCase() })\n\n $.fn[dimension] = function(value){\n var offset, el = this[0]\n if (value === undefined) return isWindow(el) ? el['inner' + dimensionProperty] :\n isDocument(el) ? el.documentElement['scroll' + dimensionProperty] :\n (offset = this.offset()) && offset[dimension]\n else return this.each(function(idx){\n el = $(this)\n el.css(dimension, funcArg(this, value, idx, el[dimension]()))\n })\n }\n })\n\n function traverseNode(node, fun) {\n fun(node)\n for (var i = 0, len = node.childNodes.length; i < len; i++)\n traverseNode(node.childNodes[i], fun)\n }\n\n // Generate the `after`, `prepend`, `before`, `append`,\n // `insertAfter`, `insertBefore`, `appendTo`, and `prependTo` methods.\n adjacencyOperators.forEach(function(operator, operatorIndex) {\n var inside = operatorIndex % 2 //=> prepend, append\n\n $.fn[operator] = function(){\n // arguments can be nodes, arrays of nodes, Zepto objects and HTML strings\n var argType, nodes = $.map(arguments, function(arg) {\n var arr = []\n argType = type(arg)\n if (argType == \"array\") {\n arg.forEach(function(el) {\n if (el.nodeType !== undefined) return arr.push(el)\n else if ($.zepto.isZ(el)) return arr = arr.concat(el.get())\n arr = arr.concat(zepto.fragment(el))\n })\n return arr\n }\n return argType == \"object\" || arg == null ?\n arg : zepto.fragment(arg)\n }),\n parent, copyByClone = this.length > 1\n if (nodes.length < 1) return this\n\n return this.each(function(_, target){\n parent = inside ? target : target.parentNode\n\n // convert all methods to a \"before\" operation\n target = operatorIndex == 0 ? target.nextSibling :\n operatorIndex == 1 ? target.firstChild :\n operatorIndex == 2 ? target :\n null\n\n var parentInDocument = $.contains(document.documentElement, parent)\n\n nodes.forEach(function(node){\n if (copyByClone) node = node.cloneNode(true)\n else if (!parent) return $(node).remove()\n\n parent.insertBefore(node, target)\n if (parentInDocument) traverseNode(node, function(el){\n if (el.nodeName != null && el.nodeName.toUpperCase() === 'SCRIPT' &&\n (!el.type || el.type === 'text/javascript') && !el.src){\n var target = el.ownerDocument ? el.ownerDocument.defaultView : window\n target['eval'].call(target, el.innerHTML)\n }\n })\n })\n })\n }\n\n // after => insertAfter\n // prepend => prependTo\n // before => insertBefore\n // append => appendTo\n $.fn[inside ? operator+'To' : 'insert'+(operatorIndex ? 'Before' : 'After')] = function(html){\n $(html)[operator](this)\n return this\n }\n })\n\n zepto.Z.prototype = Z.prototype = $.fn\n\n // Export internal API functions in the `$.zepto` namespace\n zepto.uniq = uniq\n zepto.deserializeValue = deserializeValue\n $.zepto = zepto\n\n return $\n})()\n\nwindow.Zepto = Zepto\nwindow.$ === undefined && (window.$ = Zepto)\n\n;(function($){\n var _zid = 1, undefined,\n slice = Array.prototype.slice,\n isFunction = $.isFunction,\n isString = function(obj){ return typeof obj == 'string' },\n handlers = {},\n specialEvents={},\n focusinSupported = 'onfocusin' in window,\n focus = { focus: 'focusin', blur: 'focusout' },\n hover = { mouseenter: 'mouseover', mouseleave: 'mouseout' }\n\n specialEvents.click = specialEvents.mousedown = specialEvents.mouseup = specialEvents.mousemove = 'MouseEvents'\n\n function zid(element) {\n return element._zid || (element._zid = _zid++)\n }\n function findHandlers(element, event, fn, selector) {\n event = parse(event)\n if (event.ns) var matcher = matcherFor(event.ns)\n return (handlers[zid(element)] || []).filter(function(handler) {\n return handler\n && (!event.e || handler.e == event.e)\n && (!event.ns || matcher.test(handler.ns))\n && (!fn || zid(handler.fn) === zid(fn))\n && (!selector || handler.sel == selector)\n })\n }\n function parse(event) {\n var parts = ('' + event).split('.')\n return {e: parts[0], ns: parts.slice(1).sort().join(' ')}\n }\n function matcherFor(ns) {\n return new RegExp('(?:^| )' + ns.replace(' ', ' .* ?') + '(?: |$)')\n }\n\n function eventCapture(handler, captureSetting) {\n return handler.del &&\n (!focusinSupported && (handler.e in focus)) ||\n !!captureSetting\n }\n\n function realEvent(type) {\n return hover[type] || (focusinSupported && focus[type]) || type\n }\n\n function add(element, events, fn, data, selector, delegator, capture){\n var id = zid(element), set = (handlers[id] || (handlers[id] = []))\n events.split(/\\s/).forEach(function(event){\n if (event == 'ready') return $(document).ready(fn)\n var handler = parse(event)\n handler.fn = fn\n handler.sel = selector\n // emulate mouseenter, mouseleave\n if (handler.e in hover) fn = function(e){\n var related = e.relatedTarget\n if (!related || (related !== this && !$.contains(this, related)))\n return handler.fn.apply(this, arguments)\n }\n handler.del = delegator\n var callback = delegator || fn\n handler.proxy = function(e){\n e = compatible(e)\n if (e.isImmediatePropagationStopped()) return\n e.data = data\n var result = callback.apply(element, e._args == undefined ? [e] : [e].concat(e._args))\n if (result === false) e.preventDefault(), e.stopPropagation()\n return result\n }\n handler.i = set.length\n set.push(handler)\n if ('addEventListener' in element)\n element.addEventListener(realEvent(handler.e), handler.proxy, eventCapture(handler, capture))\n })\n }\n function remove(element, events, fn, selector, capture){\n var id = zid(element)\n ;(events || '').split(/\\s/).forEach(function(event){\n findHandlers(element, event, fn, selector).forEach(function(handler){\n delete handlers[id][handler.i]\n if ('removeEventListener' in element)\n element.removeEventListener(realEvent(handler.e), handler.proxy, eventCapture(handler, capture))\n })\n })\n }\n\n $.event = { add: add, remove: remove }\n\n $.proxy = function(fn, context) {\n var args = (2 in arguments) && slice.call(arguments, 2)\n if (isFunction(fn)) {\n var proxyFn = function(){ return fn.apply(context, args ? args.concat(slice.call(arguments)) : arguments) }\n proxyFn._zid = zid(fn)\n return proxyFn\n } else if (isString(context)) {\n if (args) {\n args.unshift(fn[context], fn)\n return $.proxy.apply(null, args)\n } else {\n return $.proxy(fn[context], fn)\n }\n } else {\n throw new TypeError(\"expected function\")\n }\n }\n\n $.fn.bind = function(event, data, callback){\n return this.on(event, data, callback)\n }\n $.fn.unbind = function(event, callback){\n return this.off(event, callback)\n }\n $.fn.one = function(event, selector, data, callback){\n return this.on(event, selector, data, callback, 1)\n }\n\n var returnTrue = function(){return true},\n returnFalse = function(){return false},\n ignoreProperties = /^([A-Z]|returnValue$|layer[XY]$|webkitMovement[XY]$)/,\n eventMethods = {\n preventDefault: 'isDefaultPrevented',\n stopImmediatePropagation: 'isImmediatePropagationStopped',\n stopPropagation: 'isPropagationStopped'\n }\n\n function compatible(event, source) {\n if (source || !event.isDefaultPrevented) {\n source || (source = event)\n\n $.each(eventMethods, function(name, predicate) {\n var sourceMethod = source[name]\n event[name] = function(){\n this[predicate] = returnTrue\n return sourceMethod && sourceMethod.apply(source, arguments)\n }\n event[predicate] = returnFalse\n })\n\n event.timeStamp || (event.timeStamp = Date.now())\n\n if (source.defaultPrevented !== undefined ? source.defaultPrevented :\n 'returnValue' in source ? source.returnValue === false :\n source.getPreventDefault && source.getPreventDefault())\n event.isDefaultPrevented = returnTrue\n }\n return event\n }\n\n function createProxy(event) {\n var key, proxy = { originalEvent: event }\n for (key in event)\n if (!ignoreProperties.test(key) && event[key] !== undefined) proxy[key] = event[key]\n\n return compatible(proxy, event)\n }\n\n $.fn.delegate = function(selector, event, callback){\n return this.on(event, selector, callback)\n }\n $.fn.undelegate = function(selector, event, callback){\n return this.off(event, selector, callback)\n }\n\n $.fn.live = function(event, callback){\n $(document.body).delegate(this.selector, event, callback)\n return this\n }\n $.fn.die = function(event, callback){\n $(document.body).undelegate(this.selector, event, callback)\n return this\n }\n\n $.fn.on = function(event, selector, data, callback, one){\n var autoRemove, delegator, $this = this\n if (event && !isString(event)) {\n $.each(event, function(type, fn){\n $this.on(type, selector, data, fn, one)\n })\n return $this\n }\n\n if (!isString(selector) && !isFunction(callback) && callback !== false)\n callback = data, data = selector, selector = undefined\n if (callback === undefined || data === false)\n callback = data, data = undefined\n\n if (callback === false) callback = returnFalse\n\n return $this.each(function(_, element){\n if (one) autoRemove = function(e){\n remove(element, e.type, callback)\n return callback.apply(this, arguments)\n }\n\n if (selector) delegator = function(e){\n var evt, match = $(e.target).closest(selector, element).get(0)\n if (match && match !== element) {\n evt = $.extend(createProxy(e), {currentTarget: match, liveFired: element})\n return (autoRemove || callback).apply(match, [evt].concat(slice.call(arguments, 1)))\n }\n }\n\n add(element, event, callback, data, selector, delegator || autoRemove)\n })\n }\n $.fn.off = function(event, selector, callback){\n var $this = this\n if (event && !isString(event)) {\n $.each(event, function(type, fn){\n $this.off(type, selector, fn)\n })\n return $this\n }\n\n if (!isString(selector) && !isFunction(callback) && callback !== false)\n callback = selector, selector = undefined\n\n if (callback === false) callback = returnFalse\n\n return $this.each(function(){\n remove(this, event, callback, selector)\n })\n }\n\n $.fn.trigger = function(event, args){\n event = (isString(event) || $.isPlainObject(event)) ? $.Event(event) : compatible(event)\n event._args = args\n return this.each(function(){\n // handle focus(), blur() by calling them directly\n if (event.type in focus && typeof this[event.type] == \"function\") this[event.type]()\n // items in the collection might not be DOM elements\n else if ('dispatchEvent' in this) this.dispatchEvent(event)\n else $(this).triggerHandler(event, args)\n })\n }\n\n // triggers event handlers on current element just as if an event occurred,\n // doesn't trigger an actual event, doesn't bubble\n $.fn.triggerHandler = function(event, args){\n var e, result\n this.each(function(i, element){\n e = createProxy(isString(event) ? $.Event(event) : event)\n e._args = args\n e.target = element\n $.each(findHandlers(element, event.type || event), function(i, handler){\n result = handler.proxy(e)\n if (e.isImmediatePropagationStopped()) return false\n })\n })\n return result\n }\n\n // shortcut methods for `.bind(event, fn)` for each event type\n ;('focusin focusout focus blur load resize scroll unload click dblclick '+\n 'mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave '+\n 'change select keydown keypress keyup error').split(' ').forEach(function(event) {\n $.fn[event] = function(callback) {\n return (0 in arguments) ?\n this.bind(event, callback) :\n this.trigger(event)\n }\n })\n\n $.Event = function(type, props) {\n if (!isString(type)) props = type, type = props.type\n var event = document.createEvent(specialEvents[type] || 'Events'), bubbles = true\n if (props) for (var name in props) (name == 'bubbles') ? (bubbles = !!props[name]) : (event[name] = props[name])\n event.initEvent(type, bubbles, true)\n return compatible(event)\n }\n\n})(Zepto)\n\n;(function($){\n var jsonpID = +new Date(),\n document = window.document,\n key,\n name,\n rscript = /)<[^<]*)*<\\/script>/gi,\n scriptTypeRE = /^(?:text|application)\\/javascript/i,\n xmlTypeRE = /^(?:text|application)\\/xml/i,\n jsonType = 'application/json',\n htmlType = 'text/html',\n blankRE = /^\\s*$/,\n originAnchor = document.createElement('a')\n\n originAnchor.href = window.location.href\n\n // trigger a custom event and return false if it was cancelled\n function triggerAndReturn(context, eventName, data) {\n var event = $.Event(eventName)\n $(context).trigger(event, data)\n return !event.isDefaultPrevented()\n }\n\n // trigger an Ajax \"global\" event\n function triggerGlobal(settings, context, eventName, data) {\n if (settings.global) return triggerAndReturn(context || document, eventName, data)\n }\n\n // Number of active Ajax requests\n $.active = 0\n\n function ajaxStart(settings) {\n if (settings.global && $.active++ === 0) triggerGlobal(settings, null, 'ajaxStart')\n }\n function ajaxStop(settings) {\n if (settings.global && !(--$.active)) triggerGlobal(settings, null, 'ajaxStop')\n }\n\n // triggers an extra global event \"ajaxBeforeSend\" that's like \"ajaxSend\" but cancelable\n function ajaxBeforeSend(xhr, settings) {\n var context = settings.context\n if (settings.beforeSend.call(context, xhr, settings) === false ||\n triggerGlobal(settings, context, 'ajaxBeforeSend', [xhr, settings]) === false)\n return false\n\n triggerGlobal(settings, context, 'ajaxSend', [xhr, settings])\n }\n function ajaxSuccess(data, xhr, settings, deferred) {\n var context = settings.context, status = 'success'\n settings.success.call(context, data, status, xhr)\n if (deferred) deferred.resolveWith(context, [data, status, xhr])\n triggerGlobal(settings, context, 'ajaxSuccess', [xhr, settings, data])\n ajaxComplete(status, xhr, settings)\n }\n // type: \"timeout\", \"error\", \"abort\", \"parsererror\"\n function ajaxError(error, type, xhr, settings, deferred) {\n var context = settings.context\n settings.error.call(context, xhr, type, error)\n if (deferred) deferred.rejectWith(context, [xhr, type, error])\n triggerGlobal(settings, context, 'ajaxError', [xhr, settings, error || type])\n ajaxComplete(type, xhr, settings)\n }\n // status: \"success\", \"notmodified\", \"error\", \"timeout\", \"abort\", \"parsererror\"\n function ajaxComplete(status, xhr, settings) {\n var context = settings.context\n settings.complete.call(context, xhr, status)\n triggerGlobal(settings, context, 'ajaxComplete', [xhr, settings])\n ajaxStop(settings)\n }\n\n function ajaxDataFilter(data, type, settings) {\n if (settings.dataFilter == empty) return data\n var context = settings.context\n return settings.dataFilter.call(context, data, type)\n }\n\n // Empty function, used as default callback\n function empty() {}\n\n $.ajaxJSONP = function(options, deferred){\n if (!('type' in options)) return $.ajax(options)\n\n var _callbackName = options.jsonpCallback,\n callbackName = ($.isFunction(_callbackName) ?\n _callbackName() : _callbackName) || ('Zepto' + (jsonpID++)),\n script = document.createElement('script'),\n originalCallback = window[callbackName],\n responseData,\n abort = function(errorType) {\n $(script).triggerHandler('error', errorType || 'abort')\n },\n xhr = { abort: abort }, abortTimeout\n\n if (deferred) deferred.promise(xhr)\n\n $(script).on('load error', function(e, errorType){\n clearTimeout(abortTimeout)\n $(script).off().remove()\n\n if (e.type == 'error' || !responseData) {\n ajaxError(null, errorType || 'error', xhr, options, deferred)\n } else {\n ajaxSuccess(responseData[0], xhr, options, deferred)\n }\n\n window[callbackName] = originalCallback\n if (responseData && $.isFunction(originalCallback))\n originalCallback(responseData[0])\n\n originalCallback = responseData = undefined\n })\n\n if (ajaxBeforeSend(xhr, options) === false) {\n abort('abort')\n return xhr\n }\n\n window[callbackName] = function(){\n responseData = arguments\n }\n\n script.src = options.url.replace(/\\?(.+)=\\?/, '?$1=' + callbackName)\n document.head.appendChild(script)\n\n if (options.timeout > 0) abortTimeout = setTimeout(function(){\n abort('timeout')\n }, options.timeout)\n\n return xhr\n }\n\n $.ajaxSettings = {\n // Default type of request\n type: 'GET',\n // Callback that is executed before request\n beforeSend: empty,\n // Callback that is executed if the request succeeds\n success: empty,\n // Callback that is executed the the server drops error\n error: empty,\n // Callback that is executed on request complete (both: error and success)\n complete: empty,\n // The context for the callbacks\n context: null,\n // Whether to trigger \"global\" Ajax events\n global: true,\n // Transport\n xhr: function () {\n return new window.XMLHttpRequest()\n },\n // MIME types mapping\n // IIS returns Javascript as \"application/x-javascript\"\n accepts: {\n script: 'text/javascript, application/javascript, application/x-javascript',\n json: jsonType,\n xml: 'application/xml, text/xml',\n html: htmlType,\n text: 'text/plain'\n },\n // Whether the request is to another domain\n crossDomain: false,\n // Default timeout\n timeout: 0,\n // Whether data should be serialized to string\n processData: true,\n // Whether the browser should be allowed to cache GET responses\n cache: true,\n //Used to handle the raw response data of XMLHttpRequest.\n //This is a pre-filtering function to sanitize the response.\n //The sanitized response should be returned\n dataFilter: empty\n }\n\n function mimeToDataType(mime) {\n if (mime) mime = mime.split(';', 2)[0]\n return mime && ( mime == htmlType ? 'html' :\n mime == jsonType ? 'json' :\n scriptTypeRE.test(mime) ? 'script' :\n xmlTypeRE.test(mime) && 'xml' ) || 'text'\n }\n\n function appendQuery(url, query) {\n if (query == '') return url\n return (url + '&' + query).replace(/[&?]{1,2}/, '?')\n }\n\n // serialize payload and append it to the URL for GET requests\n function serializeData(options) {\n if (options.processData && options.data && $.type(options.data) != \"string\")\n options.data = $.param(options.data, options.traditional)\n if (options.data && (!options.type || options.type.toUpperCase() == 'GET' || 'jsonp' == options.dataType))\n options.url = appendQuery(options.url, options.data), options.data = undefined\n }\n\n $.ajax = function(options){\n var settings = $.extend({}, options || {}),\n deferred = $.Deferred && $.Deferred(),\n urlAnchor, hashIndex\n for (key in $.ajaxSettings) if (settings[key] === undefined) settings[key] = $.ajaxSettings[key]\n\n ajaxStart(settings)\n\n if (!settings.crossDomain) {\n urlAnchor = document.createElement('a')\n urlAnchor.href = settings.url\n // cleans up URL for .href (IE only), see https://github.com/madrobby/zepto/pull/1049\n urlAnchor.href = urlAnchor.href\n settings.crossDomain = (originAnchor.protocol + '//' + originAnchor.host) !== (urlAnchor.protocol + '//' + urlAnchor.host)\n }\n\n if (!settings.url) settings.url = window.location.toString()\n if ((hashIndex = settings.url.indexOf('#')) > -1) settings.url = settings.url.slice(0, hashIndex)\n serializeData(settings)\n\n var dataType = settings.dataType, hasPlaceholder = /\\?.+=\\?/.test(settings.url)\n if (hasPlaceholder) dataType = 'jsonp'\n\n if (settings.cache === false || (\n (!options || options.cache !== true) &&\n ('script' == dataType || 'jsonp' == dataType)\n ))\n settings.url = appendQuery(settings.url, '_=' + Date.now())\n\n if ('jsonp' == dataType) {\n if (!hasPlaceholder)\n settings.url = appendQuery(settings.url,\n settings.jsonp ? (settings.jsonp + '=?') : settings.jsonp === false ? '' : 'callback=?')\n return $.ajaxJSONP(settings, deferred)\n }\n\n var mime = settings.accepts[dataType],\n headers = { },\n setHeader = function(name, value) { headers[name.toLowerCase()] = [name, value] },\n protocol = /^([\\w-]+:)\\/\\//.test(settings.url) ? RegExp.$1 : window.location.protocol,\n xhr = settings.xhr(),\n nativeSetHeader = xhr.setRequestHeader,\n abortTimeout\n\n if (deferred) deferred.promise(xhr)\n\n if (!settings.crossDomain) setHeader('X-Requested-With', 'XMLHttpRequest')\n setHeader('Accept', mime || '*/*')\n if (mime = settings.mimeType || mime) {\n if (mime.indexOf(',') > -1) mime = mime.split(',', 2)[0]\n xhr.overrideMimeType && xhr.overrideMimeType(mime)\n }\n if (settings.contentType || (settings.contentType !== false && settings.data && settings.type.toUpperCase() != 'GET'))\n setHeader('Content-Type', settings.contentType || 'application/x-www-form-urlencoded')\n\n if (settings.headers) for (name in settings.headers) setHeader(name, settings.headers[name])\n xhr.setRequestHeader = setHeader\n\n xhr.onreadystatechange = function(){\n if (xhr.readyState == 4) {\n xhr.onreadystatechange = empty\n clearTimeout(abortTimeout)\n var result, error = false\n if ((xhr.status >= 200 && xhr.status < 300) || xhr.status == 304 || (xhr.status == 0 && protocol == 'file:')) {\n dataType = dataType || mimeToDataType(settings.mimeType || xhr.getResponseHeader('content-type'))\n\n if (xhr.responseType == 'arraybuffer' || xhr.responseType == 'blob')\n result = xhr.response\n else {\n result = xhr.responseText\n\n try {\n // http://perfectionkills.com/global-eval-what-are-the-options/\n // sanitize response accordingly if data filter callback provided\n result = ajaxDataFilter(result, dataType, settings)\n if (dataType == 'script') (1,eval)(result)\n else if (dataType == 'xml') result = xhr.responseXML\n else if (dataType == 'json') result = blankRE.test(result) ? null : $.parseJSON(result)\n } catch (e) { error = e }\n\n if (error) return ajaxError(error, 'parsererror', xhr, settings, deferred)\n }\n\n ajaxSuccess(result, xhr, settings, deferred)\n } else {\n ajaxError(xhr.statusText || null, xhr.status ? 'error' : 'abort', xhr, settings, deferred)\n }\n }\n }\n\n if (ajaxBeforeSend(xhr, settings) === false) {\n xhr.abort()\n ajaxError(null, 'abort', xhr, settings, deferred)\n return xhr\n }\n\n var async = 'async' in settings ? settings.async : true\n xhr.open(settings.type, settings.url, async, settings.username, settings.password)\n\n if (settings.xhrFields) for (name in settings.xhrFields) xhr[name] = settings.xhrFields[name]\n\n for (name in headers) nativeSetHeader.apply(xhr, headers[name])\n\n if (settings.timeout > 0) abortTimeout = setTimeout(function(){\n xhr.onreadystatechange = empty\n xhr.abort()\n ajaxError(null, 'timeout', xhr, settings, deferred)\n }, settings.timeout)\n\n // avoid sending empty string (#319)\n xhr.send(settings.data ? settings.data : null)\n return xhr\n }\n\n // handle optional data/success arguments\n function parseArguments(url, data, success, dataType) {\n if ($.isFunction(data)) dataType = success, success = data, data = undefined\n if (!$.isFunction(success)) dataType = success, success = undefined\n return {\n url: url\n , data: data\n , success: success\n , dataType: dataType\n }\n }\n\n $.get = function(/* url, data, success, dataType */){\n return $.ajax(parseArguments.apply(null, arguments))\n }\n\n $.post = function(/* url, data, success, dataType */){\n var options = parseArguments.apply(null, arguments)\n options.type = 'POST'\n return $.ajax(options)\n }\n\n $.getJSON = function(/* url, data, success */){\n var options = parseArguments.apply(null, arguments)\n options.dataType = 'json'\n return $.ajax(options)\n }\n\n $.fn.load = function(url, data, success){\n if (!this.length) return this\n var self = this, parts = url.split(/\\s/), selector,\n options = parseArguments(url, data, success),\n callback = options.success\n if (parts.length > 1) options.url = parts[0], selector = parts[1]\n options.success = function(response){\n self.html(selector ?\n $('
').html(response.replace(rscript, \"\")).find(selector)\n : response)\n callback && callback.apply(self, arguments)\n }\n $.ajax(options)\n return this\n }\n\n var escape = encodeURIComponent\n\n function serialize(params, obj, traditional, scope){\n var type, array = $.isArray(obj), hash = $.isPlainObject(obj)\n $.each(obj, function(key, value) {\n type = $.type(value)\n if (scope) key = traditional ? scope :\n scope + '[' + (hash || type == 'object' || type == 'array' ? key : '') + ']'\n // handle data in serializeArray() format\n if (!scope && array) params.add(value.name, value.value)\n // recurse into nested objects\n else if (type == \"array\" || (!traditional && type == \"object\"))\n serialize(params, value, traditional, key)\n else params.add(key, value)\n })\n }\n\n $.param = function(obj, traditional){\n var params = []\n params.add = function(key, value) {\n if ($.isFunction(value)) value = value()\n if (value == null) value = \"\"\n this.push(escape(key) + '=' + escape(value))\n }\n serialize(params, obj, traditional)\n return params.join('&').replace(/%20/g, '+')\n }\n})(Zepto)\n\n;(function($){\n $.fn.serializeArray = function() {\n var name, type, result = [],\n add = function(value) {\n if (value.forEach) return value.forEach(add)\n result.push({ name: name, value: value })\n }\n if (this[0]) $.each(this[0].elements, function(_, field){\n type = field.type, name = field.name\n if (name && field.nodeName.toLowerCase() != 'fieldset' &&\n !field.disabled && type != 'submit' && type != 'reset' && type != 'button' && type != 'file' &&\n ((type != 'radio' && type != 'checkbox') || field.checked))\n add($(field).val())\n })\n return result\n }\n\n $.fn.serialize = function(){\n var result = []\n this.serializeArray().forEach(function(elm){\n result.push(encodeURIComponent(elm.name) + '=' + encodeURIComponent(elm.value))\n })\n return result.join('&')\n }\n\n $.fn.submit = function(callback) {\n if (0 in arguments) this.bind('submit', callback)\n else if (this.length) {\n var event = $.Event('submit')\n this.eq(0).trigger(event)\n if (!event.isDefaultPrevented()) this.get(0).submit()\n }\n return this\n }\n\n})(Zepto)\n\n;(function(){\n // getComputedStyle shouldn't freak out when called\n // without a valid element as argument\n try {\n getComputedStyle(undefined)\n } catch(e) {\n var nativeGetComputedStyle = getComputedStyle\n window.getComputedStyle = function(element, pseudoElement){\n try {\n return nativeGetComputedStyle(element, pseudoElement)\n } catch(e) {\n return null\n }\n }\n }\n})()\n return Zepto\n}))\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** /Users/jaylinwang/Workspace/Mine/sunny-wechat/~/zepto/dist/zepto.js\n ** module id = 2\n ** module chunks = 0\n **/"],"sourceRoot":""} -------------------------------------------------------------------------------- /public/src/js/common.js: -------------------------------------------------------------------------------- 1 | webpackJsonp([0,1],[ 2 | /* 0 */ 3 | /***/ function(module, exports, __webpack_require__) { 4 | 5 | module.exports = __webpack_require__(1); 6 | 7 | 8 | /***/ }, 9 | /* 1 */ 10 | /***/ function(module, exports, __webpack_require__) { 11 | 12 | 'use strict'; 13 | 14 | var $ = __webpack_require__(2); 15 | 16 | /***/ }, 17 | /* 2 */ 18 | /***/ function(module, exports, __webpack_require__) { 19 | 20 | var __WEBPACK_AMD_DEFINE_RESULT__;/* Zepto v1.2.0 - zepto event ajax form ie - zeptojs.com/license */ 21 | (function(global, factory) { 22 | if (true) 23 | !(__WEBPACK_AMD_DEFINE_RESULT__ = function() { return factory(global) }.call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)) 24 | else 25 | factory(global) 26 | }(this, function(window) { 27 | var Zepto = (function() { 28 | var undefined, key, $, classList, emptyArray = [], concat = emptyArray.concat, filter = emptyArray.filter, slice = emptyArray.slice, 29 | document = window.document, 30 | elementDisplay = {}, classCache = {}, 31 | cssNumber = { 'column-count': 1, 'columns': 1, 'font-weight': 1, 'line-height': 1,'opacity': 1, 'z-index': 1, 'zoom': 1 }, 32 | fragmentRE = /^\s*<(\w+|!)[^>]*>/, 33 | singleTagRE = /^<(\w+)\s*\/?>(?:<\/\1>|)$/, 34 | tagExpanderRE = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/ig, 35 | rootNodeRE = /^(?:body|html)$/i, 36 | capitalRE = /([A-Z])/g, 37 | 38 | // special attributes that should be get/set via method calls 39 | methodAttributes = ['val', 'css', 'html', 'text', 'data', 'width', 'height', 'offset'], 40 | 41 | adjacencyOperators = [ 'after', 'prepend', 'before', 'append' ], 42 | table = document.createElement('table'), 43 | tableRow = document.createElement('tr'), 44 | containers = { 45 | 'tr': document.createElement('tbody'), 46 | 'tbody': table, 'thead': table, 'tfoot': table, 47 | 'td': tableRow, 'th': tableRow, 48 | '*': document.createElement('div') 49 | }, 50 | readyRE = /complete|loaded|interactive/, 51 | simpleSelectorRE = /^[\w-]*$/, 52 | class2type = {}, 53 | toString = class2type.toString, 54 | zepto = {}, 55 | camelize, uniq, 56 | tempParent = document.createElement('div'), 57 | propMap = { 58 | 'tabindex': 'tabIndex', 59 | 'readonly': 'readOnly', 60 | 'for': 'htmlFor', 61 | 'class': 'className', 62 | 'maxlength': 'maxLength', 63 | 'cellspacing': 'cellSpacing', 64 | 'cellpadding': 'cellPadding', 65 | 'rowspan': 'rowSpan', 66 | 'colspan': 'colSpan', 67 | 'usemap': 'useMap', 68 | 'frameborder': 'frameBorder', 69 | 'contenteditable': 'contentEditable' 70 | }, 71 | isArray = Array.isArray || 72 | function(object){ return object instanceof Array } 73 | 74 | zepto.matches = function(element, selector) { 75 | if (!selector || !element || element.nodeType !== 1) return false 76 | var matchesSelector = element.matches || element.webkitMatchesSelector || 77 | element.mozMatchesSelector || element.oMatchesSelector || 78 | element.matchesSelector 79 | if (matchesSelector) return matchesSelector.call(element, selector) 80 | // fall back to performing a selector: 81 | var match, parent = element.parentNode, temp = !parent 82 | if (temp) (parent = tempParent).appendChild(element) 83 | match = ~zepto.qsa(parent, selector).indexOf(element) 84 | temp && tempParent.removeChild(element) 85 | return match 86 | } 87 | 88 | function type(obj) { 89 | return obj == null ? String(obj) : 90 | class2type[toString.call(obj)] || "object" 91 | } 92 | 93 | function isFunction(value) { return type(value) == "function" } 94 | function isWindow(obj) { return obj != null && obj == obj.window } 95 | function isDocument(obj) { return obj != null && obj.nodeType == obj.DOCUMENT_NODE } 96 | function isObject(obj) { return type(obj) == "object" } 97 | function isPlainObject(obj) { 98 | return isObject(obj) && !isWindow(obj) && Object.getPrototypeOf(obj) == Object.prototype 99 | } 100 | 101 | function likeArray(obj) { 102 | var length = !!obj && 'length' in obj && obj.length, 103 | type = $.type(obj) 104 | 105 | return 'function' != type && !isWindow(obj) && ( 106 | 'array' == type || length === 0 || 107 | (typeof length == 'number' && length > 0 && (length - 1) in obj) 108 | ) 109 | } 110 | 111 | function compact(array) { return filter.call(array, function(item){ return item != null }) } 112 | function flatten(array) { return array.length > 0 ? $.fn.concat.apply([], array) : array } 113 | camelize = function(str){ return str.replace(/-+(.)?/g, function(match, chr){ return chr ? chr.toUpperCase() : '' }) } 114 | function dasherize(str) { 115 | return str.replace(/::/g, '/') 116 | .replace(/([A-Z]+)([A-Z][a-z])/g, '$1_$2') 117 | .replace(/([a-z\d])([A-Z])/g, '$1_$2') 118 | .replace(/_/g, '-') 119 | .toLowerCase() 120 | } 121 | uniq = function(array){ return filter.call(array, function(item, idx){ return array.indexOf(item) == idx }) } 122 | 123 | function classRE(name) { 124 | return name in classCache ? 125 | classCache[name] : (classCache[name] = new RegExp('(^|\\s)' + name + '(\\s|$)')) 126 | } 127 | 128 | function maybeAddPx(name, value) { 129 | return (typeof value == "number" && !cssNumber[dasherize(name)]) ? value + "px" : value 130 | } 131 | 132 | function defaultDisplay(nodeName) { 133 | var element, display 134 | if (!elementDisplay[nodeName]) { 135 | element = document.createElement(nodeName) 136 | document.body.appendChild(element) 137 | display = getComputedStyle(element, '').getPropertyValue("display") 138 | element.parentNode.removeChild(element) 139 | display == "none" && (display = "block") 140 | elementDisplay[nodeName] = display 141 | } 142 | return elementDisplay[nodeName] 143 | } 144 | 145 | function children(element) { 146 | return 'children' in element ? 147 | slice.call(element.children) : 148 | $.map(element.childNodes, function(node){ if (node.nodeType == 1) return node }) 149 | } 150 | 151 | function Z(dom, selector) { 152 | var i, len = dom ? dom.length : 0 153 | for (i = 0; i < len; i++) this[i] = dom[i] 154 | this.length = len 155 | this.selector = selector || '' 156 | } 157 | 158 | // `$.zepto.fragment` takes a html string and an optional tag name 159 | // to generate DOM nodes from the given html string. 160 | // The generated DOM nodes are returned as an array. 161 | // This function can be overridden in plugins for example to make 162 | // it compatible with browsers that don't support the DOM fully. 163 | zepto.fragment = function(html, name, properties) { 164 | var dom, nodes, container 165 | 166 | // A special case optimization for a single tag 167 | if (singleTagRE.test(html)) dom = $(document.createElement(RegExp.$1)) 168 | 169 | if (!dom) { 170 | if (html.replace) html = html.replace(tagExpanderRE, "<$1>") 171 | if (name === undefined) name = fragmentRE.test(html) && RegExp.$1 172 | if (!(name in containers)) name = '*' 173 | 174 | container = containers[name] 175 | container.innerHTML = '' + html 176 | dom = $.each(slice.call(container.childNodes), function(){ 177 | container.removeChild(this) 178 | }) 179 | } 180 | 181 | if (isPlainObject(properties)) { 182 | nodes = $(dom) 183 | $.each(properties, function(key, value) { 184 | if (methodAttributes.indexOf(key) > -1) nodes[key](value) 185 | else nodes.attr(key, value) 186 | }) 187 | } 188 | 189 | return dom 190 | } 191 | 192 | // `$.zepto.Z` swaps out the prototype of the given `dom` array 193 | // of nodes with `$.fn` and thus supplying all the Zepto functions 194 | // to the array. This method can be overridden in plugins. 195 | zepto.Z = function(dom, selector) { 196 | return new Z(dom, selector) 197 | } 198 | 199 | // `$.zepto.isZ` should return `true` if the given object is a Zepto 200 | // collection. This method can be overridden in plugins. 201 | zepto.isZ = function(object) { 202 | return object instanceof zepto.Z 203 | } 204 | 205 | // `$.zepto.init` is Zepto's counterpart to jQuery's `$.fn.init` and 206 | // takes a CSS selector and an optional context (and handles various 207 | // special cases). 208 | // This method can be overridden in plugins. 209 | zepto.init = function(selector, context) { 210 | var dom 211 | // If nothing given, return an empty Zepto collection 212 | if (!selector) return zepto.Z() 213 | // Optimize for string selectors 214 | else if (typeof selector == 'string') { 215 | selector = selector.trim() 216 | // If it's a html fragment, create nodes from it 217 | // Note: In both Chrome 21 and Firefox 15, DOM error 12 218 | // is thrown if the fragment doesn't begin with < 219 | if (selector[0] == '<' && fragmentRE.test(selector)) 220 | dom = zepto.fragment(selector, RegExp.$1, context), selector = null 221 | // If there's a context, create a collection on that context first, and select 222 | // nodes from there 223 | else if (context !== undefined) return $(context).find(selector) 224 | // If it's a CSS selector, use it to select nodes. 225 | else dom = zepto.qsa(document, selector) 226 | } 227 | // If a function is given, call it when the DOM is ready 228 | else if (isFunction(selector)) return $(document).ready(selector) 229 | // If a Zepto collection is given, just return it 230 | else if (zepto.isZ(selector)) return selector 231 | else { 232 | // normalize array if an array of nodes is given 233 | if (isArray(selector)) dom = compact(selector) 234 | // Wrap DOM nodes. 235 | else if (isObject(selector)) 236 | dom = [selector], selector = null 237 | // If it's a html fragment, create nodes from it 238 | else if (fragmentRE.test(selector)) 239 | dom = zepto.fragment(selector.trim(), RegExp.$1, context), selector = null 240 | // If there's a context, create a collection on that context first, and select 241 | // nodes from there 242 | else if (context !== undefined) return $(context).find(selector) 243 | // And last but no least, if it's a CSS selector, use it to select nodes. 244 | else dom = zepto.qsa(document, selector) 245 | } 246 | // create a new Zepto collection from the nodes found 247 | return zepto.Z(dom, selector) 248 | } 249 | 250 | // `$` will be the base `Zepto` object. When calling this 251 | // function just call `$.zepto.init, which makes the implementation 252 | // details of selecting nodes and creating Zepto collections 253 | // patchable in plugins. 254 | $ = function(selector, context){ 255 | return zepto.init(selector, context) 256 | } 257 | 258 | function extend(target, source, deep) { 259 | for (key in source) 260 | if (deep && (isPlainObject(source[key]) || isArray(source[key]))) { 261 | if (isPlainObject(source[key]) && !isPlainObject(target[key])) 262 | target[key] = {} 263 | if (isArray(source[key]) && !isArray(target[key])) 264 | target[key] = [] 265 | extend(target[key], source[key], deep) 266 | } 267 | else if (source[key] !== undefined) target[key] = source[key] 268 | } 269 | 270 | // Copy all but undefined properties from one or more 271 | // objects to the `target` object. 272 | $.extend = function(target){ 273 | var deep, args = slice.call(arguments, 1) 274 | if (typeof target == 'boolean') { 275 | deep = target 276 | target = args.shift() 277 | } 278 | args.forEach(function(arg){ extend(target, arg, deep) }) 279 | return target 280 | } 281 | 282 | // `$.zepto.qsa` is Zepto's CSS selector implementation which 283 | // uses `document.querySelectorAll` and optimizes for some special cases, like `#id`. 284 | // This method can be overridden in plugins. 285 | zepto.qsa = function(element, selector){ 286 | var found, 287 | maybeID = selector[0] == '#', 288 | maybeClass = !maybeID && selector[0] == '.', 289 | nameOnly = maybeID || maybeClass ? selector.slice(1) : selector, // Ensure that a 1 char tag name still gets checked 290 | isSimple = simpleSelectorRE.test(nameOnly) 291 | return (element.getElementById && isSimple && maybeID) ? // Safari DocumentFragment doesn't have getElementById 292 | ( (found = element.getElementById(nameOnly)) ? [found] : [] ) : 293 | (element.nodeType !== 1 && element.nodeType !== 9 && element.nodeType !== 11) ? [] : 294 | slice.call( 295 | isSimple && !maybeID && element.getElementsByClassName ? // DocumentFragment doesn't have getElementsByClassName/TagName 296 | maybeClass ? element.getElementsByClassName(nameOnly) : // If it's simple, it could be a class 297 | element.getElementsByTagName(selector) : // Or a tag 298 | element.querySelectorAll(selector) // Or it's not simple, and we need to query all 299 | ) 300 | } 301 | 302 | function filtered(nodes, selector) { 303 | return selector == null ? $(nodes) : $(nodes).filter(selector) 304 | } 305 | 306 | $.contains = document.documentElement.contains ? 307 | function(parent, node) { 308 | return parent !== node && parent.contains(node) 309 | } : 310 | function(parent, node) { 311 | while (node && (node = node.parentNode)) 312 | if (node === parent) return true 313 | return false 314 | } 315 | 316 | function funcArg(context, arg, idx, payload) { 317 | return isFunction(arg) ? arg.call(context, idx, payload) : arg 318 | } 319 | 320 | function setAttribute(node, name, value) { 321 | value == null ? node.removeAttribute(name) : node.setAttribute(name, value) 322 | } 323 | 324 | // access className property while respecting SVGAnimatedString 325 | function className(node, value){ 326 | var klass = node.className || '', 327 | svg = klass && klass.baseVal !== undefined 328 | 329 | if (value === undefined) return svg ? klass.baseVal : klass 330 | svg ? (klass.baseVal = value) : (node.className = value) 331 | } 332 | 333 | // "true" => true 334 | // "false" => false 335 | // "null" => null 336 | // "42" => 42 337 | // "42.5" => 42.5 338 | // "08" => "08" 339 | // JSON => parse if valid 340 | // String => self 341 | function deserializeValue(value) { 342 | try { 343 | return value ? 344 | value == "true" || 345 | ( value == "false" ? false : 346 | value == "null" ? null : 347 | +value + "" == value ? +value : 348 | /^[\[\{]/.test(value) ? $.parseJSON(value) : 349 | value ) 350 | : value 351 | } catch(e) { 352 | return value 353 | } 354 | } 355 | 356 | $.type = type 357 | $.isFunction = isFunction 358 | $.isWindow = isWindow 359 | $.isArray = isArray 360 | $.isPlainObject = isPlainObject 361 | 362 | $.isEmptyObject = function(obj) { 363 | var name 364 | for (name in obj) return false 365 | return true 366 | } 367 | 368 | $.isNumeric = function(val) { 369 | var num = Number(val), type = typeof val 370 | return val != null && type != 'boolean' && 371 | (type != 'string' || val.length) && 372 | !isNaN(num) && isFinite(num) || false 373 | } 374 | 375 | $.inArray = function(elem, array, i){ 376 | return emptyArray.indexOf.call(array, elem, i) 377 | } 378 | 379 | $.camelCase = camelize 380 | $.trim = function(str) { 381 | return str == null ? "" : String.prototype.trim.call(str) 382 | } 383 | 384 | // plugin compatibility 385 | $.uuid = 0 386 | $.support = { } 387 | $.expr = { } 388 | $.noop = function() {} 389 | 390 | $.map = function(elements, callback){ 391 | var value, values = [], i, key 392 | if (likeArray(elements)) 393 | for (i = 0; i < elements.length; i++) { 394 | value = callback(elements[i], i) 395 | if (value != null) values.push(value) 396 | } 397 | else 398 | for (key in elements) { 399 | value = callback(elements[key], key) 400 | if (value != null) values.push(value) 401 | } 402 | return flatten(values) 403 | } 404 | 405 | $.each = function(elements, callback){ 406 | var i, key 407 | if (likeArray(elements)) { 408 | for (i = 0; i < elements.length; i++) 409 | if (callback.call(elements[i], i, elements[i]) === false) return elements 410 | } else { 411 | for (key in elements) 412 | if (callback.call(elements[key], key, elements[key]) === false) return elements 413 | } 414 | 415 | return elements 416 | } 417 | 418 | $.grep = function(elements, callback){ 419 | return filter.call(elements, callback) 420 | } 421 | 422 | if (window.JSON) $.parseJSON = JSON.parse 423 | 424 | // Populate the class2type map 425 | $.each("Boolean Number String Function Array Date RegExp Object Error".split(" "), function(i, name) { 426 | class2type[ "[object " + name + "]" ] = name.toLowerCase() 427 | }) 428 | 429 | // Define methods that will be available on all 430 | // Zepto collections 431 | $.fn = { 432 | constructor: zepto.Z, 433 | length: 0, 434 | 435 | // Because a collection acts like an array 436 | // copy over these useful array functions. 437 | forEach: emptyArray.forEach, 438 | reduce: emptyArray.reduce, 439 | push: emptyArray.push, 440 | sort: emptyArray.sort, 441 | splice: emptyArray.splice, 442 | indexOf: emptyArray.indexOf, 443 | concat: function(){ 444 | var i, value, args = [] 445 | for (i = 0; i < arguments.length; i++) { 446 | value = arguments[i] 447 | args[i] = zepto.isZ(value) ? value.toArray() : value 448 | } 449 | return concat.apply(zepto.isZ(this) ? this.toArray() : this, args) 450 | }, 451 | 452 | // `map` and `slice` in the jQuery API work differently 453 | // from their array counterparts 454 | map: function(fn){ 455 | return $($.map(this, function(el, i){ return fn.call(el, i, el) })) 456 | }, 457 | slice: function(){ 458 | return $(slice.apply(this, arguments)) 459 | }, 460 | 461 | ready: function(callback){ 462 | // need to check if document.body exists for IE as that browser reports 463 | // document ready when it hasn't yet created the body element 464 | if (readyRE.test(document.readyState) && document.body) callback($) 465 | else document.addEventListener('DOMContentLoaded', function(){ callback($) }, false) 466 | return this 467 | }, 468 | get: function(idx){ 469 | return idx === undefined ? slice.call(this) : this[idx >= 0 ? idx : idx + this.length] 470 | }, 471 | toArray: function(){ return this.get() }, 472 | size: function(){ 473 | return this.length 474 | }, 475 | remove: function(){ 476 | return this.each(function(){ 477 | if (this.parentNode != null) 478 | this.parentNode.removeChild(this) 479 | }) 480 | }, 481 | each: function(callback){ 482 | emptyArray.every.call(this, function(el, idx){ 483 | return callback.call(el, idx, el) !== false 484 | }) 485 | return this 486 | }, 487 | filter: function(selector){ 488 | if (isFunction(selector)) return this.not(this.not(selector)) 489 | return $(filter.call(this, function(element){ 490 | return zepto.matches(element, selector) 491 | })) 492 | }, 493 | add: function(selector,context){ 494 | return $(uniq(this.concat($(selector,context)))) 495 | }, 496 | is: function(selector){ 497 | return this.length > 0 && zepto.matches(this[0], selector) 498 | }, 499 | not: function(selector){ 500 | var nodes=[] 501 | if (isFunction(selector) && selector.call !== undefined) 502 | this.each(function(idx){ 503 | if (!selector.call(this,idx)) nodes.push(this) 504 | }) 505 | else { 506 | var excludes = typeof selector == 'string' ? this.filter(selector) : 507 | (likeArray(selector) && isFunction(selector.item)) ? slice.call(selector) : $(selector) 508 | this.forEach(function(el){ 509 | if (excludes.indexOf(el) < 0) nodes.push(el) 510 | }) 511 | } 512 | return $(nodes) 513 | }, 514 | has: function(selector){ 515 | return this.filter(function(){ 516 | return isObject(selector) ? 517 | $.contains(this, selector) : 518 | $(this).find(selector).size() 519 | }) 520 | }, 521 | eq: function(idx){ 522 | return idx === -1 ? this.slice(idx) : this.slice(idx, + idx + 1) 523 | }, 524 | first: function(){ 525 | var el = this[0] 526 | return el && !isObject(el) ? el : $(el) 527 | }, 528 | last: function(){ 529 | var el = this[this.length - 1] 530 | return el && !isObject(el) ? el : $(el) 531 | }, 532 | find: function(selector){ 533 | var result, $this = this 534 | if (!selector) result = $() 535 | else if (typeof selector == 'object') 536 | result = $(selector).filter(function(){ 537 | var node = this 538 | return emptyArray.some.call($this, function(parent){ 539 | return $.contains(parent, node) 540 | }) 541 | }) 542 | else if (this.length == 1) result = $(zepto.qsa(this[0], selector)) 543 | else result = this.map(function(){ return zepto.qsa(this, selector) }) 544 | return result 545 | }, 546 | closest: function(selector, context){ 547 | var nodes = [], collection = typeof selector == 'object' && $(selector) 548 | this.each(function(_, node){ 549 | while (node && !(collection ? collection.indexOf(node) >= 0 : zepto.matches(node, selector))) 550 | node = node !== context && !isDocument(node) && node.parentNode 551 | if (node && nodes.indexOf(node) < 0) nodes.push(node) 552 | }) 553 | return $(nodes) 554 | }, 555 | parents: function(selector){ 556 | var ancestors = [], nodes = this 557 | while (nodes.length > 0) 558 | nodes = $.map(nodes, function(node){ 559 | if ((node = node.parentNode) && !isDocument(node) && ancestors.indexOf(node) < 0) { 560 | ancestors.push(node) 561 | return node 562 | } 563 | }) 564 | return filtered(ancestors, selector) 565 | }, 566 | parent: function(selector){ 567 | return filtered(uniq(this.pluck('parentNode')), selector) 568 | }, 569 | children: function(selector){ 570 | return filtered(this.map(function(){ return children(this) }), selector) 571 | }, 572 | contents: function() { 573 | return this.map(function() { return this.contentDocument || slice.call(this.childNodes) }) 574 | }, 575 | siblings: function(selector){ 576 | return filtered(this.map(function(i, el){ 577 | return filter.call(children(el.parentNode), function(child){ return child!==el }) 578 | }), selector) 579 | }, 580 | empty: function(){ 581 | return this.each(function(){ this.innerHTML = '' }) 582 | }, 583 | // `pluck` is borrowed from Prototype.js 584 | pluck: function(property){ 585 | return $.map(this, function(el){ return el[property] }) 586 | }, 587 | show: function(){ 588 | return this.each(function(){ 589 | this.style.display == "none" && (this.style.display = '') 590 | if (getComputedStyle(this, '').getPropertyValue("display") == "none") 591 | this.style.display = defaultDisplay(this.nodeName) 592 | }) 593 | }, 594 | replaceWith: function(newContent){ 595 | return this.before(newContent).remove() 596 | }, 597 | wrap: function(structure){ 598 | var func = isFunction(structure) 599 | if (this[0] && !func) 600 | var dom = $(structure).get(0), 601 | clone = dom.parentNode || this.length > 1 602 | 603 | return this.each(function(index){ 604 | $(this).wrapAll( 605 | func ? structure.call(this, index) : 606 | clone ? dom.cloneNode(true) : dom 607 | ) 608 | }) 609 | }, 610 | wrapAll: function(structure){ 611 | if (this[0]) { 612 | $(this[0]).before(structure = $(structure)) 613 | var children 614 | // drill down to the inmost element 615 | while ((children = structure.children()).length) structure = children.first() 616 | $(structure).append(this) 617 | } 618 | return this 619 | }, 620 | wrapInner: function(structure){ 621 | var func = isFunction(structure) 622 | return this.each(function(index){ 623 | var self = $(this), contents = self.contents(), 624 | dom = func ? structure.call(this, index) : structure 625 | contents.length ? contents.wrapAll(dom) : self.append(dom) 626 | }) 627 | }, 628 | unwrap: function(){ 629 | this.parent().each(function(){ 630 | $(this).replaceWith($(this).children()) 631 | }) 632 | return this 633 | }, 634 | clone: function(){ 635 | return this.map(function(){ return this.cloneNode(true) }) 636 | }, 637 | hide: function(){ 638 | return this.css("display", "none") 639 | }, 640 | toggle: function(setting){ 641 | return this.each(function(){ 642 | var el = $(this) 643 | ;(setting === undefined ? el.css("display") == "none" : setting) ? el.show() : el.hide() 644 | }) 645 | }, 646 | prev: function(selector){ return $(this.pluck('previousElementSibling')).filter(selector || '*') }, 647 | next: function(selector){ return $(this.pluck('nextElementSibling')).filter(selector || '*') }, 648 | html: function(html){ 649 | return 0 in arguments ? 650 | this.each(function(idx){ 651 | var originHtml = this.innerHTML 652 | $(this).empty().append( funcArg(this, html, idx, originHtml) ) 653 | }) : 654 | (0 in this ? this[0].innerHTML : null) 655 | }, 656 | text: function(text){ 657 | return 0 in arguments ? 658 | this.each(function(idx){ 659 | var newText = funcArg(this, text, idx, this.textContent) 660 | this.textContent = newText == null ? '' : ''+newText 661 | }) : 662 | (0 in this ? this.pluck('textContent').join("") : null) 663 | }, 664 | attr: function(name, value){ 665 | var result 666 | return (typeof name == 'string' && !(1 in arguments)) ? 667 | (0 in this && this[0].nodeType == 1 && (result = this[0].getAttribute(name)) != null ? result : undefined) : 668 | this.each(function(idx){ 669 | if (this.nodeType !== 1) return 670 | if (isObject(name)) for (key in name) setAttribute(this, key, name[key]) 671 | else setAttribute(this, name, funcArg(this, value, idx, this.getAttribute(name))) 672 | }) 673 | }, 674 | removeAttr: function(name){ 675 | return this.each(function(){ this.nodeType === 1 && name.split(' ').forEach(function(attribute){ 676 | setAttribute(this, attribute) 677 | }, this)}) 678 | }, 679 | prop: function(name, value){ 680 | name = propMap[name] || name 681 | return (1 in arguments) ? 682 | this.each(function(idx){ 683 | this[name] = funcArg(this, value, idx, this[name]) 684 | }) : 685 | (this[0] && this[0][name]) 686 | }, 687 | removeProp: function(name){ 688 | name = propMap[name] || name 689 | return this.each(function(){ delete this[name] }) 690 | }, 691 | data: function(name, value){ 692 | var attrName = 'data-' + name.replace(capitalRE, '-$1').toLowerCase() 693 | 694 | var data = (1 in arguments) ? 695 | this.attr(attrName, value) : 696 | this.attr(attrName) 697 | 698 | return data !== null ? deserializeValue(data) : undefined 699 | }, 700 | val: function(value){ 701 | if (0 in arguments) { 702 | if (value == null) value = "" 703 | return this.each(function(idx){ 704 | this.value = funcArg(this, value, idx, this.value) 705 | }) 706 | } else { 707 | return this[0] && (this[0].multiple ? 708 | $(this[0]).find('option').filter(function(){ return this.selected }).pluck('value') : 709 | this[0].value) 710 | } 711 | }, 712 | offset: function(coordinates){ 713 | if (coordinates) return this.each(function(index){ 714 | var $this = $(this), 715 | coords = funcArg(this, coordinates, index, $this.offset()), 716 | parentOffset = $this.offsetParent().offset(), 717 | props = { 718 | top: coords.top - parentOffset.top, 719 | left: coords.left - parentOffset.left 720 | } 721 | 722 | if ($this.css('position') == 'static') props['position'] = 'relative' 723 | $this.css(props) 724 | }) 725 | if (!this.length) return null 726 | if (document.documentElement !== this[0] && !$.contains(document.documentElement, this[0])) 727 | return {top: 0, left: 0} 728 | var obj = this[0].getBoundingClientRect() 729 | return { 730 | left: obj.left + window.pageXOffset, 731 | top: obj.top + window.pageYOffset, 732 | width: Math.round(obj.width), 733 | height: Math.round(obj.height) 734 | } 735 | }, 736 | css: function(property, value){ 737 | if (arguments.length < 2) { 738 | var element = this[0] 739 | if (typeof property == 'string') { 740 | if (!element) return 741 | return element.style[camelize(property)] || getComputedStyle(element, '').getPropertyValue(property) 742 | } else if (isArray(property)) { 743 | if (!element) return 744 | var props = {} 745 | var computedStyle = getComputedStyle(element, '') 746 | $.each(property, function(_, prop){ 747 | props[prop] = (element.style[camelize(prop)] || computedStyle.getPropertyValue(prop)) 748 | }) 749 | return props 750 | } 751 | } 752 | 753 | var css = '' 754 | if (type(property) == 'string') { 755 | if (!value && value !== 0) 756 | this.each(function(){ this.style.removeProperty(dasherize(property)) }) 757 | else 758 | css = dasherize(property) + ":" + maybeAddPx(property, value) 759 | } else { 760 | for (key in property) 761 | if (!property[key] && property[key] !== 0) 762 | this.each(function(){ this.style.removeProperty(dasherize(key)) }) 763 | else 764 | css += dasherize(key) + ':' + maybeAddPx(key, property[key]) + ';' 765 | } 766 | 767 | return this.each(function(){ this.style.cssText += ';' + css }) 768 | }, 769 | index: function(element){ 770 | return element ? this.indexOf($(element)[0]) : this.parent().children().indexOf(this[0]) 771 | }, 772 | hasClass: function(name){ 773 | if (!name) return false 774 | return emptyArray.some.call(this, function(el){ 775 | return this.test(className(el)) 776 | }, classRE(name)) 777 | }, 778 | addClass: function(name){ 779 | if (!name) return this 780 | return this.each(function(idx){ 781 | if (!('className' in this)) return 782 | classList = [] 783 | var cls = className(this), newName = funcArg(this, name, idx, cls) 784 | newName.split(/\s+/g).forEach(function(klass){ 785 | if (!$(this).hasClass(klass)) classList.push(klass) 786 | }, this) 787 | classList.length && className(this, cls + (cls ? " " : "") + classList.join(" ")) 788 | }) 789 | }, 790 | removeClass: function(name){ 791 | return this.each(function(idx){ 792 | if (!('className' in this)) return 793 | if (name === undefined) return className(this, '') 794 | classList = className(this) 795 | funcArg(this, name, idx, classList).split(/\s+/g).forEach(function(klass){ 796 | classList = classList.replace(classRE(klass), " ") 797 | }) 798 | className(this, classList.trim()) 799 | }) 800 | }, 801 | toggleClass: function(name, when){ 802 | if (!name) return this 803 | return this.each(function(idx){ 804 | var $this = $(this), names = funcArg(this, name, idx, className(this)) 805 | names.split(/\s+/g).forEach(function(klass){ 806 | (when === undefined ? !$this.hasClass(klass) : when) ? 807 | $this.addClass(klass) : $this.removeClass(klass) 808 | }) 809 | }) 810 | }, 811 | scrollTop: function(value){ 812 | if (!this.length) return 813 | var hasScrollTop = 'scrollTop' in this[0] 814 | if (value === undefined) return hasScrollTop ? this[0].scrollTop : this[0].pageYOffset 815 | return this.each(hasScrollTop ? 816 | function(){ this.scrollTop = value } : 817 | function(){ this.scrollTo(this.scrollX, value) }) 818 | }, 819 | scrollLeft: function(value){ 820 | if (!this.length) return 821 | var hasScrollLeft = 'scrollLeft' in this[0] 822 | if (value === undefined) return hasScrollLeft ? this[0].scrollLeft : this[0].pageXOffset 823 | return this.each(hasScrollLeft ? 824 | function(){ this.scrollLeft = value } : 825 | function(){ this.scrollTo(value, this.scrollY) }) 826 | }, 827 | position: function() { 828 | if (!this.length) return 829 | 830 | var elem = this[0], 831 | // Get *real* offsetParent 832 | offsetParent = this.offsetParent(), 833 | // Get correct offsets 834 | offset = this.offset(), 835 | parentOffset = rootNodeRE.test(offsetParent[0].nodeName) ? { top: 0, left: 0 } : offsetParent.offset() 836 | 837 | // Subtract element margins 838 | // note: when an element has margin: auto the offsetLeft and marginLeft 839 | // are the same in Safari causing offset.left to incorrectly be 0 840 | offset.top -= parseFloat( $(elem).css('margin-top') ) || 0 841 | offset.left -= parseFloat( $(elem).css('margin-left') ) || 0 842 | 843 | // Add offsetParent borders 844 | parentOffset.top += parseFloat( $(offsetParent[0]).css('border-top-width') ) || 0 845 | parentOffset.left += parseFloat( $(offsetParent[0]).css('border-left-width') ) || 0 846 | 847 | // Subtract the two offsets 848 | return { 849 | top: offset.top - parentOffset.top, 850 | left: offset.left - parentOffset.left 851 | } 852 | }, 853 | offsetParent: function() { 854 | return this.map(function(){ 855 | var parent = this.offsetParent || document.body 856 | while (parent && !rootNodeRE.test(parent.nodeName) && $(parent).css("position") == "static") 857 | parent = parent.offsetParent 858 | return parent 859 | }) 860 | } 861 | } 862 | 863 | // for now 864 | $.fn.detach = $.fn.remove 865 | 866 | // Generate the `width` and `height` functions 867 | ;['width', 'height'].forEach(function(dimension){ 868 | var dimensionProperty = 869 | dimension.replace(/./, function(m){ return m[0].toUpperCase() }) 870 | 871 | $.fn[dimension] = function(value){ 872 | var offset, el = this[0] 873 | if (value === undefined) return isWindow(el) ? el['inner' + dimensionProperty] : 874 | isDocument(el) ? el.documentElement['scroll' + dimensionProperty] : 875 | (offset = this.offset()) && offset[dimension] 876 | else return this.each(function(idx){ 877 | el = $(this) 878 | el.css(dimension, funcArg(this, value, idx, el[dimension]())) 879 | }) 880 | } 881 | }) 882 | 883 | function traverseNode(node, fun) { 884 | fun(node) 885 | for (var i = 0, len = node.childNodes.length; i < len; i++) 886 | traverseNode(node.childNodes[i], fun) 887 | } 888 | 889 | // Generate the `after`, `prepend`, `before`, `append`, 890 | // `insertAfter`, `insertBefore`, `appendTo`, and `prependTo` methods. 891 | adjacencyOperators.forEach(function(operator, operatorIndex) { 892 | var inside = operatorIndex % 2 //=> prepend, append 893 | 894 | $.fn[operator] = function(){ 895 | // arguments can be nodes, arrays of nodes, Zepto objects and HTML strings 896 | var argType, nodes = $.map(arguments, function(arg) { 897 | var arr = [] 898 | argType = type(arg) 899 | if (argType == "array") { 900 | arg.forEach(function(el) { 901 | if (el.nodeType !== undefined) return arr.push(el) 902 | else if ($.zepto.isZ(el)) return arr = arr.concat(el.get()) 903 | arr = arr.concat(zepto.fragment(el)) 904 | }) 905 | return arr 906 | } 907 | return argType == "object" || arg == null ? 908 | arg : zepto.fragment(arg) 909 | }), 910 | parent, copyByClone = this.length > 1 911 | if (nodes.length < 1) return this 912 | 913 | return this.each(function(_, target){ 914 | parent = inside ? target : target.parentNode 915 | 916 | // convert all methods to a "before" operation 917 | target = operatorIndex == 0 ? target.nextSibling : 918 | operatorIndex == 1 ? target.firstChild : 919 | operatorIndex == 2 ? target : 920 | null 921 | 922 | var parentInDocument = $.contains(document.documentElement, parent) 923 | 924 | nodes.forEach(function(node){ 925 | if (copyByClone) node = node.cloneNode(true) 926 | else if (!parent) return $(node).remove() 927 | 928 | parent.insertBefore(node, target) 929 | if (parentInDocument) traverseNode(node, function(el){ 930 | if (el.nodeName != null && el.nodeName.toUpperCase() === 'SCRIPT' && 931 | (!el.type || el.type === 'text/javascript') && !el.src){ 932 | var target = el.ownerDocument ? el.ownerDocument.defaultView : window 933 | target['eval'].call(target, el.innerHTML) 934 | } 935 | }) 936 | }) 937 | }) 938 | } 939 | 940 | // after => insertAfter 941 | // prepend => prependTo 942 | // before => insertBefore 943 | // append => appendTo 944 | $.fn[inside ? operator+'To' : 'insert'+(operatorIndex ? 'Before' : 'After')] = function(html){ 945 | $(html)[operator](this) 946 | return this 947 | } 948 | }) 949 | 950 | zepto.Z.prototype = Z.prototype = $.fn 951 | 952 | // Export internal API functions in the `$.zepto` namespace 953 | zepto.uniq = uniq 954 | zepto.deserializeValue = deserializeValue 955 | $.zepto = zepto 956 | 957 | return $ 958 | })() 959 | 960 | window.Zepto = Zepto 961 | window.$ === undefined && (window.$ = Zepto) 962 | 963 | ;(function($){ 964 | var _zid = 1, undefined, 965 | slice = Array.prototype.slice, 966 | isFunction = $.isFunction, 967 | isString = function(obj){ return typeof obj == 'string' }, 968 | handlers = {}, 969 | specialEvents={}, 970 | focusinSupported = 'onfocusin' in window, 971 | focus = { focus: 'focusin', blur: 'focusout' }, 972 | hover = { mouseenter: 'mouseover', mouseleave: 'mouseout' } 973 | 974 | specialEvents.click = specialEvents.mousedown = specialEvents.mouseup = specialEvents.mousemove = 'MouseEvents' 975 | 976 | function zid(element) { 977 | return element._zid || (element._zid = _zid++) 978 | } 979 | function findHandlers(element, event, fn, selector) { 980 | event = parse(event) 981 | if (event.ns) var matcher = matcherFor(event.ns) 982 | return (handlers[zid(element)] || []).filter(function(handler) { 983 | return handler 984 | && (!event.e || handler.e == event.e) 985 | && (!event.ns || matcher.test(handler.ns)) 986 | && (!fn || zid(handler.fn) === zid(fn)) 987 | && (!selector || handler.sel == selector) 988 | }) 989 | } 990 | function parse(event) { 991 | var parts = ('' + event).split('.') 992 | return {e: parts[0], ns: parts.slice(1).sort().join(' ')} 993 | } 994 | function matcherFor(ns) { 995 | return new RegExp('(?:^| )' + ns.replace(' ', ' .* ?') + '(?: |$)') 996 | } 997 | 998 | function eventCapture(handler, captureSetting) { 999 | return handler.del && 1000 | (!focusinSupported && (handler.e in focus)) || 1001 | !!captureSetting 1002 | } 1003 | 1004 | function realEvent(type) { 1005 | return hover[type] || (focusinSupported && focus[type]) || type 1006 | } 1007 | 1008 | function add(element, events, fn, data, selector, delegator, capture){ 1009 | var id = zid(element), set = (handlers[id] || (handlers[id] = [])) 1010 | events.split(/\s/).forEach(function(event){ 1011 | if (event == 'ready') return $(document).ready(fn) 1012 | var handler = parse(event) 1013 | handler.fn = fn 1014 | handler.sel = selector 1015 | // emulate mouseenter, mouseleave 1016 | if (handler.e in hover) fn = function(e){ 1017 | var related = e.relatedTarget 1018 | if (!related || (related !== this && !$.contains(this, related))) 1019 | return handler.fn.apply(this, arguments) 1020 | } 1021 | handler.del = delegator 1022 | var callback = delegator || fn 1023 | handler.proxy = function(e){ 1024 | e = compatible(e) 1025 | if (e.isImmediatePropagationStopped()) return 1026 | e.data = data 1027 | var result = callback.apply(element, e._args == undefined ? [e] : [e].concat(e._args)) 1028 | if (result === false) e.preventDefault(), e.stopPropagation() 1029 | return result 1030 | } 1031 | handler.i = set.length 1032 | set.push(handler) 1033 | if ('addEventListener' in element) 1034 | element.addEventListener(realEvent(handler.e), handler.proxy, eventCapture(handler, capture)) 1035 | }) 1036 | } 1037 | function remove(element, events, fn, selector, capture){ 1038 | var id = zid(element) 1039 | ;(events || '').split(/\s/).forEach(function(event){ 1040 | findHandlers(element, event, fn, selector).forEach(function(handler){ 1041 | delete handlers[id][handler.i] 1042 | if ('removeEventListener' in element) 1043 | element.removeEventListener(realEvent(handler.e), handler.proxy, eventCapture(handler, capture)) 1044 | }) 1045 | }) 1046 | } 1047 | 1048 | $.event = { add: add, remove: remove } 1049 | 1050 | $.proxy = function(fn, context) { 1051 | var args = (2 in arguments) && slice.call(arguments, 2) 1052 | if (isFunction(fn)) { 1053 | var proxyFn = function(){ return fn.apply(context, args ? args.concat(slice.call(arguments)) : arguments) } 1054 | proxyFn._zid = zid(fn) 1055 | return proxyFn 1056 | } else if (isString(context)) { 1057 | if (args) { 1058 | args.unshift(fn[context], fn) 1059 | return $.proxy.apply(null, args) 1060 | } else { 1061 | return $.proxy(fn[context], fn) 1062 | } 1063 | } else { 1064 | throw new TypeError("expected function") 1065 | } 1066 | } 1067 | 1068 | $.fn.bind = function(event, data, callback){ 1069 | return this.on(event, data, callback) 1070 | } 1071 | $.fn.unbind = function(event, callback){ 1072 | return this.off(event, callback) 1073 | } 1074 | $.fn.one = function(event, selector, data, callback){ 1075 | return this.on(event, selector, data, callback, 1) 1076 | } 1077 | 1078 | var returnTrue = function(){return true}, 1079 | returnFalse = function(){return false}, 1080 | ignoreProperties = /^([A-Z]|returnValue$|layer[XY]$|webkitMovement[XY]$)/, 1081 | eventMethods = { 1082 | preventDefault: 'isDefaultPrevented', 1083 | stopImmediatePropagation: 'isImmediatePropagationStopped', 1084 | stopPropagation: 'isPropagationStopped' 1085 | } 1086 | 1087 | function compatible(event, source) { 1088 | if (source || !event.isDefaultPrevented) { 1089 | source || (source = event) 1090 | 1091 | $.each(eventMethods, function(name, predicate) { 1092 | var sourceMethod = source[name] 1093 | event[name] = function(){ 1094 | this[predicate] = returnTrue 1095 | return sourceMethod && sourceMethod.apply(source, arguments) 1096 | } 1097 | event[predicate] = returnFalse 1098 | }) 1099 | 1100 | event.timeStamp || (event.timeStamp = Date.now()) 1101 | 1102 | if (source.defaultPrevented !== undefined ? source.defaultPrevented : 1103 | 'returnValue' in source ? source.returnValue === false : 1104 | source.getPreventDefault && source.getPreventDefault()) 1105 | event.isDefaultPrevented = returnTrue 1106 | } 1107 | return event 1108 | } 1109 | 1110 | function createProxy(event) { 1111 | var key, proxy = { originalEvent: event } 1112 | for (key in event) 1113 | if (!ignoreProperties.test(key) && event[key] !== undefined) proxy[key] = event[key] 1114 | 1115 | return compatible(proxy, event) 1116 | } 1117 | 1118 | $.fn.delegate = function(selector, event, callback){ 1119 | return this.on(event, selector, callback) 1120 | } 1121 | $.fn.undelegate = function(selector, event, callback){ 1122 | return this.off(event, selector, callback) 1123 | } 1124 | 1125 | $.fn.live = function(event, callback){ 1126 | $(document.body).delegate(this.selector, event, callback) 1127 | return this 1128 | } 1129 | $.fn.die = function(event, callback){ 1130 | $(document.body).undelegate(this.selector, event, callback) 1131 | return this 1132 | } 1133 | 1134 | $.fn.on = function(event, selector, data, callback, one){ 1135 | var autoRemove, delegator, $this = this 1136 | if (event && !isString(event)) { 1137 | $.each(event, function(type, fn){ 1138 | $this.on(type, selector, data, fn, one) 1139 | }) 1140 | return $this 1141 | } 1142 | 1143 | if (!isString(selector) && !isFunction(callback) && callback !== false) 1144 | callback = data, data = selector, selector = undefined 1145 | if (callback === undefined || data === false) 1146 | callback = data, data = undefined 1147 | 1148 | if (callback === false) callback = returnFalse 1149 | 1150 | return $this.each(function(_, element){ 1151 | if (one) autoRemove = function(e){ 1152 | remove(element, e.type, callback) 1153 | return callback.apply(this, arguments) 1154 | } 1155 | 1156 | if (selector) delegator = function(e){ 1157 | var evt, match = $(e.target).closest(selector, element).get(0) 1158 | if (match && match !== element) { 1159 | evt = $.extend(createProxy(e), {currentTarget: match, liveFired: element}) 1160 | return (autoRemove || callback).apply(match, [evt].concat(slice.call(arguments, 1))) 1161 | } 1162 | } 1163 | 1164 | add(element, event, callback, data, selector, delegator || autoRemove) 1165 | }) 1166 | } 1167 | $.fn.off = function(event, selector, callback){ 1168 | var $this = this 1169 | if (event && !isString(event)) { 1170 | $.each(event, function(type, fn){ 1171 | $this.off(type, selector, fn) 1172 | }) 1173 | return $this 1174 | } 1175 | 1176 | if (!isString(selector) && !isFunction(callback) && callback !== false) 1177 | callback = selector, selector = undefined 1178 | 1179 | if (callback === false) callback = returnFalse 1180 | 1181 | return $this.each(function(){ 1182 | remove(this, event, callback, selector) 1183 | }) 1184 | } 1185 | 1186 | $.fn.trigger = function(event, args){ 1187 | event = (isString(event) || $.isPlainObject(event)) ? $.Event(event) : compatible(event) 1188 | event._args = args 1189 | return this.each(function(){ 1190 | // handle focus(), blur() by calling them directly 1191 | if (event.type in focus && typeof this[event.type] == "function") this[event.type]() 1192 | // items in the collection might not be DOM elements 1193 | else if ('dispatchEvent' in this) this.dispatchEvent(event) 1194 | else $(this).triggerHandler(event, args) 1195 | }) 1196 | } 1197 | 1198 | // triggers event handlers on current element just as if an event occurred, 1199 | // doesn't trigger an actual event, doesn't bubble 1200 | $.fn.triggerHandler = function(event, args){ 1201 | var e, result 1202 | this.each(function(i, element){ 1203 | e = createProxy(isString(event) ? $.Event(event) : event) 1204 | e._args = args 1205 | e.target = element 1206 | $.each(findHandlers(element, event.type || event), function(i, handler){ 1207 | result = handler.proxy(e) 1208 | if (e.isImmediatePropagationStopped()) return false 1209 | }) 1210 | }) 1211 | return result 1212 | } 1213 | 1214 | // shortcut methods for `.bind(event, fn)` for each event type 1215 | ;('focusin focusout focus blur load resize scroll unload click dblclick '+ 1216 | 'mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave '+ 1217 | 'change select keydown keypress keyup error').split(' ').forEach(function(event) { 1218 | $.fn[event] = function(callback) { 1219 | return (0 in arguments) ? 1220 | this.bind(event, callback) : 1221 | this.trigger(event) 1222 | } 1223 | }) 1224 | 1225 | $.Event = function(type, props) { 1226 | if (!isString(type)) props = type, type = props.type 1227 | var event = document.createEvent(specialEvents[type] || 'Events'), bubbles = true 1228 | if (props) for (var name in props) (name == 'bubbles') ? (bubbles = !!props[name]) : (event[name] = props[name]) 1229 | event.initEvent(type, bubbles, true) 1230 | return compatible(event) 1231 | } 1232 | 1233 | })(Zepto) 1234 | 1235 | ;(function($){ 1236 | var jsonpID = +new Date(), 1237 | document = window.document, 1238 | key, 1239 | name, 1240 | rscript = /)<[^<]*)*<\/script>/gi, 1241 | scriptTypeRE = /^(?:text|application)\/javascript/i, 1242 | xmlTypeRE = /^(?:text|application)\/xml/i, 1243 | jsonType = 'application/json', 1244 | htmlType = 'text/html', 1245 | blankRE = /^\s*$/, 1246 | originAnchor = document.createElement('a') 1247 | 1248 | originAnchor.href = window.location.href 1249 | 1250 | // trigger a custom event and return false if it was cancelled 1251 | function triggerAndReturn(context, eventName, data) { 1252 | var event = $.Event(eventName) 1253 | $(context).trigger(event, data) 1254 | return !event.isDefaultPrevented() 1255 | } 1256 | 1257 | // trigger an Ajax "global" event 1258 | function triggerGlobal(settings, context, eventName, data) { 1259 | if (settings.global) return triggerAndReturn(context || document, eventName, data) 1260 | } 1261 | 1262 | // Number of active Ajax requests 1263 | $.active = 0 1264 | 1265 | function ajaxStart(settings) { 1266 | if (settings.global && $.active++ === 0) triggerGlobal(settings, null, 'ajaxStart') 1267 | } 1268 | function ajaxStop(settings) { 1269 | if (settings.global && !(--$.active)) triggerGlobal(settings, null, 'ajaxStop') 1270 | } 1271 | 1272 | // triggers an extra global event "ajaxBeforeSend" that's like "ajaxSend" but cancelable 1273 | function ajaxBeforeSend(xhr, settings) { 1274 | var context = settings.context 1275 | if (settings.beforeSend.call(context, xhr, settings) === false || 1276 | triggerGlobal(settings, context, 'ajaxBeforeSend', [xhr, settings]) === false) 1277 | return false 1278 | 1279 | triggerGlobal(settings, context, 'ajaxSend', [xhr, settings]) 1280 | } 1281 | function ajaxSuccess(data, xhr, settings, deferred) { 1282 | var context = settings.context, status = 'success' 1283 | settings.success.call(context, data, status, xhr) 1284 | if (deferred) deferred.resolveWith(context, [data, status, xhr]) 1285 | triggerGlobal(settings, context, 'ajaxSuccess', [xhr, settings, data]) 1286 | ajaxComplete(status, xhr, settings) 1287 | } 1288 | // type: "timeout", "error", "abort", "parsererror" 1289 | function ajaxError(error, type, xhr, settings, deferred) { 1290 | var context = settings.context 1291 | settings.error.call(context, xhr, type, error) 1292 | if (deferred) deferred.rejectWith(context, [xhr, type, error]) 1293 | triggerGlobal(settings, context, 'ajaxError', [xhr, settings, error || type]) 1294 | ajaxComplete(type, xhr, settings) 1295 | } 1296 | // status: "success", "notmodified", "error", "timeout", "abort", "parsererror" 1297 | function ajaxComplete(status, xhr, settings) { 1298 | var context = settings.context 1299 | settings.complete.call(context, xhr, status) 1300 | triggerGlobal(settings, context, 'ajaxComplete', [xhr, settings]) 1301 | ajaxStop(settings) 1302 | } 1303 | 1304 | function ajaxDataFilter(data, type, settings) { 1305 | if (settings.dataFilter == empty) return data 1306 | var context = settings.context 1307 | return settings.dataFilter.call(context, data, type) 1308 | } 1309 | 1310 | // Empty function, used as default callback 1311 | function empty() {} 1312 | 1313 | $.ajaxJSONP = function(options, deferred){ 1314 | if (!('type' in options)) return $.ajax(options) 1315 | 1316 | var _callbackName = options.jsonpCallback, 1317 | callbackName = ($.isFunction(_callbackName) ? 1318 | _callbackName() : _callbackName) || ('Zepto' + (jsonpID++)), 1319 | script = document.createElement('script'), 1320 | originalCallback = window[callbackName], 1321 | responseData, 1322 | abort = function(errorType) { 1323 | $(script).triggerHandler('error', errorType || 'abort') 1324 | }, 1325 | xhr = { abort: abort }, abortTimeout 1326 | 1327 | if (deferred) deferred.promise(xhr) 1328 | 1329 | $(script).on('load error', function(e, errorType){ 1330 | clearTimeout(abortTimeout) 1331 | $(script).off().remove() 1332 | 1333 | if (e.type == 'error' || !responseData) { 1334 | ajaxError(null, errorType || 'error', xhr, options, deferred) 1335 | } else { 1336 | ajaxSuccess(responseData[0], xhr, options, deferred) 1337 | } 1338 | 1339 | window[callbackName] = originalCallback 1340 | if (responseData && $.isFunction(originalCallback)) 1341 | originalCallback(responseData[0]) 1342 | 1343 | originalCallback = responseData = undefined 1344 | }) 1345 | 1346 | if (ajaxBeforeSend(xhr, options) === false) { 1347 | abort('abort') 1348 | return xhr 1349 | } 1350 | 1351 | window[callbackName] = function(){ 1352 | responseData = arguments 1353 | } 1354 | 1355 | script.src = options.url.replace(/\?(.+)=\?/, '?$1=' + callbackName) 1356 | document.head.appendChild(script) 1357 | 1358 | if (options.timeout > 0) abortTimeout = setTimeout(function(){ 1359 | abort('timeout') 1360 | }, options.timeout) 1361 | 1362 | return xhr 1363 | } 1364 | 1365 | $.ajaxSettings = { 1366 | // Default type of request 1367 | type: 'GET', 1368 | // Callback that is executed before request 1369 | beforeSend: empty, 1370 | // Callback that is executed if the request succeeds 1371 | success: empty, 1372 | // Callback that is executed the the server drops error 1373 | error: empty, 1374 | // Callback that is executed on request complete (both: error and success) 1375 | complete: empty, 1376 | // The context for the callbacks 1377 | context: null, 1378 | // Whether to trigger "global" Ajax events 1379 | global: true, 1380 | // Transport 1381 | xhr: function () { 1382 | return new window.XMLHttpRequest() 1383 | }, 1384 | // MIME types mapping 1385 | // IIS returns Javascript as "application/x-javascript" 1386 | accepts: { 1387 | script: 'text/javascript, application/javascript, application/x-javascript', 1388 | json: jsonType, 1389 | xml: 'application/xml, text/xml', 1390 | html: htmlType, 1391 | text: 'text/plain' 1392 | }, 1393 | // Whether the request is to another domain 1394 | crossDomain: false, 1395 | // Default timeout 1396 | timeout: 0, 1397 | // Whether data should be serialized to string 1398 | processData: true, 1399 | // Whether the browser should be allowed to cache GET responses 1400 | cache: true, 1401 | //Used to handle the raw response data of XMLHttpRequest. 1402 | //This is a pre-filtering function to sanitize the response. 1403 | //The sanitized response should be returned 1404 | dataFilter: empty 1405 | } 1406 | 1407 | function mimeToDataType(mime) { 1408 | if (mime) mime = mime.split(';', 2)[0] 1409 | return mime && ( mime == htmlType ? 'html' : 1410 | mime == jsonType ? 'json' : 1411 | scriptTypeRE.test(mime) ? 'script' : 1412 | xmlTypeRE.test(mime) && 'xml' ) || 'text' 1413 | } 1414 | 1415 | function appendQuery(url, query) { 1416 | if (query == '') return url 1417 | return (url + '&' + query).replace(/[&?]{1,2}/, '?') 1418 | } 1419 | 1420 | // serialize payload and append it to the URL for GET requests 1421 | function serializeData(options) { 1422 | if (options.processData && options.data && $.type(options.data) != "string") 1423 | options.data = $.param(options.data, options.traditional) 1424 | if (options.data && (!options.type || options.type.toUpperCase() == 'GET' || 'jsonp' == options.dataType)) 1425 | options.url = appendQuery(options.url, options.data), options.data = undefined 1426 | } 1427 | 1428 | $.ajax = function(options){ 1429 | var settings = $.extend({}, options || {}), 1430 | deferred = $.Deferred && $.Deferred(), 1431 | urlAnchor, hashIndex 1432 | for (key in $.ajaxSettings) if (settings[key] === undefined) settings[key] = $.ajaxSettings[key] 1433 | 1434 | ajaxStart(settings) 1435 | 1436 | if (!settings.crossDomain) { 1437 | urlAnchor = document.createElement('a') 1438 | urlAnchor.href = settings.url 1439 | // cleans up URL for .href (IE only), see https://github.com/madrobby/zepto/pull/1049 1440 | urlAnchor.href = urlAnchor.href 1441 | settings.crossDomain = (originAnchor.protocol + '//' + originAnchor.host) !== (urlAnchor.protocol + '//' + urlAnchor.host) 1442 | } 1443 | 1444 | if (!settings.url) settings.url = window.location.toString() 1445 | if ((hashIndex = settings.url.indexOf('#')) > -1) settings.url = settings.url.slice(0, hashIndex) 1446 | serializeData(settings) 1447 | 1448 | var dataType = settings.dataType, hasPlaceholder = /\?.+=\?/.test(settings.url) 1449 | if (hasPlaceholder) dataType = 'jsonp' 1450 | 1451 | if (settings.cache === false || ( 1452 | (!options || options.cache !== true) && 1453 | ('script' == dataType || 'jsonp' == dataType) 1454 | )) 1455 | settings.url = appendQuery(settings.url, '_=' + Date.now()) 1456 | 1457 | if ('jsonp' == dataType) { 1458 | if (!hasPlaceholder) 1459 | settings.url = appendQuery(settings.url, 1460 | settings.jsonp ? (settings.jsonp + '=?') : settings.jsonp === false ? '' : 'callback=?') 1461 | return $.ajaxJSONP(settings, deferred) 1462 | } 1463 | 1464 | var mime = settings.accepts[dataType], 1465 | headers = { }, 1466 | setHeader = function(name, value) { headers[name.toLowerCase()] = [name, value] }, 1467 | protocol = /^([\w-]+:)\/\//.test(settings.url) ? RegExp.$1 : window.location.protocol, 1468 | xhr = settings.xhr(), 1469 | nativeSetHeader = xhr.setRequestHeader, 1470 | abortTimeout 1471 | 1472 | if (deferred) deferred.promise(xhr) 1473 | 1474 | if (!settings.crossDomain) setHeader('X-Requested-With', 'XMLHttpRequest') 1475 | setHeader('Accept', mime || '*/*') 1476 | if (mime = settings.mimeType || mime) { 1477 | if (mime.indexOf(',') > -1) mime = mime.split(',', 2)[0] 1478 | xhr.overrideMimeType && xhr.overrideMimeType(mime) 1479 | } 1480 | if (settings.contentType || (settings.contentType !== false && settings.data && settings.type.toUpperCase() != 'GET')) 1481 | setHeader('Content-Type', settings.contentType || 'application/x-www-form-urlencoded') 1482 | 1483 | if (settings.headers) for (name in settings.headers) setHeader(name, settings.headers[name]) 1484 | xhr.setRequestHeader = setHeader 1485 | 1486 | xhr.onreadystatechange = function(){ 1487 | if (xhr.readyState == 4) { 1488 | xhr.onreadystatechange = empty 1489 | clearTimeout(abortTimeout) 1490 | var result, error = false 1491 | if ((xhr.status >= 200 && xhr.status < 300) || xhr.status == 304 || (xhr.status == 0 && protocol == 'file:')) { 1492 | dataType = dataType || mimeToDataType(settings.mimeType || xhr.getResponseHeader('content-type')) 1493 | 1494 | if (xhr.responseType == 'arraybuffer' || xhr.responseType == 'blob') 1495 | result = xhr.response 1496 | else { 1497 | result = xhr.responseText 1498 | 1499 | try { 1500 | // http://perfectionkills.com/global-eval-what-are-the-options/ 1501 | // sanitize response accordingly if data filter callback provided 1502 | result = ajaxDataFilter(result, dataType, settings) 1503 | if (dataType == 'script') (1,eval)(result) 1504 | else if (dataType == 'xml') result = xhr.responseXML 1505 | else if (dataType == 'json') result = blankRE.test(result) ? null : $.parseJSON(result) 1506 | } catch (e) { error = e } 1507 | 1508 | if (error) return ajaxError(error, 'parsererror', xhr, settings, deferred) 1509 | } 1510 | 1511 | ajaxSuccess(result, xhr, settings, deferred) 1512 | } else { 1513 | ajaxError(xhr.statusText || null, xhr.status ? 'error' : 'abort', xhr, settings, deferred) 1514 | } 1515 | } 1516 | } 1517 | 1518 | if (ajaxBeforeSend(xhr, settings) === false) { 1519 | xhr.abort() 1520 | ajaxError(null, 'abort', xhr, settings, deferred) 1521 | return xhr 1522 | } 1523 | 1524 | var async = 'async' in settings ? settings.async : true 1525 | xhr.open(settings.type, settings.url, async, settings.username, settings.password) 1526 | 1527 | if (settings.xhrFields) for (name in settings.xhrFields) xhr[name] = settings.xhrFields[name] 1528 | 1529 | for (name in headers) nativeSetHeader.apply(xhr, headers[name]) 1530 | 1531 | if (settings.timeout > 0) abortTimeout = setTimeout(function(){ 1532 | xhr.onreadystatechange = empty 1533 | xhr.abort() 1534 | ajaxError(null, 'timeout', xhr, settings, deferred) 1535 | }, settings.timeout) 1536 | 1537 | // avoid sending empty string (#319) 1538 | xhr.send(settings.data ? settings.data : null) 1539 | return xhr 1540 | } 1541 | 1542 | // handle optional data/success arguments 1543 | function parseArguments(url, data, success, dataType) { 1544 | if ($.isFunction(data)) dataType = success, success = data, data = undefined 1545 | if (!$.isFunction(success)) dataType = success, success = undefined 1546 | return { 1547 | url: url 1548 | , data: data 1549 | , success: success 1550 | , dataType: dataType 1551 | } 1552 | } 1553 | 1554 | $.get = function(/* url, data, success, dataType */){ 1555 | return $.ajax(parseArguments.apply(null, arguments)) 1556 | } 1557 | 1558 | $.post = function(/* url, data, success, dataType */){ 1559 | var options = parseArguments.apply(null, arguments) 1560 | options.type = 'POST' 1561 | return $.ajax(options) 1562 | } 1563 | 1564 | $.getJSON = function(/* url, data, success */){ 1565 | var options = parseArguments.apply(null, arguments) 1566 | options.dataType = 'json' 1567 | return $.ajax(options) 1568 | } 1569 | 1570 | $.fn.load = function(url, data, success){ 1571 | if (!this.length) return this 1572 | var self = this, parts = url.split(/\s/), selector, 1573 | options = parseArguments(url, data, success), 1574 | callback = options.success 1575 | if (parts.length > 1) options.url = parts[0], selector = parts[1] 1576 | options.success = function(response){ 1577 | self.html(selector ? 1578 | $('
').html(response.replace(rscript, "")).find(selector) 1579 | : response) 1580 | callback && callback.apply(self, arguments) 1581 | } 1582 | $.ajax(options) 1583 | return this 1584 | } 1585 | 1586 | var escape = encodeURIComponent 1587 | 1588 | function serialize(params, obj, traditional, scope){ 1589 | var type, array = $.isArray(obj), hash = $.isPlainObject(obj) 1590 | $.each(obj, function(key, value) { 1591 | type = $.type(value) 1592 | if (scope) key = traditional ? scope : 1593 | scope + '[' + (hash || type == 'object' || type == 'array' ? key : '') + ']' 1594 | // handle data in serializeArray() format 1595 | if (!scope && array) params.add(value.name, value.value) 1596 | // recurse into nested objects 1597 | else if (type == "array" || (!traditional && type == "object")) 1598 | serialize(params, value, traditional, key) 1599 | else params.add(key, value) 1600 | }) 1601 | } 1602 | 1603 | $.param = function(obj, traditional){ 1604 | var params = [] 1605 | params.add = function(key, value) { 1606 | if ($.isFunction(value)) value = value() 1607 | if (value == null) value = "" 1608 | this.push(escape(key) + '=' + escape(value)) 1609 | } 1610 | serialize(params, obj, traditional) 1611 | return params.join('&').replace(/%20/g, '+') 1612 | } 1613 | })(Zepto) 1614 | 1615 | ;(function($){ 1616 | $.fn.serializeArray = function() { 1617 | var name, type, result = [], 1618 | add = function(value) { 1619 | if (value.forEach) return value.forEach(add) 1620 | result.push({ name: name, value: value }) 1621 | } 1622 | if (this[0]) $.each(this[0].elements, function(_, field){ 1623 | type = field.type, name = field.name 1624 | if (name && field.nodeName.toLowerCase() != 'fieldset' && 1625 | !field.disabled && type != 'submit' && type != 'reset' && type != 'button' && type != 'file' && 1626 | ((type != 'radio' && type != 'checkbox') || field.checked)) 1627 | add($(field).val()) 1628 | }) 1629 | return result 1630 | } 1631 | 1632 | $.fn.serialize = function(){ 1633 | var result = [] 1634 | this.serializeArray().forEach(function(elm){ 1635 | result.push(encodeURIComponent(elm.name) + '=' + encodeURIComponent(elm.value)) 1636 | }) 1637 | return result.join('&') 1638 | } 1639 | 1640 | $.fn.submit = function(callback) { 1641 | if (0 in arguments) this.bind('submit', callback) 1642 | else if (this.length) { 1643 | var event = $.Event('submit') 1644 | this.eq(0).trigger(event) 1645 | if (!event.isDefaultPrevented()) this.get(0).submit() 1646 | } 1647 | return this 1648 | } 1649 | 1650 | })(Zepto) 1651 | 1652 | ;(function(){ 1653 | // getComputedStyle shouldn't freak out when called 1654 | // without a valid element as argument 1655 | try { 1656 | getComputedStyle(undefined) 1657 | } catch(e) { 1658 | var nativeGetComputedStyle = getComputedStyle 1659 | window.getComputedStyle = function(element, pseudoElement){ 1660 | try { 1661 | return nativeGetComputedStyle(element, pseudoElement) 1662 | } catch(e) { 1663 | return null 1664 | } 1665 | } 1666 | } 1667 | })() 1668 | return Zepto 1669 | })) 1670 | 1671 | 1672 | /***/ } 1673 | ]); 1674 | //# sourceMappingURL=common.js.map --------------------------------------------------------------------------------