Skip to content

Instantly share code, notes, and snippets.

@rcook
Last active March 30, 2020 05:47
Show Gist options
  • Save rcook/360f788a00f66194269d1efb42de3f80 to your computer and use it in GitHub Desktop.
Save rcook/360f788a00f66194269d1efb42de3f80 to your computer and use it in GitHub Desktop.
Demonstration of hello.js page display login mode
<!DOCTYPE html>
<html>
<head>
<script src="/jquery.min.js"></script>
<script src="/hello.js"></script>
<script src="/hello-ynab.js"></script>
<script>
$(() => {
const NETWORK = "ynab";
const YNAB_CLIENT_ID = "REDACTED";
const Auth = {
init: () => { hello.init({ ynab: YNAB_CLIENT_ID }); return Promise.resolve(null); },
isSignedIn: () => hello(NETWORK).getAuthResponse() != null,
signIn: () => hello(NETWORK).login({ display: "page", force: true }),
signOut: () => hello(NETWORK).logout()
};
Auth
.init()
.then(() => {
if (Auth.isSignedIn()) {
$("#sign-out").on("click", e => Auth.signOut().then(() => { window.location = "/"; })).show();
}
else {
Auth.signIn();
}
});
});
</script>
</head>
<body>
<button id="sign-out" style="display: none">Sign out</button>
</body>
</html>
(hello => {
function User(id) {
this.id = id;
}
hello.init({
ynab: {
oauth: {
version: 2,
auth: "https://app.youneedabudget.com/oauth/authorize",
response_type: "token"
},
base: "https://api.youneedabudget.com/v1/",
get: { me: "user" },
wrap: { me: obj => new User(obj.data.user.id) }
}
});
})(hello);
/**
* @hello.js
*
* HelloJS is a client side Javascript SDK for making OAuth2 logins and subsequent REST calls.
*
* @author Andrew Dodson
* @website https://adodson.com/hello.js/
*
* @copyright Andrew Dodson, 2012 - 2015
* @license MIT: You are free to use and modify this code for any use, on the condition that this copyright notice remains.
*/
var hello = function(name) {
return hello.use(name);
};
hello.utils = {
// Extend the first object with the properties and methods of the second
extend: function(r /*, a[, b[, ...]] */) {
// Get the arguments as an array but ommit the initial item
Array.prototype.slice.call(arguments, 1).forEach(function(a) {
if (Array.isArray(r) && Array.isArray(a)) {
Array.prototype.push.apply(r, a);
}
else if (r && (r instanceof Object || typeof r === 'object') && a && (a instanceof Object || typeof a === 'object') && r !== a) {
for (var x in a) {
r[x] = hello.utils.extend(r[x], a[x]);
}
}
else {
if (Array.isArray(a)) {
// Clone it
a = a.slice(0);
}
r = a;
}
});
return r;
}
};
// Core library
hello.utils.extend(hello, {
settings: {
// OAuth2 authentication defaults
redirect_uri: window.location.href.split('#')[0],
response_type: 'token',
display: 'popup',
state: '',
// OAuth1 shim
// The path to the OAuth1 server for signing user requests
// Want to recreate your own? Checkout https://github.com/MrSwitch/node-oauth-shim
oauth_proxy: 'https://auth-server.herokuapp.com/proxy',
// API timeout in milliseconds
timeout: 20000,
// Popup Options
popup: {
resizable: 1,
scrollbars: 1,
width: 500,
height: 550
},
// Default scope
// Many services require atleast a profile scope,
// HelloJS automatially includes the value of provider.scope_map.basic
// If that's not required it can be removed via hello.settings.scope.length = 0;
scope: ['basic'],
// Scope Maps
// This is the default module scope, these are the defaults which each service is mapped too.
// By including them here it prevents the scope from being applied accidentally
scope_map: {
basic: ''
},
// Default service / network
default_service: null,
// Force authentication
// When hello.login is fired.
// (null): ignore current session expiry and continue with login
// (true): ignore current session expiry and continue with login, ask for user to reauthenticate
// (false): if the current session looks good for the request scopes return the current session.
force: null,
// Page URL
// When 'display=page' this property defines where the users page should end up after redirect_uri
// Ths could be problematic if the redirect_uri is indeed the final place,
// Typically this circumvents the problem of the redirect_url being a dumb relay page.
page_uri: window.location.href
},
// Service configuration objects
services: {},
// Use
// Define a new instance of the HelloJS library with a default service
use: function(service) {
// Create self, which inherits from its parent
var self = Object.create(this);
// Inherit the prototype from its parent
self.settings = Object.create(this.settings);
// Define the default service
if (service) {
self.settings.default_service = service;
}
// Create an instance of Events
self.utils.Event.call(self);
return self;
},
// Initialize
// Define the client_ids for the endpoint services
// @param object o, contains a key value pair, service => clientId
// @param object opts, contains a key value pair of options used for defining the authentication defaults
// @param number timeout, timeout in seconds
init: function(services, options) {
var utils = this.utils;
if (!services) {
return this.services;
}
// Define provider credentials
// Reformat the ID field
for (var x in services) {if (services.hasOwnProperty(x)) {
if (typeof (services[x]) !== 'object') {
services[x] = {id: services[x]};
}
}}
// Merge services if there already exists some
utils.extend(this.services, services);
// Update the default settings with this one.
if (options) {
utils.extend(this.settings, options);
// Do this immediatly incase the browser changes the current path.
if ('redirect_uri' in options) {
this.settings.redirect_uri = utils.url(options.redirect_uri).href;
}
}
return this;
},
// Login
// Using the endpoint
// @param network stringify name to connect to
// @param options object (optional) {display mode, is either none|popup(default)|page, scope: email,birthday,publish, .. }
// @param callback function (optional) fired on signin
login: function() {
// Create an object which inherits its parent as the prototype and constructs a new event chain.
var _this = this;
var utils = _this.utils;
var error = utils.error;
var promise = utils.Promise();
// Get parameters
var p = utils.args({network: 's', options: 'o', callback: 'f'}, arguments);
// Local vars
var url;
// Get all the custom options and store to be appended to the querystring
var qs = utils.diffKey(p.options, _this.settings);
// Merge/override options with app defaults
var opts = p.options = utils.merge(_this.settings, p.options || {});
// Merge/override options with app defaults
opts.popup = utils.merge(_this.settings.popup, p.options.popup || {});
// Network
p.network = p.network || _this.settings.default_service;
// Bind callback to both reject and fulfill states
promise.proxy.then(p.callback, p.callback);
// Trigger an event on the global listener
function emit(s, value) {
hello.emit(s, value);
}
promise.proxy.then(emit.bind(this, 'auth.login auth'), emit.bind(this, 'auth.failed auth'));
// Is our service valid?
if (typeof (p.network) !== 'string' || !(p.network in _this.services)) {
// Trigger the default login.
// Ahh we dont have one.
return promise.reject(error('invalid_network', 'The provided network was not recognized'));
}
var provider = _this.services[p.network];
// Create a global listener to capture events triggered out of scope
var callbackId = utils.globalEvent(function(str) {
// The responseHandler returns a string, lets save this locally
var obj;
if (str) {
obj = JSON.parse(str);
}
else {
obj = error('cancelled', 'The authentication was not completed');
}
// Handle these response using the local
// Trigger on the parent
if (!obj.error) {
// Save on the parent window the new credentials
// This fixes an IE10 bug i think... atleast it does for me.
utils.store(obj.network, obj);
// Fulfill a successful login
promise.fulfill({
network: obj.network,
authResponse: obj
});
}
else {
// Reject a successful login
promise.reject(obj);
}
});
var redirectUri = utils.url(opts.redirect_uri).href;
// May be a space-delimited list of multiple, complementary types
var responseType = provider.oauth.response_type || opts.response_type;
// Fallback to token if the module hasn't defined a grant url
if (/\bcode\b/.test(responseType) && !provider.oauth.grant) {
responseType = responseType.replace(/\bcode\b/, 'token');
}
// Query string parameters, we may pass our own arguments to form the querystring
p.qs = utils.merge(qs, {
client_id: encodeURIComponent(provider.id),
response_type: encodeURIComponent(responseType),
redirect_uri: encodeURIComponent(redirectUri),
state: {
client_id: provider.id,
network: p.network,
display: opts.display,
callback: callbackId,
state: opts.state,
redirect_uri: redirectUri
}
});
// Get current session for merging scopes, and for quick auth response
var session = utils.store(p.network);
// Scopes (authentication permisions)
// Ensure this is a string - IE has a problem moving Arrays between windows
// Append the setup scope
var SCOPE_SPLIT = /[,\s]+/;
// Include default scope settings (cloned).
var scope = _this.settings.scope ? [_this.settings.scope.toString()] : [];
// Extend the providers scope list with the default
var scopeMap = utils.merge(_this.settings.scope_map, provider.scope || {});
// Add user defined scopes...
if (opts.scope) {
scope.push(opts.scope.toString());
}
// Append scopes from a previous session.
// This helps keep app credentials constant,
// Avoiding having to keep tabs on what scopes are authorized
if (session && 'scope' in session && session.scope instanceof String) {
scope.push(session.scope);
}
// Join and Split again
scope = scope.join(',').split(SCOPE_SPLIT);
// Format remove duplicates and empty values
scope = utils.unique(scope).filter(filterEmpty);
// Save the the scopes to the state with the names that they were requested with.
p.qs.state.scope = scope.join(',');
// Map scopes to the providers naming convention
scope = scope.map(function(item) {
// Does this have a mapping?
return (item in scopeMap) ? scopeMap[item] : item;
});
// Stringify and Arrayify so that double mapped scopes are given the chance to be formatted
scope = scope.join(',').split(SCOPE_SPLIT);
// Again...
// Format remove duplicates and empty values
scope = utils.unique(scope).filter(filterEmpty);
// Join with the expected scope delimiter into a string
p.qs.scope = scope.join(provider.scope_delim || ',');
// Is the user already signed in with the appropriate scopes, valid access_token?
if (opts.force === false) {
if (session && 'access_token' in session && session.access_token && 'expires' in session && session.expires > ((new Date()).getTime() / 1e3)) {
// What is different about the scopes in the session vs the scopes in the new login?
var diff = utils.diff((session.scope || '').split(SCOPE_SPLIT), (p.qs.state.scope || '').split(SCOPE_SPLIT));
if (diff.length === 0) {
// OK trigger the callback
promise.fulfill({
unchanged: true,
network: p.network,
authResponse: session
});
// Nothing has changed
return promise;
}
}
}
// Page URL
if (opts.display === 'page' && opts.page_uri) {
// Add a page location, place to endup after session has authenticated
p.qs.state.page_uri = utils.url(opts.page_uri).href;
}
// Bespoke
// Override login querystrings from auth_options
if ('login' in provider && typeof (provider.login) === 'function') {
// Format the paramaters according to the providers formatting function
provider.login(p);
}
// Add OAuth to state
// Where the service is going to take advantage of the oauth_proxy
if (!/\btoken\b/.test(responseType) ||
parseInt(provider.oauth.version, 10) < 2 ||
(opts.display === 'none' && provider.oauth.grant && session && session.refresh_token)) {
// Add the oauth endpoints
p.qs.state.oauth = provider.oauth;
// Add the proxy url
p.qs.state.oauth_proxy = opts.oauth_proxy;
}
// Convert state to a string
p.qs.state = encodeURIComponent(JSON.stringify(p.qs.state));
// URL
if (parseInt(provider.oauth.version, 10) === 1) {
// Turn the request to the OAuth Proxy for 3-legged auth
url = utils.qs(opts.oauth_proxy, p.qs, encodeFunction);
}
// Refresh token
else if (opts.display === 'none' && provider.oauth.grant && session && session.refresh_token) {
// Add the refresh_token to the request
p.qs.refresh_token = session.refresh_token;
// Define the request path
url = utils.qs(opts.oauth_proxy, p.qs, encodeFunction);
}
else {
url = utils.qs(provider.oauth.auth, p.qs, encodeFunction);
}
// Broadcast this event as an auth:init
emit('auth.init', p);
// Execute
// Trigger how we want self displayed
if (opts.display === 'none') {
// Sign-in in the background, iframe
utils.iframe(url, redirectUri);
}
// Triggering popup?
else if (opts.display === 'popup') {
var popup = utils.popup(url, redirectUri, opts.popup);
var timer = setInterval(function() {
if (!popup || popup.closed) {
clearInterval(timer);
if (!promise.state) {
var response = error('cancelled', 'Login has been cancelled');
if (!popup) {
response = error('blocked', 'Popup was blocked');
}
response.network = p.network;
promise.reject(response);
}
}
}, 100);
}
else {
window.location = url;
}
return promise.proxy;
function encodeFunction(s) {return s;}
function filterEmpty(s) {return !!s;}
},
// Remove any data associated with a given service
// @param string name of the service
// @param function callback
logout: function() {
var _this = this;
var utils = _this.utils;
var error = utils.error;
// Create a new promise
var promise = utils.Promise();
var p = utils.args({name:'s', options: 'o', callback: 'f'}, arguments);
p.options = p.options || {};
// Add callback to events
promise.proxy.then(p.callback, p.callback);
// Trigger an event on the global listener
function emit(s, value) {
hello.emit(s, value);
}
promise.proxy.then(emit.bind(this, 'auth.logout auth'), emit.bind(this, 'error'));
// Network
p.name = p.name || this.settings.default_service;
p.authResponse = utils.store(p.name);
if (p.name && !(p.name in _this.services)) {
promise.reject(error('invalid_network', 'The network was unrecognized'));
}
else if (p.name && p.authResponse) {
// Define the callback
var callback = function(opts) {
// Remove from the store
utils.store(p.name, null);
// Emit events by default
promise.fulfill(hello.utils.merge({network:p.name}, opts || {}));
};
// Run an async operation to remove the users session
var _opts = {};
if (p.options.force) {
var logout = _this.services[p.name].logout;
if (logout) {
// Convert logout to URL string,
// If no string is returned, then this function will handle the logout async style
if (typeof (logout) === 'function') {
logout = logout(callback, p);
}
// If logout is a string then assume URL and open in iframe.
if (typeof (logout) === 'string') {
utils.iframe(logout);
_opts.force = null;
_opts.message = 'Logout success on providers site was indeterminate';
}
else if (logout === undefined) {
// The callback function will handle the response.
return promise.proxy;
}
}
}
// Remove local credentials
callback(_opts);
}
else {
promise.reject(error('invalid_session', 'There was no session to remove'));
}
return promise.proxy;
},
// Returns all the sessions that are subscribed too
// @param string optional, name of the service to get information about.
getAuthResponse: function(service) {
// If the service doesn't exist
service = service || this.settings.default_service;
if (!service || !(service in this.services)) {
return null;
}
return this.utils.store(service) || null;
},
// Events: placeholder for the events
events: {}
});
// Core utilities
hello.utils.extend(hello.utils, {
// Error
error: function(code, message) {
return {
error: {
code: code,
message: message
}
};
},
// Append the querystring to a url
// @param string url
// @param object parameters
qs: function(url, params, formatFunction) {
if (params) {
// Set default formatting function
formatFunction = formatFunction || encodeURIComponent;
// Override the items in the URL which already exist
for (var x in params) {
var str = '([\\?\\&])' + x + '=[^\\&]*';
var reg = new RegExp(str);
if (url.match(reg)) {
url = url.replace(reg, '$1' + x + '=' + formatFunction(params[x]));
delete params[x];
}
}
}
if (!this.isEmpty(params)) {
return url + (url.indexOf('?') > -1 ? '&' : '?') + this.param(params, formatFunction);
}
return url;
},
// Param
// Explode/encode the parameters of an URL string/object
// @param string s, string to decode
param: function(s, formatFunction) {
var b;
var a = {};
var m;
if (typeof (s) === 'string') {
formatFunction = formatFunction || decodeURIComponent;
m = s.replace(/^[\#\?]/, '').match(/([^=\/\&]+)=([^\&]+)/g);
if (m) {
for (var i = 0; i < m.length; i++) {
b = m[i].match(/([^=]+)=(.*)/);
a[b[1]] = formatFunction(b[2]);
}
}
return a;
}
else {
formatFunction = formatFunction || encodeURIComponent;
var o = s;
a = [];
for (var x in o) {if (o.hasOwnProperty(x)) {
if (o.hasOwnProperty(x)) {
a.push([x, o[x] === '?' ? '?' : formatFunction(o[x])].join('='));
}
}}
return a.join('&');
}
},
// Local storage facade
store: (function() {
var a = ['localStorage', 'sessionStorage'];
var i = -1;
var prefix = 'test';
// Set LocalStorage
var localStorage;
while (a[++i]) {
try {
// In Chrome with cookies blocked, calling localStorage throws an error
localStorage = window[a[i]];
localStorage.setItem(prefix + i, i);
localStorage.removeItem(prefix + i);
break;
}
catch (e) {
localStorage = null;
}
}
if (!localStorage) {
var cache = null;
localStorage = {
getItem: function(prop) {
prop = prop + '=';
var m = document.cookie.split(';');
for (var i = 0; i < m.length; i++) {
var _m = m[i].replace(/(^\s+|\s+$)/, '');
if (_m && _m.indexOf(prop) === 0) {
return _m.substr(prop.length);
}
}
return cache;
},
setItem: function(prop, value) {
cache = value;
document.cookie = prop + '=' + value;
}
};
// Fill the cache up
cache = localStorage.getItem('hello');
}
function get() {
var json = {};
try {
json = JSON.parse(localStorage.getItem('hello')) || {};
}
catch (e) {}
return json;
}
function set(json) {
localStorage.setItem('hello', JSON.stringify(json));
}
// Check if the browser support local storage
return function(name, value, days) {
// Local storage
var json = get();
if (name && value === undefined) {
return json[name] || null;
}
else if (name && value === null) {
try {
delete json[name];
}
catch (e) {
json[name] = null;
}
}
else if (name) {
json[name] = value;
}
else {
return json;
}
set(json);
return json || null;
};
})(),
// Create and Append new DOM elements
// @param node string
// @param attr object literal
// @param dom/string
append: function(node, attr, target) {
var n = typeof (node) === 'string' ? document.createElement(node) : node;
if (typeof (attr) === 'object') {
if ('tagName' in attr) {
target = attr;
}
else {
for (var x in attr) {if (attr.hasOwnProperty(x)) {
if (typeof (attr[x]) === 'object') {
for (var y in attr[x]) {if (attr[x].hasOwnProperty(y)) {
n[x][y] = attr[x][y];
}}
}
else if (x === 'html') {
n.innerHTML = attr[x];
}
// IE doesn't like us setting methods with setAttribute
else if (!/^on/.test(x)) {
n.setAttribute(x, attr[x]);
}
else {
n[x] = attr[x];
}
}}
}
}
if (target === 'body') {
(function self() {
if (document.body) {
document.body.appendChild(n);
}
else {
setTimeout(self, 16);
}
})();
}
else if (typeof (target) === 'object') {
target.appendChild(n);
}
else if (typeof (target) === 'string') {
document.getElementsByTagName(target)[0].appendChild(n);
}
return n;
},
// An easy way to create a hidden iframe
// @param string src
iframe: function(src) {
this.append('iframe', {src: src, style: {position:'absolute', left: '-1000px', bottom: 0, height: '1px', width: '1px'}}, 'body');
},
// Recursive merge two objects into one, second parameter overides the first
// @param a array
merge: function(/* Args: a, b, c, .. n */) {
var args = Array.prototype.slice.call(arguments);
args.unshift({});
return this.extend.apply(null, args);
},
// Makes it easier to assign parameters, where some are optional
// @param o object
// @param a arguments
args: function(o, args) {
var p = {};
var i = 0;
var t = null;
var x = null;
// 'x' is the first key in the list of object parameters
for (x in o) {if (o.hasOwnProperty(x)) {
break;
}}
// Passing in hash object of arguments?
// Where the first argument can't be an object
if ((args.length === 1) && (typeof (args[0]) === 'object') && o[x] != 'o!') {
// Could this object still belong to a property?
// Check the object keys if they match any of the property keys
for (x in args[0]) {if (o.hasOwnProperty(x)) {
// Does this key exist in the property list?
if (x in o) {
// Yes this key does exist so its most likely this function has been invoked with an object parameter
// Return first argument as the hash of all arguments
return args[0];
}
}}
}
// Else loop through and account for the missing ones.
for (x in o) {if (o.hasOwnProperty(x)) {
t = typeof (args[i]);
if ((typeof (o[x]) === 'function' && o[x].test(args[i])) || (typeof (o[x]) === 'string' && (
(o[x].indexOf('s') > -1 && t === 'string') ||
(o[x].indexOf('o') > -1 && t === 'object') ||
(o[x].indexOf('i') > -1 && t === 'number') ||
(o[x].indexOf('a') > -1 && t === 'object') ||
(o[x].indexOf('f') > -1 && t === 'function')
))
) {
p[x] = args[i++];
}
else if (typeof (o[x]) === 'string' && o[x].indexOf('!') > -1) {
return false;
}
}}
return p;
},
// Returns a URL instance
url: function(path) {
// If the path is empty
if (!path) {
return window.location;
}
// Chrome and FireFox support new URL() to extract URL objects
else if (window.URL && URL instanceof Function && URL.length !== 0) {
return new URL(path, window.location);
}
// Ugly shim, it works!
else {
var a = document.createElement('a');
a.href = path;
return a.cloneNode(false);
}
},
diff: function(a, b) {
return b.filter(function(item) {
return a.indexOf(item) === -1;
});
},
// Get the different hash of properties unique to `a`, and not in `b`
diffKey: function(a, b) {
if (a || !b) {
var r = {};
for (var x in a) {
// Does the property not exist?
if (!(x in b)) {
r[x] = a[x];
}
}
return r;
}
return a;
},
// Unique
// Remove duplicate and null values from an array
// @param a array
unique: function(a) {
if (!Array.isArray(a)) { return []; }
return a.filter(function(item, index) {
// Is this the first location of item
return a.indexOf(item) === index;
});
},
isEmpty: function(obj) {
// Scalar
if (!obj)
return true;
// Array
if (Array.isArray(obj)) {
return !obj.length;
}
else if (typeof (obj) === 'object') {
// Object
for (var key in obj) {
if (obj.hasOwnProperty(key)) {
return false;
}
}
}
return true;
},
//jscs:disable
/*!
** Thenable -- Embeddable Minimum Strictly-Compliant Promises/A+ 1.1.1 Thenable
** Copyright (c) 2013-2014 Ralf S. Engelschall <http://engelschall.com>
** Licensed under The MIT License <http://opensource.org/licenses/MIT>
** Source-Code distributed on <http://github.com/rse/thenable>
*/
Promise: (function(){
/* promise states [Promises/A+ 2.1] */
var STATE_PENDING = 0; /* [Promises/A+ 2.1.1] */
var STATE_FULFILLED = 1; /* [Promises/A+ 2.1.2] */
var STATE_REJECTED = 2; /* [Promises/A+ 2.1.3] */
/* promise object constructor */
var api = function (executor) {
/* optionally support non-constructor/plain-function call */
if (!(this instanceof api))
return new api(executor);
/* initialize object */
this.id = "Thenable/1.0.6";
this.state = STATE_PENDING; /* initial state */
this.fulfillValue = undefined; /* initial value */ /* [Promises/A+ 1.3, 2.1.2.2] */
this.rejectReason = undefined; /* initial reason */ /* [Promises/A+ 1.5, 2.1.3.2] */
this.onFulfilled = []; /* initial handlers */
this.onRejected = []; /* initial handlers */
/* provide optional information-hiding proxy */
this.proxy = {
then: this.then.bind(this)
};
/* support optional executor function */
if (typeof executor === "function")
executor.call(this, this.fulfill.bind(this), this.reject.bind(this));
};
/* promise API methods */
api.prototype = {
/* promise resolving methods */
fulfill: function (value) { return deliver(this, STATE_FULFILLED, "fulfillValue", value); },
reject: function (value) { return deliver(this, STATE_REJECTED, "rejectReason", value); },
/* "The then Method" [Promises/A+ 1.1, 1.2, 2.2] */
then: function (onFulfilled, onRejected) {
var curr = this;
var next = new api(); /* [Promises/A+ 2.2.7] */
curr.onFulfilled.push(
resolver(onFulfilled, next, "fulfill")); /* [Promises/A+ 2.2.2/2.2.6] */
curr.onRejected.push(
resolver(onRejected, next, "reject" )); /* [Promises/A+ 2.2.3/2.2.6] */
execute(curr);
return next.proxy; /* [Promises/A+ 2.2.7, 3.3] */
}
};
/* deliver an action */
var deliver = function (curr, state, name, value) {
if (curr.state === STATE_PENDING) {
curr.state = state; /* [Promises/A+ 2.1.2.1, 2.1.3.1] */
curr[name] = value; /* [Promises/A+ 2.1.2.2, 2.1.3.2] */
execute(curr);
}
return curr;
};
/* execute all handlers */
var execute = function (curr) {
if (curr.state === STATE_FULFILLED)
execute_handlers(curr, "onFulfilled", curr.fulfillValue);
else if (curr.state === STATE_REJECTED)
execute_handlers(curr, "onRejected", curr.rejectReason);
};
/* execute particular set of handlers */
var execute_handlers = function (curr, name, value) {
/* global process: true */
/* global setImmediate: true */
/* global setTimeout: true */
/* short-circuit processing */
if (curr[name].length === 0)
return;
/* iterate over all handlers, exactly once */
var handlers = curr[name];
curr[name] = []; /* [Promises/A+ 2.2.2.3, 2.2.3.3] */
var func = function () {
for (var i = 0; i < handlers.length; i++)
handlers[i](value); /* [Promises/A+ 2.2.5] */
};
/* execute procedure asynchronously */ /* [Promises/A+ 2.2.4, 3.1] */
if (typeof process === "object" && typeof process.nextTick === "function")
process.nextTick(func);
else if (typeof setImmediate === "function")
setImmediate(func);
else
setTimeout(func, 0);
};
/* generate a resolver function */
var resolver = function (cb, next, method) {
return function (value) {
if (typeof cb !== "function") /* [Promises/A+ 2.2.1, 2.2.7.3, 2.2.7.4] */
next[method].call(next, value); /* [Promises/A+ 2.2.7.3, 2.2.7.4] */
else {
var result;
try { result = cb(value); } /* [Promises/A+ 2.2.2.1, 2.2.3.1, 2.2.5, 3.2] */
catch (e) {
next.reject(e); /* [Promises/A+ 2.2.7.2] */
return;
}
resolve(next, result); /* [Promises/A+ 2.2.7.1] */
}
};
};
/* "Promise Resolution Procedure" */ /* [Promises/A+ 2.3] */
var resolve = function (promise, x) {
/* sanity check arguments */ /* [Promises/A+ 2.3.1] */
if (promise === x || promise.proxy === x) {
promise.reject(new TypeError("cannot resolve promise with itself"));
return;
}
/* surgically check for a "then" method
(mainly to just call the "getter" of "then" only once) */
var then;
if ((typeof x === "object" && x !== null) || typeof x === "function") {
try { then = x.then; } /* [Promises/A+ 2.3.3.1, 3.5] */
catch (e) {
promise.reject(e); /* [Promises/A+ 2.3.3.2] */
return;
}
}
/* handle own Thenables [Promises/A+ 2.3.2]
and similar "thenables" [Promises/A+ 2.3.3] */
if (typeof then === "function") {
var resolved = false;
try {
/* call retrieved "then" method */ /* [Promises/A+ 2.3.3.3] */
then.call(x,
/* resolvePromise */ /* [Promises/A+ 2.3.3.3.1] */
function (y) {
if (resolved) return; resolved = true; /* [Promises/A+ 2.3.3.3.3] */
if (y === x) /* [Promises/A+ 3.6] */
promise.reject(new TypeError("circular thenable chain"));
else
resolve(promise, y);
},
/* rejectPromise */ /* [Promises/A+ 2.3.3.3.2] */
function (r) {
if (resolved) return; resolved = true; /* [Promises/A+ 2.3.3.3.3] */
promise.reject(r);
}
);
}
catch (e) {
if (!resolved) /* [Promises/A+ 2.3.3.3.3] */
promise.reject(e); /* [Promises/A+ 2.3.3.3.4] */
}
return;
}
/* handle other values */
promise.fulfill(x); /* [Promises/A+ 2.3.4, 2.3.3.4] */
};
/* export API */
return api;
})(),
//jscs:enable
// Event
// A contructor superclass for adding event menthods, on, off, emit.
Event: function() {
var separator = /[\s\,]+/;
// If this doesn't support getPrototype then we can't get prototype.events of the parent
// So lets get the current instance events, and add those to a parent property
this.parent = {
events: this.events,
findEvents: this.findEvents,
parent: this.parent,
utils: this.utils
};
this.events = {};
// On, subscribe to events
// @param evt string
// @param callback function
this.on = function(evt, callback) {
if (callback && typeof (callback) === 'function') {
var a = evt.split(separator);
for (var i = 0; i < a.length; i++) {
// Has this event already been fired on this instance?
this.events[a[i]] = [callback].concat(this.events[a[i]] || []);
}
}
return this;
};
// Off, unsubscribe to events
// @param evt string
// @param callback function
this.off = function(evt, callback) {
this.findEvents(evt, function(name, index) {
if (!callback || this.events[name][index] === callback) {
this.events[name][index] = null;
}
});
return this;
};
// Emit
// Triggers any subscribed events
this.emit = function(evt /*, data, ... */) {
// Get arguments as an Array, knock off the first one
var args = Array.prototype.slice.call(arguments, 1);
args.push(evt);
// Handler
var handler = function(name, index) {
// Replace the last property with the event name
args[args.length - 1] = (name === '*' ? evt : name);
// Trigger
this.events[name][index].apply(this, args);
};
// Find the callbacks which match the condition and call
var _this = this;
while (_this && _this.findEvents) {
// Find events which match
_this.findEvents(evt + ',*', handler);
_this = _this.parent;
}
return this;
};
//
// Easy functions
this.emitAfter = function() {
var _this = this;
var args = arguments;
setTimeout(function() {
_this.emit.apply(_this, args);
}, 0);
return this;
};
this.findEvents = function(evt, callback) {
var a = evt.split(separator);
for (var name in this.events) {if (this.events.hasOwnProperty(name)) {
if (a.indexOf(name) > -1) {
for (var i = 0; i < this.events[name].length; i++) {
// Does the event handler exist?
if (this.events[name][i]) {
// Emit on the local instance of this
callback.call(this, name, i);
}
}
}
}}
};
return this;
},
// Global Events
// Attach the callback to the window object
// Return its unique reference
globalEvent: function(callback, guid) {
// If the guid has not been supplied then create a new one.
guid = guid || '_hellojs_' + parseInt(Math.random() * 1e12, 10).toString(36);
// Define the callback function
window[guid] = function() {
// Trigger the callback
try {
if (callback.apply(this, arguments)) {
delete window[guid];
}
}
catch (e) {
console.error(e);
}
};
return guid;
},
// Trigger a clientside popup
// This has been augmented to support PhoneGap
popup: function(url, redirectUri, options) {
var documentElement = document.documentElement;
// Multi Screen Popup Positioning (http://stackoverflow.com/a/16861050)
// Credit: http://www.xtf.dk/2011/08/center-new-popup-window-even-on.html
// Fixes dual-screen position Most browsers Firefox
if (options.height && options.top === undefined) {
var dualScreenTop = window.screenTop !== undefined ? window.screenTop : screen.top;
var height = screen.height || window.innerHeight || documentElement.clientHeight;
options.top = parseInt((height - options.height) / 2, 10) + dualScreenTop;
}
if (options.width && options.left === undefined) {
var dualScreenLeft = window.screenLeft !== undefined ? window.screenLeft : screen.left;
var width = screen.width || window.innerWidth || documentElement.clientWidth;
options.left = parseInt((width - options.width) / 2, 10) + dualScreenLeft;
}
// Convert options into an array
var optionsArray = [];
Object.keys(options).forEach(function(name) {
var value = options[name];
optionsArray.push(name + (value !== null ? '=' + value : ''));
});
// Call the open() function with the initial path
//
// OAuth redirect, fixes URI fragments from being lost in Safari
// (URI Fragments within 302 Location URI are lost over HTTPS)
// Loading the redirect.html before triggering the OAuth Flow seems to fix it.
//
// Firefox decodes URL fragments when calling location.hash.
// - This is bad if the value contains break points which are escaped
// - Hence the url must be encoded twice as it contains breakpoints.
if (navigator.userAgent.indexOf('Safari') !== -1 && navigator.userAgent.indexOf('Chrome') === -1) {
url = redirectUri + '#oauth_redirect=' + encodeURIComponent(encodeURIComponent(url));
}
var popup = window.open(
url,
'_blank',
optionsArray.join(',')
);
if (popup && popup.focus) {
popup.focus();
}
return popup;
},
// OAuth and API response handler
responseHandler: function(window, parent) {
var _this = this;
var p;
var location = window.location;
// Is this an auth relay message which needs to call the proxy?
p = _this.param(location.search);
// OAuth2 or OAuth1 server response?
if (p && p.state && (p.code || p.oauth_token)) {
var state = JSON.parse(p.state);
// Add this path as the redirect_uri
p.redirect_uri = state.redirect_uri || location.href.replace(/[\?\#].*$/, '');
// Redirect to the host
var path = _this.qs(state.oauth_proxy, p);
location.assign(path);
return;
}
// Save session, from redirected authentication
// #access_token has come in?
//
// FACEBOOK is returning auth errors within as a query_string... thats a stickler for consistency.
// SoundCloud is the state in the querystring and the token in the hashtag, so we'll mix the two together
p = _this.merge(_this.param(location.search || ''), _this.param(location.hash || ''));
// If p.state
if (p && 'state' in p) {
// Remove any addition information
// E.g. p.state = 'facebook.page';
try {
var a = JSON.parse(p.state);
_this.extend(p, a);
}
catch (e) {
var stateDecoded = decodeURIComponent(p.state);
try {
var b = JSON.parse(stateDecoded);
_this.extend(p, b);
}
catch (e) {
console.error('Could not decode state parameter');
}
}
// Access_token?
if (('access_token' in p && p.access_token) && p.network) {
if (!p.expires_in || parseInt(p.expires_in, 10) === 0) {
// If p.expires_in is unset, set to 0
p.expires_in = 0;
}
p.expires_in = parseInt(p.expires_in, 10);
p.expires = ((new Date()).getTime() / 1e3) + (p.expires_in || (60 * 60 * 24 * 365));
// Lets use the "state" to assign it to one of our networks
authCallback(p, window, parent);
}
// Error=?
// &error_description=?
// &state=?
else if (('error' in p && p.error) && p.network) {
p.error = {
code: p.error,
message: p.error_message || p.error_description
};
// Let the state handler handle it
authCallback(p, window, parent);
}
// API call, or a cancelled login
// Result is serialized JSON string
else if (p.callback && p.callback in parent) {
// Trigger a function in the parent
var res = 'result' in p && p.result ? JSON.parse(p.result) : false;
// Trigger the callback on the parent
callback(parent, p.callback)(res);
closeWindow();
}
// If this page is still open
if (p.page_uri) {
location.assign(p.page_uri);
}
}
// OAuth redirect, fixes URI fragments from being lost in Safari
// (URI Fragments within 302 Location URI are lost over HTTPS)
// Loading the redirect.html before triggering the OAuth Flow seems to fix it.
else if ('oauth_redirect' in p) {
location.assign(decodeURIComponent(p.oauth_redirect));
return;
}
// Trigger a callback to authenticate
function authCallback(obj, window, parent) {
var cb = obj.callback;
var network = obj.network;
// Trigger the callback on the parent
_this.store(network, obj);
// If this is a page request it has no parent or opener window to handle callbacks
if (('display' in obj) && obj.display === 'page') {
return;
}
// Remove from session object
if (parent && cb && cb in parent) {
try {
delete obj.callback;
}
catch (e) {}
// Update store
_this.store(network, obj);
// Call the globalEvent function on the parent
// It's safer to pass back a string to the parent,
// Rather than an object/array (better for IE8)
var str = JSON.stringify(obj);
try {
callback(parent, cb)(str);
}
catch (e) {
// Error thrown whilst executing parent callback
}
}
closeWindow();
}
function callback(parent, callbackID) {
if (callbackID.indexOf('_hellojs_') !== 0) {
return function() {
throw 'Could not execute callback ' + callbackID;
};
}
return parent[callbackID];
}
function closeWindow() {
if (window.frameElement) {
// Inside an iframe, remove from parent
parent.document.body.removeChild(window.frameElement);
}
else {
// Close this current window
try {
window.close();
}
catch (e) {}
// IOS bug wont let us close a popup if still loading
if (window.addEventListener) {
window.addEventListener('load', function() {
window.close();
});
}
}
}
}
});
// Events
// Extend the hello object with its own event instance
hello.utils.Event.call(hello);
///////////////////////////////////
// Monitoring session state
// Check for session changes
///////////////////////////////////
(function(hello) {
// Monitor for a change in state and fire
var oldSessions = {};
// Hash of expired tokens
var expired = {};
// Listen to other triggers to Auth events, use these to update this
hello.on('auth.login, auth.logout', function(auth) {
if (auth && typeof (auth) === 'object' && auth.network) {
oldSessions[auth.network] = hello.utils.store(auth.network) || {};
}
});
(function self() {
var CURRENT_TIME = ((new Date()).getTime() / 1e3);
var emit = function(eventName) {
hello.emit('auth.' + eventName, {
network: name,
authResponse: session
});
};
// Loop through the services
for (var name in hello.services) {if (hello.services.hasOwnProperty(name)) {
if (!hello.services[name].id) {
// We haven't attached an ID so dont listen.
continue;
}
// Get session
var session = hello.utils.store(name) || {};
var provider = hello.services[name];
var oldSess = oldSessions[name] || {};
// Listen for globalEvents that did not get triggered from the child
if (session && 'callback' in session) {
// To do remove from session object...
var cb = session.callback;
try {
delete session.callback;
}
catch (e) {}
// Update store
// Removing the callback
hello.utils.store(name, session);
// Emit global events
try {
window[cb](session);
}
catch (e) {}
}
// Refresh token
if (session && ('expires' in session) && session.expires < CURRENT_TIME) {
// If auto refresh is possible
// Either the browser supports
var refresh = provider.refresh || session.refresh_token;
// Has the refresh been run recently?
if (refresh && (!(name in expired) || expired[name] < CURRENT_TIME)) {
// Try to resignin
hello.emit('notice', name + ' has expired trying to resignin');
hello.login(name, {display: 'none', force: false});
// Update expired, every 10 minutes
expired[name] = CURRENT_TIME + 600;
}
// Does this provider not support refresh
else if (!refresh && !(name in expired)) {
// Label the event
emit('expired');
expired[name] = true;
}
// If session has expired then we dont want to store its value until it can be established that its been updated
continue;
}
// Has session changed?
else if (oldSess.access_token === session.access_token &&
oldSess.expires === session.expires) {
continue;
}
// Access_token has been removed
else if (!session.access_token && oldSess.access_token) {
emit('logout');
}
// Access_token has been created
else if (session.access_token && !oldSess.access_token) {
emit('login');
}
// Access_token has been updated
else if (session.expires !== oldSess.expires) {
emit('update');
}
// Updated stored session
oldSessions[name] = session;
// Remove the expired flags
if (name in expired) {
delete expired[name];
}
}}
// Check error events
setTimeout(self, 1000);
})();
})(hello);
// EOF CORE lib
//////////////////////////////////
/////////////////////////////////////////
// API
// @param path string
// @param query object (optional)
// @param method string (optional)
// @param data object (optional)
// @param timeout integer (optional)
// @param callback function (optional)
hello.api = function() {
// Shorthand
var _this = this;
var utils = _this.utils;
var error = utils.error;
// Construct a new Promise object
var promise = utils.Promise();
// Arguments
var p = utils.args({path: 's!', query: 'o', method: 's', data: 'o', timeout: 'i', callback: 'f'}, arguments);
// Method
p.method = (p.method || 'get').toLowerCase();
// Headers
p.headers = p.headers || {};
// Query
p.query = p.query || {};
// If get, put all parameters into query
if (p.method === 'get' || p.method === 'delete') {
utils.extend(p.query, p.data);
p.data = {};
}
var data = p.data = p.data || {};
// Completed event callback
promise.then(p.callback, p.callback);
// Remove the network from path, e.g. facebook:/me/friends
// Results in { network : facebook, path : me/friends }
if (!p.path) {
return promise.reject(error('invalid_path', 'Missing the path parameter from the request'));
}
p.path = p.path.replace(/^\/+/, '');
var a = (p.path.split(/[\/\:]/, 2) || [])[0].toLowerCase();
if (a in _this.services) {
p.network = a;
var reg = new RegExp('^' + a + ':?\/?');
p.path = p.path.replace(reg, '');
}
// Network & Provider
// Define the network that this request is made for
p.network = _this.settings.default_service = p.network || _this.settings.default_service;
var o = _this.services[p.network];
// INVALID
// Is there no service by the given network name?
if (!o) {
return promise.reject(error('invalid_network', 'Could not match the service requested: ' + p.network));
}
// PATH
// As long as the path isn't flagged as unavaiable, e.g. path == false
if (!(!(p.method in o) || !(p.path in o[p.method]) || o[p.method][p.path] !== false)) {
return promise.reject(error('invalid_path', 'The provided path is not available on the selected network'));
}
// PROXY
// OAuth1 calls always need a proxy
if (!p.oauth_proxy) {
p.oauth_proxy = _this.settings.oauth_proxy;
}
if (!('proxy' in p)) {
p.proxy = p.oauth_proxy && o.oauth && parseInt(o.oauth.version, 10) === 1;
}
// TIMEOUT
// Adopt timeout from global settings by default
if (!('timeout' in p)) {
p.timeout = _this.settings.timeout;
}
// Format response
// Whether to run the raw response through post processing.
if (!('formatResponse' in p)) {
p.formatResponse = true;
}
// Get the current session
// Append the access_token to the query
p.authResponse = _this.getAuthResponse(p.network);
if (p.authResponse && p.authResponse.access_token) {
p.query.access_token = p.authResponse.access_token;
}
var url = p.path;
var m;
// Store the query as options
// This is used to populate the request object before the data is augmented by the prewrap handlers.
p.options = utils.clone(p.query);
// Clone the data object
// Prevent this script overwriting the data of the incoming object.
// Ensure that everytime we run an iteration the callbacks haven't removed some data
p.data = utils.clone(data);
// URL Mapping
// Is there a map for the given URL?
var actions = o[{'delete': 'del'}[p.method] || p.method] || {};
// Extrapolate the QueryString
// Provide a clean path
// Move the querystring into the data
if (p.method === 'get') {
var query = url.split(/[\?#]/)[1];
if (query) {
utils.extend(p.query, utils.param(query));
// Remove the query part from the URL
url = url.replace(/\?.*?(#|$)/, '$1');
}
}
// Is the hash fragment defined
if ((m = url.match(/#(.+)/, ''))) {
url = url.split('#')[0];
p.path = m[1];
}
else if (url in actions) {
p.path = url;
url = actions[url];
}
else if ('default' in actions) {
url = actions['default'];
}
// Redirect Handler
// This defines for the Form+Iframe+Hash hack where to return the results too.
p.redirect_uri = _this.settings.redirect_uri;
// Define FormatHandler
// The request can be procesed in a multitude of ways
// Here's the options - depending on the browser and endpoint
p.xhr = o.xhr;
p.jsonp = o.jsonp;
p.form = o.form;
// Make request
if (typeof (url) === 'function') {
// Does self have its own callback?
url(p, getPath);
}
else {
// Else the URL is a string
getPath(url);
}
return promise.proxy;
// If url needs a base
// Wrap everything in
function getPath(url) {
// Format the string if it needs it
url = url.replace(/\@\{([a-z\_\-]+)(\|.*?)?\}/gi, function(m, key, defaults) {
var val = defaults ? defaults.replace(/^\|/, '') : '';
if (key in p.query) {
val = p.query[key];
delete p.query[key];
}
else if (p.data && key in p.data) {
val = p.data[key];
delete p.data[key];
}
else if (!defaults) {
promise.reject(error('missing_attribute', 'The attribute ' + key + ' is missing from the request'));
}
return val;
});
// Add base
if (!url.match(/^https?:\/\//)) {
url = o.base + url;
}
// Define the request URL
p.url = url;
// Make the HTTP request with the curated request object
// CALLBACK HANDLER
// @ response object
// @ statusCode integer if available
utils.request(p, function(r, headers) {
// Is this a raw response?
if (!p.formatResponse) {
// Bad request? error statusCode or otherwise contains an error response vis JSONP?
if (typeof headers === 'object' ? (headers.statusCode >= 400) : (typeof r === 'object' && 'error' in r)) {
promise.reject(r);
}
else {
promise.fulfill(r);
}
return;
}
// Should this be an object
if (r === true) {
r = {success:true};
}
else if (!r) {
r = {};
}
// The delete callback needs a better response
if (p.method === 'delete') {
r = (!r || utils.isEmpty(r)) ? {success:true} : r;
}
// FORMAT RESPONSE?
// Does self request have a corresponding formatter
if (o.wrap && ((p.path in o.wrap) || ('default' in o.wrap))) {
var wrap = (p.path in o.wrap ? p.path : 'default');
var time = (new Date()).getTime();
// FORMAT RESPONSE
var b = o.wrap[wrap](r, headers, p);
// Has the response been utterly overwritten?
// Typically self augments the existing object.. but for those rare occassions
if (b) {
r = b;
}
}
// Is there a next_page defined in the response?
if (r && 'paging' in r && r.paging.next) {
// Add the relative path if it is missing from the paging/next path
if (r.paging.next[0] === '?') {
r.paging.next = p.path + r.paging.next;
}
// The relative path has been defined, lets markup the handler in the HashFragment
else {
r.paging.next += '#' + p.path;
}
}
// Dispatch to listeners
// Emit events which pertain to the formatted response
if (!r || 'error' in r) {
promise.reject(r);
}
else {
promise.fulfill(r);
}
});
}
};
// API utilities
hello.utils.extend(hello.utils, {
// Make an HTTP request
request: function(p, callback) {
var _this = this;
var error = _this.error;
// This has to go through a POST request
if (!_this.isEmpty(p.data) && !('FileList' in window) && _this.hasBinary(p.data)) {
// Disable XHR and JSONP
p.xhr = false;
p.jsonp = false;
}
// Check if the browser and service support CORS
var cors = this.request_cors(function() {
// If it does then run this...
return ((p.xhr === undefined) || (p.xhr && (typeof (p.xhr) !== 'function' || p.xhr(p, p.query))));
});
if (cors) {
formatUrl(p, function(url) {
var x = _this.xhr(p.method, url, p.headers, p.data, callback);
x.onprogress = p.onprogress || null;
// Windows Phone does not support xhr.upload, see #74
// Feature detect
if (x.upload && p.onuploadprogress) {
x.upload.onprogress = p.onuploadprogress;
}
});
return;
}
// Clone the query object
// Each request modifies the query object and needs to be tared after each one.
var _query = p.query;
p.query = _this.clone(p.query);
// Assign a new callbackID
p.callbackID = _this.globalEvent();
// JSONP
if (p.jsonp !== false) {
// Clone the query object
p.query.callback = p.callbackID;
// If the JSONP is a function then run it
if (typeof (p.jsonp) === 'function') {
p.jsonp(p, p.query);
}
// Lets use JSONP if the method is 'get'
if (p.method === 'get') {
formatUrl(p, function(url) {
_this.jsonp(url, callback, p.callbackID, p.timeout);
});
return;
}
else {
// It's not compatible reset query
p.query = _query;
}
}
// Otherwise we're on to the old school, iframe hacks and JSONP
if (p.form !== false) {
// Add some additional query parameters to the URL
// We're pretty stuffed if the endpoint doesn't like these
p.query.redirect_uri = p.redirect_uri;
p.query.state = JSON.stringify({callback:p.callbackID});
var opts;
if (typeof (p.form) === 'function') {
// Format the request
opts = p.form(p, p.query);
}
if (p.method === 'post' && opts !== false) {
formatUrl(p, function(url) {
_this.post(url, p.data, opts, callback, p.callbackID, p.timeout);
});
return;
}
}
// None of the methods were successful throw an error
callback(error('invalid_request', 'There was no mechanism for handling this request'));
return;
// Format URL
// Constructs the request URL, optionally wraps the URL through a call to a proxy server
// Returns the formatted URL
function formatUrl(p, callback) {
// Are we signing the request?
var sign;
// OAuth1
// Remove the token from the query before signing
if (p.authResponse && p.authResponse.oauth && parseInt(p.authResponse.oauth.version, 10) === 1) {
// OAUTH SIGNING PROXY
sign = p.query.access_token;
// Remove the access_token
delete p.query.access_token;
// Enfore use of Proxy
p.proxy = true;
}
// POST body to querystring
if (p.data && (p.method === 'get' || p.method === 'delete')) {
// Attach the p.data to the querystring.
_this.extend(p.query, p.data);
p.data = null;
}
// Construct the path
var path = _this.qs(p.url, p.query);
// Proxy the request through a server
// Used for signing OAuth1
// And circumventing services without Access-Control Headers
if (p.proxy) {
// Use the proxy as a path
path = _this.qs(p.oauth_proxy, {
path: path,
access_token: sign || '',
// This will prompt the request to be signed as though it is OAuth1
then: p.proxy_response_type || (p.method.toLowerCase() === 'get' ? 'redirect' : 'proxy'),
method: p.method.toLowerCase(),
suppress_response_codes: true
});
}
callback(path);
}
},
// Test whether the browser supports the CORS response
request_cors: function(callback) {
return 'withCredentials' in new XMLHttpRequest() && callback();
},
// Return the type of DOM object
domInstance: function(type, data) {
var test = 'HTML' + (type || '').replace(
/^[a-z]/,
function(m) {
return m.toUpperCase();
}
) + 'Element';
if (!data) {
return false;
}
if (window[test]) {
return data instanceof window[test];
}
else if (window.Element) {
return data instanceof window.Element && (!type || (data.tagName && data.tagName.toLowerCase() === type));
}
else {
return (!(data instanceof Object || data instanceof Array || data instanceof String || data instanceof Number) && data.tagName && data.tagName.toLowerCase() === type);
}
},
// Create a clone of an object
clone: function(obj) {
// Does not clone DOM elements, nor Binary data, e.g. Blobs, Filelists
if (obj === null || typeof (obj) !== 'object' || obj instanceof Date || 'nodeName' in obj || this.isBinary(obj) || (typeof FormData === 'function' && obj instanceof FormData)) {
return obj;
}
if (Array.isArray(obj)) {
// Clone each item in the array
return obj.map(this.clone.bind(this));
}
// But does clone everything else.
var clone = {};
for (var x in obj) {
clone[x] = this.clone(obj[x]);
}
return clone;
},
// XHR: uses CORS to make requests
xhr: function(method, url, headers, data, callback) {
var r = new XMLHttpRequest();
var error = this.error;
// Binary?
var binary = false;
if (method === 'blob') {
binary = method;
method = 'GET';
}
method = method.toUpperCase();
// Xhr.responseType 'json' is not supported in any of the vendors yet.
r.onload = function(e) {
var json = r.response;
try {
json = JSON.parse(r.responseText);
}
catch (_e) {
if (r.status === 401) {
json = error('access_denied', r.statusText);
}
}
var headers = headersToJSON(r.getAllResponseHeaders());
headers.statusCode = r.status;
callback(json || (method === 'GET' ? error('empty_response', 'Could not get resource') : {}), headers);
};
r.onerror = function(e) {
var json = r.responseText;
try {
json = JSON.parse(r.responseText);
}
catch (_e) {}
callback(json || error('access_denied', 'Could not get resource'));
};
var x;
// Should we add the query to the URL?
if (method === 'GET' || method === 'DELETE') {
data = null;
}
else if (data && typeof (data) !== 'string' && !(data instanceof FormData) && !(data instanceof File) && !(data instanceof Blob)) {
// Loop through and add formData
var f = new FormData();
for (x in data) if (data.hasOwnProperty(x)) {
if (data[x] instanceof HTMLInputElement) {
if ('files' in data[x] && data[x].files.length > 0) {
f.append(x, data[x].files[0]);
}
}
else if (data[x] instanceof Blob) {
f.append(x, data[x], data.name);
}
else {
f.append(x, data[x]);
}
}
data = f;
}
// Open the path, async
r.open(method, url, true);
if (binary) {
if ('responseType' in r) {
r.responseType = binary;
}
else {
r.overrideMimeType('text/plain; charset=x-user-defined');
}
}
// Set any bespoke headers
if (headers) {
for (x in headers) {
r.setRequestHeader(x, headers[x]);
}
}
r.send(data);
return r;
// Headers are returned as a string
function headersToJSON(s) {
var r = {};
var reg = /([a-z\-]+):\s?(.*);?/gi;
var m;
while ((m = reg.exec(s))) {
r[m[1]] = m[2];
}
return r;
}
},
// JSONP
// Injects a script tag into the DOM to be executed and appends a callback function to the window object
// @param string/function pathFunc either a string of the URL or a callback function pathFunc(querystringhash, continueFunc);
// @param function callback a function to call on completion;
jsonp: function(url, callback, callbackID, timeout) {
var _this = this;
var error = _this.error;
// Change the name of the callback
var bool = 0;
var head = document.getElementsByTagName('head')[0];
var operaFix;
var result = error('server_error', 'server_error');
var cb = function() {
if (!(bool++)) {
window.setTimeout(function() {
callback(result);
head.removeChild(script);
}, 0);
}
};
// Add callback to the window object
callbackID = _this.globalEvent(function(json) {
result = json;
return true;
// Mark callback as done
}, callbackID);
// The URL is a function for some cases and as such
// Determine its value with a callback containing the new parameters of this function.
url = url.replace(new RegExp('=\\?(&|$)'), '=' + callbackID + '$1');
// Build script tag
var script = _this.append('script', {
id: callbackID,
name: callbackID,
src: url,
async: true,
onload: cb,
onerror: cb,
onreadystatechange: function() {
if (/loaded|complete/i.test(this.readyState)) {
cb();
}
}
});
// Opera fix error
// Problem: If an error occurs with script loading Opera fails to trigger the script.onerror handler we specified
//
// Fix:
// By setting the request to synchronous we can trigger the error handler when all else fails.
// This action will be ignored if we've already called the callback handler "cb" with a successful onload event
if (window.navigator.userAgent.toLowerCase().indexOf('opera') > -1) {
operaFix = _this.append('script', {
text: 'document.getElementById(\'' + callbackID + '\').onerror();'
});
script.async = false;
}
// Add timeout
if (timeout) {
window.setTimeout(function() {
result = error('timeout', 'timeout');
cb();
}, timeout);
}
// TODO: add fix for IE,
// However: unable recreate the bug of firing off the onreadystatechange before the script content has been executed and the value of "result" has been defined.
// Inject script tag into the head element
head.appendChild(script);
// Append Opera Fix to run after our script
if (operaFix) {
head.appendChild(operaFix);
}
},
// Post
// Send information to a remote location using the post mechanism
// @param string uri path
// @param object data, key value data to send
// @param function callback, function to execute in response
post: function(url, data, options, callback, callbackID, timeout) {
var _this = this;
var error = _this.error;
var doc = document;
// This hack needs a form
var form = null;
var reenableAfterSubmit = [];
var newform;
var i = 0;
var x = null;
var bool = 0;
var cb = function(r) {
if (!(bool++)) {
callback(r);
}
};
// What is the name of the callback to contain
// We'll also use this to name the iframe
_this.globalEvent(cb, callbackID);
// Build the iframe window
var win;
try {
// IE7 hack, only lets us define the name here, not later.
win = doc.createElement('<iframe name="' + callbackID + '">');
}
catch (e) {
win = doc.createElement('iframe');
}
win.name = callbackID;
win.id = callbackID;
win.style.display = 'none';
// Override callback mechanism. Triggger a response onload/onerror
if (options && options.callbackonload) {
// Onload is being fired twice
win.onload = function() {
cb({
response: 'posted',
message: 'Content was posted'
});
};
}
if (timeout) {
setTimeout(function() {
cb(error('timeout', 'The post operation timed out'));
}, timeout);
}
doc.body.appendChild(win);
// If we are just posting a single item
if (_this.domInstance('form', data)) {
// Get the parent form
form = data.form;
// Loop through and disable all of its siblings
for (i = 0; i < form.elements.length; i++) {
if (form.elements[i] !== data) {
form.elements[i].setAttribute('disabled', true);
}
}
// Move the focus to the form
data = form;
}
// Posting a form
if (_this.domInstance('form', data)) {
// This is a form element
form = data;
// Does this form need to be a multipart form?
for (i = 0; i < form.elements.length; i++) {
if (!form.elements[i].disabled && form.elements[i].type === 'file') {
form.encoding = form.enctype = 'multipart/form-data';
form.elements[i].setAttribute('name', 'file');
}
}
}
else {
// Its not a form element,
// Therefore it must be a JSON object of Key=>Value or Key=>Element
// If anyone of those values are a input type=file we shall shall insert its siblings into the form for which it belongs.
for (x in data) if (data.hasOwnProperty(x)) {
// Is this an input Element?
if (_this.domInstance('input', data[x]) && data[x].type === 'file') {
form = data[x].form;
form.encoding = form.enctype = 'multipart/form-data';
}
}
// Do If there is no defined form element, lets create one.
if (!form) {
// Build form
form = doc.createElement('form');
doc.body.appendChild(form);
newform = form;
}
var input;
// Add elements to the form if they dont exist
for (x in data) if (data.hasOwnProperty(x)) {
// Is this an element?
var el = (_this.domInstance('input', data[x]) || _this.domInstance('textArea', data[x]) || _this.domInstance('select', data[x]));
// Is this not an input element, or one that exists outside the form.
if (!el || data[x].form !== form) {
// Does an element have the same name?
var inputs = form.elements[x];
if (input) {
// Remove it.
if (!(inputs instanceof NodeList)) {
inputs = [inputs];
}
for (i = 0; i < inputs.length; i++) {
inputs[i].parentNode.removeChild(inputs[i]);
}
}
// Create an input element
input = doc.createElement('input');
input.setAttribute('type', 'hidden');
input.setAttribute('name', x);
// Does it have a value attribute?
if (el) {
input.value = data[x].value;
}
else if (_this.domInstance(null, data[x])) {
input.value = data[x].innerHTML || data[x].innerText;
}
else {
input.value = data[x];
}
form.appendChild(input);
}
// It is an element, which exists within the form, but the name is wrong
else if (el && data[x].name !== x) {
data[x].setAttribute('name', x);
data[x].name = x;
}
}
// Disable elements from within the form if they weren't specified
for (i = 0; i < form.elements.length; i++) {
input = form.elements[i];
// Does the same name and value exist in the parent
if (!(input.name in data) && input.getAttribute('disabled') !== true) {
// Disable
input.setAttribute('disabled', true);
// Add re-enable to callback
reenableAfterSubmit.push(input);
}
}
}
// Set the target of the form
form.setAttribute('method', 'POST');
form.setAttribute('target', callbackID);
form.target = callbackID;
// Update the form URL
form.setAttribute('action', url);
// Submit the form
// Some reason this needs to be offset from the current window execution
setTimeout(function() {
form.submit();
setTimeout(function() {
try {
// Remove the iframe from the page.
//win.parentNode.removeChild(win);
// Remove the form
if (newform) {
newform.parentNode.removeChild(newform);
}
}
catch (e) {
try {
console.error('HelloJS: could not remove iframe');
}
catch (ee) {}
}
// Reenable the disabled form
for (var i = 0; i < reenableAfterSubmit.length; i++) {
if (reenableAfterSubmit[i]) {
reenableAfterSubmit[i].setAttribute('disabled', false);
reenableAfterSubmit[i].disabled = false;
}
}
}, 0);
}, 100);
},
// Some of the providers require that only multipart is used with non-binary forms.
// This function checks whether the form contains binary data
hasBinary: function(data) {
for (var x in data) if (data.hasOwnProperty(x)) {
if (this.isBinary(data[x])) {
return true;
}
}
return false;
},
// Determines if a variable Either Is or like a FormInput has the value of a Blob
isBinary: function(data) {
return data instanceof Object && (
(this.domInstance('input', data) && data.type === 'file') ||
('FileList' in window && data instanceof window.FileList) ||
('File' in window && data instanceof window.File) ||
('Blob' in window && data instanceof window.Blob));
},
// Convert Data-URI to Blob string
toBlob: function(dataURI) {
var reg = /^data\:([^;,]+(\;charset=[^;,]+)?)(\;base64)?,/i;
var m = dataURI.match(reg);
if (!m) {
return dataURI;
}
var binary = atob(dataURI.replace(reg, ''));
var array = [];
for (var i = 0; i < binary.length; i++) {
array.push(binary.charCodeAt(i));
}
return new Blob([new Uint8Array(array)], {type: m[1]});
}
});
// EXTRA: Convert FormElement to JSON for POSTing
// Wrappers to add additional functionality to existing functions
(function(hello) {
// Copy original function
var api = hello.api;
var utils = hello.utils;
utils.extend(utils, {
// DataToJSON
// This takes a FormElement|NodeList|InputElement|MixedObjects and convers the data object to JSON.
dataToJSON: function(p) {
var _this = this;
var w = window;
var data = p.data;
// Is data a form object
if (_this.domInstance('form', data)) {
data = _this.nodeListToJSON(data.elements);
}
else if ('NodeList' in w && data instanceof NodeList) {
data = _this.nodeListToJSON(data);
}
else if (_this.domInstance('input', data)) {
data = _this.nodeListToJSON([data]);
}
// Is data a blob, File, FileList?
if (('File' in w && data instanceof w.File) ||
('Blob' in w && data instanceof w.Blob) ||
('FileList' in w && data instanceof w.FileList)) {
data = {file: data};
}
// Loop through data if it's not form data it must now be a JSON object
if (!('FormData' in w && data instanceof w.FormData)) {
for (var x in data) if (data.hasOwnProperty(x)) {
if ('FileList' in w && data[x] instanceof w.FileList) {
if (data[x].length === 1) {
data[x] = data[x][0];
}
}
else if (_this.domInstance('input', data[x]) && data[x].type === 'file') {
continue;
}
else if (_this.domInstance('input', data[x]) ||
_this.domInstance('select', data[x]) ||
_this.domInstance('textArea', data[x])) {
data[x] = data[x].value;
}
else if (_this.domInstance(null, data[x])) {
data[x] = data[x].innerHTML || data[x].innerText;
}
}
}
p.data = data;
return data;
},
// NodeListToJSON
// Given a list of elements extrapolate their values and return as a json object
nodeListToJSON: function(nodelist) {
var json = {};
// Create a data string
for (var i = 0; i < nodelist.length; i++) {
var input = nodelist[i];
// If the name of the input is empty or diabled, dont add it.
if (input.disabled || !input.name) {
continue;
}
// Is this a file, does the browser not support 'files' and 'FormData'?
if (input.type === 'file') {
json[input.name] = input;
}
else {
json[input.name] = input.value || input.innerHTML;
}
}
return json;
}
});
// Replace it
hello.api = function() {
// Get arguments
var p = utils.args({path: 's!', method: 's', data:'o', timeout: 'i', callback: 'f'}, arguments);
// Change for into a data object
if (p.data) {
utils.dataToJSON(p);
}
return api.call(this, p);
};
})(hello);
/////////////////////////////////////
//
// Save any access token that is in the current page URL
// Handle any response solicited through iframe hash tag following an API request
//
/////////////////////////////////////
hello.utils.responseHandler(window, window.opener || window.parent);
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<a href="/dashboard.html">Go to dashboard</a>
</body>
</html>
/*! jQuery v3.3.1 | (c) JS Foundation and other contributors | jquery.org/license */
!function(e,t){"use strict";"object"==typeof module&&"object"==typeof module.exports?module.exports=e.document?t(e,!0):function(e){if(!e.document)throw new Error("jQuery requires a window with a document");return t(e)}:t(e)}("undefined"!=typeof window?window:this,function(e,t){"use strict";var n=[],r=e.document,i=Object.getPrototypeOf,o=n.slice,a=n.concat,s=n.push,u=n.indexOf,l={},c=l.toString,f=l.hasOwnProperty,p=f.toString,d=p.call(Object),h={},g=function e(t){return"function"==typeof t&&"number"!=typeof t.nodeType},y=function e(t){return null!=t&&t===t.window},v={type:!0,src:!0,noModule:!0};function m(e,t,n){var i,o=(t=t||r).createElement("script");if(o.text=e,n)for(i in v)n[i]&&(o[i]=n[i]);t.head.appendChild(o).parentNode.removeChild(o)}function x(e){return null==e?e+"":"object"==typeof e||"function"==typeof e?l[c.call(e)]||"object":typeof e}var b="3.3.1",w=function(e,t){return new w.fn.init(e,t)},T=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g;w.fn=w.prototype={jquery:"3.3.1",constructor:w,length:0,toArray:function(){return o.call(this)},get:function(e){return null==e?o.call(this):e<0?this[e+this.length]:this[e]},pushStack:function(e){var t=w.merge(this.constructor(),e);return t.prevObject=this,t},each:function(e){return w.each(this,e)},map:function(e){return this.pushStack(w.map(this,function(t,n){return e.call(t,n,t)}))},slice:function(){return this.pushStack(o.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(e){var t=this.length,n=+e+(e<0?t:0);return this.pushStack(n>=0&&n<t?[this[n]]:[])},end:function(){return this.prevObject||this.constructor()},push:s,sort:n.sort,splice:n.splice},w.extend=w.fn.extend=function(){var e,t,n,r,i,o,a=arguments[0]||{},s=1,u=arguments.length,l=!1;for("boolean"==typeof a&&(l=a,a=arguments[s]||{},s++),"object"==typeof a||g(a)||(a={}),s===u&&(a=this,s--);s<u;s++)if(null!=(e=arguments[s]))for(t in e)n=a[t],a!==(r=e[t])&&(l&&r&&(w.isPlainObject(r)||(i=Array.isArray(r)))?(i?(i=!1,o=n&&Array.isArray(n)?n:[]):o=n&&w.isPlainObject(n)?n:{},a[t]=w.extend(l,o,r)):void 0!==r&&(a[t]=r));return a},w.extend({expando:"jQuery"+("3.3.1"+Math.random()).replace(/\D/g,""),isReady:!0,error:function(e){throw new Error(e)},noop:function(){},isPlainObject:function(e){var t,n;return!(!e||"[object Object]"!==c.call(e))&&(!(t=i(e))||"function"==typeof(n=f.call(t,"constructor")&&t.constructor)&&p.call(n)===d)},isEmptyObject:function(e){var t;for(t in e)return!1;return!0},globalEval:function(e){m(e)},each:function(e,t){var n,r=0;if(C(e)){for(n=e.length;r<n;r++)if(!1===t.call(e[r],r,e[r]))break}else for(r in e)if(!1===t.call(e[r],r,e[r]))break;return e},trim:function(e){return null==e?"":(e+"").replace(T,"")},makeArray:function(e,t){var n=t||[];return null!=e&&(C(Object(e))?w.merge(n,"string"==typeof e?[e]:e):s.call(n,e)),n},inArray:function(e,t,n){return null==t?-1:u.call(t,e,n)},merge:function(e,t){for(var n=+t.length,r=0,i=e.length;r<n;r++)e[i++]=t[r];return e.length=i,e},grep:function(e,t,n){for(var r,i=[],o=0,a=e.length,s=!n;o<a;o++)(r=!t(e[o],o))!==s&&i.push(e[o]);return i},map:function(e,t,n){var r,i,o=0,s=[];if(C(e))for(r=e.length;o<r;o++)null!=(i=t(e[o],o,n))&&s.push(i);else for(o in e)null!=(i=t(e[o],o,n))&&s.push(i);return a.apply([],s)},guid:1,support:h}),"function"==typeof Symbol&&(w.fn[Symbol.iterator]=n[Symbol.iterator]),w.each("Boolean Number String Function Array Date RegExp Object Error Symbol".split(" "),function(e,t){l["[object "+t+"]"]=t.toLowerCase()});function C(e){var t=!!e&&"length"in e&&e.length,n=x(e);return!g(e)&&!y(e)&&("array"===n||0===t||"number"==typeof t&&t>0&&t-1 in e)}var E=function(e){var t,n,r,i,o,a,s,u,l,c,f,p,d,h,g,y,v,m,x,b="sizzle"+1*new Date,w=e.document,T=0,C=0,E=ae(),k=ae(),S=ae(),D=function(e,t){return e===t&&(f=!0),0},N={}.hasOwnProperty,A=[],j=A.pop,q=A.push,L=A.push,H=A.slice,O=function(e,t){for(var n=0,r=e.length;n<r;n++)if(e[n]===t)return n;return-1},P="checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",M="[\\x20\\t\\r\\n\\f]",R="(?:\\\\.|[\\w-]|[^\0-\\xa0])+",I="\\["+M+"*("+R+")(?:"+M+"*([*^$|!~]?=)"+M+"*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|("+R+"))|)"+M+"*\\]",W=":("+R+")(?:\\((('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|((?:\\\\.|[^\\\\()[\\]]|"+I+")*)|.*)\\)|)",$=new RegExp(M+"+","g"),B=new RegExp("^"+M+"+|((?:^|[^\\\\])(?:\\\\.)*)"+M+"+$","g"),F=new RegExp("^"+M+"*,"+M+"*"),_=new RegExp("^"+M+"*([>+~]|"+M+")"+M+"*"),z=new RegExp("="+M+"*([^\\]'\"]*?)"+M+"*\\]","g"),X=new RegExp(W),U=new RegExp("^"+R+"$"),V={ID:new RegExp("^#("+R+")"),CLASS:new RegExp("^\\.("+R+")"),TAG:new RegExp("^("+R+"|[*])"),ATTR:new RegExp("^"+I),PSEUDO:new RegExp("^"+W),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+M+"*(even|odd|(([+-]|)(\\d*)n|)"+M+"*(?:([+-]|)"+M+"*(\\d+)|))"+M+"*\\)|)","i"),bool:new RegExp("^(?:"+P+")$","i"),needsContext:new RegExp("^"+M+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+M+"*((?:-\\d)?\\d*)"+M+"*\\)|)(?=[^-]|$)","i")},G=/^(?:input|select|textarea|button)$/i,Y=/^h\d$/i,Q=/^[^{]+\{\s*\[native \w/,J=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,K=/[+~]/,Z=new RegExp("\\\\([\\da-f]{1,6}"+M+"?|("+M+")|.)","ig"),ee=function(e,t,n){var r="0x"+t-65536;return r!==r||n?t:r<0?String.fromCharCode(r+65536):String.fromCharCode(r>>10|55296,1023&r|56320)},te=/([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g,ne=function(e,t){return t?"\0"===e?"\ufffd":e.slice(0,-1)+"\\"+e.charCodeAt(e.length-1).toString(16)+" ":"\\"+e},re=function(){p()},ie=me(function(e){return!0===e.disabled&&("form"in e||"label"in e)},{dir:"parentNode",next:"legend"});try{L.apply(A=H.call(w.childNodes),w.childNodes),A[w.childNodes.length].nodeType}catch(e){L={apply:A.length?function(e,t){q.apply(e,H.call(t))}:function(e,t){var n=e.length,r=0;while(e[n++]=t[r++]);e.length=n-1}}}function oe(e,t,r,i){var o,s,l,c,f,h,v,m=t&&t.ownerDocument,T=t?t.nodeType:9;if(r=r||[],"string"!=typeof e||!e||1!==T&&9!==T&&11!==T)return r;if(!i&&((t?t.ownerDocument||t:w)!==d&&p(t),t=t||d,g)){if(11!==T&&(f=J.exec(e)))if(o=f[1]){if(9===T){if(!(l=t.getElementById(o)))return r;if(l.id===o)return r.push(l),r}else if(m&&(l=m.getElementById(o))&&x(t,l)&&l.id===o)return r.push(l),r}else{if(f[2])return L.apply(r,t.getElementsByTagName(e)),r;if((o=f[3])&&n.getElementsByClassName&&t.getElementsByClassName)return L.apply(r,t.getElementsByClassName(o)),r}if(n.qsa&&!S[e+" "]&&(!y||!y.test(e))){if(1!==T)m=t,v=e;else if("object"!==t.nodeName.toLowerCase()){(c=t.getAttribute("id"))?c=c.replace(te,ne):t.setAttribute("id",c=b),s=(h=a(e)).length;while(s--)h[s]="#"+c+" "+ve(h[s]);v=h.join(","),m=K.test(e)&&ge(t.parentNode)||t}if(v)try{return L.apply(r,m.querySelectorAll(v)),r}catch(e){}finally{c===b&&t.removeAttribute("id")}}}return u(e.replace(B,"$1"),t,r,i)}function ae(){var e=[];function t(n,i){return e.push(n+" ")>r.cacheLength&&delete t[e.shift()],t[n+" "]=i}return t}function se(e){return e[b]=!0,e}function ue(e){var t=d.createElement("fieldset");try{return!!e(t)}catch(e){return!1}finally{t.parentNode&&t.parentNode.removeChild(t),t=null}}function le(e,t){var n=e.split("|"),i=n.length;while(i--)r.attrHandle[n[i]]=t}function ce(e,t){var n=t&&e,r=n&&1===e.nodeType&&1===t.nodeType&&e.sourceIndex-t.sourceIndex;if(r)return r;if(n)while(n=n.nextSibling)if(n===t)return-1;return e?1:-1}function fe(e){return function(t){return"input"===t.nodeName.toLowerCase()&&t.type===e}}function pe(e){return function(t){var n=t.nodeName.toLowerCase();return("input"===n||"button"===n)&&t.type===e}}function de(e){return function(t){return"form"in t?t.parentNode&&!1===t.disabled?"label"in t?"label"in t.parentNode?t.parentNode.disabled===e:t.disabled===e:t.isDisabled===e||t.isDisabled!==!e&&ie(t)===e:t.disabled===e:"label"in t&&t.disabled===e}}function he(e){return se(function(t){return t=+t,se(function(n,r){var i,o=e([],n.length,t),a=o.length;while(a--)n[i=o[a]]&&(n[i]=!(r[i]=n[i]))})})}function ge(e){return e&&"undefined"!=typeof e.getElementsByTagName&&e}n=oe.support={},o=oe.isXML=function(e){var t=e&&(e.ownerDocument||e).documentElement;return!!t&&"HTML"!==t.nodeName},p=oe.setDocument=function(e){var t,i,a=e?e.ownerDocument||e:w;return a!==d&&9===a.nodeType&&a.documentElement?(d=a,h=d.documentElement,g=!o(d),w!==d&&(i=d.defaultView)&&i.top!==i&&(i.addEventListener?i.addEventListener("unload",re,!1):i.attachEvent&&i.attachEvent("onunload",re)),n.attributes=ue(function(e){return e.className="i",!e.getAttribute("className")}),n.getElementsByTagName=ue(function(e){return e.appendChild(d.createComment("")),!e.getElementsByTagName("*").length}),n.getElementsByClassName=Q.test(d.getElementsByClassName),n.getById=ue(function(e){return h.appendChild(e).id=b,!d.getElementsByName||!d.getElementsByName(b).length}),n.getById?(r.filter.ID=function(e){var t=e.replace(Z,ee);return function(e){return e.getAttribute("id")===t}},r.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&g){var n=t.getElementById(e);return n?[n]:[]}}):(r.filter.ID=function(e){var t=e.replace(Z,ee);return function(e){var n="undefined"!=typeof e.getAttributeNode&&e.getAttributeNode("id");return n&&n.value===t}},r.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&g){var n,r,i,o=t.getElementById(e);if(o){if((n=o.getAttributeNode("id"))&&n.value===e)return[o];i=t.getElementsByName(e),r=0;while(o=i[r++])if((n=o.getAttributeNode("id"))&&n.value===e)return[o]}return[]}}),r.find.TAG=n.getElementsByTagName?function(e,t){return"undefined"!=typeof t.getElementsByTagName?t.getElementsByTagName(e):n.qsa?t.querySelectorAll(e):void 0}:function(e,t){var n,r=[],i=0,o=t.getElementsByTagName(e);if("*"===e){while(n=o[i++])1===n.nodeType&&r.push(n);return r}return o},r.find.CLASS=n.getElementsByClassName&&function(e,t){if("undefined"!=typeof t.getElementsByClassName&&g)return t.getElementsByClassName(e)},v=[],y=[],(n.qsa=Q.test(d.querySelectorAll))&&(ue(function(e){h.appendChild(e).innerHTML="<a id='"+b+"'></a><select id='"+b+"-\r\\' msallowcapture=''><option selected=''></option></select>",e.querySelectorAll("[msallowcapture^='']").length&&y.push("[*^$]="+M+"*(?:''|\"\")"),e.querySelectorAll("[selected]").length||y.push("\\["+M+"*(?:value|"+P+")"),e.querySelectorAll("[id~="+b+"-]").length||y.push("~="),e.querySelectorAll(":checked").length||y.push(":checked"),e.querySelectorAll("a#"+b+"+*").length||y.push(".#.+[+~]")}),ue(function(e){e.innerHTML="<a href='' disabled='disabled'></a><select disabled='disabled'><option/></select>";var t=d.createElement("input");t.setAttribute("type","hidden"),e.appendChild(t).setAttribute("name","D"),e.querySelectorAll("[name=d]").length&&y.push("name"+M+"*[*^$|!~]?="),2!==e.querySelectorAll(":enabled").length&&y.push(":enabled",":disabled"),h.appendChild(e).disabled=!0,2!==e.querySelectorAll(":disabled").length&&y.push(":enabled",":disabled"),e.querySelectorAll("*,:x"),y.push(",.*:")})),(n.matchesSelector=Q.test(m=h.matches||h.webkitMatchesSelector||h.mozMatchesSelector||h.oMatchesSelector||h.msMatchesSelector))&&ue(function(e){n.disconnectedMatch=m.call(e,"*"),m.call(e,"[s!='']:x"),v.push("!=",W)}),y=y.length&&new RegExp(y.join("|")),v=v.length&&new RegExp(v.join("|")),t=Q.test(h.compareDocumentPosition),x=t||Q.test(h.contains)?function(e,t){var n=9===e.nodeType?e.documentElement:e,r=t&&t.parentNode;return e===r||!(!r||1!==r.nodeType||!(n.contains?n.contains(r):e.compareDocumentPosition&&16&e.compareDocumentPosition(r)))}:function(e,t){if(t)while(t=t.parentNode)if(t===e)return!0;return!1},D=t?function(e,t){if(e===t)return f=!0,0;var r=!e.compareDocumentPosition-!t.compareDocumentPosition;return r||(1&(r=(e.ownerDocument||e)===(t.ownerDocument||t)?e.compareDocumentPosition(t):1)||!n.sortDetached&&t.compareDocumentPosition(e)===r?e===d||e.ownerDocument===w&&x(w,e)?-1:t===d||t.ownerDocument===w&&x(w,t)?1:c?O(c,e)-O(c,t):0:4&r?-1:1)}:function(e,t){if(e===t)return f=!0,0;var n,r=0,i=e.parentNode,o=t.parentNode,a=[e],s=[t];if(!i||!o)return e===d?-1:t===d?1:i?-1:o?1:c?O(c,e)-O(c,t):0;if(i===o)return ce(e,t);n=e;while(n=n.parentNode)a.unshift(n);n=t;while(n=n.parentNode)s.unshift(n);while(a[r]===s[r])r++;return r?ce(a[r],s[r]):a[r]===w?-1:s[r]===w?1:0},d):d},oe.matches=function(e,t){return oe(e,null,null,t)},oe.matchesSelector=function(e,t){if((e.ownerDocument||e)!==d&&p(e),t=t.replace(z,"='$1']"),n.matchesSelector&&g&&!S[t+" "]&&(!v||!v.test(t))&&(!y||!y.test(t)))try{var r=m.call(e,t);if(r||n.disconnectedMatch||e.document&&11!==e.document.nodeType)return r}catch(e){}return oe(t,d,null,[e]).length>0},oe.contains=function(e,t){return(e.ownerDocument||e)!==d&&p(e),x(e,t)},oe.attr=function(e,t){(e.ownerDocument||e)!==d&&p(e);var i=r.attrHandle[t.toLowerCase()],o=i&&N.call(r.attrHandle,t.toLowerCase())?i(e,t,!g):void 0;return void 0!==o?o:n.attributes||!g?e.getAttribute(t):(o=e.getAttributeNode(t))&&o.specified?o.value:null},oe.escape=function(e){return(e+"").replace(te,ne)},oe.error=function(e){throw new Error("Syntax error, unrecognized expression: "+e)},oe.uniqueSort=function(e){var t,r=[],i=0,o=0;if(f=!n.detectDuplicates,c=!n.sortStable&&e.slice(0),e.sort(D),f){while(t=e[o++])t===e[o]&&(i=r.push(o));while(i--)e.splice(r[i],1)}return c=null,e},i=oe.getText=function(e){var t,n="",r=0,o=e.nodeType;if(o){if(1===o||9===o||11===o){if("string"==typeof e.textContent)return e.textContent;for(e=e.firstChild;e;e=e.nextSibling)n+=i(e)}else if(3===o||4===o)return e.nodeValue}else while(t=e[r++])n+=i(t);return n},(r=oe.selectors={cacheLength:50,createPseudo:se,match:V,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(Z,ee),e[3]=(e[3]||e[4]||e[5]||"").replace(Z,ee),"~="===e[2]&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),"nth"===e[1].slice(0,3)?(e[3]||oe.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*("even"===e[3]||"odd"===e[3])),e[5]=+(e[7]+e[8]||"odd"===e[3])):e[3]&&oe.error(e[0]),e},PSEUDO:function(e){var t,n=!e[6]&&e[2];return V.CHILD.test(e[0])?null:(e[3]?e[2]=e[4]||e[5]||"":n&&X.test(n)&&(t=a(n,!0))&&(t=n.indexOf(")",n.length-t)-n.length)&&(e[0]=e[0].slice(0,t),e[2]=n.slice(0,t)),e.slice(0,3))}},filter:{TAG:function(e){var t=e.replace(Z,ee).toLowerCase();return"*"===e?function(){return!0}:function(e){return e.nodeName&&e.nodeName.toLowerCase()===t}},CLASS:function(e){var t=E[e+" "];return t||(t=new RegExp("(^|"+M+")"+e+"("+M+"|$)"))&&E(e,function(e){return t.test("string"==typeof e.className&&e.className||"undefined"!=typeof e.getAttribute&&e.getAttribute("class")||"")})},ATTR:function(e,t,n){return function(r){var i=oe.attr(r,e);return null==i?"!="===t:!t||(i+="","="===t?i===n:"!="===t?i!==n:"^="===t?n&&0===i.indexOf(n):"*="===t?n&&i.indexOf(n)>-1:"$="===t?n&&i.slice(-n.length)===n:"~="===t?(" "+i.replace($," ")+" ").indexOf(n)>-1:"|="===t&&(i===n||i.slice(0,n.length+1)===n+"-"))}},CHILD:function(e,t,n,r,i){var o="nth"!==e.slice(0,3),a="last"!==e.slice(-4),s="of-type"===t;return 1===r&&0===i?function(e){return!!e.parentNode}:function(t,n,u){var l,c,f,p,d,h,g=o!==a?"nextSibling":"previousSibling",y=t.parentNode,v=s&&t.nodeName.toLowerCase(),m=!u&&!s,x=!1;if(y){if(o){while(g){p=t;while(p=p[g])if(s?p.nodeName.toLowerCase()===v:1===p.nodeType)return!1;h=g="only"===e&&!h&&"nextSibling"}return!0}if(h=[a?y.firstChild:y.lastChild],a&&m){x=(d=(l=(c=(f=(p=y)[b]||(p[b]={}))[p.uniqueID]||(f[p.uniqueID]={}))[e]||[])[0]===T&&l[1])&&l[2],p=d&&y.childNodes[d];while(p=++d&&p&&p[g]||(x=d=0)||h.pop())if(1===p.nodeType&&++x&&p===t){c[e]=[T,d,x];break}}else if(m&&(x=d=(l=(c=(f=(p=t)[b]||(p[b]={}))[p.uniqueID]||(f[p.uniqueID]={}))[e]||[])[0]===T&&l[1]),!1===x)while(p=++d&&p&&p[g]||(x=d=0)||h.pop())if((s?p.nodeName.toLowerCase()===v:1===p.nodeType)&&++x&&(m&&((c=(f=p[b]||(p[b]={}))[p.uniqueID]||(f[p.uniqueID]={}))[e]=[T,x]),p===t))break;return(x-=i)===r||x%r==0&&x/r>=0}}},PSEUDO:function(e,t){var n,i=r.pseudos[e]||r.setFilters[e.toLowerCase()]||oe.error("unsupported pseudo: "+e);return i[b]?i(t):i.length>1?(n=[e,e,"",t],r.setFilters.hasOwnProperty(e.toLowerCase())?se(function(e,n){var r,o=i(e,t),a=o.length;while(a--)e[r=O(e,o[a])]=!(n[r]=o[a])}):function(e){return i(e,0,n)}):i}},pseudos:{not:se(function(e){var t=[],n=[],r=s(e.replace(B,"$1"));return r[b]?se(function(e,t,n,i){var o,a=r(e,null,i,[]),s=e.length;while(s--)(o=a[s])&&(e[s]=!(t[s]=o))}):function(e,i,o){return t[0]=e,r(t,null,o,n),t[0]=null,!n.pop()}}),has:se(function(e){return function(t){return oe(e,t).length>0}}),contains:se(function(e){return e=e.replace(Z,ee),function(t){return(t.textContent||t.innerText||i(t)).indexOf(e)>-1}}),lang:se(function(e){return U.test(e||"")||oe.error("unsupported lang: "+e),e=e.replace(Z,ee).toLowerCase(),function(t){var n;do{if(n=g?t.lang:t.getAttribute("xml:lang")||t.getAttribute("lang"))return(n=n.toLowerCase())===e||0===n.indexOf(e+"-")}while((t=t.parentNode)&&1===t.nodeType);return!1}}),target:function(t){var n=e.location&&e.location.hash;return n&&n.slice(1)===t.id},root:function(e){return e===h},focus:function(e){return e===d.activeElement&&(!d.hasFocus||d.hasFocus())&&!!(e.type||e.href||~e.tabIndex)},enabled:de(!1),disabled:de(!0),checked:function(e){var t=e.nodeName.toLowerCase();return"input"===t&&!!e.checked||"option"===t&&!!e.selected},selected:function(e){return e.parentNode&&e.parentNode.selectedIndex,!0===e.selected},empty:function(e){for(e=e.firstChild;e;e=e.nextSibling)if(e.nodeType<6)return!1;return!0},parent:function(e){return!r.pseudos.empty(e)},header:function(e){return Y.test(e.nodeName)},input:function(e){return G.test(e.nodeName)},button:function(e){var t=e.nodeName.toLowerCase();return"input"===t&&"button"===e.type||"button"===t},text:function(e){var t;return"input"===e.nodeName.toLowerCase()&&"text"===e.type&&(null==(t=e.getAttribute("type"))||"text"===t.toLowerCase())},first:he(function(){return[0]}),last:he(function(e,t){return[t-1]}),eq:he(function(e,t,n){return[n<0?n+t:n]}),even:he(function(e,t){for(var n=0;n<t;n+=2)e.push(n);return e}),odd:he(function(e,t){for(var n=1;n<t;n+=2)e.push(n);return e}),lt:he(function(e,t,n){for(var r=n<0?n+t:n;--r>=0;)e.push(r);return e}),gt:he(function(e,t,n){for(var r=n<0?n+t:n;++r<t;)e.push(r);return e})}}).pseudos.nth=r.pseudos.eq;for(t in{radio:!0,checkbox:!0,file:!0,password:!0,image:!0})r.pseudos[t]=fe(t);for(t in{submit:!0,reset:!0})r.pseudos[t]=pe(t);function ye(){}ye.prototype=r.filters=r.pseudos,r.setFilters=new ye,a=oe.tokenize=function(e,t){var n,i,o,a,s,u,l,c=k[e+" "];if(c)return t?0:c.slice(0);s=e,u=[],l=r.preFilter;while(s){n&&!(i=F.exec(s))||(i&&(s=s.slice(i[0].length)||s),u.push(o=[])),n=!1,(i=_.exec(s))&&(n=i.shift(),o.push({value:n,type:i[0].replace(B," ")}),s=s.slice(n.length));for(a in r.filter)!(i=V[a].exec(s))||l[a]&&!(i=l[a](i))||(n=i.shift(),o.push({value:n,type:a,matches:i}),s=s.slice(n.length));if(!n)break}return t?s.length:s?oe.error(e):k(e,u).slice(0)};function ve(e){for(var t=0,n=e.length,r="";t<n;t++)r+=e[t].value;return r}function me(e,t,n){var r=t.dir,i=t.next,o=i||r,a=n&&"parentNode"===o,s=C++;return t.first?function(t,n,i){while(t=t[r])if(1===t.nodeType||a)return e(t,n,i);return!1}:function(t,n,u){var l,c,f,p=[T,s];if(u){while(t=t[r])if((1===t.nodeType||a)&&e(t,n,u))return!0}else while(t=t[r])if(1===t.nodeType||a)if(f=t[b]||(t[b]={}),c=f[t.uniqueID]||(f[t.uniqueID]={}),i&&i===t.nodeName.toLowerCase())t=t[r]||t;else{if((l=c[o])&&l[0]===T&&l[1]===s)return p[2]=l[2];if(c[o]=p,p[2]=e(t,n,u))return!0}return!1}}function xe(e){return e.length>1?function(t,n,r){var i=e.length;while(i--)if(!e[i](t,n,r))return!1;return!0}:e[0]}function be(e,t,n){for(var r=0,i=t.length;r<i;r++)oe(e,t[r],n);return n}function we(e,t,n,r,i){for(var o,a=[],s=0,u=e.length,l=null!=t;s<u;s++)(o=e[s])&&(n&&!n(o,r,i)||(a.push(o),l&&t.push(s)));return a}function Te(e,t,n,r,i,o){return r&&!r[b]&&(r=Te(r)),i&&!i[b]&&(i=Te(i,o)),se(function(o,a,s,u){var l,c,f,p=[],d=[],h=a.length,g=o||be(t||"*",s.nodeType?[s]:s,[]),y=!e||!o&&t?g:we(g,p,e,s,u),v=n?i||(o?e:h||r)?[]:a:y;if(n&&n(y,v,s,u),r){l=we(v,d),r(l,[],s,u),c=l.length;while(c--)(f=l[c])&&(v[d[c]]=!(y[d[c]]=f))}if(o){if(i||e){if(i){l=[],c=v.length;while(c--)(f=v[c])&&l.push(y[c]=f);i(null,v=[],l,u)}c=v.length;while(c--)(f=v[c])&&(l=i?O(o,f):p[c])>-1&&(o[l]=!(a[l]=f))}}else v=we(v===a?v.splice(h,v.length):v),i?i(null,a,v,u):L.apply(a,v)})}function Ce(e){for(var t,n,i,o=e.length,a=r.relative[e[0].type],s=a||r.relative[" "],u=a?1:0,c=me(function(e){return e===t},s,!0),f=me(function(e){return O(t,e)>-1},s,!0),p=[function(e,n,r){var i=!a&&(r||n!==l)||((t=n).nodeType?c(e,n,r):f(e,n,r));return t=null,i}];u<o;u++)if(n=r.relative[e[u].type])p=[me(xe(p),n)];else{if((n=r.filter[e[u].type].apply(null,e[u].matches))[b]){for(i=++u;i<o;i++)if(r.relative[e[i].type])break;return Te(u>1&&xe(p),u>1&&ve(e.slice(0,u-1).concat({value:" "===e[u-2].type?"*":""})).replace(B,"$1"),n,u<i&&Ce(e.slice(u,i)),i<o&&Ce(e=e.slice(i)),i<o&&ve(e))}p.push(n)}return xe(p)}function Ee(e,t){var n=t.length>0,i=e.length>0,o=function(o,a,s,u,c){var f,h,y,v=0,m="0",x=o&&[],b=[],w=l,C=o||i&&r.find.TAG("*",c),E=T+=null==w?1:Math.random()||.1,k=C.length;for(c&&(l=a===d||a||c);m!==k&&null!=(f=C[m]);m++){if(i&&f){h=0,a||f.ownerDocument===d||(p(f),s=!g);while(y=e[h++])if(y(f,a||d,s)){u.push(f);break}c&&(T=E)}n&&((f=!y&&f)&&v--,o&&x.push(f))}if(v+=m,n&&m!==v){h=0;while(y=t[h++])y(x,b,a,s);if(o){if(v>0)while(m--)x[m]||b[m]||(b[m]=j.call(u));b=we(b)}L.apply(u,b),c&&!o&&b.length>0&&v+t.length>1&&oe.uniqueSort(u)}return c&&(T=E,l=w),x};return n?se(o):o}return s=oe.compile=function(e,t){var n,r=[],i=[],o=S[e+" "];if(!o){t||(t=a(e)),n=t.length;while(n--)(o=Ce(t[n]))[b]?r.push(o):i.push(o);(o=S(e,Ee(i,r))).selector=e}return o},u=oe.select=function(e,t,n,i){var o,u,l,c,f,p="function"==typeof e&&e,d=!i&&a(e=p.selector||e);if(n=n||[],1===d.length){if((u=d[0]=d[0].slice(0)).length>2&&"ID"===(l=u[0]).type&&9===t.nodeType&&g&&r.relative[u[1].type]){if(!(t=(r.find.ID(l.matches[0].replace(Z,ee),t)||[])[0]))return n;p&&(t=t.parentNode),e=e.slice(u.shift().value.length)}o=V.needsContext.test(e)?0:u.length;while(o--){if(l=u[o],r.relative[c=l.type])break;if((f=r.find[c])&&(i=f(l.matches[0].replace(Z,ee),K.test(u[0].type)&&ge(t.parentNode)||t))){if(u.splice(o,1),!(e=i.length&&ve(u)))return L.apply(n,i),n;break}}}return(p||s(e,d))(i,t,!g,n,!t||K.test(e)&&ge(t.parentNode)||t),n},n.sortStable=b.split("").sort(D).join("")===b,n.detectDuplicates=!!f,p(),n.sortDetached=ue(function(e){return 1&e.compareDocumentPosition(d.createElement("fieldset"))}),ue(function(e){return e.innerHTML="<a href='#'></a>","#"===e.firstChild.getAttribute("href")})||le("type|href|height|width",function(e,t,n){if(!n)return e.getAttribute(t,"type"===t.toLowerCase()?1:2)}),n.attributes&&ue(function(e){return e.innerHTML="<input/>",e.firstChild.setAttribute("value",""),""===e.firstChild.getAttribute("value")})||le("value",function(e,t,n){if(!n&&"input"===e.nodeName.toLowerCase())return e.defaultValue}),ue(function(e){return null==e.getAttribute("disabled")})||le(P,function(e,t,n){var r;if(!n)return!0===e[t]?t.toLowerCase():(r=e.getAttributeNode(t))&&r.specified?r.value:null}),oe}(e);w.find=E,w.expr=E.selectors,w.expr[":"]=w.expr.pseudos,w.uniqueSort=w.unique=E.uniqueSort,w.text=E.getText,w.isXMLDoc=E.isXML,w.contains=E.contains,w.escapeSelector=E.escape;var k=function(e,t,n){var r=[],i=void 0!==n;while((e=e[t])&&9!==e.nodeType)if(1===e.nodeType){if(i&&w(e).is(n))break;r.push(e)}return r},S=function(e,t){for(var n=[];e;e=e.nextSibling)1===e.nodeType&&e!==t&&n.push(e);return n},D=w.expr.match.needsContext;function N(e,t){return e.nodeName&&e.nodeName.toLowerCase()===t.toLowerCase()}var A=/^<([a-z][^\/\0>:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i;function j(e,t,n){return g(t)?w.grep(e,function(e,r){return!!t.call(e,r,e)!==n}):t.nodeType?w.grep(e,function(e){return e===t!==n}):"string"!=typeof t?w.grep(e,function(e){return u.call(t,e)>-1!==n}):w.filter(t,e,n)}w.filter=function(e,t,n){var r=t[0];return n&&(e=":not("+e+")"),1===t.length&&1===r.nodeType?w.find.matchesSelector(r,e)?[r]:[]:w.find.matches(e,w.grep(t,function(e){return 1===e.nodeType}))},w.fn.extend({find:function(e){var t,n,r=this.length,i=this;if("string"!=typeof e)return this.pushStack(w(e).filter(function(){for(t=0;t<r;t++)if(w.contains(i[t],this))return!0}));for(n=this.pushStack([]),t=0;t<r;t++)w.find(e,i[t],n);return r>1?w.uniqueSort(n):n},filter:function(e){return this.pushStack(j(this,e||[],!1))},not:function(e){return this.pushStack(j(this,e||[],!0))},is:function(e){return!!j(this,"string"==typeof e&&D.test(e)?w(e):e||[],!1).length}});var q,L=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]+))$/;(w.fn.init=function(e,t,n){var i,o;if(!e)return this;if(n=n||q,"string"==typeof e){if(!(i="<"===e[0]&&">"===e[e.length-1]&&e.length>=3?[null,e,null]:L.exec(e))||!i[1]&&t)return!t||t.jquery?(t||n).find(e):this.constructor(t).find(e);if(i[1]){if(t=t instanceof w?t[0]:t,w.merge(this,w.parseHTML(i[1],t&&t.nodeType?t.ownerDocument||t:r,!0)),A.test(i[1])&&w.isPlainObject(t))for(i in t)g(this[i])?this[i](t[i]):this.attr(i,t[i]);return this}return(o=r.getElementById(i[2]))&&(this[0]=o,this.length=1),this}return e.nodeType?(this[0]=e,this.length=1,this):g(e)?void 0!==n.ready?n.ready(e):e(w):w.makeArray(e,this)}).prototype=w.fn,q=w(r);var H=/^(?:parents|prev(?:Until|All))/,O={children:!0,contents:!0,next:!0,prev:!0};w.fn.extend({has:function(e){var t=w(e,this),n=t.length;return this.filter(function(){for(var e=0;e<n;e++)if(w.contains(this,t[e]))return!0})},closest:function(e,t){var n,r=0,i=this.length,o=[],a="string"!=typeof e&&w(e);if(!D.test(e))for(;r<i;r++)for(n=this[r];n&&n!==t;n=n.parentNode)if(n.nodeType<11&&(a?a.index(n)>-1:1===n.nodeType&&w.find.matchesSelector(n,e))){o.push(n);break}return this.pushStack(o.length>1?w.uniqueSort(o):o)},index:function(e){return e?"string"==typeof e?u.call(w(e),this[0]):u.call(this,e.jquery?e[0]:e):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(e,t){return this.pushStack(w.uniqueSort(w.merge(this.get(),w(e,t))))},addBack:function(e){return this.add(null==e?this.prevObject:this.prevObject.filter(e))}});function P(e,t){while((e=e[t])&&1!==e.nodeType);return e}w.each({parent:function(e){var t=e.parentNode;return t&&11!==t.nodeType?t:null},parents:function(e){return k(e,"parentNode")},parentsUntil:function(e,t,n){return k(e,"parentNode",n)},next:function(e){return P(e,"nextSibling")},prev:function(e){return P(e,"previousSibling")},nextAll:function(e){return k(e,"nextSibling")},prevAll:function(e){return k(e,"previousSibling")},nextUntil:function(e,t,n){return k(e,"nextSibling",n)},prevUntil:function(e,t,n){return k(e,"previousSibling",n)},siblings:function(e){return S((e.parentNode||{}).firstChild,e)},children:function(e){return S(e.firstChild)},contents:function(e){return N(e,"iframe")?e.contentDocument:(N(e,"template")&&(e=e.content||e),w.merge([],e.childNodes))}},function(e,t){w.fn[e]=function(n,r){var i=w.map(this,t,n);return"Until"!==e.slice(-5)&&(r=n),r&&"string"==typeof r&&(i=w.filter(r,i)),this.length>1&&(O[e]||w.uniqueSort(i),H.test(e)&&i.reverse()),this.pushStack(i)}});var M=/[^\x20\t\r\n\f]+/g;function R(e){var t={};return w.each(e.match(M)||[],function(e,n){t[n]=!0}),t}w.Callbacks=function(e){e="string"==typeof e?R(e):w.extend({},e);var t,n,r,i,o=[],a=[],s=-1,u=function(){for(i=i||e.once,r=t=!0;a.length;s=-1){n=a.shift();while(++s<o.length)!1===o[s].apply(n[0],n[1])&&e.stopOnFalse&&(s=o.length,n=!1)}e.memory||(n=!1),t=!1,i&&(o=n?[]:"")},l={add:function(){return o&&(n&&!t&&(s=o.length-1,a.push(n)),function t(n){w.each(n,function(n,r){g(r)?e.unique&&l.has(r)||o.push(r):r&&r.length&&"string"!==x(r)&&t(r)})}(arguments),n&&!t&&u()),this},remove:function(){return w.each(arguments,function(e,t){var n;while((n=w.inArray(t,o,n))>-1)o.splice(n,1),n<=s&&s--}),this},has:function(e){return e?w.inArray(e,o)>-1:o.length>0},empty:function(){return o&&(o=[]),this},disable:function(){return i=a=[],o=n="",this},disabled:function(){return!o},lock:function(){return i=a=[],n||t||(o=n=""),this},locked:function(){return!!i},fireWith:function(e,n){return i||(n=[e,(n=n||[]).slice?n.slice():n],a.push(n),t||u()),this},fire:function(){return l.fireWith(this,arguments),this},fired:function(){return!!r}};return l};function I(e){return e}function W(e){throw e}function $(e,t,n,r){var i;try{e&&g(i=e.promise)?i.call(e).done(t).fail(n):e&&g(i=e.then)?i.call(e,t,n):t.apply(void 0,[e].slice(r))}catch(e){n.apply(void 0,[e])}}w.extend({Deferred:function(t){var n=[["notify","progress",w.Callbacks("memory"),w.Callbacks("memory"),2],["resolve","done",w.Callbacks("once memory"),w.Callbacks("once memory"),0,"resolved"],["reject","fail",w.Callbacks("once memory"),w.Callbacks("once memory"),1,"rejected"]],r="pending",i={state:function(){return r},always:function(){return o.done(arguments).fail(arguments),this},"catch":function(e){return i.then(null,e)},pipe:function(){var e=arguments;return w.Deferred(function(t){w.each(n,function(n,r){var i=g(e[r[4]])&&e[r[4]];o[r[1]](function(){var e=i&&i.apply(this,arguments);e&&g(e.promise)?e.promise().progress(t.notify).done(t.resolve).fail(t.reject):t[r[0]+"With"](this,i?[e]:arguments)})}),e=null}).promise()},then:function(t,r,i){var o=0;function a(t,n,r,i){return function(){var s=this,u=arguments,l=function(){var e,l;if(!(t<o)){if((e=r.apply(s,u))===n.promise())throw new TypeError("Thenable self-resolution");l=e&&("object"==typeof e||"function"==typeof e)&&e.then,g(l)?i?l.call(e,a(o,n,I,i),a(o,n,W,i)):(o++,l.call(e,a(o,n,I,i),a(o,n,W,i),a(o,n,I,n.notifyWith))):(r!==I&&(s=void 0,u=[e]),(i||n.resolveWith)(s,u))}},c=i?l:function(){try{l()}catch(e){w.Deferred.exceptionHook&&w.Deferred.exceptionHook(e,c.stackTrace),t+1>=o&&(r!==W&&(s=void 0,u=[e]),n.rejectWith(s,u))}};t?c():(w.Deferred.getStackHook&&(c.stackTrace=w.Deferred.getStackHook()),e.setTimeout(c))}}return w.Deferred(function(e){n[0][3].add(a(0,e,g(i)?i:I,e.notifyWith)),n[1][3].add(a(0,e,g(t)?t:I)),n[2][3].add(a(0,e,g(r)?r:W))}).promise()},promise:function(e){return null!=e?w.extend(e,i):i}},o={};return w.each(n,function(e,t){var a=t[2],s=t[5];i[t[1]]=a.add,s&&a.add(function(){r=s},n[3-e][2].disable,n[3-e][3].disable,n[0][2].lock,n[0][3].lock),a.add(t[3].fire),o[t[0]]=function(){return o[t[0]+"With"](this===o?void 0:this,arguments),this},o[t[0]+"With"]=a.fireWith}),i.promise(o),t&&t.call(o,o),o},when:function(e){var t=arguments.length,n=t,r=Array(n),i=o.call(arguments),a=w.Deferred(),s=function(e){return function(n){r[e]=this,i[e]=arguments.length>1?o.call(arguments):n,--t||a.resolveWith(r,i)}};if(t<=1&&($(e,a.done(s(n)).resolve,a.reject,!t),"pending"===a.state()||g(i[n]&&i[n].then)))return a.then();while(n--)$(i[n],s(n),a.reject);return a.promise()}});var B=/^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error$/;w.Deferred.exceptionHook=function(t,n){e.console&&e.console.warn&&t&&B.test(t.name)&&e.console.warn("jQuery.Deferred exception: "+t.message,t.stack,n)},w.readyException=function(t){e.setTimeout(function(){throw t})};var F=w.Deferred();w.fn.ready=function(e){return F.then(e)["catch"](function(e){w.readyException(e)}),this},w.extend({isReady:!1,readyWait:1,ready:function(e){(!0===e?--w.readyWait:w.isReady)||(w.isReady=!0,!0!==e&&--w.readyWait>0||F.resolveWith(r,[w]))}}),w.ready.then=F.then;function _(){r.removeEventListener("DOMContentLoaded",_),e.removeEventListener("load",_),w.ready()}"complete"===r.readyState||"loading"!==r.readyState&&!r.documentElement.doScroll?e.setTimeout(w.ready):(r.addEventListener("DOMContentLoaded",_),e.addEventListener("load",_));var z=function(e,t,n,r,i,o,a){var s=0,u=e.length,l=null==n;if("object"===x(n)){i=!0;for(s in n)z(e,t,s,n[s],!0,o,a)}else if(void 0!==r&&(i=!0,g(r)||(a=!0),l&&(a?(t.call(e,r),t=null):(l=t,t=function(e,t,n){return l.call(w(e),n)})),t))for(;s<u;s++)t(e[s],n,a?r:r.call(e[s],s,t(e[s],n)));return i?e:l?t.call(e):u?t(e[0],n):o},X=/^-ms-/,U=/-([a-z])/g;function V(e,t){return t.toUpperCase()}function G(e){return e.replace(X,"ms-").replace(U,V)}var Y=function(e){return 1===e.nodeType||9===e.nodeType||!+e.nodeType};function Q(){this.expando=w.expando+Q.uid++}Q.uid=1,Q.prototype={cache:function(e){var t=e[this.expando];return t||(t={},Y(e)&&(e.nodeType?e[this.expando]=t:Object.defineProperty(e,this.expando,{value:t,configurable:!0}))),t},set:function(e,t,n){var r,i=this.cache(e);if("string"==typeof t)i[G(t)]=n;else for(r in t)i[G(r)]=t[r];return i},get:function(e,t){return void 0===t?this.cache(e):e[this.expando]&&e[this.expando][G(t)]},access:function(e,t,n){return void 0===t||t&&"string"==typeof t&&void 0===n?this.get(e,t):(this.set(e,t,n),void 0!==n?n:t)},remove:function(e,t){var n,r=e[this.expando];if(void 0!==r){if(void 0!==t){n=(t=Array.isArray(t)?t.map(G):(t=G(t))in r?[t]:t.match(M)||[]).length;while(n--)delete r[t[n]]}(void 0===t||w.isEmptyObject(r))&&(e.nodeType?e[this.expando]=void 0:delete e[this.expando])}},hasData:function(e){var t=e[this.expando];return void 0!==t&&!w.isEmptyObject(t)}};var J=new Q,K=new Q,Z=/^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,ee=/[A-Z]/g;function te(e){return"true"===e||"false"!==e&&("null"===e?null:e===+e+""?+e:Z.test(e)?JSON.parse(e):e)}function ne(e,t,n){var r;if(void 0===n&&1===e.nodeType)if(r="data-"+t.replace(ee,"-$&").toLowerCase(),"string"==typeof(n=e.getAttribute(r))){try{n=te(n)}catch(e){}K.set(e,t,n)}else n=void 0;return n}w.extend({hasData:function(e){return K.hasData(e)||J.hasData(e)},data:function(e,t,n){return K.access(e,t,n)},removeData:function(e,t){K.remove(e,t)},_data:function(e,t,n){return J.access(e,t,n)},_removeData:function(e,t){J.remove(e,t)}}),w.fn.extend({data:function(e,t){var n,r,i,o=this[0],a=o&&o.attributes;if(void 0===e){if(this.length&&(i=K.get(o),1===o.nodeType&&!J.get(o,"hasDataAttrs"))){n=a.length;while(n--)a[n]&&0===(r=a[n].name).indexOf("data-")&&(r=G(r.slice(5)),ne(o,r,i[r]));J.set(o,"hasDataAttrs",!0)}return i}return"object"==typeof e?this.each(function(){K.set(this,e)}):z(this,function(t){var n;if(o&&void 0===t){if(void 0!==(n=K.get(o,e)))return n;if(void 0!==(n=ne(o,e)))return n}else this.each(function(){K.set(this,e,t)})},null,t,arguments.length>1,null,!0)},removeData:function(e){return this.each(function(){K.remove(this,e)})}}),w.extend({queue:function(e,t,n){var r;if(e)return t=(t||"fx")+"queue",r=J.get(e,t),n&&(!r||Array.isArray(n)?r=J.access(e,t,w.makeArray(n)):r.push(n)),r||[]},dequeue:function(e,t){t=t||"fx";var n=w.queue(e,t),r=n.length,i=n.shift(),o=w._queueHooks(e,t),a=function(){w.dequeue(e,t)};"inprogress"===i&&(i=n.shift(),r--),i&&("fx"===t&&n.unshift("inprogress"),delete o.stop,i.call(e,a,o)),!r&&o&&o.empty.fire()},_queueHooks:function(e,t){var n=t+"queueHooks";return J.get(e,n)||J.access(e,n,{empty:w.Callbacks("once memory").add(function(){J.remove(e,[t+"queue",n])})})}}),w.fn.extend({queue:function(e,t){var n=2;return"string"!=typeof e&&(t=e,e="fx",n--),arguments.length<n?w.queue(this[0],e):void 0===t?this:this.each(function(){var n=w.queue(this,e,t);w._queueHooks(this,e),"fx"===e&&"inprogress"!==n[0]&&w.dequeue(this,e)})},dequeue:function(e){return this.each(function(){w.dequeue(this,e)})},clearQueue:function(e){return this.queue(e||"fx",[])},promise:function(e,t){var n,r=1,i=w.Deferred(),o=this,a=this.length,s=function(){--r||i.resolveWith(o,[o])};"string"!=typeof e&&(t=e,e=void 0),e=e||"fx";while(a--)(n=J.get(o[a],e+"queueHooks"))&&n.empty&&(r++,n.empty.add(s));return s(),i.promise(t)}});var re=/[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/.source,ie=new RegExp("^(?:([+-])=|)("+re+")([a-z%]*)$","i"),oe=["Top","Right","Bottom","Left"],ae=function(e,t){return"none"===(e=t||e).style.display||""===e.style.display&&w.contains(e.ownerDocument,e)&&"none"===w.css(e,"display")},se=function(e,t,n,r){var i,o,a={};for(o in t)a[o]=e.style[o],e.style[o]=t[o];i=n.apply(e,r||[]);for(o in t)e.style[o]=a[o];return i};function ue(e,t,n,r){var i,o,a=20,s=r?function(){return r.cur()}:function(){return w.css(e,t,"")},u=s(),l=n&&n[3]||(w.cssNumber[t]?"":"px"),c=(w.cssNumber[t]||"px"!==l&&+u)&&ie.exec(w.css(e,t));if(c&&c[3]!==l){u/=2,l=l||c[3],c=+u||1;while(a--)w.style(e,t,c+l),(1-o)*(1-(o=s()/u||.5))<=0&&(a=0),c/=o;c*=2,w.style(e,t,c+l),n=n||[]}return n&&(c=+c||+u||0,i=n[1]?c+(n[1]+1)*n[2]:+n[2],r&&(r.unit=l,r.start=c,r.end=i)),i}var le={};function ce(e){var t,n=e.ownerDocument,r=e.nodeName,i=le[r];return i||(t=n.body.appendChild(n.createElement(r)),i=w.css(t,"display"),t.parentNode.removeChild(t),"none"===i&&(i="block"),le[r]=i,i)}function fe(e,t){for(var n,r,i=[],o=0,a=e.length;o<a;o++)(r=e[o]).style&&(n=r.style.display,t?("none"===n&&(i[o]=J.get(r,"display")||null,i[o]||(r.style.display="")),""===r.style.display&&ae(r)&&(i[o]=ce(r))):"none"!==n&&(i[o]="none",J.set(r,"display",n)));for(o=0;o<a;o++)null!=i[o]&&(e[o].style.display=i[o]);return e}w.fn.extend({show:function(){return fe(this,!0)},hide:function(){return fe(this)},toggle:function(e){return"boolean"==typeof e?e?this.show():this.hide():this.each(function(){ae(this)?w(this).show():w(this).hide()})}});var pe=/^(?:checkbox|radio)$/i,de=/<([a-z][^\/\0>\x20\t\r\n\f]+)/i,he=/^$|^module$|\/(?:java|ecma)script/i,ge={option:[1,"<select multiple='multiple'>","</select>"],thead:[1,"<table>","</table>"],col:[2,"<table><colgroup>","</colgroup></table>"],tr:[2,"<table><tbody>","</tbody></table>"],td:[3,"<table><tbody><tr>","</tr></tbody></table>"],_default:[0,"",""]};ge.optgroup=ge.option,ge.tbody=ge.tfoot=ge.colgroup=ge.caption=ge.thead,ge.th=ge.td;function ye(e,t){var n;return n="undefined"!=typeof e.getElementsByTagName?e.getElementsByTagName(t||"*"):"undefined"!=typeof e.querySelectorAll?e.querySelectorAll(t||"*"):[],void 0===t||t&&N(e,t)?w.merge([e],n):n}function ve(e,t){for(var n=0,r=e.length;n<r;n++)J.set(e[n],"globalEval",!t||J.get(t[n],"globalEval"))}var me=/<|&#?\w+;/;function xe(e,t,n,r,i){for(var o,a,s,u,l,c,f=t.createDocumentFragment(),p=[],d=0,h=e.length;d<h;d++)if((o=e[d])||0===o)if("object"===x(o))w.merge(p,o.nodeType?[o]:o);else if(me.test(o)){a=a||f.appendChild(t.createElement("div")),s=(de.exec(o)||["",""])[1].toLowerCase(),u=ge[s]||ge._default,a.innerHTML=u[1]+w.htmlPrefilter(o)+u[2],c=u[0];while(c--)a=a.lastChild;w.merge(p,a.childNodes),(a=f.firstChild).textContent=""}else p.push(t.createTextNode(o));f.textContent="",d=0;while(o=p[d++])if(r&&w.inArray(o,r)>-1)i&&i.push(o);else if(l=w.contains(o.ownerDocument,o),a=ye(f.appendChild(o),"script"),l&&ve(a),n){c=0;while(o=a[c++])he.test(o.type||"")&&n.push(o)}return f}!function(){var e=r.createDocumentFragment().appendChild(r.createElement("div")),t=r.createElement("input");t.setAttribute("type","radio"),t.setAttribute("checked","checked"),t.setAttribute("name","t"),e.appendChild(t),h.checkClone=e.cloneNode(!0).cloneNode(!0).lastChild.checked,e.innerHTML="<textarea>x</textarea>",h.noCloneChecked=!!e.cloneNode(!0).lastChild.defaultValue}();var be=r.documentElement,we=/^key/,Te=/^(?:mouse|pointer|contextmenu|drag|drop)|click/,Ce=/^([^.]*)(?:\.(.+)|)/;function Ee(){return!0}function ke(){return!1}function Se(){try{return r.activeElement}catch(e){}}function De(e,t,n,r,i,o){var a,s;if("object"==typeof t){"string"!=typeof n&&(r=r||n,n=void 0);for(s in t)De(e,s,n,r,t[s],o);return e}if(null==r&&null==i?(i=n,r=n=void 0):null==i&&("string"==typeof n?(i=r,r=void 0):(i=r,r=n,n=void 0)),!1===i)i=ke;else if(!i)return e;return 1===o&&(a=i,(i=function(e){return w().off(e),a.apply(this,arguments)}).guid=a.guid||(a.guid=w.guid++)),e.each(function(){w.event.add(this,t,i,r,n)})}w.event={global:{},add:function(e,t,n,r,i){var o,a,s,u,l,c,f,p,d,h,g,y=J.get(e);if(y){n.handler&&(n=(o=n).handler,i=o.selector),i&&w.find.matchesSelector(be,i),n.guid||(n.guid=w.guid++),(u=y.events)||(u=y.events={}),(a=y.handle)||(a=y.handle=function(t){return"undefined"!=typeof w&&w.event.triggered!==t.type?w.event.dispatch.apply(e,arguments):void 0}),l=(t=(t||"").match(M)||[""]).length;while(l--)d=g=(s=Ce.exec(t[l])||[])[1],h=(s[2]||"").split(".").sort(),d&&(f=w.event.special[d]||{},d=(i?f.delegateType:f.bindType)||d,f=w.event.special[d]||{},c=w.extend({type:d,origType:g,data:r,handler:n,guid:n.guid,selector:i,needsContext:i&&w.expr.match.needsContext.test(i),namespace:h.join(".")},o),(p=u[d])||((p=u[d]=[]).delegateCount=0,f.setup&&!1!==f.setup.call(e,r,h,a)||e.addEventListener&&e.addEventListener(d,a)),f.add&&(f.add.call(e,c),c.handler.guid||(c.handler.guid=n.guid)),i?p.splice(p.delegateCount++,0,c):p.push(c),w.event.global[d]=!0)}},remove:function(e,t,n,r,i){var o,a,s,u,l,c,f,p,d,h,g,y=J.hasData(e)&&J.get(e);if(y&&(u=y.events)){l=(t=(t||"").match(M)||[""]).length;while(l--)if(s=Ce.exec(t[l])||[],d=g=s[1],h=(s[2]||"").split(".").sort(),d){f=w.event.special[d]||{},p=u[d=(r?f.delegateType:f.bindType)||d]||[],s=s[2]&&new RegExp("(^|\\.)"+h.join("\\.(?:.*\\.|)")+"(\\.|$)"),a=o=p.length;while(o--)c=p[o],!i&&g!==c.origType||n&&n.guid!==c.guid||s&&!s.test(c.namespace)||r&&r!==c.selector&&("**"!==r||!c.selector)||(p.splice(o,1),c.selector&&p.delegateCount--,f.remove&&f.remove.call(e,c));a&&!p.length&&(f.teardown&&!1!==f.teardown.call(e,h,y.handle)||w.removeEvent(e,d,y.handle),delete u[d])}else for(d in u)w.event.remove(e,d+t[l],n,r,!0);w.isEmptyObject(u)&&J.remove(e,"handle events")}},dispatch:function(e){var t=w.event.fix(e),n,r,i,o,a,s,u=new Array(arguments.length),l=(J.get(this,"events")||{})[t.type]||[],c=w.event.special[t.type]||{};for(u[0]=t,n=1;n<arguments.length;n++)u[n]=arguments[n];if(t.delegateTarget=this,!c.preDispatch||!1!==c.preDispatch.call(this,t)){s=w.event.handlers.call(this,t,l),n=0;while((o=s[n++])&&!t.isPropagationStopped()){t.currentTarget=o.elem,r=0;while((a=o.handlers[r++])&&!t.isImmediatePropagationStopped())t.rnamespace&&!t.rnamespace.test(a.namespace)||(t.handleObj=a,t.data=a.data,void 0!==(i=((w.event.special[a.origType]||{}).handle||a.handler).apply(o.elem,u))&&!1===(t.result=i)&&(t.preventDefault(),t.stopPropagation()))}return c.postDispatch&&c.postDispatch.call(this,t),t.result}},handlers:function(e,t){var n,r,i,o,a,s=[],u=t.delegateCount,l=e.target;if(u&&l.nodeType&&!("click"===e.type&&e.button>=1))for(;l!==this;l=l.parentNode||this)if(1===l.nodeType&&("click"!==e.type||!0!==l.disabled)){for(o=[],a={},n=0;n<u;n++)void 0===a[i=(r=t[n]).selector+" "]&&(a[i]=r.needsContext?w(i,this).index(l)>-1:w.find(i,this,null,[l]).length),a[i]&&o.push(r);o.length&&s.push({elem:l,handlers:o})}return l=this,u<t.length&&s.push({elem:l,handlers:t.slice(u)}),s},addProp:function(e,t){Object.defineProperty(w.Event.prototype,e,{enumerable:!0,configurable:!0,get:g(t)?function(){if(this.originalEvent)return t(this.originalEvent)}:function(){if(this.originalEvent)return this.originalEvent[e]},set:function(t){Object.defineProperty(this,e,{enumerable:!0,configurable:!0,writable:!0,value:t})}})},fix:function(e){return e[w.expando]?e:new w.Event(e)},special:{load:{noBubble:!0},focus:{trigger:function(){if(this!==Se()&&this.focus)return this.focus(),!1},delegateType:"focusin"},blur:{trigger:function(){if(this===Se()&&this.blur)return this.blur(),!1},delegateType:"focusout"},click:{trigger:function(){if("checkbox"===this.type&&this.click&&N(this,"input"))return this.click(),!1},_default:function(e){return N(e.target,"a")}},beforeunload:{postDispatch:function(e){void 0!==e.result&&e.originalEvent&&(e.originalEvent.returnValue=e.result)}}}},w.removeEvent=function(e,t,n){e.removeEventListener&&e.removeEventListener(t,n)},w.Event=function(e,t){if(!(this instanceof w.Event))return new w.Event(e,t);e&&e.type?(this.originalEvent=e,this.type=e.type,this.isDefaultPrevented=e.defaultPrevented||void 0===e.defaultPrevented&&!1===e.returnValue?Ee:ke,this.target=e.target&&3===e.target.nodeType?e.target.parentNode:e.target,this.currentTarget=e.currentTarget,this.relatedTarget=e.relatedTarget):this.type=e,t&&w.extend(this,t),this.timeStamp=e&&e.timeStamp||Date.now(),this[w.expando]=!0},w.Event.prototype={constructor:w.Event,isDefaultPrevented:ke,isPropagationStopped:ke,isImmediatePropagationStopped:ke,isSimulated:!1,preventDefault:function(){var e=this.originalEvent;this.isDefaultPrevented=Ee,e&&!this.isSimulated&&e.preventDefault()},stopPropagation:function(){var e=this.originalEvent;this.isPropagationStopped=Ee,e&&!this.isSimulated&&e.stopPropagation()},stopImmediatePropagation:function(){var e=this.originalEvent;this.isImmediatePropagationStopped=Ee,e&&!this.isSimulated&&e.stopImmediatePropagation(),this.stopPropagation()}},w.each({altKey:!0,bubbles:!0,cancelable:!0,changedTouches:!0,ctrlKey:!0,detail:!0,eventPhase:!0,metaKey:!0,pageX:!0,pageY:!0,shiftKey:!0,view:!0,"char":!0,charCode:!0,key:!0,keyCode:!0,button:!0,buttons:!0,clientX:!0,clientY:!0,offsetX:!0,offsetY:!0,pointerId:!0,pointerType:!0,screenX:!0,screenY:!0,targetTouches:!0,toElement:!0,touches:!0,which:function(e){var t=e.button;return null==e.which&&we.test(e.type)?null!=e.charCode?e.charCode:e.keyCode:!e.which&&void 0!==t&&Te.test(e.type)?1&t?1:2&t?3:4&t?2:0:e.which}},w.event.addProp),w.each({mouseenter:"mouseover",mouseleave:"mouseout",pointerenter:"pointerover",pointerleave:"pointerout"},function(e,t){w.event.special[e]={delegateType:t,bindType:t,handle:function(e){var n,r=this,i=e.relatedTarget,o=e.handleObj;return i&&(i===r||w.contains(r,i))||(e.type=o.origType,n=o.handler.apply(this,arguments),e.type=t),n}}}),w.fn.extend({on:function(e,t,n,r){return De(this,e,t,n,r)},one:function(e,t,n,r){return De(this,e,t,n,r,1)},off:function(e,t,n){var r,i;if(e&&e.preventDefault&&e.handleObj)return r=e.handleObj,w(e.delegateTarget).off(r.namespace?r.origType+"."+r.namespace:r.origType,r.selector,r.handler),this;if("object"==typeof e){for(i in e)this.off(i,t,e[i]);return this}return!1!==t&&"function"!=typeof t||(n=t,t=void 0),!1===n&&(n=ke),this.each(function(){w.event.remove(this,e,n,t)})}});var Ne=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([a-z][^\/\0>\x20\t\r\n\f]*)[^>]*)\/>/gi,Ae=/<script|<style|<link/i,je=/checked\s*(?:[^=]|=\s*.checked.)/i,qe=/^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g;function Le(e,t){return N(e,"table")&&N(11!==t.nodeType?t:t.firstChild,"tr")?w(e).children("tbody")[0]||e:e}function He(e){return e.type=(null!==e.getAttribute("type"))+"/"+e.type,e}function Oe(e){return"true/"===(e.type||"").slice(0,5)?e.type=e.type.slice(5):e.removeAttribute("type"),e}function Pe(e,t){var n,r,i,o,a,s,u,l;if(1===t.nodeType){if(J.hasData(e)&&(o=J.access(e),a=J.set(t,o),l=o.events)){delete a.handle,a.events={};for(i in l)for(n=0,r=l[i].length;n<r;n++)w.event.add(t,i,l[i][n])}K.hasData(e)&&(s=K.access(e),u=w.extend({},s),K.set(t,u))}}function Me(e,t){var n=t.nodeName.toLowerCase();"input"===n&&pe.test(e.type)?t.checked=e.checked:"input"!==n&&"textarea"!==n||(t.defaultValue=e.defaultValue)}function Re(e,t,n,r){t=a.apply([],t);var i,o,s,u,l,c,f=0,p=e.length,d=p-1,y=t[0],v=g(y);if(v||p>1&&"string"==typeof y&&!h.checkClone&&je.test(y))return e.each(function(i){var o=e.eq(i);v&&(t[0]=y.call(this,i,o.html())),Re(o,t,n,r)});if(p&&(i=xe(t,e[0].ownerDocument,!1,e,r),o=i.firstChild,1===i.childNodes.length&&(i=o),o||r)){for(u=(s=w.map(ye(i,"script"),He)).length;f<p;f++)l=i,f!==d&&(l=w.clone(l,!0,!0),u&&w.merge(s,ye(l,"script"))),n.call(e[f],l,f);if(u)for(c=s[s.length-1].ownerDocument,w.map(s,Oe),f=0;f<u;f++)l=s[f],he.test(l.type||"")&&!J.access(l,"globalEval")&&w.contains(c,l)&&(l.src&&"module"!==(l.type||"").toLowerCase()?w._evalUrl&&w._evalUrl(l.src):m(l.textContent.replace(qe,""),c,l))}return e}function Ie(e,t,n){for(var r,i=t?w.filter(t,e):e,o=0;null!=(r=i[o]);o++)n||1!==r.nodeType||w.cleanData(ye(r)),r.parentNode&&(n&&w.contains(r.ownerDocument,r)&&ve(ye(r,"script")),r.parentNode.removeChild(r));return e}w.extend({htmlPrefilter:function(e){return e.replace(Ne,"<$1></$2>")},clone:function(e,t,n){var r,i,o,a,s=e.cloneNode(!0),u=w.contains(e.ownerDocument,e);if(!(h.noCloneChecked||1!==e.nodeType&&11!==e.nodeType||w.isXMLDoc(e)))for(a=ye(s),r=0,i=(o=ye(e)).length;r<i;r++)Me(o[r],a[r]);if(t)if(n)for(o=o||ye(e),a=a||ye(s),r=0,i=o.length;r<i;r++)Pe(o[r],a[r]);else Pe(e,s);return(a=ye(s,"script")).length>0&&ve(a,!u&&ye(e,"script")),s},cleanData:function(e){for(var t,n,r,i=w.event.special,o=0;void 0!==(n=e[o]);o++)if(Y(n)){if(t=n[J.expando]){if(t.events)for(r in t.events)i[r]?w.event.remove(n,r):w.removeEvent(n,r,t.handle);n[J.expando]=void 0}n[K.expando]&&(n[K.expando]=void 0)}}}),w.fn.extend({detach:function(e){return Ie(this,e,!0)},remove:function(e){return Ie(this,e)},text:function(e){return z(this,function(e){return void 0===e?w.text(this):this.empty().each(function(){1!==this.nodeType&&11!==this.nodeType&&9!==this.nodeType||(this.textContent=e)})},null,e,arguments.length)},append:function(){return Re(this,arguments,function(e){1!==this.nodeType&&11!==this.nodeType&&9!==this.nodeType||Le(this,e).appendChild(e)})},prepend:function(){return Re(this,arguments,function(e){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var t=Le(this,e);t.insertBefore(e,t.firstChild)}})},before:function(){return Re(this,arguments,function(e){this.parentNode&&this.parentNode.insertBefore(e,this)})},after:function(){return Re(this,arguments,function(e){this.parentNode&&this.parentNode.insertBefore(e,this.nextSibling)})},empty:function(){for(var e,t=0;null!=(e=this[t]);t++)1===e.nodeType&&(w.cleanData(ye(e,!1)),e.textContent="");return this},clone:function(e,t){return e=null!=e&&e,t=null==t?e:t,this.map(function(){return w.clone(this,e,t)})},html:function(e){return z(this,function(e){var t=this[0]||{},n=0,r=this.length;if(void 0===e&&1===t.nodeType)return t.innerHTML;if("string"==typeof e&&!Ae.test(e)&&!ge[(de.exec(e)||["",""])[1].toLowerCase()]){e=w.htmlPrefilter(e);try{for(;n<r;n++)1===(t=this[n]||{}).nodeType&&(w.cleanData(ye(t,!1)),t.innerHTML=e);t=0}catch(e){}}t&&this.empty().append(e)},null,e,arguments.length)},replaceWith:function(){var e=[];return Re(this,arguments,function(t){var n=this.parentNode;w.inArray(this,e)<0&&(w.cleanData(ye(this)),n&&n.replaceChild(t,this))},e)}}),w.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(e,t){w.fn[e]=function(e){for(var n,r=[],i=w(e),o=i.length-1,a=0;a<=o;a++)n=a===o?this:this.clone(!0),w(i[a])[t](n),s.apply(r,n.get());return this.pushStack(r)}});var We=new RegExp("^("+re+")(?!px)[a-z%]+$","i"),$e=function(t){var n=t.ownerDocument.defaultView;return n&&n.opener||(n=e),n.getComputedStyle(t)},Be=new RegExp(oe.join("|"),"i");!function(){function t(){if(c){l.style.cssText="position:absolute;left:-11111px;width:60px;margin-top:1px;padding:0;border:0",c.style.cssText="position:relative;display:block;box-sizing:border-box;overflow:scroll;margin:auto;border:1px;padding:1px;width:60%;top:1%",be.appendChild(l).appendChild(c);var t=e.getComputedStyle(c);i="1%"!==t.top,u=12===n(t.marginLeft),c.style.right="60%",s=36===n(t.right),o=36===n(t.width),c.style.position="absolute",a=36===c.offsetWidth||"absolute",be.removeChild(l),c=null}}function n(e){return Math.round(parseFloat(e))}var i,o,a,s,u,l=r.createElement("div"),c=r.createElement("div");c.style&&(c.style.backgroundClip="content-box",c.cloneNode(!0).style.backgroundClip="",h.clearCloneStyle="content-box"===c.style.backgroundClip,w.extend(h,{boxSizingReliable:function(){return t(),o},pixelBoxStyles:function(){return t(),s},pixelPosition:function(){return t(),i},reliableMarginLeft:function(){return t(),u},scrollboxSize:function(){return t(),a}}))}();function Fe(e,t,n){var r,i,o,a,s=e.style;return(n=n||$e(e))&&(""!==(a=n.getPropertyValue(t)||n[t])||w.contains(e.ownerDocument,e)||(a=w.style(e,t)),!h.pixelBoxStyles()&&We.test(a)&&Be.test(t)&&(r=s.width,i=s.minWidth,o=s.maxWidth,s.minWidth=s.maxWidth=s.width=a,a=n.width,s.width=r,s.minWidth=i,s.maxWidth=o)),void 0!==a?a+"":a}function _e(e,t){return{get:function(){if(!e())return(this.get=t).apply(this,arguments);delete this.get}}}var ze=/^(none|table(?!-c[ea]).+)/,Xe=/^--/,Ue={position:"absolute",visibility:"hidden",display:"block"},Ve={letterSpacing:"0",fontWeight:"400"},Ge=["Webkit","Moz","ms"],Ye=r.createElement("div").style;function Qe(e){if(e in Ye)return e;var t=e[0].toUpperCase()+e.slice(1),n=Ge.length;while(n--)if((e=Ge[n]+t)in Ye)return e}function Je(e){var t=w.cssProps[e];return t||(t=w.cssProps[e]=Qe(e)||e),t}function Ke(e,t,n){var r=ie.exec(t);return r?Math.max(0,r[2]-(n||0))+(r[3]||"px"):t}function Ze(e,t,n,r,i,o){var a="width"===t?1:0,s=0,u=0;if(n===(r?"border":"content"))return 0;for(;a<4;a+=2)"margin"===n&&(u+=w.css(e,n+oe[a],!0,i)),r?("content"===n&&(u-=w.css(e,"padding"+oe[a],!0,i)),"margin"!==n&&(u-=w.css(e,"border"+oe[a]+"Width",!0,i))):(u+=w.css(e,"padding"+oe[a],!0,i),"padding"!==n?u+=w.css(e,"border"+oe[a]+"Width",!0,i):s+=w.css(e,"border"+oe[a]+"Width",!0,i));return!r&&o>=0&&(u+=Math.max(0,Math.ceil(e["offset"+t[0].toUpperCase()+t.slice(1)]-o-u-s-.5))),u}function et(e,t,n){var r=$e(e),i=Fe(e,t,r),o="border-box"===w.css(e,"boxSizing",!1,r),a=o;if(We.test(i)){if(!n)return i;i="auto"}return a=a&&(h.boxSizingReliable()||i===e.style[t]),("auto"===i||!parseFloat(i)&&"inline"===w.css(e,"display",!1,r))&&(i=e["offset"+t[0].toUpperCase()+t.slice(1)],a=!0),(i=parseFloat(i)||0)+Ze(e,t,n||(o?"border":"content"),a,r,i)+"px"}w.extend({cssHooks:{opacity:{get:function(e,t){if(t){var n=Fe(e,"opacity");return""===n?"1":n}}}},cssNumber:{animationIterationCount:!0,columnCount:!0,fillOpacity:!0,flexGrow:!0,flexShrink:!0,fontWeight:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{},style:function(e,t,n,r){if(e&&3!==e.nodeType&&8!==e.nodeType&&e.style){var i,o,a,s=G(t),u=Xe.test(t),l=e.style;if(u||(t=Je(s)),a=w.cssHooks[t]||w.cssHooks[s],void 0===n)return a&&"get"in a&&void 0!==(i=a.get(e,!1,r))?i:l[t];"string"==(o=typeof n)&&(i=ie.exec(n))&&i[1]&&(n=ue(e,t,i),o="number"),null!=n&&n===n&&("number"===o&&(n+=i&&i[3]||(w.cssNumber[s]?"":"px")),h.clearCloneStyle||""!==n||0!==t.indexOf("background")||(l[t]="inherit"),a&&"set"in a&&void 0===(n=a.set(e,n,r))||(u?l.setProperty(t,n):l[t]=n))}},css:function(e,t,n,r){var i,o,a,s=G(t);return Xe.test(t)||(t=Je(s)),(a=w.cssHooks[t]||w.cssHooks[s])&&"get"in a&&(i=a.get(e,!0,n)),void 0===i&&(i=Fe(e,t,r)),"normal"===i&&t in Ve&&(i=Ve[t]),""===n||n?(o=parseFloat(i),!0===n||isFinite(o)?o||0:i):i}}),w.each(["height","width"],function(e,t){w.cssHooks[t]={get:function(e,n,r){if(n)return!ze.test(w.css(e,"display"))||e.getClientRects().length&&e.getBoundingClientRect().width?et(e,t,r):se(e,Ue,function(){return et(e,t,r)})},set:function(e,n,r){var i,o=$e(e),a="border-box"===w.css(e,"boxSizing",!1,o),s=r&&Ze(e,t,r,a,o);return a&&h.scrollboxSize()===o.position&&(s-=Math.ceil(e["offset"+t[0].toUpperCase()+t.slice(1)]-parseFloat(o[t])-Ze(e,t,"border",!1,o)-.5)),s&&(i=ie.exec(n))&&"px"!==(i[3]||"px")&&(e.style[t]=n,n=w.css(e,t)),Ke(e,n,s)}}}),w.cssHooks.marginLeft=_e(h.reliableMarginLeft,function(e,t){if(t)return(parseFloat(Fe(e,"marginLeft"))||e.getBoundingClientRect().left-se(e,{marginLeft:0},function(){return e.getBoundingClientRect().left}))+"px"}),w.each({margin:"",padding:"",border:"Width"},function(e,t){w.cssHooks[e+t]={expand:function(n){for(var r=0,i={},o="string"==typeof n?n.split(" "):[n];r<4;r++)i[e+oe[r]+t]=o[r]||o[r-2]||o[0];return i}},"margin"!==e&&(w.cssHooks[e+t].set=Ke)}),w.fn.extend({css:function(e,t){return z(this,function(e,t,n){var r,i,o={},a=0;if(Array.isArray(t)){for(r=$e(e),i=t.length;a<i;a++)o[t[a]]=w.css(e,t[a],!1,r);return o}return void 0!==n?w.style(e,t,n):w.css(e,t)},e,t,arguments.length>1)}});function tt(e,t,n,r,i){return new tt.prototype.init(e,t,n,r,i)}w.Tween=tt,tt.prototype={constructor:tt,init:function(e,t,n,r,i,o){this.elem=e,this.prop=n,this.easing=i||w.easing._default,this.options=t,this.start=this.now=this.cur(),this.end=r,this.unit=o||(w.cssNumber[n]?"":"px")},cur:function(){var e=tt.propHooks[this.prop];return e&&e.get?e.get(this):tt.propHooks._default.get(this)},run:function(e){var t,n=tt.propHooks[this.prop];return this.options.duration?this.pos=t=w.easing[this.easing](e,this.options.duration*e,0,1,this.options.duration):this.pos=t=e,this.now=(this.end-this.start)*t+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),n&&n.set?n.set(this):tt.propHooks._default.set(this),this}},tt.prototype.init.prototype=tt.prototype,tt.propHooks={_default:{get:function(e){var t;return 1!==e.elem.nodeType||null!=e.elem[e.prop]&&null==e.elem.style[e.prop]?e.elem[e.prop]:(t=w.css(e.elem,e.prop,""))&&"auto"!==t?t:0},set:function(e){w.fx.step[e.prop]?w.fx.step[e.prop](e):1!==e.elem.nodeType||null==e.elem.style[w.cssProps[e.prop]]&&!w.cssHooks[e.prop]?e.elem[e.prop]=e.now:w.style(e.elem,e.prop,e.now+e.unit)}}},tt.propHooks.scrollTop=tt.propHooks.scrollLeft={set:function(e){e.elem.nodeType&&e.elem.parentNode&&(e.elem[e.prop]=e.now)}},w.easing={linear:function(e){return e},swing:function(e){return.5-Math.cos(e*Math.PI)/2},_default:"swing"},w.fx=tt.prototype.init,w.fx.step={};var nt,rt,it=/^(?:toggle|show|hide)$/,ot=/queueHooks$/;function at(){rt&&(!1===r.hidden&&e.requestAnimationFrame?e.requestAnimationFrame(at):e.setTimeout(at,w.fx.interval),w.fx.tick())}function st(){return e.setTimeout(function(){nt=void 0}),nt=Date.now()}function ut(e,t){var n,r=0,i={height:e};for(t=t?1:0;r<4;r+=2-t)i["margin"+(n=oe[r])]=i["padding"+n]=e;return t&&(i.opacity=i.width=e),i}function lt(e,t,n){for(var r,i=(pt.tweeners[t]||[]).concat(pt.tweeners["*"]),o=0,a=i.length;o<a;o++)if(r=i[o].call(n,t,e))return r}function ct(e,t,n){var r,i,o,a,s,u,l,c,f="width"in t||"height"in t,p=this,d={},h=e.style,g=e.nodeType&&ae(e),y=J.get(e,"fxshow");n.queue||(null==(a=w._queueHooks(e,"fx")).unqueued&&(a.unqueued=0,s=a.empty.fire,a.empty.fire=function(){a.unqueued||s()}),a.unqueued++,p.always(function(){p.always(function(){a.unqueued--,w.queue(e,"fx").length||a.empty.fire()})}));for(r in t)if(i=t[r],it.test(i)){if(delete t[r],o=o||"toggle"===i,i===(g?"hide":"show")){if("show"!==i||!y||void 0===y[r])continue;g=!0}d[r]=y&&y[r]||w.style(e,r)}if((u=!w.isEmptyObject(t))||!w.isEmptyObject(d)){f&&1===e.nodeType&&(n.overflow=[h.overflow,h.overflowX,h.overflowY],null==(l=y&&y.display)&&(l=J.get(e,"display")),"none"===(c=w.css(e,"display"))&&(l?c=l:(fe([e],!0),l=e.style.display||l,c=w.css(e,"display"),fe([e]))),("inline"===c||"inline-block"===c&&null!=l)&&"none"===w.css(e,"float")&&(u||(p.done(function(){h.display=l}),null==l&&(c=h.display,l="none"===c?"":c)),h.display="inline-block")),n.overflow&&(h.overflow="hidden",p.always(function(){h.overflow=n.overflow[0],h.overflowX=n.overflow[1],h.overflowY=n.overflow[2]})),u=!1;for(r in d)u||(y?"hidden"in y&&(g=y.hidden):y=J.access(e,"fxshow",{display:l}),o&&(y.hidden=!g),g&&fe([e],!0),p.done(function(){g||fe([e]),J.remove(e,"fxshow");for(r in d)w.style(e,r,d[r])})),u=lt(g?y[r]:0,r,p),r in y||(y[r]=u.start,g&&(u.end=u.start,u.start=0))}}function ft(e,t){var n,r,i,o,a;for(n in e)if(r=G(n),i=t[r],o=e[n],Array.isArray(o)&&(i=o[1],o=e[n]=o[0]),n!==r&&(e[r]=o,delete e[n]),(a=w.cssHooks[r])&&"expand"in a){o=a.expand(o),delete e[r];for(n in o)n in e||(e[n]=o[n],t[n]=i)}else t[r]=i}function pt(e,t,n){var r,i,o=0,a=pt.prefilters.length,s=w.Deferred().always(function(){delete u.elem}),u=function(){if(i)return!1;for(var t=nt||st(),n=Math.max(0,l.startTime+l.duration-t),r=1-(n/l.duration||0),o=0,a=l.tweens.length;o<a;o++)l.tweens[o].run(r);return s.notifyWith(e,[l,r,n]),r<1&&a?n:(a||s.notifyWith(e,[l,1,0]),s.resolveWith(e,[l]),!1)},l=s.promise({elem:e,props:w.extend({},t),opts:w.extend(!0,{specialEasing:{},easing:w.easing._default},n),originalProperties:t,originalOptions:n,startTime:nt||st(),duration:n.duration,tweens:[],createTween:function(t,n){var r=w.Tween(e,l.opts,t,n,l.opts.specialEasing[t]||l.opts.easing);return l.tweens.push(r),r},stop:function(t){var n=0,r=t?l.tweens.length:0;if(i)return this;for(i=!0;n<r;n++)l.tweens[n].run(1);return t?(s.notifyWith(e,[l,1,0]),s.resolveWith(e,[l,t])):s.rejectWith(e,[l,t]),this}}),c=l.props;for(ft(c,l.opts.specialEasing);o<a;o++)if(r=pt.prefilters[o].call(l,e,c,l.opts))return g(r.stop)&&(w._queueHooks(l.elem,l.opts.queue).stop=r.stop.bind(r)),r;return w.map(c,lt,l),g(l.opts.start)&&l.opts.start.call(e,l),l.progress(l.opts.progress).done(l.opts.done,l.opts.complete).fail(l.opts.fail).always(l.opts.always),w.fx.timer(w.extend(u,{elem:e,anim:l,queue:l.opts.queue})),l}w.Animation=w.extend(pt,{tweeners:{"*":[function(e,t){var n=this.createTween(e,t);return ue(n.elem,e,ie.exec(t),n),n}]},tweener:function(e,t){g(e)?(t=e,e=["*"]):e=e.match(M);for(var n,r=0,i=e.length;r<i;r++)n=e[r],pt.tweeners[n]=pt.tweeners[n]||[],pt.tweeners[n].unshift(t)},prefilters:[ct],prefilter:function(e,t){t?pt.prefilters.unshift(e):pt.prefilters.push(e)}}),w.speed=function(e,t,n){var r=e&&"object"==typeof e?w.extend({},e):{complete:n||!n&&t||g(e)&&e,duration:e,easing:n&&t||t&&!g(t)&&t};return w.fx.off?r.duration=0:"number"!=typeof r.duration&&(r.duration in w.fx.speeds?r.duration=w.fx.speeds[r.duration]:r.duration=w.fx.speeds._default),null!=r.queue&&!0!==r.queue||(r.queue="fx"),r.old=r.complete,r.complete=function(){g(r.old)&&r.old.call(this),r.queue&&w.dequeue(this,r.queue)},r},w.fn.extend({fadeTo:function(e,t,n,r){return this.filter(ae).css("opacity",0).show().end().animate({opacity:t},e,n,r)},animate:function(e,t,n,r){var i=w.isEmptyObject(e),o=w.speed(t,n,r),a=function(){var t=pt(this,w.extend({},e),o);(i||J.get(this,"finish"))&&t.stop(!0)};return a.finish=a,i||!1===o.queue?this.each(a):this.queue(o.queue,a)},stop:function(e,t,n){var r=function(e){var t=e.stop;delete e.stop,t(n)};return"string"!=typeof e&&(n=t,t=e,e=void 0),t&&!1!==e&&this.queue(e||"fx",[]),this.each(function(){var t=!0,i=null!=e&&e+"queueHooks",o=w.timers,a=J.get(this);if(i)a[i]&&a[i].stop&&r(a[i]);else for(i in a)a[i]&&a[i].stop&&ot.test(i)&&r(a[i]);for(i=o.length;i--;)o[i].elem!==this||null!=e&&o[i].queue!==e||(o[i].anim.stop(n),t=!1,o.splice(i,1));!t&&n||w.dequeue(this,e)})},finish:function(e){return!1!==e&&(e=e||"fx"),this.each(function(){var t,n=J.get(this),r=n[e+"queue"],i=n[e+"queueHooks"],o=w.timers,a=r?r.length:0;for(n.finish=!0,w.queue(this,e,[]),i&&i.stop&&i.stop.call(this,!0),t=o.length;t--;)o[t].elem===this&&o[t].queue===e&&(o[t].anim.stop(!0),o.splice(t,1));for(t=0;t<a;t++)r[t]&&r[t].finish&&r[t].finish.call(this);delete n.finish})}}),w.each(["toggle","show","hide"],function(e,t){var n=w.fn[t];w.fn[t]=function(e,r,i){return null==e||"boolean"==typeof e?n.apply(this,arguments):this.animate(ut(t,!0),e,r,i)}}),w.each({slideDown:ut("show"),slideUp:ut("hide"),slideToggle:ut("toggle"),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"},fadeToggle:{opacity:"toggle"}},function(e,t){w.fn[e]=function(e,n,r){return this.animate(t,e,n,r)}}),w.timers=[],w.fx.tick=function(){var e,t=0,n=w.timers;for(nt=Date.now();t<n.length;t++)(e=n[t])()||n[t]!==e||n.splice(t--,1);n.length||w.fx.stop(),nt=void 0},w.fx.timer=function(e){w.timers.push(e),w.fx.start()},w.fx.interval=13,w.fx.start=function(){rt||(rt=!0,at())},w.fx.stop=function(){rt=null},w.fx.speeds={slow:600,fast:200,_default:400},w.fn.delay=function(t,n){return t=w.fx?w.fx.speeds[t]||t:t,n=n||"fx",this.queue(n,function(n,r){var i=e.setTimeout(n,t);r.stop=function(){e.clearTimeout(i)}})},function(){var e=r.createElement("input"),t=r.createElement("select").appendChild(r.createElement("option"));e.type="checkbox",h.checkOn=""!==e.value,h.optSelected=t.selected,(e=r.createElement("input")).value="t",e.type="radio",h.radioValue="t"===e.value}();var dt,ht=w.expr.attrHandle;w.fn.extend({attr:function(e,t){return z(this,w.attr,e,t,arguments.length>1)},removeAttr:function(e){return this.each(function(){w.removeAttr(this,e)})}}),w.extend({attr:function(e,t,n){var r,i,o=e.nodeType;if(3!==o&&8!==o&&2!==o)return"undefined"==typeof e.getAttribute?w.prop(e,t,n):(1===o&&w.isXMLDoc(e)||(i=w.attrHooks[t.toLowerCase()]||(w.expr.match.bool.test(t)?dt:void 0)),void 0!==n?null===n?void w.removeAttr(e,t):i&&"set"in i&&void 0!==(r=i.set(e,n,t))?r:(e.setAttribute(t,n+""),n):i&&"get"in i&&null!==(r=i.get(e,t))?r:null==(r=w.find.attr(e,t))?void 0:r)},attrHooks:{type:{set:function(e,t){if(!h.radioValue&&"radio"===t&&N(e,"input")){var n=e.value;return e.setAttribute("type",t),n&&(e.value=n),t}}}},removeAttr:function(e,t){var n,r=0,i=t&&t.match(M);if(i&&1===e.nodeType)while(n=i[r++])e.removeAttribute(n)}}),dt={set:function(e,t,n){return!1===t?w.removeAttr(e,n):e.setAttribute(n,n),n}},w.each(w.expr.match.bool.source.match(/\w+/g),function(e,t){var n=ht[t]||w.find.attr;ht[t]=function(e,t,r){var i,o,a=t.toLowerCase();return r||(o=ht[a],ht[a]=i,i=null!=n(e,t,r)?a:null,ht[a]=o),i}});var gt=/^(?:input|select|textarea|button)$/i,yt=/^(?:a|area)$/i;w.fn.extend({prop:function(e,t){return z(this,w.prop,e,t,arguments.length>1)},removeProp:function(e){return this.each(function(){delete this[w.propFix[e]||e]})}}),w.extend({prop:function(e,t,n){var r,i,o=e.nodeType;if(3!==o&&8!==o&&2!==o)return 1===o&&w.isXMLDoc(e)||(t=w.propFix[t]||t,i=w.propHooks[t]),void 0!==n?i&&"set"in i&&void 0!==(r=i.set(e,n,t))?r:e[t]=n:i&&"get"in i&&null!==(r=i.get(e,t))?r:e[t]},propHooks:{tabIndex:{get:function(e){var t=w.find.attr(e,"tabindex");return t?parseInt(t,10):gt.test(e.nodeName)||yt.test(e.nodeName)&&e.href?0:-1}}},propFix:{"for":"htmlFor","class":"className"}}),h.optSelected||(w.propHooks.selected={get:function(e){var t=e.parentNode;return t&&t.parentNode&&t.parentNode.selectedIndex,null},set:function(e){var t=e.parentNode;t&&(t.selectedIndex,t.parentNode&&t.parentNode.selectedIndex)}}),w.each(["tabIndex","readOnly","maxLength","cellSpacing","cellPadding","rowSpan","colSpan","useMap","frameBorder","contentEditable"],function(){w.propFix[this.toLowerCase()]=this});function vt(e){return(e.match(M)||[]).join(" ")}function mt(e){return e.getAttribute&&e.getAttribute("class")||""}function xt(e){return Array.isArray(e)?e:"string"==typeof e?e.match(M)||[]:[]}w.fn.extend({addClass:function(e){var t,n,r,i,o,a,s,u=0;if(g(e))return this.each(function(t){w(this).addClass(e.call(this,t,mt(this)))});if((t=xt(e)).length)while(n=this[u++])if(i=mt(n),r=1===n.nodeType&&" "+vt(i)+" "){a=0;while(o=t[a++])r.indexOf(" "+o+" ")<0&&(r+=o+" ");i!==(s=vt(r))&&n.setAttribute("class",s)}return this},removeClass:function(e){var t,n,r,i,o,a,s,u=0;if(g(e))return this.each(function(t){w(this).removeClass(e.call(this,t,mt(this)))});if(!arguments.length)return this.attr("class","");if((t=xt(e)).length)while(n=this[u++])if(i=mt(n),r=1===n.nodeType&&" "+vt(i)+" "){a=0;while(o=t[a++])while(r.indexOf(" "+o+" ")>-1)r=r.replace(" "+o+" "," ");i!==(s=vt(r))&&n.setAttribute("class",s)}return this},toggleClass:function(e,t){var n=typeof e,r="string"===n||Array.isArray(e);return"boolean"==typeof t&&r?t?this.addClass(e):this.removeClass(e):g(e)?this.each(function(n){w(this).toggleClass(e.call(this,n,mt(this),t),t)}):this.each(function(){var t,i,o,a;if(r){i=0,o=w(this),a=xt(e);while(t=a[i++])o.hasClass(t)?o.removeClass(t):o.addClass(t)}else void 0!==e&&"boolean"!==n||((t=mt(this))&&J.set(this,"__className__",t),this.setAttribute&&this.setAttribute("class",t||!1===e?"":J.get(this,"__className__")||""))})},hasClass:function(e){var t,n,r=0;t=" "+e+" ";while(n=this[r++])if(1===n.nodeType&&(" "+vt(mt(n))+" ").indexOf(t)>-1)return!0;return!1}});var bt=/\r/g;w.fn.extend({val:function(e){var t,n,r,i=this[0];{if(arguments.length)return r=g(e),this.each(function(n){var i;1===this.nodeType&&(null==(i=r?e.call(this,n,w(this).val()):e)?i="":"number"==typeof i?i+="":Array.isArray(i)&&(i=w.map(i,function(e){return null==e?"":e+""})),(t=w.valHooks[this.type]||w.valHooks[this.nodeName.toLowerCase()])&&"set"in t&&void 0!==t.set(this,i,"value")||(this.value=i))});if(i)return(t=w.valHooks[i.type]||w.valHooks[i.nodeName.toLowerCase()])&&"get"in t&&void 0!==(n=t.get(i,"value"))?n:"string"==typeof(n=i.value)?n.replace(bt,""):null==n?"":n}}}),w.extend({valHooks:{option:{get:function(e){var t=w.find.attr(e,"value");return null!=t?t:vt(w.text(e))}},select:{get:function(e){var t,n,r,i=e.options,o=e.selectedIndex,a="select-one"===e.type,s=a?null:[],u=a?o+1:i.length;for(r=o<0?u:a?o:0;r<u;r++)if(((n=i[r]).selected||r===o)&&!n.disabled&&(!n.parentNode.disabled||!N(n.parentNode,"optgroup"))){if(t=w(n).val(),a)return t;s.push(t)}return s},set:function(e,t){var n,r,i=e.options,o=w.makeArray(t),a=i.length;while(a--)((r=i[a]).selected=w.inArray(w.valHooks.option.get(r),o)>-1)&&(n=!0);return n||(e.selectedIndex=-1),o}}}}),w.each(["radio","checkbox"],function(){w.valHooks[this]={set:function(e,t){if(Array.isArray(t))return e.checked=w.inArray(w(e).val(),t)>-1}},h.checkOn||(w.valHooks[this].get=function(e){return null===e.getAttribute("value")?"on":e.value})}),h.focusin="onfocusin"in e;var wt=/^(?:focusinfocus|focusoutblur)$/,Tt=function(e){e.stopPropagation()};w.extend(w.event,{trigger:function(t,n,i,o){var a,s,u,l,c,p,d,h,v=[i||r],m=f.call(t,"type")?t.type:t,x=f.call(t,"namespace")?t.namespace.split("."):[];if(s=h=u=i=i||r,3!==i.nodeType&&8!==i.nodeType&&!wt.test(m+w.event.triggered)&&(m.indexOf(".")>-1&&(m=(x=m.split(".")).shift(),x.sort()),c=m.indexOf(":")<0&&"on"+m,t=t[w.expando]?t:new w.Event(m,"object"==typeof t&&t),t.isTrigger=o?2:3,t.namespace=x.join("."),t.rnamespace=t.namespace?new RegExp("(^|\\.)"+x.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,t.result=void 0,t.target||(t.target=i),n=null==n?[t]:w.makeArray(n,[t]),d=w.event.special[m]||{},o||!d.trigger||!1!==d.trigger.apply(i,n))){if(!o&&!d.noBubble&&!y(i)){for(l=d.delegateType||m,wt.test(l+m)||(s=s.parentNode);s;s=s.parentNode)v.push(s),u=s;u===(i.ownerDocument||r)&&v.push(u.defaultView||u.parentWindow||e)}a=0;while((s=v[a++])&&!t.isPropagationStopped())h=s,t.type=a>1?l:d.bindType||m,(p=(J.get(s,"events")||{})[t.type]&&J.get(s,"handle"))&&p.apply(s,n),(p=c&&s[c])&&p.apply&&Y(s)&&(t.result=p.apply(s,n),!1===t.result&&t.preventDefault());return t.type=m,o||t.isDefaultPrevented()||d._default&&!1!==d._default.apply(v.pop(),n)||!Y(i)||c&&g(i[m])&&!y(i)&&((u=i[c])&&(i[c]=null),w.event.triggered=m,t.isPropagationStopped()&&h.addEventListener(m,Tt),i[m](),t.isPropagationStopped()&&h.removeEventListener(m,Tt),w.event.triggered=void 0,u&&(i[c]=u)),t.result}},simulate:function(e,t,n){var r=w.extend(new w.Event,n,{type:e,isSimulated:!0});w.event.trigger(r,null,t)}}),w.fn.extend({trigger:function(e,t){return this.each(function(){w.event.trigger(e,t,this)})},triggerHandler:function(e,t){var n=this[0];if(n)return w.event.trigger(e,t,n,!0)}}),h.focusin||w.each({focus:"focusin",blur:"focusout"},function(e,t){var n=function(e){w.event.simulate(t,e.target,w.event.fix(e))};w.event.special[t]={setup:function(){var r=this.ownerDocument||this,i=J.access(r,t);i||r.addEventListener(e,n,!0),J.access(r,t,(i||0)+1)},teardown:function(){var r=this.ownerDocument||this,i=J.access(r,t)-1;i?J.access(r,t,i):(r.removeEventListener(e,n,!0),J.remove(r,t))}}});var Ct=e.location,Et=Date.now(),kt=/\?/;w.parseXML=function(t){var n;if(!t||"string"!=typeof t)return null;try{n=(new e.DOMParser).parseFromString(t,"text/xml")}catch(e){n=void 0}return n&&!n.getElementsByTagName("parsererror").length||w.error("Invalid XML: "+t),n};var St=/\[\]$/,Dt=/\r?\n/g,Nt=/^(?:submit|button|image|reset|file)$/i,At=/^(?:input|select|textarea|keygen)/i;function jt(e,t,n,r){var i;if(Array.isArray(t))w.each(t,function(t,i){n||St.test(e)?r(e,i):jt(e+"["+("object"==typeof i&&null!=i?t:"")+"]",i,n,r)});else if(n||"object"!==x(t))r(e,t);else for(i in t)jt(e+"["+i+"]",t[i],n,r)}w.param=function(e,t){var n,r=[],i=function(e,t){var n=g(t)?t():t;r[r.length]=encodeURIComponent(e)+"="+encodeURIComponent(null==n?"":n)};if(Array.isArray(e)||e.jquery&&!w.isPlainObject(e))w.each(e,function(){i(this.name,this.value)});else for(n in e)jt(n,e[n],t,i);return r.join("&")},w.fn.extend({serialize:function(){return w.param(this.serializeArray())},serializeArray:function(){return this.map(function(){var e=w.prop(this,"elements");return e?w.makeArray(e):this}).filter(function(){var e=this.type;return this.name&&!w(this).is(":disabled")&&At.test(this.nodeName)&&!Nt.test(e)&&(this.checked||!pe.test(e))}).map(function(e,t){var n=w(this).val();return null==n?null:Array.isArray(n)?w.map(n,function(e){return{name:t.name,value:e.replace(Dt,"\r\n")}}):{name:t.name,value:n.replace(Dt,"\r\n")}}).get()}});var qt=/%20/g,Lt=/#.*$/,Ht=/([?&])_=[^&]*/,Ot=/^(.*?):[ \t]*([^\r\n]*)$/gm,Pt=/^(?:about|app|app-storage|.+-extension|file|res|widget):$/,Mt=/^(?:GET|HEAD)$/,Rt=/^\/\//,It={},Wt={},$t="*/".concat("*"),Bt=r.createElement("a");Bt.href=Ct.href;function Ft(e){return function(t,n){"string"!=typeof t&&(n=t,t="*");var r,i=0,o=t.toLowerCase().match(M)||[];if(g(n))while(r=o[i++])"+"===r[0]?(r=r.slice(1)||"*",(e[r]=e[r]||[]).unshift(n)):(e[r]=e[r]||[]).push(n)}}function _t(e,t,n,r){var i={},o=e===Wt;function a(s){var u;return i[s]=!0,w.each(e[s]||[],function(e,s){var l=s(t,n,r);return"string"!=typeof l||o||i[l]?o?!(u=l):void 0:(t.dataTypes.unshift(l),a(l),!1)}),u}return a(t.dataTypes[0])||!i["*"]&&a("*")}function zt(e,t){var n,r,i=w.ajaxSettings.flatOptions||{};for(n in t)void 0!==t[n]&&((i[n]?e:r||(r={}))[n]=t[n]);return r&&w.extend(!0,e,r),e}function Xt(e,t,n){var r,i,o,a,s=e.contents,u=e.dataTypes;while("*"===u[0])u.shift(),void 0===r&&(r=e.mimeType||t.getResponseHeader("Content-Type"));if(r)for(i in s)if(s[i]&&s[i].test(r)){u.unshift(i);break}if(u[0]in n)o=u[0];else{for(i in n){if(!u[0]||e.converters[i+" "+u[0]]){o=i;break}a||(a=i)}o=o||a}if(o)return o!==u[0]&&u.unshift(o),n[o]}function Ut(e,t,n,r){var i,o,a,s,u,l={},c=e.dataTypes.slice();if(c[1])for(a in e.converters)l[a.toLowerCase()]=e.converters[a];o=c.shift();while(o)if(e.responseFields[o]&&(n[e.responseFields[o]]=t),!u&&r&&e.dataFilter&&(t=e.dataFilter(t,e.dataType)),u=o,o=c.shift())if("*"===o)o=u;else if("*"!==u&&u!==o){if(!(a=l[u+" "+o]||l["* "+o]))for(i in l)if((s=i.split(" "))[1]===o&&(a=l[u+" "+s[0]]||l["* "+s[0]])){!0===a?a=l[i]:!0!==l[i]&&(o=s[0],c.unshift(s[1]));break}if(!0!==a)if(a&&e["throws"])t=a(t);else try{t=a(t)}catch(e){return{state:"parsererror",error:a?e:"No conversion from "+u+" to "+o}}}return{state:"success",data:t}}w.extend({active:0,lastModified:{},etag:{},ajaxSettings:{url:Ct.href,type:"GET",isLocal:Pt.test(Ct.protocol),global:!0,processData:!0,async:!0,contentType:"application/x-www-form-urlencoded; charset=UTF-8",accepts:{"*":$t,text:"text/plain",html:"text/html",xml:"application/xml, text/xml",json:"application/json, text/javascript"},contents:{xml:/\bxml\b/,html:/\bhtml/,json:/\bjson\b/},responseFields:{xml:"responseXML",text:"responseText",json:"responseJSON"},converters:{"* text":String,"text html":!0,"text json":JSON.parse,"text xml":w.parseXML},flatOptions:{url:!0,context:!0}},ajaxSetup:function(e,t){return t?zt(zt(e,w.ajaxSettings),t):zt(w.ajaxSettings,e)},ajaxPrefilter:Ft(It),ajaxTransport:Ft(Wt),ajax:function(t,n){"object"==typeof t&&(n=t,t=void 0),n=n||{};var i,o,a,s,u,l,c,f,p,d,h=w.ajaxSetup({},n),g=h.context||h,y=h.context&&(g.nodeType||g.jquery)?w(g):w.event,v=w.Deferred(),m=w.Callbacks("once memory"),x=h.statusCode||{},b={},T={},C="canceled",E={readyState:0,getResponseHeader:function(e){var t;if(c){if(!s){s={};while(t=Ot.exec(a))s[t[1].toLowerCase()]=t[2]}t=s[e.toLowerCase()]}return null==t?null:t},getAllResponseHeaders:function(){return c?a:null},setRequestHeader:function(e,t){return null==c&&(e=T[e.toLowerCase()]=T[e.toLowerCase()]||e,b[e]=t),this},overrideMimeType:function(e){return null==c&&(h.mimeType=e),this},statusCode:function(e){var t;if(e)if(c)E.always(e[E.status]);else for(t in e)x[t]=[x[t],e[t]];return this},abort:function(e){var t=e||C;return i&&i.abort(t),k(0,t),this}};if(v.promise(E),h.url=((t||h.url||Ct.href)+"").replace(Rt,Ct.protocol+"//"),h.type=n.method||n.type||h.method||h.type,h.dataTypes=(h.dataType||"*").toLowerCase().match(M)||[""],null==h.crossDomain){l=r.createElement("a");try{l.href=h.url,l.href=l.href,h.crossDomain=Bt.protocol+"//"+Bt.host!=l.protocol+"//"+l.host}catch(e){h.crossDomain=!0}}if(h.data&&h.processData&&"string"!=typeof h.data&&(h.data=w.param(h.data,h.traditional)),_t(It,h,n,E),c)return E;(f=w.event&&h.global)&&0==w.active++&&w.event.trigger("ajaxStart"),h.type=h.type.toUpperCase(),h.hasContent=!Mt.test(h.type),o=h.url.replace(Lt,""),h.hasContent?h.data&&h.processData&&0===(h.contentType||"").indexOf("application/x-www-form-urlencoded")&&(h.data=h.data.replace(qt,"+")):(d=h.url.slice(o.length),h.data&&(h.processData||"string"==typeof h.data)&&(o+=(kt.test(o)?"&":"?")+h.data,delete h.data),!1===h.cache&&(o=o.replace(Ht,"$1"),d=(kt.test(o)?"&":"?")+"_="+Et+++d),h.url=o+d),h.ifModified&&(w.lastModified[o]&&E.setRequestHeader("If-Modified-Since",w.lastModified[o]),w.etag[o]&&E.setRequestHeader("If-None-Match",w.etag[o])),(h.data&&h.hasContent&&!1!==h.contentType||n.contentType)&&E.setRequestHeader("Content-Type",h.contentType),E.setRequestHeader("Accept",h.dataTypes[0]&&h.accepts[h.dataTypes[0]]?h.accepts[h.dataTypes[0]]+("*"!==h.dataTypes[0]?", "+$t+"; q=0.01":""):h.accepts["*"]);for(p in h.headers)E.setRequestHeader(p,h.headers[p]);if(h.beforeSend&&(!1===h.beforeSend.call(g,E,h)||c))return E.abort();if(C="abort",m.add(h.complete),E.done(h.success),E.fail(h.error),i=_t(Wt,h,n,E)){if(E.readyState=1,f&&y.trigger("ajaxSend",[E,h]),c)return E;h.async&&h.timeout>0&&(u=e.setTimeout(function(){E.abort("timeout")},h.timeout));try{c=!1,i.send(b,k)}catch(e){if(c)throw e;k(-1,e)}}else k(-1,"No Transport");function k(t,n,r,s){var l,p,d,b,T,C=n;c||(c=!0,u&&e.clearTimeout(u),i=void 0,a=s||"",E.readyState=t>0?4:0,l=t>=200&&t<300||304===t,r&&(b=Xt(h,E,r)),b=Ut(h,b,E,l),l?(h.ifModified&&((T=E.getResponseHeader("Last-Modified"))&&(w.lastModified[o]=T),(T=E.getResponseHeader("etag"))&&(w.etag[o]=T)),204===t||"HEAD"===h.type?C="nocontent":304===t?C="notmodified":(C=b.state,p=b.data,l=!(d=b.error))):(d=C,!t&&C||(C="error",t<0&&(t=0))),E.status=t,E.statusText=(n||C)+"",l?v.resolveWith(g,[p,C,E]):v.rejectWith(g,[E,C,d]),E.statusCode(x),x=void 0,f&&y.trigger(l?"ajaxSuccess":"ajaxError",[E,h,l?p:d]),m.fireWith(g,[E,C]),f&&(y.trigger("ajaxComplete",[E,h]),--w.active||w.event.trigger("ajaxStop")))}return E},getJSON:function(e,t,n){return w.get(e,t,n,"json")},getScript:function(e,t){return w.get(e,void 0,t,"script")}}),w.each(["get","post"],function(e,t){w[t]=function(e,n,r,i){return g(n)&&(i=i||r,r=n,n=void 0),w.ajax(w.extend({url:e,type:t,dataType:i,data:n,success:r},w.isPlainObject(e)&&e))}}),w._evalUrl=function(e){return w.ajax({url:e,type:"GET",dataType:"script",cache:!0,async:!1,global:!1,"throws":!0})},w.fn.extend({wrapAll:function(e){var t;return this[0]&&(g(e)&&(e=e.call(this[0])),t=w(e,this[0].ownerDocument).eq(0).clone(!0),this[0].parentNode&&t.insertBefore(this[0]),t.map(function(){var e=this;while(e.firstElementChild)e=e.firstElementChild;return e}).append(this)),this},wrapInner:function(e){return g(e)?this.each(function(t){w(this).wrapInner(e.call(this,t))}):this.each(function(){var t=w(this),n=t.contents();n.length?n.wrapAll(e):t.append(e)})},wrap:function(e){var t=g(e);return this.each(function(n){w(this).wrapAll(t?e.call(this,n):e)})},unwrap:function(e){return this.parent(e).not("body").each(function(){w(this).replaceWith(this.childNodes)}),this}}),w.expr.pseudos.hidden=function(e){return!w.expr.pseudos.visible(e)},w.expr.pseudos.visible=function(e){return!!(e.offsetWidth||e.offsetHeight||e.getClientRects().length)},w.ajaxSettings.xhr=function(){try{return new e.XMLHttpRequest}catch(e){}};var Vt={0:200,1223:204},Gt=w.ajaxSettings.xhr();h.cors=!!Gt&&"withCredentials"in Gt,h.ajax=Gt=!!Gt,w.ajaxTransport(function(t){var n,r;if(h.cors||Gt&&!t.crossDomain)return{send:function(i,o){var a,s=t.xhr();if(s.open(t.type,t.url,t.async,t.username,t.password),t.xhrFields)for(a in t.xhrFields)s[a]=t.xhrFields[a];t.mimeType&&s.overrideMimeType&&s.overrideMimeType(t.mimeType),t.crossDomain||i["X-Requested-With"]||(i["X-Requested-With"]="XMLHttpRequest");for(a in i)s.setRequestHeader(a,i[a]);n=function(e){return function(){n&&(n=r=s.onload=s.onerror=s.onabort=s.ontimeout=s.onreadystatechange=null,"abort"===e?s.abort():"error"===e?"number"!=typeof s.status?o(0,"error"):o(s.status,s.statusText):o(Vt[s.status]||s.status,s.statusText,"text"!==(s.responseType||"text")||"string"!=typeof s.responseText?{binary:s.response}:{text:s.responseText},s.getAllResponseHeaders()))}},s.onload=n(),r=s.onerror=s.ontimeout=n("error"),void 0!==s.onabort?s.onabort=r:s.onreadystatechange=function(){4===s.readyState&&e.setTimeout(function(){n&&r()})},n=n("abort");try{s.send(t.hasContent&&t.data||null)}catch(e){if(n)throw e}},abort:function(){n&&n()}}}),w.ajaxPrefilter(function(e){e.crossDomain&&(e.contents.script=!1)}),w.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/\b(?:java|ecma)script\b/},converters:{"text script":function(e){return w.globalEval(e),e}}}),w.ajaxPrefilter("script",function(e){void 0===e.cache&&(e.cache=!1),e.crossDomain&&(e.type="GET")}),w.ajaxTransport("script",function(e){if(e.crossDomain){var t,n;return{send:function(i,o){t=w("<script>").prop({charset:e.scriptCharset,src:e.url}).on("load error",n=function(e){t.remove(),n=null,e&&o("error"===e.type?404:200,e.type)}),r.head.appendChild(t[0])},abort:function(){n&&n()}}}});var Yt=[],Qt=/(=)\?(?=&|$)|\?\?/;w.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var e=Yt.pop()||w.expando+"_"+Et++;return this[e]=!0,e}}),w.ajaxPrefilter("json jsonp",function(t,n,r){var i,o,a,s=!1!==t.jsonp&&(Qt.test(t.url)?"url":"string"==typeof t.data&&0===(t.contentType||"").indexOf("application/x-www-form-urlencoded")&&Qt.test(t.data)&&"data");if(s||"jsonp"===t.dataTypes[0])return i=t.jsonpCallback=g(t.jsonpCallback)?t.jsonpCallback():t.jsonpCallback,s?t[s]=t[s].replace(Qt,"$1"+i):!1!==t.jsonp&&(t.url+=(kt.test(t.url)?"&":"?")+t.jsonp+"="+i),t.converters["script json"]=function(){return a||w.error(i+" was not called"),a[0]},t.dataTypes[0]="json",o=e[i],e[i]=function(){a=arguments},r.always(function(){void 0===o?w(e).removeProp(i):e[i]=o,t[i]&&(t.jsonpCallback=n.jsonpCallback,Yt.push(i)),a&&g(o)&&o(a[0]),a=o=void 0}),"script"}),h.createHTMLDocument=function(){var e=r.implementation.createHTMLDocument("").body;return e.innerHTML="<form></form><form></form>",2===e.childNodes.length}(),w.parseHTML=function(e,t,n){if("string"!=typeof e)return[];"boolean"==typeof t&&(n=t,t=!1);var i,o,a;return t||(h.createHTMLDocument?((i=(t=r.implementation.createHTMLDocument("")).createElement("base")).href=r.location.href,t.head.appendChild(i)):t=r),o=A.exec(e),a=!n&&[],o?[t.createElement(o[1])]:(o=xe([e],t,a),a&&a.length&&w(a).remove(),w.merge([],o.childNodes))},w.fn.load=function(e,t,n){var r,i,o,a=this,s=e.indexOf(" ");return s>-1&&(r=vt(e.slice(s)),e=e.slice(0,s)),g(t)?(n=t,t=void 0):t&&"object"==typeof t&&(i="POST"),a.length>0&&w.ajax({url:e,type:i||"GET",dataType:"html",data:t}).done(function(e){o=arguments,a.html(r?w("<div>").append(w.parseHTML(e)).find(r):e)}).always(n&&function(e,t){a.each(function(){n.apply(this,o||[e.responseText,t,e])})}),this},w.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(e,t){w.fn[t]=function(e){return this.on(t,e)}}),w.expr.pseudos.animated=function(e){return w.grep(w.timers,function(t){return e===t.elem}).length},w.offset={setOffset:function(e,t,n){var r,i,o,a,s,u,l,c=w.css(e,"position"),f=w(e),p={};"static"===c&&(e.style.position="relative"),s=f.offset(),o=w.css(e,"top"),u=w.css(e,"left"),(l=("absolute"===c||"fixed"===c)&&(o+u).indexOf("auto")>-1)?(a=(r=f.position()).top,i=r.left):(a=parseFloat(o)||0,i=parseFloat(u)||0),g(t)&&(t=t.call(e,n,w.extend({},s))),null!=t.top&&(p.top=t.top-s.top+a),null!=t.left&&(p.left=t.left-s.left+i),"using"in t?t.using.call(e,p):f.css(p)}},w.fn.extend({offset:function(e){if(arguments.length)return void 0===e?this:this.each(function(t){w.offset.setOffset(this,e,t)});var t,n,r=this[0];if(r)return r.getClientRects().length?(t=r.getBoundingClientRect(),n=r.ownerDocument.defaultView,{top:t.top+n.pageYOffset,left:t.left+n.pageXOffset}):{top:0,left:0}},position:function(){if(this[0]){var e,t,n,r=this[0],i={top:0,left:0};if("fixed"===w.css(r,"position"))t=r.getBoundingClientRect();else{t=this.offset(),n=r.ownerDocument,e=r.offsetParent||n.documentElement;while(e&&(e===n.body||e===n.documentElement)&&"static"===w.css(e,"position"))e=e.parentNode;e&&e!==r&&1===e.nodeType&&((i=w(e).offset()).top+=w.css(e,"borderTopWidth",!0),i.left+=w.css(e,"borderLeftWidth",!0))}return{top:t.top-i.top-w.css(r,"marginTop",!0),left:t.left-i.left-w.css(r,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var e=this.offsetParent;while(e&&"static"===w.css(e,"position"))e=e.offsetParent;return e||be})}}),w.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(e,t){var n="pageYOffset"===t;w.fn[e]=function(r){return z(this,function(e,r,i){var o;if(y(e)?o=e:9===e.nodeType&&(o=e.defaultView),void 0===i)return o?o[t]:e[r];o?o.scrollTo(n?o.pageXOffset:i,n?i:o.pageYOffset):e[r]=i},e,r,arguments.length)}}),w.each(["top","left"],function(e,t){w.cssHooks[t]=_e(h.pixelPosition,function(e,n){if(n)return n=Fe(e,t),We.test(n)?w(e).position()[t]+"px":n})}),w.each({Height:"height",Width:"width"},function(e,t){w.each({padding:"inner"+e,content:t,"":"outer"+e},function(n,r){w.fn[r]=function(i,o){var a=arguments.length&&(n||"boolean"!=typeof i),s=n||(!0===i||!0===o?"margin":"border");return z(this,function(t,n,i){var o;return y(t)?0===r.indexOf("outer")?t["inner"+e]:t.document.documentElement["client"+e]:9===t.nodeType?(o=t.documentElement,Math.max(t.body["scroll"+e],o["scroll"+e],t.body["offset"+e],o["offset"+e],o["client"+e])):void 0===i?w.css(t,n,s):w.style(t,n,i,s)},t,a?i:void 0,a)}})}),w.each("blur focus focusin focusout resize scroll click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup contextmenu".split(" "),function(e,t){w.fn[t]=function(e,n){return arguments.length>0?this.on(t,null,e,n):this.trigger(t)}}),w.fn.extend({hover:function(e,t){return this.mouseenter(e).mouseleave(t||e)}}),w.fn.extend({bind:function(e,t,n){return this.on(e,null,t,n)},unbind:function(e,t){return this.off(e,null,t)},delegate:function(e,t,n,r){return this.on(t,e,n,r)},undelegate:function(e,t,n){return 1===arguments.length?this.off(e,"**"):this.off(t,e||"**",n)}}),w.proxy=function(e,t){var n,r,i;if("string"==typeof t&&(n=e[t],t=e,e=n),g(e))return r=o.call(arguments,2),i=function(){return e.apply(t||this,r.concat(o.call(arguments)))},i.guid=e.guid=e.guid||w.guid++,i},w.holdReady=function(e){e?w.readyWait++:w.ready(!0)},w.isArray=Array.isArray,w.parseJSON=JSON.parse,w.nodeName=N,w.isFunction=g,w.isWindow=y,w.camelCase=G,w.type=x,w.now=Date.now,w.isNumeric=function(e){var t=w.type(e);return("number"===t||"string"===t)&&!isNaN(e-parseFloat(e))},"function"==typeof define&&define.amd&&define("jquery",[],function(){return w});var Jt=e.jQuery,Kt=e.$;return w.noConflict=function(t){return e.$===w&&(e.$=Kt),t&&e.jQuery===w&&(e.jQuery=Jt),w},t||(e.jQuery=e.$=w),w});
The MIT License (MIT)
Copyright (c) 2018 Richard Cook
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.
server {
listen 80 ssl;
server_name mytestingurl.org;
ssl_certificate /path/to/crt;
ssl_certificate_key /path/to/key;
ssl_session_cache builtin:1000 shared:SSL:10m;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers HIGH:!aNULL:!eNULL:!EXPORT:!CAMELLIA:!DES:!MD5:!PSK:!RC4;
ssl_prefer_server_ciphers on;
location / {
proxy_pass http://localhost:3000;
proxy_intercept_errors on;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_set_header X-NginX-Proxy true;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment