",
options: {
- disabled: false,
+ angle: 30,
+ algorithm: 1,
+ step: .1,
+ distance: 5,
+ tint1: .8,
+ tint2: .4,
+ shade1: .6,
+ shade2: .3,
+ alpha: 1
+ },
- // callbacks
- create: null
- },
- _createWidget: function (options, element) {
- element = $(element || this.defaultElement || this)[0];
- this.element = $(element);
- this.uuid = widget_uuid++;
- this.eventNamespace = "." + this.widgetName + this.uuid;
-
- this.bindings = $();
- this.hoverable = $();
- this.focusable = $();
-
- if (element !== this) {
- $.data(element, this.widgetFullName, this);
- this._on(true, this.element, {
- remove: function (event) {
- if (event.target === element) {
- this.destroy();
- }
- }
- });
- this.document = $(element.style ?
- // element within the document
- element.ownerDocument :
- // element is window or document
- element.document || element);
- this.window = $(this.document[0].defaultView || this.document[0].parentWindow);
- }
+ init: function(){
+ this.colorList = $.extend( {}, this.colorListStandard, this.colorListMetro );
+ return this;
+ },
- this.options = $.widget.extend({},
- this.options,
- this._getCreateOptions(),
- options);
+ setup: function(options){
+ this.options = $.extend( {}, this.options, options );
+ },
- this._create();
- this._trigger("create", null, this._getCreateEventData());
- this._init();
- },
- _getCreateOptions: $.noop,
- _getCreateEventData: $.noop,
- _create: $.noop,
- _init: $.noop,
-
- destroy: function () {
- this._destroy();
- // we can probably remove the unbind calls in 2.0
- // all event bindings should go through this._on()
- this.element
- .unbind(this.eventNamespace)
- .removeData(this.widgetFullName)
- // support: jquery <1.6.3
- // http://bugs.jquery.com/ticket/9413
- .removeData($.camelCase(this.widgetFullName));
- this.widget()
- .unbind(this.eventNamespace)
- .removeAttr("aria-disabled")
- .removeClass(
- this.widgetFullName + "-disabled " +
- "ui-state-disabled");
-
- // clean up events and states
- this.bindings.unbind(this.eventNamespace);
- this.hoverable.removeClass("ui-state-hover");
- this.focusable.removeClass("ui-state-focus");
- },
- _destroy: $.noop,
-
- widget: function () {
- return this.element;
- },
-
- option: function (key, value) {
- var options = key,
- parts,
- curOption,
- i;
-
- if (arguments.length === 0) {
- // don't return a reference to the internal hash
- return $.widget.extend({}, this.options);
- }
-
- if (typeof key === "string") {
- // handle nested keys, e.g., "foo.bar" => { foo: { bar: ___ } }
- options = {};
- parts = key.split(".");
- key = parts.shift();
- if (parts.length) {
- curOption = options[key] = $.widget.extend({}, this.options[key]);
- for (i = 0; i < parts.length - 1; i++) {
- curOption[parts[i]] = curOption[parts[i]] || {};
- curOption = curOption[parts[i]];
- }
- key = parts.pop();
- if (arguments.length === 1) {
- return curOption[key] === undefined ? null : curOption[key];
- }
- curOption[key] = value;
- } else {
- if (arguments.length === 1) {
- return this.options[key] === undefined ? null : this.options[key];
- }
- options[key] = value;
- }
- }
+ color: function(name, palette){
+ palette = palette || this.PALETTES.ALL;
+ return this[palette][name] !== undefined ? this[palette][name] : false;
+ },
- this._setOptions(options);
+ palette: function(palette){
+ palette = palette || this.PALETTES.ALL;
+ return Object.keys(this[palette]);
+ },
- return this;
+ hex2rgb: function(hex){
+ var regex = /^#?([a-f\d])([a-f\d])([a-f\d])$/i;
+ hex = hex.replace( regex, function( m, r, g, b ) {
+ return r + r + g + g + b + b;
+ });
+ var result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec( hex );
+ return result ? {
+ r: parseInt( result[1], 16 ),
+ g: parseInt( result[2], 16 ),
+ b: parseInt( result[3], 16 )
+ } : null;
+ },
+
+ rgb2hex: function(rgb){
+ return "#" +
+ (( 1 << 24 ) + ( rgb.r << 16 ) + ( rgb.g << 8 ) + rgb.b )
+ .toString( 16 ).slice( 1 );
},
- _setOptions: function (options) {
- var key;
- for (key in options) {
- this._setOption(key, options[key]);
+ rgb2hsv: function(rgb){
+ var hsv = new HSV();
+ var h, s, v;
+ var r = rgb.r / 255, g = rgb.g / 255, b = rgb.b / 255;
+ var max = Math.max(r, g, b);
+ var min = Math.min(r, g, b);
+ var delta = max - min;
+
+ v = max;
+
+ if (max === 0) {
+ s = 0;
+ } else {
+ s = 1 - min / max;
+ }
+
+ if (max === min) {
+ h = 0;
+ } else if (max === r && g >= b) {
+ h = 60 * ( (g - b) / delta );
+ } else if (max === r && g < b) {
+ h = 60 * ( (g - b) / delta) + 360
+ } else if (max === g) {
+ h = 60 * ( (b - r) / delta) + 120
+ } else if (max === b) {
+ h = 60 * ( (r - g) / delta) + 240
+ } else {
+ h = 0;
}
- return this;
+ hsv.h = h;
+ hsv.s = s;
+ hsv.v = v;
+
+ return hsv;
},
- _setOption: function (key, value) {
- this.options[key] = value;
- if (key === "disabled") {
- this.widget()
- .toggleClass(this.widgetFullName + "-disabled", !!value);
+ hsv2rgb: function(hsv){
+ var r, g, b;
+ var h = hsv.h, s = hsv.s * 100, v = hsv.v * 100;
+ var Hi = Math.floor(h / 60);
+ var Vmin = (100 - s) * v / 100;
+ var alpha = (v - Vmin) * ( (h % 60) / 60 );
+ var Vinc = Vmin + alpha;
+ var Vdec = v - alpha;
- // If the widget is becoming disabled, then nothing is interactive
- if (value) {
- this.hoverable.removeClass("ui-state-hover");
- this.focusable.removeClass("ui-state-focus");
- }
+ switch (Hi) {
+ case 0: r = v; g = Vinc; b = Vmin; break;
+ case 1: r = Vdec; g = v; b = Vmin; break;
+ case 2: r = Vmin; g = v; b = Vinc; break;
+ case 3: r = Vmin; g = Vdec; b = v; break;
+ case 4: r = Vinc; g = Vmin; b = v; break;
+ case 5: r = v; g = Vmin; b = Vdec; break;
}
- return this;
+ return {
+ r: Math.round(r * 255 / 100),
+ g: Math.round(g * 255 / 100),
+ b: Math.round(b * 255 / 100)
+ }
},
- enable: function () {
- return this._setOptions({disabled: false});
+ hsv2hex: function(hsv){
+ return this.rgb2hex(this.hsv2rgb(hsv));
},
- disable: function () {
- return this._setOptions({disabled: true});
+
+ hex2hsv: function(hex){
+ return this.rgb2hsv(this.hex2rgb(hex));
},
- _on: function (suppressDisabledCheck, element, handlers) {
- var delegateElement,
- instance = this;
+ rgb2cmyk: function(rgb){
+ var cmyk = new CMYK();
- // no suppressDisabledCheck flag, shuffle arguments
- if (typeof suppressDisabledCheck !== "boolean") {
- handlers = element;
- element = suppressDisabledCheck;
- suppressDisabledCheck = false;
- }
+ var r = rgb.r / 255;
+ var g = rgb.g / 255;
+ var b = rgb.b / 255;
- // no element argument, shuffle and use this.element
- if (!handlers) {
- handlers = element;
- element = this.element;
- delegateElement = this.widget();
- } else {
- element = delegateElement = $(element);
- this.bindings = this.bindings.add(element);
- }
+ cmyk.k = Math.min( 1 - r, 1 - g, 1 - b );
+ cmyk.c = ( 1 - r - cmyk.k ) / ( 1 - cmyk.k );
+ cmyk.m = ( 1 - g - cmyk.k ) / ( 1 - cmyk.k );
+ cmyk.y = ( 1 - b - cmyk.k ) / ( 1 - cmyk.k );
- $.each(handlers, function (event, handler) {
- function handlerProxy() {
- // allow widgets to customize the disabled handling
- // - disabled as an array instead of boolean
- // - disabled class as method for disabling individual parts
- if (!suppressDisabledCheck &&
- ( instance.options.disabled === true ||
- $(this).hasClass("ui-state-disabled") )) {
- return;
- }
- return ( typeof handler === "string" ? instance[handler] : handler )
- .apply(instance, arguments);
- }
+ cmyk.c = Math.round( cmyk.c * 100 );
+ cmyk.m = Math.round( cmyk.m * 100 );
+ cmyk.y = Math.round( cmyk.y * 100 );
+ cmyk.k = Math.round( cmyk.k * 100 );
- // copy the guid so direct unbinding works
- if (typeof handler !== "string") {
- handlerProxy.guid = handler.guid =
- handler.guid || handlerProxy.guid || $.guid++;
- }
+ return cmyk;
+ },
- var match = event.match(/^([\w:-]*)\s*(.*)$/),
- eventName = match[1] + instance.eventNamespace,
- selector = match[2];
- if (selector) {
- delegateElement.delegate(selector, eventName, handlerProxy);
- } else {
- element.bind(eventName, handlerProxy);
- }
- });
+ cmyk2rgb: function(cmyk){
+ var rgb = new RGB();
+
+ var c = cmyk.c / 100;
+ var m = cmyk.m / 100;
+ var y = cmyk.y / 100;
+ var k = cmyk.k / 100;
+
+ rgb.r = 1 - Math.min( 1, c * ( 1 - k ) + k );
+ rgb.g = 1 - Math.min( 1, m * ( 1 - k ) + k );
+ rgb.b = 1 - Math.min( 1, y * ( 1 - k ) + k );
+
+ rgb.r = Math.round( rgb.r * 255 );
+ rgb.g = Math.round( rgb.g * 255 );
+ rgb.b = Math.round( rgb.b * 255 );
+
+ return rgb;
},
- _off: function (element, eventName) {
- eventName = (eventName || "").split(" ").join(this.eventNamespace + " ") +
- this.eventNamespace;
- element.unbind(eventName).undelegate(eventName);
+ hsv2hsl: function(hsv){
+ var h, s, l;
+ h = hsv.h;
+ l = (2 - hsv.s) * hsv.v;
+ s = hsv.s * hsv.v;
+ s /= (l <= 1) ? l : 2 - l;
+ l /= 2;
+ return {h: h, s: s, l: l}
+ },
- // Clear the stack to avoid memory leaks (#10056)
- this.bindings = $(this.bindings.not(element).get());
- this.focusable = $(this.focusable.not(element).get());
- this.hoverable = $(this.hoverable.not(element).get());
+ hsl2hsv: function(hsl){
+ var h, s, v, l;
+ h = hsl.h;
+ l = hsl.l * 2;
+ s = hsl.s * (l <= 1 ? l : 2 - l);
+ v = (l + s) / 2;
+ s = (2 * s) / (l + s);
+ return {h: h, s: s, l: v}
},
- _delay: function (handler, delay) {
- function handlerProxy() {
- return ( typeof handler === "string" ? instance[handler] : handler )
- .apply(instance, arguments);
+ rgb2websafe: function(rgb){
+ return {
+ r: Math.round(rgb.r / 51) * 51,
+ g: Math.round(rgb.g / 51) * 51,
+ b: Math.round(rgb.b / 51) * 51
}
+ },
- var instance = this;
- return setTimeout(handlerProxy, delay || 0);
+ rgba2websafe: function(rgba){
+ return {
+ r: Math.round(rgba.r / 51) * 51,
+ g: Math.round(rgba.g / 51) * 51,
+ b: Math.round(rgba.b / 51) * 51,
+ a: rgba.a
+ }
},
- _hoverable: function (element) {
- this.hoverable = this.hoverable.add(element);
- this._on(element, {
- mouseenter: function (event) {
- $(event.currentTarget).addClass("ui-state-hover");
- },
- mouseleave: function (event) {
- $(event.currentTarget).removeClass("ui-state-hover");
- }
- });
+ hex2websafe: function(hex){
+ return this.rgb2hex(this.rgb2websafe(this.toRGB(hex)));
},
- _focusable: function (element) {
- this.focusable = this.focusable.add(element);
- this._on(element, {
- focusin: function (event) {
- $(event.currentTarget).addClass("ui-state-focus");
- },
- focusout: function (event) {
- $(event.currentTarget).removeClass("ui-state-focus");
- }
- });
+ hsv2websafe: function(hsv){
+ return this.rgb2hsv(this.rgb2websafe(this.toRGB(hsv)));
},
- _trigger: function (type, event, data) {
- var prop, orig,
- callback = this.options[type];
+ hsl2websafe: function(hsl){
+ return this.hsv2hsl(this.rgb2hsv(this.rgb2websafe(this.toRGB(hsl))));
+ },
- data = data || {};
- event = $.Event(event);
- event.type = ( type === this.widgetEventPrefix ?
- type :
- this.widgetEventPrefix + type ).toLowerCase();
- // the original event may come from any element
- // so we need to reset the target on the new event
- event.target = this.element[0];
+ cmyk2websafe: function(cmyk){
+ return this.rgb2cmyk(this.rgb2websafe(this.cmyk2rgb(cmyk)));
+ },
- // copy original event properties over to the new event
- orig = event.originalEvent;
- if (orig) {
- for (prop in orig) {
- if (!( prop in event )) {
- event[prop] = orig[prop];
- }
- }
- }
+ websafe: function(color){
+ if (this.isHEX(color)) return this.hex2websafe(color);
+ if (this.isRGB(color)) return this.rgb2websafe(color);
+ if (this.isRGBA(color)) return this.rgba2websafe(color);
+ if (this.isHSV(color)) return this.hsv2websafe(color);
+ if (this.isHSL(color)) return this.hsl2websafe(color);
+ if (this.isCMYK(color)) return this.cmyk2websafe(color);
- this.element.trigger(event, data);
- return !( $.isFunction(callback) &&
- callback.apply(this.element[0], [event].concat(data)) === false ||
- event.isDefaultPrevented() );
- }
-};
+ return color;
+ },
-$.each({show: "fadeIn", hide: "fadeOut"}, function (method, defaultEffect) {
- $.Widget.prototype["_" + method] = function (element, options, callback) {
- if (typeof options === "string") {
- options = {effect: options};
- }
- var hasOptions,
- effectName = !options ?
- method :
- options === true || typeof options === "number" ?
- defaultEffect :
- options.effect || defaultEffect;
- options = options || {};
- if (typeof options === "number") {
- options = {duration: options};
- }
- hasOptions = !$.isEmptyObject(options);
- options.complete = callback;
- if (options.delay) {
- element.delay(options.delay);
- }
- if (hasOptions && $.effects && $.effects.effect[effectName]) {
- element[method](options);
- } else if (effectName !== method && element[effectName]) {
- element[effectName](options.duration, options.easing, callback);
- } else {
- element.queue(function (next) {
- $(this)[method]();
- if (callback) {
- callback.call(element[0]);
- }
- next();
- });
- }
- };
-});
+ is: function(color){
+ if (this.isHEX(color)) return this.TYPES.HEX;
+ if (this.isRGB(color)) return this.TYPES.RGB;
+ if (this.isRGBA(color)) return this.TYPES.RGBA;
+ if (this.isHSV(color)) return this.TYPES.HSV;
+ if (this.isHSL(color)) return this.TYPES.HSL;
+ if (this.isCMYK(color)) return this.TYPES.CMYK;
-var widget = $.widget;
+ return this.TYPES.UNKNOWN;
+ },
-// Source: js/initiator.js
-$.fn.reverse = Array.prototype.reverse;
+ toRGB: function(color){
+ if (this.isHSV(color)) return this.hsv2rgb(color);
+ if (this.isHSL(color)) return this.hsv2rgb(this.hsl2hsv(color));
+ if (this.isRGB(color)) return color;
+ if (this.isHEX(color)) return this.hex2rgb(color);
+ if (this.isCMYK(color)) return this.cmyk2rgb(color);
-$.Metro = {
+ throw new Error("Unknown color format!");
+ },
- hotkeys: [],
+ toRGBA: function(color, alpha){
+ var result = this.toRGB(color);
+ result.a = alpha || 1;
+ return result;
+ },
- initWidgets: function(widgets) {
- $.each(widgets, function () {
- var $this = $(this), w = this;
- var roles = $this.data('role').split(/\s*,\s*/);
- roles.map(function (func) {
- try {
- //$(w)[func]();
- if ($.fn[func] !== undefined && $this.data(func + '-initiated') !== true) {
- $.fn[func].call($this);
- $this.data(func + '-initiated', true);
- }
- } catch (e) {
- if (window.METRO_DEBUG) {
- console.log(e.message, e.stack);
- }
- }
- });
- });
+ toHSV: function(color){
+ return this.rgb2hsv(this.toRGB(color));
},
- initHotkeys: function(hotkeys){
- $.each(hotkeys, function(){
- var element = $(this);
- var hotkey = element.data('hotkey').toLowerCase();
+ toHSL: function(color){
+ return this.hsv2hsl(this.rgb2hsv(this.toRGB(color)));
+ },
- //if ($.Metro.hotkeys.indexOf(hotkey) > -1) {
- // return;
- //}
- if (element.data('hotKeyBonded') === true ) {
- return;
- }
+ toHSLA: function(color, alpha){
+ var hsla;
+ hsla = this.hsv2hsl(this.rgb2hsv(this.toRGB(color)));
+ hsla.a = alpha || this.options.alpha;
+ return hsla;
+ },
- $.Metro.hotkeys.push(hotkey);
+ toHEX: function(color){
+ return this.rgb2hex(this.toRGB(color));
+ },
- $(document).on('keyup', null, hotkey, function(e){
- if (element === undefined) return;
+ toCMYK: function(color){
+ return this.rgb2cmyk(this.toRGB(color));
+ },
- if (element[0].tagName === 'A' &&
- element.attr('href') !== undefined &&
- element.attr('href').trim() !== '' &&
- element.attr('href').trim() !== '#') {
- document.location.href = element.attr('href');
- } else {
- element.click();
- }
- return false;
- });
+ toHexString: function(color){
+ return this.toHEX(color);
+ },
- element.data('hotKeyBonded', true);
- });
+ toHsvString: function(color){
+ var hsv = this.toHSV(color);
+ return "hsv("+[hsv.h, hsv.s, hsv.v].join(",")+")";
},
- init: function(){
- var widgets = $("[data-role]");
- var hotkeys = $("[data-hotkey]");
+ toHslString: function(color){
+ var hsl = this.toHSL(color);
+ return "hsl("+[Math.round(hsl.h), Math.round(hsl.s * 100) + "%" , Math.round(hsl.l * 100) + "%"].join(",")+")";
+ },
+
+ toHslaString: function(color){
+ var hsl = this.toHSLA(color);
+ return "hsl("+[Math.round(hsl.h), Math.round(hsl.s * 100) + "%" , Math.round(hsl.l * 100) + "%", hsl.a].join(",")+")";
+ },
+ toCmykString: function(color){
+ var cmyk = this.toCMYK(color);
+ return "cmyk("+[cmyk.c, cmyk.m, cmyk.y, cmyk.k].join(",")+")";
+ },
+
+ toRgbString: function(color){
+ var rgb = this.toRGB(color);
+ return "rgb("+[rgb.r, rgb.g, rgb.b].join(",")+")";
+ },
+
+ toRgbaString: function(color){
+ var rgb = this.toRGBA(color);
+ return "rgba("+[rgb.r, rgb.g, rgb.b, rgb.a].join(",")+")";
+ },
- $.Metro.initHotkeys(hotkeys);
- $.Metro.initWidgets(widgets);
+ toString: function(color){
+ if (this.isHEX(color)) return this.toHexString(color);
+ if (this.isRGB(color)) return this.toRgbString(color);
+ if (this.isRGBA(color)) return this.toRgbaString(color);
+ if (this.isHSV(color)) return this.toHsvString(color);
+ if (this.isHSL(color)) return this.toHslString(color);
+ if (this.isHSLA(color)) return this.toHslaString(color);
+ if (this.isCMYK(color)) return this.toCmykString(color);
- var observer, observerOptions, observerCallback;
+ throw new Error("Unknown color format!");
+ },
- observerOptions = {
- 'childList': true,
- 'subtree': true
+ grayscale: function(color, output){
+ output = output || "hex";
+ var rgb = this.toRGB(color);
+ var gray = Math.round(rgb.r * .2125 + rgb.g * .7154 + rgb.b * .0721);
+ var mono = {
+ r: gray,
+ g: gray,
+ b: gray
};
+ return this["rgb2"+output](mono);
+ },
- observerCallback = function(mutations){
+ darken: function(color, amount){
+ if (amount === undefined) {
+ amount = 10;
+ }
+ return this.lighten(color, -1 * Math.abs(amount));
+ },
- //console.log(mutations);
+ lighten: function(color, amount){
+ var col, type, res, alpha = 1;
- mutations.map(function(record){
+ if (amount === undefined) {
+ amount = 10;
+ }
- if (record.addedNodes) {
+ col = this.toHEX(color);
+ col = col.slice(1);
- /*jshint loopfunc: true */
- var obj, widgets, plugins, hotkeys;
+ type = this.is(color);
- for(var i = 0, l = record.addedNodes.length; i < l; i++) {
- obj = $(record.addedNodes[i]);
+ if (type === this.TYPES.RGBA) {
+ alpha = color.a;
+ }
- plugins = obj.find("[data-role]");
+ var num = parseInt(col, 16);
+ var r = (num >> 16) + amount;
- hotkeys = obj.find("[data-hotkey]");
+ if (r > 255) r = 255;
+ else if (r < 0) r = 0;
- $.Metro.initHotkeys(hotkeys);
+ var b = ((num >> 8) & 0x00FF) + amount;
- if (obj.data('role') !== undefined) {
- widgets = $.merge(plugins, obj);
- } else {
- widgets = plugins;
- }
+ if (b > 255) b = 255;
+ else if (b < 0) b = 0;
- if (widgets.length) {
- $.Metro.initWidgets(widgets);
- }
- }
- }
- });
- };
+ var g = (num & 0x0000FF) + amount;
- //console.log($(document));
- observer = new MutationObserver(observerCallback);
- observer.observe(document, observerOptions);
- }
-};
-// Source: js/utils/core-utils.js
-var utils = {
- isColor: function(val){
- return /(^#[0-9A-F]{6}$)|(^#[0-9A-F]{3}$)/i.test(val);
+ if (g > 255) g = 255;
+ else if (g < 0) g = 0;
+
+ res = "#" + (g | (b << 8) | (r << 16)).toString(16);
+
+ switch (type) {
+ case "rgb": return this.toRGB(res);
+ case "rgba": return this.toRGBA(res, alpha);
+ case "hsv": return this.toHSV(res);
+ case "hsl": return this.toHSL(res);
+ case "cmyk": return this.toCMYK(res);
+ default: return res;
+ }
},
- isUrl: function(val){
- return /^(ftp|http|https):\/\/(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?/.test(this);
+ isDark: function(color){
+ var rgb = this.toRGB(color);
+ var YIQ = (
+ ( rgb.r * 299 ) +
+ ( rgb.g * 587 ) +
+ ( rgb.b * 114 )
+ ) / 1000;
+ return ( YIQ < 128 )
},
- secondsToFormattedString: function(time){
- var hours, minutes, seconds;
+ isLight: function(hex){
+ return !this.isDark(hex);
+ },
- hours = parseInt( time / 3600 ) % 24;
- minutes = parseInt( time / 60 ) % 60;
- seconds = time % 60;
+ isHSV: function(val){
+ return Utils.isObject(val) && "h" in val && "s" in val && "v" in val;
+ },
- return (hours ? (hours) + ":" : "") + (minutes < 10 ? "0"+minutes : minutes) + ":" + (seconds < 10 ? "0"+seconds : seconds);
+ isHSL: function(val){
+ return Utils.isObject(val) && "h" in val && "s" in val && "l" in val;
},
- uniqueId: function (prefix) {
-var d = new Date().getTime();
- var uuid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
- var r = (d + Math.random() * 16) % 16 | 0;
- d = Math.floor(d / 16);
- return (c == 'x' ? r : (r & 0x3 | 0x8)).toString(16);
- });
- return uuid;
+ isHSLA: function(val){
+ return Utils.isObject(val) && "h" in val && "s" in val && "l" in val && "a" in val;
},
- isTouchDevice: function() {
- return (('ontouchstart' in window)
- || (navigator.MaxTouchPoints > 0)
- || (navigator.msMaxTouchPoints > 0));
+ isRGB: function(val){
+ return Utils.isObject(val) && "r" in val && "g" in val && "b" in val;
},
- arrayUnique: function (array) {
- var a = array.concat();
- for (var i = 0; i < a.length; ++i) {
- for (var j = i + 1; j < a.length; ++j) {
- if (a[i] === a[j])
- a.splice(j--, 1);
- }
- }
+ isRGBA: function(val){
+ return Utils.isObject(val) && "r" in val && "g" in val && "b" in val && "a" in val;
+ },
- return a;
+ isCMYK: function(val){
+ return Utils.isObject(val) && "c" in val && "m" in val && "y" in val && "k" in val;
},
- arrayClone: function(array){
- return array.slice(0);
+ isHEX: function(val){
+ return /(^#[0-9A-F]{6}$)|(^#[0-9A-F]{3}$)/i.test(val);
},
- arrayShuffle: function (array) {
- var currentIndex = array.length, temporaryValue, randomIndex;
+ isColor: function(color){
+ return this.isHEX(color) || this.isRGB(color) || this.isRGBA(color) || this.isHSV(color) || this.isHSL(color) || this.isCMYK(color);
+ },
- while (0 !== currentIndex) {
+ hueShift: function(h, s){
+ h+=s;
+ while (h >= 360.0) h -= 360.0;
+ while (h < 0.0) h += 360.0;
+ return h;
+ },
- randomIndex = Math.floor(Math.random() * currentIndex);
- currentIndex -= 1;
+ getScheme: function(color, name, format, options){
+ this.options = $.extend( {}, this.options, options );
- temporaryValue = array[currentIndex];
- array[currentIndex] = array[randomIndex];
- array[randomIndex] = temporaryValue;
- }
+ var i;
+ var scheme = [];
+ var hsv;
+ var that = this;
- return array;
- },
+ hsv = this.toHSV(color);
- hex2rgba: function(hex, alpha){
- var c;
- alpha = isNaN(alpha) ? 1 : alpha;
- if(/^#([A-Fa-f0-9]{3}){1,2}$/.test(hex)){
- c= hex.substring(1).split('');
- if(c.length== 3){
- c= [c[0], c[0], c[1], c[1], c[2], c[2]];
+ if (this.isHSV(hsv) === false) {
+ console.log("The value is a not supported color format!");
+ return false;
+ }
+
+ function convert(source, format) {
+ var result = [];
+ var o = that.options;
+ switch (format) {
+ case "hex": result = source.map(function(v){return Colors.toHEX(v);}); break;
+ case "rgb": result = source.map(function(v){return Colors.toRGB(v);}); break;
+ case "rgba": result = source.map(function(v){return Colors.toRGBA(v, o.alpha);}); break;
+ case "hsl": result = source.map(function(v){return Colors.toHSL(v);}); break;
+ case "cmyk": result = source.map(function(v){return Colors.toCMYK(v);}); break;
+ default: result = source;
}
- c= '0x'+c.join('');
- return 'rgba('+[(c>>16)&255, (c>>8)&255, c&255].join(',')+','+alpha+')';
+
+ return result;
}
- throw new Error('Hex2rgba error. Bad Hex value');
- },
- random: function(from, to){
- return Math.floor(Math.random()*(to-from+1)+from);
- },
+ function clamp( num, min, max ){
+ return Math.max( min, Math.min( num, max ));
+ }
- isInt: function(n){
- return Number(n) === n && n % 1 === 0;
- },
+ function toRange(a, b, c){
+ return a < b ? b : ( a > c ? c : a);
+ }
- isFloat: function(n){
- return Number(n) === n && n % 1 !== 0;
+ var rgb, h = hsv.h, s = hsv.s, v = hsv.v;
+ var o = this.options;
+
+ switch (name) {
+ case "monochromatic":
+ case "mono":
+ if (o.algorithm === 1) {
+
+ rgb = this.hsv2rgb(hsv);
+ rgb.r = toRange(Math.round(rgb.r + (255 - rgb.r) * o.tint1), 0, 255);
+ rgb.g = toRange(Math.round(rgb.g + (255 - rgb.g) * o.tint1), 0, 255);
+ rgb.b = toRange(Math.round(rgb.b + (255 - rgb.b) * o.tint1), 0, 255);
+ scheme.push(this.rgb2hsv(rgb));
+
+ rgb = this.hsv2rgb(hsv);
+ rgb.r = toRange(Math.round(rgb.r + (255 - rgb.r) * o.tint2), 0, 255);
+ rgb.g = toRange(Math.round(rgb.g + (255 - rgb.g) * o.tint2), 0, 255);
+ rgb.b = toRange(Math.round(rgb.b + (255 - rgb.b) * o.tint2), 0, 255);
+ scheme.push(this.rgb2hsv(rgb));
+
+ scheme.push(hsv);
+
+ rgb = this.hsv2rgb(hsv);
+ rgb.r = toRange(Math.round(rgb.r * o.shade1), 0, 255);
+ rgb.g = toRange(Math.round(rgb.g * o.shade1), 0, 255);
+ rgb.b = toRange(Math.round(rgb.b * o.shade1), 0, 255);
+ scheme.push(this.rgb2hsv(rgb));
+
+ rgb = this.hsv2rgb(hsv);
+ rgb.r = toRange(Math.round(rgb.r * o.shade2), 0, 255);
+ rgb.g = toRange(Math.round(rgb.g * o.shade2), 0, 255);
+ rgb.b = toRange(Math.round(rgb.b * o.shade2), 0, 255);
+ scheme.push(this.rgb2hsv(rgb));
+ } else if (o.algorithm === 2) {
+ scheme.push(hsv);
+ for(i = 1; i <= o.distance; i++) {
+ v = clamp(v - o.step, 0, 1);
+ s = clamp(s - o.step, 0, 1);
+ scheme.push({h: h, s: s, v: v});
+ }
+ } else if (o.algorithm === 3) {
+ scheme.push(hsv);
+ for(i = 1; i <= o.distance; i++) {
+ v = clamp(v - o.step, 0, 1);
+ scheme.push({h: h, s: s, v: v});
+ }
+ } else {
+ v = clamp(hsv.v + o.step * 2, 0, 1);
+ scheme.push({h: h, s: s, v: v});
+
+ v = clamp(hsv.v + o.step, 0, 1);
+ scheme.push({h: h, s: s, v: v});
+
+ scheme.push(hsv); s = hsv.s; v = hsv.v;
+
+ v = clamp(hsv.v - o.step, 0, 1);
+ scheme.push({h: h, s: s, v: v});
+
+ v = clamp(hsv.v - o.step * 2, 0, 1);
+ scheme.push({h: h, s: s, v: v});
+ }
+ break;
+
+ case 'complementary':
+ case 'complement':
+ case 'comp':
+ scheme.push(hsv);
+
+ h = this.hueShift(hsv.h, 180.0);
+ scheme.push({h: h, s: s, v: v});
+ break;
+
+ case 'double-complementary':
+ case 'double-complement':
+ case 'double':
+ scheme.push(hsv);
+
+ console.log(h);
+
+ h = this.hueShift(h, 180.0);
+ scheme.push({h: h, s: s, v: v});
+
+ console.log(h);
+
+ h = this.hueShift(h, o.angle);
+ scheme.push({h: h, s: s, v: v});
+
+ console.log(h);
+
+ h = this.hueShift(h, 180.0);
+ scheme.push({h: h, s: s, v: v});
+
+ console.log(h);
+
+ break;
+
+ case 'analogous':
+ case 'analog':
+
+ h = this.hueShift(h, o.angle);
+ scheme.push({h: h, s: s, v: v});
+
+ scheme.push(hsv);
+
+ h = this.hueShift(hsv.h, 0.0 - o.angle);
+ scheme.push({h: h, s: s, v: v});
+
+ break;
+
+ case 'triadic':
+ case 'triad':
+ scheme.push(hsv);
+ for ( i = 1; i < 3; i++ ) {
+ h = this.hueShift(h, 120.0);
+ scheme.push({h: h, s: s, v: v});
+ }
+ break;
+
+ case 'tetradic':
+ case 'tetra':
+ scheme.push(hsv);
+
+ h = this.hueShift(hsv.h, 180.0);
+ scheme.push({h: h, s: s, v: v});
+
+ h = this.hueShift(hsv.h, -1 * o.angle);
+ scheme.push({h: h, s: s, v: v});
+
+ h = this.hueShift(h, 180.0);
+ scheme.push({h: h, s: s, v: v});
+
+ break;
+
+ case 'square':
+ scheme.push(hsv);
+ for ( i = 1; i < 4; i++ ) {
+ h = this.hueShift(h, 90.0);
+ scheme.push({h: h, s: s, v: v});
+ }
+ break;
+
+ case 'split-complementary':
+ case 'split-complement':
+ case 'split':
+ h = this.hueShift(h, 180.0 - o.angle);
+ scheme.push({h: h, s: s, v: v});
+
+ scheme.push(hsv);
+
+ h = this.hueShift(hsv.h, 180.0 + o.angle);
+ scheme.push({h: h, s: s, v: v});
+ break;
+
+ default: console.log("Unknown scheme name");
+ }
+
+ return convert(scheme, format);
}
};
-$.metroUtils = window.metroUtils = utils;
+Metro['colors'] = Colors.init();
// Source: js/utils/easing.js
- $.easing['jswing'] = $.easing['swing'];
-
- $.extend($.easing, {
- def: 'easeOutQuad',
- swing: function (x, t, b, c, d) {
- //alert($.easing.default);
- return $.easing[$.easing.def](x, t, b, c, d);
- },
- easeInQuad: function (x, t, b, c, d) {
- return c * (t /= d) * t + b;
- },
- easeOutQuad: function (x, t, b, c, d) {
- return -c * (t /= d) * (t - 2) + b;
- },
- easeInOutQuad: function (x, t, b, c, d) {
- if ((t /= d / 2) < 1) return c / 2 * t * t + b;
- return -c / 2 * ((--t) * (t - 2) - 1) + b;
- },
- easeInCubic: function (x, t, b, c, d) {
- return c * (t /= d) * t * t + b;
- },
- easeOutCubic: function (x, t, b, c, d) {
- return c * ((t = t / d - 1) * t * t + 1) + b;
- },
- easeInOutCubic: function (x, t, b, c, d) {
- if ((t /= d / 2) < 1) return c / 2 * t * t * t + b;
- return c / 2 * ((t -= 2) * t * t + 2) + b;
- },
- easeInQuart: function (x, t, b, c, d) {
- return c * (t /= d) * t * t * t + b;
- },
- easeOutQuart: function (x, t, b, c, d) {
- return -c * ((t = t / d - 1) * t * t * t - 1) + b;
- },
- easeInOutQuart: function (x, t, b, c, d) {
- if ((t /= d / 2) < 1) return c / 2 * t * t * t * t + b;
- return -c / 2 * ((t -= 2) * t * t * t - 2) + b;
- },
- easeInQuint: function (x, t, b, c, d) {
- return c * (t /= d) * t * t * t * t + b;
- },
- easeOutQuint: function (x, t, b, c, d) {
- return c * ((t = t / d - 1) * t * t * t * t + 1) + b;
- },
- easeInOutQuint: function (x, t, b, c, d) {
- if ((t /= d / 2) < 1) return c / 2 * t * t * t * t * t + b;
- return c / 2 * ((t -= 2) * t * t * t * t + 2) + b;
- },
- easeInSine: function (x, t, b, c, d) {
- return -c * Math.cos(t / d * (Math.PI / 2)) + c + b;
- },
- easeOutSine: function (x, t, b, c, d) {
- return c * Math.sin(t / d * (Math.PI / 2)) + b;
- },
- easeInOutSine: function (x, t, b, c, d) {
- return -c / 2 * (Math.cos(Math.PI * t / d) - 1) + b;
- },
- easeInExpo: function (x, t, b, c, d) {
- return (t == 0) ? b : c * Math.pow(2, 10 * (t / d - 1)) + b;
- },
- easeOutExpo: function (x, t, b, c, d) {
- return (t == d) ? b + c : c * (-Math.pow(2, -10 * t / d) + 1) + b;
- },
- easeInOutExpo: function (x, t, b, c, d) {
- if (t == 0) return b;
- if (t == d) return b + c;
- if ((t /= d / 2) < 1) return c / 2 * Math.pow(2, 10 * (t - 1)) + b;
- return c / 2 * (-Math.pow(2, -10 * --t) + 2) + b;
- },
- easeInCirc: function (x, t, b, c, d) {
- return -c * (Math.sqrt(1 - (t /= d) * t) - 1) + b;
- },
- easeOutCirc: function (x, t, b, c, d) {
- return c * Math.sqrt(1 - (t = t / d - 1) * t) + b;
- },
- easeInOutCirc: function (x, t, b, c, d) {
- if ((t /= d / 2) < 1) return -c / 2 * (Math.sqrt(1 - t * t) - 1) + b;
- return c / 2 * (Math.sqrt(1 - (t -= 2) * t) + 1) + b;
- },
- easeInElastic: function (x, t, b, c, d) {
- var s = 1.70158;
- var p = 0;
- var a = c;
- if (t == 0) return b;
- if ((t /= d) == 1) return b + c;
- if (!p) p = d * .3;
- if (a < Math.abs(c)) {
- a = c;
- s = p / 4;
- }
- else s = p / (2 * Math.PI) * Math.asin(c / a);
- return -(a * Math.pow(2, 10 * (t -= 1)) * Math.sin((t * d - s) * (2 * Math.PI) / p)) + b;
- },
- easeOutElastic: function (x, t, b, c, d) {
- var s = 1.70158;
- var p = 0;
- var a = c;
- if (t == 0) return b;
- if ((t /= d) == 1) return b + c;
- if (!p) p = d * .3;
- if (a < Math.abs(c)) {
- a = c;
- s = p / 4;
- }
- else s = p / (2 * Math.PI) * Math.asin(c / a);
- return a * Math.pow(2, -10 * t) * Math.sin((t * d - s) * (2 * Math.PI) / p) + c + b;
- },
- easeInOutElastic: function (x, t, b, c, d) {
- var s = 1.70158;
- var p = 0;
- var a = c;
- if (t == 0) return b;
- if ((t /= d / 2) == 2) return b + c;
- if (!p) p = d * (.3 * 1.5);
- if (a < Math.abs(c)) {
- a = c;
- s = p / 4;
- }
- else s = p / (2 * Math.PI) * Math.asin(c / a);
- if (t < 1) return -.5 * (a * Math.pow(2, 10 * (t -= 1)) * Math.sin((t * d - s) * (2 * Math.PI) / p)) + b;
- return a * Math.pow(2, -10 * (t -= 1)) * Math.sin((t * d - s) * (2 * Math.PI) / p) * .5 + c + b;
- },
- easeInBack: function (x, t, b, c, d, s) {
- if (s == undefined) s = 1.70158;
- return c * (t /= d) * t * ((s + 1) * t - s) + b;
- },
- easeOutBack: function (x, t, b, c, d, s) {
- if (s == undefined) s = 1.70158;
- return c * ((t = t / d - 1) * t * ((s + 1) * t + s) + 1) + b;
- },
- easeInOutBack: function (x, t, b, c, d, s) {
- if (s == undefined) s = 1.70158;
- if ((t /= d / 2) < 1) return c / 2 * (t * t * (((s *= (1.525)) + 1) * t - s)) + b;
- return c / 2 * ((t -= 2) * t * (((s *= (1.525)) + 1) * t + s) + 2) + b;
- },
- easeInBounce: function (x, t, b, c, d) {
- return c - $.easing.easeOutBounce(x, d - t, 0, c, d) + b;
- },
- easeOutBounce: function (x, t, b, c, d) {
- if ((t /= d) < (1 / 2.75)) {
- return c * (7.5625 * t * t) + b;
- } else if (t < (2 / 2.75)) {
- return c * (7.5625 * (t -= (1.5 / 2.75)) * t + .75) + b;
- } else if (t < (2.5 / 2.75)) {
- return c * (7.5625 * (t -= (2.25 / 2.75)) * t + .9375) + b;
- } else {
- return c * (7.5625 * (t -= (2.625 / 2.75)) * t + .984375) + b;
- }
- },
- easeInOutBounce: function (x, t, b, c, d) {
- if (t < d / 2) return $.easing.easeInBounce(x, t * 2, 0, c, d) * .5 + b;
- return $.easing.easeOutBounce(x, t * 2 - d, 0, c, d) * .5 + c * .5 + b;
- }
+$.easing['jswing'] = $.easing['swing'];
+
+$.extend($.easing, {
+ def: 'easeOutQuad',
+ swing: function (x, t, b, c, d) {
+ //alert($.easing.default);
+ return $.easing[$.easing.def](x, t, b, c, d);
+ },
+ easeInQuad: function (x, t, b, c, d) {
+ return c * (t /= d) * t + b;
+ },
+ easeOutQuad: function (x, t, b, c, d) {
+ return -c * (t /= d) * (t - 2) + b;
+ },
+ easeInOutQuad: function (x, t, b, c, d) {
+ if ((t /= d / 2) < 1) return c / 2 * t * t + b;
+ return -c / 2 * ((--t) * (t - 2) - 1) + b;
+ },
+ easeInCubic: function (x, t, b, c, d) {
+ return c * (t /= d) * t * t + b;
+ },
+ easeOutCubic: function (x, t, b, c, d) {
+ return c * ((t = t / d - 1) * t * t + 1) + b;
+ },
+ easeInOutCubic: function (x, t, b, c, d) {
+ if ((t /= d / 2) < 1) return c / 2 * t * t * t + b;
+ return c / 2 * ((t -= 2) * t * t + 2) + b;
+ },
+ easeInQuart: function (x, t, b, c, d) {
+ return c * (t /= d) * t * t * t + b;
+ },
+ easeOutQuart: function (x, t, b, c, d) {
+ return -c * ((t = t / d - 1) * t * t * t - 1) + b;
+ },
+ easeInOutQuart: function (x, t, b, c, d) {
+ if ((t /= d / 2) < 1) return c / 2 * t * t * t * t + b;
+ return -c / 2 * ((t -= 2) * t * t * t - 2) + b;
+ },
+ easeInQuint: function (x, t, b, c, d) {
+ return c * (t /= d) * t * t * t * t + b;
+ },
+ easeOutQuint: function (x, t, b, c, d) {
+ return c * ((t = t / d - 1) * t * t * t * t + 1) + b;
+ },
+ easeInOutQuint: function (x, t, b, c, d) {
+ if ((t /= d / 2) < 1) return c / 2 * t * t * t * t * t + b;
+ return c / 2 * ((t -= 2) * t * t * t * t + 2) + b;
+ },
+ easeInSine: function (x, t, b, c, d) {
+ return -c * Math.cos(t / d * (Math.PI / 2)) + c + b;
+ },
+ easeOutSine: function (x, t, b, c, d) {
+ return c * Math.sin(t / d * (Math.PI / 2)) + b;
+ },
+ easeInOutSine: function (x, t, b, c, d) {
+ return -c / 2 * (Math.cos(Math.PI * t / d) - 1) + b;
+ },
+ easeInExpo: function (x, t, b, c, d) {
+ return (t == 0) ? b : c * Math.pow(2, 10 * (t / d - 1)) + b;
+ },
+ easeOutExpo: function (x, t, b, c, d) {
+ return (t == d) ? b + c : c * (-Math.pow(2, -10 * t / d) + 1) + b;
+ },
+ easeInOutExpo: function (x, t, b, c, d) {
+ if (t == 0) return b;
+ if (t == d) return b + c;
+ if ((t /= d / 2) < 1) return c / 2 * Math.pow(2, 10 * (t - 1)) + b;
+ return c / 2 * (-Math.pow(2, -10 * --t) + 2) + b;
+ },
+ easeInCirc: function (x, t, b, c, d) {
+ return -c * (Math.sqrt(1 - (t /= d) * t) - 1) + b;
+ },
+ easeOutCirc: function (x, t, b, c, d) {
+ return c * Math.sqrt(1 - (t = t / d - 1) * t) + b;
+ },
+ easeInOutCirc: function (x, t, b, c, d) {
+ if ((t /= d / 2) < 1) return -c / 2 * (Math.sqrt(1 - t * t) - 1) + b;
+ return c / 2 * (Math.sqrt(1 - (t -= 2) * t) + 1) + b;
+ },
+ easeInElastic: function (x, t, b, c, d) {
+ var s = 1.70158;
+ var p = 0;
+ var a = c;
+ if (t == 0) return b;
+ if ((t /= d) == 1) return b + c;
+ if (!p) p = d * .3;
+ if (a < Math.abs(c)) {
+ a = c;
+ s = p / 4;
+ }
+ else s = p / (2 * Math.PI) * Math.asin(c / a);
+ return -(a * Math.pow(2, 10 * (t -= 1)) * Math.sin((t * d - s) * (2 * Math.PI) / p)) + b;
+ },
+ easeOutElastic: function (x, t, b, c, d) {
+ var s = 1.70158;
+ var p = 0;
+ var a = c;
+ if (t == 0) return b;
+ if ((t /= d) == 1) return b + c;
+ if (!p) p = d * .3;
+ if (a < Math.abs(c)) {
+ a = c;
+ s = p / 4;
+ }
+ else s = p / (2 * Math.PI) * Math.asin(c / a);
+ return a * Math.pow(2, -10 * t) * Math.sin((t * d - s) * (2 * Math.PI) / p) + c + b;
+ },
+ easeInOutElastic: function (x, t, b, c, d) {
+ var s = 1.70158;
+ var p = 0;
+ var a = c;
+ if (t == 0) return b;
+ if ((t /= d / 2) == 2) return b + c;
+ if (!p) p = d * (.3 * 1.5);
+ if (a < Math.abs(c)) {
+ a = c;
+ s = p / 4;
+ }
+ else s = p / (2 * Math.PI) * Math.asin(c / a);
+ if (t < 1) return -.5 * (a * Math.pow(2, 10 * (t -= 1)) * Math.sin((t * d - s) * (2 * Math.PI) / p)) + b;
+ return a * Math.pow(2, -10 * (t -= 1)) * Math.sin((t * d - s) * (2 * Math.PI) / p) * .5 + c + b;
+ },
+ easeInBack: function (x, t, b, c, d, s) {
+ if (s == undefined) s = 1.70158;
+ return c * (t /= d) * t * ((s + 1) * t - s) + b;
+ },
+ easeOutBack: function (x, t, b, c, d, s) {
+ if (s == undefined) s = 1.70158;
+ return c * ((t = t / d - 1) * t * ((s + 1) * t + s) + 1) + b;
+ },
+ easeInOutBack: function (x, t, b, c, d, s) {
+ if (s == undefined) s = 1.70158;
+ if ((t /= d / 2) < 1) return c / 2 * (t * t * (((s *= (1.525)) + 1) * t - s)) + b;
+ return c / 2 * ((t -= 2) * t * (((s *= (1.525)) + 1) * t + s) + 2) + b;
+ },
+ easeInBounce: function (x, t, b, c, d) {
+ return c - $.easing.easeOutBounce(x, d - t, 0, c, d) + b;
+ },
+ easeOutBounce: function (x, t, b, c, d) {
+ if ((t /= d) < (1 / 2.75)) {
+ return c * (7.5625 * t * t) + b;
+ } else if (t < (2 / 2.75)) {
+ return c * (7.5625 * (t -= (1.5 / 2.75)) * t + .75) + b;
+ } else if (t < (2.5 / 2.75)) {
+ return c * (7.5625 * (t -= (2.25 / 2.75)) * t + .9375) + b;
+ } else {
+ return c * (7.5625 * (t -= (2.625 / 2.75)) * t + .984375) + b;
+ }
+ },
+ easeInOutBounce: function (x, t, b, c, d) {
+ if (t < d / 2) return $.easing.easeInBounce(x, t * 2, 0, c, d) * .5 + b;
+ return $.easing.easeOutBounce(x, t * 2 - d, 0, c, d) * .5 + c * .5 + b;
+ }
+});
+
+// Source: js/utils/extensions.js
+$.fn.extend({
+ toggleAttr: function(a, v){
+ return this.each(function(){
+ var el = $(this);
+ if (v !== undefined) {
+ el.attr(a, v);
+ } else {
+ if (el.attr(a) !== undefined) {
+ el.removeAttr(a);
+ } else {
+ el.attr(a, ""+a);
+ }
+ }
+ });
+ },
+ clearClasses: function(){
+ return this.each(function(){
+ this.className = "";
+ });
+ }
});
+Array.prototype.shuffle = function () {
+ var currentIndex = this.length, temporaryValue, randomIndex;
+
+ while (0 !== currentIndex) {
+
+ randomIndex = Math.floor(Math.random() * currentIndex);
+ currentIndex -= 1;
+
+ temporaryValue = this[currentIndex];
+ this[currentIndex] = this[randomIndex];
+ this[randomIndex] = temporaryValue;
+ }
+
+ return this;
+};
+
+Array.prototype.clone = function () {
+ return this.slice(0);
+};
+
+Array.prototype.unique = function () {
+ var a = this.concat();
+ for (var i = 0; i < a.length; ++i) {
+ for (var j = i + 1; j < a.length; ++j) {
+ if (a[i] === a[j])
+ a.splice(j--, 1);
+ }
+ }
+
+ return a;
+};
+
+/**
+ * Number.prototype.format(n, x, s, c)
+ *
+ * @param integer n: length of decimal
+ * @param integer x: length of whole part
+ * @param mixed s: sections delimiter
+ * @param mixed c: decimal delimiter
+ */
+Number.prototype.format = function(n, x, s, c) {
+ var re = '\\d(?=(\\d{' + (x || 3) + '})+' + (n > 0 ? '\\D' : '$') + ')',
+ num = this.toFixed(Math.max(0, ~~n));
+
+ return (c ? num.replace('.', c) : num).replace(new RegExp(re, 'g'), '$&' + (s || ','));
+};
+
+String.prototype.capitalize = function() {
+ return this.charAt(0).toUpperCase() + this.slice(1);
+};
+
+String.prototype.contains = function() {
+ return !!~String.prototype.indexOf.apply(this, arguments);
+};
+
+Date.prototype.format = function(format, locale){
+
+ if (locale === undefined) {
+ locale = "en-US";
+ }
+
+ var cal = (Metro.locales[locale] !== undefined ? Metro.locales[locale] : Metro.locales["en-US"])['calendar'];
+
+ var date = this;
+ var nDay = date.getDay(),
+ nDate = date.getDate(),
+ nMonth = date.getMonth(),
+ nYear = date.getFullYear(),
+ nHour = date.getHours(),
+ aDays = cal['days'],
+ aMonths = cal['months'],
+ aDayCount = [0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334],
+ isLeapYear = function() {
+ return (nYear%4===0 && nYear%100!==0) || nYear%400===0;
+ },
+ getThursday = function() {
+ var target = new Date(date);
+ target.setDate(nDate - ((nDay+6)%7) + 3);
+ return target;
+ },
+ zeroPad = function(nNum, nPad) {
+ return ('' + (Math.pow(10, nPad) + nNum)).slice(1);
+ };
+ return format.replace(/%[a-z]/gi, function(sMatch) {
+ return {
+ '%a': aDays[nDay].slice(0,3),
+ '%A': aDays[nDay],
+ '%b': aMonths[nMonth].slice(0,3),
+ '%B': aMonths[nMonth],
+ '%c': date.toUTCString(),
+ '%C': Math.floor(nYear/100),
+ '%d': zeroPad(nDate, 2),
+ '%e': nDate,
+ '%F': date.toISOString().slice(0,10),
+ '%G': getThursday().getFullYear(),
+ '%g': ('' + getThursday().getFullYear()).slice(2),
+ '%H': zeroPad(nHour, 2),
+ '%I': zeroPad((nHour+11)%12 + 1, 2),
+ '%j': zeroPad(aDayCount[nMonth] + nDate + ((nMonth>1 && isLeapYear()) ? 1 : 0), 3),
+ '%k': '' + nHour,
+ '%l': (nHour+11)%12 + 1,
+ '%m': zeroPad(nMonth + 1, 2),
+ '%M': zeroPad(date.getMinutes(), 2),
+ '%p': (nHour<12) ? 'AM' : 'PM',
+ '%P': (nHour<12) ? 'am' : 'pm',
+ '%s': Math.round(date.getTime()/1000),
+ '%S': zeroPad(date.getSeconds(), 2),
+ '%u': nDay || 7,
+ '%V': (function() {
+ var target = getThursday(),
+ n1stThu = target.valueOf();
+ target.setMonth(0, 1);
+ var nJan1 = target.getDay();
+ if (nJan1!==4) target.setMonth(0, 1 + ((4-nJan1)+7)%7);
+ return zeroPad(1 + Math.ceil((n1stThu-target)/604800000), 2);
+ })(),
+ '%w': '' + nDay,
+ '%x': date.toLocaleDateString(),
+ '%X': date.toLocaleTimeString(),
+ '%y': ('' + nYear).slice(2),
+ '%Y': nYear,
+ '%z': date.toTimeString().replace(/.+GMT([+-]\d+).+/, '$1'),
+ '%Z': date.toTimeString().replace(/.+\((.+?)\)$/, '$1')
+ }[sMatch] || sMatch;
+ });
+};
// Source: js/utils/hotkeys.js
-$.hotkeys = {
- version: "0.8",
+var hotkeys = {
specialKeys: {
8: "backspace",
@@ -1441,90 +1788,645 @@ $.hotkeys = {
textInputTypes: /textarea|input|select/i,
options: {
- filterInputAcceptingElements: true,
- filterTextInputs: true,
- filterContentEditable: true
- }
-};
-
-function keyHandler(handleObj) {
- if (typeof handleObj.data === "string") {
- handleObj.data = {
- keys: handleObj.data
- };
- }
+ filterInputAcceptingElements: METRO_HOTKEYS_FILTER_INPUT_ACCEPTING_ELEMENTS,
+ filterTextInputs: METRO_HOTKEYS_FILTER_TEXT_INPUTS,
+ filterContentEditable: METRO_HOTKEYS_FILTER_CONTENT_EDITABLE
+ },
- // Only care when a possible input has been specified
- if (!handleObj.data || !handleObj.data.keys || typeof handleObj.data.keys !== "string") {
- return;
- }
+ keyHandler: function(handleObj){
+ if (typeof handleObj.data === "string") {
+ handleObj.data = {
+ keys: handleObj.data
+ };
+ }
- var origHandler = handleObj.handler,
- keys = handleObj.data.keys.toLowerCase().split(" ");
-
- handleObj.handler = function(event) {
- // Don't fire in text-accepting inputs that we didn't directly bind to
- if (this !== event.target &&
- ($.hotkeys.options.filterInputAcceptingElements &&
- $.hotkeys.textInputTypes.test(event.target.nodeName) ||
- ($.hotkeys.options.filterContentEditable && $(event.target).attr('contenteditable')) ||
- ($.hotkeys.options.filterTextInputs &&
- $.inArray(event.target.type, $.hotkeys.textAcceptingInputTypes) > -1))) {
+ // Only care when a possible input has been specified
+ if (!handleObj.data || !handleObj.data.keys || typeof handleObj.data.keys !== "string") {
return;
}
- var special = event.type !== "keypress" && $.hotkeys.specialKeys[event.which],
- character = String.fromCharCode(event.which).toLowerCase(),
- modif = "",
- possible = {};
-
- $.each(["alt", "ctrl", "shift"], function(index, specialKey) {
+ var origHandler = handleObj.handler,
+ keys = handleObj.data.keys.toLowerCase().split(" ");
- if (event[specialKey + 'Key'] && special !== specialKey) {
- modif += specialKey + '+';
+ handleObj.handler = function(event) {
+ // Don't fire in text-accepting inputs that we didn't directly bind to
+ if (this !== event.target &&
+ (hotkeys.options.filterInputAcceptingElements && hotkeys.textInputTypes.test(event.target.nodeName) ||
+ (hotkeys.options.filterContentEditable && $(event.target).attr('contenteditable')) ||
+ (hotkeys.options.filterTextInputs && $.inArray(event.target.type, hotkeys.textAcceptingInputTypes) > -1))
+ )
+ {
+ return;
}
- });
- // metaKey is triggered off ctrlKey erronously
- if (event.metaKey && !event.ctrlKey && special !== "meta") {
- modif += "meta+";
- }
+ var special = event.type !== "keypress" && hotkeys.specialKeys[event.which],
+ character = String.fromCharCode(event.which).toLowerCase(),
+ modif = "",
+ possible = {};
- if (event.metaKey && special !== "meta" && modif.indexOf("alt+ctrl+shift+") > -1) {
- modif = modif.replace("alt+ctrl+shift+", "hyper+");
- }
+ $.each(["alt", "ctrl", "shift"], function(index, specialKey) {
- if (special) {
- possible[modif + special] = true;
- }
- else {
- possible[modif + character] = true;
- possible[modif + $.hotkeys.shiftNums[character]] = true;
+ if (event[specialKey + 'Key'] && special !== specialKey) {
+ modif += specialKey + '+';
+ }
+ });
- // "$" can be triggered as "Shift+4" or "Shift+$" or just "$"
- if (modif === "shift+") {
- possible[$.hotkeys.shiftNums[character]] = true;
+ // metaKey is triggered off ctrlKey erronously
+ if (event.metaKey && !event.ctrlKey && special !== "meta") {
+ modif += "meta+";
}
- }
- for (var i = 0, l = keys.length; i < l; i++) {
- if (possible[keys[i]]) {
- return origHandler.apply(this, arguments);
+ if (event.metaKey && special !== "meta" && modif.indexOf("alt+ctrl+shift+") > -1) {
+ modif = modif.replace("alt+ctrl+shift+", "hyper+");
}
- }
- };
-}
+
+ if (special) {
+ possible[modif + special] = true;
+ }
+ else {
+ possible[modif + character] = true;
+ possible[modif + hotkeys.shiftNums[character]] = true;
+
+ // "$" can be triggered as "Shift+4" or "Shift+$" or just "$"
+ if (modif === "shift+") {
+ possible[hotkeys.shiftNums[character]] = true;
+ }
+ }
+
+ for (var i = 0, l = keys.length; i < l; i++) {
+ if (possible[keys[i]]) {
+ return origHandler.apply(this, arguments);
+ }
+ }
+ };
+ }
+};
$.each(["keydown", "keyup", "keypress"], function() {
$.event.special[this] = {
- add: keyHandler
+ add: hotkeys.keyHandler
};
});
+// Source: js/utils/i18n.js
+var Locales = {
+ 'en-US': {
+ "calendar": {
+ "months": [
+ "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December",
+ "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
+ ],
+ "days": [
+ "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday",
+ "Su", "Mo", "Tu", "We", "Th", "Fr", "Sa",
+ "Sun", "Mon", "Tus", "Wen", "Thu", "Fri", "Sat"
+ ],
+ "time": {
+ "days": "DAYS",
+ "hours": "HOURS",
+ "minutes": "MINS",
+ "seconds": "SECS",
+ "month": "MON",
+ "day": "DAY",
+ "year": "YEAR"
+ }
+ },
+ "buttons": {
+ "ok": "OK",
+ "cancel": "Cancel",
+ "done": "Done",
+ "today": "Today",
+ "now": "Now",
+ "clear": "Clear",
+ "help": "Help",
+ "yes": "Yes",
+ "no": "No",
+ "random": "Random"
+ }
+ },
+
+
+ 'cn-ZH': {
+ "calendar": {
+ "months": [
+ "一月", "二月", "三月", "四月", "五月", "六月", "七月", "八月", "九月", "十月", "十一月", "十二月",
+ "1月", "2月", "3月", "4月", "5月", "6月", "7月", "8月", "9月", "10月", "11月", "12月"
+ ],
+ "days": [
+ "星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六",
+ "日", "一", "二", "三", "四", "五", "六",
+ "周日", "周一", "周二", "周三", "周四", "周五", "周六"
+ ],
+ "time": {
+ "days": "天",
+ "hours": "时",
+ "minutes": "分",
+ "seconds": "秒",
+ "month": "月",
+ "day": "日",
+ "year": "年"
+ }
+ },
+ "buttons": {
+ "ok": "确认",
+ "cancel": "取消",
+ "done": "完成",
+ "today": "今天",
+ "now": "现在",
+ "clear": "清除",
+ "help": "帮助",
+ "yes": "是",
+ "no": "否",
+ "random": "随机"
+ }
+ },
+
+
+ 'de-DE': {
+ "calendar": {
+ "months": [
+ "Januar", "Februar", "März", "April", "Mai", "Juni", "Juli", "August", "September", "Oktober", "November", "Dezember",
+ "Jan", "Feb", "Mär", "Apr", "Mai", "Jun", "Jul", "Aug", "Sep", "Okt", "Nov", "Dez"
+ ],
+ "days": [
+ "Sonntag", "Montag", "Dienstag", "Mittwoch", "Donnerstag", "Freitag", "Samstag",
+ "Sn", "Mn", "Di", "Mi", "Do", "Fr", "Sa",
+ "Son", "Mon", "Die", "Mit", "Don", "Fre", "Sam"
+ ],
+ "time": {
+ "days": "TAGE",
+ "hours": "UHR",
+ "minutes": "MIN",
+ "seconds": "SEK"
+ }
+ },
+ "buttons": {
+ "ok": "OK",
+ "cancel": "Abbrechen",
+ "done": "Fertig",
+ "today": "Heute",
+ "now": "Jetzt",
+ "clear": "Reinigen",
+ "help": "Hilfe",
+ "yes": "Ja",
+ "no": "Nein",
+ "random": "Zufällig"
+ }
+ },
+
+ 'hu-HU': {
+ "calendar": {
+ "months": [
+ 'Január', 'Február', 'Március', 'Április', 'Május', 'Június', 'Július', 'Augusztus', 'Szeptember', 'Október', 'November', 'December',
+ 'Jan', 'Feb', 'Már', 'Ápr', 'Máj', 'Jún', 'Júl', 'Aug', 'Szep', 'Okt', 'Nov', 'Dec'
+ ],
+ "days": [
+ 'Vasárnap', 'Hétfő', 'Kedd', 'Szerda', 'Csütörtök', 'Péntek', 'Szombat',
+ 'V', 'H', 'K', 'Sz', 'Cs', 'P', 'Sz',
+ 'Vas', 'Hét', 'Ke', 'Sze', 'Csü', 'Pén', 'Szom'
+ ],
+ "time": {
+ "days": "NAP",
+ "hours": "ÓRA",
+ "minutes": "PERC",
+ "seconds": "MP"
+ }
+ },
+ "buttons": {
+ "ok": "OK",
+ "cancel": "Mégse",
+ "done": "Kész",
+ "today": "Ma",
+ "now": "Most",
+ "clear": "Törlés",
+ "help": "Segítség",
+ "yes": "Igen",
+ "no": "Nem",
+ "random": "Véletlen"
+ }
+ },
+
+ 'ru-RU': {
+ "calendar": {
+ "months": [
+ "Январь", "Февраль", "Март", "Апрель", "Май", "Июнь", "Июль", "Август", "Сентябрь", "Октябрь", "Ноябрь", "Декабрь",
+ "Янв", "Фев", "Мар", "Апр", "Май", "Июн", "Июл", "Авг", "Сен", "Окт", "Ноя", "Дек"
+ ],
+ "days": [
+ "Воскресенье", "Понедельник", "Вторник", "Среда", "Четверг", "Пятница", "Суббота",
+ "Вс", "Пн", "Вт", "Ср", "Чт", "Пт", "Сб",
+ "Вос", "Пон", "Вто", "Сре", "Чет", "Пят", "Суб"
+ ],
+ "time": {
+ "days": "ДНИ",
+ "hours": "ЧАСЫ",
+ "minutes": "МИН",
+ "seconds": "СЕК"
+ }
+ },
+ "buttons": {
+ "ok": "ОК",
+ "cancel": "Отмена",
+ "done": "Готово",
+ "today": "Сегодня",
+ "now": "Сейчас",
+ "clear": "Очистить",
+ "help": "Помощь",
+ "yes": "Да",
+ "no": "Нет",
+ "random": "Случайно"
+ }
+ },
+
+ 'uk-UA': {
+ "calendar": {
+ "months": [
+ "Січень", "Лютий", "Березень", "Квітень", "Травень", "Червень", "Липень", "Серпень", "Вересень", "Жовтень", "Листопад", "Грудень",
+ "Січ", "Лют", "Бер", "Кві", "Тра", "Чер", "Лип", "Сер", "Вер", "Жов", "Лис", "Гру"
+ ],
+ "days": [
+ "Неділя", "Понеділок", "Вівторок", "Середа", "Четвер", "П’ятниця", "Субота",
+ "Нд", "Пн", "Вт", "Ср", "Чт", "Пт", "Сб",
+ "Нед", "Пон", "Вiв", "Сер", "Чет", "Пят", "Суб"
+ ],
+ "time": {
+ "days": "ДНІ",
+ "hours": "ГОД",
+ "minutes": "ХВИЛ",
+ "seconds": "СЕК"
+ }
+ },
+ "buttons": {
+ "ok": "ОК",
+ "cancel": "Відміна",
+ "done": "Готово",
+ "today": "Сьогодні",
+ "now": "Зараз",
+ "clear": "Очистити",
+ "help": "Допомога",
+ "yes": "Так",
+ "no": "Ні",
+ "random": "Випадково"
+ }
+ }
+};
+
+Metro['locales'] = Locales;
+
+// Source: js/utils/md5.js
+var hexcase = 0;
+/* hex output format. 0 - lowercase; 1 - uppercase */
+var b64pad = "";
+/* base-64 pad character. "=" for strict RFC compliance */
+
+function hex_md5(s) {
+ return rstr2hex(rstr_md5(str2rstr_utf8(s)));
+}
+function b64_md5(s) {
+ return rstr2b64(rstr_md5(str2rstr_utf8(s)));
+}
+function any_md5(s, e) {
+ return rstr2any(rstr_md5(str2rstr_utf8(s)), e);
+}
+function hex_hmac_md5(k, d) {
+ return rstr2hex(rstr_hmac_md5(str2rstr_utf8(k), str2rstr_utf8(d)));
+}
+function b64_hmac_md5(k, d) {
+ return rstr2b64(rstr_hmac_md5(str2rstr_utf8(k), str2rstr_utf8(d)));
+}
+function any_hmac_md5(k, d, e) {
+ return rstr2any(rstr_hmac_md5(str2rstr_utf8(k), str2rstr_utf8(d)), e);
+}
+
+
+/*
+ * Calculate the MD5 of a raw string
+ */
+function rstr_md5(s) {
+ return binl2rstr(binl_md5(rstr2binl(s), s.length * 8));
+}
+
+/*
+ * Calculate the HMAC-MD5, of a key and some data (raw strings)
+ */
+function rstr_hmac_md5(key, data) {
+ var bkey = rstr2binl(key);
+ if (bkey.length > 16) bkey = binl_md5(bkey, key.length * 8);
+
+ var ipad = new Array(16), opad = new Array(16);
+ for (var i = 0; i < 16; i++) {
+ ipad[i] = bkey[i] ^ 0x36363636;
+ opad[i] = bkey[i] ^ 0x5C5C5C5C;
+ }
+
+ var hash = binl_md5(ipad.concat(rstr2binl(data)), 512 + data.length * 8);
+ return binl2rstr(binl_md5(opad.concat(hash), 512 + 128));
+}
+
+/*
+ * Convert a raw string to a hex string
+ */
+function rstr2hex(input) {
+ var hex_tab = hexcase ? "0123456789ABCDEF" : "0123456789abcdef";
+ var output = "";
+ var x;
+ for (var i = 0; i < input.length; i++) {
+ x = input.charCodeAt(i);
+ output += hex_tab.charAt((x >>> 4) & 0x0F)
+ + hex_tab.charAt(x & 0x0F);
+ }
+ return output;
+}
+
+/*
+ * Convert a raw string to a base-64 string
+ */
+function rstr2b64(input) {
+ var tab = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+ var output = "";
+ var len = input.length;
+ for (var i = 0; i < len; i += 3) {
+ var triplet = (input.charCodeAt(i) << 16)
+ | (i + 1 < len ? input.charCodeAt(i + 1) << 8 : 0)
+ | (i + 2 < len ? input.charCodeAt(i + 2) : 0);
+ for (var j = 0; j < 4; j++) {
+ if (i * 8 + j * 6 > input.length * 8) output += b64pad;
+ else output += tab.charAt((triplet >>> 6 * (3 - j)) & 0x3F);
+ }
+ }
+ return output;
+}
+
+/*
+ * Convert a raw string to an arbitrary string encoding
+ */
+function rstr2any(input, encoding) {
+ var divisor = encoding.length;
+ var i, j, q, x, quotient;
+
+ /* Convert to an array of 16-bit big-endian values, forming the dividend */
+ var dividend = new Array(Math.ceil(input.length / 2));
+ for (i = 0; i < dividend.length; i++) {
+ dividend[i] = (input.charCodeAt(i * 2) << 8) | input.charCodeAt(i * 2 + 1);
+ }
+
+ /*
+ * Repeatedly perform a long division. The binary array forms the dividend,
+ * the length of the encoding is the divisor. Once computed, the quotient
+ * forms the dividend for the next step. All remainders are stored for later
+ * use.
+ */
+ var full_length = Math.ceil(input.length * 8 /
+ (Math.log(encoding.length) / Math.log(2)));
+ var remainders = new Array(full_length);
+ for (j = 0; j < full_length; j++) {
+ quotient = [];
+ x = 0;
+ for (i = 0; i < dividend.length; i++) {
+ x = (x << 16) + dividend[i];
+ q = Math.floor(x / divisor);
+ x -= q * divisor;
+ if (quotient.length > 0 || q > 0)
+ quotient[quotient.length] = q;
+ }
+ remainders[j] = x;
+ dividend = quotient;
+ }
+
+ /* Convert the remainders to the output string */
+ var output = "";
+ for (i = remainders.length - 1; i >= 0; i--)
+ output += encoding.charAt(remainders[i]);
+
+ return output;
+}
+
+/*
+ * Encode a string as utf-8.
+ * For efficiency, this assumes the input is valid utf-16.
+ */
+function str2rstr_utf8(input) {
+ var output = "";
+ var i = -1;
+ var x, y;
+
+ while (++i < input.length) {
+ /* Decode utf-16 surrogate pairs */
+ x = input.charCodeAt(i);
+ y = i + 1 < input.length ? input.charCodeAt(i + 1) : 0;
+ if (0xD800 <= x && x <= 0xDBFF && 0xDC00 <= y && y <= 0xDFFF) {
+ x = 0x10000 + ((x & 0x03FF) << 10) + (y & 0x03FF);
+ i++;
+ }
+
+ /* Encode output as utf-8 */
+ if (x <= 0x7F)
+ output += String.fromCharCode(x);
+ else if (x <= 0x7FF)
+ output += String.fromCharCode(0xC0 | ((x >>> 6 ) & 0x1F),
+ 0x80 | ( x & 0x3F));
+ else if (x <= 0xFFFF)
+ output += String.fromCharCode(0xE0 | ((x >>> 12) & 0x0F),
+ 0x80 | ((x >>> 6 ) & 0x3F),
+ 0x80 | ( x & 0x3F));
+ else if (x <= 0x1FFFFF)
+ output += String.fromCharCode(0xF0 | ((x >>> 18) & 0x07),
+ 0x80 | ((x >>> 12) & 0x3F),
+ 0x80 | ((x >>> 6 ) & 0x3F),
+ 0x80 | ( x & 0x3F));
+ }
+ return output;
+}
+
+/*
+ * Convert a raw string to an array of little-endian words
+ * Characters >255 have their high-byte silently ignored.
+ */
+function rstr2binl(input) {
+ var i;
+ var output = new Array(input.length >> 2);
+ for (i = 0; i < output.length; i++)
+ output[i] = 0;
+ for (i = 0; i < input.length * 8; i += 8)
+ output[i >> 5] |= (input.charCodeAt(i / 8) & 0xFF) << (i % 32);
+ return output;
+}
+
+/*
+ * Convert an array of little-endian words to a string
+ */
+function binl2rstr(input) {
+ var output = "";
+ for (var i = 0; i < input.length * 32; i += 8)
+ output += String.fromCharCode((input[i >> 5] >>> (i % 32)) & 0xFF);
+ return output;
+}
+
+/*
+ * Calculate the MD5 of an array of little-endian words, and a bit length.
+ */
+function binl_md5(x, len) {
+ /* append padding */
+ x[len >> 5] |= 0x80 << ((len) % 32);
+ x[(((len + 64) >>> 9) << 4) + 14] = len;
+
+ var a = 1732584193;
+ var b = -271733879;
+ var c = -1732584194;
+ var d = 271733878;
+
+ for (var i = 0; i < x.length; i += 16) {
+ var olda = a;
+ var oldb = b;
+ var oldc = c;
+ var oldd = d;
+
+ a = md5_ff(a, b, c, d, x[i], 7, -680876936);
+ d = md5_ff(d, a, b, c, x[i + 1], 12, -389564586);
+ c = md5_ff(c, d, a, b, x[i + 2], 17, 606105819);
+ b = md5_ff(b, c, d, a, x[i + 3], 22, -1044525330);
+ a = md5_ff(a, b, c, d, x[i + 4], 7, -176418897);
+ d = md5_ff(d, a, b, c, x[i + 5], 12, 1200080426);
+ c = md5_ff(c, d, a, b, x[i + 6], 17, -1473231341);
+ b = md5_ff(b, c, d, a, x[i + 7], 22, -45705983);
+ a = md5_ff(a, b, c, d, x[i + 8], 7, 1770035416);
+ d = md5_ff(d, a, b, c, x[i + 9], 12, -1958414417);
+ c = md5_ff(c, d, a, b, x[i + 10], 17, -42063);
+ b = md5_ff(b, c, d, a, x[i + 11], 22, -1990404162);
+ a = md5_ff(a, b, c, d, x[i + 12], 7, 1804603682);
+ d = md5_ff(d, a, b, c, x[i + 13], 12, -40341101);
+ c = md5_ff(c, d, a, b, x[i + 14], 17, -1502002290);
+ b = md5_ff(b, c, d, a, x[i + 15], 22, 1236535329);
+
+ a = md5_gg(a, b, c, d, x[i + 1], 5, -165796510);
+ d = md5_gg(d, a, b, c, x[i + 6], 9, -1069501632);
+ c = md5_gg(c, d, a, b, x[i + 11], 14, 643717713);
+ b = md5_gg(b, c, d, a, x[i], 20, -373897302);
+ a = md5_gg(a, b, c, d, x[i + 5], 5, -701558691);
+ d = md5_gg(d, a, b, c, x[i + 10], 9, 38016083);
+ c = md5_gg(c, d, a, b, x[i + 15], 14, -660478335);
+ b = md5_gg(b, c, d, a, x[i + 4], 20, -405537848);
+ a = md5_gg(a, b, c, d, x[i + 9], 5, 568446438);
+ d = md5_gg(d, a, b, c, x[i + 14], 9, -1019803690);
+ c = md5_gg(c, d, a, b, x[i + 3], 14, -187363961);
+ b = md5_gg(b, c, d, a, x[i + 8], 20, 1163531501);
+ a = md5_gg(a, b, c, d, x[i + 13], 5, -1444681467);
+ d = md5_gg(d, a, b, c, x[i + 2], 9, -51403784);
+ c = md5_gg(c, d, a, b, x[i + 7], 14, 1735328473);
+ b = md5_gg(b, c, d, a, x[i + 12], 20, -1926607734);
+
+ a = md5_hh(a, b, c, d, x[i + 5], 4, -378558);
+ d = md5_hh(d, a, b, c, x[i + 8], 11, -2022574463);
+ c = md5_hh(c, d, a, b, x[i + 11], 16, 1839030562);
+ b = md5_hh(b, c, d, a, x[i + 14], 23, -35309556);
+ a = md5_hh(a, b, c, d, x[i + 1], 4, -1530992060);
+ d = md5_hh(d, a, b, c, x[i + 4], 11, 1272893353);
+ c = md5_hh(c, d, a, b, x[i + 7], 16, -155497632);
+ b = md5_hh(b, c, d, a, x[i + 10], 23, -1094730640);
+ a = md5_hh(a, b, c, d, x[i + 13], 4, 681279174);
+ d = md5_hh(d, a, b, c, x[i], 11, -358537222);
+ c = md5_hh(c, d, a, b, x[i + 3], 16, -722521979);
+ b = md5_hh(b, c, d, a, x[i + 6], 23, 76029189);
+ a = md5_hh(a, b, c, d, x[i + 9], 4, -640364487);
+ d = md5_hh(d, a, b, c, x[i + 12], 11, -421815835);
+ c = md5_hh(c, d, a, b, x[i + 15], 16, 530742520);
+ b = md5_hh(b, c, d, a, x[i + 2], 23, -995338651);
+
+ a = md5_ii(a, b, c, d, x[i], 6, -198630844);
+ d = md5_ii(d, a, b, c, x[i + 7], 10, 1126891415);
+ c = md5_ii(c, d, a, b, x[i + 14], 15, -1416354905);
+ b = md5_ii(b, c, d, a, x[i + 5], 21, -57434055);
+ a = md5_ii(a, b, c, d, x[i + 12], 6, 1700485571);
+ d = md5_ii(d, a, b, c, x[i + 3], 10, -1894986606);
+ c = md5_ii(c, d, a, b, x[i + 10], 15, -1051523);
+ b = md5_ii(b, c, d, a, x[i + 1], 21, -2054922799);
+ a = md5_ii(a, b, c, d, x[i + 8], 6, 1873313359);
+ d = md5_ii(d, a, b, c, x[i + 15], 10, -30611744);
+ c = md5_ii(c, d, a, b, x[i + 6], 15, -1560198380);
+ b = md5_ii(b, c, d, a, x[i + 13], 21, 1309151649);
+ a = md5_ii(a, b, c, d, x[i + 4], 6, -145523070);
+ d = md5_ii(d, a, b, c, x[i + 11], 10, -1120210379);
+ c = md5_ii(c, d, a, b, x[i + 2], 15, 718787259);
+ b = md5_ii(b, c, d, a, x[i + 9], 21, -343485551);
+
+ a = safe_add(a, olda);
+ b = safe_add(b, oldb);
+ c = safe_add(c, oldc);
+ d = safe_add(d, oldd);
+ }
+ return [a, b, c, d];
+}
+
+/*
+ * These functions implement the four basic operations the algorithm uses.
+ */
+function md5_cmn(q, a, b, x, s, t) {
+ return safe_add(bit_rol(safe_add(safe_add(a, q), safe_add(x, t)), s), b);
+}
+function md5_ff(a, b, c, d, x, s, t) {
+ return md5_cmn((b & c) | ((~b) & d), a, b, x, s, t);
+}
+function md5_gg(a, b, c, d, x, s, t) {
+ return md5_cmn((b & d) | (c & (~d)), a, b, x, s, t);
+}
+function md5_hh(a, b, c, d, x, s, t) {
+ return md5_cmn(b ^ c ^ d, a, b, x, s, t);
+}
+function md5_ii(a, b, c, d, x, s, t) {
+ return md5_cmn(c ^ (b | (~d)), a, b, x, s, t);
+}
+
+/*
+ * Add integers, wrapping at 2^32. This uses 16-bit operations internally
+ * to work around bugs in some JS interpreters.
+ */
+function safe_add(x, y) {
+ var lsw = (x & 0xFFFF) + (y & 0xFFFF);
+ var msw = (x >> 16) + (y >> 16) + (lsw >> 16);
+ return (msw << 16) | (lsw & 0xFFFF);
+}
+
+/*
+ * Bitwise rotate a 32-bit number to the left.
+ */
+function bit_rol(num, cnt) {
+ return (num << cnt) | (num >>> (32 - cnt));
+}
+
+
+// window.md5 = {
+// hex: function(val){
+// return hex_md5(val);
+// },
+//
+// b64: function(val){
+// return b64_md5(val);
+// },
+//
+// any: function(s, e){
+// return any_md5(s, e);
+// },
+//
+// hex_hmac: function(k, d){
+// return hex_hmac_md5(k, d);
+// },
+//
+// b64_hmac: function(k, d){
+// return b64_hmac_md5(k, d);
+// },
+//
+// any_hmac: function(k, d, e){
+// return any_hmac_md5(k, d, e);
+// }
+// };
+
+//$.Metro['md5'] = hex_md5;
// Source: js/utils/mousewheel.js
-var toFix = ['wheel', 'mousewheel', 'DOMMouseScroll', 'MozMousePixelScroll'];
-var toBind = 'onwheel' in document || document.documentMode >= 9 ? ['wheel'] : ['mousewheel', 'DomMouseScroll', 'MozMousePixelScroll'];
-var lowestDelta, lowestDeltaXY;
+var toFix = ['wheel', 'mousewheel', 'DOMMouseScroll', 'MozMousePixelScroll'],
+ toBind = ( 'onwheel' in document || document.documentMode >= 9 ) ?
+ ['wheel'] : ['mousewheel', 'DomMouseScroll', 'MozMousePixelScroll'],
+ slice = Array.prototype.slice,
+ nullLowestDeltaTimeout, lowestDelta;
if ( $.event.fixHooks ) {
for ( var i = toFix.length; i; ) {
@@ -1533,199 +2435,335 @@ if ( $.event.fixHooks ) {
}
$.event.special.mousewheel = {
+ version: '3.1.12',
+
setup: function() {
if ( this.addEventListener ) {
for ( var i = toBind.length; i; ) {
- this.addEventListener( toBind[--i], handler, false );
+ this.addEventListener( toBind[--i], mousewheel_handler, false );
}
} else {
- this.onmousewheel = handler;
+ this.onmousewheel = mousewheel_handler;
}
+ // Store the line height and page height for this particular element
+
+ $.data(this, 'mousewheel-line-height', $.event.special.mousewheel.getLineHeight(this));
+ $.data(this, 'mousewheel-page-height', $.event.special.mousewheel.getPageHeight(this));
},
teardown: function() {
if ( this.removeEventListener ) {
for ( var i = toBind.length; i; ) {
- this.removeEventListener( toBind[--i], handler, false );
+ this.removeEventListener( toBind[--i], mousewheel_handler, false );
}
} else {
this.onmousewheel = null;
}
+ // Clean up the data we added to the element
+ $.removeData(this, 'mousewheel-line-height');
+ $.removeData(this, 'mousewheel-page-height');
+ },
+
+ getLineHeight: function(elem) {
+ var $elem = $(elem),
+ $parent = $elem['offsetParent' in $.fn ? 'offsetParent' : 'parent']();
+ if (!$parent.length) {
+ $parent = $('body');
+ }
+ return parseInt($parent.css('fontSize'), 10) || parseInt($elem.css('fontSize'), 10) || 16;
+ },
+
+ getPageHeight: function(elem) {
+ return $(elem).height();
+ },
+
+ settings: {
+ adjustOldDeltas: true, // see shouldAdjustOldDeltas() below
+ normalizeOffset: true // calls getBoundingClientRect for each event
}
};
$.fn.extend({
mousewheel: function(fn) {
- return fn ? this.bind("mousewheel", fn) : this.trigger("mousewheel");
+ return fn ? this.bind('mousewheel', fn) : this.trigger('mousewheel');
},
unmousewheel: function(fn) {
- return this.unbind("mousewheel", fn);
+ return this.unbind('mousewheel', fn);
}
});
-function handler(event) {
- var orgEvent = event || window.event,
- args = [].slice.call(arguments, 1),
- delta = 0,
- deltaX = 0,
- deltaY = 0,
- absDelta = 0,
- absDeltaXY = 0,
- fn;
+function mousewheel_handler(event) {
+ var orgEvent = event || window.event,
+ args = slice.call(arguments, 1),
+ delta = 0,
+ deltaX = 0,
+ deltaY = 0,
+ absDelta = 0,
+ offsetX = 0,
+ offsetY = 0;
event = $.event.fix(orgEvent);
- event.type = "mousewheel";
+ event.type = 'mousewheel';
// Old school scrollwheel delta
- if ( orgEvent.wheelDelta ) { delta = orgEvent.wheelDelta; }
- if ( orgEvent.detail ) { delta = orgEvent.detail * -1; }
+ if ( 'detail' in orgEvent ) { deltaY = orgEvent.detail * -1; }
+ if ( 'wheelDelta' in orgEvent ) { deltaY = orgEvent.wheelDelta; }
+ if ( 'wheelDeltaY' in orgEvent ) { deltaY = orgEvent.wheelDeltaY; }
+ if ( 'wheelDeltaX' in orgEvent ) { deltaX = orgEvent.wheelDeltaX * -1; }
+
+ // Firefox < 17 horizontal scrolling related to DOMMouseScroll event
+ if ( 'axis' in orgEvent && orgEvent.axis === orgEvent.HORIZONTAL_AXIS ) {
+ deltaX = deltaY * -1;
+ deltaY = 0;
+ }
+
+ // Set delta to be deltaY or deltaX if deltaY is 0 for backwards compatabilitiy
+ delta = deltaY === 0 ? deltaX : deltaY;
// New school wheel delta (wheel event)
- if ( orgEvent.deltaY ) {
+ if ( 'deltaY' in orgEvent ) {
deltaY = orgEvent.deltaY * -1;
delta = deltaY;
}
- if ( orgEvent.deltaX ) {
+ if ( 'deltaX' in orgEvent ) {
deltaX = orgEvent.deltaX;
- delta = deltaX * -1;
+ if ( deltaY === 0 ) { delta = deltaX * -1; }
+ }
+
+ // No change actually happened, no reason to go any further
+ if ( deltaY === 0 && deltaX === 0 ) { return; }
+
+ // Need to convert lines and pages to pixels if we aren't already in pixels
+ // There are three delta modes:
+ // * deltaMode 0 is by pixels, nothing to do
+ // * deltaMode 1 is by lines
+ // * deltaMode 2 is by pages
+
+ if ( orgEvent.deltaMode === 1 ) {
+ var lineHeight = $.data(this, 'mousewheel-line-height');
+ delta *= lineHeight;
+ deltaY *= lineHeight;
+ deltaX *= lineHeight;
+ } else if ( orgEvent.deltaMode === 2 ) {
+ var pageHeight = $.data(this, 'mousewheel-page-height');
+ delta *= pageHeight;
+ deltaY *= pageHeight;
+ deltaX *= pageHeight;
+ }
+
+ // Store lowest absolute delta to normalize the delta values
+ absDelta = Math.max( Math.abs(deltaY), Math.abs(deltaX) );
+
+ if ( !lowestDelta || absDelta < lowestDelta ) {
+ lowestDelta = absDelta;
+
+ // Adjust older deltas if necessary
+ if ( shouldAdjustOldDeltas(orgEvent, absDelta) ) {
+ lowestDelta /= 40;
+ }
+ }
+
+ // Adjust older deltas if necessary
+ if ( shouldAdjustOldDeltas(orgEvent, absDelta) ) {
+ // Divide all the things by 40!
+ delta /= 40;
+ deltaX /= 40;
+ deltaY /= 40;
}
- // Webkit
- if ( orgEvent.wheelDeltaY !== undefined ) { deltaY = orgEvent.wheelDeltaY; }
- if ( orgEvent.wheelDeltaX !== undefined ) { deltaX = orgEvent.wheelDeltaX * -1; }
+ // Get a whole, normalized value for the deltas
+ delta = Math[ delta >= 1 ? 'floor' : 'ceil' ](delta / lowestDelta);
+ deltaX = Math[ deltaX >= 1 ? 'floor' : 'ceil' ](deltaX / lowestDelta);
+ deltaY = Math[ deltaY >= 1 ? 'floor' : 'ceil' ](deltaY / lowestDelta);
- // Look for lowest delta to normalize the delta values
- absDelta = Math.abs(delta);
- if ( !lowestDelta || absDelta < lowestDelta ) { lowestDelta = absDelta; }
- absDeltaXY = Math.max(Math.abs(deltaY), Math.abs(deltaX));
- if ( !lowestDeltaXY || absDeltaXY < lowestDeltaXY ) { lowestDeltaXY = absDeltaXY; }
+ // Normalise offsetX and offsetY properties
+ if ( $.event.special.mousewheel.settings.normalizeOffset && this.getBoundingClientRect ) {
+ var boundingRect = this.getBoundingClientRect();
+ offsetX = event.clientX - boundingRect.left;
+ offsetY = event.clientY - boundingRect.top;
+ }
- // Get a whole value for the deltas
- fn = delta > 0 ? 'floor' : 'ceil';
- delta = Math[fn](delta / lowestDelta);
- deltaX = Math[fn](deltaX / lowestDeltaXY);
- deltaY = Math[fn](deltaY / lowestDeltaXY);
+ // Add information to the event object
+ event.deltaX = deltaX;
+ event.deltaY = deltaY;
+ event.deltaFactor = lowestDelta;
+ event.offsetX = offsetX;
+ event.offsetY = offsetY;
+ // Go ahead and set deltaMode to 0 since we converted to pixels
+ // Although this is a little odd since we overwrite the deltaX/Y
+ // properties with normalized deltas.
+ event.deltaMode = 0;
// Add event and delta to the front of the arguments
args.unshift(event, delta, deltaX, deltaY);
+ // Clearout lowestDelta after sometime to better
+ // handle multiple device types that give different
+ // a different lowestDelta
+ // Ex: trackpad = 3 and mouse wheel = 120
+ if (nullLowestDeltaTimeout) { clearTimeout(nullLowestDeltaTimeout); }
+ nullLowestDeltaTimeout = setTimeout(nullLowestDelta, 200);
+
return ($.event.dispatch || $.event.handle).apply(this, args);
}
-// Source: js/utils/pre-code.js
-function preCode(selector) {
- var els = Array.prototype.slice.call(document.querySelectorAll(selector), 0);
+function nullLowestDelta() {
+ lowestDelta = null;
+}
- els.forEach(function(el, idx, arr){
- var txt = el.textContent
- .replace(/^[\r\n]+/, "") // strip leading newline
- .replace(/\s+$/g, "");
+function shouldAdjustOldDeltas(orgEvent, absDelta) {
+ // If this is an older event and the delta is divisable by 120,
+ // then we are assuming that the browser is treating this as an
+ // older mouse wheel event and that we should divide the deltas
+ // by 40 to try and get a more usable deltaFactor.
+ // Side note, this actually impacts the reported scroll distance
+ // in older browsers and can cause scrolling to be slower than native.
+ // Turn this off by setting $.event.special.mousewheel.settings.adjustOldDeltas to false.
+ return $.event.special.mousewheel.settings.adjustOldDeltas && orgEvent.type === 'mousewheel' && absDelta % 120 === 0;
+}
+// Source: js/utils/scroll-events.js
+var dispatch = $.event.dispatch || $.event.handle;
+var special = jQuery.event.special,
+ uid1 = 'D' + (+new Date()),
+ uid2 = 'D' + (+new Date() + 1);
+
+special.scrollstart = {
+ setup: function(data) {
+ var _data = $.extend({
+ latency: special.scrollstop.latency
+ }, data);
+
+ var timer,
+ handler = function(evt) {
+ var _self = this;
+
+ if (timer) {
+ clearTimeout(timer);
+ timer = null;
+ } else {
+ evt.type = 'scrollstart';
+ dispatch.apply(_self, arguments);
+ }
- if (/^\S/gm.test(txt)) {
- el.textContent = txt;
- return;
- }
+ timer = setTimeout(function() {
+ timer = null;
+ }, _data.latency);
+ };
- var mat, str, re = /^[\t ]+/gm, len, min = 1e3;
+ $(this).on('scroll', handler).data(uid1, handler);
+ },
+ teardown: function() {
+ $(this).off('scroll', $(this).data(uid1));
+ }
+};
- while (mat = re.exec(txt)) {
- len = mat[0].length;
+special.scrollstop = {
+ latency: 250,
+ setup: function(data) {
+ var _data = $.extend({
+ latency: special.scrollstop.latency
+ }, data);
- if (len < min) {
- min = len;
- str = mat[0];
- }
- }
+ var timer,
+ handler = function(evt) {
+ var _self = this,
+ _args = arguments;
- if (min == 1e3)
- return;
+ if (timer) {
+ clearTimeout(timer);
+ timer = null;
+ }
- el.textContent = txt.replace(new RegExp("^" + str, 'gm'), "");
- });
-}
+ timer = setTimeout(function() {
+ timer = null;
+ evt.type = 'scrollstop';
+ dispatch.apply(_self, _args);
+ }, _data.latency);
+ };
-document.addEventListener("DOMContentLoaded", function() {
- preCode("pre code, textarea");
-}, false);
-// Source: js/utils/touch-handler.js
-var hasTouch = 'ontouchend' in window, eventTimer;
-var moveDirection = 'undefined', startX, startY, deltaX, deltaY, mouseDown = false;
-
-var addTouchEvents = function(element) {
- if (hasTouch) {
- element.addEventListener("touchstart", touch2Mouse, true);
- element.addEventListener("touchmove", touch2Mouse, true);
- element.addEventListener("touchend", touch2Mouse, true);
+ $(this).on('scroll', handler).data(uid2, handler);
+ },
+ teardown: function() {
+ $(this).off('scroll', $(this).data(uid2));
}
};
-function touch2Mouse(e) {
- var theTouch = e.changedTouches[0];
- var mouseEv;
-
- switch (e.type) {
- case "touchstart":
- mouseEv = "mousedown";
- break;
- case "touchend":
- mouseEv = "mouseup";
- break;
- case "touchmove":
- mouseEv = "mousemove";
- break;
- default:
- return;
- }
+// Source: js/utils/storage.js
+var Storage = {
+ key: "METRO:APP",
+ init: function( options, elem ) {
+ this.options = $.extend( {}, this.options, options );
- if (mouseEv == "mousedown") {
- eventTimer = (new Date()).getTime();
- startX = theTouch.clientX;
- startY = theTouch.clientY;
- mouseDown = true;
- }
+ return this;
+ },
+
+ nvl: function(data, other){
+ return data === undefined || data === null ? other : data;
+ },
+
+ setKey: function(key){
+ this.key = key;
+ },
+
+ getKey: function(){
+ return this.key;
+ },
+
+ setItem: function(key, value){
+ window.localStorage.setItem(this.key + ":" + key, JSON.stringify(value));
+ },
+
+ getItem: function(key, default_value, reviver){
+ var result, value;
- if (mouseEv == "mouseup") {
- if ((new Date()).getTime() - eventTimer <= 500) {
- mouseEv = "click";
- } else if ((new Date()).getTime() - eventTimer > 1000) {
- mouseEv = "longclick";
+ value = this.nvl(window.localStorage.getItem(this.key + ":" + key), default_value);
+
+ try {
+ result = JSON.parse(value, reviver);
+ } catch (e) {
+ result = null;
}
- eventTimer = 0;
- mouseDown = false;
- }
+ return result;
+ },
+
+ getItemPart: function(key, sub_key, default_value, reviver){
+ var i;
+ var val = this.getItem(key, default_value, reviver);
- if (mouseEv == "mousemove") {
- if (mouseDown) {
- deltaX = theTouch.clientX - startX;
- deltaY = theTouch.clientY - startY;
- moveDirection = deltaX > deltaY ? 'horizontal' : 'vertical';
+ sub_key = sub_key.split("->");
+ for(i = 0; i < sub_key.length; i++) {
+ val = val[sub_key[i]];
}
- }
+ return val;
+ },
- var mouseEvent = document.createEvent("MouseEvent");
- mouseEvent.initMouseEvent(mouseEv, true, true, window, 1, theTouch.screenX, theTouch.screenY, theTouch.clientX, theTouch.clientY, false, false, false, false, 0, null);
- theTouch.target.dispatchEvent(mouseEvent);
+ delItem: function(key){
+ window.localStorage.removeItem(this.key + ":" + key)
+ },
- e.preventDefault();
-}
+ size: function(unit){
+ var divider;
+ switch (unit) {
+ case 'm':
+ case 'M': {
+ divider = 1024 * 1024;
+ break;
+ }
+ case 'k':
+ case 'K': {
+ divider = 1024;
+ break;
+ }
+ default: divider = 1;
+ }
+ return JSON.stringify(window.localStorage).length / divider;
+ }
+};
+Metro['storage'] = Storage.init();
// Source: js/utils/tpl.js
-// var template =
-// 'My skills:' +
-// '<%if(this.showSkills) {%>' +
-// '<%for(var index in this.skills) {%>' +
-// '
<%this.skills[index]%>' +
-// '<%}%>' +
-// '<%} else {%>' +
-// '
none
' +
-// '<%}%>';
-// console.log(TemplateEngine(template, {
-// skills: ["js", "html", "css"],
-// showSkills: true
-// }));
-
var TemplateEngine = function(html, options) {
var re = /<%(.+?)%>/g,
reExp = /(^( )?(var|if|for|else|switch|case|break|{|}|;))(.*)?/g,
@@ -1735,7 +2773,7 @@ var TemplateEngine = function(html, options) {
match;
var add = function(line, js) {
js? (code += line.match(reExp) ? line + '\n' : 'r.push(' + line + ');\n') :
- (code += line != '' ? 'r.push("' + line.replace(/"/g, '\\"') + '");\n' : '');
+ (code += line !== '' ? 'r.push("' + line.replace(/"/g, '\\"') + '");\n' : '');
return add;
};
while(match = re.exec(html)) {
@@ -1749,1084 +2787,926 @@ var TemplateEngine = function(html, options) {
return result;
};
-window.metroTemplate = TemplateEngine;
+Metro['template'] = TemplateEngine;
-$.Template = TemplateEngine;
-// Source: js/widgets/accordion.js
-$.widget("metro.accordion", {
-
- version: "3.0.0",
+// Source: js/utils/utilities.js
+var Utils = {
+ isUrl: function (val) {
+ return /^(ftp|http|https):\/\/(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@\-\/]))?/.test(val);
+ },
- options: {
- closeAny: false,
- speed: 'fast',
- onFrameOpen: function(frame){return true;},
- onFrameOpened: function(frame){},
- onFrameClose: function(frame){return true;},
- onFrameClosed: function(frame){}
+ isTag: function(val){
+ return /^<\/?[\w\s="/.':;#-\/\?]+>/gi.test(val);
},
- init: function(){
- var that = this, element = this.element;
+ isColor: function (val) {
+ return /(^#[0-9A-F]{6}$)|(^#[0-9A-F]{3}$)/i.test(val);
+ },
- element.on('click', '.heading', function(e){
- var frame = $(this).parent();
+ isEmbedObject: function(val){
+ var embed = ["iframe", "object", "embed", "video"];
+ var result = false;
+ $.each(embed, function(){
+ if (val.indexOf(this) !== -1) {
+ result = true;
+ }
+ });
+ return result;
+ },
- if (frame.hasClass('disabled')) {return false;}
+ isVideoUrl: function(val){
+ return /youtu\.be|youtube|vimeo/gi.test(val);
+ },
- if (!frame.hasClass('active')) {
- that._openFrame(frame);
- } else {
- that._closeFrame(frame);
- }
+ isDate: function(val){
+ return (String(new Date(val)) !== "Invalid Date");
+ },
- e.preventDefault();
- e.stopPropagation();
- });
+ isInt: function(n){
+ return Number(n) === n && n % 1 === 0;
},
- _closeAllFrames: function(){
- var that = this;
- var frames = this.element.children('.frame.active');
- $.each(frames, function(){
- that._closeFrame($(this));
- });
+ isFloat: function(n){
+ return Number(n) === n && n % 1 !== 0;
},
- _openFrame: function(frame){
- var o = this.options;
- var content = frame.children('.content');
- var result;
+ isTouchDevice: function() {
+ return (('ontouchstart' in window)
+ || (navigator.MaxTouchPoints > 0)
+ || (navigator.msMaxTouchPoints > 0));
+ },
- if (typeof o.onFrameOpen === 'function') {
- if (!o.onFrameOpen(frame)) {return false;}
- } else {
- if (typeof window[o.onFrameOpen] === 'function') {
- if (!window[o.onFrameOpen](frame)) {return false;}
- } else {
- result = eval("(function(){"+o.onFrameOpen+"})");
- if (!result.call(frame)) {return false;}
- }
- }
+ isFunc: function(f){
+ return this.isType(f, 'function');
+ },
- if (o.closeAny) {this._closeAllFrames();}
+ isObject: function(o){
+ return this.isType(o, 'object')
+ },
- content.slideDown(o.speed);
- frame.addClass('active');
+ isArray: function(a){
+ return Array.isArray(a);
+ },
- if (typeof o.onFrameOpened === 'function') {
- o.onFrameOpened(frame);
- } else {
- if (typeof window[o.onFrameOpened] === 'function') {
- window[o.onFrameOpened](frame);
- } else {
- result = eval("(function(){"+o.onFrameOpened+"})");
- result.call(frame);
- }
+ isType: function(o, t){
+ if (o === undefined || o === null) {
+ return false;
}
- },
- _closeFrame: function(frame){
- var o = this.options;
- var content = frame.children('.content');
- var result;
+ if (typeof o === t) {
+ return o;
+ }
- if (typeof o.onFrameClose === 'function') {
- if (!o.onFrameClose(frame)) {return false;}
- } else {
- if (typeof window[o.onFrameClose] === 'function') {
- if (!window[o.onFrameClose](frame)) {return false;}
- } else {
- result = eval("(function(){"+o.onFrameClose+"})");
- if (!result.call(frame)) {return false;}
- }
+ if (this.isTag(o) || this.isUrl(o)) {
+ return false;
}
- content.slideUp(o.speed,function(){
- frame.removeClass("active");
- });
+ if (typeof window[o] === t) {
+ return window[o];
+ }
- if (typeof o.onFrameClosed === 'function') {
- o.onFrameClosed(frame);
- } else {
- if (typeof window[o.onFrameClosed] === 'function') {
- window[o.onFrameClosed](frame);
- } else {
- result = eval("(function(){"+o.onFrameClosed+"})");
- result.call(frame);
- }
+ if (typeof o === 'string' && o.indexOf(".") === -1) {
+ return false;
}
- },
- _create: function(){
- var that = this, o = this.options, element = this.element;
+ if (typeof o === 'string' && o.indexOf(" ") !== -1) {
+ return false;
+ }
- $.each(this.element.data(), function(key, value){
- if (key in o) {
- try {
- o[key] = $.parseJSON(value);
- } catch (e) {
- o[key] = value;
- }
- }
- });
+ if (typeof o === 'string' && o.indexOf("(") !== -1) {
+ return false;
+ }
- that.init();
- element.data('accordion', this);
+ if (typeof o === 'string' && o.indexOf("[") !== -1) {
+ return false;
+ }
- },
+ var ns = o.split(".");
+ var i, context = window;
- _destroy: function(){
+ for(i = 0; i < ns.length; i++) {
+ context = context[ns[i]];
+ }
+
+ return typeof context === t ? context : false;
},
- _setOption: function(key, value){
- this._super('_setOption', key, value);
- }
-});
+ isMetroObject: function(el, type){
+ var $el = $(el), el_obj = $el.data(type);
+ if ($el.length === 0) {
+ console.log(type + ' ' + el + ' not found!');
+ return false;
+ }
-// Source: js/widgets/appbar.js
- $.widget("metro.appbar", {
- version: "3.0.0",
- options: {
- flexstyle: "app-bar-menu", //app-bar-menu | YOUR_OWN class for the pull flexmenu, basic support for "sidebar2" are integrated in the appbar.less file
- flexclean: false, //true | false. if set all entries except the no-flexible ones will removed
- flextolerance: 3 //in px. if set the freespace is runnig out a little bit earlier, so floats
- //and not no-wrap elements have no chance to wrap. help for rounding errors also
- },
- _create: function () {
- var that = this, element = this.element, o = this.options;
-
- $.each(element.data(), function (key, value) {
- if (key in o) {
- try {
- o[key] = $.parseJSON(value);
- } catch (e) {
- o[key] = value;
- }
- }
- });
+ if (el_obj === undefined) {
+ console.log('Element not contain role '+ type +'! Please add attribute data-role="'+type+'" to element ' + el);
+ return false;
+ }
- this._initBar();
+ return true;
+ },
- element.data('appbar', this);
+ isJQueryObject: function(el){
+ return (typeof jQuery === "function" && el instanceof jQuery);
+ },
- },
- _calculateFreeSpace: function () {
- var that = this, element = this.element, o = this.options;
- var menusParentWidth = 0, childrenWidth = 0, children;
- var freeSpace;
-
- //get the overall free space from the wrapping parent of the menus
- menusParentWidth = $(that.menusParent).width();
-
- //get the width of all visible children
- children = $(that.menusParent).children(":visible").not(".app-bar-pullmenu");
-
-
- //margin support: because there could be margins between elements, we do not summarize the width up with a one liner
- //but calculate width of all children in an intelligent way, we takte the left offsett of the first element and right offset of the right element
- //for that we have to support float left and right too:
- //float left and right support: we can not be sure that the first element in dom is on the left and the last is on the right
- //right floated
- // - sort the children as the user see them
-
- //sort the children as the user see them according to the css float
- var childrenLeftFloated = [];
- var childrenRightFloated = [];
- var childrenAsUsual = [];
- var floatState;
-
- for (var i = 0, len = children.length; i < len; i++) {
- floatState = $(children[i]).css("float");
- switch (floatState) {
- case "left":
- childrenLeftFloated.push(children[i]);
- break;
- case "right":
- childrenRightFloated.push(children[i]);
- break;
- default:
- childrenAsUsual.push(children[i]);
- }
- }
- //right floats are from right to left
- childrenRightFloated.reverse();
+ embedObject: function(val){
+ if (typeof val !== "string" ) {
+ val = this.isJQueryObject(val) ? val.html() : val.innerHTML;
+ }
+ return "
" + val + "
";
+ },
- //=== build up the new children jquery object ===
- //join the left, right and normal children
- children = new Array();
- children = childrenLeftFloated.concat(childrenAsUsual, childrenRightFloated);
+ embedUrl: function(val){
+ if (val.indexOf("youtu.be") !== -1) {
+ val = "https://www.youtube.com/embed/" + val.split("/").pop();
+ }
+ return "
";
+ },
- //convert the array to jquery object again
- children = $(children);
+ secondsToTime: function(secs) {
+ var hours = Math.floor(secs / (60 * 60));
- //=== calculate the width of the elements with margin support ===
+ var divisor_for_minutes = secs % (60 * 60);
+ var minutes = Math.floor(divisor_for_minutes / 60);
- //adds the left margin dedicated to the first child
- childrenWidth += parseInt($(children).first().css("margin-left"));
+ var divisor_for_seconds = divisor_for_minutes % 60;
+ var seconds = Math.ceil(divisor_for_seconds);
- //walk trough the children and add the size,
- for (var i = 0, len = children.length - 1; i <= len; i++) {
- childrenWidth += $(children[i]).outerWidth();
- if (i !== len) {
- //the highest margin between two elements counts
- childrenWidth += Math.max(
- parseInt($(children[i]).css("margin-right")),
- parseInt($(children[i + 1]).css("margin-left"))
+ return {
+ "h": hours,
+ "m": minutes,
+ "s": seconds
+ };
+ },
- );
- }
+ hex2rgba: function(hex, alpha){
+ var c;
+ alpha = isNaN(alpha) ? 1 : alpha;
+ if(/^#([A-Fa-f0-9]{3}){1,2}$/.test(hex)){
+ c= hex.substring(1).split('');
+ if(c.length=== 3){
+ c= [c[0], c[0], c[1], c[1], c[2], c[2]];
}
- //the right margin for the right child
- childrenWidth += parseInt($(children[len]).css("margin-right"));
+ c= '0x'+c.join('');
+ return 'rgba('+[(c>>16)&255, (c>>8)&255, c&255].join(',')+','+alpha+')';
+ }
+ throw new Error('Hex2rgba error. Bad Hex value');
+ },
- //now we have all data for calculation. Yippie-Ya-Yeah, Schweinebacke!! (much cooler German translation of B. W. Yippie-Ya-Yeah, Motherf***er)
- freeSpace = menusParentWidth - childrenWidth;
+ random: function(from, to){
+ return Math.floor(Math.random()*(to-from+1)+from);
+ },
- //writing the data we found out to the element's data
- that.freeSpace = freeSpace; //not used space within the parent(mostly the appbar itself)
- that.childrenWidth = childrenWidth; //the total width of the children
- that.menusParentWidth = menusParentWidth; //the width without padding or something
+ uniqueId: function () {
+var d = new Date().getTime();
+ return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
+ var r = (d + Math.random() * 16) % 16 | 0;
+ d = Math.floor(d / 16);
+ return (c === 'x' ? r : (r & 0x3 | 0x8)).toString(16);
+ });
+ },
- return freeSpace;
- },
- _originIndexMove: function(menu, child) {
- //find all children which are lower than we
- var flexChildren = $(menu).children().filter(function () {
- return parseInt($(this).attr("data-flexorderorigin")) < parseInt($(child).attr("data-flexorderorigin"));
- });
-
- if (flexChildren.length > 0) {
- //because we are greater, we set it after the childern which are lower
- $(flexChildren).last().after(child);
- } else {
- //find all children which are greater than we are
- flexChildren = $(menu).children().filter(function () {
- return parseInt($(this).attr("data-flexorderorigin")) > parseInt($(child).attr("data-flexorderorigin"));
- });
- if (flexChildren.length > 0) {
- //because we are lower, we set us before the childern which are greater
- $(flexChildren).first().before(child);
- } else {
- //we have no children, just append it
- $(menu).append(child);
- }
- }
- },
- _moveMenuEntry: function (direction) {
- var that = this, element = this.element, o = this.options;
+ elementId: function(prefix){
+ return prefix+"-"+(new Date()).getTime()+Utils.random(1, 1000);
+ },
- direction = direction || "toPullMenu"; // "fromPullMenu" is also an option
+ secondsToFormattedString: function(time){
+ var sec_num = parseInt(time, 10);
+ var hours = Math.floor(sec_num / 3600);
+ var minutes = Math.floor((sec_num - (hours * 3600)) / 60);
+ var seconds = sec_num - (hours * 3600) - (minutes * 60);
- if (direction === "toPullMenu") {
- //get next candidate which could be moved to the pullmenu, in fact the last which not have a mark as pullmenu-entry
+ if (hours < 10) {hours = "0"+hours;}
+ if (minutes < 10) {minutes = "0"+minutes;}
+ if (seconds < 10) {seconds = "0"+seconds;}
- var nextToHide = $(that.allMenuEntries).not(".app-bar-pullmenu-entry").last();
+ return [hours, minutes, seconds].join(":");
+ },
- if (nextToHide.length === 0) {
- //nothing left, we have nothing to do
- return false;
- }
+ callback: function(f, args, context){
+ return this.exec(f, args, context);
+ },
+ exec: function(f, args, context){
+ var result;
+ if (f === undefined || f === null) {return false;}
+ var func = this.isFunc(f);
+ if (func === false) {
+ func = new Function("a", f);
+ }
- //find out in which menubar we are located in
- var topMenu = $(nextToHide).parent(); //this is only a appbar-menu not the appbar itself
- //find out where we have to go
- var topMenuIndex = $(that.flexVisibles).index($(nextToHide).parent());
- var pullMenuBar = $(that.pullMenu).find(".app-bar-pullmenubar").eq(topMenuIndex); //TODO: Make the class app-bar-menu configurable - perhaps sidebar
+ try {
+ result = func.apply(context, args);
+ } catch (err) {
+ result = null;
+ if (METRO_THROWS === true) {
+ throw err;
+ }
+ }
+ return result;
+ },
- that._originIndexMove(pullMenuBar, nextToHide);
- //move it to the pullmenu
-// if ($(topMenu).is("[data-flexdirection='reverse']")) {//data-flexdirection="reverse" support
-// $(nextToHide).appendTo(pullMenuBar);
-// } else { //normal way
-// $(nextToHide).prependTo(pullMenuBar);
-// }
+ isOutsider: function(el) {
+ el = this.isJQueryObject(el) ? el : $(el);
+ var rect;
+ var clone = el.clone();
- //mark the entry as a entry of the pullmenu
- $(nextToHide).addClass("app-bar-pullmenu-entry");
+ clone.removeAttr("data-role").css({
+ visibility: "hidden",
+ position: "absolute",
+ display: "block"
+ });
+ el.parent().append(clone);
- //the menubar is initiated with the hidden class, so we do not see empty pullmenubars, we must unhide them
- //it does not matter, if we see it already, we do it always:
- $(pullMenuBar).removeClass("hidden")
- .show();
+ rect = clone[0].getBoundingClientRect();
+ clone.remove();
- //in case there are no more entries in the top menu bar we can hide it
- if ($(topMenu).children().length === 0) {
- $(topMenu).addClass("hidden");
- }
+ return (
+ rect.top >= 0 &&
+ rect.left >= 0 &&
+ rect.bottom <= (window.innerHeight || document.documentElement.clientHeight) &&
+ rect.right <= (window.innerWidth || document.documentElement.clientWidth)
+ );
+ },
- //we show the pullbutton now
- $(that.pullButton).show();
+ inViewport: function(el){
+ if (typeof jQuery === "function" && el instanceof jQuery) {
+ el = el[0];
+ }
- return nextToHide;
+ var rect = el.getBoundingClientRect();
- } else if (direction === "fromPullMenu") {
- //get next candidate which could be moved to the topbar menu, in fact the first which is still marked as pullmenu-entry
- var nextToShow = $(that.allMenuEntries).filter(".app-bar-pullmenu-entry").first();
+ return (
+ rect.top >= 0 &&
+ rect.left >= 0 &&
+ rect.bottom <= (window.innerHeight || document.documentElement.clientHeight) &&
+ rect.right <= (window.innerWidth || document.documentElement.clientWidth)
+ );
+ },
+ objectLength: function(obj){
+ return Object.keys(obj).length;
+ },
- //find out in which pullmenu we are located in
- var pullMenuBar = $(nextToShow).parent(); //only one single menu, not the whole thing
+ percent: function(total, part, round_value){
+ if (total === 0) {
+ return 0;
+ }
+ var result = part * 100 / total;
+ return round_value === true ? Math.round(result) : Math.round(result * 100) / 100;
+ },
- //find out where we have to go
- var topMenuIndex = $(pullMenuBar).index(); //it is the same structur as that.flexVisibles, so we can use the simple index
- var topMenu = $(that.flexVisibles).eq(topMenuIndex);
+ camelCase: function(str){
+ return str.replace(/-([a-z])/g, function (g) { return g[1].toUpperCase(); });
+ },
- $(topMenu).removeClass("hidden");
- //remove the mark as a entry of the pullmenu and move it to the normal top menu
- $(nextToShow).removeClass("app-bar-pullmenu-entry");
+ objectShift: function(obj){
+ var min = 0;
+ $.each(obj, function(i){
+ if (min === 0) {
+ min = i;
+ } else {
+ if (min > i) {
+ min = i;
+ }
+ }
+ });
+ delete obj[min];
- //cosider the flexorder
+ return obj;
+ },
- //walk trough the children in topMenu and find out what we must do
+ objectDelete: function(obj, key){
+ if (obj[key] !== undefined) delete obj[key];
+ },
- //find all children which are lower than we
- that._originIndexMove(topMenu, nextToShow);
+ arrayDelete: function(arr, val){
+ arr.splice(arr.indexOf(val), 1);
+ },
- //in case there are no more entries left, we can hide the pullbar menu from this entry
- if ($(pullMenuBar).children().length === 0) {
- $(pullMenuBar).addClass("hidden")
- .hide();
- }
+ arrayDeleteByKey: function(arr, key){
+ arr.splice(key, 1);
+ },
- //in case we have no more menus in the pullbar area, we hide the pullbar thing
- if ($(that.pullMenu).children(".app-bar-pullmenubar").not(".hidden").length === 0) {
- $(that.pullMenu).hide().addClass("hidden");
- $(that.pullButton).hide();
- }
+ nvl: function(data, other){
+ return data === undefined || data === null ? other : data;
+ },
- if (nextToShow.length === 0) {
- //nothing left, we have nothing to do
- return false;
- }
- return nextToShow;
+ objectClone: function(obj){
+ var copy = {};
+ for(var key in obj) {
+ if (obj.hasOwnProperty(key)) {
+ copy[key] = obj[key];
}
- },
- _checkMenuEntries: function () {
- var that = this, element = this.element, o = this.options;
-
- var forceEndLoop = false;
-
- for (var maxLoop = 0, maxLoopLen = that.allMenuEntries.length; maxLoop < maxLoopLen; maxLoop++) { //we do nothing with this, we could use while(true) but there is a danger of infinite loops
-
- //calculate the empty space within the appbar we can use for hidden children
- that._calculateFreeSpace();
- var freeSpace = that.freeSpace;
+ }
+ return copy;
+ },
- if (freeSpace < o.flextolerance || o.flexclean) { //3px is tolerance and to be faster than the wrapping. TODO: make this configurable
- //no space left, we hide a menu entry now
+ github: function(repo, callback){
+ var that = this;
+ $.ajax({
+ url: 'https://api.github.com/repos/' + repo,
+ dataType: 'jsonp'
+ })
+ .done(function(data){
+ that.callback(callback, [data.data]);
+ });
+ },
- //move the menu entry to the pullbar and check if there are more menuentries left
- if (!(that._moveMenuEntry("toPullMenu"))) {
- //nothing left to hide
- break;
- } else {
- //we moved successfully, perhaps we can hide more entries, we recheck the appbar,
- //remember, we are in a endless loop, which checks this for us
+ detectIE: function() {
+ var ua = window.navigator.userAgent;
+ var msie = ua.indexOf('MSIE ');
+ if (msie > 0) {
+ // IE 10 or older => return version number
+ return parseInt(ua.substring(msie + 5, ua.indexOf('.', msie)), 10);
+ }
- if (!forceEndLoop) {
- continue;
- }
- }
+ var trident = ua.indexOf('Trident/');
+ if (trident > 0) {
+ // IE 11 => return version number
+ var rv = ua.indexOf('rv:');
+ return parseInt(ua.substring(rv + 3, ua.indexOf('.', rv)), 10);
+ }
- } else {
- //we have space here, we try to get more entries there
+ var edge = ua.indexOf('Edge/');
+ if (edge > 0) {
+ // Edge (IE 12+) => return version number
+ return parseInt(ua.substring(edge + 5, ua.indexOf('.', edge)), 10);
+ }
- //check if there is something to do
- if (!(that._moveMenuEntry("fromPullMenu"))) {
- //nothing left to show
- break;
- } else {
- forceEndLoop = true;
- continue;
- }
+ // other browser
+ return false;
+ },
- }
+ detectChrome: function(){
+ return /Chrome/.test(navigator.userAgent) && /Google Inc/.test(navigator.vendor);
+ },
- //we continue manually. if we reach the end of the loop we end this better so we do not produce infinite loop accidentally
- break;
- }
- },
- resize: function () {
- var that = this, element = this.element, o = this.options;
+ md5: function(s){
+ return hex_md5(s);
+ },
- if (that.initiatedAsFlex) {
- this._checkMenuEntries();
- }
- },
- _initBar: function () {
- var that = this, element = this.element, o = this.options;
+ encodeURI: function(str){
+ return encodeURI(str).replace(/%5B/g, '[').replace(/%5D/g, ']');
+ },
- that.lastFlexAction = undefined;
+ pageHeight: function(){
+ var body = document.body,
+ html = document.documentElement;
- that.pullButton = $(element).find('.app-bar-pullbutton');
- var menus = $(element).find('.app-bar-menu');
+ return Math.max( body.scrollHeight, body.offsetHeight, html.clientHeight, html.scrollHeight, html.offsetHeight );
+ },
- that.initiatedAsFlex = false; //we change it later in the code - conditionally
- o.flexclean = $(element).is("[data-flexclean='true']") || o.flexclean;
- o.flexstyle = $(element).attr("data-flexstyle") || o.flexstyle;
+ cleanPreCode: function(selector){
+ var els = Array.prototype.slice.call(document.querySelectorAll(selector), 0);
- var flexVisible, menuEntries; //temporarly used vars
+ els.forEach(function(el){
+ var txt = el.textContent
+ .replace(/^[\r\n]+/, "") // strip leading newline
+ .replace(/\s+$/g, "");
- that.flexVisibles = $(); //the menus which are directly in the appbar
- that.allMenuEntries = $(); //all menu entries in a sorted order
- that.menusParent = $(); //common parent from the menus, which can but do not need to be this.element. We get the max width from it
- that.pullMenu = $();
+ if (/^\S/gm.test(txt)) {
+ el.textContent = txt;
+ return;
+ }
- if (menus.length > 0 && $(element).is(":not('.no-flexible')")) {
- //strip off all .no-flexible menus
- that.flexVisibles = $(menus).not(".no-flexible");
+ var mat, str, re = /^[\t ]+/gm, len, min = 1e3;
- if (that.flexVisibles.length > 0) {
+ while (mat = re.exec(txt)) {
+ len = mat[0].length;
- that.initiatedAsFlex = true;
+ if (len < min) {
+ min = len;
+ str = mat[0];
+ }
+ }
- //sort the menus according to the data-flexorder attribute
- that.flexVisibles.sort(function (a, b) {
- var aValue = (parseInt($(a).data("flexorder")) || $(a).index() + 1);
- var bValue = (parseInt($(b).data("flexorder")) || $(b).index() + 1);
- return aValue - bValue;
- });
+ if (min === 1e3)
+ return;
- //get all children in a sorted order according to the data-flexorder attribute
- $(that.flexVisibles).each(function () {
- flexVisible = this;
+ el.textContent = txt.replace(new RegExp("^" + str, 'gm'), "");
+ });
+ },
- menuEntries = $(flexVisible).children();
+ coords: function(el){
+ if (this.isJQueryObject(el)) {
+ el = el[0];
+ }
- //give all menuEntries a flexorder which have not one and save the original order
- $(menuEntries).each(function () {
- $(this).attr("data-flexorderorigin", $(this).index());
-
- if(!($(this).is("[data-flexorder]"))) {
- $(this).attr("data-flexorder", $(this).index() + 1);
- }
- });
+ var box = el.getBoundingClientRect();
- menuEntries.sort(function (a, b) {
- var aValue = parseInt($(a).data("flexorder"));
- var bValue = parseInt($(b).data("flexorder"));
- return aValue - bValue;
- });
+ return {
+ top: box.top + window.pageYOffset,
+ left: box.left + window.pageXOffset
+ };
+ },
- //data-flexdirection="reverse" support
- if ($(flexVisible).is("[data-flexdirection='reverse']")) {
- menuEntries.reverse();
- }
+ positionXY: function(e, t){
+ switch (t) {
+ case 'client': return this.clientXY(e);
+ case 'screen': return this.screenXY(e);
+ case 'page': return this.pageXY(e);
+ default: return {x: 0, y: 0}
+ }
+ },
- $.merge(that.allMenuEntries, $(menuEntries).not(".no-flexible")); //strip off all .no-flexible elements
- });
+ clientXY: function(e){
+ return {
+ x: e.changedTouches ? e.changedTouches[0].clientX : e.clientX,
+ y: e.changedTouches ? e.changedTouches[0].clientY : e.clientY
+ };
+ },
- //find the parent, which contains all menus
- that.menusParent = $(element).find(".app-bar-menu").first().parent();
+ screenXY: function(e){
+ return {
+ x: e.changedTouches ? e.changedTouches[0].screenX : e.screenX,
+ y: e.changedTouches ? e.changedTouches[0].screenY : e.screenY
+ };
+ },
- // === create a pull down button + pull menu ===
- //check if a pulldown button already exists, if not we create one
- if (!(that.pullButton.length > 0)) {
- //DOC: We can create a display:none button, if we want to force to not show a pull button
- that.pullButton = $('
');
- $(that.menusParent).append(that.pullButton);
- }
+ pageXY: function(e){
+ return {
+ x: e.changedTouches ? e.changedTouches[0].pageX : e.pageX,
+ y: e.changedTouches ? e.changedTouches[0].pageY : e.pageY
+ };
+ },
- //create a pullmenu
- that.pullMenu = $('');
+ isRightMouse: function(e){
+ return "which" in e ? e.which === 3 : "button" in e ? e.button === 2 : undefined;
+ },
- //create menubars within the pullmenu
- that.flexVisibles.each(function () {
- $(that.pullMenu).append($(''));
- });
-
-
-
- // WORKAROUND: this is because a :after:before clearfix for the pullmenu do not work for some reason
- //position: absolute does not work if we do not break the float. another pure css solution should be written in the appbar.less
- //after that remove this line
- $(that.menusParent).append($('
'));
- //-----------
-
-
- $(that.pullMenu).addClass("flexstyle-" + o.flexstyle);
+ hiddenElementSize: function(el, includeMargin){
+ var clone = $(el).clone();
+ clone.removeAttr("data-role").css({
+ visibility: "hidden",
+ position: "absolute",
+ display: "block"
+ });
+ $("body").append(clone);
- $(that.menusParent).append(that.pullMenu);
+ if (includeMargin === undefined) {
+ includeMargin = false;
+ }
- //check for the first time the menu entries /hide them if needed, etc.
- that._checkMenuEntries();
+ var width = clone.outerWidth(includeMargin);
+ var height = clone.outerHeight(includeMargin);
+ clone.remove();
+ return {
+ width: width,
+ height: height
+ }
+ },
+ getStyle: function(el, pseudo){
+ if (Utils.isJQueryObject(el) === true) {
+ el = el[0];
+ }
+ return window.getComputedStyle(el, pseudo);
+ },
+ getStyleOne: function(el, property){
+ return this.getStyle(el).getPropertyValue(property);
+ },
- //=== EVENTS =================================================
+ getTransformMatrix: function(el, returnArray){
+ var computedMatrix = this.getStyleOne(el, "transform");
+ var a = computedMatrix
+ .replace("matrix(", '')
+ .slice(0, -1)
+ .split(',');
+ return returnArray !== true ? {
+ a: a[0],
+ b: a[1],
+ c: a[2],
+ d: a[3],
+ tx: a[4],
+ ty: a[5]
+ } : a;
+ },
- //activate the click event for the pull button
- $(that.pullButton).on("click", function (e) {
+ computedRgbToHex: function(rgb){
+ var a = rgb.replace(/[^\d,]/g, '').split(',');
+ var result = "#";
+ $.each(a, function(){
+ var h = parseInt(this).toString(16);
+ result += h.length === 1 ? "0" + h : h;
+ });
+ return result;
+ },
- //who am i?
- that = $(this).closest("[data-role=appbar]").data("appbar");
+ computedRgbToRgba: function(rgb, alpha){
+ var a = rgb.replace(/[^\d,]/g, '').split(',');
+ if (alpha === undefined) {
+ alpha = 1;
+ }
+ a.push(alpha);
+ return "rgba("+a.join(",")+")";
+ },
- //we show /hide the pullmenu
- if ($(that.pullMenu).length !== 0 && $(that.pullMenu).is(":hidden")) {
- $(that.pullMenu).show();
- $(that.pullMenu).find(".app-bar-pullmenubar")
- .hide().not(".hidden").slideDown("fast");
- e.preventDefault();
- e.stopPropagation();
- } else {
- $(that.pullMenu).find(".app-bar-pullmenubar")
- .not(".hidden").show().slideUp("fast", function () {
- $(that.pullMenu).hide();
- });
- }
+ computedRgbToArray: function(rgb){
+ return rgb.replace(/[^\d,]/g, '').split(',');
+ },
- });
+ hexColorToArray: function(hex){
+ var c;
+ if (/^#([A-Fa-f0-9]{3}){1,2}$/.test(hex)){
+ c= hex.substring(1).split('');
+ if(c.length === 3){
+ c= [c[0], c[0], c[1], c[1], c[2], c[2]];
+ }
+ c= '0x'+c.join('');
+ return [(c>>16)&255, (c>>8)&255, c&255];
+ }
+ return [0,0,0];
+ },
- }
+ hexColorToRgbA: function(hex, alpha){
+ var c;
+ if (/^#([A-Fa-f0-9]{3}){1,2}$/.test(hex)){
+ c= hex.substring(1).split('');
+ if(c.length === 3){
+ c= [c[0], c[0], c[1], c[1], c[2], c[2]];
}
+ c= '0x'+c.join('');
+ return 'rgba('+[(c>>16)&255, (c>>8)&255, c&255, alpha ? alpha : 1].join(',')+')';
+ }
+ return 'rgba(0,0,0,1)';
+ },
- },
- _destroy: function () {
- },
- _setOption: function (key, value) {
- this._super('_setOption', key, value);
+ getInlineStyles: function(el){
+ var styles = {};
+ if (this.isJQueryObject(el)) {
+ el = el[0];
+ }
+ for (var i = 0, l = el.style.length; i < l; i++) {
+ var s = el.style[i];
+ styles[s] = el.style[s];
}
- });
- //we have to calculate everything new, if the user resizes or zooms the window
- $(window).on('resize', function () {
- $("[data-role=appbar]:not(.no-flexible)").each(function () {
- $(this).data("appbar").resize();
- });
- });
+ return styles;
+ },
+ updateURIParameter: function(uri, key, value) {
+ var re = new RegExp("([?&])" + key + "=.*?(&|$)", "i");
+ var separator = uri.indexOf('?') !== -1 ? "&" : "?";
+ if (uri.match(re)) {
+ return uri.replace(re, '$1' + key + "=" + value + '$2');
+ }
+ else {
+ return uri + separator + key + "=" + value;
+ }
+ },
- //because fonts(also icon-fonts) are often loaded async after the page has loaded and this script walked through already,
- //we have to check again after these elements loaded. Because there is no way to observe only specific elements, we do it for the window
- $(window).on('load', function () {
- $("[data-role=appbar]:not(.no-flexible)").each(function () {
- $(this).data("appbar").resize();
- });
- });
+ getURIParameter: function(url, name){
+ if (!url) url = window.location.href;
+ name = name.replace(/[\[\]]/g, "\\$&");
+ var regex = new RegExp("[?&]" + name + "(=([^]*)|&|#|$)"),
+ results = regex.exec(url);
+ if (!results) return null;
+ if (!results[2]) return '';
+ return decodeURIComponent(results[2].replace(/\+/g, " "));
+ },
- //pictures (or other outside stuff was loaded - pictures are also often loaded async or have a lazy load or are injected after a while.
- //a picture can change a size of the element from the appbar, so we must recheck it again.
- $("[data-role=appbar]:not(.no-flexible) [src]").on("load", function () {
- //who am i?
- var appbar = $(this).closest("[data-role=appbar]").data("appbar");
- appbar.resize();
- });
+ getLocales: function(){
+ return Object.keys(Metro.locales);
+ },
-// Source: js/widgets/audio-player.js
-$.widget( "metro.audio" , {
+ addLocale: function(locale){
+ Metro.locales = $.extend( {}, Metro.locales, locale );
+ },
- version: "3.0.14",
+ strToArray: function(str, delimiter){
+ if (delimiter === undefined) {
+ delimiter = ",";
+ }
+ return str.split(delimiter).map(function(s){
+ return s.trim();
+ })
+ },
- options: {
- src: false,
- volume: .5,
- muted: false,
- loop: false,
- preload: false,
- autoplay: false,
- playList: false,
- mode: "full",
+ aspectRatioH: function(width, a){
+ if (a === "16/9") return width * 9 / 16;
+ if (a === "21/9") return width * 9 / 21;
+ if (a === "4/3") return width * 3 / 4;
+ },
- loopButton: "
",
- stopButton: "
",
- playButton: "
",
- pauseButton: "
",
- muteButton: "
",
- shuffleButton: "
",
- nextButton: "
",
- prevButton: "
",
- randomButton: "
",
- playListButton: "
",
+ aspectRatioW: function(height, a){
+ if (a === "16/9") return height * 16 / 9;
+ if (a === "21/9") return height * 21 / 9;
+ if (a === "4/3") return height * 4 / 3;
+ },
- volumeLowButton: "
",
- volumeMediumButton: "
",
- volumeHighButton: "
"
+ valueInObject: function(obj, value){
+ return Object.values(obj).indexOf(value) > -1;
+ },
+ keyInObject: function(){
+ return Object.keys(obj).indexOf(value) > -1;
},
- _create: function () {
- var that = this, element = this.element, o = this.options;
+ newCssSheet: function(media){
+ var style = document.createElement("style");
- this._setOptionsFromDOM();
+ if (media !== undefined) {
+ style.setAttribute("media", media);
+ }
- this._createPlayer();
- this._addControls();
- this._addEvents();
- this._addPlayList();
- this._setControlsVisibility();
+ style.appendChild(document.createTextNode(""));
+
+ document.head.appendChild(style);
- element.data('audio', this);
+ return style.sheet;
},
- _setControlsVisibility: function(){
- var that = this, element = this.element, o = this.options;
- if (element.find(".play-list").length == 0) {
- element.find(".controls .plist").hide();
- element.find(".controls .next").hide();
- element.find(".controls .prev").hide();
- element.find(".controls .random").hide();
+ addCssRule: function(sheet, selector, rules, index){
+ if("insertRule" in sheet) {
+ sheet.insertRule(selector + "{" + rules + "}", index);
+ }
+ else if("addRule" in sheet) {
+ sheet.addRule(selector, rules, index);
}
},
- _addPlayList: function(){
- var that = this, element = this.element, o = this.options;
- var audio = element.find("audio");
- var pl, pli, plw, poster, title;
- var play_list;
-
- if (o.playList) {
- if (window[o.playList] != undefined && typeof window[o.playList] == 'function') {
+ media: function(query){
+ return window.matchMedia(query).matches
+ }
+};
- pl = window[o.playList]();
- pli = pl.items;
- plw = $("
").addClass("play-list-wrapper").insertBefore(element.find("audio"));
+Metro['utils'] = Utils;
+// Source: js/plugins/accordion.js
+var Accordion = {
+ init: function( options, elem ) {
+ this.options = $.extend( {}, this.options, options );
+ this.elem = elem;
+ this.element = $(elem);
- if (pl.title != undefined) {
- title = $("