/*! TimelineJS Version 2.17 Designed and built by Zach Wise at VéritéCo This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/. */ /* ********************************************** Begin VMM.StoryJS.License.js ********************************************** */ /*! StoryJS Designed and built by Zach Wise at VéritéCo This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/. */ /* ********************************************** Begin VMM.js ********************************************** */ /** * VéritéCo JS Core * Designed and built by Zach Wise at VéritéCo zach@verite.co * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ /* Simple JavaScript Inheritance By John Resig http://ejohn.org/ MIT Licensed. ================================================== */ (function() { var initializing = false, fnTest = /xyz/.test(function() { xyz; }) ? /\b_super\b/: /.*/; // The base Class implementation (does nothing) this.Class = function() {}; // Create a new Class that inherits from this class Class.extend = function(prop) { var _super = this.prototype; // Instantiate a base class (but only create the instance, // don't run the init constructor) initializing = true; var prototype = new this(); initializing = false; // Copy the properties over onto the new prototype for (var name in prop) { // Check if we're overwriting an existing function prototype[name] = typeof prop[name] == "function" && typeof _super[name] == "function" && fnTest.test(prop[name]) ? (function(name, fn) { return function() { var tmp = this._super; // Add a new ._super() method that is the same method // but on the super-class this._super = _super[name]; // The method only need to be bound temporarily, so we // remove it when we're done executing var ret = fn.apply(this, arguments); this._super = tmp; return ret; }; })(name, prop[name]) : prop[name]; } // The dummy class constructor function Class() { // All construction is actually done in the init method if (!initializing && this.init) this.init.apply(this, arguments); } // Populate our constructed prototype object Class.prototype = prototype; // Enforce the constructor to be what we expect Class.prototype.constructor = Class; // And make this class extendable Class.extend = arguments.callee; return Class; }; })(); /* Access to the Global Object access the global object without hard-coding the identifier window ================================================== */ var global = (function () { return this || (1,eval)('this'); }()); /* VMM ================================================== */ if (typeof VMM == 'undefined') { /* Main Scope Container ================================================== */ //var VMM = {}; var VMM = Class.extend({}); /* Debug ================================================== */ VMM.debug = true; /* Master Config ================================================== */ VMM.master_config = ({ init: function() { return this; }, sizes: { api: { width: 0, height: 0 } }, vp: "Pellentesque nibh felis, eleifend id, commodo in, interdum vitae, leo", api_keys_master: { flickr: "RAIvxHY4hE/Elm5cieh4X5ptMyDpj7MYIxziGxi0WGCcy1s+yr7rKQ==", //google: "jwNGnYw4hE9lmAez4ll0QD+jo6SKBJFknkopLS4FrSAuGfIwyj57AusuR0s8dAo=", google: "uQKadH1VMlCsp560gN2aOiMz4evWkl1s34yryl3F/9FJOsn+/948CbBUvKLN46U=", twitter: "" }, timers: { api: 7000 }, api: { pushques: [] }, twitter: { active: false, array: [], api_loaded: false, que: [] }, flickr: { active: false, array: [], api_loaded: false, que: [] }, youtube: { active: false, array: [], api_loaded: false, que: [] }, vimeo: { active: false, array: [], api_loaded: false, que: [] }, vine: { active: false, array: [], api_loaded: false, que: [] }, webthumb: { active: false, array: [], api_loaded: false, que: [] }, googlemaps: { active: false, map_active: false, places_active: false, array: [], api_loaded: false, que: [] }, googledocs: { active: false, array: [], api_loaded: false, que: [] }, googleplus: { active: false, array: [], api_loaded: false, que: [] }, wikipedia: { active: false, array: [], api_loaded: false, que: [], tries: 0 }, soundcloud: { active: false, array: [], api_loaded: false, que: [] } }).init(); //VMM.createElement(tag, value, cName, attrs, styles); VMM.createElement = function(tag, value, cName, attrs, styles) { var ce = ""; if (tag != null && tag != "") { // TAG ce += "<" + tag; if (cName != null && cName != "") { ce += " class='" + cName + "'"; }; if (attrs != null && attrs != "") { ce += " " + attrs; }; if (styles != null && styles != "") { ce += " style='" + styles + "'"; }; ce += ">"; if (value != null && value != "") { ce += value; } // CLOSE TAG ce = ce + ""; } return ce; }; VMM.createMediaElement = function(media, caption, credit) { var ce = ""; var _valid = false; ce += "
"; if (media != null && media != "") { valid = true; ce += ""; // CREDIT if (credit != null && credit != "") { ce += VMM.createElement("div", credit, "credit"); } // CAPTION if (caption != null && caption != "") { ce += VMM.createElement("div", caption, "caption"); } } ce += "
"; return ce; }; // Hide URL Bar for iOS and Android by Scott Jehl // https://gist.github.com/1183357 VMM.hideUrlBar = function () { var win = window, doc = win.document; // If there's a hash, or addEventListener is undefined, stop here if( !location.hash || !win.addEventListener ){ //scroll to 1 window.scrollTo( 0, 1 ); var scrollTop = 1, //reset to 0 on bodyready, if needed bodycheck = setInterval(function(){ if( doc.body ){ clearInterval( bodycheck ); scrollTop = "scrollTop" in doc.body ? doc.body.scrollTop : 1; win.scrollTo( 0, scrollTop === 1 ? 0 : 1 ); } }, 15 ); win.addEventListener( "load", function(){ setTimeout(function(){ //reset to hide addr bar at onload win.scrollTo( 0, scrollTop === 1 ? 0 : 1 ); }, 0); }, false ); } }; } /* Trace (console.log) ================================================== */ function trace( msg ) { if (VMM.debug) { if (window.console) { console.log(msg); } else if ( typeof( jsTrace ) != 'undefined' ) { jsTrace.send( msg ); } else { //alert(msg); } } } /* Array Remove - By John Resig (MIT Licensed) http://ejohn.org/blog/javascript-array-remove/ ================================================== */ Array.prototype.remove = function(from, to) { var rest = this.slice((to || from) + 1 || this.length); this.length = from < 0 ? this.length + from : from; return this.push.apply(this, rest); } /* Extending Date to include Week ================================================== */ Date.prototype.getWeek = function() { var onejan = new Date(this.getFullYear(),0,1); return Math.ceil((((this - onejan) / 86400000) + onejan.getDay()+1)/7); } /* Extending Date to include Day of Year ================================================== */ Date.prototype.getDayOfYear = function() { var onejan = new Date(this.getFullYear(),0,1); return Math.ceil((this - onejan) / 86400000); } /* A MORE SPECIFIC TYPEOF(); // http://rolandog.com/archives/2007/01/18/typeof-a-more-specific-typeof/ ================================================== */ // type.of() var is={ Null:function(a){return a===null;}, Undefined:function(a){return a===undefined;}, nt:function(a){return(a===null||a===undefined);}, Function:function(a){return(typeof(a)==="function")?a.constructor.toString().match(/Function/)!==null:false;}, String:function(a){return(typeof(a)==="string")?true:(typeof(a)==="object")?a.constructor.toString().match(/string/i)!==null:false;}, Array:function(a){return(typeof(a)==="object")?a.constructor.toString().match(/array/i)!==null||a.length!==undefined:false;}, Boolean:function(a){return(typeof(a)==="boolean")?true:(typeof(a)==="object")?a.constructor.toString().match(/boolean/i)!==null:false;}, Date:function(a){return(typeof(a)==="date")?true:(typeof(a)==="object")?a.constructor.toString().match(/date/i)!==null:false;}, HTML:function(a){return(typeof(a)==="object")?a.constructor.toString().match(/html/i)!==null:false;}, Number:function(a){return(typeof(a)==="number")?true:(typeof(a)==="object")?a.constructor.toString().match(/Number/)!==null:false;}, Object:function(a){return(typeof(a)==="object")?a.constructor.toString().match(/object/i)!==null:false;}, RegExp:function(a){return(typeof(a)==="function")?a.constructor.toString().match(/regexp/i)!==null:false;} }; var type={ of:function(a){ for(var i in is){ if(is[i](a)){ return i.toLowerCase(); } } } }; /* ********************************************** Begin VMM.Library.js ********************************************** */ /* * LIBRARY ABSTRACTION ================================================== */ if(typeof VMM != 'undefined') { VMM.modal = function(elem, opt) { if( typeof( jQuery ) != 'undefined' ){ jQuery(elem).fancybox(opt); } }; VMM.smoothScrollTo = function(elem, duration, ease) { if( typeof( jQuery ) != 'undefined' ){ var _ease = "easein", _duration = 1000; if (duration != null) { if (duration < 1) { _duration = 1; } else { _duration = Math.round(duration); } } if (ease != null && ease != "") { _ease = ease; } if (jQuery(window).scrollTop() != VMM.Lib.offset(elem).top) { VMM.Lib.animate('html,body', _duration, _ease, {scrollTop: VMM.Lib.offset(elem).top}) } } }; VMM.attachElement = function(element, content) { if( typeof( jQuery ) != 'undefined' ){ jQuery(element).html(content); } }; VMM.appendElement = function(element, content) { if( typeof( jQuery ) != 'undefined' ){ jQuery(element).append(content); } }; VMM.getHTML = function(element) { var e; if( typeof( jQuery ) != 'undefined' ){ e = jQuery(element).html(); return e; } }; VMM.getElement = function(element, p) { var e; if( typeof( jQuery ) != 'undefined' ){ if (p) { e = jQuery(element).parent().get(0); } else { e = jQuery(element).get(0); } return e; } }; VMM.bindEvent = function(element, the_handler, the_event_type, event_data) { var e; var _event_type = "click"; var _event_data = {}; if (the_event_type != null && the_event_type != "") { _event_type = the_event_type; } if (_event_data != null && _event_data != "") { _event_data = event_data; } if( typeof( jQuery ) != 'undefined' ){ jQuery(element).bind(_event_type, _event_data, the_handler); //return e; } }; VMM.unbindEvent = function(element, the_handler, the_event_type) { var e; var _event_type = "click"; var _event_data = {}; if (the_event_type != null && the_event_type != "") { _event_type = the_event_type; } if( typeof( jQuery ) != 'undefined' ){ jQuery(element).unbind(_event_type, the_handler); //return e; } }; VMM.fireEvent = function(element, the_event_type, the_data) { var e; var _event_type = "click"; var _data = []; if (the_event_type != null && the_event_type != "") { _event_type = the_event_type; } if (the_data != null && the_data != "") { _data = the_data; } if( typeof( jQuery ) != 'undefined' ){ jQuery(element).trigger(_event_type, _data); //return e; } }; VMM.getJSON = function(url, data, callback) { if( typeof( jQuery ) != 'undefined' ){ jQuery.ajaxSetup({ timeout: 3000 }); /* CHECK FOR IE ================================================== */ if ( VMM.Browser.browser == "Explorer" && parseInt(VMM.Browser.version, 10) >= 7 && window.XDomainRequest) { trace("IE JSON"); var ie_url = url; if (ie_url.match('^http://')){ return jQuery.getJSON(ie_url, data, callback); } else if (ie_url.match('^https://')) { ie_url = ie_url.replace("https://","http://"); return jQuery.getJSON(ie_url, data, callback); } else { return jQuery.getJSON(url, data, callback); } } else { return jQuery.getJSON(url, data, callback); } } } VMM.parseJSON = function(the_json) { if( typeof( jQuery ) != 'undefined' ){ return jQuery.parseJSON(the_json); } } // ADD ELEMENT AND RETURN IT VMM.appendAndGetElement = function(append_to_element, tag, cName, content) { var e, _tag = "
", _class = "", _content = "", _id = ""; if (tag != null && tag != "") { _tag = tag; } if (cName != null && cName != "") { _class = cName; } if (content != null && content != "") { _content = content; } if( typeof( jQuery ) != 'undefined' ){ e = jQuery(tag); e.addClass(_class); e.html(_content); jQuery(append_to_element).append(e); } return e; }; VMM.Lib = { init: function() { return this; }, hide: function(element, duration) { if (duration != null && duration != "") { if( typeof( jQuery ) != 'undefined' ){ jQuery(element).hide(duration); } } else { if( typeof( jQuery ) != 'undefined' ){ jQuery(element).hide(); } } }, remove: function(element) { if( typeof( jQuery ) != 'undefined' ){ jQuery(element).remove(); } }, detach: function(element) { if( typeof( jQuery ) != 'undefined' ){ jQuery(element).detach(); } }, append: function(element, value) { if( typeof( jQuery ) != 'undefined' ){ jQuery(element).append(value); } }, prepend: function(element, value) { if( typeof( jQuery ) != 'undefined' ){ jQuery(element).prepend(value); } }, show: function(element, duration) { if (duration != null && duration != "") { if( typeof( jQuery ) != 'undefined' ){ jQuery(element).show(duration); } } else { if( typeof( jQuery ) != 'undefined' ){ jQuery(element).show(); } } }, load: function(element, callback_function, event_data) { var _event_data = {elem:element}; // return element by default if (_event_data != null && _event_data != "") { _event_data = event_data; } if( typeof( jQuery ) != 'undefined' ){ jQuery(element).load(_event_data, callback_function); } }, addClass: function(element, cName) { if( typeof( jQuery ) != 'undefined' ){ jQuery(element).addClass(cName); } }, removeClass: function(element, cName) { if( typeof( jQuery ) != 'undefined' ){ jQuery(element).removeClass(cName); } }, attr: function(element, aName, value) { if (value != null && value != "") { if( typeof( jQuery ) != 'undefined' ){ jQuery(element).attr(aName, value); } } else { if( typeof( jQuery ) != 'undefined' ){ return jQuery(element).attr(aName); } } }, prop: function(element, aName, value) { if (typeof jQuery == 'undefined' || !/[1-9]\.[3-9].[1-9]/.test(jQuery.fn.jquery)) { VMM.Lib.attribute(element, aName, value); } else { jQuery(element).prop(aName, value); } }, attribute: function(element, aName, value) { if (value != null && value != "") { if( typeof( jQuery ) != 'undefined' ){ jQuery(element).attr(aName, value); } } else { if( typeof( jQuery ) != 'undefined' ){ return jQuery(element).attr(aName); } } }, visible: function(element, show) { if (show != null) { if( typeof( jQuery ) != 'undefined' ){ if (show) { jQuery(element).show(0); } else { jQuery(element).hide(0); } } } else { if( typeof( jQuery ) != 'undefined' ){ if ( jQuery(element).is(':visible')){ return true; } else { return false; } } } }, css: function(element, prop, value) { if (value != null && value != "") { if( typeof( jQuery ) != 'undefined' ){ jQuery(element).css(prop, value); } } else { if( typeof( jQuery ) != 'undefined' ){ return jQuery(element).css(prop); } } }, cssmultiple: function(element, propval) { if( typeof( jQuery ) != 'undefined' ){ return jQuery(element).css(propval); } }, offset: function(element) { var p; if( typeof( jQuery ) != 'undefined' ){ p = jQuery(element).offset(); } return p; }, position: function(element) { var p; if( typeof( jQuery ) != 'undefined' ){ p = jQuery(element).position(); } return p; }, width: function(element, s) { if (s != null && s != "") { if( typeof( jQuery ) != 'undefined' ){ jQuery(element).width(s); } } else { if( typeof( jQuery ) != 'undefined' ){ return jQuery(element).width(); } } }, height: function(element, s) { if (s != null && s != "") { if( typeof( jQuery ) != 'undefined' ){ jQuery(element).height(s); } } else { if( typeof( jQuery ) != 'undefined' ){ return jQuery(element).height(); } } }, toggleClass: function(element, cName) { if( typeof( jQuery ) != 'undefined' ){ jQuery(element).toggleClass(cName); } }, each:function(element, return_function) { if( typeof( jQuery ) != 'undefined' ){ jQuery(element).each(return_function); } }, html: function(element, str) { var e; if( typeof( jQuery ) != 'undefined' ){ e = jQuery(element).html(); return e; } if (str != null && str != "") { if( typeof( jQuery ) != 'undefined' ){ jQuery(element).html(str); } } else { var e; if( typeof( jQuery ) != 'undefined' ){ e = jQuery(element).html(); return e; } } }, find: function(element, selec) { if( typeof( jQuery ) != 'undefined' ){ return jQuery(element).find(selec); } }, stop: function(element) { if( typeof( jQuery ) != 'undefined' ){ jQuery(element).stop(); } }, delay_animate: function(delay, element, duration, ease, att, callback_function) { if (VMM.Browser.device == "mobile" || VMM.Browser.device == "tablet") { var _tdd = Math.round((duration/1500)*10)/10, __duration = _tdd + 's'; VMM.Lib.css(element, '-webkit-transition', 'all '+ __duration + ' ease'); VMM.Lib.css(element, '-moz-transition', 'all '+ __duration + ' ease'); VMM.Lib.css(element, '-o-transition', 'all '+ __duration + ' ease'); VMM.Lib.css(element, '-ms-transition', 'all '+ __duration + ' ease'); VMM.Lib.css(element, 'transition', 'all '+ __duration + ' ease'); VMM.Lib.cssmultiple(element, _att); } else { if( typeof( jQuery ) != 'undefined' ){ jQuery(element).delay(delay).animate(att, {duration:duration, easing:ease} ); } } }, animate: function(element, duration, ease, att, que, callback_function) { var _ease = "easein", _que = false, _duration = 1000, _att = {}; if (duration != null) { if (duration < 1) { _duration = 1; } else { _duration = Math.round(duration); } } if (ease != null && ease != "") { _ease = ease; } if (que != null && que != "") { _que = que; } if (att != null) { _att = att } else { _att = {opacity: 0} } if (VMM.Browser.device == "mobile" || VMM.Browser.device == "tablet") { var _tdd = Math.round((_duration/1500)*10)/10, __duration = _tdd + 's'; _ease = " cubic-bezier(0.33, 0.66, 0.66, 1)"; //_ease = " ease-in-out"; for (x in _att) { if (Object.prototype.hasOwnProperty.call(_att, x)) { trace(x + " to " + _att[x]); VMM.Lib.css(element, '-webkit-transition', x + ' ' + __duration + _ease); VMM.Lib.css(element, '-moz-transition', x + ' ' + __duration + _ease); VMM.Lib.css(element, '-o-transition', x + ' ' + __duration + _ease); VMM.Lib.css(element, '-ms-transition', x + ' ' + __duration + _ease); VMM.Lib.css(element, 'transition', x + ' ' + __duration + _ease); } } VMM.Lib.cssmultiple(element, _att); } else { if( typeof( jQuery ) != 'undefined' ){ if (callback_function != null && callback_function != "") { jQuery(element).animate(_att, {queue:_que, duration:_duration, easing:_ease, complete:callback_function} ); } else { jQuery(element).animate(_att, {queue:_que, duration:_duration, easing:_ease} ); } } } } } } if( typeof( jQuery ) != 'undefined' ){ /* XDR AJAX EXTENTION FOR jQuery https://github.com/jaubourg/ajaxHooks/blob/master/src/ajax/xdr.js ================================================== */ (function( jQuery ) { if ( window.XDomainRequest ) { jQuery.ajaxTransport(function( s ) { if ( s.crossDomain && s.async ) { if ( s.timeout ) { s.xdrTimeout = s.timeout; delete s.timeout; } var xdr; return { send: function( _, complete ) { function callback( status, statusText, responses, responseHeaders ) { xdr.onload = xdr.onerror = xdr.ontimeout = jQuery.noop; xdr = undefined; complete( status, statusText, responses, responseHeaders ); } xdr = new XDomainRequest(); xdr.open( s.type, s.url ); xdr.onload = function() { callback( 200, "OK", { text: xdr.responseText }, "Content-Type: " + xdr.contentType ); }; xdr.onerror = function() { callback( 404, "Not Found" ); }; if ( s.xdrTimeout ) { xdr.ontimeout = function() { callback( 0, "timeout" ); }; xdr.timeout = s.xdrTimeout; } xdr.send( ( s.hasContent && s.data ) || null ); }, abort: function() { if ( xdr ) { xdr.onerror = jQuery.noop(); xdr.abort(); } } }; } }); } })( jQuery ); /* jQuery Easing v1.3 http://gsgd.co.uk/sandbox/jquery/easing/ ================================================== */ jQuery.easing['jswing'] = jQuery.easing['swing']; jQuery.extend( jQuery.easing, { def: 'easeOutQuad', swing: function (x, t, b, c, d) { //alert(jQuery.easing.default); return jQuery.easing[jQuery.easing.def](x, t, b, c, d); }, 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; }, 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; } }); } /* ********************************************** Begin VMM.Browser.js ********************************************** */ /* * DEVICE AND BROWSER DETECTION ================================================== */ if(typeof VMM != 'undefined' && typeof VMM.Browser == 'undefined') { VMM.Browser = { init: function () { this.browser = this.searchString(this.dataBrowser) || "An unknown browser"; this.version = this.searchVersion(navigator.userAgent) || this.searchVersion(navigator.appVersion) || "an unknown version"; this.OS = this.searchString(this.dataOS) || "an unknown OS"; this.device = this.searchDevice(navigator.userAgent); this.orientation = this.searchOrientation(window.orientation); }, searchOrientation: function(orientation) { var orient = ""; if ( orientation == 0 || orientation == 180) { orient = "portrait"; } else if ( orientation == 90 || orientation == -90) { orient = "landscape"; } else { orient = "normal"; } return orient; }, searchDevice: function(d) { var device = ""; if (d.match(/Android/i) || d.match(/iPhone|iPod/i)) { device = "mobile"; } else if (d.match(/iPad/i)) { device = "tablet"; } else if (d.match(/BlackBerry/i) || d.match(/IEMobile/i)) { device = "other mobile"; } else { device = "desktop"; } return device; }, searchString: function (data) { for (var i=0;i'mmmm d',' yyyy''", full_long: "mmm d',' yyyy 'at' hh:MM TT", full_long_small_date: "hh:MM TT'
mmm d',' yyyy''" }, month: ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"], month_abbr: ["Jan.", "Feb.", "March", "April", "May", "June", "July", "Aug.", "Sept.", "Oct.", "Nov.", "Dec."], day: ["Sunday","Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"], day_abbr: ["Sun.", "Mon.", "Tues.", "Wed.", "Thurs.", "Fri.", "Sat."], hour: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12], hour_suffix: ["am"], //B.C. bc_format: { year: "yyyy", month_short: "mmm", month: "mmmm yyyy", full_short: "mmm d", full: "mmmm d',' yyyy", time_no_seconds_short: "h:MM TT", time_no_seconds_small_date: "dddd', 'h:MM TT'
'mmmm d',' yyyy''", full_long: "dddd',' mmm d',' yyyy 'at' hh:MM TT", full_long_small_date: "hh:MM TT'
'dddd',' mmm d',' yyyy''" }, setLanguage: function(lang) { trace("SET DATE LANGUAGE"); VMM.Date.dateformats = lang.dateformats; VMM.Date.month = lang.date.month; VMM.Date.month_abbr = lang.date.month_abbr; VMM.Date.day = lang.date.day; VMM.Date.day_abbr = lang.date.day_abbr; dateFormat.i18n.dayNames = lang.date.day_abbr.concat(lang.date.day); dateFormat.i18n.monthNames = lang.date.month_abbr.concat(lang.date.month); }, parse: function(d, precision) { "use strict"; var date, date_array, time_array, time_parse, p = { year: false, month: false, day: false, hour: false, minute: false, second: false, millisecond: false }; if (type.of(d) == "date") { trace("DEBUG THIS, ITs A DATE"); date = d; } else { date = new Date(0, 0, 1, 0, 0, 0, 0); if ( d.match(/,/gi) ) { date_array = d.split(","); for(var i = 0; i < date_array.length; i++) { date_array[i] = parseInt(date_array[i], 10); } if (date_array[0]) { date.setFullYear(date_array[0]); p.year = true; } if (date_array[1]) { date.setMonth(date_array[1] - 1); p.month = true; } if (date_array[2]) { date.setDate(date_array[2]); p.day = true; } if (date_array[3]) { date.setHours(date_array[3]); p.hour = true; } if (date_array[4]) { date.setMinutes(date_array[4]); p.minute = true; } if (date_array[5]) { date.setSeconds(date_array[5]); if (date_array[5] >= 1) { p.second = true; } } if (date_array[6]) { date.setMilliseconds(date_array[6]); if (date_array[6] >= 1) { p.millisecond = true; } } } else if (d.match("/")) { if (d.match(" ")) { time_parse = d.split(" "); if (d.match(":")) { time_array = time_parse[1].split(":"); if (time_array[0] >= 0 ) { date.setHours(time_array[0]); p.hour = true; } if (time_array[1] >= 0) { date.setMinutes(time_array[1]); p.minute = true; } if (time_array[2] >= 0) { date.setSeconds(time_array[2]); p.second = true; } if (time_array[3] >= 0) { date.setMilliseconds(time_array[3]); p.millisecond = true; } } date_array = time_parse[0].split("/"); } else { date_array = d.split("/"); } if (date_array[2]) { date.setFullYear(date_array[2]); p.year = true; } if (date_array[0] >= 0) { date.setMonth(date_array[0] - 1); p.month = true; } if (date_array[1] >= 0) { if (date_array[1].length > 2) { date.setFullYear(date_array[1]); p.year = true; } else { date.setDate(date_array[1]); p.day = true; } } } else if (d.match("now")) { var now = new Date(); date.setFullYear(now.getFullYear()); p.year = true; date.setMonth(now.getMonth()); p.month = true; date.setDate(now.getDate()); p.day = true; if (d.match("hours")) { date.setHours(now.getHours()); p.hour = true; } if (d.match("minutes")) { date.setHours(now.getHours()); date.setMinutes(now.getMinutes()); p.hour = true; p.minute = true; } if (d.match("seconds")) { date.setHours(now.getHours()); date.setMinutes(now.getMinutes()); date.setSeconds(now.getSeconds()); p.hour = true; p.minute = true; p.second = true; } if (d.match("milliseconds")) { date.setHours(now.getHours()); date.setMinutes(now.getMinutes()); date.setSeconds(now.getSeconds()); date.setMilliseconds(now.getMilliseconds()); p.hour = true; p.minute = true; p.second = true; p.millisecond = true; } } else if (d.length <= 8) { p.year = true; date.setFullYear(parseInt(d, 10)); date.setMonth(0); date.setDate(1); date.setHours(0); date.setMinutes(0); date.setSeconds(0); date.setMilliseconds(0); } else if (d.match("T")) { if (navigator.userAgent.match(/MSIE\s(?!9.0)/)) { // IE 8 < Won't accept dates with a "-" in them. time_parse = d.split("T"); if (d.match(":")) { time_array = time_parse[1].split(":"); if (time_array[0] >= 1) { date.setHours(time_array[0]); p.hour = true; } if (time_array[1] >= 1) { date.setMinutes(time_array[1]); p.minute = true; } if (time_array[2] >= 1) { date.setSeconds(time_array[2]); if (time_array[2] >= 1) { p.second = true; } } if (time_array[3] >= 1) { date.setMilliseconds(time_array[3]); if (time_array[3] >= 1) { p.millisecond = true; } } } date_array = time_parse[0].split("-"); if (date_array[0]) { date.setFullYear(date_array[0]); p.year = true; } if (date_array[1] >= 0) { date.setMonth(date_array[1] - 1); p.month = true; } if (date_array[2] >= 0) { date.setDate(date_array[2]); p.day = true; } } else { date = new Date(Date.parse(d)); p.year = true; p.month = true; p.day = true; p.hour = true; p.minute = true; if (date.getSeconds() >= 1) { p.second = true; } if (date.getMilliseconds() >= 1) { p.millisecond = true; } } } else { date = new Date( parseInt(d.slice(0,4), 10), parseInt(d.slice(4,6), 10) - 1, parseInt(d.slice(6,8), 10), parseInt(d.slice(8,10), 10), parseInt(d.slice(10,12), 10) ); p.year = true; p.month = true; p.day = true; p.hour = true; p.minute = true; if (date.getSeconds() >= 1) { p.second = true; } if (date.getMilliseconds() >= 1) { p.millisecond = true; } } } if (precision != null && precision != "") { return { date: date, precision: p }; } else { return date; } }, prettyDate: function(d, is_abbr, p, d2) { var _date, _date2, format, bc_check, is_pair = false, bc_original, bc_number, bc_string; if (d2 != null && d2 != "" && typeof d2 != 'undefined') { is_pair = true; trace("D2 " + d2); } if (type.of(d) == "date") { if (type.of(p) == "object") { if (p.millisecond || p.second && d.getSeconds() >= 1) { // YEAR MONTH DAY HOUR MINUTE if (is_abbr){ format = VMM.Date.dateformats.time_short; } else { format = VMM.Date.dateformats.time_short; } } else if (p.minute) { // YEAR MONTH DAY HOUR MINUTE if (is_abbr){ format = VMM.Date.dateformats.time_no_seconds_short; } else { format = VMM.Date.dateformats.time_no_seconds_small_date; } } else if (p.hour) { // YEAR MONTH DAY HOUR if (is_abbr) { format = VMM.Date.dateformats.time_no_seconds_short; } else { format = VMM.Date.dateformats.time_no_seconds_small_date; } } else if (p.day) { // YEAR MONTH DAY if (is_abbr) { format = VMM.Date.dateformats.full_short; } else { format = VMM.Date.dateformats.full; } } else if (p.month) { // YEAR MONTH if (is_abbr) { format = VMM.Date.dateformats.month_short; } else { format = VMM.Date.dateformats.month; } } else if (p.year) { format = VMM.Date.dateformats.year; } else { format = VMM.Date.dateformats.year; } } else { if (d.getMonth() === 0 && d.getDate() == 1 && d.getHours() === 0 && d.getMinutes() === 0 ) { // YEAR ONLY format = VMM.Date.dateformats.year; } else if (d.getDate() <= 1 && d.getHours() === 0 && d.getMinutes() === 0) { // YEAR MONTH if (is_abbr) { format = VMM.Date.dateformats.month_short; } else { format = VMM.Date.dateformats.month; } } else if (d.getHours() === 0 && d.getMinutes() === 0) { // YEAR MONTH DAY if (is_abbr) { format = VMM.Date.dateformats.full_short; } else { format = VMM.Date.dateformats.full; } } else if (d.getMinutes() === 0) { // YEAR MONTH DAY HOUR if (is_abbr) { format = VMM.Date.dateformats.time_no_seconds_short; } else { format = VMM.Date.dateformats.time_no_seconds_small_date; } } else { // YEAR MONTH DAY HOUR MINUTE if (is_abbr){ format = VMM.Date.dateformats.time_no_seconds_short; } else { format = VMM.Date.dateformats.full_long; } } } _date = dateFormat(d, format, false); //_date = "Jan" bc_check = _date.split(" "); // BC TIME SUPPORT for(var i = 0; i < bc_check.length; i++) { if ( parseInt(bc_check[i], 10) < 0 ) { trace("YEAR IS BC"); bc_original = bc_check[i]; bc_number = Math.abs( parseInt(bc_check[i], 10) ); bc_string = bc_number.toString() + " B.C."; _date = _date.replace(bc_original, bc_string); } } if (is_pair) { _date2 = dateFormat(d2, format, false); bc_check = _date2.split(" "); // BC TIME SUPPORT for(var j = 0; j < bc_check.length; j++) { if ( parseInt(bc_check[j], 10) < 0 ) { trace("YEAR IS BC"); bc_original = bc_check[j]; bc_number = Math.abs( parseInt(bc_check[j], 10) ); bc_string = bc_number.toString() + " B.C."; _date2 = _date2.replace(bc_original, bc_string); } } } } else { trace("NOT A VALID DATE?"); trace(d); } if (is_pair) { return _date + " — " + _date2; } else { return _date; } } }).init(); /* * Date Format 1.2.3 * (c) 2007-2009 Steven Levithan * MIT license * * Includes enhancements by Scott Trenda * and Kris Kowal * * Accepts a date, a mask, or a date and a mask. * Returns a formatted version of the given date. * The date defaults to the current date/time. * The mask defaults to dateFormat.masks.default. */ var dateFormat = function () { var token = /d{1,4}|m{1,4}|yy(?:yy)?|([HhMsTt])\1?|[LloSZ]|"[^"]*"|'[^']*'/g, timezone = /\b(?:[PMCEA][SDP]T|(?:Pacific|Mountain|Central|Eastern|Atlantic) (?:Standard|Daylight|Prevailing) Time|(?:GMT|UTC)(?:[-+]\d{4})?)\b/g, timezoneClip = /[^-+\dA-Z]/g, pad = function (val, len) { val = String(val); len = len || 2; while (val.length < len) val = "0" + val; return val; }; // Regexes and supporting functions are cached through closure return function (date, mask, utc) { var dF = dateFormat; // You can't provide utc if you skip other args (use the "UTC:" mask prefix) if (arguments.length == 1 && Object.prototype.toString.call(date) == "[object String]" && !/\d/.test(date)) { mask = date; date = undefined; } // Passing date through Date applies Date.parse, if necessary // Caused problems in IE // date = date ? new Date(date) : new Date; if (isNaN(date)) { trace("invalid date " + date); //return ""; } mask = String(dF.masks[mask] || mask || dF.masks["default"]); // Allow setting the utc argument via the mask if (mask.slice(0, 4) == "UTC:") { mask = mask.slice(4); utc = true; } var _ = utc ? "getUTC" : "get", d = date[_ + "Date"](), D = date[_ + "Day"](), m = date[_ + "Month"](), y = date[_ + "FullYear"](), H = date[_ + "Hours"](), M = date[_ + "Minutes"](), s = date[_ + "Seconds"](), L = date[_ + "Milliseconds"](), o = utc ? 0 : date.getTimezoneOffset(), flags = { d: d, dd: pad(d), ddd: dF.i18n.dayNames[D], dddd: dF.i18n.dayNames[D + 7], m: m + 1, mm: pad(m + 1), mmm: dF.i18n.monthNames[m], mmmm: dF.i18n.monthNames[m + 12], yy: String(y).slice(2), yyyy: y, h: H % 12 || 12, hh: pad(H % 12 || 12), H: H, HH: pad(H), M: M, MM: pad(M), s: s, ss: pad(s), l: pad(L, 3), L: pad(L > 99 ? Math.round(L / 10) : L), t: H < 12 ? "a" : "p", tt: H < 12 ? "am" : "pm", T: H < 12 ? "A" : "P", TT: H < 12 ? "AM" : "PM", Z: utc ? "UTC" : (String(date).match(timezone) || [""]).pop().replace(timezoneClip, ""), o: (o > 0 ? "-" : "+") + pad(Math.floor(Math.abs(o) / 60) * 100 + Math.abs(o) % 60, 4), S: ["th", "st", "nd", "rd"][d % 10 > 3 ? 0 : (d % 100 - d % 10 != 10) * d % 10] }; return mask.replace(token, function ($0) { return $0 in flags ? flags[$0] : $0.slice(1, $0.length - 1); }); }; }(); // Some common format strings dateFormat.masks = { "default": "ddd mmm dd yyyy HH:MM:ss", shortDate: "m/d/yy", mediumDate: "mmm d, yyyy", longDate: "mmmm d, yyyy", fullDate: "dddd, mmmm d, yyyy", shortTime: "h:MM TT", mediumTime: "h:MM:ss TT", longTime: "h:MM:ss TT Z", isoDate: "yyyy-mm-dd", isoTime: "HH:MM:ss", isoDateTime: "yyyy-mm-dd'T'HH:MM:ss", isoUtcDateTime: "UTC:yyyy-mm-dd'T'HH:MM:ss'Z'" }; // Internationalization strings dateFormat.i18n = { dayNames: [ "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" ], monthNames: [ "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec", "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" ] }; // For convenience... Date.prototype.format = function (mask, utc) { return dateFormat(this, mask, utc); }; } /* ********************************************** Begin VMM.Util.js ********************************************** */ /* * Utilities and Useful Functions ================================================== */ if(typeof VMM != 'undefined' && typeof VMM.Util == 'undefined') { VMM.Util = ({ init: function() { return this; }, /* * CORRECT PROTOCOL (DOES NOT WORK) ================================================== */ correctProtocol: function(url) { var loc = (window.parent.location.protocol).toString(), prefix = "", the_url = url.split("://", 2); if (loc.match("http")) { prefix = loc; } else { prefix = "https"; } return prefix + "://" + the_url[1]; }, /* * MERGE CONFIG ================================================== */ mergeConfig: function(config_main, config_to_merge) { var x; for (x in config_to_merge) { if (Object.prototype.hasOwnProperty.call(config_to_merge, x)) { config_main[x] = config_to_merge[x]; } } return config_main; }, /* * GET OBJECT ATTRIBUTE BY INDEX ================================================== */ getObjectAttributeByIndex: function(obj, index) { if(typeof obj != 'undefined') { var i = 0; for (var attr in obj){ if (index === i){ return obj[attr]; } i++; } return ""; } else { return ""; } }, /* * ORDINAL ================================================== */ ordinal: function(n) { return ["th","st","nd","rd"][(!( ((n%10) >3) || (Math.floor(n%100/10)==1)) ) * (n%10)]; }, /* * RANDOM BETWEEN ================================================== */ //VMM.Util.randomBetween(1, 3) randomBetween: function(min, max) { return Math.floor(Math.random() * (max - min + 1) + min); }, /* * AVERAGE * http://jsfromhell.com/array/average * var x = VMM.Util.average([2, 3, 4]); * VMM.Util.average([2, 3, 4]).mean ================================================== */ average: function(a) { var r = {mean: 0, variance: 0, deviation: 0}, t = a.length; for(var m, s = 0, l = t; l--; s += a[l]); for(m = r.mean = s / t, l = t, s = 0; l--; s += Math.pow(a[l] - m, 2)); return r.deviation = Math.sqrt(r.variance = s / t), r; }, /* * CUSTOM SORT ================================================== */ customSort: function(a, b) { var a1= a, b1= b; if(a1== b1) return 0; return a1> b1? 1: -1; }, /* * Remove Duplicates from Array ================================================== */ deDupeArray: function(arr) { var i, len=arr.length, out=[], obj={}; for (i=0;i h) { _fit.height = h; //_fit.width = Math.round((w / ratio_w) * ratio_h); _fit.width = Math.round((h / ratio_h) * ratio_w); if (_fit.width > w) { trace("FIT: DIDN'T FIT!!! ") } } return _fit; }, r16_9: function(w,h) { //VMM.Util.ratio.r16_9(w, h) // Returns corresponding number if (w !== null && w !== "") { return Math.round((h / 16) * 9); } else if (h !== null && h !== "") { return Math.round((w / 9) * 16); } }, r4_3: function(w,h) { if (w !== null && w !== "") { return Math.round((h / 4) * 3); } else if (h !== null && h !== "") { return Math.round((w / 3) * 4); } } }, doubledigit: function(n) { return (n < 10 ? '0' : '') + n; }, /* * Returns a truncated segement of a long string of between min and max words. If possible, ends on a period (otherwise goes to max). ================================================== */ truncateWords: function(s, min, max) { if (!min) min = 30; if (!max) max = min; var initial_whitespace_rExp = /^[^A-Za-z0-9\'\-]+/gi; var left_trimmedStr = s.replace(initial_whitespace_rExp, ""); var words = left_trimmedStr.split(" "); var result = []; min = Math.min(words.length, min); max = Math.min(words.length, max); for (var i = 0; i$&") .replace(pseudoUrlPattern, "$1$2") .replace(emailAddressPattern, "$1"); }, linkify_with_twitter: function(text,targets,is_touch) { // http://, https://, ftp:// var urlPattern = /\b(?:https?|ftp):\/\/[a-z0-9-+&@#\/%?=~_|!:,.;]*[a-z0-9-+&@#\/%=~_|]/gim; var url_pattern = /(\()((?:ht|f)tps?:\/\/[a-z0-9\-._~!$&'()*+,;=:\/?#[\]@%]+)(\))|(\[)((?:ht|f)tps?:\/\/[a-z0-9\-._~!$&'()*+,;=:\/?#[\]@%]+)(\])|(\{)((?:ht|f)tps?:\/\/[a-z0-9\-._~!$&'()*+,;=:\/?#[\]@%]+)(\})|(<|&(?:lt|#60|#x3c);)((?:ht|f)tps?:\/\/[a-z0-9\-._~!$&'()*+,;=:\/?#[\]@%]+)(>|&(?:gt|#62|#x3e);)|((?:^|[^=\s'"\]])\s*['"]?|[^=\s]\s+)(\b(?:ht|f)tps?:\/\/[a-z0-9\-._~!$'()*+,;=:\/?#[\]@%]+(?:(?!&(?:gt|#0*62|#x0*3e);|&(?:amp|apos|quot|#0*3[49]|#x0*2[27]);[.!&',:?;]?(?:[^a-z0-9\-._~!$&'()*+,;=:\/?#[\]@%]|$))&[a-z0-9\-._~!$'()*+,;=:\/?#[\]@%]*)*[a-z0-9\-_~$()*+=\/#[\]@%])/img; var url_replace = '$1$4$7$10$13$2$5$8$11$14$3$6$9$12'; // www. sans http:// or https:// var pseudoUrlPattern = /(^|[^\/])(www\.[\S]+(\b|$))/gim; function replaceURLWithHTMLLinks(text) { var exp = /(\b(https?|ftp|file):\/\/([-A-Z0-9+&@#%?=~_|!:,.;]*)([-A-Z0-9+&@#%?\/=~_|!:,.;]*)[-A-Z0-9+&@#\/%=~_|])/ig; return text.replace(exp, "$3"); } // Email addresses var emailAddressPattern = /(([a-zA-Z0-9_\-\.]+)@[a-zA-Z_]+?(?:\.[a-zA-Z]{2,6}))+/gim; //var twitterHandlePattern = /(@([\w]+))/g; var twitterHandlePattern = /\B@([\w-]+)/gm; var twitterSearchPattern = /(#([\w]+))/g; return text //.replace(urlPattern, "$&") .replace(url_pattern, url_replace) .replace(pseudoUrlPattern, "$1$2") .replace(emailAddressPattern, "$1") .replace(twitterHandlePattern, "@$1"); // TURN THIS BACK ON TO AUTOMAGICALLY LINK HASHTAGS TO TWITTER SEARCH //.replace(twitterSearchPattern, "$1"); }, linkify_wikipedia: function(text) { var urlPattern = /]*>(.*?)<\/i>/gim; return text .replace(urlPattern, "$&") .replace(/]*>/gim, "") .replace(/<\/i>/gim, "") .replace(/]*>/gim, "") .replace(/<\/b>/gim, ""); }, /* * Turns plain text links into real links ================================================== */ // VMM.Util.unlinkify(); unlinkify: function(text) { if(!text) return text; text = text.replace(/]*>/i,""); text = text.replace(/<\/a>/i, ""); return text; }, untagify: function(text) { if (!text) { return text; } text = text.replace(/<\s*\w.*?>/g,""); return text; }, /* * TK ================================================== */ nl2br: function(text) { return text.replace(/(\r\n|[\r\n]|\\n|\\r)/g,"
"); }, /* * Generate a Unique ID ================================================== */ // VMM.Util.unique_ID(size); unique_ID: function(size) { var getRandomNumber = function(range) { return Math.floor(Math.random() * range); }; var getRandomChar = function() { var chars = "abcdefghijklmnopqurstuvwxyzABCDEFGHIJKLMNOPQURSTUVWXYZ"; return chars.substr( getRandomNumber(62), 1 ); }; var randomID = function(size) { var str = ""; for(var i = 0; i < size; i++) { str += getRandomChar(); } return str; }; return randomID(size); }, /* * Tells you if a number is even or not ================================================== */ // VMM.Util.isEven(n) isEven: function(n){ return (n%2 === 0) ? true : false; }, /* * Get URL Variables ================================================== */ // var somestring = VMM.Util.getUrlVars(str_url)["varname"]; getUrlVars: function(string) { var str = string.toString(); if (str.match('&')) { str = str.replace("&", "&"); } else if (str.match('&')) { str = str.replace("&", "&"); } else if (str.match('&')) { str = str.replace("&", "&"); } var vars = [], hash; var hashes = str.slice(str.indexOf('?') + 1).split('&'); for(var i = 0; i < hashes.length; i++) { hash = hashes[i].split('='); vars.push(hash[0]); vars[hash[0]] = hash[1]; } return vars; }, /* * Cleans up strings to become real HTML ================================================== */ toHTML: function(text) { text = this.nl2br(text); text = this.linkify(text); return text.replace(/\s\s/g,"  "); }, /* * Returns text strings as CamelCase ================================================== */ toCamelCase: function(s,forceLowerCase) { if(forceLowerCase !== false) forceLowerCase = true; var sps = ((forceLowerCase) ? s.toLowerCase() : s).split(" "); for(var i=0; i 1 ? '.' + x[1] : ''; var rgx = /(\d+)(\d{3})/; while (rgx.test(x1)) { x1 = x1.replace(rgx, '$1' + ',' + '$2'); } return x1 + x2; }, /* * Transform text to Title Case ================================================== */ toTitleCase: function(t){ if ( VMM.Browser.browser == "Explorer" && parseInt(VMM.Browser.version, 10) >= 7) { return t.replace("_", "%20"); } else { var __TitleCase = { __smallWords: ['a', 'an', 'and', 'as', 'at', 'but','by', 'en', 'for', 'if', 'in', 'of', 'on', 'or','the', 'to', 'v[.]?', 'via', 'vs[.]?'], init: function() { this.__smallRE = this.__smallWords.join('|'); this.__lowerCaseWordsRE = new RegExp('\\b(' + this.__smallRE + ')\\b', 'gi'); this.__firstWordRE = new RegExp('^([^a-zA-Z0-9 \\r\\n\\t]*)(' + this.__smallRE + ')\\b', 'gi'); this.__lastWordRE = new RegExp('\\b(' + this.__smallRE + ')([^a-zA-Z0-9 \\r\\n\\t]*)$', 'gi'); }, toTitleCase: function(string) { var line = ''; var split = string.split(/([:.;?!][ ]|(?:[ ]|^)["“])/); for (var i = 0; i < split.length; ++i) { var s = split[i]; s = s.replace(/\b([a-zA-Z][a-z.'’]*)\b/g,this.__titleCaseDottedWordReplacer); // lowercase the list of small words s = s.replace(this.__lowerCaseWordsRE, this.__lowerReplacer); // if the first word in the title is a small word then capitalize it s = s.replace(this.__firstWordRE, this.__firstToUpperCase); // if the last word in the title is a small word, then capitalize it s = s.replace(this.__lastWordRE, this.__firstToUpperCase); line += s; } // special cases line = line.replace(/ V(s?)\. /g, ' v$1. '); line = line.replace(/(['’])S\b/g, '$1s'); line = line.replace(/\b(AT&T|Q&A)\b/ig, this.__upperReplacer); return line; }, __titleCaseDottedWordReplacer: function (w) { return (w.match(/[a-zA-Z][.][a-zA-Z]/)) ? w : __TitleCase.__firstToUpperCase(w); }, __lowerReplacer: function (w) { return w.toLowerCase() }, __upperReplacer: function (w) { return w.toUpperCase() }, __firstToUpperCase: function (w) { var split = w.split(/(^[^a-zA-Z0-9]*[a-zA-Z0-9])(.*)$/); if (split[1]) { split[1] = split[1].toUpperCase(); } return split.join(''); } }; __TitleCase.init(); t = t.replace(/_/g," "); t = __TitleCase.toTitleCase(t); return t; } } }).init(); } /* ********************************************** Begin LazyLoad.js ********************************************** */ /*jslint browser: true, eqeqeq: true, bitwise: true, newcap: true, immed: true, regexp: false */ /* LazyLoad makes it easy and painless to lazily load one or more external JavaScript or CSS files on demand either during or after the rendering of a web page. Supported browsers include Firefox 2+, IE6+, Safari 3+ (including Mobile Safari), Google Chrome, and Opera 9+. Other browsers may or may not work and are not officially supported. Visit https://github.com/rgrove/lazyload/ for more info. Copyright (c) 2011 Ryan Grove All rights reserved. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the 'Software'), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. @module lazyload @class LazyLoad @static @version 2.0.3 (git) */ LazyLoad = (function (doc) { // -- Private Variables ------------------------------------------------------ // User agent and feature test information. var env, // Reference to the element (populated lazily). head, // Requests currently in progress, if any. pending = {}, // Number of times we've polled to check whether a pending stylesheet has // finished loading. If this gets too high, we're probably stalled. pollCount = 0, // Queued requests. queue = {css: [], js: []}, // Reference to the browser's list of stylesheets. styleSheets = doc.styleSheets; // -- Private Methods -------------------------------------------------------- /** Creates and returns an HTML element with the specified name and attributes. @method createNode @param {String} name element name @param {Object} attrs name/value mapping of element attributes @return {HTMLElement} @private */ function createNode(name, attrs) { var node = doc.createElement(name), attr; for (attr in attrs) { if (attrs.hasOwnProperty(attr)) { node.setAttribute(attr, attrs[attr]); } } return node; } /** Called when the current pending resource of the specified type has finished loading. Executes the associated callback (if any) and loads the next resource in the queue. @method finish @param {String} type resource type ('css' or 'js') @private */ function finish(type) { var p = pending[type], callback, urls; if (p) { callback = p.callback; urls = p.urls; urls.shift(); pollCount = 0; // If this is the last of the pending URLs, execute the callback and // start the next request in the queue (if any). if (!urls.length) { callback && callback.call(p.context, p.obj); pending[type] = null; queue[type].length && load(type); } } } /** Populates the env variable with user agent and feature test information. @method getEnv @private */ function getEnv() { var ua = navigator.userAgent; env = { // True if this browser supports disabling async mode on dynamically // created script nodes. See // http://wiki.whatwg.org/wiki/Dynamic_Script_Execution_Order async: doc.createElement('script').async === true }; (env.webkit = /AppleWebKit\//.test(ua)) || (env.ie = /MSIE/.test(ua)) || (env.opera = /Opera/.test(ua)) || (env.gecko = /Gecko\//.test(ua)) || (env.unknown = true); } /** Loads the specified resources, or the next resource of the specified type in the queue if no resources are specified. If a resource of the specified type is already being loaded, the new request will be queued until the first request has been finished. When an array of resource URLs is specified, those URLs will be loaded in parallel if it is possible to do so while preserving execution order. All browsers support parallel loading of CSS, but only Firefox and Opera support parallel loading of scripts. In other browsers, scripts will be queued and loaded one at a time to ensure correct execution order. @method load @param {String} type resource type ('css' or 'js') @param {String|Array} urls (optional) URL or array of URLs to load @param {Function} callback (optional) callback function to execute when the resource is loaded @param {Object} obj (optional) object to pass to the callback function @param {Object} context (optional) if provided, the callback function will be executed in this object's context @private */ function load(type, urls, callback, obj, context) { var _finish = function () { finish(type); }, isCSS = type === 'css', nodes = [], i, len, node, p, pendingUrls, url; env || getEnv(); if (urls) { // If urls is a string, wrap it in an array. Otherwise assume it's an // array and create a copy of it so modifications won't be made to the // original. urls = typeof urls === 'string' ? [urls] : urls.concat(); // Create a request object for each URL. If multiple URLs are specified, // the callback will only be executed after all URLs have been loaded. // // Sadly, Firefox and Opera are the only browsers capable of loading // scripts in parallel while preserving execution order. In all other // browsers, scripts must be loaded sequentially. // // All browsers respect CSS specificity based on the order of the link // elements in the DOM, regardless of the order in which the stylesheets // are actually downloaded. if (isCSS || env.async || env.gecko || env.opera) { // Load in parallel. queue[type].push({ urls : urls, callback: callback, obj : obj, context : context }); } else { // Load sequentially. for (i = 0, len = urls.length; i < len; ++i) { queue[type].push({ urls : [urls[i]], callback: i === len - 1 ? callback : null, // callback is only added to the last URL obj : obj, context : context }); } } } // If a previous load request of this type is currently in progress, we'll // wait our turn. Otherwise, grab the next item in the queue. if (pending[type] || !(p = pending[type] = queue[type].shift())) { return; } head || (head = doc.head || doc.getElementsByTagName('head')[0]); pendingUrls = p.urls; for (i = 0, len = pendingUrls.length; i < len; ++i) { url = pendingUrls[i]; if (isCSS) { node = env.gecko ? createNode('style') : createNode('link', { href: url, rel : 'stylesheet' }); } else { node = createNode('script', {src: url}); node.async = false; } node.className = 'lazyload'; node.setAttribute('charset', 'utf-8'); if (env.ie && !isCSS) { node.onreadystatechange = function () { if (/loaded|complete/.test(node.readyState)) { node.onreadystatechange = null; _finish(); } }; } else if (isCSS && (env.gecko || env.webkit)) { // Gecko and WebKit don't support the onload event on link nodes. if (env.webkit) { // In WebKit, we can poll for changes to document.styleSheets to // figure out when stylesheets have loaded. p.urls[i] = node.href; // resolve relative URLs (or polling won't work) pollWebKit(); } else { // In Gecko, we can import the requested URL into a ").appendTo("head"); }); }(window, document, jQuery)); /* ********************************************** Begin AES.js ********************************************** */ /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ /* AES implementation in JavaScript (c) Chris Veness 2005-2011 */ /* - see http://csrc.nist.gov/publications/PubsFIPS.html#197 */ /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ var Aes = {}; // Aes namespace /** * AES Cipher function: encrypt 'input' state with Rijndael algorithm * applies Nr rounds (10/12/14) using key schedule w for 'add round key' stage * * @param {Number[]} input 16-byte (128-bit) input state array * @param {Number[][]} w Key schedule as 2D byte-array (Nr+1 x Nb bytes) * @returns {Number[]} Encrypted output state array */ Aes.cipher = function(input, w) { // main Cipher function [§5.1] var Nb = 4; // block size (in words): no of columns in state (fixed at 4 for AES) var Nr = w.length/Nb - 1; // no of rounds: 10/12/14 for 128/192/256-bit keys var state = [[],[],[],[]]; // initialise 4xNb byte-array 'state' with input [§3.4] for (var i=0; i<4*Nb; i++) state[i%4][Math.floor(i/4)] = input[i]; state = Aes.addRoundKey(state, w, 0, Nb); for (var round=1; round 6 && i%Nk == 4) { temp = Aes.subWord(temp); } for (var t=0; t<4; t++) w[i][t] = w[i-Nk][t] ^ temp[t]; } return w; } /* * ---- remaining routines are private, not called externally ---- */ Aes.subBytes = function(s, Nb) { // apply SBox to state S [§5.1.1] for (var r=0; r<4; r++) { for (var c=0; c>> i*8) & 0xff; for (var i=0; i<2; i++) counterBlock[i+2] = (nonceRnd >>> i*8) & 0xff; for (var i=0; i<4; i++) counterBlock[i+4] = (nonceSec >>> i*8) & 0xff; // and convert it to a string to go on the front of the ciphertext var ctrTxt = ''; for (var i=0; i<8; i++) ctrTxt += String.fromCharCode(counterBlock[i]); // generate key schedule - an expansion of the key into distinct Key Rounds for each round var keySchedule = Aes.keyExpansion(key); var blockCount = Math.ceil(plaintext.length/blockSize); var ciphertxt = new Array(blockCount); // ciphertext as array of strings for (var b=0; b>> c*8) & 0xff; for (var c=0; c<4; c++) counterBlock[15-c-4] = (b/0x100000000 >>> c*8) var cipherCntr = Aes.cipher(counterBlock, keySchedule); // -- encrypt counter block -- // block size is reduced on final block var blockLength = b>> c*8) & 0xff; for (var c=0; c<4; c++) counterBlock[15-c-4] = (((b+1)/0x100000000-1) >>> c*8) & 0xff; var cipherCntr = Aes.cipher(counterBlock, keySchedule); // encrypt counter block var plaintxtByte = new Array(ciphertext[b].length); for (var i=0; i 0) { while (c++ < 3) { pad += '='; plain += '\0'; } } // note: doing padding here saves us doing special-case packing for trailing 1 or 2 chars for (c=0; c>18 & 0x3f; h2 = bits>>12 & 0x3f; h3 = bits>>6 & 0x3f; h4 = bits & 0x3f; // use hextets to index into code string e[c/3] = b64.charAt(h1) + b64.charAt(h2) + b64.charAt(h3) + b64.charAt(h4); } coded = e.join(''); // join() is far faster than repeated string concatenation in IE // replace 'A's from padded nulls with '='s coded = coded.slice(0, coded.length-pad.length) + pad; return coded; } /** * Decode string from Base64, as defined by RFC 4648 [http://tools.ietf.org/html/rfc4648] * (instance method extending String object). As per RFC 4648, newlines are not catered for. * * @param {String} str The string to be decoded from base-64 * @param {Boolean} [utf8decode=false] Flag to indicate whether str is Unicode string to be decoded * from UTF8 after conversion from base64 * @returns {String} decoded string */ Base64.decode = function(str, utf8decode) { utf8decode = (typeof utf8decode == 'undefined') ? false : utf8decode; var o1, o2, o3, h1, h2, h3, h4, bits, d=[], plain, coded; var b64 = Base64.code; coded = utf8decode ? str.decodeUTF8() : str; for (var c=0; c>>16 & 0xff; o2 = bits>>>8 & 0xff; o3 = bits & 0xff; d[c/4] = String.fromCharCode(o1, o2, o3); // check for padding if (h4 == 0x40) d[c/4] = String.fromCharCode(o1, o2); if (h3 == 0x40) d[c/4] = String.fromCharCode(o1); } plain = d.join(''); // join() is far faster than repeated string concatenation in IE return utf8decode ? plain.decodeUTF8() : plain; } /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ /* Utf8 class: encode / decode between multi-byte Unicode characters and UTF-8 multiple */ /* single-byte character encoding (c) Chris Veness 2002-2011 */ /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ var Utf8 = {}; // Utf8 namespace /** * Encode multi-byte Unicode string into utf-8 multiple single-byte characters * (BMP / basic multilingual plane only) * * Chars in range U+0080 - U+07FF are encoded in 2 chars, U+0800 - U+FFFF in 3 chars * * @param {String} strUni Unicode string to be encoded as UTF-8 * @returns {String} encoded string */ Utf8.encode = function(strUni) { // use regular expressions & String.replace callback function for better efficiency // than procedural approaches var strUtf = strUni.replace( /[\u0080-\u07ff]/g, // U+0080 - U+07FF => 2 bytes 110yyyyy, 10zzzzzz function(c) { var cc = c.charCodeAt(0); return String.fromCharCode(0xc0 | cc>>6, 0x80 | cc&0x3f); } ); strUtf = strUtf.replace( /[\u0800-\uffff]/g, // U+0800 - U+FFFF => 3 bytes 1110xxxx, 10yyyyyy, 10zzzzzz function(c) { var cc = c.charCodeAt(0); return String.fromCharCode(0xe0 | cc>>12, 0x80 | cc>>6&0x3F, 0x80 | cc&0x3f); } ); return strUtf; } /** * Decode utf-8 encoded string back into multi-byte Unicode characters * * @param {String} strUtf UTF-8 string to be decoded back to Unicode * @returns {String} decoded string */ Utf8.decode = function(strUtf) { // note: decode 3-byte chars first as decoded 2-byte strings could appear to be 3-byte char! var strUni = strUtf.replace( /[\u00e0-\u00ef][\u0080-\u00bf][\u0080-\u00bf]/g, // 3-byte chars function(c) { // (note parentheses for precence) var cc = ((c.charCodeAt(0)&0x0f)<<12) | ((c.charCodeAt(1)&0x3f)<<6) | ( c.charCodeAt(2)&0x3f); return String.fromCharCode(cc); } ); strUni = strUni.replace( /[\u00c0-\u00df][\u0080-\u00bf]/g, // 2-byte chars function(c) { // (note parentheses for precence) var cc = (c.charCodeAt(0)&0x1f)<<6 | c.charCodeAt(1)&0x3f; return String.fromCharCode(cc); } ); return strUni; } /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ /* ********************************************** Begin bootstrap-tooltip.js ********************************************** */ /* =========================================================== * bootstrap-tooltip.js v2.0.1 * http://twitter.github.com/bootstrap/javascript.html#tooltips * Inspired by the original jQuery.tipsy by Jason Frame * =========================================================== * Copyright 2012 Twitter, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * ========================================================== */ !function( $ ) { "use strict" /* TOOLTIP PUBLIC CLASS DEFINITION * =============================== */ var Tooltip = function ( element, options ) { this.init('tooltip', element, options) } Tooltip.prototype = { constructor: Tooltip , init: function ( type, element, options ) { var eventIn , eventOut this.type = type this.$element = $(element) this.options = this.getOptions(options) this.enabled = true if (this.options.trigger != 'manual') { eventIn = this.options.trigger == 'hover' ? 'mouseenter' : 'focus' eventOut = this.options.trigger == 'hover' ? 'mouseleave' : 'blur' this.$element.on(eventIn, this.options.selector, $.proxy(this.enter, this)) this.$element.on(eventOut, this.options.selector, $.proxy(this.leave, this)) } this.options.selector ? (this._options = $.extend({}, this.options, { trigger: 'manual', selector: '' })) : this.fixTitle() } , getOptions: function ( options ) { options = $.extend({}, $.fn[this.type].defaults, options, this.$element.data()) if (options.delay && typeof options.delay == 'number') { options.delay = { show: options.delay , hide: options.delay } } return options } , enter: function ( e ) { var self = $(e.currentTarget)[this.type](this._options).data(this.type) if (!self.options.delay || !self.options.delay.show) { self.show() } else { self.hoverState = 'in' setTimeout(function() { if (self.hoverState == 'in') { self.show() } }, self.options.delay.show) } } , leave: function ( e ) { var self = $(e.currentTarget)[this.type](this._options).data(this.type) if (!self.options.delay || !self.options.delay.hide) { self.hide() } else { self.hoverState = 'out' setTimeout(function() { if (self.hoverState == 'out') { self.hide() } }, self.options.delay.hide) } } , show: function () { var $tip , inside , pos , actualWidth , actualHeight , placement , tp if (this.hasContent() && this.enabled) { $tip = this.tip() this.setContent() if (this.options.animation) { $tip.addClass('fade') } placement = typeof this.options.placement == 'function' ? this.options.placement.call(this, $tip[0], this.$element[0]) : this.options.placement inside = /in/.test(placement) $tip .remove() .css({ top: 0, left: 0, display: 'block' }) .appendTo(inside ? this.$element : document.body) pos = this.getPosition(inside) actualWidth = $tip[0].offsetWidth actualHeight = $tip[0].offsetHeight switch (inside ? placement.split(' ')[1] : placement) { case 'bottom': tp = {top: pos.top + pos.height, left: pos.left + pos.width / 2 - actualWidth / 2} break case 'top': tp = {top: pos.top - actualHeight, left: pos.left + pos.width / 2 - actualWidth / 2} break case 'left': tp = {top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left - actualWidth} break case 'right': tp = {top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left + pos.width} break } $tip .css(tp) .addClass(placement) .addClass('in') } } , setContent: function () { var $tip = this.tip() $tip.find('.timeline-tooltip-inner').html(this.getTitle()) $tip.removeClass('fade in top bottom left right') } , hide: function () { var that = this , $tip = this.tip() $tip.removeClass('in') function removeWithAnimation() { var timeout = setTimeout(function () { $tip.off($.support.transition.end).remove() }, 500) $tip.one($.support.transition.end, function () { clearTimeout(timeout) $tip.remove() }) } $.support.transition && this.$tip.hasClass('fade') ? removeWithAnimation() : $tip.remove() } , fixTitle: function () { var $e = this.$element if ($e.attr('title') || typeof($e.attr('data-original-title')) != 'string') { $e.attr('data-original-title', $e.attr('title') || '').removeAttr('title') } } , hasContent: function () { return this.getTitle() } , getPosition: function (inside) { return $.extend({}, (inside ? {top: 0, left: 0} : this.$element.offset()), { width: this.$element[0].offsetWidth , height: this.$element[0].offsetHeight }) } , getTitle: function () { var title , $e = this.$element , o = this.options title = $e.attr('data-original-title') || (typeof o.title == 'function' ? o.title.call($e[0]) : o.title) title = title.toString().replace(/(^\s*|\s*$)/, "") return title } , tip: function () { return this.$tip = this.$tip || $(this.options.template) } , validate: function () { if (!this.$element[0].parentNode) { this.hide() this.$element = null this.options = null } } , enable: function () { this.enabled = true } , disable: function () { this.enabled = false } , toggleEnabled: function () { this.enabled = !this.enabled } , toggle: function () { this[this.tip().hasClass('in') ? 'hide' : 'show']() } } /* TOOLTIP PLUGIN DEFINITION * ========================= */ $.fn.tooltip = function ( option ) { return this.each(function () { var $this = $(this) , data = $this.data('tooltip') , options = typeof option == 'object' && option if (!data) $this.data('tooltip', (data = new Tooltip(this, options))) if (typeof option == 'string') data[option]() }) } $.fn.tooltip.Constructor = Tooltip $.fn.tooltip.defaults = { animation: true , delay: 0 , selector: false , placement: 'top' , trigger: 'hover' , title: '' , template: '
' } }( window.jQuery ); /* ********************************************** Begin VMM.StoryJS.js ********************************************** */ /* VeriteCo StoryJS ================================================== */ /* * CodeKit Import * http://incident57.com/codekit/ ================================================== */ // @codekit-prepend "VMM.StoryJS.License.js"; // @codekit-prepend "Core/VMM.Core.js"; // @codekit-prepend "Language/VMM.Language.js"; // @codekit-prepend "Media/VMM.Media.js"; // @codekit-prepend "Slider/VMM.DragSlider.js"; // @codekit-prepend "Slider/VMM.Slider.js"; // @codekit-prepend "Library/jquery.fancybox.js"; // @codekit-prepend "Library/AES.js"; // @codekit-prepend "Library/bootstrap-tooltip.js"; if(typeof VMM != 'undefined' && typeof VMM.StoryJS == 'undefined') { VMM.StoryJS = function() { /* PRIVATE VARS ================================================== */ /* PUBLIC FUNCTIONS ================================================== */ this.init = function(d) { }; } } /* ********************************************** Begin VMM.Timeline.js ********************************************** */ /** * TimelineJS * Designed and built by Zach Wise at VéritéCo * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ /* * CodeKit Import * http://incident57.com/codekit/ ================================================== */ // @codekit-prepend "VMM.Timeline.License.js"; // @codekit-prepend "Core/VMM.StoryJS.js"; // @codekit-append "VMM.Timeline.TimeNav.js"; // @codekit-append "VMM.Timeline.DataObj.js"; /* Timeline ================================================== */ if(typeof VMM != 'undefined' && typeof VMM.Timeline == 'undefined') { VMM.Timeline = function(_timeline_id, w, h) { var $timeline, $container, $feature, $feedback, $slider, $navigation, slider, timenav, version = "2.x", timeline_id = "#timelinejs", events = {}, data = {}, _dates = [], config = {}, has_width = false, has_height = false, ie7 = false, is_moving = false; if (type.of(_timeline_id) == "string") { if (_timeline_id.match("#")) { timeline_id = _timeline_id; } else { timeline_id = "#" + _timeline_id; } } else { timeline_id = "#timelinejs"; } /* CONFIG ================================================== */ config = { embed: false, events: { data_ready: "DATAREADY", messege: "MESSEGE", headline: "HEADLINE", slide_change: "SLIDE_CHANGE", resize: "resize" }, id: timeline_id, source: "nothing", type: "timeline", touch: false, orientation: "normal", maptype: "toner", version: "2.x", preload: 4, current_slide: 0, hash_bookmark: false, start_at_end: false, start_at_slide: 0, start_zoom_adjust: 0, start_page: false, api_keys: { google: "", flickr: "", twitter: "" }, interval: 10, something: 0, width: 960, height: 540, spacing: 15, loaded: { slider: false, timenav: false, percentloaded: 0 }, nav: { start_page: false, interval_width: 200, interval_override: false, // change this to override the interval of years, months etc. density: 4, minor_width: 0, minor_left: 0, constraint: { left: 0, right: 0, right_min: 0, right_max: 0 }, zoom: { adjust: 0 }, multiplier: { current: 6, min: .1, max: 50 }, rows: [1, 1, 1], width: 960, height: 200, marker: { width: 150, height: 50 } }, feature: { width: 960, height: 540 }, slider: { width: 720, height: 400, content: { width: 720, height: 400, padding: 130, padding_default:130 }, nav: { width: 100, height: 200 } }, ease: "easeInOutExpo", duration: 1000, gmap_key: "", language: VMM.Language }; if ( w != null && w != "") { config.width = w; has_width = true; } if ( h != null && h != "") { config.height = h; has_height = true; } if(window.location.hash) { var hash = window.location.hash.substring(1); if (!isNaN(hash)) { config.current_slide = parseInt(hash); } } window.onhashchange = function () { var hash = window.location.hash.substring(1); if (config.hash_bookmark) { if (is_moving) { goToEvent(parseInt(hash)); } else { is_moving = false; } } else { goToEvent(parseInt(hash)); } } /* CREATE CONFIG ================================================== */ function createConfig(conf) { // APPLY SUPPLIED CONFIG TO TIMELINE CONFIG if (typeof embed_config == 'object') { timeline_config = embed_config; } if (typeof timeline_config == 'object') { trace("HAS TIMELINE CONFIG"); config = VMM.Util.mergeConfig(config, timeline_config); } else if (typeof conf == 'object') { config = VMM.Util.mergeConfig(config, conf); } if (VMM.Browser.device == "mobile" || VMM.Browser.device == "tablet") { config.touch = true; } config.nav.width = config.width; config.nav.height = 200; config.feature.width = config.width; config.feature.height = config.height - config.nav.height; config.nav.zoom.adjust = parseInt(config.start_zoom_adjust, 10); VMM.Timeline.Config = config; VMM.master_config.Timeline = VMM.Timeline.Config; this.events = config.events; if (config.gmap_key != "") { config.api_keys.google = config.gmap_key; } trace("VERSION " + config.version); version = config.version; } /* CREATE TIMELINE STRUCTURE ================================================== */ function createStructure() { // CREATE DOM STRUCTURE $timeline = VMM.getElement(timeline_id); VMM.Lib.addClass($timeline, "vco-timeline"); VMM.Lib.addClass($timeline, "vco-storyjs"); $container = VMM.appendAndGetElement($timeline, "
", "vco-container vco-main"); $feature = VMM.appendAndGetElement($container, "
", "vco-feature"); $slider = VMM.appendAndGetElement($feature, "
", "vco-slider"); $navigation = VMM.appendAndGetElement($container, "
", "vco-navigation"); $feedback = VMM.appendAndGetElement($timeline, "
", "vco-feedback", ""); if (typeof config.language.right_to_left != 'undefined') { VMM.Lib.addClass($timeline, "vco-right-to-left"); } slider = new VMM.Slider($slider, config); timenav = new VMM.Timeline.TimeNav($navigation); if (!has_width) { config.width = VMM.Lib.width($timeline); } else { VMM.Lib.width($timeline, config.width); } if (!has_height) { config.height = VMM.Lib.height($timeline); } else { VMM.Lib.height($timeline, config.height); } if (config.touch) { VMM.Lib.addClass($timeline, "vco-touch"); } else { VMM.Lib.addClass($timeline, "vco-notouch"); } } /* ON EVENT ================================================== */ function onDataReady(e, d) { trace("onDataReady"); data = d.timeline; if (type.of(data.era) != "array") { data.era = []; } buildDates(); }; function onDatesProcessed() { build(); } function reSize() { updateSize(); slider.setSize(config.feature.width, config.feature.height); timenav.setSize(config.width, config.height); if (orientationChange()) { setViewport(); } }; function onSliderLoaded(e) { config.loaded.slider = true; onComponentLoaded(); }; function onComponentLoaded(e) { config.loaded.percentloaded = config.loaded.percentloaded + 25; if (config.loaded.slider && config.loaded.timenav) { hideMessege(); } } function onTimeNavLoaded(e) { config.loaded.timenav = true; onComponentLoaded(); } function onSlideUpdate(e) { is_moving = true; config.current_slide = slider.getCurrentNumber(); setHash(config.current_slide); timenav.setMarker(config.current_slide, config.ease,config.duration); }; function onMarkerUpdate(e) { is_moving = true; config.current_slide = timenav.getCurrentNumber(); setHash(config.current_slide); slider.setSlide(config.current_slide); }; function goToEvent(n) { if (n <= _dates.length - 1 && n >= 0) { config.current_slide = n; slider.setSlide(config.current_slide); timenav.setMarker(config.current_slide, config.ease,config.duration); } } function setHash(n) { if (config.hash_bookmark) { window.location.hash = "#" + n.toString(); } } function getViewport() { } function setViewport() { var viewport_content = "", viewport_orientation = searchOrientation(window.orientation); if (VMM.Browser.device == "mobile") { if (viewport_orientation == "portrait") { //viewport_content = "width=device-width; initial-scale=0.75, maximum-scale=0.75"; viewport_content = "width=device-width; initial-scale=0.5, maximum-scale=0.5"; } else if (viewport_orientation == "landscape") { viewport_content = "width=device-width; initial-scale=0.5, maximum-scale=0.5"; } else { viewport_content = "width=device-width, initial-scale=1, maximum-scale=1.0"; } } else if (VMM.Browser.device == "tablet") { //viewport_content = "width=device-width, initial-scale=1, maximum-scale=1.0"; } if (document.getElementById("viewport")) { //VMM.Lib.attr("#viewport", "content", viewport_content); } else { //VMM.appendElement("head", ""); } } /* ORIENTATION ================================================== */ function searchOrientation(orientation) { var orient = ""; if ( orientation == 0 || orientation == 180) { orient = "portrait"; } else if ( orientation == 90 || orientation == -90) { orient = "landscape"; } else { orient = "normal"; } return orient; } function orientationChange() { var orientation = searchOrientation(window.orientation); if (orientation == config.orientation) { return false; } else { config.orientation = orientation; return true; } } /* PUBLIC FUNCTIONS ================================================== */ this.init = function(c, _data) { trace('INIT'); setViewport(); createConfig(c); createStructure(); if (type.of(_data) == "string") { config.source = _data; } // LANGUAGE VMM.Date.setLanguage(config.language); VMM.master_config.language = config.language; // EXTERNAL API VMM.ExternalAPI.setKeys(config.api_keys); VMM.ExternalAPI.googlemaps.setMapType(config.maptype); // EVENTS VMM.bindEvent(global, onDataReady, config.events.data_ready); VMM.bindEvent(global, showMessege, config.events.messege); VMM.fireEvent(global, config.events.messege, config.language.messages.loading_timeline); /* GET DATA ================================================== */ if (VMM.Browser.browser == "Explorer" || VMM.Browser.browser == "MSIE") { if ( parseInt(VMM.Browser.version, 10) <= 7 ) { ie7 = true; } } if (type.of(config.source) == "string" || type.of(config.source) == "object") { VMM.Timeline.DataObj.getData(config.source); } else { VMM.fireEvent(global, config.events.messege, "No data source provided"); //VMM.Timeline.DataObj.getData(VMM.getElement(timeline_id)); } }; this.iframeLoaded = function() { trace("iframeLoaded"); }; this.reload = function(_d) { trace("Load new timeline data" + _d); VMM.fireEvent(global, config.events.messege, config.language.messages.loading_timeline); data = {}; VMM.Timeline.DataObj.getData(_d); config.current_slide = 0; slider.setSlide(0); timenav.setMarker(0, config.ease,config.duration); }; /* DATA ================================================== */ function getData(url) { VMM.getJSON(url, function(d) { data = VMM.Timeline.DataObj.getData(d); VMM.fireEvent(global, config.events.data_ready); }); }; /* MESSEGES ================================================== */ function showMessege(e, msg, other) { trace("showMessege " + msg); //VMM.attachElement($timeline, $feedback); if (other) { VMM.attachElement($feedback, msg); } else{ VMM.attachElement($feedback, VMM.MediaElement.loadingmessage(msg)); } }; function hideMessege() { VMM.Lib.animate($feedback, config.duration, config.ease*4, {"opacity": 0}, detachMessege); }; function detachMessege() { VMM.Lib.detach($feedback); } /* BUILD DISPLAY ================================================== */ function build() { // START AT SLIDE if (parseInt(config.start_at_slide) > 0 && config.current_slide == 0) { config.current_slide = parseInt(config.start_at_slide); } // START AT END if (config.start_at_end && config.current_slide == 0) { config.current_slide = _dates.length - 1; } // IE7 if (ie7) { ie7 = true; VMM.fireEvent(global, config.events.messege, "Internet Explorer " + VMM.Browser.version + " is not supported by TimelineJS. Please update your browser to version 8 or higher."); } else { detachMessege(); reSize(); // EVENT LISTENERS VMM.bindEvent($slider, onSliderLoaded, "LOADED"); VMM.bindEvent($navigation, onTimeNavLoaded, "LOADED"); VMM.bindEvent($slider, onSlideUpdate, "UPDATE"); VMM.bindEvent($navigation, onMarkerUpdate, "UPDATE"); // INITIALIZE COMPONENTS slider.init(_dates); timenav.init(_dates, data.era); // RESIZE EVENT LISTENERS VMM.bindEvent(global, reSize, config.events.resize); } }; function updateSize() { trace("UPDATE SIZE"); config.width = VMM.Lib.width($timeline); config.height = VMM.Lib.height($timeline); config.nav.width = config.width; config.feature.width = config.width; config.feature.height = config.height - config.nav.height - 3; if (VMM.Browser.device == "mobile") { /* if (VMM.Browser.orientation == "portrait") { config.feature.height = 480; config.height = 480 + config.nav.height; } else if(VMM.Browser.orientation == "landscape") { config.feature.height = 320; config.height = 320 + config.nav.height; } else { config.feature.height = config.height - config.nav.height - 3; } */ } if (config.width < 641) { VMM.Lib.addClass($timeline, "vco-skinny"); } else { VMM.Lib.removeClass($timeline, "vco-skinny"); } }; // BUILD DATE OBJECTS function buildDates() { _dates = []; VMM.fireEvent(global, config.events.messege, "Building Dates"); updateSize(); for(var i = 0; i < data.date.length; i++) { if (data.date[i].startDate != null && data.date[i].startDate != "") { var _date = {}, do_start = VMM.Date.parse(data.date[i].startDate, true), do_end; _date.startdate = do_start.date; _date.precisiondate = do_start.precision; if (!isNaN(_date.startdate)) { // END DATE if (data.date[i].endDate != null && data.date[i].endDate != "") { _date.enddate = VMM.Date.parse(data.date[i].endDate); } else { _date.enddate = _date.startdate; } _date.needs_slug = false; if (data.date[i].headline == "") { if (data.date[i].slug != null && data.date[i].slug != "") { _date.needs_slug = true; } } _date.title = data.date[i].headline; _date.headline = data.date[i].headline; _date.type = data.date[i].type; _date.date = VMM.Date.prettyDate(_date.startdate, false, _date.precisiondate); _date.asset = data.date[i].asset; _date.fulldate = _date.startdate.getTime(); _date.text = data.date[i].text; _date.content = ""; _date.tag = data.date[i].tag; _date.slug = data.date[i].slug; _date.uniqueid = VMM.Util.unique_ID(7); _date.classname = data.date[i].classname; _dates.push(_date); } } }; /* CUSTOM SORT ================================================== */ if (data.type != "storify") { _dates.sort(function(a, b){ return a.fulldate - b.fulldate }); } /* CREATE START PAGE IF AVAILABLE ================================================== */ if (data.headline != null && data.headline != "" && data.text != null && data.text != "") { var startpage_date, do_start, _date = {}, td_num = 0, td; if (typeof data.startDate != 'undefined') { do_start = VMM.Date.parse(data.startDate, true); startpage_date = do_start.date; } else { startpage_date = false; } trace("HAS STARTPAGE"); trace(startpage_date); if (startpage_date && startpage_date < _dates[0].startdate) { _date.startdate = new Date(startpage_date); } else { td = _dates[0].startdate; _date.startdate = new Date(_dates[0].startdate); if (td.getMonth() === 0 && td.getDate() == 1 && td.getHours() === 0 && td.getMinutes() === 0 ) { // trace("YEAR ONLY"); _date.startdate.setFullYear(td.getFullYear() - 1); } else if (td.getDate() <= 1 && td.getHours() === 0 && td.getMinutes() === 0) { // trace("YEAR MONTH"); _date.startdate.setMonth(td.getMonth() - 1); } else if (td.getHours() === 0 && td.getMinutes() === 0) { // trace("YEAR MONTH DAY"); _date.startdate.setDate(td.getDate() - 1); } else if (td.getMinutes() === 0) { // trace("YEAR MONTH DAY HOUR"); _date.startdate.setHours(td.getHours() - 1); } else { // trace("YEAR MONTH DAY HOUR MINUTE"); _date.startdate.setMinutes(td.getMinutes() - 1); } } _date.uniqueid = VMM.Util.unique_ID(7); _date.enddate = _date.startdate; _date.precisiondate = do_start.precision; _date.title = data.headline; _date.headline = data.headline; _date.text = data.text; _date.type = "start"; _date.date = VMM.Date.prettyDate(data.startDate, false, _date.precisiondate); _date.asset = data.asset; _date.slug = false; _date.needs_slug = false; _date.fulldate = _date.startdate.getTime(); if (config.embed) { VMM.fireEvent(global, config.events.headline, _date.headline); } _dates.unshift(_date); } /* CUSTOM SORT ================================================== */ if (data.type != "storify") { _dates.sort(function(a, b){ return a.fulldate - b.fulldate }); } onDatesProcessed(); } }; VMM.Timeline.Config = {}; }; /* ********************************************** Begin VMM.Timeline.TimeNav.js ********************************************** */ /* TimeNav This class handles the bottom timeline navigation. It requires the VMM.Util class and VMM.Date class ================================================== */ if(typeof VMM.Timeline != 'undefined' && typeof VMM.Timeline.TimeNav == 'undefined') { VMM.Timeline.TimeNav = function(parent, content_width, content_height) { trace("VMM.Timeline.TimeNav"); var $timenav, $content, $time, $timeintervalminor, $timeinterval, $timeintervalmajor, $timebackground, $timeintervalbackground, $timenavline, $timenavindicator, $timeintervalminor_minor, $toolbar, $zoomin, $zoomout, $dragslide, config = VMM.Timeline.Config, row_height, events = {}, timespan = {}, layout = parent, data = [], era_markers = [], markers = [], interval_array = [], interval_major_array = [], tags = [], current_marker = 0, _active = false, eras, content, timeouts = { interval_position: "" }, timenav_pos = { left: "", visible: { left: "", right: "" } }, timelookup = { day: 24, month: 12, year: 10, hour: 60, minute: 60, second: 1000, decade: 10, century: 100, millenium: 1000, age: 1000000, epoch: 10000000, era: 100000000, eon: 500000000, week: 4.34812141, days_in_month: 30.4368499, days_in_week: 7, weeks_in_month: 4.34812141, weeks_in_year: 52.177457, days_in_year: 365.242199, hours_in_day: 24 }, dateFractionBrowser = { day: 86400000, week: 7, month: 30.4166666667, year: 12, hour: 24, minute: 1440, second: 86400, decade: 10, century: 100, millenium: 1000, age: 1000000, epoch: 10000000, era: 100000000, eon: 500000000 }, interval = { type: "year", number: 10, first: 1970, last: 2011, multiplier: 100, classname: "_idd", interval_type: "interval" }, interval_major = { type: "year", number: 10, first: 1970, last: 2011, multiplier: 100, classname: "major", interval_type: "interval major" }, interval_macro = { type: "year", number: 10, first: 1970, last: 2011, multiplier: 100, classname: "_dd_minor", interval_type: "interval minor" }, interval_calc = { day: {}, month: {}, year: {}, hour: {}, minute: {}, second: {}, decade: {}, century: {}, millenium: {}, week: {}, age: {}, epoch: {}, era: {}, eon: {} }; /* ADD to Config ================================================== */ row_height = config.nav.marker.height/2; config.nav.rows = { full: [1, row_height*2, row_height*4], half: [1, row_height, row_height*2, row_height*3, row_height*4, row_height*5], current: [] } if (content_width != null && content_width != "") { config.nav.width = content_width; } if (content_height != null && content_height != "") { config.nav.height = content_height; } /* INIT ================================================== */ this.init = function(d,e) { trace('VMM.Timeline.TimeNav init'); // need to evaluate d // some function to determine type of data and prepare it if(typeof d != 'undefined') { this.setData(d, e); } else { trace("WAITING ON DATA"); } }; /* GETTERS AND SETTERS ================================================== */ this.setData = function(d,e) { if(typeof d != 'undefined') { data = {}; data = d; eras = e; build(); } else{ trace("NO DATA"); } }; this.setSize = function(w, h) { if (w != null) {config.width = w}; if (h != null) {config.height = h}; if (_active) { reSize(); } } this.setMarker = function(n, ease, duration, fast) { goToMarker(n, ease, duration); } this.getCurrentNumber = function() { return current_marker; } /* ON EVENT ================================================== */ function onConfigSet() { trace("onConfigSet"); }; function reSize(firstrun) { config.nav.constraint.left = (config.width/2); config.nav.constraint.right = config.nav.constraint.right_min - (config.width/2); $dragslide.updateConstraint(config.nav.constraint); VMM.Lib.css($timenavline, "left", Math.round(config.width/2)+2); VMM.Lib.css($timenavindicator, "left", Math.round(config.width/2)-8); goToMarker(config.current_slide, config.ease, config.duration, true, firstrun); }; function upDate() { VMM.fireEvent(layout, "UPDATE"); } function onZoomIn() { $dragslide.cancelSlide(); if (config.nav.multiplier.current > config.nav.multiplier.min) { if (config.nav.multiplier.current <= 1) { config.nav.multiplier.current = config.nav.multiplier.current - .25; } else { if (config.nav.multiplier.current > 5) { if (config.nav.multiplier.current > 16) { config.nav.multiplier.current = Math.round(config.nav.multiplier.current - 10); } else { config.nav.multiplier.current = Math.round(config.nav.multiplier.current - 4); } } else { config.nav.multiplier.current = Math.round(config.nav.multiplier.current - 1); } } if (config.nav.multiplier.current <= 0) { config.nav.multiplier.current = config.nav.multiplier.min; } refreshTimeline(); } } function onZoomOut() { $dragslide.cancelSlide(); if (config.nav.multiplier.current < config.nav.multiplier.max) { if (config.nav.multiplier.current > 4) { if (config.nav.multiplier.current > 16) { config.nav.multiplier.current = Math.round(config.nav.multiplier.current + 10); } else { config.nav.multiplier.current = Math.round(config.nav.multiplier.current + 4); } } else { config.nav.multiplier.current = Math.round(config.nav.multiplier.current + 1); } if (config.nav.multiplier.current >= config.nav.multiplier.max) { config.nav.multiplier.current = config.nav.multiplier.max; } refreshTimeline(); } } function onBackHome(e) { $dragslide.cancelSlide(); goToMarker(0); upDate(); } function onMouseScroll(e) { var delta = 0, scroll_to = 0; if (!e) { e = window.event; } if (e.originalEvent) { e = e.originalEvent; } // Browsers unable to differntiate between up/down and left/right scrolling /* if (e.wheelDelta) { delta = e.wheelDelta/6; } else if (e.detail) { delta = -e.detail*12; } */ // Webkit and browsers able to differntiate between up/down and left/right scrolling if (typeof e.wheelDeltaX != 'undefined' ) { delta = e.wheelDeltaY/6; if (Math.abs(e.wheelDeltaX) > Math.abs(e.wheelDeltaY)) { delta = e.wheelDeltaX/6; } else { //delta = e.wheelDeltaY/6; delta = 0; } } if (delta) { if (e.preventDefault) { e.preventDefault(); } e.returnValue = false; } // Stop from scrolling too far scroll_to = VMM.Lib.position($timenav).left + delta; if (scroll_to > config.nav.constraint.left) { scroll_to = config.width/2; } else if (scroll_to < config.nav.constraint.right) { scroll_to = config.nav.constraint.right; } //VMM.Lib.stop($timenav); //VMM.Lib.animate($timenav, config.duration/2, "linear", {"left": scroll_to}); VMM.Lib.css($timenav, "left", scroll_to); } function refreshTimeline() { trace("config.nav.multiplier " + config.nav.multiplier.current); positionMarkers(true); positionEras(true); positionInterval($timeinterval, interval_array, true, true); positionInterval($timeintervalmajor, interval_major_array, true); config.nav.constraint.left = (config.width/2); config.nav.constraint.right = config.nav.constraint.right_min - (config.width/2); $dragslide.updateConstraint(config.nav.constraint); }; /* MARKER EVENTS ================================================== */ function onMarkerClick(e) { $dragslide.cancelSlide(); goToMarker(e.data.number); upDate(); }; function onMarkerHover(e) { VMM.Lib.toggleClass(e.data.elem, "zFront"); }; function goToMarker(n, ease, duration, fast, firstrun) { trace("GO TO MARKER"); var _ease = config.ease, _duration = config.duration, is_last = false, is_first = false; current_marker = n; timenav_pos.left = (config.width/2) - markers[current_marker].pos_left timenav_pos.visible.left = Math.abs(timenav_pos.left) - 100; timenav_pos.visible.right = Math.abs(timenav_pos.left) + config.width + 100; if (current_marker == 0) { is_first = true; } if (current_marker +1 == markers.length) { is_last = true } if (ease != null && ease != "") {_ease = ease}; if (duration != null && duration != "") {_duration = duration}; // set marker style for(var i = 0; i < markers.length; i++) { VMM.Lib.removeClass(markers[i].marker, "active"); } if (config.start_page && markers[0].type == "start") { VMM.Lib.visible(markers[0].marker, false); VMM.Lib.addClass(markers[0].marker, "start"); } VMM.Lib.addClass(markers[current_marker].marker, "active"); // ANIMATE MARKER VMM.Lib.stop($timenav); VMM.Lib.animate($timenav, _duration, _ease, {"left": timenav_pos.left}); } /* TOUCH EVENTS ================================================== */ function onTouchUpdate(e, b) { VMM.Lib.animate($timenav, b.time/2, config.ease, {"left": b.left}); }; /* CALCULATIONS ================================================== */ function averageMarkerPositionDistance() { var last_pos = 0, pos = 0, pos_dif = 0, mp_diff = [], i = 0; for(i = 0; i < markers.length; i++) { if (data[i].type == "start") { } else { var _pos = positionOnTimeline(interval, markers[i].relative_pos), last_pos = pos; pos = _pos.begin; pos_dif = pos - last_pos; mp_diff.push(pos_dif); } } return VMM.Util.average(mp_diff).mean; } function averageDateDistance() { var last_dd = 0, dd = 0, _dd = "", date_dif = 0, date_diffs = [], is_first_date = true, i = 0; for(i = 0; i < data.length; i++) { if (data[i].type == "start") { trace("DATA DATE IS START") } else { _dd = data[i].startdate; last_dd = dd; dd = _dd; date_dif = dd - last_dd; date_diffs.push(date_dif); } } return VMM.Util.average(date_diffs); } function calculateMultiplier() { var temp_multiplier = config.nav.multiplier.current, i = 0; for(i = 0; i < temp_multiplier; i++) { if (averageMarkerPositionDistance() < 75) { if (config.nav.multiplier.current > 1) { config.nav.multiplier.current = (config.nav.multiplier.current - 1); } } } } function calculateInterval() { // NEED TO REWRITE ALL OF THIS var _first = getDateFractions(data[0].startdate), _last = getDateFractions(data[data.length - 1].enddate); // EON interval_calc.eon.type = "eon"; interval_calc.eon.first = _first.eons; interval_calc.eon.base = Math.floor(_first.eons); interval_calc.eon.last = _last.eons; interval_calc.eon.number = timespan.eons; interval_calc.eon.multiplier = timelookup.eons; interval_calc.eon.minor = timelookup.eons; // ERA interval_calc.era.type = "era"; interval_calc.era.first = _first.eras; interval_calc.era.base = Math.floor(_first.eras); interval_calc.era.last = _last.eras; interval_calc.era.number = timespan.eras; interval_calc.era.multiplier = timelookup.eras; interval_calc.era.minor = timelookup.eras; // EPOCH interval_calc.epoch.type = "epoch"; interval_calc.epoch.first = _first.epochs; interval_calc.epoch.base = Math.floor(_first.epochs); interval_calc.epoch.last = _last.epochs; interval_calc.epoch.number = timespan.epochs; interval_calc.epoch.multiplier = timelookup.epochs; interval_calc.epoch.minor = timelookup.epochs; // AGE interval_calc.age.type = "age"; interval_calc.age.first = _first.ages; interval_calc.age.base = Math.floor(_first.ages); interval_calc.age.last = _last.ages; interval_calc.age.number = timespan.ages; interval_calc.age.multiplier = timelookup.ages; interval_calc.age.minor = timelookup.ages; // MILLENIUM interval_calc.millenium.type = "millenium"; interval_calc.millenium.first = _first.milleniums; interval_calc.millenium.base = Math.floor(_first.milleniums); interval_calc.millenium.last = _last.milleniums; interval_calc.millenium.number = timespan.milleniums; interval_calc.millenium.multiplier = timelookup.millenium; interval_calc.millenium.minor = timelookup.millenium; // CENTURY interval_calc.century.type = "century"; interval_calc.century.first = _first.centuries; interval_calc.century.base = Math.floor(_first.centuries); interval_calc.century.last = _last.centuries; interval_calc.century.number = timespan.centuries; interval_calc.century.multiplier = timelookup.century; interval_calc.century.minor = timelookup.century; // DECADE interval_calc.decade.type = "decade"; interval_calc.decade.first = _first.decades; interval_calc.decade.base = Math.floor(_first.decades); interval_calc.decade.last = _last.decades; interval_calc.decade.number = timespan.decades; interval_calc.decade.multiplier = timelookup.decade; interval_calc.decade.minor = timelookup.decade; // YEAR interval_calc.year.type = "year"; interval_calc.year.first = _first.years; interval_calc.year.base = Math.floor(_first.years); interval_calc.year.last = _last.years; interval_calc.year.number = timespan.years; interval_calc.year.multiplier = 1; interval_calc.year.minor = timelookup.month; // MONTH interval_calc.month.type = "month"; interval_calc.month.first = _first.months; interval_calc.month.base = Math.floor(_first.months); interval_calc.month.last = _last.months; interval_calc.month.number = timespan.months; interval_calc.month.multiplier = 1; interval_calc.month.minor = Math.round(timelookup.week); // WEEK // NOT DONE interval_calc.week.type = "week"; interval_calc.week.first = _first.weeks; interval_calc.week.base = Math.floor(_first.weeks); interval_calc.week.last = _last.weeks; interval_calc.week.number = timespan.weeks; interval_calc.week.multiplier = 1; interval_calc.week.minor = 7; // DAY interval_calc.day.type = "day"; interval_calc.day.first = _first.days; interval_calc.day.base = Math.floor(_first.days); interval_calc.day.last = _last.days; interval_calc.day.number = timespan.days; interval_calc.day.multiplier = 1; interval_calc.day.minor = 24; // HOUR interval_calc.hour.type = "hour"; interval_calc.hour.first = _first.hours; interval_calc.hour.base = Math.floor(_first.hours); interval_calc.hour.last = _last.hours; interval_calc.hour.number = timespan.hours; interval_calc.hour.multiplier = 1; interval_calc.hour.minor = 60; // MINUTE interval_calc.minute.type = "minute"; interval_calc.minute.first = _first.minutes; interval_calc.minute.base = Math.floor(_first.minutes); interval_calc.minute.last = _last.minutes; interval_calc.minute.number = timespan.minutes; interval_calc.minute.multiplier = 1; interval_calc.minute.minor = 60; // SECOND interval_calc.second.type = "decade"; interval_calc.second.first = _first.seconds; interval_calc.second.base = Math.floor(_first.seconds); interval_calc.second.last = _last.seconds; interval_calc.second.number = timespan.seconds; interval_calc.second.multiplier = 1; interval_calc.second.minor = 10; } function getDateFractions(the_date, is_utc) { var _time = {}; _time.days = the_date / dateFractionBrowser.day; _time.weeks = _time.days / dateFractionBrowser.week; _time.months = _time.days / dateFractionBrowser.month; _time.years = _time.months / dateFractionBrowser.year; _time.hours = _time.days * dateFractionBrowser.hour; _time.minutes = _time.days * dateFractionBrowser.minute; _time.seconds = _time.days * dateFractionBrowser.second; _time.decades = _time.years / dateFractionBrowser.decade; _time.centuries = _time.years / dateFractionBrowser.century; _time.milleniums = _time.years / dateFractionBrowser.millenium; _time.ages = _time.years / dateFractionBrowser.age; _time.epochs = _time.years / dateFractionBrowser.epoch; _time.eras = _time.years / dateFractionBrowser.era; _time.eons = _time.years / dateFractionBrowser.eon; /* trace("AGES " + _time.ages); trace("EPOCHS " + _time.epochs); trace("MILLENIUMS " + _time.milleniums); trace("CENTURIES " + _time.centuries); trace("DECADES " + _time.decades); trace("YEARS " + _time.years); trace("MONTHS " + _time.months); trace("WEEKS " + _time.weeks); trace("DAYS " + _time.days); trace("HOURS " + _time.hours); trace("MINUTES " + _time.minutes); trace("SECONDS " + _time.seconds); */ return _time; } /* POSITION Positions elements on the timeline based on date relative to the calculated interval ================================================== */ function positionRelative(_interval, first, last) { var _first, _last, _type = _interval.type, timerelative = { start: "", end: "", type: _type }; /* FIRST ================================================== */ _first = getDateFractions(first); timerelative.start = first.months; if (_type == "eon") { timerelative.start = _first.eons; } else if (_type == "era") { timerelative.start = _first.eras; } else if (_type == "epoch") { timerelative.start = _first.epochs; } else if (_type == "age") { timerelative.start = _first.ages; } else if (_type == "millenium") { timerelative.start = first.milleniums; } else if (_type == "century") { timerelative.start = _first.centuries; } else if (_type == "decade") { timerelative.start = _first.decades; } else if (_type == "year") { timerelative.start = _first.years; } else if (_type == "month") { timerelative.start = _first.months; } else if (_type == "week") { timerelative.start = _first.weeks; } else if (_type == "day") { timerelative.start = _first.days; } else if (_type == "hour") { timerelative.start = _first.hours; } else if (_type == "minute") { timerelative.start = _first.minutes; } /* LAST ================================================== */ if (type.of(last) == "date") { _last = getDateFractions(last); timerelative.end = last.months; if (_type == "eon") { timerelative.end = _last.eons; } else if (_type == "era") { timerelative.end = _last.eras; } else if (_type == "epoch") { timerelative.end = _last.epochs; } else if (_type == "age") { timerelative.end = _last.ages; } else if (_type == "millenium") { timerelative.end = last.milleniums; } else if (_type == "century") { timerelative.end = _last.centuries; } else if (_type == "decade") { timerelative.end = _last.decades; } else if (_type == "year") { timerelative.end = _last.years; } else if (_type == "month") { timerelative.end = _last.months; } else if (_type == "week") { timerelative.end = _last.weeks; } else if (_type == "day") { timerelative.end = _last.days; } else if (_type == "hour") { timerelative.end = _last.hours; } else if (_type == "minute") { timerelative.end = _last.minutes; } } else { timerelative.end = timerelative.start; } return timerelative } function positionOnTimeline(the_interval, timerelative) { return { begin: (timerelative.start - interval.base) * (config.nav.interval_width / config.nav.multiplier.current), end: (timerelative.end - interval.base) * (config.nav.interval_width / config.nav.multiplier.current) }; } function positionMarkers(is_animated) { var row = 2, previous_pos = 0, pos_offset = -2, row_depth = 0, row_depth_sub = 0, line_last_height_pos = 150, line_height = 6, cur_mark = 0, in_view_margin = config.width, pos_cache_array = [], pos_cache_obj = {id: i, pos: 0, row: 0, marker: 0}, pos_cache_max = 6, in_view = { left: timenav_pos.visible.left - in_view_margin, right: timenav_pos.visible.right + in_view_margin }, i = 0, k = 0; config.nav.minor_width = config.width; VMM.Lib.removeClass(".flag", "row1"); VMM.Lib.removeClass(".flag", "row2"); VMM.Lib.removeClass(".flag", "row3"); for(i = 0; i < markers.length; i++) { var line, marker = markers[i], pos = positionOnTimeline(interval, markers[i].relative_pos), row_pos = 0, is_in_view = false, pos_cache_close = 0; // COMPENSATE FOR DATES BEING POITIONED IN THE MIDDLE pos.begin = Math.round(pos.begin + pos_offset); pos.end = Math.round(pos.end + pos_offset); line = Math.round(pos.end - pos.begin); marker.pos_left = pos.begin; if (current_marker == i) { timenav_pos.left = (config.width/2) - pos; timenav_pos.visible.left = Math.abs(timenav_pos.left); timenav_pos.visible.right = Math.abs(timenav_pos.left) + config.width; in_view.left = timenav_pos.visible.left - in_view_margin; in_view.right = timenav_pos.visible.right + in_view_margin; } if (Math.abs(pos.begin) >= in_view.left && Math.abs(pos.begin) <= in_view.right ) { is_in_view = true; } // APPLY POSITION TO MARKER if (is_animated) { VMM.Lib.stop(marker.marker); VMM.Lib.animate(marker.marker, config.duration/2, config.ease, {"left": pos.begin}); } else { VMM.Lib.stop(marker.marker); VMM.Lib.css(marker.marker, "left", pos.begin); } if (i == current_marker) { cur_mark = pos.begin; } // EVENT LENGTH LINE if (line > 5) { VMM.Lib.css(marker.lineevent, "height", line_height); VMM.Lib.css(marker.lineevent, "top", line_last_height_pos); if (is_animated) { VMM.Lib.animate(marker.lineevent, config.duration/2, config.ease, {"width": line}); } else { VMM.Lib.css(marker.lineevent, "width", line); } } // CONTROL ROW POSITION if (tags.length > 0) { var need_half_row = false, half_row_number = 0; for (k = 0; k < tags.length; k++) { if (k < config.nav.rows.current.length) { if (marker.tag == tags[k]) { row = k; if (k == config.nav.rows.current.length - 1) { trace("ON LAST ROW"); VMM.Lib.addClass(marker.flag, "flag-small-last"); } // Experimental, to try and avoid too much stacking on tagged flags if (pos.begin - previous_pos.begin < 5) { if (pos_cache_obj.row == row) { trace("TAGGED FLAG TOO CLOSE ON SAME ROW"); trace(pos_cache_obj.row); trace(row); VMM.Lib.addClass(marker.flag, "flag-small"); VMM.Lib.addClass(pos_cache_obj.marker.flag, "flag-small"); if (row < config.nav.rows.half.length - 1) { //row ++; half_row_number = (row *2) + 1; need_half_row = true; } } } else { VMM.Lib.removeClass(marker.flag, "flag-small"); } // END Experimental } } } if (need_half_row) { row_pos = config.nav.rows.half[half_row_number]; } else { row_pos = config.nav.rows.current[row]; } } else { if (pos.begin - previous_pos.begin < (config.nav.marker.width + config.spacing)) { if (row < config.nav.rows.current.length - 1) { row ++; } else { row = 0; row_depth ++; } } else { row_depth = 1; row = 1; } row_pos = config.nav.rows.current[row]; } // SET LAST MARKER POSITION previous_pos = pos; // POSITION CACHE pos_cache_obj.pos = pos; pos_cache_obj.row = row; pos_cache_obj.marker = marker; pos_cache_array.push(pos_cache_obj); if (pos_cache_array.length > pos_cache_max) { pos_cache_array.remove(0); } //if (is_animated && is_in_view) { if (is_animated) { VMM.Lib.stop(marker.flag); VMM.Lib.animate(marker.flag, config.duration, config.ease, {"top": row_pos}); } else { VMM.Lib.stop(marker.flag); VMM.Lib.css(marker.flag, "top", row_pos); } // IS THE MARKER A REPRESENTATION OF A START SCREEN? if (config.start_page && markers[i].type == "start") { VMM.Lib.visible(marker.marker, false); } if (pos > config.nav.minor_width) { config.nav.minor_width = pos; } if (pos < config.nav.minor_left) { config.nav.minor_left = pos; } } // ANIMATE THE TIMELINE TO ADJUST TO CHANGES if (is_animated) { VMM.Lib.stop($timenav); VMM.Lib.animate($timenav, config.duration/2, config.ease, {"left": (config.width/2) - (cur_mark)}); } else { } //VMM.Lib.delay_animate(config.duration, $timenav, config.duration/2, config.ease, {"left": (config.width/2) - (cur_mark)}); } function positionEras(is_animated) { var i = 0, p = 0; for(i = 0; i < era_markers.length; i++) { var era = era_markers[i], pos = positionOnTimeline(interval, era.relative_pos), row_pos = 0, row = 0, era_height = config.nav.marker.height * config.nav.rows.full.length, era_length = pos.end - pos.begin; // CONTROL ROW POSITION if (era.tag != "") { era_height = (config.nav.marker.height * config.nav.rows.full.length) / config.nav.rows.current.length; for (p = 0; p < tags.length; p++) { if (p < config.nav.rows.current.length) { if (era.tag == tags[p]) { row = p; } } } row_pos = config.nav.rows.current[row]; } else { row_pos = -1; } // APPLY POSITION TO MARKER if (is_animated) { VMM.Lib.stop(era.content); VMM.Lib.stop(era.text_content); VMM.Lib.animate(era.content, config.duration/2, config.ease, {"top": row_pos, "left": pos.begin, "width": era_length, "height":era_height}); VMM.Lib.animate(era.text_content, config.duration/2, config.ease, {"left": pos.begin}); } else { VMM.Lib.stop(era.content); VMM.Lib.stop(era.text_content); VMM.Lib.css(era.content, "left", pos.begin); VMM.Lib.css(era.content, "width", era_length); VMM.Lib.css(era.content, "height", era_height); VMM.Lib.css(era.content, "top", row_pos); VMM.Lib.css(era.text_content, "left", pos.begin); } } } function positionInterval(the_main_element, the_intervals, is_animated, is_minor) { var last_position = 0, last_position_major = 0, //in_view_margin = (config.nav.minor_width/config.nav.multiplier.current)/2, in_view_margin = config.width, in_view = { left: timenav_pos.visible.left - in_view_margin, right: timenav_pos.visible.right + in_view_margin } not_too_many = true, i = 0; config.nav.minor_left = 0; if (the_intervals.length > 100) { not_too_many = false; trace("TOO MANY " + the_intervals.length); } for(i = 0; i < the_intervals.length; i++) { var _interval = the_intervals[i].element, _interval_date = the_intervals[i].date, _interval_visible = the_intervals[i].visible, _pos = positionOnTimeline(interval, the_intervals[i].relative_pos), pos = _pos.begin, _animation = the_intervals[i].animation, is_visible = true, is_in_view = false, pos_offset = 50; _animation.pos = pos; _animation.animate = false; if (Math.abs(pos) >= in_view.left && Math.abs(pos) <= in_view.right ) { is_in_view = true; } if (true) { // CONDENSE WHAT IS DISPLAYED if (config.nav.multiplier.current > 16 && is_minor) { is_visible = false; } else { if ((pos - last_position) < 65 ) { if ((pos - last_position) < 35 ) { if (i%4 == 0) { if (pos == 0) { is_visible = false; } } else { is_visible = false; } } else { if (!VMM.Util.isEven(i)) { is_visible = false; } } } } if (is_visible) { if (the_intervals[i].is_detached) { VMM.Lib.append(the_main_element, _interval); the_intervals[i].is_detached = false; } } else { the_intervals[i].is_detached = true; VMM.Lib.detach(_interval); } if (_interval_visible) { if (!is_visible) { _animation.opacity = "0"; if (is_animated && not_too_many) { _animation.animate = true; } the_intervals[i].interval_visible = false; } else { _animation.opacity = "100"; if (is_animated && is_in_view) { _animation.animate = true; } } } else { _animation.opacity = "100"; if (is_visible) { if (is_animated && not_too_many) { _animation.animate = true; } else { if (is_animated && is_in_view) { _animation.animate = true; } } the_intervals[i].interval_visible = true; } else { if (is_animated && not_too_many) { _animation.animate = true; } } } last_position = pos; if (pos > config.nav.minor_width) { config.nav.minor_width = pos; } if (pos < config.nav.minor_left) { config.nav.minor_left = pos; } } if (_animation.animate) { VMM.Lib.animate(_interval, config.duration/2, config.ease, {opacity: _animation.opacity, left: _animation.pos}); } else { VMM.Lib.css(_interval, "opacity", _animation.opacity); VMM.Lib.css(_interval, "left", pos); } } config.nav.constraint.right_min = -(config.nav.minor_width)+(config.width); config.nav.constraint.right = config.nav.constraint.right_min + (config.width/2); VMM.Lib.css($timeintervalminor_minor, "left", config.nav.minor_left - (config.width)/2); VMM.Lib.width($timeintervalminor_minor, (config.nav.minor_width)+(config.width) + Math.abs(config.nav.minor_left) ); } /* Interval Elements ================================================== */ function createIntervalElements(_interval, _array, _element_parent) { var inc_time = 0, _first_run = true, _last_pos = 0, _largest_pos = 0, _timezone_offset, _first_date, _last_date, int_number = Math.ceil(_interval.number) + 2, firefox = { flag: false, offset: 0 }, i = 0; VMM.attachElement(_element_parent, ""); _interval.date = new Date(data[0].startdate.getFullYear(), 0, 1, 0,0,0); _timezone_offset = _interval.date.getTimezoneOffset(); for(i = 0; i < int_number; i++) { trace(_interval.type); var _is_year = false, int_obj = { element: VMM.appendAndGetElement(_element_parent, "
", _interval.classname), date: new Date(data[0].startdate.getFullYear(), 0, 1, 0,0,0), visible: false, date_string: "", type: _interval.interval_type, relative_pos: 0, is_detached: false, animation: { animate: false, pos: "", opacity: "100" } }; if (_interval.type == "eon") { if (_first_run) { _first_date = Math.floor(data[0].startdate.getFullYear() / 500000000) * 500000000; } int_obj.date.setFullYear(_first_date + (inc_time * 500000000)); _is_year = true; } else if (_interval.type == "era") { if (_first_run) { _first_date = Math.floor(data[0].startdate.getFullYear() / 100000000) * 100000000; } int_obj.date.setFullYear(_first_date + (inc_time * 100000000)); _is_year = true; } else if (_interval.type == "epoch") { if (_first_run) { _first_date = Math.floor(data[0].startdate.getFullYear() / 10000000) * 10000000 } int_obj.date.setFullYear(_first_date + (inc_time * 10000000)); _is_year = true; } else if (_interval.type == "age") { if (_first_run) { _first_date = Math.floor(data[0].startdate.getFullYear() / 1000000) * 1000000 } int_obj.date.setFullYear(_first_date + (inc_time * 1000000)); _is_year = true; } else if (_interval.type == "millenium") { if (_first_run) { _first_date = Math.floor(data[0].startdate.getFullYear() / 1000) * 1000; } int_obj.date.setFullYear(_first_date + (inc_time * 1000)); _is_year = true; } else if (_interval.type == "century") { if (_first_run) { _first_date = Math.floor(data[0].startdate.getFullYear() / 100) * 100 } int_obj.date.setFullYear(_first_date + (inc_time * 100)); _is_year = true; } else if (_interval.type == "decade") { if (_first_run) { _first_date = Math.floor(data[0].startdate.getFullYear() / 10) * 10; } int_obj.date.setFullYear(_first_date + (inc_time * 10)); _is_year = true; } else if (_interval.type == "year") { if (_first_run) { _first_date = data[0].startdate.getFullYear(); } int_obj.date.setFullYear(_first_date + inc_time); _is_year = true; } else if (_interval.type == "month") { if (_first_run) { _first_date = data[0].startdate.getMonth(); } int_obj.date.setMonth(_first_date + inc_time); } else if (_interval.type == "week") { if (_first_run) { _first_date = data[0].startdate.getMonth(); } int_obj.date.setMonth(data[0].startdate.getMonth()); int_obj.date.setDate(_first_date + (inc_time * 7) ); } else if (_interval.type == "day") { if (_first_run) { _first_date = data[0].startdate.getDate(); } int_obj.date.setMonth(data[0].startdate.getMonth()); int_obj.date.setDate(_first_date + inc_time); } else if (_interval.type == "hour") { if (_first_run) { _first_date = data[0].startdate.getHours(); } int_obj.date.setMonth(data[0].startdate.getMonth()); int_obj.date.setDate(data[0].startdate.getDate()); int_obj.date.setHours(_first_date + inc_time); } else if (_interval.type == "minute") { if (_first_run) { _first_date = data[0].startdate.getMinutes(); } int_obj.date.setMonth(data[0].startdate.getMonth()); int_obj.date.setDate(data[0].startdate.getDate()); int_obj.date.setHours(data[0].startdate.getHours()); int_obj.date.setMinutes(_first_date + inc_time); } else if (_interval.type == "second") { if (_first_run) { _first_date = data[0].startdate.getSeconds(); } int_obj.date.setMonth(data[0].startdate.getMonth()); int_obj.date.setDate(data[0].startdate.getDate()); int_obj.date.setHours(data[0].startdate.getHours()); int_obj.date.setMinutes(data[0].startdate.getMinutes()); int_obj.date.setSeconds(_first_date + inc_time); } else if (_interval.type == "millisecond") { if (_first_run) { _first_date = data[0].startdate.getMilliseconds(); } int_obj.date.setMonth(data[0].startdate.getMonth()); int_obj.date.setDate(data[0].startdate.getDate()); int_obj.date.setHours(data[0].startdate.getHours()); int_obj.date.setMinutes(data[0].startdate.getMinutes()); int_obj.date.setSeconds(data[0].startdate.getSeconds()); int_obj.date.setMilliseconds(_first_date + inc_time); } // FIX WEIRD FIREFOX BUG FOR GMT TIME FORMATTING if (VMM.Browser.browser == "Firefox") { if (int_obj.date.getFullYear() == "1970" && int_obj.date.getTimezoneOffset() != _timezone_offset) { trace("FIREFOX 1970 TIMEZONE OFFSET " + int_obj.date.getTimezoneOffset() + " SHOULD BE " + _timezone_offset); trace(_interval.type + " " + _interval.date); // try and fix firefox bug, if not the flag will catch it firefox.offset = (int_obj.date.getTimezoneOffset()/60); firefox.flag = true; int_obj.date.setHours(int_obj.date.getHours() + firefox.offset ); } else if (firefox.flag) { // catch the bug the second time around firefox.flag = false; int_obj.date.setHours(int_obj.date.getHours() + firefox.offset ); if (_is_year) { firefox.flag = true; } } } if (_is_year) { if ( int_obj.date.getFullYear() < 0 ) { int_obj.date_string = Math.abs( int_obj.date.getFullYear() ).toString() + " B.C."; } else { int_obj.date_string = int_obj.date.getFullYear(); } } else { int_obj.date_string = VMM.Date.prettyDate(int_obj.date, true); } // Increment Time inc_time = inc_time + 1; // No longer first run _first_run = false; int_obj.relative_pos = positionRelative(interval, int_obj.date); _last_pos = int_obj.relative_pos.begin; if (int_obj.relative_pos.begin > _largest_pos) { _largest_pos = int_obj.relative_pos.begin; } // Add the time string to the element and position it. VMM.appendElement(int_obj.element, int_obj.date_string); VMM.Lib.css(int_obj.element, "text-indent", -(VMM.Lib.width(int_obj.element)/2)); VMM.Lib.css(int_obj.element, "opacity", "0"); // add the interval element to the array _array.push(int_obj); } VMM.Lib.width($timeintervalminor_minor, _largest_pos); positionInterval(_element_parent, _array); } /* BUILD ================================================== */ function build() { var i = 0, j = 0; VMM.attachElement(layout, ""); $timenav = VMM.appendAndGetElement(layout, "
", "timenav"); $content = VMM.appendAndGetElement($timenav, "
", "content"); $time = VMM.appendAndGetElement($timenav, "
", "time"); $timeintervalminor = VMM.appendAndGetElement($time, "
", "time-interval-minor"); $timeintervalminor_minor = VMM.appendAndGetElement($timeintervalminor, "
", "minor"); $timeintervalmajor = VMM.appendAndGetElement($time, "
", "time-interval-major"); $timeinterval = VMM.appendAndGetElement($time, "
", "time-interval"); $timebackground = VMM.appendAndGetElement(layout, "
", "timenav-background"); $timenavline = VMM.appendAndGetElement($timebackground, "
", "timenav-line"); $timenavindicator = VMM.appendAndGetElement($timebackground, "
", "timenav-indicator"); $timeintervalbackground = VMM.appendAndGetElement($timebackground, "
", "timenav-interval-background", "
"); $toolbar = VMM.appendAndGetElement(layout, "
", "vco-toolbar"); buildInterval(); buildMarkers(); buildEras(); calculateMultiplier(); positionMarkers(false); positionEras(); positionInterval($timeinterval, interval_array, false, true); positionInterval($timeintervalmajor, interval_major_array); if (config.start_page) { $backhome = VMM.appendAndGetElement($toolbar, "
", "back-home", "
"); VMM.bindEvent(".back-home", onBackHome, "click"); VMM.Lib.attribute($backhome, "title", VMM.master_config.language.messages.return_to_title); VMM.Lib.attribute($backhome, "rel", "timeline-tooltip"); } // MAKE TIMELINE DRAGGABLE/TOUCHABLE $dragslide = new VMM.DragSlider; $dragslide.createPanel(layout, $timenav, config.nav.constraint, config.touch); if (config.touch && config.start_page) { VMM.Lib.addClass($toolbar, "touch"); VMM.Lib.css($toolbar, "top", 55); VMM.Lib.css($toolbar, "left", 10); } else { if (config.start_page) { VMM.Lib.css($toolbar, "top", 27); } $zoomin = VMM.appendAndGetElement($toolbar, "
", "zoom-in", "
"); $zoomout = VMM.appendAndGetElement($toolbar, "
", "zoom-out", "
"); // ZOOM EVENTS VMM.bindEvent($zoomin, onZoomIn, "click"); VMM.bindEvent($zoomout, onZoomOut, "click"); // TOOLTIP VMM.Lib.attribute($zoomin, "title", VMM.master_config.language.messages.expand_timeline); VMM.Lib.attribute($zoomin, "rel", "timeline-tooltip"); VMM.Lib.attribute($zoomout, "title", VMM.master_config.language.messages.contract_timeline); VMM.Lib.attribute($zoomout, "rel", "timeline-tooltip"); $toolbar.tooltip({selector: "div[rel=timeline-tooltip]", placement: "right"}); // MOUSE EVENTS VMM.bindEvent(layout, onMouseScroll, 'DOMMouseScroll'); VMM.bindEvent(layout, onMouseScroll, 'mousewheel'); } // USER CONFIGURABLE ADJUSTMENT TO DEFAULT ZOOM if (config.nav.zoom.adjust != 0) { if (config.nav.zoom.adjust < 0) { for(i = 0; i < Math.abs(config.nav.zoom.adjust); i++) { onZoomOut(); } } else { for(j = 0; j < config.nav.zoom.adjust; j++) { onZoomIn(); } } } //VMM.fireEvent(layout, "LOADED"); _active = true; reSize(true); VMM.fireEvent(layout, "LOADED"); }; function buildInterval() { var i = 0, j = 0; // CALCULATE INTERVAL timespan = getDateFractions((data[data.length - 1].enddate) - (data[0].startdate), true); trace(timespan); calculateInterval(); /* DETERMINE DEFAULT INTERVAL TYPE millenium, ages, epoch, era and eon are not optimized yet. They may never be. ================================================== */ /* if (timespan.eons > data.length / config.nav.density) { interval = interval_calc.eon; interval_major = interval_calc.eon; interval_macro = interval_calc.era; } else if (timespan.eras > data.length / config.nav.density) { interval = interval_calc.era; interval_major = interval_calc.eon; interval_macro = interval_calc.epoch; } else if (timespan.epochs > data.length / config.nav.density) { interval = interval_calc.epoch; interval_major = interval_calc.era; interval_macro = interval_calc.age; } else if (timespan.ages > data.length / config.nav.density) { interval = interval_calc.ages; interval_major = interval_calc.epoch; interval_macro = interval_calc.millenium; } else if (timespan.milleniums > data.length / config.nav.density) { interval = interval_calc.millenium; interval_major = interval_calc.age; interval_macro = interval_calc.century; } else */ if (timespan.centuries > data.length / config.nav.density) { interval = interval_calc.century; interval_major = interval_calc.millenium; interval_macro = interval_calc.decade; } else if (timespan.decades > data.length / config.nav.density) { interval = interval_calc.decade; interval_major = interval_calc.century; interval_macro = interval_calc.year; } else if (timespan.years > data.length / config.nav.density) { interval = interval_calc.year; interval_major = interval_calc.decade; interval_macro = interval_calc.month; } else if (timespan.months > data.length / config.nav.density) { interval = interval_calc.month; interval_major = interval_calc.year; interval_macro = interval_calc.day; } else if (timespan.days > data.length / config.nav.density) { interval = interval_calc.day; interval_major = interval_calc.month; interval_macro = interval_calc.hour; } else if (timespan.hours > data.length / config.nav.density) { interval = interval_calc.hour; interval_major = interval_calc.day; interval_macro = interval_calc.minute; } else if (timespan.minutes > data.length / config.nav.density) { interval = interval_calc.minute; interval_major = interval_calc.hour; interval_macro = interval_calc.second; } else if (timespan.seconds > data.length / config.nav.density) { interval = interval_calc.second; interval_major = interval_calc.minute; interval_macro = interval_calc.second; } else { trace("NO IDEA WHAT THE TYPE SHOULD BE"); interval = interval_calc.day; interval_major = interval_calc.month; interval_macro = interval_calc.hour; } trace("INTERVAL TYPE: " + interval.type); trace("INTERVAL MAJOR TYPE: " + interval_major.type); // OVERRIDE INTERVAL USING CONFIG if (config.nav.interval_override) { trace("INTERVAL OVERRIDE"); if (config.nav.interval_override == "centuries") { interval = interval_calc.century; interval_major = interval_calc.millenium; interval_macro = interval_calc.decade; } else if (config.nav.interval_override == "decades") { interval = interval_calc.decade; interval_major = interval_calc.century; interval_macro = interval_calc.year; } else if (config.nav.interval_override == "years") { interval = interval_calc.year; interval_major = interval_calc.decade; interval_macro = interval_calc.month; } else if (config.nav.interval_override == "months") { interval = interval_calc.month; interval_major = interval_calc.year; interval_macro = interval_calc.day; } else if (config.nav.interval_override == "days") { interval = interval_calc.day; interval_major = interval_calc.month; interval_macro = interval_calc.hour; } else if (config.nav.interval_override == "hours") { interval = interval_calc.hour; interval_major = interval_calc.day; interval_macro = interval_calc.minute; } else if (config.nav.interval_override == "minutes") { interval = interval_calc.minute; interval_major = interval_calc.hour; interval_macro = interval_calc.second; } else if (config.nav.interval_override == "seconds") { interval = interval_calc.second; interval_major = interval_calc.minute; interval_macro = interval_calc.second; } else { trace("NO IDEA WHAT THE TYPE SHOULD BE"); interval = interval_calc.day; interval_major = interval_calc.month; interval_macro = interval_calc.hour; } } createIntervalElements(interval, interval_array, $timeinterval); createIntervalElements(interval_major, interval_major_array, $timeintervalmajor); // Cleanup duplicate interval elements between normal and major for(i = 0; i < interval_array.length; i++) { for(j = 0; j < interval_major_array.length; j++) { if (interval_array[i].date_string == interval_major_array[j].date_string) { VMM.attachElement(interval_array[i].element, ""); } } } } function buildMarkers() { var row = 2, lpos = 0, row_depth = 0, i = 0, k = 0, l = 0; markers = []; era_markers = []; for(i = 0; i < data.length; i++) { var _marker, _marker_flag, _marker_content, _marker_dot, _marker_line, _marker_line_event, _marker_obj, _marker_title = "", has_title = false; _marker = VMM.appendAndGetElement($content, "
", "marker"); _marker_flag = VMM.appendAndGetElement(_marker, "
", "flag"); _marker_content = VMM.appendAndGetElement(_marker_flag, "
", "flag-content"); _marker_dot = VMM.appendAndGetElement(_marker, "
", "dot"); _marker_line = VMM.appendAndGetElement(_marker, "
", "line"); _marker_line_event = VMM.appendAndGetElement(_marker_line, "
", "event-line"); _marker_relative_pos = positionRelative(interval, data[i].startdate, data[i].enddate); _marker_thumb = ""; // THUMBNAIL trace(data[i].asset); trace(data[i].asset.thumbnail); if (data[i].asset != null && data[i].asset != "") { if (data[i].asset.thumbnail != null && data[i].asset.thumbnail != "") { trace("HAS THUMBNAIL"); VMM.appendElement(_marker_content, VMM.MediaElement.thumbnail(data[i].asset, 24, 24, data[i].uniqueid)); } else { VMM.appendElement(_marker_content, VMM.MediaElement.thumbnail(data[i].asset, 24, 24, data[i].uniqueid)); } } else { VMM.appendElement(_marker_content, "
"); } // ADD DATE AND TITLE if (data[i].title == "" || data[i].title == " " ) { trace("TITLE NOTHING") if (typeof data[i].slug != 'undefined' && data[i].slug != "") { trace("SLUG") _marker_title = VMM.Util.untagify(data[i].slug); has_title = true; } else { var m = VMM.MediaType(data[i].asset.media); if (m.type == "quote" || m.type == "unknown") { _marker_title = VMM.Util.untagify(m.id); has_title = true; } else { has_title = false; } } } else if (data[i].title != "" || data[i].title != " ") { trace(data[i].title) _marker_title = VMM.Util.untagify(data[i].title); has_title = true; } else { trace("TITLE SLUG NOT FOUND " + data[i].slug) } if (has_title) { VMM.appendElement(_marker_content, "

" + _marker_title + "

"); } else { VMM.appendElement(_marker_content, "

" + _marker_title + "

"); VMM.appendElement(_marker_content, "

" + _marker_title + "

"); } // ADD ID VMM.Lib.attr(_marker, "id", ( "marker_" + data[i].uniqueid).toString() ); // MARKER CLICK VMM.bindEvent(_marker_flag, onMarkerClick, "", {number: i}); VMM.bindEvent(_marker_flag, onMarkerHover, "mouseenter mouseleave", {number: i, elem:_marker_flag}); _marker_obj = { marker: _marker, flag: _marker_flag, lineevent: _marker_line_event, type: "marker", full: true, relative_pos: _marker_relative_pos, tag: data[i].tag, pos_left: 0 }; if (data[i].type == "start") { trace("BUILD MARKER HAS START PAGE"); config.start_page = true; _marker_obj.type = "start"; } if (data[i].type == "storify") { _marker_obj.type = "storify"; } if (data[i].tag) { tags.push(data[i].tag); } markers.push(_marker_obj); } // CREATE TAGS tags = VMM.Util.deDupeArray(tags); if (tags.length > 3) { config.nav.rows.current = config.nav.rows.half; } else { config.nav.rows.current = config.nav.rows.full; } for(k = 0; k < tags.length; k++) { if (k < config.nav.rows.current.length) { var tag_element = VMM.appendAndGetElement($timebackground, "
", "timenav-tag"); VMM.Lib.addClass(tag_element, "timenav-tag-row-" + (k+1)); if (tags.length > 3) { VMM.Lib.addClass(tag_element, "timenav-tag-size-half"); } else { VMM.Lib.addClass(tag_element, "timenav-tag-size-full"); } VMM.appendElement(tag_element, "

" + tags[k] + "

"); } } // RESIZE FLAGS IF NEEDED if (tags.length > 3) { for(l = 0; l < markers.length; l++) { VMM.Lib.addClass(markers[l].flag, "flag-small"); markers[l].full = false; } } } function buildEras() { var number_of_colors = 6, current_color = 0, j = 0; // CREATE ERAS for(j = 0; j < eras.length; j++) { var era = { content: VMM.appendAndGetElement($content, "
", "era"), text_content: VMM.appendAndGetElement($timeinterval, "
", "era"), startdate: VMM.Date.parse(eras[j].startDate), enddate: VMM.Date.parse(eras[j].endDate), title: eras[j].headline, uniqueid: VMM.Util.unique_ID(6), tag: "", relative_pos: "" }, st = VMM.Date.prettyDate(era.startdate), en = VMM.Date.prettyDate(era.enddate), era_text = "
 
"; if (typeof eras[j].tag != "undefined") { era.tag = eras[j].tag; } era.relative_pos = positionRelative(interval, era.startdate, era.enddate); VMM.Lib.attr(era.content, "id", era.uniqueid); VMM.Lib.attr(era.text_content, "id", era.uniqueid + "_text"); // Background Color VMM.Lib.addClass(era.content, "era"+(current_color+1)); VMM.Lib.addClass(era.text_content, "era"+(current_color+1)); if (current_color < number_of_colors) { current_color++; } else { current_color = 0; } VMM.appendElement(era.content, era_text); VMM.appendElement(era.text_content, VMM.Util.unlinkify(era.title)); era_markers.push(era); } } }; } /* ********************************************** Begin VMM.Timeline.DataObj.js ********************************************** */ /* TIMELINE SOURCE DATA PROCESSOR ================================================== */ if (typeof VMM.Timeline !== 'undefined' && typeof VMM.Timeline.DataObj == 'undefined') { VMM.Timeline.DataObj = { data_obj: {}, model_array: [], getData: function (raw_data) { VMM.Timeline.DataObj.data_obj = {}; VMM.fireEvent(global, VMM.Timeline.Config.events.messege, VMM.Timeline.Config.language.messages.loading_timeline); if (type.of(raw_data) == "object") { trace("DATA SOURCE: JSON OBJECT"); VMM.Timeline.DataObj.parseJSON(raw_data); } else if (type.of(raw_data) == "string") { if (raw_data.match("%23")) { trace("DATA SOURCE: TWITTER SEARCH"); VMM.Timeline.DataObj.model.tweets.getData("%23medill"); } else if ( raw_data.match("spreadsheet") ) { trace("DATA SOURCE: GOOGLE SPREADSHEET"); VMM.Timeline.DataObj.model.googlespreadsheet.getData(raw_data); } else if (raw_data.match("storify.com")) { trace("DATA SOURCE: STORIFY"); VMM.Timeline.DataObj.model.storify.getData(raw_data); //http://api.storify.com/v1/stories/number10gov/g8-and-nato-chicago-summit } else if (raw_data.match("\.jsonp")) { trace("DATA SOURCE: JSONP"); LoadLib.js(raw_data, VMM.Timeline.DataObj.onJSONPLoaded); } else { trace("DATA SOURCE: JSON"); var req = ""; if (raw_data.indexOf("?") > -1) { req = raw_data + "&callback=onJSONP_Data"; } else { req = raw_data + "?callback=onJSONP_Data"; } VMM.getJSON(req, VMM.Timeline.DataObj.parseJSON); } } else if (type.of(raw_data) == "html") { trace("DATA SOURCE: HTML"); VMM.Timeline.DataObj.parseHTML(raw_data); } else { trace("DATA SOURCE: UNKNOWN"); } }, onJSONPLoaded: function() { trace("JSONP IS LOADED"); VMM.fireEvent(global, VMM.Timeline.Config.events.data_ready, storyjs_jsonp_data); }, parseHTML: function (d) { trace("parseHTML"); trace("WARNING: THIS IS STILL ALPHA AND WILL NOT WORK WITH ID's other than #timeline"); var _data_obj = VMM.Timeline.DataObj.data_template_obj; /* Timeline start slide ================================================== */ if (VMM.Lib.find("#timeline section", "time")[0]) { _data_obj.timeline.startDate = VMM.Lib.html(VMM.Lib.find("#timeline section", "time")[0]); _data_obj.timeline.headline = VMM.Lib.html(VMM.Lib.find("#timeline section", "h2")); _data_obj.timeline.text = VMM.Lib.html(VMM.Lib.find("#timeline section", "article")); var found_main_media = false; if (VMM.Lib.find("#timeline section", "figure img").length != 0) { found_main_media = true; _data_obj.timeline.asset.media = VMM.Lib.attr(VMM.Lib.find("#timeline section", "figure img"), "src"); } else if (VMM.Lib.find("#timeline section", "figure a").length != 0) { found_main_media = true; _data_obj.timeline.asset.media = VMM.Lib.attr(VMM.Lib.find("#timeline section", "figure a"), "href"); } else { //trace("NOT FOUND"); } if (found_main_media) { if (VMM.Lib.find("#timeline section", "cite").length != 0) { _data_obj.timeline.asset.credit = VMM.Lib.html(VMM.Lib.find("#timeline section", "cite")); } if (VMM.Lib.find(this, "figcaption").length != 0) { _data_obj.timeline.asset.caption = VMM.Lib.html(VMM.Lib.find("#timeline section", "figcaption")); } } } /* Timeline Date Slides ================================================== */ VMM.Lib.each("#timeline li", function(i, elem){ var valid_date = false; var _date = { "type":"default", "startDate":"", "headline":"", "text":"", "asset": { "media":"", "credit":"", "caption":"" }, "tags":"Optional" }; if (VMM.Lib.find(this, "time") != 0) { valid_date = true; _date.startDate = VMM.Lib.html(VMM.Lib.find(this, "time")[0]); if (VMM.Lib.find(this, "time")[1]) { _date.endDate = VMM.Lib.html(VMM.Lib.find(this, "time")[1]); } _date.headline = VMM.Lib.html(VMM.Lib.find(this, "h3")); _date.text = VMM.Lib.html(VMM.Lib.find(this, "article")); var found_media = false; if (VMM.Lib.find(this, "figure img").length != 0) { found_media = true; _date.asset.media = VMM.Lib.attr(VMM.Lib.find(this, "figure img"), "src"); } else if (VMM.Lib.find(this, "figure a").length != 0) { found_media = true; _date.asset.media = VMM.Lib.attr(VMM.Lib.find(this, "figure a"), "href"); } else { //trace("NOT FOUND"); } if (found_media) { if (VMM.Lib.find(this, "cite").length != 0) { _date.asset.credit = VMM.Lib.html(VMM.Lib.find(this, "cite")); } if (VMM.Lib.find(this, "figcaption").length != 0) { _date.asset.caption = VMM.Lib.html(VMM.Lib.find(this, "figcaption")); } } trace(_date); _data_obj.timeline.date.push(_date); } }); VMM.fireEvent(global, VMM.Timeline.Config.events.data_ready, _data_obj); }, parseJSON: function(d) { trace("parseJSON"); if (d.timeline.type == "default") { trace("DATA SOURCE: JSON STANDARD TIMELINE"); VMM.fireEvent(global, VMM.Timeline.Config.events.data_ready, d); } else if (d.timeline.type == "twitter") { trace("DATA SOURCE: JSON TWEETS"); VMM.Timeline.DataObj.model_Tweets.buildData(d); } else { trace("DATA SOURCE: UNKNOWN JSON"); trace(type.of(d.timeline)); }; }, /* MODEL OBJECTS New Types of Data can be formatted for the timeline here ================================================== */ model: { googlespreadsheet: { getData: function(raw) { var getjsondata, key, worksheet, url, timeout, tries = 0; key = VMM.Util.getUrlVars(raw)["key"]; worksheet = VMM.Util.getUrlVars(raw)["worksheet"]; if (typeof worksheet == "undefined") worksheet = "od6"; url = "https://spreadsheets.google.com/feeds/list/" + key + "/" + worksheet + "/public/values?alt=json"; timeout = setTimeout(function() { trace("Google Docs timeout " + url); trace(url); if (tries < 3) { VMM.fireEvent(global, VMM.Timeline.Config.events.messege, "Still waiting on Google Docs, trying again " + tries); tries ++; getjsondata.abort() requestJsonData(); } else { VMM.fireEvent(global, VMM.Timeline.Config.events.messege, "Google Docs is not responding"); } }, 16000); function requestJsonData() { getjsondata = VMM.getJSON(url, function(d) { clearTimeout(timeout); VMM.Timeline.DataObj.model.googlespreadsheet.buildData(d); }) .error(function(jqXHR, textStatus, errorThrown) { trace("Google Docs ERROR"); trace("Google Docs ERROR: " + textStatus + " " + jqXHR.responseText); }) .success(function(d) { clearTimeout(timeout); }); } requestJsonData(); }, buildData: function(d) { var data_obj = VMM.Timeline.DataObj.data_template_obj, is_valid = false; VMM.fireEvent(global, VMM.Timeline.Config.events.messege, "Parsing Google Doc Data"); function getGVar(v) { if (typeof v != 'undefined') { return v.$t; } else { return ""; } } if (typeof d.feed.entry != 'undefined') { is_valid = true; for(var i = 0; i < d.feed.entry.length; i++) { var dd = d.feed.entry[i], dd_type = ""; if (typeof dd.gsx$type != 'undefined') { dd_type = dd.gsx$type.$t; } else if (typeof dd.gsx$titleslide != 'undefined') { dd_type = dd.gsx$titleslide.$t; } if (dd_type.match("start") || dd_type.match("title") ) { data_obj.timeline.startDate = getGVar(dd.gsx$startdate); data_obj.timeline.headline = getGVar(dd.gsx$headline); data_obj.timeline.asset.media = getGVar(dd.gsx$media); data_obj.timeline.asset.caption = getGVar(dd.gsx$mediacaption); data_obj.timeline.asset.credit = getGVar(dd.gsx$mediacredit); data_obj.timeline.text = getGVar(dd.gsx$text); data_obj.timeline.type = "google spreadsheet"; } else if (dd_type.match("era")) { var era = { startDate: getGVar(dd.gsx$startdate), endDate: getGVar(dd.gsx$enddate), headline: getGVar(dd.gsx$headline), text: getGVar(dd.gsx$text), tag: getGVar(dd.gsx$tag) } data_obj.timeline.era.push(era); } else { var date = { type: "google spreadsheet", startDate: getGVar(dd.gsx$startdate), endDate: getGVar(dd.gsx$enddate), headline: getGVar(dd.gsx$headline), text: getGVar(dd.gsx$text), tag: getGVar(dd.gsx$tag), asset: { media: getGVar(dd.gsx$media), credit: getGVar(dd.gsx$mediacredit), caption: getGVar(dd.gsx$mediacaption), thumbnail: getGVar(dd.gsx$mediathumbnail) } }; data_obj.timeline.date.push(date); } }; } else { } if (is_valid) { VMM.fireEvent(global, VMM.Timeline.Config.events.messege, "Finished Parsing Data"); VMM.fireEvent(global, VMM.Timeline.Config.events.data_ready, data_obj); } else { VMM.fireEvent(global, VMM.Timeline.Config.events.messege, VMM.Language.messages.loading + " Google Doc Data (cells)"); trace("There may be too many entries. Still trying to load data. Now trying to load cells to avoid Googles limitation on cells"); VMM.Timeline.DataObj.model.googlespreadsheet.getDataCells(d.feed.link[0].href); } }, getDataCells: function(raw) { var getjsondata, key, url, timeout, tries = 0; key = VMM.Util.getUrlVars(raw)["key"]; url = "https://spreadsheets.google.com/feeds/cells/" + key + "/od6/public/values?alt=json"; timeout = setTimeout(function() { trace("Google Docs timeout " + url); trace(url); if (tries < 3) { VMM.fireEvent(global, VMM.Timeline.Config.events.messege, "Still waiting on Google Docs, trying again " + tries); tries ++; getjsondata.abort() requestJsonData(); } else { VMM.fireEvent(global, VMM.Timeline.Config.events.messege, "Google Docs is not responding"); } }, 16000); function requestJsonData() { getjsondata = VMM.getJSON(url, function(d) { clearTimeout(timeout); VMM.Timeline.DataObj.model.googlespreadsheet.buildDataCells(d); }) .error(function(jqXHR, textStatus, errorThrown) { trace("Google Docs ERROR"); trace("Google Docs ERROR: " + textStatus + " " + jqXHR.responseText); }) .success(function(d) { clearTimeout(timeout); }); } requestJsonData(); }, buildDataCells: function(d) { var data_obj = VMM.Timeline.DataObj.data_template_obj, is_valid = false, cellnames = ["timeline"], list = [], max_row = 0, i = 0, k = 0; VMM.fireEvent(global, VMM.Timeline.Config.events.messege, VMM.Language.messages.loading_timeline + " Parsing Google Doc Data (cells)"); function getGVar(v) { if (typeof v != 'undefined') { return v.$t; } else { return ""; } } if (typeof d.feed.entry != 'undefined') { is_valid = true; // DETERMINE NUMBER OF ROWS for(i = 0; i < d.feed.entry.length; i++) { var dd = d.feed.entry[i]; if (parseInt(dd.gs$cell.row) > max_row) { max_row = parseInt(dd.gs$cell.row); } } // CREATE OBJECT FOR EACH ROW for(var i = 0; i < max_row + 1; i++) { var date = { type: "", startDate: "", endDate: "", headline: "", text: "", tag: "", asset: { media: "", credit: "", caption: "", thumbnail: "" } }; list.push(date); } // PREP GOOGLE DOC CELL DATA TO EVALUATE for(i = 0; i < d.feed.entry.length; i++) { var dd = d.feed.entry[i], dd_type = "", column_name = "", cell = { content: getGVar(dd.gs$cell), col: dd.gs$cell.col, row: dd.gs$cell.row, name: "" }; //trace(cell); if (cell.row == 1) { if (cell.content == "Start Date") { column_name = "startDate"; } else if (cell.content == "End Date") { column_name = "endDate"; } else if (cell.content == "Headline") { column_name = "headline"; } else if (cell.content == "Text") { column_name = "text"; } else if (cell.content == "Media") { column_name = "media"; } else if (cell.content == "Media Credit") { column_name = "credit"; } else if (cell.content == "Media Caption") { column_name = "caption"; } else if (cell.content == "Media Thumbnail") { column_name = "thumbnail"; } else if (cell.content == "Type") { column_name = "type"; } else if (cell.content == "Tag") { column_name = "tag"; } cellnames.push(column_name); } else { cell.name = cellnames[cell.col]; list[cell.row][cell.name] = cell.content; } }; for(i = 0; i < list.length; i++) { var date = list[i]; if (date.type.match("start") || date.type.match("title") ) { data_obj.timeline.startDate = date.startDate; data_obj.timeline.headline = date.headline; data_obj.timeline.asset.media = date.media; data_obj.timeline.asset.caption = date.caption; data_obj.timeline.asset.credit = date.credit; data_obj.timeline.text = date.text; data_obj.timeline.type = "google spreadsheet"; } else if (date.type.match("era")) { var era = { startDate: date.startDate, endDate: date.endDate, headline: date.headline, text: date.text, tag: date.tag } data_obj.timeline.era.push(era); } else { var date = { type: "google spreadsheet", startDate: date.startDate, endDate: date.endDate, headline: date.headline, text: date.text, tag: date.tag, asset: { media: date.media, credit: date.credit, caption: date.caption, thumbnail: date.thumbnail } }; data_obj.timeline.date.push(date); } } //trace(cellnames); //trace(max_row); //trace(list); } if (is_valid) { VMM.fireEvent(global, VMM.Timeline.Config.events.messege, "Finished Parsing Data"); VMM.fireEvent(global, VMM.Timeline.Config.events.data_ready, data_obj); } else { VMM.fireEvent(global, VMM.Timeline.Config.events.messege, "Unable to load Google Doc data source"); } } }, storify: { getData: function(raw) { var key, url, storify_timeout; //http://storify.com/number10gov/g8-and-nato-chicago-summit //http://api.storify.com/v1/stories/number10gov/g8-and-nato-chicago-summit VMM.fireEvent(global, VMM.Timeline.Config.events.messege, "Loading Storify..."); key = raw.split("storify.com\/")[1]; url = "http://api.storify.com/v1/stories/" + key + "?per_page=300&callback=?"; storify_timeout = setTimeout(function() { trace("STORIFY timeout"); VMM.fireEvent(global, VMM.Timeline.Config.events.messege, "Storify is not responding"); }, 6000); VMM.getJSON(url, VMM.Timeline.DataObj.model.storify.buildData) .error(function(jqXHR, textStatus, errorThrown) { trace("STORIFY error"); trace("STORIFY ERROR: " + textStatus + " " + jqXHR.responseText); }) .success(function(d) { clearTimeout(storify_timeout); }); }, buildData: function(d) { VMM.fireEvent(global, VMM.Timeline.Config.events.messege, "Parsing Data"); var _data_obj = VMM.Timeline.DataObj.data_template_obj; _data_obj.timeline.startDate = new Date(d.content.date.created);; _data_obj.timeline.headline = d.content.title; trace(d); //d.permalink var tt = ""; var t_name = d.content.author.username; var t_nickname = ""; if (typeof d.content.author.name != 'undefined') { t_name = d.content.author.name; t_nickname = d.content.author.username + " "; } if (typeof d.content.description != 'undefined' && d.content.description != null) { tt += d.content.description; } tt += "
" //tt += " " + "" + " "; tt += "
"; tt += "" tt += "" + t_name + ""; tt += "" + t_nickname + ""; tt += ""; //tt += "" + d.content.author.stats.stories + " Stories"; //tt += "" + d.content.author.stats.subscribers + " Subscribers"; tt += "
" tt += "
"; _data_obj.timeline.text = tt; _data_obj.timeline.asset.media = d.content.thumbnail; //_data_obj.timeline.asset.media = dd.gsx$media.$t; //_data_obj.timeline.asset.caption = dd.gsx$mediacaption.$t; //_data_obj.timeline.asset.credit = dd.gsx$mediacredit.$t; _data_obj.timeline.type = "storify"; for(var i = 0; i < d.content.elements.length; i++) { var dd = d.content.elements[i]; var is_text = false; var d_date = new Date(dd.posted_at); //trace(tempdat); trace(dd.type); //trace(dd); var _date = { "type": "storify", "startDate": dd.posted_at, "endDate": dd.posted_at, "headline": " ", "slug": "", "text": "", "asset": { "media": "", "credit": "", "caption": "" } }; /* MEDIA ================================================== */ if (dd.type == "image") { if (typeof dd.source.name != 'undefined') { if (dd.source.name == "flickr") { _date.asset.media = "http://flickr.com/photos/" + dd.meta.pathalias + "/" + dd.meta.id + "/"; _date.asset.credit = "" + dd.attribution.name + ""; _date.asset.credit += " on " + dd.source.name + ""; } else if (dd.source.name == "instagram") { _date.asset.media = dd.permalink; _date.asset.credit = "" + dd.attribution.name + ""; _date.asset.credit += " on " + dd.source.name + ""; } else { _date.asset.credit = "" + dd.attribution.name + ""; if (typeof dd.source.href != 'undefined') { _date.asset.credit += " on " + dd.source.name + ""; } _date.asset.media = dd.data.image.src; } } else { _date.asset.credit = "" + dd.attribution.name + ""; _date.asset.media = dd.data.image.src; } _date.slug = dd.attribution.name; if (typeof dd.data.image.caption != 'undefined') { if (dd.data.image.caption != 'undefined') { _date.asset.caption = dd.data.image.caption; _date.slug = dd.data.image.caption; } } } else if (dd.type == "quote") { if (dd.permalink.match("twitter")) { _date.asset.media = dd.permalink; _date.slug = VMM.Util.untagify(dd.data.quote.text); } else if (dd.permalink.match("storify")) { is_text = true; _date.asset.media = "
" + dd.data.quote.text.replace(/<\s*\/?\s*b\s*.*?>/g,"") + "
"; } } else if (dd.type == "link") { _date.headline = dd.data.link.title; _date.text = dd.data.link.description; if (dd.data.link.thumbnail != 'undefined' && dd.data.link.thumbnail != '') { _date.asset.media = dd.data.link.thumbnail; } else { _date.asset.media = dd.permalink; } //_date.asset.media = dd.permalink; _date.asset.caption = "" + dd.data.link.title + "" _date.slug = dd.data.link.title; } else if (dd.type == "text") { if (dd.permalink.match("storify")) { is_text = true; var d_name = d.content.author.username; var d_nickname = ""; if (typeof dd.attribution.name != 'undefined') { t_name = dd.attribution.name; t_nickname = dd.attribution.username + " "; } var asset_text = "
" asset_text += "

" + dd.data.text.replace(/<\s*\/?\s*b\s*.*?>/g,"") + "

"; //asset_text += " " + "" + " "; asset_text += "
"; _date.text = asset_text; // Try and put it before the element where it is expected on storify if ( (i+1) >= d.content.elements.length ) { _date.startDate = d.content.elements[i-1].posted_at; } else { if (d.content.elements[i+1].type == "text" && d.content.elements[i+1].permalink.match("storify")) { if ( (i+2) >= d.content.elements.length ) { _date.startDate = d.content.elements[i-1].posted_at; } else { if (d.content.elements[i+2].type == "text" && d.content.elements[i+2].permalink.match("storify")) { if ( (i+3) >= d.content.elements.length ) { _date.startDate = d.content.elements[i-1].posted_at; } else { if (d.content.elements[i+3].type == "text" && d.content.elements[i+3].permalink.match("storify")) { _date.startDate = d.content.elements[i-1].posted_at; } else { trace("LEVEL 3"); _date.startDate = d.content.elements[i+3].posted_at; } } } else { trace("LEVEL 2"); _date.startDate = d.content.elements[i+2].posted_at; } } } else { trace("LEVEL 1"); _date.startDate = d.content.elements[i+1].posted_at; } } _date.endDate = _date.startDate } } else if (dd.type == "video") { _date.headline = dd.data.video.title; _date.asset.caption = dd.data.video.description; _date.asset.caption = dd.source.username; _date.asset.media = dd.data.video.src; } else { trace("NO MATCH "); trace(dd); } if (is_text) { _date.slug = VMM.Util.untagify(dd.data.text); } _data_obj.timeline.date.push(_date); }; VMM.fireEvent(global, VMM.Timeline.Config.events.data_ready, _data_obj); } }, tweets: { type: "twitter", buildData: function(raw_data) { VMM.bindEvent(global, VMM.Timeline.DataObj.model.tweets.onTwitterDataReady, "TWEETSLOADED"); VMM.ExternalAPI.twitter.getTweets(raw_data.timeline.tweets); }, getData: function(raw_data) { VMM.bindEvent(global, VMM.Timeline.DataObj.model.tweets.onTwitterDataReady, "TWEETSLOADED"); VMM.ExternalAPI.twitter.getTweetSearch(raw_data); }, onTwitterDataReady: function(e, d) { var _data_obj = VMM.Timeline.DataObj.data_template_obj; for(var i = 0; i < d.tweetdata.length; i++) { var _date = { "type":"tweets", "startDate":"", "headline":"", "text":"", "asset": { "media":"", "credit":"", "caption":"" }, "tags":"Optional" }; // pass in the 'created_at' string returned from twitter // // stamp arrives formatted as Tue Apr 07 22:52:51 +0000 2009 // //var twit_date = VMM.ExternalAPI.twitter.parseTwitterDate(d.tweetdata[i].raw.created_at); //trace(twit_date); _date.startDate = d.tweetdata[i].raw.created_at; if (type.of(d.tweetdata[i].raw.from_user_name)) { _date.headline = d.tweetdata[i].raw.from_user_name + " (" + "@" + d.tweetdata[i].raw.from_user + ")" ; } else { _date.headline = d.tweetdata[i].raw.user.name + " (" + "@" + d.tweetdata[i].raw.user.screen_name + ")" ; } _date.asset.media = d.tweetdata[i].content; _data_obj.timeline.date.push(_date); }; VMM.fireEvent(global, VMM.Timeline.Config.events.data_ready, _data_obj); } } }, /* TEMPLATE OBJECTS ================================================== */ data_template_obj: { "timeline": { "headline":"", "description":"", "asset": { "media":"", "credit":"", "caption":"" }, "date": [], "era":[] } }, date_obj: {"startDate":"2012,2,2,11,30", "headline":"", "text":"", "asset": {"media":"http://youtu.be/vjVfu8-Wp6s", "credit":"", "caption":"" }, "tags":"Optional"} }; }