diff --git a/Gruntfile.js b/Gruntfile.js index df8bc7e..ef1b058 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -35,11 +35,23 @@ module.exports = function(grunt) { '!node_modules/**/*' ] } + }, + 'http-server': { + 'dev': { + root: '.', + port: 3000, + host: "127.0.0.1", + cache: 1, + showDir : true, + autoIndex: true, + ext: "html" + } } }); grunt.loadNpmTasks('grunt-contrib-jshint'); grunt.loadNpmTasks('grunt-html-validation'); + grunt.loadNpmTasks('grunt-http-server'); grunt.registerTask('default', ['jshint', 'validation']); }; diff --git a/images/.DS_Store b/images/.DS_Store new file mode 100644 index 0000000..3056c32 Binary files /dev/null and b/images/.DS_Store differ diff --git a/images/arm.jpeg b/images/arm.jpeg new file mode 100644 index 0000000..28ca4cd Binary files /dev/null and b/images/arm.jpeg differ diff --git a/images/head.jpeg b/images/head.jpeg new file mode 100644 index 0000000..3cd5d07 Binary files /dev/null and b/images/head.jpeg differ diff --git a/images/img-1all.jpeg b/images/img-1all.jpeg new file mode 100644 index 0000000..a6a23dc Binary files /dev/null and b/images/img-1all.jpeg differ diff --git a/images/img-1none.jpeg b/images/img-1none.jpeg new file mode 100644 index 0000000..c79487d Binary files /dev/null and b/images/img-1none.jpeg differ diff --git a/images/img-2all.jpeg b/images/img-2all.jpeg new file mode 100644 index 0000000..22dcece Binary files /dev/null and b/images/img-2all.jpeg differ diff --git a/images/img-2none.jpeg b/images/img-2none.jpeg new file mode 100644 index 0000000..830b26e Binary files /dev/null and b/images/img-2none.jpeg differ diff --git a/images/img0-1.png b/images/img0-1.png new file mode 100644 index 0000000..276bed8 Binary files /dev/null and b/images/img0-1.png differ diff --git a/images/img0-2.png b/images/img0-2.png new file mode 100644 index 0000000..ca81253 Binary files /dev/null and b/images/img0-2.png differ diff --git a/images/img00.png b/images/img00.png new file mode 100644 index 0000000..28afd4d Binary files /dev/null and b/images/img00.png differ diff --git a/images/img01.png b/images/img01.png new file mode 100644 index 0000000..25266f3 Binary files /dev/null and b/images/img01.png differ diff --git a/images/img02.png b/images/img02.png new file mode 100644 index 0000000..2e32dca Binary files /dev/null and b/images/img02.png differ diff --git a/images/img0all.jpeg b/images/img0all.jpeg new file mode 100644 index 0000000..51968c4 Binary files /dev/null and b/images/img0all.jpeg differ diff --git a/images/img0none.jpeg b/images/img0none.jpeg new file mode 100644 index 0000000..ca1614f Binary files /dev/null and b/images/img0none.jpeg differ diff --git a/images/img1-1.png b/images/img1-1.png new file mode 100644 index 0000000..ce4b3e6 Binary files /dev/null and b/images/img1-1.png differ diff --git a/images/img1-2.png b/images/img1-2.png new file mode 100644 index 0000000..d54b4d0 Binary files /dev/null and b/images/img1-2.png differ diff --git a/images/img10.png b/images/img10.png new file mode 100644 index 0000000..ab119e5 Binary files /dev/null and b/images/img10.png differ diff --git a/images/img11.png b/images/img11.png new file mode 100644 index 0000000..3c039fd Binary files /dev/null and b/images/img11.png differ diff --git a/images/img12.png b/images/img12.png new file mode 100644 index 0000000..0fb4e19 Binary files /dev/null and b/images/img12.png differ diff --git a/images/img1all.jpeg b/images/img1all.jpeg new file mode 100644 index 0000000..4d9807c Binary files /dev/null and b/images/img1all.jpeg differ diff --git a/images/img1none.jpeg b/images/img1none.jpeg new file mode 100644 index 0000000..fb9a282 Binary files /dev/null and b/images/img1none.jpeg differ diff --git a/images/img2-1.png b/images/img2-1.png new file mode 100644 index 0000000..aac9804 Binary files /dev/null and b/images/img2-1.png differ diff --git a/images/img2-2.png b/images/img2-2.png new file mode 100644 index 0000000..56adba1 Binary files /dev/null and b/images/img2-2.png differ diff --git a/images/img20.png b/images/img20.png new file mode 100644 index 0000000..c2b4521 Binary files /dev/null and b/images/img20.png differ diff --git a/images/img21.png b/images/img21.png new file mode 100644 index 0000000..c49e867 Binary files /dev/null and b/images/img21.png differ diff --git a/images/img22.png b/images/img22.png new file mode 100644 index 0000000..ea25608 Binary files /dev/null and b/images/img22.png differ diff --git a/images/img2all.jpeg b/images/img2all.jpeg new file mode 100644 index 0000000..5253ce6 Binary files /dev/null and b/images/img2all.jpeg differ diff --git a/images/img2none.jpeg b/images/img2none.jpeg new file mode 100644 index 0000000..1d254a3 Binary files /dev/null and b/images/img2none.jpeg differ diff --git a/images/img3-1.png b/images/img3-1.png new file mode 100644 index 0000000..b0e72f5 Binary files /dev/null and b/images/img3-1.png differ diff --git a/images/img3-2.png b/images/img3-2.png new file mode 100644 index 0000000..1ae6484 Binary files /dev/null and b/images/img3-2.png differ diff --git a/images/img30.png b/images/img30.png new file mode 100644 index 0000000..f3efc4f Binary files /dev/null and b/images/img30.png differ diff --git a/images/img31.png b/images/img31.png new file mode 100644 index 0000000..128a39f Binary files /dev/null and b/images/img31.png differ diff --git a/images/img32.png b/images/img32.png new file mode 100644 index 0000000..35e730d Binary files /dev/null and b/images/img32.png differ diff --git a/images/img4-1.png b/images/img4-1.png new file mode 100644 index 0000000..a5769f1 Binary files /dev/null and b/images/img4-1.png differ diff --git a/images/img4-2.png b/images/img4-2.png new file mode 100644 index 0000000..8dc43d6 Binary files /dev/null and b/images/img4-2.png differ diff --git a/images/img40.png b/images/img40.png new file mode 100644 index 0000000..c164c46 Binary files /dev/null and b/images/img40.png differ diff --git a/images/img41.png b/images/img41.png new file mode 100644 index 0000000..20589fc Binary files /dev/null and b/images/img41.png differ diff --git a/images/img42.png b/images/img42.png new file mode 100644 index 0000000..48dfbb7 Binary files /dev/null and b/images/img42.png differ diff --git a/images/leg.jpeg b/images/leg.jpeg new file mode 100644 index 0000000..6c87d92 Binary files /dev/null and b/images/leg.jpeg differ diff --git a/images/pixlr0.pxd b/images/pixlr0.pxd new file mode 100644 index 0000000..740070f Binary files /dev/null and b/images/pixlr0.pxd differ diff --git a/images/pxlr-1.pxd b/images/pxlr-1.pxd new file mode 100644 index 0000000..d37a250 Binary files /dev/null and b/images/pxlr-1.pxd differ diff --git a/images/pxlr1.pxd b/images/pxlr1.pxd new file mode 100644 index 0000000..9b39474 Binary files /dev/null and b/images/pxlr1.pxd differ diff --git a/images/pxlr2.pxd b/images/pxlr2.pxd new file mode 100644 index 0000000..73a0bb2 Binary files /dev/null and b/images/pxlr2.pxd differ diff --git a/index copy.html b/index copy.html new file mode 100644 index 0000000..f97f2c8 --- /dev/null +++ b/index copy.html @@ -0,0 +1,18 @@ + + + + moneppo's Instructional Assignment + + + + + + + + + + + + + + diff --git a/index.html b/index.html index 6257184..5e1e551 100644 --- a/index.html +++ b/index.html @@ -1,9 +1,18 @@ - So-and-so's Instructional Assignment + moneppo's Instructional Assignment + - YOUR CODE HERE + + + + + + + + + diff --git a/index.js b/index.js new file mode 100644 index 0000000..0567bc1 --- /dev/null +++ b/index.js @@ -0,0 +1,106 @@ +Zepto(function($){ + var $canvas = $('#canvas'); + var $parts = $('.part'); + var ctx = $canvas[0].getContext('2d'); + + var none = []; + var parts = []; + + var attached = [false,false,false,false,false]; + + var bucket = 0; + function draw() { + ctx.drawImage(none[bucket], 0, 0); + for (var i = 0; i < attached.length;i++) { + if (attached[i]) { + ctx.drawImage(parts[i][bucket], 0,0); + } + } + } + + function mouseMove(e) { + var x = (e.pageX - $canvas.offset().left) / $canvas.width(); + bucket = Math.floor(x * 5) - 2; + if (bucket < -2) bucket = -2; + if (bucket > 2) bucket = 2; + draw(); + } + + function loadImages(update, then) { + var count = 0; + var totalImages = 30; + + function imageLoaded() { + count++; + update(count / totalImages); + if (count == totalImages) { + then(); + } + } + + // Load backgrounds + for (var p = -2; p <= 2; p++) { + var filename = 'images/img' + p + 'none.jpeg'; + var img = new Image(); + none[p] = img; + img.onload = imageLoaded; + img.src = filename; + } + + for (var i = 0; i < 5; i++) { + parts[i] = []; + for (var p = -2; p <= 2; p++) { + var filename = 'images/img' + i + p + '.png'; + var img = new Image(); + parts[i][p] = img; + img.onload = imageLoaded; + img.src = filename; + } + } + } + + loadImages( + function(amount) { + + }, + function() { + $canvas.on('mousemove', mouseMove); + draw(); + + $parts.draggable({ + start: function () { + this.css('-webkit-transform', 'scale(2)'); + }, + stop: function () { + this.css('-webkit-transform', 'scale(1)'); + } + }); + + $canvas.droppable({ + drop: function (e, dragEl, dropEl) { + if(dragEl.hasClass('head')) { + attached[0] = true; + } + + if(dragEl.hasClass('arm')) { + if (attached[1]) { + attached[2] = true; + } else attached[1] = true; + } + + if(dragEl.hasClass('leg')) { + if (attached[3]) { + attached[4] = true; + } else attached[3] = true; + } + + dragEl.hide(); + draw(); + + return true; + } + }); + } + ); +}); + diff --git a/main.css b/main.css new file mode 100644 index 0000000..b426c1a --- /dev/null +++ b/main.css @@ -0,0 +1,17 @@ +#canvas { + padding-left: 0; + padding-right: 0; + padding-top: 5%; + margin-left: auto; + margin-right: auto; + display: block; + width: 400px; +} + +body { + background-color: #AAA; +} + +.part { + float: left; +} \ No newline at end of file diff --git a/package.json b/package.json index 995397d..542909e 100644 --- a/package.json +++ b/package.json @@ -7,6 +7,7 @@ "devDependencies": { "grunt": "^0.4.4", "grunt-contrib-jshint": "^0.10.0", - "grunt-html-validation": "^0.1.15" + "grunt-html-validation": "^0.1.15", + "grunt-http-server": "~1.0.0" } } diff --git a/zepto.dragdrop.js b/zepto.dragdrop.js new file mode 100644 index 0000000..7a630b9 --- /dev/null +++ b/zepto.dragdrop.js @@ -0,0 +1,365 @@ +/** + * zepto.dragdrop.js v0.1.1 - Drag & Drop for Zepto with touch and mouse events. + * + * Copyright 2012, Michal Kuklis + * Dual licensed under the MIT or GPL Version 2 licenses. + * + **/ + +(function ($) { + + "use strict"; + + var draggable; // current draggable + + function Draggable(el, opts) { + var eventName = ($.touchable) ? "touchstart" : "mousedown"; + var o = el.offset(); + + this.opts = opts || {}; + this.ctx = this.opts.context || el; + this.pos = { left: o.left, top: o.top }; + + if (this.opts.selector) { + el.on(eventName, this.opts.selector, $.proxy(this.start, this)); + } + else { + el.on(eventName, $.proxy(this.start, this)); + } + } + + Draggable.prototype = { + constructor: Draggable, + + start: function (e) { + var offset, zIndex; + if (!draggable) { + this.curEl = $(e.currentTarget); + offset = this.curEl.offset(); + this.curEl.data(offset); + this.setRevert(offset); + this.setZIndex(1); + this.opts.start && this.opts.start.call(this.ctx, this.curEl); + this.curEl.trigger('draggable:start', [e, this.curEl]); + + this.setPosition(e); + draggable = this; + redraw(); + } + + e.preventDefault(); + e.stopPropagation(); + }, + + stop: function (e) { + if (draggable) { + e.el = this.curEl; + this.setZIndex(-1); + this.opts.stop && this.opts.stop.call(this.ctx, this.curEl); + this.curEl.trigger('draggable:end', [e, this.curEl]); + + redraw(); + draggable = null; + } + + e.preventDefault(); + e.stopPropagation(); + }, + + drag: function () { + this.curEl.css(this.pos); + this.opts.drag && this.opts.drag.call(this.ctx, this.curEl); + }, + + setPosition: function (e) { + var pos = $.getPos(e); + var h = this.curEl.height(); + var w = this.curEl.width(); + var offset = this.findOffset(); + this.pos = { + left: pos.x - w / offset, + top: pos.y - h / offset }; + + e.preventDefault(); + e.stopPropagation(); + }, + + setRevert: function (offset) { + if (this.opts.revert && !this.curEl.data('revert')) { + this.curEl.data({ + rtop: offset.top, + rleft: offset.left, + revert: this.opts.revert }); + } + }, + + findOffset: function () { + var ow = this.curEl.data('width'); + var nw = this.curEl.width(); + + return (ow > nw) ? 2 * ow / nw : 2 * nw / ow; + }, + + setZIndex: function (val) { + var zIndex = parseInt(this.curEl.css('z-index'), 10); + this.curEl.css('z-index', zIndex + val); + } + }; + + // helpers + function redraw() { + if (draggable) { + draggable.drag(); + window.requestAnimationFrame(redraw); + } + return false; + } + + // draggable plugin + $.fn.draggable = function (options) { + return this.each(function () { + var $this = $(this); + var data = $this.data('draggable'); + if (!data) { + data = new Draggable($this, options); + $this.data('draggable', data); + } + }); + } + + $(function () { + //TODO: support unbind + $(document).on("mousemove touchmove mouseup touchend", function (e) { + if (!draggable) return; + switch (e.type) { + case "mousemove": + case "touchmove": + draggable.setPosition(e); + break; + case "mouseup": + case "touchend": + draggable.stop(e); + break; + } + + e.preventDefault(); + e.stopPropagation(); + }); + }); + +})(Zepto); + +/** + * zepto.dragdrop.js v0.1.1 - Drag & Drop for Zepto with touch and mouse events. + * + * Copyright 2012, Michal Kuklis + * Dual licensed under the MIT or GPL Version 2 licenses. + * + **/ + +(function ($) { + + "use strict"; + + function Droppable(el, opts) { + this.el = el; + this.opts = opts || {}; + this.ctx = this.opts.context || this.el; + } + + Droppable.prototype.drop = function (e, pos) { + var isDrop = true; + var dragEl = $(e.el); + + if (this.opts.drop) { + isDrop &= this.opts.drop.call(this.ctx, e, dragEl, this.el, pos); + } + + isDrop && this.el.trigger('droppable:drop', [e, dragEl, this.el, pos]); + + // only revert if element was not dropped + if (!isDrop && dragEl.data('revert')) { + this.revert(dragEl); + } + }; + + Droppable.prototype.revert = function (dragEl) { + var left = dragEl.data('rleft'); + var top = dragEl.data('rtop'); + var rev = dragEl.data('revert'); + + if ($.isFunction(rev)) { + rev.call(dragEl); + } + + dragEl.css({ left: left, top: top }); + }; + + + // helpers + function dropOrRevert(e) { + var droppable, pos; + var dragEl = e.el; + + if (dragEl) { + pos = $.getPos(e); + droppable = findDroppable(e, pos); + if (droppable) { + droppable.drop(e, pos); + } + else if (dragEl.data('revert')){ + Droppable.prototype.revert(dragEl); + } + } + + e.preventDefault(); + e.stopPropagation(); + } + + function findDroppable(e, pos) { + var droppable, dropEl; + var dragEl = e.el; + + dragEl.css({ display: 'none' }); + dropEl = $.elementFromPoint(pos.x, pos.y); + dragEl.css({ display: 'block' }); + return $(dropEl).data('droppable'); + } + + // droppable api + $.fn.droppable = function (options) { + return this.each(function () { + var $this = $(this); + var droppable = $this.data('droppable'); + if (!droppable) { + droppable = new Droppable($this, options); + $this.data('droppable', droppable); + } + }); + }; + + // bind mouse/touch event + $(function () { + $(document).on("mouseup touchend", dropOrRevert); + }); + +})(Zepto); + +// Zepto.js +// (c) 2010-2012 Thomas Fuchs +// Zepto.js may be freely distributed under the MIT license. + +// The following code is heavily inspired by jQuery's $.fn.data() + +;(function($) { + var data = {}, dataAttr = $.fn.data, camelize = $.zepto.camelize, + exp = $.expando = 'Zepto' + (+new Date()) + + // Get value from node: + // 1. first try key as given, + // 2. then try camelized key, + // 3. fall back to reading "data-*" attribute. + function getData(node, name) { + var id = node[exp], store = id && data[id] + if (name === undefined) return store || setData(node) + else { + if (store) { + if (name in store) return store[name] + var camelName = camelize(name) + if (camelName in store) return store[camelName] + } + return dataAttr.call($(node), name) + } + } + + // Store value under camelized key on node + function setData(node, name, value) { + var id = node[exp] || (node[exp] = ++$.uuid), + store = data[id] || (data[id] = attributeData(node)) + if (name !== undefined) store[camelize(name)] = value + return store + } + + // Read all "data-*" attributes from a node + function attributeData(node) { + var store = {} + $.each(node.attributes, function(i, attr){ + if (attr.name.indexOf('data-') === 0) + store[camelize(attr.name.replace('data-', ''))] = attr.value + }) + return store + } + + $.fn.data = function(name, value) { + return value === undefined ? + // set multiple values via object + $.isPlainObject(name) ? + this.each(function(i, node){ + $.each(name, function(key, value){ setData(node, key, value) }) + }) : + // get value from first element + this.length === 0 ? undefined : getData(this[0], name) : + // set value on all elements + this.each(function(){ setData(this, name, value) }) + } + + $.fn.removeData = function(names) { + if (typeof names == 'string') names = names.split(/\s+/) + return this.each(function(){ + var id = this[exp], store = id && data[id] + if (store) $.each(names, function(){ delete store[camelize(this)] }) + }) + } +})(Zepto); + +(function ($) { + + "use strict"; + + // for testing + var phantom = navigator.userAgent.match(/PhantomJS/); + + $.touchable = (function () { + // http://modernizr.github.com/Modernizr/touch.html + return !!('ontouchstart' in window) && !phantom + })(); + + // helpers + $.getPos = function (e) { + var pos = {}, touch; + + if ($.touchable) { + touch = (e.targetTouches.length) ? e.targetTouches[0] : e.changedTouches[0]; + pos = { x: touch.pageX, y: touch.pageY }; + } + else { + pos = { x: e.pageX, y: e.pageY }; + } + + return pos; + } + + var doc = document; + + $.elementFromPoint = function (x, y) { + var moved = false; + var yo = window.pageYOffset; + var xo = window.pageXOffset; + var h = window.innerHeight; + var w = window.innerWidth; + + if (yo > 0) { + moved = (!doc.elementFromPoint(0, yo + h - 1)); + } else if (xo > 0) { + moved = (!doc.elementFromPoint(xo + w - 1, 0)); + } + + return (moved) ? + doc.elementFromPoint(x - xo, y - yo) : + doc.elementFromPoint(x, y); + } + + // https://gist.github.com/997619 + window.requestAnimationFrame = function(a,b){while(a--&&!(b=window["oR0msR0mozR0webkitR0r".split(0)[a]+"equestAnimationFrame"]));return b||function(a){setTimeout(a,15)}}(5); + +})(Zepto); diff --git a/zepto.js b/zepto.js new file mode 100644 index 0000000..9bae7a7 --- /dev/null +++ b/zepto.js @@ -0,0 +1,1422 @@ +/* Zepto v1.0rc1 - polyfill zepto event detect fx ajax form touch - zeptojs.com/license */ +;(function(undefined){ + if (String.prototype.trim === undefined) // fix for iOS 3.2 + String.prototype.trim = function(){ return this.replace(/^\s+/, '').replace(/\s+$/, '') } + + // For iOS 3.x + // from https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/reduce + if (Array.prototype.reduce === undefined) + Array.prototype.reduce = function(fun){ + if(this === void 0 || this === null) throw new TypeError() + var t = Object(this), len = t.length >>> 0, k = 0, accumulator + if(typeof fun != 'function') throw new TypeError() + if(len == 0 && arguments.length == 1) throw new TypeError() + + if(arguments.length >= 2) + accumulator = arguments[1] + else + do{ + if(k in t){ + accumulator = t[k++] + break + } + if(++k >= len) throw new TypeError() + } while (true) + + while (k < len){ + if(k in t) accumulator = fun.call(undefined, accumulator, t[k], k, t) + k++ + } + return accumulator + } + +})() +var Zepto = (function() { + var undefined, key, $, classList, emptyArray = [], slice = emptyArray.slice, + document = window.document, + elementDisplay = {}, classCache = {}, + getComputedStyle = document.defaultView.getComputedStyle, + cssNumber = { 'column-count': 1, 'columns': 1, 'font-weight': 1, 'line-height': 1,'opacity': 1, 'z-index': 1, 'zoom': 1 }, + fragmentRE = /^\s*<(\w+|!)[^>]*>/, + + // Used by `$.zepto.init` to wrap elements, text/comment nodes, document, + // and document fragment node types. + elementTypes = [1, 3, 8, 9, 11], + + adjacencyOperators = [ 'after', 'prepend', 'before', 'append' ], + table = document.createElement('table'), + tableRow = document.createElement('tr'), + containers = { + 'tr': document.createElement('tbody'), + 'tbody': table, 'thead': table, 'tfoot': table, + 'td': tableRow, 'th': tableRow, + '*': document.createElement('div') + }, + readyRE = /complete|loaded|interactive/, + classSelectorRE = /^\.([\w-]+)$/, + idSelectorRE = /^#([\w-]+)$/, + tagSelectorRE = /^[\w-]+$/, + toString = ({}).toString, + zepto = {}, + camelize, uniq, + tempParent = document.createElement('div') + + zepto.matches = function(element, selector) { + if (!element || element.nodeType !== 1) return false + var matchesSelector = element.webkitMatchesSelector || element.mozMatchesSelector || + element.oMatchesSelector || element.matchesSelector + if (matchesSelector) return matchesSelector.call(element, selector) + // fall back to performing a selector: + var match, parent = element.parentNode, temp = !parent + if (temp) (parent = tempParent).appendChild(element) + match = ~zepto.qsa(parent, selector).indexOf(element) + temp && tempParent.removeChild(element) + return match + } + + function isFunction(value) { return toString.call(value) == "[object Function]" } + function isObject(value) { return value instanceof Object } + function isPlainObject(value) { + var key, ctor + if (toString.call(value) !== "[object Object]") return false + ctor = (isFunction(value.constructor) && value.constructor.prototype) + if (!ctor || !hasOwnProperty.call(ctor, 'isPrototypeOf')) return false + for (key in value); + return key === undefined || hasOwnProperty.call(value, key) + } + function isArray(value) { return value instanceof Array } + function likeArray(obj) { return typeof obj.length == 'number' } + + function compact(array) { return array.filter(function(item){ return item !== undefined && item !== null }) } + function flatten(array) { return array.length > 0 ? [].concat.apply([], array) : array } + camelize = function(str){ return str.replace(/-+(.)?/g, function(match, chr){ return chr ? chr.toUpperCase() : '' }) } + function dasherize(str) { + return str.replace(/::/g, '/') + .replace(/([A-Z]+)([A-Z][a-z])/g, '$1_$2') + .replace(/([a-z\d])([A-Z])/g, '$1_$2') + .replace(/_/g, '-') + .toLowerCase() + } + uniq = function(array){ return array.filter(function(item, idx){ return array.indexOf(item) == idx }) } + + function classRE(name) { + return name in classCache ? + classCache[name] : (classCache[name] = new RegExp('(^|\\s)' + name + '(\\s|$)')) + } + + function maybeAddPx(name, value) { + return (typeof value == "number" && !cssNumber[dasherize(name)]) ? value + "px" : value + } + + function defaultDisplay(nodeName) { + var element, display + if (!elementDisplay[nodeName]) { + element = document.createElement(nodeName) + document.body.appendChild(element) + display = getComputedStyle(element, '').getPropertyValue("display") + element.parentNode.removeChild(element) + display == "none" && (display = "block") + elementDisplay[nodeName] = display + } + return elementDisplay[nodeName] + } + + // `$.zepto.fragment` takes a html string and an optional tag name + // to generate DOM nodes nodes from the given html string. + // The generated DOM nodes are returned as an array. + // This function can be overriden in plugins for example to make + // it compatible with browsers that don't support the DOM fully. + zepto.fragment = function(html, name) { + if (name === undefined) name = fragmentRE.test(html) && RegExp.$1 + if (!(name in containers)) name = '*' + var container = containers[name] + container.innerHTML = '' + html + return $.each(slice.call(container.childNodes), function(){ + container.removeChild(this) + }) + } + + // `$.zepto.Z` swaps out the prototype of the given `dom` array + // of nodes with `$.fn` and thus supplying all the Zepto functions + // to the array. Note that `__proto__` is not supported on Internet + // Explorer. This method can be overriden in plugins. + zepto.Z = function(dom, selector) { + dom = dom || [] + dom.__proto__ = arguments.callee.prototype + dom.selector = selector || '' + return dom + } + + // `$.zepto.isZ` should return `true` if the given object is a Zepto + // collection. This method can be overriden in plugins. + zepto.isZ = function(object) { + return object instanceof zepto.Z + } + + // `$.zepto.init` is Zepto's counterpart to jQuery's `$.fn.init` and + // takes a CSS selector and an optional context (and handles various + // special cases). + // This method can be overriden in plugins. + zepto.init = function(selector, context) { + // If nothing given, return an empty Zepto collection + if (!selector) return zepto.Z() + // If a function is given, call it when the DOM is ready + else if (isFunction(selector)) return $(document).ready(selector) + // If a Zepto collection is given, juts return it + else if (zepto.isZ(selector)) return selector + else { + var dom + // normalize array if an array of nodes is given + if (isArray(selector)) dom = compact(selector) + // if a JavaScript object is given, return a copy of it + // this is a somewhat peculiar option, but supported by + // jQuery so we'll do it, too + else if (isPlainObject(selector)) + dom = [$.extend({}, selector)], selector = null + // wrap stuff like `document` or `window` + else if (elementTypes.indexOf(selector.nodeType) >= 0 || selector === window) + dom = [selector], selector = null + // If it's a html fragment, create nodes from it + else if (fragmentRE.test(selector)) + dom = zepto.fragment(selector.trim(), RegExp.$1), selector = null + // If there's a context, create a collection on that context first, and select + // nodes from there + else if (context !== undefined) return $(context).find(selector) + // And last but no least, if it's a CSS selector, use it to select nodes. + else dom = zepto.qsa(document, selector) + // create a new Zepto collection from the nodes found + return zepto.Z(dom, selector) + } + } + + // `$` will be the base `Zepto` object. When calling this + // function just call `$.zepto.init, whichs makes the implementation + // details of selecting nodes and creating Zepto collections + // patchable in plugins. + $ = function(selector, context){ + return zepto.init(selector, context) + } + + // Copy all but undefined properties from one or more + // objects to the `target` object. + $.extend = function(target){ + slice.call(arguments, 1).forEach(function(source) { + for (key in source) + if (source[key] !== undefined) + target[key] = source[key] + }) + return target + } + + // `$.zepto.qsa` is Zepto's CSS selector implementation which + // uses `document.querySelectorAll` and optimizes for some special cases, like `#id`. + // This method can be overriden in plugins. + zepto.qsa = function(element, selector){ + var found + return (element === document && idSelectorRE.test(selector)) ? + ( (found = element.getElementById(RegExp.$1)) ? [found] : emptyArray ) : + (element.nodeType !== 1 && element.nodeType !== 9) ? emptyArray : + slice.call( + classSelectorRE.test(selector) ? element.getElementsByClassName(RegExp.$1) : + tagSelectorRE.test(selector) ? element.getElementsByTagName(selector) : + element.querySelectorAll(selector) + ) + } + + function filtered(nodes, selector) { + return selector === undefined ? $(nodes) : $(nodes).filter(selector) + } + + function funcArg(context, arg, idx, payload) { + return isFunction(arg) ? arg.call(context, idx, payload) : arg + } + + $.isFunction = isFunction + $.isObject = isObject + $.isArray = isArray + $.isPlainObject = isPlainObject + + $.inArray = function(elem, array, i){ + return emptyArray.indexOf.call(array, elem, i) + } + + $.trim = function(str) { return str.trim() } + + // plugin compatibility + $.uuid = 0 + + $.map = function(elements, callback){ + var value, values = [], i, key + if (likeArray(elements)) + for (i = 0; i < elements.length; i++) { + value = callback(elements[i], i) + if (value != null) values.push(value) + } + else + for (key in elements) { + value = callback(elements[key], key) + if (value != null) values.push(value) + } + return flatten(values) + } + + $.each = function(elements, callback){ + var i, key + if (likeArray(elements)) { + for (i = 0; i < elements.length; i++) + if (callback.call(elements[i], i, elements[i]) === false) return elements + } else { + for (key in elements) + if (callback.call(elements[key], key, elements[key]) === false) return elements + } + + return elements + } + + // Define methods that will be available on all + // Zepto collections + $.fn = { + // Because a collection acts like an array + // copy over these useful array functions. + forEach: emptyArray.forEach, + reduce: emptyArray.reduce, + push: emptyArray.push, + indexOf: emptyArray.indexOf, + concat: emptyArray.concat, + + // `map` and `slice` in the jQuery API work differently + // from their array counterparts + map: function(fn){ + return $.map(this, function(el, i){ return fn.call(el, i, el) }) + }, + slice: function(){ + return $(slice.apply(this, arguments)) + }, + + ready: function(callback){ + if (readyRE.test(document.readyState)) callback($) + else document.addEventListener('DOMContentLoaded', function(){ callback($) }, false) + return this + }, + get: function(idx){ + return idx === undefined ? slice.call(this) : this[idx] + }, + toArray: function(){ return this.get() }, + size: function(){ + return this.length + }, + remove: function(){ + return this.each(function(){ + if (this.parentNode != null) + this.parentNode.removeChild(this) + }) + }, + each: function(callback){ + this.forEach(function(el, idx){ callback.call(el, idx, el) }) + return this + }, + filter: function(selector){ + return $([].filter.call(this, function(element){ + return zepto.matches(element, selector) + })) + }, + add: function(selector,context){ + return $(uniq(this.concat($(selector,context)))) + }, + is: function(selector){ + return this.length > 0 && zepto.matches(this[0], selector) + }, + not: function(selector){ + var nodes=[] + if (isFunction(selector) && selector.call !== undefined) + this.each(function(idx){ + if (!selector.call(this,idx)) nodes.push(this) + }) + else { + var excludes = typeof selector == 'string' ? this.filter(selector) : + (likeArray(selector) && isFunction(selector.item)) ? slice.call(selector) : $(selector) + this.forEach(function(el){ + if (excludes.indexOf(el) < 0) nodes.push(el) + }) + } + return $(nodes) + }, + eq: function(idx){ + return idx === -1 ? this.slice(idx) : this.slice(idx, + idx + 1) + }, + first: function(){ + var el = this[0] + return el && !isObject(el) ? el : $(el) + }, + last: function(){ + var el = this[this.length - 1] + return el && !isObject(el) ? el : $(el) + }, + find: function(selector){ + var result + if (this.length == 1) result = zepto.qsa(this[0], selector) + else result = this.map(function(){ return zepto.qsa(this, selector) }) + return $(result) + }, + closest: function(selector, context){ + var node = this[0] + while (node && !zepto.matches(node, selector)) + node = node !== context && node !== document && node.parentNode + return $(node) + }, + parents: function(selector){ + var ancestors = [], nodes = this + while (nodes.length > 0) + nodes = $.map(nodes, function(node){ + if ((node = node.parentNode) && node !== document && ancestors.indexOf(node) < 0) { + ancestors.push(node) + return node + } + }) + return filtered(ancestors, selector) + }, + parent: function(selector){ + return filtered(uniq(this.pluck('parentNode')), selector) + }, + children: function(selector){ + return filtered(this.map(function(){ return slice.call(this.children) }), selector) + }, + siblings: function(selector){ + return filtered(this.map(function(i, el){ + return slice.call(el.parentNode.children).filter(function(child){ return child!==el }) + }), selector) + }, + empty: function(){ + return this.each(function(){ this.innerHTML = '' }) + }, + // `pluck` is borrowed from Prototype.js + pluck: function(property){ + return this.map(function(){ return this[property] }) + }, + show: function(){ + return this.each(function(){ + this.style.display == "none" && (this.style.display = null) + if (getComputedStyle(this, '').getPropertyValue("display") == "none") + this.style.display = defaultDisplay(this.nodeName) + }) + }, + replaceWith: function(newContent){ + return this.before(newContent).remove() + }, + wrap: function(newContent){ + return this.each(function(){ + $(this).wrapAll($(newContent)[0].cloneNode(false)) + }) + }, + wrapAll: function(newContent){ + if (this[0]) { + $(this[0]).before(newContent = $(newContent)) + newContent.append(this) + } + return this + }, + unwrap: function(){ + this.parent().each(function(){ + $(this).replaceWith($(this).children()) + }) + return this + }, + clone: function(){ + return $(this.map(function(){ return this.cloneNode(true) })) + }, + hide: function(){ + return this.css("display", "none") + }, + toggle: function(setting){ + return (setting === undefined ? this.css("display") == "none" : setting) ? this.show() : this.hide() + }, + prev: function(){ return $(this.pluck('previousElementSibling')) }, + next: function(){ return $(this.pluck('nextElementSibling')) }, + html: function(html){ + return html === undefined ? + (this.length > 0 ? this[0].innerHTML : null) : + this.each(function(idx){ + var originHtml = this.innerHTML + $(this).empty().append( funcArg(this, html, idx, originHtml) ) + }) + }, + text: function(text){ + return text === undefined ? + (this.length > 0 ? this[0].textContent : null) : + this.each(function(){ this.textContent = text }) + }, + attr: function(name, value){ + var result + return (typeof name == 'string' && value === undefined) ? + (this.length == 0 || this[0].nodeType !== 1 ? undefined : + (name == 'value' && this[0].nodeName == 'INPUT') ? this.val() : + (!(result = this[0].getAttribute(name)) && name in this[0]) ? this[0][name] : result + ) : + this.each(function(idx){ + if (this.nodeType !== 1) return + if (isObject(name)) for (key in name) this.setAttribute(key, name[key]) + else this.setAttribute(name, funcArg(this, value, idx, this.getAttribute(name))) + }) + }, + removeAttr: function(name){ + return this.each(function(){ if (this.nodeType === 1) this.removeAttribute(name) }) + }, + prop: function(name, value){ + return (value === undefined) ? + (this[0] ? this[0][name] : undefined) : + this.each(function(idx){ + this[name] = funcArg(this, value, idx, this[name]) + }) + }, + data: function(name, value){ + var data = this.attr('data-' + dasherize(name), value) + return data !== null ? data : undefined + }, + val: function(value){ + return (value === undefined) ? + (this.length > 0 ? this[0].value : undefined) : + this.each(function(idx){ + this.value = funcArg(this, value, idx, this.value) + }) + }, + offset: function(){ + if (this.length==0) return null + var obj = this[0].getBoundingClientRect() + return { + left: obj.left + window.pageXOffset, + top: obj.top + window.pageYOffset, + width: obj.width, + height: obj.height + } + }, + css: function(property, value){ + if (value === undefined && typeof property == 'string') + return ( + this.length == 0 + ? undefined + : this[0].style[camelize(property)] || getComputedStyle(this[0], '').getPropertyValue(property)) + + var css = '' + for (key in property) + if(typeof property[key] == 'string' && property[key] == '') + this.each(function(){ this.style.removeProperty(dasherize(key)) }) + else + css += dasherize(key) + ':' + maybeAddPx(key, property[key]) + ';' + + if (typeof property == 'string') + if (value == '') + this.each(function(){ this.style.removeProperty(dasherize(property)) }) + else + css = dasherize(property) + ":" + maybeAddPx(property, value) + + return this.each(function(){ this.style.cssText += ';' + css }) + }, + index: function(element){ + return element ? this.indexOf($(element)[0]) : this.parent().children().indexOf(this[0]) + }, + hasClass: function(name){ + if (this.length < 1) return false + else return classRE(name).test(this[0].className) + }, + addClass: function(name){ + return this.each(function(idx){ + classList = [] + var cls = this.className, newName = funcArg(this, name, idx, cls) + newName.split(/\s+/g).forEach(function(klass){ + if (!$(this).hasClass(klass)) classList.push(klass) + }, this) + classList.length && (this.className += (cls ? " " : "") + classList.join(" ")) + }) + }, + removeClass: function(name){ + return this.each(function(idx){ + if (name === undefined) + return this.className = '' + classList = this.className + funcArg(this, name, idx, classList).split(/\s+/g).forEach(function(klass){ + classList = classList.replace(classRE(klass), " ") + }) + this.className = classList.trim() + }) + }, + toggleClass: function(name, when){ + return this.each(function(idx){ + var newName = funcArg(this, name, idx, this.className) + ;(when === undefined ? !$(this).hasClass(newName) : when) ? + $(this).addClass(newName) : $(this).removeClass(newName) + }) + } + } + + // Generate the `width` and `height` functions + ;['width', 'height'].forEach(function(dimension){ + $.fn[dimension] = function(value){ + var offset, Dimension = dimension.replace(/./, function(m){ return m[0].toUpperCase() }) + if (value === undefined) return this[0] == window ? window['inner' + Dimension] : + this[0] == document ? document.documentElement['offset' + Dimension] : + (offset = this.offset()) && offset[dimension] + else return this.each(function(idx){ + var el = $(this) + el.css(dimension, funcArg(this, value, idx, el[dimension]())) + }) + } + }) + + function insert(operator, target, node) { + var parent = (operator % 2) ? target : target.parentNode + parent ? parent.insertBefore(node, + !operator ? target.nextSibling : // after + operator == 1 ? parent.firstChild : // prepend + operator == 2 ? target : // before + null) : // append + $(node).remove() + } + + function traverseNode(node, fun) { + fun(node) + for (var key in node.childNodes) traverseNode(node.childNodes[key], fun) + } + + // Generate the `after`, `prepend`, `before`, `append`, + // `insertAfter`, `insertBefore`, `appendTo`, and `prependTo` methods. + adjacencyOperators.forEach(function(key, operator) { + $.fn[key] = function(){ + // arguments can be nodes, arrays of nodes, Zepto objects and HTML strings + var nodes = $.map(arguments, function(n){ return isObject(n) ? n : zepto.fragment(n) }) + if (nodes.length < 1) return this + var size = this.length, copyByClone = size > 1, inReverse = operator < 2 + + return this.each(function(index, target){ + for (var i = 0; i < nodes.length; i++) { + var node = nodes[inReverse ? nodes.length-i-1 : i] + traverseNode(node, function(node){ + if (node.nodeName != null && node.nodeName.toUpperCase() === 'SCRIPT' && (!node.type || node.type === 'text/javascript')) + window['eval'].call(window, node.innerHTML) + }) + if (copyByClone && index < size - 1) node = node.cloneNode(true) + insert(operator, target, node) + } + }) + } + + $.fn[(operator % 2) ? key+'To' : 'insert'+(operator ? 'Before' : 'After')] = function(html){ + $(html)[key](this) + return this + } + }) + + zepto.Z.prototype = $.fn + + // Export internal API functions in the `$.zepto` namespace + zepto.camelize = camelize + zepto.uniq = uniq + $.zepto = zepto + + return $ +})() + +// If `$` is not yet defined, point it to `Zepto` +window.Zepto = Zepto +'$' in window || (window.$ = Zepto) +;(function($){ + var $$ = $.zepto.qsa, handlers = {}, _zid = 1, specialEvents={} + + specialEvents.click = specialEvents.mousedown = specialEvents.mouseup = specialEvents.mousemove = 'MouseEvents' + + function zid(element) { + return element._zid || (element._zid = _zid++) + } + function findHandlers(element, event, fn, selector) { + event = parse(event) + if (event.ns) var matcher = matcherFor(event.ns) + return (handlers[zid(element)] || []).filter(function(handler) { + return handler + && (!event.e || handler.e == event.e) + && (!event.ns || matcher.test(handler.ns)) + && (!fn || zid(handler.fn) === zid(fn)) + && (!selector || handler.sel == selector) + }) + } + function parse(event) { + var parts = ('' + event).split('.') + return {e: parts[0], ns: parts.slice(1).sort().join(' ')} + } + function matcherFor(ns) { + return new RegExp('(?:^| )' + ns.replace(' ', ' .* ?') + '(?: |$)') + } + + function eachEvent(events, fn, iterator){ + if ($.isObject(events)) $.each(events, iterator) + else events.split(/\s/).forEach(function(type){ iterator(type, fn) }) + } + + function add(element, events, fn, selector, getDelegate, capture){ + capture = !!capture + var id = zid(element), set = (handlers[id] || (handlers[id] = [])) + eachEvent(events, fn, function(event, fn){ + var delegate = getDelegate && getDelegate(fn, event), + callback = delegate || fn + var proxyfn = function (event) { + var result = callback.apply(element, [event].concat(event.data)) + if (result === false) event.preventDefault() + return result + } + var handler = $.extend(parse(event), {fn: fn, proxy: proxyfn, sel: selector, del: delegate, i: set.length}) + set.push(handler) + element.addEventListener(handler.e, proxyfn, capture) + }) + } + function remove(element, events, fn, selector){ + var id = zid(element) + eachEvent(events || '', fn, function(event, fn){ + findHandlers(element, event, fn, selector).forEach(function(handler){ + delete handlers[id][handler.i] + element.removeEventListener(handler.e, handler.proxy, false) + }) + }) + } + + $.event = { add: add, remove: remove } + + $.proxy = function(fn, context) { + if ($.isFunction(fn)) { + var proxyFn = function(){ return fn.apply(context, arguments) } + proxyFn._zid = zid(fn) + return proxyFn + } else if (typeof context == 'string') { + return $.proxy(fn[context], fn) + } else { + throw new TypeError("expected function") + } + } + + $.fn.bind = function(event, callback){ + return this.each(function(){ + add(this, event, callback) + }) + } + $.fn.unbind = function(event, callback){ + return this.each(function(){ + remove(this, event, callback) + }) + } + $.fn.one = function(event, callback){ + return this.each(function(i, element){ + add(this, event, callback, null, function(fn, type){ + return function(){ + var result = fn.apply(element, arguments) + remove(element, type, fn) + return result + } + }) + }) + } + + var returnTrue = function(){return true}, + returnFalse = function(){return false}, + eventMethods = { + preventDefault: 'isDefaultPrevented', + stopImmediatePropagation: 'isImmediatePropagationStopped', + stopPropagation: 'isPropagationStopped' + } + function createProxy(event) { + var proxy = $.extend({originalEvent: event}, event) + $.each(eventMethods, function(name, predicate) { + proxy[name] = function(){ + this[predicate] = returnTrue + return event[name].apply(event, arguments) + } + proxy[predicate] = returnFalse + }) + return proxy + } + + // emulates the 'defaultPrevented' property for browsers that have none + function fix(event) { + if (!('defaultPrevented' in event)) { + event.defaultPrevented = false + var prevent = event.preventDefault + event.preventDefault = function() { + this.defaultPrevented = true + prevent.call(this) + } + } + } + + $.fn.delegate = function(selector, event, callback){ + var capture = false + if(event == 'blur' || event == 'focus'){ + if($.iswebkit) + event = event == 'blur' ? 'focusout' : event == 'focus' ? 'focusin' : event + else + capture = true + } + + return this.each(function(i, element){ + add(element, event, callback, selector, function(fn){ + return function(e){ + var evt, match = $(e.target).closest(selector, element).get(0) + if (match) { + evt = $.extend(createProxy(e), {currentTarget: match, liveFired: element}) + return fn.apply(match, [evt].concat([].slice.call(arguments, 1))) + } + } + }, capture) + }) + } + $.fn.undelegate = function(selector, event, callback){ + return this.each(function(){ + remove(this, event, callback, selector) + }) + } + + $.fn.live = function(event, callback){ + $(document.body).delegate(this.selector, event, callback) + return this + } + $.fn.die = function(event, callback){ + $(document.body).undelegate(this.selector, event, callback) + return this + } + + $.fn.on = function(event, selector, callback){ + return selector == undefined || $.isFunction(selector) ? + this.bind(event, selector) : this.delegate(selector, event, callback) + } + $.fn.off = function(event, selector, callback){ + return selector == undefined || $.isFunction(selector) ? + this.unbind(event, selector) : this.undelegate(selector, event, callback) + } + + $.fn.trigger = function(event, data){ + if (typeof event == 'string') event = $.Event(event) + fix(event) + event.data = data + return this.each(function(){ + // items in the collection might not be DOM elements + // (todo: possibly support events on plain old objects) + if('dispatchEvent' in this) this.dispatchEvent(event) + }) + } + + // triggers event handlers on current element just as if an event occurred, + // doesn't trigger an actual event, doesn't bubble + $.fn.triggerHandler = function(event, data){ + var e, result + this.each(function(i, element){ + e = createProxy(typeof event == 'string' ? $.Event(event) : event) + e.data = data + e.target = element + $.each(findHandlers(element, event.type || event), function(i, handler){ + result = handler.proxy(e) + if (e.isImmediatePropagationStopped()) return false + }) + }) + return result + } + + // shortcut methods for `.bind(event, fn)` for each event type + ;('focusin focusout load resize scroll unload click dblclick '+ + 'mousedown mouseup mousemove mouseover mouseout '+ + 'change select keydown keypress keyup error').split(' ').forEach(function(event) { + $.fn[event] = function(callback){ return this.bind(event, callback) } + }) + + ;['focus', 'blur'].forEach(function(name) { + $.fn[name] = function(callback) { + if (callback) this.bind(name, callback) + else if (this.length) try { this.get(0)[name]() } catch(e){} + return this + } + }) + + $.Event = function(type, props) { + var event = document.createEvent(specialEvents[type] || 'Events'), bubbles = true + if (props) for (var name in props) (name == 'bubbles') ? (bubbles = !!props[name]) : (event[name] = props[name]) + event.initEvent(type, bubbles, true, null, null, null, null, null, null, null, null, null, null, null, null) + return event + } + +})(Zepto) +;(function($){ + function detect(ua){ + var os = this.os = {}, browser = this.browser = {}, + webkit = ua.match(/WebKit\/([\d.]+)/), + android = ua.match(/(Android)\s+([\d.]+)/), + ipad = ua.match(/(iPad).*OS\s([\d_]+)/), + iphone = !ipad && ua.match(/(iPhone\sOS)\s([\d_]+)/), + webos = ua.match(/(webOS|hpwOS)[\s\/]([\d.]+)/), + touchpad = webos && ua.match(/TouchPad/), + kindle = ua.match(/Kindle\/([\d.]+)/), + silk = ua.match(/Silk\/([\d._]+)/), + blackberry = ua.match(/(BlackBerry).*Version\/([\d.]+)/) + + // todo clean this up with a better OS/browser + // separation. we need to discern between multiple + // browsers on android, and decide if kindle fire in + // silk mode is android or not + + if (browser.webkit = !!webkit) browser.version = webkit[1] + + if (android) os.android = true, os.version = android[2] + if (iphone) os.ios = os.iphone = true, os.version = iphone[2].replace(/_/g, '.') + if (ipad) os.ios = os.ipad = true, os.version = ipad[2].replace(/_/g, '.') + if (webos) os.webos = true, os.version = webos[2] + if (touchpad) os.touchpad = true + if (blackberry) os.blackberry = true, os.version = blackberry[2] + if (kindle) os.kindle = true, os.version = kindle[1] + if (silk) browser.silk = true, browser.version = silk[1] + if (!silk && os.android && ua.match(/Kindle Fire/)) browser.silk = true + } + + detect.call($, navigator.userAgent) + // make available to unit tests + $.__detect = detect + +})(Zepto) +;(function($, undefined){ + var prefix = '', eventPrefix, endEventName, endAnimationName, + vendors = { Webkit: 'webkit', Moz: '', O: 'o', ms: 'MS' }, + document = window.document, testEl = document.createElement('div'), + supportedTransforms = /^((translate|rotate|scale)(X|Y|Z|3d)?|matrix(3d)?|perspective|skew(X|Y)?)$/i, + clearProperties = {} + + function downcase(str) { return str.toLowerCase() } + function normalizeEvent(name) { return eventPrefix ? eventPrefix + name : downcase(name) } + + $.each(vendors, function(vendor, event){ + if (testEl.style[vendor + 'TransitionProperty'] !== undefined) { + prefix = '-' + downcase(vendor) + '-' + eventPrefix = event + return false + } + }) + + clearProperties[prefix + 'transition-property'] = + clearProperties[prefix + 'transition-duration'] = + clearProperties[prefix + 'transition-timing-function'] = + clearProperties[prefix + 'animation-name'] = + clearProperties[prefix + 'animation-duration'] = '' + + $.fx = { + off: (eventPrefix === undefined && testEl.style.transitionProperty === undefined), + cssPrefix: prefix, + transitionEnd: normalizeEvent('TransitionEnd'), + animationEnd: normalizeEvent('AnimationEnd') + } + + $.fn.animate = function(properties, duration, ease, callback){ + if ($.isObject(duration)) + ease = duration.easing, callback = duration.complete, duration = duration.duration + if (duration) duration = duration / 1000 + return this.anim(properties, duration, ease, callback) + } + + $.fn.anim = function(properties, duration, ease, callback){ + var transforms, cssProperties = {}, key, that = this, wrappedCallback, endEvent = $.fx.transitionEnd + if (duration === undefined) duration = 0.4 + if ($.fx.off) duration = 0 + + if (typeof properties == 'string') { + // keyframe animation + cssProperties[prefix + 'animation-name'] = properties + cssProperties[prefix + 'animation-duration'] = duration + 's' + endEvent = $.fx.animationEnd + } else { + // CSS transitions + for (key in properties) + if (supportedTransforms.test(key)) { + transforms || (transforms = []) + transforms.push(key + '(' + properties[key] + ')') + } + else cssProperties[key] = properties[key] + + if (transforms) cssProperties[prefix + 'transform'] = transforms.join(' ') + if (!$.fx.off && typeof properties === 'object') { + cssProperties[prefix + 'transition-property'] = Object.keys(properties).join(', ') + cssProperties[prefix + 'transition-duration'] = duration + 's' + cssProperties[prefix + 'transition-timing-function'] = (ease || 'linear') + } + } + + wrappedCallback = function(event){ + if (typeof event !== 'undefined') { + if (event.target !== event.currentTarget) return // makes sure the event didn't bubble from "below" + $(event.target).unbind(endEvent, arguments.callee) + } + $(this).css(clearProperties) + callback && callback.call(this) + } + if (duration > 0) this.bind(endEvent, wrappedCallback) + + setTimeout(function() { + that.css(cssProperties) + if (duration <= 0) setTimeout(function() { + that.each(function(){ wrappedCallback.call(this) }) + }, 0) + }, 0) + + return this + } + + testEl = null +})(Zepto) +;(function($){ + var jsonpID = 0, + isObject = $.isObject, + document = window.document, + key, + name, + rscript = /)<[^<]*)*<\/script>/gi, + scriptTypeRE = /^(?:text|application)\/javascript/i, + xmlTypeRE = /^(?:text|application)\/xml/i, + jsonType = 'application/json', + htmlType = 'text/html', + blankRE = /^\s*$/ + + // trigger a custom event and return false if it was cancelled + function triggerAndReturn(context, eventName, data) { + var event = $.Event(eventName) + $(context).trigger(event, data) + return !event.defaultPrevented + } + + // trigger an Ajax "global" event + function triggerGlobal(settings, context, eventName, data) { + if (settings.global) return triggerAndReturn(context || document, eventName, data) + } + + // Number of active Ajax requests + $.active = 0 + + function ajaxStart(settings) { + if (settings.global && $.active++ === 0) triggerGlobal(settings, null, 'ajaxStart') + } + function ajaxStop(settings) { + if (settings.global && !(--$.active)) triggerGlobal(settings, null, 'ajaxStop') + } + + // triggers an extra global event "ajaxBeforeSend" that's like "ajaxSend" but cancelable + function ajaxBeforeSend(xhr, settings) { + var context = settings.context + if (settings.beforeSend.call(context, xhr, settings) === false || + triggerGlobal(settings, context, 'ajaxBeforeSend', [xhr, settings]) === false) + return false + + triggerGlobal(settings, context, 'ajaxSend', [xhr, settings]) + } + function ajaxSuccess(data, xhr, settings) { + var context = settings.context, status = 'success' + settings.success.call(context, data, status, xhr) + triggerGlobal(settings, context, 'ajaxSuccess', [xhr, settings, data]) + ajaxComplete(status, xhr, settings) + } + // type: "timeout", "error", "abort", "parsererror" + function ajaxError(error, type, xhr, settings) { + var context = settings.context + settings.error.call(context, xhr, type, error) + triggerGlobal(settings, context, 'ajaxError', [xhr, settings, error]) + ajaxComplete(type, xhr, settings) + } + // status: "success", "notmodified", "error", "timeout", "abort", "parsererror" + function ajaxComplete(status, xhr, settings) { + var context = settings.context + settings.complete.call(context, xhr, status) + triggerGlobal(settings, context, 'ajaxComplete', [xhr, settings]) + ajaxStop(settings) + } + + // Empty function, used as default callback + function empty() {} + + $.ajaxJSONP = function(options){ + var callbackName = 'jsonp' + (++jsonpID), + script = document.createElement('script'), + abort = function(){ + $(script).remove() + if (callbackName in window) window[callbackName] = empty + ajaxComplete('abort', xhr, options) + }, + xhr = { abort: abort }, abortTimeout + + if (options.error) script.onerror = function() { + xhr.abort() + options.error() + } + + window[callbackName] = function(data){ + clearTimeout(abortTimeout) + $(script).remove() + delete window[callbackName] + ajaxSuccess(data, xhr, options) + } + + serializeData(options) + script.src = options.url.replace(/=\?/, '=' + callbackName) + $('head').append(script) + + if (options.timeout > 0) abortTimeout = setTimeout(function(){ + xhr.abort() + ajaxComplete('timeout', xhr, options) + }, options.timeout) + + return xhr + } + + $.ajaxSettings = { + // Default type of request + type: 'GET', + // Callback that is executed before request + beforeSend: empty, + // Callback that is executed if the request succeeds + success: empty, + // Callback that is executed the the server drops error + error: empty, + // Callback that is executed on request complete (both: error and success) + complete: empty, + // The context for the callbacks + context: null, + // Whether to trigger "global" Ajax events + global: true, + // Transport + xhr: function () { + return new window.XMLHttpRequest() + }, + // MIME types mapping + accepts: { + script: 'text/javascript, application/javascript', + json: jsonType, + xml: 'application/xml, text/xml', + html: htmlType, + text: 'text/plain' + }, + // Whether the request is to another domain + crossDomain: false, + // Default timeout + timeout: 0 + } + + function mimeToDataType(mime) { + return mime && ( mime == htmlType ? 'html' : + mime == jsonType ? 'json' : + scriptTypeRE.test(mime) ? 'script' : + xmlTypeRE.test(mime) && 'xml' ) || 'text' + } + + function appendQuery(url, query) { + return (url + '&' + query).replace(/[&?]{1,2}/, '?') + } + + // serialize payload and append it to the URL for GET requests + function serializeData(options) { + if (isObject(options.data)) options.data = $.param(options.data) + if (options.data && (!options.type || options.type.toUpperCase() == 'GET')) + options.url = appendQuery(options.url, options.data) + } + + $.ajax = function(options){ + var settings = $.extend({}, options || {}) + for (key in $.ajaxSettings) if (settings[key] === undefined) settings[key] = $.ajaxSettings[key] + + ajaxStart(settings) + + if (!settings.crossDomain) settings.crossDomain = /^([\w-]+:)?\/\/([^\/]+)/.test(settings.url) && + RegExp.$2 != window.location.host + + var dataType = settings.dataType, hasPlaceholder = /=\?/.test(settings.url) + if (dataType == 'jsonp' || hasPlaceholder) { + if (!hasPlaceholder) settings.url = appendQuery(settings.url, 'callback=?') + return $.ajaxJSONP(settings) + } + + if (!settings.url) settings.url = window.location.toString() + serializeData(settings) + + var mime = settings.accepts[dataType], + baseHeaders = { }, + protocol = /^([\w-]+:)\/\//.test(settings.url) ? RegExp.$1 : window.location.protocol, + xhr = $.ajaxSettings.xhr(), abortTimeout + + if (!settings.crossDomain) baseHeaders['X-Requested-With'] = 'XMLHttpRequest' + if (mime) { + baseHeaders['Accept'] = mime + if (mime.indexOf(',') > -1) mime = mime.split(',', 2)[0] + xhr.overrideMimeType && xhr.overrideMimeType(mime) + } + if (settings.contentType || (settings.data && settings.type.toUpperCase() != 'GET')) + baseHeaders['Content-Type'] = (settings.contentType || 'application/x-www-form-urlencoded') + settings.headers = $.extend(baseHeaders, settings.headers || {}) + + xhr.onreadystatechange = function(){ + if (xhr.readyState == 4) { + clearTimeout(abortTimeout) + var result, error = false + if ((xhr.status >= 200 && xhr.status < 300) || xhr.status == 304 || (xhr.status == 0 && protocol == 'file:')) { + dataType = dataType || mimeToDataType(xhr.getResponseHeader('content-type')) + result = xhr.responseText + + try { + if (dataType == 'script') (1,eval)(result) + else if (dataType == 'xml') result = xhr.responseXML + else if (dataType == 'json') result = blankRE.test(result) ? null : JSON.parse(result) + } catch (e) { error = e } + + if (error) ajaxError(error, 'parsererror', xhr, settings) + else ajaxSuccess(result, xhr, settings) + } else { + ajaxError(null, 'error', xhr, settings) + } + } + } + + var async = 'async' in settings ? settings.async : true + xhr.open(settings.type, settings.url, async) + + for (name in settings.headers) xhr.setRequestHeader(name, settings.headers[name]) + + if (ajaxBeforeSend(xhr, settings) === false) { + xhr.abort() + return false + } + + if (settings.timeout > 0) abortTimeout = setTimeout(function(){ + xhr.onreadystatechange = empty + xhr.abort() + ajaxError(null, 'timeout', xhr, settings) + }, settings.timeout) + + // avoid sending empty string (#319) + xhr.send(settings.data ? settings.data : null) + return xhr + } + + $.get = function(url, success){ return $.ajax({ url: url, success: success }) } + + $.post = function(url, data, success, dataType){ + if ($.isFunction(data)) dataType = dataType || success, success = data, data = null + return $.ajax({ type: 'POST', url: url, data: data, success: success, dataType: dataType }) + } + + $.getJSON = function(url, success){ + return $.ajax({ url: url, success: success, dataType: 'json' }) + } + + $.fn.load = function(url, success){ + if (!this.length) return this + var self = this, parts = url.split(/\s/), selector + if (parts.length > 1) url = parts[0], selector = parts[1] + $.get(url, function(response){ + self.html(selector ? + $(document.createElement('div')).html(response.replace(rscript, "")).find(selector).html() + : response) + success && success.call(self) + }) + return this + } + + var escape = encodeURIComponent + + function serialize(params, obj, traditional, scope){ + var array = $.isArray(obj) + $.each(obj, function(key, value) { + if (scope) key = traditional ? scope : scope + '[' + (array ? '' : key) + ']' + // handle data in serializeArray() format + if (!scope && array) params.add(value.name, value.value) + // recurse into nested objects + else if (traditional ? $.isArray(value) : isObject(value)) + serialize(params, value, traditional, key) + else params.add(key, value) + }) + } + + $.param = function(obj, traditional){ + var params = [] + params.add = function(k, v){ this.push(escape(k) + '=' + escape(v)) } + serialize(params, obj, traditional) + return params.join('&').replace('%20', '+') + } +})(Zepto) +;(function ($) { + $.fn.serializeArray = function () { + var result = [], el + $( Array.prototype.slice.call(this.get(0).elements) ).each(function () { + el = $(this) + var type = el.attr('type') + if (this.nodeName.toLowerCase() != 'fieldset' && + !this.disabled && type != 'submit' && type != 'reset' && type != 'button' && + ((type != 'radio' && type != 'checkbox') || this.checked)) + result.push({ + name: el.attr('name'), + value: el.val() + }) + }) + return result + } + + $.fn.serialize = function () { + var result = [] + this.serializeArray().forEach(function (elm) { + result.push( encodeURIComponent(elm.name) + '=' + encodeURIComponent(elm.value) ) + }) + return result.join('&') + } + + $.fn.submit = function (callback) { + if (callback) this.bind('submit', callback) + else if (this.length) { + var event = $.Event('submit') + this.eq(0).trigger(event) + if (!event.defaultPrevented) this.get(0).submit() + } + return this + } + +})(Zepto) +/* +;(function($){ + var touch = {}, touchTimeout + + function parentIfText(node){ + return 'tagName' in node ? node : node.parentNode + } + + function swipeDirection(x1, x2, y1, y2){ + var xDelta = Math.abs(x1 - x2), yDelta = Math.abs(y1 - y2) + return xDelta >= yDelta ? (x1 - x2 > 0 ? 'Left' : 'Right') : (y1 - y2 > 0 ? 'Up' : 'Down') + } + + var longTapDelay = 750, longTapTimeout + + function longTap(){ + longTapTimeout = null + if (touch.last) { + touch.el.trigger('longTap') + touch = {} + } + } + + function cancelLongTap(){ + if (longTapTimeout) clearTimeout(longTapTimeout) + longTapTimeout = null + } + + $(document).ready(function(){ + var now, delta + + $(document.body).bind('touchstart', function(e){ + now = Date.now() + delta = now - (touch.last || now) + touch.el = $(parentIfText(e.touches[0].target)) + touchTimeout && clearTimeout(touchTimeout) + touch.x1 = e.touches[0].pageX + touch.y1 = e.touches[0].pageY + if (delta > 0 && delta <= 250) touch.isDoubleTap = true + touch.last = now + longTapTimeout = setTimeout(longTap, longTapDelay) + }).bind('touchmove', function(e){ + cancelLongTap() + touch.x2 = e.touches[0].pageX + touch.y2 = e.touches[0].pageY + }).bind('touchend', function(e){ + cancelLongTap() + + // double tap (tapped twice within 250ms) + if (touch.isDoubleTap) { + touch.el.trigger('doubleTap') + touch = {} + + // swipe + } else if ((touch.x2 && Math.abs(touch.x1 - touch.x2) > 30) || + (touch.y2 && Math.abs(touch.y1 - touch.y2) > 30)) { + touch.el.trigger('swipe') && + touch.el.trigger('swipe' + (swipeDirection(touch.x1, touch.x2, touch.y1, touch.y2))) + touch = {} + + // normal tap + } else if ('last' in touch) { + touch.el.trigger('tap') + + touchTimeout = setTimeout(function(){ + touchTimeout = null + touch.el.trigger('singleTap') + touch = {} + }, 250) + } + }).bind('touchcancel', function(){ + if (touchTimeout) clearTimeout(touchTimeout) + if (longTapTimeout) clearTimeout(longTapTimeout) + longTapTimeout = touchTimeout = null + touch = {} + }) + }) + + ;['swipe', 'swipeLeft', 'swipeRight', 'swipeUp', 'swipeDown', 'doubleTap', 'tap', 'singleTap', 'longTap'].forEach(function(m){ + $.fn[m] = function(callback){ return this.bind(m, callback) } + }) +})(Zepto) +*/ +// Zepto.js +// (c) 2010-2012 Thomas Fuchs +// Zepto.js may be freely distributed under the MIT license. + +// The following code is heavily inspired by jQuery's $.fn.data() +;(function($) { + var data = {}, dataAttr = $.fn.data, camelize = $.zepto.camelize, + exp = $.expando = 'Zepto' + (+new Date()) + + // Get value from node: + // 1. first try key as given, + // 2. then try camelized key, + // 3. fall back to reading "data-*" attribute. + function getData(node, name) { + var id = node[exp], store = id && data[id] + if (name === undefined) return store || setData(node) + else { + if (store) { + if (name in store) return store[name] + var camelName = camelize(name) + if (camelName in store) return store[camelName] + } + return dataAttr.call($(node), name) + } + } + + // Store value under camelized key on node + function setData(node, name, value) { + var id = node[exp] || (node[exp] = ++$.uuid), + store = data[id] || (data[id] = attributeData(node)) + if (name !== undefined) store[camelize(name)] = value + return store + } + + // Read all "data-*" attributes from a node + function attributeData(node) { + var store = {} + $.each(node.attributes, function(i, attr){ + if (attr.name.indexOf('data-') == 0) + store[camelize(attr.name.replace('data-', ''))] = attr.value + }) + return store + } + + $.fn.data = function(name, value) { + return value === undefined ? + // set multiple values via object + $.isPlainObject(name) ? + this.each(function(i, node){ + $.each(name, function(key, value){ setData(node, key, value) }) + }) : + // get value from first element + this.length == 0 ? undefined : getData(this[0], name) : + // set value on all elements + this.each(function(){ setData(this, name, value) }) + } + + $.fn.removeData = function(names) { + if (typeof names == 'string') names = names.split(/\s+/) + return this.each(function(){ + var id = this[exp], store = id && data[id] + if (store) $.each(names, function(){ delete store[camelize(this)] }) + }) + } +})(Zepto) diff --git a/zepto.min.js b/zepto.min.js new file mode 100644 index 0000000..c629fd6 --- /dev/null +++ b/zepto.min.js @@ -0,0 +1,2 @@ +/* Zepto v1.1.4 - zepto event ajax form ie - zeptojs.com/license */ +var Zepto=function(){function L(t){return null==t?String(t):j[S.call(t)]||"object"}function Z(t){return"function"==L(t)}function $(t){return null!=t&&t==t.window}function _(t){return null!=t&&t.nodeType==t.DOCUMENT_NODE}function D(t){return"object"==L(t)}function R(t){return D(t)&&!$(t)&&Object.getPrototypeOf(t)==Object.prototype}function M(t){return"number"==typeof t.length}function k(t){return s.call(t,function(t){return null!=t})}function z(t){return t.length>0?n.fn.concat.apply([],t):t}function F(t){return t.replace(/::/g,"/").replace(/([A-Z]+)([A-Z][a-z])/g,"$1_$2").replace(/([a-z\d])([A-Z])/g,"$1_$2").replace(/_/g,"-").toLowerCase()}function q(t){return t in f?f[t]:f[t]=new RegExp("(^|\\s)"+t+"(\\s|$)")}function H(t,e){return"number"!=typeof e||c[F(t)]?e:e+"px"}function I(t){var e,n;return u[t]||(e=a.createElement(t),a.body.appendChild(e),n=getComputedStyle(e,"").getPropertyValue("display"),e.parentNode.removeChild(e),"none"==n&&(n="block"),u[t]=n),u[t]}function V(t){return"children"in t?o.call(t.children):n.map(t.childNodes,function(t){return 1==t.nodeType?t:void 0})}function B(n,i,r){for(e in i)r&&(R(i[e])||A(i[e]))?(R(i[e])&&!R(n[e])&&(n[e]={}),A(i[e])&&!A(n[e])&&(n[e]=[]),B(n[e],i[e],r)):i[e]!==t&&(n[e]=i[e])}function U(t,e){return null==e?n(t):n(t).filter(e)}function J(t,e,n,i){return Z(e)?e.call(t,n,i):e}function X(t,e,n){null==n?t.removeAttribute(e):t.setAttribute(e,n)}function W(e,n){var i=e.className,r=i&&i.baseVal!==t;return n===t?r?i.baseVal:i:void(r?i.baseVal=n:e.className=n)}function Y(t){var e;try{return t?"true"==t||("false"==t?!1:"null"==t?null:/^0/.test(t)||isNaN(e=Number(t))?/^[\[\{]/.test(t)?n.parseJSON(t):t:e):t}catch(i){return t}}function G(t,e){e(t);for(var n=0,i=t.childNodes.length;i>n;n++)G(t.childNodes[n],e)}var t,e,n,i,C,N,r=[],o=r.slice,s=r.filter,a=window.document,u={},f={},c={"column-count":1,columns:1,"font-weight":1,"line-height":1,opacity:1,"z-index":1,zoom:1},l=/^\s*<(\w+|!)[^>]*>/,h=/^<(\w+)\s*\/?>(?:<\/\1>|)$/,p=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi,d=/^(?:body|html)$/i,m=/([A-Z])/g,g=["val","css","html","text","data","width","height","offset"],v=["after","prepend","before","append"],y=a.createElement("table"),x=a.createElement("tr"),b={tr:a.createElement("tbody"),tbody:y,thead:y,tfoot:y,td:x,th:x,"*":a.createElement("div")},w=/complete|loaded|interactive/,E=/^[\w-]*$/,j={},S=j.toString,T={},O=a.createElement("div"),P={tabindex:"tabIndex",readonly:"readOnly","for":"htmlFor","class":"className",maxlength:"maxLength",cellspacing:"cellSpacing",cellpadding:"cellPadding",rowspan:"rowSpan",colspan:"colSpan",usemap:"useMap",frameborder:"frameBorder",contenteditable:"contentEditable"},A=Array.isArray||function(t){return t instanceof Array};return T.matches=function(t,e){if(!e||!t||1!==t.nodeType)return!1;var n=t.webkitMatchesSelector||t.mozMatchesSelector||t.oMatchesSelector||t.matchesSelector;if(n)return n.call(t,e);var i,r=t.parentNode,o=!r;return o&&(r=O).appendChild(t),i=~T.qsa(r,e).indexOf(t),o&&O.removeChild(t),i},C=function(t){return t.replace(/-+(.)?/g,function(t,e){return e?e.toUpperCase():""})},N=function(t){return s.call(t,function(e,n){return t.indexOf(e)==n})},T.fragment=function(e,i,r){var s,u,f;return h.test(e)&&(s=n(a.createElement(RegExp.$1))),s||(e.replace&&(e=e.replace(p,"<$1>")),i===t&&(i=l.test(e)&&RegExp.$1),i in b||(i="*"),f=b[i],f.innerHTML=""+e,s=n.each(o.call(f.childNodes),function(){f.removeChild(this)})),R(r)&&(u=n(s),n.each(r,function(t,e){g.indexOf(t)>-1?u[t](e):u.attr(t,e)})),s},T.Z=function(t,e){return t=t||[],t.__proto__=n.fn,t.selector=e||"",t},T.isZ=function(t){return t instanceof T.Z},T.init=function(e,i){var r;if(!e)return T.Z();if("string"==typeof e)if(e=e.trim(),"<"==e[0]&&l.test(e))r=T.fragment(e,RegExp.$1,i),e=null;else{if(i!==t)return n(i).find(e);r=T.qsa(a,e)}else{if(Z(e))return n(a).ready(e);if(T.isZ(e))return e;if(A(e))r=k(e);else if(D(e))r=[e],e=null;else if(l.test(e))r=T.fragment(e.trim(),RegExp.$1,i),e=null;else{if(i!==t)return n(i).find(e);r=T.qsa(a,e)}}return T.Z(r,e)},n=function(t,e){return T.init(t,e)},n.extend=function(t){var e,n=o.call(arguments,1);return"boolean"==typeof t&&(e=t,t=n.shift()),n.forEach(function(n){B(t,n,e)}),t},T.qsa=function(t,e){var n,i="#"==e[0],r=!i&&"."==e[0],s=i||r?e.slice(1):e,a=E.test(s);return _(t)&&a&&i?(n=t.getElementById(s))?[n]:[]:1!==t.nodeType&&9!==t.nodeType?[]:o.call(a&&!i?r?t.getElementsByClassName(s):t.getElementsByTagName(e):t.querySelectorAll(e))},n.contains=a.documentElement.contains?function(t,e){return t!==e&&t.contains(e)}:function(t,e){for(;e&&(e=e.parentNode);)if(e===t)return!0;return!1},n.type=L,n.isFunction=Z,n.isWindow=$,n.isArray=A,n.isPlainObject=R,n.isEmptyObject=function(t){var e;for(e in t)return!1;return!0},n.inArray=function(t,e,n){return r.indexOf.call(e,t,n)},n.camelCase=C,n.trim=function(t){return null==t?"":String.prototype.trim.call(t)},n.uuid=0,n.support={},n.expr={},n.map=function(t,e){var n,r,o,i=[];if(M(t))for(r=0;r=0?e:e+this.length]},toArray:function(){return this.get()},size:function(){return this.length},remove:function(){return this.each(function(){null!=this.parentNode&&this.parentNode.removeChild(this)})},each:function(t){return r.every.call(this,function(e,n){return t.call(e,n,e)!==!1}),this},filter:function(t){return Z(t)?this.not(this.not(t)):n(s.call(this,function(e){return T.matches(e,t)}))},add:function(t,e){return n(N(this.concat(n(t,e))))},is:function(t){return this.length>0&&T.matches(this[0],t)},not:function(e){var i=[];if(Z(e)&&e.call!==t)this.each(function(t){e.call(this,t)||i.push(this)});else{var r="string"==typeof e?this.filter(e):M(e)&&Z(e.item)?o.call(e):n(e);this.forEach(function(t){r.indexOf(t)<0&&i.push(t)})}return n(i)},has:function(t){return this.filter(function(){return D(t)?n.contains(this,t):n(this).find(t).size()})},eq:function(t){return-1===t?this.slice(t):this.slice(t,+t+1)},first:function(){var t=this[0];return t&&!D(t)?t:n(t)},last:function(){var t=this[this.length-1];return t&&!D(t)?t:n(t)},find:function(t){var e,i=this;return e=t?"object"==typeof t?n(t).filter(function(){var t=this;return r.some.call(i,function(e){return n.contains(e,t)})}):1==this.length?n(T.qsa(this[0],t)):this.map(function(){return T.qsa(this,t)}):[]},closest:function(t,e){var i=this[0],r=!1;for("object"==typeof t&&(r=n(t));i&&!(r?r.indexOf(i)>=0:T.matches(i,t));)i=i!==e&&!_(i)&&i.parentNode;return n(i)},parents:function(t){for(var e=[],i=this;i.length>0;)i=n.map(i,function(t){return(t=t.parentNode)&&!_(t)&&e.indexOf(t)<0?(e.push(t),t):void 0});return U(e,t)},parent:function(t){return U(N(this.pluck("parentNode")),t)},children:function(t){return U(this.map(function(){return V(this)}),t)},contents:function(){return this.map(function(){return o.call(this.childNodes)})},siblings:function(t){return U(this.map(function(t,e){return s.call(V(e.parentNode),function(t){return t!==e})}),t)},empty:function(){return this.each(function(){this.innerHTML=""})},pluck:function(t){return n.map(this,function(e){return e[t]})},show:function(){return this.each(function(){"none"==this.style.display&&(this.style.display=""),"none"==getComputedStyle(this,"").getPropertyValue("display")&&(this.style.display=I(this.nodeName))})},replaceWith:function(t){return this.before(t).remove()},wrap:function(t){var e=Z(t);if(this[0]&&!e)var i=n(t).get(0),r=i.parentNode||this.length>1;return this.each(function(o){n(this).wrapAll(e?t.call(this,o):r?i.cloneNode(!0):i)})},wrapAll:function(t){if(this[0]){n(this[0]).before(t=n(t));for(var e;(e=t.children()).length;)t=e.first();n(t).append(this)}return this},wrapInner:function(t){var e=Z(t);return this.each(function(i){var r=n(this),o=r.contents(),s=e?t.call(this,i):t;o.length?o.wrapAll(s):r.append(s)})},unwrap:function(){return this.parent().each(function(){n(this).replaceWith(n(this).children())}),this},clone:function(){return this.map(function(){return this.cloneNode(!0)})},hide:function(){return this.css("display","none")},toggle:function(e){return this.each(function(){var i=n(this);(e===t?"none"==i.css("display"):e)?i.show():i.hide()})},prev:function(t){return n(this.pluck("previousElementSibling")).filter(t||"*")},next:function(t){return n(this.pluck("nextElementSibling")).filter(t||"*")},html:function(t){return 0 in arguments?this.each(function(e){var i=this.innerHTML;n(this).empty().append(J(this,t,e,i))}):0 in this?this[0].innerHTML:null},text:function(t){return 0 in arguments?this.each(function(e){var n=J(this,t,e,this.textContent);this.textContent=null==n?"":""+n}):0 in this?this[0].textContent:null},attr:function(n,i){var r;return"string"!=typeof n||1 in arguments?this.each(function(t){if(1===this.nodeType)if(D(n))for(e in n)X(this,e,n[e]);else X(this,n,J(this,i,t,this.getAttribute(n)))}):this.length&&1===this[0].nodeType?!(r=this[0].getAttribute(n))&&n in this[0]?this[0][n]:r:t},removeAttr:function(t){return this.each(function(){1===this.nodeType&&X(this,t)})},prop:function(t,e){return t=P[t]||t,1 in arguments?this.each(function(n){this[t]=J(this,e,n,this[t])}):this[0]&&this[0][t]},data:function(e,n){var i="data-"+e.replace(m,"-$1").toLowerCase(),r=1 in arguments?this.attr(i,n):this.attr(i);return null!==r?Y(r):t},val:function(t){return 0 in arguments?this.each(function(e){this.value=J(this,t,e,this.value)}):this[0]&&(this[0].multiple?n(this[0]).find("option").filter(function(){return this.selected}).pluck("value"):this[0].value)},offset:function(t){if(t)return this.each(function(e){var i=n(this),r=J(this,t,e,i.offset()),o=i.offsetParent().offset(),s={top:r.top-o.top,left:r.left-o.left};"static"==i.css("position")&&(s.position="relative"),i.css(s)});if(!this.length)return null;var e=this[0].getBoundingClientRect();return{left:e.left+window.pageXOffset,top:e.top+window.pageYOffset,width:Math.round(e.width),height:Math.round(e.height)}},css:function(t,i){if(arguments.length<2){var r=this[0],o=getComputedStyle(r,"");if(!r)return;if("string"==typeof t)return r.style[C(t)]||o.getPropertyValue(t);if(A(t)){var s={};return n.each(A(t)?t:[t],function(t,e){s[e]=r.style[C(e)]||o.getPropertyValue(e)}),s}}var a="";if("string"==L(t))i||0===i?a=F(t)+":"+H(t,i):this.each(function(){this.style.removeProperty(F(t))});else for(e in t)t[e]||0===t[e]?a+=F(e)+":"+H(e,t[e])+";":this.each(function(){this.style.removeProperty(F(e))});return this.each(function(){this.style.cssText+=";"+a})},index:function(t){return t?this.indexOf(n(t)[0]):this.parent().children().indexOf(this[0])},hasClass:function(t){return t?r.some.call(this,function(t){return this.test(W(t))},q(t)):!1},addClass:function(t){return t?this.each(function(e){i=[];var r=W(this),o=J(this,t,e,r);o.split(/\s+/g).forEach(function(t){n(this).hasClass(t)||i.push(t)},this),i.length&&W(this,r+(r?" ":"")+i.join(" "))}):this},removeClass:function(e){return this.each(function(n){return e===t?W(this,""):(i=W(this),J(this,e,n,i).split(/\s+/g).forEach(function(t){i=i.replace(q(t)," ")}),void W(this,i.trim()))})},toggleClass:function(e,i){return e?this.each(function(r){var o=n(this),s=J(this,e,r,W(this));s.split(/\s+/g).forEach(function(e){(i===t?!o.hasClass(e):i)?o.addClass(e):o.removeClass(e)})}):this},scrollTop:function(e){if(this.length){var n="scrollTop"in this[0];return e===t?n?this[0].scrollTop:this[0].pageYOffset:this.each(n?function(){this.scrollTop=e}:function(){this.scrollTo(this.scrollX,e)})}},scrollLeft:function(e){if(this.length){var n="scrollLeft"in this[0];return e===t?n?this[0].scrollLeft:this[0].pageXOffset:this.each(n?function(){this.scrollLeft=e}:function(){this.scrollTo(e,this.scrollY)})}},position:function(){if(this.length){var t=this[0],e=this.offsetParent(),i=this.offset(),r=d.test(e[0].nodeName)?{top:0,left:0}:e.offset();return i.top-=parseFloat(n(t).css("margin-top"))||0,i.left-=parseFloat(n(t).css("margin-left"))||0,r.top+=parseFloat(n(e[0]).css("border-top-width"))||0,r.left+=parseFloat(n(e[0]).css("border-left-width"))||0,{top:i.top-r.top,left:i.left-r.left}}},offsetParent:function(){return this.map(function(){for(var t=this.offsetParent||a.body;t&&!d.test(t.nodeName)&&"static"==n(t).css("position");)t=t.offsetParent;return t})}},n.fn.detach=n.fn.remove,["width","height"].forEach(function(e){var i=e.replace(/./,function(t){return t[0].toUpperCase()});n.fn[e]=function(r){var o,s=this[0];return r===t?$(s)?s["inner"+i]:_(s)?s.documentElement["scroll"+i]:(o=this.offset())&&o[e]:this.each(function(t){s=n(this),s.css(e,J(this,r,t,s[e]()))})}}),v.forEach(function(t,e){var i=e%2;n.fn[t]=function(){var t,o,r=n.map(arguments,function(e){return t=L(e),"object"==t||"array"==t||null==e?e:T.fragment(e)}),s=this.length>1;return r.length<1?this:this.each(function(t,u){o=i?u:u.parentNode,u=0==e?u.nextSibling:1==e?u.firstChild:2==e?u:null;var f=n.contains(a.documentElement,o);r.forEach(function(t){if(s)t=t.cloneNode(!0);else if(!o)return n(t).remove();o.insertBefore(t,u),f&&G(t,function(t){null==t.nodeName||"SCRIPT"!==t.nodeName.toUpperCase()||t.type&&"text/javascript"!==t.type||t.src||window.eval.call(window,t.innerHTML)})})})},n.fn[i?t+"To":"insert"+(e?"Before":"After")]=function(e){return n(e)[t](this),this}}),T.Z.prototype=n.fn,T.uniq=N,T.deserializeValue=Y,n.zepto=T,n}();window.Zepto=Zepto,void 0===window.$&&(window.$=Zepto),function(t){function l(t){return t._zid||(t._zid=e++)}function h(t,e,n,i){if(e=p(e),e.ns)var r=d(e.ns);return(s[l(t)]||[]).filter(function(t){return!(!t||e.e&&t.e!=e.e||e.ns&&!r.test(t.ns)||n&&l(t.fn)!==l(n)||i&&t.sel!=i)})}function p(t){var e=(""+t).split(".");return{e:e[0],ns:e.slice(1).sort().join(" ")}}function d(t){return new RegExp("(?:^| )"+t.replace(" "," .* ?")+"(?: |$)")}function m(t,e){return t.del&&!u&&t.e in f||!!e}function g(t){return c[t]||u&&f[t]||t}function v(e,i,r,o,a,u,f){var h=l(e),d=s[h]||(s[h]=[]);i.split(/\s/).forEach(function(i){if("ready"==i)return t(document).ready(r);var s=p(i);s.fn=r,s.sel=a,s.e in c&&(r=function(e){var n=e.relatedTarget;return!n||n!==this&&!t.contains(this,n)?s.fn.apply(this,arguments):void 0}),s.del=u;var l=u||r;s.proxy=function(t){if(t=j(t),!t.isImmediatePropagationStopped()){t.data=o;var i=l.apply(e,t._args==n?[t]:[t].concat(t._args));return i===!1&&(t.preventDefault(),t.stopPropagation()),i}},s.i=d.length,d.push(s),"addEventListener"in e&&e.addEventListener(g(s.e),s.proxy,m(s,f))})}function y(t,e,n,i,r){var o=l(t);(e||"").split(/\s/).forEach(function(e){h(t,e,n,i).forEach(function(e){delete s[o][e.i],"removeEventListener"in t&&t.removeEventListener(g(e.e),e.proxy,m(e,r))})})}function j(e,i){return(i||!e.isDefaultPrevented)&&(i||(i=e),t.each(E,function(t,n){var r=i[t];e[t]=function(){return this[n]=x,r&&r.apply(i,arguments)},e[n]=b}),(i.defaultPrevented!==n?i.defaultPrevented:"returnValue"in i?i.returnValue===!1:i.getPreventDefault&&i.getPreventDefault())&&(e.isDefaultPrevented=x)),e}function S(t){var e,i={originalEvent:t};for(e in t)w.test(e)||t[e]===n||(i[e]=t[e]);return j(i,t)}var n,e=1,i=Array.prototype.slice,r=t.isFunction,o=function(t){return"string"==typeof t},s={},a={},u="onfocusin"in window,f={focus:"focusin",blur:"focusout"},c={mouseenter:"mouseover",mouseleave:"mouseout"};a.click=a.mousedown=a.mouseup=a.mousemove="MouseEvents",t.event={add:v,remove:y},t.proxy=function(e,n){var s=2 in arguments&&i.call(arguments,2);if(r(e)){var a=function(){return e.apply(n,s?s.concat(i.call(arguments)):arguments)};return a._zid=l(e),a}if(o(n))return s?(s.unshift(e[n],e),t.proxy.apply(null,s)):t.proxy(e[n],e);throw new TypeError("expected function")},t.fn.bind=function(t,e,n){return this.on(t,e,n)},t.fn.unbind=function(t,e){return this.off(t,e)},t.fn.one=function(t,e,n,i){return this.on(t,e,n,i,1)};var x=function(){return!0},b=function(){return!1},w=/^([A-Z]|returnValue$|layer[XY]$)/,E={preventDefault:"isDefaultPrevented",stopImmediatePropagation:"isImmediatePropagationStopped",stopPropagation:"isPropagationStopped"};t.fn.delegate=function(t,e,n){return this.on(e,t,n)},t.fn.undelegate=function(t,e,n){return this.off(e,t,n)},t.fn.live=function(e,n){return t(document.body).delegate(this.selector,e,n),this},t.fn.die=function(e,n){return t(document.body).undelegate(this.selector,e,n),this},t.fn.on=function(e,s,a,u,f){var c,l,h=this;return e&&!o(e)?(t.each(e,function(t,e){h.on(t,s,a,e,f)}),h):(o(s)||r(u)||u===!1||(u=a,a=s,s=n),(r(a)||a===!1)&&(u=a,a=n),u===!1&&(u=b),h.each(function(n,r){f&&(c=function(t){return y(r,t.type,u),u.apply(this,arguments)}),s&&(l=function(e){var n,o=t(e.target).closest(s,r).get(0);return o&&o!==r?(n=t.extend(S(e),{currentTarget:o,liveFired:r}),(c||u).apply(o,[n].concat(i.call(arguments,1)))):void 0}),v(r,e,u,a,s,l||c)}))},t.fn.off=function(e,i,s){var a=this;return e&&!o(e)?(t.each(e,function(t,e){a.off(t,i,e)}),a):(o(i)||r(s)||s===!1||(s=i,i=n),s===!1&&(s=b),a.each(function(){y(this,e,s,i)}))},t.fn.trigger=function(e,n){return e=o(e)||t.isPlainObject(e)?t.Event(e):j(e),e._args=n,this.each(function(){"dispatchEvent"in this?this.dispatchEvent(e):t(this).triggerHandler(e,n)})},t.fn.triggerHandler=function(e,n){var i,r;return this.each(function(s,a){i=S(o(e)?t.Event(e):e),i._args=n,i.target=a,t.each(h(a,e.type||e),function(t,e){return r=e.proxy(i),i.isImmediatePropagationStopped()?!1:void 0})}),r},"focusin focusout load resize scroll unload click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select keydown keypress keyup error".split(" ").forEach(function(e){t.fn[e]=function(t){return t?this.bind(e,t):this.trigger(e)}}),["focus","blur"].forEach(function(e){t.fn[e]=function(t){return t?this.bind(e,t):this.each(function(){try{this[e]()}catch(t){}}),this}}),t.Event=function(t,e){o(t)||(e=t,t=e.type);var n=document.createEvent(a[t]||"Events"),i=!0;if(e)for(var r in e)"bubbles"==r?i=!!e[r]:n[r]=e[r];return n.initEvent(t,i,!0),j(n)}}(Zepto),function(t){function l(e,n,i){var r=t.Event(n);return t(e).trigger(r,i),!r.isDefaultPrevented()}function h(t,e,i,r){return t.global?l(e||n,i,r):void 0}function p(e){e.global&&0===t.active++&&h(e,null,"ajaxStart")}function d(e){e.global&&!--t.active&&h(e,null,"ajaxStop")}function m(t,e){var n=e.context;return e.beforeSend.call(n,t,e)===!1||h(e,n,"ajaxBeforeSend",[t,e])===!1?!1:void h(e,n,"ajaxSend",[t,e])}function g(t,e,n,i){var r=n.context,o="success";n.success.call(r,t,o,e),i&&i.resolveWith(r,[t,o,e]),h(n,r,"ajaxSuccess",[e,n,t]),y(o,e,n)}function v(t,e,n,i,r){var o=i.context;i.error.call(o,n,e,t),r&&r.rejectWith(o,[n,e,t]),h(i,o,"ajaxError",[n,i,t||e]),y(e,n,i)}function y(t,e,n){var i=n.context;n.complete.call(i,e,t),h(n,i,"ajaxComplete",[e,n]),d(n)}function x(){}function b(t){return t&&(t=t.split(";",2)[0]),t&&(t==f?"html":t==u?"json":s.test(t)?"script":a.test(t)&&"xml")||"text"}function w(t,e){return""==e?t:(t+"&"+e).replace(/[&?]{1,2}/,"?")}function E(e){e.processData&&e.data&&"string"!=t.type(e.data)&&(e.data=t.param(e.data,e.traditional)),!e.data||e.type&&"GET"!=e.type.toUpperCase()||(e.url=w(e.url,e.data),e.data=void 0)}function j(e,n,i,r){return t.isFunction(n)&&(r=i,i=n,n=void 0),t.isFunction(i)||(r=i,i=void 0),{url:e,data:n,success:i,dataType:r}}function T(e,n,i,r){var o,s=t.isArray(n),a=t.isPlainObject(n);t.each(n,function(n,u){o=t.type(u),r&&(n=i?r:r+"["+(a||"object"==o||"array"==o?n:"")+"]"),!r&&s?e.add(u.name,u.value):"array"==o||!i&&"object"==o?T(e,u,i,n):e.add(n,u)})}var i,r,e=0,n=window.document,o=/)<[^<]*)*<\/script>/gi,s=/^(?:text|application)\/javascript/i,a=/^(?:text|application)\/xml/i,u="application/json",f="text/html",c=/^\s*$/;t.active=0,t.ajaxJSONP=function(i,r){if(!("type"in i))return t.ajax(i);var f,h,o=i.jsonpCallback,s=(t.isFunction(o)?o():o)||"jsonp"+ ++e,a=n.createElement("script"),u=window[s],c=function(e){t(a).triggerHandler("error",e||"abort")},l={abort:c};return r&&r.promise(l),t(a).on("load error",function(e,n){clearTimeout(h),t(a).off().remove(),"error"!=e.type&&f?g(f[0],l,i,r):v(null,n||"error",l,i,r),window[s]=u,f&&t.isFunction(u)&&u(f[0]),u=f=void 0}),m(l,i)===!1?(c("abort"),l):(window[s]=function(){f=arguments},a.src=i.url.replace(/\?(.+)=\?/,"?$1="+s),n.head.appendChild(a),i.timeout>0&&(h=setTimeout(function(){c("timeout")},i.timeout)),l)},t.ajaxSettings={type:"GET",beforeSend:x,success:x,error:x,complete:x,context:null,global:!0,xhr:function(){return new window.XMLHttpRequest},accepts:{script:"text/javascript, application/javascript, application/x-javascript",json:u,xml:"application/xml, text/xml",html:f,text:"text/plain"},crossDomain:!1,timeout:0,processData:!0,cache:!0},t.ajax=function(e){var n=t.extend({},e||{}),o=t.Deferred&&t.Deferred();for(i in t.ajaxSettings)void 0===n[i]&&(n[i]=t.ajaxSettings[i]);p(n),n.crossDomain||(n.crossDomain=/^([\w-]+:)?\/\/([^\/]+)/.test(n.url)&&RegExp.$2!=window.location.host),n.url||(n.url=window.location.toString()),E(n);var s=n.dataType,a=/\?.+=\?/.test(n.url);if(a&&(s="jsonp"),n.cache!==!1&&(e&&e.cache===!0||"script"!=s&&"jsonp"!=s)||(n.url=w(n.url,"_="+Date.now())),"jsonp"==s)return a||(n.url=w(n.url,n.jsonp?n.jsonp+"=?":n.jsonp===!1?"":"callback=?")),t.ajaxJSONP(n,o);var j,u=n.accepts[s],f={},l=function(t,e){f[t.toLowerCase()]=[t,e]},h=/^([\w-]+:)\/\//.test(n.url)?RegExp.$1:window.location.protocol,d=n.xhr(),y=d.setRequestHeader;if(o&&o.promise(d),n.crossDomain||l("X-Requested-With","XMLHttpRequest"),l("Accept",u||"*/*"),(u=n.mimeType||u)&&(u.indexOf(",")>-1&&(u=u.split(",",2)[0]),d.overrideMimeType&&d.overrideMimeType(u)),(n.contentType||n.contentType!==!1&&n.data&&"GET"!=n.type.toUpperCase())&&l("Content-Type",n.contentType||"application/x-www-form-urlencoded"),n.headers)for(r in n.headers)l(r,n.headers[r]);if(d.setRequestHeader=l,d.onreadystatechange=function(){if(4==d.readyState){d.onreadystatechange=x,clearTimeout(j);var e,i=!1;if(d.status>=200&&d.status<300||304==d.status||0==d.status&&"file:"==h){s=s||b(n.mimeType||d.getResponseHeader("content-type")),e=d.responseText;try{"script"==s?(1,eval)(e):"xml"==s?e=d.responseXML:"json"==s&&(e=c.test(e)?null:t.parseJSON(e))}catch(r){i=r}i?v(i,"parsererror",d,n,o):g(e,d,n,o)}else v(d.statusText||null,d.status?"error":"abort",d,n,o)}},m(d,n)===!1)return d.abort(),v(null,"abort",d,n,o),d;if(n.xhrFields)for(r in n.xhrFields)d[r]=n.xhrFields[r];var S="async"in n?n.async:!0;d.open(n.type,n.url,S,n.username,n.password);for(r in f)y.apply(d,f[r]);return n.timeout>0&&(j=setTimeout(function(){d.onreadystatechange=x,d.abort(),v(null,"timeout",d,n,o)},n.timeout)),d.send(n.data?n.data:null),d},t.get=function(){return t.ajax(j.apply(null,arguments))},t.post=function(){var e=j.apply(null,arguments);return e.type="POST",t.ajax(e)},t.getJSON=function(){var e=j.apply(null,arguments);return e.dataType="json",t.ajax(e)},t.fn.load=function(e,n,i){if(!this.length)return this;var a,r=this,s=e.split(/\s/),u=j(e,n,i),f=u.success;return s.length>1&&(u.url=s[0],a=s[1]),u.success=function(e){r.html(a?t("
").html(e.replace(o,"")).find(a):e),f&&f.apply(r,arguments)},t.ajax(u),this};var S=encodeURIComponent;t.param=function(t,e){var n=[];return n.add=function(t,e){this.push(S(t)+"="+S(e))},T(n,t,e),n.join("&").replace(/%20/g,"+")}}(Zepto),function(t){t.fn.serializeArray=function(){var n,e=[];return t([].slice.call(this.get(0).elements)).each(function(){n=t(this);var i=n.attr("type");"fieldset"!=this.nodeName.toLowerCase()&&!this.disabled&&"submit"!=i&&"reset"!=i&&"button"!=i&&("radio"!=i&&"checkbox"!=i||this.checked)&&e.push({name:n.attr("name"),value:n.val()})}),e},t.fn.serialize=function(){var t=[];return this.serializeArray().forEach(function(e){t.push(encodeURIComponent(e.name)+"="+encodeURIComponent(e.value))}),t.join("&")},t.fn.submit=function(e){if(e)this.bind("submit",e);else if(this.length){var n=t.Event("submit");this.eq(0).trigger(n),n.isDefaultPrevented()||this.get(0).submit()}return this}}(Zepto),function(t){"__proto__"in{}||t.extend(t.zepto,{Z:function(e,n){return e=e||[],t.extend(e,t.fn),e.selector=n||"",e.__Z=!0,e},isZ:function(e){return"array"===t.type(e)&&"__Z"in e}});try{getComputedStyle(void 0)}catch(e){var n=getComputedStyle;window.getComputedStyle=function(t){try{return n(t)}catch(e){return null}}}}(Zepto); \ No newline at end of file