diff --git a/app/assets/javascripts/app/alert-manager.js b/app/assets/javascripts/app/alert-manager.js
index 0b224548f..fff26cc6d 100644
--- a/app/assets/javascripts/app/alert-manager.js
+++ b/app/assets/javascripts/app/alert-manager.js
@@ -6,6 +6,9 @@ define(
function () {
'use strict';
+ // The events the alert broadcasts.
+ var _events = {};
+
// HTML element for the alert container.
var _alertContainer;
@@ -59,6 +62,7 @@ function () {
// Hiding the alert box clears its content and hides it using CSS.
function hide() {
+ _broadcastEvent('close');
_alertContainer.classList.add('hide');
_content.innerHTML = '';
}
@@ -68,10 +72,24 @@ function () {
hide();
}
+ // @param evt [String] The type of event to broadcast.
+ // Supports 'close'.
+ function _broadcastEvent(evt) {
+ if (_events[evt])
+ _events[evt].call();
+ }
+
+ // @param event [String] The event name to listen for. Supports 'close'.
+ // @param callback [Function] The function called when the event has fired.
+ function addEventListener(event, callback) {
+ _events[event] = callback;
+ }
+
return {
init:init,
show:show,
hide:hide,
- type:type
+ type:type,
+ addEventListener:addEventListener
};
});
diff --git a/app/assets/javascripts/app/app-init.js b/app/assets/javascripts/app/app-init.js
index 22f4f4540..b63fdfa07 100644
--- a/app/assets/javascripts/app/app-init.js
+++ b/app/assets/javascripts/app/app-init.js
@@ -1,17 +1,18 @@
// Manages the application initialization for most pages.
// This script is called by the homepage, search result
// and search details pages. It is not called by
-// the about page, because that page does not have popups to manage.
+// the about page.
require([
+ 'util/translation/google-translate-manager',
'app/popup-manager',
'app/alert-manager'
],
-function (pm, alert) {
+function (googleTranslate, popups, alert) {
'use strict';
- // If box-shadow CSS is supported, initialize the popups.
- if (Modernizr.boxshadow)
- pm.init();
+ // If page is not translated, initialize the header popups.
+ if (!googleTranslate.isTranslated())
+ popups.init();
alert.init();
});
diff --git a/app/assets/javascripts/app/popup-manager.js b/app/assets/javascripts/app/popup-manager.js
index 7d8217f7b..48f4d102f 100644
--- a/app/assets/javascripts/app/popup-manager.js
+++ b/app/assets/javascripts/app/popup-manager.js
@@ -17,21 +17,8 @@ function (util, feedback) {
var PADDING = 20;
function init() {
- if (!_isTranslated()) {
- _addPopups();
- feedback.init();
- }
- }
-
- // Check if the page is currently translated using Google Translation.
- function _isTranslated() {
- var translate = util.getQueryParams().translate;
- if (translate && translate !== 'en')
- return true;
- var googtrans = util.getCookie('googtrans');
- if (googtrans && googtrans !== '/en/en')
- return true;
- return false;
+ _addPopups();
+ feedback.init();
}
// Adds hooks for triggering popups present on the page.
diff --git a/app/assets/javascripts/application.js b/app/assets/javascripts/application.js
index e9ac1a359..0ef894ff1 100644
--- a/app/assets/javascripts/application.js
+++ b/app/assets/javascripts/application.js
@@ -70,11 +70,16 @@
//
require([
'util/translation/google-translate-manager',
+ 'util/browser-upgrade-notice',
'domReady!'
],
-function (googleTranslate) {
+function (googleTranslate, browserUpgradeNotice) {
'use strict';
+ // Show a browser upgrade notice on IE8 and below.
+ if (document.documentElement.classList.contains('lt-ie9'))
+ browserUpgradeNotice.show();
+
// The Google translate manager handles loading of the
// Google Website Translator Gadget at the bottom of the page's body.
// The layout settings passed in as an argument to the initialization
diff --git a/app/assets/javascripts/search/filter/TextInput.js b/app/assets/javascripts/search/filter/TextInput.js
index 2bddd0b6d..4016ebbb3 100644
--- a/app/assets/javascripts/search/filter/TextInput.js
+++ b/app/assets/javascripts/search/filter/TextInput.js
@@ -32,7 +32,7 @@ function () {
_input.value = '';
}
- function _initCloseButton() {
+ function _initClearButton() {
// Retrieve first and only input element.
// Throw an error if it isn't found.
_input = _container.getElementsByTagName('input')[0];
@@ -44,7 +44,6 @@ function () {
if (_input.value === '')
_buttonClear.className += ' hide';
_container.appendChild(_buttonClear);
-
_buttonClear.addEventListener('click', function (evt) {
evt.preventDefault();
reset();
@@ -85,7 +84,7 @@ function () {
}
// Initialize TextInput instance.
- if (_container) _initCloseButton();
+ if (_container) _initClearButton();
else _throwInitializationError();
return {
diff --git a/app/assets/javascripts/util/browser-upgrade-notice.js b/app/assets/javascripts/util/browser-upgrade-notice.js
new file mode 100644
index 000000000..d2588c9fb
--- /dev/null
+++ b/app/assets/javascripts/util/browser-upgrade-notice.js
@@ -0,0 +1,31 @@
+// Provides a upgrade notice that can be shown to outdated browsers (e.g. IE8).
+define([
+ 'util/cookie',
+ 'app/alert-manager'
+],
+function (cookie, alert) {
+ 'use strict';
+
+ // Show upgrade notice if browser-upgrade-notice cookie isn't set.
+ function show() {
+ if (cookie.read('browser-upgrade-notice') === null) {
+ var notice = " " +
+ 'Your browser is out-of-date and has known security issues.' +
+ '
' +
+ "" +
+ 'Please visit this page to download an up-to-date browser.' +
+ '';
+ alert.addEventListener('close', _alertClosed);
+ alert.show(notice, alert.type.INFO);
+ }
+ }
+
+ // Create a cookie when the alert is closed that will hide the alert for the next day.
+ function _alertClosed() {
+ cookie.create('browser-upgrade-notice', 'true', true, 1);
+ }
+
+ return {
+ show:show
+ };
+});
diff --git a/app/assets/javascripts/util/cookie.js.erb b/app/assets/javascripts/util/cookie.js.erb
new file mode 100644
index 000000000..74ad1b188
--- /dev/null
+++ b/app/assets/javascripts/util/cookie.js.erb
@@ -0,0 +1,52 @@
+// Cookie CRUD functions, from http://www.quirksmode.org/js/cookies.html
+// ERB needed to retrieve domain name that the cookie is saved under.
+define(
+function () {
+ 'use strict';
+
+ // @param name [String] The cookie's name.
+ // @param value [String] The cookie's value.
+ // @param useDomain [Boolean] Whether set under subdomains or not.
+ // @param days [Number] Number of days till the cookie expires.
+ // Can be negative.
+ function create(name, value, useDomain, days) {
+ if (days) {
+ var date = new Date();
+ date.setTime(date.getTime() + (days*24*60*60*1000));
+ var expires = '; expires=' + date.toGMTString();
+ }
+ else var expires = '';
+
+ var setting = name + '=' + value + expires + '; path=/';
+
+ // Sets the cookie under domain and subdomains (if useDomain parameter is present).
+ document.cookie = setting;
+ if (useDomain)
+ document.cookie = setting + "; domain=.<%= ENV['DOMAIN_NAME'] %>";
+ }
+
+ // @param name [String] The cookie's name to read.
+ // @return [String] The named cookie's value, or null.
+ function read(name) {
+ var nameEQ = name + "=";
+ var ca = document.cookie.split(';');
+ for(var i=0;i < ca.length;i++) {
+ var c = ca[i];
+ while (c.charAt(0)==' ') c = c.substring(1,c.length);
+ if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length);
+ }
+ return null;
+ }
+
+ // @param name [String] The cookie's name to remove.
+ // @param usedDomain [Boolean] Whether to clear subdomains also.
+ function erase(name, useDomain) {
+ create(name, '', !!useDomain, -1);
+ }
+
+ return {
+ create:create,
+ read:read,
+ erase:erase
+ };
+});
diff --git a/app/assets/javascripts/util/geolocation/geolocator.js b/app/assets/javascripts/util/geolocation/geolocator.js
index 77c15d7bb..b683fd388 100644
--- a/app/assets/javascripts/util/geolocation/geolocator.js
+++ b/app/assets/javascripts/util/geolocation/geolocator.js
@@ -8,7 +8,6 @@ define(function () {
function locate(pCallBack) {
_callBack = pCallBack;
- // Modernizr should pick this up, but just in case...
var geolocator = navigator.geolocation;
if (geolocator) {
var geoOptions = {
diff --git a/app/assets/javascripts/util/translation/google-translate-manager.js b/app/assets/javascripts/util/translation/google-translate-manager.js
index d45b102b6..177d644dd 100644
--- a/app/assets/javascripts/util/translation/google-translate-manager.js
+++ b/app/assets/javascripts/util/translation/google-translate-manager.js
@@ -1,8 +1,10 @@
// Manages behavior of the Google Website Translator Gadget.
define([
+ 'util/util',
+ 'util/cookie',
'util/translation/layout/DropDownLayout'
],
-function (DropDownLayout) {
+function (util, cookie, DropDownLayout) {
'use strict';
// The layout object in use.
@@ -26,7 +28,7 @@ function (DropDownLayout) {
function init(layoutType) {
_layoutType = layoutType;
- _deleteTranslateCookies();
+ _writeTranslateCookies();
_layout = DropDownLayout.create();
_layout.init(GOOGLE_TRANSLATE_ELEMENT_ID);
@@ -45,6 +47,18 @@ function (DropDownLayout) {
window.GoogleTranslate = GoogleTranslate;
}
+ // Checks if the 'googtrans' cookie is set to English or not,
+ // indicating whether the page has been translated using the
+ // Google Website Translator Gadget.
+ // @return [Boolean] true if Google Translation has translated the page.
+ // Returns false if the page is not translated and is in English.
+ function isTranslated() {
+ var googtrans = cookie.read('googtrans');
+ if (googtrans && decodeURIComponent(googtrans) === '/en/en')
+ return true;
+ return false;
+ }
+
// Initialize the Google Website Translator Gadget.
function _googleTranslateElementInit() {
var gadgetOptions = {
@@ -69,22 +83,23 @@ function (DropDownLayout) {
return google.translate.TranslateElement.InlineLayout.HORIZONTAL;
}
- // Removes the Google Website Translator cookies by setting their expiration
- // date into the past.
- function _deleteTranslateCookies() {
- var cookies, cookie, eqPos, name;
- cookies = document.cookie.split('; ');
- for (var i = 0, len = cookies.length; i < len; i++) {
- cookie = cookies[i];
- eqPos = cookie.indexOf('=');
- name = eqPos > -1 ? cookie.substr(0, eqPos) : cookie;
- if (name === 'googtrans')
- document.cookie = name + '=; expires=Thu, 01 Jan 1970 00:00:00 GMT';
+ // Overwrite/Create Google Website Translator Gadget cookies if the
+ // 'translate' URL parameter is present.
+ function _writeTranslateCookies() {
+ var translateRequested = util.getParameterByName('translate');
+ if (translateRequested) {
+ var newCookieValue = '/en/'+translateRequested;
+ var oldCookieValue = decodeURIComponent(cookie.read('googtrans'));
+ if(newCookieValue !== oldCookieValue) {
+ cookie.create('googtrans', newCookieValue, true, 30);
+ window.location.reload();
+ }
}
}
return {
init:init,
+ isTranslated:isTranslated,
InlineLayout:InlineLayout
};
});
diff --git a/app/assets/javascripts/util/util.js b/app/assets/javascripts/util/util.js
index 4d93c6ea2..329161775 100644
--- a/app/assets/javascripts/util/util.js
+++ b/app/assets/javascripts/util/util.js
@@ -2,18 +2,6 @@ define(
function () {
'use strict';
- // Check if any object is empty of parameters.
- // (from http://stackoverflow.com/questions/3426979/
- // javascript-checking-if-an-object-has-no-properties-or-if-a-map-
- // associative-arra)
- function isEmpty(map) {
- for(var key in map) {
- if (map.hasOwnProperty(key))
- return false;
- }
- return true;
- }
-
// Detects whether a particular event is supported.
// (from http://stackoverflow.com/questions/2877393/
// detecting-support-for-a-given-javascript-event)
@@ -97,16 +85,6 @@ function () {
};
}
- // @return [Object] Browser-appropriate requestanimationframe implementation.
- // @example util.requestAnimationFrame()(_animate_callback);
- function requestAnimationFrame() {
- return window.webkitRequestAnimationFrame ||
- window.mozRequestAnimationFrame ||
- window.oRequestAnimationFrame ||
- window.msRequestAnimationFrame;
- }
-
-
// Get computed style
// (from http://stackoverflow.com/questions/2664045/
// how-to-retrieve-a-styles-value-in-javascript)
@@ -141,6 +119,7 @@ function () {
}
}
+
// Insert parameters in the URL.
// @param params [Object] (optional)
// @return [String] the appended URL query string
@@ -180,55 +159,22 @@ function () {
}
}
- // Parse query string into object
- // (from http://stackoverflow.com/questions/979975/
- // how-to-get-the-value-from-url-parameter)
- // @param [String] the query string parameter
- // @return [Object] query string as object
- function getQueryParams(qs) {
- if (!qs) qs = document.location.search;
- qs = qs.split('+').join(' ');
-
- var params = {}, tokens, re = /[?&]?([^=]+)=([^&]*)/g;
-
- while ( (tokens = re.exec(qs)) )
- params[decodeURIComponent(tokens[1])] = decodeURIComponent(tokens[2]);
-
- return params;
- }
-
- // Check if a URL parameter is present.
- // (from http://stackoverflow.com/questions/1314383/
- // how-to-check-if-a-querystring-value-is-present-via-javascript)
- // @param [String] The parameter to check for the existence of.
- function isURLParamPresent(param) {
- var url = window.location.href;
- if (url.indexOf('?' + param + '=') !== -1)
- return true;
- else if (url.indexOf('&' + param + '=') !== -1)
- return true;
- return false;
+ // Retrieve named query parameter.
+ // (from http://stackoverflow.com/questions/901115/
+ // how-can-i-get-query-string-values-in-javascript)
+ function getParameterByName(name) {
+ name = name.replace(/[\[]/, "\\[").replace(/[\]]/, "\\]");
+ var regex = new RegExp("[\\?&]" + name + "=([^]*)"),
+ results = regex.exec(location.search);
+ return results == null ? "" : decodeURIComponent(results[1].replace(/\+/g, " "));
}
- // Retrieve a cookie value by name.
- // @param [String] the name of the cookie.
- // @return [String] the cookie value.
- function getCookie(name) {
- var parts = document.cookie.split(name + '=');
- if (parts.length === 2) return parts.pop().split(';').shift();
- }
-
-
return {
- isEmpty:isEmpty,
isEventSupported:isEventSupported,
getWindowRect:getWindowRect,
getOffset:getOffset,
- requestAnimationFrame:requestAnimationFrame,
getStyle:getStyle,
queryString:queryString,
- getQueryParams:getQueryParams,
- isURLParamPresent:isURLParamPresent,
- getCookie:getCookie
+ getParameterByName:getParameterByName
};
});
diff --git a/app/assets/stylesheets/_base.scss b/app/assets/stylesheets/_base.scss
index 48afa31c7..142436ee8 100644
--- a/app/assets/stylesheets/_base.scss
+++ b/app/assets/stylesheets/_base.scss
@@ -329,7 +329,6 @@ sup
font-size: $font_size_120;
}
- .close-button:after,
.close-button::after
{
content: "×";
@@ -351,6 +350,7 @@ sup
font-size: $font_size_110;
border-bottom: 6px solid $accentA-light;
padding-bottom: 10px;
+ padding-right: 10px;
margin-bottom: 10px;
text-align: center;
}
@@ -370,7 +370,7 @@ sup
}
// Feedback form styles.
- input,textarea,button
+ input, textarea, button
{
padding: 5px;
width: 228px;
@@ -1284,7 +1284,6 @@ body { top: 0px !important; }
font-family: $font_serif;
}
- h1.name > a:after,
h1.name > a::after
{
content: " more...";
@@ -1294,7 +1293,6 @@ body { top: 0px !important; }
color: rgba($black,.4);
}
- h1.name > a:hover:after,
h1.name > a:hover::after
{
color: $black;
@@ -1302,7 +1300,6 @@ body { top: 0px !important; }
border-top: 0;
}
-
h2.agency
{
font-size: 14px;
@@ -1461,7 +1458,6 @@ body { top: 0px !important; }
font-family: $font_serif;
}
- .button-close:after,
.button-close::after
{
content: "×";
@@ -1732,8 +1728,7 @@ body { top: 0px !important; }
margin-right: 4px;
}
- >.fax:after,
- >.fax::after
+ > .fax::after
{
content: "FAX";
font-size: 10px;
@@ -1785,7 +1780,6 @@ body { top: 0px !important; }
line-height: normal;
}
- a:last-child:after,
a:last-child::after
{
content: ">";
@@ -1793,7 +1787,6 @@ body { top: 0px !important; }
color: rgba($black,.4);
}
- a:last-child:before,
a:last-child::before
{
content: "<";
diff --git a/app/assets/stylesheets/components/_alert.scss b/app/assets/stylesheets/components/_alert.scss
index bc4a6285b..eae91cda9 100644
--- a/app/assets/stylesheets/components/_alert.scss
+++ b/app/assets/stylesheets/components/_alert.scss
@@ -51,9 +51,11 @@
{
color: lighten($black,50) !important; // IE Fallback
color: rgba($white,.5) !important;
- border-bottom:none !important;
- margin-top:5px;
- margin-bottom:5px;
+ border-bottom: none !important;
+ margin-top: 5px;
+ margin-bottom: 5px;
+ min-width: 28px;
+ min-height: 32px;
@include inline-block();
}
diff --git a/app/assets/stylesheets/components/_input-search.scss b/app/assets/stylesheets/components/_input-search.scss
index 36fbee5c5..e5a75151e 100644
--- a/app/assets/stylesheets/components/_input-search.scss
+++ b/app/assets/stylesheets/components/_input-search.scss
@@ -248,13 +248,13 @@
cursor: pointer;
@include rounded-except(bottom);
- >span
+ > span
{
color: $black; // IE fallback
color: midtone($black, 0.5);
}
- >.fa
+ > .fa
{
color: $input-fa-color;
}
@@ -316,7 +316,6 @@
background: transparent;
}
- .button-clear:after,
.button-clear::after
{
content: "×";
diff --git a/app/assets/stylesheets/ie8.scss b/app/assets/stylesheets/ie8.scss
new file mode 100755
index 000000000..b87f92e86
--- /dev/null
+++ b/app/assets/stylesheets/ie8.scss
@@ -0,0 +1,117 @@
+/* ==========================================================================
+ Internet Explorer version 8 and earlier.
+ ========================================================================== */
+
+html.lt-ie9
+{
+ // Adjustments for popups in header.
+ #popups
+ {
+ .popup-container > article
+ {
+ padding: 10px;
+ @include box-sizing(border-box);
+ border: 1px solid $black;
+ }
+
+ .arrow
+ {
+ display: none;
+ }
+
+ .close-button:after
+ {
+ color: $greyscale_midtone;
+ content: "×";
+ }
+ }
+
+ // Adjustments for alert box component.
+ .alert
+ {
+ border: 1px solid $black;
+
+ // Since IE8 doesn't support rbga() notation, make alert links
+ // lines thicker on roll-over.
+ a
+ {
+ color:$white;
+ border-bottom:1px solid $white;
+ text-decoration: none;
+ }
+
+ a:hover
+ {
+ color:$white;
+ border-bottom:2px solid $white;
+ }
+ }
+
+ // Adjustments location details
+ #detail-info
+ {
+ // The < and > around the "more"
+ // button on the description are not included
+ // because IE8 doesn't support :last-child
+ // .description a:last-child:after
+ // .description a:last-child:before
+
+ .fax:after
+ {
+ content: "FAX";
+ font-size: 10px;
+ font-family: $font_san_serif;
+ @include inline-block();
+ }
+ }
+
+ // Adjustments for search result list.
+ #list-view
+ {
+ .results-entry
+ {
+ > header
+ {
+ >hgroup
+ {
+ h1.name > a:after
+ {
+ content: " more...";
+ font-size: $font_size_90;
+ font-family: $font_san_serif;
+ color: $greyscale_midtone; // IE fallback
+ color: rgba($black,.4);
+ }
+
+ h1.name > a:hover:after
+ {
+ color: $black;
+ border-right: 0;
+ border-top: 0;
+ }
+ }
+ }
+ }
+ }
+
+ // Clearable search input fields.
+ .clearable
+ {
+ .button-clear:after
+ {
+ content: "×";
+ }
+ }
+
+ // Search results map infobox.
+ #map-canvas
+ {
+ .infoBox
+ {
+ .button-close:after
+ {
+ content: "×";
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/assets/stylesheets/main.css.scss b/app/assets/stylesheets/main.css.scss
index cc9ad5ad1..4d925e9b9 100755
--- a/app/assets/stylesheets/main.css.scss
+++ b/app/assets/stylesheets/main.css.scss
@@ -30,3 +30,8 @@
========================================================================== */
@import "responsive";
@import "print";
+
+/* ==========================================================================
+ Browser-specific override imports
+ ========================================================================== */
+@import "ie8"
\ No newline at end of file
diff --git a/app/views/layouts/application.html.haml b/app/views/layouts/application.html.haml
index 75bb0feb9..d097cd5ba 100644
--- a/app/views/layouts/application.html.haml
+++ b/app/views/layouts/application.html.haml
@@ -8,12 +8,14 @@
%head
= render 'shared/head'
- %body{class: "#{controller_name == 'home' ? '' : 'inside '}#{controller_name} #{action_name}"}
+ %body{ class: "#{controller_name == 'home' ? '' : 'inside '}#{controller_name} #{action_name}" }
%section#content
= render 'shared/alert'
= render 'shared/header'
%main.main= yield
= render 'shared/footer'
+ = requirejs_include_tag("routes/#{controller_name}/#{action_name}")
+
- if Rails.env.production? && ENV['GOOGLE_ANALYTICS_ID'].present?
- = render 'shared/google_analytics/event_tracking'
\ No newline at end of file
+ = render 'shared/google_analytics/event_tracking'
diff --git a/app/views/shared/_footer.html.haml b/app/views/shared/_footer.html.haml
index b57a732c4..2b87ab424 100644
--- a/app/views/shared/_footer.html.haml
+++ b/app/views/shared/_footer.html.haml
@@ -15,7 +15,4 @@
for your city or
#{link_to 'view project details', 'http://ohanapi.org'}.
- -# This line needs to go ABOVE the Google Translate code, or it can take too long to load (see issue #462)
- = requirejs_include_tag("routes/#{controller_name}/#{action_name}").gsub("/assets/routes/#{controller_name}/#{action_name}", "routes/#{controller_name}/#{action_name}").html_safe
-
#google-translate-container
diff --git a/vendor/assets/javascripts/google-maps/OverlappingMarkerSpiderfier.js b/vendor/assets/javascripts/google-maps/OverlappingMarkerSpiderfier.js
index 58f28167d..292ce1661 100644
--- a/vendor/assets/javascripts/google-maps/OverlappingMarkerSpiderfier.js
+++ b/vendor/assets/javascripts/google-maps/OverlappingMarkerSpiderfier.js
@@ -35,4 +35,4 @@ e;a=++f)if(g=b[a],g===c)return a;return-1};w.g=function(b){return this.setMap(b)
// ------------------------------------------------------------------
return OverlappingMarkerSpiderfier;
-});
\ No newline at end of file
+});
diff --git a/vendor/assets/javascripts/google-maps/infobox.js b/vendor/assets/javascripts/google-maps/infobox.js
index 5b49983ab..a91aef8f7 100644
--- a/vendor/assets/javascripts/google-maps/infobox.js
+++ b/vendor/assets/javascripts/google-maps/infobox.js
@@ -14,4 +14,4 @@ eval(function(p,a,c,k,e,r){e=function(c){return(c unable to shiv
- supportsHtml5Styles = true;
- supportsUnknownElements = true;
- }
-
- }());
-
- /*--------------------------------------------------------------------------*/
-
- /**
- * Creates a style sheet with the given CSS text and adds it to the document.
- * @private
- * @param {Document} ownerDocument The document.
- * @param {String} cssText The CSS text.
- * @returns {StyleSheet} The style element.
- */
- function addStyleSheet(ownerDocument, cssText) {
- var p = ownerDocument.createElement('p'),
- parent = ownerDocument.getElementsByTagName('head')[0] || ownerDocument.documentElement;
-
- p.innerHTML = 'x';
- return parent.insertBefore(p.lastChild, parent.firstChild);
- }
-
- /**
- * Returns the value of `html5.elements` as an array.
- * @private
- * @returns {Array} An array of shived element node names.
- */
- function getElements() {
- var elements = html5.elements;
- return typeof elements == 'string' ? elements.split(' ') : elements;
- }
-
- /**
- * Extends the built-in list of html5 elements
- * @memberOf html5
- * @param {String|Array} newElements whitespace separated list or array of new element names to shiv
- * @param {Document} ownerDocument The context document.
- */
- function addElements(newElements, ownerDocument) {
- var elements = html5.elements;
- if(typeof elements != 'string'){
- elements = elements.join(' ');
- }
- if(typeof newElements != 'string'){
- newElements = newElements.join(' ');
- }
- html5.elements = elements +' '+ newElements;
- shivDocument(ownerDocument);
- }
-
- /**
- * Returns the data associated to the given document
- * @private
- * @param {Document} ownerDocument The document.
- * @returns {Object} An object of data.
- */
- function getExpandoData(ownerDocument) {
- var data = expandoData[ownerDocument[expando]];
- if (!data) {
- data = {};
- expanID++;
- ownerDocument[expando] = expanID;
- expandoData[expanID] = data;
- }
- return data;
- }
-
- /**
- * returns a shived element for the given nodeName and document
- * @memberOf html5
- * @param {String} nodeName name of the element
- * @param {Document} ownerDocument The context document.
- * @returns {Object} The shived element.
- */
- function createElement(nodeName, ownerDocument, data){
- if (!ownerDocument) {
- ownerDocument = document;
- }
- if(supportsUnknownElements){
- return ownerDocument.createElement(nodeName);
- }
- if (!data) {
- data = getExpandoData(ownerDocument);
- }
- var node;
-
- if (data.cache[nodeName]) {
- node = data.cache[nodeName].cloneNode();
- } else if (saveClones.test(nodeName)) {
- node = (data.cache[nodeName] = data.createElem(nodeName)).cloneNode();
- } else {
- node = data.createElem(nodeName);
- }
-
- // Avoid adding some elements to fragments in IE < 9 because
- // * Attributes like `name` or `type` cannot be set/changed once an element
- // is inserted into a document/fragment
- // * Link elements with `src` attributes that are inaccessible, as with
- // a 403 response, will cause the tab/window to crash
- // * Script elements appended to fragments will execute when their `src`
- // or `text` property is set
- return node.canHaveChildren && !reSkip.test(nodeName) && !node.tagUrn ? data.frag.appendChild(node) : node;
- }
-
- /**
- * returns a shived DocumentFragment for the given document
- * @memberOf html5
- * @param {Document} ownerDocument The context document.
- * @returns {Object} The shived DocumentFragment.
- */
- function createDocumentFragment(ownerDocument, data){
- if (!ownerDocument) {
- ownerDocument = document;
- }
- if(supportsUnknownElements){
- return ownerDocument.createDocumentFragment();
- }
- data = data || getExpandoData(ownerDocument);
- var clone = data.frag.cloneNode(),
- i = 0,
- elems = getElements(),
- l = elems.length;
- for(;i+~])(' + getElements().join('|') + ')(?=[[\\s,>+~#.:]|$)', 'gi'),
- replacement = '$1' + shivNamespace + '\\:$2';
-
- while (index--) {
- pair = parts[index] = parts[index].split('}');
- pair[pair.length - 1] = pair[pair.length - 1].replace(reElements, replacement);
- parts[index] = pair.join('}');
- }
- return parts.join('{');
- }
-
- /**
- * Removes the given wrappers, leaving the original elements.
- * @private
- * @params {Array} wrappers An array of printable wrappers.
- */
- function removeWrappers(wrappers) {
- var index = wrappers.length;
- while (index--) {
- wrappers[index].removeNode();
- }
- }
-
- /*--------------------------------------------------------------------------*/
-
- /**
- * Shivs the given document for print.
- * @memberOf html5
- * @param {Document} ownerDocument The document to shiv.
- * @returns {Document} The shived document.
- */
- function shivPrint(ownerDocument) {
- var shivedSheet,
- wrappers,
- data = getExpandoData(ownerDocument),
- namespaces = ownerDocument.namespaces,
- ownerWindow = ownerDocument.parentWindow;
-
- if (!supportsShivableSheets || ownerDocument.printShived) {
- return ownerDocument;
- }
- if (typeof namespaces[shivNamespace] == 'undefined') {
- namespaces.add(shivNamespace);
- }
-
- function removeSheet() {
- clearTimeout(data._removeSheetTimer);
- if (shivedSheet) {
- shivedSheet.removeNode(true);
- }
- shivedSheet= null;
- }
-
- ownerWindow.attachEvent('onbeforeprint', function() {
-
- removeSheet();
-
- var imports,
- length,
- sheet,
- collection = ownerDocument.styleSheets,
- cssText = [],
- index = collection.length,
- sheets = Array(index);
-
- // convert styleSheets collection to an array
- while (index--) {
- sheets[index] = collection[index];
- }
- // concat all style sheet CSS text
- while ((sheet = sheets.pop())) {
- // IE does not enforce a same origin policy for external style sheets...
- // but has trouble with some dynamically created stylesheets
- if (!sheet.disabled && reMedia.test(sheet.media)) {
-
- try {
- imports = sheet.imports;
- length = imports.length;
- } catch(er){
- length = 0;
- }
-
- for (index = 0; index < length; index++) {
- sheets.push(imports[index]);
- }
-
- try {
- cssText.push(sheet.cssText);
- } catch(er){}
- }
- }
-
- // wrap all HTML5 elements with printable elements and add the shived style sheet
- cssText = shivCssText(cssText.reverse().join(''));
- wrappers = addWrappers(ownerDocument);
- shivedSheet = addStyleSheet(ownerDocument, cssText);
-
- });
-
- ownerWindow.attachEvent('onafterprint', function() {
- // remove wrappers, leaving the original elements, and remove the shived style sheet
- removeWrappers(wrappers);
- clearTimeout(data._removeSheetTimer);
- data._removeSheetTimer = setTimeout(removeSheet, 500);
- });
-
- ownerDocument.printShived = true;
- return ownerDocument;
- }
-
- /*--------------------------------------------------------------------------*/
-
- // expose API
- html5.type += ' print';
- html5.shivPrint = shivPrint;
-
- // shiv for print
- shivPrint(document);
-
-}(this, document));
diff --git a/vendor/assets/javascripts/polyfills/modernizr.min.js b/vendor/assets/javascripts/polyfills/modernizr.min.js
index 79de80ced..2a8b98517 100644
--- a/vendor/assets/javascripts/polyfills/modernizr.min.js
+++ b/vendor/assets/javascripts/polyfills/modernizr.min.js
@@ -1,4 +1,4 @@
-/* Modernizr 2.6.3 (Custom Build) | MIT & BSD
- * Build: http://modernizr.com/download/#-boxshadow-geolocation-printshiv-mq-cssclasses-teststyles-testprop-testallprops-domprefixes-load
+/* Modernizr 2.8.3 (Custom Build) | MIT & BSD
+ * Build: http://modernizr.com/download/#-fontface-backgroundsize-borderradius-boxshadow-rgba-textshadow-generatedcontent-cssgradients-input-inputtypes-geolocation-touch-printshiv-mq-cssclasses-teststyles-testprop-testallprops-hasevent-prefixes-domprefixes-load
*/
-;window.Modernizr=function(a,b,c){function z(a){j.cssText=a}function A(a,b){return z(prefixes.join(a+";")+(b||""))}function B(a,b){return typeof a===b}function C(a,b){return!!~(""+a).indexOf(b)}function D(a,b){for(var d in a){var e=a[d];if(!C(e,"-")&&j[e]!==c)return b=="pfx"?e:!0}return!1}function E(a,b,d){for(var e in a){var f=b[a[e]];if(f!==c)return d===!1?a[e]:B(f,"function")?f.bind(d||b):f}return!1}function F(a,b,c){var d=a.charAt(0).toUpperCase()+a.slice(1),e=(a+" "+n.join(d+" ")+d).split(" ");return B(b,"string")||B(b,"undefined")?D(e,b):(e=(a+" "+o.join(d+" ")+d).split(" "),E(e,b,c))}var d="2.6.3",e={},f=!0,g=b.documentElement,h="modernizr",i=b.createElement(h),j=i.style,k,l={}.toString,m="Webkit Moz O ms",n=m.split(" "),o=m.toLowerCase().split(" "),p={},q={},r={},s=[],t=s.slice,u,v=function(a,c,d,e){var f,i,j,k,l=b.createElement("div"),m=b.body,n=m||b.createElement("body");if(parseInt(d,10))while(d--)j=b.createElement("div"),j.id=e?e[d]:h+(d+1),l.appendChild(j);return f=["",'"].join(""),l.id=h,(m?l:n).innerHTML+=f,n.appendChild(l),m||(n.style.background="",n.style.overflow="hidden",k=g.style.overflow,g.style.overflow="hidden",g.appendChild(n)),i=c(l,a),m?l.parentNode.removeChild(l):(n.parentNode.removeChild(n),g.style.overflow=k),!!i},w=function(b){var c=a.matchMedia||a.msMatchMedia;if(c)return c(b).matches;var d;return v("@media "+b+" { #"+h+" { position: absolute; } }",function(b){d=(a.getComputedStyle?getComputedStyle(b,null):b.currentStyle)["position"]=="absolute"}),d},x={}.hasOwnProperty,y;!B(x,"undefined")&&!B(x.call,"undefined")?y=function(a,b){return x.call(a,b)}:y=function(a,b){return b in a&&B(a.constructor.prototype[b],"undefined")},Function.prototype.bind||(Function.prototype.bind=function(b){var c=this;if(typeof c!="function")throw new TypeError;var d=t.call(arguments,1),e=function(){if(this instanceof e){var a=function(){};a.prototype=c.prototype;var f=new a,g=c.apply(f,d.concat(t.call(arguments)));return Object(g)===g?g:f}return c.apply(b,d.concat(t.call(arguments)))};return e}),p.geolocation=function(){return"geolocation"in navigator},p.boxshadow=function(){return F("boxShadow")};for(var G in p)y(p,G)&&(u=G.toLowerCase(),e[u]=p[G](),s.push((e[u]?"":"no-")+u));return e.addTest=function(a,b){if(typeof a=="object")for(var d in a)y(a,d)&&e.addTest(d,a[d]);else{a=a.toLowerCase();if(e[a]!==c)return e;b=typeof b=="function"?b():b,typeof f!="undefined"&&f&&(g.className+=" "+(b?"":"no-")+a),e[a]=b}return e},z(""),i=k=null,e._version=d,e._domPrefixes=o,e._cssomPrefixes=n,e.mq=w,e.testProp=function(a){return D([a])},e.testAllProps=F,e.testStyles=v,g.className=g.className.replace(/(^|\s)no-js(\s|$)/,"$1$2")+(f?" js "+s.join(" "):""),e}(this,this.document),function(a,b){function k(a,b){var c=a.createElement("p"),d=a.getElementsByTagName("head")[0]||a.documentElement;return c.innerHTML="x",d.insertBefore(c.lastChild,d.firstChild)}function l(){var a=r.elements;return typeof a=="string"?a.split(" "):a}function m(a){var b=i[a[g]];return b||(b={},h++,a[g]=h,i[h]=b),b}function n(a,c,f){c||(c=b);if(j)return c.createElement(a);f||(f=m(c));var g;return f.cache[a]?g=f.cache[a].cloneNode():e.test(a)?g=(f.cache[a]=f.createElem(a)).cloneNode():g=f.createElem(a),g.canHaveChildren&&!d.test(a)?f.frag.appendChild(g):g}function o(a,c){a||(a=b);if(j)return a.createDocumentFragment();c=c||m(a);var d=c.frag.cloneNode(),e=0,f=l(),g=f.length;for(;e+~])("+l().join("|")+")(?=[[\\s,>+~#.:]|$)","gi"),f="$1"+t+"\\:$2";while(d--)b=c[d]=c[d].split("}"),b[b.length-1]=b[b.length-1].replace(e,f),c[d]=b.join("}");return c.join("{")}function y(a){var b=a.length;while(b--)a[b].removeNode()}function z(a){function g(){clearTimeout(d._removeSheetTimer),b&&b.removeNode(!0),b=null}var b,c,d=m(a),e=a.namespaces,f=a.parentWindow;return!u||a.printShived?a:(typeof e[t]=="undefined"&&e.add(t),f.attachEvent("onbeforeprint",function(){g();var d,e,f,h=a.styleSheets,i=[],j=h.length,l=Array(j);while(j--)l[j]=h[j];while(f=l.pop())if(!f.disabled&&s.test(f.media)){try{d=f.imports,e=d.length}catch(m){e=0}for(j=0;j",f="hidden"in a,j=a.childNodes.length==1||function(){b.createElement("a");var a=b.createDocumentFragment();return typeof a.cloneNode=="undefined"||typeof a.createDocumentFragment=="undefined"||typeof a.createElement=="undefined"}()}catch(c){f=!0,j=!0}})();var r={elements:c.elements||"abbr article aside audio bdi canvas data datalist details figcaption figure footer header hgroup mark meter nav output progress section summary time video",shivCSS:c.shivCSS!==!1,supportsUnknownElements:j,shivMethods:c.shivMethods!==!1,type:"default",shivDocument:q,createElement:n,createDocumentFragment:o};a.html5=r,q(b);var s=/^$|\b(?:all|print)\b/,t="html5shiv",u=!j&&function(){var c=b.documentElement;return typeof b.namespaces!="undefined"&&typeof b.parentWindow!="undefined"&&typeof c.applyElement!="undefined"&&typeof c.removeNode!="undefined"&&typeof a.attachEvent!="undefined"}();r.type+=" print",r.shivPrint=z,z(b)}(this,document),function(a,b,c){function d(a){return"[object Function]"==o.call(a)}function e(a){return"string"==typeof a}function f(){}function g(a){return!a||"loaded"==a||"complete"==a||"uninitialized"==a}function h(){var a=p.shift();q=1,a?a.t?m(function(){("c"==a.t?B.injectCss:B.injectJs)(a.s,0,a.a,a.x,a.e,1)},0):(a(),h()):q=0}function i(a,c,d,e,f,i,j){function k(b){if(!o&&g(l.readyState)&&(u.r=o=1,!q&&h(),l.onload=l.onreadystatechange=null,b)){"img"!=a&&m(function(){t.removeChild(l)},50);for(var d in y[c])y[c].hasOwnProperty(d)&&y[c][d].onload()}}var j=j||B.errorTimeout,l=b.createElement(a),o=0,r=0,u={t:d,s:c,e:f,a:i,x:j};1===y[c]&&(r=1,y[c]=[]),"object"==a?l.data=c:(l.src=c,l.type=a),l.width=l.height="0",l.onerror=l.onload=l.onreadystatechange=function(){k.call(this,r)},p.splice(e,0,u),"img"!=a&&(r||2===y[c]?(t.insertBefore(l,s?null:n),m(k,j)):y[c].push(l))}function j(a,b,c,d,f){return q=0,b=b||"j",e(a)?i("c"==b?v:u,a,b,this.i++,c,d,f):(p.splice(this.i++,0,a),1==p.length&&h()),this}function k(){var a=B;return a.loader={load:j,i:0},a}var l=b.documentElement,m=a.setTimeout,n=b.getElementsByTagName("script")[0],o={}.toString,p=[],q=0,r="MozAppearance"in l.style,s=r&&!!b.createRange().compareNode,t=s?l:n.parentNode,l=a.opera&&"[object Opera]"==o.call(a.opera),l=!!b.attachEvent&&!l,u=r?"object":l?"script":"img",v=l?"script":u,w=Array.isArray||function(a){return"[object Array]"==o.call(a)},x=[],y={},z={timeout:function(a,b){return b.length&&(a.timeout=b[0]),a}},A,B;B=function(a){function b(a){var a=a.split("!"),b=x.length,c=a.pop(),d=a.length,c={url:c,origUrl:c,prefixes:a},e,f,g;for(f=0;f',a,""].join(""),l.id=h,(m?l:n).innerHTML+=f,n.appendChild(l),m||(n.style.background="",n.style.overflow="hidden",k=g.style.overflow,g.style.overflow="hidden",g.appendChild(n)),i=c(l,a),m?l.parentNode.removeChild(l):(n.parentNode.removeChild(n),g.style.overflow=k),!!i},y=function(b){var c=a.matchMedia||a.msMatchMedia;if(c)return c(b)&&c(b).matches||!1;var d;return x("@media "+b+" { #"+h+" { position: absolute; } }",function(b){d=(a.getComputedStyle?getComputedStyle(b,null):b.currentStyle)["position"]=="absolute"}),d},z=function(){function d(d,e){e=e||b.createElement(a[d]||"div"),d="on"+d;var f=d in e;return f||(e.setAttribute||(e=b.createElement("div")),e.setAttribute&&e.removeAttribute&&(e.setAttribute(d,""),f=E(e[d],"function"),E(e[d],"undefined")||(e[d]=c),e.removeAttribute(d))),e=null,f}var a={select:"input",change:"input",submit:"form",reset:"form",error:"img",load:"img",abort:"img"};return d}(),A={}.hasOwnProperty,B;!E(A,"undefined")&&!E(A.call,"undefined")?B=function(a,b){return A.call(a,b)}:B=function(a,b){return b in a&&E(a.constructor.prototype[b],"undefined")},Function.prototype.bind||(Function.prototype.bind=function(b){var c=this;if(typeof c!="function")throw new TypeError;var d=v.call(arguments,1),e=function(){if(this instanceof e){var a=function(){};a.prototype=c.prototype;var f=new a,g=c.apply(f,d.concat(v.call(arguments)));return Object(g)===g?g:f}return c.apply(b,d.concat(v.call(arguments)))};return e}),r.touch=function(){var c;return"ontouchstart"in a||a.DocumentTouch&&b instanceof DocumentTouch?c=!0:x(["@media (",n.join("touch-enabled),("),h,")","{#modernizr{top:9px;position:absolute}}"].join(""),function(a){c=a.offsetTop===9}),c},r.geolocation=function(){return"geolocation"in navigator},r.rgba=function(){return C("background-color:rgba(150,255,150,.5)"),F(j.backgroundColor,"rgba")},r.backgroundsize=function(){return I("backgroundSize")},r.borderradius=function(){return I("borderRadius")},r.boxshadow=function(){return I("boxShadow")},r.textshadow=function(){return b.createElement("div").style.textShadow===""},r.cssgradients=function(){var a="background-image:",b="gradient(linear,left top,right bottom,from(#9f9),to(white));",c="linear-gradient(left top,#9f9, white);";return C((a+"-webkit- ".split(" ").join(b+a)+n.join(c+a)).slice(0,-a.length)),F(j.backgroundImage,"gradient")},r.fontface=function(){var a;return x('@font-face {font-family:"font";src:url("https://")}',function(c,d){var e=b.getElementById("smodernizr"),f=e.sheet||e.styleSheet,g=f?f.cssRules&&f.cssRules[0]?f.cssRules[0].cssText:f.cssText||"":"";a=/src/i.test(g)&&g.indexOf(d.split(" ")[0])===0}),a},r.generatedcontent=function(){var a;return x(["#",h,"{font:0/0 a}#",h,':after{content:"',l,'";visibility:hidden;font:3px/1 a}'].join(""),function(b){a=b.offsetHeight>=3}),a};for(var K in r)B(r,K)&&(w=K.toLowerCase(),e[w]=r[K](),u.push((e[w]?"":"no-")+w));return e.input||J(),e.addTest=function(a,b){if(typeof a=="object")for(var d in a)B(a,d)&&e.addTest(d,a[d]);else{a=a.toLowerCase();if(e[a]!==c)return e;b=typeof b=="function"?b():b,typeof f!="undefined"&&f&&(g.className+=" "+(b?"":"no-")+a),e[a]=b}return e},C(""),i=k=null,e._version=d,e._prefixes=n,e._domPrefixes=q,e._cssomPrefixes=p,e.mq=y,e.hasEvent=z,e.testProp=function(a){return G([a])},e.testAllProps=I,e.testStyles=x,g.className=g.className.replace(/(^|\s)no-js(\s|$)/,"$1$2")+(f?" js "+u.join(" "):""),e}(this,this.document),function(a,b){function l(a,b){var c=a.createElement("p"),d=a.getElementsByTagName("head")[0]||a.documentElement;return c.innerHTML="x",d.insertBefore(c.lastChild,d.firstChild)}function m(){var a=s.elements;return typeof a=="string"?a.split(" "):a}function n(a){var b=j[a[h]];return b||(b={},i++,a[h]=i,j[i]=b),b}function o(a,c,d){c||(c=b);if(k)return c.createElement(a);d||(d=n(c));var g;return d.cache[a]?g=d.cache[a].cloneNode():f.test(a)?g=(d.cache[a]=d.createElem(a)).cloneNode():g=d.createElem(a),g.canHaveChildren&&!e.test(a)&&!g.tagUrn?d.frag.appendChild(g):g}function p(a,c){a||(a=b);if(k)return a.createDocumentFragment();c=c||n(a);var d=c.frag.cloneNode(),e=0,f=m(),g=f.length;for(;e+~])("+m().join("|")+")(?=[[\\s,>+~#.:]|$)","gi"),f="$1"+u+"\\:$2";while(d--)b=c[d]=c[d].split("}"),b[b.length-1]=b[b.length-1].replace(e,f),c[d]=b.join("}");return c.join("{")}function z(a){var b=a.length;while(b--)a[b].removeNode()}function A(a){function g(){clearTimeout(d._removeSheetTimer),b&&b.removeNode(!0),b=null}var b,c,d=n(a),e=a.namespaces,f=a.parentWindow;return!v||a.printShived?a:(typeof e[u]=="undefined"&&e.add(u),f.attachEvent("onbeforeprint",function(){g();var d,e,f,h=a.styleSheets,i=[],j=h.length,k=Array(j);while(j--)k[j]=h[j];while(f=k.pop())if(!f.disabled&&t.test(f.media)){try{d=f.imports,e=d.length}catch(m){e=0}for(j=0;j",g="hidden"in a,k=a.childNodes.length==1||function(){b.createElement("a");var a=b.createDocumentFragment();return typeof a.cloneNode=="undefined"||typeof a.createDocumentFragment=="undefined"||typeof a.createElement=="undefined"}()}catch(c){g=!0,k=!0}})();var s={elements:d.elements||"abbr article aside audio bdi canvas data datalist details dialog figcaption figure footer header hgroup main mark meter nav output progress section summary template time video",version:c,shivCSS:d.shivCSS!==!1,supportsUnknownElements:k,shivMethods:d.shivMethods!==!1,type:"default",shivDocument:r,createElement:o,createDocumentFragment:p};a.html5=s,r(b);var t=/^$|\b(?:all|print)\b/,u="html5shiv",v=!k&&function(){var c=b.documentElement;return typeof b.namespaces!="undefined"&&typeof b.parentWindow!="undefined"&&typeof c.applyElement!="undefined"&&typeof c.removeNode!="undefined"&&typeof a.attachEvent!="undefined"}();s.type+=" print",s.shivPrint=A,A(b)}(this,document),function(a,b,c){function d(a){return"[object Function]"==o.call(a)}function e(a){return"string"==typeof a}function f(){}function g(a){return!a||"loaded"==a||"complete"==a||"uninitialized"==a}function h(){var a=p.shift();q=1,a?a.t?m(function(){("c"==a.t?B.injectCss:B.injectJs)(a.s,0,a.a,a.x,a.e,1)},0):(a(),h()):q=0}function i(a,c,d,e,f,i,j){function k(b){if(!o&&g(l.readyState)&&(u.r=o=1,!q&&h(),l.onload=l.onreadystatechange=null,b)){"img"!=a&&m(function(){t.removeChild(l)},50);for(var d in y[c])y[c].hasOwnProperty(d)&&y[c][d].onload()}}var j=j||B.errorTimeout,l=b.createElement(a),o=0,r=0,u={t:d,s:c,e:f,a:i,x:j};1===y[c]&&(r=1,y[c]=[]),"object"==a?l.data=c:(l.src=c,l.type=a),l.width=l.height="0",l.onerror=l.onload=l.onreadystatechange=function(){k.call(this,r)},p.splice(e,0,u),"img"!=a&&(r||2===y[c]?(t.insertBefore(l,s?null:n),m(k,j)):y[c].push(l))}function j(a,b,c,d,f){return q=0,b=b||"j",e(a)?i("c"==b?v:u,a,b,this.i++,c,d,f):(p.splice(this.i++,0,a),1==p.length&&h()),this}function k(){var a=B;return a.loader={load:j,i:0},a}var l=b.documentElement,m=a.setTimeout,n=b.getElementsByTagName("script")[0],o={}.toString,p=[],q=0,r="MozAppearance"in l.style,s=r&&!!b.createRange().compareNode,t=s?l:n.parentNode,l=a.opera&&"[object Opera]"==o.call(a.opera),l=!!b.attachEvent&&!l,u=r?"object":l?"script":"img",v=l?"script":u,w=Array.isArray||function(a){return"[object Array]"==o.call(a)},x=[],y={},z={timeout:function(a,b){return b.length&&(a.timeout=b[0]),a}},A,B;B=function(a){function b(a){var a=a.split("!"),b=x.length,c=a.pop(),d=a.length,c={url:c,origUrl:c,prefixes:a},e,f,g;for(f=0;f