/*! Flowplayer v6.0.5 (Wednesday, 13. January 2016 09:17AM) | flowplayer.org/license */ /*! (C) WebReflection Mit Style License */ (function(e){function g(e,t,n,r){for(var i,s=n.slice(),o=w(t,e),u=0,a=s.length;u' + innerHTML + '').attr(attributes)[0]; } }; common.toggleClass = function (el, cls, flag) { if (!el) return; var classes = ClassList(el); if (typeof flag === 'undefined') classes.toggle(cls); else if (flag) classes.add(cls); else if (!flag) classes.remove(cls); }; common.addClass = function (el, cls) { return common.toggleClass(el, cls, true); }; common.removeClass = function (el, cls) { return common.toggleClass(el, cls, false); }; common.append = function (par, child) { par.appendChild(child); return par; }; common.appendTo = function (child, par) { common.append(par, child); return child; }; common.prepend = function (par, child) { par.insertBefore(child, par.firstChild); }; // Inserts `el` after `child` that is child of `par` common.insertAfter = function (par, child, el) { if (child == common.lastChild(par)) par.appendChild(el); var childIndex = Array.prototype.indexOf.call(par.children, child); par.insertBefore(el, par.children[childIndex + 1]); }; common.html = function (elms, val) { elms = elms.length ? elms : [elms]; elms.forEach(function (elm) { elm.innerHTML = val; }); }; common.attr = function (el, key, val) { if (key === 'class') key = 'className'; if (common.hasOwnOrPrototypeProperty(el, key)) { try { el[key] = val; } catch (e) { // Most likely IE not letting set property if ($) { $(el).attr(key, val); } else { throw e; } } } else { if (val === false) { el.removeAttribute(key); } else { el.setAttribute(key, val); } } return el; }; common.prop = function (el, key, val) { if (typeof val === 'undefined') { return el && el[key]; } el[key] = val; }; common.offset = function (el) { var ret = el.getBoundingClientRect(); if (el.offsetWidth / el.offsetHeight > el.clientWidth / el.clientHeight) { // https://github.com/flowplayer/flowplayer/issues/757 ret = { left: ret.left * 100, right: ret.right * 100, top: ret.top * 100, bottom: ret.bottom * 100, width: ret.width * 100, height: ret.height * 100 }; } return ret; }; common.width = function (el, val) { /*jshint -W093 */ if (val) return el.style.width = ('' + val).replace(/px$/, '') + 'px'; var ret = common.offset(el).width; return typeof ret === 'undefined' ? el.offsetWidth : ret; }; common.height = function (el, val) { /*jshint -W093 */ if (val) return el.style.height = ('' + val).replace(/px$/, '') + 'px'; var ret = common.offset(el).height; return typeof ret === 'undefined' ? el.offsetHeight : ret; }; common.lastChild = function (el) { return el.children[el.children.length - 1]; }; common.hasParent = function (el, parentSelector) { var parent = el.parentElement; while (parent) { if (common.matches(parent, parentSelector)) return true; parent = parent.parentElement; } return false; }; common.createAbsoluteUrl = function (url) { return common.createElement('a', { href: url }).href; // This won't work on IE7 }; common.xhrGet = function (url, successCb, errorCb) { var xhr = new XMLHttpRequest(); xhr.onreadystatechange = function () { if (this.readyState !== 4) return; if (this.status >= 400) return errorCb(); successCb(this.responseText); }; xhr.open('get', url, true); xhr.send(); }; common.pick = function (obj, props) { var ret = {}; props.forEach(function (prop) { if (obj.hasOwnProperty(prop)) ret[prop] = obj[prop]; }); return ret; }; common.hostname = function (host) { return punycode.toUnicode(host || window.location.hostname); }; //Hacks common.browser = { webkit: 'WebkitAppearance' in document.documentElement.style }; common.getPrototype = function (el) { /* jshint proto:true */ if (!Object.getPrototypeOf) return el.__proto__; return Object.getPrototypeOf(el); }; common.hasOwnOrPrototypeProperty = function (obj, prop) { var o = obj; while (o) { if (Object.prototype.hasOwnProperty.call(o, prop)) return true; o = common.getPrototype(o); } return false; }; // Polyfill for Element.matches // adapted from https://developer.mozilla.org/en/docs/Web/API/Element/matches common.matches = function (elem, selector) { var proto = Element.prototype, fn = proto.matches || proto.matchesSelector || proto.mozMatchesSelector || proto.msMatchesSelector || proto.oMatchesSelector || proto.webkitMatchesSelector || function (selector) { var element = this, matches = (element.document || element.ownerDocument).querySelectorAll(selector), i = 0; while (matches[i] && matches[i] !== element) { i++; } return matches[i] ? true : false; }; return fn.call(elem, selector); }; // Polyfill for CSSStyleDeclaration // from https://github.com/shawnbot/aight (function (CSSSDProto) { function getAttribute(property) { return property.replace(/-[a-z]/g, function (bit) { return bit[1].toUpperCase(); }); } // patch CSSStyleDeclaration.prototype using IE8's methods if (typeof CSSSDProto.setAttribute !== "undefined") { CSSSDProto.setProperty = function (property, value) { return this.setAttribute(getAttribute(property), String(value) /*, important */); }; CSSSDProto.getPropertyValue = function (property) { return this.getAttribute(getAttribute(property)) || null; }; CSSSDProto.removeProperty = function (property) { var value = this.getPropertyValue(property); this.removeAttribute(getAttribute(property)); return value; }; } })(window.CSSStyleDeclaration.prototype); }, { "class-list": 22, "computed-style": 24, "punycode": 21}], 2: [function (_dereq_, module, exports) { 'use strict'; var common = _dereq_('../common'); // movie required in opts module.exports = function embed(swf, flashvars, wmode, bgColor) { wmode = wmode || "opaque"; var id = "obj" + ("" + Math.random()).slice(2, 15), tag = ' -1; tag += msie ? 'classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000">' : ' data="' + swf + '" type="application/x-shockwave-flash">'; var opts = { width: "100%", height: "100%", allowscriptaccess: "always", wmode: wmode, quality: "high", flashvars: "", // https://github.com/flowplayer/flowplayer/issues/13#issuecomment-9369919 movie: swf + (msie ? "?" + id : ""), name: id }; if (wmode !== 'transparent') opts.bgcolor = bgColor || '#333333'; // flashvars Object.keys(flashvars).forEach(function (key) { opts.flashvars += key + "=" + flashvars[key] + "&"; }); // parameters Object.keys(opts).forEach(function (key) { tag += ''; }); tag += ""; var el = common.createElement('div', {}, tag); return common.find('object', el); }; // Flash is buggy allover if (window.attachEvent) { window.attachEvent("onbeforeunload", function () { window.__flash_savedUnloadHandler = window.__flash_unloadHandler = function () { }; }); } }, { "../common": 1}], 3: [function (_dereq_, module, exports) { 'use strict'; var flowplayer = _dereq_('../flowplayer'), common = _dereq_('../common'), embed = _dereq_('./embed'), extend = _dereq_('extend-object'), bean = _dereq_('bean'), engineImpl; engineImpl = function flashEngine(player, root) { var conf = player.conf, video = player.video, loadVideo, callbackId, objectTag, api; var win = window; var engine = { engineName: engineImpl.engineName, pick: function (sources) { var source = extend({}, (function () { if (flowplayer.support.flashVideo) { var selectedSource; for (var i = 0, source; i < sources.length; i++) { source = sources[i]; if (/mp4|flv|flash/i.test(source.type)) selectedSource = source; if (player.conf.swfHls && /mpegurl/i.test(source.type)) selectedSource = source; if (selectedSource && !/mp4/i.test(selectedSource.type)) return selectedSource; // Did not find any source or source was video/mp4, let's try find more } return selectedSource; // Accept the fact we don't have anything or just an MP4 } })()); if (!source) return; if (source.src && !isAbsolute(source.src) && !player.conf.rtmp && !source.rtmp) source.src = common.createAbsoluteUrl(source.src); return source; }, load: function (video) { loadVideo = video; function escapeURL(url) { return url.replace(/&/g, '%26').replace(/&/g, '%26').replace(/=/g, '%3D'); } var html5Tag = common.findDirect('video', root)[0] || common.find('.fp-player > video', root)[0], url = video.src, is_absolute = isAbsolute(url); var removeTag = function () { common.removeNode(html5Tag); }; var hasSupportedSource = function (sources) { return sources.some(function (src) { return !!html5Tag.canPlayType(src.type); }); }; if (flowplayer.support.video && common.prop(html5Tag, 'autoplay') && hasSupportedSource(video.sources)) bean.one(html5Tag, 'timeupdate', removeTag); else removeTag(); // convert to absolute var rtmp = video.rtmp || conf.rtmp; if (!is_absolute && !rtmp) url = common.createAbsoluteUrl(url); if (api && isHLS(video) && api.data !== conf.swfHls) engine.unload(); if (api) { ['live', 'preload', 'loop'].forEach(function (prop) { if (!video.hasOwnProperty(prop)) return; api.__set(prop, video[prop]); }); Object.keys(video.flashls || {}).forEach(function (key) { api.__set('hls_' + key, video.flashls[key]); }); var providerChangeNeeded = false; if (!is_absolute && rtmp) api.__set('rtmp', rtmp.url || rtmp); else { var oldRtmp = api.__get('rtmp'); providerChangeNeeded = !!oldRtmp; api.__set('rtmp', null); } api.__play(url, providerChangeNeeded || video.rtmp && video.rtmp !== conf.rtmp); } else { callbackId = "fpCallback" + ("" + Math.random()).slice(3, 15); url = escapeURL(url); var opts = { hostname: conf.embedded ? common.hostname(conf.hostname) : common.hostname(location.hostname), url: url, callback: callbackId }; if (root.getAttribute('data-origin')) { opts.origin = root.getAttribute('data-origin'); } // optional conf ['proxy', 'key', 'autoplay', 'preload', 'subscribe', 'live', 'loop', 'debug', 'splash', 'poster', 'rtmpt'].forEach(function (key) { if (conf.hasOwnProperty(key)) opts[key] = conf[key]; if (video.hasOwnProperty(key)) opts[key] = video[key]; if ((conf.rtmp || {}).hasOwnProperty(key)) opts[key] = (conf.rtmp || {})[key]; if ((video.rtmp || {}).hasOwnProperty(key)) opts[key] = (video.rtmp || {})[key]; }); if (conf.rtmp) opts.rtmp = conf.rtmp.url || conf.rtmp; if (video.rtmp) opts.rtmp = video.rtmp.url || video.rtmp; Object.keys(video.flashls || {}).forEach(function (key) { var val = video.flashls[key]; opts['hls_' + key] = val; }); // bufferTime might be 0 if (conf.bufferTime !== undefined) opts.bufferTime = conf.bufferTime; if (is_absolute) delete opts.rtmp; // issues #376 if (opts.rtmp) { opts.rtmp = escapeURL(opts.rtmp); } // issues #733, 906 var bgColor = conf.bgcolor || common.css(root, 'background-color') || '', bg; if (bgColor.indexOf('rgb') === 0) { bg = toHex(bgColor); } else if (bgColor.indexOf('#') === 0) { bg = toLongHex(bgColor); } // issues #387 opts.initialVolume = player.volumeLevel; var swfUrl = isHLS(video) ? conf.swfHls : conf.swf; api = embed(swfUrl, opts, conf.wmode, bg)[0]; var container = common.find('.fp-player', root)[0]; common.prepend(container, api); // throw error if no loading occurs setTimeout(function () { try { if (!api.PercentLoaded()) { return player.trigger("error", [player, { code: 7, url: conf.swf}]); } } catch (e) { } }, 5000); // detect disabled flash setTimeout(function () { if (typeof api.PercentLoaded === 'undefined') { player.trigger('flashdisabled', [player]); } }, 1000); player.off('resume.flashhack').on('resume.flashhack', function () { var timer = setTimeout(function () { if (player.playing) { player.trigger('flashdisabled', [player]); } }, 1000); player.one('progress', function () { clearTimeout(timer); }); }); api.pollInterval = setInterval(function () { if (!api) return; var status = api.__status ? api.__status() : null; if (!status) return; if (player.playing && status.time && status.time !== player.video.time) player.trigger("progress", [player, status.time]); video.buffer = status.buffer / video.bytes * video.duration; player.trigger("buffer", [player, video.buffer]); if (!video.buffered && status.time > 0) { video.buffered = true; player.trigger("buffered", [player]); } }, 250); // listen window[callbackId] = function (type, arg) { var video = loadVideo; if (conf.debug) { if (type.indexOf('debug') === 0 && arg && arg.length) { console.log.apply(console, ['-- ' + type].concat(arg)); } else console.log("--", type, arg); } var event = { type: type }; switch (type) { // RTMP sends a lot of finish events in vain // case "finish": if (conf.rtmp) return; case "ready": arg = extend(video, arg); break; case "click": event.flash = true; break; case "keydown": event.which = arg; break; case "seek": video.time = arg; break; case "status": player.trigger("progress", [player, arg.time]); if (arg.buffer < video.bytes && !video.buffered) { video.buffer = arg.buffer / video.bytes * video.duration; player.trigger("buffer", video.buffer); } else if (!video.buffered) { video.buffered = true; player.trigger("buffered"); } break; } if (type === 'click' || type === 'keydown') { event.target = root; bean.fire(root, type, [event]); } else if (type != 'buffered' && type !== 'unload') { // add some delay so that player is truly ready after an event setTimeout(function () { player.trigger(event, [player, arg]); }, 1); } else if (type === 'unload') { player.trigger(event, [player, arg]); } }; } }, // not supported yet speed: common.noop, unload: function () { if (api && api.__unload) api.__unload(); try { if (callbackId && window[callbackId]) delete window[callbackId]; } catch (e) { } common.find("object", root).forEach(common.removeNode); api = 0; player.off('.flashengine'); clearInterval(api.pollInterval); } }; ['pause', 'resume', 'seek', 'volume'].forEach(function (name) { engine[name] = function (arg) { try { if (player.ready) { if (arg === undefined) { api["__" + name](); } else { api["__" + name](arg); } } } catch (e) { if (typeof api["__" + name] === 'undefined') { //flash lost it's methods return player.trigger('flashdisabled', [player]); } throw e; } }; }); function toHex(bg) { function hex(x) { return ("0" + parseInt(x).toString(16)).slice(-2); } bg = bg.match(/^rgb\((\d+),\s*(\d+),\s*(\d+)\)$/); if (!bg) return; return '#' + hex(bg[1]) + hex(bg[2]) + hex(bg[3]); } function toLongHex(bg) { if (bg.length === 7) return bg; var a = bg.split('').slice(1); return '#' + a.map(function (i) { return i + i; }).join(''); } function isHLS(video) { return /application\/x-mpegurl/i.test(video.type); } return engine; }; engineImpl.engineName = 'flash'; engineImpl.canPlay = function (type, conf) { return flowplayer.support.flashVideo && /video\/(mp4|flash|flv)/i.test(type) || flowplayer.support.flashVideo && conf.swfHls && /mpegurl/i.test(type); }; flowplayer.engines.push(engineImpl); function isAbsolute(url) { return /^https?:/.test(url); } }, { "../common": 1, "../flowplayer": 18, "./embed": 2, "bean": 20, "extend-object": 26}], 4: [function (_dereq_, module, exports) { 'use strict'; var flowplayer = _dereq_('../flowplayer'), bean = _dereq_('bean'), ClassList = _dereq_('class-list'), extend = _dereq_('extend-object'), common = _dereq_('../common'); var VIDEO = document.createElement('video'); // HTML5 --> Flowplayer event var EVENTS = { // fired ended: 'finish', pause: 'pause', play: 'resume', progress: 'buffer', timeupdate: 'progress', volumechange: 'volume', ratechange: 'speed', //seeking: 'beforeseek', seeked: 'seek', // abort: 'resume', // not fired loadeddata: 'ready', // loadedmetadata: 0, // canplay: 0, // error events // load: 0, // emptied: 0, // empty: 0, error: 'error', dataunavailable: 'error', webkitendfullscreen: !flowplayer.support.inlineVideo && 'unload' }; function round(val, per) { per = per || 100; return Math.round(val * per) / per; } function getType(type) { return /mpegurl/i.test(type) ? "application/x-mpegurl" : type; } function canPlay(type) { if (!/^(video|application)/i.test(type)) type = getType(type); return !!VIDEO.canPlayType(type).replace("no", ''); } function findFromSourcesByType(sources, type) { var arr = sources.filter(function (s) { return s.type === type; }); return arr.length ? arr[0] : null; } var videoTagCache; var createVideoTag = function (video, autoplay, preload, useCache) { if (typeof autoplay === 'undefined') autoplay = true; if (typeof preload === 'undefined') preload = 'none'; if (typeof useCache === 'undefined') useCache = true; if (useCache && videoTagCache) { videoTagCache.type = getType(video.type); videoTagCache.src = video.src; common.find('track', videoTagCache).forEach(common.removeNode); videoTagCache.removeAttribute('crossorigin'); return videoTagCache; } var el = document.createElement('video'); el.src = video.src; el.type = getType(video.type); el.className = 'fp-engine'; el.autoplay = autoplay ? 'autoplay' : false; el.preload = preload; el.setAttribute('x-webkit-airplay', 'allow'); if (useCache) videoTagCache = el; return el; }; var engine; engine = function (player, root) { var api = common.findDirect('video', root)[0] || common.find('.fp-player > video', root)[0], support = flowplayer.support, track = common.find("track", api)[0], conf = player.conf, self, timer, volumeLevel; /*jshint -W093 */ return self = { engineName: engine.engineName, pick: function (sources) { var source = (function () { if (support.video) { if (conf.videoTypePreference) { var mp4source = findFromSourcesByType(sources, conf.videoTypePreference); if (mp4source) return mp4source; } for (var i = 0, source; i < sources.length; i++) { if (canPlay(sources[i].type)) return sources[i]; } } })(); if (!source) return; if (typeof source.src === 'string') source.src = common.createAbsoluteUrl(source.src); return source; }, load: function (video) { var created = false, container = common.find('.fp-player', root)[0], reload = false; if (conf.splash && !api) { api = createVideoTag(video); common.prepend(container, api); created = true; } else if (!api) { api = createVideoTag(video, !!video.autoplay || !!conf.autoplay, conf.clip.preload || 'metadata', false); common.prepend(container, api); created = true; } else { ClassList(api).add('fp-engine'); common.find('source,track', api).forEach(common.removeNode); if (!player.conf.nativesubtitles) common.attr(api, 'crossorigin', false); reload = api.src === video.src; } if (!support.inlineVideo) { common.css(api, { position: 'absolute', top: '-9999em' }); } //TODO subtitles support // IE does not fire delegated timeupdate events bean.off(api, 'timeupdate', common.noop); bean.on(api, 'timeupdate', common.noop); common.prop(api, 'loop', !!(video.loop || conf.loop)); if (typeof volumeLevel !== 'undefined') { api.volume = volumeLevel; } if (player.video.src && video.src != player.video.src || video.index) common.attr(api, 'autoplay', 'autoplay'); api.src = video.src; api.type = video.type; self._listeners = listen(api, common.find("source", api).concat(api), video); // iPad (+others?) demands load() if (conf.clip.preload != 'none' && video.type != "mpegurl" || !support.zeropreload || !support.dataload) api.load(); if (created || reload) api.load(); if (api.paused && (video.autoplay || conf.autoplay)) api.play(); }, pause: function () { api.pause(); }, resume: function () { api.play(); }, speed: function (val) { api.playbackRate = val; }, seek: function (time) { try { var pausedState = player.paused; api.currentTime = time; if (pausedState) api.pause(); } catch (ignored) { } }, volume: function (level) { volumeLevel = level; if (api) { api.volume = level; } }, unload: function () { common.find('video.fp-engine', root).forEach(common.removeNode); if (!support.cachedVideoTag) videoTagCache = null; timer = clearInterval(timer); var instanceId = root.getAttribute('data-flowplayer-instance-id'); delete api.listeners[instanceId]; api = 0; if (self._listeners) Object.keys(self._listeners).forEach(function (typ) { self._listeners[typ].forEach(function (l) { root.removeEventListener(typ, l, true); }); }); } }; function listen(api, sources, video) { // listen only once var instanceId = root.getAttribute('data-flowplayer-instance-id'); if (api.listeners && api.listeners.hasOwnProperty(instanceId)) { api.listeners[instanceId] = video; return; } (api.listeners || (api.listeners = {}))[instanceId] = video; bean.on(sources, 'error', function (e) { try { if (canPlay(e.target.getAttribute('type'))) { player.trigger("error", [player, { code: 4, video: extend(video, { src: api.src, url: api.src })}]); } } catch (er) { // Most likely: https://bugzilla.mozilla.org/show_bug.cgi?id=208427 } }); player.on('shutdown', function () { bean.off(sources); }); var eventListeners = {}; Object.keys(EVENTS).forEach(function (type) { var flow = EVENTS[type]; if (!flow) return; var l = function (e) { video = api.listeners[instanceId]; if (!e.target || !ClassList(e.target).contains('fp-engine')) return; if (conf.debug && !/progress/.test(flow)) console.log(type, "->", flow, e); // no events if player not ready if (!player.ready && !/ready|error/.test(flow) || !flow || !common.find('video', root).length) { return; } var arg, vtype; if (flow === 'unload') { //Call player unload player.unload(); return; } var triggerEvent = function () { player.trigger(flow, [player, arg]); }; switch (flow) { case "ready": arg = extend(video, { duration: api.duration, width: api.videoWidth, height: api.videoHeight, url: api.currentSrc, src: api.currentSrc }); try { arg.seekable = !player.live && /mpegurl/i.test(video ? (video.type || '') : '') && api.duration || api.seekable && api.seekable.end(null); } catch (ignored) { } // buffer timer = timer || setInterval(function () { try { arg.buffer = api.buffered.end(null); } catch (ignored) { } if (arg.buffer) { if (round(arg.buffer, 1000) < round(arg.duration, 1000) && !arg.buffered) { player.trigger("buffer", e); } else if (!arg.buffered) { arg.buffered = true; player.trigger("buffer", e).trigger("buffered", e); clearInterval(timer); timer = 0; } } }, 250); if (!player.live && !arg.duration && !support.hlsDuration && type === "loadeddata") { var durationChanged = function () { arg.duration = api.duration; try { arg.seekable = api.seekable && api.seekable.end(null); } catch (ignored) { } triggerEvent(); api.removeEventListener('durationchange', durationChanged); ClassList(root).remove('is-live'); }; api.addEventListener('durationchange', durationChanged); // Ugly hack to handle broken Android devices var timeUpdated = function () { if (!player.ready && !api.duration) { // No duration even though the video already plays arg.duration = 0; ClassList(root).add('is-live'); // Make UI believe it's live triggerEvent(); } api.removeEventListener('timeupdate', timeUpdated); }; api.addEventListener('timeupdate', timeUpdated); return; } break; case "progress": case "seek": var dur = player.video.duration; if (api.currentTime > 0 || player.live) { arg = Math.max(api.currentTime, 0); } else if (flow == 'progress') { return; } break; case "speed": arg = round(api.playbackRate); break; case "volume": arg = round(api.volume); break; case "error": try { arg = (e.srcElement || e.originalTarget).error; arg.video = extend(video, { src: api.src, url: api.src }); } catch (er) { // Most likely https://bugzilla.mozilla.org/show_bug.cgi?id=208427 return; } } triggerEvent(); }; root.addEventListener(type, l, true); if (!eventListeners[type]) eventListeners[type] = []; eventListeners[type].push(l); }); return eventListeners; } }; engine.canPlay = function (type) { return flowplayer.support.video && canPlay(type); }; engine.engineName = 'html5'; flowplayer.engines.push(engine); }, { "../common": 1, "../flowplayer": 18, "bean": 20, "class-list": 22, "extend-object": 26}], 5: [function (_dereq_, module, exports) { 'use strict'; /* global _gat */ var flowplayer = _dereq_('../flowplayer'), TYPE_RE = _dereq_('./resolve').TYPE_RE, scriptjs = _dereq_('scriptjs'), bean = _dereq_('bean'); flowplayer(function (player, root) { var id = player.conf.analytics, time = 0, last = 0, timer; if (id) { // load Analytics script if needed if (typeof _gat == 'undefined') scriptjs("//google-analytics.com/ga.js"); var getTracker = function () { var tracker = _gat._getTracker(id); tracker._setAllowLinker(true); return tracker; }; var track = function track(e, api, video) { video = video || player.video; if (time && typeof _gat != 'undefined') { var tracker = getTracker(); // http://code.google.com/apis/analytics/docs/tracking/eventTrackerGuide.html tracker._trackEvent( "Video / Seconds played", player.engine.engineName + "/" + video.type, video.title || root.getAttribute("title") || video.src.split("/").slice(-1)[0].replace(TYPE_RE, ''), Math.round(time / 1000) ); time = 0; if (timer) { clearTimeout(timer); timer = null; } } }; player.bind("load unload", track).bind("progress", function () { if (!player.seeking) { time += last ? (+new Date() - last) : 0; last = +new Date(); } if (!timer) { timer = setTimeout(function () { timer = null; var tracker = getTracker(); tracker._trackEvent('Flowplayer heartbeat', 'Heartbeat', '', 0, true); }, 10 * 60 * 1000); // heartbeat every 10 minutes } }).bind("pause", function () { last = 0; }); player.bind('shutdown', function () { bean.off(window, 'unload', track); }); bean.on(window, 'unload', track); } }); }, { "../flowplayer": 18, "./resolve": 13, "bean": 20, "scriptjs": 29}], 6: [function (_dereq_, module, exports) { 'use strict'; var flowplayer = _dereq_('../flowplayer'), ClassList = _dereq_('class-list'), common = _dereq_('../common'), bean = _dereq_('bean'); flowplayer(function (player, root) { var CUE_RE = / ?cue\d+ ?/; var lastTime = 0, cuepointsDisabled = false; function setClass(index) { root.className = root.className.replace(CUE_RE, " "); if (index >= 0) ClassList(root).add('cue' + index); } var segments = {}, lastFiredSegment = -0.125; var fire = function (cue) { var idx = player.cuepoints.indexOf(cue); if (!isNaN(cue)) cue = { time: cue }; cue.index = idx; setClass(idx); player.trigger('cuepoint', [player, cue]); }; player.on("progress", function (e, api, time) { if (cuepointsDisabled) return; var segment = segmentForCue(time); while (lastFiredSegment < segment) { lastFiredSegment += 0.125; if (!segments[lastFiredSegment]) continue; segments[lastFiredSegment].forEach(fire); } }).on("unload", setClass) .on('beforeseek', function (ev) { setTimeout(function () { if (!ev.defaultPrevented) cuepointsDisabled = true; }); }).on("seek", function (ev, api, time) { setClass(); lastFiredSegment = segmentForCue(time || 0) - 0.125; cuepointsDisabled = false; if (!time && segments[0]) segments[0].forEach(fire); }).on('ready', function (e, api, video) { lastFiredSegment = -0.125; var cues = video.cuepoints || player.conf.cuepoints || []; player.setCuepoints(cues); }).on('finish', function () { lastFiredSegment = -0.125; }); if (player.conf.generate_cuepoints) { player.bind("load", function () { // clean up cuepoint elements of previous playlist items common.find('.fp-cuepoint', root).forEach(common.removeNode); }); } /** * API */ player.setCuepoints = function (cues) { player.cuepoints = []; segments = {}; cues.forEach(player.addCuepoint); return player; }; player.addCuepoint = function (cue) { if (!player.cuepoints) player.cuepoints = []; var segment = segmentForCue(cue); if (!segments[segment]) segments[segment] = []; segments[segment].push(cue); player.cuepoints.push(cue); if (player.conf.generate_cuepoints && cue.visible !== false) { var duration = player.video.duration, timeline = common.find('.fp-timeline', root)[0]; common.css(timeline, "overflow", "visible"); var time = cue.time || cue; if (time < 0) time = duration + time; var el = common.createElement('a', { className: 'fp-cuepoint fp-cuepoint' + (player.cuepoints.length - 1) }); common.css(el, "left", (time / duration * 100) + "%"); timeline.appendChild(el); bean.on(el, 'mousedown', function (e) { e.preventDefault(); e.stopPropagation(); player.seek(time); }); } return player; }; player.removeCuepoint = function (cue) { var idx = player.cuepoints.indexOf(cue), segment = segmentForCue(cue); if (idx === -1) return; player.cuepoints = player.cuepoints.slice(0, idx).concat(player.cuepoints.slice(idx + 1)); var sIdx = segments[segment].indexOf(cue); if (sIdx === -1) return; segments[segment] = segments[segment].slice(0, sIdx).concat(segments[segment].slice(sIdx + 1)); return player; }; function segmentForCue(cue) { var time = cue && !isNaN(cue.time) ? cue.time : cue; if (time < 0) time = player.video.duration + time; return Math.round(time / 0.125) * 0.125; } }); }, { "../common": 1, "../flowplayer": 18, "bean": 20, "class-list": 22}], 7: [function (_dereq_, module, exports) { 'use strict'; var flowplayer = _dereq_('../flowplayer'), bean = _dereq_('bean'), common = _dereq_('../common'), isObject = _dereq_('is-object'), extend = _dereq_('extend-object'), ClassList = _dereq_('class-list'); flowplayer(function (player, root) { // no embedding if (player.conf.embed === false) return; var conf = player.conf, ui = common.find('.fp-ui', root)[0], trigger = common.createElement('a', { "class": "fp-embed", title: 'Copy to your site' }), target = common.createElement('div', { 'class': 'fp-embed-code' }, ''), area = common.find("textarea", target)[0]; ui.appendChild(trigger); ui.appendChild(target); player.embedCode = function () { var embedConf = player.conf.embed || {}, video = player.video; if (embedConf.iframe) { var src = player.conf.embed.iframe, width = embedConf.width || video.width || common.width(root), height = embedConf.height || video.height || common.height(root); return ''; } var props = ['ratio', 'rtmp', 'live', 'bufferTime', 'origin', 'analytics', 'key', 'subscribe', 'swf', 'swfHls', 'embed', 'adaptiveRatio', 'logo']; if (embedConf.playlist) props.push('playlist'); var c = common.pick(player.conf, props); if (c.logo) c.logo = common.createElement('img', { src: c.logo }).src; if (!embedConf.playlist || !player.conf.playlist.length) c.clip = extend({}, player.conf.clip, common.pick(player.video, ['sources'])); var script = "var w=window,d=document,e;w._fpes||(w._fpes=[],w.addEventListener(\"load\",function(){var s=d.createElement(\"script\");s.src=\"//embed.flowplayer.org/6.0.5/embed.min.js\",d.body.appendChild(s)})),e=[].slice.call(d.getElementsByTagName(\"script\"),-1)[0].parentNode,w._fpes.push({e:e,l:\"$library\",c:$conf});\n".replace('$conf', JSON.stringify(c)).replace('$library', embedConf.library || ''); return 'Watch video!\n'.replace('$href', player.conf.origin || window.location.href).replace('$script', script); }; fptip(root, ".fp-embed", "is-embedding"); bean.on(root, 'click', '.fp-embed-code textarea', function () { area.select(); }); bean.on(root, 'click', '.fp-embed', function () { area.textContent = player.embedCode().replace(/(\r\n|\n|\r)/gm, ""); area.focus(); area.select(); }); }); var fptip = function (root, trigger, active) { function close() { rootClasses.remove(active); bean.off(document, '.st'); } var rootClasses = ClassList(root); bean.on(root, 'click', trigger || 'a', function (e) { e.preventDefault(); rootClasses.toggle(active); if (rootClasses.contains(active)) { bean.on(document, 'keydown.st', function (e) { if (e.which == 27) close(); }); bean.on(document, 'click.st', function (e) { if (!common.hasParent(e.target, '.' + active)) close(); }); } }); }; }, { "../common": 1, "../flowplayer": 18, "bean": 20, "class-list": 22, "extend-object": 26, "is-object": 28}], 8: [function (_dereq_, module, exports) { 'use strict'; /* global jQuery */ /** * Mimimal jQuery-like event emitter implementation */ module.exports = function (obj, elem) { if (!elem) elem = document.createElement('div'); //In this case we always want to trigger (Custom)Events on dom element var handlers = {}, eventArguments = {}; var listenEvent = function (type, hndlr, disposable) { var actualEvent = type.split('.')[0]; //Strip namespace var internalHandler = function (ev) { if (disposable) { elem.removeEventListener(actualEvent, internalHandler); handlers[type].splice(handlers[type].indexOf(internalHandler), 1); } var args = [ev].concat(eventArguments[ev.timeStamp + ev.type] || []); if (hndlr) hndlr.apply(undefined, args); }; elem.addEventListener(actualEvent, internalHandler); //Store handlers for unbinding if (!handlers[type]) handlers[type] = []; handlers[type].push(internalHandler); }; obj.on = obj.bind = function (typ, hndlr) { var types = typ.split(' '); types.forEach(function (type) { listenEvent(type, hndlr); }); return obj; //for chaining }; obj.one = function (typ, hndlr) { var types = typ.split(' '); types.forEach(function (type) { listenEvent(type, hndlr, true); }); return obj; }; // Function to check if all items in toBeContained array are in the containing array var containsAll = function (containing, toBeContained) { return toBeContained.filter(function (i) { return containing.indexOf(i) === -1; }).length === 0; }; obj.off = obj.unbind = function (typ) { var types = typ.split(' '); types.forEach(function (type) { var typeNameSpaces = type.split('.').slice(1), actualType = type.split('.')[0]; Object.keys(handlers).filter(function (t) { var handlerNamespaces = t.split('.').slice(1); return (!actualType || t.indexOf(actualType) === 0) && containsAll(handlerNamespaces, typeNameSpaces); }).forEach(function (t) { var registererHandlers = handlers[t], actualEvent = t.split('.')[0]; registererHandlers.forEach(function (hndlr) { elem.removeEventListener(actualEvent, hndlr); registererHandlers.splice(registererHandlers.indexOf(hndlr), 1); }); }); }); return obj; }; obj.trigger = function (typ, args, returnEvent) { if (!typ) return; args = (args || []).length ? args || [] : [args]; var event = document.createEvent('Event'), typStr; typStr = typ.type || typ; event.initEvent(typStr, false, true); if (Object.defineProperty) event.preventDefault = function () { Object.defineProperty(this, 'defaultPrevented', { get: function () { return true; } }); }; eventArguments[event.timeStamp + event.type] = args; elem.dispatchEvent(event); return returnEvent ? event : obj; }; }; module.exports.EVENTS = [ 'beforeseek', 'disable', 'error', 'finish', 'fullscreen', 'fullscreen-exit', 'load', 'mute', 'pause', 'progress', 'ready', 'resume', 'seek', 'speed', 'stop', 'unload', 'volume', 'boot', 'shutdown' ]; }, {}], 9: [function (_dereq_, module, exports) { 'use strict'; var flowplayer = _dereq_('../flowplayer'), bean = _dereq_('bean'), ClassList = _dereq_('class-list'), extend = _dereq_('extend-object'), common = _dereq_('../common'), VENDOR = flowplayer.support.browser.mozilla ? "moz" : "webkit", FS_ENTER = "fullscreen", FS_EXIT = "fullscreen-exit", FULL_PLAYER, FS_SUPPORT = flowplayer.support.fullscreen, FS_NATIVE_SUPPORT = typeof document.exitFullscreen == 'function', ua = navigator.userAgent.toLowerCase(), IS_SAFARI = /(safari)[ \/]([\w.]+)/.exec(ua) && !/(chrome)[ \/]([\w.]+)/.exec(ua); // esc button bean.on(document, "fullscreenchange.ffscr webkitfullscreenchange.ffscr mozfullscreenchange.ffscr MSFullscreenChange.ffscr", function (e) { var el = document.webkitCurrentFullScreenElement || document.mozFullScreenElement || document.fullscreenElement || document.msFullscreenElement || e.target; if (!FULL_PLAYER && (!el.parentNode || !el.parentNode.getAttribute('data-flowplayer-instance-id'))) return; var player = FULL_PLAYER || flowplayer(el.parentNode); if (el && !FULL_PLAYER) { FULL_PLAYER = player.trigger(FS_ENTER, [el]); } else { FULL_PLAYER.trigger(FS_EXIT, [FULL_PLAYER]); FULL_PLAYER = null; } }); flowplayer(function (player, root) { var wrapper = common.createElement('div', { className: 'fp-player' }); Array.prototype.map.call(root.children, common.identity).forEach(function (el) { if (common.matches(el, '.fp-ratio,script')) return; wrapper.appendChild(el); }); root.appendChild(wrapper); if (!player.conf.fullscreen) return; var win = window, scrollY, scrollX, rootClasses = ClassList(root); player.isFullscreen = false; player.fullscreen = function (flag) { if (player.disabled) return; if (flag === undefined) flag = !player.isFullscreen; if (flag) { scrollY = win.scrollY; scrollX = win.scrollX; } if (FS_SUPPORT) { if (flag) { ['requestFullScreen', 'webkitRequestFullScreen', 'mozRequestFullScreen', 'msRequestFullscreen'].forEach(function (fName) { if (typeof wrapper[fName] === 'function') { wrapper[fName](Element.ALLOW_KEYBOARD_INPUT); if (IS_SAFARI && !document.webkitCurrentFullScreenElement && !document.mozFullScreenElement) { // Element.ALLOW_KEYBOARD_INPUT not allowed wrapper[fName](); } return false; } }); } else { ['exitFullscreen', 'webkitCancelFullScreen', 'mozCancelFullScreen', 'msExitFullscreen'].forEach(function (fName) { if (typeof document[fName] === 'function') { document[fName](); return false; } }); } } else { player.trigger(flag ? FS_ENTER : FS_EXIT, [player]); } return player; }; var lastClick; player.on("mousedown.fs", function () { if (+new Date() - lastClick < 150 && player.ready) player.fullscreen(); lastClick = +new Date(); }); player.on(FS_ENTER, function (e) { rootClasses.add("is-fullscreen"); if (!FS_SUPPORT) common.css(root, 'position', 'fixed'); player.isFullscreen = true; }).on(FS_EXIT, function (e) { var oldOpacity; if (!FS_SUPPORT && player.engine === "html5") { oldOpacity = root.css('opacity') || ''; common.css(root, 'opacity', 0); } if (!FS_SUPPORT) common.css(root, 'position', ''); rootClasses.remove("is-fullscreen"); if (!FS_SUPPORT && player.engine === "html5") setTimeout(function () { root.css('opacity', oldOpacity); }); player.isFullscreen = false; win.scrollTo(scrollX, scrollY); }).on('unload', function () { if (player.isFullscreen) player.fullscreen(); }); player.on('shutdown', function () { FULL_PLAYER = null; }); }); }, { "../common": 1, "../flowplayer": 18, "bean": 20, "class-list": 22, "extend-object": 26}], 10: [function (_dereq_, module, exports) { 'use strict'; var flowplayer = _dereq_('../flowplayer'), bean = _dereq_('bean'), focused, focusedRoot, IS_HELP = "is-help", common = _dereq_('../common'), ClassList = _dereq_('class-list'); // keyboard. single global listener bean.on(document, "keydown.fp", function (e) { var el = focused, metaKeyPressed = e.ctrlKey || e.metaKey || e.altKey, key = e.which, conf = el && el.conf, focusedRootClasses = focusedRoot && ClassList(focusedRoot); if (!el || !conf.keyboard || el.disabled) return; // help dialog (shift key not truly required) if ([63, 187, 191].indexOf(key) != -1) { focusedRootClasses.toggle(IS_HELP); return false; } // close help / unload if (key == 27 && focusedRootClasses.contains(IS_HELP)) { focusedRootClasses.toggle(IS_HELP); return false; } if (!metaKeyPressed && el.ready) { e.preventDefault(); // slow motion / fast forward if (e.shiftKey) { if (key == 39) el.speed(true); else if (key == 37) el.speed(false); return; } // 1, 2, 3, 4 .. if (key < 58 && key > 47) return el.seekTo(key - 48); switch (key) { case 38: case 75: el.volume(el.volumeLevel + 0.15); break; // volume up case 40: case 74: el.volume(el.volumeLevel - 0.15); break; // volume down case 39: case 76: el.seeking = true; el.seek(true); break; // forward case 37: case 72: el.seeking = true; el.seek(false); break; // backward case 190: el.seekTo(); break; // to last seek position case 32: el.toggle(); break; // spacebar case 70: if (conf.fullscreen) el.fullscreen(); break; // toggle fullscreen case 77: el.mute(); break; // mute case 81: el.unload(); break; // unload/stop } } }); flowplayer(function (api, root) { // no keyboard configured if (!api.conf.keyboard) return; // hover bean.on(root, "mouseenter mouseleave", function (e) { focused = !api.disabled && e.type == 'mouseover' ? api : 0; if (focused) focusedRoot = root; }); var speedhelp = flowplayer.support.video && api.conf.engine !== "flash" && !!document.createElement('video').playbackRate ? '

shift + slower / faster

' : ''; // TODO: add to player-layout.html root.appendChild(common.createElement('div', { className: 'fp-help' }, '\ \
\

spaceplay / pause

\

qunload | stop

\

ffullscreen

' + speedhelp + '\
\
\

volume

\

mmute

\
\
\

seek

\

 . seek to previous\

126 seek to 10%, 20% … 60%

\
\ ')); if (api.conf.tooltip) { var ui = common.find('.fp-ui', root)[0]; ui.setAttribute('title', 'Hit ? for help'); bean.one(root, "mouseout.tip", '.fp-ui', function () { ui.removeAttribute('title'); }); } bean.on(root, 'click', '.fp-close', function () { ClassList(root).toggle(IS_HELP); }); api.bind('shutdown', function () { if (focusedRoot == root) focusedRoot = null; }); }); }, { "../common": 1, "../flowplayer": 18, "bean": 20, "class-list": 22}], 11: [function (_dereq_, module, exports) { 'use strict'; var flowplayer = _dereq_('../flowplayer'), isIeMobile = /IEMobile/.test(window.navigator.userAgent), ClassList = _dereq_('class-list'), common = _dereq_('../common'), bean = _dereq_('bean'), format = _dereq_('./ui').format, UA = window.navigator.userAgent; if (flowplayer.support.touch || isIeMobile) { flowplayer(function (player, root) { var isAndroid = /Android/.test(UA) && !/Firefox/.test(UA) && !/Opera/.test(UA), isSilk = /Silk/.test(UA), androidVer = isAndroid ? parseFloat(/Android\ (\d\.\d)/.exec(UA)[1], 10) : 0, rootClasses = ClassList(root); // custom load for android if (isAndroid && !isIeMobile) { if (!/Chrome/.test(UA) && androidVer < 4) { var originalLoad = player.load; player.load = function (video, callback) { var ret = originalLoad.apply(player, arguments); player.trigger('ready', [player, player.video]); return ret; }; } var timer, currentTime = 0; var resumeTimer = function (api) { timer = setInterval(function () { api.video.time = ++currentTime; api.trigger('progress', [api, currentTime]); }, 1000); }; player.bind('ready pause unload', function () { if (timer) { clearInterval(timer); timer = null; } }); player.bind('ready', function () { currentTime = 0; }); player.bind('resume', function (ev, api) { if (!api.live) return; if (currentTime) { return resumeTimer(api); } player.one('progress', function (ev, api, t) { if (t === 0) { // https://github.com/flowplayer/flowplayer/issues/727 resumeTimer(api); } }); }); } // hide volume if (!flowplayer.support.volume) { rootClasses.add("no-volume"); rootClasses.add("no-mute"); } rootClasses.add("is-touch"); if (player.sliders && player.sliders.timeline) player.sliders.timeline.disableAnimation(); if (!flowplayer.support.inlineVideo || player.conf.native_fullscreen) player.conf.nativesubtitles = true; // fake mouseover effect with click var hasMoved = false; bean.on(root, 'touchmove', function () { hasMoved = true; }); bean.on(root, 'touchend click', function (e) { if (hasMoved) { //not intentional, most likely scrolling hasMoved = false; return; } if (player.playing && !rootClasses.contains("is-mouseover")) { rootClasses.add("is-mouseover"); rootClasses.remove("is-mouseout"); e.preventDefault(); e.stopPropagation(); return; } if (!player.playing && !player.splash && rootClasses.contains('is-mouseout') && !rootClasses.contains('is-mouseover')) { setTimeout(function () { if (!player.playing && !player.splash) { player.resume(); } }, 400); } }); // native fullscreen if (player.conf.native_fullscreen && typeof document.createElement('video').webkitEnterFullScreen === 'function') { player.fullscreen = function () { var video = common.find('video.fp-engine', root)[0]; video.webkitEnterFullScreen(); bean.one(video, 'webkitendfullscreen', function () { common.prop(video, 'controls', true); common.prop(video, 'controls', false); }); }; } // Android browser gives video.duration == 1 until second 'timeupdate' event if (isAndroid || isSilk) player.bind("ready", function () { var video = common.find('video.fp-engine', root)[0]; bean.one(video, 'canplay', function () { video.play(); }); video.play(); player.bind("progress.dur", function () { var duration = video.duration; if (duration !== 1) { player.video.duration = duration; common.find(".fp-duration", root)[0].innerHTML = format(duration); player.unbind("progress.dur"); } }); }); }); } }, { "../common": 1, "../flowplayer": 18, "./ui": 17, "bean": 20, "class-list": 22}], 12: [function (_dereq_, module, exports) { 'use strict'; var flowplayer = _dereq_('../flowplayer'), extend = _dereq_('extend-object'), bean = _dereq_('bean'), ClassList = _dereq_('class-list'), common = _dereq_('../common'), Resolve = _dereq_('./resolve'), resolver = new Resolve(), $ = window.jQuery, externalRe = /^#/; flowplayer(function (player, root) { var conf = extend({ active: 'is-active', advance: true, query: ".fp-playlist a" }, player.conf), klass = conf.active, rootClasses = ClassList(root); // getters function els() { return common.find(conf.query, queryRoot()); } function queryRoot() { if (externalRe.test(conf.query)) return; return root; } function active() { return common.find(conf.query + "." + klass, queryRoot()); } player.play = function (i) { if (i === undefined) return player.resume(); if (typeof i === 'number' && !player.conf.playlist[i]) return player; else if (typeof i != 'number') return player.load.apply(null, arguments); var arg = extend({ index: i }, player.conf.playlist[i]); if (i === player.video.index) return player.load(arg, function () { player.resume(); }); player.off('resume.fromfirst'); // Don't start from beginning if clip explicitely chosen player.load(arg, function () { player.video.index = i; }); return player; }; player.next = function (e) { if (e) e.preventDefault(); var current = player.video.index; if (current != -1) { current = current === player.conf.playlist.length - 1 ? 0 : current + 1; player.play(current); } return player; }; player.prev = function (e) { if (e) e.preventDefault(); var current = player.video.index; if (current != -1) { current = current === 0 ? player.conf.playlist.length - 1 : current - 1; player.play(current); } return player; }; player.setPlaylist = function (items) { player.conf.playlist = items; delete player.video.index; generatePlaylist(); return player; }; player.addPlaylistItem = function (item) { return player.setPlaylist(player.conf.playlist.concat([item])); }; player.removePlaylistItem = function (idx) { var pl = player.conf.playlist; return player.setPlaylist(pl.slice(0, idx).concat(pl.slice(idx + 1))); }; bean.on(root, 'click', '.fp-next', player.next); bean.on(root, 'click', '.fp-prev', player.prev); if (conf.advance) { player.off("finish.pl").on("finish.pl", function (e, player) { // clip looping if (player.video.loop) return player.seek(0, function () { player.resume(); }); // next clip is found or loop var next = player.video.index >= 0 ? player.video.index + 1 : undefined; if (next < player.conf.playlist.length || conf.loop) { next = next === player.conf.playlist.length ? 0 : next; rootClasses.remove('is-finished'); setTimeout(function () { // Let other finish callbacks fire first player.play(next); }); // stop to last clip, play button starts from 1:st clip } else { // If we have multiple items in playlist, start from first if (player.conf.playlist.length > 1) player.one("resume.fromfirst", function () { player.play(0); return false; }); } }); } function generatePlaylist() { var plEl = common.find('.fp-playlist', root)[0]; if (!plEl) { plEl = common.createElement('div', { className: 'fp-playlist' }); var cntrls = common.find('.fp-next,.fp-prev', root); if (!cntrls.length) common.insertAfter(root, common.find('video', root)[0], plEl); else cntrls[0].parentElement.insertBefore(plEl, cntrls[0]); } plEl.innerHTML = ''; if (player.conf.playlist[0].length) { // FP5 style playlist player.conf.playlist = player.conf.playlist.map(function (itm) { if (typeof itm === 'string') { var type = itm.split(Resolve.TYPE_RE)[1]; return { sources: [{ type: type.toLowerCase() === 'm3u8' ? 'application/x-mpegurl' : 'video/' + type, src: itm }] }; } return { sources: itm.map(function (src) { var s = {}; Object.keys(src).forEach(function (k) { s.type = /mpegurl/i.test(k) ? 'application/x-mpegurl' : 'video/' + k; s.src = src[k]; }); return s; }) }; }); } player.conf.playlist.forEach(function (item, i) { var href = item.sources[0].src; plEl.appendChild(common.createElement('a', { href: href, 'data-index': i })); }); } var playlistInitialized = false; if (player.conf.playlist.length) { // playlist configured by javascript, generate playlist playlistInitialized = true; generatePlaylist(); if (!player.conf.clip || !player.conf.clip.sources.length) { player.conf.clip = player.conf.playlist[player.conf.startIndex || 0]; } } if (els().length && !playlistInitialized) { //generate playlist from existing elements player.conf.playlist = []; delete player.conf.startIndex; els().forEach(function (el) { var src = el.href; el.setAttribute('data-index', player.conf.playlist.length); var itm = resolver.resolve(src, player.conf.clip.sources); if ($) { extend(itm, $(el).data()); } player.conf.playlist.push(itm); }); } /* click -> play */ bean.on(externalRe.test(conf.query) ? document : root, "click", conf.query, function (e) { e.preventDefault(); var el = e.currentTarget; var toPlay = Number(el.getAttribute('data-index')); if (toPlay != -1) { player.play(toPlay); } }); // highlight function videoIndex(video) { if (typeof video.index !== 'undefined') return video.index; if (typeof player.video.index !== 'undefined') return player.video.index; return player.conf.startIndex || 0; } player.on("load", function (e, api, video) { if (!player.conf.playlist.length) return; var prev = active()[0], prevIndex = prev && prev.getAttribute('data-index'), index = video.index = videoIndex(video), el = common.find(conf.query + '[data-index="' + index + '"]', queryRoot())[0], is_last = index == player.conf.playlist.length - 1; if (prev) ClassList(prev).remove(klass); if (el) ClassList(el).add(klass); // index rootClasses.remove("video" + prevIndex); rootClasses.add("video" + index); common.toggleClass(root, "last-video", is_last); // video properties video.index = api.video.index = index; video.is_last = api.video.is_last = is_last; // without namespace callback called only once. unknown rason. }).on("unload.pl", function () { if (!player.conf.playlist.length) return; active().forEach(function (el) { ClassList(el).toggle(klass); }); player.conf.playlist.forEach(function (itm, i) { rootClasses.remove('video' + i); }); }); if (player.conf.playlist.length) { // disable single clip looping player.conf.loop = false; } }); }, { "../common": 1, "../flowplayer": 18, "./resolve": 13, "bean": 20, "class-list": 22, "extend-object": 26}], 13: [function (_dereq_, module, exports) { 'use strict'; var TYPE_RE = /\.(\w{3,4})(\?.*)?$/i, extend = _dereq_('extend-object'); function parseSource(el) { var src = el.attr("src"), type = el.attr("type") || "", suffix = src.split(TYPE_RE)[1]; type = type.toLowerCase(); return extend(el.data(), { src: src, suffix: suffix || type, type: type || suffix }); } function getType(typ) { if (/mpegurl/i.test(typ)) return 'application/x-mpegurl'; return 'video/' + typ; } /* Resolves video object from initial configuration and from load() method */ module.exports = function URLResolver() { var self = this; self.sourcesFromVideoTag = function (videoTag, $) { /* global $ */ var sources = []; // initial sources $("source", videoTag).each(function () { sources.push(parseSource($(this))); }); if (!sources.length && videoTag.length) sources.push(parseSource(videoTag)); return sources; }; self.resolve = function (video, sources) { if (!video) return { sources: sources }; if (typeof video == 'string') { video = { src: video, sources: [] }; video.sources = (sources || []).map(function (source) { var suffix = source.src.split(TYPE_RE)[1]; return { type: source.type, src: video.src.replace(TYPE_RE, '.' + suffix + "$2") }; }); } if (video instanceof Array) { video = { sources: video.map(function (src) { if (src.type && src.src) return src; return Object.keys(src).reduce(function (m, typ) { return extend(m, { type: getType(typ), src: src[typ] }); }, {}); }) }; } return video; }; }; module.exports.TYPE_RE = TYPE_RE; }, { "extend-object": 26}], 14: [function (_dereq_, module, exports) { 'use strict'; // skip IE policies // document.ondragstart = function () { return false; }; // var ClassList = _dereq_('class-list'), bean = _dereq_('bean'), common = _dereq_('../common'); // execute function every ms var throttle = function (fn, delay) { var locked; return function () { if (!locked) { fn.apply(this, arguments); locked = 1; setTimeout(function () { locked = 0; }, delay); } }; }; var slider = function (root, rtl) { var IS_IPAD = /iPad/.test(navigator.userAgent) && !/CriOS/.test(navigator.userAgent); var progress = common.lastChild(root), rootClasses = ClassList(root), progressClasses = ClassList(progress), disabled, offset, width, height, vertical, size, maxValue, max, skipAnimation = false, /* private */ calc = function () { offset = common.offset(root); width = common.width(root); height = common.height(root); /* exit from fullscreen can mess this up.*/ // vertical = height > width; size = vertical ? height : width; max = toDelta(maxValue); }, fire = function (value) { if (!disabled && value != api.value && (!maxValue || value < maxValue)) { bean.fire(root, 'slide', [value]); api.value = value; } }, mousemove = function (e) { var pageX = e.pageX || e.clientX; if (!pageX && e.originalEvent && e.originalEvent.touches && e.originalEvent.touches.length) { pageX = e.originalEvent.touches[0].pageX; } var delta = vertical ? e.pageY - offset.top : pageX - offset.left; delta = Math.max(0, Math.min(max || size, delta)); var value = delta / size; if (vertical) value = 1 - value; if (rtl) value = 1 - value; return move(value, 0, true); }, move = function (value, speed) { if (speed === undefined) { speed = 0; } if (value > 1) value = 1; var to = (Math.round(value * 1000) / 10) + "%"; if (!maxValue || value <= maxValue) { progressClasses.remove('animated'); if (skipAnimation) { progressClasses.remove('animated'); } else { progressClasses.add('animated'); common.css(progress, 'transition-duration', (speed || 0) + 'ms'); } common.css(progress, 'width', to); } return value; }, toDelta = function (value) { return Math.max(0, Math.min(size, vertical ? (1 - value) * height : value * width)); }, /* public */ api = { max: function (value) { maxValue = value; }, disable: function (flag) { disabled = flag; }, slide: function (value, speed, fireEvent) { calc(); if (fireEvent) fire(value); move(value, speed); }, // Should animation be handled via css disableAnimation: function (value, alsoCssAnimations) { skipAnimation = value !== false; common.toggleClass(root, 'no-animation', !!alsoCssAnimations); } }; calc(); // bound dragging into document bean.on(root, 'mousedown.sld touchstart', function (e) { e.preventDefault(); if (!disabled) { // begin --> recalculate. allows dynamic resizing of the slider var delayedFire = throttle(fire, 100); calc(); api.dragging = true; rootClasses.add('is-dragging'); fire(mousemove(e)); bean.on(document, 'mousemove.sld touchmove.sld', function (e) { e.preventDefault(); delayedFire(mousemove(e)); }); bean.one(document, 'mouseup touchend', function () { api.dragging = false; rootClasses.remove('is-dragging'); bean.off(document, 'mousemove.sld touchmove.sld'); }); } }); return api; }; module.exports = slider; }, { "../common": 1, "bean": 20, "class-list": 22}], 15: [function (_dereq_, module, exports) { 'use strict'; var flowplayer = _dereq_('../flowplayer'), common = _dereq_('../common'), bean = _dereq_('bean'), ClassList = _dereq_('class-list'); flowplayer.defaults.subtitleParser = function (txt) { var TIMECODE_RE = /^(([0-9]{2}:){1,2}[0-9]{2}[,.][0-9]{3}) --\> (([0-9]{2}:){1,2}[0-9]{2}[,.][0-9]{3})(.*)/; function seconds(timecode) { var els = timecode.split(':'); if (els.length == 2) els.unshift(0); return els[0] * 60 * 60 + els[1] * 60 + parseFloat(els[2].replace(',', '.')); } var entries = []; for (var i = 0, lines = txt.split("\n"), len = lines.length, entry = {}, title, timecode, text, cue; i < len; i++) { timecode = TIMECODE_RE.exec(lines[i]); if (timecode) { // title title = lines[i - 1]; // text text = "

" + lines[++i] + "


"; while (typeof lines[++i] === 'string' && lines[i].trim() && i < lines.length) text += "

" + lines[i] + "


"; // entry entry = { title: title, startTime: seconds(timecode[1]), endTime: seconds(timecode[3]), text: text }; entries.push(entry); } } return entries; }; flowplayer(function (p, root) { var wrapClasses, currentPoint, wrap, rootClasses = ClassList(root), subtitleControl; var createSubtitleControl = function () { subtitleControl = common.createElement('a', { className: 'fp-menu' }); var menu = common.createElement('ul', { className: 'fp-dropdown fp-dropup' }); menu.appendChild(common.createElement('li', { 'data-subtitle-index': -1 }, 'No subtitles')); (p.video.subtitles || []).forEach(function (st, i) { var srcLang = st.srclang || 'en', label = st.label || 'Default (' + srcLang + ')'; var item = common.createElement('li', { 'data-subtitle-index': i }, label); menu.appendChild(item); }); subtitleControl.appendChild(menu); common.find('.fp-controls', root)[0].appendChild(subtitleControl); return subtitleControl; }; bean.on(root, 'click', '.fp-menu', function (ev) { ClassList(subtitleControl).toggle('dropdown-open'); }); bean.on(root, 'click', '.fp-menu li[data-subtitle-index]', function (ev) { var idx = ev.target.getAttribute('data-subtitle-index'); if (idx === '-1') return p.disableSubtitles(); p.loadSubtitles(idx); }); var createUIElements = function () { var playerEl = common.find('.fp-player', root)[0]; wrap = common.find('.fp-subtitle', root)[0]; wrap = wrap || common.appendTo(common.createElement('div', { 'class': 'fp-subtitle' }), playerEl); Array.prototype.forEach.call(wrap.children, common.removeNode); wrapClasses = ClassList(wrap); common.find('.fp-menu', root).forEach(common.removeNode); createSubtitleControl(); }; p.on('ready', function (ev, player, video) { var conf = player.conf; if (flowplayer.support.subtitles && conf.nativesubtitles && player.engine.engineName == 'html5') { var setMode = function (mode) { var tracks = common.find('video', root)[0].textTracks; if (!tracks.length) return; tracks[0].mode = mode; }; if (!video.subtitles || !video.subtitles.length) return; var videoTag = common.find('video.fp-engine', root)[0]; if (video.subtitles.some(function (st) { return !common.isSameDomain(st.src); })) common.attr(videoTag, 'crossorigin', 'anonymous'); videoTag.textTracks.addEventListener('addtrack', function () { setMode('disabled'); setMode('showing'); }); video.subtitles.forEach(function (st) { videoTag.appendChild(common.createElement('track', { kind: 'subtitles', srclang: st.srclang || 'en', label: st.label || 'en', src: st.src, 'default': st['default'] })); }); return; } player.subtitles = []; createUIElements(); rootClasses.remove('has-menu'); p.disableSubtitles(); if (!video.subtitles || !video.subtitles.length) return; rootClasses.add('has-menu'); var defaultSubtitle = video.subtitles.filter(function (one) { return one['default']; })[0]; if (defaultSubtitle) player.loadSubtitles(video.subtitles.indexOf(defaultSubtitle)); }); p.bind("cuepoint", function (e, api, cue) { if (cue.subtitle) { currentPoint = cue.index; common.html(wrap, cue.subtitle.text); wrapClasses.add('fp-active'); } else if (cue.subtitleEnd) { wrapClasses.remove('fp-active'); currentPoint = cue.index; } }); p.bind("seek", function (e, api, time) { // Clear future subtitles if seeking backwards if (currentPoint && p.cuepoints[currentPoint] && p.cuepoints[currentPoint].time > time) { wrapClasses.remove('fp-active'); currentPoint = null; } (p.cuepoints || []).forEach(function (cue) { var entry = cue.subtitle; //Trigger cuepoint if start time before seek position and end time nonexistent or in the future if (entry && currentPoint != cue.index) { if (time >= cue.time && (!entry.endTime || time <= entry.endTime)) p.trigger("cuepoint", [p, cue]); } // Also handle cuepoints that act as the removal trigger else if (cue.subtitleEnd && time >= cue.time && cue.index == currentPoint + 1) p.trigger("cuepoint", [p, cue]); }); }); var setActiveSubtitleClass = function (idx) { common.toggleClass(common.find('li.active', root)[0], 'active'); common.toggleClass(common.find('li[data-subtitle-index="' + idx + '"]', root)[0], 'active'); }; p.disableSubtitles = function () { p.subtitles = []; (p.cuepoints || []).forEach(function (c) { if (c.subtitle || c.subtitleEnd) p.removeCuepoint(c); }); if (wrap) Array.prototype.forEach.call(wrap.children, common.removeNode); setActiveSubtitleClass(-1); return p; }; p.loadSubtitles = function (i) { //First remove possible old subtitles p.disableSubtitles(); var st = p.video.subtitles[i]; var url = st.src; if (!url) return; setActiveSubtitleClass(i); common.xhrGet(url, function (txt) { var entries = p.conf.subtitleParser(txt); entries.forEach(function (entry) { var cue = { time: entry.startTime, subtitle: entry, visible: false }; p.subtitles.push(entry); p.addCuepoint(cue); p.addCuepoint({ time: entry.endTime, subtitleEnd: entry.title, visible: false }); // initial cuepoint if (entry.startTime === 0 && !p.video.time) { p.trigger("cuepoint", [p, cue]); } }); }, function () { p.trigger("error", { code: 8, url: url }); return false; }); return p; }; }); }, { "../common": 1, "../flowplayer": 18, "bean": 20, "class-list": 22}], 16: [function (_dereq_, module, exports) { 'use strict'; /* global ActiveXObject */ var flowplayer = _dereq_('../flowplayer'), extend = _dereq_('extend-object'); (function () { var parseIpadVersion = function (UA) { var e = /Version\/(\d\.\d)/.exec(UA); if (e && e.length > 1) { return parseFloat(e[1], 10); } return 0; }; var createVideoTag = function () { var videoTag = document.createElement('video'); try { videoTag.loop = true; videoTag.autoplay = true; videoTag.preload = true; } catch (e) { } return videoTag; }; var b = {}, ua = navigator.userAgent.toLowerCase(), match = /(chrome)[ \/]([\w.]+)/.exec(ua) || /(safari)[ \/]([\w.]+)/.exec(ua) || /(webkit)[ \/]([\w.]+)/.exec(ua) || /(opera)(?:.*version|)[ \/]([\w.]+)/.exec(ua) || /(msie) ([\w.]+)/.exec(ua) || ua.indexOf("compatible") < 0 && /(mozilla)(?:.*? rv:([\w.]+)|)/.exec(ua) || []; if (match[1]) { b[match[1]] = true; b.version = match[2] || "0"; } var video = createVideoTag(), UA = navigator.userAgent, IS_IE = b.msie || /Trident\/7/.test(UA), IS_IPAD = /iPad|MeeGo/.test(UA) && !/CriOS/.test(UA), IS_IPAD_CHROME = /iPad/.test(UA) && /CriOS/.test(UA), IS_IPHONE = /iP(hone|od)/i.test(UA) && !/iPad/.test(UA) && !/IEMobile/i.test(UA), IS_ANDROID = /Android/.test(UA) && !/Firefox/.test(UA), IS_ANDROID_FIREFOX = /Android/.test(UA) && /Firefox/.test(UA), IS_SILK = /Silk/.test(UA), IS_WP = /IEMobile/.test(UA), WP_VER = IS_WP ? parseFloat(/Windows\ Phone\ (\d+\.\d+)/.exec(UA)[1], 10) : 0, IE_MOBILE_VER = IS_WP ? parseFloat(/IEMobile\/(\d+\.\d+)/.exec(UA)[1], 10) : 0, IPAD_VER = IS_IPAD ? parseIpadVersion(UA) : 0, ANDROID_VER = IS_ANDROID ? parseFloat(/Android\ (\d\.\d)/.exec(UA)[1], 10) : 0, s = extend(flowplayer.support, { browser: b, subtitles: !!video.addTextTrack, fullscreen: typeof document.webkitCancelFullScreen == 'function' && !/Mac OS X 10_5.+Version\/5\.0\.\d Safari/.test(UA) || document.mozFullScreenEnabled || typeof document.exitFullscreen == 'function' || typeof document.msExitFullscreen == 'function', inlineBlock: !(IS_IE && b.version < 8), touch: ('ontouchstart' in window), dataload: !IS_IPAD && !IS_IPHONE && !IS_WP, zeropreload: !IS_IE && !IS_ANDROID, // IE supports only preload=metadata volume: !IS_IPAD && !IS_ANDROID && !IS_IPHONE && !IS_SILK && !IS_IPAD_CHROME, cachedVideoTag: !IS_IPAD && !IS_IPHONE && !IS_IPAD_CHROME && !IS_WP, firstframe: !IS_IPHONE && !IS_IPAD && !IS_ANDROID && !IS_SILK && !IS_IPAD_CHROME && !IS_WP && !IS_ANDROID_FIREFOX, inlineVideo: !IS_IPHONE && (!IS_WP || (WP_VER >= 8.1 && IE_MOBILE_VER >= 11)) && (!IS_ANDROID || ANDROID_VER >= 3), hlsDuration: !IS_ANDROID && (!b.safari || IS_IPAD || IS_IPHONE || IS_IPAD_CHROME), seekable: !IS_IPAD && !IS_IPAD_CHROME }); // flashVideo try { var plugin = navigator.plugins["Shockwave Flash"], ver = IS_IE ? new ActiveXObject("ShockwaveFlash.ShockwaveFlash").GetVariable('$version') : plugin.description; if (!IS_IE && !plugin[0].enabledPlugin) s.flashVideo = false; else { ver = ver.split(/\D+/); if (ver.length && !ver[0]) ver = ver.slice(1); s.flashVideo = ver[0] > 9 || ver[0] == 9 && ver[3] >= 115; } //s.flashVideo = false; } catch (ignored) { } try { s.video = !!video.canPlayType; if (s.video) video.canPlayType('video/mp4'); } catch (e) { s.video = false; } // animation s.animation = (function () { var vendors = ['', 'Webkit', 'Moz', 'O', 'ms', 'Khtml'], el = document.createElement('p'); for (var i = 0; i < vendors.length; i++) { if (typeof el.style[vendors[i] + 'AnimationName'] !== 'undefined') return true; } })(); })(); }, { "../flowplayer": 18, "extend-object": 26}], 17: [function (_dereq_, module, exports) { 'use strict'; var flowplayer = _dereq_('../flowplayer'), common = _dereq_('../common'), ClassList = _dereq_('class-list'), bean = _dereq_('bean'), slider = _dereq_('./slider'); function zeropad(val) { val = parseInt(val, 10); return val >= 10 ? val : "0" + val; } // display seconds in hh:mm:ss format function format(sec) { sec = sec || 0; var h = Math.floor(sec / 3600), min = Math.floor(sec / 60); sec = sec - (min * 60); if (h >= 1) { min -= h * 60; return h + ":" + zeropad(min) + ":" + zeropad(sec); } return zeropad(min) + ":" + zeropad(sec); } flowplayer(function (api, root) { var conf = api.conf, support = flowplayer.support, hovertimer, rootClasses = ClassList(root); common.find('.fp-ratio,.fp-ui', root).forEach(common.removeNode); rootClasses.add('flowplayer'); root.appendChild(common.createElement('div', { className: 'fp-ratio' })); var ui = common.createElement('div', { className: 'fp-ui' }, '\
\ \ \

\
\ \
\
\
\
\
\
\ \
\
\
\
\
\
\ 00:00\ \ 00:00\
\

'.replace(/class="/g, 'class="fp-')); root.appendChild(ui); function find(klass) { return common.find(".fp-" + klass, root)[0]; } // widgets var progress = find("progress"), buffer = find("buffer"), elapsed = find("elapsed"), remaining = find("remaining"), waiting = find("waiting"), ratio = find("ratio"), speed = find("speed"), speedClasses = ClassList(speed), durationEl = find("duration"), controls = find('controls'), timelineTooltip = find('timeline-tooltip'), origRatio = common.css(ratio, 'padding-top'), // sliders timeline = find("timeline"), timelineApi = slider(timeline, api.rtl), volume = find("volume"), fullscreen = find("fullscreen"), volumeSlider = find("volumeslider"), volumeApi = slider(volumeSlider, api.rtl), noToggle = rootClasses.contains('fixed-controls') || rootClasses.contains('no-toggle'); timelineApi.disableAnimation(rootClasses.contains('is-touch')); api.sliders = api.sliders || {}; api.sliders.timeline = timelineApi; api.sliders.volume = volumeApi; // aspect ratio function setRatio(val) { common.css(ratio, 'padding-top', val * 100 + "%"); if (!support.inlineBlock) common.height(common.find('object', root)[0], common.height(root)); } function hover(flag) { if (flag) { rootClasses.add('is-mouseover'); rootClasses.remove('is-mouseout'); } else { rootClasses.add('is-mouseout'); rootClasses.remove('is-mouseover'); } } // loading... if (!support.animation) common.html(waiting, "

loading …

"); if (conf.ratio) setRatio(conf.ratio); // no fullscreen in IFRAME try { if (!conf.fullscreen) common.removeNode(fullscreen); } catch (e) { common.removeNode(fullscreen); } api.on("ready", function (ev, api, video) { var duration = api.video.duration; timelineApi.disable(api.disabled || !duration); if (conf.adaptiveRatio && !isNaN(video.height / video.width)) setRatio(video.height / video.width, true); // initial time & volume common.html([durationEl, remaining], format(duration)); // do we need additional space for showing hour common.toggleClass(root, 'is-long', duration >= 3600); volumeApi.slide(api.volumeLevel); if (api.engine.engineName === 'flash') timelineApi.disableAnimation(true, true); else timelineApi.disableAnimation(false); common.find('.fp-title', ui).forEach(common.removeNode); if (video.title) { common.prepend(ui, common.createElement('div', { className: 'fp-title' }, video.title)); } }).on("unload", function () { if (!origRatio && !conf.splash) common.css(ratio, "paddingTop", ""); timelineApi.slide(0); // buffer }).on("buffer", function () { var video = api.video, max = video.buffer / video.duration; if (!video.seekable && support.seekable) timelineApi.max(max); if (max < 1) common.css(buffer, "width", (max * 100) + "%"); else common.css(buffer, 'width', '100%'); }).on("speed", function (e, api, val) { common.text(speed, val + "x"); speedClasses.add('fp-hilite'); setTimeout(function () { speedClasses.remove('fp-hilite'); }, 1000); }).on("buffered", function () { common.css(buffer, 'width', '100%'); timelineApi.max(1); // progress }).on("progress", function () { var time = api.video.time, duration = api.video.duration; if (!timelineApi.dragging) { timelineApi.slide(time / duration, api.seeking ? 0 : 250); } common.html(elapsed, format(time)); common.html(remaining, '-' + format(duration - time)); }).on("finish resume seek", function (e) { common.toggleClass(root, "is-finished", e.type == "finish"); }).on("stop", function () { common.html(elapsed, format(0)); timelineApi.slide(0, 100); }).on("finish", function () { common.html(elapsed, format(api.video.duration)); timelineApi.slide(1, 100); rootClasses.remove('is-seeking'); // misc }).on("beforeseek", function () { //TODO FIXME //progress.stop(); }).on("volume", function () { volumeApi.slide(api.volumeLevel); }).on("disable", function () { var flag = api.disabled; timelineApi.disable(flag); volumeApi.disable(flag); common.toggleClass(root, 'is-disabled', api.disabled); }).on("mute", function (e, api, flag) { common.toggleClass(root, 'is-muted', flag); }).on("error", function (e, api, error) { common.removeClass(root, 'is-loading'); common.removeClass(root, 'is-seeking'); common.addClass(root, 'is-error'); if (error) { error.message = conf.errors[error.code]; api.error = true; var el = common.find('.fp-message', root)[0], video = error.video || api.video; common.find('h2', el)[0].innerHTML = (api.engine && api.engine.engineName || 'html5') + ": " + error.message; common.find('p', el)[0].innerHTML = error.url || video.url || video.src || conf.errorUrls[error.code]; api.off("mouseenter click"); rootClasses.remove('is-mouseover'); } // hover }); //Interaction events bean.on(root, "mouseenter mouseleave", function (e) { if (noToggle) return; var is_over = e.type == "mouseover", lastMove; // is-mouseover/out hover(is_over); if (is_over) { var reg = function () { hover(true); lastMove = new Date(); }; api.on("pause.x volume.x", reg); bean.on(root, 'mousemove.x', reg); hovertimer = setInterval(function () { if (new Date() - lastMove > conf.mouseoutTimeout) { hover(false); lastMove = new Date(); } }, 100); } else { bean.off(root, 'mousemove.x'); api.off("pause.x volume.x"); clearInterval(hovertimer); } // allow dragging over the player edge }); bean.on(root, "mouseleave", function () { if (timelineApi.dragging || volumeApi.dragging) { rootClasses.add('is-mouseover'); rootClasses.remove('is-mouseout'); } // click }); bean.on(root, "click.player", function (e) { if (api.disabled) return; var kls = ClassList(e.target); if (kls.contains('fp-ui') || kls.contains('fp-engine') || e.flash) { if (e.preventDefault) e.preventDefault(); return api.toggle(); } }); bean.on(root, 'mousemove', '.fp-timeline', function (ev) { var x = ev.pageX || ev.clientX, delta = x - common.offset(timeline).left, percentage = delta / common.width(timeline), seconds = percentage * api.video.duration; if (percentage < 0) return; common.html(timelineTooltip, format(seconds)); common.css(timelineTooltip, 'left', (x - common.offset(controls).left - common.width(timelineTooltip) / 2) + 'px'); }); bean.on(root, 'contextmenu', function (ev) { var o = common.offset(common.find('.fp-player', root)[0]), w = window, left = ev.clientX - (o.left + w.scrollX), t = ev.clientY - (o.top + w.scrollY); if (rootClasses.contains('is-flash-disabled')) return; var menu = common.find('.fp-context-menu', root)[0]; if (!menu) return; ev.preventDefault(); common.css(menu, { left: left + 'px', top: t + 'px', display: 'block' }); bean.on(root, 'click', '.fp-context-menu', function (ev) { ev.stopPropagation(); }); bean.on(document, 'click.outsidemenu', function (ev) { common.css(menu, 'display', 'none'); bean.off(document, 'click.outsidemenu'); }); }); api.on('flashdisabled', function () { rootClasses.add('is-flash-disabled'); api.one('ready progress', function () { rootClasses.remove('is-flash-disabled'); common.find('.fp-flash-disabled', root).forEach(common.removeNode); }); root.appendChild(common.createElement('div', { className: "fp-flash-disabled" }, 'Adobe Flash is disabled for this page, click player area to enable')); }); // poster -> background image if (conf.poster) common.css(root, 'background-image', "url(" + conf.poster + ")"); var bc = common.css(root, 'background-color'), has_bg = common.css(root, 'background-image') != "none" || bc && bc != "rgba(0, 0, 0, 0)" && bc != "transparent"; // is-poster class if (has_bg && !conf.splash) { if (!conf.poster) conf.poster = true; api.on("ready stop", function () { rootClasses.add("is-poster"); api.poster = true; api.one("progress", function () { rootClasses.remove("is-poster"); api.poster = false; }); }); } if (typeof conf.splash === 'string') { common.css(root, 'background-image', "url('" + conf.splash + "')"); } // default background color if not present if (!has_bg && api.forcedSplash) { common.css(root, "background-color", "#555"); } bean.on(root, 'click', '.fp-toggle, .fp-play', function () { if (api.disabled) return; api.toggle(); }); /* controlbar elements */ bean.on(root, 'click', '.fp-mute', function () { api.mute(); }); bean.on(root, 'click', '.fp-fullscreen', function () { api.fullscreen(); }); bean.on(root, 'click', '.fp-unload', function () { api.unload(); }); bean.on(timeline, 'slide', function (val) { api.seeking = true; api.seek(val * api.video.duration); }); bean.on(volumeSlider, 'slide', function (val) { api.volume(val); }); // times var time = find('time'); bean.on(root, 'click', '.fp-time', function () { ClassList(time).toggle('is-inverted'); }); hover(noToggle); api.on('shutdown', function () { bean.off(timeline); bean.off(volumeSlider); }); }); module.exports.format = format; }, { "../common": 1, "../flowplayer": 18, "./slider": 14, "bean": 20, "class-list": 22}], 18: [function (_dereq_, module, exports) { 'use strict'; var extend = _dereq_('extend-object'), isFunction = _dereq_('is-function'), ClassList = _dereq_('class-list'), bean = _dereq_('bean'), common = _dereq_('./common'), events = _dereq_('./ext/events'); var instances = [], extensions = [], UA = window.navigator.userAgent; var oldHandler = window.onbeforeunload; window.onbeforeunload = function (ev) { instances.forEach(function (api) { if (api.conf.splash) { api.unload(); } else { api.bind("error", function () { common.find('.flowplayer.is-error .fp-message').forEach(common.removeNode); }); } }); if (oldHandler) return oldHandler(ev); }; var supportLocalStorage = false; try { if (typeof window.localStorage == "object") { window.localStorage.flowplayerTestStorage = "test"; supportLocalStorage = true; } } catch (ignored) { } var isSafari = /Safari/.exec(navigator.userAgent) && !/Chrome/.exec(navigator.userAgent), m = /(\d+\.\d+) Safari/.exec(navigator.userAgent), safariVersion = m ? Number(m[1]) : 100; /* flowplayer() */ var flowplayer = module.exports = function (fn, opts, callback) { if (isFunction(fn)) return extensions.push(fn); if (typeof fn == 'number' || typeof fn === 'undefined') return instances[fn || 0]; if (fn.nodeType) { // Is an element if (fn.getAttribute('data-flowplayer-instance-id') !== null) { // Already flowplayer instance return instances[fn.getAttribute('data-flowplayer-instance-id')]; } if (!opts) return; // Can't initialize without data return initializePlayer(fn, opts, callback); } if (fn.jquery) return flowplayer(fn[0], opts, callback); if (typeof fn === 'string') { var el = common.find(fn)[0]; return el && flowplayer(el, opts, callback); } }; extend(flowplayer, { version: '6.0.5', engines: [], conf: {}, set: function (key, value) { if (typeof key === 'string') flowplayer.conf[key] = value; else extend(flowplayer.conf, key); }, support: {}, defaults: { debug: supportLocalStorage ? !!localStorage.flowplayerDebug : false, // true = forced playback disabled: false, fullscreen: window == window.top, // keyboard shortcuts keyboard: true, // default aspect ratio ratio: 9 / 16, adaptiveRatio: false, rtmp: 0, proxy: 'best', splash: false, live: false, swf: "/Scripts/flowplayer-6.0.5/flowplayer.swf", swfHls: "/Scripts/flowplayer-6.0.5/flowplayerhls.swf", speeds: [0.25, 0.5, 1, 1.5, 2], tooltip: true, mouseoutTimeout: 5000, // initial volume level volume: !supportLocalStorage ? 1 : localStorage.muted == "true" ? 0 : !isNaN(localStorage.volume) ? localStorage.volume || 1 : 1, // http://www.whatwg.org/specs/web-apps/current-work/multipage/the-video-element.html#error-codes errors: [ // video exceptions '', 'Video loading aborted', 'Network error', 'Video not properly encoded', 'Video file not found', // player exceptions 'Unsupported video', 'Skin not found', 'SWF file not found', 'Subtitles not found', 'Invalid RTMP URL', 'Unsupported video format. Try installing Adobe Flash.' ], errorUrls: ['', '', '', '', '', '', '', '', '', '', 'http://get.adobe.com/flashplayer/' ], playlist: [], hlsFix: isSafari && safariVersion < 8 }, // Expose utilities for plugins bean: bean, common: common, extend: extend }); // keep track of players var playerCount = 0; var URLResolver = _dereq_('./ext/resolve'); if (typeof window.jQuery !== 'undefined') { var $ = window.jQuery; // auto-install (any video tag with parent .flowplayer) $(function () { if (typeof $.fn.flowplayer == 'function') { $('.flowplayer:has(video,script[type="application/json"])').flowplayer(); } }); // jQuery plugin var videoTagConfig = function (videoTag) { if (!videoTag.length) return {}; var clip = videoTag.data() || {}, conf = {}; $.each(['autoplay', 'loop', 'preload', 'poster'], function (i, key) { var val = videoTag.attr(key); if (val !== undefined && ['autoplay', 'poster'].indexOf(key) !== -1) conf[key] = val ? val : true; else if (val !== undefined) clip[key] = val ? val : true; }); clip.subtitles = videoTag.find('track').map(function () { var tr = $(this); return { src: tr.attr('src'), kind: tr.attr('kind'), label: tr.attr('label'), srclang: tr.attr('srclang'), 'default': tr.prop('default') }; }).get(); clip.sources = (new URLResolver()).sourcesFromVideoTag(videoTag, $); return extend(conf, { clip: clip }); }; $.fn.flowplayer = function (opts, callback) { return this.each(function () { if (typeof opts == 'string') opts = { swf: opts }; if (isFunction(opts)) { callback = opts; opts = {}; } var root = $(this), scriptConf = root.find('script[type="application/json"]'), confObject = scriptConf.length ? JSON.parse(scriptConf.text()) : videoTagConfig(root.find('video')), conf = $.extend({}, opts || {}, confObject, root.data()); var api = initializePlayer(this, conf, callback); events.EVENTS.forEach(function (evName) { api.on(evName + '.jquery', function (ev) { root.trigger.call(root, ev.type, ev.detail && ev.detail.args); }); }); root.data('flowplayer', api); }); }; } function initializePlayer(element, opts, callback) { if (opts && opts.embed) opts.embed = extend({}, flowplayer.defaults.embed, opts.embed); var root = element, rootClasses = ClassList(root), conf = extend({}, flowplayer.defaults, flowplayer.conf, opts), storage = {}, lastSeekPosition, engine, url, urlResolver = new URLResolver(); rootClasses.add('is-loading'); try { storage = supportLocalStorage ? window.localStorage : storage; } catch (e) { } var isRTL = (root.currentStyle && root.currentStyle.direction === 'rtl') || (window.getComputedStyle && window.getComputedStyle(root, null) !== null && window.getComputedStyle(root, null).getPropertyValue('direction') === 'rtl'); if (isRTL) rootClasses.add('is-rtl'); /*** API ***/ var api = { // properties conf: conf, currentSpeed: 1, volumeLevel: conf.muted ? 0 : typeof conf.volume === "undefined" ? storage.volume * 1 : conf.volume, video: {}, // states disabled: false, finished: false, loading: false, muted: storage.muted == "true" || conf.muted, paused: false, playing: false, ready: false, splash: false, rtl: isRTL, // methods load: function (video, callback) { if (api.error || api.loading) return; api.video = {}; api.finished = false; video = video || conf.clip; // resolve URL video = extend({}, urlResolver.resolve(video, conf.clip.sources)); if (api.playing || api.engine) video.autoplay = true; var engineImpl = selectEngine(video); if (!engineImpl) return api.trigger("error", [api, { code: flowplayer.support.flashVideo ? 5 : 10}]); if (!engineImpl.engineName) throw new Error('engineName property of factory should be exposed'); if (!api.engine || engineImpl.engineName !== api.engine.engineName) { api.ready = false; if (api.engine) { api.engine.unload(); api.conf.autoplay = true; } engine = api.engine = engineImpl(api, root); api.one('ready', function () { engine.volume(api.volumeLevel); }); } extend(video, engine.pick(video.sources.filter(function (source) { // Filter out sources explicitely configured for some other engine if (!source.engine) return true; return source.engine === engine.engineName; }))); if (video.src) { var e = api.trigger('load', [api, video, engine], true); if (!e.defaultPrevented) { engine.load(video); // callback if (isFunction(video)) callback = video; if (callback) api.one("ready", callback); } else { api.loading = false; } } return api; }, pause: function (fn) { if (api.ready && !api.seeking && !api.loading) { engine.pause(); api.one("pause", fn); } return api; }, resume: function () { if (api.ready && api.paused) { engine.resume(); // Firefox (+others?) does not fire "resume" after finish if (api.finished) { api.trigger("resume", [api]); api.finished = false; } } return api; }, toggle: function () { return api.ready ? api.paused ? api.resume() : api.pause() : api.load(); }, /* seek(1.4) -> 1.4s time seek(true) -> 10% forward seek(false) -> 10% backward */ seek: function (time, callback) { if (api.ready && !api.live) { if (typeof time == "boolean") { var delta = api.video.duration * 0.1; time = api.video.time + (time ? delta : -delta); } time = lastSeekPosition = Math.min(Math.max(time, 0), api.video.duration - 0.1).toFixed(1); var ev = api.trigger('beforeseek', [api, time], true); if (!ev.defaultPrevented) { engine.seek(time); if (isFunction(callback)) api.one("seek", callback); } else { api.seeking = false; common.toggleClass(root, 'is-seeking', api.seeking); // remove loading indicator } } return api; }, /* seekTo(1) -> 10% seekTo(2) -> 20% seekTo(3) -> 30% ... seekTo() -> last position */ seekTo: function (position, fn) { var time = position === undefined ? lastSeekPosition : api.video.duration * 0.1 * position; return api.seek(time, fn); }, mute: function (flag, skipStore) { if (flag === undefined) flag = !api.muted; if (!skipStore) { storage.muted = api.muted = flag; storage.volume = !isNaN(storage.volume) ? storage.volume : conf.volume; // make sure storage has volume } api.volume(flag ? 0 : storage.volume, true); api.trigger("mute", [api, flag]); return api; }, volume: function (level, skipStore) { if (api.ready) { level = Math.min(Math.max(level, 0), 1); if (!skipStore) storage.volume = level; engine.volume(level); } return api; }, speed: function (val, callback) { if (api.ready) { // increase / decrease if (typeof val == "boolean") { val = conf.speeds[conf.speeds.indexOf(api.currentSpeed) + (val ? 1 : -1)] || api.currentSpeed; } engine.speed(val); if (callback) root.one("speed", callback); } return api; }, stop: function () { if (api.ready) { api.pause(); api.seek(0, function () { api.trigger("stop", [api]); }); } return api; }, unload: function () { if (!rootClasses.contains("is-embedding")) { if (conf.splash) { api.trigger("unload", [api]); if (engine) { engine.unload(); api.engine = engine = 0; } } else { api.stop(); } } return api; }, shutdown: function () { api.unload(); api.trigger('shutdown', [api]); bean.off(root); delete instances[root.getAttribute('data-flowplayer-instance-id')]; root.removeAttribute('data-flowplayer-instance-id'); }, disable: function (flag) { if (flag === undefined) flag = !api.disabled; if (flag != api.disabled) { api.disabled = flag; api.trigger("disable", flag); } return api; } }; api.conf = extend(api.conf, conf); /* event binding / unbinding */ events(api); var selectEngine = function (clip) { var engine; var engines = flowplayer.engines; if (conf.engine) { var eng = engines.filter(function (e) { return e.engineName === conf.engine; })[0]; if (eng && clip.sources.some(function (source) { if (source.engine && source.engine !== eng.engineName) return false; return eng.canPlay(source.type, api.conf); })) return eng; } if (conf.enginePreference) engines = flowplayer.engines.filter(function (one) { return conf.enginePreference.indexOf(one.engineName) > -1; }).sort(function (a, b) { return conf.enginePreference.indexOf(a.engineName) - conf.enginePreference.indexOf(b.engineName); }); clip.sources.some(function (source) { var eng = engines.filter(function (engine) { if (source.engine && source.engine !== engine.engineName) return false; return engine.canPlay(source.type, api.conf); }).shift(); if (eng) engine = eng; return !!eng; }); return engine; }; /*** Behaviour ***/ if (!root.getAttribute('data-flowplayer-instance-id')) { // Only bind once root.setAttribute('data-flowplayer-instance-id', playerCount++); api.on('boot', function () { // splash if (conf.splash || rootClasses.contains("is-splash") || !flowplayer.support.firstframe) { api.forcedSplash = !conf.splash && !rootClasses.contains("is-splash"); api.splash = conf.autoplay = true; if (!conf.splash) conf.splash = true; rootClasses.add("is-splash"); } if (conf.splash) common.find('video', root).forEach(common.removeNode); if (conf.live || rootClasses.contains('is-live')) { api.live = conf.live = true; rootClasses.add('is-live'); } // extensions extensions.forEach(function (e) { e(api, root); }); // instances instances.push(api); // start if (conf.splash) api.unload(); else api.load(); // disabled if (conf.disabled) api.disable(); // initial callback api.one("ready", callback); }).on("load", function (e, api, video) { // unload others if (conf.splash) { common.find('.flowplayer.is-ready,.flowplayer.is-loading').forEach(function (el) { var playerId = el.getAttribute('data-flowplayer-instance-id'); if (playerId === root.getAttribute('data-flowplayer-instance-id')) return; var a = instances[Number(playerId)]; if (a && a.conf.splash) a.unload(); }); } // loading rootClasses.add("is-loading"); api.loading = true; if (typeof video.live !== 'undefined') { common.toggleClass(root, 'is-live', video.live); api.live = video.live; } }).on("ready", function (e, api, video) { video.time = 0; api.video = video; rootClasses.remove("is-loading"); api.loading = false; // saved state if (api.muted) api.mute(true, true); else api.volume(api.volumeLevel); // see https://github.com/flowplayer/flowplayer/issues/479 var hlsFix = api.conf.hlsFix && /mpegurl/i.exec(video.type); common.toggleClass(root, 'hls-fix', !!hlsFix); }).on("unload", function (e) { rootClasses.remove("is-loading"); api.loading = false; }).on("ready unload", function (e) { var is_ready = e.type == "ready"; common.toggleClass(root, 'is-splash', !is_ready); common.toggleClass(root, 'is-ready', is_ready); api.ready = is_ready; api.splash = !is_ready; }).on("progress", function (e, api, time) { api.video.time = time; }).on("speed", function (e, api, val) { api.currentSpeed = val; }).on("volume", function (e, api, level) { api.volumeLevel = Math.round(level * 100) / 100; if (!api.muted) storage.volume = level; else if (level) api.mute(false); }).on("beforeseek seek", function (e) { api.seeking = e.type == "beforeseek"; common.toggleClass(root, 'is-seeking', api.seeking); }).on("ready pause resume unload finish stop", function (e, _api, video) { // PAUSED: pause / finish api.paused = /pause|finish|unload|stop/.test(e.type); api.paused = api.paused || e.type === 'ready' && !conf.autoplay && !api.playing; // the opposite api.playing = !api.paused; // CSS classes common.toggleClass(root, 'is-paused', api.paused); common.toggleClass(root, 'is-playing', api.playing); // sanity check if (!api.load.ed) api.pause(); }).on("finish", function (e) { api.finished = true; }).on("error", function () { }); } // boot api.trigger('boot', [api, root]); return api; } }, { "./common": 1, "./ext/events": 8, "./ext/resolve": 13, "bean": 20, "class-list": 22, "extend-object": 26, "is-function": 27}], 19: [function (_dereq_, module, exports) { //Flowplayer with extensions _dereq_('es5-shim'); var flowplayer = module.exports = _dereq_('./flowplayer'); // //Support needed before engines _dereq_('./ext/support'); //Engines _dereq_('./engine/embed'); _dereq_('./engine/html5'); _dereq_('./engine/flash'); //Extensions //require('./ext/slider'); //TODO enable _dereq_('./ext/ui'); _dereq_('./ext/keyboard'); _dereq_('./ext/playlist'); _dereq_('./ext/cuepoint'); _dereq_('./ext/subtitle'); _dereq_('./ext/analytics'); _dereq_('./ext/embed'); //Have to add fullscreen last _dereq_('./ext/fullscreen'); _dereq_('./ext/mobile'); flowplayer(function (e, o) { function a(e) { var o = document.createElement("a"); return o.href = e, t.hostname(o.hostname) } var n = function (e, o) { var a = e.className.split(" "); -1 === a.indexOf(o) && (e.className += " " + o) }, r = function (e) { return "none" !== window.getComputedStyle(e).display }, l = e.conf, t = flowplayer.common, i = t.createElement, d = l.swf.indexOf("flowplayer.org") && l.e && o.getAttribute("data-origin"), p = d ? a(d) : t.hostname(), s = (document, l.key); "file:" == location.protocol && (p = "localhost"), e.load.ed = 1, l.hostname = p, l.origin = d || location.href, d && n(o, "is-embedded"), "string" == typeof s && (s = s.split(/,\s*/)); var f = function (e, a) { var n = i("a", { href: a, className: "fp-brand" }); n.innerHTML = e, t.find(".fp-controls", o)[0].appendChild(n) }; if (s && "function" == typeof key_check && key_check(s, p)) { if (l.logo) { var c = t.find(".fp-player", o)[0], h = i("a", { className: "fp-logo" }); d && (h.href = d), l.embed && l.embed.popup && (h.target = "_blank"); var y = i("img", { src: l.logo }); h.appendChild(y), (c || o).appendChild(h) } l.brand && d || l.brand && l.brand.showOnOrigin ? f(l.brand.text || l.brand, d || location.href) : t.addClass(o, "no-brand") } else { f("flowplayer", "http://flowplayer.org"); var h = i("a", { href: "http://flowplayer.org" }); o.appendChild(h); var u = i("div", { className: "fp-context-menu" }, ''), g = window.location.href.indexOf("localhost"), c = t.find(".fp-player", o)[0]; 7 !== g && (c || o).appendChild(u), e.on("pause resume finish unload ready", function (e, a) { t.removeClass(o, "no-brand"); var n = -1; if (a.video.src) for (var l = [["org", "flowplayer", "drive"], ["org", "flowplayer", "my"], ["org", "flowplayer", "cdn"]], i = 0; i < l.length && (n = a.video.src.indexOf("://" + l[i].reverse().join(".")), -1 === n); i++); if ((4 === n || 5 === n) && t.addClass(o, "no-brand"), /pause|resume/.test(e.type) && "flash" != a.engine.engineName && 4 != n && 5 != n) { var d = { display: "block", position: "absolute", left: "16px", bottom: "46px", zIndex: 99999, width: "100px", height: "20px", backgroundImage: "url(" + [".png", "logo", "/", ".net", ".cloudfront", "d32wqyuo10o653", "//"].reverse().join("") + ")" }; for (var p in d) d.hasOwnProperty(p) && (h.style[p] = d[p]); a.load.ed = r(h) && (7 === g || u.parentNode == o || u.parentNode == c) && !t.hasClass(o, "no-brand"), a.load.ed || a.pause() } else h.style.display = "none" }) } }); }, { "./engine/embed": 2, "./engine/flash": 3, "./engine/html5": 4, "./ext/analytics": 5, "./ext/cuepoint": 6, "./ext/embed": 7, "./ext/fullscreen": 9, "./ext/keyboard": 10, "./ext/mobile": 11, "./ext/playlist": 12, "./ext/subtitle": 15, "./ext/support": 16, "./ext/ui": 17, "./flowplayer": 18, "es5-shim": 25}], 20: [function (_dereq_, module, exports) { /*! * Bean - copyright (c) Jacob Thornton 2011-2012 * https://github.com/fat/bean * MIT license */ (function (name, context, definition) { if (typeof module != 'undefined' && module.exports) module.exports = definition() else if (typeof define == 'function' && define.amd) define(definition) else context[name] = definition() })('bean', this, function (name, context) { name = name || 'bean' context = context || this var win = window , old = context[name] , namespaceRegex = /[^\.]*(?=\..*)\.|.*/ , nameRegex = /\..*/ , addEvent = 'addEventListener' , removeEvent = 'removeEventListener' , doc = document || {} , root = doc.documentElement || {} , W3C_MODEL = root[addEvent] , eventSupport = W3C_MODEL ? addEvent : 'attachEvent' , ONE = {} // singleton for quick matching making add() do one() , slice = Array.prototype.slice , str2arr = function (s, d) { return s.split(d || ' ') } , isString = function (o) { return typeof o == 'string' } , isFunction = function (o) { return typeof o == 'function' } // events that we consider to be 'native', anything not in this list will // be treated as a custom event , standardNativeEvents = 'click dblclick mouseup mousedown contextmenu ' + // mouse buttons 'mousewheel mousemultiwheel DOMMouseScroll ' + // mouse wheel 'mouseover mouseout mousemove selectstart selectend ' + // mouse movement 'keydown keypress keyup ' + // keyboard 'orientationchange ' + // mobile 'focus blur change reset select submit ' + // form elements 'load unload beforeunload resize move DOMContentLoaded ' + // window 'readystatechange message ' + // window 'error abort scroll ' // misc // element.fireEvent('onXYZ'... is not forgiving if we try to fire an event // that doesn't actually exist, so make sure we only do these on newer browsers , w3cNativeEvents = 'show ' + // mouse buttons 'input invalid ' + // form elements 'touchstart touchmove touchend touchcancel ' + // touch 'gesturestart gesturechange gestureend ' + // gesture 'textinput ' + // TextEvent 'readystatechange pageshow pagehide popstate ' + // window 'hashchange offline online ' + // window 'afterprint beforeprint ' + // printing 'dragstart dragenter dragover dragleave drag drop dragend ' + // dnd 'loadstart progress suspend emptied stalled loadmetadata ' + // media 'loadeddata canplay canplaythrough playing waiting seeking ' + // media 'seeked ended durationchange timeupdate play pause ratechange ' + // media 'volumechange cuechange ' + // media 'checking noupdate downloading cached updateready obsolete ' // appcache // convert to a hash for quick lookups , nativeEvents = (function (hash, events, i) { for (i = 0; i < events.length; i++) events[i] && (hash[events[i]] = 1) return hash } ({}, str2arr(standardNativeEvents + (W3C_MODEL ? w3cNativeEvents : '')))) // custom events are events that we *fake*, they are not provided natively but // we can use native events to generate them , customEvents = (function () { var isAncestor = 'compareDocumentPosition' in root ? function (element, container) { return container.compareDocumentPosition && (container.compareDocumentPosition(element) & 16) === 16 } : 'contains' in root ? function (element, container) { container = container.nodeType === 9 || container === window ? root : container return container !== element && container.contains(element) } : function (element, container) { while (element = element.parentNode) if (element === container) return 1 return 0 } , check = function (event) { var related = event.relatedTarget return !related ? related == null : (related !== this && related.prefix !== 'xul' && !/document/.test(this.toString()) && !isAncestor(related, this)) } return { mouseenter: { base: 'mouseover', condition: check } , mouseleave: { base: 'mouseout', condition: check } , mousewheel: { base: /Firefox/.test(navigator.userAgent) ? 'DOMMouseScroll' : 'mousewheel' } } } ()) // we provide a consistent Event object across browsers by taking the actual DOM // event object and generating a new one from its properties. , Event = (function () { // a whitelist of properties (for different event types) tells us what to check for and copy var commonProps = str2arr('altKey attrChange attrName bubbles cancelable ctrlKey currentTarget ' + 'detail eventPhase getModifierState isTrusted metaKey relatedNode relatedTarget shiftKey ' + 'srcElement target timeStamp type view which propertyName') , mouseProps = commonProps.concat(str2arr('button buttons clientX clientY dataTransfer ' + 'fromElement offsetX offsetY pageX pageY screenX screenY toElement')) , mouseWheelProps = mouseProps.concat(str2arr('wheelDelta wheelDeltaX wheelDeltaY wheelDeltaZ ' + 'axis')) // 'axis' is FF specific , keyProps = commonProps.concat(str2arr('char charCode key keyCode keyIdentifier ' + 'keyLocation location')) , textProps = commonProps.concat(str2arr('data')) , touchProps = commonProps.concat(str2arr('touches targetTouches changedTouches scale rotation')) , messageProps = commonProps.concat(str2arr('data origin source')) , stateProps = commonProps.concat(str2arr('state')) , overOutRegex = /over|out/ // some event types need special handling and some need special properties, do that all here , typeFixers = [ { // key events reg: /key/i , fix: function (event, newEvent) { newEvent.keyCode = event.keyCode || event.which return keyProps } } , { // mouse events reg: /click|mouse(?!(.*wheel|scroll))|menu|drag|drop/i , fix: function (event, newEvent, type) { newEvent.rightClick = event.which === 3 || event.button === 2 newEvent.pos = { x: 0, y: 0 } if (event.pageX || event.pageY) { newEvent.clientX = event.pageX newEvent.clientY = event.pageY } else if (event.clientX || event.clientY) { newEvent.clientX = event.clientX + doc.body.scrollLeft + root.scrollLeft newEvent.clientY = event.clientY + doc.body.scrollTop + root.scrollTop } if (overOutRegex.test(type)) { newEvent.relatedTarget = event.relatedTarget || event[(type == 'mouseover' ? 'from' : 'to') + 'Element'] } return mouseProps } } , { // mouse wheel events reg: /mouse.*(wheel|scroll)/i , fix: function () { return mouseWheelProps } } , { // TextEvent reg: /^text/i , fix: function () { return textProps } } , { // touch and gesture events reg: /^touch|^gesture/i , fix: function () { return touchProps } } , { // message events reg: /^message$/i , fix: function () { return messageProps } } , { // popstate events reg: /^popstate$/i , fix: function () { return stateProps } } , { // everything else reg: /.*/ , fix: function () { return commonProps } } ] , typeFixerMap = {} // used to map event types to fixer functions (above), a basic cache mechanism , Event = function (event, element, isNative) { if (!arguments.length) return event = event || ((element.ownerDocument || element.document || element).parentWindow || win).event this.originalEvent = event this.isNative = isNative this.isBean = true if (!event) return var type = event.type , target = event.target || event.srcElement , i, l, p, props, fixer this.target = target && target.nodeType === 3 ? target.parentNode : target if (isNative) { // we only need basic augmentation on custom events, the rest expensive & pointless fixer = typeFixerMap[type] if (!fixer) { // haven't encountered this event type before, map a fixer function for it for (i = 0, l = typeFixers.length; i < l; i++) { if (typeFixers[i].reg.test(type)) { // guaranteed to match at least one, last is .* typeFixerMap[type] = fixer = typeFixers[i].fix break } } } props = fixer(event, this, type) for (i = props.length; i--; ) { if (!((p = props[i]) in this) && p in event) this[p] = event[p] } } } // preventDefault() and stopPropagation() are a consistent interface to those functions // on the DOM, stop() is an alias for both of them together Event.prototype.preventDefault = function () { if (this.originalEvent.preventDefault) this.originalEvent.preventDefault() else this.originalEvent.returnValue = false } Event.prototype.stopPropagation = function () { if (this.originalEvent.stopPropagation) this.originalEvent.stopPropagation() else this.originalEvent.cancelBubble = true } Event.prototype.stop = function () { this.preventDefault() this.stopPropagation() this.stopped = true } // stopImmediatePropagation() has to be handled internally because we manage the event list for // each element // note that originalElement may be a Bean#Event object in some situations Event.prototype.stopImmediatePropagation = function () { if (this.originalEvent.stopImmediatePropagation) this.originalEvent.stopImmediatePropagation() this.isImmediatePropagationStopped = function () { return true } } Event.prototype.isImmediatePropagationStopped = function () { return this.originalEvent.isImmediatePropagationStopped && this.originalEvent.isImmediatePropagationStopped() } Event.prototype.clone = function (currentTarget) { //TODO: this is ripe for optimisation, new events are *expensive* // improving this will speed up delegated events var ne = new Event(this, this.element, this.isNative) ne.currentTarget = currentTarget return ne } return Event } ()) // if we're in old IE we can't do onpropertychange on doc or win so we use doc.documentElement for both , targetElement = function (element, isNative) { return !W3C_MODEL && !isNative && (element === doc || element === win) ? root : element } /** * Bean maintains an internal registry for event listeners. We don't touch elements, objects * or functions to identify them, instead we store everything in the registry. * Each event listener has a RegEntry object, we have one 'registry' for the whole instance. */ , RegEntry = (function () { // each handler is wrapped so we can handle delegation and custom events var wrappedHandler = function (element, fn, condition, args) { var call = function (event, eargs) { return fn.apply(element, args ? slice.call(eargs, event ? 0 : 1).concat(args) : eargs) } , findTarget = function (event, eventElement) { return fn.__beanDel ? fn.__beanDel.ft(event.target, element) : eventElement } , handler = condition ? function (event) { var target = findTarget(event, this) // deleated event if (condition.apply(target, arguments)) { if (event) event.currentTarget = target return call(event, arguments) } } : function (event) { if (fn.__beanDel) event = event.clone(findTarget(event)) // delegated event, fix the fix return call(event, arguments) } handler.__beanDel = fn.__beanDel return handler } , RegEntry = function (element, type, handler, original, namespaces, args, root) { var customType = customEvents[type] , isNative if (type == 'unload') { // self clean-up handler = once(removeListener, element, type, handler, original) } if (customType) { if (customType.condition) { handler = wrappedHandler(element, handler, customType.condition, args) } type = customType.base || type } this.isNative = isNative = nativeEvents[type] && !!element[eventSupport] this.customType = !W3C_MODEL && !isNative && type this.element = element this.type = type this.original = original this.namespaces = namespaces this.eventType = W3C_MODEL || isNative ? type : 'propertychange' this.target = targetElement(element, isNative) this[eventSupport] = !!this.target[eventSupport] this.root = root this.handler = wrappedHandler(element, handler, null, args) } // given a list of namespaces, is our entry in any of them? RegEntry.prototype.inNamespaces = function (checkNamespaces) { var i, j, c = 0 if (!checkNamespaces) return true if (!this.namespaces) return false for (i = checkNamespaces.length; i--; ) { for (j = this.namespaces.length; j--; ) { if (checkNamespaces[i] == this.namespaces[j]) c++ } } return checkNamespaces.length === c } // match by element, original fn (opt), handler fn (opt) RegEntry.prototype.matches = function (checkElement, checkOriginal, checkHandler) { return this.element === checkElement && (!checkOriginal || this.original === checkOriginal) && (!checkHandler || this.handler === checkHandler) } return RegEntry } ()) , registry = (function () { // our map stores arrays by event type, just because it's better than storing // everything in a single array. // uses '$' as a prefix for the keys for safety and 'r' as a special prefix for // rootListeners so we can look them up fast var map = {} // generic functional search of our registry for matching listeners, // `fn` returns false to break out of the loop , forAll = function (element, type, original, handler, root, fn) { var pfx = root ? 'r' : '$' if (!type || type == '*') { // search the whole registry for (var t in map) { if (t.charAt(0) == pfx) { forAll(element, t.substr(1), original, handler, root, fn) } } } else { var i = 0, l, list = map[pfx + type], all = element == '*' if (!list) return for (l = list.length; i < l; i++) { if ((all || list[i].matches(element, original, handler)) && !fn(list[i], list, i, type)) return } } } , has = function (element, type, original, root) { // we're not using forAll here simply because it's a bit slower and this // needs to be fast var i, list = map[(root ? 'r' : '$') + type] if (list) { for (i = list.length; i--; ) { if (!list[i].root && list[i].matches(element, original, null)) return true } } return false } , get = function (element, type, original, root) { var entries = [] forAll(element, type, original, null, root, function (entry) { return entries.push(entry) }) return entries } , put = function (entry) { var has = !entry.root && !this.has(entry.element, entry.type, null, false) , key = (entry.root ? 'r' : '$') + entry.type ; (map[key] || (map[key] = [])).push(entry) return has } , del = function (entry) { forAll(entry.element, entry.type, null, entry.handler, entry.root, function (entry, list, i) { list.splice(i, 1) entry.removed = true if (list.length === 0) delete map[(entry.root ? 'r' : '$') + entry.type] return false }) } // dump all entries, used for onunload , entries = function () { var t, entries = [] for (t in map) { if (t.charAt(0) == '$') entries = entries.concat(map[t]) } return entries } return { has: has, get: get, put: put, del: del, entries: entries } } ()) // we need a selector engine for delegated events, use querySelectorAll if it exists // but for older browsers we need Qwery, Sizzle or similar , selectorEngine , setSelectorEngine = function (e) { if (!arguments.length) { selectorEngine = doc.querySelectorAll ? function (s, r) { return r.querySelectorAll(s) } : function () { throw new Error('Bean: No selector engine installed') // eeek } } else { selectorEngine = e } } // we attach this listener to each DOM event that we need to listen to, only once // per event type per DOM element , rootListener = function (event, type) { if (!W3C_MODEL && type && event && event.propertyName != '_on' + type) return var listeners = registry.get(this, type || event.type, null, false) , l = listeners.length , i = 0 event = new Event(event, this, true) if (type) event.type = type // iterate through all handlers registered for this type, calling them unless they have // been removed by a previous handler or stopImmediatePropagation() has been called for (; i < l && !event.isImmediatePropagationStopped(); i++) { if (!listeners[i].removed) listeners[i].handler.call(this, event) } } // add and remove listeners to DOM elements , listener = W3C_MODEL ? function (element, type, add) { // new browsers element[add ? addEvent : removeEvent](type, rootListener, false) } : function (element, type, add, custom) { // IE8 and below, use attachEvent/detachEvent and we have to piggy-back propertychange events // to simulate event bubbling etc. var entry if (add) { registry.put(entry = new RegEntry( element , custom || type , function (event) { // handler rootListener.call(element, event, custom) } , rootListener , null , null , true // is root )) if (custom && element['_on' + custom] == null) element['_on' + custom] = 0 entry.target.attachEvent('on' + entry.eventType, entry.handler) } else { entry = registry.get(element, custom || type, rootListener, true)[0] if (entry) { entry.target.detachEvent('on' + entry.eventType, entry.handler) registry.del(entry) } } } , once = function (rm, element, type, fn, originalFn) { // wrap the handler in a handler that does a remove as well return function () { fn.apply(this, arguments) rm(element, type, originalFn) } } , removeListener = function (element, orgType, handler, namespaces) { var type = orgType && orgType.replace(nameRegex, '') , handlers = registry.get(element, type, null, false) , removed = {} , i, l for (i = 0, l = handlers.length; i < l; i++) { if ((!handler || handlers[i].original === handler) && handlers[i].inNamespaces(namespaces)) { // TODO: this is problematic, we have a registry.get() and registry.del() that // both do registry searches so we waste cycles doing this. Needs to be rolled into // a single registry.forAll(fn) that removes while finding, but the catch is that // we'll be splicing the arrays that we're iterating over. Needs extra tests to // make sure we don't screw it up. @rvagg registry.del(handlers[i]) if (!removed[handlers[i].eventType] && handlers[i][eventSupport]) removed[handlers[i].eventType] = { t: handlers[i].eventType, c: handlers[i].type } } } // check each type/element for removed listeners and remove the rootListener where it's no longer needed for (i in removed) { if (!registry.has(element, removed[i].t, null, false)) { // last listener of this type, remove the rootListener listener(element, removed[i].t, false, removed[i].c) } } } // set up a delegate helper using the given selector, wrap the handler function , delegate = function (selector, fn) { //TODO: findTarget (therefore $) is called twice, once for match and once for // setting e.currentTarget, fix this so it's only needed once var findTarget = function (target, root) { var i, array = isString(selector) ? selectorEngine(selector, root) : selector for (; target && target !== root; target = target.parentNode) { for (i = array.length; i--; ) { if (array[i] === target) return target } } } , handler = function (e) { var match = findTarget(e.target, this) if (match) fn.apply(match, arguments) } // __beanDel isn't pleasant but it's a private function, not exposed outside of Bean handler.__beanDel = { ft: findTarget // attach it here for customEvents to use too , selector: selector } return handler } , fireListener = W3C_MODEL ? function (isNative, type, element) { // modern browsers, do a proper dispatchEvent() var evt = doc.createEvent(isNative ? 'HTMLEvents' : 'UIEvents') evt[isNative ? 'initEvent' : 'initUIEvent'](type, true, true, win, 1) element.dispatchEvent(evt) } : function (isNative, type, element) { // old browser use onpropertychange, just increment a custom property to trigger the event element = targetElement(element, isNative) isNative ? element.fireEvent('on' + type, doc.createEventObject()) : element['_on' + type]++ } /** * Public API: off(), on(), add(), (remove()), one(), fire(), clone() */ /** * off(element[, eventType(s)[, handler ]]) */ , off = function (element, typeSpec, fn) { var isTypeStr = isString(typeSpec) , k, type, namespaces, i if (isTypeStr && typeSpec.indexOf(' ') > 0) { // off(el, 't1 t2 t3', fn) or off(el, 't1 t2 t3') typeSpec = str2arr(typeSpec) for (i = typeSpec.length; i--; ) off(element, typeSpec[i], fn) return element } type = isTypeStr && typeSpec.replace(nameRegex, '') if (type && customEvents[type]) type = customEvents[type].base if (!typeSpec || isTypeStr) { // off(el) or off(el, t1.ns) or off(el, .ns) or off(el, .ns1.ns2.ns3) if (namespaces = isTypeStr && typeSpec.replace(namespaceRegex, '')) namespaces = str2arr(namespaces, '.') removeListener(element, type, fn, namespaces) } else if (isFunction(typeSpec)) { // off(el, fn) removeListener(element, null, typeSpec) } else { // off(el, { t1: fn1, t2, fn2 }) for (k in typeSpec) { if (typeSpec.hasOwnProperty(k)) off(element, k, typeSpec[k]) } } return element } /** * on(element, eventType(s)[, selector], handler[, args ]) */ , on = function (element, events, selector, fn) { var originalFn, type, types, i, args, entry, first //TODO: the undefined check means you can't pass an 'args' argument, fix this perhaps? if (selector === undefined && typeof events == 'object') { //TODO: this can't handle delegated events for (type in events) { if (events.hasOwnProperty(type)) { on.call(this, element, type, events[type]) } } return } if (!isFunction(selector)) { // delegated event originalFn = fn args = slice.call(arguments, 4) fn = delegate(selector, originalFn, selectorEngine) } else { args = slice.call(arguments, 3) fn = originalFn = selector } types = str2arr(events) // special case for one(), wrap in a self-removing handler if (this === ONE) { fn = once(off, element, events, fn, originalFn) } for (i = types.length; i--; ) { // add new handler to the registry and check if it's the first for this element/type first = registry.put(entry = new RegEntry( element , types[i].replace(nameRegex, '') // event type , fn , originalFn , str2arr(types[i].replace(namespaceRegex, ''), '.') // namespaces , args , false // not root )) if (entry[eventSupport] && first) { // first event of this type on this element, add root listener listener(element, entry.eventType, true, entry.customType) } } return element } /** * add(element[, selector], eventType(s), handler[, args ]) * * Deprecated: kept (for now) for backward-compatibility */ , add = function (element, events, fn, delfn) { return on.apply( null , !isString(fn) ? slice.call(arguments) : [element, fn, events, delfn].concat(arguments.length > 3 ? slice.call(arguments, 5) : []) ) } /** * one(element, eventType(s)[, selector], handler[, args ]) */ , one = function () { return on.apply(ONE, arguments) } /** * fire(element, eventType(s)[, args ]) * * The optional 'args' argument must be an array, if no 'args' argument is provided * then we can use the browser's DOM event system, otherwise we trigger handlers manually */ , fire = function (element, type, args) { var types = str2arr(type) , i, j, l, names, handlers for (i = types.length; i--; ) { type = types[i].replace(nameRegex, '') if (names = types[i].replace(namespaceRegex, '')) names = str2arr(names, '.') if (!names && !args && element[eventSupport]) { fireListener(nativeEvents[type], type, element) } else { // non-native event, either because of a namespace, arguments or a non DOM element // iterate over all listeners and manually 'fire' handlers = registry.get(element, type, null, false) args = [false].concat(args) for (j = 0, l = handlers.length; j < l; j++) { if (handlers[j].inNamespaces(names)) { handlers[j].handler.apply(element, args) } } } } return element } /** * clone(dstElement, srcElement[, eventType ]) * * TODO: perhaps for consistency we should allow the same flexibility in type specifiers? */ , clone = function (element, from, type) { var handlers = registry.get(from, type, null, false) , l = handlers.length , i = 0 , args, beanDel for (; i < l; i++) { if (handlers[i].original) { args = [element, handlers[i].type] if (beanDel = handlers[i].handler.__beanDel) args.push(beanDel.selector) args.push(handlers[i].original) on.apply(null, args) } } return element } , bean = { 'on': on , 'add': add , 'one': one , 'off': off , 'remove': off , 'clone': clone , 'fire': fire , 'Event': Event , 'setSelectorEngine': setSelectorEngine , 'noConflict': function () { context[name] = old return this } } // for IE, clean up on unload to avoid leaks if (win.attachEvent) { var cleanup = function () { var i, entries = registry.entries() for (i in entries) { if (entries[i].type && entries[i].type !== 'unload') off(entries[i].element, entries[i].type) } win.detachEvent('onunload', cleanup) win.CollectGarbage && win.CollectGarbage() } win.attachEvent('onunload', cleanup) } // initialize selector engine to internal default (qSA or throw Error) setSelectorEngine() return bean }); }, {}], 21: [function (_dereq_, module, exports) { (function (global) { /*! http://mths.be/punycode v1.2.4 by @mathias */ ; (function (root) { /** Detect free variables */ var freeExports = typeof exports == 'object' && exports; var freeModule = typeof module == 'object' && module && module.exports == freeExports && module; var freeGlobal = typeof global == 'object' && global; if (freeGlobal.global === freeGlobal || freeGlobal.window === freeGlobal) { root = freeGlobal; } /** * The `punycode` object. * @name punycode * @type Object */ var punycode, /** Highest positive signed 32-bit float value */ maxInt = 2147483647, // aka. 0x7FFFFFFF or 2^31-1 /** Bootstring parameters */ base = 36, tMin = 1, tMax = 26, skew = 38, damp = 700, initialBias = 72, initialN = 128, // 0x80 delimiter = '-', // '\x2D' /** Regular expressions */ regexPunycode = /^xn--/, regexNonASCII = /[^ -~]/, // unprintable ASCII chars + non-ASCII chars regexSeparators = /\x2E|\u3002|\uFF0E|\uFF61/g, // RFC 3490 separators /** Error messages */ errors = { 'overflow': 'Overflow: input needs wider integers to process', 'not-basic': 'Illegal input >= 0x80 (not a basic code point)', 'invalid-input': 'Invalid input' }, /** Convenience shortcuts */ baseMinusTMin = base - tMin, floor = Math.floor, stringFromCharCode = String.fromCharCode, /** Temporary variable */ key; /*--------------------------------------------------------------------------*/ /** * A generic error utility function. * @private * @param {String} type The error type. * @returns {Error} Throws a `RangeError` with the applicable error message. */ function error(type) { throw RangeError(errors[type]); } /** * A generic `Array#map` utility function. * @private * @param {Array} array The array to iterate over. * @param {Function} callback The function that gets called for every array * item. * @returns {Array} A new array of values returned by the callback function. */ function map(array, fn) { var length = array.length; while (length--) { array[length] = fn(array[length]); } return array; } /** * A simple `Array#map`-like wrapper to work with domain name strings. * @private * @param {String} domain The domain name. * @param {Function} callback The function that gets called for every * character. * @returns {Array} A new string of characters returned by the callback * function. */ function mapDomain(string, fn) { return map(string.split(regexSeparators), fn).join('.'); } /** * Creates an array containing the numeric code points of each Unicode * character in the string. While JavaScript uses UCS-2 internally, * this function will convert a pair of surrogate halves (each of which * UCS-2 exposes as separate characters) into a single code point, * matching UTF-16. * @see `punycode.ucs2.encode` * @see * @memberOf punycode.ucs2 * @name decode * @param {String} string The Unicode input string (UCS-2). * @returns {Array} The new array of code points. */ function ucs2decode(string) { var output = [], counter = 0, length = string.length, value, extra; while (counter < length) { value = string.charCodeAt(counter++); if (value >= 0xD800 && value <= 0xDBFF && counter < length) { // high surrogate, and there is a next character extra = string.charCodeAt(counter++); if ((extra & 0xFC00) == 0xDC00) { // low surrogate output.push(((value & 0x3FF) << 10) + (extra & 0x3FF) + 0x10000); } else { // unmatched surrogate; only append this code unit, in case the next // code unit is the high surrogate of a surrogate pair output.push(value); counter--; } } else { output.push(value); } } return output; } /** * Creates a string based on an array of numeric code points. * @see `punycode.ucs2.decode` * @memberOf punycode.ucs2 * @name encode * @param {Array} codePoints The array of numeric code points. * @returns {String} The new Unicode string (UCS-2). */ function ucs2encode(array) { return map(array, function (value) { var output = ''; if (value > 0xFFFF) { value -= 0x10000; output += stringFromCharCode(value >>> 10 & 0x3FF | 0xD800); value = 0xDC00 | value & 0x3FF; } output += stringFromCharCode(value); return output; }).join(''); } /** * Converts a basic code point into a digit/integer. * @see `digitToBasic()` * @private * @param {Number} codePoint The basic numeric code point value. * @returns {Number} The numeric value of a basic code point (for use in * representing integers) in the range `0` to `base - 1`, or `base` if * the code point does not represent a value. */ function basicToDigit(codePoint) { if (codePoint - 48 < 10) { return codePoint - 22; } if (codePoint - 65 < 26) { return codePoint - 65; } if (codePoint - 97 < 26) { return codePoint - 97; } return base; } /** * Converts a digit/integer into a basic code point. * @see `basicToDigit()` * @private * @param {Number} digit The numeric value of a basic code point. * @returns {Number} The basic code point whose value (when used for * representing integers) is `digit`, which needs to be in the range * `0` to `base - 1`. If `flag` is non-zero, the uppercase form is * used; else, the lowercase form is used. The behavior is undefined * if `flag` is non-zero and `digit` has no uppercase form. */ function digitToBasic(digit, flag) { // 0..25 map to ASCII a..z or A..Z // 26..35 map to ASCII 0..9 return digit + 22 + 75 * (digit < 26) - ((flag != 0) << 5); } /** * Bias adaptation function as per section 3.4 of RFC 3492. * http://tools.ietf.org/html/rfc3492#section-3.4 * @private */ function adapt(delta, numPoints, firstTime) { var k = 0; delta = firstTime ? floor(delta / damp) : delta >> 1; delta += floor(delta / numPoints); for (/* no initialization */; delta > baseMinusTMin * tMax >> 1; k += base) { delta = floor(delta / baseMinusTMin); } return floor(k + (baseMinusTMin + 1) * delta / (delta + skew)); } /** * Converts a Punycode string of ASCII-only symbols to a string of Unicode * symbols. * @memberOf punycode * @param {String} input The Punycode string of ASCII-only symbols. * @returns {String} The resulting string of Unicode symbols. */ function decode(input) { // Don't use UCS-2 var output = [], inputLength = input.length, out, i = 0, n = initialN, bias = initialBias, basic, j, index, oldi, w, k, digit, t, /** Cached calculation results */ baseMinusT; // Handle the basic code points: let `basic` be the number of input code // points before the last delimiter, or `0` if there is none, then copy // the first basic code points to the output. basic = input.lastIndexOf(delimiter); if (basic < 0) { basic = 0; } for (j = 0; j < basic; ++j) { // if it's not a basic code point if (input.charCodeAt(j) >= 0x80) { error('not-basic'); } output.push(input.charCodeAt(j)); } // Main decoding loop: start just after the last delimiter if any basic code // points were copied; start at the beginning otherwise. for (index = basic > 0 ? basic + 1 : 0; index < inputLength; /* no final expression */) { // `index` is the index of the next character to be consumed. // Decode a generalized variable-length integer into `delta`, // which gets added to `i`. The overflow checking is easier // if we increase `i` as we go, then subtract off its starting // value at the end to obtain `delta`. for (oldi = i, w = 1, k = base; /* no condition */; k += base) { if (index >= inputLength) { error('invalid-input'); } digit = basicToDigit(input.charCodeAt(index++)); if (digit >= base || digit > floor((maxInt - i) / w)) { error('overflow'); } i += digit * w; t = k <= bias ? tMin : (k >= bias + tMax ? tMax : k - bias); if (digit < t) { break; } baseMinusT = base - t; if (w > floor(maxInt / baseMinusT)) { error('overflow'); } w *= baseMinusT; } out = output.length + 1; bias = adapt(i - oldi, out, oldi == 0); // `i` was supposed to wrap around from `out` to `0`, // incrementing `n` each time, so we'll fix that now: if (floor(i / out) > maxInt - n) { error('overflow'); } n += floor(i / out); i %= out; // Insert `n` at position `i` of the output output.splice(i++, 0, n); } return ucs2encode(output); } /** * Converts a string of Unicode symbols to a Punycode string of ASCII-only * symbols. * @memberOf punycode * @param {String} input The string of Unicode symbols. * @returns {String} The resulting Punycode string of ASCII-only symbols. */ function encode(input) { var n, delta, handledCPCount, basicLength, bias, j, m, q, k, t, currentValue, output = [], /** `inputLength` will hold the number of code points in `input`. */ inputLength, /** Cached calculation results */ handledCPCountPlusOne, baseMinusT, qMinusT; // Convert the input in UCS-2 to Unicode input = ucs2decode(input); // Cache the length inputLength = input.length; // Initialize the state n = initialN; delta = 0; bias = initialBias; // Handle the basic code points for (j = 0; j < inputLength; ++j) { currentValue = input[j]; if (currentValue < 0x80) { output.push(stringFromCharCode(currentValue)); } } handledCPCount = basicLength = output.length; // `handledCPCount` is the number of code points that have been handled; // `basicLength` is the number of basic code points. // Finish the basic string - if it is not empty - with a delimiter if (basicLength) { output.push(delimiter); } // Main encoding loop: while (handledCPCount < inputLength) { // All non-basic code points < n have been handled already. Find the next // larger one: for (m = maxInt, j = 0; j < inputLength; ++j) { currentValue = input[j]; if (currentValue >= n && currentValue < m) { m = currentValue; } } // Increase `delta` enough to advance the decoder's state to , // but guard against overflow handledCPCountPlusOne = handledCPCount + 1; if (m - n > floor((maxInt - delta) / handledCPCountPlusOne)) { error('overflow'); } delta += (m - n) * handledCPCountPlusOne; n = m; for (j = 0; j < inputLength; ++j) { currentValue = input[j]; if (currentValue < n && ++delta > maxInt) { error('overflow'); } if (currentValue == n) { // Represent delta as a generalized variable-length integer for (q = delta, k = base; /* no condition */; k += base) { t = k <= bias ? tMin : (k >= bias + tMax ? tMax : k - bias); if (q < t) { break; } qMinusT = q - t; baseMinusT = base - t; output.push( stringFromCharCode(digitToBasic(t + qMinusT % baseMinusT, 0)) ); q = floor(qMinusT / baseMinusT); } output.push(stringFromCharCode(digitToBasic(q, 0))); bias = adapt(delta, handledCPCountPlusOne, handledCPCount == basicLength); delta = 0; ++handledCPCount; } } ++delta; ++n; } return output.join(''); } /** * Converts a Punycode string representing a domain name to Unicode. Only the * Punycoded parts of the domain name will be converted, i.e. it doesn't * matter if you call it on a string that has already been converted to * Unicode. * @memberOf punycode * @param {String} domain The Punycode domain name to convert to Unicode. * @returns {String} The Unicode representation of the given Punycode * string. */ function toUnicode(domain) { return mapDomain(domain, function (string) { return regexPunycode.test(string) ? decode(string.slice(4).toLowerCase()) : string; }); } /** * Converts a Unicode string representing a domain name to Punycode. Only the * non-ASCII parts of the domain name will be converted, i.e. it doesn't * matter if you call it with a domain that's already in ASCII. * @memberOf punycode * @param {String} domain The domain name to convert, as a Unicode string. * @returns {String} The Punycode representation of the given domain name. */ function toASCII(domain) { return mapDomain(domain, function (string) { return regexNonASCII.test(string) ? 'xn--' + encode(string) : string; }); } /*--------------------------------------------------------------------------*/ /** Define the public API */ punycode = { /** * A string representing the current Punycode.js version number. * @memberOf punycode * @type String */ 'version': '1.2.4', /** * An object of methods to convert from JavaScript's internal character * representation (UCS-2) to Unicode code points, and back. * @see * @memberOf punycode * @type Object */ 'ucs2': { 'decode': ucs2decode, 'encode': ucs2encode }, 'decode': decode, 'encode': encode, 'toASCII': toASCII, 'toUnicode': toUnicode }; /** Expose `punycode` */ // Some AMD build optimizers, like r.js, check for specific condition patterns // like the following: if ( typeof define == 'function' && typeof define.amd == 'object' && define.amd ) { define('punycode', function () { return punycode; }); } else if (freeExports && !freeExports.nodeType) { if (freeModule) { // in Node.js or RingoJS v0.8.0+ freeModule.exports = punycode; } else { // in Narwhal or RingoJS v0.7.0- for (key in punycode) { punycode.hasOwnProperty(key) && (freeExports[key] = punycode[key]); } } } else { // in Rhino or a web browser root.punycode = punycode; } } (this)); }).call(this, typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) }, {}], 22: [function (_dereq_, module, exports) { // contains, add, remove, toggle var indexof = _dereq_('indexof') module.exports = ClassList function ClassList(elem) { var cl = elem.classList if (cl) { return cl } var classList = { add: add , remove: remove , contains: contains , toggle: toggle , toString: $toString , length: 0 , item: item } return classList function add(token) { var list = getTokens() if (indexof(list, token) > -1) { return } list.push(token) setTokens(list) } function remove(token) { var list = getTokens() , index = indexof(list, token) if (index === -1) { return } list.splice(index, 1) setTokens(list) } function contains(token) { return indexof(getTokens(), token) > -1 } function toggle(token) { if (contains(token)) { remove(token) return false } else { add(token) return true } } function $toString() { return elem.className } function item(index) { var tokens = getTokens() return tokens[index] || null } function getTokens() { var className = elem.className return filter(className.split(" "), isTruthy) } function setTokens(list) { var length = list.length elem.className = list.join(" ") classList.length = length for (var i = 0; i < list.length; i++) { classList[i] = list[i] } delete list[length] } } function filter(arr, fn) { var ret = [] for (var i = 0; i < arr.length; i++) { if (fn(arr[i])) ret.push(arr[i]) } return ret } function isTruthy(value) { return !!value } }, { "indexof": 23}], 23: [function (_dereq_, module, exports) { var indexOf = [].indexOf; module.exports = function (arr, obj) { if (indexOf) return arr.indexOf(obj); for (var i = 0; i < arr.length; ++i) { if (arr[i] === obj) return i; } return -1; }; }, {}], 24: [function (_dereq_, module, exports) { // DEV: We don't use var but favor parameters since these play nicer with minification function computedStyle(el, prop, getComputedStyle, style) { getComputedStyle = window.getComputedStyle; style = // If we have getComputedStyle getComputedStyle ? // Query it // TODO: From CSS-Query notes, we might need (node, null) for FF getComputedStyle(el) : // Otherwise, we are in IE and use currentStyle el.currentStyle; if (style) { return style [ // Switch to camelCase for CSSOM // DEV: Grabbed from jQuery // https://github.com/jquery/jquery/blob/1.9-stable/src/css.js#L191-L194 // https://github.com/jquery/jquery/blob/1.9-stable/src/core.js#L593-L597 prop.replace(/-(\w)/gi, function (word, letter) { return letter.toUpperCase(); }) ]; } } module.exports = computedStyle; }, {}], 25: [function (_dereq_, module, exports) { /*! * https://github.com/es-shims/es5-shim * @license es5-shim Copyright 2009-2015 by contributors, MIT License * see https://github.com/es-shims/es5-shim/blob/master/LICENSE */ // vim: ts=4 sts=4 sw=4 expandtab // Add semicolon to prevent IIFE from being passed as argument to concatenated code. ; // UMD (Universal Module Definition) // see https://github.com/umdjs/umd/blob/master/templates/returnExports.js (function (root, factory) { 'use strict'; /* global define, exports, module */ if (typeof define === 'function' && define.amd) { // AMD. Register as an anonymous module. define(factory); } else if (typeof exports === 'object') { // Node. Does not work with strict CommonJS, but // only CommonJS-like enviroments that support module.exports, // like Node. module.exports = factory(); } else { // Browser globals (root is window) root.returnExports = factory(); } } (this, function () { /** * Brings an environment as close to ECMAScript 5 compliance * as is possible with the facilities of erstwhile engines. * * Annotated ES5: http://es5.github.com/ (specific links below) * ES5 Spec: http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-262.pdf * Required reading: http://javascriptweblog.wordpress.com/2011/12/05/extending-javascript-natives/ */ // Shortcut to an often accessed properties, in order to avoid multiple // dereference that costs universally. This also holds a reference to known-good // functions. var $Array = Array; var ArrayPrototype = $Array.prototype; var $Object = Object; var ObjectPrototype = $Object.prototype; var FunctionPrototype = Function.prototype; var $String = String; var StringPrototype = $String.prototype; var $Number = Number; var NumberPrototype = $Number.prototype; var array_slice = ArrayPrototype.slice; var array_splice = ArrayPrototype.splice; var array_push = ArrayPrototype.push; var array_unshift = ArrayPrototype.unshift; var array_concat = ArrayPrototype.concat; var call = FunctionPrototype.call; var apply = FunctionPrototype.apply; var max = Math.max; var min = Math.min; // Having a toString local variable name breaks in Opera so use to_string. var to_string = ObjectPrototype.toString; var hasToStringTag = typeof Symbol === 'function' && typeof Symbol.toStringTag === 'symbol'; var isCallable; /* inlined from https://npmjs.com/is-callable */var fnToStr = Function.prototype.toString, tryFunctionObject = function tryFunctionObject(value) { try { fnToStr.call(value); return true; } catch (e) { return false; } }, fnClass = '[object Function]', genClass = '[object GeneratorFunction]'; isCallable = function isCallable(value) { if (typeof value !== 'function') { return false; } if (hasToStringTag) { return tryFunctionObject(value); } var strClass = to_string.call(value); return strClass === fnClass || strClass === genClass; }; var isRegex; /* inlined from https://npmjs.com/is-regex */var regexExec = RegExp.prototype.exec, tryRegexExec = function tryRegexExec(value) { try { regexExec.call(value); return true; } catch (e) { return false; } }, regexClass = '[object RegExp]'; isRegex = function isRegex(value) { if (typeof value !== 'object') { return false; } return hasToStringTag ? tryRegexExec(value) : to_string.call(value) === regexClass; }; var isString; /* inlined from https://npmjs.com/is-string */var strValue = String.prototype.valueOf, tryStringObject = function tryStringObject(value) { try { strValue.call(value); return true; } catch (e) { return false; } }, stringClass = '[object String]'; isString = function isString(value) { if (typeof value === 'string') { return true; } if (typeof value !== 'object') { return false; } return hasToStringTag ? tryStringObject(value) : to_string.call(value) === stringClass; }; /* inlined from http://npmjs.com/define-properties */ var supportsDescriptors = $Object.defineProperty && (function () { try { var obj = {}; $Object.defineProperty(obj, 'x', { enumerable: false, value: obj }); for (var _ in obj) { return false; } return obj.x === obj; } catch (e) { /* this is ES3 */ return false; } } ()); var defineProperties = (function (has) { // Define configurable, writable, and non-enumerable props // if they don't exist. var defineProperty; if (supportsDescriptors) { defineProperty = function (object, name, method, forceAssign) { if (!forceAssign && (name in object)) { return; } $Object.defineProperty(object, name, { configurable: true, enumerable: false, writable: true, value: method }); }; } else { defineProperty = function (object, name, method, forceAssign) { if (!forceAssign && (name in object)) { return; } object[name] = method; }; } return function defineProperties(object, map, forceAssign) { for (var name in map) { if (has.call(map, name)) { defineProperty(object, name, map[name], forceAssign); } } }; } (ObjectPrototype.hasOwnProperty)); // // Util // ====== // /* replaceable with https://npmjs.com/package/es-abstract /helpers/isPrimitive */ var isPrimitive = function isPrimitive(input) { var type = typeof input; return input === null || (type !== 'object' && type !== 'function'); }; var isActualNaN = $Number.isNaN || function (x) { return x !== x; }; var ES = { // ES5 9.4 // http://es5.github.com/#x9.4 // http://jsperf.com/to-integer /* replaceable with https://npmjs.com/package/es-abstract ES5.ToInteger */ ToInteger: function ToInteger(num) { var n = +num; if (isActualNaN(n)) { n = 0; } else if (n !== 0 && n !== (1 / 0) && n !== -(1 / 0)) { n = (n > 0 || -1) * Math.floor(Math.abs(n)); } return n; }, /* replaceable with https://npmjs.com/package/es-abstract ES5.ToPrimitive */ ToPrimitive: function ToPrimitive(input) { var val, valueOf, toStr; if (isPrimitive(input)) { return input; } valueOf = input.valueOf; if (isCallable(valueOf)) { val = valueOf.call(input); if (isPrimitive(val)) { return val; } } toStr = input.toString; if (isCallable(toStr)) { val = toStr.call(input); if (isPrimitive(val)) { return val; } } throw new TypeError(); }, // ES5 9.9 // http://es5.github.com/#x9.9 /* replaceable with https://npmjs.com/package/es-abstract ES5.ToObject */ ToObject: function (o) { if (o == null) { // this matches both null and undefined throw new TypeError("can't convert " + o + ' to object'); } return $Object(o); }, /* replaceable with https://npmjs.com/package/es-abstract ES5.ToUint32 */ ToUint32: function ToUint32(x) { return x >>> 0; } }; // // Function // ======== // // ES-5 15.3.4.5 // http://es5.github.com/#x15.3.4.5 var Empty = function Empty() { }; defineProperties(FunctionPrototype, { bind: function bind(that) { // .length is 1 // 1. Let Target be the this value. var target = this; // 2. If IsCallable(Target) is false, throw a TypeError exception. if (!isCallable(target)) { throw new TypeError('Function.prototype.bind called on incompatible ' + target); } // 3. Let A be a new (possibly empty) internal list of all of the // argument values provided after thisArg (arg1, arg2 etc), in order. // XXX slicedArgs will stand in for "A" if used var args = array_slice.call(arguments, 1); // for normal call // 4. Let F be a new native ECMAScript object. // 11. Set the [[Prototype]] internal property of F to the standard // built-in Function prototype object as specified in 15.3.3.1. // 12. Set the [[Call]] internal property of F as described in // 15.3.4.5.1. // 13. Set the [[Construct]] internal property of F as described in // 15.3.4.5.2. // 14. Set the [[HasInstance]] internal property of F as described in // 15.3.4.5.3. var bound; var binder = function () { if (this instanceof bound) { // 15.3.4.5.2 [[Construct]] // When the [[Construct]] internal method of a function object, // F that was created using the bind function is called with a // list of arguments ExtraArgs, the following steps are taken: // 1. Let target be the value of F's [[TargetFunction]] // internal property. // 2. If target has no [[Construct]] internal method, a // TypeError exception is thrown. // 3. Let boundArgs be the value of F's [[BoundArgs]] internal // property. // 4. Let args be a new list containing the same values as the // list boundArgs in the same order followed by the same // values as the list ExtraArgs in the same order. // 5. Return the result of calling the [[Construct]] internal // method of target providing args as the arguments. var result = target.apply( this, array_concat.call(args, array_slice.call(arguments)) ); if ($Object(result) === result) { return result; } return this; } else { // 15.3.4.5.1 [[Call]] // When the [[Call]] internal method of a function object, F, // which was created using the bind function is called with a // this value and a list of arguments ExtraArgs, the following // steps are taken: // 1. Let boundArgs be the value of F's [[BoundArgs]] internal // property. // 2. Let boundThis be the value of F's [[BoundThis]] internal // property. // 3. Let target be the value of F's [[TargetFunction]] internal // property. // 4. Let args be a new list containing the same values as the // list boundArgs in the same order followed by the same // values as the list ExtraArgs in the same order. // 5. Return the result of calling the [[Call]] internal method // of target providing boundThis as the this value and // providing args as the arguments. // equiv: target.call(this, ...boundArgs, ...args) return target.apply( that, array_concat.call(args, array_slice.call(arguments)) ); } }; // 15. If the [[Class]] internal property of Target is "Function", then // a. Let L be the length property of Target minus the length of A. // b. Set the length own property of F to either 0 or L, whichever is // larger. // 16. Else set the length own property of F to 0. var boundLength = max(0, target.length - args.length); // 17. Set the attributes of the length own property of F to the values // specified in 15.3.5.1. var boundArgs = []; for (var i = 0; i < boundLength; i++) { array_push.call(boundArgs, '$' + i); } // XXX Build a dynamic function with desired amount of arguments is the only // way to set the length property of a function. // In environments where Content Security Policies enabled (Chrome extensions, // for ex.) all use of eval or Function costructor throws an exception. // However in all of these environments Function.prototype.bind exists // and so this code will never be executed. bound = Function('binder', 'return function (' + boundArgs.join(',') + '){ return binder.apply(this, arguments); }')(binder); if (target.prototype) { Empty.prototype = target.prototype; bound.prototype = new Empty(); // Clean up dangling references. Empty.prototype = null; } // TODO // 18. Set the [[Extensible]] internal property of F to true. // TODO // 19. Let thrower be the [[ThrowTypeError]] function Object (13.2.3). // 20. Call the [[DefineOwnProperty]] internal method of F with // arguments "caller", PropertyDescriptor {[[Get]]: thrower, [[Set]]: // thrower, [[Enumerable]]: false, [[Configurable]]: false}, and // false. // 21. Call the [[DefineOwnProperty]] internal method of F with // arguments "arguments", PropertyDescriptor {[[Get]]: thrower, // [[Set]]: thrower, [[Enumerable]]: false, [[Configurable]]: false}, // and false. // TODO // NOTE Function objects created using Function.prototype.bind do not // have a prototype property or the [[Code]], [[FormalParameters]], and // [[Scope]] internal properties. // XXX can't delete prototype in pure-js. // 22. Return F. return bound; } }); // _Please note: Shortcuts are defined after `Function.prototype.bind` as we // use it in defining shortcuts. var owns = call.bind(ObjectPrototype.hasOwnProperty); var toStr = call.bind(ObjectPrototype.toString); var arraySlice = call.bind(array_slice); var arraySliceApply = apply.bind(array_slice); var strSlice = call.bind(StringPrototype.slice); var strSplit = call.bind(StringPrototype.split); var strIndexOf = call.bind(StringPrototype.indexOf); var push = call.bind(array_push); var isEnum = call.bind(ObjectPrototype.propertyIsEnumerable); var arraySort = call.bind(ArrayPrototype.sort); // // Array // ===== // var isArray = $Array.isArray || function isArray(obj) { return toStr(obj) === '[object Array]'; }; // ES5 15.4.4.12 // http://es5.github.com/#x15.4.4.13 // Return len+argCount. // [bugfix, ielt8] // IE < 8 bug: [].unshift(0) === undefined but should be "1" var hasUnshiftReturnValueBug = [].unshift(0) !== 1; defineProperties(ArrayPrototype, { unshift: function () { array_unshift.apply(this, arguments); return this.length; } }, hasUnshiftReturnValueBug); // ES5 15.4.3.2 // http://es5.github.com/#x15.4.3.2 // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/isArray defineProperties($Array, { isArray: isArray }); // The IsCallable() check in the Array functions // has been replaced with a strict check on the // internal class of the object to trap cases where // the provided function was actually a regular // expression literal, which in V8 and // JavaScriptCore is a typeof "function". Only in // V8 are regular expression literals permitted as // reduce parameters, so it is desirable in the // general case for the shim to match the more // strict and common behavior of rejecting regular // expressions. // ES5 15.4.4.18 // http://es5.github.com/#x15.4.4.18 // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/array/forEach // Check failure of by-index access of string characters (IE < 9) // and failure of `0 in boxedString` (Rhino) var boxedString = $Object('a'); var splitString = boxedString[0] !== 'a' || !(0 in boxedString); var properlyBoxesContext = function properlyBoxed(method) { // Check node 0.6.21 bug where third parameter is not boxed var properlyBoxesNonStrict = true; var properlyBoxesStrict = true; if (method) { method.call('foo', function (_, __, context) { if (typeof context !== 'object') { properlyBoxesNonStrict = false; } }); method.call([1], function () { 'use strict'; properlyBoxesStrict = typeof this === 'string'; }, 'x'); } return !!method && properlyBoxesNonStrict && properlyBoxesStrict; }; defineProperties(ArrayPrototype, { forEach: function forEach(callbackfn/*, thisArg*/) { var object = ES.ToObject(this); var self = splitString && isString(this) ? strSplit(this, '') : object; var i = -1; var length = ES.ToUint32(self.length); var T; if (arguments.length > 1) { T = arguments[1]; } // If no callback function or if callback is not a callable function if (!isCallable(callbackfn)) { throw new TypeError('Array.prototype.forEach callback must be a function'); } while (++i < length) { if (i in self) { // Invoke the callback function with call, passing arguments: // context, property value, property key, thisArg object if (typeof T === 'undefined') { callbackfn(self[i], i, object); } else { callbackfn.call(T, self[i], i, object); } } } } }, !properlyBoxesContext(ArrayPrototype.forEach)); // ES5 15.4.4.19 // http://es5.github.com/#x15.4.4.19 // https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/map defineProperties(ArrayPrototype, { map: function map(callbackfn/*, thisArg*/) { var object = ES.ToObject(this); var self = splitString && isString(this) ? strSplit(this, '') : object; var length = ES.ToUint32(self.length); var result = $Array(length); var T; if (arguments.length > 1) { T = arguments[1]; } // If no callback function or if callback is not a callable function if (!isCallable(callbackfn)) { throw new TypeError('Array.prototype.map callback must be a function'); } for (var i = 0; i < length; i++) { if (i in self) { if (typeof T === 'undefined') { result[i] = callbackfn(self[i], i, object); } else { result[i] = callbackfn.call(T, self[i], i, object); } } } return result; } }, !properlyBoxesContext(ArrayPrototype.map)); // ES5 15.4.4.20 // http://es5.github.com/#x15.4.4.20 // https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/filter defineProperties(ArrayPrototype, { filter: function filter(callbackfn/*, thisArg*/) { var object = ES.ToObject(this); var self = splitString && isString(this) ? strSplit(this, '') : object; var length = ES.ToUint32(self.length); var result = []; var value; var T; if (arguments.length > 1) { T = arguments[1]; } // If no callback function or if callback is not a callable function if (!isCallable(callbackfn)) { throw new TypeError('Array.prototype.filter callback must be a function'); } for (var i = 0; i < length; i++) { if (i in self) { value = self[i]; if (typeof T === 'undefined' ? callbackfn(value, i, object) : callbackfn.call(T, value, i, object)) { push(result, value); } } } return result; } }, !properlyBoxesContext(ArrayPrototype.filter)); // ES5 15.4.4.16 // http://es5.github.com/#x15.4.4.16 // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/every defineProperties(ArrayPrototype, { every: function every(callbackfn/*, thisArg*/) { var object = ES.ToObject(this); var self = splitString && isString(this) ? strSplit(this, '') : object; var length = ES.ToUint32(self.length); var T; if (arguments.length > 1) { T = arguments[1]; } // If no callback function or if callback is not a callable function if (!isCallable(callbackfn)) { throw new TypeError('Array.prototype.every callback must be a function'); } for (var i = 0; i < length; i++) { if (i in self && !(typeof T === 'undefined' ? callbackfn(self[i], i, object) : callbackfn.call(T, self[i], i, object))) { return false; } } return true; } }, !properlyBoxesContext(ArrayPrototype.every)); // ES5 15.4.4.17 // http://es5.github.com/#x15.4.4.17 // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/some defineProperties(ArrayPrototype, { some: function some(callbackfn/*, thisArg */) { var object = ES.ToObject(this); var self = splitString && isString(this) ? strSplit(this, '') : object; var length = ES.ToUint32(self.length); var T; if (arguments.length > 1) { T = arguments[1]; } // If no callback function or if callback is not a callable function if (!isCallable(callbackfn)) { throw new TypeError('Array.prototype.some callback must be a function'); } for (var i = 0; i < length; i++) { if (i in self && (typeof T === 'undefined' ? callbackfn(self[i], i, object) : callbackfn.call(T, self[i], i, object))) { return true; } } return false; } }, !properlyBoxesContext(ArrayPrototype.some)); // ES5 15.4.4.21 // http://es5.github.com/#x15.4.4.21 // https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/reduce var reduceCoercesToObject = false; if (ArrayPrototype.reduce) { reduceCoercesToObject = typeof ArrayPrototype.reduce.call('es5', function (_, __, ___, list) { return list; }) === 'object'; } defineProperties(ArrayPrototype, { reduce: function reduce(callbackfn/*, initialValue*/) { var object = ES.ToObject(this); var self = splitString && isString(this) ? strSplit(this, '') : object; var length = ES.ToUint32(self.length); // If no callback function or if callback is not a callable function if (!isCallable(callbackfn)) { throw new TypeError('Array.prototype.reduce callback must be a function'); } // no value to return if no initial value and an empty array if (length === 0 && arguments.length === 1) { throw new TypeError('reduce of empty array with no initial value'); } var i = 0; var result; if (arguments.length >= 2) { result = arguments[1]; } else { do { if (i in self) { result = self[i++]; break; } // if array contains no values, no initial value to return if (++i >= length) { throw new TypeError('reduce of empty array with no initial value'); } } while (true); } for (; i < length; i++) { if (i in self) { result = callbackfn(result, self[i], i, object); } } return result; } }, !reduceCoercesToObject); // ES5 15.4.4.22 // http://es5.github.com/#x15.4.4.22 // https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/reduceRight var reduceRightCoercesToObject = false; if (ArrayPrototype.reduceRight) { reduceRightCoercesToObject = typeof ArrayPrototype.reduceRight.call('es5', function (_, __, ___, list) { return list; }) === 'object'; } defineProperties(ArrayPrototype, { reduceRight: function reduceRight(callbackfn/*, initial*/) { var object = ES.ToObject(this); var self = splitString && isString(this) ? strSplit(this, '') : object; var length = ES.ToUint32(self.length); // If no callback function or if callback is not a callable function if (!isCallable(callbackfn)) { throw new TypeError('Array.prototype.reduceRight callback must be a function'); } // no value to return if no initial value, empty array if (length === 0 && arguments.length === 1) { throw new TypeError('reduceRight of empty array with no initial value'); } var result; var i = length - 1; if (arguments.length >= 2) { result = arguments[1]; } else { do { if (i in self) { result = self[i--]; break; } // if array contains no values, no initial value to return if (--i < 0) { throw new TypeError('reduceRight of empty array with no initial value'); } } while (true); } if (i < 0) { return result; } do { if (i in self) { result = callbackfn(result, self[i], i, object); } } while (i--); return result; } }, !reduceRightCoercesToObject); // ES5 15.4.4.14 // http://es5.github.com/#x15.4.4.14 // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/indexOf var hasFirefox2IndexOfBug = ArrayPrototype.indexOf && [0, 1].indexOf(1, 2) !== -1; defineProperties(ArrayPrototype, { indexOf: function indexOf(searchElement/*, fromIndex */) { var self = splitString && isString(this) ? strSplit(this, '') : ES.ToObject(this); var length = ES.ToUint32(self.length); if (length === 0) { return -1; } var i = 0; if (arguments.length > 1) { i = ES.ToInteger(arguments[1]); } // handle negative indices i = i >= 0 ? i : max(0, length + i); for (; i < length; i++) { if (i in self && self[i] === searchElement) { return i; } } return -1; } }, hasFirefox2IndexOfBug); // ES5 15.4.4.15 // http://es5.github.com/#x15.4.4.15 // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/lastIndexOf var hasFirefox2LastIndexOfBug = ArrayPrototype.lastIndexOf && [0, 1].lastIndexOf(0, -3) !== -1; defineProperties(ArrayPrototype, { lastIndexOf: function lastIndexOf(searchElement/*, fromIndex */) { var self = splitString && isString(this) ? strSplit(this, '') : ES.ToObject(this); var length = ES.ToUint32(self.length); if (length === 0) { return -1; } var i = length - 1; if (arguments.length > 1) { i = min(i, ES.ToInteger(arguments[1])); } // handle negative indices i = i >= 0 ? i : length - Math.abs(i); for (; i >= 0; i--) { if (i in self && searchElement === self[i]) { return i; } } return -1; } }, hasFirefox2LastIndexOfBug); // ES5 15.4.4.12 // http://es5.github.com/#x15.4.4.12 var spliceNoopReturnsEmptyArray = (function () { var a = [1, 2]; var result = a.splice(); return a.length === 2 && isArray(result) && result.length === 0; } ()); defineProperties(ArrayPrototype, { // Safari 5.0 bug where .splice() returns undefined splice: function splice(start, deleteCount) { if (arguments.length === 0) { return []; } else { return array_splice.apply(this, arguments); } } }, !spliceNoopReturnsEmptyArray); var spliceWorksWithEmptyObject = (function () { var obj = {}; ArrayPrototype.splice.call(obj, 0, 0, 1); return obj.length === 1; } ()); defineProperties(ArrayPrototype, { splice: function splice(start, deleteCount) { if (arguments.length === 0) { return []; } var args = arguments; this.length = max(ES.ToInteger(this.length), 0); if (arguments.length > 0 && typeof deleteCount !== 'number') { args = arraySlice(arguments); if (args.length < 2) { push(args, this.length - start); } else { args[1] = ES.ToInteger(deleteCount); } } return array_splice.apply(this, args); } }, !spliceWorksWithEmptyObject); var spliceWorksWithLargeSparseArrays = (function () { // Per https://github.com/es-shims/es5-shim/issues/295 // Safari 7/8 breaks with sparse arrays of size 1e5 or greater var arr = new $Array(1e5); // note: the index MUST be 8 or larger or the test will false pass arr[8] = 'x'; arr.splice(1, 1); // note: this test must be defined *after* the indexOf shim // per https://github.com/es-shims/es5-shim/issues/313 return arr.indexOf('x') === 7; } ()); var spliceWorksWithSmallSparseArrays = (function () { // Per https://github.com/es-shims/es5-shim/issues/295 // Opera 12.15 breaks on this, no idea why. var n = 256; var arr = []; arr[n] = 'a'; arr.splice(n + 1, 0, 'b'); return arr[n] === 'a'; } ()); defineProperties(ArrayPrototype, { splice: function splice(start, deleteCount) { var O = ES.ToObject(this); var A = []; var len = ES.ToUint32(O.length); var relativeStart = ES.ToInteger(start); var actualStart = relativeStart < 0 ? max((len + relativeStart), 0) : min(relativeStart, len); var actualDeleteCount = min(max(ES.ToInteger(deleteCount), 0), len - actualStart); var k = 0; var from; while (k < actualDeleteCount) { from = $String(actualStart + k); if (owns(O, from)) { A[k] = O[from]; } k += 1; } var items = arraySlice(arguments, 2); var itemCount = items.length; var to; if (itemCount < actualDeleteCount) { k = actualStart; while (k < (len - actualDeleteCount)) { from = $String(k + actualDeleteCount); to = $String(k + itemCount); if (owns(O, from)) { O[to] = O[from]; } else { delete O[to]; } k += 1; } k = len; while (k > (len - actualDeleteCount + itemCount)) { delete O[k - 1]; k -= 1; } } else if (itemCount > actualDeleteCount) { k = len - actualDeleteCount; while (k > actualStart) { from = $String(k + actualDeleteCount - 1); to = $String(k + itemCount - 1); if (owns(O, from)) { O[to] = O[from]; } else { delete O[to]; } k -= 1; } } k = actualStart; for (var i = 0; i < items.length; ++i) { O[k] = items[i]; k += 1; } O.length = len - actualDeleteCount + itemCount; return A; } }, !spliceWorksWithLargeSparseArrays || !spliceWorksWithSmallSparseArrays); var originalJoin = ArrayPrototype.join; var hasStringJoinBug; try { hasStringJoinBug = Array.prototype.join.call('123', ',') !== '1,2,3'; } catch (e) { hasStringJoinBug = true; } if (hasStringJoinBug) { defineProperties(ArrayPrototype, { join: function join(separator) { var sep = typeof separator === 'undefined' ? ',' : separator; return originalJoin.call(isString(this) ? strSplit(this, '') : this, sep); } }, hasStringJoinBug); } var hasJoinUndefinedBug = [1, 2].join(undefined) !== '1,2'; if (hasJoinUndefinedBug) { defineProperties(ArrayPrototype, { join: function join(separator) { var sep = typeof separator === 'undefined' ? ',' : separator; return originalJoin.call(this, sep); } }, hasJoinUndefinedBug); } var pushShim = function push(item) { var O = ES.ToObject(this); var n = ES.ToUint32(O.length); var i = 0; while (i < arguments.length) { O[n + i] = arguments[i]; i += 1; } O.length = n + i; return n + i; }; var pushIsNotGeneric = (function () { var obj = {}; var result = Array.prototype.push.call(obj, undefined); return result !== 1 || obj.length !== 1 || typeof obj[0] !== 'undefined' || !owns(obj, 0); } ()); defineProperties(ArrayPrototype, { push: function push(item) { if (isArray(this)) { return array_push.apply(this, arguments); } return pushShim.apply(this, arguments); } }, pushIsNotGeneric); // This fixes a very weird bug in Opera 10.6 when pushing `undefined var pushUndefinedIsWeird = (function () { var arr = []; var result = arr.push(undefined); return result !== 1 || arr.length !== 1 || typeof arr[0] !== 'undefined' || !owns(arr, 0); } ()); defineProperties(ArrayPrototype, { push: pushShim }, pushUndefinedIsWeird); // ES5 15.2.3.14 // http://es5.github.io/#x15.4.4.10 // Fix boxed string bug defineProperties(ArrayPrototype, { slice: function (start, end) { var arr = isString(this) ? strSplit(this, '') : this; return arraySliceApply(arr, arguments); } }, splitString); var sortIgnoresNonFunctions = (function () { try { [1, 2].sort(null); [1, 2].sort({}); return true; } catch (e) { /**/ } return false; } ()); var sortThrowsOnRegex = (function () { // this is a problem in Firefox 4, in which `typeof /a/ === 'function'` try { [1, 2].sort(/a/); return false; } catch (e) { /**/ } return true; } ()); var sortIgnoresUndefined = (function () { // applies in IE 8, for one. try { [1, 2].sort(undefined); return true; } catch (e) { /**/ } return false; } ()); defineProperties(ArrayPrototype, { sort: function sort(compareFn) { if (typeof compareFn === 'undefined') { return arraySort(this); } if (!isCallable(compareFn)) { throw new TypeError('Array.prototype.sort callback must be a function'); } return arraySort(this, compareFn); } }, sortIgnoresNonFunctions || !sortIgnoresUndefined || !sortThrowsOnRegex); // // Object // ====== // // ES5 15.2.3.14 // http://es5.github.com/#x15.2.3.14 // http://whattheheadsaid.com/2010/10/a-safer-object-keys-compatibility-implementation var hasDontEnumBug = !({ 'toString': null }).propertyIsEnumerable('toString'); var hasProtoEnumBug = function () { } .propertyIsEnumerable('prototype'); var hasStringEnumBug = !owns('x', '0'); var equalsConstructorPrototype = function (o) { var ctor = o.constructor; return ctor && ctor.prototype === o; }; var blacklistedKeys = { $window: true, $console: true, $parent: true, $self: true, $frame: true, $frames: true, $frameElement: true, $webkitIndexedDB: true, $webkitStorageInfo: true, $external: true }; var hasAutomationEqualityBug = (function () { /* globals window */ if (typeof window === 'undefined') { return false; } for (var k in window) { try { if (!blacklistedKeys['$' + k] && owns(window, k) && window[k] !== null && typeof window[k] === 'object') { equalsConstructorPrototype(window[k]); } } catch (e) { return true; } } return false; } ()); var equalsConstructorPrototypeIfNotBuggy = function (object) { if (typeof window === 'undefined' || !hasAutomationEqualityBug) { return equalsConstructorPrototype(object); } try { return equalsConstructorPrototype(object); } catch (e) { return false; } }; var dontEnums = [ 'toString', 'toLocaleString', 'valueOf', 'hasOwnProperty', 'isPrototypeOf', 'propertyIsEnumerable', 'constructor' ]; var dontEnumsLength = dontEnums.length; // taken directly from https://github.com/ljharb/is-arguments/blob/master/index.js // can be replaced with require('is-arguments') if we ever use a build process instead var isStandardArguments = function isArguments(value) { return toStr(value) === '[object Arguments]'; }; var isLegacyArguments = function isArguments(value) { return value !== null && typeof value === 'object' && typeof value.length === 'number' && value.length >= 0 && !isArray(value) && isCallable(value.callee); }; var isArguments = isStandardArguments(arguments) ? isStandardArguments : isLegacyArguments; defineProperties($Object, { keys: function keys(object) { var isFn = isCallable(object); var isArgs = isArguments(object); var isObject = object !== null && typeof object === 'object'; var isStr = isObject && isString(object); if (!isObject && !isFn && !isArgs) { throw new TypeError('Object.keys called on a non-object'); } var theKeys = []; var skipProto = hasProtoEnumBug && isFn; if ((isStr && hasStringEnumBug) || isArgs) { for (var i = 0; i < object.length; ++i) { push(theKeys, $String(i)); } } if (!isArgs) { for (var name in object) { if (!(skipProto && name === 'prototype') && owns(object, name)) { push(theKeys, $String(name)); } } } if (hasDontEnumBug) { var skipConstructor = equalsConstructorPrototypeIfNotBuggy(object); for (var j = 0; j < dontEnumsLength; j++) { var dontEnum = dontEnums[j]; if (!(skipConstructor && dontEnum === 'constructor') && owns(object, dontEnum)) { push(theKeys, dontEnum); } } } return theKeys; } }); var keysWorksWithArguments = $Object.keys && (function () { // Safari 5.0 bug return $Object.keys(arguments).length === 2; } (1, 2)); var keysHasArgumentsLengthBug = $Object.keys && (function () { var argKeys = $Object.keys(arguments); return arguments.length !== 1 || argKeys.length !== 1 || argKeys[0] !== 1; } (1)); var originalKeys = $Object.keys; defineProperties($Object, { keys: function keys(object) { if (isArguments(object)) { return originalKeys(arraySlice(object)); } else { return originalKeys(object); } } }, !keysWorksWithArguments || keysHasArgumentsLengthBug); // // Date // ==== // // ES5 15.9.5.43 // http://es5.github.com/#x15.9.5.43 // This function returns a String value represent the instance in time // represented by this Date object. The format of the String is the Date Time // string format defined in 15.9.1.15. All fields are present in the String. // The time zone is always UTC, denoted by the suffix Z. If the time value of // this object is not a finite Number a RangeError exception is thrown. var negativeDate = -62198755200000; var negativeYearString = '-000001'; var hasNegativeDateBug = Date.prototype.toISOString && new Date(negativeDate).toISOString().indexOf(negativeYearString) === -1; var hasSafari51DateBug = Date.prototype.toISOString && new Date(-1).toISOString() !== '1969-12-31T23:59:59.999Z'; defineProperties(Date.prototype, { toISOString: function toISOString() { var result, length, value, year, month; if (!isFinite(this)) { throw new RangeError('Date.prototype.toISOString called on non-finite value.'); } year = this.getUTCFullYear(); month = this.getUTCMonth(); // see https://github.com/es-shims/es5-shim/issues/111 year += Math.floor(month / 12); month = (month % 12 + 12) % 12; // the date time string format is specified in 15.9.1.15. result = [month + 1, this.getUTCDate(), this.getUTCHours(), this.getUTCMinutes(), this.getUTCSeconds()]; year = ( (year < 0 ? '-' : (year > 9999 ? '+' : '')) + strSlice('00000' + Math.abs(year), (0 <= year && year <= 9999) ? -4 : -6) ); length = result.length; while (length--) { value = result[length]; // pad months, days, hours, minutes, and seconds to have two // digits. if (value < 10) { result[length] = '0' + value; } } // pad milliseconds to have three digits. return ( year + '-' + arraySlice(result, 0, 2).join('-') + 'T' + arraySlice(result, 2).join(':') + '.' + strSlice('000' + this.getUTCMilliseconds(), -3) + 'Z' ); } }, hasNegativeDateBug || hasSafari51DateBug); // ES5 15.9.5.44 // http://es5.github.com/#x15.9.5.44 // This function provides a String representation of a Date object for use by // JSON.stringify (15.12.3). var dateToJSONIsSupported = (function () { try { return Date.prototype.toJSON && new Date(NaN).toJSON() === null && new Date(negativeDate).toJSON().indexOf(negativeYearString) !== -1 && Date.prototype.toJSON.call({ // generic toISOString: function () { return true; } }); } catch (e) { return false; } } ()); if (!dateToJSONIsSupported) { Date.prototype.toJSON = function toJSON(key) { // When the toJSON method is called with argument key, the following // steps are taken: // 1. Let O be the result of calling ToObject, giving it the this // value as its argument. // 2. Let tv be ES.ToPrimitive(O, hint Number). var O = $Object(this); var tv = ES.ToPrimitive(O); // 3. If tv is a Number and is not finite, return null. if (typeof tv === 'number' && !isFinite(tv)) { return null; } // 4. Let toISO be the result of calling the [[Get]] internal method of // O with argument "toISOString". var toISO = O.toISOString; // 5. If IsCallable(toISO) is false, throw a TypeError exception. if (!isCallable(toISO)) { throw new TypeError('toISOString property is not callable'); } // 6. Return the result of calling the [[Call]] internal method of // toISO with O as the this value and an empty argument list. return toISO.call(O); // NOTE 1 The argument is ignored. // NOTE 2 The toJSON function is intentionally generic; it does not // require that its this value be a Date object. Therefore, it can be // transferred to other kinds of objects for use as a method. However, // it does require that any such object have a toISOString method. An // object is free to use the argument key to filter its // stringification. }; } // ES5 15.9.4.2 // http://es5.github.com/#x15.9.4.2 // based on work shared by Daniel Friesen (dantman) // http://gist.github.com/303249 var supportsExtendedYears = Date.parse('+033658-09-27T01:46:40.000Z') === 1e15; var acceptsInvalidDates = !isNaN(Date.parse('2012-04-04T24:00:00.500Z')) || !isNaN(Date.parse('2012-11-31T23:59:59.000Z')) || !isNaN(Date.parse('2012-12-31T23:59:60.000Z')); var doesNotParseY2KNewYear = isNaN(Date.parse('2000-01-01T00:00:00.000Z')); if (doesNotParseY2KNewYear || acceptsInvalidDates || !supportsExtendedYears) { // XXX global assignment won't work in embeddings that use // an alternate object for the context. /* global Date: true */ /* eslint-disable no-undef */ var maxSafeUnsigned32Bit = Math.pow(2, 31) - 1; var hasSafariSignedIntBug = isActualNaN(new Date(1970, 0, 1, 0, 0, 0, maxSafeUnsigned32Bit + 1).getTime()); Date = (function (NativeDate) { /* eslint-enable no-undef */ // Date.length === 7 var DateShim = function Date(Y, M, D, h, m, s, ms) { var length = arguments.length; var date; if (this instanceof NativeDate) { var seconds = s; var millis = ms; if (hasSafariSignedIntBug && length >= 7 && ms > maxSafeUnsigned32Bit) { // work around a Safari 8/9 bug where it treats the seconds as signed var msToShift = Math.floor(ms / maxSafeUnsigned32Bit) * maxSafeUnsigned32Bit; var sToShift = Math.floor(msToShift / 1e3); seconds += sToShift; millis -= sToShift * 1e3; } date = length === 1 && $String(Y) === Y ? // isString(Y) // We explicitly pass it through parse: new NativeDate(DateShim.parse(Y)) : // We have to manually make calls depending on argument // length here length >= 7 ? new NativeDate(Y, M, D, h, m, seconds, millis) : length >= 6 ? new NativeDate(Y, M, D, h, m, seconds) : length >= 5 ? new NativeDate(Y, M, D, h, m) : length >= 4 ? new NativeDate(Y, M, D, h) : length >= 3 ? new NativeDate(Y, M, D) : length >= 2 ? new NativeDate(Y, M) : length >= 1 ? new NativeDate(Y) : new NativeDate(); } else { date = NativeDate.apply(this, arguments); } if (!isPrimitive(date)) { // Prevent mixups with unfixed Date object defineProperties(date, { constructor: DateShim }, true); } return date; }; // 15.9.1.15 Date Time String Format. var isoDateExpression = new RegExp('^' + '(\\d{4}|[+-]\\d{6})' + // four-digit year capture or sign + // 6-digit extended year '(?:-(\\d{2})' + // optional month capture '(?:-(\\d{2})' + // optional day capture '(?:' + // capture hours:minutes:seconds.milliseconds 'T(\\d{2})' + // hours capture ':(\\d{2})' + // minutes capture '(?:' + // optional :seconds.milliseconds ':(\\d{2})' + // seconds capture '(?:(\\.\\d{1,}))?' + // milliseconds capture ')?' + '(' + // capture UTC offset component 'Z|' + // UTC capture '(?:' + // offset specifier +/-hours:minutes '([-+])' + // sign capture '(\\d{2})' + // hours offset capture ':(\\d{2})' + // minutes offset capture ')' + ')?)?)?)?' + '$'); var months = [0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365]; var dayFromMonth = function dayFromMonth(year, month) { var t = month > 1 ? 1 : 0; return ( months[month] + Math.floor((year - 1969 + t) / 4) - Math.floor((year - 1901 + t) / 100) + Math.floor((year - 1601 + t) / 400) + 365 * (year - 1970) ); }; var toUTC = function toUTC(t) { var s = 0; var ms = t; if (hasSafariSignedIntBug && ms > maxSafeUnsigned32Bit) { // work around a Safari 8/9 bug where it treats the seconds as signed var msToShift = Math.floor(ms / maxSafeUnsigned32Bit) * maxSafeUnsigned32Bit; var sToShift = Math.floor(msToShift / 1e3); s += sToShift; ms -= sToShift * 1e3; } return $Number(new NativeDate(1970, 0, 1, 0, 0, s, ms)); }; // Copy any custom methods a 3rd party library may have added for (var key in NativeDate) { if (owns(NativeDate, key)) { DateShim[key] = NativeDate[key]; } } // Copy "native" methods explicitly; they may be non-enumerable defineProperties(DateShim, { now: NativeDate.now, UTC: NativeDate.UTC }, true); DateShim.prototype = NativeDate.prototype; defineProperties(DateShim.prototype, { constructor: DateShim }, true); // Upgrade Date.parse to handle simplified ISO 8601 strings var parseShim = function parse(string) { var match = isoDateExpression.exec(string); if (match) { // parse months, days, hours, minutes, seconds, and milliseconds // provide default values if necessary // parse the UTC offset component var year = $Number(match[1]), month = $Number(match[2] || 1) - 1, day = $Number(match[3] || 1) - 1, hour = $Number(match[4] || 0), minute = $Number(match[5] || 0), second = $Number(match[6] || 0), millisecond = Math.floor($Number(match[7] || 0) * 1000), // When time zone is missed, local offset should be used // (ES 5.1 bug) // see https://bugs.ecmascript.org/show_bug.cgi?id=112 isLocalTime = Boolean(match[4] && !match[8]), signOffset = match[9] === '-' ? 1 : -1, hourOffset = $Number(match[10] || 0), minuteOffset = $Number(match[11] || 0), result; var hasMinutesOrSecondsOrMilliseconds = minute > 0 || second > 0 || millisecond > 0; if ( hour < (hasMinutesOrSecondsOrMilliseconds ? 24 : 25) && minute < 60 && second < 60 && millisecond < 1000 && month > -1 && month < 12 && hourOffset < 24 && minuteOffset < 60 && // detect invalid offsets day > -1 && day < (dayFromMonth(year, month + 1) - dayFromMonth(year, month)) ) { result = ( (dayFromMonth(year, month) + day) * 24 + hour + hourOffset * signOffset ) * 60; result = ( (result + minute + minuteOffset * signOffset) * 60 + second ) * 1000 + millisecond; if (isLocalTime) { result = toUTC(result); } if (-8.64e15 <= result && result <= 8.64e15) { return result; } } return NaN; } return NativeDate.parse.apply(this, arguments); }; defineProperties(DateShim, { parse: parseShim }); return DateShim; } (Date)); /* global Date: false */ } // ES5 15.9.4.4 // http://es5.github.com/#x15.9.4.4 if (!Date.now) { Date.now = function now() { return new Date().getTime(); }; } // // Number // ====== // // ES5.1 15.7.4.5 // http://es5.github.com/#x15.7.4.5 var hasToFixedBugs = NumberPrototype.toFixed && ( (0.00008).toFixed(3) !== '0.000' || (0.9).toFixed(0) !== '1' || (1.255).toFixed(2) !== '1.25' || (1000000000000000128).toFixed(0) !== '1000000000000000128' ); var toFixedHelpers = { base: 1e7, size: 6, data: [0, 0, 0, 0, 0, 0], multiply: function multiply(n, c) { var i = -1; var c2 = c; while (++i < toFixedHelpers.size) { c2 += n * toFixedHelpers.data[i]; toFixedHelpers.data[i] = c2 % toFixedHelpers.base; c2 = Math.floor(c2 / toFixedHelpers.base); } }, divide: function divide(n) { var i = toFixedHelpers.size, c = 0; while (--i >= 0) { c += toFixedHelpers.data[i]; toFixedHelpers.data[i] = Math.floor(c / n); c = (c % n) * toFixedHelpers.base; } }, numToString: function numToString() { var i = toFixedHelpers.size; var s = ''; while (--i >= 0) { if (s !== '' || i === 0 || toFixedHelpers.data[i] !== 0) { var t = $String(toFixedHelpers.data[i]); if (s === '') { s = t; } else { s += strSlice('0000000', 0, 7 - t.length) + t; } } } return s; }, pow: function pow(x, n, acc) { return (n === 0 ? acc : (n % 2 === 1 ? pow(x, n - 1, acc * x) : pow(x * x, n / 2, acc))); }, log: function log(x) { var n = 0; var x2 = x; while (x2 >= 4096) { n += 12; x2 /= 4096; } while (x2 >= 2) { n += 1; x2 /= 2; } return n; } }; var toFixedShim = function toFixed(fractionDigits) { var f, x, s, m, e, z, j, k; // Test for NaN and round fractionDigits down f = $Number(fractionDigits); f = isActualNaN(f) ? 0 : Math.floor(f); if (f < 0 || f > 20) { throw new RangeError('Number.toFixed called with invalid number of decimals'); } x = $Number(this); if (isActualNaN(x)) { return 'NaN'; } // If it is too big or small, return the string value of the number if (x <= -1e21 || x >= 1e21) { return $String(x); } s = ''; if (x < 0) { s = '-'; x = -x; } m = '0'; if (x > 1e-21) { // 1e-21 < x < 1e21 // -70 < log2(x) < 70 e = toFixedHelpers.log(x * toFixedHelpers.pow(2, 69, 1)) - 69; z = (e < 0 ? x * toFixedHelpers.pow(2, -e, 1) : x / toFixedHelpers.pow(2, e, 1)); z *= 0x10000000000000; // Math.pow(2, 52); e = 52 - e; // -18 < e < 122 // x = z / 2 ^ e if (e > 0) { toFixedHelpers.multiply(0, z); j = f; while (j >= 7) { toFixedHelpers.multiply(1e7, 0); j -= 7; } toFixedHelpers.multiply(toFixedHelpers.pow(10, j, 1), 0); j = e - 1; while (j >= 23) { toFixedHelpers.divide(1 << 23); j -= 23; } toFixedHelpers.divide(1 << j); toFixedHelpers.multiply(1, 1); toFixedHelpers.divide(2); m = toFixedHelpers.numToString(); } else { toFixedHelpers.multiply(0, z); toFixedHelpers.multiply(1 << (-e), 0); m = toFixedHelpers.numToString() + strSlice('0.00000000000000000000', 2, 2 + f); } } if (f > 0) { k = m.length; if (k <= f) { m = s + strSlice('0.0000000000000000000', 0, f - k + 2) + m; } else { m = s + strSlice(m, 0, k - f) + '.' + strSlice(m, k - f); } } else { m = s + m; } return m; }; defineProperties(NumberPrototype, { toFixed: toFixedShim }, hasToFixedBugs); var hasToPrecisionUndefinedBug = (function () { try { return 1.0.toPrecision(undefined) === '1'; } catch (e) { return true; } } ()); var originalToPrecision = NumberPrototype.toPrecision; defineProperties(NumberPrototype, { toPrecision: function toPrecision(precision) { return typeof precision === 'undefined' ? originalToPrecision.call(this) : originalToPrecision.call(this, precision); } }, hasToPrecisionUndefinedBug); // // String // ====== // // ES5 15.5.4.14 // http://es5.github.com/#x15.5.4.14 // [bugfix, IE lt 9, firefox 4, Konqueror, Opera, obscure browsers] // Many browsers do not split properly with regular expressions or they // do not perform the split correctly under obscure conditions. // See http://blog.stevenlevithan.com/archives/cross-browser-split // I've tested in many browsers and this seems to cover the deviant ones: // 'ab'.split(/(?:ab)*/) should be ["", ""], not [""] // '.'.split(/(.?)(.?)/) should be ["", ".", "", ""], not ["", ""] // 'tesst'.split(/(s)*/) should be ["t", undefined, "e", "s", "t"], not // [undefined, "t", undefined, "e", ...] // ''.split(/.?/) should be [], not [""] // '.'.split(/()()/) should be ["."], not ["", "", "."] if ( 'ab'.split(/(?:ab)*/).length !== 2 || '.'.split(/(.?)(.?)/).length !== 4 || 'tesst'.split(/(s)*/)[1] === 't' || 'test'.split(/(?:)/, -1).length !== 4 || ''.split(/.?/).length || '.'.split(/()()/).length > 1 ) { (function () { var compliantExecNpcg = typeof (/()??/).exec('')[1] === 'undefined'; // NPCG: nonparticipating capturing group var maxSafe32BitInt = Math.pow(2, 32) - 1; StringPrototype.split = function (separator, limit) { var string = String(this); if (typeof separator === 'undefined' && limit === 0) { return []; } // If `separator` is not a regex, use native split if (!isRegex(separator)) { return strSplit(this, separator, limit); } var output = []; var flags = (separator.ignoreCase ? 'i' : '') + (separator.multiline ? 'm' : '') + (separator.unicode ? 'u' : '') + // in ES6 (separator.sticky ? 'y' : ''), // Firefox 3+ and ES6 lastLastIndex = 0, // Make `global` and avoid `lastIndex` issues by working with a copy separator2, match, lastIndex, lastLength; var separatorCopy = new RegExp(separator.source, flags + 'g'); if (!compliantExecNpcg) { // Doesn't need flags gy, but they don't hurt separator2 = new RegExp('^' + separatorCopy.source + '$(?!\\s)', flags); } /* Values for `limit`, per the spec: * If undefined: 4294967295 // maxSafe32BitInt * If 0, Infinity, or NaN: 0 * If positive number: limit = Math.floor(limit); if (limit > 4294967295) limit -= 4294967296; * If negative number: 4294967296 - Math.floor(Math.abs(limit)) * If other: Type-convert, then use the above rules */ var splitLimit = typeof limit === 'undefined' ? maxSafe32BitInt : ES.ToUint32(limit); match = separatorCopy.exec(string); while (match) { // `separatorCopy.lastIndex` is not reliable cross-browser lastIndex = match.index + match[0].length; if (lastIndex > lastLastIndex) { push(output, strSlice(string, lastLastIndex, match.index)); // Fix browsers whose `exec` methods don't consistently return `undefined` for // nonparticipating capturing groups if (!compliantExecNpcg && match.length > 1) { /* eslint-disable no-loop-func */ match[0].replace(separator2, function () { for (var i = 1; i < arguments.length - 2; i++) { if (typeof arguments[i] === 'undefined') { match[i] = void 0; } } }); /* eslint-enable no-loop-func */ } if (match.length > 1 && match.index < string.length) { array_push.apply(output, arraySlice(match, 1)); } lastLength = match[0].length; lastLastIndex = lastIndex; if (output.length >= splitLimit) { break; } } if (separatorCopy.lastIndex === match.index) { separatorCopy.lastIndex++; // Avoid an infinite loop } match = separatorCopy.exec(string); } if (lastLastIndex === string.length) { if (lastLength || !separatorCopy.test('')) { push(output, ''); } } else { push(output, strSlice(string, lastLastIndex)); } return output.length > splitLimit ? strSlice(output, 0, splitLimit) : output; }; } ()); // [bugfix, chrome] // If separator is undefined, then the result array contains just one String, // which is the this value (converted to a String). If limit is not undefined, // then the output array is truncated so that it contains no more than limit // elements. // "0".split(undefined, 0) -> [] } else if ('0'.split(void 0, 0).length) { StringPrototype.split = function split(separator, limit) { if (typeof separator === 'undefined' && limit === 0) { return []; } return strSplit(this, separator, limit); }; } var str_replace = StringPrototype.replace; var replaceReportsGroupsCorrectly = (function () { var groups = []; 'x'.replace(/x(.)?/g, function (match, group) { push(groups, group); }); return groups.length === 1 && typeof groups[0] === 'undefined'; } ()); if (!replaceReportsGroupsCorrectly) { StringPrototype.replace = function replace(searchValue, replaceValue) { var isFn = isCallable(replaceValue); var hasCapturingGroups = isRegex(searchValue) && (/\)[*?]/).test(searchValue.source); if (!isFn || !hasCapturingGroups) { return str_replace.call(this, searchValue, replaceValue); } else { var wrappedReplaceValue = function (match) { var length = arguments.length; var originalLastIndex = searchValue.lastIndex; searchValue.lastIndex = 0; var args = searchValue.exec(match) || []; searchValue.lastIndex = originalLastIndex; push(args, arguments[length - 2], arguments[length - 1]); return replaceValue.apply(this, args); }; return str_replace.call(this, searchValue, wrappedReplaceValue); } }; } // ECMA-262, 3rd B.2.3 // Not an ECMAScript standard, although ECMAScript 3rd Edition has a // non-normative section suggesting uniform semantics and it should be // normalized across all browsers // [bugfix, IE lt 9] IE < 9 substr() with negative value not working in IE var string_substr = StringPrototype.substr; var hasNegativeSubstrBug = ''.substr && '0b'.substr(-1) !== 'b'; defineProperties(StringPrototype, { substr: function substr(start, length) { var normalizedStart = start; if (start < 0) { normalizedStart = max(this.length + start, 0); } return string_substr.call(this, normalizedStart, length); } }, hasNegativeSubstrBug); // ES5 15.5.4.20 // whitespace from: http://es5.github.io/#x15.5.4.20 var ws = '\x09\x0A\x0B\x0C\x0D\x20\xA0\u1680\u180E\u2000\u2001\u2002\u2003' + '\u2004\u2005\u2006\u2007\u2008\u2009\u200A\u202F\u205F\u3000\u2028' + '\u2029\uFEFF'; var zeroWidth = '\u200b'; var wsRegexChars = '[' + ws + ']'; var trimBeginRegexp = new RegExp('^' + wsRegexChars + wsRegexChars + '*'); var trimEndRegexp = new RegExp(wsRegexChars + wsRegexChars + '*$'); var hasTrimWhitespaceBug = StringPrototype.trim && (ws.trim() || !zeroWidth.trim()); defineProperties(StringPrototype, { // http://blog.stevenlevithan.com/archives/faster-trim-javascript // http://perfectionkills.com/whitespace-deviations/ trim: function trim() { if (typeof this === 'undefined' || this === null) { throw new TypeError("can't convert " + this + ' to object'); } return $String(this).replace(trimBeginRegexp, '').replace(trimEndRegexp, ''); } }, hasTrimWhitespaceBug); var hasLastIndexBug = StringPrototype.lastIndexOf && 'abcあい'.lastIndexOf('あい', 2) !== -1; defineProperties(StringPrototype, { lastIndexOf: function lastIndexOf(searchString) { if (typeof this === 'undefined' || this === null) { throw new TypeError("can't convert " + this + ' to object'); } var S = $String(this); var searchStr = $String(searchString); var numPos = arguments.length > 1 ? $Number(arguments[1]) : NaN; var pos = isActualNaN(numPos) ? Infinity : ES.ToInteger(numPos); var start = min(max(pos, 0), S.length); var searchLen = searchStr.length; var k = start + searchLen; while (k > 0) { k = max(0, k - searchLen); var index = strIndexOf(strSlice(S, k, start + searchLen), searchStr); if (index !== -1) { return k + index; } } return -1; } }, hasLastIndexBug); var originalLastIndexOf = StringPrototype.lastIndexOf; defineProperties(StringPrototype, { lastIndexOf: function lastIndexOf(searchString) { return originalLastIndexOf.apply(this, arguments); } }, StringPrototype.lastIndexOf.length !== 1); // ES-5 15.1.2.2 /* eslint-disable radix */ if (parseInt(ws + '08') !== 8 || parseInt(ws + '0x16') !== 22) { /* eslint-enable radix */ /* global parseInt: true */ parseInt = (function (origParseInt) { var hexRegex = /^[\-+]?0[xX]/; return function parseInt(str, radix) { var string = $String(str).trim(); var defaultedRadix = $Number(radix) || (hexRegex.test(string) ? 16 : 10); return origParseInt(string, defaultedRadix); }; } (parseInt)); } if (String(new RangeError('test')) !== 'RangeError: test') { var errorToStringShim = function toString() { if (typeof this === 'undefined' || this === null) { throw new TypeError("can't convert " + this + ' to object'); } var name = this.name; if (typeof name === 'undefined') { name = 'Error'; } else if (typeof name !== 'string') { name = $String(name); } var msg = this.message; if (typeof msg === 'undefined') { msg = ''; } else if (typeof msg !== 'string') { msg = $String(msg); } if (!name) { return msg; } if (!msg) { return name; } return name + ': ' + msg; }; // can't use defineProperties here because of toString enumeration issue in IE <= 8 Error.prototype.toString = errorToStringShim; } if (supportsDescriptors) { var ensureNonEnumerable = function (obj, prop) { if (isEnum(obj, prop)) { var desc = Object.getOwnPropertyDescriptor(obj, prop); desc.enumerable = false; Object.defineProperty(obj, prop, desc); } }; ensureNonEnumerable(Error.prototype, 'message'); if (Error.prototype.message !== '') { Error.prototype.message = ''; } ensureNonEnumerable(Error.prototype, 'name'); } if (String(/a/mig) !== '/a/gim') { var regexToString = function toString() { var str = '/' + this.source + '/'; if (this.global) { str += 'g'; } if (this.ignoreCase) { str += 'i'; } if (this.multiline) { str += 'm'; } return str; }; // can't use defineProperties here because of toString enumeration issue in IE <= 8 RegExp.prototype.toString = regexToString; } })); }, {}], 26: [function (_dereq_, module, exports) { var arr = []; var each = arr.forEach; var slice = arr.slice; module.exports = function (obj) { each.call(slice.call(arguments, 1), function (source) { if (source) { for (var prop in source) { obj[prop] = source[prop]; } } }); return obj; }; }, {}], 27: [function (_dereq_, module, exports) { module.exports = isFunction var toString = Object.prototype.toString function isFunction(fn) { var string = toString.call(fn) return string === '[object Function]' || (typeof fn === 'function' && string !== '[object RegExp]') || (typeof window !== 'undefined' && // IE8 and below (fn === window.setTimeout || fn === window.alert || fn === window.confirm || fn === window.prompt)) }; }, {}], 28: [function (_dereq_, module, exports) { "use strict"; module.exports = function isObject(x) { return typeof x === "object" && x !== null; }; }, {}], 29: [function (_dereq_, module, exports) { /*! * $script.js JS loader & dependency manager * https://github.com/ded/script.js * (c) Dustin Diaz 2014 | License MIT */ (function (name, definition) { if (typeof module != 'undefined' && module.exports) module.exports = definition() else if (typeof define == 'function' && define.amd) define(definition) else this[name] = definition() })('$script', function () { var doc = document , head = doc.getElementsByTagName('head')[0] , s = 'string' , f = false , push = 'push' , readyState = 'readyState' , onreadystatechange = 'onreadystatechange' , list = {} , ids = {} , delay = {} , scripts = {} , scriptpath , urlArgs function every(ar, fn) { for (var i = 0, j = ar.length; i < j; ++i) if (!fn(ar[i])) return f return 1 } function each(ar, fn) { every(ar, function (el) { return !fn(el) }) } function $script(paths, idOrDone, optDone) { paths = paths[push] ? paths : [paths] var idOrDoneIsDone = idOrDone && idOrDone.call , done = idOrDoneIsDone ? idOrDone : optDone , id = idOrDoneIsDone ? paths.join('') : idOrDone , queue = paths.length function loopFn(item) { return item.call ? item() : list[item] } function callback() { if (! --queue) { list[id] = 1 done && done() for (var dset in delay) { every(dset.split('|'), loopFn) && !each(delay[dset], loopFn) && (delay[dset] = []) } } } setTimeout(function () { each(paths, function loading(path, force) { if (path === null) return callback() if (!force && !/^https?:\/\//.test(path) && scriptpath) { path = (path.indexOf('.js') === -1) ? scriptpath + path + '.js' : scriptpath + path; } if (scripts[path]) { if (id) ids[id] = 1 return (scripts[path] == 2) ? callback() : setTimeout(function () { loading(path, true) }, 0) } scripts[path] = 1 if (id) ids[id] = 1 create(path, callback) }) }, 0) return $script } function create(path, fn) { var el = doc.createElement('script'), loaded el.onload = el.onerror = el[onreadystatechange] = function () { if ((el[readyState] && !(/^c|loade/.test(el[readyState]))) || loaded) return; el.onload = el[onreadystatechange] = null loaded = 1 scripts[path] = 2 fn() } el.async = 1 el.src = urlArgs ? path + (path.indexOf('?') === -1 ? '?' : '&') + urlArgs : path; head.insertBefore(el, head.lastChild) } $script.get = create $script.order = function (scripts, id, done) { (function callback(s) { s = scripts.shift() !scripts.length ? $script(s, id, done) : $script(s, callback) } ()) } $script.path = function (p) { scriptpath = p } $script.urlArgs = function (str) { urlArgs = str; } $script.ready = function (deps, ready, req) { deps = deps[push] ? deps : [deps] var missing = []; !each(deps, function (dep) { list[dep] || missing[push](dep); }) && every(deps, function (dep) { return list[dep] }) ? ready() : !function (key) { delay[key] = delay[key] || [] delay[key][push](ready) req && req(missing) } (deps.join('|')) return $script } $script.done = function (idOrDone) { $script([null], idOrDone) } return $script }); }, {}] }, {}, [19])(19) });