+*/
+
+var swfmini = function() {
+ var wasRemoved = function(){webshims.error('This method was removed from swfmini');};
+ var UNDEF = "undefined",
+ OBJECT = "object",
+ webshims = window.webshims,
+ SHOCKWAVE_FLASH = "Shockwave Flash",
+ SHOCKWAVE_FLASH_AX = "ShockwaveFlash.ShockwaveFlash",
+ FLASH_MIME_TYPE = "application/x-shockwave-flash",
+
+ win = window,
+ doc = document,
+ nav = navigator,
+
+ plugin = false,
+ domLoadFnArr = [main],
+
+ isDomLoaded = false,
+ autoHideShow = true,
+
+ /* Centralized function for browser feature detection
+ - User agent string detection is only used when no good alternative is possible
+ - Is executed directly for optimal performance
+ */
+ ua = function() {
+ var w3cdom = typeof doc.getElementById != UNDEF && typeof doc.getElementsByTagName != UNDEF && typeof doc.createElement != UNDEF,
+ u = nav.userAgent.toLowerCase(),
+ p = nav.platform.toLowerCase(),
+ windows = p ? /win/.test(p) : /win/.test(u),
+ mac = p ? /mac/.test(p) : /mac/.test(u),
+ webkit = /webkit/.test(u) ? parseFloat(u.replace(/^.*webkit\/(\d+(\.\d+)?).*$/, "$1")) : false, // returns either the webkit version or false if not webkit
+ ie = !+"\v1", // feature detection based on Andrea Giammarchi's solution: http://webreflection.blogspot.com/2009/01/32-bytes-to-know-if-your-browser-is-ie.html
+ playerVersion = [0,0,0],
+ d = null;
+ if (typeof nav.plugins != UNDEF && typeof nav.plugins[SHOCKWAVE_FLASH] == OBJECT) {
+ d = nav.plugins[SHOCKWAVE_FLASH].description;
+ if (d && !(typeof nav.mimeTypes != UNDEF && nav.mimeTypes[FLASH_MIME_TYPE] && !nav.mimeTypes[FLASH_MIME_TYPE].enabledPlugin)) { // navigator.mimeTypes["application/x-shockwave-flash"].enabledPlugin indicates whether plug-ins are enabled or disabled in Safari 3+
+ plugin = true;
+ ie = false; // cascaded feature detection for Internet Explorer
+ d = d.replace(/^.*\s+(\S+\s+\S+$)/, "$1");
+ playerVersion[0] = parseInt(d.replace(/^(.*)\..*$/, "$1"), 10);
+ playerVersion[1] = parseInt(d.replace(/^.*\.(.*)\s.*$/, "$1"), 10);
+ playerVersion[2] = /[a-zA-Z]/.test(d) ? parseInt(d.replace(/^.*[a-zA-Z]+(.*)$/, "$1"), 10) : 0;
+ }
+ }
+ else if (typeof win.ActiveXObject != UNDEF) {
+ try {
+ var a = new ActiveXObject(SHOCKWAVE_FLASH_AX);
+ if (a) { // a will return null when ActiveX is disabled
+ d = a.GetVariable("$version");
+ if (d) {
+ ie = true; // cascaded feature detection for Internet Explorer
+ d = d.split(" ")[1].split(",");
+ playerVersion = [parseInt(d[0], 10), parseInt(d[1], 10), parseInt(d[2], 10)];
+ }
+ }
+ }
+ catch(e) {}
+ }
+ return { w3:w3cdom, pv:playerVersion, wk:webkit, ie:ie, win:windows, mac:mac };
+ }();
+
+
+ function callDomLoadFunctions() {
+ if (isDomLoaded) { return; }
+ isDomLoaded = true;
+ var dl = domLoadFnArr.length;
+ for (var i = 0; i < dl; i++) {
+ domLoadFnArr[i]();
+ }
+ }
+
+ function addDomLoadEvent(fn) {
+ if (isDomLoaded) {
+ fn();
+ }
+ else {
+ domLoadFnArr[domLoadFnArr.length] = fn; // Array.push() is only available in IE5.5+
+ }
+ }
+
+
+ /* Main function
+ - Will preferably execute onDomLoad, otherwise onload (as a fallback)
+ */
+ function main() {
+ if (plugin) {
+ testPlayerVersion();
+ }
+ }
+
+ /* Detect the Flash Player version for non-Internet Explorer browsers
+ - Detecting the plug-in version via the object element is more precise than using the plugins collection item's description:
+ a. Both release and build numbers can be detected
+ b. Avoid wrong descriptions by corrupt installers provided by Adobe
+ c. Avoid wrong descriptions by multiple Flash Player entries in the plugin Array, caused by incorrect browser imports
+ - Disadvantage of this method is that it depends on the availability of the DOM, while the plugins collection is immediately available
+ */
+ function testPlayerVersion() {
+ var b = doc.getElementsByTagName("body")[0];
+ var o = createElement(OBJECT);
+ o.setAttribute("type", FLASH_MIME_TYPE);
+ var t = b.appendChild(o);
+ if (t) {
+ var counter = 0;
+ (function(){
+ if (typeof t.GetVariable != UNDEF) {
+ var d = t.GetVariable("$version");
+ if (d) {
+ d = d.split(" ")[1].split(",");
+ ua.pv = [parseInt(d[0], 10), parseInt(d[1], 10), parseInt(d[2], 10)];
+ }
+ }
+ else if (counter < 10) {
+ counter++;
+ setTimeout(arguments.callee, 10);
+ return;
+ }
+ b.removeChild(o);
+ t = null;
+ })();
+ }
+ }
+
+
+ function createElement(el) {
+ return doc.createElement(el);
+ }
+
+
+ /* Flash Player and SWF content version matching
+ */
+ function hasPlayerVersion(rv) {
+ var pv = ua.pv, v = rv.split(".");
+ v[0] = parseInt(v[0], 10);
+ v[1] = parseInt(v[1], 10) || 0; // supports short notation, e.g. "9" instead of "9.0.0"
+ v[2] = parseInt(v[2], 10) || 0;
+ return (pv[0] > v[0] || (pv[0] == v[0] && pv[1] > v[1]) || (pv[0] == v[0] && pv[1] == v[1] && pv[2] >= v[2])) ? true : false;
+ }
+
+
+
+
+
+ webshims.ready('DOM', callDomLoadFunctions);
+
+ webshims.loader.addModule('swfmini-embed', {d: ['swfmini']});
+ var loadEmbed = hasPlayerVersion('9.0.0') ?
+ function(){
+ webshims.loader.loadList(['swfmini-embed']);
+ return true;
+ } :
+ webshims.$.noop
+ ;
+
+ if(!webshims.support.mediaelement){
+ loadEmbed();
+ } else {
+ webshims.ready('WINDOWLOAD', loadEmbed);
+ }
+
+ return {
+ /* Public API
+ - Reference: http://code.google.com/p/swfobject/wiki/documentation
+ */
+ registerObject: wasRemoved,
+
+ getObjectById: wasRemoved,
+
+ embedSWF: function(swfUrlStr, replaceElemIdStr, widthStr, heightStr, swfVersionStr, xiSwfUrlStr, flashvarsObj, parObj, attObj, callbackFn) {
+ var args = arguments;
+ if(loadEmbed()){
+ webshims.ready('swfmini-embed', function(){
+ swfmini.embedSWF.apply(swfmini, args);
+ });
+ } else if(callbackFn) {
+ callbackFn({success:false, id:replaceElemIdStr});
+ }
+ },
+
+ switchOffAutoHideShow: function() {
+ autoHideShow = false;
+ },
+
+ ua: ua,
+
+ getFlashPlayerVersion: function() {
+ return { major:ua.pv[0], minor:ua.pv[1], release:ua.pv[2] };
+ },
+
+ hasFlashPlayerVersion: hasPlayerVersion,
+
+ createSWF: function(attObj, parObj, replaceElemIdStr) {
+ if (ua.w3) {
+ return createSWF(attObj, parObj, replaceElemIdStr);
+ }
+ else {
+ return undefined;
+ }
+ },
+
+ showExpressInstall: wasRemoved,
+
+ removeSWF: wasRemoved,
+
+ createCSS: wasRemoved,
+
+ addDomLoadEvent: addDomLoadEvent,
+
+ addLoadEvent: wasRemoved,
+
+
+ // For internal usage only
+ expressInstallCallback: wasRemoved
+ };
+}();
+
+webshims.isReady('swfmini', true);
+;
+//this might was already extended by ES5 shim feature
+(function($){
+ "use strict";
+ var webshims = window.webshims;
+ if(webshims.defineProperties){return;}
+ var defineProperty = 'defineProperty';
+ var has = Object.prototype.hasOwnProperty;
+ var descProps = ['configurable', 'enumerable', 'writable'];
+ var extendUndefined = function(prop){
+ for(var i = 0; i < 3; i++){
+ if(prop[descProps[i]] === undefined && (descProps[i] !== 'writable' || prop.value !== undefined)){
+ prop[descProps[i]] = true;
+ }
+ }
+ };
+
+ var extendProps = function(props){
+ if(props){
+ for(var i in props){
+ if(has.call(props, i)){
+ extendUndefined(props[i]);
+ }
+ }
+ }
+ };
+
+ if(Object.create){
+ webshims.objectCreate = function(proto, props, opts){
+ extendProps(props);
+ var o = Object.create(proto, props);
+ if(opts){
+ o.options = $.extend(true, {}, o.options || {}, opts);
+ opts = o.options;
+ }
+ if(o._create && $.isFunction(o._create)){
+ o._create(opts);
+ }
+ return o;
+ };
+ }
+
+ if(Object[defineProperty]){
+ webshims[defineProperty] = function(obj, prop, desc){
+ extendUndefined(desc);
+ return Object[defineProperty](obj, prop, desc);
+ };
+ }
+ if(Object.defineProperties){
+ webshims.defineProperties = function(obj, props){
+ extendProps(props);
+ return Object.defineProperties(obj, props);
+ };
+ }
+ webshims.getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor;
+
+ webshims.getPrototypeOf = Object.getPrototypeOf;
+})(window.webshims.$);
+//DOM-Extension helper
+webshims.register('dom-extend', function($, webshims, window, document, undefined){
+ "use strict";
+ var supportHrefNormalized = !('hrefNormalized' in $.support) || $.support.hrefNormalized;
+ var supportGetSetAttribute = !('getSetAttribute' in $.support) || $.support.getSetAttribute;
+ var has = Object.prototype.hasOwnProperty;
+ webshims.assumeARIA = true;
+
+ if($('').attr('type') == 'text' || $('').attr('novalidate') === "" || ('required' in $('')[0].attributes)){
+ webshims.error("IE browser modes are busted in IE10+. Please test your HTML/CSS/JS with a real IE version or at least IETester or similiar tools");
+ }
+
+ if('debug' in webshims){
+ webshims.error('Use webshims.setOptions("debug", true||false||"noCombo"); to debug flag');
+ }
+
+ if (!webshims.cfg.no$Switch) {
+ var switch$ = function(){
+ if (window.jQuery && (!window.$ || window.jQuery == window.$) && !window.jQuery.webshims) {
+ webshims.error("jQuery was included more than once. Make sure to include it only once or try the $.noConflict(extreme) feature! Webshims and other Plugins might not work properly. Or set webshims.cfg.no$Switch to 'true'.");
+ if (window.$) {
+ window.$ = webshims.$;
+ }
+ window.jQuery = webshims.$;
+ }
+ };
+ switch$();
+ setTimeout(switch$, 90);
+ webshims.ready('DOM', switch$);
+ $(switch$);
+ webshims.ready('WINDOWLOAD', switch$);
+
+ }
+
+ //shortcus
+ var modules = webshims.modules;
+ var listReg = /\s*,\s*/;
+
+ //proxying attribute
+ var olds = {};
+ var havePolyfill = {};
+ var hasPolyfillMethod = {};
+ var extendedProps = {};
+ var extendQ = {};
+ var modifyProps = {};
+
+ var oldVal = $.fn.val;
+ var singleVal = function(elem, name, val, pass, _argless){
+ return (_argless) ? oldVal.call($(elem)) : oldVal.call($(elem), val);
+ };
+
+ //jquery mobile and jquery ui
+ if(!$.widget){
+ (function(){
+ var _cleanData = $.cleanData;
+ $.cleanData = function( elems ) {
+ if(!$.widget){
+ for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) {
+ try {
+ $( elem ).triggerHandler( "remove" );
+ // http://bugs.jquery.com/ticket/8235
+ } catch( e ) {}
+ }
+ }
+ _cleanData( elems );
+ };
+ })();
+ }
+
+
+ $.fn.val = function(val){
+ var elem = this[0];
+ if(arguments.length && val == null){
+ val = '';
+ }
+ if(!arguments.length){
+ if(!elem || elem.nodeType !== 1){return oldVal.call(this);}
+ return $.prop(elem, 'value', val, 'val', true);
+ }
+ if($.isArray(val)){
+ return oldVal.apply(this, arguments);
+ }
+ var isFunction = $.isFunction(val);
+ return this.each(function(i){
+ elem = this;
+ if(elem.nodeType === 1){
+ if(isFunction){
+ var genVal = val.call( elem, i, $.prop(elem, 'value', undefined, 'val', true));
+ if(genVal == null){
+ genVal = '';
+ }
+ $.prop(elem, 'value', genVal, 'val') ;
+ } else {
+ $.prop(elem, 'value', val, 'val');
+ }
+ }
+ });
+ };
+ $.fn.onTrigger = function(evt, fn){
+ return this.on(evt, fn).each(fn);
+ };
+
+ $.fn.onWSOff = function(evt, fn, trigger, evtDel){
+ if(!evtDel){
+ evtDel = document;
+ }
+ $(evtDel)[trigger ? 'onTrigger' : 'on'](evt, fn);
+ this.on('remove', function(e){
+ if(!e.originalEvent){
+ $(evtDel).off(evt, fn);
+ }
+ });
+ return this;
+ };
+ var idCount = 0;
+ var dataID = '_webshims'+ (Math.round(Math.random() * 1000));
+ var elementData = function(elem, key, val){
+ elem = elem.jquery ? elem[0] : elem;
+ if(!elem){return val || {};}
+ var data = $.data(elem, dataID);
+ if(val !== undefined){
+ if(!data){
+ data = $.data(elem, dataID, {});
+ }
+ if(key){
+ data[key] = val;
+ }
+ }
+
+ return key ? data && data[key] : data;
+ };
+
+
+ [{name: 'getNativeElement', prop: 'nativeElement'}, {name: 'getShadowElement', prop: 'shadowElement'}, {name: 'getShadowFocusElement', prop: 'shadowFocusElement'}].forEach(function(data){
+ $.fn[data.name] = function(){
+ var elems = [];
+ this.each(function(){
+ var shadowData = elementData(this, 'shadowData');
+ var elem = shadowData && shadowData[data.prop] || this;
+ if($.inArray(elem, elems) == -1){
+ elems.push(elem);
+ }
+ });
+ return this.pushStack(elems);
+ };
+ });
+
+ function clone(elem, dataAndEvents, uniqueIds){
+ var cloned = $.clone( elem, dataAndEvents, false );
+ $(cloned.querySelectorAll('.'+webshims.shadowClass)).detach();
+ if(uniqueIds){
+ idCount++;
+ $(cloned.querySelectorAll('[id]')).prop('id', function(i, id){
+ return id +idCount;
+ });
+ } else {
+ $(cloned.querySelectorAll('audio[id^="ID-"], video[id^="ID-"], label[id^="ID-"]')).removeAttr('id');
+ }
+ return cloned;
+ }
+
+ $.fn.clonePolyfill = function(dataAndEvents, uniqueIds){
+ dataAndEvents = dataAndEvents || false;
+ return this
+ .map(function() {
+ var cloned = clone( this, dataAndEvents, uniqueIds );
+ setTimeout(function(){
+ if($.contains(document.body, cloned)){
+ $(cloned).updatePolyfill();
+ }
+ });
+ return cloned;
+ })
+ ;
+ };
+
+ //add support for $('video').trigger('play') in case extendNative is set to false
+ if(!webshims.cfg.extendNative && !webshims.cfg.noTriggerOverride){
+ (function(oldTrigger){
+ $.event.trigger = function(event, data, elem, onlyHandlers){
+
+ if(!hasPolyfillMethod[event] || onlyHandlers || !elem || elem.nodeType !== 1){
+ return oldTrigger.apply(this, arguments);
+ }
+ var ret, isOrig, origName;
+ var origFn = elem[event];
+ var polyfilledFn = $.prop(elem, event);
+ var changeFn = polyfilledFn && origFn != polyfilledFn;
+ if(changeFn){
+ origName = '__ws'+event;
+ isOrig = (event in elem) && has.call(elem, event);
+ elem[event] = polyfilledFn;
+ elem[origName] = origFn;
+ }
+
+ ret = oldTrigger.apply(this, arguments);
+ if (changeFn) {
+ if(isOrig){
+ elem[event] = origFn;
+ } else {
+ delete elem[event];
+ }
+ delete elem[origName];
+ }
+
+ return ret;
+ };
+ })($.event.trigger);
+ }
+
+ ['removeAttr', 'prop', 'attr'].forEach(function(type){
+ olds[type] = $[type];
+ $[type] = function(elem, name, value, pass, _argless){
+ var isVal = (pass == 'val');
+ var oldMethod = !isVal ? olds[type] : singleVal;
+ if( !elem || !havePolyfill[name] || elem.nodeType !== 1 || (!isVal && pass && type == 'attr' && $.attrFn[name]) ){
+ return oldMethod(elem, name, value, pass, _argless);
+ }
+
+ var nodeName = (elem.nodeName || '').toLowerCase();
+ var desc = extendedProps[nodeName];
+ var curType = (type == 'attr' && (value === false || value === null)) ? 'removeAttr' : type;
+ var propMethod;
+ var oldValMethod;
+ var ret;
+
+
+ if(!desc){
+ desc = extendedProps['*'];
+ }
+ if(desc){
+ desc = desc[name];
+ }
+
+ if(desc){
+ propMethod = desc[curType];
+ }
+
+ if(propMethod){
+ if(name == 'value'){
+ oldValMethod = propMethod.isVal;
+ propMethod.isVal = isVal;
+ }
+ if(curType === 'removeAttr'){
+ return propMethod.value.call(elem);
+ } else if(value === undefined){
+ return (propMethod.get) ?
+ propMethod.get.call(elem) :
+ propMethod.value
+ ;
+ } else if(propMethod.set) {
+ if(type == 'attr' && value === true){
+ value = name;
+ }
+
+ ret = propMethod.set.call(elem, value);
+ }
+ if(name == 'value'){
+ propMethod.isVal = oldValMethod;
+ }
+ } else {
+ ret = oldMethod(elem, name, value, pass, _argless);
+ }
+ if((value !== undefined || curType === 'removeAttr') && modifyProps[nodeName] && modifyProps[nodeName][name]){
+
+ var boolValue;
+ if(curType == 'removeAttr'){
+ boolValue = false;
+ } else if(curType == 'prop'){
+ boolValue = !!(value);
+ } else {
+ boolValue = true;
+ }
+
+ modifyProps[nodeName][name].forEach(function(fn){
+ if(!fn.only || (fn.only = 'prop' && type == 'prop') || (fn.only == 'attr' && type != 'prop')){
+ fn.call(elem, value, boolValue, (isVal) ? 'val' : curType, type);
+ }
+ });
+ }
+ return ret;
+ };
+
+ extendQ[type] = function(nodeName, prop, desc){
+
+ if(!extendedProps[nodeName]){
+ extendedProps[nodeName] = {};
+ }
+ if(!extendedProps[nodeName][prop]){
+ extendedProps[nodeName][prop] = {};
+ }
+ var oldDesc = extendedProps[nodeName][prop][type];
+ var getSup = function(propType, descriptor, oDesc){
+ var origProp;
+ if(descriptor && descriptor[propType]){
+ return descriptor[propType];
+ }
+ if(oDesc && oDesc[propType]){
+ return oDesc[propType];
+ }
+ if(type == 'prop' && prop == 'value'){
+ return function(value){
+ var elem = this;
+ return (desc.isVal) ?
+ singleVal(elem, prop, value, false, (arguments.length === 0)) :
+ olds[type](elem, prop, value)
+ ;
+ };
+ }
+ if(type == 'prop' && propType == 'value' && desc.value.apply){
+ origProp = '__ws'+prop;
+ hasPolyfillMethod[prop] = true;
+ return function(value){
+ var sup = this[origProp] || olds[type](this, prop);
+ if(sup && sup.apply){
+ sup = sup.apply(this, arguments);
+ }
+ return sup;
+ };
+ }
+ return function(value){
+ return olds[type](this, prop, value);
+ };
+ };
+ extendedProps[nodeName][prop][type] = desc;
+ if(desc.value === undefined){
+ if(!desc.set){
+ desc.set = desc.writeable ?
+ getSup('set', desc, oldDesc) :
+ (webshims.cfg.useStrict && prop == 'prop') ?
+ function(){throw(prop +' is readonly on '+ nodeName);} :
+ function(){webshims.info(prop +' is readonly on '+ nodeName);}
+ ;
+ }
+ if(!desc.get){
+ desc.get = getSup('get', desc, oldDesc);
+ }
+
+ }
+
+ ['value', 'get', 'set'].forEach(function(descProp){
+ if(desc[descProp]){
+ desc['_sup'+descProp] = getSup(descProp, oldDesc);
+ }
+ });
+ };
+
+ });
+
+ var extendNativeValue = (function(){
+ var UNKNOWN = webshims.getPrototypeOf(document.createElement('foobar'));
+
+ //see also: https://github.com/lojjic/PIE/issues/40 | https://prototype.lighthouseapp.com/projects/8886/tickets/1107-ie8-fatal-crash-when-prototypejs-is-loaded-with-rounded-cornershtc
+ var isExtendNativeSave = webshims.support.advancedObjectProperties && webshims.support.objectAccessor;
+ return function(nodeName, prop, desc){
+ var elem , elemProto;
+ if( isExtendNativeSave && (elem = document.createElement(nodeName)) && (elemProto = webshims.getPrototypeOf(elem)) && UNKNOWN !== elemProto && ( !elem[prop] || !has.call(elem, prop) ) ){
+ var sup = elem[prop];
+ desc._supvalue = function(){
+ if(sup && sup.apply){
+ return sup.apply(this, arguments);
+ }
+ return sup;
+ };
+ elemProto[prop] = desc.value;
+ } else {
+ desc._supvalue = function(){
+ var data = elementData(this, 'propValue');
+ if(data && data[prop] && data[prop].apply){
+ return data[prop].apply(this, arguments);
+ }
+ return data && data[prop];
+ };
+ initProp.extendValue(nodeName, prop, desc.value);
+ }
+ desc.value._supvalue = desc._supvalue;
+ };
+ })();
+
+ var initProp = (function(){
+
+ var initProps = {};
+
+ webshims.addReady(function(context, contextElem){
+ var nodeNameCache = {};
+ var getElementsByName = function(name){
+ if(!nodeNameCache[name]){
+ nodeNameCache[name] = $(context.getElementsByTagName(name));
+ if(contextElem[0] && $.nodeName(contextElem[0], name)){
+ nodeNameCache[name] = nodeNameCache[name].add(contextElem);
+ }
+ }
+ };
+
+
+ $.each(initProps, function(name, fns){
+ getElementsByName(name);
+ if(!fns || !fns.forEach){
+ webshims.warn('Error: with '+ name +'-property. methods: '+ fns);
+ return;
+ }
+ fns.forEach(function(fn){
+ nodeNameCache[name].each(fn);
+ });
+ });
+ nodeNameCache = null;
+ });
+
+ var tempCache;
+ var emptyQ = $([]);
+ var createNodeNameInit = function(nodeName, fn){
+ if(!initProps[nodeName]){
+ initProps[nodeName] = [fn];
+ } else {
+ initProps[nodeName].push(fn);
+ }
+ if($.isDOMReady){
+ (tempCache || $( document.getElementsByTagName(nodeName) )).each(fn);
+ }
+ };
+
+ var elementExtends = {};
+ return {
+ createTmpCache: function(nodeName){
+ if($.isDOMReady){
+ tempCache = tempCache || $( document.getElementsByTagName(nodeName) );
+ }
+ return tempCache || emptyQ;
+ },
+ flushTmpCache: function(){
+ tempCache = null;
+ },
+ content: function(nodeName, prop){
+ createNodeNameInit(nodeName, function(){
+ var val = $.attr(this, prop);
+ if(val != null){
+ $.attr(this, prop, val);
+ }
+ });
+ },
+ createElement: function(nodeName, fn){
+ createNodeNameInit(nodeName, fn);
+ },
+ extendValue: function(nodeName, prop, value){
+ createNodeNameInit(nodeName, function(){
+ $(this).each(function(){
+ var data = elementData(this, 'propValue', {});
+ data[prop] = this[prop];
+ this[prop] = value;
+ });
+ });
+ }
+ };
+ })();
+
+ var createPropDefault = function(descs, removeType){
+ if(descs.defaultValue === undefined){
+ descs.defaultValue = '';
+ }
+ if(!descs.removeAttr){
+ descs.removeAttr = {
+ value: function(){
+ descs[removeType || 'prop'].set.call(this, descs.defaultValue);
+ descs.removeAttr._supvalue.call(this);
+ }
+ };
+ }
+ if(!descs.attr){
+ descs.attr = {};
+ }
+ };
+
+ $.extend(webshims, {
+ getID: (function(){
+ var ID = new Date().getTime();
+ return function(elem){
+ elem = $(elem);
+ var id = elem.prop('id');
+ if(!id){
+ ID++;
+ id = 'ID-'+ ID;
+ elem.eq(0).prop('id', id);
+ }
+ return id;
+ };
+ })(),
+ shadowClass: 'wsshadow-'+(Date.now()),
+ implement: function(elem, type){
+ var data = elementData(elem, 'implemented') || elementData(elem, 'implemented', {});
+ if(data[type]){
+ webshims.warn(type +' already implemented for element #'+elem.id);
+ return false;
+ }
+ data[type] = true;
+ return true;
+ },
+ extendUNDEFProp: function(obj, props){
+ $.each(props, function(name, prop){
+ if( !(name in obj) ){
+ obj[name] = prop;
+ }
+ });
+ },
+ getOptions: (function(){
+ var normalName = /\-([a-z])/g;
+ var regs = {};
+ var nameRegs = {};
+ var regFn = function(f, upper){
+ return upper.toLowerCase();
+ };
+ var nameFn = function(f, dashed){
+ return dashed.toUpperCase();
+ };
+ return function(elem, name, bases, stringAllowed){
+ if(nameRegs[name]){
+ name = nameRegs[name];
+ } else {
+ nameRegs[name] = name.replace(normalName, nameFn);
+ name = nameRegs[name];
+ }
+ var data = elementData(elem, 'cfg'+name);
+ var dataName;
+ var cfg = {};
+
+ if(data){
+ return data;
+ }
+ data = $(elem).data();
+ if(data && typeof data[name] == 'string'){
+ if(stringAllowed){
+ return elementData(elem, 'cfg'+name, data[name]);
+ }
+ webshims.error('data-'+ name +' attribute has to be a valid JSON, was: '+ data[name]);
+ }
+ if(!bases){
+ bases = [true, {}];
+ } else if(!Array.isArray(bases)){
+ bases = [true, {}, bases];
+ } else {
+ bases.unshift(true, {});
+ }
+
+ if(data && typeof data[name] == 'object'){
+ bases.push(data[name]);
+ }
+
+ if(!regs[name]){
+ regs[name] = new RegExp('^'+ name +'([A-Z])');
+ }
+
+ for(dataName in data){
+ if(regs[name].test(dataName)){
+ cfg[dataName.replace(regs[name], regFn)] = data[dataName];
+ }
+ }
+ bases.push(cfg);
+ return elementData(elem, 'cfg'+name, $.extend.apply($, bases));
+ };
+ })(),
+ //http://www.w3.org/TR/html5/common-dom-interfaces.html#reflect
+ createPropDefault: createPropDefault,
+ data: elementData,
+ moveToFirstEvent: function(elem, eventType, bindType){
+ var events = ($._data(elem, 'events') || {})[eventType];
+ var fn;
+
+ if(events && events.length > 1){
+ fn = events.pop();
+ if(!bindType){
+ bindType = 'bind';
+ }
+ if(bindType == 'bind' && events.delegateCount){
+ events.splice( events.delegateCount, 0, fn);
+ } else {
+ events.unshift( fn );
+ }
+
+
+ }
+ elem = null;
+ },
+ addShadowDom: (function(){
+ var resizeTimer;
+ var lastHeight;
+ var lastWidth;
+ var $window = $(window);
+ var docObserve = {
+ init: false,
+ runs: 0,
+ test: function(){
+ var height = docObserve.getHeight();
+ var width = docObserve.getWidth();
+
+ if(height != docObserve.height || width != docObserve.width){
+ docObserve.height = height;
+ docObserve.width = width;
+ docObserve.handler({type: 'docresize'});
+ docObserve.runs++;
+ if(docObserve.runs < 9){
+ setTimeout(docObserve.test, 90);
+ }
+ } else {
+ docObserve.runs = 0;
+ }
+ },
+ handler: (function(){
+ var trigger = function(){
+ $(document).triggerHandler('updateshadowdom');
+ };
+ return function(e){
+ clearTimeout(resizeTimer);
+ resizeTimer = setTimeout(function(){
+ if(e.type == 'resize'){
+ var width = $window.width();
+ var height = $window.width();
+
+ if(height == lastHeight && width == lastWidth){
+ return;
+ }
+ lastHeight = height;
+ lastWidth = width;
+
+ docObserve.height = docObserve.getHeight();
+ docObserve.width = docObserve.getWidth();
+ }
+
+ if(window.requestAnimationFrame){
+ requestAnimationFrame(trigger);
+ } else {
+ setTimeout(trigger, 0);
+ }
+
+ }, (e.type == 'resize' && !window.requestAnimationFrame) ? 50 : 9);
+ };
+ })(),
+ _create: function(){
+ $.each({ Height: "getHeight", Width: "getWidth" }, function(name, type){
+ var body = document.body;
+ var doc = document.documentElement;
+ docObserve[type] = function (){
+ return Math.max(
+ body[ "scroll" + name ], doc[ "scroll" + name ],
+ body[ "offset" + name ], doc[ "offset" + name ],
+ doc[ "client" + name ]
+ );
+ };
+ });
+ },
+ start: function(){
+ if(!this.init && document.body){
+ this.init = true;
+ this._create();
+ this.height = docObserve.getHeight();
+ this.width = docObserve.getWidth();
+ setInterval(this.test, 999);
+ $(this.test);
+ if($.support.boxSizing == null){
+ $(function(){
+ if($.support.boxSizing){
+ docObserve.handler({type: 'boxsizing'});
+ }
+ });
+ }
+ webshims.ready('WINDOWLOAD', this.test);
+ $(document).on('updatelayout.webshim pageinit popupafteropen panelbeforeopen tabsactivate collapsibleexpand shown.bs.modal shown.bs.collapse slid.bs.carousel playerdimensionchange', this.handler);
+ $(window).on('resize', this.handler);
+ }
+ }
+ };
+
+
+ webshims.docObserve = function(){
+ webshims.ready('DOM', function(){
+ docObserve.start();
+
+ });
+ };
+ return function(nativeElem, shadowElem, opts){
+ if(nativeElem && shadowElem){
+ opts = opts || {};
+ if(nativeElem.jquery){
+ nativeElem = nativeElem[0];
+ }
+ if(shadowElem.jquery){
+ shadowElem = shadowElem[0];
+ }
+ var nativeData = $.data(nativeElem, dataID) || $.data(nativeElem, dataID, {});
+ var shadowData = $.data(shadowElem, dataID) || $.data(shadowElem, dataID, {});
+ var shadowFocusElementData = {};
+ if(!opts.shadowFocusElement){
+ opts.shadowFocusElement = shadowElem;
+ } else if(opts.shadowFocusElement){
+ if(opts.shadowFocusElement.jquery){
+ opts.shadowFocusElement = opts.shadowFocusElement[0];
+ }
+ shadowFocusElementData = $.data(opts.shadowFocusElement, dataID) || $.data(opts.shadowFocusElement, dataID, shadowFocusElementData);
+ }
+
+ $(nativeElem).on('remove', function(e){
+ if (!e.originalEvent) {
+ setTimeout(function(){
+ $(shadowElem).remove();
+ }, 4);
+ }
+ });
+
+ nativeData.hasShadow = shadowElem;
+ shadowFocusElementData.nativeElement = shadowData.nativeElement = nativeElem;
+ shadowFocusElementData.shadowData = shadowData.shadowData = nativeData.shadowData = {
+ nativeElement: nativeElem,
+ shadowElement: shadowElem,
+ shadowFocusElement: opts.shadowFocusElement
+ };
+ if(opts.shadowChilds){
+ opts.shadowChilds.each(function(){
+ elementData(this, 'shadowData', shadowData.shadowData);
+ });
+ }
+
+ if(opts.data){
+ shadowFocusElementData.shadowData.data = shadowData.shadowData.data = nativeData.shadowData.data = opts.data;
+ }
+ opts = null;
+ }
+ webshims.docObserve();
+ };
+ })(),
+ propTypes: {
+ standard: function(descs, name){
+ createPropDefault(descs);
+ if(descs.prop){return;}
+ descs.prop = {
+ set: function(val){
+ descs.attr.set.call(this, ''+val);
+ },
+ get: function(){
+ return descs.attr.get.call(this) || descs.defaultValue;
+ }
+ };
+
+ },
+ "boolean": function(descs, name){
+
+ createPropDefault(descs);
+ if(descs.prop){return;}
+ descs.prop = {
+ set: function(val){
+ if(val){
+ descs.attr.set.call(this, "");
+ } else {
+ descs.removeAttr.value.call(this);
+ }
+ },
+ get: function(){
+ return descs.attr.get.call(this) != null;
+ }
+ };
+ },
+ "src": (function(){
+ var anchor = document.createElement('a');
+ anchor.style.display = "none";
+ return function(descs, name){
+
+ createPropDefault(descs);
+ if(descs.prop){return;}
+ descs.prop = {
+ set: function(val){
+ descs.attr.set.call(this, val);
+ },
+ get: function(){
+ var href = this.getAttribute(name);
+ var ret;
+ if(href == null){return '';}
+
+ anchor.setAttribute('href', href+'' );
+
+ if(!supportHrefNormalized){
+ try {
+ $(anchor).insertAfter(this);
+ ret = anchor.getAttribute('href', 4);
+ } catch(er){
+ ret = anchor.getAttribute('href', 4);
+ }
+ $(anchor).detach();
+ }
+ return ret || anchor.href;
+ }
+ };
+ };
+ })(),
+ enumarated: function(descs, name){
+
+ createPropDefault(descs);
+ if(descs.prop){return;}
+ descs.prop = {
+ set: function(val){
+ descs.attr.set.call(this, val);
+ },
+ get: function(){
+ var val = (descs.attr.get.call(this) || '').toLowerCase();
+ if(!val || descs.limitedTo.indexOf(val) == -1){
+ val = descs.defaultValue;
+ }
+ return val;
+ }
+ };
+ }
+
+// ,unsignedLong: $.noop
+// ,"doubble": $.noop
+// ,"long": $.noop
+// ,tokenlist: $.noop
+// ,settableTokenlist: $.noop
+ },
+ reflectProperties: function(nodeNames, props){
+ if(typeof props == 'string'){
+ props = props.split(listReg);
+ }
+ props.forEach(function(prop){
+ webshims.defineNodeNamesProperty(nodeNames, prop, {
+ prop: {
+ set: function(val){
+ $.attr(this, prop, val);
+ },
+ get: function(){
+ return $.attr(this, prop) || '';
+ }
+ }
+ });
+ });
+ },
+ defineNodeNameProperty: function(nodeName, prop, descs){
+ havePolyfill[prop] = true;
+
+ if(descs.reflect){
+ if(descs.propType && !webshims.propTypes[descs.propType]){
+ webshims.error('could not finde propType '+ descs.propType);
+ } else {
+ webshims.propTypes[descs.propType || 'standard'](descs, prop);
+ }
+
+ }
+
+ ['prop', 'attr', 'removeAttr'].forEach(function(type){
+ var desc = descs[type];
+ if(desc){
+ if(type === 'prop'){
+ desc = $.extend({writeable: true}, desc);
+ } else {
+ desc = $.extend({}, desc, {writeable: true});
+ }
+
+ extendQ[type](nodeName, prop, desc);
+ if(nodeName != '*' && webshims.cfg.extendNative && type == 'prop' && desc.value && $.isFunction(desc.value)){
+ extendNativeValue(nodeName, prop, desc);
+ }
+ descs[type] = desc;
+ }
+ });
+ if(descs.initAttr){
+ initProp.content(nodeName, prop);
+ }
+ return descs;
+ },
+
+ defineNodeNameProperties: function(name, descs, propType, _noTmpCache){
+ var olddesc;
+ for(var prop in descs){
+ if(!_noTmpCache && descs[prop].initAttr){
+ initProp.createTmpCache(name);
+ }
+ if(propType){
+ if(descs[prop][propType]){
+ //webshims.log('override: '+ name +'['+prop +'] for '+ propType);
+ } else {
+ descs[prop][propType] = {};
+ ['value', 'set', 'get'].forEach(function(copyProp){
+ if(copyProp in descs[prop]){
+ descs[prop][propType][copyProp] = descs[prop][copyProp];
+ delete descs[prop][copyProp];
+ }
+ });
+ }
+ }
+ descs[prop] = webshims.defineNodeNameProperty(name, prop, descs[prop]);
+ }
+ if(!_noTmpCache){
+ initProp.flushTmpCache();
+ }
+ return descs;
+ },
+
+ createElement: function(nodeName, create, descs){
+ var ret;
+ if($.isFunction(create)){
+ create = {
+ after: create
+ };
+ }
+ initProp.createTmpCache(nodeName);
+ if(create.before){
+ initProp.createElement(nodeName, create.before);
+ }
+ if(descs){
+ ret = webshims.defineNodeNameProperties(nodeName, descs, false, true);
+ }
+ if(create.after){
+ initProp.createElement(nodeName, create.after);
+ }
+ initProp.flushTmpCache();
+ return ret;
+ },
+ onNodeNamesPropertyModify: function(nodeNames, props, desc, only){
+ if(typeof nodeNames == 'string'){
+ nodeNames = nodeNames.split(listReg);
+ }
+ if($.isFunction(desc)){
+ desc = {set: desc};
+ }
+
+ nodeNames.forEach(function(name){
+ if(!modifyProps[name]){
+ modifyProps[name] = {};
+ }
+ if(typeof props == 'string'){
+ props = props.split(listReg);
+ }
+ if(desc.initAttr){
+ initProp.createTmpCache(name);
+ }
+ props.forEach(function(prop){
+ if(!modifyProps[name][prop]){
+ modifyProps[name][prop] = [];
+ havePolyfill[prop] = true;
+ }
+ if(desc.set){
+ if(only){
+ desc.set.only = only;
+ }
+ modifyProps[name][prop].push(desc.set);
+ }
+
+ if(desc.initAttr){
+ initProp.content(name, prop);
+ }
+ });
+ initProp.flushTmpCache();
+
+ });
+ },
+ defineNodeNamesBooleanProperty: function(elementNames, prop, descs){
+ if(!descs){
+ descs = {};
+ }
+ if($.isFunction(descs)){
+ descs.set = descs;
+ }
+ webshims.defineNodeNamesProperty(elementNames, prop, {
+ attr: {
+ set: function(val){
+ if(descs.useContentAttribute){
+ webshims.contentAttr(this, prop, val);
+ } else {
+ this.setAttribute(prop, val);
+ }
+ if(descs.set){
+ descs.set.call(this, true);
+ }
+ },
+ get: function(){
+ var ret = (descs.useContentAttribute) ? webshims.contentAttr(this, prop) : this.getAttribute(prop);
+ return (ret == null) ? undefined : prop;
+ }
+ },
+ removeAttr: {
+ value: function(){
+ this.removeAttribute(prop);
+ if(descs.set){
+ descs.set.call(this, false);
+ }
+ }
+ },
+ reflect: true,
+ propType: 'boolean',
+ initAttr: descs.initAttr || false
+ });
+ },
+ contentAttr: function(elem, name, val){
+ if(!elem.nodeName){return;}
+ var attr;
+ if(val === undefined){
+ attr = (elem.attributes[name] || {});
+ val = attr.specified ? attr.value : null;
+ return (val == null) ? undefined : val;
+ }
+
+ if(typeof val == 'boolean'){
+ if(!val){
+ elem.removeAttribute(name);
+ } else {
+ elem.setAttribute(name, name);
+ }
+ } else {
+ elem.setAttribute(name, val);
+ }
+ },
+
+ activeLang: (function(){
+ var curLang = [];
+ var langDatas = [];
+ var loading = {};
+ var load = function(src, obj, loadingLang){
+ obj._isLoading = true;
+ if(loading[src]){
+ loading[src].push(obj);
+ } else {
+ loading[src] = [obj];
+ webshims.loader.loadScript(src, function(){
+ if(loadingLang == curLang.join()){
+ $.each(loading[src], function(i, obj){
+ select(obj);
+ });
+ }
+ delete loading[src];
+ });
+ }
+ };
+
+ var select = function(obj){
+ var oldLang = obj.__active;
+ var selectLang = function(i, lang){
+ obj._isLoading = false;
+ if(obj[lang] || obj.availableLangs.indexOf(lang) != -1){
+ if(obj[lang]){
+ obj.__active = obj[lang];
+ obj.__activeName = lang;
+ } else {
+ load(obj.langSrc+lang, obj, curLang.join());
+ }
+ return false;
+ }
+ };
+ $.each(curLang, selectLang);
+ if(!obj.__active){
+ obj.__active = obj[''];
+ obj.__activeName = '';
+ }
+ if(oldLang != obj.__active){
+ $(obj).trigger('change');
+ }
+ };
+ return function(lang){
+ var shortLang;
+ if(typeof lang == 'string'){
+ if(curLang[0] != lang){
+ curLang = [lang];
+ shortLang = curLang[0].split('-')[0];
+ if(shortLang && shortLang != lang){
+ curLang.push(shortLang);
+ }
+ langDatas.forEach(select);
+ }
+ } else if(typeof lang == 'object'){
+ if(!lang.__active){
+ langDatas.push(lang);
+ select(lang);
+ }
+ return lang.__active;
+ }
+ return curLang[0];
+ };
+ })()
+ });
+
+ $.each({
+ defineNodeNamesProperty: 'defineNodeNameProperty',
+ defineNodeNamesProperties: 'defineNodeNameProperties',
+ createElements: 'createElement'
+ }, function(name, baseMethod){
+ webshims[name] = function(names, a, b, c){
+ if(typeof names == 'string'){
+ names = names.split(listReg);
+ }
+ var retDesc = {};
+ names.forEach(function(nodeName){
+ retDesc[nodeName] = webshims[baseMethod](nodeName, a, b, c);
+ });
+ return retDesc;
+ };
+ });
+
+ webshims.isReady('webshimLocalization', true);
+
+//html5a11y + hidden attribute
+(function(){
+ if(('content' in document.createElement('template'))){return;}
+
+ $(function(){
+ var main = $('main').attr({role: 'main'});
+ if(main.length > 1){
+ webshims.error('only one main element allowed in document');
+ } else if(main.is('article *, section *')) {
+ webshims.error('main not allowed inside of article/section elements');
+ }
+ });
+
+ if(('hidden' in document.createElement('a'))){
+ return;
+ }
+
+ webshims.defineNodeNamesBooleanProperty(['*'], 'hidden');
+
+ var elemMappings = {
+ article: "article",
+ aside: "complementary",
+ section: "region",
+ nav: "navigation",
+ address: "contentinfo"
+ };
+ var addRole = function(elem, role){
+ var hasRole = elem.getAttribute('role');
+ if (!hasRole) {
+ elem.setAttribute('role', role);
+ }
+ };
+
+
+ $.webshims.addReady(function(context, contextElem){
+ $.each(elemMappings, function(name, role){
+ var elems = $(name, context).add(contextElem.filter(name));
+ for (var i = 0, len = elems.length; i < len; i++) {
+ addRole(elems[i], role);
+ }
+ });
+ if (context === document) {
+ var header = document.getElementsByTagName('header')[0];
+ var footers = document.getElementsByTagName('footer');
+ var footerLen = footers.length;
+
+ if (header && !$(header).closest('section, article')[0]) {
+ addRole(header, 'banner');
+ }
+ if (!footerLen) {
+ return;
+ }
+ var footer = footers[footerLen - 1];
+ if (!$(footer).closest('section, article')[0]) {
+ addRole(footer, 'contentinfo');
+ }
+ }
+ });
+
+})();
+});
+;webshims.register('form-core', function($, webshims, window, document, undefined, options){
+ "use strict";
+
+ webshims.capturingEventPrevented = function(e){
+ if(!e._isPolyfilled){
+ var isDefaultPrevented = e.isDefaultPrevented;
+ var preventDefault = e.preventDefault;
+ e.preventDefault = function(){
+ clearTimeout($.data(e.target, e.type + 'DefaultPrevented'));
+ $.data(e.target, e.type + 'DefaultPrevented', setTimeout(function(){
+ $.removeData(e.target, e.type + 'DefaultPrevented');
+ }, 30));
+ return preventDefault.apply(this, arguments);
+ };
+ e.isDefaultPrevented = function(){
+ return !!(isDefaultPrevented.apply(this, arguments) || $.data(e.target, e.type + 'DefaultPrevented') || false);
+ };
+ e._isPolyfilled = true;
+ }
+ };
+
+
+ var modules = webshims.modules;
+ var support = webshims.support;
+ var isValid = function(elem){
+ return ($.prop(elem, 'validity') || {valid: 1}).valid;
+ };
+ var lazyLoad = function(){
+ var toLoad = ['form-validation'];
+ if(options.lazyCustomMessages){
+ options.customMessages = true;
+ toLoad.push('form-message');
+ }
+
+ if(webshims._getAutoEnhance(options.customDatalist)){
+ options.fD = true;
+ toLoad.push('form-datalist');
+ }
+
+ if(options.addValidators){
+ toLoad.push('form-validators');
+ }
+ webshims.reTest(toLoad);
+ $(document).off('.lazyloadvalidation');
+ };
+ /*
+ * Selectors for all browsers
+ */
+
+ var extendSels = function(){
+ var matches, matchesOverride;
+ var exp = $.expr[":"];
+ var rElementsGroup = /^(?:form|fieldset)$/i;
+ var hasInvalid = function(elem){
+ var ret = false;
+ $(elem).jProp('elements').each(function(){
+ if(!rElementsGroup.test(this.nodeName || '')){
+ ret = exp.invalid(this);
+ if(ret){
+ return false;
+ }
+ }
+
+ });
+ return ret;
+ };
+ $.extend(exp, {
+ "valid-element": function(elem){
+ return rElementsGroup.test(elem.nodeName || '') ? !hasInvalid(elem) : !!($.prop(elem, 'willValidate') && isValid(elem));
+ },
+ "invalid-element": function(elem){
+ return rElementsGroup.test(elem.nodeName || '') ? hasInvalid(elem) : !!($.prop(elem, 'willValidate') && !isValid(elem));
+ },
+ "required-element": function(elem){
+ return !!($.prop(elem, 'willValidate') && $.prop(elem, 'required'));
+ },
+ "user-error": function(elem){
+ return ($.prop(elem, 'willValidate') && $(elem).getShadowElement().hasClass((options.iVal.errorClass || 'user-error')));
+ },
+ "optional-element": function(elem){
+ return !!($.prop(elem, 'willValidate') && $.prop(elem, 'required') === false);
+ }
+ });
+
+ ['valid', 'invalid', 'required', 'optional'].forEach(function(name){
+ exp[name] = $.expr[":"][name+"-element"];
+ });
+
+ // sizzle/jQuery has a bug with :disabled/:enabled selectors
+ if(support.fieldsetdisabled && !$('').find(':disabled').filter(':disabled').is(':disabled')){
+ matches = $.find.matches;
+ matchesOverride = {':disabled': 1, ':enabled': 1};
+ $.find.matches = function(expr, elements){
+ if(matchesOverride[expr]){
+ return matches.call(this, '*'+expr, elements);
+ }
+ return matches.apply(this, arguments);
+ };
+ $.extend(exp, {
+ "enabled": function( elem ) {
+ return elem.disabled === false && !$(elem).is('fieldset[disabled] *');
+ },
+
+ "disabled": function( elem ) {
+ return elem.disabled === true || ('disabled' in elem && $(elem).is('fieldset[disabled] *'));
+ }
+ });
+ }
+
+
+ //bug was partially fixed in 1.10.0 for IE9, but not IE8 (move to es5 as soon as 1.10.2 is used)
+ if(typeof document.activeElement == 'unknown'){
+ var pseudoFocus = exp.focus;
+ exp.focus = function(){
+ try {
+ return pseudoFocus.apply(this, arguments);
+ } catch(e){
+ webshims.error(e);
+ }
+ return false;
+ };
+ }
+ };
+ var formExtras = {
+ noAutoCallback: true,
+ options: options
+ };
+ var addModule = webshims.loader.addModule;
+ var lazyLoadProxy = function(obj, fn, args){
+ lazyLoad();
+ webshims.ready('form-validation', function(){
+ obj[fn].apply(obj, args);
+ });
+ };
+
+ var transClass = ('transitionDelay' in document.documentElement.style) ? '' : ' no-transition';
+ var poCFG = webshims.cfg.wspopover;
+
+ addModule('form-validation', $.extend({d: ['form-message']}, formExtras));
+
+ addModule('form-validators', $.extend({}, formExtras));
+
+
+ if(support.formvalidation && !webshims.bugs.bustedValidity){
+ //create delegatable events
+ webshims.capturingEvents(['invalid'], true);
+ }
+
+ if($.expr.filters){
+ extendSels();
+ } else {
+ webshims.ready('sizzle', extendSels);
+ }
+
+ webshims.triggerInlineForm = function(elem, event){
+ $(elem).trigger(event);
+ };
+
+
+ if(!poCFG.position && poCFG.position !== false){
+ poCFG.position = {
+ at: 'left bottom',
+ my: 'left top',
+ collision: 'fit flip'
+ };
+ }
+ webshims.wsPopover = {
+ id: 0,
+ _create: function(){
+ this.options = $.extend(true, {}, poCFG, this.options);
+ this.id = webshims.wsPopover.id++;
+ this.eventns = '.wsoverlay' + this.id;
+ this.timers = {};
+ this.element = $('');
+ this.contentElement = $('.ws-po-box', this.element);
+ this.lastElement = $([]);
+ this.bindElement();
+
+ this.element.data('wspopover', this);
+
+ },
+ options: {},
+ content: function(html){
+ this.contentElement.html(html);
+ },
+ bindElement: function(){
+ var that = this;
+ var stopBlur = function(){
+ that.stopBlur = false;
+ };
+ this.preventBlur = function(e){
+ that.stopBlur = true;
+ clearTimeout(that.timers.stopBlur);
+ that.timers.stopBlur = setTimeout(stopBlur, 9);
+ };
+ this.element.on({
+ 'mousedown': this.preventBlur
+ });
+ },
+ show: function(){
+ lazyLoadProxy(this, 'show', arguments);
+ }
+ };
+
+ /* some extra validation UI */
+ webshims.validityAlert = {
+ showFor: function(){
+ lazyLoadProxy(this, 'showFor', arguments);
+ }
+ };
+
+
+ webshims.getContentValidationMessage = function(elem, validity, key){
+ var customRule;
+ if(webshims.errorbox && webshims.errorbox.initIvalContentMessage){
+ webshims.errorbox.initIvalContentMessage(elem);
+ }
+ var message = (webshims.getOptions && webshims.errorbox ? webshims.getOptions(elem, 'errormessage', false, true) : $(elem).data('errormessage')) || elem.getAttribute('x-moz-errormessage') || '';
+ if(key && message[key]){
+ message = message[key];
+ } else if(message) {
+ validity = validity || $.prop(elem, 'validity') || {valid: 1};
+ if(validity.valid){
+ message = '';
+ }
+ }
+ if(typeof message == 'object'){
+ validity = validity || $.prop(elem, 'validity') || {valid: 1};
+ if(validity.customError && (customRule = $.data(elem, 'customMismatchedRule')) && message[customRule] && typeof message[customRule] == 'string'){
+ message = message[customRule];
+ } else if(!validity.valid){
+ $.each(validity, function(name, prop){
+ if(prop && name != 'valid' && message[name]){
+ message = message[name];
+ return false;
+ }
+ });
+ if(typeof message == 'object'){
+ if(validity.typeMismatch && message.badInput){
+ message = message.badInput;
+ }
+ if(validity.badInput && message.typeMismatch){
+ message = message.typeMismatch;
+ }
+ }
+ }
+ }
+
+ if(typeof message == 'object'){
+ message = message.defaultMessage;
+ }
+ if(webshims.replaceValidationplaceholder){
+ message = webshims.replaceValidationplaceholder(elem, message);
+ }
+ return message || '';
+ };
+
+ $.fn.getErrorMessage = function(key){
+ var message = '';
+ var elem = this[0];
+ if(elem){
+ message = webshims.getContentValidationMessage(elem, false, key) || $.prop(elem, 'customValidationMessage') || $.prop(elem, 'validationMessage');
+ }
+ return message;
+ };
+
+ $.event.special.valuevalidation = {
+ setup: function(){
+ webshims.error('valuevalidation was renamed to validatevalue!');
+ }
+ };
+
+
+ $.event.special.validatevalue = {
+ setup: function(){
+ var data = $(this).data() || $.data(this, {});
+ if(!('validatevalue' in data)){
+ data.validatevalue = true;
+ }
+ }
+ };
+
+
+
+ $(document).on('focusin.lazyloadvalidation', function(e){
+ if('form' in e.target){
+ lazyLoad();
+ }
+ });
+
+ webshims.ready('WINDOWLOAD', lazyLoad);
+
+ if(modules['form-number-date-ui'].loaded && !options.customMessages && (modules['form-number-date-api'].test() || (support.inputtypes.range && support.inputtypes.color))){
+ webshims.isReady('form-number-date-ui', true);
+ }
+
+ webshims.ready('DOM', function(){
+ if(document.querySelector('.ws-custom-file')){
+ webshims.reTest(['form-validation']);
+ }
+ });
+
+ $(function(){
+ var fileReaderReady = ('FileReader' in window && 'FormData' in window);
+ if(!fileReaderReady){
+ webshims.addReady(function(context){
+ if(!fileReaderReady && !modules.filereader.loaded && !modules.moxie.loaded){
+ if(context.querySelector('input.ws-filereader')){
+ webshims.reTest(['filereader', 'moxie']);
+ fileReaderReady = true;
+ }
+ }
+ });
+ }
+ });
+});
+;webshims.register('form-message', function($, webshims, window, document, undefined, options){
+ "use strict";
+ if(options.lazyCustomMessages){
+ options.customMessages = true;
+ }
+ var validityMessages = webshims.validityMessages;
+
+ var implementProperties = options.customMessages ? ['customValidationMessage'] : [];
+
+ validityMessages.en = $.extend(true, {
+ typeMismatch: {
+ defaultMessage: 'Please enter a valid value.',
+ email: 'Please enter an email address.',
+ url: 'Please enter a URL.'
+ },
+ badInput: {
+ defaultMessage: 'Please enter a valid value.',
+ number: 'Please enter a number.',
+ date: 'Please enter a date.',
+ time: 'Please enter a time.',
+ range: 'Invalid input.',
+ month: 'Please enter a valid value.',
+ "datetime-local": 'Please enter a datetime.'
+ },
+ rangeUnderflow: {
+ defaultMessage: 'Value must be greater than or equal to {%min}.'
+ },
+ rangeOverflow: {
+ defaultMessage: 'Value must be less than or equal to {%max}.'
+ },
+ stepMismatch: 'Invalid input.',
+ tooLong: 'Please enter at most {%maxlength} character(s). You entered {%valueLen}.',
+ tooShort: 'Please enter at least {%minlength} character(s). You entered {%valueLen}.',
+ patternMismatch: 'Invalid input. {%title}',
+ valueMissing: {
+ defaultMessage: 'Please fill out this field.',
+ checkbox: 'Please check this box if you want to proceed.'
+ }
+ }, (validityMessages.en || validityMessages['en-US'] || {}));
+
+ if(typeof validityMessages['en'].valueMissing == 'object'){
+ ['select', 'radio'].forEach(function(type){
+ validityMessages.en.valueMissing[type] = validityMessages.en.valueMissing[type] || 'Please select an option.';
+ });
+ }
+ if(typeof validityMessages.en.rangeUnderflow == 'object'){
+ ['date', 'time', 'datetime-local', 'month'].forEach(function(type){
+ validityMessages.en.rangeUnderflow[type] = validityMessages.en.rangeUnderflow[type] || 'Value must be at or after {%min}.';
+ });
+ }
+ if(typeof validityMessages.en.rangeOverflow == 'object'){
+ ['date', 'time', 'datetime-local', 'month'].forEach(function(type){
+ validityMessages.en.rangeOverflow[type] = validityMessages.en.rangeOverflow[type] || 'Value must be at or before {%max}.';
+ });
+ }
+ if(!validityMessages['en-US']){
+ validityMessages['en-US'] = $.extend(true, {}, validityMessages.en);
+ }
+ if(!validityMessages['en-GB']){
+ validityMessages['en-GB'] = $.extend(true, {}, validityMessages.en);
+ }
+ if(!validityMessages['en-AU']){
+ validityMessages['en-AU'] = $.extend(true, {}, validityMessages.en);
+ }
+ validityMessages[''] = validityMessages[''] || validityMessages['en-US'];
+
+ validityMessages.de = $.extend(true, {
+ typeMismatch: {
+ defaultMessage: '{%value} ist in diesem Feld nicht zulässig.',
+ email: '{%value} ist keine gültige E-Mail-Adresse.',
+ url: '{%value} ist kein(e) gültige(r) Webadresse/Pfad.'
+ },
+ badInput: {
+ defaultMessage: 'Geben Sie einen zulässigen Wert ein.',
+ number: 'Geben Sie eine Nummer ein.',
+ date: 'Geben Sie ein Datum ein.',
+ time: 'Geben Sie eine Uhrzeit ein.',
+ month: 'Geben Sie einen Monat mit Jahr ein.',
+ range: 'Geben Sie eine Nummer.',
+ "datetime-local": 'Geben Sie ein Datum mit Uhrzeit ein.'
+ },
+ rangeUnderflow: {
+ defaultMessage: '{%value} ist zu niedrig. {%min} ist der unterste Wert, den Sie benutzen können.'
+ },
+ rangeOverflow: {
+ defaultMessage: '{%value} ist zu hoch. {%max} ist der oberste Wert, den Sie benutzen können.'
+ },
+ stepMismatch: 'Der Wert {%value} ist in diesem Feld nicht zulässig. Hier sind nur bestimmte Werte zulässig. {%title}',
+ tooLong: 'Der eingegebene Text ist zu lang! Sie haben {%valueLen} Zeichen eingegeben, dabei sind {%maxlength} das Maximum.',
+ tooShort: 'Der eingegebene Text ist zu kurz! Sie haben {%valueLen} Zeichen eingegeben, dabei sind {%minlength} das Minimum.',
+ patternMismatch: '{%value} hat für dieses Eingabefeld ein falsches Format. {%title}',
+ valueMissing: {
+ defaultMessage: 'Bitte geben Sie einen Wert ein.',
+ checkbox: 'Bitte aktivieren Sie das Kästchen.'
+ }
+ }, (validityMessages.de || {}));
+
+ if(typeof validityMessages.de.valueMissing == 'object'){
+ ['select', 'radio'].forEach(function(type){
+ validityMessages.de.valueMissing[type] = validityMessages.de.valueMissing[type] || 'Bitte wählen Sie eine Option aus.';
+ });
+ }
+ if(typeof validityMessages.de.rangeUnderflow == 'object'){
+ ['date', 'time', 'datetime-local', 'month'].forEach(function(type){
+ validityMessages.de.rangeUnderflow[type] = validityMessages.de.rangeUnderflow[type] || '{%value} ist zu früh. {%min} ist die früheste Zeit, die Sie benutzen können.';
+ });
+ }
+ if(typeof validityMessages.de.rangeOverflow == 'object'){
+ ['date', 'time', 'datetime-local', 'month'].forEach(function(type){
+ validityMessages.de.rangeOverflow[type] = validityMessages.de.rangeOverflow[type] || '{%value} ist zu spät. {%max} ist die späteste Zeit, die Sie benutzen können.';
+ });
+ }
+
+ var currentValidationMessage = validityMessages[''];
+ var getMessageFromObj = function(message, elem){
+ if(message && typeof message !== 'string'){
+ message = message[ $.prop(elem, 'type') ] || message[ (elem.nodeName || '').toLowerCase() ] || message[ 'defaultMessage' ];
+ }
+ return message || '';
+ };
+ var lReg = //g;
+ var valueVals = {
+ value: 1,
+ min: 1,
+ max: 1
+ };
+ var toLocale = (function(){
+ var monthFormatter;
+ var transforms = {
+ number: function(val){
+ var num = val * 1;
+ if(num.toLocaleString && !isNaN(num)){
+ val = num.toLocaleString() || val;
+ }
+ return val;
+ }
+ };
+ var _toLocale = function(val, elem, attr){
+ var type, widget;
+ if(valueVals[attr]){
+ type = $.prop(elem, 'type');
+ widget = $(elem).getShadowElement().data('wsWidget'+ type );
+ if(widget && widget.formatValue){
+ val = widget.formatValue(val, false);
+ } else if(transforms[type]){
+ val = transforms[type](val);
+ }
+ }
+ return val;
+ };
+
+ [{n: 'date', f: 'toLocaleDateString'}, {n: 'time', f: 'toLocaleTimeString'}, {n: 'datetime-local', f: 'toLocaleString'}].forEach(function(desc){
+ transforms[desc.n] = function(val){
+ var date = new Date(val);
+ if(date && date[desc.f]){
+ val = date[desc.f]() || val;
+ }
+ return val;
+ };
+ });
+
+ if(window.Intl && Intl.DateTimeFormat){
+ monthFormatter = new Intl.DateTimeFormat(navigator.browserLanguage || navigator.language, {year: "numeric", month: "2-digit"}).format(new Date());
+ if(monthFormatter && monthFormatter.format){
+ transforms.month = function(val){
+ var date = new Date(val);
+ if(date){
+ val = monthFormatter.format(date) || val;
+ }
+ return val;
+ };
+ }
+ }
+
+ webshims.format = {};
+
+ ['date', 'number', 'month', 'time', 'datetime-local'].forEach(function(name){
+ webshims.format[name] = function(val, opts){
+ if(opts && opts.nodeType){
+ return _toLocale(val, opts, name);
+ }
+ if(name == 'number' && opts && opts.toFixed ){
+ val = (val * 1);
+ if(!opts.fixOnlyFloat || val % 1){
+ val = val.toFixed(opts.toFixed);
+ }
+ }
+ if(webshims._format && webshims._format[name]){
+ return webshims._format[name](val, opts);
+ }
+ return transforms[name](val);
+ };
+ });
+
+ return _toLocale;
+ })();
+
+ webshims.replaceValidationplaceholder = function(elem, message, name){
+ var val = $.prop(elem, 'title');
+ if(message){
+ if(name == 'patternMismatch' && !val){
+ webshims.error('no title for patternMismatch provided. Always add a title attribute.');
+ }
+ if(val){
+ val = ''+ val.replace(lReg, '<').replace(gReg, '>') +'';
+ }
+
+ if(message.indexOf('{%title}') != -1){
+ message = message.replace('{%title}', val);
+ } else if(val) {
+ message = message+' '+val;
+ }
+ }
+
+ if(message && message.indexOf('{%') != -1){
+ ['value', 'min', 'max', 'maxlength', 'minlength', 'label'].forEach(function(attr){
+ if(message.indexOf('{%'+attr) === -1){return;}
+ var val = ((attr == 'label') ? $.trim($('label[for="'+ elem.id +'"]', elem.form).text()).replace(/\*$|:$/, '') : $.prop(elem, attr) || $.attr(elem, attr) || '') || '';
+ val = ''+val;
+
+
+ val = toLocale(val, elem, attr);
+
+ message = message.replace('{%'+ attr +'}', val.replace(lReg, '<').replace(gReg, '>'));
+ if('value' == attr){
+ message = message.replace('{%valueLen}', val.length);
+ }
+
+ });
+ }
+ return message;
+ };
+
+ webshims.createValidationMessage = function(elem, name){
+
+ var message = getMessageFromObj(currentValidationMessage[name], elem);
+ if(!message && name == 'badInput'){
+ message = getMessageFromObj(currentValidationMessage.typeMismatch, elem);
+ }
+ if(!message && name == 'typeMismatch'){
+ message = getMessageFromObj(currentValidationMessage.badInput, elem);
+ }
+ if(!message){
+ message = getMessageFromObj(validityMessages[''][name], elem) || $.prop(elem, 'validationMessage');
+ if(name != 'customError'){
+ webshims.info('could not find errormessage for: '+ name +' / '+ $.prop(elem, 'type') +'. in language: '+webshims.activeLang());
+ }
+ }
+ message = webshims.replaceValidationplaceholder(elem, message, name);
+
+ return message || '';
+ };
+
+
+ if(!webshims.support.formvalidation || webshims.bugs.bustedValidity){
+ implementProperties.push('validationMessage');
+ }
+
+ currentValidationMessage = webshims.activeLang(validityMessages);
+
+ $(validityMessages).on('change', function(e, data){
+ currentValidationMessage = validityMessages.__active;
+ });
+
+ implementProperties.forEach(function(messageProp){
+
+ webshims.defineNodeNamesProperty(['fieldset', 'output', 'button'], messageProp, {
+ prop: {
+ value: '',
+ writeable: false
+ }
+ });
+ ['input', 'select', 'textarea'].forEach(function(nodeName){
+ var desc = webshims.defineNodeNameProperty(nodeName, messageProp, {
+ prop: {
+ get: function(){
+ var elem = this;
+ var message = '';
+ if(!$.prop(elem, 'willValidate')){
+ return message;
+ }
+
+ var validity = $.prop(elem, 'validity') || {valid: 1};
+
+ if(validity.valid){return message;}
+ message = webshims.getContentValidationMessage(elem, validity);
+
+ if(message){return message;}
+
+ if(validity.customError && elem.nodeName){
+ message = (webshims.support.formvalidation && !webshims.bugs.bustedValidity && desc.prop._supget) ? desc.prop._supget.call(elem) : webshims.data(elem, 'customvalidationMessage');
+ if(message){return message;}
+ }
+ $.each(validity, function(name, prop){
+ if(name == 'valid' || !prop){return;}
+
+ message = webshims.createValidationMessage(elem, name);
+ if(message){
+ return false;
+ }
+ });
+
+ return message || '';
+ },
+ writeable: false
+ }
+ });
+ });
+
+ });
+});
+;(function(webshims){
+ "use strict";
+ var support = webshims.support;
+ var hasNative = support.mediaelement;
+ var supportsLoop = false;
+ var bugs = webshims.bugs;
+ var swfType = 'mediaelement-jaris';
+ var loadSwf = function(){
+ webshims.ready(swfType, function(){
+ if(!webshims.mediaelement.createSWF){
+ webshims.mediaelement.loadSwf = true;
+ webshims.reTest([swfType], hasNative);
+ }
+ });
+ };
+
+ var wsCfg = webshims.cfg;
+ var options = wsCfg.mediaelement;
+ var isIE = navigator.userAgent.indexOf('MSIE') != -1;
+ if(!options){
+ webshims.error("mediaelement wasn't implemented but loaded");
+ return;
+ }
+
+ if(hasNative){
+ var videoElem = document.createElement('video');
+ support.videoBuffered = ('buffered' in videoElem);
+ support.mediaDefaultMuted = ('defaultMuted' in videoElem);
+ supportsLoop = ('loop' in videoElem);
+ support.mediaLoop = supportsLoop;
+
+ webshims.capturingEvents(['play', 'playing', 'waiting', 'paused', 'ended', 'durationchange', 'loadedmetadata', 'canplay', 'volumechange']);
+
+ if( !support.videoBuffered || !supportsLoop || (!support.mediaDefaultMuted && isIE && 'ActiveXObject' in window) ){
+ webshims.addPolyfill('mediaelement-native-fix', {
+ d: ['dom-support']
+ });
+ webshims.loader.loadList(['mediaelement-native-fix']);
+ }
+ }
+
+ if(support.track && !bugs.track){
+ (function(){
+ if(!bugs.track){
+
+ if(window.VTTCue && !window.TextTrackCue){
+ window.TextTrackCue = window.VTTCue;
+ } else if(!window.VTTCue){
+ window.VTTCue = window.TextTrackCue;
+ }
+
+ try {
+ new VTTCue(2, 3, '');
+ } catch(e){
+ bugs.track = true;
+ }
+ }
+ })();
+ }
+
+webshims.register('mediaelement-core', function($, webshims, window, document, undefined, options){
+ var hasSwf = swfmini.hasFlashPlayerVersion('10.0.3');
+ var mediaelement = webshims.mediaelement;
+
+ mediaelement.parseRtmp = function(data){
+ var src = data.src.split('://');
+ var paths = src[1].split('/');
+ var i, len, found;
+ data.server = src[0]+'://'+paths[0]+'/';
+ data.streamId = [];
+ for(i = 1, len = paths.length; i < len; i++){
+ if(!found && paths[i].indexOf(':') !== -1){
+ paths[i] = paths[i].split(':')[1];
+ found = true;
+ }
+ if(!found){
+ data.server += paths[i]+'/';
+ } else {
+ data.streamId.push(paths[i]);
+ }
+ }
+ if(!data.streamId.length){
+ webshims.error('Could not parse rtmp url');
+ }
+ data.streamId = data.streamId.join('/');
+ };
+
+ var getSrcObj = function(elem, nodeName){
+ elem = $(elem);
+ var src = {src: elem.attr('src') || '', elem: elem, srcProp: elem.prop('src')};
+ var tmp;
+
+ if(!src.src){return src;}
+
+ tmp = elem.attr('data-server');
+ if(tmp != null){
+ src.server = tmp;
+ }
+
+ tmp = elem.attr('type') || elem.attr('data-type');
+ if(tmp){
+ src.type = tmp;
+ src.container = $.trim(tmp.split(';')[0]);
+ } else {
+ if(!nodeName){
+ nodeName = elem[0].nodeName.toLowerCase();
+ if(nodeName == 'source'){
+ nodeName = (elem.closest('video, audio')[0] || {nodeName: 'video'}).nodeName.toLowerCase();
+ }
+ }
+ if(src.server){
+ src.type = nodeName+'/rtmp';
+ src.container = nodeName+'/rtmp';
+ } else {
+
+ tmp = mediaelement.getTypeForSrc( src.src, nodeName, src );
+
+ if(tmp){
+ src.type = tmp;
+ src.container = tmp;
+ }
+ }
+ }
+
+ tmp = elem.attr('media');
+ if(tmp){
+ src.media = tmp;
+ }
+ if(src.type == 'audio/rtmp' || src.type == 'video/rtmp'){
+ if(src.server){
+ src.streamId = src.src;
+ } else {
+ mediaelement.parseRtmp(src);
+ }
+ }
+ return src;
+ };
+
+
+
+ var hasYt = !hasSwf && ('postMessage' in window) && hasNative;
+
+ var loadTrackUi = function(){
+ if(loadTrackUi.loaded){return;}
+ loadTrackUi.loaded = true;
+ if(!options.noAutoTrack){
+ webshims.ready('WINDOWLOAD', function(){
+ loadThird();
+ webshims.loader.loadList(['track-ui']);
+ });
+ }
+ };
+
+ var loadYt = (function(){
+ var loaded;
+ return function(){
+ if(loaded || !hasYt){return;}
+ loaded = true;
+ webshims.loader.loadScript("https://www.youtube.com/player_api");
+ $(function(){
+ webshims._polyfill(["mediaelement-yt"]);
+ });
+ };
+ })();
+ var loadThird = function(){
+ if(hasSwf){
+ loadSwf();
+ } else {
+ loadYt();
+ }
+ };
+
+ webshims.addPolyfill('mediaelement-yt', {
+ test: !hasYt,
+ d: ['dom-support']
+ });
+
+
+
+ mediaelement.mimeTypes = {
+ audio: {
+ //ogm shouldn´t be used!
+ 'audio/ogg': ['ogg','oga', 'ogm'],
+ 'audio/ogg;codecs="opus"': 'opus',
+ 'audio/mpeg': ['mp2','mp3','mpga','mpega'],
+ 'audio/mp4': ['mp4','mpg4', 'm4r', 'm4a', 'm4p', 'm4b', 'aac'],
+ 'audio/wav': ['wav'],
+ 'audio/3gpp': ['3gp','3gpp'],
+ 'audio/webm': ['webm'],
+ 'audio/fla': ['flv', 'f4a', 'fla'],
+ 'application/x-mpegURL': ['m3u8', 'm3u']
+ },
+ video: {
+ //ogm shouldn´t be used!
+ 'video/ogg': ['ogg','ogv', 'ogm'],
+ 'video/mpeg': ['mpg','mpeg','mpe'],
+ 'video/mp4': ['mp4','mpg4', 'm4v'],
+ 'video/quicktime': ['mov','qt'],
+ 'video/x-msvideo': ['avi'],
+ 'video/x-ms-asf': ['asf', 'asx'],
+ 'video/flv': ['flv', 'f4v'],
+ 'video/3gpp': ['3gp','3gpp'],
+ 'video/webm': ['webm'],
+ 'application/x-mpegURL': ['m3u8', 'm3u'],
+ 'video/MP2T': ['ts']
+ }
+ }
+ ;
+
+ mediaelement.mimeTypes.source = $.extend({}, mediaelement.mimeTypes.audio, mediaelement.mimeTypes.video);
+
+ mediaelement.getTypeForSrc = function(src, nodeName){
+ if(src.indexOf('youtube.com/watch?') != -1 || src.indexOf('youtube.com/v/') != -1){
+ return 'video/youtube';
+ }
+ if(src.indexOf('rtmp') === 0){
+ return nodeName+'/rtmp';
+ }
+ src = src.split('?')[0].split('#')[0].split('.');
+ src = src[src.length - 1];
+ var mt;
+
+ $.each(mediaelement.mimeTypes[nodeName], function(mimeType, exts){
+ if(exts.indexOf(src) !== -1){
+ mt = mimeType;
+ return false;
+ }
+ });
+ return mt;
+ };
+
+
+ mediaelement.srces = function(mediaElem, srces){
+ mediaElem = $(mediaElem);
+ if(!srces){
+ srces = [];
+ var nodeName = mediaElem[0].nodeName.toLowerCase();
+ var src = getSrcObj(mediaElem, nodeName);
+
+ if(!src.src){
+ $('source', mediaElem).each(function(){
+ src = getSrcObj(this, nodeName);
+ if(src.src){srces.push(src);}
+ });
+ } else {
+ srces.push(src);
+ }
+ return srces;
+ } else {
+ webshims.error('setting sources was removed.');
+ }
+ };
+
+ mediaelement.swfMimeTypes = ['video/3gpp', 'video/x-msvideo', 'video/quicktime', 'video/x-m4v', 'video/mp4', 'video/m4p', 'video/x-flv', 'video/flv', 'audio/mpeg', 'audio/aac', 'audio/mp4', 'audio/x-m4a', 'audio/m4a', 'audio/mp3', 'audio/x-fla', 'audio/fla', 'youtube/flv', 'video/jarisplayer', 'jarisplayer/jarisplayer', 'video/youtube', 'video/rtmp', 'audio/rtmp'];
+
+ mediaelement.canThirdPlaySrces = function(mediaElem, srces){
+ var ret = '';
+ if(hasSwf || hasYt){
+ mediaElem = $(mediaElem);
+ srces = srces || mediaelement.srces(mediaElem);
+ $.each(srces, function(i, src){
+ if(src.container && src.src && ((hasSwf && mediaelement.swfMimeTypes.indexOf(src.container) != -1) || (hasYt && src.container == 'video/youtube'))){
+ ret = src;
+ return false;
+ }
+ });
+
+ }
+
+ return ret;
+ };
+
+ var nativeCanPlayType = {};
+ mediaelement.canNativePlaySrces = function(mediaElem, srces){
+ var ret = '';
+ if(hasNative){
+ mediaElem = $(mediaElem);
+ var nodeName = (mediaElem[0].nodeName || '').toLowerCase();
+ var nativeCanPlay = (nativeCanPlayType[nodeName] || {prop: {_supvalue: false}}).prop._supvalue || mediaElem[0].canPlayType;
+ if(!nativeCanPlay){return ret;}
+ srces = srces || mediaelement.srces(mediaElem);
+
+ $.each(srces, function(i, src){
+ if(src.type && nativeCanPlay.call(mediaElem[0], src.type) ){
+ ret = src;
+ return false;
+ }
+ });
+ }
+ return ret;
+ };
+ var emptyType = (/^\s*application\/octet\-stream\s*$/i);
+ var getRemoveEmptyType = function(){
+ var ret = emptyType.test($.attr(this, 'type') || '');
+ if(ret){
+ $(this).removeAttr('type');
+ }
+ return ret;
+ };
+ mediaelement.setError = function(elem, message){
+ if($('source', elem).filter(getRemoveEmptyType).length){
+ webshims.error('"application/octet-stream" is a useless mimetype for audio/video. Please change this attribute.');
+ try {
+ $(elem).mediaLoad();
+ } catch(er){}
+ } else {
+ if(!message){
+ message = "can't play sources";
+ }
+ $(elem).pause().data('mediaerror', message);
+ webshims.error('mediaelementError: '+ message +'. Run the following line in your console to get more info: webshim.mediaelement.loadDebugger();');
+ setTimeout(function(){
+ if($(elem).data('mediaerror')){
+ $(elem).addClass('media-error').trigger('mediaerror');
+ }
+ }, 1);
+ }
+
+
+ };
+
+ var handleThird = (function(){
+ var requested;
+ var readyType = hasSwf ? swfType : 'mediaelement-yt';
+ return function( mediaElem, ret, data ){
+ //readd to ready
+
+ webshims.ready(readyType, function(){
+ if(mediaelement.createSWF && $(mediaElem).parent()[0]){
+ mediaelement.createSWF( mediaElem, ret, data );
+ } else if(!requested) {
+ requested = true;
+ loadThird();
+
+ handleThird( mediaElem, ret, data );
+ }
+ });
+ if(!requested && hasYt && !mediaelement.createSWF){
+ loadYt();
+ }
+ };
+ })();
+
+ var activate = {
+ native: function(elem, src, data){
+ if(data && data.isActive == 'third') {
+ mediaelement.setActive(elem, 'html5', data);
+ }
+ },
+ third: handleThird
+ };
+
+ var stepSources = function(elem, data, srces){
+ var i, src;
+ var testOrder = [{test: 'canNativePlaySrces', activate: 'native'}, {test: 'canThirdPlaySrces', activate: 'third'}];
+ if(options.preferFlash || (data && data.isActive == 'third') ){
+ testOrder.reverse();
+ }
+ for(i = 0; i < 2; i++){
+ src = mediaelement[testOrder[i].test](elem, srces);
+ if(src){
+ activate[testOrder[i].activate](elem, src, data);
+ break;
+ }
+ }
+
+ if(!src){
+ mediaelement.setError(elem, false);
+ if(data && data.isActive == 'third') {
+ mediaelement.setActive(elem, 'html5', data);
+ }
+ }
+ };
+ var stopParent = /^(?:embed|object|datalist|picture)$/i;
+ var selectSource = function(elem, data){
+ var baseData = webshims.data(elem, 'mediaelementBase') || webshims.data(elem, 'mediaelementBase', {});
+ var _srces = mediaelement.srces(elem);
+ var parent = elem.parentNode;
+
+ clearTimeout(baseData.loadTimer);
+ $(elem).removeClass('media-error');
+ $.data(elem, 'mediaerror', false);
+
+ if(!_srces.length || !parent || parent.nodeType != 1 || stopParent.test(parent.nodeName || '')){return;}
+ data = data || webshims.data(elem, 'mediaelement');
+ if(mediaelement.sortMedia){
+ _srces.sort(mediaelement.sortMedia);
+ }
+ stepSources(elem, data, _srces);
+
+ };
+ mediaelement.selectSource = selectSource;
+
+
+ $(document).on('ended', function(e){
+ var data = webshims.data(e.target, 'mediaelement');
+ if( supportsLoop && (!data || data.isActive == 'html5') && !$.prop(e.target, 'loop')){return;}
+ setTimeout(function(){
+ if( $.prop(e.target, 'paused') || !$.prop(e.target, 'loop') ){return;}
+ $(e.target).prop('currentTime', 0).play();
+ });
+
+ });
+
+ var handleMedia = false;
+
+ var initMediaElements = function(){
+ var testFixMedia = function(){
+
+ if(webshims.implement(this, 'mediaelement')){
+ selectSource(this);
+ if(!support.mediaDefaultMuted && $.attr(this, 'muted') != null){
+ $.prop(this, 'muted', true);
+ }
+
+ }
+ };
+
+ webshims.ready('dom-support', function(){
+ handleMedia = true;
+
+ if(!supportsLoop){
+ webshims.defineNodeNamesBooleanProperty(['audio', 'video'], 'loop');
+ }
+
+ ['audio', 'video'].forEach(function(nodeName){
+ var supLoad;
+ supLoad = webshims.defineNodeNameProperty(nodeName, 'load', {
+ prop: {
+ value: function(){
+ var data = webshims.data(this, 'mediaelement');
+
+ selectSource(this, data);
+ if(hasNative && (!data || data.isActive == 'html5') && supLoad.prop._supvalue){
+ supLoad.prop._supvalue.apply(this, arguments);
+ }
+ if(!loadTrackUi.loaded && this.querySelector('track')){
+ loadTrackUi();
+ }
+ $(this).triggerHandler('wsmediareload');
+ }
+ }
+ });
+
+ nativeCanPlayType[nodeName] = webshims.defineNodeNameProperty(nodeName, 'canPlayType', {
+ prop: {
+ value: function(type){
+ var ret = '';
+ if(hasNative && nativeCanPlayType[nodeName].prop._supvalue){
+ ret = nativeCanPlayType[nodeName].prop._supvalue.call(this, type);
+ if(ret == 'no'){
+ ret = '';
+ }
+ }
+ if(!ret && hasSwf){
+ type = $.trim((type || '').split(';')[0]);
+ if(mediaelement.swfMimeTypes.indexOf(type) != -1){
+ ret = 'maybe';
+ }
+ }
+ if(!ret && hasYt && type == 'video/youtube'){
+ ret = 'maybe';
+ }
+ return ret;
+ }
+ }
+ });
+ });
+
+
+ webshims.onNodeNamesPropertyModify(['audio', 'video'], ['src', 'poster'], {
+ set: function(){
+ var elem = this;
+ var baseData = webshims.data(elem, 'mediaelementBase') || webshims.data(elem, 'mediaelementBase', {});
+ clearTimeout(baseData.loadTimer);
+ baseData.loadTimer = setTimeout(function(){
+ selectSource(elem);
+ elem = null;
+ }, 9);
+ }
+ });
+
+
+ webshims.addReady(function(context, insertedElement){
+ var media = $('video, audio', context)
+ .add(insertedElement.filter('video, audio'))
+ .each(testFixMedia)
+ ;
+ if(!loadTrackUi.loaded && $('track', media).length){
+ loadTrackUi();
+ }
+ media = null;
+ });
+ });
+
+ if(hasNative && !handleMedia){
+ webshims.addReady(function(context, insertedElement){
+ if(!handleMedia){
+ $('video, audio', context)
+ .add(insertedElement.filter('video, audio'))
+ .each(function(){
+ if(!mediaelement.canNativePlaySrces(this)){
+ loadThird();
+ handleMedia = true;
+ return false;
+ }
+ })
+ ;
+ }
+ });
+ }
+ };
+
+ mediaelement.loadDebugger = function(){
+ webshims.ready('dom-support', function(){
+ webshims.loader.loadScript('mediaelement-debug');
+ });
+ };
+
+ if(({noCombo: 1, media: 1})[webshims.cfg.debug]){
+ $(document).on('mediaerror', function(e){
+ mediaelement.loadDebugger();
+ });
+ }
+ //set native implementation ready, before swf api is retested
+ if(hasNative){
+ webshims.isReady('mediaelement-core', true);
+ initMediaElements();
+ webshims.ready('WINDOWLOAD mediaelement', loadThird);
+ } else {
+ webshims.ready(swfType, initMediaElements);
+ }
+ webshims.ready('track', loadTrackUi);
+});
+
+})(webshims);
diff --git a/public/webshims/shims/combos/9.js b/public/webshims/shims/combos/9.js
new file mode 100644
index 00000000..2099a7b3
--- /dev/null
+++ b/public/webshims/shims/combos/9.js
@@ -0,0 +1,4107 @@
+
+//this might was already extended by ES5 shim feature
+(function($){
+ "use strict";
+ var webshims = window.webshims;
+ if(webshims.defineProperties){return;}
+ var defineProperty = 'defineProperty';
+ var has = Object.prototype.hasOwnProperty;
+ var descProps = ['configurable', 'enumerable', 'writable'];
+ var extendUndefined = function(prop){
+ for(var i = 0; i < 3; i++){
+ if(prop[descProps[i]] === undefined && (descProps[i] !== 'writable' || prop.value !== undefined)){
+ prop[descProps[i]] = true;
+ }
+ }
+ };
+
+ var extendProps = function(props){
+ if(props){
+ for(var i in props){
+ if(has.call(props, i)){
+ extendUndefined(props[i]);
+ }
+ }
+ }
+ };
+
+ if(Object.create){
+ webshims.objectCreate = function(proto, props, opts){
+ extendProps(props);
+ var o = Object.create(proto, props);
+ if(opts){
+ o.options = $.extend(true, {}, o.options || {}, opts);
+ opts = o.options;
+ }
+ if(o._create && $.isFunction(o._create)){
+ o._create(opts);
+ }
+ return o;
+ };
+ }
+
+ if(Object[defineProperty]){
+ webshims[defineProperty] = function(obj, prop, desc){
+ extendUndefined(desc);
+ return Object[defineProperty](obj, prop, desc);
+ };
+ }
+ if(Object.defineProperties){
+ webshims.defineProperties = function(obj, props){
+ extendProps(props);
+ return Object.defineProperties(obj, props);
+ };
+ }
+ webshims.getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor;
+
+ webshims.getPrototypeOf = Object.getPrototypeOf;
+})(window.webshims.$);
+//DOM-Extension helper
+webshims.register('dom-extend', function($, webshims, window, document, undefined){
+ "use strict";
+ var supportHrefNormalized = !('hrefNormalized' in $.support) || $.support.hrefNormalized;
+ var supportGetSetAttribute = !('getSetAttribute' in $.support) || $.support.getSetAttribute;
+ var has = Object.prototype.hasOwnProperty;
+ webshims.assumeARIA = true;
+
+ if($('').attr('type') == 'text' || $('').attr('novalidate') === "" || ('required' in $('')[0].attributes)){
+ webshims.error("IE browser modes are busted in IE10+. Please test your HTML/CSS/JS with a real IE version or at least IETester or similiar tools");
+ }
+
+ if('debug' in webshims){
+ webshims.error('Use webshims.setOptions("debug", true||false||"noCombo"); to debug flag');
+ }
+
+ if (!webshims.cfg.no$Switch) {
+ var switch$ = function(){
+ if (window.jQuery && (!window.$ || window.jQuery == window.$) && !window.jQuery.webshims) {
+ webshims.error("jQuery was included more than once. Make sure to include it only once or try the $.noConflict(extreme) feature! Webshims and other Plugins might not work properly. Or set webshims.cfg.no$Switch to 'true'.");
+ if (window.$) {
+ window.$ = webshims.$;
+ }
+ window.jQuery = webshims.$;
+ }
+ };
+ switch$();
+ setTimeout(switch$, 90);
+ webshims.ready('DOM', switch$);
+ $(switch$);
+ webshims.ready('WINDOWLOAD', switch$);
+
+ }
+
+ //shortcus
+ var modules = webshims.modules;
+ var listReg = /\s*,\s*/;
+
+ //proxying attribute
+ var olds = {};
+ var havePolyfill = {};
+ var hasPolyfillMethod = {};
+ var extendedProps = {};
+ var extendQ = {};
+ var modifyProps = {};
+
+ var oldVal = $.fn.val;
+ var singleVal = function(elem, name, val, pass, _argless){
+ return (_argless) ? oldVal.call($(elem)) : oldVal.call($(elem), val);
+ };
+
+ //jquery mobile and jquery ui
+ if(!$.widget){
+ (function(){
+ var _cleanData = $.cleanData;
+ $.cleanData = function( elems ) {
+ if(!$.widget){
+ for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) {
+ try {
+ $( elem ).triggerHandler( "remove" );
+ // http://bugs.jquery.com/ticket/8235
+ } catch( e ) {}
+ }
+ }
+ _cleanData( elems );
+ };
+ })();
+ }
+
+
+ $.fn.val = function(val){
+ var elem = this[0];
+ if(arguments.length && val == null){
+ val = '';
+ }
+ if(!arguments.length){
+ if(!elem || elem.nodeType !== 1){return oldVal.call(this);}
+ return $.prop(elem, 'value', val, 'val', true);
+ }
+ if($.isArray(val)){
+ return oldVal.apply(this, arguments);
+ }
+ var isFunction = $.isFunction(val);
+ return this.each(function(i){
+ elem = this;
+ if(elem.nodeType === 1){
+ if(isFunction){
+ var genVal = val.call( elem, i, $.prop(elem, 'value', undefined, 'val', true));
+ if(genVal == null){
+ genVal = '';
+ }
+ $.prop(elem, 'value', genVal, 'val') ;
+ } else {
+ $.prop(elem, 'value', val, 'val');
+ }
+ }
+ });
+ };
+ $.fn.onTrigger = function(evt, fn){
+ return this.on(evt, fn).each(fn);
+ };
+
+ $.fn.onWSOff = function(evt, fn, trigger, evtDel){
+ if(!evtDel){
+ evtDel = document;
+ }
+ $(evtDel)[trigger ? 'onTrigger' : 'on'](evt, fn);
+ this.on('remove', function(e){
+ if(!e.originalEvent){
+ $(evtDel).off(evt, fn);
+ }
+ });
+ return this;
+ };
+ var idCount = 0;
+ var dataID = '_webshims'+ (Math.round(Math.random() * 1000));
+ var elementData = function(elem, key, val){
+ elem = elem.jquery ? elem[0] : elem;
+ if(!elem){return val || {};}
+ var data = $.data(elem, dataID);
+ if(val !== undefined){
+ if(!data){
+ data = $.data(elem, dataID, {});
+ }
+ if(key){
+ data[key] = val;
+ }
+ }
+
+ return key ? data && data[key] : data;
+ };
+
+
+ [{name: 'getNativeElement', prop: 'nativeElement'}, {name: 'getShadowElement', prop: 'shadowElement'}, {name: 'getShadowFocusElement', prop: 'shadowFocusElement'}].forEach(function(data){
+ $.fn[data.name] = function(){
+ var elems = [];
+ this.each(function(){
+ var shadowData = elementData(this, 'shadowData');
+ var elem = shadowData && shadowData[data.prop] || this;
+ if($.inArray(elem, elems) == -1){
+ elems.push(elem);
+ }
+ });
+ return this.pushStack(elems);
+ };
+ });
+
+ function clone(elem, dataAndEvents, uniqueIds){
+ var cloned = $.clone( elem, dataAndEvents, false );
+ $(cloned.querySelectorAll('.'+webshims.shadowClass)).detach();
+ if(uniqueIds){
+ idCount++;
+ $(cloned.querySelectorAll('[id]')).prop('id', function(i, id){
+ return id +idCount;
+ });
+ } else {
+ $(cloned.querySelectorAll('audio[id^="ID-"], video[id^="ID-"], label[id^="ID-"]')).removeAttr('id');
+ }
+ return cloned;
+ }
+
+ $.fn.clonePolyfill = function(dataAndEvents, uniqueIds){
+ dataAndEvents = dataAndEvents || false;
+ return this
+ .map(function() {
+ var cloned = clone( this, dataAndEvents, uniqueIds );
+ setTimeout(function(){
+ if($.contains(document.body, cloned)){
+ $(cloned).updatePolyfill();
+ }
+ });
+ return cloned;
+ })
+ ;
+ };
+
+ //add support for $('video').trigger('play') in case extendNative is set to false
+ if(!webshims.cfg.extendNative && !webshims.cfg.noTriggerOverride){
+ (function(oldTrigger){
+ $.event.trigger = function(event, data, elem, onlyHandlers){
+
+ if(!hasPolyfillMethod[event] || onlyHandlers || !elem || elem.nodeType !== 1){
+ return oldTrigger.apply(this, arguments);
+ }
+ var ret, isOrig, origName;
+ var origFn = elem[event];
+ var polyfilledFn = $.prop(elem, event);
+ var changeFn = polyfilledFn && origFn != polyfilledFn;
+ if(changeFn){
+ origName = '__ws'+event;
+ isOrig = (event in elem) && has.call(elem, event);
+ elem[event] = polyfilledFn;
+ elem[origName] = origFn;
+ }
+
+ ret = oldTrigger.apply(this, arguments);
+ if (changeFn) {
+ if(isOrig){
+ elem[event] = origFn;
+ } else {
+ delete elem[event];
+ }
+ delete elem[origName];
+ }
+
+ return ret;
+ };
+ })($.event.trigger);
+ }
+
+ ['removeAttr', 'prop', 'attr'].forEach(function(type){
+ olds[type] = $[type];
+ $[type] = function(elem, name, value, pass, _argless){
+ var isVal = (pass == 'val');
+ var oldMethod = !isVal ? olds[type] : singleVal;
+ if( !elem || !havePolyfill[name] || elem.nodeType !== 1 || (!isVal && pass && type == 'attr' && $.attrFn[name]) ){
+ return oldMethod(elem, name, value, pass, _argless);
+ }
+
+ var nodeName = (elem.nodeName || '').toLowerCase();
+ var desc = extendedProps[nodeName];
+ var curType = (type == 'attr' && (value === false || value === null)) ? 'removeAttr' : type;
+ var propMethod;
+ var oldValMethod;
+ var ret;
+
+
+ if(!desc){
+ desc = extendedProps['*'];
+ }
+ if(desc){
+ desc = desc[name];
+ }
+
+ if(desc){
+ propMethod = desc[curType];
+ }
+
+ if(propMethod){
+ if(name == 'value'){
+ oldValMethod = propMethod.isVal;
+ propMethod.isVal = isVal;
+ }
+ if(curType === 'removeAttr'){
+ return propMethod.value.call(elem);
+ } else if(value === undefined){
+ return (propMethod.get) ?
+ propMethod.get.call(elem) :
+ propMethod.value
+ ;
+ } else if(propMethod.set) {
+ if(type == 'attr' && value === true){
+ value = name;
+ }
+
+ ret = propMethod.set.call(elem, value);
+ }
+ if(name == 'value'){
+ propMethod.isVal = oldValMethod;
+ }
+ } else {
+ ret = oldMethod(elem, name, value, pass, _argless);
+ }
+ if((value !== undefined || curType === 'removeAttr') && modifyProps[nodeName] && modifyProps[nodeName][name]){
+
+ var boolValue;
+ if(curType == 'removeAttr'){
+ boolValue = false;
+ } else if(curType == 'prop'){
+ boolValue = !!(value);
+ } else {
+ boolValue = true;
+ }
+
+ modifyProps[nodeName][name].forEach(function(fn){
+ if(!fn.only || (fn.only = 'prop' && type == 'prop') || (fn.only == 'attr' && type != 'prop')){
+ fn.call(elem, value, boolValue, (isVal) ? 'val' : curType, type);
+ }
+ });
+ }
+ return ret;
+ };
+
+ extendQ[type] = function(nodeName, prop, desc){
+
+ if(!extendedProps[nodeName]){
+ extendedProps[nodeName] = {};
+ }
+ if(!extendedProps[nodeName][prop]){
+ extendedProps[nodeName][prop] = {};
+ }
+ var oldDesc = extendedProps[nodeName][prop][type];
+ var getSup = function(propType, descriptor, oDesc){
+ var origProp;
+ if(descriptor && descriptor[propType]){
+ return descriptor[propType];
+ }
+ if(oDesc && oDesc[propType]){
+ return oDesc[propType];
+ }
+ if(type == 'prop' && prop == 'value'){
+ return function(value){
+ var elem = this;
+ return (desc.isVal) ?
+ singleVal(elem, prop, value, false, (arguments.length === 0)) :
+ olds[type](elem, prop, value)
+ ;
+ };
+ }
+ if(type == 'prop' && propType == 'value' && desc.value.apply){
+ origProp = '__ws'+prop;
+ hasPolyfillMethod[prop] = true;
+ return function(value){
+ var sup = this[origProp] || olds[type](this, prop);
+ if(sup && sup.apply){
+ sup = sup.apply(this, arguments);
+ }
+ return sup;
+ };
+ }
+ return function(value){
+ return olds[type](this, prop, value);
+ };
+ };
+ extendedProps[nodeName][prop][type] = desc;
+ if(desc.value === undefined){
+ if(!desc.set){
+ desc.set = desc.writeable ?
+ getSup('set', desc, oldDesc) :
+ (webshims.cfg.useStrict && prop == 'prop') ?
+ function(){throw(prop +' is readonly on '+ nodeName);} :
+ function(){webshims.info(prop +' is readonly on '+ nodeName);}
+ ;
+ }
+ if(!desc.get){
+ desc.get = getSup('get', desc, oldDesc);
+ }
+
+ }
+
+ ['value', 'get', 'set'].forEach(function(descProp){
+ if(desc[descProp]){
+ desc['_sup'+descProp] = getSup(descProp, oldDesc);
+ }
+ });
+ };
+
+ });
+
+ var extendNativeValue = (function(){
+ var UNKNOWN = webshims.getPrototypeOf(document.createElement('foobar'));
+
+ //see also: https://github.com/lojjic/PIE/issues/40 | https://prototype.lighthouseapp.com/projects/8886/tickets/1107-ie8-fatal-crash-when-prototypejs-is-loaded-with-rounded-cornershtc
+ var isExtendNativeSave = webshims.support.advancedObjectProperties && webshims.support.objectAccessor;
+ return function(nodeName, prop, desc){
+ var elem , elemProto;
+ if( isExtendNativeSave && (elem = document.createElement(nodeName)) && (elemProto = webshims.getPrototypeOf(elem)) && UNKNOWN !== elemProto && ( !elem[prop] || !has.call(elem, prop) ) ){
+ var sup = elem[prop];
+ desc._supvalue = function(){
+ if(sup && sup.apply){
+ return sup.apply(this, arguments);
+ }
+ return sup;
+ };
+ elemProto[prop] = desc.value;
+ } else {
+ desc._supvalue = function(){
+ var data = elementData(this, 'propValue');
+ if(data && data[prop] && data[prop].apply){
+ return data[prop].apply(this, arguments);
+ }
+ return data && data[prop];
+ };
+ initProp.extendValue(nodeName, prop, desc.value);
+ }
+ desc.value._supvalue = desc._supvalue;
+ };
+ })();
+
+ var initProp = (function(){
+
+ var initProps = {};
+
+ webshims.addReady(function(context, contextElem){
+ var nodeNameCache = {};
+ var getElementsByName = function(name){
+ if(!nodeNameCache[name]){
+ nodeNameCache[name] = $(context.getElementsByTagName(name));
+ if(contextElem[0] && $.nodeName(contextElem[0], name)){
+ nodeNameCache[name] = nodeNameCache[name].add(contextElem);
+ }
+ }
+ };
+
+
+ $.each(initProps, function(name, fns){
+ getElementsByName(name);
+ if(!fns || !fns.forEach){
+ webshims.warn('Error: with '+ name +'-property. methods: '+ fns);
+ return;
+ }
+ fns.forEach(function(fn){
+ nodeNameCache[name].each(fn);
+ });
+ });
+ nodeNameCache = null;
+ });
+
+ var tempCache;
+ var emptyQ = $([]);
+ var createNodeNameInit = function(nodeName, fn){
+ if(!initProps[nodeName]){
+ initProps[nodeName] = [fn];
+ } else {
+ initProps[nodeName].push(fn);
+ }
+ if($.isDOMReady){
+ (tempCache || $( document.getElementsByTagName(nodeName) )).each(fn);
+ }
+ };
+
+ var elementExtends = {};
+ return {
+ createTmpCache: function(nodeName){
+ if($.isDOMReady){
+ tempCache = tempCache || $( document.getElementsByTagName(nodeName) );
+ }
+ return tempCache || emptyQ;
+ },
+ flushTmpCache: function(){
+ tempCache = null;
+ },
+ content: function(nodeName, prop){
+ createNodeNameInit(nodeName, function(){
+ var val = $.attr(this, prop);
+ if(val != null){
+ $.attr(this, prop, val);
+ }
+ });
+ },
+ createElement: function(nodeName, fn){
+ createNodeNameInit(nodeName, fn);
+ },
+ extendValue: function(nodeName, prop, value){
+ createNodeNameInit(nodeName, function(){
+ $(this).each(function(){
+ var data = elementData(this, 'propValue', {});
+ data[prop] = this[prop];
+ this[prop] = value;
+ });
+ });
+ }
+ };
+ })();
+
+ var createPropDefault = function(descs, removeType){
+ if(descs.defaultValue === undefined){
+ descs.defaultValue = '';
+ }
+ if(!descs.removeAttr){
+ descs.removeAttr = {
+ value: function(){
+ descs[removeType || 'prop'].set.call(this, descs.defaultValue);
+ descs.removeAttr._supvalue.call(this);
+ }
+ };
+ }
+ if(!descs.attr){
+ descs.attr = {};
+ }
+ };
+
+ $.extend(webshims, {
+ getID: (function(){
+ var ID = new Date().getTime();
+ return function(elem){
+ elem = $(elem);
+ var id = elem.prop('id');
+ if(!id){
+ ID++;
+ id = 'ID-'+ ID;
+ elem.eq(0).prop('id', id);
+ }
+ return id;
+ };
+ })(),
+ shadowClass: 'wsshadow-'+(Date.now()),
+ implement: function(elem, type){
+ var data = elementData(elem, 'implemented') || elementData(elem, 'implemented', {});
+ if(data[type]){
+ webshims.warn(type +' already implemented for element #'+elem.id);
+ return false;
+ }
+ data[type] = true;
+ return true;
+ },
+ extendUNDEFProp: function(obj, props){
+ $.each(props, function(name, prop){
+ if( !(name in obj) ){
+ obj[name] = prop;
+ }
+ });
+ },
+ getOptions: (function(){
+ var normalName = /\-([a-z])/g;
+ var regs = {};
+ var nameRegs = {};
+ var regFn = function(f, upper){
+ return upper.toLowerCase();
+ };
+ var nameFn = function(f, dashed){
+ return dashed.toUpperCase();
+ };
+ return function(elem, name, bases, stringAllowed){
+ if(nameRegs[name]){
+ name = nameRegs[name];
+ } else {
+ nameRegs[name] = name.replace(normalName, nameFn);
+ name = nameRegs[name];
+ }
+ var data = elementData(elem, 'cfg'+name);
+ var dataName;
+ var cfg = {};
+
+ if(data){
+ return data;
+ }
+ data = $(elem).data();
+ if(data && typeof data[name] == 'string'){
+ if(stringAllowed){
+ return elementData(elem, 'cfg'+name, data[name]);
+ }
+ webshims.error('data-'+ name +' attribute has to be a valid JSON, was: '+ data[name]);
+ }
+ if(!bases){
+ bases = [true, {}];
+ } else if(!Array.isArray(bases)){
+ bases = [true, {}, bases];
+ } else {
+ bases.unshift(true, {});
+ }
+
+ if(data && typeof data[name] == 'object'){
+ bases.push(data[name]);
+ }
+
+ if(!regs[name]){
+ regs[name] = new RegExp('^'+ name +'([A-Z])');
+ }
+
+ for(dataName in data){
+ if(regs[name].test(dataName)){
+ cfg[dataName.replace(regs[name], regFn)] = data[dataName];
+ }
+ }
+ bases.push(cfg);
+ return elementData(elem, 'cfg'+name, $.extend.apply($, bases));
+ };
+ })(),
+ //http://www.w3.org/TR/html5/common-dom-interfaces.html#reflect
+ createPropDefault: createPropDefault,
+ data: elementData,
+ moveToFirstEvent: function(elem, eventType, bindType){
+ var events = ($._data(elem, 'events') || {})[eventType];
+ var fn;
+
+ if(events && events.length > 1){
+ fn = events.pop();
+ if(!bindType){
+ bindType = 'bind';
+ }
+ if(bindType == 'bind' && events.delegateCount){
+ events.splice( events.delegateCount, 0, fn);
+ } else {
+ events.unshift( fn );
+ }
+
+
+ }
+ elem = null;
+ },
+ addShadowDom: (function(){
+ var resizeTimer;
+ var lastHeight;
+ var lastWidth;
+ var $window = $(window);
+ var docObserve = {
+ init: false,
+ runs: 0,
+ test: function(){
+ var height = docObserve.getHeight();
+ var width = docObserve.getWidth();
+
+ if(height != docObserve.height || width != docObserve.width){
+ docObserve.height = height;
+ docObserve.width = width;
+ docObserve.handler({type: 'docresize'});
+ docObserve.runs++;
+ if(docObserve.runs < 9){
+ setTimeout(docObserve.test, 90);
+ }
+ } else {
+ docObserve.runs = 0;
+ }
+ },
+ handler: (function(){
+ var trigger = function(){
+ $(document).triggerHandler('updateshadowdom');
+ };
+ return function(e){
+ clearTimeout(resizeTimer);
+ resizeTimer = setTimeout(function(){
+ if(e.type == 'resize'){
+ var width = $window.width();
+ var height = $window.width();
+
+ if(height == lastHeight && width == lastWidth){
+ return;
+ }
+ lastHeight = height;
+ lastWidth = width;
+
+ docObserve.height = docObserve.getHeight();
+ docObserve.width = docObserve.getWidth();
+ }
+
+ if(window.requestAnimationFrame){
+ requestAnimationFrame(trigger);
+ } else {
+ setTimeout(trigger, 0);
+ }
+
+ }, (e.type == 'resize' && !window.requestAnimationFrame) ? 50 : 9);
+ };
+ })(),
+ _create: function(){
+ $.each({ Height: "getHeight", Width: "getWidth" }, function(name, type){
+ var body = document.body;
+ var doc = document.documentElement;
+ docObserve[type] = function (){
+ return Math.max(
+ body[ "scroll" + name ], doc[ "scroll" + name ],
+ body[ "offset" + name ], doc[ "offset" + name ],
+ doc[ "client" + name ]
+ );
+ };
+ });
+ },
+ start: function(){
+ if(!this.init && document.body){
+ this.init = true;
+ this._create();
+ this.height = docObserve.getHeight();
+ this.width = docObserve.getWidth();
+ setInterval(this.test, 999);
+ $(this.test);
+ if($.support.boxSizing == null){
+ $(function(){
+ if($.support.boxSizing){
+ docObserve.handler({type: 'boxsizing'});
+ }
+ });
+ }
+ webshims.ready('WINDOWLOAD', this.test);
+ $(document).on('updatelayout.webshim pageinit popupafteropen panelbeforeopen tabsactivate collapsibleexpand shown.bs.modal shown.bs.collapse slid.bs.carousel playerdimensionchange', this.handler);
+ $(window).on('resize', this.handler);
+ }
+ }
+ };
+
+
+ webshims.docObserve = function(){
+ webshims.ready('DOM', function(){
+ docObserve.start();
+
+ });
+ };
+ return function(nativeElem, shadowElem, opts){
+ if(nativeElem && shadowElem){
+ opts = opts || {};
+ if(nativeElem.jquery){
+ nativeElem = nativeElem[0];
+ }
+ if(shadowElem.jquery){
+ shadowElem = shadowElem[0];
+ }
+ var nativeData = $.data(nativeElem, dataID) || $.data(nativeElem, dataID, {});
+ var shadowData = $.data(shadowElem, dataID) || $.data(shadowElem, dataID, {});
+ var shadowFocusElementData = {};
+ if(!opts.shadowFocusElement){
+ opts.shadowFocusElement = shadowElem;
+ } else if(opts.shadowFocusElement){
+ if(opts.shadowFocusElement.jquery){
+ opts.shadowFocusElement = opts.shadowFocusElement[0];
+ }
+ shadowFocusElementData = $.data(opts.shadowFocusElement, dataID) || $.data(opts.shadowFocusElement, dataID, shadowFocusElementData);
+ }
+
+ $(nativeElem).on('remove', function(e){
+ if (!e.originalEvent) {
+ setTimeout(function(){
+ $(shadowElem).remove();
+ }, 4);
+ }
+ });
+
+ nativeData.hasShadow = shadowElem;
+ shadowFocusElementData.nativeElement = shadowData.nativeElement = nativeElem;
+ shadowFocusElementData.shadowData = shadowData.shadowData = nativeData.shadowData = {
+ nativeElement: nativeElem,
+ shadowElement: shadowElem,
+ shadowFocusElement: opts.shadowFocusElement
+ };
+ if(opts.shadowChilds){
+ opts.shadowChilds.each(function(){
+ elementData(this, 'shadowData', shadowData.shadowData);
+ });
+ }
+
+ if(opts.data){
+ shadowFocusElementData.shadowData.data = shadowData.shadowData.data = nativeData.shadowData.data = opts.data;
+ }
+ opts = null;
+ }
+ webshims.docObserve();
+ };
+ })(),
+ propTypes: {
+ standard: function(descs, name){
+ createPropDefault(descs);
+ if(descs.prop){return;}
+ descs.prop = {
+ set: function(val){
+ descs.attr.set.call(this, ''+val);
+ },
+ get: function(){
+ return descs.attr.get.call(this) || descs.defaultValue;
+ }
+ };
+
+ },
+ "boolean": function(descs, name){
+
+ createPropDefault(descs);
+ if(descs.prop){return;}
+ descs.prop = {
+ set: function(val){
+ if(val){
+ descs.attr.set.call(this, "");
+ } else {
+ descs.removeAttr.value.call(this);
+ }
+ },
+ get: function(){
+ return descs.attr.get.call(this) != null;
+ }
+ };
+ },
+ "src": (function(){
+ var anchor = document.createElement('a');
+ anchor.style.display = "none";
+ return function(descs, name){
+
+ createPropDefault(descs);
+ if(descs.prop){return;}
+ descs.prop = {
+ set: function(val){
+ descs.attr.set.call(this, val);
+ },
+ get: function(){
+ var href = this.getAttribute(name);
+ var ret;
+ if(href == null){return '';}
+
+ anchor.setAttribute('href', href+'' );
+
+ if(!supportHrefNormalized){
+ try {
+ $(anchor).insertAfter(this);
+ ret = anchor.getAttribute('href', 4);
+ } catch(er){
+ ret = anchor.getAttribute('href', 4);
+ }
+ $(anchor).detach();
+ }
+ return ret || anchor.href;
+ }
+ };
+ };
+ })(),
+ enumarated: function(descs, name){
+
+ createPropDefault(descs);
+ if(descs.prop){return;}
+ descs.prop = {
+ set: function(val){
+ descs.attr.set.call(this, val);
+ },
+ get: function(){
+ var val = (descs.attr.get.call(this) || '').toLowerCase();
+ if(!val || descs.limitedTo.indexOf(val) == -1){
+ val = descs.defaultValue;
+ }
+ return val;
+ }
+ };
+ }
+
+// ,unsignedLong: $.noop
+// ,"doubble": $.noop
+// ,"long": $.noop
+// ,tokenlist: $.noop
+// ,settableTokenlist: $.noop
+ },
+ reflectProperties: function(nodeNames, props){
+ if(typeof props == 'string'){
+ props = props.split(listReg);
+ }
+ props.forEach(function(prop){
+ webshims.defineNodeNamesProperty(nodeNames, prop, {
+ prop: {
+ set: function(val){
+ $.attr(this, prop, val);
+ },
+ get: function(){
+ return $.attr(this, prop) || '';
+ }
+ }
+ });
+ });
+ },
+ defineNodeNameProperty: function(nodeName, prop, descs){
+ havePolyfill[prop] = true;
+
+ if(descs.reflect){
+ if(descs.propType && !webshims.propTypes[descs.propType]){
+ webshims.error('could not finde propType '+ descs.propType);
+ } else {
+ webshims.propTypes[descs.propType || 'standard'](descs, prop);
+ }
+
+ }
+
+ ['prop', 'attr', 'removeAttr'].forEach(function(type){
+ var desc = descs[type];
+ if(desc){
+ if(type === 'prop'){
+ desc = $.extend({writeable: true}, desc);
+ } else {
+ desc = $.extend({}, desc, {writeable: true});
+ }
+
+ extendQ[type](nodeName, prop, desc);
+ if(nodeName != '*' && webshims.cfg.extendNative && type == 'prop' && desc.value && $.isFunction(desc.value)){
+ extendNativeValue(nodeName, prop, desc);
+ }
+ descs[type] = desc;
+ }
+ });
+ if(descs.initAttr){
+ initProp.content(nodeName, prop);
+ }
+ return descs;
+ },
+
+ defineNodeNameProperties: function(name, descs, propType, _noTmpCache){
+ var olddesc;
+ for(var prop in descs){
+ if(!_noTmpCache && descs[prop].initAttr){
+ initProp.createTmpCache(name);
+ }
+ if(propType){
+ if(descs[prop][propType]){
+ //webshims.log('override: '+ name +'['+prop +'] for '+ propType);
+ } else {
+ descs[prop][propType] = {};
+ ['value', 'set', 'get'].forEach(function(copyProp){
+ if(copyProp in descs[prop]){
+ descs[prop][propType][copyProp] = descs[prop][copyProp];
+ delete descs[prop][copyProp];
+ }
+ });
+ }
+ }
+ descs[prop] = webshims.defineNodeNameProperty(name, prop, descs[prop]);
+ }
+ if(!_noTmpCache){
+ initProp.flushTmpCache();
+ }
+ return descs;
+ },
+
+ createElement: function(nodeName, create, descs){
+ var ret;
+ if($.isFunction(create)){
+ create = {
+ after: create
+ };
+ }
+ initProp.createTmpCache(nodeName);
+ if(create.before){
+ initProp.createElement(nodeName, create.before);
+ }
+ if(descs){
+ ret = webshims.defineNodeNameProperties(nodeName, descs, false, true);
+ }
+ if(create.after){
+ initProp.createElement(nodeName, create.after);
+ }
+ initProp.flushTmpCache();
+ return ret;
+ },
+ onNodeNamesPropertyModify: function(nodeNames, props, desc, only){
+ if(typeof nodeNames == 'string'){
+ nodeNames = nodeNames.split(listReg);
+ }
+ if($.isFunction(desc)){
+ desc = {set: desc};
+ }
+
+ nodeNames.forEach(function(name){
+ if(!modifyProps[name]){
+ modifyProps[name] = {};
+ }
+ if(typeof props == 'string'){
+ props = props.split(listReg);
+ }
+ if(desc.initAttr){
+ initProp.createTmpCache(name);
+ }
+ props.forEach(function(prop){
+ if(!modifyProps[name][prop]){
+ modifyProps[name][prop] = [];
+ havePolyfill[prop] = true;
+ }
+ if(desc.set){
+ if(only){
+ desc.set.only = only;
+ }
+ modifyProps[name][prop].push(desc.set);
+ }
+
+ if(desc.initAttr){
+ initProp.content(name, prop);
+ }
+ });
+ initProp.flushTmpCache();
+
+ });
+ },
+ defineNodeNamesBooleanProperty: function(elementNames, prop, descs){
+ if(!descs){
+ descs = {};
+ }
+ if($.isFunction(descs)){
+ descs.set = descs;
+ }
+ webshims.defineNodeNamesProperty(elementNames, prop, {
+ attr: {
+ set: function(val){
+ if(descs.useContentAttribute){
+ webshims.contentAttr(this, prop, val);
+ } else {
+ this.setAttribute(prop, val);
+ }
+ if(descs.set){
+ descs.set.call(this, true);
+ }
+ },
+ get: function(){
+ var ret = (descs.useContentAttribute) ? webshims.contentAttr(this, prop) : this.getAttribute(prop);
+ return (ret == null) ? undefined : prop;
+ }
+ },
+ removeAttr: {
+ value: function(){
+ this.removeAttribute(prop);
+ if(descs.set){
+ descs.set.call(this, false);
+ }
+ }
+ },
+ reflect: true,
+ propType: 'boolean',
+ initAttr: descs.initAttr || false
+ });
+ },
+ contentAttr: function(elem, name, val){
+ if(!elem.nodeName){return;}
+ var attr;
+ if(val === undefined){
+ attr = (elem.attributes[name] || {});
+ val = attr.specified ? attr.value : null;
+ return (val == null) ? undefined : val;
+ }
+
+ if(typeof val == 'boolean'){
+ if(!val){
+ elem.removeAttribute(name);
+ } else {
+ elem.setAttribute(name, name);
+ }
+ } else {
+ elem.setAttribute(name, val);
+ }
+ },
+
+ activeLang: (function(){
+ var curLang = [];
+ var langDatas = [];
+ var loading = {};
+ var load = function(src, obj, loadingLang){
+ obj._isLoading = true;
+ if(loading[src]){
+ loading[src].push(obj);
+ } else {
+ loading[src] = [obj];
+ webshims.loader.loadScript(src, function(){
+ if(loadingLang == curLang.join()){
+ $.each(loading[src], function(i, obj){
+ select(obj);
+ });
+ }
+ delete loading[src];
+ });
+ }
+ };
+
+ var select = function(obj){
+ var oldLang = obj.__active;
+ var selectLang = function(i, lang){
+ obj._isLoading = false;
+ if(obj[lang] || obj.availableLangs.indexOf(lang) != -1){
+ if(obj[lang]){
+ obj.__active = obj[lang];
+ obj.__activeName = lang;
+ } else {
+ load(obj.langSrc+lang, obj, curLang.join());
+ }
+ return false;
+ }
+ };
+ $.each(curLang, selectLang);
+ if(!obj.__active){
+ obj.__active = obj[''];
+ obj.__activeName = '';
+ }
+ if(oldLang != obj.__active){
+ $(obj).trigger('change');
+ }
+ };
+ return function(lang){
+ var shortLang;
+ if(typeof lang == 'string'){
+ if(curLang[0] != lang){
+ curLang = [lang];
+ shortLang = curLang[0].split('-')[0];
+ if(shortLang && shortLang != lang){
+ curLang.push(shortLang);
+ }
+ langDatas.forEach(select);
+ }
+ } else if(typeof lang == 'object'){
+ if(!lang.__active){
+ langDatas.push(lang);
+ select(lang);
+ }
+ return lang.__active;
+ }
+ return curLang[0];
+ };
+ })()
+ });
+
+ $.each({
+ defineNodeNamesProperty: 'defineNodeNameProperty',
+ defineNodeNamesProperties: 'defineNodeNameProperties',
+ createElements: 'createElement'
+ }, function(name, baseMethod){
+ webshims[name] = function(names, a, b, c){
+ if(typeof names == 'string'){
+ names = names.split(listReg);
+ }
+ var retDesc = {};
+ names.forEach(function(nodeName){
+ retDesc[nodeName] = webshims[baseMethod](nodeName, a, b, c);
+ });
+ return retDesc;
+ };
+ });
+
+ webshims.isReady('webshimLocalization', true);
+
+//html5a11y + hidden attribute
+(function(){
+ if(('content' in document.createElement('template'))){return;}
+
+ $(function(){
+ var main = $('main').attr({role: 'main'});
+ if(main.length > 1){
+ webshims.error('only one main element allowed in document');
+ } else if(main.is('article *, section *')) {
+ webshims.error('main not allowed inside of article/section elements');
+ }
+ });
+
+ if(('hidden' in document.createElement('a'))){
+ return;
+ }
+
+ webshims.defineNodeNamesBooleanProperty(['*'], 'hidden');
+
+ var elemMappings = {
+ article: "article",
+ aside: "complementary",
+ section: "region",
+ nav: "navigation",
+ address: "contentinfo"
+ };
+ var addRole = function(elem, role){
+ var hasRole = elem.getAttribute('role');
+ if (!hasRole) {
+ elem.setAttribute('role', role);
+ }
+ };
+
+
+ $.webshims.addReady(function(context, contextElem){
+ $.each(elemMappings, function(name, role){
+ var elems = $(name, context).add(contextElem.filter(name));
+ for (var i = 0, len = elems.length; i < len; i++) {
+ addRole(elems[i], role);
+ }
+ });
+ if (context === document) {
+ var header = document.getElementsByTagName('header')[0];
+ var footers = document.getElementsByTagName('footer');
+ var footerLen = footers.length;
+
+ if (header && !$(header).closest('section, article')[0]) {
+ addRole(header, 'banner');
+ }
+ if (!footerLen) {
+ return;
+ }
+ var footer = footers[footerLen - 1];
+ if (!$(footer).closest('section, article')[0]) {
+ addRole(footer, 'contentinfo');
+ }
+ }
+ });
+
+})();
+});
+;(function($){
+ "use strict";
+
+ var isNumber = function(string){
+ return (typeof string == 'number' || (string && string == string * 1));
+ };
+ var retDefault = function(val, def){
+ if(!(typeof val == 'number' || (val && val == val * 1))){
+ return def;
+ }
+ return val * 1;
+ };
+ var createOpts = ['step', 'min', 'max', 'readonly', 'title', 'disabled', 'tabindex'];
+ var normalizeTouch = (function(){
+ var types = {
+ touchstart: 1,
+ touchend: 1,
+ touchmove: 1
+ };
+ var normalize = ['pageX', 'pageY'];
+ return function(e){
+ if(types[e.type] && e.originalEvent && e.originalEvent.touches && e.originalEvent.touches.length){
+ for(var i = 0; i < normalize.length; i++){
+ e[normalize[i]] = e.originalEvent.touches[0][normalize[i]];
+ }
+
+ }
+ return e;
+ };
+ })();
+ var rangeProto = {
+ _create: function(){
+ var i;
+
+ this.element.addClass(this.options.baseClass || 'ws-range ws-input').attr({role: 'slider'}).append('');
+ this.trail = $('.ws-range-track', this.element);
+ this.range = $('.ws-range-progress', this.element);
+ this.thumb = $('.ws-range-thumb', this.trail);
+ this.thumbValue = $('span[data-value]', this.thumb);
+
+ this.updateMetrics();
+
+ this.orig = this.options.orig;
+
+ for(i = 0; i < createOpts.length; i++){
+ this[createOpts[i]](this.options[createOpts[i]]);
+ }
+
+ this.value = this._value;
+ this.value(this.options.value);
+ this.initDataList();
+ this.element.data('rangeUi', this);
+ this.addBindings();
+ this._init = true;
+ },
+ value: $.noop,
+ _value: function(val, _noNormalize, animate){
+ var left, posDif;
+ var o = this.options;
+ var oVal = val;
+ var thumbStyle = {};
+ var rangeStyle = {};
+
+ if(!_noNormalize && parseFloat(val, 10) != val){
+ val = o.min + ((o.max - o.min) / 2);
+ }
+
+ if(!_noNormalize){
+ val = this.normalizeVal(val);
+ }
+ left = 100 * ((val - o.min) / (o.max - o.min));
+
+ if(this._init && val == o.value && oVal == val){return;}
+ o.value = val;
+
+ if($.fn.stop){
+ this.thumb.stop();
+ this.range.stop();
+ }
+
+ rangeStyle[this.dirs.width] = left+'%';
+
+ if(this.vertical){
+ left = Math.abs(left - 100);
+ }
+ thumbStyle[this.dirs.left] = left+'%';
+
+
+ if(!animate || !$.fn.animate){
+ this.thumb[0].style[this.dirs.left] = thumbStyle[this.dirs.left];
+ this.range[0].style[this.dirs.width] = rangeStyle[this.dirs.width];
+ } else {
+ if(typeof animate != 'object'){
+ animate = {};
+ } else {
+ animate = $.extend({}, animate);
+ }
+ if(!animate.duration){
+ posDif = Math.abs(left - parseInt(this.thumb[0].style[this.dirs.left] || 50, 10));
+ animate.duration = Math.max(Math.min(999, posDif * 5), 99);
+ }
+ this.thumb.animate(thumbStyle, animate);
+ this.range.animate(rangeStyle, animate);
+ }
+ if(this.orig && (oVal != val || (!this._init && this.orig.value != val)) ){
+ this.options._change(val);
+ }
+
+ this._setValueMarkup();
+ },
+ _setValueMarkup: function(){
+ var o = this.options;
+ var textValue = o.textValue ? o.textValue(this.options.value) : o.options[o.value] || o.value;
+
+ this.element[0].setAttribute('aria-valuenow', this.options.value);
+ this.element[0].setAttribute('aria-valuetext', textValue);
+
+ this.thumbValue[0].setAttribute('data-value', this.options.value);
+ this.thumbValue[0].setAttribute('data-valuetext', textValue);
+
+ if(o.selectedOption){
+ $(o.selectedOption).removeClass('ws-selected-option');
+ o.selectedOption = null;
+ }
+ if(o.value in o.options){
+ o.selectedOption = $('[data-value="'+o.value+'"].ws-range-ticks', this.trail).addClass('ws-selected-option');
+ }
+ },
+ initDataList: function(){
+ if(this.orig){
+ var listTimer;
+ var that = this;
+ var updateList = function(){
+ $(that.orig)
+ .jProp('list')
+ .off('updateDatalist', updateList)
+ .on('updateDatalist', updateList)
+ ;
+ clearTimeout(listTimer);
+ listTimer = setTimeout(function(){
+ if(that.list){
+ that.list();
+ }
+ }, 9);
+
+ };
+
+ $(this.orig).on('listdatalistchange', updateList);
+ this.list();
+ }
+ },
+ list: function(opts){
+ var o = this.options;
+ var min = o.min;
+ var max = o.max;
+ var trail = this.trail;
+ var that = this;
+
+ this.element.attr({'aria-valuetext': o.options[o.value] || o.value});
+ $('.ws-range-ticks', trail).remove();
+
+
+ $(this.orig).jProp('list').find('option:not([disabled])').each(function(){
+ o.options[$.prop(this, 'value')] = $.prop(this, 'label') || '';
+ });
+
+ $.each(o.options, function(val, label){
+ if(!isNumber(val) || val < min || val > max){return;}
+ var left = 100 * ((val - min) / (max - min));
+ var attr = 'data-value="'+val+'"';
+ if(label){
+ attr += ' data-label="'+label+'"';
+ if(o.showLabels){
+ attr += ' title="'+label+'"';
+ }
+ }
+ if(that.vertical){
+ left = Math.abs(left - 100);
+ }
+
+ that.posCenter(
+ $('').appendTo(trail)
+ );
+ });
+ if(o.value in o.options){
+ this._setValueMarkup();
+ }
+ },
+ readonly: function(val){
+ val = !!val;
+ this.options.readonly = val;
+ this.element.attr('aria-readonly', ''+val);
+ if(this._init){
+ this.updateMetrics();
+ }
+ },
+ disabled: function(val){
+ val = !!val;
+ this.options.disabled = val;
+ if(val){
+ this.element.attr({tabindex: -1, 'aria-disabled': 'true'});
+ } else {
+ this.element.attr({tabindex: this.options.tabindex, 'aria-disabled': 'false'});
+ }
+ if(this._init){
+ this.updateMetrics();
+ }
+ },
+ tabindex: function(val){
+ this.options.tabindex = val;
+ if(!this.options.disabled){
+ this.element.attr({tabindex: val});
+ }
+ },
+ title: function(val){
+ this.element.prop('title', val);
+ },
+ min: function(val){
+ this.options.min = retDefault(val, 0);
+ this.element.attr('aria-valuemin', this.options.min);
+ this.value(this.options.value, true);
+ },
+ max: function(val){
+ this.options.max = retDefault(val, 100);
+ this.element.attr('aria-valuemax', this.options.max);
+ this.value(this.options.value, true);
+ },
+ step: function(val){
+ var o = this.options;
+ var step = val == 'any' ? 'any' : retDefault(val, 1);
+
+ if(o.stepping){
+ webshims.error('stepping was removed. Use stepfactor instead.');
+ }
+
+ if(o.stepfactor && step != 'any'){
+ step *= o.stepfactor;
+ }
+
+ o.step = step;
+ this.value(this.options.value);
+ },
+
+ normalizeVal: function(val){
+ var valModStep, alignValue, step;
+ var o = this.options;
+
+ if(val <= o.min){
+ val = o.min;
+ } else if(val >= o.max) {
+ val = o.max;
+ } else if(o.step != 'any'){
+ step = o.step;
+ valModStep = (val - o.min) % step;
+ alignValue = val - valModStep;
+
+ if ( Math.abs(valModStep) * 2 >= step ) {
+ alignValue += ( valModStep > 0 ) ? step : ( -step );
+ }
+ val = alignValue.toFixed(5) * 1;
+ }
+ return val;
+ },
+ doStep: function(factor, animate){
+ var step = retDefault(this.options.step, 1);
+ if(this.options.step == 'any'){
+ step = Math.min(step, (this.options.max - this.options.min) / 10);
+ }
+ this.value( this.options.value + (step * factor), false, animate );
+
+ },
+
+ getStepedValueFromPos: function(pos){
+ var val, valModStep, alignValue, step;
+
+ if(pos <= 0){
+ val = this.options[this.dirs[this.isRtl ? 'max' : 'min']];
+ } else if(pos > 100) {
+ val = this.options[this.dirs[this.isRtl ? 'min' : 'max']];
+ } else {
+ if(this.vertical || this.isRtl){
+ pos = Math.abs(pos - 100);
+ }
+ val = ((this.options.max - this.options.min) * (pos / 100)) + this.options.min;
+ step = this.options.step;
+ if(step != 'any'){
+ valModStep = (val - this.options.min) % step;
+ alignValue = val - valModStep;
+
+ if ( Math.abs(valModStep) * 2 >= step ) {
+ alignValue += ( valModStep > 0 ) ? step : ( -step );
+ }
+ val = ((alignValue).toFixed(5)) * 1;
+
+ }
+ }
+
+ return val;
+ },
+ addRemoveClass: function(cName, add){
+ var isIn = this.element.prop('className').indexOf(cName) != -1;
+ var action;
+ if(!add && isIn){
+ action = 'removeClass';
+ this.element.removeClass(cName);
+ this.updateMetrics();
+ } else if(add && !isIn){
+ action = 'addClass';
+
+ }
+ if(action){
+ this.element[action](cName);
+ if(this._init){
+ this.updateMetrics();
+ }
+ }
+ },
+ addBindings: function(){
+ var leftOffset, widgetUnits, hasFocus, isActive;
+ var that = this;
+ var o = this.options;
+
+ var eventTimer = (function(){
+ var events = {};
+ return {
+ init: function(name, curVal, fn){
+ if(!events[name]){
+ events[name] = {fn: fn};
+ if(that.orig){
+ $(that.orig).on(name, function(){
+ events[name].val = $.prop(that.orig, 'value');
+ });
+ }
+
+ }
+ events[name].val = curVal;
+ },
+ call: function(name, val){
+ if(events[name].val != val){
+ clearTimeout(events[name].timer);
+ events[name].val = val;
+ events[name].timer = setTimeout(function(){
+ events[name].fn(val, that);
+ }, 0);
+ }
+ }
+ };
+ })();
+
+ var updateValue = function(val, animate){
+ if(val != o.value){
+ that.value(val, false, animate);
+ eventTimer.call('input', val);
+ }
+ };
+ var setValueFromPos = function(e, animate){
+ if(e.type == 'touchmove'){
+ e.preventDefault();
+ normalizeTouch(e);
+ }
+
+ updateValue(that.getStepedValueFromPos((e[that.dirs.mouse] - leftOffset) * widgetUnits), animate);
+
+ if(e && e.type == 'mousemove'){
+ e.preventDefault();
+ }
+ };
+ var remove = function(e){
+ if(e && (e.type == 'mouseup' || e.type == 'touchend')){
+ eventTimer.call('input', o.value);
+ eventTimer.call('change', o.value);
+ }
+ that.addRemoveClass('ws-active');
+ $(document).off('mousemove touchmove', setValueFromPos).off('mouseup touchend', remove);
+ $(window).off('blur', removeWin);
+ isActive = false;
+ };
+ var removeWin = function(e){
+ if(e.target == window){remove();}
+ };
+ var add = function(e){
+ if(isActive || (e.type == 'touchstart' && (!e.originalEvent || !e.originalEvent.touches || e.originalEvent.touches.length != 1))){
+ return;
+ }
+ e.preventDefault();
+
+ $(document).off('mousemove touchmove', setValueFromPos).off('mouseup touchend', remove);
+ $(window).off('blur', removeWin);
+ if(!o.readonly && !o.disabled){
+ eventTimer.init('input', o.value);
+ eventTimer.init('change', o.value);
+ normalizeTouch(e);
+ that.element.trigger('focus');
+ that.addRemoveClass('ws-active', true);
+ leftOffset = that.element.offset();
+ widgetUnits = that.element[that.dirs.innerWidth]();
+ if(!widgetUnits || !leftOffset){return;}
+ leftOffset = leftOffset[that.dirs.pos];
+ widgetUnits = 100 / widgetUnits;
+
+ if(e.target.className == 'ws-range-ticks'){
+ updateValue(e.target.getAttribute('data-value'), o.animate);
+ } else {
+ setValueFromPos(e, o.animate);
+ }
+ isActive = true;
+ $(document)
+ .on(e.type == 'touchstart' ?
+ {
+ touchend: remove,
+ touchmove: setValueFromPos
+ } :
+ {
+ mouseup: remove,
+ mousemove: setValueFromPos
+ }
+ )
+ ;
+ $(window).on('blur', removeWin);
+ e.stopPropagation();
+ }
+ };
+ var elementEvts = {
+ 'touchstart mousedown': add,
+ focus: function(e){
+ if(!o.disabled && !hasFocus){
+ if(!isActive){
+ eventTimer.init('input', o.value);
+ eventTimer.init('change', o.value);
+ }
+ that.addRemoveClass('ws-focus', true);
+ that.updateMetrics();
+ }
+ hasFocus = true;
+ },
+ blur: function(e){
+ that.element.removeClass('ws-focus ws-active');
+ that.updateMetrics();
+ hasFocus = false;
+ eventTimer.init('input', o.value);
+ eventTimer.call('change', o.value);
+ },
+ keyup: function(){
+ that.addRemoveClass('ws-active');
+ eventTimer.call('input', o.value);
+ eventTimer.call('change', o.value);
+ },
+
+ keydown: function(e){
+ var step = true;
+ var code = e.keyCode;
+ if(!o.readonly && !o.disabled){
+ if(that.isRtl){
+ if(code == 39){
+ code = 37;
+ } else if(code == 37){
+ code = 39;
+ }
+ }
+ if (code == 39 || code == 38) {
+ that.doStep(1);
+ } else if (code == 37 || code == 40) {
+ that.doStep(-1);
+ } else if (code == 33) {
+ that.doStep(10, o.animate);
+ } else if (code == 34) {
+ that.doStep(-10, o.animate);
+ } else if (code == 36) {
+ that.value(that.options.max, false, o.animate);
+ } else if (code == 35) {
+ that.value(that.options.min, false, o.animate);
+ } else {
+ step = false;
+ }
+ if (step) {
+ that.addRemoveClass('ws-active', true);
+ eventTimer.call('input', o.value);
+ e.preventDefault();
+ }
+ }
+ }
+ };
+
+ eventTimer.init('input', o.value, this.options.input);
+ eventTimer.init('change', o.value, this.options.change);
+
+ elementEvts[$.fn.mwheelIntent ? 'mwheelIntent' : 'mousewheel'] = function(e, delta){
+ if(delta && hasFocus && !o.readonly && !o.disabled){
+ that.doStep(delta);
+ e.preventDefault();
+ eventTimer.call('input', o.value);
+ }
+ };
+ this.element.on(elementEvts);
+ this.thumb.on({
+ mousedown: add
+ });
+
+ if(this.orig){
+ $(this.orig).jProp('form').on('reset', function(){
+ var val = $.prop(that.orig, 'value');
+ that.value(val);
+ setTimeout(function(){
+ var val2 = $.prop(that.orig, 'value');
+ if(val != val2){
+ that.value(val2);
+ }
+ }, 4);
+ });
+ }
+
+ if (window.webshims) {
+ webshims.ready('WINDOWLOAD', function(){
+ webshims.ready('dom-support', function(){
+ if ($.fn.onWSOff) {
+ var timer;
+ var update = function(){
+ that.updateMetrics();
+ };
+ that.element.onWSOff('updateshadowdom', function(){
+ clearTimeout(timer);
+ timer = setTimeout(update, 100);
+ });
+ }
+ });
+ if (!$.fn.onWSOff && webshims._polyfill) {
+ webshims._polyfill(['dom-support']);
+ }
+ });
+ }
+ },
+ posCenter: function(elem, outerWidth){
+ var temp, eS;
+
+ if(this.options.calcCenter && (!this._init || this.element[0].offsetWidth)){
+ if(!elem){
+ elem = this.thumb;
+ }
+ eS = elem[0].style;
+ if(!outerWidth){
+ outerWidth = elem[this.dirs.outerWidth]();
+ }
+ outerWidth = outerWidth / -2;
+ eS[this.dirs.marginLeft] = outerWidth +'px';
+
+ if(this.options.calcTrail && elem[0] == this.thumb[0]){
+ temp = this.element[this.dirs.innerHeight]();
+ eS[this.dirs.marginTop] = ((elem[this.dirs.outerHeight]() - temp) / -2) + 'px';
+ this.range[0].style[this.dirs.marginTop] = ((this.range[this.dirs.outerHeight]() - temp) / -2 ) +'px';
+
+ this.range[0].style[this.dirs.posLeft] = outerWidth +'px';
+
+ outerWidth *= -1;
+
+ this.range[0].style[this.dirs.paddingRight] = outerWidth +'px';
+ this.trail[0].style[this.dirs.left] = outerWidth +'px';
+ this.trail[0].style[this.dirs.right] = outerWidth +'px';
+
+
+ }
+ }
+ },
+ updateMetrics: function(){
+ var width = this.element.innerWidth();
+ this.vertical = (width && this.element.innerHeight() - width > 10);
+
+ this.dirs = this.vertical ?
+ {mouse: 'pageY', pos: 'top', posLeft: 'bottom', paddingRight: 'paddingTop', min: 'max', max: 'min', left: 'top', right: 'bottom', width: 'height', innerWidth: 'innerHeight', innerHeight: 'innerWidth', outerWidth: 'outerHeight', outerHeight: 'outerWidth', marginTop: 'marginLeft', marginLeft: 'marginTop'} :
+ {mouse: 'pageX', pos: 'left', posLeft: 'left', paddingRight: 'paddingRight', min: 'min', max: 'max', left: 'left', right: 'right', width: 'width', innerWidth: 'innerWidth', innerHeight: 'innerHeight', outerWidth: 'outerWidth', outerHeight: 'outerHeight', marginTop: 'marginTop', marginLeft: 'marginLeft'}
+ ;
+ if(!this.vertical && this.element.css('direction') == 'rtl'){
+ this.isRtl = true;
+ this.dirs.left = 'right';
+ this.dirs.right = 'left';
+ this.dirs.marginLeft = 'marginRight';
+ this.dirs.posLeft = 'right';
+ }
+ this.element
+ [this.vertical ? 'addClass' : 'removeClass']('vertical-range')
+ [this.isRtl ? 'addClass' : 'removeClass']('ws-is-rtl')
+ ;
+ this.updateMetrics = this.posCenter;
+ this.posCenter();
+ }
+ };
+
+ var oCreate = function (o) {
+ function F() {}
+ F.prototype = o;
+ return new F();
+ };
+
+ $.fn.rangeUI = function(opts){
+ opts = $.extend({
+ readonly: false,
+ disabled: false,
+ tabindex: 0,
+ min: 0,
+ step: 1,
+ max: 100,
+ value: 50,
+ input: $.noop,
+ change: $.noop,
+ _change: $.noop,
+ showLabels: true,
+ options: {},
+ calcCenter: true,
+ calcTrail: true
+ }, opts);
+ return this.each(function(){
+ var obj = $.extend(oCreate(rangeProto), {element: $(this)});
+ obj.options = opts;
+ obj._create.call(obj);
+ });
+ };
+ $.fn.rangeUI.normalizeTouch = normalizeTouch;
+ if(window.webshims && webshims.isReady){
+ webshims.isReady('range-ui', true);
+ }
+})(window.webshims ? webshims.$ : jQuery);
+;webshims.register('form-number-date-ui', function($, webshims, window, document, undefined, options){
+ "use strict";
+ var curCfg;
+ var formcfg = webshims.formcfg;
+ var hasFormValidation = webshims.support.formvalidation && !webshims.bugs.bustedValidity;
+ var monthDigits = ['01', '02', '03', '04', '05', '06', '07', '08', '09', '10', '11', '12'];
+ var stopPropagation = function(e){
+ e.stopImmediatePropagation();
+ };
+ var getMonthOptions = function(opts){
+ var selectName = 'monthSelect'+opts.monthNames;
+ if(!curCfg[selectName]){
+ var labels = curCfg.date[opts.monthNames] || monthDigits;
+ curCfg[selectName] = ('')+$.map(monthDigits, function(val, i){
+ return '';
+ }).join('');
+ }
+ return curCfg[selectName];
+ };
+ var daySelect = '';
+ var createFormat = function(name){
+ if(!curCfg.patterns[name+'Obj']){
+ var obj = {};
+ $.each(curCfg.patterns[name].split(curCfg[name+'Format']), function(i, name){
+ obj[name] = i;
+ });
+ curCfg.patterns[name+'Obj'] = obj;
+ }
+ };
+ var createYearSelect = function(obj, opts){
+ var options, nowY, max, min;
+ if(opts.yearSelect){
+ nowY = parseInt(opts.value.split('-')[0], 10);
+ max = opts.max.split('-');
+ min = opts.min.split('-');
+ options = webshims.picker.createYearSelect(nowY || parseInt(min[0], 10) || parseInt(max[0], 10) || nowYear, max, min);
+ options.unshift('');
+ $(obj.elements)
+ .filter('select.yy')
+ .html(options.join(''))
+ .each(function(){
+ if(!nowY){
+ $('option[selected]', this).removeAttr('selected');
+ $(this).val();
+ }
+ })
+ ;
+ }
+ };
+ var numericType = webshims.support.inputtypes.tel && navigator.userAgent.indexOf('Mobile') != -1 && !('inputMode' in document.createElement('input') && !('inputmode' in document.createElement('input'))) ?
+ 'tel' : 'text';
+ var splitInputs = {
+ date: {
+ _create: function(opts){
+ var obj = {
+ splits: []
+ };
+
+ if(opts.yearSelect){
+ obj.splits.push($('')[0]);
+ } else {
+ obj.splits.push($('')[0]);
+ }
+
+ if(opts.monthSelect){
+ obj.splits.push($('')[0]);
+ } else {
+ obj.splits.push($('')[0]);
+ }
+ if(opts.daySelect){
+ obj.splits.push($(daySelect)[0]);
+ } else {
+ obj.splits.push($('')[0]);
+ }
+
+ obj.elements = [obj.splits[0], $('')[0], obj.splits[1], $('')[0], obj.splits[2]];
+ createYearSelect(obj, opts);
+ return obj;
+ },
+ sort: function(element){
+ createFormat('d');
+ var i = 0;
+ var seperators = $('.ws-input-seperator', element).html(curCfg.dFormat);
+ var inputs = $('input, select', element);
+ $.each(curCfg.patterns.dObj, function(name, value){
+ var input = inputs.filter('.'+ name);
+ if(input[0]){
+
+ input.appendTo(element);
+ if(i < seperators.length){
+ seperators.eq(i).insertAfter(input);
+ }
+ i++;
+ }
+ });
+ }
+ },
+ month: {
+ _create: function(opts){
+
+ var obj = {
+ splits: []
+ };
+
+ if(opts.yearSelect){
+ obj.splits.push($('')[0]);
+ } else {
+ obj.splits.push($('')[0]);
+ }
+
+ if(opts.monthSelect){
+ obj.splits.push($('')[0]);
+ } else {
+ obj.splits.push($('')[0]);
+ if(opts.onlyMonthDigits){
+ $().attr({inputmode: 'numeric', size: 2, maxlength: 2});
+ try {
+ obj.splits[1].setAttribute('type', numericType);
+ } catch(e){}
+ }
+ }
+
+ obj.elements = [obj.splits[0], $('')[0], obj.splits[1]];
+ createYearSelect(obj, opts);
+ return obj;
+ },
+ sort: function(element){
+ var seperator = $('.ws-input-seperator', element).html(curCfg.dFormat);
+ var mm = $('input.mm, select.mm', element);
+ var action;
+ if(curCfg.date.showMonthAfterYear){
+ mm.appendTo(element);
+ action = 'insertBefore';
+ } else {
+ mm.prependTo(element);
+ action = 'insertAfter';
+ }
+ seperator[action](mm);
+ }
+ }
+ };
+
+ var nowDate = new Date(new Date().getTime() - (new Date().getTimezoneOffset() * 60 * 1000 ));
+ var nowYear = nowDate.getFullYear();
+ nowDate = new Date(nowDate.getFullYear(), nowDate.getMonth(), nowDate.getDate(), nowDate.getHours()).getTime();
+ var steps = {
+ number: {
+ step: 1
+ },
+// week: {
+// step: 1,
+// start: new Date(nowDate)
+// },
+ 'datetime-local': {
+ step: 60,
+ start: new Date(nowDate).getTime()
+ },
+ time: {
+ step: 60
+ },
+ month: {
+ step: 1,
+ start: new Date(nowDate)
+ },
+ date: {
+ step: 1,
+ start: new Date(nowDate)
+ }
+ };
+ var labelWidth = (function(){
+ var getId = function(){
+ return webshims.getID(this);
+ };
+ return function(element, labels, noFocus){
+ $(element).attr({'aria-labelledby': labels.map(getId).get().join(' ')});
+ if(!noFocus){
+ labels.on('click', function(e){
+ element.getShadowFocusElement().focus();
+ e.preventDefault();
+ return false;
+ });
+ }
+ };
+ })();
+ var addZero = function(val){
+ if(!val){return "";}
+ val = val+'';
+ return val.length == 1 ? '0'+val : val;
+ };
+
+ var loadPicker = function(type, name){
+ type = (type == 'color' ? 'color' : 'forms')+'-picker';
+ if(!loadPicker[name+'Loaded'+type]){
+ loadPicker[name+'Loaded'+type] = true;
+ webshims.ready(name, function(){
+ webshims.loader.loadList([type]);
+
+ });
+ }
+ return type;
+ };
+
+
+ options.addZero = addZero;
+ webshims.loader.addModule('forms-picker', {
+ noAutoCallback: true,
+ css: 'styles/forms-picker.css',
+ options: options
+ });
+ webshims.loader.addModule('color-picker', {
+ noAutoCallback: true,
+ css: 'jpicker/jpicker.css',
+ options: options,
+ d: ['forms-picker']
+ });
+
+ options.steps = steps;
+
+ (function(){
+
+ formcfg.de = $.extend(true, {
+ numberFormat: {
+ ",": ".",
+ ".": ","
+ },
+ timeSigns: ":. ",
+ numberSigns: ',',
+ dateSigns: '.',
+ dFormat: ".",
+ patterns: {
+ d: "dd.mm.yy"
+ },
+ month: {
+ currentText: 'Aktueller Monat'
+ },
+ time: {
+ currentText: 'Jetzt'
+ },
+ date: {
+ close: 'schließen',
+ clear: 'Löschen',
+ prevText: 'Zurück',
+ nextText: 'Vor',
+ currentText: 'Heute',
+ monthNames: ['Januar','Februar','März','April','Mai','Juni',
+ 'Juli','August','September','Oktober','November','Dezember'],
+ monthNamesShort: ['Jan','Feb','Mär','Apr','Mai','Jun',
+ 'Jul','Aug','Sep','Okt','Nov','Dez'],
+ dayNames: ['Sonntag','Montag','Dienstag','Mittwoch','Donnerstag','Freitag','Samstag'],
+ dayNamesShort: ['So','Mo','Di','Mi','Do','Fr','Sa'],
+ dayNamesMin: ['So','Mo','Di','Mi','Do','Fr','Sa'],
+ weekHeader: 'KW',
+ firstDay: 1,
+ isRTL: false,
+ showMonthAfterYear: false,
+ yearSuffix: ''
+ }
+ }, formcfg.de || {});
+
+ formcfg.en = $.extend(true, {
+ numberFormat: {
+ ".": ".",
+ ",": ","
+ },
+ numberSigns: '.',
+ dateSigns: '/',
+ timeSigns: ":. ",
+ dFormat: "/",
+ patterns: {
+ d: "mm/dd/yy"
+ },
+ meridian: ['AM', 'PM'],
+ month: {
+ currentText: 'This month'
+ },
+ time: {
+ "currentText": "Now"
+ },
+ date: {
+ "closeText": "Done",
+ clear: 'Clear',
+ "prevText": "Prev",
+ "nextText": "Next",
+ "currentText": "Today",
+ "monthNames": ["January","February","March","April","May","June","July","August","September","October","November","December"],
+ "monthNamesShort": ["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],
+ "dayNames": ["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],
+ "dayNamesShort": ["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],
+ "dayNamesMin": ["Su","Mo","Tu","We","Th","Fr","Sa"],
+ "weekHeader": "Wk",
+ "firstDay": 0,
+ "isRTL": false,
+ "showMonthAfterYear": false,
+ "yearSuffix": ""
+ }
+ }, formcfg.en || {});
+
+ if(!formcfg['en-US']){
+ formcfg['en-US'] = $.extend(true, {}, formcfg['en']);
+ }
+ if(!formcfg['en-GB']){
+ formcfg['en-GB'] = $.extend(true, {}, formcfg.en, {
+ date: {firstDay: 1},
+ patterns: {d: "dd/mm/yy"}
+ });
+ }
+ if(!formcfg['en-AU']){
+ formcfg['en-AU'] = $.extend(true, {}, formcfg['en-GB']);
+ }
+ if(!formcfg['']){
+ formcfg[''] = formcfg['en-US'];
+ }
+
+ curCfg = formcfg[''];
+
+ var processLangCFG = function(langCfg){
+ if(!langCfg.date.monthkeys){
+ var create = function(i, name){
+ var strNum;
+ var num = i + 1;
+ strNum = (num < 10) ? '0'+num : ''+num;
+ langCfg.date.monthkeys[num] = strNum;
+ langCfg.date.monthkeys[name] = strNum;
+ langCfg.date.monthkeys[name.toLowerCase()] = strNum;
+ };
+ langCfg.date.monthkeys = {};
+ langCfg.date.monthDigits = monthDigits;
+ langCfg.numberSigns += '-';
+ if(langCfg.meridian){
+ langCfg.timeSigns += langCfg.meridian[0] + langCfg.meridian[1] + langCfg.meridian[0].toLowerCase() + langCfg.meridian[1].toLowerCase();
+ }
+ $.each(langCfg.date.monthNames, create);
+ $.each(langCfg.date.monthNamesShort, create);
+ }
+ if(!langCfg.colorSigns){
+ langCfg.colorSigns = '#abcdefABCDEF';
+ }
+ if(!langCfg['datetime-localSigns']){
+ langCfg['datetime-localSigns'] = langCfg.dateSigns+langCfg.timeSigns;
+ }
+ if(!langCfg['datetime-local']){
+ langCfg['datetime-local'] = {};
+ }
+ if(!langCfg.time){
+ langCfg.time = {};
+ }
+ if(!langCfg['datetime-local'].currentText && langCfg.time.currentText){
+ langCfg['datetime-local'].currentText = langCfg.time.currentText;
+ }
+ };
+ var triggerLocaleChange = function(){
+ processLangCFG(curCfg);
+ $(document).triggerHandler('wslocalechange');
+ };
+
+ curCfg = webshims.activeLang(formcfg);
+
+ triggerLocaleChange();
+
+ $(formcfg).on('change', function(){
+ curCfg = formcfg.__active;
+ triggerLocaleChange();
+ });
+
+ })();
+
+
+
+ (function(){
+
+ var retDefault = function(val, def){
+ if(!(typeof val == 'number' || (val && val == val * 1))){
+ return def;
+ }
+ return val * 1;
+ };
+
+
+ var formatVal = {
+ number: function(val, o, noCorrect){
+ var parts, len, i, isNegative;
+ if(o && o.nogrouping){
+ return (val+'').replace(/\,/g, '').replace(/\./, curCfg.numberFormat['.']);
+ }
+
+ val += '';
+
+ if(val.charAt(0) == '-'){
+ isNegative = true;
+ val = val.replace('-', '');
+ }
+ parts = val.split('.');
+ len = parts[0].length;
+ i = len - 1;
+
+ val = "";
+ while(i >= 0) {
+ val = parts[0].charAt(i) + val;
+ if (i > 0 && (len - i) % 3 === 0) {
+ val = curCfg.numberFormat[','] + val;
+ }
+ --i;
+ }
+ if(parts[1] != null){
+ if(!noCorrect){
+ parts[1] = parts[1].replace(/\-/g, '0');
+ }
+ val += curCfg.numberFormat['.'] + parts[1];
+ }
+ if(isNegative){
+ val = '-'+val;
+ }
+ return val;
+ },
+ time: function(val){
+ var fVal;
+ if(val && curCfg.meridian){
+ val = val.split(':');
+ fVal = (val[0] * 1);
+ if(fVal && fVal >= 12){
+ val[0] = addZero(fVal - 12+'');
+ fVal = 1;
+
+ } else {
+ fVal = 0;
+ }
+ if(val[0] === '00'){
+ val[0] = '12';
+ }
+ val = $.trim(val.join(':')) + ' '+ curCfg.meridian[fVal];
+ }
+ return val;
+ },
+ 'datetime-local': function(val, o){
+ var fVal = $.trim(val || '').split('T');
+ if(fVal.length == 2){
+ val = this.date(fVal[0], o) +' '+this.time(fVal[1], o);
+ }
+ return val;
+ },
+// week: function(val){
+// return val;
+// },
+ //todo empty val for month/split
+ month: function(val, options){
+ var names;
+ var p = val.split('-');
+ if(p[0] && p[1]){
+
+ if(!options || !options.monthSelect){
+ names = curCfg.date[options.monthNames] || curCfg.date.monthNames;
+ p[1] = names[(p[1] * 1) - 1];
+ }
+
+ if(options && options.splitInput){
+ val = [p[0] || '', p[1] || ''];
+ } else if(p[1]){
+ val = curCfg.date.showMonthAfterYear ? p.join(' ') : p[1]+' '+p[0];
+ }
+ } else if(options && options.splitInput){
+ val = [p[0] || '', p[1] || ''];
+ }
+ return val;
+ },
+ date: function(val, opts){
+ var p = (val+'').split('-');
+ if(p[2] && p[1] && p[0]){
+ if(opts && opts.splitInput){
+ val = p;
+ } else {
+ val = curCfg.patterns.d.replace('yy', p[0] || '');
+ val = val.replace('mm', p[1] || '');
+ val = val.replace('dd', p[2] || '');
+ }
+ } else if(opts && opts.splitInput){
+ val = [p[0] || '', p[1] || '', p[2] || ''];
+ }
+
+ return val;
+ },
+ color: function(val, opts){
+ var ret = '#000000';
+ if(val){
+ val = val.toLowerCase();
+ if(val.length == 7 && createHelper('color').isValid(val)) {
+ ret = val;
+ }
+ }
+ return ret;
+ }
+ };
+
+ var parseVal = {
+ number: function(val){
+ return (val+'').split(curCfg.numberFormat[',']).join('').replace(curCfg.numberFormat['.'], '.');
+ },
+// week: function(val){
+// return val;
+// },
+ 'datetime-local': function(val, o){
+ var tmp;
+ var fVal = $.trim(val || '').split(/\s+/);
+ if(fVal.length == 2){
+ if(fVal[0].indexOf(':') != -1 && fVal[1].indexOf(':') == -1){
+ tmp = fVal[1];
+ fVal[1] = fVal[0];
+ fVal[0] = tmp;
+ }
+ val = this.date(fVal[0], o) +'T'+ this.time(fVal[1], o);
+ } else if (fVal.length == 3) {
+ val = this.date(fVal[0], o) +'T'+ this.time(fVal[1]+fVal[2], o);
+ }
+ return val;
+ },
+ time: function(val){
+ var fVal;
+ if(val && curCfg.meridian){
+ val = val.toUpperCase();
+ if(val.substr(0,2) === "12"){
+ val = "00" + val.substr(2);
+ }
+ if(val.indexOf(curCfg.meridian[1]) != -1){
+ val = val.split(':');
+ fVal = (val[0] * 1);
+ if(!isNaN(fVal)){
+ val[0] = fVal + 12;
+ }
+ val = val.join(':');
+ }
+ val = $.trim(val.replace(curCfg.meridian[0], '').replace(curCfg.meridian[1], ''));
+ }
+ return val;
+ },
+ month: function(val, opts, noCorrect){
+
+ var p = (!opts.splitInput) ? val.trim().split(/[\.\s-\/\\]+/) : val;
+
+ if(p.length == 2 && p[0] && p[1]){
+ p[0] = !noCorrect && curCfg.date.monthkeys[p[0]] || p[0];
+ p[1] = !noCorrect && curCfg.date.monthkeys[p[1]] || p[1];
+ if(p[1].length == 2 && p[0].length > 3){
+ val = p[0]+'-'+p[1];
+ } else if(p[0].length == 2 && p[1].length > 3){
+ val = p[1]+'-'+p[0];
+ } else {
+ val = '';
+ }
+ } else if(opts.splitInput) {
+ val = '';
+ }
+ return val;
+ },
+ date: function(val, opts, noCorrect){
+ createFormat('d');
+ var tmp, obj;
+ var ret = '';
+ if(opts.splitInput){
+ obj = {yy: 0, mm: 1, dd: 2};
+ } else {
+ obj = curCfg.patterns.dObj;
+ val = val.split(curCfg.dFormat);
+ }
+ if(val.length == 3 && val[0] && val[1] && val[2] && (!noCorrect || (val[obj.yy].length > 3 && val[obj.mm].length == 2 && val[obj.dd].length == 2))){
+ if(!opts.noDayMonthSwitch && val[obj.mm] > 12 && val[obj.dd] < 13){
+ tmp = val[obj.dd];
+ val[obj.dd] = val[obj.mm];
+ val[obj.mm] = tmp;
+ }
+ if(val[obj.yy].length < 4){
+ tmp = ((new Date()).getFullYear() +'').substr(0, 4 - val[obj.yy].length);
+ if(val[obj.yy] > 50){
+ tmp--;
+ }
+ val[obj.yy] = tmp + val[obj.yy];
+ }
+ ret = ([addZero(val[obj.yy]), addZero(val[obj.mm]), addZero(val[obj.dd])]).join('-');
+ }
+ return ret
+ ;
+ },
+ color: function(val, opts){
+ var ret = '#000000';
+ if(val){
+ val = val.toLowerCase();
+ if (val.indexOf('#') !== 0) {
+ val = '#' + val;
+ }
+ if(val.length == 4){
+ val = '#' + val.charAt(1) + val.charAt(1) + val.charAt(2) + val.charAt(2) + val.charAt(3) + val.charAt(3);
+ }
+ if(val.length == 7 && createHelper('color').isValid(val)) {
+ ret = val;
+ }
+ }
+ return ret;
+ }
+ };
+
+ var placeholderFormat = {
+ date: function(val, opts){
+ var hintValue = (val || '').split('-');
+ if(hintValue.length == 3){
+ hintValue = opts.splitInput ?
+ hintValue :
+ curCfg.patterns.d.replace('yy', hintValue[0]).replace('mm', hintValue[1]).replace('dd', hintValue[2]);
+ } else {
+ hintValue = opts.splitInput ?
+ [val, val, val] :
+ val;
+ }
+ return hintValue;
+ },
+ month: function(val, opts){
+ var hintValue = (val || '').split('-');
+
+ if(hintValue.length == 2){
+ hintValue = opts.splitInput ?
+ hintValue :
+ curCfg.date.showMonthAfterYear ?
+ hintValue[0] +' '+hintValue[1] :
+
+ hintValue[1] +' '+ hintValue[0];
+ } else {
+ hintValue = opts.splitInput ?
+ [val, val] :
+ val;
+ }
+ return hintValue;
+ }
+ };
+
+ var createHelper = (function(){
+ var types = {};
+ return function(type){
+ var input;
+ if(!types[type]){
+ input = $('');
+ types[type] = {
+ asNumber: function(val){
+ var type = (typeof val == 'object') ? 'valueAsDate' : 'value';
+ return input.prop(type, val).prop('valueAsNumber');
+ },
+ asValue: function(val){
+ var type = (typeof val == 'object') ? 'valueAsDate' : 'valueAsNumber';
+ return input.prop(type, val).prop('value');
+ },
+ asDate: function(val){
+ var type = (typeof val == 'number') ? 'valueAsNumber' : 'value';
+ return input.prop(type, val).prop('valueAsDate');
+ },
+ isValid: function(val, attrs){
+ if(attrs && (attrs.nodeName || attrs.jquery)){
+ attrs = {
+ min: $(attrs).prop('min') || '',
+ max: $(attrs).prop('max') || '',
+ step: $(attrs).prop('step') || 'any'
+ };
+ }
+ attrs = $.extend({step: 'any', min: '', max: ''}, attrs || {});
+ return input.attr(attrs).prop('value', val).is(':valid') && input.prop('value') == val;
+ }
+ };
+ }
+ return types[type];
+ };
+ })();
+
+ steps.range = steps.number;
+
+ var wsWidgetProto = {
+ _create: function(){
+ var i, that, timedMirror;
+ var o = this.options;
+ var createOpts = this.createOpts;
+
+ this.type = o.type;
+ this.orig = o.orig;
+
+ this.buttonWrapper = $('').insertAfter(this.element);
+ this.options.containerElements.push(this.buttonWrapper[0]);
+
+ o.mirrorValidity = o.mirrorValidity && this.orig && hasFormValidation;
+
+ if(o.splitInput && this._addSplitInputs){
+ if(o.monthSelect){
+ this.element.addClass('ws-month-select');
+ }
+ this._addSplitInputs();
+ } else {
+ this.inputElements = this.element;
+ }
+
+ if( steps[this.type] && typeof steps[this.type].start == 'object'){
+ steps[this.type].start = this.asNumber(steps[this.type].start);
+ }
+
+ for(i = 0; i < createOpts.length; i++){
+ if(o[createOpts[i]] != null){
+ this[createOpts[i]](o[createOpts[i]], o[createOpts[i]]);
+ }
+ }
+ if(this.type == 'color'){
+ this.inputElements.prop('maxLength', 7);
+ }
+ this.addBindings();
+ $(this.element).data('wsWidget'+o.type, this);
+
+
+ if(o.buttonOnly){
+ this.inputElements.prop({readOnly: true});
+ }
+
+ this._init = true;
+
+ if(o.mirrorValidity){
+ that = this;
+ timedMirror = function(){
+ clearTimeout(timedMirror._timerDealy);
+ timedMirror._timerDealy = setTimeout(timedMirror._wsexec, 9);
+ };
+ timedMirror._wsexec = function(){
+ clearTimeout(timedMirror._timerDealy);
+ that.mirrorValidity(true);
+ };
+
+ timedMirror();
+ $(this.orig).on('change input', function(e){
+ if(e.type == 'input'){
+ timedMirror();
+ } else {
+ timedMirror._wsexec();
+ }
+ });
+ }
+ },
+ mirrorValidity: function(_noTest){
+ //
+ if(this._init && this.options.mirrorValidity){
+ if(!_noTest){
+ $.prop(this.orig, 'validity');
+ }
+ var message = $(this.orig).getErrorMessage();
+ if(message !== this.lastErrorMessage){
+ this.inputElements.prop('setCustomValidity', function(i, val){
+ if(val._supvalue){
+ val._supvalue.call(this, message);
+ }
+ });
+ this.lastErrorMessage = message;
+ }
+ }
+ },
+ addBindings: function(){
+ var that = this;
+ var o = this.options;
+ var run = function(){
+ that._addBindings();
+ };
+ if(this._addBindings){
+ run();
+ } else {
+ webshims.ready('forms-picker', run);
+ loadPicker(this.type, 'WINDOWLOAD');
+ }
+
+ this.inputElements
+ .add(this.buttonWrapper)
+ .add(this.element)
+ .one('mousedown focusin', function(e){
+ loadPicker(that.type, 'DOM');
+ })
+ .on({
+ 'change input focus focusin blur focusout': function(e){
+ var oVal, nVal;
+ $(e.target).trigger('ws__'+e.type);
+ if(o.toFixed && o.type == 'number' && e.type == 'change'){
+ oVal = that.element.prop('value');
+ nVal = that.toFixed(oVal, true);
+ if(oVal != nVal){
+ that.element[0].value = nVal;
+ }
+ }
+ }
+ })
+
+ ;
+
+ if(this.type != 'color'){
+ (function(){
+ var localeChange, select, selectVal;
+ if(!o.splitInput){
+ localeChange = function(){
+
+ if(o.value){
+ that.value(o.value, true);
+ }
+
+ if(placeholderFormat[that.type] && o.placeholder){
+ that.placeholder(o.placeholder);
+ }
+ };
+ } else {
+ localeChange = function(){
+ that.reorderInputs();
+ if(o.monthSelect){
+ select = that.inputElements.filter('select.mm');
+ selectVal = select.prop('value');
+ select.html(getMonthOptions(o));
+ select.prop('value', selectVal);
+ }
+ };
+ that.reorderInputs();
+ }
+ $(that.orig).onWSOff('wslocalechange', localeChange);
+ })();
+ }
+ },
+ required: function(val, boolVal){
+ this.inputElements.attr({'aria-required': ''+boolVal});
+ this.mirrorValidity();
+ },
+ parseValue: function(noCorrect){
+ var value = this.inputElements.map(function(){
+ return $.prop(this, 'value');
+ }).get();
+ if(!this.options.splitInput){
+ value = value[0];
+ }
+ return parseVal[this.type](value, this.options, noCorrect);
+ },
+ formatValue: function(val, noSplit){
+ return formatVal[this.type](val, noSplit === false ? false : this.options);
+ },
+ createOpts: ['readonly', 'title', 'disabled', 'tabindex', 'placeholder', 'defaultValue', 'value', 'required'],
+ placeholder: function(val){
+ var options = this.options;
+ options.placeholder = val;
+ var placeholder = val;
+ if(placeholderFormat[this.type]){
+ placeholder = placeholderFormat[this.type](val, this.options);
+ }
+ if(options.splitInput && typeof placeholder == 'object'){
+ $.each(this.splits, function(i, elem){
+ if($.nodeName(elem, 'select')){
+ $(elem).children('option:first-child').text(placeholder[i]);
+ } else {
+ $.prop(elem, 'placeholder', placeholder[i]);
+ }
+ });
+ } else {
+ this.element.prop('placeholder', placeholder);
+ }
+ },
+ list: function(val){
+ if(this.type == 'number'){
+ this.element.attr('list', $.attr(this.orig, 'list'));
+ }
+ this.options.list = val;
+ this._propertyChange('list');
+ },
+ _propertyChange: $.noop,
+ tabindex: function(val){
+ this.options.tabindex = val;
+ this.inputElements.prop('tabindex', this.options.tabindex);
+ $('button', this.buttonWrapper).prop('tabindex', this.options.tabindex);
+ },
+ title: function(val){
+ if(!val && this.orig && $.attr(this.orig, 'title') == null){
+ val = null;
+ }
+ this.options.title = val;
+ if(val == null){
+ this.inputElements.removeAttr('title');
+ } else {
+ this.inputElements.prop('title', this.options.title);
+ }
+ }
+ };
+
+ ['defaultValue', 'value'].forEach(function(name){
+ wsWidgetProto[name] = function(val, force){
+ if(!this._init || force || val !== this.options[name]){
+ this.element.prop(name, this.formatValue(val));
+ this.options[name] = val;
+ this._propertyChange(name);
+ this.mirrorValidity();
+ }
+ };
+ });
+
+ ['readonly', 'disabled'].forEach(function(name){
+ var isDisabled = name == 'disabled';
+ wsWidgetProto[name] = function(val, boolVal){
+ var options = this.options;
+ if(options[name] != boolVal || !this._init){
+ options[name] = !!boolVal;
+
+ if(!isDisabled && options.buttonOnly){
+ this.inputElements.attr({'aria-readonly': options[name]});
+ } else {
+ this.inputElements.prop(name, options[name]);
+ }
+ this.buttonWrapper[options[name] ? 'addClass' : 'removeClass']('ws-'+name);
+ if(isDisabled){
+ $('button', this.buttonWrapper).prop('disabled', options[name]);
+ }
+ }
+ };
+ });
+
+ var spinBtnProto = $.extend({}, wsWidgetProto, {
+ _create: function(){
+ var o = this.options;
+ var helper = createHelper(o.type);
+
+ this.elemHelper = $('');
+ this.asNumber = helper.asNumber;
+ this.asValue = helper.asValue;
+ this.isValid = helper.isValid;
+ this.asDate = helper.asDate;
+
+
+ wsWidgetProto._create.apply(this, arguments);
+ this._init = false;
+
+ this.buttonWrapper.html('');
+
+ if(this.type == 'number'){
+ this.inputElements.attr('inputmode', 'numeric');
+ }
+
+ if((!o.max && typeof o.relMax == 'number') || (!o.min && typeof o.relMin == 'number')){
+ webshims.error('relMax/relMin are not supported anymore calculate at set it your own.');
+ }
+
+ if(this.options.relDefaultValue){
+ webshims.warn('relDefaultValue was removed use startValue instead!');
+ }
+
+ this._init = true;
+ },
+ createOpts: ['step', 'min', 'max', 'readonly', 'title', 'disabled', 'tabindex', 'placeholder', 'defaultValue', 'value', 'required'],
+ _addSplitInputs: function(){
+ if(!this.inputElements){
+ var create = splitInputs[this.type]._create(this.options);
+ this.splits = create.splits;
+ this.inputElements = $(create.elements).prependTo(this.element).filter('input, select');
+ }
+ },
+ addZero: addZero,
+ _setStartInRange: function(){
+ var start = this.options.startValue && this.asNumber( this.options.startValue ) || steps[this.type].start || 0;
+ if(!isNaN(this.minAsNumber) && start < this.minAsNumber){
+ start = this.minAsNumber;
+ } else if(!isNaN(this.maxAsNumber) && start > this.maxAsNumber){
+ start = this.maxAsNumber;
+ }
+ try {
+ this.elemHelper.prop('valueAsNumber', start);
+ } catch(e){
+ webshims.warn('valueAsNumber set: '+e);
+ }
+ this.options.defValue = this.elemHelper.prop('value');
+ },
+ reorderInputs: function(){
+ if(splitInputs[this.type]){
+ var element = this.element.attr('dir', curCfg.date.isRTL ? 'rtl' : 'ltr');
+ splitInputs[this.type].sort(element, this.options);
+ setTimeout(function(){
+ var data = webshims.data(element);
+ if(data && data.shadowData){
+ data.shadowData.shadowFocusElement = element.find('input, select')[0] || element[0];
+ }
+ }, 9);
+ }
+ },
+ step: function(val){
+ var defStep = steps[this.type];
+ this.options.step = val;
+ this.elemHelper.prop('step', retDefault(val, defStep.step));
+ this.mirrorValidity();
+ },
+ _beforeValue: function(val){
+ this.valueAsNumber = this.asNumber(val);
+ this.options.value = val;
+
+ if(isNaN(this.valueAsNumber) || (!isNaN(this.minAsNumber) && this.valueAsNumber < this.minAsNumber) || (!isNaN(this.maxAsNumber) && this.valueAsNumber > this.maxAsNumber)){
+ this._setStartInRange();
+ } else {
+ this.elemHelper.prop('value', val);
+ this.options.defValue = "";
+ }
+ },
+ toFixed: function(val, force){
+ var o = this.options;
+ if(o.toFixed && o.type == 'number' && val && !isNaN(this.valueAsNumber) && (force || !this.element.is(':focus')) && (!o.fixOnlyFloat || (this.valueAsNumber % 1))){
+ val = formatVal[this.type](this.valueAsNumber.toFixed(o.toFixed), this.options);
+ }
+ return val;
+ }
+ });
+
+ ['defaultValue', 'value'].forEach(function(name){
+ var isValue = name == 'value';
+ spinBtnProto[name] = function(val, force, isLive){
+ var selectionEnd;
+ if(!this._init || force || this.options[name] !== val){
+ if(isValue){
+ this._beforeValue(val);
+ } else {
+ this.elemHelper.prop(name, val);
+ }
+
+ val = formatVal[this.type](val, this.options);
+ if(this.options.splitInput){
+ $.each(this.splits, function(i, elem){
+ var setOption;
+ if(!(name in elem) && !isValue && $.nodeName(elem, 'select')){
+ $('option[value="'+ val[i] +'"]', elem).prop('defaultSelected', true);
+ } else {
+ $.prop(elem, name, val[i]);
+ }
+ });
+ } else {
+ val = this.toFixed(val);
+ if(isLive && this._getSelectionEnd){
+ selectionEnd = this._getSelectionEnd(val);
+ }
+ this.element.prop(name, val);
+ if(selectionEnd != null){
+ this.element.prop('selectionEnd', selectionEnd);
+ }
+ }
+ this._propertyChange(name);
+ this.mirrorValidity();
+ }
+ };
+ });
+
+ $.each({min: 1, max: -1}, function(name, factor){
+ var numName = name +'AsNumber';
+ spinBtnProto[name] = function(val){
+ this.elemHelper.prop(name, val);
+ this[numName] = this.asNumber(val);
+
+ if(this.valueAsNumber != null && (isNaN(this.valueAsNumber) || (!isNaN(this[numName]) && (this.valueAsNumber * factor) < (this[numName] * factor)))){
+ this._setStartInRange();
+ }
+ this.options[name] = val;
+ if(this._init){
+ createYearSelect({elements: this.inputElements}, this.options);
+ }
+ this._propertyChange(name);
+ this.mirrorValidity();
+ };
+ });
+
+ $.fn.wsBaseWidget = function(opts){
+ opts = $.extend({}, opts);
+ return this.each(function(){
+ webshims.objectCreate(wsWidgetProto, {
+ element: {
+ value: $(this)
+ }
+ }, opts);
+ });
+ };
+
+ $.fn.wsBaseWidget.wsProto = wsWidgetProto;
+
+ $.fn.spinbtnUI = function(opts){
+ opts = $.extend({
+ monthNames: 'monthNamesShort'
+ }, opts);
+ return this.each(function(){
+ webshims.objectCreate(spinBtnProto, {
+ element: {
+ value: $(this)
+ }
+ }, opts);
+ });
+ };
+
+ $.fn.spinbtnUI.wsProto = spinBtnProto;
+
+ webshims._format = formatVal;
+
+ })();
+
+
+
+ if(!$.fn.wsTouchClick){
+
+ $.fn.wsTouchClick = (function(){
+ var supportsTouchaction = ('touchAction' in document.documentElement.style);
+ var addTouch = !supportsTouchaction && ('ontouchstart' in window) && document.addEventListener;
+ return function(target, handler){
+ var touchData, touchEnd, touchStart, stopClick, allowClick;
+ var runHandler = function(){
+ if(!stopClick){
+ return handler.apply(this, arguments);
+ }
+ };
+ if(addTouch){
+ allowClick = function(){
+ stopClick = false;
+ };
+ touchEnd = function(e){
+ var ret, touch;
+ e = e.originalEvent || {};
+ $(this).off('touchend touchcancel', touchEnd);
+ var changedTouches = e.changedTouches || e.touches;
+ if(e.type == 'touchcancel' || !touchData || !changedTouches || changedTouches.length != 1){
+ return;
+ }
+
+ touch = changedTouches[0];
+ if(Math.abs(touchData.x - touch.pageX) > 40 || Math.abs(touchData.y - touch.pageY) > 40 || Date.now() - touchData.now > 300){
+ return;
+ }
+
+ e.preventDefault();
+ stopClick = true;
+ setTimeout(allowClick, 400);
+
+ ret = handler.apply(this, arguments);
+
+ return ret;
+ };
+
+ touchStart = function(e){
+ var touch, elemTarget;
+ if((!e || e.touches.length != 1)){
+ return;
+ }
+ touch = e.touches[0];
+ elemTarget = target ? $(touch.target).closest(target) : $(this);
+ if(!elemTarget.length){
+ return;
+ }
+ touchData = {
+ x: touch.pageX,
+ y: touch.pageY,
+ now: Date.now()
+ };
+ elemTarget.on('touchend touchcancel', touchEnd);
+ };
+
+ this.each(function(){
+ this.addEventListener('touchstart', touchStart, true);
+ });
+ } else if(supportsTouchaction){
+ this.css('touch-action', 'manipulation');
+ }
+
+ if($.isFunction(target)){
+ handler = target;
+ target = false;
+ this.on('click', runHandler);
+ } else {
+ this.on('click', target, runHandler);
+ }
+ return this;
+ };
+ })();
+ }
+
+ (function(){
+ var picker = {};
+ var assumeVirtualKeyBoard = (window.Modernizr && (Modernizr.touchevents || Modernizr.touch)) || (/android|iphone|ipad|ipod|blackberry|iemobile/i.test(navigator.userAgent.toLowerCase()));
+ webshims.inlinePopover = {
+ _create: function(){
+ this.element = $('').data('wspopover', this);
+ this.contentElement = $('.ws-po-box', this.element);
+ this.element.insertAfter(this.options.prepareFor);
+ },
+ show: $.noop,
+ hide: $.noop,
+ preventBlur: $.noop,
+ isVisible: true
+ };
+
+ picker.isInRange = function(value, max, min){
+ return !((min[0] && min[0] > value[0]) || (max[0] && max[0] < value[0]));
+ };
+
+
+ picker.createYearSelect = function(value, max, min, valueAdd, stepper){
+ if(!stepper){
+ stepper = {start: value, step: 1, label: value};
+ }
+ var temp;
+ var goUp = true;
+ var goDown = true;
+ var options = [''];
+ var i = 0;
+ var createOption = function(value, add){
+ var value2, label;
+ if(stepper.step > 1){
+ value2 = value + stepper.step - 1;
+ label = value+' – '+value2;
+ } else {
+ label = value;
+ }
+
+ if(picker.isInRange([value], max, min) || (value2 && picker.isInRange([value2], max, min))){
+ options[add]('');
+ return true;
+ }
+ };
+ if(!valueAdd){
+ valueAdd = '';
+ }
+ while(i < 18 && (goUp || goDown)){
+ i++;
+ if(goUp){
+ temp = stepper.start - (i * stepper.step);
+ goUp = createOption(temp, 'unshift');
+ }
+ if(goDown){
+ temp = stepper.start + (i * stepper.step);
+ goDown = createOption(temp, 'push');
+ }
+
+ }
+
+ return options;
+ };
+
+ picker._genericSetFocus = function(element, _noFocus){
+ element = $(element || this.activeButton);
+
+ if(!this.popover.openedByFocus && !_noFocus){
+ var that = this;
+ var setFocus = function(noTrigger){
+ clearTimeout(that.timer);
+ that.timer = setTimeout(function(){
+ if(element[0]){
+ element.trigger('focus');
+ if(noTrigger !== true && !element.is(':focus')){
+ setFocus(true);
+ }
+ }
+ }, that.popover.isVisible ? 0 : 360);
+ };
+ this.popover.activateElement(element);
+ setFocus();
+ }
+ };
+
+ picker._actions = {
+ changeInput: function(val, popover, data){
+ if(!data.options.noChangeDismiss){
+ picker._actions.cancel(val, popover, data);
+ }
+ data.setChange(val);
+ },
+ cancel: function(val, popover, data){
+ if(!data.options.inlinePicker){
+ popover.stopOpen = true;
+ if(!popover.openedByFocus && assumeVirtualKeyBoard){
+ $('button', data.buttonWrapper).trigger('focus');
+ } else {
+ data.element.getShadowFocusElement().trigger('focus');
+ }
+ setTimeout(function(){
+ popover.stopOpen = false;
+ }, 9);
+ popover.hide();
+ }
+ }
+ };
+
+
+ picker.commonInit = function(data, popover){
+ if(data._commonInit){return;}
+ data._commonInit = true;
+ var tabbable;
+
+ popover.isDirty = true;
+
+ popover.element.on('updatepickercontent pickerchange', function(){
+ tabbable = false;
+ });
+
+ if(!data.options.inlinePicker){
+ popover.contentElement.on({
+ keydown: function(e){
+ if(e.keyCode == 9){
+ if(!tabbable){
+ tabbable = $('input:not(:disabled), [tabindex="0"]:not(:disabled)', this).filter(':visible');
+ }
+ var index = tabbable.index(e.target);
+ if(e.shiftKey && index <= 0){
+ tabbable.last().focus();
+ return false;
+ }
+ if(!e.shiftKey && index >= tabbable.length - 1){
+ tabbable.first().focus();
+ return false;
+ }
+ } else if(e.keyCode == 27){
+ data.element.getShadowFocusElement().focus();
+ popover.hide();
+ return false;
+ }
+ }
+ });
+ }
+
+ data._propertyChange = (function(){
+ var timer;
+ var update = function(){
+ if(popover.isVisible){
+ popover.element.triggerHandler('updatepickercontent');
+ }
+ };
+ return function(prop){
+ if(prop == 'value' && (!data.options.inlinePicker || data._handledValue )){return;}
+ popover.isDirty = true;
+
+ if(popover.isVisible){
+ clearTimeout(timer);
+ timer = setTimeout(update, 9);
+ }
+ };
+ })();
+
+ popover.activeElement = $([]);
+
+ popover.activateElement = function(element){
+ element = $(element);
+ if(element[0] != popover.activeElement[0]){
+ popover.activeElement.removeClass('ws-focus');
+ element.addClass('ws-focus');
+ }
+ popover.activeElement = element;
+ };
+ popover.element.on({
+ wspopoverbeforeshow: function(){
+ data.element.triggerHandler('wsupdatevalue');
+ popover.element.triggerHandler('updatepickercontent');
+ }
+ });
+
+
+ $(data.orig).on('remove', function(e){
+ if(!e.originalEvent){
+ $(document).off('wslocalechange', data._propertyChange);
+ }
+ });
+ };
+
+
+ picker._common = function(data){
+ if(data.options.nopicker){return;}
+ var options = data.options;
+ var popover = webshims.objectCreate(options.inlinePicker ? webshims.inlinePopover : webshims.wsPopover, {}, $.extend(options.popover || {}, {prepareFor: options.inlinePicker ? data.buttonWrapper : data.element}));
+ var opener = $('').appendTo(data.buttonWrapper);
+
+ var showPickerContent = function(){
+ (picker[data.type].showPickerContent || picker.showPickerContent)(data, popover);
+ };
+ var show = function(){
+ var type = loadPicker(data.type, 'DOM');
+ if(!options.disabled && !options.readonly && (options.inlinePicker || !popover.isVisible)){
+ webshims.ready(type, showPickerContent);
+ popover.show(data.element);
+ }
+ };
+ var open = function(){
+ if((options.inlinePicker || popover.isVisible) && popover.activeElement){
+ popover.openedByFocus = false;
+ popover.activeElement.focus();
+ }
+ show();
+ };
+ var toogle = function(){
+ if(popover.openedByFocus || !popover.isVisible){
+ open();
+ } else {
+ popover.hide();
+ }
+ }
+
+
+ options.containerElements.push(popover.element[0]);
+
+ popover.element
+ .addClass(data.type+'-popover input-picker')
+ .attr({role: 'application'})
+ .on({
+ wspopoverhide: function(){
+ popover.openedByFocus = false;
+ },
+ focusin: function(e){
+ if(popover.activateElement){
+ popover.openedByFocus = false;
+ popover.activateElement(e.target);
+ }
+ },
+ focusout: function(){
+ if(popover.activeElement){
+ popover.activeElement.removeClass('ws-focus');
+ }
+ if(options.inlinePicker){
+ popover.openedByFocus = true;
+ }
+ }
+ })
+ ;
+
+ labelWidth(popover.element.children('div.ws-po-outerbox').attr({role: 'group'}), options.labels, true);
+ labelWidth(opener, options.labels, true);
+
+ if(options.tabindex != null){
+ opener.attr({tabindex: options.tabindex});
+ }
+
+ if(options.disabled){
+ opener.prop({disabled: true});
+ }
+
+
+ opener.wsTouchClick(toogle);
+
+ if(options.inlinePicker){
+ popover.openedByFocus = true;
+ } else {
+ opener
+ .on({
+ mousedown: function(){
+ stopPropagation.apply(this, arguments);
+ popover.preventBlur();
+ },
+ keydown: function(e){
+ if(e.keyCode == 40 && e.altKey){
+ open();
+ }
+ },
+ 'focus mousedown': (function(){
+ var allowClose = true;
+ var reset = function(){
+ allowClose = true;
+ };
+ return function(e){
+ if(e.type == 'mousedown'){
+ allowClose = false;
+ setTimeout(reset);
+ }
+ if(e.type == 'focus' && allowClose && options.openOnFocus && popover.openedByFocus && (popover.options.appendTo == 'auto' || popover.options.appendTo == 'element')){
+ popover.hide();
+ } else {
+ popover.preventBlur();
+ }
+ };
+ })()
+ })
+ ;
+
+ (function(){
+ var mouseFocus = false;
+ var resetMouseFocus = function(){
+ mouseFocus = false;
+ };
+ data.inputElements.on({
+ keydown: function(e){
+ if(e.keyCode == 40 && e.altKey && !$.nodeName(e.target, 'select')){
+ open();
+ }
+ },
+ focus: function(e){
+ if(!popover.stopOpen && (options.buttonOnly || options.openOnFocus || (mouseFocus && options.openOnMouseFocus)) && !$.nodeName(e.target, 'select')){
+ popover.openedByFocus = options.buttonOnly ? false : !options.noInput;
+ show();
+ } else {
+ popover.preventBlur();
+ }
+ },
+ mousedown: function(e){
+ mouseFocus = true;
+ setTimeout(resetMouseFocus, 9);
+ if(options.buttonOnly && popover.isVisible && popover.activeElement){
+ popover.openedByFocus = false;
+ setTimeout(function(){
+ popover.openedByFocus = false;
+ popover.activeElement.focus();
+ }, 4);
+ }
+ if(data.element.is(':focus') && !$.nodeName(e.target, 'select')){
+ popover.openedByFocus = options.buttonOnly ? false : !options.noInput;
+ show();
+ }
+ popover.preventBlur();
+ }
+ });
+ })();
+ }
+
+ data.popover = popover;
+ data.opener = opener;
+ $(data.orig).on('remove', function(e){
+ if(!e.originalEvent){
+ setTimeout(function(){
+ opener.remove();
+ popover.element.remove();
+ }, 4);
+ }
+ });
+ if(options.inlinePicker){
+ show();
+ }
+ };
+
+ picker.month = picker._common;
+ picker.date = picker._common;
+ picker.time = picker._common;
+ picker['datetime-local'] = picker._common;
+// picker.week = picker._common;
+ picker.color = function(data){
+ var ret = picker._common.apply(this, arguments);
+ var alpha = $(data.orig).data('alphacontrol');
+ var colorIndicator = data.opener
+ .prepend('')
+ .find('.ws-color-indicator')
+ ;
+ var showColor = function(){
+ colorIndicator.css({backgroundColor: $.prop(this, 'value') || '#000000'});
+ };
+ var showOpacity = (function(){
+ var timer;
+ var show = function(){
+ try {
+ var value = data.alpha.prop('valueAsNumber') / (data.alpha.prop('max') || 1);
+ if(!isNaN(value)){
+ colorIndicator.css({opacity: value});
+ }
+ } catch(er){}
+
+ };
+ return function(e){
+ clearTimeout(timer);
+ timer = setTimeout(show, !e || e.type == 'change' ? 4: 40);
+ };
+ })();
+ data.alpha = (alpha) ? $('#'+alpha) : $([]);
+
+ $(data.orig).on('wsupdatevalue change', showColor).each(showColor);
+ data.alpha.on('wsupdatevalue change input', showOpacity).each(showOpacity);
+ return ret;
+ };
+
+ webshims.picker = picker;
+ })();
+
+ (function(){
+
+ var stopCircular, isCheckValidity;
+
+ var supportInputTypes = webshims.support.inputtypes;
+ var inputTypes = {
+
+ };
+ var boolAttrs = {disabled: 1, required: 1, readonly: 1};
+ var copyProps = [
+ 'disabled',
+ 'readonly',
+ 'value',
+ 'defaultValue',
+ 'min',
+ 'max',
+ 'step',
+ 'title',
+ 'required',
+ 'placeholder'
+ ];
+
+ //
+ var copyAttrs = ['data-placeholder', 'tabindex'];
+
+ $.each(copyProps.concat(copyAttrs), function(i, name){
+ var fnName = name.replace(/^data\-/, '');
+ webshims.onNodeNamesPropertyModify('input', name, function(val, boolVal){
+ if(!stopCircular){
+ var shadowData = webshims.data(this, 'shadowData');
+ if(shadowData && shadowData.data && shadowData.nativeElement === this && shadowData.data[fnName]){
+ if(boolAttrs[fnName]){
+ shadowData.data[fnName](val, boolVal);
+ } else {
+ shadowData.data[fnName](val);
+ }
+ }
+ }
+ });
+ });
+
+ if(options.replaceUI && 'valueAsNumber' in document.createElement('input')){
+ var reflectFn = function(){
+ if(webshims.data(this, 'hasShadow')){
+ $.prop(this, 'value', $.prop(this, 'value'));
+ }
+ };
+
+ webshims.onNodeNamesPropertyModify('input', 'valueAsNumber', reflectFn);
+ webshims.onNodeNamesPropertyModify('input', 'valueAsDate', reflectFn);
+ $.each({stepUp: 1, stepDown: -1}, function(name, stepFactor){
+ var stepDescriptor = webshims.defineNodeNameProperty('input', name, {
+ prop: {
+ value: function(){
+ var ret;
+ if(stepDescriptor.prop && stepDescriptor.prop._supvalue){
+ ret = stepDescriptor.prop._supvalue.apply(this, arguments);
+ reflectFn.apply(this, arguments);
+ }
+ return ret;
+ }
+ }
+ });
+ });
+ }
+
+ var extendType = (function(){
+ return function(name, data){
+ inputTypes[name] = data;
+ data.attrs = $.merge([], copyAttrs, data.attrs);
+ data.props = $.merge([], copyProps, data.props);
+ };
+ })();
+
+ var isVisible = function(){
+ return $.css(this, 'display') != 'none';
+ };
+ var sizeInput = function(data){
+ var init, parent, lastWidth, left, right, isRtl, hasButtons;
+ var oriStyleO = data.orig.style;
+ var styleO = data.element[0].style;
+ if($.support.boxSizing == null){
+ $(function(){
+ parent = data.orig.parentNode;
+ });
+ } else {
+ parent = data.orig.parentNode;
+ }
+ var updateStyles = function(){
+ var curWidth, marginR, marginL, assignWidth;
+ var correctWidth = 0.8;
+
+ if(parent){
+ curWidth = parent.offsetWidth;
+ }
+
+ if(!init || (curWidth && curWidth != lastWidth)){
+ lastWidth = curWidth;
+ oriStyleO.display = '';
+ styleO.display = 'none';
+
+ if(!init){
+ hasButtons = data.buttonWrapper && data.buttonWrapper.filter(isVisible).length;
+ isRtl = hasButtons && data.buttonWrapper.css('direction') == 'rtl';
+ if(isRtl){
+ left = 'Right';
+ right = 'Left';
+ } else {
+ left = 'Left';
+ right = 'Right';
+ }
+ if(hasButtons){
+ data.buttonWrapper[isRtl ? 'addClass' : 'removeClass']('ws-is-rtl');
+ }
+ }
+
+ marginR = $.css( data.orig, 'margin'+right);
+
+ styleO['margin'+left] = $.css( data.orig, 'margin'+left);
+ styleO['margin'+right] = hasButtons ? '0px' : marginR;
+
+
+ if(hasButtons){
+
+ marginL = (parseInt(data.buttonWrapper.css('margin'+left), 10) || 0);
+ styleO['padding'+right] = '';
+
+ if(marginL < 0){
+ marginR = (parseInt(marginR, 10) || 0) + ((data.buttonWrapper.outerWidth() + marginL) * -1);
+ data.buttonWrapper[0].style['margin'+right] = marginR+'px';
+
+ styleO['padding'+right] = ((parseInt( data.element.css('padding'+right), 10) || 0) + data.buttonWrapper.outerWidth()) +'px';
+
+ } else {
+ data.buttonWrapper[0].style['margin'+right] = marginR;
+ correctWidth = data.buttonWrapper.outerWidth(true) + correctWidth;
+ }
+ }
+
+ assignWidth = $(data.orig).outerWidth() - correctWidth;
+
+ styleO.display = '';
+ data.element.outerWidth(assignWidth);
+ oriStyleO.display = 'none';
+ init = true;
+ }
+
+ };
+ oriStyleO.webkitAppearance = 'none';
+ data.element.onWSOff('updateshadowdom', updateStyles, true);
+ };
+
+
+ var implementType = function(){
+
+ var type = $.prop(this, 'type');
+ var i, opts, data, optsName, labels, cNames, hasInitialFocus;
+
+ if(inputTypes[type] && webshims.implement(this, 'inputwidgets') && (!supportInputTypes[type] || !$(this).hasClass('ws-noreplace'))){
+ data = {};
+ optsName = type;
+ hasInitialFocus = $(this).is(':focus');
+ labels = $(this).jProp('labels');
+
+ opts = $.extend(webshims.getOptions(this, type, [options.widgets, options[type], $($.prop(this, 'form')).data(type)]), {
+ orig: this,
+ type: type,
+ labels: labels,
+ options: {},
+ input: function(val){
+ opts._change(val, 'input');
+ },
+ change: function(val){
+ opts._change(val, 'change');
+ },
+ _change: function(val, trigger){
+ stopCircular = true;
+ $.prop(opts.orig, 'value', val);
+ stopCircular = false;
+ if(trigger){
+ $(opts.orig).trigger(trigger);
+ }
+ },
+ containerElements: []
+ });
+
+ for(i = 0; i < copyProps.length; i++){
+ opts[copyProps[i]] = $.prop(this, copyProps[i]);
+ }
+
+ for(i = 0; i < copyAttrs.length; i++){
+ optsName = copyAttrs[i].replace(/^data\-/, '');
+ if(optsName == 'placeholder' || !opts[optsName]){
+ opts[optsName] = $.attr(this, copyAttrs[i]) || opts[optsName];
+ }
+ }
+
+ if(opts.formatMonthNames){
+ webshims.error('formatMonthNames was renamded to monthNames');
+ }
+ if(opts.onlyMonthDigits){
+ opts.monthNames = 'monthDigits';
+ }
+ data.shim = inputTypes[type]._create(opts);
+
+ webshims.addShadowDom(this, data.shim.element, {
+ data: data.shim || {}
+ });
+
+ data.shim.options.containerElements.push(data.shim.element[0]);
+ cNames = $.prop(this, 'className');
+ if(opts.classes){
+ cNames += ' '+opts.classes;
+ $(this).addClass(opts.classes);
+ }
+
+ if(opts.splitInput || type == 'range'){
+ cNames = cNames.replace('form-control', '');
+ }
+
+ data.shim.element.on('change input', stopPropagation).addClass(cNames+' '+webshims.shadowClass);
+
+ if(data.shim.buttonWrapper){
+
+ data.shim.buttonWrapper.addClass('input-button-size-'+(data.shim.buttonWrapper.children().filter(isVisible).length)+' '+webshims.shadowClass);
+
+ if(data.shim.buttonWrapper.filter(isVisible).length){
+ data.shim.element.addClass('has-input-buttons');
+ }
+ }
+
+ labelWidth($(this).getShadowFocusElement(), labels);
+
+ $(this).on('change', function(e){
+ if(!stopCircular){
+ data.shim.value($.prop(this, 'value'));
+ }
+ });
+
+ (function(){
+ var has = {
+ focusin: true,
+ focus: true
+ };
+ var timer;
+ var hasFocusTriggered = false;
+ var hasFocus = false;
+
+ $(data.shim.options.containerElements)
+ .on({
+ 'focusin focus focusout blur': function(e){
+ e.stopImmediatePropagation();
+ hasFocus = has[e.type];
+ clearTimeout(timer);
+ timer = setTimeout(function(){
+ if(hasFocus != hasFocusTriggered){
+ hasFocusTriggered = hasFocus;
+ $(opts.orig).triggerHandler(hasFocus ? 'focus' : 'blur');
+ $(opts.orig).trigger(hasFocus ? 'focusin' : 'focusout');
+ }
+ hasFocusTriggered = hasFocus;
+ }, 9);
+ }
+ })
+ ;
+ })();
+
+
+
+ if(hasFormValidation){
+ $(opts.orig).on('firstinvalid', function(e){
+ if(!webshims.fromSubmit && isCheckValidity){return;}
+ $(opts.orig).off('invalid.replacedwidgetbubble').on('invalid.replacedwidgetbubble', function(evt){
+ if(!evt.isDefaultPrevented()){
+ webshims.validityAlert.showFor( e.target );
+ e.preventDefault();
+ evt.preventDefault();
+ }
+ $(opts.orig).off('invalid.replacedwidgetbubble');
+ });
+ });
+ }
+
+ if(opts.calculateWidth){
+ sizeInput(data.shim);
+ } else {
+ $(this).css('display', 'none');
+ }
+ if(hasInitialFocus){
+ $(this).getShadowFocusElement().trigger('focus');
+ }
+ }
+
+ };
+
+
+ if(hasFormValidation){
+ ['input', 'form'].forEach(function(name){
+ var desc = webshims.defineNodeNameProperty(name, 'checkValidity', {
+ prop: {
+ value: function(){
+ isCheckValidity = true;
+ var ret = desc.prop._supvalue.apply(this, arguments);
+ isCheckValidity = false;
+ return ret;
+ }
+ }
+ });
+ });
+ }
+
+ var replace = {};
+
+
+ if(options.replaceUI){
+ if( $.isPlainObject(options.replaceUI) ){
+ $.extend(replace, options.replaceUI);
+ } else {
+ $.extend(replace, {
+ 'range': 1,
+ 'number': 1,
+ 'time': 1,
+ 'month': 1,
+ 'date': 1,
+ 'color': 1,
+ 'datetime-local': 1
+ });
+ }
+ }
+ if(supportInputTypes.number && navigator.userAgent.indexOf('Touch') == -1 && ((/MSIE 1[0|1]\.\d/.test(navigator.userAgent)) || (/Trident\/7\.0/.test(navigator.userAgent)))){
+ replace.number = 1;
+ }
+
+ if(!supportInputTypes.range || replace.range){
+ extendType('range', {
+ _create: function(opts, set){
+ var data = $('').insertAfter(opts.orig).rangeUI(opts).data('rangeUi');
+ return data;
+ }
+ });
+ }
+
+
+ ['number', 'time', 'month', 'date', 'color', 'datetime-local'].forEach(function(name){
+ if(!supportInputTypes[name] || replace[name]){
+ extendType(name, {
+ _create: function(opts, set){
+ if(opts.monthSelect || opts.daySelect || opts.yearSelect){
+ opts.splitInput = true;
+ }
+ if(opts.splitInput && !splitInputs[name]){
+ webshims.warn('splitInput not supported for '+ name);
+ opts.splitInput = false;
+ }
+ var markup = opts.splitInput ?
+ '' :
+ '';
+ var data = $(markup).insertAfter(opts.orig);
+ if(steps[name]){
+ data = data.spinbtnUI(opts).data('wsWidget'+name);
+ } else {
+ data = data.wsBaseWidget(opts).data('wsWidget'+name);
+ }
+ if(webshims.picker && webshims.picker[name]){
+ webshims.picker[name](data);
+ }
+ return data;
+ }
+ });
+ }
+ });
+
+ var init = function(){
+ webshims.addReady(function(context, contextElem){
+ $('input', context)
+ .add(contextElem.filter('input'))
+ .each(implementType)
+ ;
+ });
+ };
+
+
+ if($('').prop('labels') == null){
+ webshims.defineNodeNamesProperty('button, input, keygen, meter, output, progress, select, textarea', 'labels', {
+ prop: {
+ get: function(){
+ if(this.type == 'hidden'){return null;}
+ var id = this.id;
+ var labels = $(this)
+ .closest('label')
+ .filter(function(){
+ var hFor = (this.attributes['for'] || {});
+ return (!hFor.specified || hFor.value == id);
+ })
+ ;
+
+ if(id) {
+ labels = labels.add('label[for="'+ id +'"]');
+ }
+ return labels.get();
+ },
+ writeable: false
+ }
+ });
+ }
+
+ if(formcfg._isLoading){
+ $(formcfg).one('change', init);
+ } else {
+ init();
+ }
+
+ })();
+});
+
+;webshims.register('form-datalist', function($, webshims, window, document, undefined, options){
+ "use strict";
+ var lazyLoad = function(name){
+ if(!name || typeof name != 'string'){
+ name = 'DOM';
+ }
+ if(!lazyLoad[name+'Loaded']){
+ lazyLoad[name+'Loaded'] = true;
+ webshims.ready(name, function(){
+ webshims.loader.loadList(['form-datalist-lazy']);
+ });
+ }
+ };
+ var noDatalistSupport = {
+ submit: 1,
+ button: 1,
+ reset: 1,
+ hidden: 1,
+
+ range: 1,
+ date: 1,
+ month: 1
+ };
+ if(webshims.modules["form-number-date-ui"].loaded){
+ $.extend(noDatalistSupport, {
+ number: 1,
+ time: 1
+ });
+ }
+
+
+ /*
+ * implement propType "element" currently only used for list-attribute (will be moved to dom-extend, if needed)
+ */
+ webshims.propTypes.element = function(descs, name){
+ webshims.createPropDefault(descs, 'attr');
+ if(descs.prop){return;}
+ descs.prop = {
+ get: function(){
+ var elem = $.attr(this, name);
+ if(elem){
+ elem = document.getElementById(elem);
+ if(elem && descs.propNodeName && !$.nodeName(elem, descs.propNodeName)){
+ elem = null;
+ }
+ }
+ return elem || null;
+ },
+ writeable: false
+ };
+ };
+
+
+ /*
+ * Implements datalist element and list attribute
+ */
+
+ (function(){
+ var formsCFG = webshims.cfg.forms;
+ var listSupport = webshims.support.datalist;
+ if(listSupport && !formsCFG.customDatalist){return;}
+
+ var initializeDatalist = function(){
+
+ var updateDatlistAndOptions = function(){
+ var id;
+ if(!$.data(this, 'datalistWidgetData') && (id = $.prop(this, 'id'))){
+ $('input[list="'+ id +'"], input[data-wslist="'+ id +'"]').eq(0).attr('list', id);
+ } else {
+ $(this).triggerHandler('updateDatalist');
+ }
+ };
+
+ var inputListProto = {
+ //override autocomplete
+ autocomplete: {
+ attr: {
+ get: function(){
+ var elem = this;
+ var data = $.data(elem, 'datalistWidget');
+ if(data){
+ return data._autocomplete;
+ }
+ return ('autocomplete' in elem) ? elem.autocomplete : elem.getAttribute('autocomplete');
+ },
+ set: function(value){
+ var elem = this;
+ var data = $.data(elem, 'datalistWidget');
+ if(data){
+ data._autocomplete = value;
+ if(value == 'off'){
+ data.hideList();
+ }
+ } else {
+ if('autocomplete' in elem){
+ elem.autocomplete = value;
+ } else {
+ elem.setAttribute('autocomplete', value);
+ }
+ }
+ }
+ }
+ }
+ };
+
+ if(listSupport){
+ //options only return options, if option-elements are rooted: but this makes this part of HTML5 less backwards compatible
+ if(!($('').prop('options') || []).length ){
+ webshims.defineNodeNameProperty('datalist', 'options', {
+ prop: {
+ writeable: false,
+ get: function(){
+ var options = this.options || [];
+ if(!options.length){
+ var elem = this;
+ var select = $('select', elem);
+ if(select[0] && select[0].options && select[0].options.length){
+ options = select[0].options;
+ }
+ }
+ return options;
+ }
+ }
+ });
+ }
+ inputListProto.list = {
+ attr: {
+ get: function(){
+ var val = webshims.contentAttr(this, 'list');
+ if(val != null){
+ $.data(this, 'datalistListAttr', val);
+ if(!noDatalistSupport[$.prop(this, 'type')] && !noDatalistSupport[$.attr(this, 'type')]){
+ this.removeAttribute('list');
+ }
+ } else {
+ val = $.data(this, 'datalistListAttr');
+ }
+
+ return (val == null) ? undefined : val;
+ },
+ set: function(value){
+ var elem = this;
+ $.data(elem, 'datalistListAttr', value);
+ if (!noDatalistSupport[$.prop(this, 'type')] && !noDatalistSupport[$.attr(this, 'type')]) {
+ webshims.objectCreate(shadowListProto, undefined, {
+ input: elem,
+ id: value,
+ datalist: $.prop(elem, 'list')
+ });
+ elem.setAttribute('data-wslist', value);
+ } else {
+ elem.setAttribute('list', value);
+ }
+ $(elem).triggerHandler('listdatalistchange');
+ }
+ },
+ initAttr: true,
+ reflect: true,
+ propType: 'element',
+ propNodeName: 'datalist'
+ };
+ } else {
+ webshims.defineNodeNameProperties('input', {
+ list: {
+ attr: {
+ get: function(){
+ var val = webshims.contentAttr(this, 'list');
+ return (val == null) ? undefined : val;
+ },
+ set: function(value){
+ var elem = this;
+ webshims.contentAttr(elem, 'list', value);
+ webshims.objectCreate(options.shadowListProto, undefined, {input: elem, id: value, datalist: $.prop(elem, 'list')});
+ $(elem).triggerHandler('listdatalistchange');
+ }
+ },
+ initAttr: true,
+ reflect: true,
+ propType: 'element',
+ propNodeName: 'datalist'
+ }
+ });
+ }
+
+ webshims.defineNodeNameProperties('input', inputListProto);
+
+ webshims.addReady(function(context, contextElem){
+ contextElem
+ .filter('datalist > select, datalist, datalist > option, datalist > select > option')
+ .closest('datalist')
+ .each(updateDatlistAndOptions)
+ ;
+ });
+ };
+
+
+ /*
+ * ShadowList
+ */
+
+ var shadowListProto = {
+ _create: function(opts){
+
+ if(noDatalistSupport[$.prop(opts.input, 'type')] || noDatalistSupport[$.attr(opts.input, 'type')]){return;}
+ var datalist = opts.datalist;
+ var data = $.data(opts.input, 'datalistWidget');
+ var that = this;
+ if(datalist && data && data.datalist !== datalist){
+ data.datalist = datalist;
+ data.id = opts.id;
+
+
+ $(data.datalist)
+ .off('updateDatalist.datalistWidget')
+ .on('updateDatalist.datalistWidget', $.proxy(data, '_resetListCached'))
+ ;
+
+ data._resetListCached();
+ return;
+ } else if(!datalist){
+ if(data){
+ data.destroy();
+ }
+ return;
+ } else if(data && data.datalist === datalist){
+ return;
+ }
+
+
+
+ this.datalist = datalist;
+ this.id = opts.id;
+ this.hasViewableData = true;
+ this._autocomplete = $.attr(opts.input, 'autocomplete');
+ $.data(opts.input, 'datalistWidget', this);
+ $.data(datalist, 'datalistWidgetData', this);
+
+ lazyLoad('WINDOWLOAD');
+
+ if(webshims.isReady('form-datalist-lazy')){
+ if(window.QUnit){
+ that._lazyCreate(opts);
+ } else {
+ setTimeout(function(){
+ that._lazyCreate(opts);
+ }, 9);
+ }
+ } else {
+ $(opts.input).one('focus', lazyLoad);
+ webshims.ready('form-datalist-lazy', function(){
+ if(!that._destroyed){
+ that._lazyCreate(opts);
+ }
+ });
+ }
+ },
+ destroy: function(e){
+ var input;
+ var autocomplete = $.attr(this.input, 'autocomplete');
+ $(this.input)
+ .off('.datalistWidget')
+ .removeData('datalistWidget')
+ ;
+ this.shadowList.remove();
+ $(document).off('.datalist'+this.id);
+ $(window).off('.datalist'+this.id);
+ if(this.input.form && this.input.id){
+ $(this.input.form).off('submit.datalistWidget'+this.input.id);
+ }
+ this.input.removeAttribute('aria-haspopup');
+ if(autocomplete === undefined){
+ this.input.removeAttribute('autocomplete');
+ } else {
+ $(this.input).attr('autocomplete', autocomplete);
+ }
+ if(e && e.type == 'beforeunload'){
+ input = this.input;
+ setTimeout(function(){
+ $.attr(input, 'list', $.attr(input, 'list'));
+ }, 9);
+ }
+ this._destroyed = true;
+ }
+ };
+
+ webshims.loader.addModule('form-datalist-lazy', {
+ noAutoCallback: true,
+ options: $.extend(options, {shadowListProto: shadowListProto})
+ });
+ if(!options.list){
+ options.list = {};
+ }
+ //init datalist update
+ initializeDatalist();
+ })();
+
+});
diff --git a/public/webshims/shims/combos/97.js b/public/webshims/shims/combos/97.js
new file mode 100644
index 00000000..41dc387c
--- /dev/null
+++ b/public/webshims/shims/combos/97.js
@@ -0,0 +1,1052 @@
+webshims.register('jmebase', function($, webshims, window, doc, undefined){
+ "use strict";
+ var props = {};
+ var fns = {};
+ var slice = Array.prototype.slice;
+ var readyLength = 0;
+ var options = $.extend({selector: '.mediaplayer'}, webshims.cfg.mediaelement.jme);
+ var baseSelector = options.selector;
+
+ webshims.cfg.mediaelement.jme = options;
+
+ if(!$.jme){
+ $.jme = {};
+ }
+
+ $.extend($.jme, {
+ pluginsClasses: [],
+ pluginsSel: '',
+ plugins: {},
+ props: props,
+ fns: fns,
+ data: function(elem, name, value){
+ var data = $(elem).data('jme') || $.data(elem, 'jme', {});
+ if(value === undefined){
+ return (name) ? data[name] : data;
+ } else {
+ data[name] = value;
+ }
+ },
+ runPlugin: function(sel){
+ if(readyLength){
+ $(document.querySelectorAll(baseSelector)).each(function(){
+ var controls = this.querySelectorAll(sel);
+ if(controls.length){
+ $(this).jmeFn('addControls', controls);
+ }
+ });
+ }
+ },
+ registerPlugin: function(name, plugin){
+ this.plugins[name] = plugin;
+ if(!plugin.nodeName){
+ plugin.nodeName = '';
+ }
+ if(!plugin.className){
+ plugin.className = name;
+ }
+
+ this.pluginsClasses.push('.'+plugin.className);
+
+ this.pluginsSel = this.pluginsClasses.join(', ');
+
+ options[name] = $.extend(plugin.options || {}, options[name]);
+
+ if(options[name] && options[name].text){
+ plugin.text = options[name].text;
+ } else if(options.i18n && options.i18n[name]){
+ plugin.text = options.i18n[name];
+ }
+ this.runPlugin('.'+plugin.className);
+ },
+ configmenuPlugins: {},
+ addToConfigmenu: function(name, create){
+ this.configmenuPlugins[name] = create;
+ },
+ defineMethod: function(name, fn){
+ fns[name] = fn;
+ },
+ defineProp: function(name, desc){
+ if(!desc){
+ desc = {};
+ }
+ if(!desc.set){
+ if(desc.readonly){
+ desc.set = function(){
+ throw(name +' is readonly');
+ };
+ } else {
+ desc.set = $.noop;
+ }
+ }
+ if(!desc.get){
+ desc.get = function(elem){
+ return $.jme.data(elem, name);
+ };
+ }
+ props[name] = desc;
+ },
+ prop: function(elem, name, value){
+ if(!props[name]){
+ return $.prop(elem, name, value);
+ }
+ if(value === undefined){
+ return props[name].get( elem );
+ } else {
+ var setValue = props[name].set(elem, value);
+ if(setValue === undefined){
+ setValue = value;
+ }
+ if(setValue != 'noDataSet'){
+ $.jme.data(elem, name, setValue);
+ }
+ }
+ }
+ });
+
+ $.fn.jmeProp = function(name, value){
+ return $.access( this, $.jme.prop, name, value, arguments.length > 1 );
+ };
+
+ $.fn.jmeFn = function(fn){
+ var args = slice.call( arguments, 1 );
+ var ret;
+ this.each(function(){
+ if(!$.jme.data(this).media){
+ $(this).closest(baseSelector).jmePlayer();
+ webshims.warn('jmeFn called to early or on wrong element!');
+ }
+ ret = (fns[fn] || $.prop(this, fn)).apply(this, args);
+ if(ret !== undefined){
+ return false;
+ }
+ });
+ return (ret !== undefined) ? ret : this;
+ };
+ var idlStates = {
+ emptied: 1,
+ pause: 1
+ };
+ var unwaitingEvents = {
+ canplay: 1, canplaythrough: 1
+ };
+
+
+ $.jme.initJME = function(context, insertedElement){
+ readyLength += $(context.querySelectorAll(baseSelector)).add(insertedElement.filter(baseSelector)).jmePlayer().length;
+ };
+
+
+ $.jme.getDOMList = function(attr){
+ var list = [];
+ if(!attr){
+ attr = [];
+ }
+ if(typeof attr == 'string'){
+ attr = attr.split(' ');
+ }
+ $.each(attr, function(i, id){
+ if(id){
+ id = document.getElementById(id);
+ if(id){
+ list.push(id);
+ }
+ }
+ });
+ return list;
+ };
+
+
+ $.jme.getButtonText = function(button, classes){
+ var isCheckbox;
+ var lastState;
+ var txtChangeFn = function(state){
+ if(lastState === state){return;}
+ lastState = state;
+
+
+ button
+ .removeClass(classes[(state) ? 0 : 1])
+ .addClass(classes[state])
+ ;
+
+ if(isCheckbox){
+ button.prop('checked', !!state);
+ (button.data('checkboxradio') || {refresh: $.noop}).refresh();
+ }
+ };
+
+ if (button.is('[type="checkbox"], [type="radio"]')){
+ button.prop('checked', function(){
+ return this.defaultChecked;
+ });
+ isCheckbox = true;
+ } else if(button.is('a')){
+ button.on('click', function(e){
+ e.preventDefault();
+ });
+ }
+
+ return txtChangeFn;
+ };
+
+ $.fn.jmePlayer = function(opts){
+
+ return this.each(function(){
+
+
+ var mediaUpdateFn, canPlay, removeCanPlay, canplayTimer, lastState, stopEmptiedEvent, forceRender;
+ var media = $('audio, video', this).eq(0);
+ var base = $(this);
+
+ var jmeData = $.jme.data(this);
+ var mediaData = $.jme.data(media[0]);
+
+
+ base.addClass(media.prop('nodeName').toLowerCase()+'player');
+ mediaData.player = base;
+ mediaData.media = media;
+ if(!jmeData.media){
+ forceRender = function(){
+ base[0].className = base[0].className;
+ };
+ removeCanPlay = function(){
+ media.off('canplay', canPlay);
+ clearTimeout(canplayTimer);
+ };
+ canPlay = function(){
+ var state = (media.prop('paused')) ? 'idle' : 'playing';
+ base.attr('data-state', state);
+ };
+ mediaUpdateFn = function(e){
+ var state = e.type;
+ var readyState;
+ var paused;
+ removeCanPlay();
+
+ if(unwaitingEvents[state] && lastState != 'waiting'){
+ return;
+ }
+
+ if(stopEmptiedEvent && state == 'emptied'){
+ return;
+ }
+
+ if(state == 'ended' || $.prop(this, 'ended')){
+ state = 'ended';
+ } else if(state == 'waiting'){
+
+ if($.prop(this, 'readyState') > 2){
+ state = '';
+ } else {
+ canplayTimer = setTimeout(function(){
+ if(media.prop('readyState') > 2){
+ canPlay();
+ }
+ }, 9);
+ media.on('canPlay', canPlay);
+ }
+
+ } else if(idlStates[state]){
+ state = 'idle';
+ } else {
+ readyState = $.prop(this, 'readyState');
+ paused = $.prop(this, 'paused');
+ if(!paused && readyState < 3){
+ state = 'waiting';
+ } else if(!paused && readyState > 2){
+ state = 'playing';
+ } else {
+ state = 'idle';
+ }
+ }
+
+ if(state == 'idle' && base._seekpause){
+ state = false;
+ }
+
+ if(state){
+ lastState = state;
+ base.attr('data-state', state);
+ setTimeout(forceRender);
+ }
+ };
+
+
+ jmeData.media = media;
+ jmeData.player = base;
+ media
+ .on('ended emptied play', (function(){
+ var timer;
+ var releaseEmptied = function(){
+ stopEmptiedEvent = false;
+ };
+ var ended = function(){
+ removeCanPlay();
+ media.jmeFn('pause');
+ if(!options.noReload && media.prop('ended') && media.prop('paused') && !media.prop('autoplay') && !media.prop('loop') && !media.hasClass('no-reload')){
+ stopEmptiedEvent = true;
+ media.jmeFn('load');
+ base.attr('data-state', 'ended');
+ setTimeout(releaseEmptied);
+
+ }
+ };
+ return function(e){
+
+ clearTimeout(timer);
+ if(e.type == 'ended' && !options.noReload && !media.prop('autoplay') && !media.prop('loop') && !media.hasClass('no-reload')){
+ timer = setTimeout(ended);
+ }
+ };
+ })())
+ .on('emptied waiting canplay canplaythrough playing ended pause mediaerror', mediaUpdateFn)
+ .on('volumechange updateJMEState', function(){
+ var volume = $.prop(this, 'volume');
+ base[!volume || $.prop(this, 'muted') ? 'addClass' : 'removeClass']('state-muted');
+
+ if(volume < 0.01){
+ volume = 'no';
+ } else if(volume < 0.36){
+ volume = 'low';
+ } else if(volume < 0.7){
+ volume = 'medium';
+ } else {
+ volume = 'high';
+ }
+ base.attr('data-volume', volume);
+ })
+ ;
+ if($.jme.pluginsSel){
+ base.jmeFn('addControls', $(base[0].querySelectorAll($.jme.pluginsSel)));
+ }
+ if(mediaUpdateFn){
+ media.on('updateJMEState', mediaUpdateFn).triggerHandler('updateJMEState');
+ }
+ }
+ });
+ };
+
+
+ $.jme.defineProp('isPlaying', {
+ get: function(elem){
+ return (!$.prop(elem, 'ended') && !$.prop(elem, 'paused') && $.prop(elem, 'readyState') > 1 && !$.data(elem, 'mediaerror'));
+ },
+ readonly: true
+ });
+
+ $.jme.defineProp('player', {
+ readonly: true
+ });
+
+ $.jme.defineProp('media', {
+ readonly: true
+ });
+
+ $.jme.defineProp('srces', {
+ get: function(elem){
+ var srces;
+ var data = $.jme.data(elem);
+ var src = data.media.prop('src');
+ if(src){
+ return [{src: src}];
+ }
+ srces = $.map($('source', data.media).get(), function(source){
+ var i, len;
+ var src = {
+ src: $.prop(source, 'src')
+ };
+ var attributes = source.attributes;
+
+ for(i = 0, len = attributes.length; i < len; i++){
+ if(!('specified' in attributes[i]) || attributes[i].specified){
+ src[attributes[i].nodeName] = attributes[i].nodeValue;
+ }
+ }
+ return src;
+ });
+ return srces;
+ },
+ set: function(elem, srces){
+ var data = $.jme.data(elem);
+
+ var setSrc = function(i, src){
+ if(typeof src == 'string'){
+ src = {src: src};
+ }
+ $(document.createElement('source')).attr(src).appendTo(data.media);
+ };
+ data.media.removeAttr('src').find('source').remove();
+ if($.isArray(srces)){
+ $.each(srces, setSrc);
+ } else {
+ setSrc(0, srces);
+ }
+ data.media.jmeFn('load');
+ return 'noDataSet';
+ }
+ });
+
+ $.jme.defineMethod('togglePlay', function(){
+ $(this).jmeFn( ( props.isPlaying.get(this) ) ? 'pause' : 'play' );
+ });
+
+
+ $.jme.defineMethod('addControls', function(controls){
+ var data = $.jme.data(this) || {};
+
+ if(!data.media){return;}
+ var oldControls = $.jme.data(data.player[0], 'controlElements') || $([]);
+ controls = $(controls);
+ if($.jme.pluginsSel){
+ controls = controls.find($.jme.pluginsSel).add(controls.filter($.jme.pluginsSel));
+ }
+ if(controls.length){
+ $.each($.jme.plugins, function(name, plugin){
+ var control, options, i, opt;
+ var pluginControls = controls.filter('.'+plugin.className);
+
+ for(i = 0; i < pluginControls.length; i++){
+ control = $(pluginControls[i]);
+ options = $.jme.data(pluginControls[i]);
+ options.player = data.player;
+ options.media = data.media;
+ if(!options._rendered){
+ options._rendered = true;
+
+ if(plugin.options){
+ for(opt in plugin.options){
+ if(!(opt in options)){
+ options[opt] = plugin.options[opt];
+ }
+ }
+ }
+
+ plugin._create(control, data.media, data.player, options);
+ }
+ }
+
+ });
+
+ $.jme.data(data.player[0], 'controlElements', oldControls.add(controls));
+
+ data.player.triggerHandler('controlsadded');
+ }
+ });
+
+ webshims.ready('DOM mediaelement', function(){
+ webshims.isReady('jme', true);
+ webshims.addReady($.jme.initJME);
+ webshims.isReady('jme-base', true);
+
+ if(webshims.cfg.debug !== false && document.getElementsByTagName('video').length && !document.querySelector(baseSelector)){
+ webshims.warn("found video element but video wasn't wrapped inside a ."+ baseSelector +" element. Will not add control UI");
+ }
+ });
+
+});
+;webshims.ready('jme-base DOM', function(){
+ "use strict";
+ var webshims = window.webshims;
+ var $ = webshims.$;
+ var jme = $.jme;
+ var listId = 0;
+ var btnStructure = '';
+
+ function PlaylistList(data){
+ this._data = data;
+ this.lists = {};
+
+ this.on('showcontrolschange', this._updateControlsClass);
+ }
+
+ $.extend(PlaylistList.prototype, {
+ on: function(){
+ $.fn.on.apply($(this), arguments);
+ },
+ off: function(){
+ $.fn.off.apply($(this), arguments);
+ },
+ _getListId: function(list){
+ var id;
+ if(typeof list == 'string'){
+ id = list;
+ } else {
+ id = list.id;
+ }
+ return id;
+ },
+ _updateControlsClass: function(){
+ this._data.player[this.getShowcontrolsList() ? 'addClass' : 'removeClass']('has-playlist');
+ },
+ add: function(list, opts){
+
+ list = new Playlist(list, this, opts);
+ if(!list.id){
+ listId++;
+ list.id = 'list-'+listId;
+ }
+ this.lists[list.id] = list;
+
+ if(list.options.showcontrols){
+ this._data.player.addClass('has-playlist');
+ }
+
+ return list;
+ },
+ remove: function(list){
+ var id = this._getListId(list);
+ if(this.lists[id]){
+ this.lists[id]._remove();
+ delete this.lists[id];
+ }
+ if(!this.getShowcontrolsList()){
+ this._data.player.removeClass('has-playlist');
+ }
+ },
+ getAutoplayList: function(){
+ var clist = null;
+ $.each(this.lists, function(id, list){
+ if(list.options.autoplay){
+ clist = list;
+ return false;
+ }
+ });
+ return clist;
+ },
+ getShowcontrolsList: function(){
+ var clist = null;
+ $.each(this.lists, function(id, list){
+ if(list.options.showcontrols){
+ clist = list;
+ return false;
+ }
+ });
+ return clist;
+ }
+
+ });
+
+ function Playlist(list, parent, opts){
+ this.list = list || [];
+ this.playlists = parent;
+ this.media = parent._data.media;
+ this.player = parent._data.player;
+ this.options = $.extend(true, {}, Playlist.defaults, opts);
+ this.options.itemTmpl = this.options.itemTmpl.trim();
+
+ this.deferred = $.Deferred();
+ this._selectedIndex = -1;
+ this._selectedItem = null;
+ this.$rendered = null;
+
+ this._detectListType();
+
+ this.autoplay(this.options.autoplay);
+
+ this.deferred.done(function(){
+ this._addEvents(this);
+ if(this.options.defaultSelected == 'auto' && !this.media.jmeProp('srces').length){
+ this.options.defaultSelected = 0;
+ }
+ if(this.list[this.options.defaultSelected]){
+ this.selectedIndex(this.options.defaultSelected);
+ }
+ this._fire('addlist');
+ });
+ }
+
+ Playlist.getText = function($elem){
+ return $elem.attr('content') || ($elem.text() || '').trim();
+ };
+ Playlist.getUrl = function($elem){
+ return $elem.attr('content') || $elem.attr('url') || $elem.attr('href') || $elem.attr('src') || ($elem.text() || '').trim();
+ };
+
+ Playlist.defaults = {
+ loop: false,
+ autoplay: false,
+ defaultSelected: 'auto',
+ addItemEvents: true,
+ showcontrols: true,
+ ajax: {},
+ itemTmpl: '' +
+ '<% if(typeof poster == "string" && poster) {%><% }%>' +
+ '<%=title%>
' +
+ '<% if(typeof description == "string" && description) {%><%=description%>
<% }%>' +
+ '',
+ renderer: function(item, template){
+ return $.jme.tmpl(template, item);
+ },
+ mapDom: function(element){
+
+ return {
+ title: Playlist.getText($('[itemprop="name"], h1, h2, h3, h4, h5, h6, a', element)),
+ srces: $('[itemprop="contentUrl"], a[type^="video"], a[type^="audio"]', element).map(function(){
+ var tmp;
+ var src = {src: Playlist.getUrl($(this))};
+ if(this.nodeName.toLowerCase() == 'a'){
+ tmp = $.prop(this, 'type');
+ } else {
+ tmp = Playlist.getText($('[itemprop="encodingFormat"]', element));
+ }
+ if(tmp){
+ src.type = tmp;
+ }
+ tmp = $.attr(this, 'data-media');
+ if(tmp){
+ src.media = tmp;
+ }
+ return src;
+ }).get(),
+ tracks: $('a[type="text/vtt"]').map(mapTrackUrl).get(),
+ poster: Playlist.getUrl($('[itemprop="thumbnailUrl"], a[type^="image"], img', element)) || null,
+ description: Playlist.getText($('[itemprop="description"], .item-description, p', element)) || null
+ };
+ },
+ mapUrl: function(opts, callback){
+ $.ajax($.extend(opts, {
+ success: function(data){
+ var list;
+ if($.isArray(data)){
+ list = data;
+ } else if(data.responseData && data.responseData.feed){
+ data = data.responseData.feed;
+ list = (data.entries || []).map(mapJsonFeed);
+ } else {
+ list = [];
+ $('item', data).each(function(){
+ var srces = $('enclosure, media\\:content', this)
+ .filter('[type^="video"], [type^="audio"]')
+ .map(mapUrl)
+ .get()
+ ;
+ if(srces.length){
+ list.push({
+ title: $('title', this).html(),
+ srces: srces,
+ publishedDate: $('pubDate', this).html() || null,
+ description: $('description', this).text() || null,
+ poster: Playlist.getUrl($('itunes\\:image, media\\:thumbnail, enclosure[type^="image"], media\\:content[type^="image"]', this)) || null,
+ author: $('itunes\\:author', this).html() || null,
+ duration: $('itunes\\:duration', this).html() || null,
+ tracks: $('media\\:subTitle', this).map(mapTrackUrl).get() || null
+ });
+ }
+ });
+ }
+ if(list != data){
+ list.fullData = data;
+ }
+ callback(list);
+ }
+ }));
+ }
+ };
+
+ function mapJsonFeed(item){
+ item.description = item.description || item.content;
+ item.srces = [];
+ (item.mediaGroups || []).forEach(function(mediagroup){
+ (mediagroup.contents || []).forEach(function(itemSrc){
+ itemSrc.src = itemSrc.src || itemSrc.url;
+ item.srces.push(itemSrc);
+ });
+ });
+ return item;
+ }
+
+ function mapTrackUrl(){
+ return {
+ src: $.attr(this, 'href'),
+ srclang: $.attr(this, 'lang'),
+ label: $.attr(this, 'data-label')
+ };
+ }
+
+ function mapUrl(){
+ return {
+ src: $.attr(this, 'url') || $.attr(this, 'href'),
+ type: $.attr(this, 'type')
+ };
+ }
+
+ function filterNode(){
+ return this.nodeType == 1;
+ }
+
+ $.extend(Playlist.prototype, {
+ on: function(){
+ $.fn.on.apply($(this), arguments);
+ },
+ off: function(){
+ $.fn.off.apply($(this), arguments);
+ },
+ _detectListType: function(){
+ var fullData;
+ if(typeof this.list == 'string'){
+ this._createListFromUrl();
+ return;
+ }
+ if(this.list.nodeName || (this.list.length > 0 && this.list[0].nodeName)){
+ this._createListFromDom();
+ } else if(this.list.responseData && this.list.responseData.feed){
+ fullData = this.list.responseData.feed;
+ this.list = (fullData.entries || []).map(mapJsonFeed);
+ this.list.fullData = fullData;
+ }
+ this.deferred.resolveWith(this);
+
+ },
+ _createListFromUrl: function(){
+ var that = this;
+ this.options.ajax.url = this.list;
+ this.options.mapUrl(this.options.ajax, function(list){
+ that.list = list;
+ that.deferred.resolveWith(that);
+ });
+ },
+ _createListFromDom: function(){
+ var that = this;
+
+ this.$rendered = $(this.list).eq(0);
+ this.list = [];
+
+ if(this.$rendered){
+ this._addDomList();
+ this.list = this.$rendered.children().map(function(){
+ return that._createItemFromDom(this);
+ }).get();
+ }
+ },
+ _createItemFromDom: function(dom){
+ var item = this.options.mapDom(dom);
+ this._addItemData(item, dom);
+ return item;
+ },
+ _fire: function(evt, extra){
+ var evt = $.Event(evt);
+ $(this).triggerHandler(evt, extra);
+ $(this.playlists).triggerHandler(evt, $.merge([{list: this}], extra || []));
+ if(this.$rendered){
+ this.$rendered.triggerHandler(evt, extra);
+ }
+ },
+ _addDomList: function(){
+ this.$rendered
+ .attr({
+ 'data-autoplay': this.options.autoplay,
+ 'data-loop': this.options.loop
+ })
+ .addClass('media-playlist')
+ .data('playlist', this)
+ ;
+ },
+ _addItemData: function(item, dom){
+ var that = this;
+ item.$item = $(dom).data('itemData', item);
+
+ if(item == this._selectedItem){
+ item.$item.addClass('selected-item');
+ }
+ if(this.options.addItemEvents){
+ item.$item.on('click.playlist', function(e){
+ if(that.options.addItemEvents){
+ that.playItem(item, e);
+ return false;
+ }
+ });
+ }
+ },
+ _addEvents: function(that){
+ var o = that.options;
+ var onEnded = function(e){
+ if(o.autoplay){
+ that.playNext(e);
+ }
+ };
+ this.media.on('ended', onEnded);
+ this._remove = function(){
+ that.media.off('ended', onEnded);
+ that.autoplay(false);
+
+ if(that.$rendered){
+ that.$rendered.remove();
+ }
+
+ that._fire('removelist');
+ };
+ },
+ _remove: function(){
+ this._fire('removelist');
+ },
+ render: function(callback){
+ if(this.$rendered){
+ callback(this.$rendered, this.player, this);
+ } else {
+ this.deferred.done(function(){
+ var nodeName;
+ var that = this;
+ var items = [];
+ if(!this.$rendered){
+ $.each(this.list, function(i, item){
+ var domItem = $($.parseHTML(that.options.renderer(item, that.options.itemTmpl))).filter(filterNode)[0];
+ that._addItemData(item, domItem);
+ items.push(domItem);
+ });
+ nodeName = (items[0] && items[0].nodeName || '').toLowerCase();
+
+ switch (nodeName){
+ case 'li':
+ this.$rendered = $.parseHTML('');
+ break;
+ case 'option':
+ this.$rendered = $.parseHTML('');
+ break;
+ default:
+ this.$rendered = $.parseHTML('');
+ break;
+ }
+ this.$rendered = $(this.$rendered).html(items);
+ this._addDomList();
+ }
+ callback(this.$rendered, this.player, this);
+ });
+ }
+ },
+ /*
+
+ addItem: function(item, pos){
+
+ },
+ removeItem: function(item){
+
+ },
+ */
+ _loadItem: function(item){
+ var media = this.media;
+ media.attr('poster', item.poster || '');
+
+ $('track', media).remove();
+
+ $.each(item.tracks || [], function(i, track){
+ $('').attr(track).appendTo(media);
+ });
+ if(!item.srces){
+ item.srces = item;
+ }
+ media.jmeProp('srces', item.srces);
+ },
+ _getItem: function(item){
+ if(item && (item.nodeName || item.jquery || typeof item == 'string')){
+ item = $(item).data('itemData');
+ }
+ return item;
+ },
+ playItem: function(item, e){
+ var media;
+ this.selectedItem(item, e);
+ if(item){
+ media = this.media.play();
+ setTimeout(function(){
+ media.play();
+ }, 9);
+ }
+ },
+ selectedIndex: function(index, e){
+ if(arguments.length){
+ this.selectedItem(this.list[index], e);
+ } else {
+ return this._selectedIndex;
+ }
+ },
+
+ selectedItem: function(item, e){
+ var oldItem, found;
+
+ if(arguments.length){
+ found = -1;
+ item = this._getItem(item);
+ if(item){
+ $.each(this.list, function(i){
+ if(item == this){
+ found = i;
+ return false;
+ }
+ });
+ }
+
+ if(found >= 0){
+ this._loadItem(this.list[found]);
+ }
+
+ if(found != this._selectedIndex){
+ oldItem = this._selectedItem || null;
+ if(oldItem && oldItem.$item){
+ oldItem.$item.removeClass('selected-item');
+ }
+ this._selectedItem = this.list[found] || null;
+ this._selectedIndex = found;
+ if(this._selectedItem && this._selectedItem.$item){
+ this._selectedItem.$item.addClass('selected-item');
+ }
+ if(oldItem !== this._selectedItem){
+ this._fire('itemchange', [{oldItem: oldItem, from: e || null}]);
+ }
+ }
+
+ } else {
+ return this._selectedItem;
+ }
+ },
+ playNext: function(){
+ var item = this.getNext();
+ if(item){
+ this.playItem(item);
+ }
+ },
+ playPrev: function(){
+ var item = this.getPrev();
+ if(item){
+ this.playItem(item);
+ }
+ },
+ getNext: function(){
+ var index = this._selectedIndex + 1;
+ return this.list[index] || (this.options.loop ? this.list[0] : null);
+ },
+ getPrev: function(){
+ var index = this._selectedIndex - 1;
+ return this.list[index] || (this.options.loop ? this.list[this.list.length - 1] : null);
+ }
+ });
+
+ [{name: 'autoplay', fn: 'getAutoplayList'}, {name: 'showcontrols', fn: 'getShowcontrolsList'}, {name: 'loop'}].forEach(function(desc){
+ Playlist.prototype[desc.name] = function(value){
+ var curList;
+ if(arguments.length){
+ value = !!value;
+
+ if(value && desc.fn){
+ curList = this.playlists[desc.fn]();
+ if(curList && curList != this){
+ curList[desc.name](false);
+ }
+ }
+
+ if(this.options[desc.name] != value){
+ this.options[desc.name] = value;
+ if(this.$rendered){
+ this.$rendered.attr('data-'+desc.name, value);
+ }
+ this._fire(desc.name+'change');
+ }
+ } else {
+ return this.options[desc.name];
+ }
+ }
+ });
+
+ jme.defineProp('playlists', {
+ writable: false,
+ get: function(elem){
+ var data = $.jme.data(elem);
+
+ if(elem != data.player[0]){return null;}
+ if(!data.playlists){
+ data.playlists = new PlaylistList(data);
+ }
+ return data.playlists;
+ }
+ });
+
+ jme.defineMethod('addPlaylist', function(list, options){
+ var playlists = $.jme.prop(this, 'playlists');
+ if(playlists && playlists.add){
+ return playlists.add(list, options);
+ }
+ return null;
+ });
+
+ [
+ {name: 'playlist-prev', text: 'previous', get: 'getPrev', play: 'playPrev'},
+ {name: 'playlist-next', text: 'next', get: 'getNext', play: 'playNext'}
+ ]
+ .forEach(function(desc){
+ $.jme.registerPlugin(desc.name, {
+ structure: btnStructure,
+ text: desc.text,
+ _create: function(control, media, base){
+ var cList;
+ var playlists = base.jmeProp('playlists');
+
+ function itemChange(){
+ var item = cList[desc.get]();
+ if(item){
+ control.prop({'disabled': false, title: item.title});
+ } else {
+ control.prop({'disabled': true, title: ''});
+ }
+ }
+
+ function listchange(){
+ var newClist = playlists.getShowcontrolsList();
+ if(newClist != cList){
+ if(cList){
+ cList.off('itemchange', itemChange);
+ }
+ cList = newClist;
+ if(cList){
+ cList.on('itemchange', itemChange);
+ itemChange();
+ }
+ }
+ }
+
+ control.on('click', function(){
+ if(cList){
+ cList[desc.play]();
+ }
+ });
+
+ playlists.on({
+ 'addlist removelist showcontrolschange':listchange
+ });
+ listchange();
+ }
+ });
+ })
+ ;
+
+
+ // Simple JavaScript Templating
+ (function() {
+ var cache = {};
+ $.jme.tmpl = function tmpl(str, data) {
+ // Figure out if we're getting a template, or if we need to
+ // load the template - and be sure to cache the result.
+ if(!cache[str]){
+ cache[str] = new Function("obj",
+ "var p=[],print=function(){p.push.apply(p,arguments);};" +
+
+ // Introduce the data as local variables using with(){}
+ "with(obj){p.push('" +
+
+ // Convert the template into pure JavaScript
+ str.replace(/[\r\t\n]/g, " ")
+ .replace(/'(?=[^%]*%>)/g,"\t")
+ .split("'").join("\\'")
+ .split("\t").join("'")
+ .replace(/<%=(.+?)%>/g, "',$1,'")
+ .split("<%").join("');")
+ .split("%>").join("p.push('")
+ + "');}return p.join('');");
+ }
+
+ // Provide some basic currying to the user
+ return data ? cache[str](data) : cache[str];
+ };
+ })();
+ $.jme.Playlist = Playlist;
+ webshims.isReady('playlist', true);
+});
diff --git a/public/webshims/shims/combos/98.js b/public/webshims/shims/combos/98.js
new file mode 100644
index 00000000..2936fa89
--- /dev/null
+++ b/public/webshims/shims/combos/98.js
@@ -0,0 +1,1433 @@
+webshims.register('jmebase', function($, webshims, window, doc, undefined){
+ "use strict";
+ var props = {};
+ var fns = {};
+ var slice = Array.prototype.slice;
+ var readyLength = 0;
+ var options = $.extend({selector: '.mediaplayer'}, webshims.cfg.mediaelement.jme);
+ var baseSelector = options.selector;
+
+ webshims.cfg.mediaelement.jme = options;
+
+ if(!$.jme){
+ $.jme = {};
+ }
+
+ $.extend($.jme, {
+ pluginsClasses: [],
+ pluginsSel: '',
+ plugins: {},
+ props: props,
+ fns: fns,
+ data: function(elem, name, value){
+ var data = $(elem).data('jme') || $.data(elem, 'jme', {});
+ if(value === undefined){
+ return (name) ? data[name] : data;
+ } else {
+ data[name] = value;
+ }
+ },
+ runPlugin: function(sel){
+ if(readyLength){
+ $(document.querySelectorAll(baseSelector)).each(function(){
+ var controls = this.querySelectorAll(sel);
+ if(controls.length){
+ $(this).jmeFn('addControls', controls);
+ }
+ });
+ }
+ },
+ registerPlugin: function(name, plugin){
+ this.plugins[name] = plugin;
+ if(!plugin.nodeName){
+ plugin.nodeName = '';
+ }
+ if(!plugin.className){
+ plugin.className = name;
+ }
+
+ this.pluginsClasses.push('.'+plugin.className);
+
+ this.pluginsSel = this.pluginsClasses.join(', ');
+
+ options[name] = $.extend(plugin.options || {}, options[name]);
+
+ if(options[name] && options[name].text){
+ plugin.text = options[name].text;
+ } else if(options.i18n && options.i18n[name]){
+ plugin.text = options.i18n[name];
+ }
+ this.runPlugin('.'+plugin.className);
+ },
+ configmenuPlugins: {},
+ addToConfigmenu: function(name, create){
+ this.configmenuPlugins[name] = create;
+ },
+ defineMethod: function(name, fn){
+ fns[name] = fn;
+ },
+ defineProp: function(name, desc){
+ if(!desc){
+ desc = {};
+ }
+ if(!desc.set){
+ if(desc.readonly){
+ desc.set = function(){
+ throw(name +' is readonly');
+ };
+ } else {
+ desc.set = $.noop;
+ }
+ }
+ if(!desc.get){
+ desc.get = function(elem){
+ return $.jme.data(elem, name);
+ };
+ }
+ props[name] = desc;
+ },
+ prop: function(elem, name, value){
+ if(!props[name]){
+ return $.prop(elem, name, value);
+ }
+ if(value === undefined){
+ return props[name].get( elem );
+ } else {
+ var setValue = props[name].set(elem, value);
+ if(setValue === undefined){
+ setValue = value;
+ }
+ if(setValue != 'noDataSet'){
+ $.jme.data(elem, name, setValue);
+ }
+ }
+ }
+ });
+
+ $.fn.jmeProp = function(name, value){
+ return $.access( this, $.jme.prop, name, value, arguments.length > 1 );
+ };
+
+ $.fn.jmeFn = function(fn){
+ var args = slice.call( arguments, 1 );
+ var ret;
+ this.each(function(){
+ if(!$.jme.data(this).media){
+ $(this).closest(baseSelector).jmePlayer();
+ webshims.warn('jmeFn called to early or on wrong element!');
+ }
+ ret = (fns[fn] || $.prop(this, fn)).apply(this, args);
+ if(ret !== undefined){
+ return false;
+ }
+ });
+ return (ret !== undefined) ? ret : this;
+ };
+ var idlStates = {
+ emptied: 1,
+ pause: 1
+ };
+ var unwaitingEvents = {
+ canplay: 1, canplaythrough: 1
+ };
+
+
+ $.jme.initJME = function(context, insertedElement){
+ readyLength += $(context.querySelectorAll(baseSelector)).add(insertedElement.filter(baseSelector)).jmePlayer().length;
+ };
+
+
+ $.jme.getDOMList = function(attr){
+ var list = [];
+ if(!attr){
+ attr = [];
+ }
+ if(typeof attr == 'string'){
+ attr = attr.split(' ');
+ }
+ $.each(attr, function(i, id){
+ if(id){
+ id = document.getElementById(id);
+ if(id){
+ list.push(id);
+ }
+ }
+ });
+ return list;
+ };
+
+
+ $.jme.getButtonText = function(button, classes){
+ var isCheckbox;
+ var lastState;
+ var txtChangeFn = function(state){
+ if(lastState === state){return;}
+ lastState = state;
+
+
+ button
+ .removeClass(classes[(state) ? 0 : 1])
+ .addClass(classes[state])
+ ;
+
+ if(isCheckbox){
+ button.prop('checked', !!state);
+ (button.data('checkboxradio') || {refresh: $.noop}).refresh();
+ }
+ };
+
+ if (button.is('[type="checkbox"], [type="radio"]')){
+ button.prop('checked', function(){
+ return this.defaultChecked;
+ });
+ isCheckbox = true;
+ } else if(button.is('a')){
+ button.on('click', function(e){
+ e.preventDefault();
+ });
+ }
+
+ return txtChangeFn;
+ };
+
+ $.fn.jmePlayer = function(opts){
+
+ return this.each(function(){
+
+
+ var mediaUpdateFn, canPlay, removeCanPlay, canplayTimer, lastState, stopEmptiedEvent, forceRender;
+ var media = $('audio, video', this).eq(0);
+ var base = $(this);
+
+ var jmeData = $.jme.data(this);
+ var mediaData = $.jme.data(media[0]);
+
+
+ base.addClass(media.prop('nodeName').toLowerCase()+'player');
+ mediaData.player = base;
+ mediaData.media = media;
+ if(!jmeData.media){
+ forceRender = function(){
+ base[0].className = base[0].className;
+ };
+ removeCanPlay = function(){
+ media.off('canplay', canPlay);
+ clearTimeout(canplayTimer);
+ };
+ canPlay = function(){
+ var state = (media.prop('paused')) ? 'idle' : 'playing';
+ base.attr('data-state', state);
+ };
+ mediaUpdateFn = function(e){
+ var state = e.type;
+ var readyState;
+ var paused;
+ removeCanPlay();
+
+ if(unwaitingEvents[state] && lastState != 'waiting'){
+ return;
+ }
+
+ if(stopEmptiedEvent && state == 'emptied'){
+ return;
+ }
+
+ if(state == 'ended' || $.prop(this, 'ended')){
+ state = 'ended';
+ } else if(state == 'waiting'){
+
+ if($.prop(this, 'readyState') > 2){
+ state = '';
+ } else {
+ canplayTimer = setTimeout(function(){
+ if(media.prop('readyState') > 2){
+ canPlay();
+ }
+ }, 9);
+ media.on('canPlay', canPlay);
+ }
+
+ } else if(idlStates[state]){
+ state = 'idle';
+ } else {
+ readyState = $.prop(this, 'readyState');
+ paused = $.prop(this, 'paused');
+ if(!paused && readyState < 3){
+ state = 'waiting';
+ } else if(!paused && readyState > 2){
+ state = 'playing';
+ } else {
+ state = 'idle';
+ }
+ }
+
+ if(state == 'idle' && base._seekpause){
+ state = false;
+ }
+
+ if(state){
+ lastState = state;
+ base.attr('data-state', state);
+ setTimeout(forceRender);
+ }
+ };
+
+
+ jmeData.media = media;
+ jmeData.player = base;
+ media
+ .on('ended emptied play', (function(){
+ var timer;
+ var releaseEmptied = function(){
+ stopEmptiedEvent = false;
+ };
+ var ended = function(){
+ removeCanPlay();
+ media.jmeFn('pause');
+ if(!options.noReload && media.prop('ended') && media.prop('paused') && !media.prop('autoplay') && !media.prop('loop') && !media.hasClass('no-reload')){
+ stopEmptiedEvent = true;
+ media.jmeFn('load');
+ base.attr('data-state', 'ended');
+ setTimeout(releaseEmptied);
+
+ }
+ };
+ return function(e){
+
+ clearTimeout(timer);
+ if(e.type == 'ended' && !options.noReload && !media.prop('autoplay') && !media.prop('loop') && !media.hasClass('no-reload')){
+ timer = setTimeout(ended);
+ }
+ };
+ })())
+ .on('emptied waiting canplay canplaythrough playing ended pause mediaerror', mediaUpdateFn)
+ .on('volumechange updateJMEState', function(){
+ var volume = $.prop(this, 'volume');
+ base[!volume || $.prop(this, 'muted') ? 'addClass' : 'removeClass']('state-muted');
+
+ if(volume < 0.01){
+ volume = 'no';
+ } else if(volume < 0.36){
+ volume = 'low';
+ } else if(volume < 0.7){
+ volume = 'medium';
+ } else {
+ volume = 'high';
+ }
+ base.attr('data-volume', volume);
+ })
+ ;
+ if($.jme.pluginsSel){
+ base.jmeFn('addControls', $(base[0].querySelectorAll($.jme.pluginsSel)));
+ }
+ if(mediaUpdateFn){
+ media.on('updateJMEState', mediaUpdateFn).triggerHandler('updateJMEState');
+ }
+ }
+ });
+ };
+
+
+ $.jme.defineProp('isPlaying', {
+ get: function(elem){
+ return (!$.prop(elem, 'ended') && !$.prop(elem, 'paused') && $.prop(elem, 'readyState') > 1 && !$.data(elem, 'mediaerror'));
+ },
+ readonly: true
+ });
+
+ $.jme.defineProp('player', {
+ readonly: true
+ });
+
+ $.jme.defineProp('media', {
+ readonly: true
+ });
+
+ $.jme.defineProp('srces', {
+ get: function(elem){
+ var srces;
+ var data = $.jme.data(elem);
+ var src = data.media.prop('src');
+ if(src){
+ return [{src: src}];
+ }
+ srces = $.map($('source', data.media).get(), function(source){
+ var i, len;
+ var src = {
+ src: $.prop(source, 'src')
+ };
+ var attributes = source.attributes;
+
+ for(i = 0, len = attributes.length; i < len; i++){
+ if(!('specified' in attributes[i]) || attributes[i].specified){
+ src[attributes[i].nodeName] = attributes[i].nodeValue;
+ }
+ }
+ return src;
+ });
+ return srces;
+ },
+ set: function(elem, srces){
+ var data = $.jme.data(elem);
+
+ var setSrc = function(i, src){
+ if(typeof src == 'string'){
+ src = {src: src};
+ }
+ $(document.createElement('source')).attr(src).appendTo(data.media);
+ };
+ data.media.removeAttr('src').find('source').remove();
+ if($.isArray(srces)){
+ $.each(srces, setSrc);
+ } else {
+ setSrc(0, srces);
+ }
+ data.media.jmeFn('load');
+ return 'noDataSet';
+ }
+ });
+
+ $.jme.defineMethod('togglePlay', function(){
+ $(this).jmeFn( ( props.isPlaying.get(this) ) ? 'pause' : 'play' );
+ });
+
+
+ $.jme.defineMethod('addControls', function(controls){
+ var data = $.jme.data(this) || {};
+
+ if(!data.media){return;}
+ var oldControls = $.jme.data(data.player[0], 'controlElements') || $([]);
+ controls = $(controls);
+ if($.jme.pluginsSel){
+ controls = controls.find($.jme.pluginsSel).add(controls.filter($.jme.pluginsSel));
+ }
+ if(controls.length){
+ $.each($.jme.plugins, function(name, plugin){
+ var control, options, i, opt;
+ var pluginControls = controls.filter('.'+plugin.className);
+
+ for(i = 0; i < pluginControls.length; i++){
+ control = $(pluginControls[i]);
+ options = $.jme.data(pluginControls[i]);
+ options.player = data.player;
+ options.media = data.media;
+ if(!options._rendered){
+ options._rendered = true;
+
+ if(plugin.options){
+ for(opt in plugin.options){
+ if(!(opt in options)){
+ options[opt] = plugin.options[opt];
+ }
+ }
+ }
+
+ plugin._create(control, data.media, data.player, options);
+ }
+ }
+
+ });
+
+ $.jme.data(data.player[0], 'controlElements', oldControls.add(controls));
+
+ data.player.triggerHandler('controlsadded');
+ }
+ });
+
+ webshims.ready('DOM mediaelement', function(){
+ webshims.isReady('jme', true);
+ webshims.addReady($.jme.initJME);
+ webshims.isReady('jme-base', true);
+
+ if(webshims.cfg.debug !== false && document.getElementsByTagName('video').length && !document.querySelector(baseSelector)){
+ webshims.warn("found video element but video wasn't wrapped inside a ."+ baseSelector +" element. Will not add control UI");
+ }
+ });
+
+});
+;webshims.register('mediacontrols', function($, webshims, window){
+ "use strict";
+ var pseudoClasses = 'pseudoClasses';
+
+ var options = webshims.cfg.mediaelement.jme;
+ var baseSelector = options.selector;
+ var jme = $.jme;
+ var unknownStructure = '';
+ var btnStructure = '';
+ var slideStructure = '';
+ var timeStructure = '00:00
';
+
+ var noVolumeClass = (function(){
+ var audio;
+ var ret = '';
+
+ if(window.Audio){
+ try {
+ audio = new Audio();
+ audio.volume = 0.55;
+ ret = ((Math.round(audio.volume * 100) / 100) == 0.55) ? '' : ' no-volume-api';
+ } catch(e){}
+
+ }
+ return ret;
+ })();
+
+ var getBarHtml = (function(){
+ var cache = {};
+ var regTemplate = /\{\{(.+?)\}\}/igm;
+
+ return function(template, invalidCache){
+ if(!template){
+ template = options.barTemplate;
+ }
+ if(!cache[template] || invalidCache){
+ cache[template] = template.replace(regTemplate, function(match, matchName){
+ var plugin = jme.plugins[matchName];
+ if(plugin){
+ if(!plugin.structure){
+ webshims.warn('no structure option provided for plugin: '+ matchName +'. Fallback to standard div');
+ plugin.structure = unknownStructure;
+ }
+ return plugin.structure.replace('{%class%}', matchName).replace('{%text%}', plugin.text || '');
+ }
+ return match;
+ });
+ }
+
+ return cache[template] || '';
+ };
+ })();
+ var ios6 = /iP(hone|od|ad)/i.test(navigator.platform) && parseInt(((navigator.appVersion).match(/OS (\d+)_\d+/) || ['','8'])[1], 10) < 7;
+ var loadLazy = function(){
+ if(!loadLazy.loaded){
+ loadLazy.loaded = true;
+ webshims.loader.loadList(['mediacontrols-lazy', 'range-ui']);
+ }
+ };
+ var lazyLoadPlugin = function(fn){
+ if(!fn){
+ fn = '_create';
+ }
+ var rfn = function(c, media){
+ var obj = this;
+ var args = arguments;
+ loadLazy();
+ webshims.ready('mediacontrols-lazy', function(){
+ if(rfn != obj[fn] && $.data(media[0])){
+ return obj[fn].apply(obj, args);
+ } else {
+ webshims.error('stop too much recursion');
+ }
+ });
+ };
+ return rfn;
+ };
+
+ webshims.loader.addModule('mediacontrols-lazy', {
+ src: 'jme/mediacontrols-lazy'
+ });
+
+ var userActivity = {
+ _create: lazyLoadPlugin()
+ };
+ jme.plugins.useractivity = userActivity;
+
+ jme.defineProp('controlbar', {
+ set: function(elem, value){
+ value = !!value;
+ var controls, playerSize;
+ var data = jme.data(elem);
+ var controlBar = $('div.jme-mediaoverlay, div.jme-controlbar', data.player);
+ var structure = '';
+ if(value && !controlBar[0]){
+ if(data._controlbar){
+ data._controlbar.appendTo(data.player);
+ } else {
+ if(ios6){
+ data.media.removeAttr('controls');
+ data.media.mediaLoad();
+ }
+ data.media.prop('controls', false);
+ structure = getBarHtml();
+ data._controlbar = $( options.barStructure );
+ controlBar = data._controlbar.find('div.jme-cb-box').addClass('media-controls');
+ controls = data._controlbar.filter('.jme-media-overlay');
+ controls = controls.add( controlBar );
+ $(structure).appendTo(controlBar);
+ data._controlbar.appendTo(data.player);
+ data.player.jmeFn('addControls', controls);
+
+ playerSize = (function(){
+ var lastSize = {};
+ var sizes = [
+ {size: 290, name: 'xx-small', names: 's xs xxs'},
+ {size: 380, name: 'x-small', names: 's xs'},
+ {size: 478, name: 'small', names: 's'},
+ {size: 756, name: 'medium', names: 'm'},
+ {size: 1024, name: 'large', names: 'l'},
+ {size: Number.MAX_VALUE, name: 'x-large', names: 'l xl'}
+ ];
+
+
+ var len = sizes.length;
+ return function(){
+ var size;
+ var i = 0;
+ var width = data.player.outerWidth();
+ var fSize = Math.max(parseInt(data.player.css('fontSize'), 10) || 16, 13);
+
+ width = width * (16 / fSize);
+ for(; i < len; i++){
+ if(sizes[i].size >= width){
+ size = sizes[i];
+ break;
+ }
+ }
+
+ if(lastSize.name != size.name){
+ lastSize = size;
+ data.player.attr('data-playersize', size.name);
+ data.player.attr('data-playersizes', size.names);
+ }
+ };
+ })();
+ var $poster = $('').insertAfter(data.media);
+ var posterState = (function(){
+ var lastPosterState, lastYoutubeState, lastPoster;
+ var hasFlash = window.swfmini && swfmini.hasFlashPlayerVersion('10.0.3');
+ var regYt = /youtube\.com\/[watch\?|v\/]+/i;
+
+ var isInitial = data.media.prop('paused');
+ if(isInitial){
+ data.player.addClass('initial-state');
+ }
+ if(!('backgroundSize' in $poster[0].style)){
+ data.player.addClass('no-backgroundsize');
+ }
+ data.media.on('playing waiting seeked seeking', function(){
+ if(isInitial){
+ isInitial = false;
+ data.player.removeClass('initial-state');
+ }
+ });
+ return function(){
+ var poster = data.media.attr('poster');
+ var hasPoster = !!poster;
+ var currentSrc = data.media.prop('currentSrc') || '';
+ var isYt = regYt.test(currentSrc);
+ var hasYt = (hasFlash && hasPoster) ? false : isYt;
+
+ if(!hasPoster && isYt){
+ poster = currentSrc.match(/(?:youtube\.com\/(?:[^\/]+\/.+\/|(?:v|e(?:mbed)?)\/|.*[?&]v=)|youtu\.be\/)([^"&?\/ ]{11})/i) || '';
+ if(poster){
+ poster = 'https://img.youtube.com/vi/'+ poster[1] +'/0.jpg';
+ hasPoster = !!poster;
+ }
+ }
+
+ if(lastPoster !== poster){
+ lastPoster = poster;
+ $poster[0].style.backgroundImage = poster ? 'url('+poster+')' : '';
+ }
+
+ if(lastPosterState !== hasPoster){
+ lastPosterState = hasPoster;
+ data.player[hasPoster ? 'removeClass' : 'addClass']('no-poster');
+ }
+
+ if(data.media.prop('paused')){
+ data.player.addClass('initial-state');
+ isInitial = true;
+ }
+
+ if(lastYoutubeState !== hasYt){
+ lastYoutubeState = hasYt;
+ data.player[hasYt ? 'addClass' : 'removeClass']('has-ytposter');
+ }
+ };
+ })();
+
+
+ userActivity._create(data.player, data.media, data.player);
+
+ data.media.on('emptied loadstart', function(){
+ setTimeout(posterState);
+ });
+
+ playerSize();
+ posterState();
+ webshims.ready('dom-support', function(){
+ data.player.onWSOff('updateshadowdom', playerSize);
+ controls.add(data._controlbar).add($poster).addClass(webshims.shadowClass);
+ webshims.addShadowDom();
+ });
+ }
+
+ } else if(!value) {
+ controlBar.detach();
+ }
+ return value;
+ }
+ });
+
+ jme.registerPlugin('play-pause', {
+ structure: btnStructure,
+ text: 'play / pause',
+ _create: lazyLoadPlugin()
+ });
+
+ jme.registerPlugin('mute-unmute', {
+ structure: btnStructure,
+ text: 'mute / unmute',
+ _create: lazyLoadPlugin()
+ });
+
+ jme.registerPlugin('jme-media-overlay', {
+ _create: lazyLoadPlugin()
+ });
+
+
+
+
+ jme.registerPlugin('volume-slider', {
+ structure: slideStructure,
+ text: 'volume level',
+ _create: lazyLoadPlugin()
+ });
+
+ jme.registerPlugin('time-slider', {
+ structure: slideStructure,
+
+ options: {
+ format: ['mm', 'ss']
+ },
+ text: 'time position',
+ _create: lazyLoadPlugin()
+ });
+
+
+ jme.defineProp('format', {
+ set: function(elem, format){
+ if(!$.isArray(format)){
+ format = format.split(':');
+ }
+ var data = jme.data(elem);
+ data.format = format;
+ $(elem).triggerHandler('updatetimeformat');
+ data.player.triggerHandler('updatetimeformat');
+ return 'noDataSet';
+ }
+ });
+
+ jme.registerPlugin('duration-display', {
+ structure: timeStructure,
+ options: {
+ format: "mm:ss"
+ },
+ _create: lazyLoadPlugin()
+ });
+
+ jme.defineProp('countdown', {
+ set: function(elem, value){
+
+ var data = jme.data(elem);
+ data.countdown = !!value;
+ $(elem).triggerHandler('updatetimeformat');
+ data.player.triggerHandler('updatetimeformat');
+ return 'noDataSet';
+ }
+ });
+
+ jme.registerPlugin('currenttime-display', {
+ structure: timeStructure,
+ options: {
+ format: "mm:ss",
+ countdown: false
+ },
+ _create: lazyLoadPlugin()
+ });
+
+
+ /**
+ * Added Poster Plugin
+ * @author mderting
+ */
+
+ /*
+ * the old technique wasn't fully bullet proof
+ * beside this, jme2 adovactes to use the new improved state-classes to handle visual effect on specific state (see CSS change)
+ */
+ jme.registerPlugin('poster-display', {
+ structure: '',
+ options: {
+ },
+ _create: lazyLoadPlugin()
+ });
+
+
+ jme.registerPlugin('fullscreen', {
+
+ options: {
+ fullscreen: true,
+ autoplayfs: false
+ },
+ structure: btnStructure,
+ text: 'enter fullscreen / exit fullscreen',
+ _create: lazyLoadPlugin()
+ });
+
+ jme.registerPlugin('mediaconfigmenu', {
+ structure: btnStructure,
+ text: 'configuration',
+ _create: lazyLoadPlugin()
+ });
+
+
+ jme.registerPlugin('captions', {
+ structure: btnStructure,
+ text: 'subtitles',
+ _create: function(control, media, base){
+ var trackElems = media.find('track').filter(':not([kind]), [kind="subtitles"], [data-kind="subtitles"], [kind="captions"], [data-kind="captions"]');
+ control.wsclonedcheckbox = $(control).clone().attr({role: 'checkbox'}).insertBefore(control);
+ base.attr('data-tracks', trackElems.length > 1 ? 'many' : trackElems.length);
+ control.attr('aria-haspopup', 'true');
+ lazyLoadPlugin().apply(this, arguments);
+ }
+ });
+
+
+ jme.registerPlugin('chapters', {
+ structure: btnStructure,
+ text: 'chapters',
+ _create: function(control, media, base){
+ var trackElems = media.find('track').filter('[kind="chapters"], [data-kind="chapters"]');
+ control.attr('aria-haspopup', 'true');
+ if(trackElems.length){
+ webshims._polyfill(['track']);
+ base.addClass('has-chapter-tracks');
+ }
+ lazyLoadPlugin().apply(this, arguments);
+ }
+ });
+
+
+
+ webshims.ready(webshims.cfg.mediaelement.plugins.concat(['mediaelement', 'jme-base']), function(){
+ if(!options.barTemplate){
+ options.barTemplate = '{{play-pause}}
{{playlist-prev}}
{{playlist-next}}
{{currenttime-display}}
{{time-slider}}
{{duration-display}}
{{mute-unmute}}
{{volume-slider}}
{{fullscreen}}
';
+ }
+ if(!options.barStructure){
+ options.barStructure = '';
+ }
+
+ webshims.addReady(function(context, insertedElement){
+ $(baseSelector, context).add(insertedElement.filter(baseSelector)).jmeProp('controlbar', true);
+ });
+ });
+ webshims.ready('WINDOWLOAD', loadLazy);
+});
+;webshims.ready('jme-base DOM', function(){
+ "use strict";
+ var webshims = window.webshims;
+ var $ = webshims.$;
+ var jme = $.jme;
+ var listId = 0;
+ var btnStructure = '';
+
+ function PlaylistList(data){
+ this._data = data;
+ this.lists = {};
+
+ this.on('showcontrolschange', this._updateControlsClass);
+ }
+
+ $.extend(PlaylistList.prototype, {
+ on: function(){
+ $.fn.on.apply($(this), arguments);
+ },
+ off: function(){
+ $.fn.off.apply($(this), arguments);
+ },
+ _getListId: function(list){
+ var id;
+ if(typeof list == 'string'){
+ id = list;
+ } else {
+ id = list.id;
+ }
+ return id;
+ },
+ _updateControlsClass: function(){
+ this._data.player[this.getShowcontrolsList() ? 'addClass' : 'removeClass']('has-playlist');
+ },
+ add: function(list, opts){
+
+ list = new Playlist(list, this, opts);
+ if(!list.id){
+ listId++;
+ list.id = 'list-'+listId;
+ }
+ this.lists[list.id] = list;
+
+ if(list.options.showcontrols){
+ this._data.player.addClass('has-playlist');
+ }
+
+ return list;
+ },
+ remove: function(list){
+ var id = this._getListId(list);
+ if(this.lists[id]){
+ this.lists[id]._remove();
+ delete this.lists[id];
+ }
+ if(!this.getShowcontrolsList()){
+ this._data.player.removeClass('has-playlist');
+ }
+ },
+ getAutoplayList: function(){
+ var clist = null;
+ $.each(this.lists, function(id, list){
+ if(list.options.autoplay){
+ clist = list;
+ return false;
+ }
+ });
+ return clist;
+ },
+ getShowcontrolsList: function(){
+ var clist = null;
+ $.each(this.lists, function(id, list){
+ if(list.options.showcontrols){
+ clist = list;
+ return false;
+ }
+ });
+ return clist;
+ }
+
+ });
+
+ function Playlist(list, parent, opts){
+ this.list = list || [];
+ this.playlists = parent;
+ this.media = parent._data.media;
+ this.player = parent._data.player;
+ this.options = $.extend(true, {}, Playlist.defaults, opts);
+ this.options.itemTmpl = this.options.itemTmpl.trim();
+
+ this.deferred = $.Deferred();
+ this._selectedIndex = -1;
+ this._selectedItem = null;
+ this.$rendered = null;
+
+ this._detectListType();
+
+ this.autoplay(this.options.autoplay);
+
+ this.deferred.done(function(){
+ this._addEvents(this);
+ if(this.options.defaultSelected == 'auto' && !this.media.jmeProp('srces').length){
+ this.options.defaultSelected = 0;
+ }
+ if(this.list[this.options.defaultSelected]){
+ this.selectedIndex(this.options.defaultSelected);
+ }
+ this._fire('addlist');
+ });
+ }
+
+ Playlist.getText = function($elem){
+ return $elem.attr('content') || ($elem.text() || '').trim();
+ };
+ Playlist.getUrl = function($elem){
+ return $elem.attr('content') || $elem.attr('url') || $elem.attr('href') || $elem.attr('src') || ($elem.text() || '').trim();
+ };
+
+ Playlist.defaults = {
+ loop: false,
+ autoplay: false,
+ defaultSelected: 'auto',
+ addItemEvents: true,
+ showcontrols: true,
+ ajax: {},
+ itemTmpl: '' +
+ '<% if(typeof poster == "string" && poster) {%><% }%>' +
+ '<%=title%>
' +
+ '<% if(typeof description == "string" && description) {%><%=description%>
<% }%>' +
+ '',
+ renderer: function(item, template){
+ return $.jme.tmpl(template, item);
+ },
+ mapDom: function(element){
+
+ return {
+ title: Playlist.getText($('[itemprop="name"], h1, h2, h3, h4, h5, h6, a', element)),
+ srces: $('[itemprop="contentUrl"], a[type^="video"], a[type^="audio"]', element).map(function(){
+ var tmp;
+ var src = {src: Playlist.getUrl($(this))};
+ if(this.nodeName.toLowerCase() == 'a'){
+ tmp = $.prop(this, 'type');
+ } else {
+ tmp = Playlist.getText($('[itemprop="encodingFormat"]', element));
+ }
+ if(tmp){
+ src.type = tmp;
+ }
+ tmp = $.attr(this, 'data-media');
+ if(tmp){
+ src.media = tmp;
+ }
+ return src;
+ }).get(),
+ tracks: $('a[type="text/vtt"]').map(mapTrackUrl).get(),
+ poster: Playlist.getUrl($('[itemprop="thumbnailUrl"], a[type^="image"], img', element)) || null,
+ description: Playlist.getText($('[itemprop="description"], .item-description, p', element)) || null
+ };
+ },
+ mapUrl: function(opts, callback){
+ $.ajax($.extend(opts, {
+ success: function(data){
+ var list;
+ if($.isArray(data)){
+ list = data;
+ } else if(data.responseData && data.responseData.feed){
+ data = data.responseData.feed;
+ list = (data.entries || []).map(mapJsonFeed);
+ } else {
+ list = [];
+ $('item', data).each(function(){
+ var srces = $('enclosure, media\\:content', this)
+ .filter('[type^="video"], [type^="audio"]')
+ .map(mapUrl)
+ .get()
+ ;
+ if(srces.length){
+ list.push({
+ title: $('title', this).html(),
+ srces: srces,
+ publishedDate: $('pubDate', this).html() || null,
+ description: $('description', this).text() || null,
+ poster: Playlist.getUrl($('itunes\\:image, media\\:thumbnail, enclosure[type^="image"], media\\:content[type^="image"]', this)) || null,
+ author: $('itunes\\:author', this).html() || null,
+ duration: $('itunes\\:duration', this).html() || null,
+ tracks: $('media\\:subTitle', this).map(mapTrackUrl).get() || null
+ });
+ }
+ });
+ }
+ if(list != data){
+ list.fullData = data;
+ }
+ callback(list);
+ }
+ }));
+ }
+ };
+
+ function mapJsonFeed(item){
+ item.description = item.description || item.content;
+ item.srces = [];
+ (item.mediaGroups || []).forEach(function(mediagroup){
+ (mediagroup.contents || []).forEach(function(itemSrc){
+ itemSrc.src = itemSrc.src || itemSrc.url;
+ item.srces.push(itemSrc);
+ });
+ });
+ return item;
+ }
+
+ function mapTrackUrl(){
+ return {
+ src: $.attr(this, 'href'),
+ srclang: $.attr(this, 'lang'),
+ label: $.attr(this, 'data-label')
+ };
+ }
+
+ function mapUrl(){
+ return {
+ src: $.attr(this, 'url') || $.attr(this, 'href'),
+ type: $.attr(this, 'type')
+ };
+ }
+
+ function filterNode(){
+ return this.nodeType == 1;
+ }
+
+ $.extend(Playlist.prototype, {
+ on: function(){
+ $.fn.on.apply($(this), arguments);
+ },
+ off: function(){
+ $.fn.off.apply($(this), arguments);
+ },
+ _detectListType: function(){
+ var fullData;
+ if(typeof this.list == 'string'){
+ this._createListFromUrl();
+ return;
+ }
+ if(this.list.nodeName || (this.list.length > 0 && this.list[0].nodeName)){
+ this._createListFromDom();
+ } else if(this.list.responseData && this.list.responseData.feed){
+ fullData = this.list.responseData.feed;
+ this.list = (fullData.entries || []).map(mapJsonFeed);
+ this.list.fullData = fullData;
+ }
+ this.deferred.resolveWith(this);
+
+ },
+ _createListFromUrl: function(){
+ var that = this;
+ this.options.ajax.url = this.list;
+ this.options.mapUrl(this.options.ajax, function(list){
+ that.list = list;
+ that.deferred.resolveWith(that);
+ });
+ },
+ _createListFromDom: function(){
+ var that = this;
+
+ this.$rendered = $(this.list).eq(0);
+ this.list = [];
+
+ if(this.$rendered){
+ this._addDomList();
+ this.list = this.$rendered.children().map(function(){
+ return that._createItemFromDom(this);
+ }).get();
+ }
+ },
+ _createItemFromDom: function(dom){
+ var item = this.options.mapDom(dom);
+ this._addItemData(item, dom);
+ return item;
+ },
+ _fire: function(evt, extra){
+ var evt = $.Event(evt);
+ $(this).triggerHandler(evt, extra);
+ $(this.playlists).triggerHandler(evt, $.merge([{list: this}], extra || []));
+ if(this.$rendered){
+ this.$rendered.triggerHandler(evt, extra);
+ }
+ },
+ _addDomList: function(){
+ this.$rendered
+ .attr({
+ 'data-autoplay': this.options.autoplay,
+ 'data-loop': this.options.loop
+ })
+ .addClass('media-playlist')
+ .data('playlist', this)
+ ;
+ },
+ _addItemData: function(item, dom){
+ var that = this;
+ item.$item = $(dom).data('itemData', item);
+
+ if(item == this._selectedItem){
+ item.$item.addClass('selected-item');
+ }
+ if(this.options.addItemEvents){
+ item.$item.on('click.playlist', function(e){
+ if(that.options.addItemEvents){
+ that.playItem(item, e);
+ return false;
+ }
+ });
+ }
+ },
+ _addEvents: function(that){
+ var o = that.options;
+ var onEnded = function(e){
+ if(o.autoplay){
+ that.playNext(e);
+ }
+ };
+ this.media.on('ended', onEnded);
+ this._remove = function(){
+ that.media.off('ended', onEnded);
+ that.autoplay(false);
+
+ if(that.$rendered){
+ that.$rendered.remove();
+ }
+
+ that._fire('removelist');
+ };
+ },
+ _remove: function(){
+ this._fire('removelist');
+ },
+ render: function(callback){
+ if(this.$rendered){
+ callback(this.$rendered, this.player, this);
+ } else {
+ this.deferred.done(function(){
+ var nodeName;
+ var that = this;
+ var items = [];
+ if(!this.$rendered){
+ $.each(this.list, function(i, item){
+ var domItem = $($.parseHTML(that.options.renderer(item, that.options.itemTmpl))).filter(filterNode)[0];
+ that._addItemData(item, domItem);
+ items.push(domItem);
+ });
+ nodeName = (items[0] && items[0].nodeName || '').toLowerCase();
+
+ switch (nodeName){
+ case 'li':
+ this.$rendered = $.parseHTML('');
+ break;
+ case 'option':
+ this.$rendered = $.parseHTML('');
+ break;
+ default:
+ this.$rendered = $.parseHTML('');
+ break;
+ }
+ this.$rendered = $(this.$rendered).html(items);
+ this._addDomList();
+ }
+ callback(this.$rendered, this.player, this);
+ });
+ }
+ },
+ /*
+
+ addItem: function(item, pos){
+
+ },
+ removeItem: function(item){
+
+ },
+ */
+ _loadItem: function(item){
+ var media = this.media;
+ media.attr('poster', item.poster || '');
+
+ $('track', media).remove();
+
+ $.each(item.tracks || [], function(i, track){
+ $('').attr(track).appendTo(media);
+ });
+ if(!item.srces){
+ item.srces = item;
+ }
+ media.jmeProp('srces', item.srces);
+ },
+ _getItem: function(item){
+ if(item && (item.nodeName || item.jquery || typeof item == 'string')){
+ item = $(item).data('itemData');
+ }
+ return item;
+ },
+ playItem: function(item, e){
+ var media;
+ this.selectedItem(item, e);
+ if(item){
+ media = this.media.play();
+ setTimeout(function(){
+ media.play();
+ }, 9);
+ }
+ },
+ selectedIndex: function(index, e){
+ if(arguments.length){
+ this.selectedItem(this.list[index], e);
+ } else {
+ return this._selectedIndex;
+ }
+ },
+
+ selectedItem: function(item, e){
+ var oldItem, found;
+
+ if(arguments.length){
+ found = -1;
+ item = this._getItem(item);
+ if(item){
+ $.each(this.list, function(i){
+ if(item == this){
+ found = i;
+ return false;
+ }
+ });
+ }
+
+ if(found >= 0){
+ this._loadItem(this.list[found]);
+ }
+
+ if(found != this._selectedIndex){
+ oldItem = this._selectedItem || null;
+ if(oldItem && oldItem.$item){
+ oldItem.$item.removeClass('selected-item');
+ }
+ this._selectedItem = this.list[found] || null;
+ this._selectedIndex = found;
+ if(this._selectedItem && this._selectedItem.$item){
+ this._selectedItem.$item.addClass('selected-item');
+ }
+ if(oldItem !== this._selectedItem){
+ this._fire('itemchange', [{oldItem: oldItem, from: e || null}]);
+ }
+ }
+
+ } else {
+ return this._selectedItem;
+ }
+ },
+ playNext: function(){
+ var item = this.getNext();
+ if(item){
+ this.playItem(item);
+ }
+ },
+ playPrev: function(){
+ var item = this.getPrev();
+ if(item){
+ this.playItem(item);
+ }
+ },
+ getNext: function(){
+ var index = this._selectedIndex + 1;
+ return this.list[index] || (this.options.loop ? this.list[0] : null);
+ },
+ getPrev: function(){
+ var index = this._selectedIndex - 1;
+ return this.list[index] || (this.options.loop ? this.list[this.list.length - 1] : null);
+ }
+ });
+
+ [{name: 'autoplay', fn: 'getAutoplayList'}, {name: 'showcontrols', fn: 'getShowcontrolsList'}, {name: 'loop'}].forEach(function(desc){
+ Playlist.prototype[desc.name] = function(value){
+ var curList;
+ if(arguments.length){
+ value = !!value;
+
+ if(value && desc.fn){
+ curList = this.playlists[desc.fn]();
+ if(curList && curList != this){
+ curList[desc.name](false);
+ }
+ }
+
+ if(this.options[desc.name] != value){
+ this.options[desc.name] = value;
+ if(this.$rendered){
+ this.$rendered.attr('data-'+desc.name, value);
+ }
+ this._fire(desc.name+'change');
+ }
+ } else {
+ return this.options[desc.name];
+ }
+ }
+ });
+
+ jme.defineProp('playlists', {
+ writable: false,
+ get: function(elem){
+ var data = $.jme.data(elem);
+
+ if(elem != data.player[0]){return null;}
+ if(!data.playlists){
+ data.playlists = new PlaylistList(data);
+ }
+ return data.playlists;
+ }
+ });
+
+ jme.defineMethod('addPlaylist', function(list, options){
+ var playlists = $.jme.prop(this, 'playlists');
+ if(playlists && playlists.add){
+ return playlists.add(list, options);
+ }
+ return null;
+ });
+
+ [
+ {name: 'playlist-prev', text: 'previous', get: 'getPrev', play: 'playPrev'},
+ {name: 'playlist-next', text: 'next', get: 'getNext', play: 'playNext'}
+ ]
+ .forEach(function(desc){
+ $.jme.registerPlugin(desc.name, {
+ structure: btnStructure,
+ text: desc.text,
+ _create: function(control, media, base){
+ var cList;
+ var playlists = base.jmeProp('playlists');
+
+ function itemChange(){
+ var item = cList[desc.get]();
+ if(item){
+ control.prop({'disabled': false, title: item.title});
+ } else {
+ control.prop({'disabled': true, title: ''});
+ }
+ }
+
+ function listchange(){
+ var newClist = playlists.getShowcontrolsList();
+ if(newClist != cList){
+ if(cList){
+ cList.off('itemchange', itemChange);
+ }
+ cList = newClist;
+ if(cList){
+ cList.on('itemchange', itemChange);
+ itemChange();
+ }
+ }
+ }
+
+ control.on('click', function(){
+ if(cList){
+ cList[desc.play]();
+ }
+ });
+
+ playlists.on({
+ 'addlist removelist showcontrolschange':listchange
+ });
+ listchange();
+ }
+ });
+ })
+ ;
+
+
+ // Simple JavaScript Templating
+ (function() {
+ var cache = {};
+ $.jme.tmpl = function tmpl(str, data) {
+ // Figure out if we're getting a template, or if we need to
+ // load the template - and be sure to cache the result.
+ if(!cache[str]){
+ cache[str] = new Function("obj",
+ "var p=[],print=function(){p.push.apply(p,arguments);};" +
+
+ // Introduce the data as local variables using with(){}
+ "with(obj){p.push('" +
+
+ // Convert the template into pure JavaScript
+ str.replace(/[\r\t\n]/g, " ")
+ .replace(/'(?=[^%]*%>)/g,"\t")
+ .split("'").join("\\'")
+ .split("\t").join("'")
+ .replace(/<%=(.+?)%>/g, "',$1,'")
+ .split("<%").join("');")
+ .split("%>").join("p.push('")
+ + "');}return p.join('');");
+ }
+
+ // Provide some basic currying to the user
+ return data ? cache[str](data) : cache[str];
+ };
+ })();
+ $.jme.Playlist = Playlist;
+ webshims.isReady('playlist', true);
+});
diff --git a/public/webshims/shims/combos/99.js b/public/webshims/shims/combos/99.js
new file mode 100644
index 00000000..560becfa
--- /dev/null
+++ b/public/webshims/shims/combos/99.js
@@ -0,0 +1,828 @@
+webshims.register('jmebase', function($, webshims, window, doc, undefined){
+ "use strict";
+ var props = {};
+ var fns = {};
+ var slice = Array.prototype.slice;
+ var readyLength = 0;
+ var options = $.extend({selector: '.mediaplayer'}, webshims.cfg.mediaelement.jme);
+ var baseSelector = options.selector;
+
+ webshims.cfg.mediaelement.jme = options;
+
+ if(!$.jme){
+ $.jme = {};
+ }
+
+ $.extend($.jme, {
+ pluginsClasses: [],
+ pluginsSel: '',
+ plugins: {},
+ props: props,
+ fns: fns,
+ data: function(elem, name, value){
+ var data = $(elem).data('jme') || $.data(elem, 'jme', {});
+ if(value === undefined){
+ return (name) ? data[name] : data;
+ } else {
+ data[name] = value;
+ }
+ },
+ runPlugin: function(sel){
+ if(readyLength){
+ $(document.querySelectorAll(baseSelector)).each(function(){
+ var controls = this.querySelectorAll(sel);
+ if(controls.length){
+ $(this).jmeFn('addControls', controls);
+ }
+ });
+ }
+ },
+ registerPlugin: function(name, plugin){
+ this.plugins[name] = plugin;
+ if(!plugin.nodeName){
+ plugin.nodeName = '';
+ }
+ if(!plugin.className){
+ plugin.className = name;
+ }
+
+ this.pluginsClasses.push('.'+plugin.className);
+
+ this.pluginsSel = this.pluginsClasses.join(', ');
+
+ options[name] = $.extend(plugin.options || {}, options[name]);
+
+ if(options[name] && options[name].text){
+ plugin.text = options[name].text;
+ } else if(options.i18n && options.i18n[name]){
+ plugin.text = options.i18n[name];
+ }
+ this.runPlugin('.'+plugin.className);
+ },
+ configmenuPlugins: {},
+ addToConfigmenu: function(name, create){
+ this.configmenuPlugins[name] = create;
+ },
+ defineMethod: function(name, fn){
+ fns[name] = fn;
+ },
+ defineProp: function(name, desc){
+ if(!desc){
+ desc = {};
+ }
+ if(!desc.set){
+ if(desc.readonly){
+ desc.set = function(){
+ throw(name +' is readonly');
+ };
+ } else {
+ desc.set = $.noop;
+ }
+ }
+ if(!desc.get){
+ desc.get = function(elem){
+ return $.jme.data(elem, name);
+ };
+ }
+ props[name] = desc;
+ },
+ prop: function(elem, name, value){
+ if(!props[name]){
+ return $.prop(elem, name, value);
+ }
+ if(value === undefined){
+ return props[name].get( elem );
+ } else {
+ var setValue = props[name].set(elem, value);
+ if(setValue === undefined){
+ setValue = value;
+ }
+ if(setValue != 'noDataSet'){
+ $.jme.data(elem, name, setValue);
+ }
+ }
+ }
+ });
+
+ $.fn.jmeProp = function(name, value){
+ return $.access( this, $.jme.prop, name, value, arguments.length > 1 );
+ };
+
+ $.fn.jmeFn = function(fn){
+ var args = slice.call( arguments, 1 );
+ var ret;
+ this.each(function(){
+ if(!$.jme.data(this).media){
+ $(this).closest(baseSelector).jmePlayer();
+ webshims.warn('jmeFn called to early or on wrong element!');
+ }
+ ret = (fns[fn] || $.prop(this, fn)).apply(this, args);
+ if(ret !== undefined){
+ return false;
+ }
+ });
+ return (ret !== undefined) ? ret : this;
+ };
+ var idlStates = {
+ emptied: 1,
+ pause: 1
+ };
+ var unwaitingEvents = {
+ canplay: 1, canplaythrough: 1
+ };
+
+
+ $.jme.initJME = function(context, insertedElement){
+ readyLength += $(context.querySelectorAll(baseSelector)).add(insertedElement.filter(baseSelector)).jmePlayer().length;
+ };
+
+
+ $.jme.getDOMList = function(attr){
+ var list = [];
+ if(!attr){
+ attr = [];
+ }
+ if(typeof attr == 'string'){
+ attr = attr.split(' ');
+ }
+ $.each(attr, function(i, id){
+ if(id){
+ id = document.getElementById(id);
+ if(id){
+ list.push(id);
+ }
+ }
+ });
+ return list;
+ };
+
+
+ $.jme.getButtonText = function(button, classes){
+ var isCheckbox;
+ var lastState;
+ var txtChangeFn = function(state){
+ if(lastState === state){return;}
+ lastState = state;
+
+
+ button
+ .removeClass(classes[(state) ? 0 : 1])
+ .addClass(classes[state])
+ ;
+
+ if(isCheckbox){
+ button.prop('checked', !!state);
+ (button.data('checkboxradio') || {refresh: $.noop}).refresh();
+ }
+ };
+
+ if (button.is('[type="checkbox"], [type="radio"]')){
+ button.prop('checked', function(){
+ return this.defaultChecked;
+ });
+ isCheckbox = true;
+ } else if(button.is('a')){
+ button.on('click', function(e){
+ e.preventDefault();
+ });
+ }
+
+ return txtChangeFn;
+ };
+
+ $.fn.jmePlayer = function(opts){
+
+ return this.each(function(){
+
+
+ var mediaUpdateFn, canPlay, removeCanPlay, canplayTimer, lastState, stopEmptiedEvent, forceRender;
+ var media = $('audio, video', this).eq(0);
+ var base = $(this);
+
+ var jmeData = $.jme.data(this);
+ var mediaData = $.jme.data(media[0]);
+
+
+ base.addClass(media.prop('nodeName').toLowerCase()+'player');
+ mediaData.player = base;
+ mediaData.media = media;
+ if(!jmeData.media){
+ forceRender = function(){
+ base[0].className = base[0].className;
+ };
+ removeCanPlay = function(){
+ media.off('canplay', canPlay);
+ clearTimeout(canplayTimer);
+ };
+ canPlay = function(){
+ var state = (media.prop('paused')) ? 'idle' : 'playing';
+ base.attr('data-state', state);
+ };
+ mediaUpdateFn = function(e){
+ var state = e.type;
+ var readyState;
+ var paused;
+ removeCanPlay();
+
+ if(unwaitingEvents[state] && lastState != 'waiting'){
+ return;
+ }
+
+ if(stopEmptiedEvent && state == 'emptied'){
+ return;
+ }
+
+ if(state == 'ended' || $.prop(this, 'ended')){
+ state = 'ended';
+ } else if(state == 'waiting'){
+
+ if($.prop(this, 'readyState') > 2){
+ state = '';
+ } else {
+ canplayTimer = setTimeout(function(){
+ if(media.prop('readyState') > 2){
+ canPlay();
+ }
+ }, 9);
+ media.on('canPlay', canPlay);
+ }
+
+ } else if(idlStates[state]){
+ state = 'idle';
+ } else {
+ readyState = $.prop(this, 'readyState');
+ paused = $.prop(this, 'paused');
+ if(!paused && readyState < 3){
+ state = 'waiting';
+ } else if(!paused && readyState > 2){
+ state = 'playing';
+ } else {
+ state = 'idle';
+ }
+ }
+
+ if(state == 'idle' && base._seekpause){
+ state = false;
+ }
+
+ if(state){
+ lastState = state;
+ base.attr('data-state', state);
+ setTimeout(forceRender);
+ }
+ };
+
+
+ jmeData.media = media;
+ jmeData.player = base;
+ media
+ .on('ended emptied play', (function(){
+ var timer;
+ var releaseEmptied = function(){
+ stopEmptiedEvent = false;
+ };
+ var ended = function(){
+ removeCanPlay();
+ media.jmeFn('pause');
+ if(!options.noReload && media.prop('ended') && media.prop('paused') && !media.prop('autoplay') && !media.prop('loop') && !media.hasClass('no-reload')){
+ stopEmptiedEvent = true;
+ media.jmeFn('load');
+ base.attr('data-state', 'ended');
+ setTimeout(releaseEmptied);
+
+ }
+ };
+ return function(e){
+
+ clearTimeout(timer);
+ if(e.type == 'ended' && !options.noReload && !media.prop('autoplay') && !media.prop('loop') && !media.hasClass('no-reload')){
+ timer = setTimeout(ended);
+ }
+ };
+ })())
+ .on('emptied waiting canplay canplaythrough playing ended pause mediaerror', mediaUpdateFn)
+ .on('volumechange updateJMEState', function(){
+ var volume = $.prop(this, 'volume');
+ base[!volume || $.prop(this, 'muted') ? 'addClass' : 'removeClass']('state-muted');
+
+ if(volume < 0.01){
+ volume = 'no';
+ } else if(volume < 0.36){
+ volume = 'low';
+ } else if(volume < 0.7){
+ volume = 'medium';
+ } else {
+ volume = 'high';
+ }
+ base.attr('data-volume', volume);
+ })
+ ;
+ if($.jme.pluginsSel){
+ base.jmeFn('addControls', $(base[0].querySelectorAll($.jme.pluginsSel)));
+ }
+ if(mediaUpdateFn){
+ media.on('updateJMEState', mediaUpdateFn).triggerHandler('updateJMEState');
+ }
+ }
+ });
+ };
+
+
+ $.jme.defineProp('isPlaying', {
+ get: function(elem){
+ return (!$.prop(elem, 'ended') && !$.prop(elem, 'paused') && $.prop(elem, 'readyState') > 1 && !$.data(elem, 'mediaerror'));
+ },
+ readonly: true
+ });
+
+ $.jme.defineProp('player', {
+ readonly: true
+ });
+
+ $.jme.defineProp('media', {
+ readonly: true
+ });
+
+ $.jme.defineProp('srces', {
+ get: function(elem){
+ var srces;
+ var data = $.jme.data(elem);
+ var src = data.media.prop('src');
+ if(src){
+ return [{src: src}];
+ }
+ srces = $.map($('source', data.media).get(), function(source){
+ var i, len;
+ var src = {
+ src: $.prop(source, 'src')
+ };
+ var attributes = source.attributes;
+
+ for(i = 0, len = attributes.length; i < len; i++){
+ if(!('specified' in attributes[i]) || attributes[i].specified){
+ src[attributes[i].nodeName] = attributes[i].nodeValue;
+ }
+ }
+ return src;
+ });
+ return srces;
+ },
+ set: function(elem, srces){
+ var data = $.jme.data(elem);
+
+ var setSrc = function(i, src){
+ if(typeof src == 'string'){
+ src = {src: src};
+ }
+ $(document.createElement('source')).attr(src).appendTo(data.media);
+ };
+ data.media.removeAttr('src').find('source').remove();
+ if($.isArray(srces)){
+ $.each(srces, setSrc);
+ } else {
+ setSrc(0, srces);
+ }
+ data.media.jmeFn('load');
+ return 'noDataSet';
+ }
+ });
+
+ $.jme.defineMethod('togglePlay', function(){
+ $(this).jmeFn( ( props.isPlaying.get(this) ) ? 'pause' : 'play' );
+ });
+
+
+ $.jme.defineMethod('addControls', function(controls){
+ var data = $.jme.data(this) || {};
+
+ if(!data.media){return;}
+ var oldControls = $.jme.data(data.player[0], 'controlElements') || $([]);
+ controls = $(controls);
+ if($.jme.pluginsSel){
+ controls = controls.find($.jme.pluginsSel).add(controls.filter($.jme.pluginsSel));
+ }
+ if(controls.length){
+ $.each($.jme.plugins, function(name, plugin){
+ var control, options, i, opt;
+ var pluginControls = controls.filter('.'+plugin.className);
+
+ for(i = 0; i < pluginControls.length; i++){
+ control = $(pluginControls[i]);
+ options = $.jme.data(pluginControls[i]);
+ options.player = data.player;
+ options.media = data.media;
+ if(!options._rendered){
+ options._rendered = true;
+
+ if(plugin.options){
+ for(opt in plugin.options){
+ if(!(opt in options)){
+ options[opt] = plugin.options[opt];
+ }
+ }
+ }
+
+ plugin._create(control, data.media, data.player, options);
+ }
+ }
+
+ });
+
+ $.jme.data(data.player[0], 'controlElements', oldControls.add(controls));
+
+ data.player.triggerHandler('controlsadded');
+ }
+ });
+
+ webshims.ready('DOM mediaelement', function(){
+ webshims.isReady('jme', true);
+ webshims.addReady($.jme.initJME);
+ webshims.isReady('jme-base', true);
+
+ if(webshims.cfg.debug !== false && document.getElementsByTagName('video').length && !document.querySelector(baseSelector)){
+ webshims.warn("found video element but video wasn't wrapped inside a ."+ baseSelector +" element. Will not add control UI");
+ }
+ });
+
+});
+;webshims.register('mediacontrols', function($, webshims, window){
+ "use strict";
+ var pseudoClasses = 'pseudoClasses';
+
+ var options = webshims.cfg.mediaelement.jme;
+ var baseSelector = options.selector;
+ var jme = $.jme;
+ var unknownStructure = '';
+ var btnStructure = '';
+ var slideStructure = '';
+ var timeStructure = '00:00
';
+
+ var noVolumeClass = (function(){
+ var audio;
+ var ret = '';
+
+ if(window.Audio){
+ try {
+ audio = new Audio();
+ audio.volume = 0.55;
+ ret = ((Math.round(audio.volume * 100) / 100) == 0.55) ? '' : ' no-volume-api';
+ } catch(e){}
+
+ }
+ return ret;
+ })();
+
+ var getBarHtml = (function(){
+ var cache = {};
+ var regTemplate = /\{\{(.+?)\}\}/igm;
+
+ return function(template, invalidCache){
+ if(!template){
+ template = options.barTemplate;
+ }
+ if(!cache[template] || invalidCache){
+ cache[template] = template.replace(regTemplate, function(match, matchName){
+ var plugin = jme.plugins[matchName];
+ if(plugin){
+ if(!plugin.structure){
+ webshims.warn('no structure option provided for plugin: '+ matchName +'. Fallback to standard div');
+ plugin.structure = unknownStructure;
+ }
+ return plugin.structure.replace('{%class%}', matchName).replace('{%text%}', plugin.text || '');
+ }
+ return match;
+ });
+ }
+
+ return cache[template] || '';
+ };
+ })();
+ var ios6 = /iP(hone|od|ad)/i.test(navigator.platform) && parseInt(((navigator.appVersion).match(/OS (\d+)_\d+/) || ['','8'])[1], 10) < 7;
+ var loadLazy = function(){
+ if(!loadLazy.loaded){
+ loadLazy.loaded = true;
+ webshims.loader.loadList(['mediacontrols-lazy', 'range-ui']);
+ }
+ };
+ var lazyLoadPlugin = function(fn){
+ if(!fn){
+ fn = '_create';
+ }
+ var rfn = function(c, media){
+ var obj = this;
+ var args = arguments;
+ loadLazy();
+ webshims.ready('mediacontrols-lazy', function(){
+ if(rfn != obj[fn] && $.data(media[0])){
+ return obj[fn].apply(obj, args);
+ } else {
+ webshims.error('stop too much recursion');
+ }
+ });
+ };
+ return rfn;
+ };
+
+ webshims.loader.addModule('mediacontrols-lazy', {
+ src: 'jme/mediacontrols-lazy'
+ });
+
+ var userActivity = {
+ _create: lazyLoadPlugin()
+ };
+ jme.plugins.useractivity = userActivity;
+
+ jme.defineProp('controlbar', {
+ set: function(elem, value){
+ value = !!value;
+ var controls, playerSize;
+ var data = jme.data(elem);
+ var controlBar = $('div.jme-mediaoverlay, div.jme-controlbar', data.player);
+ var structure = '';
+ if(value && !controlBar[0]){
+ if(data._controlbar){
+ data._controlbar.appendTo(data.player);
+ } else {
+ if(ios6){
+ data.media.removeAttr('controls');
+ data.media.mediaLoad();
+ }
+ data.media.prop('controls', false);
+ structure = getBarHtml();
+ data._controlbar = $( options.barStructure );
+ controlBar = data._controlbar.find('div.jme-cb-box').addClass('media-controls');
+ controls = data._controlbar.filter('.jme-media-overlay');
+ controls = controls.add( controlBar );
+ $(structure).appendTo(controlBar);
+ data._controlbar.appendTo(data.player);
+ data.player.jmeFn('addControls', controls);
+
+ playerSize = (function(){
+ var lastSize = {};
+ var sizes = [
+ {size: 290, name: 'xx-small', names: 's xs xxs'},
+ {size: 380, name: 'x-small', names: 's xs'},
+ {size: 478, name: 'small', names: 's'},
+ {size: 756, name: 'medium', names: 'm'},
+ {size: 1024, name: 'large', names: 'l'},
+ {size: Number.MAX_VALUE, name: 'x-large', names: 'l xl'}
+ ];
+
+
+ var len = sizes.length;
+ return function(){
+ var size;
+ var i = 0;
+ var width = data.player.outerWidth();
+ var fSize = Math.max(parseInt(data.player.css('fontSize'), 10) || 16, 13);
+
+ width = width * (16 / fSize);
+ for(; i < len; i++){
+ if(sizes[i].size >= width){
+ size = sizes[i];
+ break;
+ }
+ }
+
+ if(lastSize.name != size.name){
+ lastSize = size;
+ data.player.attr('data-playersize', size.name);
+ data.player.attr('data-playersizes', size.names);
+ }
+ };
+ })();
+ var $poster = $('').insertAfter(data.media);
+ var posterState = (function(){
+ var lastPosterState, lastYoutubeState, lastPoster;
+ var hasFlash = window.swfmini && swfmini.hasFlashPlayerVersion('10.0.3');
+ var regYt = /youtube\.com\/[watch\?|v\/]+/i;
+
+ var isInitial = data.media.prop('paused');
+ if(isInitial){
+ data.player.addClass('initial-state');
+ }
+ if(!('backgroundSize' in $poster[0].style)){
+ data.player.addClass('no-backgroundsize');
+ }
+ data.media.on('playing waiting seeked seeking', function(){
+ if(isInitial){
+ isInitial = false;
+ data.player.removeClass('initial-state');
+ }
+ });
+ return function(){
+ var poster = data.media.attr('poster');
+ var hasPoster = !!poster;
+ var currentSrc = data.media.prop('currentSrc') || '';
+ var isYt = regYt.test(currentSrc);
+ var hasYt = (hasFlash && hasPoster) ? false : isYt;
+
+ if(!hasPoster && isYt){
+ poster = currentSrc.match(/(?:youtube\.com\/(?:[^\/]+\/.+\/|(?:v|e(?:mbed)?)\/|.*[?&]v=)|youtu\.be\/)([^"&?\/ ]{11})/i) || '';
+ if(poster){
+ poster = 'https://img.youtube.com/vi/'+ poster[1] +'/0.jpg';
+ hasPoster = !!poster;
+ }
+ }
+
+ if(lastPoster !== poster){
+ lastPoster = poster;
+ $poster[0].style.backgroundImage = poster ? 'url('+poster+')' : '';
+ }
+
+ if(lastPosterState !== hasPoster){
+ lastPosterState = hasPoster;
+ data.player[hasPoster ? 'removeClass' : 'addClass']('no-poster');
+ }
+
+ if(data.media.prop('paused')){
+ data.player.addClass('initial-state');
+ isInitial = true;
+ }
+
+ if(lastYoutubeState !== hasYt){
+ lastYoutubeState = hasYt;
+ data.player[hasYt ? 'addClass' : 'removeClass']('has-ytposter');
+ }
+ };
+ })();
+
+
+ userActivity._create(data.player, data.media, data.player);
+
+ data.media.on('emptied loadstart', function(){
+ setTimeout(posterState);
+ });
+
+ playerSize();
+ posterState();
+ webshims.ready('dom-support', function(){
+ data.player.onWSOff('updateshadowdom', playerSize);
+ controls.add(data._controlbar).add($poster).addClass(webshims.shadowClass);
+ webshims.addShadowDom();
+ });
+ }
+
+ } else if(!value) {
+ controlBar.detach();
+ }
+ return value;
+ }
+ });
+
+ jme.registerPlugin('play-pause', {
+ structure: btnStructure,
+ text: 'play / pause',
+ _create: lazyLoadPlugin()
+ });
+
+ jme.registerPlugin('mute-unmute', {
+ structure: btnStructure,
+ text: 'mute / unmute',
+ _create: lazyLoadPlugin()
+ });
+
+ jme.registerPlugin('jme-media-overlay', {
+ _create: lazyLoadPlugin()
+ });
+
+
+
+
+ jme.registerPlugin('volume-slider', {
+ structure: slideStructure,
+ text: 'volume level',
+ _create: lazyLoadPlugin()
+ });
+
+ jme.registerPlugin('time-slider', {
+ structure: slideStructure,
+
+ options: {
+ format: ['mm', 'ss']
+ },
+ text: 'time position',
+ _create: lazyLoadPlugin()
+ });
+
+
+ jme.defineProp('format', {
+ set: function(elem, format){
+ if(!$.isArray(format)){
+ format = format.split(':');
+ }
+ var data = jme.data(elem);
+ data.format = format;
+ $(elem).triggerHandler('updatetimeformat');
+ data.player.triggerHandler('updatetimeformat');
+ return 'noDataSet';
+ }
+ });
+
+ jme.registerPlugin('duration-display', {
+ structure: timeStructure,
+ options: {
+ format: "mm:ss"
+ },
+ _create: lazyLoadPlugin()
+ });
+
+ jme.defineProp('countdown', {
+ set: function(elem, value){
+
+ var data = jme.data(elem);
+ data.countdown = !!value;
+ $(elem).triggerHandler('updatetimeformat');
+ data.player.triggerHandler('updatetimeformat');
+ return 'noDataSet';
+ }
+ });
+
+ jme.registerPlugin('currenttime-display', {
+ structure: timeStructure,
+ options: {
+ format: "mm:ss",
+ countdown: false
+ },
+ _create: lazyLoadPlugin()
+ });
+
+
+ /**
+ * Added Poster Plugin
+ * @author mderting
+ */
+
+ /*
+ * the old technique wasn't fully bullet proof
+ * beside this, jme2 adovactes to use the new improved state-classes to handle visual effect on specific state (see CSS change)
+ */
+ jme.registerPlugin('poster-display', {
+ structure: '',
+ options: {
+ },
+ _create: lazyLoadPlugin()
+ });
+
+
+ jme.registerPlugin('fullscreen', {
+
+ options: {
+ fullscreen: true,
+ autoplayfs: false
+ },
+ structure: btnStructure,
+ text: 'enter fullscreen / exit fullscreen',
+ _create: lazyLoadPlugin()
+ });
+
+ jme.registerPlugin('mediaconfigmenu', {
+ structure: btnStructure,
+ text: 'configuration',
+ _create: lazyLoadPlugin()
+ });
+
+
+ jme.registerPlugin('captions', {
+ structure: btnStructure,
+ text: 'subtitles',
+ _create: function(control, media, base){
+ var trackElems = media.find('track').filter(':not([kind]), [kind="subtitles"], [data-kind="subtitles"], [kind="captions"], [data-kind="captions"]');
+ control.wsclonedcheckbox = $(control).clone().attr({role: 'checkbox'}).insertBefore(control);
+ base.attr('data-tracks', trackElems.length > 1 ? 'many' : trackElems.length);
+ control.attr('aria-haspopup', 'true');
+ lazyLoadPlugin().apply(this, arguments);
+ }
+ });
+
+
+ jme.registerPlugin('chapters', {
+ structure: btnStructure,
+ text: 'chapters',
+ _create: function(control, media, base){
+ var trackElems = media.find('track').filter('[kind="chapters"], [data-kind="chapters"]');
+ control.attr('aria-haspopup', 'true');
+ if(trackElems.length){
+ webshims._polyfill(['track']);
+ base.addClass('has-chapter-tracks');
+ }
+ lazyLoadPlugin().apply(this, arguments);
+ }
+ });
+
+
+
+ webshims.ready(webshims.cfg.mediaelement.plugins.concat(['mediaelement', 'jme-base']), function(){
+ if(!options.barTemplate){
+ options.barTemplate = '{{play-pause}}
{{playlist-prev}}
{{playlist-next}}
{{currenttime-display}}
{{time-slider}}
{{duration-display}}
{{mute-unmute}}
{{volume-slider}}
{{fullscreen}}
';
+ }
+ if(!options.barStructure){
+ options.barStructure = '';
+ }
+
+ webshims.addReady(function(context, insertedElement){
+ $(baseSelector, context).add(insertedElement.filter(baseSelector)).jmeProp('controlbar', true);
+ });
+ });
+ webshims.ready('WINDOWLOAD', loadLazy);
+});
diff --git a/public/webshims/shims/details.js b/public/webshims/shims/details.js
new file mode 100644
index 00000000..c2325641
--- /dev/null
+++ b/public/webshims/shims/details.js
@@ -0,0 +1,148 @@
+webshims.register('details', function($, webshims, window, doc, undefined, options){
+ var isInterActiveSummary = function(summary){
+ var details = $(summary).parent('details');
+ if(details[0] && details.children(':first').get(0) === summary){
+ return details;
+ }
+ };
+
+ var bindDetailsSummary = function(summary, details){
+ summary = $(summary);
+ details = $(details);
+ var oldSummary = $.data(details[0], 'summaryElement');
+ $.data(summary[0], 'detailsElement', details);
+ if(!oldSummary || summary[0] !== oldSummary[0]){
+ if(oldSummary){
+ if(oldSummary.hasClass('fallback-summary')){
+ oldSummary.remove();
+ } else {
+ oldSummary
+ .off('.summaryPolyfill')
+ .removeData('detailsElement')
+ .removeAttr('role')
+ .removeAttr('tabindex')
+ .removeAttr('aria-expanded')
+ .removeClass('summary-button')
+ .find('span.details-open-indicator')
+ .remove()
+ ;
+ }
+ }
+ $.data(details[0], 'summaryElement', summary);
+ details.prop('open', details.prop('open'));
+ }
+ };
+ var getSummary = function(details){
+ var summary = $.data(details, 'summaryElement');
+ if(!summary){
+ summary = $(details).children('summary:first-child');
+ if(!summary[0]){
+ $(details).prependPolyfill(''+ options.text +'');
+ summary = $.data(details, 'summaryElement');
+ } else {
+ bindDetailsSummary(summary, details);
+ }
+ }
+ return summary;
+ };
+
+// var isOriginalPrevented = function(e){
+// var src = e.originalEvent;
+// if(!src){return e.isDefaultPrevented();}
+//
+// return src.defaultPrevented || src.returnValue === false ||
+// src.getPreventDefault && src.getPreventDefault();
+// };
+
+ webshims.createElement('summary', function(){
+ var details = isInterActiveSummary(this);
+ if(!details || $.data(this, 'detailsElement')){return;}
+ var timer;
+ var stopNativeClickTest;
+ var tabindex = $.attr(this, 'tabIndex') || '0';
+ bindDetailsSummary(this, details);
+ $(this)
+ .on({
+ 'focus.summaryPolyfill': function(){
+ $(this).addClass('summary-has-focus');
+ },
+ 'blur.summaryPolyfill': function(){
+ $(this).removeClass('summary-has-focus');
+ },
+ 'mouseenter.summaryPolyfill': function(){
+ $(this).addClass('summary-has-hover');
+ },
+ 'mouseleave.summaryPolyfill': function(){
+ $(this).removeClass('summary-has-hover');
+ },
+ 'click.summaryPolyfill': function(e){
+ var details = isInterActiveSummary(this);
+ if(details){
+ if(!stopNativeClickTest && e.originalEvent){
+ stopNativeClickTest = true;
+ e.stopImmediatePropagation();
+ e.preventDefault();
+ $(this).trigger('click');
+ stopNativeClickTest = false;
+ return false;
+ } else {
+ clearTimeout(timer);
+
+ timer = setTimeout(function(){
+ if(!e.isDefaultPrevented()){
+ details.prop('open', !details.prop('open'));
+ }
+ }, 0);
+ }
+ }
+ },
+ 'keydown.summaryPolyfill': function(e){
+ if( (e.keyCode == 13 || e.keyCode == 32) && !e.isDefaultPrevented()){
+ stopNativeClickTest = true;
+ e.preventDefault();
+ $(this).trigger('click');
+ stopNativeClickTest = false;
+ }
+ }
+ })
+ .attr({tabindex: tabindex, role: 'button'})
+ .prepend('')
+ ;
+ webshims.moveToFirstEvent(this, 'click');
+ });
+
+ var initDetails;
+ webshims.defineNodeNamesBooleanProperty('details', 'open', function(val){
+ var summary = $($.data(this, 'summaryElement'));
+ if(!summary){return;}
+ var action = (val) ? 'removeClass' : 'addClass';
+ var details = $(this);
+ if (!initDetails && options.animate){
+ details.stop().css({width: '', height: ''});
+ var start = {
+ width: details.width(),
+ height: details.height()
+ };
+ }
+ summary.attr('aria-expanded', ''+val);
+ details[action]('closed-details-summary').children().not(summary[0])[action]('closed-details-child');
+ if(!initDetails && options.animate){
+ var end = {
+ width: details.width(),
+ height: details.height()
+ };
+ details.css(start).animate(end, {
+ complete: function(){
+ $(this).css({width: '', height: ''});
+ }
+ });
+ }
+
+ });
+ webshims.createElement('details', function(){
+ initDetails = true;
+ var summary = getSummary(this);
+ $.prop(this, 'open', $.prop(this, 'open'));
+ initDetails = false;
+ });
+});
diff --git a/public/webshims/shims/dom-extend.js b/public/webshims/shims/dom-extend.js
new file mode 100644
index 00000000..bad678ea
--- /dev/null
+++ b/public/webshims/shims/dom-extend.js
@@ -0,0 +1,1212 @@
+
+//this might was already extended by ES5 shim feature
+(function($){
+ "use strict";
+ var webshims = window.webshims;
+ if(webshims.defineProperties){return;}
+ var defineProperty = 'defineProperty';
+ var has = Object.prototype.hasOwnProperty;
+ var descProps = ['configurable', 'enumerable', 'writable'];
+ var extendUndefined = function(prop){
+ for(var i = 0; i < 3; i++){
+ if(prop[descProps[i]] === undefined && (descProps[i] !== 'writable' || prop.value !== undefined)){
+ prop[descProps[i]] = true;
+ }
+ }
+ };
+
+ var extendProps = function(props){
+ if(props){
+ for(var i in props){
+ if(has.call(props, i)){
+ extendUndefined(props[i]);
+ }
+ }
+ }
+ };
+
+ if(Object.create){
+ webshims.objectCreate = function(proto, props, opts){
+ extendProps(props);
+ var o = Object.create(proto, props);
+ if(opts){
+ o.options = $.extend(true, {}, o.options || {}, opts);
+ opts = o.options;
+ }
+ if(o._create && $.isFunction(o._create)){
+ o._create(opts);
+ }
+ return o;
+ };
+ }
+
+ if(Object[defineProperty]){
+ webshims[defineProperty] = function(obj, prop, desc){
+ extendUndefined(desc);
+ return Object[defineProperty](obj, prop, desc);
+ };
+ }
+ if(Object.defineProperties){
+ webshims.defineProperties = function(obj, props){
+ extendProps(props);
+ return Object.defineProperties(obj, props);
+ };
+ }
+ webshims.getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor;
+
+ webshims.getPrototypeOf = Object.getPrototypeOf;
+})(window.webshims.$);
+//DOM-Extension helper
+webshims.register('dom-extend', function($, webshims, window, document, undefined){
+ "use strict";
+ var supportHrefNormalized = !('hrefNormalized' in $.support) || $.support.hrefNormalized;
+ var supportGetSetAttribute = !('getSetAttribute' in $.support) || $.support.getSetAttribute;
+ var has = Object.prototype.hasOwnProperty;
+ webshims.assumeARIA = true;
+
+ if($('').attr('type') == 'text' || $('').attr('novalidate') === "" || ('required' in $('')[0].attributes)){
+ webshims.error("IE browser modes are busted in IE10+. Please test your HTML/CSS/JS with a real IE version or at least IETester or similiar tools");
+ }
+
+ if('debug' in webshims){
+ webshims.error('Use webshims.setOptions("debug", true||false||"noCombo"); to debug flag');
+ }
+
+ if (!webshims.cfg.no$Switch) {
+ var switch$ = function(){
+ if (window.jQuery && (!window.$ || window.jQuery == window.$) && !window.jQuery.webshims) {
+ webshims.error("jQuery was included more than once. Make sure to include it only once or try the $.noConflict(extreme) feature! Webshims and other Plugins might not work properly. Or set webshims.cfg.no$Switch to 'true'.");
+ if (window.$) {
+ window.$ = webshims.$;
+ }
+ window.jQuery = webshims.$;
+ }
+ };
+ switch$();
+ setTimeout(switch$, 90);
+ webshims.ready('DOM', switch$);
+ $(switch$);
+ webshims.ready('WINDOWLOAD', switch$);
+
+ }
+
+ //shortcus
+ var modules = webshims.modules;
+ var listReg = /\s*,\s*/;
+
+ //proxying attribute
+ var olds = {};
+ var havePolyfill = {};
+ var hasPolyfillMethod = {};
+ var extendedProps = {};
+ var extendQ = {};
+ var modifyProps = {};
+
+ var oldVal = $.fn.val;
+ var singleVal = function(elem, name, val, pass, _argless){
+ return (_argless) ? oldVal.call($(elem)) : oldVal.call($(elem), val);
+ };
+
+ //jquery mobile and jquery ui
+ if(!$.widget){
+ (function(){
+ var _cleanData = $.cleanData;
+ $.cleanData = function( elems ) {
+ if(!$.widget){
+ for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) {
+ try {
+ $( elem ).triggerHandler( "remove" );
+ // http://bugs.jquery.com/ticket/8235
+ } catch( e ) {}
+ }
+ }
+ _cleanData( elems );
+ };
+ })();
+ }
+
+
+ $.fn.val = function(val){
+ var elem = this[0];
+ if(arguments.length && val == null){
+ val = '';
+ }
+ if(!arguments.length){
+ if(!elem || elem.nodeType !== 1){return oldVal.call(this);}
+ return $.prop(elem, 'value', val, 'val', true);
+ }
+ if($.isArray(val)){
+ return oldVal.apply(this, arguments);
+ }
+ var isFunction = $.isFunction(val);
+ return this.each(function(i){
+ elem = this;
+ if(elem.nodeType === 1){
+ if(isFunction){
+ var genVal = val.call( elem, i, $.prop(elem, 'value', undefined, 'val', true));
+ if(genVal == null){
+ genVal = '';
+ }
+ $.prop(elem, 'value', genVal, 'val') ;
+ } else {
+ $.prop(elem, 'value', val, 'val');
+ }
+ }
+ });
+ };
+ $.fn.onTrigger = function(evt, fn){
+ return this.on(evt, fn).each(fn);
+ };
+
+ $.fn.onWSOff = function(evt, fn, trigger, evtDel){
+ if(!evtDel){
+ evtDel = document;
+ }
+ $(evtDel)[trigger ? 'onTrigger' : 'on'](evt, fn);
+ this.on('remove', function(e){
+ if(!e.originalEvent){
+ $(evtDel).off(evt, fn);
+ }
+ });
+ return this;
+ };
+ var idCount = 0;
+ var dataID = '_webshims'+ (Math.round(Math.random() * 1000));
+ var elementData = function(elem, key, val){
+ elem = elem.jquery ? elem[0] : elem;
+ if(!elem){return val || {};}
+ var data = $.data(elem, dataID);
+ if(val !== undefined){
+ if(!data){
+ data = $.data(elem, dataID, {});
+ }
+ if(key){
+ data[key] = val;
+ }
+ }
+
+ return key ? data && data[key] : data;
+ };
+
+
+ [{name: 'getNativeElement', prop: 'nativeElement'}, {name: 'getShadowElement', prop: 'shadowElement'}, {name: 'getShadowFocusElement', prop: 'shadowFocusElement'}].forEach(function(data){
+ $.fn[data.name] = function(){
+ var elems = [];
+ this.each(function(){
+ var shadowData = elementData(this, 'shadowData');
+ var elem = shadowData && shadowData[data.prop] || this;
+ if($.inArray(elem, elems) == -1){
+ elems.push(elem);
+ }
+ });
+ return this.pushStack(elems);
+ };
+ });
+
+ function clone(elem, dataAndEvents, uniqueIds){
+ var cloned = $.clone( elem, dataAndEvents, false );
+ $(cloned.querySelectorAll('.'+webshims.shadowClass)).detach();
+ if(uniqueIds){
+ idCount++;
+ $(cloned.querySelectorAll('[id]')).prop('id', function(i, id){
+ return id +idCount;
+ });
+ } else {
+ $(cloned.querySelectorAll('audio[id^="ID-"], video[id^="ID-"], label[id^="ID-"]')).removeAttr('id');
+ }
+ return cloned;
+ }
+
+ $.fn.clonePolyfill = function(dataAndEvents, uniqueIds){
+ dataAndEvents = dataAndEvents || false;
+ return this
+ .map(function() {
+ var cloned = clone( this, dataAndEvents, uniqueIds );
+ setTimeout(function(){
+ if($.contains(document.body, cloned)){
+ $(cloned).updatePolyfill();
+ }
+ });
+ return cloned;
+ })
+ ;
+ };
+
+ //add support for $('video').trigger('play') in case extendNative is set to false
+ if(!webshims.cfg.extendNative && !webshims.cfg.noTriggerOverride){
+ (function(oldTrigger){
+ $.event.trigger = function(event, data, elem, onlyHandlers){
+
+ if(!hasPolyfillMethod[event] || onlyHandlers || !elem || elem.nodeType !== 1){
+ return oldTrigger.apply(this, arguments);
+ }
+ var ret, isOrig, origName;
+ var origFn = elem[event];
+ var polyfilledFn = $.prop(elem, event);
+ var changeFn = polyfilledFn && origFn != polyfilledFn;
+ if(changeFn){
+ origName = '__ws'+event;
+ isOrig = (event in elem) && has.call(elem, event);
+ elem[event] = polyfilledFn;
+ elem[origName] = origFn;
+ }
+
+ ret = oldTrigger.apply(this, arguments);
+ if (changeFn) {
+ if(isOrig){
+ elem[event] = origFn;
+ } else {
+ delete elem[event];
+ }
+ delete elem[origName];
+ }
+
+ return ret;
+ };
+ })($.event.trigger);
+ }
+
+ ['removeAttr', 'prop', 'attr'].forEach(function(type){
+ olds[type] = $[type];
+ $[type] = function(elem, name, value, pass, _argless){
+ var isVal = (pass == 'val');
+ var oldMethod = !isVal ? olds[type] : singleVal;
+ if( !elem || !havePolyfill[name] || elem.nodeType !== 1 || (!isVal && pass && type == 'attr' && $.attrFn[name]) ){
+ return oldMethod(elem, name, value, pass, _argless);
+ }
+
+ var nodeName = (elem.nodeName || '').toLowerCase();
+ var desc = extendedProps[nodeName];
+ var curType = (type == 'attr' && (value === false || value === null)) ? 'removeAttr' : type;
+ var propMethod;
+ var oldValMethod;
+ var ret;
+
+
+ if(!desc){
+ desc = extendedProps['*'];
+ }
+ if(desc){
+ desc = desc[name];
+ }
+
+ if(desc){
+ propMethod = desc[curType];
+ }
+
+ if(propMethod){
+ if(name == 'value'){
+ oldValMethod = propMethod.isVal;
+ propMethod.isVal = isVal;
+ }
+ if(curType === 'removeAttr'){
+ return propMethod.value.call(elem);
+ } else if(value === undefined){
+ return (propMethod.get) ?
+ propMethod.get.call(elem) :
+ propMethod.value
+ ;
+ } else if(propMethod.set) {
+ if(type == 'attr' && value === true){
+ value = name;
+ }
+
+ ret = propMethod.set.call(elem, value);
+ }
+ if(name == 'value'){
+ propMethod.isVal = oldValMethod;
+ }
+ } else {
+ ret = oldMethod(elem, name, value, pass, _argless);
+ }
+ if((value !== undefined || curType === 'removeAttr') && modifyProps[nodeName] && modifyProps[nodeName][name]){
+
+ var boolValue;
+ if(curType == 'removeAttr'){
+ boolValue = false;
+ } else if(curType == 'prop'){
+ boolValue = !!(value);
+ } else {
+ boolValue = true;
+ }
+
+ modifyProps[nodeName][name].forEach(function(fn){
+ if(!fn.only || (fn.only = 'prop' && type == 'prop') || (fn.only == 'attr' && type != 'prop')){
+ fn.call(elem, value, boolValue, (isVal) ? 'val' : curType, type);
+ }
+ });
+ }
+ return ret;
+ };
+
+ extendQ[type] = function(nodeName, prop, desc){
+
+ if(!extendedProps[nodeName]){
+ extendedProps[nodeName] = {};
+ }
+ if(!extendedProps[nodeName][prop]){
+ extendedProps[nodeName][prop] = {};
+ }
+ var oldDesc = extendedProps[nodeName][prop][type];
+ var getSup = function(propType, descriptor, oDesc){
+ var origProp;
+ if(descriptor && descriptor[propType]){
+ return descriptor[propType];
+ }
+ if(oDesc && oDesc[propType]){
+ return oDesc[propType];
+ }
+ if(type == 'prop' && prop == 'value'){
+ return function(value){
+ var elem = this;
+ return (desc.isVal) ?
+ singleVal(elem, prop, value, false, (arguments.length === 0)) :
+ olds[type](elem, prop, value)
+ ;
+ };
+ }
+ if(type == 'prop' && propType == 'value' && desc.value.apply){
+ origProp = '__ws'+prop;
+ hasPolyfillMethod[prop] = true;
+ return function(value){
+ var sup = this[origProp] || olds[type](this, prop);
+ if(sup && sup.apply){
+ sup = sup.apply(this, arguments);
+ }
+ return sup;
+ };
+ }
+ return function(value){
+ return olds[type](this, prop, value);
+ };
+ };
+ extendedProps[nodeName][prop][type] = desc;
+ if(desc.value === undefined){
+ if(!desc.set){
+ desc.set = desc.writeable ?
+ getSup('set', desc, oldDesc) :
+ (webshims.cfg.useStrict && prop == 'prop') ?
+ function(){throw(prop +' is readonly on '+ nodeName);} :
+ function(){webshims.info(prop +' is readonly on '+ nodeName);}
+ ;
+ }
+ if(!desc.get){
+ desc.get = getSup('get', desc, oldDesc);
+ }
+
+ }
+
+ ['value', 'get', 'set'].forEach(function(descProp){
+ if(desc[descProp]){
+ desc['_sup'+descProp] = getSup(descProp, oldDesc);
+ }
+ });
+ };
+
+ });
+
+ var extendNativeValue = (function(){
+ var UNKNOWN = webshims.getPrototypeOf(document.createElement('foobar'));
+
+ //see also: https://github.com/lojjic/PIE/issues/40 | https://prototype.lighthouseapp.com/projects/8886/tickets/1107-ie8-fatal-crash-when-prototypejs-is-loaded-with-rounded-cornershtc
+ var isExtendNativeSave = webshims.support.advancedObjectProperties && webshims.support.objectAccessor;
+ return function(nodeName, prop, desc){
+ var elem , elemProto;
+ if( isExtendNativeSave && (elem = document.createElement(nodeName)) && (elemProto = webshims.getPrototypeOf(elem)) && UNKNOWN !== elemProto && ( !elem[prop] || !has.call(elem, prop) ) ){
+ var sup = elem[prop];
+ desc._supvalue = function(){
+ if(sup && sup.apply){
+ return sup.apply(this, arguments);
+ }
+ return sup;
+ };
+ elemProto[prop] = desc.value;
+ } else {
+ desc._supvalue = function(){
+ var data = elementData(this, 'propValue');
+ if(data && data[prop] && data[prop].apply){
+ return data[prop].apply(this, arguments);
+ }
+ return data && data[prop];
+ };
+ initProp.extendValue(nodeName, prop, desc.value);
+ }
+ desc.value._supvalue = desc._supvalue;
+ };
+ })();
+
+ var initProp = (function(){
+
+ var initProps = {};
+
+ webshims.addReady(function(context, contextElem){
+ var nodeNameCache = {};
+ var getElementsByName = function(name){
+ if(!nodeNameCache[name]){
+ nodeNameCache[name] = $(context.getElementsByTagName(name));
+ if(contextElem[0] && $.nodeName(contextElem[0], name)){
+ nodeNameCache[name] = nodeNameCache[name].add(contextElem);
+ }
+ }
+ };
+
+
+ $.each(initProps, function(name, fns){
+ getElementsByName(name);
+ if(!fns || !fns.forEach){
+ webshims.warn('Error: with '+ name +'-property. methods: '+ fns);
+ return;
+ }
+ fns.forEach(function(fn){
+ nodeNameCache[name].each(fn);
+ });
+ });
+ nodeNameCache = null;
+ });
+
+ var tempCache;
+ var emptyQ = $([]);
+ var createNodeNameInit = function(nodeName, fn){
+ if(!initProps[nodeName]){
+ initProps[nodeName] = [fn];
+ } else {
+ initProps[nodeName].push(fn);
+ }
+ if($.isDOMReady){
+ (tempCache || $( document.getElementsByTagName(nodeName) )).each(fn);
+ }
+ };
+
+ var elementExtends = {};
+ return {
+ createTmpCache: function(nodeName){
+ if($.isDOMReady){
+ tempCache = tempCache || $( document.getElementsByTagName(nodeName) );
+ }
+ return tempCache || emptyQ;
+ },
+ flushTmpCache: function(){
+ tempCache = null;
+ },
+ content: function(nodeName, prop){
+ createNodeNameInit(nodeName, function(){
+ var val = $.attr(this, prop);
+ if(val != null){
+ $.attr(this, prop, val);
+ }
+ });
+ },
+ createElement: function(nodeName, fn){
+ createNodeNameInit(nodeName, fn);
+ },
+ extendValue: function(nodeName, prop, value){
+ createNodeNameInit(nodeName, function(){
+ $(this).each(function(){
+ var data = elementData(this, 'propValue', {});
+ data[prop] = this[prop];
+ this[prop] = value;
+ });
+ });
+ }
+ };
+ })();
+
+ var createPropDefault = function(descs, removeType){
+ if(descs.defaultValue === undefined){
+ descs.defaultValue = '';
+ }
+ if(!descs.removeAttr){
+ descs.removeAttr = {
+ value: function(){
+ descs[removeType || 'prop'].set.call(this, descs.defaultValue);
+ descs.removeAttr._supvalue.call(this);
+ }
+ };
+ }
+ if(!descs.attr){
+ descs.attr = {};
+ }
+ };
+
+ $.extend(webshims, {
+ getID: (function(){
+ var ID = new Date().getTime();
+ return function(elem){
+ elem = $(elem);
+ var id = elem.prop('id');
+ if(!id){
+ ID++;
+ id = 'ID-'+ ID;
+ elem.eq(0).prop('id', id);
+ }
+ return id;
+ };
+ })(),
+ shadowClass: 'wsshadow-'+(Date.now()),
+ implement: function(elem, type){
+ var data = elementData(elem, 'implemented') || elementData(elem, 'implemented', {});
+ if(data[type]){
+ webshims.warn(type +' already implemented for element #'+elem.id);
+ return false;
+ }
+ data[type] = true;
+ return true;
+ },
+ extendUNDEFProp: function(obj, props){
+ $.each(props, function(name, prop){
+ if( !(name in obj) ){
+ obj[name] = prop;
+ }
+ });
+ },
+ getOptions: (function(){
+ var normalName = /\-([a-z])/g;
+ var regs = {};
+ var nameRegs = {};
+ var regFn = function(f, upper){
+ return upper.toLowerCase();
+ };
+ var nameFn = function(f, dashed){
+ return dashed.toUpperCase();
+ };
+ return function(elem, name, bases, stringAllowed){
+ if(nameRegs[name]){
+ name = nameRegs[name];
+ } else {
+ nameRegs[name] = name.replace(normalName, nameFn);
+ name = nameRegs[name];
+ }
+ var data = elementData(elem, 'cfg'+name);
+ var dataName;
+ var cfg = {};
+
+ if(data){
+ return data;
+ }
+ data = $(elem).data();
+ if(data && typeof data[name] == 'string'){
+ if(stringAllowed){
+ return elementData(elem, 'cfg'+name, data[name]);
+ }
+ webshims.error('data-'+ name +' attribute has to be a valid JSON, was: '+ data[name]);
+ }
+ if(!bases){
+ bases = [true, {}];
+ } else if(!Array.isArray(bases)){
+ bases = [true, {}, bases];
+ } else {
+ bases.unshift(true, {});
+ }
+
+ if(data && typeof data[name] == 'object'){
+ bases.push(data[name]);
+ }
+
+ if(!regs[name]){
+ regs[name] = new RegExp('^'+ name +'([A-Z])');
+ }
+
+ for(dataName in data){
+ if(regs[name].test(dataName)){
+ cfg[dataName.replace(regs[name], regFn)] = data[dataName];
+ }
+ }
+ bases.push(cfg);
+ return elementData(elem, 'cfg'+name, $.extend.apply($, bases));
+ };
+ })(),
+ //http://www.w3.org/TR/html5/common-dom-interfaces.html#reflect
+ createPropDefault: createPropDefault,
+ data: elementData,
+ moveToFirstEvent: function(elem, eventType, bindType){
+ var events = ($._data(elem, 'events') || {})[eventType];
+ var fn;
+
+ if(events && events.length > 1){
+ fn = events.pop();
+ if(!bindType){
+ bindType = 'bind';
+ }
+ if(bindType == 'bind' && events.delegateCount){
+ events.splice( events.delegateCount, 0, fn);
+ } else {
+ events.unshift( fn );
+ }
+
+
+ }
+ elem = null;
+ },
+ addShadowDom: (function(){
+ var resizeTimer;
+ var lastHeight;
+ var lastWidth;
+ var $window = $(window);
+ var docObserve = {
+ init: false,
+ runs: 0,
+ test: function(){
+ var height = docObserve.getHeight();
+ var width = docObserve.getWidth();
+
+ if(height != docObserve.height || width != docObserve.width){
+ docObserve.height = height;
+ docObserve.width = width;
+ docObserve.handler({type: 'docresize'});
+ docObserve.runs++;
+ if(docObserve.runs < 9){
+ setTimeout(docObserve.test, 90);
+ }
+ } else {
+ docObserve.runs = 0;
+ }
+ },
+ handler: (function(){
+ var trigger = function(){
+ $(document).triggerHandler('updateshadowdom');
+ };
+ return function(e){
+ clearTimeout(resizeTimer);
+ resizeTimer = setTimeout(function(){
+ if(e.type == 'resize'){
+ var width = $window.width();
+ var height = $window.width();
+
+ if(height == lastHeight && width == lastWidth){
+ return;
+ }
+ lastHeight = height;
+ lastWidth = width;
+
+ docObserve.height = docObserve.getHeight();
+ docObserve.width = docObserve.getWidth();
+ }
+
+ if(window.requestAnimationFrame){
+ requestAnimationFrame(trigger);
+ } else {
+ setTimeout(trigger, 0);
+ }
+
+ }, (e.type == 'resize' && !window.requestAnimationFrame) ? 50 : 9);
+ };
+ })(),
+ _create: function(){
+ $.each({ Height: "getHeight", Width: "getWidth" }, function(name, type){
+ var body = document.body;
+ var doc = document.documentElement;
+ docObserve[type] = function (){
+ return Math.max(
+ body[ "scroll" + name ], doc[ "scroll" + name ],
+ body[ "offset" + name ], doc[ "offset" + name ],
+ doc[ "client" + name ]
+ );
+ };
+ });
+ },
+ start: function(){
+ if(!this.init && document.body){
+ this.init = true;
+ this._create();
+ this.height = docObserve.getHeight();
+ this.width = docObserve.getWidth();
+ setInterval(this.test, 999);
+ $(this.test);
+ if($.support.boxSizing == null){
+ $(function(){
+ if($.support.boxSizing){
+ docObserve.handler({type: 'boxsizing'});
+ }
+ });
+ }
+ webshims.ready('WINDOWLOAD', this.test);
+ $(document).on('updatelayout.webshim pageinit popupafteropen panelbeforeopen tabsactivate collapsibleexpand shown.bs.modal shown.bs.collapse slid.bs.carousel playerdimensionchange', this.handler);
+ $(window).on('resize', this.handler);
+ }
+ }
+ };
+
+
+ webshims.docObserve = function(){
+ webshims.ready('DOM', function(){
+ docObserve.start();
+
+ });
+ };
+ return function(nativeElem, shadowElem, opts){
+ if(nativeElem && shadowElem){
+ opts = opts || {};
+ if(nativeElem.jquery){
+ nativeElem = nativeElem[0];
+ }
+ if(shadowElem.jquery){
+ shadowElem = shadowElem[0];
+ }
+ var nativeData = $.data(nativeElem, dataID) || $.data(nativeElem, dataID, {});
+ var shadowData = $.data(shadowElem, dataID) || $.data(shadowElem, dataID, {});
+ var shadowFocusElementData = {};
+ if(!opts.shadowFocusElement){
+ opts.shadowFocusElement = shadowElem;
+ } else if(opts.shadowFocusElement){
+ if(opts.shadowFocusElement.jquery){
+ opts.shadowFocusElement = opts.shadowFocusElement[0];
+ }
+ shadowFocusElementData = $.data(opts.shadowFocusElement, dataID) || $.data(opts.shadowFocusElement, dataID, shadowFocusElementData);
+ }
+
+ $(nativeElem).on('remove', function(e){
+ if (!e.originalEvent) {
+ setTimeout(function(){
+ $(shadowElem).remove();
+ }, 4);
+ }
+ });
+
+ nativeData.hasShadow = shadowElem;
+ shadowFocusElementData.nativeElement = shadowData.nativeElement = nativeElem;
+ shadowFocusElementData.shadowData = shadowData.shadowData = nativeData.shadowData = {
+ nativeElement: nativeElem,
+ shadowElement: shadowElem,
+ shadowFocusElement: opts.shadowFocusElement
+ };
+ if(opts.shadowChilds){
+ opts.shadowChilds.each(function(){
+ elementData(this, 'shadowData', shadowData.shadowData);
+ });
+ }
+
+ if(opts.data){
+ shadowFocusElementData.shadowData.data = shadowData.shadowData.data = nativeData.shadowData.data = opts.data;
+ }
+ opts = null;
+ }
+ webshims.docObserve();
+ };
+ })(),
+ propTypes: {
+ standard: function(descs, name){
+ createPropDefault(descs);
+ if(descs.prop){return;}
+ descs.prop = {
+ set: function(val){
+ descs.attr.set.call(this, ''+val);
+ },
+ get: function(){
+ return descs.attr.get.call(this) || descs.defaultValue;
+ }
+ };
+
+ },
+ "boolean": function(descs, name){
+
+ createPropDefault(descs);
+ if(descs.prop){return;}
+ descs.prop = {
+ set: function(val){
+ if(val){
+ descs.attr.set.call(this, "");
+ } else {
+ descs.removeAttr.value.call(this);
+ }
+ },
+ get: function(){
+ return descs.attr.get.call(this) != null;
+ }
+ };
+ },
+ "src": (function(){
+ var anchor = document.createElement('a');
+ anchor.style.display = "none";
+ return function(descs, name){
+
+ createPropDefault(descs);
+ if(descs.prop){return;}
+ descs.prop = {
+ set: function(val){
+ descs.attr.set.call(this, val);
+ },
+ get: function(){
+ var href = this.getAttribute(name);
+ var ret;
+ if(href == null){return '';}
+
+ anchor.setAttribute('href', href+'' );
+
+ if(!supportHrefNormalized){
+ try {
+ $(anchor).insertAfter(this);
+ ret = anchor.getAttribute('href', 4);
+ } catch(er){
+ ret = anchor.getAttribute('href', 4);
+ }
+ $(anchor).detach();
+ }
+ return ret || anchor.href;
+ }
+ };
+ };
+ })(),
+ enumarated: function(descs, name){
+
+ createPropDefault(descs);
+ if(descs.prop){return;}
+ descs.prop = {
+ set: function(val){
+ descs.attr.set.call(this, val);
+ },
+ get: function(){
+ var val = (descs.attr.get.call(this) || '').toLowerCase();
+ if(!val || descs.limitedTo.indexOf(val) == -1){
+ val = descs.defaultValue;
+ }
+ return val;
+ }
+ };
+ }
+
+// ,unsignedLong: $.noop
+// ,"doubble": $.noop
+// ,"long": $.noop
+// ,tokenlist: $.noop
+// ,settableTokenlist: $.noop
+ },
+ reflectProperties: function(nodeNames, props){
+ if(typeof props == 'string'){
+ props = props.split(listReg);
+ }
+ props.forEach(function(prop){
+ webshims.defineNodeNamesProperty(nodeNames, prop, {
+ prop: {
+ set: function(val){
+ $.attr(this, prop, val);
+ },
+ get: function(){
+ return $.attr(this, prop) || '';
+ }
+ }
+ });
+ });
+ },
+ defineNodeNameProperty: function(nodeName, prop, descs){
+ havePolyfill[prop] = true;
+
+ if(descs.reflect){
+ if(descs.propType && !webshims.propTypes[descs.propType]){
+ webshims.error('could not finde propType '+ descs.propType);
+ } else {
+ webshims.propTypes[descs.propType || 'standard'](descs, prop);
+ }
+
+ }
+
+ ['prop', 'attr', 'removeAttr'].forEach(function(type){
+ var desc = descs[type];
+ if(desc){
+ if(type === 'prop'){
+ desc = $.extend({writeable: true}, desc);
+ } else {
+ desc = $.extend({}, desc, {writeable: true});
+ }
+
+ extendQ[type](nodeName, prop, desc);
+ if(nodeName != '*' && webshims.cfg.extendNative && type == 'prop' && desc.value && $.isFunction(desc.value)){
+ extendNativeValue(nodeName, prop, desc);
+ }
+ descs[type] = desc;
+ }
+ });
+ if(descs.initAttr){
+ initProp.content(nodeName, prop);
+ }
+ return descs;
+ },
+
+ defineNodeNameProperties: function(name, descs, propType, _noTmpCache){
+ var olddesc;
+ for(var prop in descs){
+ if(!_noTmpCache && descs[prop].initAttr){
+ initProp.createTmpCache(name);
+ }
+ if(propType){
+ if(descs[prop][propType]){
+ //webshims.log('override: '+ name +'['+prop +'] for '+ propType);
+ } else {
+ descs[prop][propType] = {};
+ ['value', 'set', 'get'].forEach(function(copyProp){
+ if(copyProp in descs[prop]){
+ descs[prop][propType][copyProp] = descs[prop][copyProp];
+ delete descs[prop][copyProp];
+ }
+ });
+ }
+ }
+ descs[prop] = webshims.defineNodeNameProperty(name, prop, descs[prop]);
+ }
+ if(!_noTmpCache){
+ initProp.flushTmpCache();
+ }
+ return descs;
+ },
+
+ createElement: function(nodeName, create, descs){
+ var ret;
+ if($.isFunction(create)){
+ create = {
+ after: create
+ };
+ }
+ initProp.createTmpCache(nodeName);
+ if(create.before){
+ initProp.createElement(nodeName, create.before);
+ }
+ if(descs){
+ ret = webshims.defineNodeNameProperties(nodeName, descs, false, true);
+ }
+ if(create.after){
+ initProp.createElement(nodeName, create.after);
+ }
+ initProp.flushTmpCache();
+ return ret;
+ },
+ onNodeNamesPropertyModify: function(nodeNames, props, desc, only){
+ if(typeof nodeNames == 'string'){
+ nodeNames = nodeNames.split(listReg);
+ }
+ if($.isFunction(desc)){
+ desc = {set: desc};
+ }
+
+ nodeNames.forEach(function(name){
+ if(!modifyProps[name]){
+ modifyProps[name] = {};
+ }
+ if(typeof props == 'string'){
+ props = props.split(listReg);
+ }
+ if(desc.initAttr){
+ initProp.createTmpCache(name);
+ }
+ props.forEach(function(prop){
+ if(!modifyProps[name][prop]){
+ modifyProps[name][prop] = [];
+ havePolyfill[prop] = true;
+ }
+ if(desc.set){
+ if(only){
+ desc.set.only = only;
+ }
+ modifyProps[name][prop].push(desc.set);
+ }
+
+ if(desc.initAttr){
+ initProp.content(name, prop);
+ }
+ });
+ initProp.flushTmpCache();
+
+ });
+ },
+ defineNodeNamesBooleanProperty: function(elementNames, prop, descs){
+ if(!descs){
+ descs = {};
+ }
+ if($.isFunction(descs)){
+ descs.set = descs;
+ }
+ webshims.defineNodeNamesProperty(elementNames, prop, {
+ attr: {
+ set: function(val){
+ if(descs.useContentAttribute){
+ webshims.contentAttr(this, prop, val);
+ } else {
+ this.setAttribute(prop, val);
+ }
+ if(descs.set){
+ descs.set.call(this, true);
+ }
+ },
+ get: function(){
+ var ret = (descs.useContentAttribute) ? webshims.contentAttr(this, prop) : this.getAttribute(prop);
+ return (ret == null) ? undefined : prop;
+ }
+ },
+ removeAttr: {
+ value: function(){
+ this.removeAttribute(prop);
+ if(descs.set){
+ descs.set.call(this, false);
+ }
+ }
+ },
+ reflect: true,
+ propType: 'boolean',
+ initAttr: descs.initAttr || false
+ });
+ },
+ contentAttr: function(elem, name, val){
+ if(!elem.nodeName){return;}
+ var attr;
+ if(val === undefined){
+ attr = (elem.attributes[name] || {});
+ val = attr.specified ? attr.value : null;
+ return (val == null) ? undefined : val;
+ }
+
+ if(typeof val == 'boolean'){
+ if(!val){
+ elem.removeAttribute(name);
+ } else {
+ elem.setAttribute(name, name);
+ }
+ } else {
+ elem.setAttribute(name, val);
+ }
+ },
+
+ activeLang: (function(){
+ var curLang = [];
+ var langDatas = [];
+ var loading = {};
+ var load = function(src, obj, loadingLang){
+ obj._isLoading = true;
+ if(loading[src]){
+ loading[src].push(obj);
+ } else {
+ loading[src] = [obj];
+ webshims.loader.loadScript(src, function(){
+ if(loadingLang == curLang.join()){
+ $.each(loading[src], function(i, obj){
+ select(obj);
+ });
+ }
+ delete loading[src];
+ });
+ }
+ };
+
+ var select = function(obj){
+ var oldLang = obj.__active;
+ var selectLang = function(i, lang){
+ obj._isLoading = false;
+ if(obj[lang] || obj.availableLangs.indexOf(lang) != -1){
+ if(obj[lang]){
+ obj.__active = obj[lang];
+ obj.__activeName = lang;
+ } else {
+ load(obj.langSrc+lang, obj, curLang.join());
+ }
+ return false;
+ }
+ };
+ $.each(curLang, selectLang);
+ if(!obj.__active){
+ obj.__active = obj[''];
+ obj.__activeName = '';
+ }
+ if(oldLang != obj.__active){
+ $(obj).trigger('change');
+ }
+ };
+ return function(lang){
+ var shortLang;
+ if(typeof lang == 'string'){
+ if(curLang[0] != lang){
+ curLang = [lang];
+ shortLang = curLang[0].split('-')[0];
+ if(shortLang && shortLang != lang){
+ curLang.push(shortLang);
+ }
+ langDatas.forEach(select);
+ }
+ } else if(typeof lang == 'object'){
+ if(!lang.__active){
+ langDatas.push(lang);
+ select(lang);
+ }
+ return lang.__active;
+ }
+ return curLang[0];
+ };
+ })()
+ });
+
+ $.each({
+ defineNodeNamesProperty: 'defineNodeNameProperty',
+ defineNodeNamesProperties: 'defineNodeNameProperties',
+ createElements: 'createElement'
+ }, function(name, baseMethod){
+ webshims[name] = function(names, a, b, c){
+ if(typeof names == 'string'){
+ names = names.split(listReg);
+ }
+ var retDesc = {};
+ names.forEach(function(nodeName){
+ retDesc[nodeName] = webshims[baseMethod](nodeName, a, b, c);
+ });
+ return retDesc;
+ };
+ });
+
+ webshims.isReady('webshimLocalization', true);
+
+//html5a11y + hidden attribute
+(function(){
+ if(('content' in document.createElement('template'))){return;}
+
+ $(function(){
+ var main = $('main').attr({role: 'main'});
+ if(main.length > 1){
+ webshims.error('only one main element allowed in document');
+ } else if(main.is('article *, section *')) {
+ webshims.error('main not allowed inside of article/section elements');
+ }
+ });
+
+ if(('hidden' in document.createElement('a'))){
+ return;
+ }
+
+ webshims.defineNodeNamesBooleanProperty(['*'], 'hidden');
+
+ var elemMappings = {
+ article: "article",
+ aside: "complementary",
+ section: "region",
+ nav: "navigation",
+ address: "contentinfo"
+ };
+ var addRole = function(elem, role){
+ var hasRole = elem.getAttribute('role');
+ if (!hasRole) {
+ elem.setAttribute('role', role);
+ }
+ };
+
+
+ $.webshims.addReady(function(context, contextElem){
+ $.each(elemMappings, function(name, role){
+ var elems = $(name, context).add(contextElem.filter(name));
+ for (var i = 0, len = elems.length; i < len; i++) {
+ addRole(elems[i], role);
+ }
+ });
+ if (context === document) {
+ var header = document.getElementsByTagName('header')[0];
+ var footers = document.getElementsByTagName('footer');
+ var footerLen = footers.length;
+
+ if (header && !$(header).closest('section, article')[0]) {
+ addRole(header, 'banner');
+ }
+ if (!footerLen) {
+ return;
+ }
+ var footer = footers[footerLen - 1];
+ if (!$(footer).closest('section, article')[0]) {
+ addRole(footer, 'contentinfo');
+ }
+ }
+ });
+
+})();
+});
diff --git a/public/webshims/shims/es5.js b/public/webshims/shims/es5.js
new file mode 100644
index 00000000..6fc6836d
--- /dev/null
+++ b/public/webshims/shims/es5.js
@@ -0,0 +1,1529 @@
+// Copyright 2009-2012 by contributors, MIT License
+// vim: ts=4 sts=4 sw=4 expandtab
+
+(function () {
+setTimeout(function(){
+ webshims.isReady('es5', true);
+});
+ /**
+ * 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.
+ var call = Function.prototype.call;
+ var prototypeOfArray = Array.prototype;
+ var prototypeOfObject = Object.prototype;
+ var _Array_slice_ = prototypeOfArray.slice;
+ var array_splice = Array.prototype.splice;
+ var array_push = Array.prototype.push;
+ var array_unshift = Array.prototype.unshift;
+
+// Having a toString local variable name breaks in Opera so use _toString.
+ var _toString = prototypeOfObject.toString;
+
+ var isFunction = function (val) {
+ return prototypeOfObject.toString.call(val) === '[object Function]';
+ };
+ var isRegex = function (val) {
+ return prototypeOfObject.toString.call(val) === '[object RegExp]';
+ };
+ var isArray = function isArray(obj) {
+ return _toString.call(obj) === "[object Array]";
+ };
+ var isArguments = function isArguments(value) {
+ var str = _toString.call(value);
+ var isArgs = str === '[object Arguments]';
+ if (!isArgs) {
+ isArgs = !isArray(str)
+ && value !== null
+ && typeof value === 'object'
+ && typeof value.length === 'number'
+ && value.length >= 0
+ && isFunction(value.callee);
+ }
+ return isArgs;
+ };
+
+//
+// Function
+// ========
+//
+
+// ES-5 15.3.4.5
+// http://es5.github.com/#x15.3.4.5
+
+ function Empty() {}
+
+ if (!Function.prototype.bind) {
+ Function.prototype.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 (!isFunction(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 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,
+ args.concat(_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,
+ args.concat(_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 = Math.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++) {
+ boundArgs.push("$" + 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.
+ var 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
+// us it in defining shortcuts.
+ var owns = call.bind(prototypeOfObject.hasOwnProperty);
+
+// If JS engine supports accessors creating shortcuts.
+ var defineGetter;
+ var defineSetter;
+ var lookupGetter;
+ var lookupSetter;
+ var supportsAccessors;
+ if ((supportsAccessors = owns(prototypeOfObject, "__defineGetter__"))) {
+ defineGetter = call.bind(prototypeOfObject.__defineGetter__);
+ defineSetter = call.bind(prototypeOfObject.__defineSetter__);
+ lookupGetter = call.bind(prototypeOfObject.__lookupGetter__);
+ lookupSetter = call.bind(prototypeOfObject.__lookupSetter__);
+ }
+
+//
+// Array
+// =====
+//
+
+// ES5 15.4.4.12
+// http://es5.github.com/#x15.4.4.12
+ var spliceWorksWithEmptyObject = (function () {
+ var obj = {};
+ Array.prototype.splice.call(obj, 0, 0, 1);
+ return obj.length === 1;
+ }());
+ var omittingSecondSpliceArgIsNoop = [1].splice(0).length === 0;
+ var spliceNoopReturnsEmptyArray = (function () {
+ var a = [1, 2];
+ var result = a.splice();
+ return a.length === 2 && isArray(result) && result.length === 0;
+ }());
+ if (spliceNoopReturnsEmptyArray) {
+ // Safari 5.0 bug where .split() returns undefined
+ Array.prototype.splice = function splice(start, deleteCount) {
+ if (arguments.length === 0) { return []; }
+ else { return array_splice.apply(this, arguments); }
+ };
+ }
+ if (!omittingSecondSpliceArgIsNoop || !spliceWorksWithEmptyObject) {
+ Array.prototype.splice = function splice(start, deleteCount) {
+ if (arguments.length === 0) { return []; }
+ var args = arguments;
+ this.length = Math.max(toInteger(this.length), 0);
+ if (arguments.length > 0 && typeof deleteCount !== 'number') {
+ args = _Array_slice_.call(arguments);
+ if (args.length < 2) { args.push(toInteger(deleteCount)); }
+ else { args[1] = toInteger(deleteCount); }
+ }
+ return array_splice.apply(this, args);
+ };
+ }
+
+// 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"
+ if ([].unshift(0) !== 1) {
+ Array.prototype.unshift = function () {
+ array_unshift.apply(this, arguments);
+ return this.length;
+ };
+ }
+
+// ES5 15.4.3.2
+// http://es5.github.com/#x15.4.3.2
+// https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/isArray
+ if (!Array.isArray) {
+ 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;
+ };
+
+ if (!Array.prototype.forEach || !properlyBoxesContext(Array.prototype.forEach)) {
+ Array.prototype.forEach = function forEach(fun /*, thisp*/) {
+ var object = toObject(this),
+ self = splitString && _toString.call(this) === "[object String]" ?
+ this.split("") :
+ object,
+ thisp = arguments[1],
+ i = -1,
+ length = self.length >>> 0;
+
+ // If no callback function or if callback is not a callable function
+ if (!isFunction(fun)) {
+ throw new TypeError(); // TODO message
+ }
+
+ while (++i < length) {
+ if (i in self) {
+ // Invoke the callback function with call, passing arguments:
+ // context, property value, property key, thisArg object
+ // context
+ fun.call(thisp, self[i], i, object);
+ }
+ }
+ };
+ }
+
+// 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
+ if (!Array.prototype.map || !properlyBoxesContext(Array.prototype.map)) {
+ Array.prototype.map = function map(fun /*, thisp*/) {
+ var object = toObject(this),
+ self = splitString && _toString.call(this) === "[object String]" ?
+ this.split("") :
+ object,
+ length = self.length >>> 0,
+ result = Array(length),
+ thisp = arguments[1];
+
+ // If no callback function or if callback is not a callable function
+ if (!isFunction(fun)) {
+ throw new TypeError(fun + " is not a function");
+ }
+
+ for (var i = 0; i < length; i++) {
+ if (i in self) {
+ result[i] = fun.call(thisp, self[i], i, object);
+ }
+ }
+ return result;
+ };
+ }
+
+// 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
+ if (!Array.prototype.filter || !properlyBoxesContext(Array.prototype.filter)) {
+ Array.prototype.filter = function filter(fun /*, thisp */) {
+ var object = toObject(this),
+ self = splitString && _toString.call(this) === "[object String]" ?
+ this.split("") :
+ object,
+ length = self.length >>> 0,
+ result = [],
+ value,
+ thisp = arguments[1];
+
+ // If no callback function or if callback is not a callable function
+ if (!isFunction(fun)) {
+ throw new TypeError(fun + " is not a function");
+ }
+
+ for (var i = 0; i < length; i++) {
+ if (i in self) {
+ value = self[i];
+ if (fun.call(thisp, value, i, object)) {
+ result.push(value);
+ }
+ }
+ }
+ return result;
+ };
+ }
+
+// ES5 15.4.4.16
+// http://es5.github.com/#x15.4.4.16
+// https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/every
+ if (!Array.prototype.every || !properlyBoxesContext(Array.prototype.every)) {
+ Array.prototype.every = function every(fun /*, thisp */) {
+ var object = toObject(this),
+ self = splitString && _toString.call(this) === "[object String]" ?
+ this.split("") :
+ object,
+ length = self.length >>> 0,
+ thisp = arguments[1];
+
+ // If no callback function or if callback is not a callable function
+ if (!isFunction(fun)) {
+ throw new TypeError(fun + " is not a function");
+ }
+
+ for (var i = 0; i < length; i++) {
+ if (i in self && !fun.call(thisp, self[i], i, object)) {
+ return false;
+ }
+ }
+ return true;
+ };
+ }
+
+// ES5 15.4.4.17
+// http://es5.github.com/#x15.4.4.17
+// https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/some
+ if (!Array.prototype.some || !properlyBoxesContext(Array.prototype.some)) {
+ Array.prototype.some = function some(fun /*, thisp */) {
+ var object = toObject(this),
+ self = splitString && _toString.call(this) === "[object String]" ?
+ this.split("") :
+ object,
+ length = self.length >>> 0,
+ thisp = arguments[1];
+
+ // If no callback function or if callback is not a callable function
+ if (!isFunction(fun)) {
+ throw new TypeError(fun + " is not a function");
+ }
+
+ for (var i = 0; i < length; i++) {
+ if (i in self && fun.call(thisp, self[i], i, object)) {
+ return true;
+ }
+ }
+ return false;
+ };
+ }
+
+// 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 (Array.prototype.reduce) {
+ reduceCoercesToObject = typeof Array.prototype.reduce.call('es5', function (_, __, ___, list) { return list; }) === 'object';
+ }
+ if (!Array.prototype.reduce || !reduceCoercesToObject) {
+ Array.prototype.reduce = function reduce(fun /*, initial*/) {
+ var object = toObject(this),
+ self = splitString && _toString.call(this) === "[object String]" ?
+ this.split("") :
+ object,
+ length = self.length >>> 0;
+
+ // If no callback function or if callback is not a callable function
+ if (!isFunction(fun)) {
+ throw new TypeError(fun + " is not a function");
+ }
+
+ // no value to return if no initial value and an empty array
+ if (!length && 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 = fun.call(void 0, result, self[i], i, object);
+ }
+ }
+
+ return result;
+ };
+ }
+
+// 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 (Array.prototype.reduceRight) {
+ reduceRightCoercesToObject = typeof Array.prototype.reduceRight.call('es5', function (_, __, ___, list) { return list; }) === 'object';
+ }
+ if (!Array.prototype.reduceRight || !reduceRightCoercesToObject) {
+ Array.prototype.reduceRight = function reduceRight(fun /*, initial*/) {
+ var object = toObject(this),
+ self = splitString && _toString.call(this) === "[object String]" ?
+ this.split("") :
+ object,
+ length = self.length >>> 0;
+
+ // If no callback function or if callback is not a callable function
+ if (!isFunction(fun)) {
+ throw new TypeError(fun + " is not a function");
+ }
+
+ // no value to return if no initial value, empty array
+ if (!length && arguments.length === 1) {
+ throw new TypeError("reduceRight of empty array with no initial value");
+ }
+
+ var result, 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 = fun.call(void 0, result, self[i], i, object);
+ }
+ } while (i--);
+
+ return result;
+ };
+ }
+
+// ES5 15.4.4.14
+// http://es5.github.com/#x15.4.4.14
+// https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/indexOf
+ if (!Array.prototype.indexOf || ([0, 1].indexOf(1, 2) !== -1)) {
+ Array.prototype.indexOf = function indexOf(sought /*, fromIndex */ ) {
+ var self = splitString && _toString.call(this) === "[object String]" ?
+ this.split("") :
+ toObject(this),
+ length = self.length >>> 0;
+
+ if (!length) {
+ return -1;
+ }
+
+ var i = 0;
+ if (arguments.length > 1) {
+ i = toInteger(arguments[1]);
+ }
+
+ // handle negative indices
+ i = i >= 0 ? i : Math.max(0, length + i);
+ for (; i < length; i++) {
+ if (i in self && self[i] === sought) {
+ return i;
+ }
+ }
+ return -1;
+ };
+ }
+
+// ES5 15.4.4.15
+// http://es5.github.com/#x15.4.4.15
+// https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/lastIndexOf
+ if (!Array.prototype.lastIndexOf || ([0, 1].lastIndexOf(0, -3) !== -1)) {
+ Array.prototype.lastIndexOf = function lastIndexOf(sought /*, fromIndex */) {
+ var self = splitString && _toString.call(this) === "[object String]" ?
+ this.split("") :
+ toObject(this),
+ length = self.length >>> 0;
+
+ if (!length) {
+ return -1;
+ }
+ var i = length - 1;
+ if (arguments.length > 1) {
+ i = Math.min(i, toInteger(arguments[1]));
+ }
+ // handle negative indices
+ i = i >= 0 ? i : length - Math.abs(i);
+ for (; i >= 0; i--) {
+ if (i in self && sought === self[i]) {
+ return i;
+ }
+ }
+ return -1;
+ };
+ }
+
+//
+// Object
+// ======
+//
+
+// ES5 15.2.3.14
+// http://es5.github.com/#x15.2.3.14
+ var keysWorksWithArguments = Object.keys && (function () {
+ return Object.keys(arguments).length === 2;
+ }(1, 2));
+ if (!Object.keys) {
+ // http://whattheheadsaid.com/2010/10/a-safer-object-keys-compatibility-implementation
+ var hasDontEnumBug = !({'toString': null}).propertyIsEnumerable('toString'),
+ hasProtoEnumBug = (function () {}).propertyIsEnumerable('prototype'),
+ dontEnums = [
+ "toString",
+ "toLocaleString",
+ "valueOf",
+ "hasOwnProperty",
+ "isPrototypeOf",
+ "propertyIsEnumerable",
+ "constructor"
+ ],
+ dontEnumsLength = dontEnums.length;
+
+ Object.keys = function keys(object) {
+ var isFn = isFunction(object),
+ isArgs = isArguments(object),
+ isObject = object !== null && typeof object === 'object',
+ isString = isObject && _toString.call(object) === '[object String]';
+
+ if (!isObject && !isFn && !isArgs) {
+ throw new TypeError("Object.keys called on a non-object");
+ }
+
+ var theKeys = [];
+ var skipProto = hasProtoEnumBug && isFn;
+ if (isString || isArgs) {
+ for (var i = 0; i < object.length; ++i) {
+ theKeys.push(String(i));
+ }
+ } else {
+ for (var name in object) {
+ if (!(skipProto && name === 'prototype') && owns(object, name)) {
+ theKeys.push(String(name));
+ }
+ }
+ }
+
+ if (hasDontEnumBug) {
+ var ctor = object.constructor,
+ skipConstructor = ctor && ctor.prototype === object;
+ for (var j = 0; j < dontEnumsLength; j++) {
+ var dontEnum = dontEnums[j];
+ if (!(skipConstructor && dontEnum === 'constructor') && owns(object, dontEnum)) {
+ theKeys.push(dontEnum);
+ }
+ }
+ }
+ return theKeys;
+ };
+ } else if (!keysWorksWithArguments) {
+ // Safari 5.0 bug
+ var originalKeys = Object.keys;
+ Object.keys = function keys(object) {
+ if (isArguments(object)) {
+ return originalKeys(Array.prototype.slice.call(object));
+ } else {
+ return originalKeys(object);
+ }
+ };
+ }
+
+//
+// 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,
+ negativeYearString = "-000001";
+ if (
+ !Date.prototype.toISOString ||
+ (new Date(negativeDate).toISOString().indexOf(negativeYearString) === -1)
+ ) {
+ 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 ? "+" : "")) +
+ ("00000" + Math.abs(year)).slice(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 + "-" + result.slice(0, 2).join("-") +
+ "T" + result.slice(2).join(":") + "." +
+ ("000" + this.getUTCMilliseconds()).slice(-3) + "Z"
+ );
+ };
+ }
+
+
+// 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 = false;
+ try {
+ dateToJSONIsSupported = (
+ 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) {
+ }
+ 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 toPrimitive(O, hint Number).
+ var o = Object(this),
+ tv = toPrimitive(o),
+ toISO;
+ // 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".
+ toISO = o.toISOString;
+ // 5. If IsCallable(toISO) is false, throw a TypeError exception.
+ if (typeof toISO !== "function") {
+ 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'));
+ var doesNotParseY2KNewYear = isNaN(Date.parse("2000-01-01T00:00:00.000Z"));
+ if (!Date.parse || doesNotParseY2KNewYear || acceptsInvalidDates || !supportsExtendedYears) {
+ // XXX global assignment won't work in embeddings that use
+ // an alternate object for the context.
+ Date = (function (NativeDate) {
+
+ // Date.length === 7
+ function Date(Y, M, D, h, m, s, ms) {
+ var length = arguments.length;
+ if (this instanceof NativeDate) {
+ var date = length === 1 && String(Y) === Y ? // isString(Y)
+ // We explicitly pass it through parse:
+ new NativeDate(Date.parse(Y)) :
+ // We have to manually make calls depending on argument
+ // length here
+ length >= 7 ? new NativeDate(Y, M, D, h, m, s, ms) :
+ length >= 6 ? new NativeDate(Y, M, D, h, m, s) :
+ 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();
+ // Prevent mixups with unfixed Date object
+ date.constructor = Date;
+ return date;
+ }
+ return NativeDate.apply(this, arguments);
+ }
+
+ // 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
+ ];
+
+ 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)
+ );
+ }
+
+ function toUTC(t) {
+ return Number(new NativeDate(1970, 0, 1, 0, 0, 0, t));
+ }
+
+ // Copy any custom methods a 3rd party library may have added
+ for (var key in NativeDate) {
+ Date[key] = NativeDate[key];
+ }
+
+ // Copy "native" methods explicitly; they may be non-enumerable
+ Date.now = NativeDate.now;
+ Date.UTC = NativeDate.UTC;
+ Date.prototype = NativeDate.prototype;
+ Date.prototype.constructor = Date;
+
+ // Upgrade Date.parse to handle simplified ISO 8601 strings
+ Date.parse = 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;
+ if (
+ hour < (
+ minute > 0 || second > 0 || millisecond > 0 ?
+ 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);
+ };
+
+ return Date;
+ })(Date);
+ }
+
+// 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
+ if (!Number.prototype.toFixed || (0.00008).toFixed(3) !== '0.000' || (0.9).toFixed(0) === '0' || (1.255).toFixed(2) !== '1.25' || (1000000000000000128).toFixed(0) !== "1000000000000000128") {
+ // Hide these variables and functions
+ (function () {
+ var base, size, data, i;
+
+ base = 1e7;
+ size = 6;
+ data = [0, 0, 0, 0, 0, 0];
+
+ function multiply(n, c) {
+ var i = -1;
+ while (++i < size) {
+ c += n * data[i];
+ data[i] = c % base;
+ c = Math.floor(c / base);
+ }
+ }
+
+ function divide(n) {
+ var i = size, c = 0;
+ while (--i >= 0) {
+ c += data[i];
+ data[i] = Math.floor(c / n);
+ c = (c % n) * base;
+ }
+ }
+
+ function numToString() {
+ var i = size;
+ var s = '';
+ while (--i >= 0) {
+ if (s !== '' || i === 0 || data[i] !== 0) {
+ var t = String(data[i]);
+ if (s === '') {
+ s = t;
+ } else {
+ s += '0000000'.slice(0, 7 - t.length) + t;
+ }
+ }
+ }
+ return s;
+ }
+
+ function pow(x, n, acc) {
+ return (n === 0 ? acc : (n % 2 === 1 ? pow(x, n - 1, acc * x) : pow(x * x, n / 2, acc)));
+ }
+
+ function log(x) {
+ var n = 0;
+ while (x >= 4096) {
+ n += 12;
+ x /= 4096;
+ }
+ while (x >= 2) {
+ n += 1;
+ x /= 2;
+ }
+ return n;
+ }
+
+ Number.prototype.toFixed = function toFixed(fractionDigits) {
+ var f, x, s, m, e, z, j, k;
+
+ // Test for NaN and round fractionDigits down
+ f = Number(fractionDigits);
+ f = f !== f ? 0 : Math.floor(f);
+
+ if (f < 0 || f > 20) {
+ throw new RangeError("Number.toFixed called with invalid number of decimals");
+ }
+
+ x = Number(this);
+
+ // Test for NaN
+ if (x !== 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 = log(x * pow(2, 69, 1)) - 69;
+ z = (e < 0 ? x * pow(2, -e, 1) : x / pow(2, e, 1));
+ z *= 0x10000000000000; // Math.pow(2, 52);
+ e = 52 - e;
+
+ // -18 < e < 122
+ // x = z / 2 ^ e
+ if (e > 0) {
+ multiply(0, z);
+ j = f;
+
+ while (j >= 7) {
+ multiply(1e7, 0);
+ j -= 7;
+ }
+
+ multiply(pow(10, j, 1), 0);
+ j = e - 1;
+
+ while (j >= 23) {
+ divide(1 << 23);
+ j -= 23;
+ }
+
+ divide(1 << j);
+ multiply(1, 1);
+ divide(2);
+ m = numToString();
+ } else {
+ multiply(0, z);
+ multiply(1 << (-e), 0);
+ m = numToString() + '0.00000000000000000000'.slice(2, 2 + f);
+ }
+ }
+
+ if (f > 0) {
+ k = m.length;
+
+ if (k <= f) {
+ m = s + '0.0000000000000000000'.slice(0, f - k + 2) + m;
+ } else {
+ m = s + m.slice(0, k - f) + '.' + m.slice(k - f);
+ }
+ } else {
+ m = s + m;
+ }
+
+ return m;
+ };
+ }());
+ }
+
+
+//
+// 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 ["", "", "."]
+
+ var string_split = String.prototype.split;
+ 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 = /()??/.exec("")[1] === void 0; // NPCG: nonparticipating capturing group
+
+ String.prototype.split = function (separator, limit) {
+ var string = this;
+ if (separator === void 0 && limit === 0) {
+ return [];
+ }
+
+ // If `separator` is not a regex, use native split
+ if (_toString.call(separator) !== "[object RegExp]") {
+ return string_split.call(this, separator, limit);
+ }
+
+ var output = [],
+ flags = (separator.ignoreCase ? "i" : "") +
+ (separator.multiline ? "m" : "") +
+ (separator.extended ? "x" : "") + // Proposed for ES6
+ (separator.sticky ? "y" : ""), // Firefox 3+
+ lastLastIndex = 0,
+ // Make `global` and avoid `lastIndex` issues by working with a copy
+ separator2, match, lastIndex, lastLength;
+ separator = new RegExp(separator.source, flags + "g");
+ string += ""; // Type-convert
+ if (!compliantExecNpcg) {
+ // Doesn't need flags gy, but they don't hurt
+ separator2 = new RegExp("^" + separator.source + "$(?!\\s)", flags);
+ }
+ /* Values for `limit`, per the spec:
+ * If undefined: 4294967295 // Math.pow(2, 32) - 1
+ * 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
+ */
+ limit = limit === void 0 ?
+ -1 >>> 0 : // Math.pow(2, 32) - 1
+ ToUint32(limit);
+ while (match = separator.exec(string)) {
+ // `separator.lastIndex` is not reliable cross-browser
+ lastIndex = match.index + match[0].length;
+ if (lastIndex > lastLastIndex) {
+ output.push(string.slice(lastLastIndex, match.index));
+ // Fix browsers whose `exec` methods don't consistently return `undefined` for
+ // nonparticipating capturing groups
+ if (!compliantExecNpcg && match.length > 1) {
+ match[0].replace(separator2, function () {
+ for (var i = 1; i < arguments.length - 2; i++) {
+ if (arguments[i] === void 0) {
+ match[i] = void 0;
+ }
+ }
+ });
+ }
+ if (match.length > 1 && match.index < string.length) {
+ Array.prototype.push.apply(output, match.slice(1));
+ }
+ lastLength = match[0].length;
+ lastLastIndex = lastIndex;
+ if (output.length >= limit) {
+ break;
+ }
+ }
+ if (separator.lastIndex === match.index) {
+ separator.lastIndex++; // Avoid an infinite loop
+ }
+ }
+ if (lastLastIndex === string.length) {
+ if (lastLength || !separator.test("")) {
+ output.push("");
+ }
+ } else {
+ output.push(string.slice(lastLastIndex));
+ }
+ return output.length > limit ? output.slice(0, limit) : 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) {
+ String.prototype.split = function split(separator, limit) {
+ if (separator === void 0 && limit === 0) { return []; }
+ return string_split.call(this, separator, limit);
+ };
+ }
+
+ var str_replace = String.prototype.replace;
+ var replaceReportsGroupsCorrectly = (function () {
+ var groups = [];
+ 'x'.replace(/x(.)?/g, function (match, group) {
+ groups.push(group);
+ });
+ return groups.length === 1 && typeof groups[0] === 'undefined';
+ }());
+
+ if (!replaceReportsGroupsCorrectly) {
+ String.prototype.replace = function replace(searchValue, replaceValue) {
+ var isFn = isFunction(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;
+ args.push(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
+ if ("".substr && "0b".substr(-1) !== "b") {
+ var string_substr = String.prototype.substr;
+ /**
+ * Get the substring of a string
+ * @param {integer} start where to start the substring
+ * @param {integer} length how many characters to return
+ * @return {string}
+ */
+ String.prototype.substr = function substr(start, length) {
+ return string_substr.call(
+ this,
+ start < 0 ? ((start = this.length + start) < 0 ? 0 : start) : start,
+ length
+ );
+ };
+ }
+
+// 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';
+ if (!String.prototype.trim || ws.trim() || !zeroWidth.trim()) {
+ // http://blog.stevenlevithan.com/archives/faster-trim-javascript
+ // http://perfectionkills.com/whitespace-deviations/
+ ws = "[" + ws + "]";
+ var trimBeginRegexp = new RegExp("^" + ws + ws + "*"),
+ trimEndRegexp = new RegExp(ws + ws + "*$");
+ String.prototype.trim = function trim() {
+ if (this === void 0 || this === null) {
+ throw new TypeError("can't convert " + this + " to object");
+ }
+ return String(this)
+ .replace(trimBeginRegexp, "")
+ .replace(trimEndRegexp, "");
+ };
+ }
+
+// ES-5 15.1.2.2
+ if (parseInt(ws + '08') !== 8 || parseInt(ws + '0x16') !== 22) {
+ parseInt = (function (origParseInt) {
+ var hexRegex = /^0[xX]/;
+ return function parseIntES5(str, radix) {
+ str = String(str).trim();
+ if (!Number(radix)) {
+ radix = hexRegex.test(str) ? 16 : 10;
+ }
+ return origParseInt(str, radix);
+ };
+ }(parseInt));
+ }
+
+//
+// Util
+// ======
+//
+
+// ES5 9.4
+// http://es5.github.com/#x9.4
+// http://jsperf.com/to-integer
+
+ function toInteger(n) {
+ n = +n;
+ if (n !== n) { // isNaN
+ n = 0;
+ } else if (n !== 0 && n !== (1 / 0) && n !== -(1 / 0)) {
+ n = (n > 0 || -1) * Math.floor(Math.abs(n));
+ }
+ return n;
+ }
+
+ function isPrimitive(input) {
+ var type = typeof input;
+ return (
+ input === null ||
+ type === "undefined" ||
+ type === "boolean" ||
+ type === "number" ||
+ type === "string"
+ );
+ }
+
+ function toPrimitive(input) {
+ var val, valueOf, toStr;
+ if (isPrimitive(input)) {
+ return input;
+ }
+ valueOf = input.valueOf;
+ if (isFunction(valueOf)) {
+ val = valueOf.call(input);
+ if (isPrimitive(val)) {
+ return val;
+ }
+ }
+ toStr = input.toString;
+ if (isFunction(toStr)) {
+ val = toStr.call(input);
+ if (isPrimitive(val)) {
+ return val;
+ }
+ }
+ throw new TypeError();
+ }
+
+// ES5 9.9
+// http://es5.github.com/#x9.9
+ var toObject = function (o) {
+ if (o == null) { // this matches both null and undefined
+ throw new TypeError("can't convert " + o + " to object");
+ }
+ return Object(o);
+ };
+
+ var ToUint32 = function ToUint32(x) {
+ return x >>> 0;
+ };
+
+})();
+
+
+
+
+(function($, shims){
+ var defineProperty = 'defineProperty';
+ var advancedObjectProperties = !!(Object.create && Object.defineProperties && Object.getOwnPropertyDescriptor);
+ //safari5 has defineProperty-interface, but it can't be used on dom-object
+ //only do this test in non-IE browsers, because this hurts dhtml-behavior in some IE8 versions
+ if (advancedObjectProperties && Object[defineProperty] && Object.prototype.__defineGetter__) {
+ (function(){
+ try {
+ var foo = document.createElement('foo');
+ Object[defineProperty](foo, 'bar', {
+ get: function(){
+ return true;
+ }
+ });
+ advancedObjectProperties = !!foo.bar;
+ }
+ catch (e) {
+ advancedObjectProperties = false;
+ }
+ foo = null;
+ })();
+ }
+ var support = webshims.support;
+ support.objectAccessor = !!((advancedObjectProperties || (Object.prototype.__defineGetter__ && Object.prototype.__lookupSetter__)));
+ support.advancedObjectProperties = advancedObjectProperties;
+
+if((!advancedObjectProperties || !Object.create || !Object.defineProperties || !Object.getOwnPropertyDescriptor || !Object.defineProperty)){
+ var call = Function.prototype.call;
+ var prototypeOfObject = Object.prototype;
+ var owns = call.bind(prototypeOfObject.hasOwnProperty);
+
+ shims.objectCreate = function(proto, props, opts, no__proto__){
+ var o;
+ var f = function(){};
+
+ f.prototype = proto;
+ o = new f();
+
+ if(!no__proto__ && !('__proto__' in o) && !support.objectAccessor){
+ o.__proto__ = proto;
+ }
+
+ if(props){
+ shims.defineProperties(o, props);
+ }
+
+ if(opts){
+ o.options = $.extend(true, {}, o.options || {}, opts);
+ opts = o.options;
+ }
+
+ if(o._create && $.isFunction(o._create)){
+ o._create(opts);
+ }
+ return o;
+ };
+
+ shims.defineProperties = function(object, props){
+ for (var name in props) {
+ if (owns(props, name)) {
+ shims.defineProperty(object, name, props[name]);
+ }
+ }
+ return object;
+ };
+
+ var descProps = ['configurable', 'enumerable', 'writable'];
+ shims.defineProperty = function(proto, property, descriptor){
+ if(typeof descriptor != "object" || descriptor === null){return proto;}
+
+ if(owns(descriptor, "value")){
+ proto[property] = descriptor.value;
+ return proto;
+ }
+
+ if(proto.__defineGetter__){
+ if (typeof descriptor.get == "function") {
+ proto.__defineGetter__(property, descriptor.get);
+ }
+ if (typeof descriptor.set == "function"){
+ proto.__defineSetter__(property, descriptor.set);
+ }
+ }
+ return proto;
+ };
+
+ shims.getPrototypeOf = function (object) {
+ return Object.getPrototypeOf && Object.getPrototypeOf(object) || object.__proto__ || object.constructor && object.constructor.prototype;
+ };
+
+ //based on http://www.refactory.org/s/object_getownpropertydescriptor/view/latest
+ shims.getOwnPropertyDescriptor = function(obj, prop){
+ if (typeof obj !== "object" && typeof obj !== "function" || obj === null){
+ throw new TypeError("Object.getOwnPropertyDescriptor called on a non-object");
+ }
+ var descriptor;
+ if(Object.defineProperty && Object.getOwnPropertyDescriptor){
+ try{
+ descriptor = Object.getOwnPropertyDescriptor(obj, prop);
+ return descriptor;
+ } catch(e){}
+ }
+ descriptor = {
+ configurable: true,
+ enumerable: true,
+ writable: true,
+ value: undefined
+ };
+ var getter = obj.__lookupGetter__ && obj.__lookupGetter__(prop),
+ setter = obj.__lookupSetter__ && obj.__lookupSetter__(prop)
+ ;
+
+ if (!getter && !setter) { // not an accessor so return prop
+ if(!owns(obj, prop)){
+ return;
+ }
+ descriptor.value = obj[prop];
+ return descriptor;
+ }
+
+ // there is an accessor, remove descriptor.writable; populate descriptor.get and descriptor.set
+ delete descriptor.writable;
+ delete descriptor.value;
+ descriptor.get = descriptor.set = undefined;
+
+ if(getter){
+ descriptor.get = getter;
+ }
+
+ if(setter){
+ descriptor.set = setter;
+ }
+
+ return descriptor;
+ };
+
+}
+webshims.isReady('es5', true);
+})(webshims.$, webshims);
+
+
diff --git a/public/webshims/shims/es6.js b/public/webshims/shims/es6.js
new file mode 100755
index 00000000..1fdca9bb
--- /dev/null
+++ b/public/webshims/shims/es6.js
@@ -0,0 +1,1887 @@
+// ES6-shim 0.8.0 (c) 2013 Paul Miller (paulmillr.com)
+// ES6-shim may be freely distributed under the MIT license.
+// For more details and documentation:
+// https://github.com/paulmillr/es6-shim/
+webshim.register('es6', function($, webshim, window, document, undefined){
+
+ 'use strict';
+
+ var isCallableWithoutNew = function(func) {
+ try { func(); }
+ catch (e) { return false; }
+ return true;
+ };
+
+ var supportsSubclassing = function(C, f) {
+ /* jshint proto:true */
+ try {
+ var Sub = function() { C.apply(this, arguments); };
+ if (!Sub.__proto__) { return false; /* skip test on IE < 11 */ }
+ Object.setPrototypeOf(Sub, C);
+ Sub.prototype = Object.create(C.prototype, {
+ constructor: { value: C }
+ });
+ return f(Sub);
+ } catch (e) {
+ return false;
+ }
+ };
+
+ var arePropertyDescriptorsSupported = function() {
+ try {
+ Object.defineProperty({}, 'x', {});
+ return true;
+ } catch (e) { /* this is IE 8. */
+ return false;
+ }
+ };
+
+ var startsWithRejectsRegex = function() {
+ var rejectsRegex = false;
+ if (String.prototype.startsWith) {
+ try {
+ '/a/'.startsWith(/a/);
+ } catch (e) { /* this is spec compliant */
+ rejectsRegex = true;
+ }
+ }
+ return rejectsRegex;
+ };
+
+ /*jshint evil: true */
+ var getGlobal = new Function('return this;');
+ /*jshint evil: false */
+
+ var main = function() {
+ var globals = getGlobal();
+ var global_isFinite = globals.isFinite;
+ var supportsDescriptors = !!Object.defineProperty && arePropertyDescriptorsSupported();
+ var startsWithIsCompliant = startsWithRejectsRegex();
+ var _slice = Array.prototype.slice;
+ var _indexOf = String.prototype.indexOf;
+ var _toString = Object.prototype.toString;
+ var _hasOwnProperty = Object.prototype.hasOwnProperty;
+ var ArrayIterator; // make our implementation private
+
+ // Define configurable, writable and non-enumerable props
+ // if they don’t exist.
+ var defineProperties = function(object, map) {
+ Object.keys(map).forEach(function(name) {
+ var method = map[name];
+ if (name in object) return;
+ if (supportsDescriptors) {
+ Object.defineProperty(object, name, {
+ configurable: true,
+ enumerable: false,
+ writable: true,
+ value: method
+ });
+ } else {
+ object[name] = method;
+ }
+ });
+ };
+
+ // Simple shim for Object.create on ES3 browsers
+ // (unlike real shim, no attempt to support `prototype === null`)
+ var create = Object.create || function(prototype, properties) {
+ function Type() {}
+ Type.prototype = prototype;
+ var object = new Type();
+ if (typeof properties !== "undefined") {
+ defineProperties(object, properties);
+ }
+ return object;
+ };
+
+ // This is a private name in the es6 spec, equal to '[Symbol.iterator]'
+ // we're going to use an arbitrary _-prefixed name to make our shims
+ // work properly with each other, even though we don't have full Iterator
+ // support. That is, `Array.from(map.keys())` will work, but we don't
+ // pretend to export a "real" Iterator interface.
+ var $iterator$ = (typeof Symbol === 'object' && Symbol.iterator) ||
+ '_es6shim_iterator_';
+ // Firefox ships a partial implementation using the name @@iterator.
+ // https://bugzilla.mozilla.org/show_bug.cgi?id=907077#c14
+ // So use that name if we detect it.
+ if (globals.Set && typeof new globals.Set()['@@iterator'] === 'function') {
+ $iterator$ = '@@iterator';
+ }
+ var addIterator = function(prototype, impl) {
+ if (!impl) { impl = function iterator() { return this; }; }
+ var o = {};
+ o[$iterator$] = impl;
+ defineProperties(prototype, o);
+ };
+
+ // 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 isArguments = function isArguments(value) {
+ var str = _toString.call(value);
+ var result = str === '[object Arguments]';
+ if (!result) {
+ result = str !== '[object Array]' &&
+ value !== null &&
+ typeof value === 'object' &&
+ typeof value.length === 'number' &&
+ value.length >= 0 &&
+ _toString.call(value.callee) === '[object Function]';
+ }
+ return result;
+ };
+
+ var emulateES6construct = function(o) {
+ if (!ES.TypeIsObject(o)) throw new TypeError('bad object');
+ // es5 approximation to es6 subclass semantics: in es6, 'new Foo'
+ // would invoke Foo.@@create to allocation/initialize the new object.
+ // In es5 we just get the plain object. So if we detect an
+ // uninitialized object, invoke o.constructor.@@create
+ if (!o._es6construct) {
+ if (o.constructor && ES.IsCallable(o.constructor['@@create'])) {
+ o = o.constructor['@@create'](o);
+ }
+ defineProperties(o, { _es6construct: true });
+ }
+ return o;
+ };
+
+ var ES = {
+ CheckObjectCoercible: function(x, optMessage) {
+ /* jshint eqnull:true */
+ if (x == null)
+ throw new TypeError(optMessage || ('Cannot call method on ' + x));
+ return x;
+ },
+
+ TypeIsObject: function(x) {
+ /* jshint eqnull:true */
+ // this is expensive when it returns false; use this function
+ // when you expect it to return true in the common case.
+ return x != null && Object(x) === x;
+ },
+
+ ToObject: function(o, optMessage) {
+ return Object(ES.CheckObjectCoercible(o, optMessage));
+ },
+
+ IsCallable: function(x) {
+ return typeof x === 'function' &&
+ // some versions of IE say that typeof /abc/ === 'function'
+ _toString.call(x) === '[object Function]';
+ },
+
+ ToInt32: function(x) {
+ return x >> 0;
+ },
+
+ ToUint32: function(x) {
+ return x >>> 0;
+ },
+
+ ToInteger: function(value) {
+ var number = +value;
+ if (Number.isNaN(number)) return 0;
+ if (number === 0 || !Number.isFinite(number)) return number;
+ return Math.sign(number) * Math.floor(Math.abs(number));
+ },
+
+ ToLength: function(value) {
+ var len = ES.ToInteger(value);
+ if (len <= 0) return 0; // includes converting -0 to +0
+ if (len > Number.MAX_SAFE_INTEGER) return Number.MAX_SAFE_INTEGER;
+ return len;
+ },
+
+ SameValue: function(a, b) {
+ if (a === b) {
+ // 0 === -0, but they are not identical.
+ if (a === 0) return 1 / a === 1 / b;
+ return true;
+ }
+ return Number.isNaN(a) && Number.isNaN(b);
+ },
+
+ SameValueZero: function(a, b) {
+ // same as SameValue except for SameValueZero(+0, -0) == true
+ return (a === b) || (Number.isNaN(a) && Number.isNaN(b));
+ },
+
+ IsIterable: function(o) {
+ return ES.TypeIsObject(o) &&
+ (o[$iterator$] !== undefined || isArguments(o));
+ },
+
+ GetIterator: function(o) {
+ if (isArguments(o)) {
+ // special case support for `arguments`
+ return new ArrayIterator(o, "value");
+ }
+ var it = o[$iterator$]();
+ if (!ES.TypeIsObject(it)) {
+ throw new TypeError('bad iterator');
+ }
+ return it;
+ },
+
+ IteratorNext: function(it) {
+ var result = (arguments.length > 1) ? it.next(arguments[1]) : it.next();
+ if (!ES.TypeIsObject(result)) {
+ throw new TypeError('bad iterator');
+ }
+ return result;
+ },
+
+ Construct: function(C, args) {
+ // CreateFromConstructor
+ var obj;
+ if (ES.IsCallable(C['@@create'])) {
+ obj = C['@@create']();
+ } else {
+ // OrdinaryCreateFromConstructor
+ obj = create(C.prototype || null);
+ }
+ // Mark that we've used the es6 construct path
+ // (see emulateES6construct)
+ defineProperties(obj, { _es6construct: true });
+ // Call the constructor.
+ var result = C.apply(obj, args);
+ return ES.TypeIsObject(result) ? result : obj;
+ }
+ };
+
+ var numberConversion = (function () {
+ // from https://github.com/inexorabletash/polyfill/blob/master/typedarray.js#L176-L266
+ // with permission and license, per https://twitter.com/inexorabletash/status/372206509540659200
+
+ function roundToEven(n) {
+ var w = Math.floor(n), f = n - w;
+ if (f < 0.5) {
+ return w;
+ }
+ if (f > 0.5) {
+ return w + 1;
+ }
+ return w % 2 ? w + 1 : w;
+ }
+
+ function packIEEE754(v, ebits, fbits) {
+ var bias = (1 << (ebits - 1)) - 1,
+ s, e, f, ln,
+ i, bits, str, bytes;
+
+ // Compute sign, exponent, fraction
+ if (v !== v) {
+ // NaN
+ // http://dev.w3.org/2006/webapi/WebIDL/#es-type-mapping
+ e = (1 << ebits) - 1;
+ f = Math.pow(2, fbits - 1);
+ s = 0;
+ } else if (v === Infinity || v === -Infinity) {
+ e = (1 << ebits) - 1;
+ f = 0;
+ s = (v < 0) ? 1 : 0;
+ } else if (v === 0) {
+ e = 0;
+ f = 0;
+ s = (1 / v === -Infinity) ? 1 : 0;
+ } else {
+ s = v < 0;
+ v = Math.abs(v);
+
+ if (v >= Math.pow(2, 1 - bias)) {
+ e = Math.min(Math.floor(Math.log(v) / Math.LN2), 1023);
+ f = roundToEven(v / Math.pow(2, e) * Math.pow(2, fbits));
+ if (f / Math.pow(2, fbits) >= 2) {
+ e = e + 1;
+ f = 1;
+ }
+ if (e > bias) {
+ // Overflow
+ e = (1 << ebits) - 1;
+ f = 0;
+ } else {
+ // Normal
+ e = e + bias;
+ f = f - Math.pow(2, fbits);
+ }
+ } else {
+ // Subnormal
+ e = 0;
+ f = roundToEven(v / Math.pow(2, 1 - bias - fbits));
+ }
+ }
+
+ // Pack sign, exponent, fraction
+ bits = [];
+ for (i = fbits; i; i -= 1) {
+ bits.push(f % 2 ? 1 : 0);
+ f = Math.floor(f / 2);
+ }
+ for (i = ebits; i; i -= 1) {
+ bits.push(e % 2 ? 1 : 0);
+ e = Math.floor(e / 2);
+ }
+ bits.push(s ? 1 : 0);
+ bits.reverse();
+ str = bits.join('');
+
+ // Bits to bytes
+ bytes = [];
+ while (str.length) {
+ bytes.push(parseInt(str.substring(0, 8), 2));
+ str = str.substring(8);
+ }
+ return bytes;
+ }
+
+ function unpackIEEE754(bytes, ebits, fbits) {
+ // Bytes to bits
+ var bits = [], i, j, b, str,
+ bias, s, e, f;
+
+ for (i = bytes.length; i; i -= 1) {
+ b = bytes[i - 1];
+ for (j = 8; j; j -= 1) {
+ bits.push(b % 2 ? 1 : 0);
+ b = b >> 1;
+ }
+ }
+ bits.reverse();
+ str = bits.join('');
+
+ // Unpack sign, exponent, fraction
+ bias = (1 << (ebits - 1)) - 1;
+ s = parseInt(str.substring(0, 1), 2) ? -1 : 1;
+ e = parseInt(str.substring(1, 1 + ebits), 2);
+ f = parseInt(str.substring(1 + ebits), 2);
+
+ // Produce number
+ if (e === (1 << ebits) - 1) {
+ return f !== 0 ? NaN : s * Infinity;
+ } else if (e > 0) {
+ // Normalized
+ return s * Math.pow(2, e - bias) * (1 + f / Math.pow(2, fbits));
+ } else if (f !== 0) {
+ // Denormalized
+ return s * Math.pow(2, -(bias - 1)) * (f / Math.pow(2, fbits));
+ } else {
+ return s < 0 ? -0 : 0;
+ }
+ }
+
+ function unpackFloat64(b) { return unpackIEEE754(b, 11, 52); }
+ function packFloat64(v) { return packIEEE754(v, 11, 52); }
+ function unpackFloat32(b) { return unpackIEEE754(b, 8, 23); }
+ function packFloat32(v) { return packIEEE754(v, 8, 23); }
+
+ var conversions = {
+ toFloat32: function (num) { return unpackFloat32(packFloat32(num)); }
+ };
+ if (typeof Float32Array !== 'undefined') {
+ var float32array = new Float32Array(1);
+ conversions.toFloat32 = function (num) {
+ float32array[0] = num;
+ return float32array[0];
+ };
+ }
+ return conversions;
+ }());
+
+ defineProperties(String, {
+ fromCodePoint: function() {
+ var points = _slice.call(arguments, 0, arguments.length);
+ var result = [];
+ var next;
+ for (var i = 0, length = points.length; i < length; i++) {
+ next = Number(points[i]);
+ if (!ES.SameValue(next, ES.ToInteger(next)) ||
+ next < 0 || next > 0x10FFFF) {
+ throw new RangeError('Invalid code point ' + next);
+ }
+
+ if (next < 0x10000) {
+ result.push(String.fromCharCode(next));
+ } else {
+ next -= 0x10000;
+ result.push(String.fromCharCode((next >> 10) + 0xD800));
+ result.push(String.fromCharCode((next % 0x400) + 0xDC00));
+ }
+ }
+ return result.join('');
+ },
+
+ raw: function(callSite) { // raw.length===1
+ var substitutions = _slice.call(arguments, 1, arguments.length);
+ var cooked = ES.ToObject(callSite, 'bad callSite');
+ var rawValue = cooked.raw;
+ var raw = ES.ToObject(rawValue, 'bad raw value');
+ var len = Object.keys(raw).length;
+ var literalsegments = ES.ToLength(len);
+ if (literalsegments === 0) {
+ return '';
+ }
+
+ var stringElements = [];
+ var nextIndex = 0;
+ var nextKey, next, nextSeg, nextSub;
+ while (nextIndex < literalsegments) {
+ nextKey = String(nextIndex);
+ next = raw[nextKey];
+ nextSeg = String(next);
+ stringElements.push(nextSeg);
+ if (nextIndex + 1 >= literalsegments) {
+ break;
+ }
+ next = substitutions[nextKey];
+ if (next === undefined) {
+ break;
+ }
+ nextSub = String(next);
+ stringElements.push(nextSub);
+ nextIndex++;
+ }
+ return stringElements.join('');
+ }
+ });
+
+ var StringShims = {
+ // Fast repeat, uses the `Exponentiation by squaring` algorithm.
+ // Perf: http://jsperf.com/string-repeat2/2
+ repeat: (function() {
+ var repeat = function(s, times) {
+ if (times < 1) return '';
+ if (times % 2) return repeat(s, times - 1) + s;
+ var half = repeat(s, times / 2);
+ return half + half;
+ };
+
+ return function(times) {
+ var thisStr = String(ES.CheckObjectCoercible(this));
+ times = ES.ToInteger(times);
+ if (times < 0 || times === Infinity) {
+ throw new RangeError('Invalid String#repeat value');
+ }
+ return repeat(thisStr, times);
+ };
+ })(),
+
+ startsWith: function(searchStr) {
+ var thisStr = String(ES.CheckObjectCoercible(this));
+ if (_toString.call(searchStr) === '[object RegExp]') throw new TypeError('Cannot call method "startsWith" with a regex');
+ searchStr = String(searchStr);
+ var startArg = arguments.length > 1 ? arguments[1] : undefined;
+ var start = Math.max(ES.ToInteger(startArg), 0);
+ return thisStr.slice(start, start + searchStr.length) === searchStr;
+ },
+
+ endsWith: function(searchStr) {
+ var thisStr = String(ES.CheckObjectCoercible(this));
+ if (_toString.call(searchStr) === '[object RegExp]') throw new TypeError('Cannot call method "endsWith" with a regex');
+ searchStr = String(searchStr);
+ var thisLen = thisStr.length;
+ var posArg = arguments.length > 1 ? arguments[1] : undefined;
+ var pos = posArg === undefined ? thisLen : ES.ToInteger(posArg);
+ var end = Math.min(Math.max(pos, 0), thisLen);
+ return thisStr.slice(end - searchStr.length, end) === searchStr;
+ },
+
+ contains: function(searchString) {
+ var position = arguments.length > 1 ? arguments[1] : undefined;
+ // Somehow this trick makes method 100% compat with the spec.
+ return _indexOf.call(this, searchString, position) !== -1;
+ },
+
+ codePointAt: function(pos) {
+ var thisStr = String(ES.CheckObjectCoercible(this));
+ var position = ES.ToInteger(pos);
+ var length = thisStr.length;
+ if (position < 0 || position >= length) return undefined;
+ var first = thisStr.charCodeAt(position);
+ var isEnd = (position + 1 === length);
+ if (first < 0xD800 || first > 0xDBFF || isEnd) return first;
+ var second = thisStr.charCodeAt(position + 1);
+ if (second < 0xDC00 || second > 0xDFFF) return first;
+ return ((first - 0xD800) * 1024) + (second - 0xDC00) + 0x10000;
+ }
+ };
+ defineProperties(String.prototype, StringShims);
+
+ var hasStringTrimBug = '\u0085'.trim().length !== 1;
+ if (hasStringTrimBug) {
+ var originalStringTrim = String.prototype.trim;
+ delete String.prototype.trim;
+ // whitespace from: http://es5.github.io/#x15.5.4.20
+ // implementation from https://github.com/es-shims/es5-shim/blob/v3.4.0/es5-shim.js#L1304-L1324
+ 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'
+ ].join('');
+ var trimBeginRegexp = new RegExp('^[' + ws + '][' + ws + ']*');
+ var trimEndRegexp = new RegExp('[' + ws + '][' + ws + ']*$');
+ defineProperties(String.prototype, {
+ trim: function() {
+ if (this === undefined || this === null) {
+ throw new TypeError("can't convert " + this + " to object");
+ }
+ return String(this)
+ .replace(trimBeginRegexp, "")
+ .replace(trimEndRegexp, "");
+ }
+ });
+ }
+
+ // see https://people.mozilla.org/~jorendorff/es6-draft.html#sec-string.prototype-@@iterator
+ var StringIterator = function(s) {
+ this._s = String(ES.CheckObjectCoercible(s));
+ this._i = 0;
+ };
+ StringIterator.prototype.next = function() {
+ var s = this._s, i = this._i;
+ if (s === undefined || i >= s.length) {
+ this._s = undefined;
+ return { value: undefined, done: true };
+ }
+ var first = s.charCodeAt(i), second, len;
+ if (first < 0xD800 || first > 0xDBFF || (i+1) == s.length) {
+ len = 1;
+ } else {
+ second = s.charCodeAt(i+1);
+ len = (second < 0xDC00 || second > 0xDFFF) ? 1 : 2;
+ }
+ this._i = i + len;
+ return { value: s.substr(i, len), done: false };
+ };
+ addIterator(StringIterator.prototype);
+ addIterator(String.prototype, function() {
+ return new StringIterator(this);
+ });
+
+ if (!startsWithIsCompliant) {
+ // Firefox has a noncompliant startsWith implementation
+ String.prototype.startsWith = StringShims.startsWith;
+ String.prototype.endsWith = StringShims.endsWith;
+ }
+
+ defineProperties(Array, {
+ from: function(iterable) {
+ var mapFn = arguments.length > 1 ? arguments[1] : undefined;
+ var thisArg = arguments.length > 2 ? arguments[2] : undefined;
+
+ var list = ES.ToObject(iterable, 'bad iterable');
+ if (mapFn !== undefined && !ES.IsCallable(mapFn)) {
+ throw new TypeError('Array.from: when provided, the second argument must be a function');
+ }
+
+ var usingIterator = ES.IsIterable(list);
+ // does the spec really mean that Arrays should use ArrayIterator?
+ // https://bugs.ecmascript.org/show_bug.cgi?id=2416
+ //if (Array.isArray(list)) { usingIterator=false; }
+ var length = usingIterator ? 0 : ES.ToLength(list.length);
+ var result = ES.IsCallable(this) ? Object(usingIterator ? new this() : new this(length)) : new Array(length);
+ var it = usingIterator ? ES.GetIterator(list) : null;
+ var value;
+
+ for (var i = 0; usingIterator || (i < length); i++) {
+ if (usingIterator) {
+ value = ES.IteratorNext(it);
+ if (value.done) {
+ length = i;
+ break;
+ }
+ value = value.value;
+ } else {
+ value = list[i];
+ }
+ if (mapFn) {
+ result[i] = thisArg ? mapFn.call(thisArg, value, i) : mapFn(value, i);
+ } else {
+ result[i] = value;
+ }
+ }
+
+ result.length = length;
+ return result;
+ },
+
+ of: function() {
+ return Array.from(arguments);
+ }
+ });
+
+ // Our ArrayIterator is private; see
+ // https://github.com/paulmillr/es6-shim/issues/252
+ ArrayIterator = function(array, kind) {
+ this.i = 0;
+ this.array = array;
+ this.kind = kind;
+ };
+
+ defineProperties(ArrayIterator.prototype, {
+ next: function() {
+ var i = this.i, array = this.array;
+ if (i === undefined || this.kind === undefined) {
+ throw new TypeError('Not an ArrayIterator');
+ }
+ if (array!==undefined) {
+ var len = ES.ToLength(array.length);
+ for (; i < len; i++) {
+ var kind = this.kind;
+ var retval;
+ if (kind === "key") {
+ retval = i;
+ } else if (kind === "value") {
+ retval = array[i];
+ } else if (kind === "entry") {
+ retval = [i, array[i]];
+ }
+ this.i = i + 1;
+ return { value: retval, done: false };
+ }
+ }
+ this.array = undefined;
+ return { value: undefined, done: true };
+ }
+ });
+ addIterator(ArrayIterator.prototype);
+
+ defineProperties(Array.prototype, {
+ copyWithin: function(target, start) {
+ var end = arguments[2]; // copyWithin.length must be 2
+ var o = ES.ToObject(this);
+ var len = ES.ToLength(o.length);
+ target = ES.ToInteger(target);
+ start = ES.ToInteger(start);
+ var to = target < 0 ? Math.max(len + target, 0) : Math.min(target, len);
+ var from = start < 0 ? Math.max(len + start, 0) : Math.min(start, len);
+ end = (end===undefined) ? len : ES.ToInteger(end);
+ var fin = end < 0 ? Math.max(len + end, 0) : Math.min(end, len);
+ var count = Math.min(fin - from, len - to);
+ var direction = 1;
+ if (from < to && to < (from + count)) {
+ direction = -1;
+ from += count - 1;
+ to += count - 1;
+ }
+ while (count > 0) {
+ if (_hasOwnProperty.call(o, from)) {
+ o[to] = o[from];
+ } else {
+ delete o[from];
+ }
+ from += direction;
+ to += direction;
+ count -= 1;
+ }
+ return o;
+ },
+
+ fill: function(value) {
+ var start = arguments[1], end = arguments[2]; // fill.length===1
+ var O = ES.ToObject(this);
+ var len = ES.ToLength(O.length);
+ start = ES.ToInteger(start===undefined ? 0 : start);
+ end = ES.ToInteger(end===undefined ? len : end);
+
+ var relativeStart = start < 0 ? Math.max(len + start, 0) : Math.min(start, len);
+
+ for (var i = relativeStart; i < len && i < end; ++i) {
+ O[i] = value;
+ }
+ return O;
+ },
+
+ find: function(predicate) {
+ var list = ES.ToObject(this);
+ var length = ES.ToLength(list.length);
+ if (!ES.IsCallable(predicate)) {
+ throw new TypeError('Array#find: predicate must be a function');
+ }
+ var thisArg = arguments[1];
+ for (var i = 0, value; i < length; i++) {
+ if (i in list) {
+ value = list[i];
+ if (predicate.call(thisArg, value, i, list)) return value;
+ }
+ }
+ return undefined;
+ },
+
+ findIndex: function(predicate) {
+ var list = ES.ToObject(this);
+ var length = ES.ToLength(list.length);
+ if (!ES.IsCallable(predicate)) {
+ throw new TypeError('Array#findIndex: predicate must be a function');
+ }
+ var thisArg = arguments[1];
+ for (var i = 0; i < length; i++) {
+ if (i in list) {
+ if (predicate.call(thisArg, list[i], i, list)) return i;
+ }
+ }
+ return -1;
+ },
+
+ keys: function() {
+ return new ArrayIterator(this, "key");
+ },
+
+ values: function() {
+ return new ArrayIterator(this, "value");
+ },
+
+ entries: function() {
+ return new ArrayIterator(this, "entry");
+ }
+ });
+ addIterator(Array.prototype, function() { return this.values(); });
+ // Chrome defines keys/values/entries on Array, but doesn't give us
+ // any way to identify its iterator. So add our own shimmed field.
+ if (Object.getPrototypeOf) {
+ addIterator(Object.getPrototypeOf([].values()));
+ }
+
+ var maxSafeInteger = Math.pow(2, 53) - 1;
+ defineProperties(Number, {
+ MAX_SAFE_INTEGER: maxSafeInteger,
+ MIN_SAFE_INTEGER: -maxSafeInteger,
+ EPSILON: 2.220446049250313e-16,
+
+ parseInt: globals.parseInt,
+ parseFloat: globals.parseFloat,
+
+ isFinite: function(value) {
+ return typeof value === 'number' && global_isFinite(value);
+ },
+
+ isInteger: function(value) {
+ return typeof value === 'number' &&
+ !Number.isNaN(value) &&
+ Number.isFinite(value) &&
+ ES.ToInteger(value) === value;
+ },
+
+ isSafeInteger: function(value) {
+ return Number.isInteger(value) && Math.abs(value) <= Number.MAX_SAFE_INTEGER;
+ },
+
+ isNaN: function(value) {
+ // NaN !== NaN, but they are identical.
+ // NaNs are the only non-reflexive value, i.e., if x !== x,
+ // then x is NaN.
+ // isNaN is broken: it converts its argument to number, so
+ // isNaN('foo') => true
+ return value !== value;
+ }
+
+ });
+
+ if (supportsDescriptors) {
+ defineProperties(Object, {
+ getPropertyDescriptor: function(subject, name) {
+ var pd = Object.getOwnPropertyDescriptor(subject, name);
+ var proto = Object.getPrototypeOf(subject);
+ while (pd === undefined && proto !== null) {
+ pd = Object.getOwnPropertyDescriptor(proto, name);
+ proto = Object.getPrototypeOf(proto);
+ }
+ return pd;
+ },
+
+ getPropertyNames: function(subject) {
+ var result = Object.getOwnPropertyNames(subject);
+ var proto = Object.getPrototypeOf(subject);
+
+ var addProperty = function(property) {
+ if (result.indexOf(property) === -1) {
+ result.push(property);
+ }
+ };
+
+ while (proto !== null) {
+ Object.getOwnPropertyNames(proto).forEach(addProperty);
+ proto = Object.getPrototypeOf(proto);
+ }
+ return result;
+ }
+ });
+
+ defineProperties(Object, {
+ // 19.1.3.1
+ assign: function(target, source) {
+ if (!ES.TypeIsObject(target)) {
+ throw new TypeError('target must be an object');
+ }
+ return Array.prototype.reduce.call(arguments, function(target, source) {
+ if (!ES.TypeIsObject(source)) {
+ throw new TypeError('source must be an object');
+ }
+ return Object.keys(source).reduce(function(target, key) {
+ target[key] = source[key];
+ return target;
+ }, target);
+ });
+ },
+
+ getOwnPropertyKeys: function(subject) {
+ return Object.keys(subject);
+ },
+
+ is: function(a, b) {
+ return ES.SameValue(a, b);
+ },
+
+ // 19.1.3.9
+ // shim from https://gist.github.com/WebReflection/5593554
+ setPrototypeOf: (function(Object, magic) {
+ var set;
+
+ var checkArgs = function(O, proto) {
+ if (!ES.TypeIsObject(O)) {
+ throw new TypeError('cannot set prototype on a non-object');
+ }
+ if (!(proto===null || ES.TypeIsObject(proto))) {
+ throw new TypeError('can only set prototype to an object or null'+proto);
+ }
+ };
+
+ var setPrototypeOf = function(O, proto) {
+ checkArgs(O, proto);
+ set.call(O, proto);
+ return O;
+ };
+
+ try {
+ // this works already in Firefox and Safari
+ set = Object.getOwnPropertyDescriptor(Object.prototype, magic).set;
+ set.call({}, null);
+ } catch (e) {
+ if (Object.prototype !== {}[magic]) {
+ // IE < 11 cannot be shimmed
+ return;
+ }
+ // probably Chrome or some old Mobile stock browser
+ set = function(proto) {
+ this[magic] = proto;
+ };
+ // please note that this will **not** work
+ // in those browsers that do not inherit
+ // __proto__ by mistake from Object.prototype
+ // in these cases we should probably throw an error
+ // or at least be informed about the issue
+ setPrototypeOf.polyfill = setPrototypeOf(
+ setPrototypeOf({}, null),
+ Object.prototype
+ ) instanceof Object;
+ // setPrototypeOf.polyfill === true means it works as meant
+ // setPrototypeOf.polyfill === false means it's not 100% reliable
+ // setPrototypeOf.polyfill === undefined
+ // or
+ // setPrototypeOf.polyfill == null means it's not a polyfill
+ // which means it works as expected
+ // we can even delete Object.prototype.__proto__;
+ }
+ return setPrototypeOf;
+ })(Object, '__proto__')
+ });
+ }
+
+ // Workaround bug in Opera 12 where setPrototypeOf(x, null) doesn't work,
+ // but Object.create(null) does.
+ if (Object.setPrototypeOf && Object.getPrototypeOf &&
+ Object.getPrototypeOf(Object.setPrototypeOf({}, null)) !== null &&
+ Object.getPrototypeOf(Object.create(null)) === null) {
+ (function() {
+ var FAKENULL = Object.create(null);
+ var gpo = Object.getPrototypeOf, spo = Object.setPrototypeOf;
+ Object.getPrototypeOf = function(o) {
+ var result = gpo(o);
+ return result === FAKENULL ? null : result;
+ };
+ Object.setPrototypeOf = function(o, p) {
+ if (p === null) { p = FAKENULL; }
+ return spo(o, p);
+ };
+ Object.setPrototypeOf.polyfill = false;
+ })();
+ }
+
+ try {
+ Object.keys('foo');
+ } catch (e) {
+ var originalObjectKeys = Object.keys;
+ Object.keys = function (obj) {
+ return originalObjectKeys(ES.ToObject(obj));
+ };
+ }
+
+ var MathShims = {
+ acosh: function(value) {
+ value = Number(value);
+ if (Number.isNaN(value) || value < 1) return NaN;
+ if (value === 1) return 0;
+ if (value === Infinity) return value;
+ return Math.log(value + Math.sqrt(value * value - 1));
+ },
+
+ asinh: function(value) {
+ value = Number(value);
+ if (value === 0 || !global_isFinite(value)) {
+ return value;
+ }
+ return value < 0 ? -Math.asinh(-value) : Math.log(value + Math.sqrt(value * value + 1));
+ },
+
+ atanh: function(value) {
+ value = Number(value);
+ if (Number.isNaN(value) || value < -1 || value > 1) {
+ return NaN;
+ }
+ if (value === -1) return -Infinity;
+ if (value === 1) return Infinity;
+ if (value === 0) return value;
+ return 0.5 * Math.log((1 + value) / (1 - value));
+ },
+
+ cbrt: function(value) {
+ value = Number(value);
+ if (value === 0) return value;
+ var negate = value < 0, result;
+ if (negate) value = -value;
+ result = Math.pow(value, 1/3);
+ return negate ? -result : result;
+ },
+
+ clz32: function(value) {
+ // See https://bugs.ecmascript.org/show_bug.cgi?id=2465
+ value = Number(value);
+ if (Number.isNaN(value)) return NaN;
+ var number = ES.ToUint32(value);
+ if (number === 0) {
+ return 32;
+ }
+ return 32 - (number).toString(2).length;
+ },
+
+ cosh: function(value) {
+ value = Number(value);
+ if (value === 0) return 1; // +0 or -0
+ if (Number.isNaN(value)) return NaN;
+ if (!global_isFinite(value)) return Infinity;
+ if (value < 0) value = -value;
+ if (value > 21) return Math.exp(value) / 2;
+ return (Math.exp(value) + Math.exp(-value)) / 2;
+ },
+
+ expm1: function(value) {
+ value = Number(value);
+ if (value === -Infinity) return -1;
+ if (!global_isFinite(value) || value === 0) return value;
+ return Math.exp(value) - 1;
+ },
+
+ hypot: function(x, y) {
+ var anyNaN = false;
+ var allZero = true;
+ var anyInfinity = false;
+ var numbers = [];
+ Array.prototype.every.call(arguments, function(arg) {
+ var num = Number(arg);
+ if (Number.isNaN(num)) anyNaN = true;
+ else if (num === Infinity || num === -Infinity) anyInfinity = true;
+ else if (num !== 0) allZero = false;
+ if (anyInfinity) {
+ return false;
+ } else if (!anyNaN) {
+ numbers.push(Math.abs(num));
+ }
+ return true;
+ });
+ if (anyInfinity) return Infinity;
+ if (anyNaN) return NaN;
+ if (allZero) return 0;
+
+ numbers.sort(function (a, b) { return b - a; });
+ var largest = numbers[0];
+ var divided = numbers.map(function (number) { return number / largest; });
+ var sum = divided.reduce(function (sum, number) { return sum += number * number; }, 0);
+ return largest * Math.sqrt(sum);
+ },
+
+ log2: function(value) {
+ return Math.log(value) * Math.LOG2E;
+ },
+
+ log10: function(value) {
+ return Math.log(value) * Math.LOG10E;
+ },
+
+ log1p: function(value) {
+ value = Number(value);
+ if (value < -1 || Number.isNaN(value)) return NaN;
+ if (value === 0 || value === Infinity) return value;
+ if (value === -1) return -Infinity;
+ var result = 0;
+ var n = 50;
+
+ if (value < 0 || value > 1) return Math.log(1 + value);
+ for (var i = 1; i < n; i++) {
+ if ((i % 2) === 0) {
+ result -= Math.pow(value, i) / i;
+ } else {
+ result += Math.pow(value, i) / i;
+ }
+ }
+
+ return result;
+ },
+
+ sign: function(value) {
+ var number = +value;
+ if (number === 0) return number;
+ if (Number.isNaN(number)) return number;
+ return number < 0 ? -1 : 1;
+ },
+
+ sinh: function(value) {
+ value = Number(value);
+ if (!global_isFinite(value) || value === 0) return value;
+ return (Math.exp(value) - Math.exp(-value)) / 2;
+ },
+
+ tanh: function(value) {
+ value = Number(value);
+ if (Number.isNaN(value) || value === 0) return value;
+ if (value === Infinity) return 1;
+ if (value === -Infinity) return -1;
+ return (Math.exp(value) - Math.exp(-value)) / (Math.exp(value) + Math.exp(-value));
+ },
+
+ trunc: function(value) {
+ var number = Number(value);
+ return number < 0 ? -Math.floor(-number) : Math.floor(number);
+ },
+
+ imul: function(x, y) {
+ // taken from https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/imul
+ var ah = (x >>> 16) & 0xffff;
+ var al = x & 0xffff;
+ var bh = (y >>> 16) & 0xffff;
+ var bl = y & 0xffff;
+ // the shift by 0 fixes the sign on the high part
+ // the final |0 converts the unsigned value into a signed value
+ return ((al * bl) + (((ah * bl + al * bh) << 16) >>> 0)|0);
+ },
+
+ fround: function(x) {
+ if (x === 0 || x === Infinity || x === -Infinity || Number.isNaN(x)) {
+ return x;
+ }
+ var num = Number(x);
+ return numberConversion.toFloat32(num);
+ }
+ };
+ defineProperties(Math, MathShims);
+
+ if (Math.imul(0xffffffff, 5) !== -5) {
+ // Safari 6.1, at least, reports "0" for this value
+ Math.imul = MathShims.imul;
+ }
+
+ // Promises
+ // Simplest possible implementation; use a 3rd-party library if you
+ // want the best possible speed and/or long stack traces.
+ var PromiseShim = (function() {
+
+ var Promise, Promise$prototype;
+
+ ES.IsPromise = function(promise) {
+ if (!ES.TypeIsObject(promise)) {
+ return false;
+ }
+ if (!promise._promiseConstructor) {
+ // _promiseConstructor is a bit more unique than _status, so we'll
+ // check that instead of the [[PromiseStatus]] internal field.
+ return false;
+ }
+ if (promise._status === undefined) {
+ return false; // uninitialized
+ }
+ return true;
+ };
+
+ // "PromiseCapability" in the spec is what most promise implementations
+ // call a "deferred".
+ var PromiseCapability = function(C) {
+ if (!ES.IsCallable(C)) {
+ throw new TypeError('bad promise constructor');
+ }
+ var capability = this;
+ var resolver = function(resolve, reject) {
+ capability.resolve = resolve;
+ capability.reject = reject;
+ };
+ capability.promise = ES.Construct(C, [resolver]);
+ // see https://bugs.ecmascript.org/show_bug.cgi?id=2478
+ if (!capability.promise._es6construct) {
+ throw new TypeError('bad promise constructor');
+ }
+ if (!(ES.IsCallable(capability.resolve) &&
+ ES.IsCallable(capability.reject))) {
+ throw new TypeError('bad promise constructor');
+ }
+ };
+
+ // find an appropriate setImmediate-alike
+ var setTimeout = globals.setTimeout;
+ var makeZeroTimeout;
+ if (typeof window !== 'undefined' && ES.IsCallable(window.postMessage)) {
+ makeZeroTimeout = function() {
+ // from http://dbaron.org/log/20100309-faster-timeouts
+ var timeouts = [];
+ var messageName = "zero-timeout-message";
+ var setZeroTimeout = function(fn) {
+ timeouts.push(fn);
+ window.postMessage(messageName, "*");
+ };
+ var handleMessage = function(event) {
+ if (event.source == window && event.data == messageName) {
+ event.stopPropagation();
+ if (timeouts.length === 0) { return; }
+ var fn = timeouts.shift();
+ fn();
+ }
+ };
+ window.addEventListener("message", handleMessage, true);
+ return setZeroTimeout;
+ };
+ }
+ var makePromiseAsap = function() {
+ // An efficient task-scheduler based on a pre-existing Promise
+ // implementation, which we can use even if we override the
+ // global Promise below (in order to workaround bugs)
+ // https://github.com/Raynos/observ-hash/issues/2#issuecomment-35857671
+ var P = globals.Promise;
+ return P && P.resolve && function(task) {
+ return P.resolve().then(task);
+ };
+ };
+ var enqueue = ES.IsCallable(globals.setImmediate) ?
+ globals.setImmediate.bind(globals) :
+ typeof process === 'object' && process.nextTick ? process.nextTick :
+ makePromiseAsap() ||
+ (ES.IsCallable(makeZeroTimeout) ? makeZeroTimeout() :
+ function(task) { setTimeout(task, 0); }); // fallback
+
+ var triggerPromiseReactions = function(reactions, x) {
+ reactions.forEach(function(reaction) {
+ enqueue(function() {
+ // PromiseReactionTask
+ var handler = reaction.handler;
+ var capability = reaction.capability;
+ var resolve = capability.resolve;
+ var reject = capability.reject;
+ try {
+ var result = handler(x);
+ if (result === capability.promise) {
+ throw new TypeError('self resolution');
+ }
+ var updateResult =
+ updatePromiseFromPotentialThenable(result, capability);
+ if (!updateResult) {
+ resolve(result);
+ }
+ } catch (e) {
+ reject(e);
+ }
+ });
+ });
+ };
+
+ var updatePromiseFromPotentialThenable = function(x, capability) {
+ if (!ES.TypeIsObject(x)) {
+ return false;
+ }
+ var resolve = capability.resolve;
+ var reject = capability.reject;
+ try {
+ var then = x.then; // only one invocation of accessor
+ if (!ES.IsCallable(then)) { return false; }
+ then.call(x, resolve, reject);
+ } catch(e) {
+ reject(e);
+ }
+ return true;
+ };
+
+ var promiseResolutionHandler = function(promise, onFulfilled, onRejected){
+ return function(x) {
+ if (x === promise) {
+ return onRejected(new TypeError('self resolution'));
+ }
+ var C = promise._promiseConstructor;
+ var capability = new PromiseCapability(C);
+ var updateResult = updatePromiseFromPotentialThenable(x, capability);
+ if (updateResult) {
+ return capability.promise.then(onFulfilled, onRejected);
+ } else {
+ return onFulfilled(x);
+ }
+ };
+ };
+
+ Promise = function(resolver) {
+ var promise = this;
+ promise = emulateES6construct(promise);
+ if (!promise._promiseConstructor) {
+ // we use _promiseConstructor as a stand-in for the internal
+ // [[PromiseStatus]] field; it's a little more unique.
+ throw new TypeError('bad promise');
+ }
+ if (promise._status !== undefined) {
+ throw new TypeError('promise already initialized');
+ }
+ // see https://bugs.ecmascript.org/show_bug.cgi?id=2482
+ if (!ES.IsCallable(resolver)) {
+ throw new TypeError('not a valid resolver');
+ }
+ promise._status = 'unresolved';
+ promise._resolveReactions = [];
+ promise._rejectReactions = [];
+
+ var resolve = function(resolution) {
+ if (promise._status !== 'unresolved') { return; }
+ var reactions = promise._resolveReactions;
+ promise._result = resolution;
+ promise._resolveReactions = undefined;
+ promise._rejectReactions = undefined;
+ promise._status = 'has-resolution';
+ triggerPromiseReactions(reactions, resolution);
+ };
+ var reject = function(reason) {
+ if (promise._status !== 'unresolved') { return; }
+ var reactions = promise._rejectReactions;
+ promise._result = reason;
+ promise._resolveReactions = undefined;
+ promise._rejectReactions = undefined;
+ promise._status = 'has-rejection';
+ triggerPromiseReactions(reactions, reason);
+ };
+ try {
+ resolver(resolve, reject);
+ } catch (e) {
+ reject(e);
+ }
+ return promise;
+ };
+ Promise$prototype = Promise.prototype;
+ defineProperties(Promise, {
+ '@@create': function(obj) {
+ var constructor = this;
+ // AllocatePromise
+ // The `obj` parameter is a hack we use for es5
+ // compatibility.
+ var prototype = constructor.prototype || Promise$prototype;
+ obj = obj || create(prototype);
+ defineProperties(obj, {
+ _status: undefined,
+ _result: undefined,
+ _resolveReactions: undefined,
+ _rejectReactions: undefined,
+ _promiseConstructor: undefined
+ });
+ obj._promiseConstructor = constructor;
+ return obj;
+ }
+ });
+
+ var _promiseAllResolver = function(index, values, capability, remaining) {
+ var done = false;
+ return function(x) {
+ if (done) { return; } // protect against being called multiple times
+ done = true;
+ values[index] = x;
+ if ((--remaining.count) === 0) {
+ var resolve = capability.resolve;
+ resolve(values); // call w/ this===undefined
+ }
+ };
+ };
+
+ Promise.all = function(iterable) {
+ var C = this;
+ var capability = new PromiseCapability(C);
+ var resolve = capability.resolve;
+ var reject = capability.reject;
+ try {
+ if (!ES.IsIterable(iterable)) {
+ throw new TypeError('bad iterable');
+ }
+ var it = ES.GetIterator(iterable);
+ var values = [], remaining = { count: 1 };
+ for (var index = 0; ; index++) {
+ var next = ES.IteratorNext(it);
+ if (next.done) {
+ break;
+ }
+ var nextPromise = C.resolve(next.value);
+ var resolveElement = _promiseAllResolver(
+ index, values, capability, remaining
+ );
+ remaining.count++;
+ nextPromise.then(resolveElement, capability.reject);
+ }
+ if ((--remaining.count) === 0) {
+ resolve(values); // call w/ this===undefined
+ }
+ } catch (e) {
+ reject(e);
+ }
+ return capability.promise;
+ };
+
+ Promise.race = function(iterable) {
+ var C = this;
+ var capability = new PromiseCapability(C);
+ var resolve = capability.resolve;
+ var reject = capability.reject;
+ try {
+ if (!ES.IsIterable(iterable)) {
+ throw new TypeError('bad iterable');
+ }
+ var it = ES.GetIterator(iterable);
+ while (true) {
+ var next = ES.IteratorNext(it);
+ if (next.done) {
+ // If iterable has no items, resulting promise will never
+ // resolve; see:
+ // https://github.com/domenic/promises-unwrapping/issues/75
+ // https://bugs.ecmascript.org/show_bug.cgi?id=2515
+ break;
+ }
+ var nextPromise = C.resolve(next.value);
+ nextPromise.then(resolve, reject);
+ }
+ } catch (e) {
+ reject(e);
+ }
+ return capability.promise;
+ };
+
+ Promise.reject = function(reason) {
+ var C = this;
+ var capability = new PromiseCapability(C);
+ var reject = capability.reject;
+ reject(reason); // call with this===undefined
+ return capability.promise;
+ };
+
+ Promise.resolve = function(v) {
+ var C = this;
+ if (ES.IsPromise(v)) {
+ var constructor = v._promiseConstructor;
+ if (constructor === C) { return v; }
+ }
+ var capability = new PromiseCapability(C);
+ var resolve = capability.resolve;
+ resolve(v); // call with this===undefined
+ return capability.promise;
+ };
+
+ Promise.prototype['catch'] = function( onRejected ) {
+ return this.then(undefined, onRejected);
+ };
+
+ Promise.prototype.then = function( onFulfilled, onRejected ) {
+ var promise = this;
+ if (!ES.IsPromise(promise)) { throw new TypeError('not a promise'); }
+ // this.constructor not this._promiseConstructor; see
+ // https://bugs.ecmascript.org/show_bug.cgi?id=2513
+ var C = this.constructor;
+ var capability = new PromiseCapability(C);
+ if (!ES.IsCallable(onRejected)) {
+ onRejected = function(e) { throw e; };
+ }
+ if (!ES.IsCallable(onFulfilled)) {
+ onFulfilled = function(x) { return x; };
+ }
+ var resolutionHandler =
+ promiseResolutionHandler(promise, onFulfilled, onRejected);
+ var resolveReaction =
+ { capability: capability, handler: resolutionHandler };
+ var rejectReaction =
+ { capability: capability, handler: onRejected };
+ switch (promise._status) {
+ case 'unresolved':
+ promise._resolveReactions.push(resolveReaction);
+ promise._rejectReactions.push(rejectReaction);
+ break;
+ case 'has-resolution':
+ triggerPromiseReactions([resolveReaction], promise._result);
+ break;
+ case 'has-rejection':
+ triggerPromiseReactions([rejectReaction], promise._result);
+ break;
+ default:
+ throw new TypeError('unexpected');
+ }
+ return capability.promise;
+ };
+
+ return Promise;
+ })();
+ // export the Promise constructor.
+ defineProperties(globals, { Promise: PromiseShim });
+ // In Chrome 33 (and thereabouts) Promise is defined, but the
+ // implementation is buggy in a number of ways. Let's check subclassing
+ // support to see if we have a buggy implementation.
+ var promiseSupportsSubclassing = supportsSubclassing(globals.Promise, function(S) {
+ return S.resolve(42) instanceof S;
+ });
+ var promiseIgnoresNonFunctionThenCallbacks = (function () {
+ try {
+ globals.Promise.reject(42).then(null, 5).then(null, function () {});
+ return true;
+ } catch (ex) {
+ return false;
+ }
+ }());
+ if (!promiseSupportsSubclassing || !promiseIgnoresNonFunctionThenCallbacks) {
+ globals.Promise = PromiseShim;
+ }
+
+ // Map and Set require a true ES5 environment
+ if (supportsDescriptors) {
+
+ var fastkey = function fastkey(key) {
+ var type = typeof key;
+ if (type === 'string') {
+ return '$' + key;
+ } else if (type === 'number') {
+ // note that -0 will get coerced to "0" when used as a property key
+ return key;
+ }
+ return null;
+ };
+
+ var emptyObject = function emptyObject() {
+ // accomodate some older not-quite-ES5 browsers
+ return Object.create ? Object.create(null) : {};
+ };
+
+ var collectionShims = {
+ Map: (function() {
+
+ var empty = {};
+
+ function MapEntry(key, value) {
+ this.key = key;
+ this.value = value;
+ this.next = null;
+ this.prev = null;
+ }
+
+ MapEntry.prototype.isRemoved = function() {
+ return this.key === empty;
+ };
+
+ function MapIterator(map, kind) {
+ this.head = map._head;
+ this.i = this.head;
+ this.kind = kind;
+ }
+
+ MapIterator.prototype = {
+ next: function() {
+ var i = this.i, kind = this.kind, head = this.head, result;
+ if (this.i === undefined) {
+ return { value: undefined, done: true };
+ }
+ while (i.isRemoved() && i !== head) {
+ // back up off of removed entries
+ i = i.prev;
+ }
+ // advance to next unreturned element.
+ while (i.next !== head) {
+ i = i.next;
+ if (!i.isRemoved()) {
+ if (kind === "key") {
+ result = i.key;
+ } else if (kind === "value") {
+ result = i.value;
+ } else {
+ result = [i.key, i.value];
+ }
+ this.i = i;
+ return { value: result, done: false };
+ }
+ }
+ // once the iterator is done, it is done forever.
+ this.i = undefined;
+ return { value: undefined, done: true };
+ }
+ };
+ addIterator(MapIterator.prototype);
+
+ function Map() {
+ var map = this;
+ map = emulateES6construct(map);
+ if (!map._es6map) {
+ throw new TypeError('bad map');
+ }
+
+ var head = new MapEntry(null, null);
+ // circular doubly-linked list.
+ head.next = head.prev = head;
+
+ defineProperties(map, {
+ '_head': head,
+ '_storage': emptyObject(),
+ '_size': 0
+ });
+
+ // Optionally initialize map from iterable
+ var iterable = arguments[0];
+ if (iterable !== undefined && iterable !== null) {
+ var it = ES.GetIterator(iterable);
+ var adder = map.set;
+ if (!ES.IsCallable(adder)) { throw new TypeError('bad map'); }
+ while (true) {
+ var next = ES.IteratorNext(it);
+ if (next.done) { break; }
+ var nextItem = next.value;
+ if (!ES.TypeIsObject(nextItem)) {
+ throw new TypeError('expected iterable of pairs');
+ }
+ adder.call(map, nextItem[0], nextItem[1]);
+ }
+ }
+ return map;
+ }
+ var Map$prototype = Map.prototype;
+ defineProperties(Map, {
+ '@@create': function(obj) {
+ var constructor = this;
+ var prototype = constructor.prototype || Map$prototype;
+ obj = obj || create(prototype);
+ defineProperties(obj, { _es6map: true });
+ return obj;
+ }
+ });
+
+ Object.defineProperty(Map.prototype, 'size', {
+ configurable: true,
+ enumerable: false,
+ get: function() {
+ if (typeof this._size === 'undefined') {
+ throw new TypeError('size method called on incompatible Map');
+ }
+ return this._size;
+ }
+ });
+
+ defineProperties(Map.prototype, {
+ get: function(key) {
+ var fkey = fastkey(key);
+ if (fkey !== null) {
+ // fast O(1) path
+ var entry = this._storage[fkey];
+ return entry ? entry.value : undefined;
+ }
+ var head = this._head, i = head;
+ while ((i = i.next) !== head) {
+ if (ES.SameValueZero(i.key, key)) {
+ return i.value;
+ }
+ }
+ return undefined;
+ },
+
+ has: function(key) {
+ var fkey = fastkey(key);
+ if (fkey !== null) {
+ // fast O(1) path
+ return typeof this._storage[fkey] !== 'undefined';
+ }
+ var head = this._head, i = head;
+ while ((i = i.next) !== head) {
+ if (ES.SameValueZero(i.key, key)) {
+ return true;
+ }
+ }
+ return false;
+ },
+
+ set: function(key, value) {
+ var head = this._head, i = head, entry;
+ var fkey = fastkey(key);
+ if (fkey !== null) {
+ // fast O(1) path
+ if (typeof this._storage[fkey] !== 'undefined') {
+ this._storage[fkey].value = value;
+ return;
+ } else {
+ entry = this._storage[fkey] = new MapEntry(key, value);
+ i = head.prev;
+ // fall through
+ }
+ }
+ while ((i = i.next) !== head) {
+ if (ES.SameValueZero(i.key, key)) {
+ i.value = value;
+ return;
+ }
+ }
+ entry = entry || new MapEntry(key, value);
+ if (ES.SameValue(-0, key)) {
+ entry.key = +0; // coerce -0 to +0 in entry
+ }
+ entry.next = this._head;
+ entry.prev = this._head.prev;
+ entry.prev.next = entry;
+ entry.next.prev = entry;
+ this._size += 1;
+ },
+
+ 'delete': function(key) {
+ var head = this._head, i = head;
+ var fkey = fastkey(key);
+ if (fkey !== null) {
+ // fast O(1) path
+ if (typeof this._storage[fkey] === 'undefined') {
+ return false;
+ }
+ i = this._storage[fkey].prev;
+ delete this._storage[fkey];
+ // fall through
+ }
+ while ((i = i.next) !== head) {
+ if (ES.SameValueZero(i.key, key)) {
+ i.key = i.value = empty;
+ i.prev.next = i.next;
+ i.next.prev = i.prev;
+ this._size -= 1;
+ return true;
+ }
+ }
+ return false;
+ },
+
+ clear: function() {
+ this._size = 0;
+ this._storage = emptyObject();
+ var head = this._head, i = head, p = i.next;
+ while ((i = p) !== head) {
+ i.key = i.value = empty;
+ p = i.next;
+ i.next = i.prev = head;
+ }
+ head.next = head.prev = head;
+ },
+
+ keys: function() {
+ return new MapIterator(this, "key");
+ },
+
+ values: function() {
+ return new MapIterator(this, "value");
+ },
+
+ entries: function() {
+ return new MapIterator(this, "key+value");
+ },
+
+ forEach: function(callback) {
+ var context = arguments.length > 1 ? arguments[1] : null;
+ var it = this.entries();
+ for (var entry = it.next(); !entry.done; entry = it.next()) {
+ callback.call(context, entry.value[1], entry.value[0], this);
+ }
+ }
+ });
+ addIterator(Map.prototype, function() { return this.entries(); });
+
+ return Map;
+ })(),
+
+ Set: (function() {
+ // Creating a Map is expensive. To speed up the common case of
+ // Sets containing only string or numeric keys, we use an object
+ // as backing storage and lazily create a full Map only when
+ // required.
+ var SetShim = function Set() {
+ var set = this;
+ set = emulateES6construct(set);
+ if (!set._es6set) {
+ throw new TypeError('bad set');
+ }
+
+ defineProperties(set, {
+ '[[SetData]]': null,
+ '_storage': emptyObject()
+ });
+
+ // Optionally initialize map from iterable
+ var iterable = arguments[0];
+ if (iterable !== undefined && iterable !== null) {
+ var it = ES.GetIterator(iterable);
+ var adder = set.add;
+ if (!ES.IsCallable(adder)) { throw new TypeError('bad set'); }
+ while (true) {
+ var next = ES.IteratorNext(it);
+ if (next.done) { break; }
+ var nextItem = next.value;
+ adder.call(set, nextItem);
+ }
+ }
+ return set;
+ };
+ var Set$prototype = SetShim.prototype;
+ defineProperties(SetShim, {
+ '@@create': function(obj) {
+ var constructor = this;
+ var prototype = constructor.prototype || Set$prototype;
+ obj = obj || create(prototype);
+ defineProperties(obj, { _es6set: true });
+ return obj;
+ }
+ });
+
+ // Switch from the object backing storage to a full Map.
+ var ensureMap = function ensureMap(set) {
+ if (!set['[[SetData]]']) {
+ var m = set['[[SetData]]'] = new collectionShims.Map();
+ Object.keys(set._storage).forEach(function(k) {
+ // fast check for leading '$'
+ if (k.charCodeAt(0) === 36) {
+ k = k.substring(1);
+ } else {
+ k = +k;
+ }
+ m.set(k, k);
+ });
+ set._storage = null; // free old backing storage
+ }
+ };
+
+ Object.defineProperty(SetShim.prototype, 'size', {
+ configurable: true,
+ enumerable: false,
+ get: function() {
+ if (typeof this._storage === 'undefined') {
+ // https://github.com/paulmillr/es6-shim/issues/176
+ throw new TypeError('size method called on incompatible Set');
+ }
+ ensureMap(this);
+ return this['[[SetData]]'].size;
+ }
+ });
+
+ defineProperties(SetShim.prototype, {
+ has: function(key) {
+ var fkey;
+ if (this._storage && (fkey = fastkey(key)) !== null) {
+ return !!this._storage[fkey];
+ }
+ ensureMap(this);
+ return this['[[SetData]]'].has(key);
+ },
+
+ add: function(key) {
+ var fkey;
+ if (this._storage && (fkey = fastkey(key)) !== null) {
+ this._storage[fkey]=true;
+ return;
+ }
+ ensureMap(this);
+ return this['[[SetData]]'].set(key, key);
+ },
+
+ 'delete': function(key) {
+ var fkey;
+ if (this._storage && (fkey = fastkey(key)) !== null) {
+ delete this._storage[fkey];
+ return;
+ }
+ ensureMap(this);
+ return this['[[SetData]]']['delete'](key);
+ },
+
+ clear: function() {
+ if (this._storage) {
+ this._storage = emptyObject();
+ return;
+ }
+ return this['[[SetData]]'].clear();
+ },
+
+ keys: function() {
+ ensureMap(this);
+ return this['[[SetData]]'].keys();
+ },
+
+ values: function() {
+ ensureMap(this);
+ return this['[[SetData]]'].values();
+ },
+
+ entries: function() {
+ ensureMap(this);
+ return this['[[SetData]]'].entries();
+ },
+
+ forEach: function(callback) {
+ var context = arguments.length > 1 ? arguments[1] : null;
+ var entireSet = this;
+ ensureMap(this);
+ this['[[SetData]]'].forEach(function(value, key) {
+ callback.call(context, key, key, entireSet);
+ });
+ }
+ });
+ addIterator(SetShim.prototype, function() { return this.values(); });
+
+ return SetShim;
+ })()
+ };
+ defineProperties(globals, collectionShims);
+
+ if (globals.Map || globals.Set) {
+ /*
+ - In Firefox < 23, Map#size is a function.
+ - In all current Firefox, Set#entries/keys/values & Map#clear do not exist
+ - https://bugzilla.mozilla.org/show_bug.cgi?id=869996
+ - In Firefox 24, Map and Set do not implement forEach
+ - In Firefox 25 at least, Map and Set are callable without "new"
+ */
+ if (
+ typeof globals.Map.prototype.clear !== 'function' ||
+ new globals.Set().size !== 0 ||
+ new globals.Map().size !== 0 ||
+ typeof globals.Map.prototype.keys !== 'function' ||
+ typeof globals.Set.prototype.keys !== 'function' ||
+ typeof globals.Map.prototype.forEach !== 'function' ||
+ typeof globals.Set.prototype.forEach !== 'function' ||
+ isCallableWithoutNew(globals.Map) ||
+ isCallableWithoutNew(globals.Set) ||
+ !supportsSubclassing(globals.Map, function(M) {
+ return (new M([])) instanceof M;
+ })
+ ) {
+ globals.Map = collectionShims.Map;
+ globals.Set = collectionShims.Set;
+ }
+ }
+ // Shim incomplete iterator implementations.
+ addIterator(Object.getPrototypeOf((new globals.Map()).keys()));
+ addIterator(Object.getPrototypeOf((new globals.Set()).keys()));
+ }
+ };
+
+ if (typeof define === 'function' && define.amd) {
+ define(main); // RequireJS
+ } else {
+ main(); // CommonJS and
+ */
+ var dispatches = [
+ /**
+ Dispatched when runtime is connected and file-picker is ready to be used.
+
+ @event ready
+ @param {Object} event
+ */
+ 'ready',
+
+ /**
+ Dispatched right after [ready](#event_ready) event, and whenever [refresh()](#method_refresh) is invoked.
+ Check [corresponding documentation entry](#method_refresh) for more info.
+
+ @event refresh
+ @param {Object} event
+ */
+
+ /**
+ Dispatched when selection of files in the dialog is complete.
+
+ @event change
+ @param {Object} event
+ */
+ 'change',
+
+ 'cancel', // TODO: might be useful
+
+ /**
+ Dispatched when mouse cursor enters file-picker area. Can be used to style element
+ accordingly.
+
+ @event mouseenter
+ @param {Object} event
+ */
+ 'mouseenter',
+
+ /**
+ Dispatched when mouse cursor leaves file-picker area. Can be used to style element
+ accordingly.
+
+ @event mouseleave
+ @param {Object} event
+ */
+ 'mouseleave',
+
+ /**
+ Dispatched when functional mouse button is pressed on top of file-picker area.
+
+ @event mousedown
+ @param {Object} event
+ */
+ 'mousedown',
+
+ /**
+ Dispatched when functional mouse button is released on top of file-picker area.
+
+ @event mouseup
+ @param {Object} event
+ */
+ 'mouseup'
+ ];
+
+ function FileInput(options) {
+ var self = this,
+ container, browseButton, defaults;
+
+ // if flat argument passed it should be browse_button id
+ if (Basic.inArray(Basic.typeOf(options), ['string', 'node']) !== -1) {
+ options = { browse_button : options };
+ }
+
+ // this will help us to find proper default container
+ browseButton = Dom.get(options.browse_button);
+ if (!browseButton) {
+ // browse button is required
+ throw new x.DOMException(x.DOMException.NOT_FOUND_ERR);
+ }
+
+ // figure out the options
+ defaults = {
+ accept: [{
+ title: I18n.translate('All Files'),
+ extensions: '*'
+ }],
+ name: 'file',
+ multiple: false,
+ required_caps: false,
+ container: browseButton.parentNode || document.body
+ };
+
+ options = Basic.extend({}, defaults, options);
+
+ // convert to object representation
+ if (typeof(options.required_caps) === 'string') {
+ options.required_caps = Runtime.parseCaps(options.required_caps);
+ }
+
+ // normalize accept option (could be list of mime types or array of title/extensions pairs)
+ if (typeof(options.accept) === 'string') {
+ options.accept = Mime.mimes2extList(options.accept);
+ }
+
+ container = Dom.get(options.container);
+ // make sure we have container
+ if (!container) {
+ container = document.body;
+ }
+
+ // make container relative, if it's not
+ if (Dom.getStyle(container, 'position') === 'static') {
+ container.style.position = 'relative';
+ }
+
+ container = browseButton = null; // IE
+
+ RuntimeClient.call(self);
+
+ Basic.extend(self, {
+ /**
+ Unique id of the component
+
+ @property uid
+ @protected
+ @readOnly
+ @type {String}
+ @default UID
+ */
+ uid: Basic.guid('uid_'),
+
+ /**
+ Unique id of the connected runtime, if any.
+
+ @property ruid
+ @protected
+ @type {String}
+ */
+ ruid: null,
+
+ /**
+ Unique id of the runtime container. Useful to get hold of it for various manipulations.
+
+ @property shimid
+ @protected
+ @type {String}
+ */
+ shimid: null,
+
+ /**
+ Array of selected mOxie.File objects
+
+ @property files
+ @type {Array}
+ @default null
+ */
+ files: null,
+
+ /**
+ Initializes the file-picker, connects it to runtime and dispatches event ready when done.
+
+ @method init
+ */
+ init: function() {
+ self.convertEventPropsToHandlers(dispatches);
+
+ self.bind('RuntimeInit', function(e, runtime) {
+ self.ruid = runtime.uid;
+ self.shimid = runtime.shimid;
+
+ self.bind("Ready", function() {
+ self.trigger("Refresh");
+ }, 999);
+
+ self.bind("Change", function() {
+ var files = runtime.exec.call(self, 'FileInput', 'getFiles');
+
+ self.files = [];
+
+ Basic.each(files, function(file) {
+ // ignore empty files (IE10 for example hangs if you try to send them via XHR)
+ if (file.size === 0) {
+ return true;
+ }
+ self.files.push(new File(self.ruid, file));
+ });
+ }, 999);
+
+ // re-position and resize shim container
+ self.bind('Refresh', function() {
+ var pos, size, browseButton, shimContainer;
+
+ browseButton = Dom.get(options.browse_button);
+ shimContainer = Dom.get(runtime.shimid); // do not use runtime.getShimContainer(), since it will create container if it doesn't exist
+
+ if (browseButton) {
+ pos = Dom.getPos(browseButton, Dom.get(options.container));
+ size = Dom.getSize(browseButton);
+
+ if (shimContainer) {
+ Basic.extend(shimContainer.style, {
+ top : pos.y + 'px',
+ left : pos.x + 'px',
+ width : size.w + 'px',
+ height : size.h + 'px'
+ });
+ }
+ }
+ shimContainer = browseButton = null;
+ });
+
+ runtime.exec.call(self, 'FileInput', 'init', options);
+ });
+
+ // runtime needs: options.required_features, options.runtime_order and options.container
+ self.connectRuntime(Basic.extend({}, options, {
+ required_caps: {
+ select_file: true
+ }
+ }));
+ },
+
+ /**
+ Disables file-picker element, so that it doesn't react to mouse clicks.
+
+ @method disable
+ @param {Boolean} [state=true] Disable component if - true, enable if - false
+ */
+ disable: function(state) {
+ var runtime = this.getRuntime();
+ if (runtime) {
+ runtime.exec.call(this, 'FileInput', 'disable', Basic.typeOf(state) === 'undefined' ? true : state);
+ }
+ },
+
+
+ /**
+ Reposition and resize dialog trigger to match the position and size of browse_button element.
+
+ @method refresh
+ */
+ refresh: function() {
+ self.trigger("Refresh");
+ },
+
+
+ /**
+ Destroy component.
+
+ @method destroy
+ */
+ destroy: function() {
+ var runtime = this.getRuntime();
+ if (runtime) {
+ runtime.exec.call(this, 'FileInput', 'destroy');
+ this.disconnectRuntime();
+ }
+
+ if (Basic.typeOf(this.files) === 'array') {
+ // no sense in leaving associated files behind
+ Basic.each(this.files, function(file) {
+ file.destroy();
+ });
+ }
+ this.files = null;
+ }
+ });
+ }
+
+ FileInput.prototype = EventTarget.instance;
+
+ return FileInput;
+});
+
+// Included from: src/javascript/runtime/RuntimeTarget.js
+
+/**
+ * RuntimeTarget.js
+ *
+ * Copyright 2013, Moxiecode Systems AB
+ * Released under GPL License.
+ *
+ * License: http://www.plupload.com/license
+ * Contributing: http://www.plupload.com/contributing
+ */
+
+define('moxie/runtime/RuntimeTarget', [
+ 'moxie/core/utils/Basic',
+ 'moxie/runtime/RuntimeClient',
+ "moxie/core/EventTarget"
+], function(Basic, RuntimeClient, EventTarget) {
+ /**
+ Instance of this class can be used as a target for the events dispatched by shims,
+ when allowing them onto components is for either reason inappropriate
+
+ @class RuntimeTarget
+ @constructor
+ @protected
+ @extends EventTarget
+ */
+ function RuntimeTarget() {
+ this.uid = Basic.guid('uid_');
+
+ RuntimeClient.call(this);
+
+ this.destroy = function() {
+ this.disconnectRuntime();
+ this.unbindAll();
+ };
+ }
+
+ RuntimeTarget.prototype = EventTarget.instance;
+
+ return RuntimeTarget;
+});
+
+// Included from: src/javascript/file/FileReader.js
+
+/**
+ * FileReader.js
+ *
+ * Copyright 2013, Moxiecode Systems AB
+ * Released under GPL License.
+ *
+ * License: http://www.plupload.com/license
+ * Contributing: http://www.plupload.com/contributing
+ */
+
+define('moxie/file/FileReader', [
+ 'moxie/core/utils/Basic',
+ 'moxie/core/utils/Encode',
+ 'moxie/core/Exceptions',
+ 'moxie/core/EventTarget',
+ 'moxie/file/Blob',
+ 'moxie/file/File',
+ 'moxie/runtime/RuntimeTarget'
+], function(Basic, Encode, x, EventTarget, Blob, File, RuntimeTarget) {
+ /**
+ Utility for preloading o.Blob/o.File objects in memory. By design closely follows [W3C FileReader](http://www.w3.org/TR/FileAPI/#dfn-filereader)
+ interface. Where possible uses native FileReader, where - not falls back to shims.
+
+ @class FileReader
+ @constructor FileReader
+ @extends EventTarget
+ @uses RuntimeClient
+ */
+ var dispatches = [
+
+ /**
+ Dispatched when the read starts.
+
+ @event loadstart
+ @param {Object} event
+ */
+ 'loadstart',
+
+ /**
+ Dispatched while reading (and decoding) blob, and reporting partial Blob data (progess.loaded/progress.total).
+
+ @event progress
+ @param {Object} event
+ */
+ 'progress',
+
+ /**
+ Dispatched when the read has successfully completed.
+
+ @event load
+ @param {Object} event
+ */
+ 'load',
+
+ /**
+ Dispatched when the read has been aborted. For instance, by invoking the abort() method.
+
+ @event abort
+ @param {Object} event
+ */
+ 'abort',
+
+ /**
+ Dispatched when the read has failed.
+
+ @event error
+ @param {Object} event
+ */
+ 'error',
+
+ /**
+ Dispatched when the request has completed (either in success or failure).
+
+ @event loadend
+ @param {Object} event
+ */
+ 'loadend'
+ ];
+
+ function FileReader() {
+ var self = this, _fr;
+
+ Basic.extend(this, {
+ /**
+ UID of the component instance.
+
+ @property uid
+ @type {String}
+ */
+ uid: Basic.guid('uid_'),
+
+ /**
+ Contains current state of FileReader object. Can take values of FileReader.EMPTY, FileReader.LOADING
+ and FileReader.DONE.
+
+ @property readyState
+ @type {Number}
+ @default FileReader.EMPTY
+ */
+ readyState: FileReader.EMPTY,
+
+ /**
+ Result of the successful read operation.
+
+ @property result
+ @type {String}
+ */
+ result: null,
+
+ /**
+ Stores the error of failed asynchronous read operation.
+
+ @property error
+ @type {DOMError}
+ */
+ error: null,
+
+ /**
+ Initiates reading of File/Blob object contents to binary string.
+
+ @method readAsBinaryString
+ @param {Blob|File} blob Object to preload
+ */
+ readAsBinaryString: function(blob) {
+ _read.call(this, 'readAsBinaryString', blob);
+ },
+
+ /**
+ Initiates reading of File/Blob object contents to dataURL string.
+
+ @method readAsDataURL
+ @param {Blob|File} blob Object to preload
+ */
+ readAsDataURL: function(blob) {
+ _read.call(this, 'readAsDataURL', blob);
+ },
+
+ /**
+ Initiates reading of File/Blob object contents to string.
+
+ @method readAsText
+ @param {Blob|File} blob Object to preload
+ */
+ readAsText: function(blob) {
+ _read.call(this, 'readAsText', blob);
+ },
+
+ /**
+ Aborts preloading process.
+
+ @method abort
+ */
+ abort: function() {
+ this.result = null;
+
+ if (Basic.inArray(this.readyState, [FileReader.EMPTY, FileReader.DONE]) !== -1) {
+ return;
+ } else if (this.readyState === FileReader.LOADING) {
+ this.readyState = FileReader.DONE;
+ }
+
+ if (_fr) {
+ _fr.getRuntime().exec.call(this, 'FileReader', 'abort');
+ }
+
+ this.trigger('abort');
+ this.trigger('loadend');
+ },
+
+ /**
+ Destroy component and release resources.
+
+ @method destroy
+ */
+ destroy: function() {
+ this.abort();
+
+ if (_fr) {
+ _fr.getRuntime().exec.call(this, 'FileReader', 'destroy');
+ _fr.disconnectRuntime();
+ }
+
+ self = _fr = null;
+ }
+ });
+
+
+ function _read(op, blob) {
+ _fr = new RuntimeTarget();
+
+ function error(err) {
+ self.readyState = FileReader.DONE;
+ self.error = err;
+ self.trigger('error');
+ loadEnd();
+ }
+
+ function loadEnd() {
+ _fr.destroy();
+ _fr = null;
+ self.trigger('loadend');
+ }
+
+ function exec(runtime) {
+ _fr.bind('Error', function(e, err) {
+ error(err);
+ });
+
+ _fr.bind('Progress', function(e) {
+ self.result = runtime.exec.call(_fr, 'FileReader', 'getResult');
+ self.trigger(e);
+ });
+
+ _fr.bind('Load', function(e) {
+ self.readyState = FileReader.DONE;
+ self.result = runtime.exec.call(_fr, 'FileReader', 'getResult');
+ self.trigger(e);
+ loadEnd();
+ });
+
+ runtime.exec.call(_fr, 'FileReader', 'read', op, blob);
+ }
+
+ this.convertEventPropsToHandlers(dispatches);
+
+ if (this.readyState === FileReader.LOADING) {
+ return error(new x.DOMException(x.DOMException.INVALID_STATE_ERR));
+ }
+
+ this.readyState = FileReader.LOADING;
+ this.trigger('loadstart');
+
+ // if source is o.Blob/o.File
+ if (blob instanceof Blob) {
+ if (blob.isDetached()) {
+ var src = blob.getSource();
+ switch (op) {
+ case 'readAsText':
+ case 'readAsBinaryString':
+ this.result = src;
+ break;
+ case 'readAsDataURL':
+ this.result = 'data:' + blob.type + ';base64,' + Encode.btoa(src);
+ break;
+ }
+ this.readyState = FileReader.DONE;
+ this.trigger('load');
+ loadEnd();
+ } else {
+ exec(_fr.connectRuntime(blob.ruid));
+ }
+ } else {
+ error(new x.DOMException(x.DOMException.NOT_FOUND_ERR));
+ }
+ }
+ }
+
+ /**
+ Initial FileReader state
+
+ @property EMPTY
+ @type {Number}
+ @final
+ @static
+ @default 0
+ */
+ FileReader.EMPTY = 0;
+
+ /**
+ FileReader switches to this state when it is preloading the source
+
+ @property LOADING
+ @type {Number}
+ @final
+ @static
+ @default 1
+ */
+ FileReader.LOADING = 1;
+
+ /**
+ Preloading is complete, this is a final state
+
+ @property DONE
+ @type {Number}
+ @final
+ @static
+ @default 2
+ */
+ FileReader.DONE = 2;
+
+ FileReader.prototype = EventTarget.instance;
+
+ return FileReader;
+});
+
+// Included from: src/javascript/core/utils/Url.js
+
+/**
+ * Url.js
+ *
+ * Copyright 2013, Moxiecode Systems AB
+ * Released under GPL License.
+ *
+ * License: http://www.plupload.com/license
+ * Contributing: http://www.plupload.com/contributing
+ */
+
+define('moxie/core/utils/Url', [], function() {
+ /**
+ Parse url into separate components and fill in absent parts with parts from current url,
+ based on https://raw.github.com/kvz/phpjs/master/functions/url/parse_url.js
+
+ @method parseUrl
+ @for Utils
+ @static
+ @param {String} url Url to parse (defaults to empty string if undefined)
+ @return {Object} Hash containing extracted uri components
+ */
+ var parseUrl = function(url, currentUrl) {
+ var key = ['source', 'scheme', 'authority', 'userInfo', 'user', 'pass', 'host', 'port', 'relative', 'path', 'directory', 'file', 'query', 'fragment']
+ , i = key.length
+ , ports = {
+ http: 80,
+ https: 443
+ }
+ , uri = {}
+ , regex = /^(?:([^:\/?#]+):)?(?:\/\/()(?:(?:()(?:([^:@]*):?([^:@]*))?@)?([^:\/?#]*)(?::(\d*))?))?()(?:(()(?:(?:[^?#\/]*\/)*)()(?:[^?#]*))(?:\\?([^#]*))?(?:#(.*))?)/
+ , m = regex.exec(url || '')
+ ;
+
+ while (i--) {
+ if (m[i]) {
+ uri[key[i]] = m[i];
+ }
+ }
+
+ // when url is relative, we set the origin and the path ourselves
+ if (!uri.scheme) {
+ // come up with defaults
+ if (!currentUrl || typeof(currentUrl) === 'string') {
+ currentUrl = parseUrl(currentUrl || document.location.href);
+ }
+
+ uri.scheme = currentUrl.scheme;
+ uri.host = currentUrl.host;
+ uri.port = currentUrl.port;
+
+ var path = '';
+ // for urls without trailing slash we need to figure out the path
+ if (/^[^\/]/.test(uri.path)) {
+ path = currentUrl.path;
+ // if path ends with a filename, strip it
+ if (!/(\/|\/[^\.]+)$/.test(path)) {
+ path = path.replace(/\/[^\/]+$/, '/');
+ } else {
+ path += '/';
+ }
+ }
+ uri.path = path + (uri.path || ''); // site may reside at domain.com or domain.com/subdir
+ }
+
+ if (!uri.port) {
+ uri.port = ports[uri.scheme] || 80;
+ }
+
+ uri.port = parseInt(uri.port, 10);
+
+ if (!uri.path) {
+ uri.path = "/";
+ }
+
+ delete uri.source;
+
+ return uri;
+ };
+
+ /**
+ Resolve url - among other things will turn relative url to absolute
+
+ @method resolveUrl
+ @static
+ @param {String} url Either absolute or relative
+ @return {String} Resolved, absolute url
+ */
+ var resolveUrl = function(url) {
+ var ports = { // we ignore default ports
+ http: 80,
+ https: 443
+ }
+ , urlp = parseUrl(url)
+ ;
+
+ return urlp.scheme + '://' + urlp.host + (urlp.port !== ports[urlp.scheme] ? ':' + urlp.port : '') + urlp.path + (urlp.query ? urlp.query : '');
+ };
+
+ /**
+ Check if specified url has the same origin as the current document
+
+ @method hasSameOrigin
+ @param {String|Object} url
+ @return {Boolean}
+ */
+ var hasSameOrigin = function(url) {
+ function origin(url) {
+ return [url.scheme, url.host, url.port].join('/');
+ }
+
+ if (typeof url === 'string') {
+ url = parseUrl(url);
+ }
+
+ return origin(parseUrl()) === origin(url);
+ };
+
+ return {
+ parseUrl: parseUrl,
+ resolveUrl: resolveUrl,
+ hasSameOrigin: hasSameOrigin
+ };
+});
+
+// Included from: src/javascript/file/FileReaderSync.js
+
+/**
+ * FileReaderSync.js
+ *
+ * Copyright 2013, Moxiecode Systems AB
+ * Released under GPL License.
+ *
+ * License: http://www.plupload.com/license
+ * Contributing: http://www.plupload.com/contributing
+ */
+
+define('moxie/file/FileReaderSync', [
+ 'moxie/core/utils/Basic',
+ 'moxie/runtime/RuntimeClient',
+ 'moxie/core/utils/Encode'
+], function(Basic, RuntimeClient, Encode) {
+ /**
+ Synchronous FileReader implementation. Something like this is available in WebWorkers environment, here
+ it can be used to read only preloaded blobs/files and only below certain size (not yet sure what that'd be,
+ but probably < 1mb). Not meant to be used directly by user.
+
+ @class FileReaderSync
+ @private
+ @constructor
+ */
+ return function() {
+ RuntimeClient.call(this);
+
+ Basic.extend(this, {
+ uid: Basic.guid('uid_'),
+
+ readAsBinaryString: function(blob) {
+ return _read.call(this, 'readAsBinaryString', blob);
+ },
+
+ readAsDataURL: function(blob) {
+ return _read.call(this, 'readAsDataURL', blob);
+ },
+
+ /*readAsArrayBuffer: function(blob) {
+ return _read.call(this, 'readAsArrayBuffer', blob);
+ },*/
+
+ readAsText: function(blob) {
+ return _read.call(this, 'readAsText', blob);
+ }
+ });
+
+ function _read(op, blob) {
+ if (blob.isDetached()) {
+ var src = blob.getSource();
+ switch (op) {
+ case 'readAsBinaryString':
+ return src;
+ case 'readAsDataURL':
+ return 'data:' + blob.type + ';base64,' + Encode.btoa(src);
+ case 'readAsText':
+ var txt = '';
+ for (var i = 0, length = src.length; i < length; i++) {
+ txt += String.fromCharCode(src[i]);
+ }
+ return txt;
+ }
+ } else {
+ var result = this.connectRuntime(blob.ruid).exec.call(this, 'FileReaderSync', 'read', op, blob);
+ this.disconnectRuntime();
+ return result;
+ }
+ }
+ };
+});
+
+// Included from: src/javascript/xhr/FormData.js
+
+/**
+ * FormData.js
+ *
+ * Copyright 2013, Moxiecode Systems AB
+ * Released under GPL License.
+ *
+ * License: http://www.plupload.com/license
+ * Contributing: http://www.plupload.com/contributing
+ */
+
+define("moxie/xhr/FormData", [
+ "moxie/core/Exceptions",
+ "moxie/core/utils/Basic",
+ "moxie/file/Blob"
+], function(x, Basic, Blob) {
+ /**
+ FormData
+
+ @class FormData
+ @constructor
+ */
+ function FormData() {
+ var _blob, _fields = [];
+
+ Basic.extend(this, {
+ /**
+ Append another key-value pair to the FormData object
+
+ @method append
+ @param {String} name Name for the new field
+ @param {String|Blob|Array|Object} value Value for the field
+ */
+ append: function(name, value) {
+ var self = this, valueType = Basic.typeOf(value);
+
+ // according to specs value might be either Blob or String
+ if (value instanceof Blob) {
+ _blob = {
+ name: name,
+ value: value // unfortunately we can only send single Blob in one FormData
+ };
+ } else if ('array' === valueType) {
+ name += '[]';
+
+ Basic.each(value, function(value) {
+ self.append(name, value);
+ });
+ } else if ('object' === valueType) {
+ Basic.each(value, function(value, key) {
+ self.append(name + '[' + key + ']', value);
+ });
+ } else if ('null' === valueType || 'undefined' === valueType || 'number' === valueType && isNaN(value)) {
+ self.append(name, "false");
+ } else {
+ _fields.push({
+ name: name,
+ value: value.toString()
+ });
+ }
+ },
+
+ /**
+ Checks if FormData contains Blob.
+
+ @method hasBlob
+ @return {Boolean}
+ */
+ hasBlob: function() {
+ return !!this.getBlob();
+ },
+
+ /**
+ Retrieves blob.
+
+ @method getBlob
+ @return {Object} Either Blob if found or null
+ */
+ getBlob: function() {
+ return _blob && _blob.value || null;
+ },
+
+ /**
+ Retrieves blob field name.
+
+ @method getBlobName
+ @return {String} Either Blob field name or null
+ */
+ getBlobName: function() {
+ return _blob && _blob.name || null;
+ },
+
+ /**
+ Loop over the fields in FormData and invoke the callback for each of them.
+
+ @method each
+ @param {Function} cb Callback to call for each field
+ */
+ each: function(cb) {
+ Basic.each(_fields, function(field) {
+ cb(field.value, field.name);
+ });
+
+ if (_blob) {
+ cb(_blob.value, _blob.name);
+ }
+ },
+
+ destroy: function() {
+ _blob = null;
+ _fields = [];
+ }
+ });
+ }
+
+ return FormData;
+});
+
+// Included from: src/javascript/xhr/XMLHttpRequest.js
+
+/**
+ * XMLHttpRequest.js
+ *
+ * Copyright 2013, Moxiecode Systems AB
+ * Released under GPL License.
+ *
+ * License: http://www.plupload.com/license
+ * Contributing: http://www.plupload.com/contributing
+ */
+
+define("moxie/xhr/XMLHttpRequest", [
+ "moxie/core/utils/Basic",
+ "moxie/core/Exceptions",
+ "moxie/core/EventTarget",
+ "moxie/core/utils/Encode",
+ "moxie/core/utils/Url",
+ "moxie/runtime/Runtime",
+ "moxie/runtime/RuntimeTarget",
+ "moxie/file/Blob",
+ "moxie/file/FileReaderSync",
+ "moxie/xhr/FormData",
+ "moxie/core/utils/Env",
+ "moxie/core/utils/Mime"
+], function(Basic, x, EventTarget, Encode, Url, Runtime, RuntimeTarget, Blob, FileReaderSync, FormData, Env, Mime) {
+
+ var httpCode = {
+ 100: 'Continue',
+ 101: 'Switching Protocols',
+ 102: 'Processing',
+
+ 200: 'OK',
+ 201: 'Created',
+ 202: 'Accepted',
+ 203: 'Non-Authoritative Information',
+ 204: 'No Content',
+ 205: 'Reset Content',
+ 206: 'Partial Content',
+ 207: 'Multi-Status',
+ 226: 'IM Used',
+
+ 300: 'Multiple Choices',
+ 301: 'Moved Permanently',
+ 302: 'Found',
+ 303: 'See Other',
+ 304: 'Not Modified',
+ 305: 'Use Proxy',
+ 306: 'Reserved',
+ 307: 'Temporary Redirect',
+
+ 400: 'Bad Request',
+ 401: 'Unauthorized',
+ 402: 'Payment Required',
+ 403: 'Forbidden',
+ 404: 'Not Found',
+ 405: 'Method Not Allowed',
+ 406: 'Not Acceptable',
+ 407: 'Proxy Authentication Required',
+ 408: 'Request Timeout',
+ 409: 'Conflict',
+ 410: 'Gone',
+ 411: 'Length Required',
+ 412: 'Precondition Failed',
+ 413: 'Request Entity Too Large',
+ 414: 'Request-URI Too Long',
+ 415: 'Unsupported Media Type',
+ 416: 'Requested Range Not Satisfiable',
+ 417: 'Expectation Failed',
+ 422: 'Unprocessable Entity',
+ 423: 'Locked',
+ 424: 'Failed Dependency',
+ 426: 'Upgrade Required',
+
+ 500: 'Internal Server Error',
+ 501: 'Not Implemented',
+ 502: 'Bad Gateway',
+ 503: 'Service Unavailable',
+ 504: 'Gateway Timeout',
+ 505: 'HTTP Version Not Supported',
+ 506: 'Variant Also Negotiates',
+ 507: 'Insufficient Storage',
+ 510: 'Not Extended'
+ };
+
+ function XMLHttpRequestUpload() {
+ this.uid = Basic.guid('uid_');
+ }
+
+ XMLHttpRequestUpload.prototype = EventTarget.instance;
+
+ /**
+ Implementation of XMLHttpRequest
+
+ @class XMLHttpRequest
+ @constructor
+ @uses RuntimeClient
+ @extends EventTarget
+ */
+ var dispatches = ['loadstart', 'progress', 'abort', 'error', 'load', 'timeout', 'loadend']; // & readystatechange (for historical reasons)
+
+ var NATIVE = 1, RUNTIME = 2;
+
+ function XMLHttpRequest() {
+ var self = this,
+ // this (together with _p() @see below) is here to gracefully upgrade to setter/getter syntax where possible
+ props = {
+ /**
+ The amount of milliseconds a request can take before being terminated. Initially zero. Zero means there is no timeout.
+
+ @property timeout
+ @type Number
+ @default 0
+ */
+ timeout: 0,
+
+ /**
+ Current state, can take following values:
+ UNSENT (numeric value 0)
+ The object has been constructed.
+
+ OPENED (numeric value 1)
+ The open() method has been successfully invoked. During this state request headers can be set using setRequestHeader() and the request can be made using the send() method.
+
+ HEADERS_RECEIVED (numeric value 2)
+ All redirects (if any) have been followed and all HTTP headers of the final response have been received. Several response members of the object are now available.
+
+ LOADING (numeric value 3)
+ The response entity body is being received.
+
+ DONE (numeric value 4)
+
+ @property readyState
+ @type Number
+ @default 0 (UNSENT)
+ */
+ readyState: XMLHttpRequest.UNSENT,
+
+ /**
+ True when user credentials are to be included in a cross-origin request. False when they are to be excluded
+ in a cross-origin request and when cookies are to be ignored in its response. Initially false.
+
+ @property withCredentials
+ @type Boolean
+ @default false
+ */
+ withCredentials: false,
+
+ /**
+ Returns the HTTP status code.
+
+ @property status
+ @type Number
+ @default 0
+ */
+ status: 0,
+
+ /**
+ Returns the HTTP status text.
+
+ @property statusText
+ @type String
+ */
+ statusText: "",
+
+ /**
+ Returns the response type. Can be set to change the response type. Values are:
+ the empty string (default), "arraybuffer", "blob", "document", "json", and "text".
+
+ @property responseType
+ @type String
+ */
+ responseType: "",
+
+ /**
+ Returns the document response entity body.
+
+ Throws an "InvalidStateError" exception if responseType is not the empty string or "document".
+
+ @property responseXML
+ @type Document
+ */
+ responseXML: null,
+
+ /**
+ Returns the text response entity body.
+
+ Throws an "InvalidStateError" exception if responseType is not the empty string or "text".
+
+ @property responseText
+ @type String
+ */
+ responseText: null,
+
+ /**
+ Returns the response entity body (http://www.w3.org/TR/XMLHttpRequest/#response-entity-body).
+ Can become: ArrayBuffer, Blob, Document, JSON, Text
+
+ @property response
+ @type Mixed
+ */
+ response: null
+ },
+
+ _async = true,
+ _url,
+ _method,
+ _headers = {},
+ _user,
+ _password,
+ _encoding = null,
+ _mimeType = null,
+
+ // flags
+ _sync_flag = false,
+ _send_flag = false,
+ _upload_events_flag = false,
+ _upload_complete_flag = false,
+ _error_flag = false,
+ _same_origin_flag = false,
+
+ // times
+ _start_time,
+ _timeoutset_time,
+
+ _finalMime = null,
+ _finalCharset = null,
+
+ _options = {},
+ _xhr,
+ _responseHeaders = '',
+ _responseHeadersBag
+ ;
+
+
+ Basic.extend(this, props, {
+ /**
+ Unique id of the component
+
+ @property uid
+ @type String
+ */
+ uid: Basic.guid('uid_'),
+
+ /**
+ Target for Upload events
+
+ @property upload
+ @type XMLHttpRequestUpload
+ */
+ upload: new XMLHttpRequestUpload(),
+
+
+ /**
+ Sets the request method, request URL, synchronous flag, request username, and request password.
+
+ Throws a "SyntaxError" exception if one of the following is true:
+
+ method is not a valid HTTP method.
+ url cannot be resolved.
+ url contains the "user:password" format in the userinfo production.
+ Throws a "SecurityError" exception if method is a case-insensitive match for CONNECT, TRACE or TRACK.
+
+ Throws an "InvalidAccessError" exception if one of the following is true:
+
+ Either user or password is passed as argument and the origin of url does not match the XMLHttpRequest origin.
+ There is an associated XMLHttpRequest document and either the timeout attribute is not zero,
+ the withCredentials attribute is true, or the responseType attribute is not the empty string.
+
+
+ @method open
+ @param {String} method HTTP method to use on request
+ @param {String} url URL to request
+ @param {Boolean} [async=true] If false request will be done in synchronous manner. Asynchronous by default.
+ @param {String} [user] Username to use in HTTP authentication process on server-side
+ @param {String} [password] Password to use in HTTP authentication process on server-side
+ */
+ open: function(method, url, async, user, password) {
+ var urlp;
+
+ // first two arguments are required
+ if (!method || !url) {
+ throw new x.DOMException(x.DOMException.SYNTAX_ERR);
+ }
+
+ // 2 - check if any code point in method is higher than U+00FF or after deflating method it does not match the method
+ if (/[\u0100-\uffff]/.test(method) || Encode.utf8_encode(method) !== method) {
+ throw new x.DOMException(x.DOMException.SYNTAX_ERR);
+ }
+
+ // 3
+ if (!!~Basic.inArray(method.toUpperCase(), ['CONNECT', 'DELETE', 'GET', 'HEAD', 'OPTIONS', 'POST', 'PUT', 'TRACE', 'TRACK'])) {
+ _method = method.toUpperCase();
+ }
+
+
+ // 4 - allowing these methods poses a security risk
+ if (!!~Basic.inArray(_method, ['CONNECT', 'TRACE', 'TRACK'])) {
+ throw new x.DOMException(x.DOMException.SECURITY_ERR);
+ }
+
+ // 5
+ url = Encode.utf8_encode(url);
+
+ // 6 - Resolve url relative to the XMLHttpRequest base URL. If the algorithm returns an error, throw a "SyntaxError".
+ urlp = Url.parseUrl(url);
+
+ _same_origin_flag = Url.hasSameOrigin(urlp);
+
+ // 7 - manually build up absolute url
+ _url = Url.resolveUrl(url);
+
+ // 9-10, 12-13
+ if ((user || password) && !_same_origin_flag) {
+ throw new x.DOMException(x.DOMException.INVALID_ACCESS_ERR);
+ }
+
+ _user = user || urlp.user;
+ _password = password || urlp.pass;
+
+ // 11
+ _async = async || true;
+
+ if (_async === false && (_p('timeout') || _p('withCredentials') || _p('responseType') !== "")) {
+ throw new x.DOMException(x.DOMException.INVALID_ACCESS_ERR);
+ }
+
+ // 14 - terminate abort()
+
+ // 15 - terminate send()
+
+ // 18
+ _sync_flag = !_async;
+ _send_flag = false;
+ _headers = {};
+ _reset.call(this);
+
+ // 19
+ _p('readyState', XMLHttpRequest.OPENED);
+
+ // 20
+ this.convertEventPropsToHandlers(['readystatechange']); // unify event handlers
+ this.dispatchEvent('readystatechange');
+ },
+
+ /**
+ Appends an header to the list of author request headers, or if header is already
+ in the list of author request headers, combines its value with value.
+
+ Throws an "InvalidStateError" exception if the state is not OPENED or if the send() flag is set.
+ Throws a "SyntaxError" exception if header is not a valid HTTP header field name or if value
+ is not a valid HTTP header field value.
+
+ @method setRequestHeader
+ @param {String} header
+ @param {String|Number} value
+ */
+ setRequestHeader: function(header, value) {
+ var uaHeaders = [ // these headers are controlled by the user agent
+ "accept-charset",
+ "accept-encoding",
+ "access-control-request-headers",
+ "access-control-request-method",
+ "connection",
+ "content-length",
+ "cookie",
+ "cookie2",
+ "content-transfer-encoding",
+ "date",
+ "expect",
+ "host",
+ "keep-alive",
+ "origin",
+ "referer",
+ "te",
+ "trailer",
+ "transfer-encoding",
+ "upgrade",
+ "user-agent",
+ "via"
+ ];
+
+ // 1-2
+ if (_p('readyState') !== XMLHttpRequest.OPENED || _send_flag) {
+ throw new x.DOMException(x.DOMException.INVALID_STATE_ERR);
+ }
+
+ // 3
+ if (/[\u0100-\uffff]/.test(header) || Encode.utf8_encode(header) !== header) {
+ throw new x.DOMException(x.DOMException.SYNTAX_ERR);
+ }
+
+ // 4
+ /* this step is seemingly bypassed in browsers, probably to allow various unicode characters in header values
+ if (/[\u0100-\uffff]/.test(value) || Encode.utf8_encode(value) !== value) {
+ throw new x.DOMException(x.DOMException.SYNTAX_ERR);
+ }*/
+
+ header = Basic.trim(header).toLowerCase();
+
+ // setting of proxy-* and sec-* headers is prohibited by spec
+ if (!!~Basic.inArray(header, uaHeaders) || /^(proxy\-|sec\-)/.test(header)) {
+ return false;
+ }
+
+ // camelize
+ // browsers lowercase header names (at least for custom ones)
+ // header = header.replace(/\b\w/g, function($1) { return $1.toUpperCase(); });
+
+ if (!_headers[header]) {
+ _headers[header] = value;
+ } else {
+ // http://tools.ietf.org/html/rfc2616#section-4.2 (last paragraph)
+ _headers[header] += ', ' + value;
+ }
+ return true;
+ },
+
+ /**
+ Returns all headers from the response, with the exception of those whose field name is Set-Cookie or Set-Cookie2.
+
+ @method getAllResponseHeaders
+ @return {String} reponse headers or empty string
+ */
+ getAllResponseHeaders: function() {
+ return _responseHeaders || '';
+ },
+
+ /**
+ Returns the header field value from the response of which the field name matches header,
+ unless the field name is Set-Cookie or Set-Cookie2.
+
+ @method getResponseHeader
+ @param {String} header
+ @return {String} value(s) for the specified header or null
+ */
+ getResponseHeader: function(header) {
+ header = header.toLowerCase();
+
+ if (_error_flag || !!~Basic.inArray(header, ['set-cookie', 'set-cookie2'])) {
+ return null;
+ }
+
+ if (_responseHeaders && _responseHeaders !== '') {
+ // if we didn't parse response headers until now, do it and keep for later
+ if (!_responseHeadersBag) {
+ _responseHeadersBag = {};
+ Basic.each(_responseHeaders.split(/\r\n/), function(line) {
+ var pair = line.split(/:\s+/);
+ if (pair.length === 2) { // last line might be empty, omit
+ pair[0] = Basic.trim(pair[0]); // just in case
+ _responseHeadersBag[pair[0].toLowerCase()] = { // simply to retain header name in original form
+ header: pair[0],
+ value: Basic.trim(pair[1])
+ };
+ }
+ });
+ }
+ if (_responseHeadersBag.hasOwnProperty(header)) {
+ return _responseHeadersBag[header].header + ': ' + _responseHeadersBag[header].value;
+ }
+ }
+ return null;
+ },
+
+ /**
+ Sets the Content-Type header for the response to mime.
+ Throws an "InvalidStateError" exception if the state is LOADING or DONE.
+ Throws a "SyntaxError" exception if mime is not a valid media type.
+
+ @method overrideMimeType
+ @param String mime Mime type to set
+ */
+ overrideMimeType: function(mime) {
+ var matches, charset;
+
+ // 1
+ if (!!~Basic.inArray(_p('readyState'), [XMLHttpRequest.LOADING, XMLHttpRequest.DONE])) {
+ throw new x.DOMException(x.DOMException.INVALID_STATE_ERR);
+ }
+
+ // 2
+ mime = Basic.trim(mime.toLowerCase());
+
+ if (/;/.test(mime) && (matches = mime.match(/^([^;]+)(?:;\scharset\=)?(.*)$/))) {
+ mime = matches[1];
+ if (matches[2]) {
+ charset = matches[2];
+ }
+ }
+
+ if (!Mime.mimes[mime]) {
+ throw new x.DOMException(x.DOMException.SYNTAX_ERR);
+ }
+
+ // 3-4
+ _finalMime = mime;
+ _finalCharset = charset;
+ },
+
+ /**
+ Initiates the request. The optional argument provides the request entity body.
+ The argument is ignored if request method is GET or HEAD.
+
+ Throws an "InvalidStateError" exception if the state is not OPENED or if the send() flag is set.
+
+ @method send
+ @param {Blob|Document|String|FormData} [data] Request entity body
+ @param {Object} [options] Set of requirements and pre-requisities for runtime initialization
+ */
+ send: function(data, options) {
+ if (Basic.typeOf(options) === 'string') {
+ _options = { ruid: options };
+ } else if (!options) {
+ _options = {};
+ } else {
+ _options = options;
+ }
+
+ this.convertEventPropsToHandlers(dispatches);
+ this.upload.convertEventPropsToHandlers(dispatches);
+
+ // 1-2
+ if (this.readyState !== XMLHttpRequest.OPENED || _send_flag) {
+ throw new x.DOMException(x.DOMException.INVALID_STATE_ERR);
+ }
+
+ // 3
+ // sending Blob
+ if (data instanceof Blob) {
+ _options.ruid = data.ruid;
+ _mimeType = data.type || 'application/octet-stream';
+ }
+
+ // FormData
+ else if (data instanceof FormData) {
+ if (data.hasBlob()) {
+ var blob = data.getBlob();
+ _options.ruid = blob.ruid;
+ _mimeType = blob.type || 'application/octet-stream';
+ }
+ }
+
+ // DOMString
+ else if (typeof data === 'string') {
+ _encoding = 'UTF-8';
+ _mimeType = 'text/plain;charset=UTF-8';
+
+ // data should be converted to Unicode and encoded as UTF-8
+ data = Encode.utf8_encode(data);
+ }
+
+ // if withCredentials not set, but requested, set it automatically
+ if (!this.withCredentials) {
+ this.withCredentials = (_options.required_caps && _options.required_caps.send_browser_cookies) && !_same_origin_flag;
+ }
+
+ // 4 - storage mutex
+ // 5
+ _upload_events_flag = (!_sync_flag && this.upload.hasEventListener()); // DSAP
+ // 6
+ _error_flag = false;
+ // 7
+ _upload_complete_flag = !data;
+ // 8 - Asynchronous steps
+ if (!_sync_flag) {
+ // 8.1
+ _send_flag = true;
+ // 8.2
+ // this.dispatchEvent('loadstart'); // will be dispatched either by native or runtime xhr
+ // 8.3
+ //if (!_upload_complete_flag) {
+ // this.upload.dispatchEvent('loadstart'); // will be dispatched either by native or runtime xhr
+ //}
+ }
+ // 8.5 - Return the send() method call, but continue running the steps in this algorithm.
+ _doXHR.call(this, data);
+ },
+
+ /**
+ Cancels any network activity.
+
+ @method abort
+ */
+ abort: function() {
+ _error_flag = true;
+ _sync_flag = false;
+
+ if (!~Basic.inArray(_p('readyState'), [XMLHttpRequest.UNSENT, XMLHttpRequest.OPENED, XMLHttpRequest.DONE])) {
+ _p('readyState', XMLHttpRequest.DONE);
+ _send_flag = false;
+
+ if (_xhr) {
+ _xhr.getRuntime().exec.call(_xhr, 'XMLHttpRequest', 'abort', _upload_complete_flag);
+ } else {
+ throw new x.DOMException(x.DOMException.INVALID_STATE_ERR);
+ }
+
+ _upload_complete_flag = true;
+ } else {
+ _p('readyState', XMLHttpRequest.UNSENT);
+ }
+ },
+
+ destroy: function() {
+ if (_xhr) {
+ if (Basic.typeOf(_xhr.destroy) === 'function') {
+ _xhr.destroy();
+ }
+ _xhr = null;
+ }
+
+ this.unbindAll();
+
+ if (this.upload) {
+ this.upload.unbindAll();
+ this.upload = null;
+ }
+ }
+ });
+
+ /* this is nice, but maybe too lengthy
+
+ // if supported by JS version, set getters/setters for specific properties
+ o.defineProperty(this, 'readyState', {
+ configurable: false,
+
+ get: function() {
+ return _p('readyState');
+ }
+ });
+
+ o.defineProperty(this, 'timeout', {
+ configurable: false,
+
+ get: function() {
+ return _p('timeout');
+ },
+
+ set: function(value) {
+
+ if (_sync_flag) {
+ throw new x.DOMException(x.DOMException.INVALID_ACCESS_ERR);
+ }
+
+ // timeout still should be measured relative to the start time of request
+ _timeoutset_time = (new Date).getTime();
+
+ _p('timeout', value);
+ }
+ });
+
+ // the withCredentials attribute has no effect when fetching same-origin resources
+ o.defineProperty(this, 'withCredentials', {
+ configurable: false,
+
+ get: function() {
+ return _p('withCredentials');
+ },
+
+ set: function(value) {
+ // 1-2
+ if (!~o.inArray(_p('readyState'), [XMLHttpRequest.UNSENT, XMLHttpRequest.OPENED]) || _send_flag) {
+ throw new x.DOMException(x.DOMException.INVALID_STATE_ERR);
+ }
+
+ // 3-4
+ if (_anonymous_flag || _sync_flag) {
+ throw new x.DOMException(x.DOMException.INVALID_ACCESS_ERR);
+ }
+
+ // 5
+ _p('withCredentials', value);
+ }
+ });
+
+ o.defineProperty(this, 'status', {
+ configurable: false,
+
+ get: function() {
+ return _p('status');
+ }
+ });
+
+ o.defineProperty(this, 'statusText', {
+ configurable: false,
+
+ get: function() {
+ return _p('statusText');
+ }
+ });
+
+ o.defineProperty(this, 'responseType', {
+ configurable: false,
+
+ get: function() {
+ return _p('responseType');
+ },
+
+ set: function(value) {
+ // 1
+ if (!!~o.inArray(_p('readyState'), [XMLHttpRequest.LOADING, XMLHttpRequest.DONE])) {
+ throw new x.DOMException(x.DOMException.INVALID_STATE_ERR);
+ }
+
+ // 2
+ if (_sync_flag) {
+ throw new x.DOMException(x.DOMException.INVALID_ACCESS_ERR);
+ }
+
+ // 3
+ _p('responseType', value.toLowerCase());
+ }
+ });
+
+ o.defineProperty(this, 'responseText', {
+ configurable: false,
+
+ get: function() {
+ // 1
+ if (!~o.inArray(_p('responseType'), ['', 'text'])) {
+ throw new x.DOMException(x.DOMException.INVALID_STATE_ERR);
+ }
+
+ // 2-3
+ if (_p('readyState') !== XMLHttpRequest.DONE && _p('readyState') !== XMLHttpRequest.LOADING || _error_flag) {
+ throw new x.DOMException(x.DOMException.INVALID_STATE_ERR);
+ }
+
+ return _p('responseText');
+ }
+ });
+
+ o.defineProperty(this, 'responseXML', {
+ configurable: false,
+
+ get: function() {
+ // 1
+ if (!~o.inArray(_p('responseType'), ['', 'document'])) {
+ throw new x.DOMException(x.DOMException.INVALID_STATE_ERR);
+ }
+
+ // 2-3
+ if (_p('readyState') !== XMLHttpRequest.DONE || _error_flag) {
+ throw new x.DOMException(x.DOMException.INVALID_STATE_ERR);
+ }
+
+ return _p('responseXML');
+ }
+ });
+
+ o.defineProperty(this, 'response', {
+ configurable: false,
+
+ get: function() {
+ if (!!~o.inArray(_p('responseType'), ['', 'text'])) {
+ if (_p('readyState') !== XMLHttpRequest.DONE && _p('readyState') !== XMLHttpRequest.LOADING || _error_flag) {
+ return '';
+ }
+ }
+
+ if (_p('readyState') !== XMLHttpRequest.DONE || _error_flag) {
+ return null;
+ }
+
+ return _p('response');
+ }
+ });
+
+ */
+
+ function _p(prop, value) {
+ if (!props.hasOwnProperty(prop)) {
+ return;
+ }
+ if (arguments.length === 1) { // get
+ return Env.can('define_property') ? props[prop] : self[prop];
+ } else { // set
+ if (Env.can('define_property')) {
+ props[prop] = value;
+ } else {
+ self[prop] = value;
+ }
+ }
+ }
+
+ /*
+ function _toASCII(str, AllowUnassigned, UseSTD3ASCIIRules) {
+ // TODO: http://tools.ietf.org/html/rfc3490#section-4.1
+ return str.toLowerCase();
+ }
+ */
+
+
+ function _doXHR(data) {
+ var self = this;
+
+ _start_time = new Date().getTime();
+
+ _xhr = new RuntimeTarget();
+
+ function loadEnd() {
+ if (_xhr) { // it could have been destroyed by now
+ _xhr.destroy();
+ _xhr = null;
+ }
+ self.dispatchEvent('loadend');
+ self = null;
+ }
+
+ function exec(runtime) {
+ _xhr.bind('LoadStart', function(e) {
+ _p('readyState', XMLHttpRequest.LOADING);
+ self.dispatchEvent('readystatechange');
+
+ self.dispatchEvent(e);
+
+ if (_upload_events_flag) {
+ self.upload.dispatchEvent(e);
+ }
+ });
+
+ _xhr.bind('Progress', function(e) {
+ if (_p('readyState') !== XMLHttpRequest.LOADING) {
+ _p('readyState', XMLHttpRequest.LOADING); // LoadStart unreliable (in Flash for example)
+ self.dispatchEvent('readystatechange');
+ }
+ self.dispatchEvent(e);
+ });
+
+ _xhr.bind('UploadProgress', function(e) {
+ if (_upload_events_flag) {
+ self.upload.dispatchEvent({
+ type: 'progress',
+ lengthComputable: false,
+ total: e.total,
+ loaded: e.loaded
+ });
+ }
+ });
+
+ _xhr.bind('Load', function(e) {
+ _p('readyState', XMLHttpRequest.DONE);
+ _p('status', Number(runtime.exec.call(_xhr, 'XMLHttpRequest', 'getStatus') || 0));
+ _p('statusText', httpCode[_p('status')] || "");
+
+ _p('response', runtime.exec.call(_xhr, 'XMLHttpRequest', 'getResponse', _p('responseType')));
+
+ if (!!~Basic.inArray(_p('responseType'), ['text', ''])) {
+ _p('responseText', _p('response'));
+ } else if (_p('responseType') === 'document') {
+ _p('responseXML', _p('response'));
+ }
+
+ _responseHeaders = runtime.exec.call(_xhr, 'XMLHttpRequest', 'getAllResponseHeaders');
+
+ self.dispatchEvent('readystatechange');
+
+ if (_p('status') > 0) { // status 0 usually means that server is unreachable
+ if (_upload_events_flag) {
+ self.upload.dispatchEvent(e);
+ }
+ self.dispatchEvent(e);
+ } else {
+ _error_flag = true;
+ self.dispatchEvent('error');
+ }
+ loadEnd();
+ });
+
+ _xhr.bind('Abort', function(e) {
+ self.dispatchEvent(e);
+ loadEnd();
+ });
+
+ _xhr.bind('Error', function(e) {
+ _error_flag = true;
+ _p('readyState', XMLHttpRequest.DONE);
+ self.dispatchEvent('readystatechange');
+ _upload_complete_flag = true;
+ self.dispatchEvent(e);
+ loadEnd();
+ });
+
+ runtime.exec.call(_xhr, 'XMLHttpRequest', 'send', {
+ url: _url,
+ method: _method,
+ async: _async,
+ user: _user,
+ password: _password,
+ headers: _headers,
+ mimeType: _mimeType,
+ encoding: _encoding,
+ responseType: self.responseType,
+ withCredentials: self.withCredentials,
+ options: _options
+ }, data);
+ }
+
+ // clarify our requirements
+ if (typeof(_options.required_caps) === 'string') {
+ _options.required_caps = Runtime.parseCaps(_options.required_caps);
+ }
+
+ _options.required_caps = Basic.extend({}, _options.required_caps, {
+ return_response_type: self.responseType
+ });
+
+ if (data instanceof FormData) {
+ _options.required_caps.send_multipart = true;
+ }
+
+ if (!_same_origin_flag) {
+ _options.required_caps.do_cors = true;
+ }
+
+
+ if (_options.ruid) { // we do not need to wait if we can connect directly
+ exec(_xhr.connectRuntime(_options));
+ } else {
+ _xhr.bind('RuntimeInit', function(e, runtime) {
+ exec(runtime);
+ });
+ _xhr.bind('RuntimeError', function(e, err) {
+ self.dispatchEvent('RuntimeError', err);
+ });
+ _xhr.connectRuntime(_options);
+ }
+ }
+
+
+ function _reset() {
+ _p('responseText', "");
+ _p('responseXML', null);
+ _p('response', null);
+ _p('status', 0);
+ _p('statusText', "");
+ _start_time = _timeoutset_time = null;
+ }
+ }
+
+ XMLHttpRequest.UNSENT = 0;
+ XMLHttpRequest.OPENED = 1;
+ XMLHttpRequest.HEADERS_RECEIVED = 2;
+ XMLHttpRequest.LOADING = 3;
+ XMLHttpRequest.DONE = 4;
+
+ XMLHttpRequest.prototype = EventTarget.instance;
+
+ return XMLHttpRequest;
+});
+
+// Included from: src/javascript/runtime/flash/Runtime.js
+
+/**
+ * Runtime.js
+ *
+ * Copyright 2013, Moxiecode Systems AB
+ * Released under GPL License.
+ *
+ * License: http://www.plupload.com/license
+ * Contributing: http://www.plupload.com/contributing
+ */
+
+/*global ActiveXObject:true */
+
+/**
+Defines constructor for Flash runtime.
+
+@class moxie/runtime/flash/Runtime
+@private
+*/
+define("moxie/runtime/flash/Runtime", [
+ "moxie/core/utils/Basic",
+ "moxie/core/utils/Env",
+ "moxie/core/utils/Dom",
+ "moxie/core/Exceptions",
+ "moxie/runtime/Runtime"
+], function(Basic, Env, Dom, x, Runtime) {
+
+ var type = 'flash', extensions = {};
+
+ /**
+ Get the version of the Flash Player
+
+ @method getShimVersion
+ @private
+ @return {Number} Flash Player version
+ */
+ function getShimVersion() {
+ var version;
+
+ try {
+ version = navigator.plugins['Shockwave Flash'];
+ version = version.description;
+ } catch (e1) {
+ try {
+ version = new ActiveXObject('ShockwaveFlash.ShockwaveFlash').GetVariable('$version');
+ } catch (e2) {
+ version = '0.0';
+ }
+ }
+ version = version.match(/\d+/g);
+ return parseFloat(version[0] + '.' + version[1]);
+ }
+
+ /**
+ Constructor for the Flash Runtime
+
+ @class FlashRuntime
+ @extends Runtime
+ */
+ function FlashRuntime(options) {
+ var I = this, initTimer;
+
+ options = Basic.extend({ swf_url: Env.swf_url }, options);
+
+ Runtime.call(this, options, type, {
+ access_binary: function(value) {
+ return value && I.mode === 'browser';
+ },
+ access_image_binary: function(value) {
+ return value && I.mode === 'browser';
+ },
+ display_media: Runtime.capTrue,
+ do_cors: Runtime.capTrue,
+ drag_and_drop: false,
+ report_upload_progress: function() {
+ return I.mode === 'client';
+ },
+ resize_image: Runtime.capTrue,
+ return_response_headers: false,
+ return_response_type: function(responseType) {
+ if (responseType === 'json' && !!window.JSON) {
+ return true;
+ }
+ return !Basic.arrayDiff(responseType, ['', 'text', 'document']) || I.mode === 'browser';
+ },
+ return_status_code: function(code) {
+ return I.mode === 'browser' || !Basic.arrayDiff(code, [200, 404]);
+ },
+ select_file: Runtime.capTrue,
+ select_multiple: Runtime.capTrue,
+ send_binary_string: function(value) {
+ return value && I.mode === 'browser';
+ },
+ send_browser_cookies: function(value) {
+ return value && I.mode === 'browser';
+ },
+ send_custom_headers: function(value) {
+ return value && I.mode === 'browser';
+ },
+ send_multipart: Runtime.capTrue,
+ slice_blob: function(value) {
+ return value && I.mode === 'browser';
+ },
+ stream_upload: function(value) {
+ return value && I.mode === 'browser';
+ },
+ summon_file_dialog: false,
+ upload_filesize: function(size) {
+ return Basic.parseSizeStr(size) <= 2097152 || I.mode === 'client';
+ },
+ use_http_method: function(methods) {
+ return !Basic.arrayDiff(methods, ['GET', 'POST']);
+ }
+ }, {
+ // capabilities that require specific mode
+ access_binary: function(value) {
+ return value ? 'browser' : 'client';
+ },
+ access_image_binary: function(value) {
+ return value ? 'browser' : 'client';
+ },
+ report_upload_progress: function(value) {
+ return value ? 'browser' : 'client';
+ },
+ return_response_type: function(responseType) {
+ return Basic.arrayDiff(responseType, ['', 'text', 'json', 'document']) ? 'browser' : ['client', 'browser'];
+ },
+ return_status_code: function(code) {
+ return Basic.arrayDiff(code, [200, 404]) ? 'browser' : ['client', 'browser'];
+ },
+ send_binary_string: function(value) {
+ return value ? 'browser' : 'client';
+ },
+ send_browser_cookies: function(value) {
+ return value ? 'browser' : 'client';
+ },
+ send_custom_headers: function(value) {
+ return value ? 'browser' : 'client';
+ },
+ stream_upload: function(value) {
+ return value ? 'client' : 'browser';
+ },
+ upload_filesize: function(size) {
+ return Basic.parseSizeStr(size) >= 2097152 ? 'client' : 'browser';
+ }
+ }, 'client');
+
+
+ // minimal requirement for Flash Player version
+ if (getShimVersion() < 10) {
+ this.mode = false; // with falsy mode, runtime won't operable, no matter what the mode was before
+ }
+
+
+ Basic.extend(this, {
+
+ getShim: function() {
+ return Dom.get(this.uid);
+ },
+
+ shimExec: function(component, action) {
+ var args = [].slice.call(arguments, 2);
+ return I.getShim().exec(this.uid, component, action, args);
+ },
+
+ init: function() {
+ var html, el, container;
+
+ container = this.getShimContainer();
+
+ // if not the minimal height, shims are not initialized in older browsers (e.g FF3.6, IE6,7,8, Safari 4.0,5.0, etc)
+ Basic.extend(container.style, {
+ position: 'absolute',
+ top: '-8px',
+ left: '-8px',
+ width: '9px',
+ height: '9px',
+ overflow: 'hidden'
+ });
+
+ // insert flash object
+ html = '';
+
+ if (Env.browser === 'IE') {
+ el = document.createElement('div');
+ container.appendChild(el);
+ el.outerHTML = html;
+ el = container = null; // just in case
+ } else {
+ container.innerHTML = html;
+ }
+
+ // Init is dispatched by the shim
+ initTimer = setTimeout(function() {
+ if (I && !I.initialized) { // runtime might be already destroyed by this moment
+ I.trigger("Error", new x.RuntimeError(x.RuntimeError.NOT_INIT_ERR));
+ }
+ }, 5000);
+ },
+
+ destroy: (function(destroy) { // extend default destroy method
+ return function() {
+ destroy.call(I);
+ clearTimeout(initTimer); // initialization check might be still onwait
+ options = initTimer = destroy = I = null;
+ };
+ }(this.destroy))
+
+ }, extensions);
+ }
+
+ Runtime.addConstructor(type, FlashRuntime);
+
+ return extensions;
+});
+
+// Included from: src/javascript/runtime/flash/file/Blob.js
+
+/**
+ * Blob.js
+ *
+ * Copyright 2013, Moxiecode Systems AB
+ * Released under GPL License.
+ *
+ * License: http://www.plupload.com/license
+ * Contributing: http://www.plupload.com/contributing
+ */
+
+/**
+@class moxie/runtime/flash/file/Blob
+@private
+*/
+define("moxie/runtime/flash/file/Blob", [
+ "moxie/runtime/flash/Runtime",
+ "moxie/file/Blob"
+], function(extensions, Blob) {
+
+ var FlashBlob = {
+ slice: function(blob, start, end, type) {
+ var self = this.getRuntime();
+
+ if (start < 0) {
+ start = Math.max(blob.size + start, 0);
+ } else if (start > 0) {
+ start = Math.min(start, blob.size);
+ }
+
+ if (end < 0) {
+ end = Math.max(blob.size + end, 0);
+ } else if (end > 0) {
+ end = Math.min(end, blob.size);
+ }
+
+ blob = self.shimExec.call(this, 'Blob', 'slice', start, end, type || '');
+
+ if (blob) {
+ blob = new Blob(self.uid, blob);
+ }
+ return blob;
+ }
+ };
+
+ return (extensions.Blob = FlashBlob);
+});
+
+// Included from: src/javascript/runtime/flash/file/FileInput.js
+
+/**
+ * FileInput.js
+ *
+ * Copyright 2013, Moxiecode Systems AB
+ * Released under GPL License.
+ *
+ * License: http://www.plupload.com/license
+ * Contributing: http://www.plupload.com/contributing
+ */
+
+/**
+@class moxie/runtime/flash/file/FileInput
+@private
+*/
+define("moxie/runtime/flash/file/FileInput", [
+ "moxie/runtime/flash/Runtime"
+], function(extensions) {
+
+ var FileInput = {
+ init: function(options) {
+ this.getRuntime().shimExec.call(this, 'FileInput', 'init', {
+ name: options.name,
+ accept: options.accept,
+ multiple: options.multiple
+ });
+ this.trigger('ready');
+ }
+ };
+
+ return (extensions.FileInput = FileInput);
+});
+
+// Included from: src/javascript/runtime/flash/file/FileReader.js
+
+/**
+ * FileReader.js
+ *
+ * Copyright 2013, Moxiecode Systems AB
+ * Released under GPL License.
+ *
+ * License: http://www.plupload.com/license
+ * Contributing: http://www.plupload.com/contributing
+ */
+
+/**
+@class moxie/runtime/flash/file/FileReader
+@private
+*/
+define("moxie/runtime/flash/file/FileReader", [
+ "moxie/runtime/flash/Runtime",
+ "moxie/core/utils/Encode"
+], function(extensions, Encode) {
+
+ var _result = '';
+
+ function _formatData(data, op) {
+ switch (op) {
+ case 'readAsText':
+ return Encode.atob(data, 'utf8');
+ case 'readAsBinaryString':
+ return Encode.atob(data);
+ case 'readAsDataURL':
+ return data;
+ }
+ return null;
+ }
+
+ var FileReader = {
+ read: function(op, blob) {
+ var target = this, self = target.getRuntime();
+
+ // special prefix for DataURL read mode
+ if (op === 'readAsDataURL') {
+ _result = 'data:' + (blob.type || '') + ';base64,';
+ }
+
+ target.bind('Progress', function(e, data) {
+ if (data) {
+ _result += _formatData(data, op);
+ }
+ });
+
+ return self.shimExec.call(this, 'FileReader', 'readAsBase64', blob.uid);
+ },
+
+ getResult: function() {
+ return _result;
+ },
+
+ destroy: function() {
+ _result = null;
+ }
+ };
+
+ return (extensions.FileReader = FileReader);
+});
+
+// Included from: src/javascript/runtime/flash/file/FileReaderSync.js
+
+/**
+ * FileReaderSync.js
+ *
+ * Copyright 2013, Moxiecode Systems AB
+ * Released under GPL License.
+ *
+ * License: http://www.plupload.com/license
+ * Contributing: http://www.plupload.com/contributing
+ */
+
+/**
+@class moxie/runtime/flash/file/FileReaderSync
+@private
+*/
+define("moxie/runtime/flash/file/FileReaderSync", [
+ "moxie/runtime/flash/Runtime",
+ "moxie/core/utils/Encode"
+], function(extensions, Encode) {
+
+ function _formatData(data, op) {
+ switch (op) {
+ case 'readAsText':
+ return Encode.atob(data, 'utf8');
+ case 'readAsBinaryString':
+ return Encode.atob(data);
+ case 'readAsDataURL':
+ return data;
+ }
+ return null;
+ }
+
+ var FileReaderSync = {
+ read: function(op, blob) {
+ var result, self = this.getRuntime();
+
+ result = self.shimExec.call(this, 'FileReaderSync', 'readAsBase64', blob.uid);
+ if (!result) {
+ return null; // or throw ex
+ }
+
+ // special prefix for DataURL read mode
+ if (op === 'readAsDataURL') {
+ result = 'data:' + (blob.type || '') + ';base64,' + result;
+ }
+
+ return _formatData(result, op, blob.type);
+ }
+ };
+
+ return (extensions.FileReaderSync = FileReaderSync);
+});
+
+// Included from: src/javascript/runtime/Transporter.js
+
+/**
+ * Transporter.js
+ *
+ * Copyright 2013, Moxiecode Systems AB
+ * Released under GPL License.
+ *
+ * License: http://www.plupload.com/license
+ * Contributing: http://www.plupload.com/contributing
+ */
+
+define("moxie/runtime/Transporter", [
+ "moxie/core/utils/Basic",
+ "moxie/core/utils/Encode",
+ "moxie/runtime/RuntimeClient",
+ "moxie/core/EventTarget"
+], function(Basic, Encode, RuntimeClient, EventTarget) {
+ function Transporter() {
+ var mod, _runtime, _data, _size, _pos, _chunk_size;
+
+ RuntimeClient.call(this);
+
+ Basic.extend(this, {
+ uid: Basic.guid('uid_'),
+
+ state: Transporter.IDLE,
+
+ result: null,
+
+ transport: function(data, type, options) {
+ var self = this;
+
+ options = Basic.extend({
+ chunk_size: 204798
+ }, options);
+
+ // should divide by three, base64 requires this
+ if ((mod = options.chunk_size % 3)) {
+ options.chunk_size += 3 - mod;
+ }
+
+ _chunk_size = options.chunk_size;
+
+ _reset.call(this);
+ _data = data;
+ _size = data.length;
+
+ if (Basic.typeOf(options) === 'string' || options.ruid) {
+ _run.call(self, type, this.connectRuntime(options));
+ } else {
+ // we require this to run only once
+ var cb = function(e, runtime) {
+ self.unbind("RuntimeInit", cb);
+ _run.call(self, type, runtime);
+ };
+ this.bind("RuntimeInit", cb);
+ this.connectRuntime(options);
+ }
+ },
+
+ abort: function() {
+ var self = this;
+
+ self.state = Transporter.IDLE;
+ if (_runtime) {
+ _runtime.exec.call(self, 'Transporter', 'clear');
+ self.trigger("TransportingAborted");
+ }
+
+ _reset.call(self);
+ },
+
+
+ destroy: function() {
+ this.unbindAll();
+ _runtime = null;
+ this.disconnectRuntime();
+ _reset.call(this);
+ }
+ });
+
+ function _reset() {
+ _size = _pos = 0;
+ _data = this.result = null;
+ }
+
+ function _run(type, runtime) {
+ var self = this;
+
+ _runtime = runtime;
+
+ //self.unbind("RuntimeInit");
+
+ self.bind("TransportingProgress", function(e) {
+ _pos = e.loaded;
+
+ if (_pos < _size && Basic.inArray(self.state, [Transporter.IDLE, Transporter.DONE]) === -1) {
+ _transport.call(self);
+ }
+ }, 999);
+
+ self.bind("TransportingComplete", function() {
+ _pos = _size;
+ self.state = Transporter.DONE;
+ _data = null; // clean a bit
+ self.result = _runtime.exec.call(self, 'Transporter', 'getAsBlob', type || '');
+ }, 999);
+
+ self.state = Transporter.BUSY;
+ self.trigger("TransportingStarted");
+ _transport.call(self);
+ }
+
+ function _transport() {
+ var self = this,
+ chunk,
+ bytesLeft = _size - _pos;
+
+ if (_chunk_size > bytesLeft) {
+ _chunk_size = bytesLeft;
+ }
+
+ chunk = Encode.btoa(_data.substr(_pos, _chunk_size));
+ _runtime.exec.call(self, 'Transporter', 'receive', chunk, _size);
+ }
+ }
+
+ Transporter.IDLE = 0;
+ Transporter.BUSY = 1;
+ Transporter.DONE = 2;
+
+ Transporter.prototype = EventTarget.instance;
+
+ return Transporter;
+});
+
+// Included from: src/javascript/runtime/flash/xhr/XMLHttpRequest.js
+
+/**
+ * XMLHttpRequest.js
+ *
+ * Copyright 2013, Moxiecode Systems AB
+ * Released under GPL License.
+ *
+ * License: http://www.plupload.com/license
+ * Contributing: http://www.plupload.com/contributing
+ */
+
+/**
+@class moxie/runtime/flash/xhr/XMLHttpRequest
+@private
+*/
+define("moxie/runtime/flash/xhr/XMLHttpRequest", [
+ "moxie/runtime/flash/Runtime",
+ "moxie/core/utils/Basic",
+ "moxie/file/Blob",
+ "moxie/file/File",
+ "moxie/file/FileReaderSync",
+ "moxie/xhr/FormData",
+ "moxie/runtime/Transporter"
+], function(extensions, Basic, Blob, File, FileReaderSync, FormData, Transporter) {
+
+ var XMLHttpRequest = {
+
+ send: function(meta, data) {
+ var target = this, self = target.getRuntime();
+
+ function send() {
+ meta.transport = self.mode;
+ self.shimExec.call(target, 'XMLHttpRequest', 'send', meta, data);
+ }
+
+
+ function appendBlob(name, blob) {
+ self.shimExec.call(target, 'XMLHttpRequest', 'appendBlob', name, blob.uid);
+ data = null;
+ send();
+ }
+
+
+ function attachBlob(blob, cb) {
+ var tr = new Transporter();
+
+ tr.bind("TransportingComplete", function() {
+ cb(this.result);
+ });
+
+ tr.transport(blob.getSource(), blob.type, {
+ ruid: self.uid
+ });
+ }
+
+ // copy over the headers if any
+ if (!Basic.isEmptyObj(meta.headers)) {
+ Basic.each(meta.headers, function(value, header) {
+ self.shimExec.call(target, 'XMLHttpRequest', 'setRequestHeader', header, value.toString()); // Silverlight doesn't accept integers into the arguments of type object
+ });
+ }
+
+ // transfer over multipart params and blob itself
+ if (data instanceof FormData) {
+ var blobField;
+ data.each(function(value, name) {
+ if (value instanceof Blob) {
+ blobField = name;
+ } else {
+ self.shimExec.call(target, 'XMLHttpRequest', 'append', name, value);
+ }
+ });
+
+ if (!data.hasBlob()) {
+ data = null;
+ send();
+ } else {
+ var blob = data.getBlob();
+ if (blob.isDetached()) {
+ attachBlob(blob, function(attachedBlob) {
+ blob.destroy();
+ appendBlob(blobField, attachedBlob);
+ });
+ } else {
+ appendBlob(blobField, blob);
+ }
+ }
+ } else if (data instanceof Blob) {
+ if (data.isDetached()) {
+ attachBlob(data, function(attachedBlob) {
+ data.destroy();
+ data = attachedBlob.uid;
+ send();
+ });
+ } else {
+ data = data.uid;
+ send();
+ }
+ } else {
+ send();
+ }
+ },
+
+ getResponse: function(responseType) {
+ var frs, blob, self = this.getRuntime();
+
+ blob = self.shimExec.call(this, 'XMLHttpRequest', 'getResponseAsBlob');
+
+ if (blob) {
+ blob = new File(self.uid, blob);
+
+ if ('blob' === responseType) {
+ return blob;
+ }
+
+ try {
+ frs = new FileReaderSync();
+
+ if (!!~Basic.inArray(responseType, ["", "text"])) {
+ return frs.readAsText(blob);
+ } else if ('json' === responseType && !!window.JSON) {
+ return JSON.parse(frs.readAsText(blob));
+ }
+ } finally {
+ blob.destroy();
+ }
+ }
+ return null;
+ },
+
+ abort: function(upload_complete_flag) {
+ var self = this.getRuntime();
+
+ self.shimExec.call(this, 'XMLHttpRequest', 'abort');
+
+ this.dispatchEvent('readystatechange');
+ // this.dispatchEvent('progress');
+ this.dispatchEvent('abort');
+
+ //if (!upload_complete_flag) {
+ // this.dispatchEvent('uploadprogress');
+ //}
+ }
+ };
+
+ return (extensions.XMLHttpRequest = XMLHttpRequest);
+});
+
+// Included from: src/javascript/runtime/html4/Runtime.js
+
+/**
+ * Runtime.js
+ *
+ * Copyright 2013, Moxiecode Systems AB
+ * Released under GPL License.
+ *
+ * License: http://www.plupload.com/license
+ * Contributing: http://www.plupload.com/contributing
+ */
+
+/*global File:true */
+
+/**
+Defines constructor for HTML4 runtime.
+
+@class moxie/runtime/html4/Runtime
+@private
+*/
+define("moxie/runtime/html4/Runtime", [
+ "moxie/core/utils/Basic",
+ "moxie/core/Exceptions",
+ "moxie/runtime/Runtime",
+ "moxie/core/utils/Env"
+], function(Basic, x, Runtime, Env) {
+
+ var type = 'html4', extensions = {};
+
+ function Html4Runtime(options) {
+ var I = this
+ , Test = Runtime.capTest
+ , True = Runtime.capTrue
+ ;
+
+ Runtime.call(this, options, type, {
+ access_binary: Test(window.FileReader || window.File && File.getAsDataURL),
+ access_image_binary: false,
+ display_media: Test(extensions.Image && (Env.can('create_canvas') || Env.can('use_data_uri_over32kb'))),
+ do_cors: false,
+ drag_and_drop: false,
+ filter_by_extension: Test(function() { // if you know how to feature-detect this, please suggest
+ return (Env.browser === 'Chrome' && Env.version >= 28) || (Env.browser === 'IE' && Env.version >= 10);
+ }()),
+ resize_image: function() {
+ return extensions.Image && I.can('access_binary') && Env.can('create_canvas');
+ },
+ report_upload_progress: false,
+ return_response_headers: false,
+ return_response_type: function(responseType) {
+ if (responseType === 'json' && !!window.JSON) {
+ return true;
+ }
+ return !!~Basic.inArray(responseType, ['text', 'document', '']);
+ },
+ return_status_code: function(code) {
+ return !Basic.arrayDiff(code, [200, 404]);
+ },
+ select_file: function() {
+ return Env.can('use_fileinput');
+ },
+ select_multiple: false,
+ send_binary_string: false,
+ send_custom_headers: false,
+ send_multipart: true,
+ slice_blob: false,
+ stream_upload: function() {
+ return I.can('select_file');
+ },
+ summon_file_dialog: Test(function() { // yeah... some dirty sniffing here...
+ return (Env.browser === 'Firefox' && Env.version >= 4) ||
+ (Env.browser === 'Opera' && Env.version >= 12) ||
+ !!~Basic.inArray(Env.browser, ['Chrome', 'Safari']);
+ }()),
+ upload_filesize: True,
+ use_http_method: function(methods) {
+ return !Basic.arrayDiff(methods, ['GET', 'POST']);
+ }
+ });
+
+
+ Basic.extend(this, {
+ init : function() {
+ this.trigger("Init");
+ },
+
+ destroy: (function(destroy) { // extend default destroy method
+ return function() {
+ destroy.call(I);
+ destroy = I = null;
+ };
+ }(this.destroy))
+ });
+
+ Basic.extend(this.getShim(), extensions);
+ }
+
+ Runtime.addConstructor(type, Html4Runtime);
+
+ return extensions;
+});
+
+// Included from: src/javascript/core/utils/Events.js
+
+/**
+ * Events.js
+ *
+ * Copyright 2013, Moxiecode Systems AB
+ * Released under GPL License.
+ *
+ * License: http://www.plupload.com/license
+ * Contributing: http://www.plupload.com/contributing
+ */
+
+define('moxie/core/utils/Events', [
+ 'moxie/core/utils/Basic'
+], function(Basic) {
+ var eventhash = {}, uid = 'moxie_' + Basic.guid();
+
+ // IE W3C like event funcs
+ function preventDefault() {
+ this.returnValue = false;
+ }
+
+ function stopPropagation() {
+ this.cancelBubble = true;
+ }
+
+ /**
+ Adds an event handler to the specified object and store reference to the handler
+ in objects internal Plupload registry (@see removeEvent).
+
+ @method addEvent
+ @for Utils
+ @static
+ @param {Object} obj DOM element like object to add handler to.
+ @param {String} name Name to add event listener to.
+ @param {Function} callback Function to call when event occurs.
+ @param {String} [key] that might be used to add specifity to the event record.
+ */
+ var addEvent = function(obj, name, callback, key) {
+ var func, events;
+
+ name = name.toLowerCase();
+
+ // Add event listener
+ if (obj.addEventListener) {
+ func = callback;
+
+ obj.addEventListener(name, func, false);
+ } else if (obj.attachEvent) {
+ func = function() {
+ var evt = window.event;
+
+ if (!evt.target) {
+ evt.target = evt.srcElement;
+ }
+
+ evt.preventDefault = preventDefault;
+ evt.stopPropagation = stopPropagation;
+
+ callback(evt);
+ };
+
+ obj.attachEvent('on' + name, func);
+ }
+
+ // Log event handler to objects internal mOxie registry
+ if (!obj[uid]) {
+ obj[uid] = Basic.guid();
+ }
+
+ if (!eventhash.hasOwnProperty(obj[uid])) {
+ eventhash[obj[uid]] = {};
+ }
+
+ events = eventhash[obj[uid]];
+
+ if (!events.hasOwnProperty(name)) {
+ events[name] = [];
+ }
+
+ events[name].push({
+ func: func,
+ orig: callback, // store original callback for IE
+ key: key
+ });
+ };
+
+
+ /**
+ Remove event handler from the specified object. If third argument (callback)
+ is not specified remove all events with the specified name.
+
+ @method removeEvent
+ @static
+ @param {Object} obj DOM element to remove event listener(s) from.
+ @param {String} name Name of event listener to remove.
+ @param {Function|String} [callback] might be a callback or unique key to match.
+ */
+ var removeEvent = function(obj, name, callback) {
+ var type, undef;
+
+ name = name.toLowerCase();
+
+ if (obj[uid] && eventhash[obj[uid]] && eventhash[obj[uid]][name]) {
+ type = eventhash[obj[uid]][name];
+ } else {
+ return;
+ }
+
+ for (var i = type.length - 1; i >= 0; i--) {
+ // undefined or not, key should match
+ if (type[i].orig === callback || type[i].key === callback) {
+ if (obj.removeEventListener) {
+ obj.removeEventListener(name, type[i].func, false);
+ } else if (obj.detachEvent) {
+ obj.detachEvent('on'+name, type[i].func);
+ }
+
+ type[i].orig = null;
+ type[i].func = null;
+ type.splice(i, 1);
+
+ // If callback was passed we are done here, otherwise proceed
+ if (callback !== undef) {
+ break;
+ }
+ }
+ }
+
+ // If event array got empty, remove it
+ if (!type.length) {
+ delete eventhash[obj[uid]][name];
+ }
+
+ // If mOxie registry has become empty, remove it
+ if (Basic.isEmptyObj(eventhash[obj[uid]])) {
+ delete eventhash[obj[uid]];
+
+ // IE doesn't let you remove DOM object property with - delete
+ try {
+ delete obj[uid];
+ } catch(e) {
+ obj[uid] = undef;
+ }
+ }
+ };
+
+
+ /**
+ Remove all kind of events from the specified object
+
+ @method removeAllEvents
+ @static
+ @param {Object} obj DOM element to remove event listeners from.
+ @param {String} [key] unique key to match, when removing events.
+ */
+ var removeAllEvents = function(obj, key) {
+ if (!obj || !obj[uid]) {
+ return;
+ }
+
+ Basic.each(eventhash[obj[uid]], function(events, name) {
+ removeEvent(obj, name, key);
+ });
+ };
+
+ return {
+ addEvent: addEvent,
+ removeEvent: removeEvent,
+ removeAllEvents: removeAllEvents
+ };
+});
+
+// Included from: src/javascript/runtime/html4/file/FileInput.js
+
+/**
+ * FileInput.js
+ *
+ * Copyright 2013, Moxiecode Systems AB
+ * Released under GPL License.
+ *
+ * License: http://www.plupload.com/license
+ * Contributing: http://www.plupload.com/contributing
+ */
+
+/**
+@class moxie/runtime/html4/file/FileInput
+@private
+*/
+define("moxie/runtime/html4/file/FileInput", [
+ "moxie/runtime/html4/Runtime",
+ "moxie/core/utils/Basic",
+ "moxie/core/utils/Dom",
+ "moxie/core/utils/Events",
+ "moxie/core/utils/Mime",
+ "moxie/core/utils/Env"
+], function(extensions, Basic, Dom, Events, Mime, Env) {
+
+ function FileInput() {
+ var _uid, _files = [], _mimes = [], _options;
+
+ function addInput() {
+ var comp = this, I = comp.getRuntime(), shimContainer, browseButton, currForm, form, input, uid;
+
+ uid = Basic.guid('uid_');
+
+ shimContainer = I.getShimContainer(); // we get new ref everytime to avoid memory leaks in IE
+
+ if (_uid) { // move previous form out of the view
+ currForm = Dom.get(_uid + '_form');
+ if (currForm) {
+ Basic.extend(currForm.style, { top: '100%' });
+ }
+ }
+
+ // build form in DOM, since innerHTML version not able to submit file for some reason
+ form = document.createElement('form');
+ form.setAttribute('id', uid + '_form');
+ form.setAttribute('method', 'post');
+ form.setAttribute('enctype', 'multipart/form-data');
+ form.setAttribute('encoding', 'multipart/form-data');
+
+ Basic.extend(form.style, {
+ overflow: 'hidden',
+ position: 'absolute',
+ top: 0,
+ left: 0,
+ width: '100%',
+ height: '100%'
+ });
+
+ input = document.createElement('input');
+ input.setAttribute('id', uid);
+ input.setAttribute('type', 'file');
+ input.setAttribute('name', _options.name || 'Filedata');
+ input.setAttribute('accept', _mimes.join(','));
+
+ Basic.extend(input.style, {
+ fontSize: '999px',
+ opacity: 0
+ });
+
+ form.appendChild(input);
+ shimContainer.appendChild(form);
+
+ // prepare file input to be placed underneath the browse_button element
+ Basic.extend(input.style, {
+ position: 'absolute',
+ top: 0,
+ left: 0,
+ width: '100%',
+ height: '100%'
+ });
+
+ if (Env.browser === 'IE' && Env.version < 10) {
+ Basic.extend(input.style, {
+ filter : "progid:DXImageTransform.Microsoft.Alpha(opacity=0)"
+ });
+ }
+
+ input.onchange = function() { // there should be only one handler for this
+ var file;
+
+ if (!this.value) {
+ return;
+ }
+
+ if (this.files) {
+ file = this.files[0];
+ } else {
+ file = {
+ name: this.value
+ };
+ }
+
+ _files = [file];
+
+ this.onchange = function() {}; // clear event handler
+ addInput.call(comp);
+
+ // after file is initialized as o.File, we need to update form and input ids
+ comp.bind('change', function onChange() {
+ var input = Dom.get(uid), form = Dom.get(uid + '_form'), file;
+
+ comp.unbind('change', onChange);
+
+ if (comp.files.length && input && form) {
+ file = comp.files[0];
+
+ input.setAttribute('id', file.uid);
+ form.setAttribute('id', file.uid + '_form');
+
+ // set upload target
+ form.setAttribute('target', file.uid + '_iframe');
+ }
+ input = form = null;
+ }, 998);
+
+ input = form = null;
+ comp.trigger('change');
+ };
+
+
+ // route click event to the input
+ if (I.can('summon_file_dialog')) {
+ browseButton = Dom.get(_options.browse_button);
+ Events.removeEvent(browseButton, 'click', comp.uid);
+ Events.addEvent(browseButton, 'click', function(e) {
+ if (input && !input.disabled) { // for some reason FF (up to 8.0.1 so far) lets to click disabled input[type=file]
+ input.click();
+ }
+ e.preventDefault();
+ }, comp.uid);
+ }
+
+ _uid = uid;
+
+ shimContainer = currForm = browseButton = null;
+ }
+
+ Basic.extend(this, {
+ init: function(options) {
+ var comp = this, I = comp.getRuntime(), shimContainer;
+
+ // figure out accept string
+ _options = options;
+ _mimes = options.accept.mimes || Mime.extList2mimes(options.accept, I.can('filter_by_extension'));
+
+ shimContainer = I.getShimContainer();
+
+ (function() {
+ var browseButton, zIndex, top;
+
+ browseButton = Dom.get(options.browse_button);
+
+ // Route click event to the input[type=file] element for browsers that support such behavior
+ if (I.can('summon_file_dialog')) {
+ if (Dom.getStyle(browseButton, 'position') === 'static') {
+ browseButton.style.position = 'relative';
+ }
+
+ zIndex = parseInt(Dom.getStyle(browseButton, 'z-index'), 10) || 1;
+
+ browseButton.style.zIndex = zIndex;
+ shimContainer.style.zIndex = zIndex - 1;
+ }
+
+ /* Since we have to place input[type=file] on top of the browse_button for some browsers,
+ browse_button loses interactivity, so we restore it here */
+ top = I.can('summon_file_dialog') ? browseButton : shimContainer;
+
+ Events.addEvent(top, 'mouseover', function() {
+ comp.trigger('mouseenter');
+ }, comp.uid);
+
+ Events.addEvent(top, 'mouseout', function() {
+ comp.trigger('mouseleave');
+ }, comp.uid);
+
+ Events.addEvent(top, 'mousedown', function() {
+ comp.trigger('mousedown');
+ }, comp.uid);
+
+ Events.addEvent(Dom.get(options.container), 'mouseup', function() {
+ comp.trigger('mouseup');
+ }, comp.uid);
+
+ browseButton = null;
+ }());
+
+ addInput.call(this);
+
+ shimContainer = null;
+
+ // trigger ready event asynchronously
+ comp.trigger({
+ type: 'ready',
+ async: true
+ });
+ },
+
+ getFiles: function() {
+ return _files;
+ },
+
+ disable: function(state) {
+ var input;
+
+ if ((input = Dom.get(_uid))) {
+ input.disabled = !!state;
+ }
+ },
+
+ destroy: function() {
+ var I = this.getRuntime()
+ , shim = I.getShim()
+ , shimContainer = I.getShimContainer()
+ ;
+
+ Events.removeAllEvents(shimContainer, this.uid);
+ Events.removeAllEvents(_options && Dom.get(_options.container), this.uid);
+ Events.removeAllEvents(_options && Dom.get(_options.browse_button), this.uid);
+
+ if (shimContainer) {
+ shimContainer.innerHTML = '';
+ }
+
+ shim.removeInstance(this.uid);
+
+ _uid = _files = _mimes = _options = shimContainer = shim = null;
+ }
+ });
+ }
+
+ return (extensions.FileInput = FileInput);
+});
+
+// Included from: src/javascript/runtime/html5/Runtime.js
+
+/**
+ * Runtime.js
+ *
+ * Copyright 2013, Moxiecode Systems AB
+ * Released under GPL License.
+ *
+ * License: http://www.plupload.com/license
+ * Contributing: http://www.plupload.com/contributing
+ */
+
+/*global File:true */
+
+/**
+Defines constructor for HTML5 runtime.
+
+@class moxie/runtime/html5/Runtime
+@private
+*/
+define("moxie/runtime/html5/Runtime", [
+ "moxie/core/utils/Basic",
+ "moxie/core/Exceptions",
+ "moxie/runtime/Runtime",
+ "moxie/core/utils/Env"
+], function(Basic, x, Runtime, Env) {
+
+ var type = "html5", extensions = {};
+
+ function Html5Runtime(options) {
+ var I = this
+ , Test = Runtime.capTest
+ , True = Runtime.capTrue
+ ;
+
+ var caps = Basic.extend({
+ access_binary: Test(window.FileReader || window.File && window.File.getAsDataURL),
+ access_image_binary: function() {
+ return I.can('access_binary') && !!extensions.Image;
+ },
+ display_media: Test(Env.can('create_canvas') || Env.can('use_data_uri_over32kb')),
+ do_cors: Test(window.XMLHttpRequest && 'withCredentials' in new XMLHttpRequest()),
+ drag_and_drop: Test(function() {
+ // this comes directly from Modernizr: http://www.modernizr.com/
+ var div = document.createElement('div');
+ // IE has support for drag and drop since version 5, but doesn't support dropping files from desktop
+ return (('draggable' in div) || ('ondragstart' in div && 'ondrop' in div)) && (Env.browser !== 'IE' || Env.version > 9);
+ }()),
+ filter_by_extension: Test(function() { // if you know how to feature-detect this, please suggest
+ return (Env.browser === 'Chrome' && Env.version >= 28) || (Env.browser === 'IE' && Env.version >= 10);
+ }()),
+ return_response_headers: True,
+ return_response_type: function(responseType) {
+ if (responseType === 'json' && !!window.JSON) { // we can fake this one even if it's not supported
+ return true;
+ }
+ return Env.can('return_response_type', responseType);
+ },
+ return_status_code: True,
+ report_upload_progress: Test(window.XMLHttpRequest && new XMLHttpRequest().upload),
+ resize_image: function() {
+ return I.can('access_binary') && Env.can('create_canvas');
+ },
+ select_file: function() {
+ return Env.can('use_fileinput') && window.File;
+ },
+ select_folder: function() {
+ return I.can('select_file') && Env.browser === 'Chrome' && Env.version >= 21;
+ },
+ select_multiple: function() {
+ // it is buggy on Safari Windows and iOS
+ return I.can('select_file') &&
+ !(Env.browser === 'Safari' && Env.os === 'Windows') &&
+ !(Env.os === 'iOS' && Env.verComp(Env.osVersion, "7.0.4", '<'));
+ },
+ send_binary_string: Test(window.XMLHttpRequest && (new XMLHttpRequest().sendAsBinary || (window.Uint8Array && window.ArrayBuffer))),
+ send_custom_headers: Test(window.XMLHttpRequest),
+ send_multipart: function() {
+ return !!(window.XMLHttpRequest && new XMLHttpRequest().upload && window.FormData) || I.can('send_binary_string');
+ },
+ slice_blob: Test(window.File && (File.prototype.mozSlice || File.prototype.webkitSlice || File.prototype.slice)),
+ stream_upload: function(){
+ return I.can('slice_blob') && I.can('send_multipart');
+ },
+ summon_file_dialog: Test(function() { // yeah... some dirty sniffing here...
+ return (Env.browser === 'Firefox' && Env.version >= 4) ||
+ (Env.browser === 'Opera' && Env.version >= 12) ||
+ (Env.browser === 'IE' && Env.version >= 10) ||
+ !!~Basic.inArray(Env.browser, ['Chrome', 'Safari']);
+ }()),
+ upload_filesize: True
+ },
+ arguments[2]
+ );
+
+ Runtime.call(this, options, (arguments[1] || type), caps);
+
+
+ Basic.extend(this, {
+
+ init : function() {
+ this.trigger("Init");
+ },
+
+ destroy: (function(destroy) { // extend default destroy method
+ return function() {
+ destroy.call(I);
+ destroy = I = null;
+ };
+ }(this.destroy))
+ });
+
+ Basic.extend(this.getShim(), extensions);
+ }
+
+ Runtime.addConstructor(type, Html5Runtime);
+
+ return extensions;
+});
+
+// Included from: src/javascript/runtime/html5/file/FileReader.js
+
+/**
+ * FileReader.js
+ *
+ * Copyright 2013, Moxiecode Systems AB
+ * Released under GPL License.
+ *
+ * License: http://www.plupload.com/license
+ * Contributing: http://www.plupload.com/contributing
+ */
+
+/**
+@class moxie/runtime/html5/file/FileReader
+@private
+*/
+define("moxie/runtime/html5/file/FileReader", [
+ "moxie/runtime/html5/Runtime",
+ "moxie/core/utils/Encode",
+ "moxie/core/utils/Basic"
+], function(extensions, Encode, Basic) {
+
+ function FileReader() {
+ var _fr, _convertToBinary = false;
+
+ Basic.extend(this, {
+
+ read: function(op, blob) {
+ var target = this;
+
+ _fr = new window.FileReader();
+
+ _fr.addEventListener('progress', function(e) {
+ target.trigger(e);
+ });
+
+ _fr.addEventListener('load', function(e) {
+ target.trigger(e);
+ });
+
+ _fr.addEventListener('error', function(e) {
+ target.trigger(e, _fr.error);
+ });
+
+ _fr.addEventListener('loadend', function() {
+ _fr = null;
+ });
+
+ if (Basic.typeOf(_fr[op]) === 'function') {
+ _convertToBinary = false;
+ _fr[op](blob.getSource());
+ } else if (op === 'readAsBinaryString') { // readAsBinaryString is depricated in general and never existed in IE10+
+ _convertToBinary = true;
+ _fr.readAsDataURL(blob.getSource());
+ }
+ },
+
+ getResult: function() {
+ return _fr && _fr.result ? (_convertToBinary ? _toBinary(_fr.result) : _fr.result) : null;
+ },
+
+ abort: function() {
+ if (_fr) {
+ _fr.abort();
+ }
+ },
+
+ destroy: function() {
+ _fr = null;
+ }
+ });
+
+ function _toBinary(str) {
+ return Encode.atob(str.substring(str.indexOf('base64,') + 7));
+ }
+ }
+
+ return (extensions.FileReader = FileReader);
+});
+
+// Included from: src/javascript/runtime/html4/file/FileReader.js
+
+/**
+ * FileReader.js
+ *
+ * Copyright 2013, Moxiecode Systems AB
+ * Released under GPL License.
+ *
+ * License: http://www.plupload.com/license
+ * Contributing: http://www.plupload.com/contributing
+ */
+
+/**
+@class moxie/runtime/html4/file/FileReader
+@private
+*/
+define("moxie/runtime/html4/file/FileReader", [
+ "moxie/runtime/html4/Runtime",
+ "moxie/runtime/html5/file/FileReader"
+], function(extensions, FileReader) {
+ return (extensions.FileReader = FileReader);
+});
+
+// Included from: src/javascript/runtime/html4/xhr/XMLHttpRequest.js
+
+/**
+ * XMLHttpRequest.js
+ *
+ * Copyright 2013, Moxiecode Systems AB
+ * Released under GPL License.
+ *
+ * License: http://www.plupload.com/license
+ * Contributing: http://www.plupload.com/contributing
+ */
+
+/**
+@class moxie/runtime/html4/xhr/XMLHttpRequest
+@private
+*/
+define("moxie/runtime/html4/xhr/XMLHttpRequest", [
+ "moxie/runtime/html4/Runtime",
+ "moxie/core/utils/Basic",
+ "moxie/core/utils/Dom",
+ "moxie/core/utils/Url",
+ "moxie/core/Exceptions",
+ "moxie/core/utils/Events",
+ "moxie/file/Blob",
+ "moxie/xhr/FormData"
+], function(extensions, Basic, Dom, Url, x, Events, Blob, FormData) {
+
+ function XMLHttpRequest() {
+ var _status, _response, _iframe;
+
+ function cleanup(cb) {
+ var target = this, uid, form, inputs, i, hasFile = false;
+
+ if (!_iframe) {
+ return;
+ }
+
+ uid = _iframe.id.replace(/_iframe$/, '');
+
+ form = Dom.get(uid + '_form');
+ if (form) {
+ inputs = form.getElementsByTagName('input');
+ i = inputs.length;
+
+ while (i--) {
+ switch (inputs[i].getAttribute('type')) {
+ case 'hidden':
+ inputs[i].parentNode.removeChild(inputs[i]);
+ break;
+ case 'file':
+ hasFile = true; // flag the case for later
+ break;
+ }
+ }
+ inputs = [];
+
+ if (!hasFile) { // we need to keep the form for sake of possible retries
+ form.parentNode.removeChild(form);
+ }
+ form = null;
+ }
+
+ // without timeout, request is marked as canceled (in console)
+ setTimeout(function() {
+ Events.removeEvent(_iframe, 'load', target.uid);
+ if (_iframe.parentNode) { // #382
+ _iframe.parentNode.removeChild(_iframe);
+ }
+
+ // check if shim container has any other children, if - not, remove it as well
+ var shimContainer = target.getRuntime().getShimContainer();
+ if (!shimContainer.children.length) {
+ shimContainer.parentNode.removeChild(shimContainer);
+ }
+
+ shimContainer = _iframe = null;
+ cb();
+ }, 1);
+ }
+
+ Basic.extend(this, {
+ send: function(meta, data) {
+ var target = this, I = target.getRuntime(), uid, form, input, blob;
+
+ _status = _response = null;
+
+ function createIframe() {
+ var container = I.getShimContainer() || document.body
+ , temp = document.createElement('div')
+ ;
+
+ // IE 6 won't be able to set the name using setAttribute or iframe.name
+ temp.innerHTML = '';
+ _iframe = temp.firstChild;
+ container.appendChild(_iframe);
+
+ /* _iframe.onreadystatechange = function() {
+ console.info(_iframe.readyState);
+ };*/
+
+ Events.addEvent(_iframe, 'load', function() { // _iframe.onload doesn't work in IE lte 8
+ var el;
+
+ try {
+ el = _iframe.contentWindow.document || _iframe.contentDocument || window.frames[_iframe.id].document;
+
+ // try to detect some standard error pages
+ if (/^4(0[0-9]|1[0-7]|2[2346])\s/.test(el.title)) { // test if title starts with 4xx HTTP error
+ _status = el.title.replace(/^(\d+).*$/, '$1');
+ } else {
+ _status = 200;
+ // get result
+ _response = Basic.trim(el.body.innerHTML);
+
+ // we need to fire these at least once
+ target.trigger({
+ type: 'progress',
+ loaded: _response.length,
+ total: _response.length
+ });
+
+ if (blob) { // if we were uploading a file
+ target.trigger({
+ type: 'uploadprogress',
+ loaded: blob.size || 1025,
+ total: blob.size || 1025
+ });
+ }
+ }
+ } catch (ex) {
+ if (Url.hasSameOrigin(meta.url)) {
+ // if response is sent with error code, iframe in IE gets redirected to res://ieframe.dll/http_x.htm
+ // which obviously results to cross domain error (wtf?)
+ _status = 404;
+ } else {
+ cleanup.call(target, function() {
+ target.trigger('error');
+ });
+ return;
+ }
+ }
+
+ cleanup.call(target, function() {
+ target.trigger('load');
+ });
+ }, target.uid);
+ } // end createIframe
+
+ // prepare data to be sent and convert if required
+ if (data instanceof FormData && data.hasBlob()) {
+ blob = data.getBlob();
+ uid = blob.uid;
+ input = Dom.get(uid);
+ form = Dom.get(uid + '_form');
+ if (!form) {
+ throw new x.DOMException(x.DOMException.NOT_FOUND_ERR);
+ }
+ } else {
+ uid = Basic.guid('uid_');
+
+ form = document.createElement('form');
+ form.setAttribute('id', uid + '_form');
+ form.setAttribute('method', meta.method);
+ form.setAttribute('enctype', 'multipart/form-data');
+ form.setAttribute('encoding', 'multipart/form-data');
+ form.setAttribute('target', uid + '_iframe');
+
+ I.getShimContainer().appendChild(form);
+ }
+
+ if (data instanceof FormData) {
+ data.each(function(value, name) {
+ if (value instanceof Blob) {
+ if (input) {
+ input.setAttribute('name', name);
+ }
+ } else {
+ var hidden = document.createElement('input');
+
+ Basic.extend(hidden, {
+ type : 'hidden',
+ name : name,
+ value : value
+ });
+
+ // make sure that input[type="file"], if it's there, comes last
+ if (input) {
+ form.insertBefore(hidden, input);
+ } else {
+ form.appendChild(hidden);
+ }
+ }
+ });
+ }
+
+ // set destination url
+ form.setAttribute("action", meta.url);
+
+ createIframe();
+ form.submit();
+ target.trigger('loadstart');
+ },
+
+ getStatus: function() {
+ return _status;
+ },
+
+ getResponse: function(responseType) {
+ if ('json' === responseType) {
+ // strip off ..
tags that might be enclosing the response
+ if (Basic.typeOf(_response) === 'string' && !!window.JSON) {
+ try {
+ return JSON.parse(_response.replace(/^\s*]*>/, '').replace(/<\/pre>\s*$/, ''));
+ } catch (ex) {
+ return null;
+ }
+ }
+ } else if ('document' === responseType) {
+
+ }
+ return _response;
+ },
+
+ abort: function() {
+ var target = this;
+
+ if (_iframe && _iframe.contentWindow) {
+ if (_iframe.contentWindow.stop) { // FireFox/Safari/Chrome
+ _iframe.contentWindow.stop();
+ } else if (_iframe.contentWindow.document.execCommand) { // IE
+ _iframe.contentWindow.document.execCommand('Stop');
+ } else {
+ _iframe.src = "about:blank";
+ }
+ }
+
+ cleanup.call(this, function() {
+ // target.dispatchEvent('readystatechange');
+ target.dispatchEvent('abort');
+ });
+ }
+ });
+ }
+
+ return (extensions.XMLHttpRequest = XMLHttpRequest);
+});
+
+// Included from: src/javascript/runtime/silverlight/Runtime.js
+
+/**
+ * RunTime.js
+ *
+ * Copyright 2013, Moxiecode Systems AB
+ * Released under GPL License.
+ *
+ * License: http://www.plupload.com/license
+ * Contributing: http://www.plupload.com/contributing
+ */
+
+/*global ActiveXObject:true */
+
+/**
+Defines constructor for Silverlight runtime.
+
+@class moxie/runtime/silverlight/Runtime
+@private
+*/
+define("moxie/runtime/silverlight/Runtime", [
+ "moxie/core/utils/Basic",
+ "moxie/core/utils/Env",
+ "moxie/core/utils/Dom",
+ "moxie/core/Exceptions",
+ "moxie/runtime/Runtime"
+], function(Basic, Env, Dom, x, Runtime) {
+
+ var type = "silverlight", extensions = {};
+
+ function isInstalled(version) {
+ var isVersionSupported = false, control = null, actualVer,
+ actualVerArray, reqVerArray, requiredVersionPart, actualVersionPart, index = 0;
+
+ try {
+ try {
+ control = new ActiveXObject('AgControl.AgControl');
+
+ if (control.IsVersionSupported(version)) {
+ isVersionSupported = true;
+ }
+
+ control = null;
+ } catch (e) {
+ var plugin = navigator.plugins["Silverlight Plug-In"];
+
+ if (plugin) {
+ actualVer = plugin.description;
+
+ if (actualVer === "1.0.30226.2") {
+ actualVer = "2.0.30226.2";
+ }
+
+ actualVerArray = actualVer.split(".");
+
+ while (actualVerArray.length > 3) {
+ actualVerArray.pop();
+ }
+
+ while ( actualVerArray.length < 4) {
+ actualVerArray.push(0);
+ }
+
+ reqVerArray = version.split(".");
+
+ while (reqVerArray.length > 4) {
+ reqVerArray.pop();
+ }
+
+ do {
+ requiredVersionPart = parseInt(reqVerArray[index], 10);
+ actualVersionPart = parseInt(actualVerArray[index], 10);
+ index++;
+ } while (index < reqVerArray.length && requiredVersionPart === actualVersionPart);
+
+ if (requiredVersionPart <= actualVersionPart && !isNaN(requiredVersionPart)) {
+ isVersionSupported = true;
+ }
+ }
+ }
+ } catch (e2) {
+ isVersionSupported = false;
+ }
+
+ return isVersionSupported;
+ }
+
+ /**
+ Constructor for the Silverlight Runtime
+
+ @class SilverlightRuntime
+ @extends Runtime
+ */
+ function SilverlightRuntime(options) {
+ var I = this, initTimer;
+
+ options = Basic.extend({ xap_url: Env.xap_url }, options);
+
+ Runtime.call(this, options, type, {
+ access_binary: Runtime.capTrue,
+ access_image_binary: Runtime.capTrue,
+ display_media: Runtime.capTrue,
+ do_cors: Runtime.capTrue,
+ drag_and_drop: false,
+ report_upload_progress: Runtime.capTrue,
+ resize_image: Runtime.capTrue,
+ return_response_headers: function(value) {
+ return value && I.mode === 'client';
+ },
+ return_response_type: function(responseType) {
+ if (responseType !== 'json') {
+ return true;
+ } else {
+ return !!window.JSON;
+ }
+ },
+ return_status_code: function(code) {
+ return I.mode === 'client' || !Basic.arrayDiff(code, [200, 404]);
+ },
+ select_file: Runtime.capTrue,
+ select_multiple: Runtime.capTrue,
+ send_binary_string: Runtime.capTrue,
+ send_browser_cookies: function(value) {
+ return value && I.mode === 'browser';
+ },
+ send_custom_headers: function(value) {
+ return value && I.mode === 'client';
+ },
+ send_multipart: Runtime.capTrue,
+ slice_blob: Runtime.capTrue,
+ stream_upload: true,
+ summon_file_dialog: false,
+ upload_filesize: Runtime.capTrue,
+ use_http_method: function(methods) {
+ return I.mode === 'client' || !Basic.arrayDiff(methods, ['GET', 'POST']);
+ }
+ }, {
+ // capabilities that require specific mode
+ return_response_headers: function(value) {
+ return value ? 'client' : 'browser';
+ },
+ return_status_code: function(code) {
+ return Basic.arrayDiff(code, [200, 404]) ? 'client' : ['client', 'browser'];
+ },
+ send_browser_cookies: function(value) {
+ return value ? 'browser' : 'client';
+ },
+ send_custom_headers: function(value) {
+ return value ? 'client' : 'browser';
+ },
+ use_http_method: function(methods) {
+ return Basic.arrayDiff(methods, ['GET', 'POST']) ? 'client' : ['client', 'browser'];
+ }
+ });
+
+
+ // minimal requirement
+ if (!isInstalled('2.0.31005.0') || Env.browser === 'Opera') {
+ this.mode = false;
+ }
+
+
+ Basic.extend(this, {
+ getShim: function() {
+ return Dom.get(this.uid).content.Moxie;
+ },
+
+ shimExec: function(component, action) {
+ var args = [].slice.call(arguments, 2);
+ return I.getShim().exec(this.uid, component, action, args);
+ },
+
+ init : function() {
+ var container;
+
+ container = this.getShimContainer();
+
+ container.innerHTML = '';
+
+ // Init is dispatched by the shim
+ initTimer = setTimeout(function() {
+ if (I && !I.initialized) { // runtime might be already destroyed by this moment
+ I.trigger("Error", new x.RuntimeError(x.RuntimeError.NOT_INIT_ERR));
+ }
+ }, Env.OS !== 'Windows'? 10000 : 5000); // give it more time to initialize in non Windows OS (like Mac)
+ },
+
+ destroy: (function(destroy) { // extend default destroy method
+ return function() {
+ destroy.call(I);
+ clearTimeout(initTimer); // initialization check might be still onwait
+ options = initTimer = destroy = I = null;
+ };
+ }(this.destroy))
+
+ }, extensions);
+ }
+
+ Runtime.addConstructor(type, SilverlightRuntime);
+
+ return extensions;
+});
+
+// Included from: src/javascript/runtime/silverlight/file/Blob.js
+
+/**
+ * Blob.js
+ *
+ * Copyright 2013, Moxiecode Systems AB
+ * Released under GPL License.
+ *
+ * License: http://www.plupload.com/license
+ * Contributing: http://www.plupload.com/contributing
+ */
+
+/**
+@class moxie/runtime/silverlight/file/Blob
+@private
+*/
+define("moxie/runtime/silverlight/file/Blob", [
+ "moxie/runtime/silverlight/Runtime",
+ "moxie/core/utils/Basic",
+ "moxie/runtime/flash/file/Blob"
+], function(extensions, Basic, Blob) {
+ return (extensions.Blob = Basic.extend({}, Blob));
+});
+
+// Included from: src/javascript/runtime/silverlight/file/FileInput.js
+
+/**
+ * FileInput.js
+ *
+ * Copyright 2013, Moxiecode Systems AB
+ * Released under GPL License.
+ *
+ * License: http://www.plupload.com/license
+ * Contributing: http://www.plupload.com/contributing
+ */
+
+/**
+@class moxie/runtime/silverlight/file/FileInput
+@private
+*/
+define("moxie/runtime/silverlight/file/FileInput", [
+ "moxie/runtime/silverlight/Runtime"
+], function(extensions) {
+
+ var FileInput = {
+ init: function(options) {
+
+ function toFilters(accept) {
+ var filter = '';
+ for (var i = 0; i < accept.length; i++) {
+ filter += (filter !== '' ? '|' : '') + accept[i].title + " | *." + accept[i].extensions.replace(/,/g, ';*.');
+ }
+ return filter;
+ }
+
+ this.getRuntime().shimExec.call(this, 'FileInput', 'init', toFilters(options.accept), options.name, options.multiple);
+ this.trigger('ready');
+ }
+ };
+
+ return (extensions.FileInput = FileInput);
+});
+
+// Included from: src/javascript/runtime/silverlight/file/FileReader.js
+
+/**
+ * FileReader.js
+ *
+ * Copyright 2013, Moxiecode Systems AB
+ * Released under GPL License.
+ *
+ * License: http://www.plupload.com/license
+ * Contributing: http://www.plupload.com/contributing
+ */
+
+/**
+@class moxie/runtime/silverlight/file/FileReader
+@private
+*/
+define("moxie/runtime/silverlight/file/FileReader", [
+ "moxie/runtime/silverlight/Runtime",
+ "moxie/core/utils/Basic",
+ "moxie/runtime/flash/file/FileReader"
+], function(extensions, Basic, FileReader) {
+ return (extensions.FileReader = Basic.extend({}, FileReader));
+});
+
+// Included from: src/javascript/runtime/silverlight/file/FileReaderSync.js
+
+/**
+ * FileReaderSync.js
+ *
+ * Copyright 2013, Moxiecode Systems AB
+ * Released under GPL License.
+ *
+ * License: http://www.plupload.com/license
+ * Contributing: http://www.plupload.com/contributing
+ */
+
+/**
+@class moxie/runtime/silverlight/file/FileReaderSync
+@private
+*/
+define("moxie/runtime/silverlight/file/FileReaderSync", [
+ "moxie/runtime/silverlight/Runtime",
+ "moxie/core/utils/Basic",
+ "moxie/runtime/flash/file/FileReaderSync"
+], function(extensions, Basic, FileReaderSync) {
+ return (extensions.FileReaderSync = Basic.extend({}, FileReaderSync));
+});
+
+// Included from: src/javascript/runtime/silverlight/xhr/XMLHttpRequest.js
+
+/**
+ * XMLHttpRequest.js
+ *
+ * Copyright 2013, Moxiecode Systems AB
+ * Released under GPL License.
+ *
+ * License: http://www.plupload.com/license
+ * Contributing: http://www.plupload.com/contributing
+ */
+
+/**
+@class moxie/runtime/silverlight/xhr/XMLHttpRequest
+@private
+*/
+define("moxie/runtime/silverlight/xhr/XMLHttpRequest", [
+ "moxie/runtime/silverlight/Runtime",
+ "moxie/core/utils/Basic",
+ "moxie/runtime/flash/xhr/XMLHttpRequest"
+], function(extensions, Basic, XMLHttpRequest) {
+ return (extensions.XMLHttpRequest = Basic.extend({}, XMLHttpRequest));
+});
+
+expose(["moxie/core/utils/Basic","moxie/core/I18n","moxie/core/utils/Mime","moxie/core/utils/Env","moxie/core/utils/Dom","moxie/core/Exceptions","moxie/core/EventTarget","moxie/core/utils/Encode","moxie/runtime/Runtime","moxie/runtime/RuntimeClient","moxie/file/Blob","moxie/file/File","moxie/file/FileInput","moxie/runtime/RuntimeTarget","moxie/file/FileReader","moxie/core/utils/Url","moxie/file/FileReaderSync","moxie/xhr/FormData","moxie/xhr/XMLHttpRequest","moxie/runtime/Transporter","moxie/core/utils/Events"]);
+})(this);/**
+ * o.js
+ *
+ * Copyright 2013, Moxiecode Systems AB
+ * Released under GPL License.
+ *
+ * License: http://www.plupload.com/license
+ * Contributing: http://www.plupload.com/contributing
+ */
+
+/*global moxie:true */
+
+/**
+Globally exposed namespace with the most frequently used public classes and handy methods.
+
+@class o
+@static
+@private
+*/
+(function(exports) {
+ "use strict";
+
+ var o = {}, inArray = exports.moxie.core.utils.Basic.inArray;
+
+ // directly add some public classes
+ // (we do it dynamically here, since for custom builds we cannot know beforehand what modules were included)
+ (function addAlias(ns) {
+ var name, itemType;
+ for (name in ns) {
+ itemType = typeof(ns[name]);
+ if (itemType === 'object' && !~inArray(name, ['Exceptions', 'Env', 'Mime'])) {
+ addAlias(ns[name]);
+ } else if (itemType === 'function') {
+ o[name] = ns[name];
+ }
+ }
+ })(exports.moxie);
+
+ // add some manually
+ o.Env = exports.moxie.core.utils.Env;
+ o.Mime = exports.moxie.core.utils.Mime;
+ o.Exceptions = exports.moxie.core.Exceptions;
+
+ // expose globally
+ exports.mOxie = o;
+ if (!exports.o) {
+ exports.o = o;
+ }
+ return o;
+})(this);
diff --git a/public/webshims/shims/moxie/silverlight/Moxie.cdn.xap b/public/webshims/shims/moxie/silverlight/Moxie.cdn.xap
new file mode 100644
index 00000000..f0d499f9
Binary files /dev/null and b/public/webshims/shims/moxie/silverlight/Moxie.cdn.xap differ
diff --git a/public/webshims/shims/moxie/silverlight/Moxie.min.xap b/public/webshims/shims/moxie/silverlight/Moxie.min.xap
new file mode 100644
index 00000000..40b12c2b
Binary files /dev/null and b/public/webshims/shims/moxie/silverlight/Moxie.min.xap differ
diff --git a/public/webshims/shims/picture.js b/public/webshims/shims/picture.js
new file mode 100644
index 00000000..458c4e2c
--- /dev/null
+++ b/public/webshims/shims/picture.js
@@ -0,0 +1,617 @@
+(function(){
+ "use strict";
+ try {
+ new Image();
+ } catch(e){
+ window.Image = function(){
+ return document.createElement('img');
+ };
+ }
+
+ webshim.isReady('picture', true);
+ setTimeout(function(){
+ webshim.ready('matchMedia', function(){
+ if(window.picturefill){
+ var sel = 'picture, img[srcset]';
+ webshim.addReady(function(context){
+ if(context.querySelector(sel)){
+ window.picturefill();
+ }
+ });
+ }
+ });
+ });
+})();
+
+/*! Picturefill - v2.1.0-beta - 2014-06-03
+ * http://scottjehl.github.io/picturefill
+ * Copyright (c) 2014 https://github.com/scottjehl/picturefill/blob/master/Authors.txt; Licensed MIT */
+
+/*! Picturefill - Responsive Images that work today.
+ * Author: Scott Jehl, Filament Group, 2012 ( new proposal implemented by Shawn Jansepar )
+ * License: MIT/GPLv2
+ * Spec: http://picture.responsiveimages.org/
+ */
+(function( w, doc ) {
+ // Enable strict mode
+ "use strict";
+
+ // If picture is supported, well, that's awesome. Let's get outta here...
+ if ( w.HTMLPictureElement ) {
+ return;
+ }
+
+ // HTML shim|v it for old IE (IE9 will still need the HTML video tag workaround)
+ doc.createElement( "picture" );
+
+ // local object for method references and testing exposure
+ var pf = {};
+
+ // namespace
+ pf.ns = "picturefill";
+
+ // srcset support test
+ pf.srcsetSupported = new w.Image().srcset !== undefined;
+
+ // just a string trim workaround
+ pf.trim = function( str ) {
+ return str.trim ? str.trim() : str.replace( /^\s+|\s+$/g, "" );
+ };
+
+ // just a string endsWith workaround
+ pf.endsWith = function( str, suffix ) {
+ return str.endsWith ? str.endsWith( suffix ) : str.indexOf( suffix, str.length - suffix.length ) !== -1;
+ };
+
+ /**
+ * Shortcut method for matchMedia ( for easy overriding in tests )
+ */
+ pf.matchesMedia = function( media ) {
+ return w.matchMedia && w.matchMedia( media ).matches;
+ };
+
+ /**
+ * Shortcut method for `devicePixelRatio` ( for easy overriding in tests )
+ */
+ pf.getDpr = function() {
+ return ( w.devicePixelRatio || 1 );
+ };
+
+ /**
+ * Get width in css pixel value from a "length" value
+ * http://dev.w3.org/csswg/css-values-3/#length-value
+ */
+ pf.getWidthFromLength = function( length ) {
+ // If no length was specified, or it is 0, default to `100vw` (per the spec).
+ length = length && parseFloat( length ) > 0 ? length : "100vw";
+
+ /**
+ * If length is specified in `vw` units, use `%` instead since the div we’re measuring
+ * is injected at the top of the document.
+ *
+ * TODO: maybe we should put this behind a feature test for `vw`?
+ */
+ length = length.replace( "vw", "%" );
+
+ // Create a cached element for getting length value widths
+ if ( !pf.lengthEl ) {
+ pf.lengthEl = doc.createElement( "div" );
+ doc.documentElement.insertBefore( pf.lengthEl, doc.documentElement.firstChild );
+ }
+
+ // Positioning styles help prevent padding/margin/width on `html` from throwing calculations off.
+ pf.lengthEl.style.cssText = "position: absolute; left: 0; width: " + length + ";";
+ // Using offsetWidth to get width from CSS
+ return pf.lengthEl.offsetWidth;
+ };
+
+ // container of supported mime types that one might need to qualify before using
+ pf.types = {};
+
+ // Add support for standard mime types.
+ pf.types["image/jpeg"] = true;
+ pf.types["image/gif"] = true;
+ pf.types["image/png"] = true;
+
+ // test svg support
+ pf.types[ "image/svg+xml" ] = doc.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#Image", "1.1");
+
+ // test webp support, only when the markup calls for it
+ pf.types[ "image/webp" ] = function() {
+ // based on Modernizr's lossless img-webp test
+ // note: asynchronous
+ var img = new w.Image(),
+ type = "image/webp";
+
+ img.onerror = function() {
+ pf.types[ type ] = false;
+ picturefill();
+ };
+ img.onload = function() {
+ pf.types[ type ] = img.width === 1;
+ picturefill();
+ };
+ img.src = "data:image/webp;base64,UklGRh4AAABXRUJQVlA4TBEAAAAvAAAAAAfQ//73v/+BiOh/AAA=";
+ };
+
+ /**
+ * Takes a source element and checks if its type attribute is present and if so, supported
+ * Note: for type tests that require a async logic,
+ * you can define them as a function that'll run only if that type needs to be tested. Just make the test function call picturefill again when it is complete.
+ * see the async webp test above for example
+ */
+ pf.verifyTypeSupport = function( source ) {
+ var type = source.getAttribute( "type" );
+ // if type attribute exists, return test result, otherwise return true
+ if ( type === null || type === "" ) {
+ return true;
+ } else {
+ // if the type test is a function, run it and return "pending" status. The function will rerun picturefill on pending elements once finished.
+ if ( typeof( pf.types[ type ] ) === "function" ) {
+ pf.types[ type ]();
+ return "pending";
+ } else {
+ return pf.types[ type ];
+ }
+ }
+ };
+
+ /**
+ * Parses an individual `size` and returns the length, and optional media query
+ */
+ pf.parseSize = function( sourceSizeStr ) {
+ var match = /(\([^)]+\))?\s*(.+)/g.exec( sourceSizeStr );
+ return {
+ media: match && match[1],
+ length: match && match[2]
+ };
+ };
+
+ /**
+ * Takes a string of sizes and returns the width in pixels as a number
+ */
+ pf.findWidthFromSourceSize = function( sourceSizeListStr ) {
+ // Split up source size list, ie ( max-width: 30em ) 100%, ( max-width: 50em ) 50%, 33%
+ // or (min-width:30em) calc(30% - 15px)
+ var sourceSizeList = pf.trim( sourceSizeListStr ).split( /\s*,\s*/ ),
+ winningLength;
+
+ for ( var i = 0, len = sourceSizeList.length; i < len; i++ ) {
+ // Match ? length, ie ( min-width: 50em ) 100%
+ var sourceSize = sourceSizeList[ i ],
+ // Split "( min-width: 50em ) 100%" into separate strings
+ parsedSize = pf.parseSize( sourceSize ),
+ length = parsedSize.length,
+ media = parsedSize.media;
+
+ if ( !length ) {
+ continue;
+ }
+ if ( !media || pf.matchesMedia( media ) ) {
+ // if there is no media query or it matches, choose this as our winning length
+ // and end algorithm
+ winningLength = length;
+ break;
+ }
+ }
+
+ // pass the length to a method that can properly determine length
+ // in pixels based on these formats: http://dev.w3.org/csswg/css-values-3/#length-value
+ return pf.getWidthFromLength( winningLength );
+ };
+
+ pf.parseSrcset = function( srcset ) {
+ /**
+ * A lot of this was pulled from Boris Smus’ parser for the now-defunct WHATWG `srcset`
+ * https://github.com/borismus/srcset-polyfill/blob/master/js/srcset-info.js
+ *
+ * 1. Let input (`srcset`) be the value passed to this algorithm.
+ * 2. Let position be a pointer into input, initially pointing at the start of the string.
+ * 3. Let raw candidates be an initially empty ordered list of URLs with associated
+ * unparsed descriptors. The order of entries in the list is the order in which entries
+ * are added to the list.
+ */
+ var candidates = [];
+
+ while ( srcset !== "" ) {
+ srcset = srcset.replace(/^\s+/g,"");
+
+ // 5. Collect a sequence of characters that are not space characters, and let that be url.
+ var pos = srcset.search(/\s/g),
+ url, descriptor = null;
+
+ if ( pos !== -1 ) {
+ url = srcset.slice( 0, pos );
+
+ var last = url[ url.length - 1 ];
+
+ // 6. If url ends with a U+002C COMMA character (,), remove that character from url
+ // and let descriptors be the empty string. Otherwise, follow these substeps
+ // 6.1. If url is empty, then jump to the step labeled descriptor parser.
+
+ if ( last === "," || url === "" ) {
+ url = url.replace(/,+$/, "");
+ descriptor = "";
+ }
+ srcset = srcset.slice( pos + 1 );
+
+ // 6.2. Collect a sequence of characters that are not U+002C COMMA characters (,), and
+ // let that be descriptors.
+ if ( descriptor === null ) {
+ var descpos = srcset.indexOf(",");
+ if ( descpos !== -1 ) {
+ descriptor = srcset.slice( 0, descpos );
+ srcset = srcset.slice( descpos + 1 );
+ } else {
+ descriptor = srcset;
+ srcset = "";
+ }
+ }
+ } else {
+ url = srcset;
+ srcset = "";
+ }
+
+ // 7. Add url to raw candidates, associated with descriptors.
+ if ( url || descriptor ) {
+ candidates.push({
+ url: url,
+ descriptor: descriptor
+ });
+ }
+ }
+ return candidates;
+ };
+
+ pf.parseDescriptor = function( descriptor, sizes ) {
+ // 11. Descriptor parser: Let candidates be an initially empty source set. The order of entries in the list
+ // is the order in which entries are added to the list.
+ var sizeDescriptor = descriptor && descriptor.replace(/(^\s+|\s+$)/g, ""),
+ widthInCssPixels = sizes ? pf.findWidthFromSourceSize( sizes ) : "100%",
+ resCandidate;
+
+ if ( sizeDescriptor ) {
+ var splitDescriptor = sizeDescriptor.split(" ");
+
+ for (var i = splitDescriptor.length + 1; i >= 0; i--) {
+
+ var curr = splitDescriptor[ i ],
+ lastchar = curr && curr.slice( curr.length - 1 );
+
+ if ( lastchar === "w" || lastchar === "x" ) {
+ resCandidate = curr;
+ }
+ if ( sizes && resCandidate ) {
+ // get the dpr by taking the length / width in css pixels
+ resCandidate = parseFloat( ( parseInt( curr, 10 ) / widthInCssPixels ) );
+ } else {
+ // get the dpr by grabbing the value of Nx
+ var res = curr && parseFloat( curr, 10 );
+
+ resCandidate = res && !isNaN( res ) && lastchar === "x" || lastchar === "w" ? res : 1;
+ }
+ }
+ } else {
+ resCandidate = 1;
+ }
+ return resCandidate;
+ };
+
+ /**
+ * Takes a srcset in the form of url/
+ * ex. "images/pic-medium.png 1x, images/pic-medium-2x.png 2x" or
+ * "images/pic-medium.png 400w, images/pic-medium-2x.png 800w" or
+ * "images/pic-small.png"
+ * Get an array of image candidates in the form of
+ * {url: "/foo/bar.png", resolution: 1}
+ * where resolution is http://dev.w3.org/csswg/css-values-3/#resolution-value
+ * If sizes is specified, resolution is calculated
+ */
+ pf.getCandidatesFromSourceSet = function( srcset, sizes ) {
+ var candidates = pf.parseSrcset( srcset ),
+ formattedCandidates = [];
+
+ for ( var i = 0, len = candidates.length; i < len; i++ ) {
+ var candidate = candidates[ i ];
+
+ formattedCandidates.push({
+ url: candidate.url,
+ resolution: pf.parseDescriptor( candidate.descriptor, sizes )
+ });
+ }
+ return formattedCandidates;
+ };
+
+ /*
+ * if it's an img element and it has a srcset property,
+ * we need to remove the attribute so we can manipulate src
+ * (the property's existence infers native srcset support, and a srcset-supporting browser will prioritize srcset's value over our winning picture candidate)
+ * this moves srcset's value to memory for later use and removes the attr
+ */
+ pf.dodgeSrcset = function( img ) {
+ if ( img.srcset ) {
+ img[ pf.ns ].srcset = img.srcset;
+ img.removeAttribute( "srcset" );
+ }
+ };
+
+ /*
+ * Accept a source or img element and process its srcset and sizes attrs
+ */
+ pf.processSourceSet = function( el ) {
+ var srcset = el.getAttribute( "srcset" ),
+ sizes = el.getAttribute( "sizes" ),
+ candidates = [];
+
+ // if it's an img element, use the cached srcset property (defined or not)
+ if ( el.nodeName.toUpperCase() === "IMG" && el[ pf.ns ] && el[ pf.ns ].srcset ) {
+ srcset = el[ pf.ns ].srcset;
+ }
+
+ if ( srcset ) {
+ candidates = pf.getCandidatesFromSourceSet( srcset, sizes );
+ }
+ return candidates;
+ };
+
+ pf.applyBestCandidate = function( candidates, picImg ) {
+ var candidate,
+ length,
+ bestCandidate;
+
+ candidates.sort( pf.ascendingSort );
+
+ length = candidates.length;
+ bestCandidate = candidates[ length - 1 ];
+
+ for ( var i = 0; i < length; i++ ) {
+ candidate = candidates[ i ];
+ if ( candidate.resolution >= pf.getDpr() ) {
+ bestCandidate = candidate;
+ break;
+ }
+ }
+
+ if ( !pf.endsWith( picImg.src, bestCandidate.url ) ) {
+ picImg.src = bestCandidate.url;
+ // currentSrc attribute and property to match
+ // http://picture.responsiveimages.org/#the-img-element
+ picImg.currentSrc = picImg.src;
+ }
+ };
+
+ pf.ascendingSort = function( a, b ) {
+ return a.resolution - b.resolution;
+ };
+
+ /*
+ * In IE9,