/* handlebars-3.0.0.min.js */
/*!

 handlebars v3.0.0

Copyright (C) 2011-2014 by Yehuda Katz

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.

@license
*/
!function(a,b){"function"==typeof define&&define.amd?define([],b):"object"==typeof exports?module.exports=b():a.Handlebars=b()}(this,function(){var a=function(){"use strict";function a(a){return i[a]}function b(a){for(var b=1;b<arguments.length;b++)for(var c in arguments[b])Object.prototype.hasOwnProperty.call(arguments[b],c)&&(a[c]=arguments[b][c]);return a}function c(a,b){for(var c=0,d=a.length;d>c;c++)if(a[c]===b)return c;return-1}function d(b){return b&&b.toHTML?b.toHTML():null==b?"":b?(b=""+b,k.test(b)?b.replace(j,a):b):b+""}function e(a){return a||0===a?n(a)&&0===a.length?!0:!1:!0}function f(a,b){return a.path=b,a}function g(a,b){return(a?a+".":"")+b}var h={},i={"&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;","'":"&#x27;","`":"&#x60;"},j=/[&<>"'`]/g,k=/[&<>"'`]/;h.extend=b;var l=Object.prototype.toString;h.toString=l;var m=function(a){return"function"==typeof a};m(/x/)&&(m=function(a){return"function"==typeof a&&"[object Function]"===l.call(a)});var m;h.isFunction=m;var n=Array.isArray||function(a){return a&&"object"==typeof a?"[object Array]"===l.call(a):!1};return h.isArray=n,h.indexOf=c,h.escapeExpression=d,h.isEmpty=e,h.blockParams=f,h.appendContextPath=g,h}(),b=function(){"use strict";function a(a,b){var d,e,f=b&&b.loc;f&&(d=f.start.line,e=f.start.column,a+=" - "+d+":"+e);for(var g=Error.prototype.constructor.call(this,a),h=0;h<c.length;h++)this[c[h]]=g[c[h]];f&&(this.lineNumber=d,this.column=e)}var b,c=["description","fileName","lineNumber","message","name","number","stack"];return a.prototype=new Error,b=a}(),c=function(a,b){"use strict";function c(a,b){this.helpers=a||{},this.partials=b||{},d(this)}function d(a){a.registerHelper("helperMissing",function(){if(1===arguments.length)return void 0;throw new g("Missing helper: '"+arguments[arguments.length-1].name+"'")}),a.registerHelper("blockHelperMissing",function(b,c){var d=c.inverse,e=c.fn;if(b===!0)return e(this);if(b===!1||null==b)return d(this);if(k(b))return b.length>0?(c.ids&&(c.ids=[c.name]),a.helpers.each(b,c)):d(this);if(c.data&&c.ids){var g=q(c.data);g.contextPath=f.appendContextPath(c.data.contextPath,c.name),c={data:g}}return e(b,c)}),a.registerHelper("each",function(a,b){function c(b,c,g){d&&(d.key=b,d.index=c,d.first=0===c,d.last=!!g,e&&(d.contextPath=e+b)),m+=h(a[b],{data:d,blockParams:f.blockParams([a[b],b],[e+b,null])})}if(!b)throw new g("Must pass iterator to #each");var d,e,h=b.fn,i=b.inverse,j=0,m="";if(b.data&&b.ids&&(e=f.appendContextPath(b.data.contextPath,b.ids[0])+"."),l(a)&&(a=a.call(this)),b.data&&(d=q(b.data)),a&&"object"==typeof a)if(k(a))for(var n=a.length;n>j;j++)c(j,j,j===a.length-1);else{var o;for(var p in a)a.hasOwnProperty(p)&&(o&&c(o,j-1),o=p,j++);o&&c(o,j-1,!0)}return 0===j&&(m=i(this)),m}),a.registerHelper("if",function(a,b){return l(a)&&(a=a.call(this)),!b.hash.includeZero&&!a||f.isEmpty(a)?b.inverse(this):b.fn(this)}),a.registerHelper("unless",function(b,c){return a.helpers["if"].call(this,b,{fn:c.inverse,inverse:c.fn,hash:c.hash})}),a.registerHelper("with",function(a,b){l(a)&&(a=a.call(this));var c=b.fn;if(f.isEmpty(a))return b.inverse(this);if(b.data&&b.ids){var d=q(b.data);d.contextPath=f.appendContextPath(b.data.contextPath,b.ids[0]),b={data:d}}return c(a,b)}),a.registerHelper("log",function(b,c){var d=c.data&&null!=c.data.level?parseInt(c.data.level,10):1;a.log(d,b)}),a.registerHelper("lookup",function(a,b){return a&&a[b]})}var e={},f=a,g=b,h="3.0.0";e.VERSION=h;var i=6;e.COMPILER_REVISION=i;var j={1:"<= 1.0.rc.2",2:"== 1.0.0-rc.3",3:"== 1.0.0-rc.4",4:"== 1.x.x",5:"== 2.0.0-alpha.x",6:">= 2.0.0-beta.1"};e.REVISION_CHANGES=j;var k=f.isArray,l=f.isFunction,m=f.toString,n="[object Object]";e.HandlebarsEnvironment=c,c.prototype={constructor:c,logger:o,log:p,registerHelper:function(a,b){if(m.call(a)===n){if(b)throw new g("Arg not supported with multiple helpers");f.extend(this.helpers,a)}else this.helpers[a]=b},unregisterHelper:function(a){delete this.helpers[a]},registerPartial:function(a,b){if(m.call(a)===n)f.extend(this.partials,a);else{if("undefined"==typeof b)throw new g("Attempting to register a partial as undefined");this.partials[a]=b}},unregisterPartial:function(a){delete this.partials[a]}};var o={methodMap:{0:"debug",1:"info",2:"warn",3:"error"},DEBUG:0,INFO:1,WARN:2,ERROR:3,level:1,log:function(a,b){if("undefined"!=typeof console&&o.level<=a){var c=o.methodMap[a];(console[c]||console.log).call(console,b)}}};e.logger=o;var p=o.log;e.log=p;var q=function(a){var b=f.extend({},a);return b._parent=a,b};return e.createFrame=q,e}(a,b),d=function(){"use strict";function a(a){this.string=a}var b;return a.prototype.toString=a.prototype.toHTML=function(){return""+this.string},b=a}(),e=function(a,b,c){"use strict";function d(a){var b=a&&a[0]||1,c=n;if(b!==c){if(c>b){var d=o[c],e=o[b];throw new m("Template was precompiled with an older version of Handlebars than the current runtime. Please update your precompiler to a newer version ("+d+") or downgrade your runtime to an older version ("+e+").")}throw new m("Template was precompiled with a newer version of Handlebars than the current runtime. Please update your runtime to a newer version ("+a[1]+").")}}function e(a,b){if(!b)throw new m("No environment passed to template");if(!a||!a.main)throw new m("Unknown template object: "+typeof a);b.VM.checkRevision(a.compiler);var c=function(c,d,e){e.hash&&(d=l.extend({},d,e.hash)),c=b.VM.resolvePartial.call(this,c,d,e);var f=b.VM.invokePartial.call(this,c,d,e);if(null==f&&b.compile&&(e.partials[e.name]=b.compile(c,a.compilerOptions,b),f=e.partials[e.name](d,e)),null!=f){if(e.indent){for(var g=f.split("\n"),h=0,i=g.length;i>h&&(g[h]||h+1!==i);h++)g[h]=e.indent+g[h];f=g.join("\n")}return f}throw new m("The partial "+e.name+" could not be compiled when running in runtime-only mode")},d={strict:function(a,b){if(!(b in a))throw new m('"'+b+'" not defined in '+a);return a[b]},lookup:function(a,b){for(var c=a.length,d=0;c>d;d++)if(a[d]&&null!=a[d][b])return a[d][b]},lambda:function(a,b){return"function"==typeof a?a.call(b):a},escapeExpression:l.escapeExpression,invokePartial:c,fn:function(b){return a[b]},programs:[],program:function(a,b,c,d,e){var g=this.programs[a],h=this.fn(a);return b||e||d||c?g=f(this,a,h,b,c,d,e):g||(g=this.programs[a]=f(this,a,h)),g},data:function(a,b){for(;a&&b--;)a=a._parent;return a},merge:function(a,b){var c=a||b;return a&&b&&a!==b&&(c=l.extend({},b,a)),c},noop:b.VM.noop,compilerInfo:a.compiler},e=function(b,c){c=c||{};var f=c.data;e._setup(c),!c.partial&&a.useData&&(f=j(b,f));var g,h=a.useBlockParams?[]:void 0;return a.useDepths&&(g=c.depths?[b].concat(c.depths):[b]),a.main.call(d,b,d.helpers,d.partials,f,h,g)};return e.isTop=!0,e._setup=function(c){c.partial?(d.helpers=c.helpers,d.partials=c.partials):(d.helpers=d.merge(c.helpers,b.helpers),a.usePartial&&(d.partials=d.merge(c.partials,b.partials)))},e._child=function(b,c,e,g){if(a.useBlockParams&&!e)throw new m("must pass block params");if(a.useDepths&&!g)throw new m("must pass parent depths");return f(d,b,a[b],c,0,e,g)},e}function f(a,b,c,d,e,f,g){var h=function(b,e){return e=e||{},c.call(a,b,a.helpers,a.partials,e.data||d,f&&[e.blockParams].concat(f),g&&[b].concat(g))};return h.program=b,h.depth=g?g.length:0,h.blockParams=e||0,h}function g(a,b,c){return a?a.call||c.name||(c.name=a,a=c.partials[a]):a=c.partials[c.name],a}function h(a,b,c){if(c.partial=!0,void 0===a)throw new m("The partial "+c.name+" could not be found");return a instanceof Function?a(b,c):void 0}function i(){return""}function j(a,b){return b&&"root"in b||(b=b?p(b):{},b.root=a),b}var k={},l=a,m=b,n=c.COMPILER_REVISION,o=c.REVISION_CHANGES,p=c.createFrame;return k.checkRevision=d,k.template=e,k.program=f,k.resolvePartial=g,k.invokePartial=h,k.noop=i,k}(a,b,c),f=function(a,b,c,d,e){"use strict";var f,g=a,h=b,i=c,j=d,k=e,l=function(){var a=new g.HandlebarsEnvironment;return j.extend(a,g),a.SafeString=h,a.Exception=i,a.Utils=j,a.escapeExpression=j.escapeExpression,a.VM=k,a.template=function(b){return k.template(b,a)},a},m=l();m.create=l;var n="undefined"!=typeof global?global:window,o=n.Handlebars;return m.noConflict=function(){n.Handlebars===m&&(n.Handlebars=o)},m["default"]=m,f=m}(c,d,b,a,e),g=function(){"use strict";var a,b={Program:function(a,b,c,d){this.loc=d,this.type="Program",this.body=a,this.blockParams=b,this.strip=c},MustacheStatement:function(a,b,c,d,e,f){this.loc=f,this.type="MustacheStatement",this.path=a,this.params=b||[],this.hash=c,this.escaped=d,this.strip=e},BlockStatement:function(a,b,c,d,e,f,g,h,i){this.loc=i,this.type="BlockStatement",this.path=a,this.params=b||[],this.hash=c,this.program=d,this.inverse=e,this.openStrip=f,this.inverseStrip=g,this.closeStrip=h},PartialStatement:function(a,b,c,d,e){this.loc=e,this.type="PartialStatement",this.name=a,this.params=b||[],this.hash=c,this.indent="",this.strip=d},ContentStatement:function(a,b){this.loc=b,this.type="ContentStatement",this.original=this.value=a},CommentStatement:function(a,b,c){this.loc=c,this.type="CommentStatement",this.value=a,this.strip=b},SubExpression:function(a,b,c,d){this.loc=d,this.type="SubExpression",this.path=a,this.params=b||[],this.hash=c},PathExpression:function(a,b,c,d,e){this.loc=e,this.type="PathExpression",this.data=a,this.original=d,this.parts=c,this.depth=b},StringLiteral:function(a,b){this.loc=b,this.type="StringLiteral",this.original=this.value=a},NumberLiteral:function(a,b){this.loc=b,this.type="NumberLiteral",this.original=this.value=Number(a)},BooleanLiteral:function(a,b){this.loc=b,this.type="BooleanLiteral",this.original=this.value="true"===a},Hash:function(a,b){this.loc=b,this.type="Hash",this.pairs=a},HashPair:function(a,b,c){this.loc=c,this.type="HashPair",this.key=a,this.value=b},helpers:{helperExpression:function(a){return!("SubExpression"!==a.type&&!a.params.length&&!a.hash)},scopedId:function(a){return/^\.|this\b/.test(a.original)},simpleId:function(a){return 1===a.parts.length&&!b.helpers.scopedId(a)&&!a.depth}}};return a=b}(),h=function(){"use strict";var a,b=function(){function a(){this.yy={}}var b={trace:function(){},yy:{},symbols_:{error:2,root:3,program:4,EOF:5,program_repetition0:6,statement:7,mustache:8,block:9,rawBlock:10,partial:11,content:12,COMMENT:13,CONTENT:14,openRawBlock:15,END_RAW_BLOCK:16,OPEN_RAW_BLOCK:17,helperName:18,openRawBlock_repetition0:19,openRawBlock_option0:20,CLOSE_RAW_BLOCK:21,openBlock:22,block_option0:23,closeBlock:24,openInverse:25,block_option1:26,OPEN_BLOCK:27,openBlock_repetition0:28,openBlock_option0:29,openBlock_option1:30,CLOSE:31,OPEN_INVERSE:32,openInverse_repetition0:33,openInverse_option0:34,openInverse_option1:35,openInverseChain:36,OPEN_INVERSE_CHAIN:37,openInverseChain_repetition0:38,openInverseChain_option0:39,openInverseChain_option1:40,inverseAndProgram:41,INVERSE:42,inverseChain:43,inverseChain_option0:44,OPEN_ENDBLOCK:45,OPEN:46,mustache_repetition0:47,mustache_option0:48,OPEN_UNESCAPED:49,mustache_repetition1:50,mustache_option1:51,CLOSE_UNESCAPED:52,OPEN_PARTIAL:53,partialName:54,partial_repetition0:55,partial_option0:56,param:57,sexpr:58,OPEN_SEXPR:59,sexpr_repetition0:60,sexpr_option0:61,CLOSE_SEXPR:62,hash:63,hash_repetition_plus0:64,hashSegment:65,ID:66,EQUALS:67,blockParams:68,OPEN_BLOCK_PARAMS:69,blockParams_repetition_plus0:70,CLOSE_BLOCK_PARAMS:71,path:72,dataName:73,STRING:74,NUMBER:75,BOOLEAN:76,DATA:77,pathSegments:78,SEP:79,$accept:0,$end:1},terminals_:{2:"error",5:"EOF",13:"COMMENT",14:"CONTENT",16:"END_RAW_BLOCK",17:"OPEN_RAW_BLOCK",21:"CLOSE_RAW_BLOCK",27:"OPEN_BLOCK",31:"CLOSE",32:"OPEN_INVERSE",37:"OPEN_INVERSE_CHAIN",42:"INVERSE",45:"OPEN_ENDBLOCK",46:"OPEN",49:"OPEN_UNESCAPED",52:"CLOSE_UNESCAPED",53:"OPEN_PARTIAL",59:"OPEN_SEXPR",62:"CLOSE_SEXPR",66:"ID",67:"EQUALS",69:"OPEN_BLOCK_PARAMS",71:"CLOSE_BLOCK_PARAMS",74:"STRING",75:"NUMBER",76:"BOOLEAN",77:"DATA",79:"SEP"},productions_:[0,[3,2],[4,1],[7,1],[7,1],[7,1],[7,1],[7,1],[7,1],[12,1],[10,3],[15,5],[9,4],[9,4],[22,6],[25,6],[36,6],[41,2],[43,3],[43,1],[24,3],[8,5],[8,5],[11,5],[57,1],[57,1],[58,5],[63,1],[65,3],[68,3],[18,1],[18,1],[18,1],[18,1],[18,1],[54,1],[54,1],[73,2],[72,1],[78,3],[78,1],[6,0],[6,2],[19,0],[19,2],[20,0],[20,1],[23,0],[23,1],[26,0],[26,1],[28,0],[28,2],[29,0],[29,1],[30,0],[30,1],[33,0],[33,2],[34,0],[34,1],[35,0],[35,1],[38,0],[38,2],[39,0],[39,1],[40,0],[40,1],[44,0],[44,1],[47,0],[47,2],[48,0],[48,1],[50,0],[50,2],[51,0],[51,1],[55,0],[55,2],[56,0],[56,1],[60,0],[60,2],[61,0],[61,1],[64,1],[64,2],[70,1],[70,2]],performAction:function(a,b,c,d,e,f){var g=f.length-1;switch(e){case 1:return f[g-1];case 2:this.$=new d.Program(f[g],null,{},d.locInfo(this._$));break;case 3:this.$=f[g];break;case 4:this.$=f[g];break;case 5:this.$=f[g];break;case 6:this.$=f[g];break;case 7:this.$=f[g];break;case 8:this.$=new d.CommentStatement(d.stripComment(f[g]),d.stripFlags(f[g],f[g]),d.locInfo(this._$));break;case 9:this.$=new d.ContentStatement(f[g],d.locInfo(this._$));break;case 10:this.$=d.prepareRawBlock(f[g-2],f[g-1],f[g],this._$);break;case 11:this.$={path:f[g-3],params:f[g-2],hash:f[g-1]};break;case 12:this.$=d.prepareBlock(f[g-3],f[g-2],f[g-1],f[g],!1,this._$);break;case 13:this.$=d.prepareBlock(f[g-3],f[g-2],f[g-1],f[g],!0,this._$);break;case 14:this.$={path:f[g-4],params:f[g-3],hash:f[g-2],blockParams:f[g-1],strip:d.stripFlags(f[g-5],f[g])};break;case 15:this.$={path:f[g-4],params:f[g-3],hash:f[g-2],blockParams:f[g-1],strip:d.stripFlags(f[g-5],f[g])};break;case 16:this.$={path:f[g-4],params:f[g-3],hash:f[g-2],blockParams:f[g-1],strip:d.stripFlags(f[g-5],f[g])};break;case 17:this.$={strip:d.stripFlags(f[g-1],f[g-1]),program:f[g]};break;case 18:var h=d.prepareBlock(f[g-2],f[g-1],f[g],f[g],!1,this._$),i=new d.Program([h],null,{},d.locInfo(this._$));i.chained=!0,this.$={strip:f[g-2].strip,program:i,chain:!0};break;case 19:this.$=f[g];break;case 20:this.$={path:f[g-1],strip:d.stripFlags(f[g-2],f[g])};break;case 21:this.$=d.prepareMustache(f[g-3],f[g-2],f[g-1],f[g-4],d.stripFlags(f[g-4],f[g]),this._$);break;case 22:this.$=d.prepareMustache(f[g-3],f[g-2],f[g-1],f[g-4],d.stripFlags(f[g-4],f[g]),this._$);break;case 23:this.$=new d.PartialStatement(f[g-3],f[g-2],f[g-1],d.stripFlags(f[g-4],f[g]),d.locInfo(this._$));break;case 24:this.$=f[g];break;case 25:this.$=f[g];break;case 26:this.$=new d.SubExpression(f[g-3],f[g-2],f[g-1],d.locInfo(this._$));break;case 27:this.$=new d.Hash(f[g],d.locInfo(this._$));break;case 28:this.$=new d.HashPair(f[g-2],f[g],d.locInfo(this._$));break;case 29:this.$=f[g-1];break;case 30:this.$=f[g];break;case 31:this.$=f[g];break;case 32:this.$=new d.StringLiteral(f[g],d.locInfo(this._$));break;case 33:this.$=new d.NumberLiteral(f[g],d.locInfo(this._$));break;case 34:this.$=new d.BooleanLiteral(f[g],d.locInfo(this._$));break;case 35:this.$=f[g];break;case 36:this.$=f[g];break;case 37:this.$=d.preparePath(!0,f[g],this._$);break;case 38:this.$=d.preparePath(!1,f[g],this._$);break;case 39:f[g-2].push({part:f[g],separator:f[g-1]}),this.$=f[g-2];break;case 40:this.$=[{part:f[g]}];break;case 41:this.$=[];break;case 42:f[g-1].push(f[g]);break;case 43:this.$=[];break;case 44:f[g-1].push(f[g]);break;case 51:this.$=[];break;case 52:f[g-1].push(f[g]);break;case 57:this.$=[];break;case 58:f[g-1].push(f[g]);break;case 63:this.$=[];break;case 64:f[g-1].push(f[g]);break;case 71:this.$=[];break;case 72:f[g-1].push(f[g]);break;case 75:this.$=[];break;case 76:f[g-1].push(f[g]);break;case 79:this.$=[];break;case 80:f[g-1].push(f[g]);break;case 83:this.$=[];break;case 84:f[g-1].push(f[g]);break;case 87:this.$=[f[g]];break;case 88:f[g-1].push(f[g]);break;case 89:this.$=[f[g]];break;case 90:f[g-1].push(f[g])}},table:[{3:1,4:2,5:[2,41],6:3,13:[2,41],14:[2,41],17:[2,41],27:[2,41],32:[2,41],46:[2,41],49:[2,41],53:[2,41]},{1:[3]},{5:[1,4]},{5:[2,2],7:5,8:6,9:7,10:8,11:9,12:10,13:[1,11],14:[1,18],15:16,17:[1,21],22:14,25:15,27:[1,19],32:[1,20],37:[2,2],42:[2,2],45:[2,2],46:[1,12],49:[1,13],53:[1,17]},{1:[2,1]},{5:[2,42],13:[2,42],14:[2,42],17:[2,42],27:[2,42],32:[2,42],37:[2,42],42:[2,42],45:[2,42],46:[2,42],49:[2,42],53:[2,42]},{5:[2,3],13:[2,3],14:[2,3],17:[2,3],27:[2,3],32:[2,3],37:[2,3],42:[2,3],45:[2,3],46:[2,3],49:[2,3],53:[2,3]},{5:[2,4],13:[2,4],14:[2,4],17:[2,4],27:[2,4],32:[2,4],37:[2,4],42:[2,4],45:[2,4],46:[2,4],49:[2,4],53:[2,4]},{5:[2,5],13:[2,5],14:[2,5],17:[2,5],27:[2,5],32:[2,5],37:[2,5],42:[2,5],45:[2,5],46:[2,5],49:[2,5],53:[2,5]},{5:[2,6],13:[2,6],14:[2,6],17:[2,6],27:[2,6],32:[2,6],37:[2,6],42:[2,6],45:[2,6],46:[2,6],49:[2,6],53:[2,6]},{5:[2,7],13:[2,7],14:[2,7],17:[2,7],27:[2,7],32:[2,7],37:[2,7],42:[2,7],45:[2,7],46:[2,7],49:[2,7],53:[2,7]},{5:[2,8],13:[2,8],14:[2,8],17:[2,8],27:[2,8],32:[2,8],37:[2,8],42:[2,8],45:[2,8],46:[2,8],49:[2,8],53:[2,8]},{18:22,66:[1,30],72:23,73:24,74:[1,25],75:[1,26],76:[1,27],77:[1,29],78:28},{18:31,66:[1,30],72:23,73:24,74:[1,25],75:[1,26],76:[1,27],77:[1,29],78:28},{4:32,6:3,13:[2,41],14:[2,41],17:[2,41],27:[2,41],32:[2,41],37:[2,41],42:[2,41],45:[2,41],46:[2,41],49:[2,41],53:[2,41]},{4:33,6:3,13:[2,41],14:[2,41],17:[2,41],27:[2,41],32:[2,41],42:[2,41],45:[2,41],46:[2,41],49:[2,41],53:[2,41]},{12:34,14:[1,18]},{18:36,54:35,58:37,59:[1,38],66:[1,30],72:23,73:24,74:[1,25],75:[1,26],76:[1,27],77:[1,29],78:28},{5:[2,9],13:[2,9],14:[2,9],16:[2,9],17:[2,9],27:[2,9],32:[2,9],37:[2,9],42:[2,9],45:[2,9],46:[2,9],49:[2,9],53:[2,9]},{18:39,66:[1,30],72:23,73:24,74:[1,25],75:[1,26],76:[1,27],77:[1,29],78:28},{18:40,66:[1,30],72:23,73:24,74:[1,25],75:[1,26],76:[1,27],77:[1,29],78:28},{18:41,66:[1,30],72:23,73:24,74:[1,25],75:[1,26],76:[1,27],77:[1,29],78:28},{31:[2,71],47:42,59:[2,71],66:[2,71],74:[2,71],75:[2,71],76:[2,71],77:[2,71]},{21:[2,30],31:[2,30],52:[2,30],59:[2,30],62:[2,30],66:[2,30],69:[2,30],74:[2,30],75:[2,30],76:[2,30],77:[2,30]},{21:[2,31],31:[2,31],52:[2,31],59:[2,31],62:[2,31],66:[2,31],69:[2,31],74:[2,31],75:[2,31],76:[2,31],77:[2,31]},{21:[2,32],31:[2,32],52:[2,32],59:[2,32],62:[2,32],66:[2,32],69:[2,32],74:[2,32],75:[2,32],76:[2,32],77:[2,32]},{21:[2,33],31:[2,33],52:[2,33],59:[2,33],62:[2,33],66:[2,33],69:[2,33],74:[2,33],75:[2,33],76:[2,33],77:[2,33]},{21:[2,34],31:[2,34],52:[2,34],59:[2,34],62:[2,34],66:[2,34],69:[2,34],74:[2,34],75:[2,34],76:[2,34],77:[2,34]},{21:[2,38],31:[2,38],52:[2,38],59:[2,38],62:[2,38],66:[2,38],69:[2,38],74:[2,38],75:[2,38],76:[2,38],77:[2,38],79:[1,43]},{66:[1,30],78:44},{21:[2,40],31:[2,40],52:[2,40],59:[2,40],62:[2,40],66:[2,40],69:[2,40],74:[2,40],75:[2,40],76:[2,40],77:[2,40],79:[2,40]},{50:45,52:[2,75],59:[2,75],66:[2,75],74:[2,75],75:[2,75],76:[2,75],77:[2,75]},{23:46,36:48,37:[1,50],41:49,42:[1,51],43:47,45:[2,47]},{26:52,41:53,42:[1,51],45:[2,49]},{16:[1,54]},{31:[2,79],55:55,59:[2,79],66:[2,79],74:[2,79],75:[2,79],76:[2,79],77:[2,79]},{31:[2,35],59:[2,35],66:[2,35],74:[2,35],75:[2,35],76:[2,35],77:[2,35]},{31:[2,36],59:[2,36],66:[2,36],74:[2,36],75:[2,36],76:[2,36],77:[2,36]},{18:56,66:[1,30],72:23,73:24,74:[1,25],75:[1,26],76:[1,27],77:[1,29],78:28},{28:57,31:[2,51],59:[2,51],66:[2,51],69:[2,51],74:[2,51],75:[2,51],76:[2,51],77:[2,51]},{31:[2,57],33:58,59:[2,57],66:[2,57],69:[2,57],74:[2,57],75:[2,57],76:[2,57],77:[2,57]},{19:59,21:[2,43],59:[2,43],66:[2,43],74:[2,43],75:[2,43],76:[2,43],77:[2,43]},{18:63,31:[2,73],48:60,57:61,58:64,59:[1,38],63:62,64:65,65:66,66:[1,67],72:23,73:24,74:[1,25],75:[1,26],76:[1,27],77:[1,29],78:28},{66:[1,68]},{21:[2,37],31:[2,37],52:[2,37],59:[2,37],62:[2,37],66:[2,37],69:[2,37],74:[2,37],75:[2,37],76:[2,37],77:[2,37],79:[1,43]},{18:63,51:69,52:[2,77],57:70,58:64,59:[1,38],63:71,64:65,65:66,66:[1,67],72:23,73:24,74:[1,25],75:[1,26],76:[1,27],77:[1,29],78:28},{24:72,45:[1,73]},{45:[2,48]},{4:74,6:3,13:[2,41],14:[2,41],17:[2,41],27:[2,41],32:[2,41],37:[2,41],42:[2,41],45:[2,41],46:[2,41],49:[2,41],53:[2,41]},{45:[2,19]},{18:75,66:[1,30],72:23,73:24,74:[1,25],75:[1,26],76:[1,27],77:[1,29],78:28},{4:76,6:3,13:[2,41],14:[2,41],17:[2,41],27:[2,41],32:[2,41],45:[2,41],46:[2,41],49:[2,41],53:[2,41]},{24:77,45:[1,73]},{45:[2,50]},{5:[2,10],13:[2,10],14:[2,10],17:[2,10],27:[2,10],32:[2,10],37:[2,10],42:[2,10],45:[2,10],46:[2,10],49:[2,10],53:[2,10]},{18:63,31:[2,81],56:78,57:79,58:64,59:[1,38],63:80,64:65,65:66,66:[1,67],72:23,73:24,74:[1,25],75:[1,26],76:[1,27],77:[1,29],78:28},{59:[2,83],60:81,62:[2,83],66:[2,83],74:[2,83],75:[2,83],76:[2,83],77:[2,83]},{18:63,29:82,31:[2,53],57:83,58:64,59:[1,38],63:84,64:65,65:66,66:[1,67],69:[2,53],72:23,73:24,74:[1,25],75:[1,26],76:[1,27],77:[1,29],78:28},{18:63,31:[2,59],34:85,57:86,58:64,59:[1,38],63:87,64:65,65:66,66:[1,67],69:[2,59],72:23,73:24,74:[1,25],75:[1,26],76:[1,27],77:[1,29],78:28},{18:63,20:88,21:[2,45],57:89,58:64,59:[1,38],63:90,64:65,65:66,66:[1,67],72:23,73:24,74:[1,25],75:[1,26],76:[1,27],77:[1,29],78:28},{31:[1,91]},{31:[2,72],59:[2,72],66:[2,72],74:[2,72],75:[2,72],76:[2,72],77:[2,72]},{31:[2,74]},{21:[2,24],31:[2,24],52:[2,24],59:[2,24],62:[2,24],66:[2,24],69:[2,24],74:[2,24],75:[2,24],76:[2,24],77:[2,24]},{21:[2,25],31:[2,25],52:[2,25],59:[2,25],62:[2,25],66:[2,25],69:[2,25],74:[2,25],75:[2,25],76:[2,25],77:[2,25]},{21:[2,27],31:[2,27],52:[2,27],62:[2,27],65:92,66:[1,93],69:[2,27]},{21:[2,87],31:[2,87],52:[2,87],62:[2,87],66:[2,87],69:[2,87]},{21:[2,40],31:[2,40],52:[2,40],59:[2,40],62:[2,40],66:[2,40],67:[1,94],69:[2,40],74:[2,40],75:[2,40],76:[2,40],77:[2,40],79:[2,40]},{21:[2,39],31:[2,39],52:[2,39],59:[2,39],62:[2,39],66:[2,39],69:[2,39],74:[2,39],75:[2,39],76:[2,39],77:[2,39],79:[2,39]},{52:[1,95]},{52:[2,76],59:[2,76],66:[2,76],74:[2,76],75:[2,76],76:[2,76],77:[2,76]},{52:[2,78]},{5:[2,12],13:[2,12],14:[2,12],17:[2,12],27:[2,12],32:[2,12],37:[2,12],42:[2,12],45:[2,12],46:[2,12],49:[2,12],53:[2,12]},{18:96,66:[1,30],72:23,73:24,74:[1,25],75:[1,26],76:[1,27],77:[1,29],78:28},{36:48,37:[1,50],41:49,42:[1,51],43:98,44:97,45:[2,69]},{31:[2,63],38:99,59:[2,63],66:[2,63],69:[2,63],74:[2,63],75:[2,63],76:[2,63],77:[2,63]},{45:[2,17]},{5:[2,13],13:[2,13],14:[2,13],17:[2,13],27:[2,13],32:[2,13],37:[2,13],42:[2,13],45:[2,13],46:[2,13],49:[2,13],53:[2,13]},{31:[1,100]},{31:[2,80],59:[2,80],66:[2,80],74:[2,80],75:[2,80],76:[2,80],77:[2,80]},{31:[2,82]},{18:63,57:102,58:64,59:[1,38],61:101,62:[2,85],63:103,64:65,65:66,66:[1,67],72:23,73:24,74:[1,25],75:[1,26],76:[1,27],77:[1,29],78:28},{30:104,31:[2,55],68:105,69:[1,106]},{31:[2,52],59:[2,52],66:[2,52],69:[2,52],74:[2,52],75:[2,52],76:[2,52],77:[2,52]},{31:[2,54],69:[2,54]},{31:[2,61],35:107,68:108,69:[1,106]},{31:[2,58],59:[2,58],66:[2,58],69:[2,58],74:[2,58],75:[2,58],76:[2,58],77:[2,58]},{31:[2,60],69:[2,60]},{21:[1,109]},{21:[2,44],59:[2,44],66:[2,44],74:[2,44],75:[2,44],76:[2,44],77:[2,44]},{21:[2,46]},{5:[2,21],13:[2,21],14:[2,21],17:[2,21],27:[2,21],32:[2,21],37:[2,21],42:[2,21],45:[2,21],46:[2,21],49:[2,21],53:[2,21]},{21:[2,88],31:[2,88],52:[2,88],62:[2,88],66:[2,88],69:[2,88]},{67:[1,94]},{18:63,57:110,58:64,59:[1,38],66:[1,30],72:23,73:24,74:[1,25],75:[1,26],76:[1,27],77:[1,29],78:28},{5:[2,22],13:[2,22],14:[2,22],17:[2,22],27:[2,22],32:[2,22],37:[2,22],42:[2,22],45:[2,22],46:[2,22],49:[2,22],53:[2,22]},{31:[1,111]},{45:[2,18]},{45:[2,70]},{18:63,31:[2,65],39:112,57:113,58:64,59:[1,38],63:114,64:65,65:66,66:[1,67],69:[2,65],72:23,73:24,74:[1,25],75:[1,26],76:[1,27],77:[1,29],78:28},{5:[2,23],13:[2,23],14:[2,23],17:[2,23],27:[2,23],32:[2,23],37:[2,23],42:[2,23],45:[2,23],46:[2,23],49:[2,23],53:[2,23]},{62:[1,115]},{59:[2,84],62:[2,84],66:[2,84],74:[2,84],75:[2,84],76:[2,84],77:[2,84]},{62:[2,86]},{31:[1,116]},{31:[2,56]},{66:[1,118],70:117},{31:[1,119]},{31:[2,62]},{14:[2,11]},{21:[2,28],31:[2,28],52:[2,28],62:[2,28],66:[2,28],69:[2,28]},{5:[2,20],13:[2,20],14:[2,20],17:[2,20],27:[2,20],32:[2,20],37:[2,20],42:[2,20],45:[2,20],46:[2,20],49:[2,20],53:[2,20]},{31:[2,67],40:120,68:121,69:[1,106]},{31:[2,64],59:[2,64],66:[2,64],69:[2,64],74:[2,64],75:[2,64],76:[2,64],77:[2,64]},{31:[2,66],69:[2,66]},{21:[2,26],31:[2,26],52:[2,26],59:[2,26],62:[2,26],66:[2,26],69:[2,26],74:[2,26],75:[2,26],76:[2,26],77:[2,26]},{13:[2,14],14:[2,14],17:[2,14],27:[2,14],32:[2,14],37:[2,14],42:[2,14],45:[2,14],46:[2,14],49:[2,14],53:[2,14]},{66:[1,123],71:[1,122]},{66:[2,89],71:[2,89]},{13:[2,15],14:[2,15],17:[2,15],27:[2,15],32:[2,15],42:[2,15],45:[2,15],46:[2,15],49:[2,15],53:[2,15]},{31:[1,124]},{31:[2,68]},{31:[2,29]},{66:[2,90],71:[2,90]},{13:[2,16],14:[2,16],17:[2,16],27:[2,16],32:[2,16],37:[2,16],42:[2,16],45:[2,16],46:[2,16],49:[2,16],53:[2,16]}],defaultActions:{4:[2,1],47:[2,48],49:[2,19],53:[2,50],62:[2,74],71:[2,78],76:[2,17],80:[2,82],90:[2,46],97:[2,18],98:[2,70],103:[2,86],105:[2,56],108:[2,62],109:[2,11],121:[2,68],122:[2,29]},parseError:function(a){throw new Error(a)},parse:function(a){function b(){var a;return a=c.lexer.lex()||1,"number"!=typeof a&&(a=c.symbols_[a]||a),a}var c=this,d=[0],e=[null],f=[],g=this.table,h="",i=0,j=0,k=0;this.lexer.setInput(a),this.lexer.yy=this.yy,this.yy.lexer=this.lexer,this.yy.parser=this,"undefined"==typeof this.lexer.yylloc&&(this.lexer.yylloc={});var l=this.lexer.yylloc;f.push(l);var m=this.lexer.options&&this.lexer.options.ranges;"function"==typeof this.yy.parseError&&(this.parseError=this.yy.parseError);for(var n,o,p,q,r,s,t,u,v,w={};;){if(p=d[d.length-1],this.defaultActions[p]?q=this.defaultActions[p]:((null===n||"undefined"==typeof n)&&(n=b()),q=g[p]&&g[p][n]),"undefined"==typeof q||!q.length||!q[0]){var x="";if(!k){v=[];for(s in g[p])this.terminals_[s]&&s>2&&v.push("'"+this.terminals_[s]+"'");x=this.lexer.showPosition?"Parse error on line "+(i+1)+":\n"+this.lexer.showPosition()+"\nExpecting "+v.join(", ")+", got '"+(this.terminals_[n]||n)+"'":"Parse error on line "+(i+1)+": Unexpected "+(1==n?"end of input":"'"+(this.terminals_[n]||n)+"'"),this.parseError(x,{text:this.lexer.match,token:this.terminals_[n]||n,line:this.lexer.yylineno,loc:l,expected:v})}}if(q[0]instanceof Array&&q.length>1)throw new Error("Parse Error: multiple actions possible at state: "+p+", token: "+n);switch(q[0]){case 1:d.push(n),e.push(this.lexer.yytext),f.push(this.lexer.yylloc),d.push(q[1]),n=null,o?(n=o,o=null):(j=this.lexer.yyleng,h=this.lexer.yytext,i=this.lexer.yylineno,l=this.lexer.yylloc,k>0&&k--);break;case 2:if(t=this.productions_[q[1]][1],w.$=e[e.length-t],w._$={first_line:f[f.length-(t||1)].first_line,last_line:f[f.length-1].last_line,first_column:f[f.length-(t||1)].first_column,last_column:f[f.length-1].last_column},m&&(w._$.range=[f[f.length-(t||1)].range[0],f[f.length-1].range[1]]),r=this.performAction.call(w,h,j,i,this.yy,q[1],e,f),"undefined"!=typeof r)return r;t&&(d=d.slice(0,-1*t*2),e=e.slice(0,-1*t),f=f.slice(0,-1*t)),d.push(this.productions_[q[1]][0]),e.push(w.$),f.push(w._$),u=g[d[d.length-2]][d[d.length-1]],d.push(u);break;case 3:return!0}}return!0}},c=function(){var a={EOF:1,parseError:function(a,b){if(!this.yy.parser)throw new Error(a);this.yy.parser.parseError(a,b)},setInput:function(a){return this._input=a,this._more=this._less=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this},input:function(){var a=this._input[0];this.yytext+=a,this.yyleng++,this.offset++,this.match+=a,this.matched+=a;var b=a.match(/(?:\r\n?|\n).*/g);return b?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),a},unput:function(a){var b=a.length,c=a.split(/(?:\r\n?|\n)/g);this._input=a+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-b-1),this.offset-=b;var d=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),c.length-1&&(this.yylineno-=c.length-1);var e=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:c?(c.length===d.length?this.yylloc.first_column:0)+d[d.length-c.length].length-c[0].length:this.yylloc.first_column-b},this.options.ranges&&(this.yylloc.range=[e[0],e[0]+this.yyleng-b]),this},more:function(){return this._more=!0,this},less:function(a){this.unput(this.match.slice(a))},pastInput:function(){var a=this.matched.substr(0,this.matched.length-this.match.length);return(a.length>20?"...":"")+a.substr(-20).replace(/\n/g,"")},upcomingInput:function(){var a=this.match;return a.length<20&&(a+=this._input.substr(0,20-a.length)),(a.substr(0,20)+(a.length>20?"...":"")).replace(/\n/g,"")},showPosition:function(){var a=this.pastInput(),b=new Array(a.length+1).join("-");return a+this.upcomingInput()+"\n"+b+"^"},next:function(){if(this.done)return this.EOF;this._input||(this.done=!0);var a,b,c,d,e;this._more||(this.yytext="",this.match="");for(var f=this._currentRules(),g=0;g<f.length&&(c=this._input.match(this.rules[f[g]]),!c||b&&!(c[0].length>b[0].length)||(b=c,d=g,this.options.flex));g++);return b?(e=b[0].match(/(?:\r\n?|\n).*/g),e&&(this.yylineno+=e.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:e?e[e.length-1].length-e[e.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+b[0].length},this.yytext+=b[0],this.match+=b[0],this.matches=b,this.yyleng=this.yytext.length,this.options.ranges&&(this.yylloc.range=[this.offset,this.offset+=this.yyleng]),this._more=!1,this._input=this._input.slice(b[0].length),this.matched+=b[0],a=this.performAction.call(this,this.yy,this,f[d],this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),a?a:void 0):""===this._input?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+". Unrecognized text.\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},lex:function(){var a=this.next();return"undefined"!=typeof a?a:this.lex()},begin:function(a){this.conditionStack.push(a)},popState:function(){return this.conditionStack.pop()},_currentRules:function(){return this.conditions[this.conditionStack[this.conditionStack.length-1]].rules},topState:function(){return this.conditionStack[this.conditionStack.length-2]},pushState:function(a){this.begin(a)}};return a.options={},a.performAction=function(a,b,c,d){function e(a,c){return b.yytext=b.yytext.substr(a,b.yyleng-c)}switch(c){case 0:if("\\\\"===b.yytext.slice(-2)?(e(0,1),this.begin("mu")):"\\"===b.yytext.slice(-1)?(e(0,1),this.begin("emu")):this.begin("mu"),b.yytext)return 14;break;case 1:return 14;case 2:return this.popState(),14;case 3:return b.yytext=b.yytext.substr(5,b.yyleng-9),this.popState(),16;case 4:return 14;case 5:return this.popState(),13;case 6:return 59;case 7:return 62;case 8:return 17;case 9:return this.popState(),this.begin("raw"),21;case 10:return 53;case 11:return 27;case 12:return 45;case 13:return this.popState(),42;case 14:return this.popState(),42;case 15:return 32;case 16:return 37;case 17:return 49;case 18:return 46;case 19:this.unput(b.yytext),this.popState(),this.begin("com");break;case 20:return this.popState(),13;case 21:return 46;case 22:return 67;case 23:return 66;case 24:return 66;case 25:return 79;case 26:break;case 27:return this.popState(),52;case 28:return this.popState(),31;case 29:return b.yytext=e(1,2).replace(/\\"/g,'"'),74;case 30:return b.yytext=e(1,2).replace(/\\'/g,"'"),74;case 31:return 77;case 32:return 76;case 33:return 76;case 34:return 75;case 35:return 69;case 36:return 71;case 37:return 66;case 38:return b.yytext=e(1,2),66;case 39:return"INVALID";case 40:return 5}},a.rules=[/^(?:[^\x00]*?(?=(\{\{)))/,/^(?:[^\x00]+)/,/^(?:[^\x00]{2,}?(?=(\{\{|\\\{\{|\\\\\{\{|$)))/,/^(?:\{\{\{\{\/[^\s!"#%-,\.\/;->@\[-\^`\{-~]+(?=[=}\s\/.])\}\}\}\})/,/^(?:[^\x00]*?(?=(\{\{\{\{\/)))/,/^(?:[\s\S]*?--(~)?\}\})/,/^(?:\()/,/^(?:\))/,/^(?:\{\{\{\{)/,/^(?:\}\}\}\})/,/^(?:\{\{(~)?>)/,/^(?:\{\{(~)?#)/,/^(?:\{\{(~)?\/)/,/^(?:\{\{(~)?\^\s*(~)?\}\})/,/^(?:\{\{(~)?\s*else\s*(~)?\}\})/,/^(?:\{\{(~)?\^)/,/^(?:\{\{(~)?\s*else\b)/,/^(?:\{\{(~)?\{)/,/^(?:\{\{(~)?&)/,/^(?:\{\{(~)?!--)/,/^(?:\{\{(~)?![\s\S]*?\}\})/,/^(?:\{\{(~)?)/,/^(?:=)/,/^(?:\.\.)/,/^(?:\.(?=([=~}\s\/.)|])))/,/^(?:[\/.])/,/^(?:\s+)/,/^(?:\}(~)?\}\})/,/^(?:(~)?\}\})/,/^(?:"(\\["]|[^"])*")/,/^(?:'(\\[']|[^'])*')/,/^(?:@)/,/^(?:true(?=([~}\s)])))/,/^(?:false(?=([~}\s)])))/,/^(?:-?[0-9]+(?:\.[0-9]+)?(?=([~}\s)])))/,/^(?:as\s+\|)/,/^(?:\|)/,/^(?:([^\s!"#%-,\.\/;->@\[-\^`\{-~]+(?=([=~}\s\/.)|]))))/,/^(?:\[[^\]]*\])/,/^(?:.)/,/^(?:$)/],a.conditions={mu:{rules:[6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40],inclusive:!1},emu:{rules:[2],inclusive:!1},com:{rules:[5],inclusive:!1},raw:{rules:[3,4],inclusive:!1},INITIAL:{rules:[0,1,40],inclusive:!0}},a
}();return b.lexer=c,a.prototype=b,b.Parser=a,new a}();return a=b}(),i=function(a,b){"use strict";function c(){this.parents=[]}var d,e=a,f=b;return c.prototype={constructor:c,mutating:!1,acceptKey:function(a,b){var c=this.accept(a[b]);if(this.mutating){if(c&&(!c.type||!f[c.type]))throw new e('Unexpected node type "'+c.type+'" found when accepting '+b+" on "+a.type);a[b]=c}},acceptRequired:function(a,b){if(this.acceptKey(a,b),!a[b])throw new e(a.type+" requires "+b)},acceptArray:function(a){for(var b=0,c=a.length;c>b;b++)this.acceptKey(a,b),a[b]||(a.splice(b,1),b--,c--)},accept:function(a){if(a){this.current&&this.parents.unshift(this.current),this.current=a;var b=this[a.type](a);return this.current=this.parents.shift(),!this.mutating||b?b:b!==!1?a:void 0}},Program:function(a){this.acceptArray(a.body)},MustacheStatement:function(a){this.acceptRequired(a,"path"),this.acceptArray(a.params),this.acceptKey(a,"hash")},BlockStatement:function(a){this.acceptRequired(a,"path"),this.acceptArray(a.params),this.acceptKey(a,"hash"),this.acceptKey(a,"program"),this.acceptKey(a,"inverse")},PartialStatement:function(a){this.acceptRequired(a,"name"),this.acceptArray(a.params),this.acceptKey(a,"hash")},ContentStatement:function(){},CommentStatement:function(){},SubExpression:function(a){this.acceptRequired(a,"path"),this.acceptArray(a.params),this.acceptKey(a,"hash")},PartialExpression:function(a){this.acceptRequired(a,"name"),this.acceptArray(a.params),this.acceptKey(a,"hash")},PathExpression:function(){},StringLiteral:function(){},NumberLiteral:function(){},BooleanLiteral:function(){},Hash:function(a){this.acceptArray(a.pairs)},HashPair:function(a){this.acceptRequired(a,"value")}},d=c}(b,g),j=function(a){"use strict";function b(){}function c(a,b,c){void 0===b&&(b=a.length);var d=a[b-1],e=a[b-2];return d?"ContentStatement"===d.type?(e||!c?/\r?\n\s*?$/:/(^|\r?\n)\s*?$/).test(d.original):void 0:c}function d(a,b,c){void 0===b&&(b=-1);var d=a[b+1],e=a[b+2];return d?"ContentStatement"===d.type?(e||!c?/^\s*?\r?\n/:/^\s*?(\r?\n|$)/).test(d.original):void 0:c}function e(a,b,c){var d=a[null==b?0:b+1];if(d&&"ContentStatement"===d.type&&(c||!d.rightStripped)){var e=d.value;d.value=d.value.replace(c?/^\s+/:/^[ \t]*\r?\n?/,""),d.rightStripped=d.value!==e}}function f(a,b,c){var d=a[null==b?a.length-1:b-1];if(d&&"ContentStatement"===d.type&&(c||!d.leftStripped)){var e=d.value;return d.value=d.value.replace(c?/\s+$/:/[ \t]+$/,""),d.leftStripped=d.value!==e,d.leftStripped}}var g,h=a;return b.prototype=new h,b.prototype.Program=function(a){var b=!this.isRootSeen;this.isRootSeen=!0;for(var g=a.body,h=0,i=g.length;i>h;h++){var j=g[h],k=this.accept(j);if(k){var l=c(g,h,b),m=d(g,h,b),n=k.openStandalone&&l,o=k.closeStandalone&&m,p=k.inlineStandalone&&l&&m;k.close&&e(g,h,!0),k.open&&f(g,h,!0),p&&(e(g,h),f(g,h)&&"PartialStatement"===j.type&&(j.indent=/([ \t]+$)/.exec(g[h-1].original)[1])),n&&(e((j.program||j.inverse).body),f(g,h)),o&&(e(g,h),f((j.inverse||j.program).body))}}return a},b.prototype.BlockStatement=function(a){this.accept(a.program),this.accept(a.inverse);var b=a.program||a.inverse,g=a.program&&a.inverse,h=g,i=g;if(g&&g.chained)for(h=g.body[0].program;i.chained;)i=i.body[i.body.length-1].program;var j={open:a.openStrip.open,close:a.closeStrip.close,openStandalone:d(b.body),closeStandalone:c((h||b).body)};if(a.openStrip.close&&e(b.body,null,!0),g){var k=a.inverseStrip;k.open&&f(b.body,null,!0),k.close&&e(h.body,null,!0),a.closeStrip.open&&f(i.body,null,!0),c(b.body)&&d(h.body)&&(f(b.body),e(h.body))}else a.closeStrip.open&&f(b.body,null,!0);return j},b.prototype.MustacheStatement=function(a){return a.strip},b.prototype.PartialStatement=b.prototype.CommentStatement=function(a){var b=a.strip||{};return{inlineStandalone:!0,open:b.open,close:b.close}},g=b}(i),k=function(a){"use strict";function b(a,b){this.source=a,this.start={line:b.first_line,column:b.first_column},this.end={line:b.last_line,column:b.last_column}}function c(a,b){return{open:"~"===a.charAt(2),close:"~"===b.charAt(b.length-3)}}function d(a){return a.replace(/^\{\{~?\!-?-?/,"").replace(/-?-?~?\}\}$/,"")}function e(a,b,c){c=this.locInfo(c);for(var d=a?"@":"",e=[],f=0,g="",h=0,i=b.length;i>h;h++){var k=b[h].part;if(d+=(b[h].separator||"")+k,".."===k||"."===k||"this"===k){if(e.length>0)throw new j("Invalid path: "+d,{loc:c});".."===k&&(f++,g+="../")}else e.push(k)}return new this.PathExpression(a,f,e,d,c)}function f(a,b,c,d,e,f){var g=d.charAt(3)||d.charAt(2),h="{"!==g&&"&"!==g;return new this.MustacheStatement(a,b,c,h,e,this.locInfo(f))}function g(a,b,c,d){if(a.path.original!==c){var e={loc:a.path.loc};throw new j(a.path.original+" doesn't match "+c,e)}d=this.locInfo(d);var f=new this.Program([b],null,{},d);return new this.BlockStatement(a.path,a.params,a.hash,f,void 0,{},{},{},d)}function h(a,b,c,d,e,f){if(d&&d.path&&a.path.original!==d.path.original){var g={loc:a.path.loc};throw new j(a.path.original+" doesn't match "+d.path.original,g)}b.blockParams=a.blockParams;var h,i;return c&&(c.chain&&(c.program.body[0].closeStrip=d.strip),i=c.strip,h=c.program),e&&(e=h,h=b,b=e),new this.BlockStatement(a.path,a.params,a.hash,b,h,a.strip,i,d&&d.strip,this.locInfo(f))}var i={},j=a;return i.SourceLocation=b,i.stripFlags=c,i.stripComment=d,i.preparePath=e,i.prepareMustache=f,i.prepareRawBlock=g,i.prepareBlock=h,i}(b),l=function(a,b,c,d,e){"use strict";function f(a,b){if("Program"===a.type)return a;h.yy=m,m.locInfo=function(a){return new m.SourceLocation(b&&b.srcName,a)};var c=new j;return c.accept(h.parse(a))}var g={},h=a,i=b,j=c,k=d,l=e.extend;g.parser=h;var m={};return l(m,k,i),g.parse=f,g}(h,g,j,k,a),m=function(a,b,c){"use strict";function d(){}function e(a,b,c){if(null==a||"string"!=typeof a&&"Program"!==a.type)throw new j("You must pass a string or Handlebars AST to Handlebars.precompile. You passed "+a);b=b||{},"data"in b||(b.data=!0),b.compat&&(b.useDepths=!0);var d=c.parse(a,b),e=(new c.Compiler).compile(d,b);return(new c.JavaScriptCompiler).compile(e,b)}function f(a,b,c){function d(){var d=c.parse(a,b),e=(new c.Compiler).compile(d,b),f=(new c.JavaScriptCompiler).compile(e,b,void 0,!0);return c.template(f)}if(null==a||"string"!=typeof a&&"Program"!==a.type)throw new j("You must pass a string or Handlebars AST to Handlebars.compile. You passed "+a);b=b||{},"data"in b||(b.data=!0),b.compat&&(b.useDepths=!0);var e,f=function(a,b){return e||(e=d()),e.call(this,a,b)};return f._setup=function(a){return e||(e=d()),e._setup(a)},f._child=function(a,b,c,f){return e||(e=d()),e._child(a,b,c,f)},f}function g(a,b){if(a===b)return!0;if(k(a)&&k(b)&&a.length===b.length){for(var c=0;c<a.length;c++)if(!g(a[c],b[c]))return!1;return!0}}function h(a){if(!a.path.parts){var b=a.path;a.path=new m.PathExpression(!1,0,[b.original+""],b.original+"",b.log)}}var i={},j=a,k=b.isArray,l=b.indexOf,m=c,n=[].slice;return i.Compiler=d,d.prototype={compiler:d,equals:function(a){var b=this.opcodes.length;if(a.opcodes.length!==b)return!1;for(var c=0;b>c;c++){var d=this.opcodes[c],e=a.opcodes[c];if(d.opcode!==e.opcode||!g(d.args,e.args))return!1}for(b=this.children.length,c=0;b>c;c++)if(!this.children[c].equals(a.children[c]))return!1;return!0},guid:0,compile:function(a,b){this.sourceNode=[],this.opcodes=[],this.children=[],this.options=b,this.stringParams=b.stringParams,this.trackIds=b.trackIds,b.blockParams=b.blockParams||[];var c=b.knownHelpers;if(b.knownHelpers={helperMissing:!0,blockHelperMissing:!0,each:!0,"if":!0,unless:!0,"with":!0,log:!0,lookup:!0},c)for(var d in c)b.knownHelpers[d]=c[d];return this.accept(a)},compileProgram:function(a){var b=(new this.compiler).compile(a,this.options),c=this.guid++;return this.usePartial=this.usePartial||b.usePartial,this.children[c]=b,this.useDepths=this.useDepths||b.useDepths,c},accept:function(a){this.sourceNode.unshift(a);var b=this[a.type](a);return this.sourceNode.shift(),b},Program:function(a){this.options.blockParams.unshift(a.blockParams);for(var b=a.body,c=0,d=b.length;d>c;c++)this.accept(b[c]);return this.options.blockParams.shift(),this.isSimple=1===d,this.blockParams=a.blockParams?a.blockParams.length:0,this},BlockStatement:function(a){h(a);var b=a.program,c=a.inverse;b=b&&this.compileProgram(b),c=c&&this.compileProgram(c);var d=this.classifySexpr(a);"helper"===d?this.helperSexpr(a,b,c):"simple"===d?(this.simpleSexpr(a),this.opcode("pushProgram",b),this.opcode("pushProgram",c),this.opcode("emptyHash"),this.opcode("blockValue",a.path.original)):(this.ambiguousSexpr(a,b,c),this.opcode("pushProgram",b),this.opcode("pushProgram",c),this.opcode("emptyHash"),this.opcode("ambiguousBlockValue")),this.opcode("append")},PartialStatement:function(a){this.usePartial=!0;var b=a.params;if(b.length>1)throw new j("Unsupported number of partial arguments: "+b.length,a);b.length||b.push({type:"PathExpression",parts:[],depth:0});var c=a.name.original,d="SubExpression"===a.name.type;d&&this.accept(a.name),this.setupFullMustacheParams(a,void 0,void 0,!0);var e=a.indent||"";this.options.preventIndent&&e&&(this.opcode("appendContent",e),e=""),this.opcode("invokePartial",d,c,e),this.opcode("append")},MustacheStatement:function(a){this.SubExpression(a),this.opcode(a.escaped&&!this.options.noEscape?"appendEscaped":"append")},ContentStatement:function(a){a.value&&this.opcode("appendContent",a.value)},CommentStatement:function(){},SubExpression:function(a){h(a);var b=this.classifySexpr(a);"simple"===b?this.simpleSexpr(a):"helper"===b?this.helperSexpr(a):this.ambiguousSexpr(a)},ambiguousSexpr:function(a,b,c){var d=a.path,e=d.parts[0],f=null!=b||null!=c;this.opcode("getContext",d.depth),this.opcode("pushProgram",b),this.opcode("pushProgram",c),this.accept(d),this.opcode("invokeAmbiguous",e,f)},simpleSexpr:function(a){this.accept(a.path),this.opcode("resolvePossibleLambda")},helperSexpr:function(a,b,c){var d=this.setupFullMustacheParams(a,b,c),e=a.path,f=e.parts[0];if(this.options.knownHelpers[f])this.opcode("invokeKnownHelper",d.length,f);else{if(this.options.knownHelpersOnly)throw new j("You specified knownHelpersOnly, but used the unknown helper "+f,a);e.falsy=!0,this.accept(e),this.opcode("invokeHelper",d.length,e.original,m.helpers.simpleId(e))}},PathExpression:function(a){this.addDepth(a.depth),this.opcode("getContext",a.depth);var b=a.parts[0],c=m.helpers.scopedId(a),d=!a.depth&&!c&&this.blockParamIndex(b);d?this.opcode("lookupBlockParam",d,a.parts):b?a.data?(this.options.data=!0,this.opcode("lookupData",a.depth,a.parts)):this.opcode("lookupOnContext",a.parts,a.falsy,c):this.opcode("pushContext")},StringLiteral:function(a){this.opcode("pushString",a.value)},NumberLiteral:function(a){this.opcode("pushLiteral",a.value)},BooleanLiteral:function(a){this.opcode("pushLiteral",a.value)},Hash:function(a){var b,c,d=a.pairs;for(this.opcode("pushHash"),b=0,c=d.length;c>b;b++)this.pushParam(d[b].value);for(;b--;)this.opcode("assignToHash",d[b].key);this.opcode("popHash")},opcode:function(a){this.opcodes.push({opcode:a,args:n.call(arguments,1),loc:this.sourceNode[0].loc})},addDepth:function(a){a&&(this.useDepths=!0)},classifySexpr:function(a){var b=m.helpers.simpleId(a.path),c=b&&!!this.blockParamIndex(a.path.parts[0]),d=!c&&m.helpers.helperExpression(a),e=!c&&(d||b),f=this.options;if(e&&!d){var g=a.path.parts[0];f.knownHelpers[g]?d=!0:f.knownHelpersOnly&&(e=!1)}return d?"helper":e?"ambiguous":"simple"},pushParams:function(a){for(var b=0,c=a.length;c>b;b++)this.pushParam(a[b])},pushParam:function(a){var b=null!=a.value?a.value:a.original||"";if(this.stringParams)b.replace&&(b=b.replace(/^(\.?\.\/)*/g,"").replace(/\//g,".")),a.depth&&this.addDepth(a.depth),this.opcode("getContext",a.depth||0),this.opcode("pushStringParam",b,a.type),"SubExpression"===a.type&&this.accept(a);else{if(this.trackIds){var c;if(!a.parts||m.helpers.scopedId(a)||a.depth||(c=this.blockParamIndex(a.parts[0])),c){var d=a.parts.slice(1).join(".");this.opcode("pushId","BlockParam",c,d)}else b=a.original||b,b.replace&&(b=b.replace(/^\.\//g,"").replace(/^\.$/g,"")),this.opcode("pushId",a.type,b)}this.accept(a)}},setupFullMustacheParams:function(a,b,c,d){var e=a.params;return this.pushParams(e),this.opcode("pushProgram",b),this.opcode("pushProgram",c),a.hash?this.accept(a.hash):this.opcode("emptyHash",d),e},blockParamIndex:function(a){for(var b=0,c=this.options.blockParams.length;c>b;b++){var d=this.options.blockParams[b],e=d&&l(d,a);if(d&&e>=0)return[b,e]}}},i.precompile=e,i.compile=f,i}(b,a,g),n=function(a){"use strict";function b(a,b,c){if(e(a)){for(var d=[],f=0,g=a.length;g>f;f++)d.push(b.wrap(a[f],c));return d}return"boolean"==typeof a||"number"==typeof a?a+"":a}function c(a){this.srcFile=a,this.source=[]}var d,e=a.isArray;try{var f=require("source-map"),g=f.SourceNode}catch(h){g=function(a,b,c,d){this.src="",d&&this.add(d)},g.prototype={add:function(a){e(a)&&(a=a.join("")),this.src+=a},prepend:function(a){e(a)&&(a=a.join("")),this.src=a+this.src},toStringWithSourceMap:function(){return{code:this.toString()}},toString:function(){return this.src}}}return c.prototype={prepend:function(a,b){this.source.unshift(this.wrap(a,b))},push:function(a,b){this.source.push(this.wrap(a,b))},merge:function(){var a=this.empty();return this.each(function(b){a.add(["  ",b,"\n"])}),a},each:function(a){for(var b=0,c=this.source.length;c>b;b++)a(this.source[b])},empty:function(a){return a=a||this.currentLocation||{start:{}},new g(a.start.line,a.start.column,this.srcFile)},wrap:function(a,c){return a instanceof g?a:(c=c||this.currentLocation||{start:{}},a=b(a,this,c),new g(c.start.line,c.start.column,this.srcFile,a))},functionCall:function(a,b,c){return c=this.generateList(c),this.wrap([a,b?"."+b+"(":"(",c,")"])},quotedString:function(a){return'"'+(a+"").replace(/\\/g,"\\\\").replace(/"/g,'\\"').replace(/\n/g,"\\n").replace(/\r/g,"\\r").replace(/\u2028/g,"\\u2028").replace(/\u2029/g,"\\u2029")+'"'},objectLiteral:function(a){var c=[];for(var d in a)if(a.hasOwnProperty(d)){var e=b(a[d],this);"undefined"!==e&&c.push([this.quotedString(d),":",e])}var f=this.generateList(c);return f.prepend("{"),f.add("}"),f},generateList:function(a,c){for(var d=this.empty(c),e=0,f=a.length;f>e;e++)e&&d.add(","),d.add(b(a[e],this,c));return d},generateArray:function(a,b){var c=this.generateList(a,b);return c.prepend("["),c.add("]"),c}},d=c}(a),o=function(a,b,c,d){"use strict";function e(a){this.value=a}function f(){}function g(a,b,c,d){var e=b.popStack(),f=0,g=c.length;for(a&&g--;g>f;f++)e=b.nameLookup(e,c[f],d);return a?[b.aliasable("this.strict"),"(",e,", ",b.quotedString(c[f]),")"]:e}var h,i=a.COMPILER_REVISION,j=a.REVISION_CHANGES,k=b,l=c.isArray,m=d;f.prototype={nameLookup:function(a,b){return f.isValidJavaScriptVariableName(b)?[a,".",b]:[a,"['",b,"']"]},depthedLookup:function(a){return[this.aliasable("this.lookup"),'(depths, "',a,'")']},compilerInfo:function(){var a=i,b=j[a];return[a,b]},appendToBuffer:function(a,b,c){return l(a)||(a=[a]),a=this.source.wrap(a,b),this.environment.isSimple?["return ",a,";"]:c?["buffer += ",a,";"]:(a.appendToBuffer=!0,a)},initializeBuffer:function(){return this.quotedString("")},compile:function(a,b,c,d){this.environment=a,this.options=b,this.stringParams=this.options.stringParams,this.trackIds=this.options.trackIds,this.precompile=!d,this.name=this.environment.name,this.isChild=!!c,this.context=c||{programs:[],environments:[]},this.preamble(),this.stackSlot=0,this.stackVars=[],this.aliases={},this.registers={list:[]},this.hashes=[],this.compileStack=[],this.inlineStack=[],this.blockParams=[],this.compileChildren(a,b),this.useDepths=this.useDepths||a.useDepths||this.options.compat,this.useBlockParams=this.useBlockParams||a.useBlockParams;var e,f,g,h,i=a.opcodes;for(g=0,h=i.length;h>g;g++)e=i[g],this.source.currentLocation=e.loc,f=f||e.loc,this[e.opcode].apply(this,e.args);if(this.source.currentLocation=f,this.pushSource(""),this.stackSlot||this.inlineStack.length||this.compileStack.length)throw new k("Compile completed with content left on stack");var j=this.createFunctionContext(d);if(this.isChild)return j;var l={compiler:this.compilerInfo(),main:j},m=this.context.programs;for(g=0,h=m.length;h>g;g++)m[g]&&(l[g]=m[g]);return this.environment.usePartial&&(l.usePartial=!0),this.options.data&&(l.useData=!0),this.useDepths&&(l.useDepths=!0),this.useBlockParams&&(l.useBlockParams=!0),this.options.compat&&(l.compat=!0),d?l.compilerOptions=this.options:(l.compiler=JSON.stringify(l.compiler),this.source.currentLocation={start:{line:1,column:0}},l=this.objectLiteral(l),b.srcName?(l=l.toStringWithSourceMap({file:b.destName}),l.map=l.map&&l.map.toString()):l=l.toString()),l},preamble:function(){this.lastContext=0,this.source=new m(this.options.srcName)},createFunctionContext:function(a){var b="",c=this.stackVars.concat(this.registers.list);c.length>0&&(b+=", "+c.join(", "));var d=0;for(var e in this.aliases){var f=this.aliases[e];this.aliases.hasOwnProperty(e)&&f.children&&f.referenceCount>1&&(b+=", alias"+ ++d+"="+e,f.children[0]="alias"+d)}var g=["depth0","helpers","partials","data"];(this.useBlockParams||this.useDepths)&&g.push("blockParams"),this.useDepths&&g.push("depths");var h=this.mergeSource(b);return a?(g.push(h),Function.apply(this,g)):this.source.wrap(["function(",g.join(","),") {\n  ",h,"}"])},mergeSource:function(a){var b,c,d,e,f=this.environment.isSimple,g=!this.forceBuffer;return this.source.each(function(a){a.appendToBuffer?(d?a.prepend("  + "):d=a,e=a):(d&&(c?d.prepend("buffer += "):b=!0,e.add(";"),d=e=void 0),c=!0,f||(g=!1))}),g?d?(d.prepend("return "),e.add(";")):c||this.source.push('return "";'):(a+=", buffer = "+(b?"":this.initializeBuffer()),d?(d.prepend("return buffer + "),e.add(";")):this.source.push("return buffer;")),a&&this.source.prepend("var "+a.substring(2)+(b?"":";\n")),this.source.merge()},blockValue:function(a){var b=this.aliasable("helpers.blockHelperMissing"),c=[this.contextName(0)];this.setupHelperArgs(a,0,c);var d=this.popStack();c.splice(1,0,d),this.push(this.source.functionCall(b,"call",c))},ambiguousBlockValue:function(){var a=this.aliasable("helpers.blockHelperMissing"),b=[this.contextName(0)];this.setupHelperArgs("",0,b,!0),this.flushInline();var c=this.topStack();b.splice(1,0,c),this.pushSource(["if (!",this.lastHelper,") { ",c," = ",this.source.functionCall(a,"call",b),"}"])},appendContent:function(a){this.pendingContent?a=this.pendingContent+a:this.pendingLocation=this.source.currentLocation,this.pendingContent=a},append:function(){if(this.isInline())this.replaceStack(function(a){return[" != null ? ",a,' : ""']}),this.pushSource(this.appendToBuffer(this.popStack()));else{var a=this.popStack();this.pushSource(["if (",a," != null) { ",this.appendToBuffer(a,void 0,!0)," }"]),this.environment.isSimple&&this.pushSource(["else { ",this.appendToBuffer("''",void 0,!0)," }"])}},appendEscaped:function(){this.pushSource(this.appendToBuffer([this.aliasable("this.escapeExpression"),"(",this.popStack(),")"]))},getContext:function(a){this.lastContext=a},pushContext:function(){this.pushStackLiteral(this.contextName(this.lastContext))},lookupOnContext:function(a,b,c){var d=0;c||!this.options.compat||this.lastContext?this.pushContext():this.push(this.depthedLookup(a[d++])),this.resolvePath("context",a,d,b)},lookupBlockParam:function(a,b){this.useBlockParams=!0,this.push(["blockParams[",a[0],"][",a[1],"]"]),this.resolvePath("context",b,1)},lookupData:function(a,b){this.pushStackLiteral(a?"this.data(data, "+a+")":"data"),this.resolvePath("data",b,0,!0)},resolvePath:function(a,b,c,d){if(this.options.strict||this.options.assumeObjects)return void this.push(g(this.options.strict,this,b,a));for(var e=b.length;e>c;c++)this.replaceStack(function(e){var f=this.nameLookup(e,b[c],a);return d?[" && ",f]:[" != null ? ",f," : ",e]})},resolvePossibleLambda:function(){this.push([this.aliasable("this.lambda"),"(",this.popStack(),", ",this.contextName(0),")"])},pushStringParam:function(a,b){this.pushContext(),this.pushString(b),"SubExpression"!==b&&("string"==typeof a?this.pushString(a):this.pushStackLiteral(a))},emptyHash:function(a){this.trackIds&&this.push("{}"),this.stringParams&&(this.push("{}"),this.push("{}")),this.pushStackLiteral(a?"undefined":"{}")},pushHash:function(){this.hash&&this.hashes.push(this.hash),this.hash={values:[],types:[],contexts:[],ids:[]}},popHash:function(){var a=this.hash;this.hash=this.hashes.pop(),this.trackIds&&this.push(this.objectLiteral(a.ids)),this.stringParams&&(this.push(this.objectLiteral(a.contexts)),this.push(this.objectLiteral(a.types))),this.push(this.objectLiteral(a.values))},pushString:function(a){this.pushStackLiteral(this.quotedString(a))},pushLiteral:function(a){this.pushStackLiteral(a)},pushProgram:function(a){this.pushStackLiteral(null!=a?this.programExpression(a):null)},invokeHelper:function(a,b,c){var d=this.popStack(),e=this.setupHelper(a,b),f=c?[e.name," || "]:"",g=["("].concat(f,d);this.options.strict||g.push(" || ",this.aliasable("helpers.helperMissing")),g.push(")"),this.push(this.source.functionCall(g,"call",e.callParams))},invokeKnownHelper:function(a,b){var c=this.setupHelper(a,b);this.push(this.source.functionCall(c.name,"call",c.callParams))},invokeAmbiguous:function(a,b){this.useRegister("helper");var c=this.popStack();this.emptyHash();var d=this.setupHelper(0,a,b),e=this.lastHelper=this.nameLookup("helpers",a,"helper"),f=["(","(helper = ",e," || ",c,")"];this.options.strict||(f[0]="(helper = ",f.push(" != null ? helper : ",this.aliasable("helpers.helperMissing"))),this.push(["(",f,d.paramsInit?["),(",d.paramsInit]:[],"),","(typeof helper === ",this.aliasable('"function"')," ? ",this.source.functionCall("helper","call",d.callParams)," : helper))"])},invokePartial:function(a,b,c){var d=[],e=this.setupParams(b,1,d,!1);a&&(b=this.popStack(),delete e.name),c&&(e.indent=JSON.stringify(c)),e.helpers="helpers",e.partials="partials",d.unshift(a?b:this.nameLookup("partials",b,"partial")),this.options.compat&&(e.depths="depths"),e=this.objectLiteral(e),d.push(e),this.push(this.source.functionCall("this.invokePartial","",d))},assignToHash:function(a){var b,c,d,e=this.popStack();this.trackIds&&(d=this.popStack()),this.stringParams&&(c=this.popStack(),b=this.popStack());var f=this.hash;b&&(f.contexts[a]=b),c&&(f.types[a]=c),d&&(f.ids[a]=d),f.values[a]=e},pushId:function(a,b,c){"BlockParam"===a?this.pushStackLiteral("blockParams["+b[0]+"].path["+b[1]+"]"+(c?" + "+JSON.stringify("."+c):"")):"PathExpression"===a?this.pushString(b):this.pushStackLiteral("SubExpression"===a?"true":"null")},compiler:f,compileChildren:function(a,b){for(var c,d,e=a.children,f=0,g=e.length;g>f;f++){c=e[f],d=new this.compiler;var h=this.matchExistingProgram(c);null==h?(this.context.programs.push(""),h=this.context.programs.length,c.index=h,c.name="program"+h,this.context.programs[h]=d.compile(c,b,this.context,!this.precompile),this.context.environments[h]=c,this.useDepths=this.useDepths||d.useDepths,this.useBlockParams=this.useBlockParams||d.useBlockParams):(c.index=h,c.name="program"+h,this.useDepths=this.useDepths||c.useDepths,this.useBlockParams=this.useBlockParams||c.useBlockParams)}},matchExistingProgram:function(a){for(var b=0,c=this.context.environments.length;c>b;b++){var d=this.context.environments[b];if(d&&d.equals(a))return b}},programExpression:function(a){var b=this.environment.children[a],c=[b.index,"data",b.blockParams];return(this.useBlockParams||this.useDepths)&&c.push("blockParams"),this.useDepths&&c.push("depths"),"this.program("+c.join(", ")+")"},useRegister:function(a){this.registers[a]||(this.registers[a]=!0,this.registers.list.push(a))},push:function(a){return a instanceof e||(a=this.source.wrap(a)),this.inlineStack.push(a),a},pushStackLiteral:function(a){this.push(new e(a))},pushSource:function(a){this.pendingContent&&(this.source.push(this.appendToBuffer(this.source.quotedString(this.pendingContent),this.pendingLocation)),this.pendingContent=void 0),a&&this.source.push(a)},replaceStack:function(a){var b,c,d,f=["("];if(!this.isInline())throw new k("replaceStack on non-inline");var g=this.popStack(!0);if(g instanceof e)b=[g.value],f=["(",b],d=!0;else{c=!0;var h=this.incrStack();f=["((",this.push(h)," = ",g,")"],b=this.topStack()}var i=a.call(this,b);d||this.popStack(),c&&this.stackSlot--,this.push(f.concat(i,")"))},incrStack:function(){return this.stackSlot++,this.stackSlot>this.stackVars.length&&this.stackVars.push("stack"+this.stackSlot),this.topStackName()},topStackName:function(){return"stack"+this.stackSlot},flushInline:function(){var a=this.inlineStack;this.inlineStack=[];for(var b=0,c=a.length;c>b;b++){var d=a[b];if(d instanceof e)this.compileStack.push(d);else{var f=this.incrStack();this.pushSource([f," = ",d,";"]),this.compileStack.push(f)}}},isInline:function(){return this.inlineStack.length},popStack:function(a){var b=this.isInline(),c=(b?this.inlineStack:this.compileStack).pop();if(!a&&c instanceof e)return c.value;if(!b){if(!this.stackSlot)throw new k("Invalid stack pop");this.stackSlot--}return c},topStack:function(){var a=this.isInline()?this.inlineStack:this.compileStack,b=a[a.length-1];return b instanceof e?b.value:b},contextName:function(a){return this.useDepths&&a?"depths["+a+"]":"depth"+a},quotedString:function(a){return this.source.quotedString(a)},objectLiteral:function(a){return this.source.objectLiteral(a)},aliasable:function(a){var b=this.aliases[a];return b?(b.referenceCount++,b):(b=this.aliases[a]=this.source.wrap(a),b.aliasable=!0,b.referenceCount=1,b)},setupHelper:function(a,b,c){var d=[],e=this.setupHelperArgs(b,a,d,c),f=this.nameLookup("helpers",b,"helper");return{params:d,paramsInit:e,name:f,callParams:[this.contextName(0)].concat(d)}},setupParams:function(a,b,c){var d,e={},f=[],g=[],h=[];e.name=this.quotedString(a),e.hash=this.popStack(),this.trackIds&&(e.hashIds=this.popStack()),this.stringParams&&(e.hashTypes=this.popStack(),e.hashContexts=this.popStack());var i=this.popStack(),j=this.popStack();(j||i)&&(e.fn=j||"this.noop",e.inverse=i||"this.noop");for(var k=b;k--;)d=this.popStack(),c[k]=d,this.trackIds&&(h[k]=this.popStack()),this.stringParams&&(g[k]=this.popStack(),f[k]=this.popStack());return this.trackIds&&(e.ids=this.source.generateArray(h)),this.stringParams&&(e.types=this.source.generateArray(g),e.contexts=this.source.generateArray(f)),this.options.data&&(e.data="data"),this.useBlockParams&&(e.blockParams="blockParams"),e},setupHelperArgs:function(a,b,c,d){var e=this.setupParams(a,b,c,!0);return e=this.objectLiteral(e),d?(this.useRegister("options"),c.push("options"),["options=",e]):(c.push(e),"")}};for(var n="break else new var case finally return void catch for switch while continue function this with default if throw delete in try do instanceof typeof abstract enum int short boolean export interface static byte extends long super char final native synchronized class float package throws const goto private transient debugger implements protected volatile double import public let yield await null true false".split(" "),o=f.RESERVED_WORDS={},p=0,q=n.length;q>p;p++)o[n[p]]=!0;return f.isValidJavaScriptVariableName=function(a){return!f.RESERVED_WORDS[a]&&/^[a-zA-Z_$][0-9a-zA-Z_$]*$/.test(a)},h=f}(c,b,a,n),p=function(a,b,c,d,e){"use strict";var f,g=a,h=b,i=c.parser,j=c.parse,k=d.Compiler,l=d.compile,m=d.precompile,n=e,o=g.create,p=function(){var a=o();return a.compile=function(b,c){return l(b,c,a)},a.precompile=function(b,c){return m(b,c,a)},a.AST=h,a.Compiler=k,a.JavaScriptCompiler=n,a.Parser=i,a.parse=j,a};g=p(),g.create=p;var q="undefined"!=typeof global?global:window,r=q.Handlebars;return g.noConflict=function(){q.Handlebars===g&&(q.Handlebars=r)},g["default"]=g,f=g}(f,g,l,m,o);return p});
/* HandlebarsHelpers.js */

var HandlebarsHelpers = function(){
/* jshint ignore:start */

	/**
	 * Replace \n with br tags
	 * @return {[type]} [description]
	 */
	Handlebars.registerHelper('breaklines', function(text) {
		text = Handlebars.Utils.escapeExpression(text);
		text = text.replace(/(\r\n|\n|\r)/gm, '<br />');
		return new Handlebars.SafeString(text);
	});

	/**
	 * Compare a value
	 * @return {[type]} [description]
	 */
	Handlebars.registerHelper('compare', function(lvalue, rvalue, options) {

		if (arguments.length < 3) {
			throw new Error("Handlerbars Helper 'compare' needs 2 parameters");
		}

		operator = options.hash.operator || "==";

		var operators = {
			'==':       function(l,r) { return l == r; },
			'===':      function(l,r) { return l === r; },
			'!=':       function(l,r) { return l != r; },
			'<':        function(l,r) { return l < r; },
			'>':        function(l,r) { return l > r; },
			'<=':       function(l,r) { return l <= r; },
			'>=':       function(l,r) { return l >= r; },
			'typeof':   function(l,r) { return typeof l == r; }
		}

		if (!operators[operator]) {
			throw new Error("Handlerbars Helper 'compare' doesn't know the operator "+operator);
		}

		var result = operators[operator](lvalue,rvalue);

		if (result) {
			return options.fn(this);
		} else {
			return options.inverse(this);
		}

	});

/* jshint ignore:end */
};

/* imagesloaded.pkgd.min.js */
/*!
 * imagesLoaded PACKAGED v3.1.8
 * JavaScript is all like "You images are done yet or what?"
 * MIT License
 */

(function(){function e(){}function t(e,t){for(var n=e.length;n--;)if(e[n].listener===t)return n;return-1}function n(e){return function(){return this[e].apply(this,arguments)}}var i=e.prototype,r=this,o=r.EventEmitter;i.getListeners=function(e){var t,n,i=this._getEvents();if("object"==typeof e){t={};for(n in i)i.hasOwnProperty(n)&&e.test(n)&&(t[n]=i[n])}else t=i[e]||(i[e]=[]);return t},i.flattenListeners=function(e){var t,n=[];for(t=0;e.length>t;t+=1)n.push(e[t].listener);return n},i.getListenersAsObject=function(e){var t,n=this.getListeners(e);return n instanceof Array&&(t={},t[e]=n),t||n},i.addListener=function(e,n){var i,r=this.getListenersAsObject(e),o="object"==typeof n;for(i in r)r.hasOwnProperty(i)&&-1===t(r[i],n)&&r[i].push(o?n:{listener:n,once:!1});return this},i.on=n("addListener"),i.addOnceListener=function(e,t){return this.addListener(e,{listener:t,once:!0})},i.once=n("addOnceListener"),i.defineEvent=function(e){return this.getListeners(e),this},i.defineEvents=function(e){for(var t=0;e.length>t;t+=1)this.defineEvent(e[t]);return this},i.removeListener=function(e,n){var i,r,o=this.getListenersAsObject(e);for(r in o)o.hasOwnProperty(r)&&(i=t(o[r],n),-1!==i&&o[r].splice(i,1));return this},i.off=n("removeListener"),i.addListeners=function(e,t){return this.manipulateListeners(!1,e,t)},i.removeListeners=function(e,t){return this.manipulateListeners(!0,e,t)},i.manipulateListeners=function(e,t,n){var i,r,o=e?this.removeListener:this.addListener,s=e?this.removeListeners:this.addListeners;if("object"!=typeof t||t instanceof RegExp)for(i=n.length;i--;)o.call(this,t,n[i]);else for(i in t)t.hasOwnProperty(i)&&(r=t[i])&&("function"==typeof r?o.call(this,i,r):s.call(this,i,r));return this},i.removeEvent=function(e){var t,n=typeof e,i=this._getEvents();if("string"===n)delete i[e];else if("object"===n)for(t in i)i.hasOwnProperty(t)&&e.test(t)&&delete i[t];else delete this._events;return this},i.removeAllListeners=n("removeEvent"),i.emitEvent=function(e,t){var n,i,r,o,s=this.getListenersAsObject(e);for(r in s)if(s.hasOwnProperty(r))for(i=s[r].length;i--;)n=s[r][i],n.once===!0&&this.removeListener(e,n.listener),o=n.listener.apply(this,t||[]),o===this._getOnceReturnValue()&&this.removeListener(e,n.listener);return this},i.trigger=n("emitEvent"),i.emit=function(e){var t=Array.prototype.slice.call(arguments,1);return this.emitEvent(e,t)},i.setOnceReturnValue=function(e){return this._onceReturnValue=e,this},i._getOnceReturnValue=function(){return this.hasOwnProperty("_onceReturnValue")?this._onceReturnValue:!0},i._getEvents=function(){return this._events||(this._events={})},e.noConflict=function(){return r.EventEmitter=o,e},"function"==typeof define&&define.amd?define("eventEmitter/EventEmitter",[],function(){return e}):"object"==typeof module&&module.exports?module.exports=e:this.EventEmitter=e}).call(this),function(e){function t(t){var n=e.event;return n.target=n.target||n.srcElement||t,n}var n=document.documentElement,i=function(){};n.addEventListener?i=function(e,t,n){e.addEventListener(t,n,!1)}:n.attachEvent&&(i=function(e,n,i){e[n+i]=i.handleEvent?function(){var n=t(e);i.handleEvent.call(i,n)}:function(){var n=t(e);i.call(e,n)},e.attachEvent("on"+n,e[n+i])});var r=function(){};n.removeEventListener?r=function(e,t,n){e.removeEventListener(t,n,!1)}:n.detachEvent&&(r=function(e,t,n){e.detachEvent("on"+t,e[t+n]);try{delete e[t+n]}catch(i){e[t+n]=void 0}});var o={bind:i,unbind:r};"function"==typeof define&&define.amd?define("eventie/eventie",o):e.eventie=o}(this),function(e,t){"function"==typeof define&&define.amd?define(["eventEmitter/EventEmitter","eventie/eventie"],function(n,i){return t(e,n,i)}):"object"==typeof exports?module.exports=t(e,require("wolfy87-eventemitter"),require("eventie")):e.imagesLoaded=t(e,e.EventEmitter,e.eventie)}(window,function(e,t,n){function i(e,t){for(var n in t)e[n]=t[n];return e}function r(e){return"[object Array]"===d.call(e)}function o(e){var t=[];if(r(e))t=e;else if("number"==typeof e.length)for(var n=0,i=e.length;i>n;n++)t.push(e[n]);else t.push(e);return t}function s(e,t,n){if(!(this instanceof s))return new s(e,t);"string"==typeof e&&(e=document.querySelectorAll(e)),this.elements=o(e),this.options=i({},this.options),"function"==typeof t?n=t:i(this.options,t),n&&this.on("always",n),this.getImages(),a&&(this.jqDeferred=new a.Deferred);var r=this;setTimeout(function(){r.check()})}function f(e){this.img=e}function c(e){this.src=e,v[e]=this}var a=e.jQuery,u=e.console,h=u!==void 0,d=Object.prototype.toString;s.prototype=new t,s.prototype.options={},s.prototype.getImages=function(){this.images=[];for(var e=0,t=this.elements.length;t>e;e++){var n=this.elements[e];"IMG"===n.nodeName&&this.addImage(n);var i=n.nodeType;if(i&&(1===i||9===i||11===i))for(var r=n.querySelectorAll("img"),o=0,s=r.length;s>o;o++){var f=r[o];this.addImage(f)}}},s.prototype.addImage=function(e){var t=new f(e);this.images.push(t)},s.prototype.check=function(){function e(e,r){return t.options.debug&&h&&u.log("confirm",e,r),t.progress(e),n++,n===i&&t.complete(),!0}var t=this,n=0,i=this.images.length;if(this.hasAnyBroken=!1,!i)return this.complete(),void 0;for(var r=0;i>r;r++){var o=this.images[r];o.on("confirm",e),o.check()}},s.prototype.progress=function(e){this.hasAnyBroken=this.hasAnyBroken||!e.isLoaded;var t=this;setTimeout(function(){t.emit("progress",t,e),t.jqDeferred&&t.jqDeferred.notify&&t.jqDeferred.notify(t,e)})},s.prototype.complete=function(){var e=this.hasAnyBroken?"fail":"done";this.isComplete=!0;var t=this;setTimeout(function(){if(t.emit(e,t),t.emit("always",t),t.jqDeferred){var n=t.hasAnyBroken?"reject":"resolve";t.jqDeferred[n](t)}})},a&&(a.fn.imagesLoaded=function(e,t){var n=new s(this,e,t);return n.jqDeferred.promise(a(this))}),f.prototype=new t,f.prototype.check=function(){var e=v[this.img.src]||new c(this.img.src);if(e.isConfirmed)return this.confirm(e.isLoaded,"cached was confirmed"),void 0;if(this.img.complete&&void 0!==this.img.naturalWidth)return this.confirm(0!==this.img.naturalWidth,"naturalWidth"),void 0;var t=this;e.on("confirm",function(e,n){return t.confirm(e.isLoaded,n),!0}),e.check()},f.prototype.confirm=function(e,t){this.isLoaded=e,this.emit("confirm",this,t)};var v={};return c.prototype=new t,c.prototype.check=function(){if(!this.isChecked){var e=new Image;n.bind(e,"load",this),n.bind(e,"error",this),e.src=this.src,this.isChecked=!0}},c.prototype.handleEvent=function(e){var t="on"+e.type;this[t]&&this[t](e)},c.prototype.onload=function(e){this.confirm(!0,"onload"),this.unbindProxyEvents(e)},c.prototype.onerror=function(e){this.confirm(!1,"onerror"),this.unbindProxyEvents(e)},c.prototype.confirm=function(e,t){this.isConfirmed=!0,this.isLoaded=e,this.emit("confirm",this,t)},c.prototype.unbindProxyEvents=function(e){n.unbind(e.target,"load",this),n.unbind(e.target,"error",this)},s});
/* masonry.pkgd.min.js */
/*!
 * Masonry PACKAGED v3.2.2
 * Cascading grid layout library
 * http://masonry.desandro.com
 * MIT License
 * by David DeSandro
 */

!function(a){function b(){}function c(a){function c(b){b.prototype.option||(b.prototype.option=function(b){a.isPlainObject(b)&&(this.options=a.extend(!0,this.options,b))})}function e(b,c){a.fn[b]=function(e){if("string"==typeof e){for(var g=d.call(arguments,1),h=0,i=this.length;i>h;h++){var j=this[h],k=a.data(j,b);if(k)if(a.isFunction(k[e])&&"_"!==e.charAt(0)){var l=k[e].apply(k,g);if(void 0!==l)return l}else f("no such method '"+e+"' for "+b+" instance");else f("cannot call methods on "+b+" prior to initialization; attempted to call '"+e+"'")}return this}return this.each(function(){var d=a.data(this,b);d?(d.option(e),d._init()):(d=new c(this,e),a.data(this,b,d))})}}if(a){var f="undefined"==typeof console?b:function(a){console.error(a)};return a.bridget=function(a,b){c(b),e(a,b)},a.bridget}}var d=Array.prototype.slice;"function"==typeof define&&define.amd?define("jquery-bridget/jquery.bridget",["jquery"],c):c("object"==typeof exports?require("jquery"):a.jQuery)}(window),function(a){function b(b){var c=a.event;return c.target=c.target||c.srcElement||b,c}var c=document.documentElement,d=function(){};c.addEventListener?d=function(a,b,c){a.addEventListener(b,c,!1)}:c.attachEvent&&(d=function(a,c,d){a[c+d]=d.handleEvent?function(){var c=b(a);d.handleEvent.call(d,c)}:function(){var c=b(a);d.call(a,c)},a.attachEvent("on"+c,a[c+d])});var e=function(){};c.removeEventListener?e=function(a,b,c){a.removeEventListener(b,c,!1)}:c.detachEvent&&(e=function(a,b,c){a.detachEvent("on"+b,a[b+c]);try{delete a[b+c]}catch(d){a[b+c]=void 0}});var f={bind:d,unbind:e};"function"==typeof define&&define.amd?define("eventie/eventie",f):"object"==typeof exports?module.exports=f:a.eventie=f}(this),function(a){function b(a){"function"==typeof a&&(b.isReady?a():g.push(a))}function c(a){var c="readystatechange"===a.type&&"complete"!==f.readyState;b.isReady||c||d()}function d(){b.isReady=!0;for(var a=0,c=g.length;c>a;a++){var d=g[a];d()}}function e(e){return"complete"===f.readyState?d():(e.bind(f,"DOMContentLoaded",c),e.bind(f,"readystatechange",c),e.bind(a,"load",c)),b}var f=a.document,g=[];b.isReady=!1,"function"==typeof define&&define.amd?define("doc-ready/doc-ready",["eventie/eventie"],e):"object"==typeof exports?module.exports=e(require("eventie")):a.docReady=e(a.eventie)}(window),function(){function a(){}function b(a,b){for(var c=a.length;c--;)if(a[c].listener===b)return c;return-1}function c(a){return function(){return this[a].apply(this,arguments)}}var d=a.prototype,e=this,f=e.EventEmitter;d.getListeners=function(a){var b,c,d=this._getEvents();if(a instanceof RegExp){b={};for(c in d)d.hasOwnProperty(c)&&a.test(c)&&(b[c]=d[c])}else b=d[a]||(d[a]=[]);return b},d.flattenListeners=function(a){var b,c=[];for(b=0;b<a.length;b+=1)c.push(a[b].listener);return c},d.getListenersAsObject=function(a){var b,c=this.getListeners(a);return c instanceof Array&&(b={},b[a]=c),b||c},d.addListener=function(a,c){var d,e=this.getListenersAsObject(a),f="object"==typeof c;for(d in e)e.hasOwnProperty(d)&&-1===b(e[d],c)&&e[d].push(f?c:{listener:c,once:!1});return this},d.on=c("addListener"),d.addOnceListener=function(a,b){return this.addListener(a,{listener:b,once:!0})},d.once=c("addOnceListener"),d.defineEvent=function(a){return this.getListeners(a),this},d.defineEvents=function(a){for(var b=0;b<a.length;b+=1)this.defineEvent(a[b]);return this},d.removeListener=function(a,c){var d,e,f=this.getListenersAsObject(a);for(e in f)f.hasOwnProperty(e)&&(d=b(f[e],c),-1!==d&&f[e].splice(d,1));return this},d.off=c("removeListener"),d.addListeners=function(a,b){return this.manipulateListeners(!1,a,b)},d.removeListeners=function(a,b){return this.manipulateListeners(!0,a,b)},d.manipulateListeners=function(a,b,c){var d,e,f=a?this.removeListener:this.addListener,g=a?this.removeListeners:this.addListeners;if("object"!=typeof b||b instanceof RegExp)for(d=c.length;d--;)f.call(this,b,c[d]);else for(d in b)b.hasOwnProperty(d)&&(e=b[d])&&("function"==typeof e?f.call(this,d,e):g.call(this,d,e));return this},d.removeEvent=function(a){var b,c=typeof a,d=this._getEvents();if("string"===c)delete d[a];else if(a instanceof RegExp)for(b in d)d.hasOwnProperty(b)&&a.test(b)&&delete d[b];else delete this._events;return this},d.removeAllListeners=c("removeEvent"),d.emitEvent=function(a,b){var c,d,e,f,g=this.getListenersAsObject(a);for(e in g)if(g.hasOwnProperty(e))for(d=g[e].length;d--;)c=g[e][d],c.once===!0&&this.removeListener(a,c.listener),f=c.listener.apply(this,b||[]),f===this._getOnceReturnValue()&&this.removeListener(a,c.listener);return this},d.trigger=c("emitEvent"),d.emit=function(a){var b=Array.prototype.slice.call(arguments,1);return this.emitEvent(a,b)},d.setOnceReturnValue=function(a){return this._onceReturnValue=a,this},d._getOnceReturnValue=function(){return this.hasOwnProperty("_onceReturnValue")?this._onceReturnValue:!0},d._getEvents=function(){return this._events||(this._events={})},a.noConflict=function(){return e.EventEmitter=f,a},"function"==typeof define&&define.amd?define("eventEmitter/EventEmitter",[],function(){return a}):"object"==typeof module&&module.exports?module.exports=a:e.EventEmitter=a}.call(this),function(a){function b(a){if(a){if("string"==typeof d[a])return a;a=a.charAt(0).toUpperCase()+a.slice(1);for(var b,e=0,f=c.length;f>e;e++)if(b=c[e]+a,"string"==typeof d[b])return b}}var c="Webkit Moz ms Ms O".split(" "),d=document.documentElement.style;"function"==typeof define&&define.amd?define("get-style-property/get-style-property",[],function(){return b}):"object"==typeof exports?module.exports=b:a.getStyleProperty=b}(window),function(a){function b(a){var b=parseFloat(a),c=-1===a.indexOf("%")&&!isNaN(b);return c&&b}function c(){}function d(){for(var a={width:0,height:0,innerWidth:0,innerHeight:0,outerWidth:0,outerHeight:0},b=0,c=g.length;c>b;b++){var d=g[b];a[d]=0}return a}function e(c){function e(){if(!m){m=!0;var d=a.getComputedStyle;if(j=function(){var a=d?function(a){return d(a,null)}:function(a){return a.currentStyle};return function(b){var c=a(b);return c||f("Style returned "+c+". Are you running this code in a hidden iframe on Firefox? See http://bit.ly/getsizebug1"),c}}(),k=c("boxSizing")){var e=document.createElement("div");e.style.width="200px",e.style.padding="1px 2px 3px 4px",e.style.borderStyle="solid",e.style.borderWidth="1px 2px 3px 4px",e.style[k]="border-box";var g=document.body||document.documentElement;g.appendChild(e);var h=j(e);l=200===b(h.width),g.removeChild(e)}}}function h(a){if(e(),"string"==typeof a&&(a=document.querySelector(a)),a&&"object"==typeof a&&a.nodeType){var c=j(a);if("none"===c.display)return d();var f={};f.width=a.offsetWidth,f.height=a.offsetHeight;for(var h=f.isBorderBox=!(!k||!c[k]||"border-box"!==c[k]),m=0,n=g.length;n>m;m++){var o=g[m],p=c[o];p=i(a,p);var q=parseFloat(p);f[o]=isNaN(q)?0:q}var r=f.paddingLeft+f.paddingRight,s=f.paddingTop+f.paddingBottom,t=f.marginLeft+f.marginRight,u=f.marginTop+f.marginBottom,v=f.borderLeftWidth+f.borderRightWidth,w=f.borderTopWidth+f.borderBottomWidth,x=h&&l,y=b(c.width);y!==!1&&(f.width=y+(x?0:r+v));var z=b(c.height);return z!==!1&&(f.height=z+(x?0:s+w)),f.innerWidth=f.width-(r+v),f.innerHeight=f.height-(s+w),f.outerWidth=f.width+t,f.outerHeight=f.height+u,f}}function i(b,c){if(a.getComputedStyle||-1===c.indexOf("%"))return c;var d=b.style,e=d.left,f=b.runtimeStyle,g=f&&f.left;return g&&(f.left=b.currentStyle.left),d.left=c,c=d.pixelLeft,d.left=e,g&&(f.left=g),c}var j,k,l,m=!1;return h}var f="undefined"==typeof console?c:function(a){console.error(a)},g=["paddingLeft","paddingRight","paddingTop","paddingBottom","marginLeft","marginRight","marginTop","marginBottom","borderLeftWidth","borderRightWidth","borderTopWidth","borderBottomWidth"];"function"==typeof define&&define.amd?define("get-size/get-size",["get-style-property/get-style-property"],e):"object"==typeof exports?module.exports=e(require("desandro-get-style-property")):a.getSize=e(a.getStyleProperty)}(window),function(a){function b(a,b){return a[g](b)}function c(a){if(!a.parentNode){var b=document.createDocumentFragment();b.appendChild(a)}}function d(a,b){c(a);for(var d=a.parentNode.querySelectorAll(b),e=0,f=d.length;f>e;e++)if(d[e]===a)return!0;return!1}function e(a,d){return c(a),b(a,d)}var f,g=function(){if(a.matchesSelector)return"matchesSelector";for(var b=["webkit","moz","ms","o"],c=0,d=b.length;d>c;c++){var e=b[c],f=e+"MatchesSelector";if(a[f])return f}}();if(g){var h=document.createElement("div"),i=b(h,"div");f=i?b:e}else f=d;"function"==typeof define&&define.amd?define("matches-selector/matches-selector",[],function(){return f}):"object"==typeof exports?module.exports=f:window.matchesSelector=f}(Element.prototype),function(a){function b(a,b){for(var c in b)a[c]=b[c];return a}function c(a){for(var b in a)return!1;return b=null,!0}function d(a){return a.replace(/([A-Z])/g,function(a){return"-"+a.toLowerCase()})}function e(a,e,f){function h(a,b){a&&(this.element=a,this.layout=b,this.position={x:0,y:0},this._create())}var i=f("transition"),j=f("transform"),k=i&&j,l=!!f("perspective"),m={WebkitTransition:"webkitTransitionEnd",MozTransition:"transitionend",OTransition:"otransitionend",transition:"transitionend"}[i],n=["transform","transition","transitionDuration","transitionProperty"],o=function(){for(var a={},b=0,c=n.length;c>b;b++){var d=n[b],e=f(d);e&&e!==d&&(a[d]=e)}return a}();b(h.prototype,a.prototype),h.prototype._create=function(){this._transn={ingProperties:{},clean:{},onEnd:{}},this.css({position:"absolute"})},h.prototype.handleEvent=function(a){var b="on"+a.type;this[b]&&this[b](a)},h.prototype.getSize=function(){this.size=e(this.element)},h.prototype.css=function(a){var b=this.element.style;for(var c in a){var d=o[c]||c;b[d]=a[c]}},h.prototype.getPosition=function(){var a=g(this.element),b=this.layout.options,c=b.isOriginLeft,d=b.isOriginTop,e=parseInt(a[c?"left":"right"],10),f=parseInt(a[d?"top":"bottom"],10);e=isNaN(e)?0:e,f=isNaN(f)?0:f;var h=this.layout.size;e-=c?h.paddingLeft:h.paddingRight,f-=d?h.paddingTop:h.paddingBottom,this.position.x=e,this.position.y=f},h.prototype.layoutPosition=function(){var a=this.layout.size,b=this.layout.options,c={};b.isOriginLeft?(c.left=this.position.x+a.paddingLeft+"px",c.right=""):(c.right=this.position.x+a.paddingRight+"px",c.left=""),b.isOriginTop?(c.top=this.position.y+a.paddingTop+"px",c.bottom=""):(c.bottom=this.position.y+a.paddingBottom+"px",c.top=""),this.css(c),this.emitEvent("layout",[this])};var p=l?function(a,b){return"translate3d("+a+"px, "+b+"px, 0)"}:function(a,b){return"translate("+a+"px, "+b+"px)"};h.prototype._transitionTo=function(a,b){this.getPosition();var c=this.position.x,d=this.position.y,e=parseInt(a,10),f=parseInt(b,10),g=e===this.position.x&&f===this.position.y;if(this.setPosition(a,b),g&&!this.isTransitioning)return void this.layoutPosition();var h=a-c,i=b-d,j={},k=this.layout.options;h=k.isOriginLeft?h:-h,i=k.isOriginTop?i:-i,j.transform=p(h,i),this.transition({to:j,onTransitionEnd:{transform:this.layoutPosition},isCleaning:!0})},h.prototype.goTo=function(a,b){this.setPosition(a,b),this.layoutPosition()},h.prototype.moveTo=k?h.prototype._transitionTo:h.prototype.goTo,h.prototype.setPosition=function(a,b){this.position.x=parseInt(a,10),this.position.y=parseInt(b,10)},h.prototype._nonTransition=function(a){this.css(a.to),a.isCleaning&&this._removeStyles(a.to);for(var b in a.onTransitionEnd)a.onTransitionEnd[b].call(this)},h.prototype._transition=function(a){if(!parseFloat(this.layout.options.transitionDuration))return void this._nonTransition(a);var b=this._transn;for(var c in a.onTransitionEnd)b.onEnd[c]=a.onTransitionEnd[c];for(c in a.to)b.ingProperties[c]=!0,a.isCleaning&&(b.clean[c]=!0);if(a.from){this.css(a.from);var d=this.element.offsetHeight;d=null}this.enableTransition(a.to),this.css(a.to),this.isTransitioning=!0};var q=j&&d(j)+",opacity";h.prototype.enableTransition=function(){this.isTransitioning||(this.css({transitionProperty:q,transitionDuration:this.layout.options.transitionDuration}),this.element.addEventListener(m,this,!1))},h.prototype.transition=h.prototype[i?"_transition":"_nonTransition"],h.prototype.onwebkitTransitionEnd=function(a){this.ontransitionend(a)},h.prototype.onotransitionend=function(a){this.ontransitionend(a)};var r={"-webkit-transform":"transform","-moz-transform":"transform","-o-transform":"transform"};h.prototype.ontransitionend=function(a){if(a.target===this.element){var b=this._transn,d=r[a.propertyName]||a.propertyName;if(delete b.ingProperties[d],c(b.ingProperties)&&this.disableTransition(),d in b.clean&&(this.element.style[a.propertyName]="",delete b.clean[d]),d in b.onEnd){var e=b.onEnd[d];e.call(this),delete b.onEnd[d]}this.emitEvent("transitionEnd",[this])}},h.prototype.disableTransition=function(){this.removeTransitionStyles(),this.element.removeEventListener(m,this,!1),this.isTransitioning=!1},h.prototype._removeStyles=function(a){var b={};for(var c in a)b[c]="";this.css(b)};var s={transitionProperty:"",transitionDuration:""};return h.prototype.removeTransitionStyles=function(){this.css(s)},h.prototype.removeElem=function(){this.element.parentNode.removeChild(this.element),this.emitEvent("remove",[this])},h.prototype.remove=function(){if(!i||!parseFloat(this.layout.options.transitionDuration))return void this.removeElem();var a=this;this.on("transitionEnd",function(){return a.removeElem(),!0}),this.hide()},h.prototype.reveal=function(){delete this.isHidden,this.css({display:""});var a=this.layout.options;this.transition({from:a.hiddenStyle,to:a.visibleStyle,isCleaning:!0})},h.prototype.hide=function(){this.isHidden=!0,this.css({display:""});var a=this.layout.options;this.transition({from:a.visibleStyle,to:a.hiddenStyle,isCleaning:!0,onTransitionEnd:{opacity:function(){this.isHidden&&this.css({display:"none"})}}})},h.prototype.destroy=function(){this.css({position:"",left:"",right:"",top:"",bottom:"",transition:"",transform:""})},h}var f=a.getComputedStyle,g=f?function(a){return f(a,null)}:function(a){return a.currentStyle};"function"==typeof define&&define.amd?define("outlayer/item",["eventEmitter/EventEmitter","get-size/get-size","get-style-property/get-style-property"],e):"object"==typeof exports?module.exports=e(require("wolfy87-eventemitter"),require("get-size"),require("desandro-get-style-property")):(a.Outlayer={},a.Outlayer.Item=e(a.EventEmitter,a.getSize,a.getStyleProperty))}(window),function(a){function b(a,b){for(var c in b)a[c]=b[c];return a}function c(a){return"[object Array]"===l.call(a)}function d(a){var b=[];if(c(a))b=a;else if(a&&"number"==typeof a.length)for(var d=0,e=a.length;e>d;d++)b.push(a[d]);else b.push(a);return b}function e(a,b){var c=n(b,a);-1!==c&&b.splice(c,1)}function f(a){return a.replace(/(.)([A-Z])/g,function(a,b,c){return b+"-"+c}).toLowerCase()}function g(c,g,l,n,o,p){function q(a,c){if("string"==typeof a&&(a=h.querySelector(a)),!a||!m(a))return void(i&&i.error("Bad "+this.constructor.namespace+" element: "+a));this.element=a,this.options=b({},this.constructor.defaults),this.option(c);var d=++r;this.element.outlayerGUID=d,s[d]=this,this._create(),this.options.isInitLayout&&this.layout()}var r=0,s={};return q.namespace="outlayer",q.Item=p,q.defaults={containerStyle:{position:"relative"},isInitLayout:!0,isOriginLeft:!0,isOriginTop:!0,isResizeBound:!0,isResizingContainer:!0,transitionDuration:"0.4s",hiddenStyle:{opacity:0,transform:"scale(0.001)"},visibleStyle:{opacity:1,transform:"scale(1)"}},b(q.prototype,l.prototype),q.prototype.option=function(a){b(this.options,a)},q.prototype._create=function(){this.reloadItems(),this.stamps=[],this.stamp(this.options.stamp),b(this.element.style,this.options.containerStyle),this.options.isResizeBound&&this.bindResize()},q.prototype.reloadItems=function(){this.items=this._itemize(this.element.children)},q.prototype._itemize=function(a){for(var b=this._filterFindItemElements(a),c=this.constructor.Item,d=[],e=0,f=b.length;f>e;e++){var g=b[e],h=new c(g,this);d.push(h)}return d},q.prototype._filterFindItemElements=function(a){a=d(a);for(var b=this.options.itemSelector,c=[],e=0,f=a.length;f>e;e++){var g=a[e];if(m(g))if(b){o(g,b)&&c.push(g);for(var h=g.querySelectorAll(b),i=0,j=h.length;j>i;i++)c.push(h[i])}else c.push(g)}return c},q.prototype.getItemElements=function(){for(var a=[],b=0,c=this.items.length;c>b;b++)a.push(this.items[b].element);return a},q.prototype.layout=function(){this._resetLayout(),this._manageStamps();var a=void 0!==this.options.isLayoutInstant?this.options.isLayoutInstant:!this._isLayoutInited;this.layoutItems(this.items,a),this._isLayoutInited=!0},q.prototype._init=q.prototype.layout,q.prototype._resetLayout=function(){this.getSize()},q.prototype.getSize=function(){this.size=n(this.element)},q.prototype._getMeasurement=function(a,b){var c,d=this.options[a];d?("string"==typeof d?c=this.element.querySelector(d):m(d)&&(c=d),this[a]=c?n(c)[b]:d):this[a]=0},q.prototype.layoutItems=function(a,b){a=this._getItemsForLayout(a),this._layoutItems(a,b),this._postLayout()},q.prototype._getItemsForLayout=function(a){for(var b=[],c=0,d=a.length;d>c;c++){var e=a[c];e.isIgnored||b.push(e)}return b},q.prototype._layoutItems=function(a,b){function c(){d.emitEvent("layoutComplete",[d,a])}var d=this;if(!a||!a.length)return void c();this._itemsOn(a,"layout",c);for(var e=[],f=0,g=a.length;g>f;f++){var h=a[f],i=this._getItemLayoutPosition(h);i.item=h,i.isInstant=b||h.isLayoutInstant,e.push(i)}this._processLayoutQueue(e)},q.prototype._getItemLayoutPosition=function(){return{x:0,y:0}},q.prototype._processLayoutQueue=function(a){for(var b=0,c=a.length;c>b;b++){var d=a[b];this._positionItem(d.item,d.x,d.y,d.isInstant)}},q.prototype._positionItem=function(a,b,c,d){d?a.goTo(b,c):a.moveTo(b,c)},q.prototype._postLayout=function(){this.resizeContainer()},q.prototype.resizeContainer=function(){if(this.options.isResizingContainer){var a=this._getContainerSize();a&&(this._setContainerMeasure(a.width,!0),this._setContainerMeasure(a.height,!1))}},q.prototype._getContainerSize=k,q.prototype._setContainerMeasure=function(a,b){if(void 0!==a){var c=this.size;c.isBorderBox&&(a+=b?c.paddingLeft+c.paddingRight+c.borderLeftWidth+c.borderRightWidth:c.paddingBottom+c.paddingTop+c.borderTopWidth+c.borderBottomWidth),a=Math.max(a,0),this.element.style[b?"width":"height"]=a+"px"}},q.prototype._itemsOn=function(a,b,c){function d(){return e++,e===f&&c.call(g),!0}for(var e=0,f=a.length,g=this,h=0,i=a.length;i>h;h++){var j=a[h];j.on(b,d)}},q.prototype.ignore=function(a){var b=this.getItem(a);b&&(b.isIgnored=!0)},q.prototype.unignore=function(a){var b=this.getItem(a);b&&delete b.isIgnored},q.prototype.stamp=function(a){if(a=this._find(a)){this.stamps=this.stamps.concat(a);for(var b=0,c=a.length;c>b;b++){var d=a[b];this.ignore(d)}}},q.prototype.unstamp=function(a){if(a=this._find(a))for(var b=0,c=a.length;c>b;b++){var d=a[b];e(d,this.stamps),this.unignore(d)}},q.prototype._find=function(a){return a?("string"==typeof a&&(a=this.element.querySelectorAll(a)),a=d(a)):void 0},q.prototype._manageStamps=function(){if(this.stamps&&this.stamps.length){this._getBoundingRect();for(var a=0,b=this.stamps.length;b>a;a++){var c=this.stamps[a];this._manageStamp(c)}}},q.prototype._getBoundingRect=function(){var a=this.element.getBoundingClientRect(),b=this.size;this._boundingRect={left:a.left+b.paddingLeft+b.borderLeftWidth,top:a.top+b.paddingTop+b.borderTopWidth,right:a.right-(b.paddingRight+b.borderRightWidth),bottom:a.bottom-(b.paddingBottom+b.borderBottomWidth)}},q.prototype._manageStamp=k,q.prototype._getElementOffset=function(a){var b=a.getBoundingClientRect(),c=this._boundingRect,d=n(a),e={left:b.left-c.left-d.marginLeft,top:b.top-c.top-d.marginTop,right:c.right-b.right-d.marginRight,bottom:c.bottom-b.bottom-d.marginBottom};return e},q.prototype.handleEvent=function(a){var b="on"+a.type;this[b]&&this[b](a)},q.prototype.bindResize=function(){this.isResizeBound||(c.bind(a,"resize",this),this.isResizeBound=!0)},q.prototype.unbindResize=function(){this.isResizeBound&&c.unbind(a,"resize",this),this.isResizeBound=!1},q.prototype.onresize=function(){function a(){b.resize(),delete b.resizeTimeout}this.resizeTimeout&&clearTimeout(this.resizeTimeout);var b=this;this.resizeTimeout=setTimeout(a,100)},q.prototype.resize=function(){this.isResizeBound&&this.needsResizeLayout()&&this.layout()},q.prototype.needsResizeLayout=function(){var a=n(this.element),b=this.size&&a;return b&&a.innerWidth!==this.size.innerWidth},q.prototype.addItems=function(a){var b=this._itemize(a);return b.length&&(this.items=this.items.concat(b)),b},q.prototype.appended=function(a){var b=this.addItems(a);b.length&&(this.layoutItems(b,!0),this.reveal(b))},q.prototype.prepended=function(a){var b=this._itemize(a);if(b.length){var c=this.items.slice(0);this.items=b.concat(c),this._resetLayout(),this._manageStamps(),this.layoutItems(b,!0),this.reveal(b),this.layoutItems(c)}},q.prototype.reveal=function(a){var b=a&&a.length;if(b)for(var c=0;b>c;c++){var d=a[c];d.reveal()}},q.prototype.hide=function(a){var b=a&&a.length;if(b)for(var c=0;b>c;c++){var d=a[c];d.hide()}},q.prototype.getItem=function(a){for(var b=0,c=this.items.length;c>b;b++){var d=this.items[b];if(d.element===a)return d}},q.prototype.getItems=function(a){if(a&&a.length){for(var b=[],c=0,d=a.length;d>c;c++){var e=a[c],f=this.getItem(e);f&&b.push(f)}return b}},q.prototype.remove=function(a){a=d(a);var b=this.getItems(a);if(b&&b.length){this._itemsOn(b,"remove",function(){this.emitEvent("removeComplete",[this,b])});for(var c=0,f=b.length;f>c;c++){var g=b[c];g.remove(),e(g,this.items)}}},q.prototype.destroy=function(){var a=this.element.style;a.height="",a.position="",a.width="";for(var b=0,c=this.items.length;c>b;b++){var d=this.items[b];d.destroy()}this.unbindResize();var e=this.element.outlayerGUID;delete s[e],delete this.element.outlayerGUID,j&&j.removeData(this.element,this.constructor.namespace)},q.data=function(a){var b=a&&a.outlayerGUID;return b&&s[b]},q.create=function(a,c){function d(){q.apply(this,arguments)}return Object.create?d.prototype=Object.create(q.prototype):b(d.prototype,q.prototype),d.prototype.constructor=d,d.defaults=b({},q.defaults),b(d.defaults,c),d.prototype.settings={},d.namespace=a,d.data=q.data,d.Item=function(){p.apply(this,arguments)},d.Item.prototype=new p,g(function(){for(var b=f(a),c=h.querySelectorAll(".js-"+b),e="data-"+b+"-options",g=0,k=c.length;k>g;g++){var l,m=c[g],n=m.getAttribute(e);try{l=n&&JSON.parse(n)}catch(o){i&&i.error("Error parsing "+e+" on "+m.nodeName.toLowerCase()+(m.id?"#"+m.id:"")+": "+o);continue}var p=new d(m,l);j&&j.data(m,a,p)}}),j&&j.bridget&&j.bridget(a,d),d},q.Item=p,q}var h=a.document,i=a.console,j=a.jQuery,k=function(){},l=Object.prototype.toString,m="function"==typeof HTMLElement||"object"==typeof HTMLElement?function(a){return a instanceof HTMLElement}:function(a){return a&&"object"==typeof a&&1===a.nodeType&&"string"==typeof a.nodeName},n=Array.prototype.indexOf?function(a,b){return a.indexOf(b)}:function(a,b){for(var c=0,d=a.length;d>c;c++)if(a[c]===b)return c;return-1};"function"==typeof define&&define.amd?define("outlayer/outlayer",["eventie/eventie","doc-ready/doc-ready","eventEmitter/EventEmitter","get-size/get-size","matches-selector/matches-selector","./item"],g):"object"==typeof exports?module.exports=g(require("eventie"),require("doc-ready"),require("wolfy87-eventemitter"),require("get-size"),require("desandro-matches-selector"),require("./item")):a.Outlayer=g(a.eventie,a.docReady,a.EventEmitter,a.getSize,a.matchesSelector,a.Outlayer.Item)}(window),function(a){function b(a,b){var d=a.create("masonry");return d.prototype._resetLayout=function(){this.getSize(),this._getMeasurement("columnWidth","outerWidth"),this._getMeasurement("gutter","outerWidth"),this.measureColumns();var a=this.cols;for(this.colYs=[];a--;)this.colYs.push(0);this.maxY=0},d.prototype.measureColumns=function(){if(this.getContainerWidth(),!this.columnWidth){var a=this.items[0],c=a&&a.element;this.columnWidth=c&&b(c).outerWidth||this.containerWidth}this.columnWidth+=this.gutter,this.cols=Math.floor((this.containerWidth+this.gutter)/this.columnWidth),this.cols=Math.max(this.cols,1)},d.prototype.getContainerWidth=function(){var a=this.options.isFitWidth?this.element.parentNode:this.element,c=b(a);this.containerWidth=c&&c.innerWidth},d.prototype._getItemLayoutPosition=function(a){a.getSize();var b=a.size.outerWidth%this.columnWidth,d=b&&1>b?"round":"ceil",e=Math[d](a.size.outerWidth/this.columnWidth);e=Math.min(e,this.cols);for(var f=this._getColGroup(e),g=Math.min.apply(Math,f),h=c(f,g),i={x:this.columnWidth*h,y:g},j=g+a.size.outerHeight,k=this.cols+1-f.length,l=0;k>l;l++)this.colYs[h+l]=j;return i},d.prototype._getColGroup=function(a){if(2>a)return this.colYs;for(var b=[],c=this.cols+1-a,d=0;c>d;d++){var e=this.colYs.slice(d,d+a);b[d]=Math.max.apply(Math,e)}return b},d.prototype._manageStamp=function(a){var c=b(a),d=this._getElementOffset(a),e=this.options.isOriginLeft?d.left:d.right,f=e+c.outerWidth,g=Math.floor(e/this.columnWidth);g=Math.max(0,g);var h=Math.floor(f/this.columnWidth);h-=f%this.columnWidth?0:1,h=Math.min(this.cols-1,h);for(var i=(this.options.isOriginTop?d.top:d.bottom)+c.outerHeight,j=g;h>=j;j++)this.colYs[j]=Math.max(i,this.colYs[j])},d.prototype._getContainerSize=function(){this.maxY=Math.max.apply(Math,this.colYs);var a={height:this.maxY};return this.options.isFitWidth&&(a.width=this._getContainerFitWidth()),a},d.prototype._getContainerFitWidth=function(){for(var a=0,b=this.cols;--b&&0===this.colYs[b];)a++;return(this.cols-a)*this.columnWidth-this.gutter},d.prototype.needsResizeLayout=function(){var a=this.containerWidth;return this.getContainerWidth(),a!==this.containerWidth},d}var c=Array.prototype.indexOf?function(a,b){return a.indexOf(b)}:function(a,b){for(var c=0,d=a.length;d>c;c++){var e=a[c];if(e===b)return c}return-1};"function"==typeof define&&define.amd?define(["outlayer/outlayer","get-size/get-size"],b):"object"==typeof exports?module.exports=b(require("outlayer"),require("get-size")):a.Masonry=b(a.Outlayer,a.getSize)}(window);
/* jquery.touchSwipe.min.js */
(function(e){var o="left",n="right",d="up",v="down",c="in",w="out",l="none",r="auto",k="swipe",s="pinch",x="tap",i="doubletap",b="longtap",A="horizontal",t="vertical",h="all",q=10,f="start",j="move",g="end",p="cancel",a="ontouchstart" in window,y="TouchSwipe";var m={fingers:1,threshold:75,cancelThreshold:null,pinchThreshold:20,maxTimeThreshold:null,fingerReleaseThreshold:250,longTapThreshold:500,doubleTapThreshold:200,swipe:null,swipeLeft:null,swipeRight:null,swipeUp:null,swipeDown:null,swipeStatus:null,pinchIn:null,pinchOut:null,pinchStatus:null,click:null,tap:null,doubleTap:null,longTap:null,triggerOnTouchEnd:true,triggerOnTouchLeave:false,allowPageScroll:"auto",fallbackToMouseEvents:true,excludedElements:"button, input, select, textarea, a, .noSwipe"};e.fn.swipe=function(D){var C=e(this),B=C.data(y);if(B&&typeof D==="string"){if(B[D]){return B[D].apply(this,Array.prototype.slice.call(arguments,1))}else{e.error("Method "+D+" does not exist on jQuery.swipe")}}else{if(!B&&(typeof D==="object"||!D)){return u.apply(this,arguments)}}return C};e.fn.swipe.defaults=m;e.fn.swipe.phases={PHASE_START:f,PHASE_MOVE:j,PHASE_END:g,PHASE_CANCEL:p};e.fn.swipe.directions={LEFT:o,RIGHT:n,UP:d,DOWN:v,IN:c,OUT:w};e.fn.swipe.pageScroll={NONE:l,HORIZONTAL:A,VERTICAL:t,AUTO:r};e.fn.swipe.fingers={ONE:1,TWO:2,THREE:3,ALL:h};function u(B){if(B&&(B.allowPageScroll===undefined&&(B.swipe!==undefined||B.swipeStatus!==undefined))){B.allowPageScroll=l}if(B.click!==undefined&&B.tap===undefined){B.tap=B.click}if(!B){B={}}B=e.extend({},e.fn.swipe.defaults,B);return this.each(function(){var D=e(this);var C=D.data(y);if(!C){C=new z(this,B);D.data(y,C)}})}function z(a0,aq){var av=(a||!aq.fallbackToMouseEvents),G=av?"touchstart":"mousedown",au=av?"touchmove":"mousemove",R=av?"touchend":"mouseup",P=av?null:"mouseleave",az="touchcancel";var ac=0,aL=null,Y=0,aX=0,aV=0,D=1,am=0,aF=0,J=null;var aN=e(a0);var W="start";var T=0;var aM=null;var Q=0,aY=0,a1=0,aa=0,K=0;var aS=null;try{aN.bind(G,aJ);aN.bind(az,a5)}catch(ag){e.error("events not supported "+G+","+az+" on jQuery.swipe")}this.enable=function(){aN.bind(G,aJ);aN.bind(az,a5);return aN};this.disable=function(){aG();return aN};this.destroy=function(){aG();aN.data(y,null);return aN};this.option=function(a8,a7){if(aq[a8]!==undefined){if(a7===undefined){return aq[a8]}else{aq[a8]=a7}}else{e.error("Option "+a8+" does not exist on jQuery.swipe.options")}};function aJ(a9){if(ax()){return}if(e(a9.target).closest(aq.excludedElements,aN).length>0){return}var ba=a9.originalEvent?a9.originalEvent:a9;var a8,a7=a?ba.touches[0]:ba;W=f;if(a){T=ba.touches.length}else{a9.preventDefault()}ac=0;aL=null;aF=null;Y=0;aX=0;aV=0;D=1;am=0;aM=af();J=X();O();if(!a||(T===aq.fingers||aq.fingers===h)||aT()){ae(0,a7);Q=ao();if(T==2){ae(1,ba.touches[1]);aX=aV=ap(aM[0].start,aM[1].start)}if(aq.swipeStatus||aq.pinchStatus){a8=L(ba,W)}}else{a8=false}if(a8===false){W=p;L(ba,W);return a8}else{ak(true)}}function aZ(ba){var bd=ba.originalEvent?ba.originalEvent:ba;if(W===g||W===p||ai()){return}var a9,a8=a?bd.touches[0]:bd;var bb=aD(a8);aY=ao();if(a){T=bd.touches.length}W=j;if(T==2){if(aX==0){ae(1,bd.touches[1]);aX=aV=ap(aM[0].start,aM[1].start)}else{aD(bd.touches[1]);aV=ap(aM[0].end,aM[1].end);aF=an(aM[0].end,aM[1].end)}D=a3(aX,aV);am=Math.abs(aX-aV)}if((T===aq.fingers||aq.fingers===h)||!a||aT()){aL=aH(bb.start,bb.end);ah(ba,aL);ac=aO(bb.start,bb.end);Y=aI();aE(aL,ac);if(aq.swipeStatus||aq.pinchStatus){a9=L(bd,W)}if(!aq.triggerOnTouchEnd||aq.triggerOnTouchLeave){var a7=true;if(aq.triggerOnTouchLeave){var bc=aU(this);a7=B(bb.end,bc)}if(!aq.triggerOnTouchEnd&&a7){W=ay(j)}else{if(aq.triggerOnTouchLeave&&!a7){W=ay(g)}}if(W==p||W==g){L(bd,W)}}}else{W=p;L(bd,W)}if(a9===false){W=p;L(bd,W)}}function I(a7){var a8=a7.originalEvent;if(a){if(a8.touches.length>0){C();return true}}if(ai()){T=aa}a7.preventDefault();aY=ao();Y=aI();if(a6()){W=p;L(a8,W)}else{if(aq.triggerOnTouchEnd||(aq.triggerOnTouchEnd==false&&W===j)){W=g;L(a8,W)}else{if(!aq.triggerOnTouchEnd&&a2()){W=g;aB(a8,W,x)}else{if(W===j){W=p;L(a8,W)}}}}ak(false)}function a5(){T=0;aY=0;Q=0;aX=0;aV=0;D=1;O();ak(false)}function H(a7){var a8=a7.originalEvent;if(aq.triggerOnTouchLeave){W=ay(g);L(a8,W)}}function aG(){aN.unbind(G,aJ);aN.unbind(az,a5);aN.unbind(au,aZ);aN.unbind(R,I);if(P){aN.unbind(P,H)}ak(false)}function ay(bb){var ba=bb;var a9=aw();var a8=aj();var a7=a6();if(!a9||a7){ba=p}else{if(a8&&bb==j&&(!aq.triggerOnTouchEnd||aq.triggerOnTouchLeave)){ba=g}else{if(!a8&&bb==g&&aq.triggerOnTouchLeave){ba=p}}}return ba}function L(a9,a7){var a8=undefined;if(F()||S()){a8=aB(a9,a7,k)}else{if((M()||aT())&&a8!==false){a8=aB(a9,a7,s)}}if(aC()&&a8!==false){a8=aB(a9,a7,i)}else{if(al()&&a8!==false){a8=aB(a9,a7,b)}else{if(ad()&&a8!==false){a8=aB(a9,a7,x)}}}if(a7===p){a5(a9)}if(a7===g){if(a){if(a9.touches.length==0){a5(a9)}}else{a5(a9)}}return a8}function aB(ba,a7,a9){var a8=undefined;if(a9==k){aN.trigger("swipeStatus",[a7,aL||null,ac||0,Y||0,T]);if(aq.swipeStatus){a8=aq.swipeStatus.call(aN,ba,a7,aL||null,ac||0,Y||0,T);if(a8===false){return false}}if(a7==g&&aR()){aN.trigger("swipe",[aL,ac,Y,T]);if(aq.swipe){a8=aq.swipe.call(aN,ba,aL,ac,Y,T);if(a8===false){return false}}switch(aL){case o:aN.trigger("swipeLeft",[aL,ac,Y,T]);if(aq.swipeLeft){a8=aq.swipeLeft.call(aN,ba,aL,ac,Y,T)}break;case n:aN.trigger("swipeRight",[aL,ac,Y,T]);if(aq.swipeRight){a8=aq.swipeRight.call(aN,ba,aL,ac,Y,T)}break;case d:aN.trigger("swipeUp",[aL,ac,Y,T]);if(aq.swipeUp){a8=aq.swipeUp.call(aN,ba,aL,ac,Y,T)}break;case v:aN.trigger("swipeDown",[aL,ac,Y,T]);if(aq.swipeDown){a8=aq.swipeDown.call(aN,ba,aL,ac,Y,T)}break}}}if(a9==s){aN.trigger("pinchStatus",[a7,aF||null,am||0,Y||0,T,D]);if(aq.pinchStatus){a8=aq.pinchStatus.call(aN,ba,a7,aF||null,am||0,Y||0,T,D);if(a8===false){return false}}if(a7==g&&a4()){switch(aF){case c:aN.trigger("pinchIn",[aF||null,am||0,Y||0,T,D]);if(aq.pinchIn){a8=aq.pinchIn.call(aN,ba,aF||null,am||0,Y||0,T,D)}break;case w:aN.trigger("pinchOut",[aF||null,am||0,Y||0,T,D]);if(aq.pinchOut){a8=aq.pinchOut.call(aN,ba,aF||null,am||0,Y||0,T,D)}break}}}if(a9==x){if(a7===p||a7===g){clearTimeout(aS);if(V()&&!E()){K=ao();aS=setTimeout(e.proxy(function(){K=null;aN.trigger("tap",[ba.target]);if(aq.tap){a8=aq.tap.call(aN,ba,ba.target)}},this),aq.doubleTapThreshold)}else{K=null;aN.trigger("tap",[ba.target]);if(aq.tap){a8=aq.tap.call(aN,ba,ba.target)}}}}else{if(a9==i){if(a7===p||a7===g){clearTimeout(aS);K=null;aN.trigger("doubletap",[ba.target]);if(aq.doubleTap){a8=aq.doubleTap.call(aN,ba,ba.target)}}}else{if(a9==b){if(a7===p||a7===g){clearTimeout(aS);K=null;aN.trigger("longtap",[ba.target]);if(aq.longTap){a8=aq.longTap.call(aN,ba,ba.target)}}}}}return a8}function aj(){var a7=true;if(aq.threshold!==null){a7=ac>=aq.threshold}return a7}function a6(){var a7=false;if(aq.cancelThreshold!==null&&aL!==null){a7=(aP(aL)-ac)>=aq.cancelThreshold}return a7}function ab(){if(aq.pinchThreshold!==null){return am>=aq.pinchThreshold}return true}function aw(){var a7;if(aq.maxTimeThreshold){if(Y>=aq.maxTimeThreshold){a7=false}else{a7=true}}else{a7=true}return a7}function ah(a7,a8){if(aq.allowPageScroll===l||aT()){a7.preventDefault()}else{var a9=aq.allowPageScroll===r;switch(a8){case o:if((aq.swipeLeft&&a9)||(!a9&&aq.allowPageScroll!=A)){a7.preventDefault()}break;case n:if((aq.swipeRight&&a9)||(!a9&&aq.allowPageScroll!=A)){a7.preventDefault()}break;case d:if((aq.swipeUp&&a9)||(!a9&&aq.allowPageScroll!=t)){a7.preventDefault()}break;case v:if((aq.swipeDown&&a9)||(!a9&&aq.allowPageScroll!=t)){a7.preventDefault()}break}}}function a4(){var a8=aK();var a7=U();var a9=ab();return a8&&a7&&a9}function aT(){return !!(aq.pinchStatus||aq.pinchIn||aq.pinchOut)}function M(){return !!(a4()&&aT())}function aR(){var ba=aw();var bc=aj();var a9=aK();var a7=U();var a8=a6();var bb=!a8&&a7&&a9&&bc&&ba;return bb}function S(){return !!(aq.swipe||aq.swipeStatus||aq.swipeLeft||aq.swipeRight||aq.swipeUp||aq.swipeDown)}function F(){return !!(aR()&&S())}function aK(){return((T===aq.fingers||aq.fingers===h)||!a)}function U(){return aM[0].end.x!==0}function a2(){return !!(aq.tap)}function V(){return !!(aq.doubleTap)}function aQ(){return !!(aq.longTap)}function N(){if(K==null){return false}var a7=ao();return(V()&&((a7-K)<=aq.doubleTapThreshold))}function E(){return N()}function at(){return((T===1||!a)&&(isNaN(ac)||ac===0))}function aW(){return((Y>aq.longTapThreshold)&&(ac<q))}function ad(){return !!(at()&&a2())}function aC(){return !!(N()&&V())}function al(){return !!(aW()&&aQ())}function C(){a1=ao();aa=event.touches.length+1}function O(){a1=0;aa=0}function ai(){var a7=false;if(a1){var a8=ao()-a1;if(a8<=aq.fingerReleaseThreshold){a7=true}}return a7}function ax(){return !!(aN.data(y+"_intouch")===true)}function ak(a7){if(a7===true){aN.bind(au,aZ);aN.bind(R,I);if(P){aN.bind(P,H)}}else{aN.unbind(au,aZ,false);aN.unbind(R,I,false);if(P){aN.unbind(P,H,false)}}aN.data(y+"_intouch",a7===true)}function ae(a8,a7){var a9=a7.identifier!==undefined?a7.identifier:0;aM[a8].identifier=a9;aM[a8].start.x=aM[a8].end.x=a7.pageX||a7.clientX;aM[a8].start.y=aM[a8].end.y=a7.pageY||a7.clientY;return aM[a8]}function aD(a7){var a9=a7.identifier!==undefined?a7.identifier:0;var a8=Z(a9);a8.end.x=a7.pageX||a7.clientX;a8.end.y=a7.pageY||a7.clientY;return a8}function Z(a8){for(var a7=0;a7<aM.length;a7++){if(aM[a7].identifier==a8){return aM[a7]}}}function af(){var a7=[];for(var a8=0;a8<=5;a8++){a7.push({start:{x:0,y:0},end:{x:0,y:0},identifier:0})}return a7}function aE(a7,a8){a8=Math.max(a8,aP(a7));J[a7].distance=a8}function aP(a7){return J[a7].distance}function X(){var a7={};a7[o]=ar(o);a7[n]=ar(n);a7[d]=ar(d);a7[v]=ar(v);return a7}function ar(a7){return{direction:a7,distance:0}}function aI(){return aY-Q}function ap(ba,a9){var a8=Math.abs(ba.x-a9.x);var a7=Math.abs(ba.y-a9.y);return Math.round(Math.sqrt(a8*a8+a7*a7))}function a3(a7,a8){var a9=(a8/a7)*1;return a9.toFixed(2)}function an(){if(D<1){return w}else{return c}}function aO(a8,a7){return Math.round(Math.sqrt(Math.pow(a7.x-a8.x,2)+Math.pow(a7.y-a8.y,2)))}function aA(ba,a8){var a7=ba.x-a8.x;var bc=a8.y-ba.y;var a9=Math.atan2(bc,a7);var bb=Math.round(a9*180/Math.PI);if(bb<0){bb=360-Math.abs(bb)}return bb}function aH(a8,a7){var a9=aA(a8,a7);if((a9<=45)&&(a9>=0)){return o}else{if((a9<=360)&&(a9>=315)){return o}else{if((a9>=135)&&(a9<=225)){return n}else{if((a9>45)&&(a9<135)){return v}else{return d}}}}}function ao(){var a7=new Date();return a7.getTime()}function aU(a7){a7=e(a7);var a9=a7.offset();var a8={left:a9.left,right:a9.left+a7.outerWidth(),top:a9.top,bottom:a9.top+a7.outerHeight()};return a8}function B(a7,a8){return(a7.x>a8.left&&a7.x<a8.right&&a7.y>a8.top&&a7.y<a8.bottom)}}})(jQuery);
/* jquery.validate.min.js */
/*! jQuery Validation Plugin - v1.13.1 - 10/14/2014
 * http://jqueryvalidation.org/
 * Copyright (c) 2014 JÃ¶rn Zaefferer; Licensed MIT */
!function(a){"function"==typeof define&&define.amd?define(["jquery"],a):a(jQuery)}(function(a){a.extend(a.fn,{validate:function(b){if(!this.length)return void(b&&b.debug&&window.console&&console.warn("Nothing selected, can't validate, returning nothing."));var c=a.data(this[0],"validator");return c?c:(this.attr("novalidate","novalidate"),c=new a.validator(b,this[0]),a.data(this[0],"validator",c),c.settings.onsubmit&&(this.validateDelegate(":submit","click",function(b){c.settings.submitHandler&&(c.submitButton=b.target),a(b.target).hasClass("cancel")&&(c.cancelSubmit=!0),void 0!==a(b.target).attr("formnovalidate")&&(c.cancelSubmit=!0)}),this.submit(function(b){function d(){var d,e;return c.settings.submitHandler?(c.submitButton&&(d=a("<input type='hidden'/>").attr("name",c.submitButton.name).val(a(c.submitButton).val()).appendTo(c.currentForm)),e=c.settings.submitHandler.call(c,c.currentForm,b),c.submitButton&&d.remove(),void 0!==e?e:!1):!0}return c.settings.debug&&b.preventDefault(),c.cancelSubmit?(c.cancelSubmit=!1,d()):c.form()?c.pendingRequest?(c.formSubmitted=!0,!1):d():(c.focusInvalid(),!1)})),c)},valid:function(){var b,c;return a(this[0]).is("form")?b=this.validate().form():(b=!0,c=a(this[0].form).validate(),this.each(function(){b=c.element(this)&&b})),b},removeAttrs:function(b){var c={},d=this;return a.each(b.split(/\s/),function(a,b){c[b]=d.attr(b),d.removeAttr(b)}),c},rules:function(b,c){var d,e,f,g,h,i,j=this[0];if(b)switch(d=a.data(j.form,"validator").settings,e=d.rules,f=a.validator.staticRules(j),b){case"add":a.extend(f,a.validator.normalizeRule(c)),delete f.messages,e[j.name]=f,c.messages&&(d.messages[j.name]=a.extend(d.messages[j.name],c.messages));break;case"remove":return c?(i={},a.each(c.split(/\s/),function(b,c){i[c]=f[c],delete f[c],"required"===c&&a(j).removeAttr("aria-required")}),i):(delete e[j.name],f)}return g=a.validator.normalizeRules(a.extend({},a.validator.classRules(j),a.validator.attributeRules(j),a.validator.dataRules(j),a.validator.staticRules(j)),j),g.required&&(h=g.required,delete g.required,g=a.extend({required:h},g),a(j).attr("aria-required","true")),g.remote&&(h=g.remote,delete g.remote,g=a.extend(g,{remote:h})),g}}),a.extend(a.expr[":"],{blank:function(b){return!a.trim(""+a(b).val())},filled:function(b){return!!a.trim(""+a(b).val())},unchecked:function(b){return!a(b).prop("checked")}}),a.validator=function(b,c){this.settings=a.extend(!0,{},a.validator.defaults,b),this.currentForm=c,this.init()},a.validator.format=function(b,c){return 1===arguments.length?function(){var c=a.makeArray(arguments);return c.unshift(b),a.validator.format.apply(this,c)}:(arguments.length>2&&c.constructor!==Array&&(c=a.makeArray(arguments).slice(1)),c.constructor!==Array&&(c=[c]),a.each(c,function(a,c){b=b.replace(new RegExp("\\{"+a+"\\}","g"),function(){return c})}),b)},a.extend(a.validator,{defaults:{messages:{},groups:{},rules:{},errorClass:"error",validClass:"valid",errorElement:"label",focusCleanup:!1,focusInvalid:!0,errorContainer:a([]),errorLabelContainer:a([]),onsubmit:!0,ignore:":hidden",ignoreTitle:!1,onfocusin:function(a){this.lastActive=a,this.settings.focusCleanup&&(this.settings.unhighlight&&this.settings.unhighlight.call(this,a,this.settings.errorClass,this.settings.validClass),this.hideThese(this.errorsFor(a)))},onfocusout:function(a){this.checkable(a)||!(a.name in this.submitted)&&this.optional(a)||this.element(a)},onkeyup:function(a,b){(9!==b.which||""!==this.elementValue(a))&&(a.name in this.submitted||a===this.lastElement)&&this.element(a)},onclick:function(a){a.name in this.submitted?this.element(a):a.parentNode.name in this.submitted&&this.element(a.parentNode)},highlight:function(b,c,d){"radio"===b.type?this.findByName(b.name).addClass(c).removeClass(d):a(b).addClass(c).removeClass(d)},unhighlight:function(b,c,d){"radio"===b.type?this.findByName(b.name).removeClass(c).addClass(d):a(b).removeClass(c).addClass(d)}},setDefaults:function(b){a.extend(a.validator.defaults,b)},messages:{required:"This field is required.",remote:"Please fix this field.",email:"Please enter a valid email address.",url:"Please enter a valid URL.",date:"Please enter a valid date.",dateISO:"Please enter a valid date ( ISO ).",number:"Please enter a valid number.",digits:"Please enter only digits.",creditcard:"Please enter a valid credit card number.",equalTo:"Please enter the same value again.",maxlength:a.validator.format("Please enter no more than {0} characters."),minlength:a.validator.format("Please enter at least {0} characters."),rangelength:a.validator.format("Please enter a value between {0} and {1} characters long."),range:a.validator.format("Please enter a value between {0} and {1}."),max:a.validator.format("Please enter a value less than or equal to {0}."),min:a.validator.format("Please enter a value greater than or equal to {0}.")},autoCreateRanges:!1,prototype:{init:function(){function b(b){var c=a.data(this[0].form,"validator"),d="on"+b.type.replace(/^validate/,""),e=c.settings;e[d]&&!this.is(e.ignore)&&e[d].call(c,this[0],b)}this.labelContainer=a(this.settings.errorLabelContainer),this.errorContext=this.labelContainer.length&&this.labelContainer||a(this.currentForm),this.containers=a(this.settings.errorContainer).add(this.settings.errorLabelContainer),this.submitted={},this.valueCache={},this.pendingRequest=0,this.pending={},this.invalid={},this.reset();var c,d=this.groups={};a.each(this.settings.groups,function(b,c){"string"==typeof c&&(c=c.split(/\s/)),a.each(c,function(a,c){d[c]=b})}),c=this.settings.rules,a.each(c,function(b,d){c[b]=a.validator.normalizeRule(d)}),a(this.currentForm).validateDelegate(":text, [type='password'], [type='file'], select, textarea, [type='number'], [type='search'] ,[type='tel'], [type='url'], [type='email'], [type='datetime'], [type='date'], [type='month'], [type='week'], [type='time'], [type='datetime-local'], [type='range'], [type='color'], [type='radio'], [type='checkbox']","focusin focusout keyup",b).validateDelegate("select, option, [type='radio'], [type='checkbox']","click",b),this.settings.invalidHandler&&a(this.currentForm).bind("invalid-form.validate",this.settings.invalidHandler),a(this.currentForm).find("[required], [data-rule-required], .required").attr("aria-required","true")},form:function(){return this.checkForm(),a.extend(this.submitted,this.errorMap),this.invalid=a.extend({},this.errorMap),this.valid()||a(this.currentForm).triggerHandler("invalid-form",[this]),this.showErrors(),this.valid()},checkForm:function(){this.prepareForm();for(var a=0,b=this.currentElements=this.elements();b[a];a++)this.check(b[a]);return this.valid()},element:function(b){var c=this.clean(b),d=this.validationTargetFor(c),e=!0;return this.lastElement=d,void 0===d?delete this.invalid[c.name]:(this.prepareElement(d),this.currentElements=a(d),e=this.check(d)!==!1,e?delete this.invalid[d.name]:this.invalid[d.name]=!0),a(b).attr("aria-invalid",!e),this.numberOfInvalids()||(this.toHide=this.toHide.add(this.containers)),this.showErrors(),e},showErrors:function(b){if(b){a.extend(this.errorMap,b),this.errorList=[];for(var c in b)this.errorList.push({message:b[c],element:this.findByName(c)[0]});this.successList=a.grep(this.successList,function(a){return!(a.name in b)})}this.settings.showErrors?this.settings.showErrors.call(this,this.errorMap,this.errorList):this.defaultShowErrors()},resetForm:function(){a.fn.resetForm&&a(this.currentForm).resetForm(),this.submitted={},this.lastElement=null,this.prepareForm(),this.hideErrors(),this.elements().removeClass(this.settings.errorClass).removeData("previousValue").removeAttr("aria-invalid")},numberOfInvalids:function(){return this.objectLength(this.invalid)},objectLength:function(a){var b,c=0;for(b in a)c++;return c},hideErrors:function(){this.hideThese(this.toHide)},hideThese:function(a){a.not(this.containers).text(""),this.addWrapper(a).hide()},valid:function(){return 0===this.size()},size:function(){return this.errorList.length},focusInvalid:function(){if(this.settings.focusInvalid)try{a(this.findLastActive()||this.errorList.length&&this.errorList[0].element||[]).filter(":visible").focus().trigger("focusin")}catch(b){}},findLastActive:function(){var b=this.lastActive;return b&&1===a.grep(this.errorList,function(a){return a.element.name===b.name}).length&&b},elements:function(){var b=this,c={};return a(this.currentForm).find("input, select, textarea").not(":submit, :reset, :image, [disabled], [readonly]").not(this.settings.ignore).filter(function(){return!this.name&&b.settings.debug&&window.console&&console.error("%o has no name assigned",this),this.name in c||!b.objectLength(a(this).rules())?!1:(c[this.name]=!0,!0)})},clean:function(b){return a(b)[0]},errors:function(){var b=this.settings.errorClass.split(" ").join(".");return a(this.settings.errorElement+"."+b,this.errorContext)},reset:function(){this.successList=[],this.errorList=[],this.errorMap={},this.toShow=a([]),this.toHide=a([]),this.currentElements=a([])},prepareForm:function(){this.reset(),this.toHide=this.errors().add(this.containers)},prepareElement:function(a){this.reset(),this.toHide=this.errorsFor(a)},elementValue:function(b){var c,d=a(b),e=b.type;return"radio"===e||"checkbox"===e?a("input[name='"+b.name+"']:checked").val():"number"===e&&"undefined"!=typeof b.validity?b.validity.badInput?!1:d.val():(c=d.val(),"string"==typeof c?c.replace(/\r/g,""):c)},check:function(b){b=this.validationTargetFor(this.clean(b));var c,d,e,f=a(b).rules(),g=a.map(f,function(a,b){return b}).length,h=!1,i=this.elementValue(b);for(d in f){e={method:d,parameters:f[d]};try{if(c=a.validator.methods[d].call(this,i,b,e.parameters),"dependency-mismatch"===c&&1===g){h=!0;continue}if(h=!1,"pending"===c)return void(this.toHide=this.toHide.not(this.errorsFor(b)));if(!c)return this.formatAndAdd(b,e),!1}catch(j){throw this.settings.debug&&window.console&&console.log("Exception occurred when checking element "+b.id+", check the '"+e.method+"' method.",j),j}}if(!h)return this.objectLength(f)&&this.successList.push(b),!0},customDataMessage:function(b,c){return a(b).data("msg"+c.charAt(0).toUpperCase()+c.substring(1).toLowerCase())||a(b).data("msg")},customMessage:function(a,b){var c=this.settings.messages[a];return c&&(c.constructor===String?c:c[b])},findDefined:function(){for(var a=0;a<arguments.length;a++)if(void 0!==arguments[a])return arguments[a];return void 0},defaultMessage:function(b,c){return this.findDefined(this.customMessage(b.name,c),this.customDataMessage(b,c),!this.settings.ignoreTitle&&b.title||void 0,a.validator.messages[c],"<strong>Warning: No message defined for "+b.name+"</strong>")},formatAndAdd:function(b,c){var d=this.defaultMessage(b,c.method),e=/\$?\{(\d+)\}/g;"function"==typeof d?d=d.call(this,c.parameters,b):e.test(d)&&(d=a.validator.format(d.replace(e,"{$1}"),c.parameters)),this.errorList.push({message:d,element:b,method:c.method}),this.errorMap[b.name]=d,this.submitted[b.name]=d},addWrapper:function(a){return this.settings.wrapper&&(a=a.add(a.parent(this.settings.wrapper))),a},defaultShowErrors:function(){var a,b,c;for(a=0;this.errorList[a];a++)c=this.errorList[a],this.settings.highlight&&this.settings.highlight.call(this,c.element,this.settings.errorClass,this.settings.validClass),this.showLabel(c.element,c.message);if(this.errorList.length&&(this.toShow=this.toShow.add(this.containers)),this.settings.success)for(a=0;this.successList[a];a++)this.showLabel(this.successList[a]);if(this.settings.unhighlight)for(a=0,b=this.validElements();b[a];a++)this.settings.unhighlight.call(this,b[a],this.settings.errorClass,this.settings.validClass);this.toHide=this.toHide.not(this.toShow),this.hideErrors(),this.addWrapper(this.toShow).show()},validElements:function(){return this.currentElements.not(this.invalidElements())},invalidElements:function(){return a(this.errorList).map(function(){return this.element})},showLabel:function(b,c){var d,e,f,g=this.errorsFor(b),h=this.idOrName(b),i=a(b).attr("aria-describedby");g.length?(g.removeClass(this.settings.validClass).addClass(this.settings.errorClass),g.html(c)):(g=a("<"+this.settings.errorElement+">").attr("id",h+"-error").addClass(this.settings.errorClass).html(c||""),d=g,this.settings.wrapper&&(d=g.hide().show().wrap("<"+this.settings.wrapper+"/>").parent()),this.labelContainer.length?this.labelContainer.append(d):this.settings.errorPlacement?this.settings.errorPlacement(d,a(b)):d.insertAfter(b),g.is("label")?g.attr("for",h):0===g.parents("label[for='"+h+"']").length&&(f=g.attr("id").replace(/(:|\.|\[|\])/g,"\\$1"),i?i.match(new RegExp("\\b"+f+"\\b"))||(i+=" "+f):i=f,a(b).attr("aria-describedby",i),e=this.groups[b.name],e&&a.each(this.groups,function(b,c){c===e&&a("[name='"+b+"']",this.currentForm).attr("aria-describedby",g.attr("id"))}))),!c&&this.settings.success&&(g.text(""),"string"==typeof this.settings.success?g.addClass(this.settings.success):this.settings.success(g,b)),this.toShow=this.toShow.add(g)},errorsFor:function(b){var c=this.idOrName(b),d=a(b).attr("aria-describedby"),e="label[for='"+c+"'], label[for='"+c+"'] *";return d&&(e=e+", #"+d.replace(/\s+/g,", #")),this.errors().filter(e)},idOrName:function(a){return this.groups[a.name]||(this.checkable(a)?a.name:a.id||a.name)},validationTargetFor:function(b){return this.checkable(b)&&(b=this.findByName(b.name)),a(b).not(this.settings.ignore)[0]},checkable:function(a){return/radio|checkbox/i.test(a.type)},findByName:function(b){return a(this.currentForm).find("[name='"+b+"']")},getLength:function(b,c){switch(c.nodeName.toLowerCase()){case"select":return a("option:selected",c).length;case"input":if(this.checkable(c))return this.findByName(c.name).filter(":checked").length}return b.length},depend:function(a,b){return this.dependTypes[typeof a]?this.dependTypes[typeof a](a,b):!0},dependTypes:{"boolean":function(a){return a},string:function(b,c){return!!a(b,c.form).length},"function":function(a,b){return a(b)}},optional:function(b){var c=this.elementValue(b);return!a.validator.methods.required.call(this,c,b)&&"dependency-mismatch"},startRequest:function(a){this.pending[a.name]||(this.pendingRequest++,this.pending[a.name]=!0)},stopRequest:function(b,c){this.pendingRequest--,this.pendingRequest<0&&(this.pendingRequest=0),delete this.pending[b.name],c&&0===this.pendingRequest&&this.formSubmitted&&this.form()?(a(this.currentForm).submit(),this.formSubmitted=!1):!c&&0===this.pendingRequest&&this.formSubmitted&&(a(this.currentForm).triggerHandler("invalid-form",[this]),this.formSubmitted=!1)},previousValue:function(b){return a.data(b,"previousValue")||a.data(b,"previousValue",{old:null,valid:!0,message:this.defaultMessage(b,"remote")})}},classRuleSettings:{required:{required:!0},email:{email:!0},url:{url:!0},date:{date:!0},dateISO:{dateISO:!0},number:{number:!0},digits:{digits:!0},creditcard:{creditcard:!0}},addClassRules:function(b,c){b.constructor===String?this.classRuleSettings[b]=c:a.extend(this.classRuleSettings,b)},classRules:function(b){var c={},d=a(b).attr("class");return d&&a.each(d.split(" "),function(){this in a.validator.classRuleSettings&&a.extend(c,a.validator.classRuleSettings[this])}),c},attributeRules:function(b){var c,d,e={},f=a(b),g=b.getAttribute("type");for(c in a.validator.methods)"required"===c?(d=b.getAttribute(c),""===d&&(d=!0),d=!!d):d=f.attr(c),/min|max/.test(c)&&(null===g||/number|range|text/.test(g))&&(d=Number(d)),d||0===d?e[c]=d:g===c&&"range"!==g&&(e[c]=!0);return e.maxlength&&/-1|2147483647|524288/.test(e.maxlength)&&delete e.maxlength,e},dataRules:function(b){var c,d,e={},f=a(b);for(c in a.validator.methods)d=f.data("rule"+c.charAt(0).toUpperCase()+c.substring(1).toLowerCase()),void 0!==d&&(e[c]=d);return e},staticRules:function(b){var c={},d=a.data(b.form,"validator");return d.settings.rules&&(c=a.validator.normalizeRule(d.settings.rules[b.name])||{}),c},normalizeRules:function(b,c){return a.each(b,function(d,e){if(e===!1)return void delete b[d];if(e.param||e.depends){var f=!0;switch(typeof e.depends){case"string":f=!!a(e.depends,c.form).length;break;case"function":f=e.depends.call(c,c)}f?b[d]=void 0!==e.param?e.param:!0:delete b[d]}}),a.each(b,function(d,e){b[d]=a.isFunction(e)?e(c):e}),a.each(["minlength","maxlength"],function(){b[this]&&(b[this]=Number(b[this]))}),a.each(["rangelength","range"],function(){var c;b[this]&&(a.isArray(b[this])?b[this]=[Number(b[this][0]),Number(b[this][1])]:"string"==typeof b[this]&&(c=b[this].replace(/[\[\]]/g,"").split(/[\s,]+/),b[this]=[Number(c[0]),Number(c[1])]))}),a.validator.autoCreateRanges&&(null!=b.min&&null!=b.max&&(b.range=[b.min,b.max],delete b.min,delete b.max),null!=b.minlength&&null!=b.maxlength&&(b.rangelength=[b.minlength,b.maxlength],delete b.minlength,delete b.maxlength)),b},normalizeRule:function(b){if("string"==typeof b){var c={};a.each(b.split(/\s/),function(){c[this]=!0}),b=c}return b},addMethod:function(b,c,d){a.validator.methods[b]=c,a.validator.messages[b]=void 0!==d?d:a.validator.messages[b],c.length<3&&a.validator.addClassRules(b,a.validator.normalizeRule(b))},methods:{required:function(b,c,d){if(!this.depend(d,c))return"dependency-mismatch";if("select"===c.nodeName.toLowerCase()){var e=a(c).val();return e&&e.length>0}return this.checkable(c)?this.getLength(b,c)>0:a.trim(b).length>0},email:function(a,b){return this.optional(b)||/^[a-zA-Z0-9.!#$%&'*+\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/.test(a)},url:function(a,b){return this.optional(b)||/^(https?|s?ftp):\/\/(((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:)*@)?(((\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5]))|((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?)(:\d*)?)(\/((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)+(\/(([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)*)*)?)?(\?((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|[\uE000-\uF8FF]|\/|\?)*)?(#((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|\/|\?)*)?$/i.test(a)},date:function(a,b){return this.optional(b)||!/Invalid|NaN/.test(new Date(a).toString())},dateISO:function(a,b){return this.optional(b)||/^\d{4}[\/\-](0?[1-9]|1[012])[\/\-](0?[1-9]|[12][0-9]|3[01])$/.test(a)},number:function(a,b){return this.optional(b)||/^-?(?:\d+|\d{1,3}(?:,\d{3})+)?(?:\.\d+)?$/.test(a)},digits:function(a,b){return this.optional(b)||/^\d+$/.test(a)},creditcard:function(a,b){if(this.optional(b))return"dependency-mismatch";if(/[^0-9 \-]+/.test(a))return!1;var c,d,e=0,f=0,g=!1;if(a=a.replace(/\D/g,""),a.length<13||a.length>19)return!1;for(c=a.length-1;c>=0;c--)d=a.charAt(c),f=parseInt(d,10),g&&(f*=2)>9&&(f-=9),e+=f,g=!g;return e%10===0},minlength:function(b,c,d){var e=a.isArray(b)?b.length:this.getLength(b,c);return this.optional(c)||e>=d},maxlength:function(b,c,d){var e=a.isArray(b)?b.length:this.getLength(b,c);return this.optional(c)||d>=e},rangelength:function(b,c,d){var e=a.isArray(b)?b.length:this.getLength(b,c);return this.optional(c)||e>=d[0]&&e<=d[1]},min:function(a,b,c){return this.optional(b)||a>=c},max:function(a,b,c){return this.optional(b)||c>=a},range:function(a,b,c){return this.optional(b)||a>=c[0]&&a<=c[1]},equalTo:function(b,c,d){var e=a(d);return this.settings.onfocusout&&e.unbind(".validate-equalTo").bind("blur.validate-equalTo",function(){a(c).valid()}),b===e.val()},remote:function(b,c,d){if(this.optional(c))return"dependency-mismatch";var e,f,g=this.previousValue(c);return this.settings.messages[c.name]||(this.settings.messages[c.name]={}),g.originalMessage=this.settings.messages[c.name].remote,this.settings.messages[c.name].remote=g.message,d="string"==typeof d&&{url:d}||d,g.old===b?g.valid:(g.old=b,e=this,this.startRequest(c),f={},f[c.name]=b,a.ajax(a.extend(!0,{url:d,mode:"abort",port:"validate"+c.name,dataType:"json",data:f,context:e.currentForm,success:function(d){var f,h,i,j=d===!0||"true"===d;e.settings.messages[c.name].remote=g.originalMessage,j?(i=e.formSubmitted,e.prepareElement(c),e.formSubmitted=i,e.successList.push(c),delete e.invalid[c.name],e.showErrors()):(f={},h=d||e.defaultMessage(c,"remote"),f[c.name]=g.message=a.isFunction(h)?h(b):h,e.invalid[c.name]=!0,e.showErrors(f)),g.valid=j,e.stopRequest(c,j)}},d)),"pending")}}}),a.format=function(){throw"$.format has been deprecated. Please use $.validator.format instead."};var b,c={};a.ajaxPrefilter?a.ajaxPrefilter(function(a,b,d){var e=a.port;"abort"===a.mode&&(c[e]&&c[e].abort(),c[e]=d)}):(b=a.ajax,a.ajax=function(d){var e=("mode"in d?d:a.ajaxSettings).mode,f=("port"in d?d:a.ajaxSettings).port;return"abort"===e?(c[f]&&c[f].abort(),c[f]=b.apply(this,arguments),c[f]):b.apply(this,arguments)}),a.extend(a.fn,{validateDelegate:function(b,c,d){return this.bind(c,function(c){var e=a(c.target);return e.is(b)?d.apply(e,arguments):void 0})}})});
/* swfobject-2.2.min.js */
/*	SWFObject v2.2 <http://code.google.com/p/swfobject/> 
	is released under the MIT License <http://www.opensource.org/licenses/mit-license.php> 
*/
var swfobject=function(){var D="undefined",r="object",S="Shockwave Flash",W="ShockwaveFlash.ShockwaveFlash",q="application/x-shockwave-flash",R="SWFObjectExprInst",x="onreadystatechange",O=window,j=document,t=navigator,T=false,U=[h],o=[],N=[],I=[],l,Q,E,B,J=false,a=false,n,G,m=true,M=function(){var aa=typeof j.getElementById!=D&&typeof j.getElementsByTagName!=D&&typeof j.createElement!=D,ah=t.userAgent.toLowerCase(),Y=t.platform.toLowerCase(),ae=Y?/win/.test(Y):/win/.test(ah),ac=Y?/mac/.test(Y):/mac/.test(ah),af=/webkit/.test(ah)?parseFloat(ah.replace(/^.*webkit\/(\d+(\.\d+)?).*$/,"$1")):false,X=!+"\v1",ag=[0,0,0],ab=null;if(typeof t.plugins!=D&&typeof t.plugins[S]==r){ab=t.plugins[S].description;if(ab&&!(typeof t.mimeTypes!=D&&t.mimeTypes[q]&&!t.mimeTypes[q].enabledPlugin)){T=true;X=false;ab=ab.replace(/^.*\s+(\S+\s+\S+$)/,"$1");ag[0]=parseInt(ab.replace(/^(.*)\..*$/,"$1"),10);ag[1]=parseInt(ab.replace(/^.*\.(.*)\s.*$/,"$1"),10);ag[2]=/[a-zA-Z]/.test(ab)?parseInt(ab.replace(/^.*[a-zA-Z]+(.*)$/,"$1"),10):0}}else{if(typeof O.ActiveXObject!=D){try{var ad=new ActiveXObject(W);if(ad){ab=ad.GetVariable("$version");if(ab){X=true;ab=ab.split(" ")[1].split(",");ag=[parseInt(ab[0],10),parseInt(ab[1],10),parseInt(ab[2],10)]}}}catch(Z){}}}return{w3:aa,pv:ag,wk:af,ie:X,win:ae,mac:ac}}(),k=function(){if(!M.w3){return}if((typeof j.readyState!=D&&j.readyState=="complete")||(typeof j.readyState==D&&(j.getElementsByTagName("body")[0]||j.body))){f()}if(!J){if(typeof j.addEventListener!=D){j.addEventListener("DOMContentLoaded",f,false)}if(M.ie&&M.win){j.attachEvent(x,function(){if(j.readyState=="complete"){j.detachEvent(x,arguments.callee);f()}});if(O==top){(function(){if(J){return}try{j.documentElement.doScroll("left")}catch(X){setTimeout(arguments.callee,0);return}f()})()}}if(M.wk){(function(){if(J){return}if(!/loaded|complete/.test(j.readyState)){setTimeout(arguments.callee,0);return}f()})()}s(f)}}();function f(){if(J){return}try{var Z=j.getElementsByTagName("body")[0].appendChild(C("span"));Z.parentNode.removeChild(Z)}catch(aa){return}J=true;var X=U.length;for(var Y=0;Y<X;Y++){U[Y]()}}function K(X){if(J){X()}else{U[U.length]=X}}function s(Y){if(typeof O.addEventListener!=D){O.addEventListener("load",Y,false)}else{if(typeof j.addEventListener!=D){j.addEventListener("load",Y,false)}else{if(typeof O.attachEvent!=D){i(O,"onload",Y)}else{if(typeof O.onload=="function"){var X=O.onload;O.onload=function(){X();Y()}}else{O.onload=Y}}}}}function h(){if(T){V()}else{H()}}function V(){var X=j.getElementsByTagName("body")[0];var aa=C(r);aa.setAttribute("type",q);var Z=X.appendChild(aa);if(Z){var Y=0;(function(){if(typeof Z.GetVariable!=D){var ab=Z.GetVariable("$version");if(ab){ab=ab.split(" ")[1].split(",");M.pv=[parseInt(ab[0],10),parseInt(ab[1],10),parseInt(ab[2],10)]}}else{if(Y<10){Y++;setTimeout(arguments.callee,10);return}}X.removeChild(aa);Z=null;H()})()}else{H()}}function H(){var ag=o.length;if(ag>0){for(var af=0;af<ag;af++){var Y=o[af].id;var ab=o[af].callbackFn;var aa={success:false,id:Y};if(M.pv[0]>0){var ae=c(Y);if(ae){if(F(o[af].swfVersion)&&!(M.wk&&M.wk<312)){w(Y,true);if(ab){aa.success=true;aa.ref=z(Y);ab(aa)}}else{if(o[af].expressInstall&&A()){var ai={};ai.data=o[af].expressInstall;ai.width=ae.getAttribute("width")||"0";ai.height=ae.getAttribute("height")||"0";if(ae.getAttribute("class")){ai.styleclass=ae.getAttribute("class")}if(ae.getAttribute("align")){ai.align=ae.getAttribute("align")}var ah={};var X=ae.getElementsByTagName("param");var ac=X.length;for(var ad=0;ad<ac;ad++){if(X[ad].getAttribute("name").toLowerCase()!="movie"){ah[X[ad].getAttribute("name")]=X[ad].getAttribute("value")}}P(ai,ah,Y,ab)}else{p(ae);if(ab){ab(aa)}}}}}else{w(Y,true);if(ab){var Z=z(Y);if(Z&&typeof Z.SetVariable!=D){aa.success=true;aa.ref=Z}ab(aa)}}}}}function z(aa){var X=null;var Y=c(aa);if(Y&&Y.nodeName=="OBJECT"){if(typeof Y.SetVariable!=D){X=Y}else{var Z=Y.getElementsByTagName(r)[0];if(Z){X=Z}}}return X}function A(){return !a&&F("6.0.65")&&(M.win||M.mac)&&!(M.wk&&M.wk<312)}function P(aa,ab,X,Z){a=true;E=Z||null;B={success:false,id:X};var ae=c(X);if(ae){if(ae.nodeName=="OBJECT"){l=g(ae);Q=null}else{l=ae;Q=X}aa.id=R;if(typeof aa.width==D||(!/%$/.test(aa.width)&&parseInt(aa.width,10)<310)){aa.width="310"}if(typeof aa.height==D||(!/%$/.test(aa.height)&&parseInt(aa.height,10)<137)){aa.height="137"}j.title=j.title.slice(0,47)+" - Flash Player Installation";var ad=M.ie&&M.win?"ActiveX":"PlugIn",ac="MMredirectURL="+O.location.toString().replace(/&/g,"%26")+"&MMplayerType="+ad+"&MMdoctitle="+j.title;if(typeof ab.flashvars!=D){ab.flashvars+="&"+ac}else{ab.flashvars=ac}if(M.ie&&M.win&&ae.readyState!=4){var Y=C("div");X+="SWFObjectNew";Y.setAttribute("id",X);ae.parentNode.insertBefore(Y,ae);ae.style.display="none";(function(){if(ae.readyState==4){ae.parentNode.removeChild(ae)}else{setTimeout(arguments.callee,10)}})()}u(aa,ab,X)}}function p(Y){if(M.ie&&M.win&&Y.readyState!=4){var X=C("div");Y.parentNode.insertBefore(X,Y);X.parentNode.replaceChild(g(Y),X);Y.style.display="none";(function(){if(Y.readyState==4){Y.parentNode.removeChild(Y)}else{setTimeout(arguments.callee,10)}})()}else{Y.parentNode.replaceChild(g(Y),Y)}}function g(ab){var aa=C("div");if(M.win&&M.ie){aa.innerHTML=ab.innerHTML}else{var Y=ab.getElementsByTagName(r)[0];if(Y){var ad=Y.childNodes;if(ad){var X=ad.length;for(var Z=0;Z<X;Z++){if(!(ad[Z].nodeType==1&&ad[Z].nodeName=="PARAM")&&!(ad[Z].nodeType==8)){aa.appendChild(ad[Z].cloneNode(true))}}}}}return aa}function u(ai,ag,Y){var X,aa=c(Y);if(M.wk&&M.wk<312){return X}if(aa){if(typeof ai.id==D){ai.id=Y}if(M.ie&&M.win){var ah="";for(var ae in ai){if(ai[ae]!=Object.prototype[ae]){if(ae.toLowerCase()=="data"){ag.movie=ai[ae]}else{if(ae.toLowerCase()=="styleclass"){ah+=' class="'+ai[ae]+'"'}else{if(ae.toLowerCase()!="classid"){ah+=" "+ae+'="'+ai[ae]+'"'}}}}}var af="";for(var ad in ag){if(ag[ad]!=Object.prototype[ad]){af+='<param name="'+ad+'" value="'+ag[ad]+'" />'}}aa.outerHTML='<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"'+ah+">"+af+"</object>";N[N.length]=ai.id;X=c(ai.id)}else{var Z=C(r);Z.setAttribute("type",q);for(var ac in ai){if(ai[ac]!=Object.prototype[ac]){if(ac.toLowerCase()=="styleclass"){Z.setAttribute("class",ai[ac])}else{if(ac.toLowerCase()!="classid"){Z.setAttribute(ac,ai[ac])}}}}for(var ab in ag){if(ag[ab]!=Object.prototype[ab]&&ab.toLowerCase()!="movie"){e(Z,ab,ag[ab])}}aa.parentNode.replaceChild(Z,aa);X=Z}}return X}function e(Z,X,Y){var aa=C("param");aa.setAttribute("name",X);aa.setAttribute("value",Y);Z.appendChild(aa)}function y(Y){var X=c(Y);if(X&&X.nodeName=="OBJECT"){if(M.ie&&M.win){X.style.display="none";(function(){if(X.readyState==4){b(Y)}else{setTimeout(arguments.callee,10)}})()}else{X.parentNode.removeChild(X)}}}function b(Z){var Y=c(Z);if(Y){for(var X in Y){if(typeof Y[X]=="function"){Y[X]=null}}Y.parentNode.removeChild(Y)}}function c(Z){var X=null;try{X=j.getElementById(Z)}catch(Y){}return X}function C(X){return j.createElement(X)}function i(Z,X,Y){Z.attachEvent(X,Y);I[I.length]=[Z,X,Y]}function F(Z){var Y=M.pv,X=Z.split(".");X[0]=parseInt(X[0],10);X[1]=parseInt(X[1],10)||0;X[2]=parseInt(X[2],10)||0;return(Y[0]>X[0]||(Y[0]==X[0]&&Y[1]>X[1])||(Y[0]==X[0]&&Y[1]==X[1]&&Y[2]>=X[2]))?true:false}function v(ac,Y,ad,ab){if(M.ie&&M.mac){return}var aa=j.getElementsByTagName("head")[0];if(!aa){return}var X=(ad&&typeof ad=="string")?ad:"screen";if(ab){n=null;G=null}if(!n||G!=X){var Z=C("style");Z.setAttribute("type","text/css");Z.setAttribute("media",X);n=aa.appendChild(Z);if(M.ie&&M.win&&typeof j.styleSheets!=D&&j.styleSheets.length>0){n=j.styleSheets[j.styleSheets.length-1]}G=X}if(M.ie&&M.win){if(n&&typeof n.addRule==r){n.addRule(ac,Y)}}else{if(n&&typeof j.createTextNode!=D){n.appendChild(j.createTextNode(ac+" {"+Y+"}"))}}}function w(Z,X){if(!m){return}var Y=X?"visible":"hidden";if(J&&c(Z)){c(Z).style.visibility=Y}else{v("#"+Z,"visibility:"+Y)}}function L(Y){var Z=/[\\\"<>\.;]/;var X=Z.exec(Y)!=null;return X&&typeof encodeURIComponent!=D?encodeURIComponent(Y):Y}var d=function(){if(M.ie&&M.win){window.attachEvent("onunload",function(){var ac=I.length;for(var ab=0;ab<ac;ab++){I[ab][0].detachEvent(I[ab][1],I[ab][2])}var Z=N.length;for(var aa=0;aa<Z;aa++){y(N[aa])}for(var Y in M){M[Y]=null}M=null;for(var X in swfobject){swfobject[X]=null}swfobject=null})}}();return{registerObject:function(ab,X,aa,Z){if(M.w3&&ab&&X){var Y={};Y.id=ab;Y.swfVersion=X;Y.expressInstall=aa;Y.callbackFn=Z;o[o.length]=Y;w(ab,false)}else{if(Z){Z({success:false,id:ab})}}},getObjectById:function(X){if(M.w3){return z(X)}},embedSWF:function(ab,ah,ae,ag,Y,aa,Z,ad,af,ac){var X={success:false,id:ah};if(M.w3&&!(M.wk&&M.wk<312)&&ab&&ah&&ae&&ag&&Y){w(ah,false);K(function(){ae+="";ag+="";var aj={};if(af&&typeof af===r){for(var al in af){aj[al]=af[al]}}aj.data=ab;aj.width=ae;aj.height=ag;var am={};if(ad&&typeof ad===r){for(var ak in ad){am[ak]=ad[ak]}}if(Z&&typeof Z===r){for(var ai in Z){if(typeof am.flashvars!=D){am.flashvars+="&"+ai+"="+Z[ai]}else{am.flashvars=ai+"="+Z[ai]}}}if(F(Y)){var an=u(aj,am,ah);if(aj.id==ah){w(ah,true)}X.success=true;X.ref=an}else{if(aa&&A()){aj.data=aa;P(aj,am,ah,ac);return}else{w(ah,true)}}if(ac){ac(X)}})}else{if(ac){ac(X)}}},switchOffAutoHideShow:function(){m=false},ua:M,getFlashPlayerVersion:function(){return{major:M.pv[0],minor:M.pv[1],release:M.pv[2]}},hasFlashPlayerVersion:F,createSWF:function(Z,Y,X){if(M.w3){return u(Z,Y,X)}else{return undefined}},showExpressInstall:function(Z,aa,X,Y){if(M.w3&&A()){P(Z,aa,X,Y)}},removeSWF:function(X){if(M.w3){y(X)}},createCSS:function(aa,Z,Y,X){if(M.w3){v(aa,Z,Y,X)}},addDomLoadEvent:K,addLoadEvent:s,getQueryParamValue:function(aa){var Z=j.location.search||j.location.hash;if(Z){if(/\?/.test(Z)){Z=Z.split("?")[1]}if(aa==null){return L(Z)}var Y=Z.split("&");for(var X=0;X<Y.length;X++){if(Y[X].substring(0,Y[X].indexOf("="))==aa){return L(Y[X].substring((Y[X].indexOf("=")+1)))}}}return""},expressInstallCallback:function(){if(a){var X=c(R);if(X&&l){X.parentNode.replaceChild(l,X);if(Q){w(Q,true);if(M.ie&&M.win){l.style.display="block"}}if(E){E(B)}}a=false}}}}();
/* TargetEverestVideoPlayer.js */
 
var ABV = ABV || {};

if(typeof log == "undefined") {
	function log(str) { try { console.log(str); } catch(e) {} }
}

ABV.EverestVideoPlayer = function(containerId, width, height, playerUrl, name, options) {
	if(typeof ABV.EverestVideoPlayer.instances == "undefined")
		ABV.EverestVideoPlayer.instances = [];
		
	this.videoPlayerId = ABV.EverestVideoPlayer.instances.length;
	ABV.EverestVideoPlayer.instances.push(this);
		
	this.containerId_ = containerId;
	this.flashId_ = "flashVideoPlayer" + this.videoPlayerId;
	
	this.flashPlayer_ = null;
	this.name = "ABV.EverestVideoPlayer.instances["+this.videoPlayerId+"]";
	this.playerUrl_ = playerUrl || null;
	this.expressInstallUrl_ = null;

	this.flashParams_ = [
		{"name": "allowScriptAccess", "value": "always"},
		{"name": "allowFullScreen",   "value": "true"},
		{"name": "wmode",             "value": "opaque"}
	];
	this.flashVars_ = [];
	
	this.width_ = width || 558;
	this.height_ = height || 322;
	this.version_ = "9.0.115";
	
	this.movieLoadTimeout_ = 2000;
	this.retryInterval_ = 50;
	this.flashHasLoaded_ = false;
	this.isSWFReady = false;
	this.currentStream = null;
	
	//set flashvars from options
	if(typeof options == "object"){
		var item;
		for(item in options){
			this.addFlashVar(item, options[item]);
		}
	}
	
	//register callback method and id of this instance
	this.addFlashVar("objectName", this.name);
	this.addFlashVar("readyCallback", this.name+".onSWFReady");
	this.createFlashPlayer();
	if(options && options["source"]) this.currentStream = options;
};

ABV.EverestVideoPlayer.prototype.onSWFReady = function() {
	
	if(this.isSWFReady == true){
		return;
	}
	
	this.isSWFReady = true;
	if(this.currentStream){
		try { 
			if(this.flashPlayer_ == null) this.flashPlayer_ = this.getFlashPlayer();
			this.flashPlayer_.source(this.currentStream);
			log("success");	
		}			
		catch(e) {
			log("error " + e);
		}
	}
};

ABV.EverestVideoPlayer.prototype.setFlashId = function(flashId) {
	this.flashId_ = flashId;
};

ABV.EverestVideoPlayer.prototype.setPlayerUrl = function(playerUrl) {
	this.playerUrl_ = playerUrl;
};

ABV.EverestVideoPlayer.prototype.setVersion = function(version) {
	this.version_ = version;
};

ABV.EverestVideoPlayer.prototype.setExpressInstallUrl = function(expressInstallUrl) {
	this.expressInstallUrl_ = expressInstallUrl;
};

ABV.EverestVideoPlayer.prototype.addParameter = function(name, value) {
	var found = false;
	for(var i = 0; !found && i < this.flashParams_.length; ++i) {
		if(name == this.flashParams_[i].name) {
			this.flashParams_[i].value = value;
			found = true;
		}
	}
	if(!found) 
		this.flashParams_.push({"name": name, "value": value});
};

ABV.EverestVideoPlayer.prototype.addFlashVar = function(name, value) {
	this.flashVars_.push({"name": name, "value": value});
};

ABV.EverestVideoPlayer.prototype.movieIsLoaded = function() {
	
	log("movieIsLoaded :: " + this.flashHasLoaded_ + " : " + this.flashPlayer_ + " : " + this.flashPlayer_.PercentLoaded())
	
	if (this.flashHasLoaded_)
		return true;
	
	try {
		// First make sure the movie's defined. Browsers treat this 
		// differently, so return false on error.
		if (this.flashPlayer_ && this.flashPlayer_.PercentLoaded()) {
			// If it is, check how much of it is loaded.
			if (this.flashPlayer_.PercentLoaded() == 100) {
				this.flashHasLoaded_ = true;
				return true;
			} 
			else {
				return false;
			}
		} 
		else {
			// If the movie isn't defined, it's not loaded.
			return false;
		}
	}
	catch(err){
		log("movieIsLoaded: error" + err);
		return false;
	}
}

ABV.EverestVideoPlayer.prototype.playVideo = function(options) {
	this.currentStream = options;
	this.flashPlayer_ = this.getFlashPlayer();
	if(this.flashPlayer_ == null) {
		this.createFlashPlayer();
		this.flashPlayer_ = this.getFlashPlayer();
		log("success");	
	}else if(this.isSWFReady){
		this.flashPlayer_.source(options);
	}else{
		this.currentStream = options;
	}
};

ABV.EverestVideoPlayer.prototype.pause = function() {
	this.flashPlayer_ = this.getFlashPlayer();
	if(this.flashPlayer_ != null) this.flashPlayer_.pause();
}

ABV.EverestVideoPlayer.prototype.play = function() {
	this.flashPlayer_ = this.getFlashPlayer();
	if(this.flashPlayer_ != null) this.flashPlayer_.playVideo();
}

ABV.EverestVideoPlayer.prototype.stop = function() {
	this.flashPlayer_ = this.getFlashPlayer();
	if(this.flashPlayer_ != null) this.flashPlayer_.stopVideo();
}

ABV.EverestVideoPlayer.prototype.close = function() {
	this.flashPlayer_ = this.getFlashPlayer();
	if(this.flashPlayer_ != null) this.flashPlayer_.close();
}

ABV.EverestVideoPlayer.prototype.getFlashPlayer = function() {
	var r = null;
	var o = document.getElementById(this.flashId_);
	if (o) {
		var n = o.getElementsByTagName("object")[0];
		
		if(!n || (n && typeof(o.SetVariable) != "undefined")) {
	    	r = o;
		} else if (typeof(n.SetVariable) != "undefined") {
			r = n;
		}
	}
	return r;
};

ABV.EverestVideoPlayer.prototype.createFlashPlayer = function(defaultVideo) {	
	if(typeof swfobject != "undefined") {
		var fv = new Object(); var fp = new Object();
		
		for(var i = 0; i < this.flashVars_.length; ++i) 
			fv[this.flashVars_[i].name] = this.flashVars_[i].value;
		
		if(typeof defaultVideo != "undefined")
			fv["defaultVideo"] = escape(defaultVideo);
		
		if(this.width_ >= 0) fv["width"] = this.width_;
		if(this.height_ >= 0) fv["height"] = this.height_;
		
		for(var i = 0; i < this.flashParams_.length; ++i)
			fp[this.flashParams_[i].name] = this.flashParams_[i].value;
		
		try {
			swfobject.embedSWF(this.playerUrl_, this.containerId_, this.width_, this.height_, this.version_, this.expressInstallUrl_, 
				/* FlashVars */ fv, /* Parameters */ fp, 
				{id:this.flashId_, name:this.flashId_});
			log("player created");
			return true;
		}
		catch(e) {
			log("error " + e);
			return false;
		}
	}
	else if(typeof SWFObject != "undefined") {
		var so = new SWFObject(this.playerUrl_, this.flashId_, this.width_, this.height_, this.version_);
		for(var i = 0; i < this.flashParams_.length; ++i)
			so.addParam(this.flashParams_[i].name, this.flashParams_[i].value);
		
		if(typeof defaultVideo != "undefined") 
			so.addVariable("defaultVideo", escape(defaultVideo));
		
		for(var i = 0; i < this.flashVars_.length; ++i)
			so.addVariable(this.flashVars_[i].name, this.flashVars_[i].value);
			
		if(this.width_ >= 0) so.addVariable("width", this.width_);
		if(this.height_ >= 0) so.addVariable("height", this.height_);
		
		try {
			if(so.write(this.containerId_)) {
				log("player created");
				return true;
			}
			else {
				return false;
			}
		
		}
		catch(e) {
			log("error " + e);
			return false;
		} 
	}
};
/* Utilities.js */
var ABV = ABV || {};

/**
 * Utilities
 * 
 * @description
 * - Defines application utility functions
 * 		
 * @requires jQuery
 * @requires ABV.Constants
 *
 * @constructor
 * @author      zake <zak.eddington@popagency.com>
 * @copyright   Copyright (c) 2015 Target Brands, Inc.
 */
ABV.Utils = {

	/**
	*	returns an Ajax GET request using deferred
	*	@param {String}  url           - url of the request
	*	@param {String}  dataType      - type of response expected
	*	@param {Boolean} isCrossDomain - is it a cross domain request
	**/
	getAjaxContent: function(url, dataType, isCrossDomain) {
		return $.ajax({
			type        : 'GET',
			url         : url,
			dataType    : dataType || 'json',
			crossDomain : isCrossDomain || false,
		});
	},


	/**
	*	create pseudo 'resizeEnd' event
	**/
	resizeEndEvent: function() {
		var timer = false;
		$(window).on('resize', function(e) {
			clearTimeout(timer);
			timer = setTimeout(function() {
				$.event.trigger('resizeEnd');
			},200);
		});
	},

	/**
	*	create pseudo 'scrollEnd' event
	**/
	scrollEndEvent: function() {
		var timer = false;
		$(window).on('scroll', function(e) {
			clearTimeout(timer);
			timer = setTimeout(function() {
				//console.log('scrollEnd');
				$.event.trigger('scrollEnd');
			},200);
		});
	}

}

/**
*	Universal loader
**/
ABV.Utils.Loader = function($target, objOptions) {
	this.elTarget = $target;
	this.options = $.extend({
		overlay: '<div class="loader-overlay"></div>',
		spinner: '<div class="loader-spinner"></div>'
	}, objOptions || {});
	this.elOverlay = $(this.options.overlay);
	this.elSpinner = $(this.options.spinner);
};
ABV.Utils.Loader.prototype = {
	addLoader: function() {
		var self = this;
		this.elTarget.append(this.elOverlay, this.elSpinner);
		setTimeout(function(){
			self.elSpinner.click(); //spinner gif gets 'stuck' and needs a click
		}, 10);
	},
	removeLoader: function() {
		this.elOverlay.remove();
		this.elSpinner.remove();
	}
};
/* Analytics.js */
var ABV = ABV || {};
var dataLayer = dataLayer || [];

/**
 * Analytics
 * 
 * @description
 * - Push additional events to GTM dataLayer
 * 		
 * @requires jQuery
 * @requires ABV.Constants
 *
 * @constructor
 * @author      zake <zak.eddington@popagency.com>
 * @copyright   Copyright (c) 2015 Target Brands, Inc.
 */
ABV.Analytics = {

	/* PUBLIC METHODS */

	/**
	 * Initializes analytics
	 */
	init: function() {

		this.state = {
			numLoadMoreClicks : 0
		};

		this.constant = {
			noTitle   : 'no title available',
			noImage   : 'no image available',
			noNetwork : 'no network available',
			noAction  : 'no action available'
		};

		this._addEventListeners();
	},

	/**
	 * Push data for load more buttons
	 * Fired as callback from ABV.LoadMore, ABV.SocialWall, ABV.GalleryWall on button click event
	 * @param  {Event} $event
	 */
	onLoadMoreButton: function( $event ) {	
		this.state.numLoadMoreClicks++;

		dataLayer.push({
			'event'         : 'showMore', 
			'showMoreCount' : this.state.numLoadMoreClicks
		});
	},

	/**
	 * Push data for carousel arrows
	 * Fired as callback from ABV.Carousel on arrow click event
	 * @param  {String} $direction - 'back' or 'next' per carousel arrow classes
	 */
	onCarouselArrows: function( $direction ) {
		var direction;

		if ( $direction === 'next' ) {
			direction = 'right';
		} else {
			direction = 'left';
		}

		dataLayer.push({
			'event'        : 'carouselClick', 
			'carouselItem' : direction
		});
	},

	/**
	 * Push data for PDF report builder
	 * Fired on ABV.ReportBuilder download button click events
	 * @param  {String} strLabel - name of the pdf (e.g. 'crr: cover page | section 3 | section 5')
	 */
	onReportBuilderDownload: function( strLabel ) {
		dataLayer.push({
			'event'    : 'pdfDownload', 
			'pdfTitle' : strLabel
		});
	},

	/**
	 * Push data for tab switchers
	 * /corporate-responsibility/goals-reporting
	 * @param  {String} strTitle - Text value of nav item selected
	 */
	onTabSwitcher: function( strTitle ) {
		var title = strTitle;

		if ( !title ) {
			title = this.constant.noTitle;
		}

		dataLayer.push({
			'event'        : 'carouselClick', 
			'carouselItem' : title
		});
	},

	/**
	 * Push data for accordion triggers
	 * @param  {String} strTitle - Text value of trigger selected
	 */
	onAccordion: function( strTitle ) {
		var title = strTitle;

		if ( !title ) {
			title = this.constant.noTitle;
		}

		dataLayer.push({
			'event'        : 'accordionClick', 
			'accordionItem' : title
		});
	},

	setEnlighten: function() {
		var BootStrapObj = {};
		var curBootStr;
		BootStrapObj.convertString = function (strToConvert, convertFromStr, convertToStr) {
		    var regEx = new RegExp(convertFromStr, "g");
		    var newStr = strToConvert.replace(regEx, convertToStr);
		    return newStr;
		}
		BootStrapObj.pathStr = window.location.pathname
		BootStrapObj.pathArray = BootStrapObj.pathStr.split('/');
		BootStrapObj.pathName = "a bullseye view";
		BootStrapObj.i = 0;
		BootStrapObj.pathLength = BootStrapObj.pathArray.length;
		if (BootStrapObj.pathStr.length > 1) {
		    //all other sections but home
		    for (BootStrapObj.i = 0; BootStrapObj.i < BootStrapObj.pathLength; BootStrapObj.i++) {
		        curBootStr = BootStrapObj.pathArray[BootStrapObj.i];
		        //only if we're not a number
		        if(isNaN(curBootStr)){
		            BootStrapObj.pathName += ": ";
		            if (curBootStr === 'article') {
		                BootStrapObj.pathName += 'news and features';
		            } else {
		                BootStrapObj.pathName += BootStrapObj.pathArray[BootStrapObj.i];
		            }
		        }
		    }
		} else {
		    // generic homepage string
		    BootStrapObj.pathName += ": home";
		}

		if (window.Bootstrapper) {
            window.Bootstrapper._trackAnalytics('pageView',
                {
                    "dynamicDataLayer": {
                        "analytics": {
                            "guest": {}, "appState": { "pageName": BootStrapObj.pathName, "pageTemplateType": "a bullseye view" }, "experience": { "channel": "a bullseye view" }
                        }
                    }
                }
            );
        }
	}, 


	/* PRIVATE METHODS */

	_addEventListeners: function() {

		// Back to top links
		$('.btn-back-top').on('click', $.proxy(this._onBackToTop, this) );

		// Join our team form submit
		$('.gtm-job-search input[type="submit"]').on('click', $.proxy(this._onJobSearchForm, this) );
		
		// Category filters
		$('#category-filter a').on('click', $.proxy(this._onCategoryFilter, this) );

		// Social icon actions
		$('body').on('click', '[class*="gtm-social-"]', $.proxy(this._onSocialActions, this) );

		// Region clicks
		$('#main-content > form').on('click', 
			'> .hero a, > .primary a, > .secondary a, > .tertiary a', 
			$.proxy(this._onRegion, this) 
		);
		$('.header-quick-reads a').on('click', $.proxy(this._onRegion, this) );
	},

	/**
	 * Push data for back to top links
	 * /corporate-responsibility/goals-reporting
	 * @param  {Event} $event
	 */
	_onBackToTop: function( $event ) {
		var title = $('h1').text();

		if ( !title ) {
			title = this.constant.noTitle;
		}

		dataLayer.push({
			'event'    : 'backToTopClick', 
			'pageItem' : title
		});
	},

	/**
	 * Push data for /careers join our team form submit
	 * @param  {Event} $event
	 */
	_onJobSearchForm: function( $event ) {
		var $curTarget = $( $event.currentTarget ),
			term       = $curTarget.parents('.gtm-job-search').find('input[type="search"]').val();

		if ( !term ) {
			term = 'no search term entered';
		}

		dataLayer.push({
			'event'         : 'jobsearch-submit',
			'jobSearchTerm' : term
		});
	},

	/**
	 * Push data for category filters on /news-features
	 * @param  {Event} $event
	 */
	_onCategoryFilter: function( $event ) {
		var title = $( $event.currentTarget ).text();

		if ( !title ) {
			title = this.constant.noTitle;
		}

		dataLayer.push({
			'event'        : 'carouselClick', 
			'carouselItem' : title
		});
	},

	/**
	 * Push data for tab switcher
	 * /corporate-responsibility/goals-reporting
	 * @param  {Event} $event
	 */
	_onTabSwitcher: function( $event ) {
		var title = $( $event.currentTarget ).text();

		if ( !title ) {
			title = this.constant.noTitle;
		}

		dataLayer.push({
			'event'        : 'carouselClick', 
			'carouselItem' : title
		});
	},

	/**
	 * Push data for region clicks
	 * @param  {Event} $event
	 */
	_onRegion: function( $event ) {
		var $curTarget = $( $event.currentTarget ),
			url        = window.location.href;
			
		if ( $curTarget.parents('.hero').length ) {
			region = 'Hero';
		}
		else if ( $curTarget.parents('.primary').length ) {
			region = 'Primary';
		}
		else if ( $curTarget.parents('.secondary').length ) {
			region = 'Secondary';
		}
		else if ( $curTarget.parents('.tertiary').length ) {
			region = 'Tertiary';
		}
		else if ( $curTarget.parents('.header-quick-reads').length ) {
			region = 'header promo boxes';
		}
		else {
			region = 'no region available';
		}

		dataLayer.push({
			'event'      : 'regionClick', 
			'region'     : region, 
			'breakpoint' : ABV.Constants.breakpoint,
			'elementHref': url
		});
	},

	/**
	 * Push data for Social Wall action icons (like, share, etc)
	 * @param  {Event} $event
	 */
	_onSocialActions: function( $event ) {
		var $curTarget = $( $event.currentTarget ),
			title      = $curTarget.parents('.gtm-parent').find('.gtm-title').text(),
			network,
			action;

		if ( !title ) {
			title = this.constant.noTitle;
		}

		if ( $curTarget.hasClass('gtm-social-facebook-comment') ) {
			network = 'Facebook';
			action  = 'comment';
		}
		else if ( $curTarget.hasClass('gtm-social-facebook-share') ) {
			network = 'Facebook';
			action  = 'share';
		}
		else if ( $curTarget.hasClass('gtm-social-twitter-reply') ) {
			network = 'Twitter';
			action  = 'reply';
		}
		else if ( $curTarget.hasClass('gtm-social-twitter-tweet') ) {
			network = 'Twitter';
			action  = 'tweet';
		}
		else if ( $curTarget.hasClass('gtm-social-twitter-retweet') ) {
			network = 'Twitter';
			action  = 'retweet';
		}
		else if ( $curTarget.hasClass('gtm-social-twitter-favorite') ) {
			network = 'Twitter';
			action  = 'favorite';
		}
		else if ( $curTarget.hasClass('gtm-social-instagram-like') ) {
			network = 'Instagram';
			action  = 'like';
		}
		else if ( $curTarget.hasClass('gtm-social-pinterest-pin') ) {
			network = 'Pinterest';
			action  = 'pin';
		}
		else if ( $curTarget.hasClass('gtm-social-linkedin-share') ) {
			network = 'LinkedIn';
			action  = 'share';
		}
		else {
			network = this.constant.noNetwork;
			action  = this.constant.noAction;
		}

		dataLayer.push({
			'event'         : 'socialInt', 
			'socialNetwork' : network, 
			'socialAction'  : action, 
			'socialTarget'  : title
		});
	}
};
/* PinElement.js */
var ABV = ABV || {};

/**
 * Pin Element
 * 
 * @description
 * - Pin an element below the nav on scroll
 * 		
 * @requires jQuery
 * @requires jQuery imagesLoaded plugin
 * @requires TweenMax
 * @requires ABV.Constants
 *
 * @constructor
 * @author      zake <zak.eddington@popagency.com>
 * @copyright   Copyright (c) 2015 Target Brands, Inc.
 */
ABV.PinElement = function( $target, objOptions ) {

	this.options = $.extend({
		selectorImgContainer : '.hero',          // element containing images that need to be preloaded
		classPin             : 'pin-title',      // class to apply to body when element is pinned
		pinTopPos            : 50,               // distance from top the element needs to be when pinned
		animDistance         : -50,              // distance to animate from when transitioning into pinned state
		animSpeed            : 0.5,              // (seconds) time taken to transition into pinned state
		animEase             : 'Expo.easeInOut'  // TweenMax easing function to use on transitions

	}, objOptions || {});

	/**
	 * Constants for animations, positions, etc.
	 */
	this.constant = {
		triggerPos   : 0,
		topPos       : 0
	};

	/**
	 * DOM elements 
	 */
	this.ui = {
		window       : $(window),
		body         : $('body'),
		pinElement   : $target,
		imgContainer : null
	};

	this.init();
};

ABV.PinElement.prototype = {

	/* PUBLIC METHODS */

	/**
	 * Initializes the widget
	 */
	init: function() {
		var self = this;

		this.ui.imgContainer = $( this.options.selectorImgContainer );

		// Do nothing if the element doesn't exist
		if ( this.ui.pinElement.length ) {

			// If we have an image container, preload images to get proper offset position
			if ( this.ui.imgContainer.length ) {
				this.ui.imgContainer.imagesLoaded( function() {
					self._addEventListeners();
					self._getPinTrigger();
				});
			}
			// Otherwise, just roll with it
			else {
				this._addEventListeners();
				this._getPinTrigger();
			}
		}
	},


	/* PRIVATE METHODS */

	/**
	 * Set the top position that will trigger the pinned state
	 * (element top offset minus pinned nav height)
	 */
	_getPinTrigger: function() {
		this.constant.topPos     = this.ui.pinElement.offset().top;
		this.constant.triggerPos = this.constant.topPos - this.options.pinTopPos;
		this._pinElement();
	},

	/**
	 * Pin the element when it scrolls past the trigger point but only on desktop
	 */
	_pinElement: function() {
		var scrollTop  = this.ui.window.scrollTop();

		// If we're scrolled past the trigger position
		if ( scrollTop >= this.constant.triggerPos && ABV.Constants.breakpoint === 'desktop' ) {

			// pin the element if it's not already pinned.
			if ( !this.ui.body.hasClass( this.options.classPin ) ) {
				this.ui.body.addClass( this.options.classPin );
				this._animatePin();
			}
		}
		// Otherwise, unpin it.
		else {
			this.ui.body.removeClass( this.options.classPin );
			this.ui.pinElement.removeAttr('style');
		}
	},

	/**
	 * Animate the position of top level nav items on desktop
	 */
	_animatePin: function() {
		TweenMax.fromTo( this.ui.pinElement, this.options.animSpeed, {
			top: this.options.animDistance
		}, {
			top: this.options.pinTopPos,
			position: 'fixed'
		});
	},

	/**
	 * Event Listeners
	 */
	_addEventListeners: function() {
		this.ui.window.on('scrollEnd',  $.proxy(this._pinElement, this) );
		this.ui.body.on(  'breakpoint', $.proxy(this._getPinTrigger, this) );
	}
};
/* Carousel.js */
var ABV = ABV || {};

/**
 * Carousel
 * 
 * @description
 * - Takes an ol/ul of content and assembles it into a horizontal carousel.
 * - Optional - infinite looping, autoplay, grouped pagination and fade/slide animations
 * 		
 * @requires jQuery
 * @requires jQuery touchSwipe plugin
 * @requires jQuery imagesLoaded plugin
 * @requires TweenMax
 * @requires ABV.Constants
 * @requires ABV.Analytics
 *
 * @example
 * new ABV.Carousel($('#myCarousel'), {options})
 *
 * @constructor
 * @author      zake <zak.eddington@popagency.com>
 * @copyright   Copyright (c) 2015 Target Brands, Inc.
 *
 * @param {Object} $container - jQuery element for widget
 * @param {Object} objOptions - Optional object of properties to mixin to the instance
 * @param {Object} objData    - Optional JSON data to use for generating markup 
 */
ABV.Carousel = function( $element, objOptions, objData ) {

	/**
	 * Default configuration for component
	 */
	this.options = $.extend({
		numVisiblePanels       : 1,                  // how many panels you want visible at a time on desktop
		numVisiblePanelsTablet : 1,                  // how many panels you want visible at a time on tablet
		numVisiblePanelsMobile : 1,                  // how many panels you want visible at a time on mobile
		wrapperClass           : 'carousel-wrapper', // css class for div that will wrap the entire carousel
		strPanel               : '> li',             // panel selector
		showSocialButtons      : false,              // boolean for including AddThis share buttons
		isSlider               : true,               // horizontally slide content
		isInfinite             : false,              // boolean for infinite behavior
		strTitleSelector       : null,               // button/tab text
		strButtonElement       : 'button',           // override default button element
		strDisabledClass       : 'disabled',         // class set for disabled state
		strActiveClass         : 'active',           // class set for active state
		startIndex             : 0,                  // index for first content loaded
		maxWidth               : '100%',             // (string including units) max width of carousel wrapper
		maxHeight              : null,               // how tall each panel should be:
													 // -> null       = adjust height on panel change
													 // -> 'landscape'= set height to tallest landscape panel
													 // -> 'tallest'  = set height to tallest panel
													 // -> 'shortest' = set height to shortest panel
													 // -> '500px'    = set height to value including units ('500px', etc)
													 // -> number     = set height to aspect ratio of width (.67, .5625, etc)
		maxHeightMobile        : null,               // override for maxHeight on mobile
		cycleSpeed             : 5000,               // (milliseconds) speed through auto cycle
		transitionSpeed        : 0.5,                // (seconds) time taken to animate between panels
		transitionEase         : 'Sine.easeInOut',   // TweenMax easing function to use on transitions
		autoCycle              : false,              // boolean for auto cycling
		autoCycleStartText     : 'start auto cycle', // button text for starting auto cycling
		autoCycleStopText      : 'stop auto cycle',  // button text for stopping auto cycling
		showPagination         : true,               // boolean for pagination buttons
		maxPagination          : 20,                 // max number of pagination buttons (if over, buttons replaced with x of xx label)
		showArrows             : true,               // boolean for arrow buttons
		showNext               : false,              // boolean for displaying next panel title
		showNextText           : 'Next: ',           // next text indicator
		showItemCount          : false,              // boolean for item count display
		numItemCountSeparator  : ' of ',             // set separator for item count
		onPanelLoad            : null,               // happens when a new panel is loaded
		onPaginationClick      : null,               // happens when a new panel is loaded
		onInitialize           : null,               // happens on instantiation
		htmlTemplateSelector   : null,               // optional Handlebars template id
		htmlTargetSelector     : null                // optional target element to append markup
	}, objOptions || {});

	/**
	 * Constants
	 */
	this.constant = {
		numTotalPanels         : null,
		numPanelGroups         : null,
		isPanelGroups          : false,
		numPanelWidth          : null,
		arrFocusables          : ['a', 'button', 'input', 'select', 'textarea', 'area', 'iframe', '[tabindex]']
	};

	/**
	 * Widget states
	 *
	 * @type {Object}
	 */
	this.state = {
		overMaxPagination      : false,
		numVisiblePanels       : this.options.numVisiblePanels,
		cycling                : false,
		animating              : false,
		curIndex               : this.options.startIndex,
		maxHeight              : this.options.maxHeight
	};

	/**
	 * UI elements
	 *
	 * @type {Object}
	 */
	this.ui = {
		body                   : $('body'),
		wrapper                : null,
		carousel               : $element,
		panels                 : null,
		currentPanels          : null,
		targetPanels           : null,
		controlsWrapper        : null,
		paginationWrapper      : null,
		paginationMaxLabel     : null,
		arrowsWrapper          : null,
		arrowBack              : null,
		arrowNext              : null,
		countWrapper           : null,
		showNextWrapper        : null,
		cycleButton            : null
	};
	this.ui.panels             = this.ui.carousel.find( this.options.strPanel );
	
	this.namespace             = null;  // dynamically created namespace for this instance

	this.data                  = objData;

	this.progressInterval      = null;

	this._initialize();
};



ABV.Carousel.prototype = {
	/**
	 * Initializes the widget
	 */
	_initialize: function() {
		var self = this;

		// set namespace for this instance of the modal window
		this.namespace = Date.now();

		this.ui.carousel.wrap( $('<div class="' + this.options.wrapperClass + '" />') );
		this.ui.wrapper = this.ui.carousel.parent();

		this.constant.numTotalPanels = this.ui.panels.length;

		if (this.options.autoCycle && this.constant.numPanelGroups > 1 ) {
			this.state.cycling = true;
		}

		this._setVisiblePanels();

		// set and cache first panel(s)
		this._setCurPanels( this.options.startIndex );

		// fire panel load callback
		if (typeof this.options.onPanelLoad === 'function') {
			this.options.onPanelLoad(this);
		}

		// build out navigation
		this._buildUI();

		this._setPanel(this.options.startIndex, null, false);
		
		// cycle through panels
		if (this.options.autoCycle && this.constant.numPanelGroups > 1) {
			//this.state.cycling = true;

			setTimeout(function () {
				if (self.state.cycling) {
					self._cycleStart();
				}
			}, this.options.cycleSpeed);
		}

		if ( this.options.showSocialButtons ) {
			if ( window.addthis ) {
				setTimeout(function() {
					addthis.toolbox( '.' + self.options.wrapperClass );
				}, 500);
			}
		}
	},

	/**
	 * Reset carousel on breakpoint change
	 */
	_onBreakpoint: function() {
		this._unBindEvents();
		this._setVisiblePanels();
		this._buildUI();
		this._setPanel(this.options.startIndex, null, false);
	},

	/**
	 * Define the ui.currentPanels object
	 * @param {Number} $index - index of the first item that is currently visible
	 */
	_setCurPanels: function( $index ) {
		var index = $index;

		if (this.constant.isPanelGroups) {
			index *= this.state.numVisiblePanels;
			this.ui.currentPanels = [];
			for ( var i = 0, len = this.state.numVisiblePanels - 1; i <= len; i++) {
				if ( $(this.ui.panels).eq(i + index).length ) {
					this.ui.currentPanels.push( $(this.ui.panels).eq(i + index) );
				}
			}
		} else {
			this.ui.currentPanels = $(this.ui.panels).eq( index );
		}
	},

	/**
	 * Define the ui.targetPanels object
	 * @param {Number} $index - index of the first item that we're transitioning into view
	 */
	_setTargetPanels: function( $index ) {
		var index = $index;

		if (this.constant.isPanelGroups) {
			index *= this.state.numVisiblePanels;
			this.ui.targetPanels = [];
			for ( var i = 0, len = this.state.numVisiblePanels - 1; i <= len; i++) {
				if( $(this.ui.panels).eq(i + index).length ) {
					this.ui.targetPanels.push( $(this.ui.panels).eq(i + index) );
				}
			}
		} else {
			this.ui.targetPanels = $(this.ui.panels).eq( index );
		}
	},


	/**
	 * Reset carousel to the current breakpoint
	 */
	_setVisiblePanels: function() {

		if ( ABV.Constants.breakpoint === 'desktop' ) {
			this.state.numVisiblePanels = this.options.numVisiblePanels;
			this.state.maxHeight        = this.options.maxHeight;
		}

		if ( ABV.Constants.breakpoint === 'tablet' ) {
			this.state.numVisiblePanels = this.options.numVisiblePanelsTablet;
			this.state.maxHeight        = this.options.maxHeight;
		}

		if ( ABV.Constants.breakpoint === 'mobile' ) {
			this.state.numVisiblePanels = this.options.numVisiblePanelsMobile;
			this.state.maxHeight        = this.options.maxHeightMobile;
		}

		if ( this.state.numVisiblePanels > 1 ) {
			this.constant.isPanelGroups = true;
		}
		this.constant.numPanelGroups = Math.ceil( this.constant.numTotalPanels / this.state.numVisiblePanels );

		this._setElementStyles();
	},

	/**
	 * Set CSS styles for carousel elements
	 */
	_setElementStyles: function() {
		var self   = this,
			styles = {
				carouselWidth : null,
				height        : 0,
				opacity       : null,
				overflow      : 'hidden',
				position      : null,
				visiblePanels : this.constant.numTotalPanels / this.state.numVisiblePanels
			};

		// Remove any styles previously applied
		this.ui.wrapper.removeAttr('style');
		this.ui.carousel.removeAttr('style');
		this.ui.panels.removeAttr('style');

		// Set styles based on slide or fade
		if ( this.options.isSlider ) {
			styles.opacity              = '';
			styles.position             = 'relative';
			styles.carouselWidth        = styles.visiblePanels * 100;
			this.constant.numPanelWidth = (styles.carouselWidth / this.constant.numTotalPanels) / styles.visiblePanels;
		} else {
			styles.opacity              = 0;
			styles.position             = 'absolute';
			styles.carouselWidth        = styles.visiblePanels * 100;
			this.constant.numPanelWidth = (styles.carouselWidth / this.constant.numTotalPanels) / styles.visiblePanels;
		}

		// Check which height criteria to use based on maxHeight option
		// Set height to current panel
		if ( this.state.maxHeight === null ) {

			var $activePanel = this.ui.panels.eq(this.options.startIndex);

			// Preload images
			var imgLoad = imagesLoaded( $activePanel, function() {
					var curHeight = $activePanel.outerHeight(true);
					styles.height = curHeight + 'px';
					this._applyStyles(styles);
				}.bind(this) );	
		}

		// Set height to tallest or shortest panel
		else if ( this.state.maxHeight === 'landscape' || this.state.maxHeight === 'tallest' || this.state.maxHeight === 'shortest' ) {
			var isTallest   = true,
				isLandscape = false;

			if ( this.state.maxHeight === 'landscape' ) {
				isLandscape = true;
			}
			if ( this.state.maxHeight === 'shortest' ) {
				isTallest     = false;
				styles.height = 99999;
			}

			// Preload images before getting height 
			var imgLoad = imagesLoaded( this.ui.panels, function() {
				// Placeholder arrays for landscape option
				var landscape = [],
					others    = [];

				// Loop through each slide
				$.each( this.ui.panels, function() {
					var curHeight = $(this).outerHeight(true),
						curWidth  = $(this).outerWidth(true);

					// Push items into arrays for landscape
					if ( isLandscape ) {
						if ( curWidth > curHeight ) {
							landscape.push(curHeight);
						} else {
							others.push(curHeight);
						}
					}
					// Or set tallest height 
					else if ( isTallest ) {
						if ( curHeight > styles.height ) {
							styles.height = curHeight;
						}
					}
					// Or set shortest height
					else {
						if ( curHeight < styles.height ) {
							styles.height = curHeight;
						}
					}
				});

				// Get tallest landscape height or tallest other if none are landscape
				if ( isLandscape ) {
					var landscapeMax = Math.max.apply( Math, landscape ),
						othersMax    = Math.max.apply( Math, others );
					if ( landscapeMax > 0 ) {
						styles.height = landscapeMax;
					} else {
						styles.height = othersMax;
					}
				}

				// Apply the height
				styles.height += 'px';
				this._applyStyles(styles);
			}.bind(this) );
		}

		// Set height to options value including units
		else if ( typeof this.state.maxHeight === 'string' ) {
			styles.height = this.state.maxHeight;
			this._applyStyles(styles);
		}

		// Set height to options value for the aspect ratio
		else {
			styles.height = this.ui.wrapper.outerWidth() * this.state.maxHeight + 'px';
			this._applyStyles(styles);
		}
	},

	/**
	 * Apply CSS styles above to carousel elements
	 * @param  {Object} objStyles - css values to apply
	 */
	_applyStyles: function( objStyles ) {
		var styles = objStyles,
			wrapperCss = {
				'overflow': styles.overflow,
				'position': 'relative',
				'width': this.options.maxWidth
			},
			containerListCss = {
				'overflow': styles.overflow,
				'position': 'relative',
				'width': styles.carouselWidth + '%',
				'height': styles.height
			},
			panelCss = {
				'float': 'left',
				'opacity': styles.opacity,
				'position': styles.position,
				'width': this.constant.numPanelWidth + '%'
			};

		this.ui.wrapper.css( wrapperCss );
		this.ui.carousel.css( containerListCss );
		this.ui.panels.css( panelCss );

		// fire onInitialize callback
		if (typeof this.options.onInitialize === 'function') {
			this.options.onInitialize(this);
		}
	},

	/**
	 * Build out UI to interact with the widget
	 */
	_buildUI: function() {
		var strNextText,
			strCycleText,
			elNextPanel;

		// define or empty controls container
		if ( this.ui.controlsWrapper ) {
			this.ui.controlsWrapper.empty();
		} else {
			this.ui.controlsWrapper = $('<div class="panel-controls"></div>');
		}

		// add cycle control
		if (this.ui.cycleButton) {
			this.ui.cycleButton.remove();
		}
		if (this.options.autoCycle) {
			if (this.state.cycling) {
				strCycleText = this.options.autoCycleStopText;
			} else {
				strCycleText = this.options.autoCycleStartText;
			}
			this.ui.cycleButton = $('<' + this.options.strButtonElement + ' class="nav-cycle" />').text( strCycleText );
			this.ui.wrapper.prepend(this.ui.cycleButton);
		}

		if ( this.constant.numPanelGroups > 1 ) {
			// add next/back buttons
			if (this.options.showArrows) {
				this._addArrows();
			}

			// add pagination/tabs
			if (this.options.showPagination) {
				this._addPagination();
			}
		}

		// display next panel title
		if (this.options.showNext) {
			this.ui.showNextWrapper = $('<p class="panel-next"></p>');

			elNextPanel = this.ui.currentPanels[ this.ui.currentPanels.length - 1 ].get(0) !== this.ui.panels.last().get(0) ? this.ui.panels.eq(this.ui.currentPanels[0].index() + 1) : this.ui.panels.eq(0);
			strNextText = this.options.showNextText + elNextPanel.find(this.options.strTitleSelector).text();

			this.ui.showNextWrapper.text(strNextText);
			this.ui.controlsWrapper.append(this.ui.showNextWrapper);
		}

		// display item count
		if (this.options.showItemCount) {
			this.ui.countWrapper = $('<p class="panel-count"></p>');

			this.ui.countWrapper.text((this.ui.currentPanels[0].index() + 1) + this.options.numItemCountSeparator + this.constant.numTotalPanels);
			this.ui.controlsWrapper.append(this.ui.countWrapper);
		}

		this.ui.wrapper.append(this.ui.controlsWrapper);

		this._bindEvents();
	},

	/**
	 * Update UI to reflect the current state of the widget
	 */
	_updateUI: function( $index ) {
		var numCurrentIndex = $index,
			numViewablePanels = this.constant.numTotalPanels - (this.ui.wrapper.width() / this.ui.panels.outerWidth()),
			elNextPanel,
			elPaginationButtons,
			elCurrentPagination,
			strActiveText,
			strNextText;


		if ( this.constant.numPanelGroups > 1 ) {
			// update current panel indicator
			if (this.options.showPagination) {

				if ( this.state.overMaxPagination ) {
					this.ui.paginationMaxLabel.text( $index + 1 );
				} else {
					elPaginationButtons = this.ui.paginationWrapper.children('li');
					elCurrentPagination = elPaginationButtons.eq( $index );

					elPaginationButtons.removeClass(this.options.strActiveClass);
					elCurrentPagination.addClass(this.options.strActiveClass);

					elPaginationButtons.children(this.options.strButtonElement).find('span').remove();

					elCurrentPagination.children(this.options.strButtonElement).append($('<span />').text(', currently active'));
				}
			}

			// enable/disable arrows
			if (this.options.showArrows && !this.options.isInfinite) {
				this.ui.arrowsWrapper.find('span').remove();

				this.ui.arrowsWrapper.find('li').removeClass(this.options.strDisabledClass);

				if (numCurrentIndex === 0) {
					this.ui.arrowsWrapper.find('.btn-back').addClass(this.options.strDisabledClass).find(this.options.strButtonElement).append($('<span />').text(', currently disabled'));
				} else if (numCurrentIndex === this.constant.numPanelGroups - 1 || numCurrentIndex === numViewablePanels) {
					this.ui.arrowsWrapper.find('.btn-next').addClass(this.options.strDisabledClass).find(this.options.strButtonElement).append($('<span />').text(', currently disabled'));
				}
			}
		}

		// keep track of current panel
		if (this.options.showItemCount) {
			this.ui.countWrapper.text((numCurrentIndex + 1) + this.options.numItemCountSeparator + (this.constant.numTotalPanels));
		}

		// show upcoming panel
		if (this.options.showNext) {
			elNextPanel = this.ui.currentPanels.get(0) !== this.ui.panels.last().get(0) ? this.ui.panels.eq(numCurrentIndex + 1) : this.ui.panels.eq(0);
			strNextText = this.options.showNextText + elNextPanel.find(this.options.strTitleSelector).text();

			this.ui.showNextWrapper.text(strNextText);
		}
	},

	/**
	 * Add back / next button naviation
	 */
	_addArrows: function() {
		var strButtonElement = this.options.strButtonElement,
			elBtnBack,
			elBtnNext;

		// define back/next button container
		this.ui.arrowsWrapper = $('<ul class="nav-panels-arrows" />');

		// back/next buttons
		elBtnBack = $('<li class="btn-back" title="Previous Panel"><' + strButtonElement + '>Previous Panel</' + strButtonElement + '></li>');
		elBtnNext = $('<li class="btn-next" title="Next Panel"><' + strButtonElement + '>Next Panel</' + strButtonElement + '></li>');

		this.ui.arrowsWrapper.append(elBtnNext, elBtnBack);
		this.ui.controlsWrapper.append(this.ui.arrowsWrapper);

		// disable button if appropriate
		if (!this.options.isInfinite) {
			if (this.options.startIndex === 0) {
				this.ui.arrowsWrapper.find('.btn-back').addClass(this.options.strDisabledClass).find(strButtonElement).append($('<span />').text(', currently disabled'));
			} else if (this.options.startIndex === this.constant.numPanelGroups - 1) {
				this.ui.arrowsWrapper.find('.btn-next').addClass(this.options.strDisabledClass).find(strButtonElement).append($('<span />').text(', currently disabled'));
			}
		}

		this.ui.arrowBack = this.ui.arrowsWrapper.find('.btn-back');
		this.ui.arrowNext = this.ui.arrowsWrapper.find('.btn-next');
	},

	/**
	 * Add pagination button naviation
	 */
	_addPagination: function() {
		var strButtonElement = this.options.strButtonElement,
			strButtonText,
			strActiveText,
			elNavItem,
			i;

		// define pagination button container
		this.ui.paginationWrapper = $('<ul class="nav-panels-pagination" />');

		// If we are over the pagination limit, only show text progress indicator
		if ( this.constant.numPanelGroups > this.options.maxPagination ) {
			this.state.overMaxPagination = true;

			elNavItem = $('<li>' + '<span>' + (this.options.startIndex + 1) + '</span>' + this.options.numItemCountSeparator + this.constant.numPanelGroups + '</li>');
			this.ui.paginationWrapper.append(elNavItem);

			// define current panel element
			this.ui.paginationMaxLabel = this.ui.paginationWrapper.find('span');
		}
		// Otherwise, create pagination buttons
		else {
			// add button for each item in the carousel
			for (i = 0; i < this.constant.numPanelGroups; i += 1) {
				strButtonText = this.options.strTitleSelector ? this.ui.panels.eq(i).find(this.options.strTitleSelector).text() + ', ' : '';
				strButtonText += 'Panel ' + (i + 1) + this.options.numItemCountSeparator + this.constant.numPanelGroups;

				elNavItem = $('<li><' + strButtonElement + '>' + strButtonText + '</' + strButtonElement + '></li>');

				if (i === this.options.startIndex) {
					elNavItem.addClass(this.options.strActiveClass);

					elNavItem.children( strButtonElement ).append($('<span />').text(', currently active'));
				}

				this.ui.paginationWrapper.append(elNavItem);
			}
		}

		this.ui.controlsWrapper.append(this.ui.paginationWrapper);
	},

	/**
	 * Bind events for all interactions
	 */
	_bindEvents: function() {
		var self = this,
			elNavPagination = this.ui.paginationWrapper ? this.ui.paginationWrapper.children('li') : null,
				elNavArrows = this.ui.arrowsWrapper ? this.ui.arrowsWrapper.children('li') : null;

		// bind click to cycle control
		if (this.options.autoCycle) {
			this.ui.wrapper.find('.nav-cycle').on('click', this._onCycle.bind(this));
		}

		// bind click to all pagination/tab buttons
		if (elNavPagination) {
			elNavPagination.on('click', this._onPagination.bind(this));
		}

		// bind click to arrow buttons
		if (elNavArrows) {
			elNavArrows.on('click', this._onArrows.bind(this));
			elNavArrows.on('mouseover', this._onArrowsOver.bind(this));
			elNavArrows.on('mouseout', this._onArrowsOut.bind(this));
		}

		// make panel items focusable once interacted with
		this.ui.panels.on('focus', '*', this._onPanelItemFocus.bind(this));
		this.ui.panels.on('hover', this.constant.arrFocusables.join(','), this._onPanelItemFocus.bind(this));

		this.ui.body.on('breakpoint.' + this.namespace, $.proxy(this._onBreakpoint, this));
		//window.onresize = $.proxy(this._onBreakpoint, this);


		//uses jquery.touchSwipe.min.js plugin
		if ( ABV.Constants.isTouchDevice ) {
			this.ui.carousel.children().swipe({
				swipeLeft:function(event, distance, duration, fingerCount) {
					if (!self.state.animating) {
						self._onArrows( null, self.ui.arrowNext );
					}
				},
				swipeRight:function(event, distance, duration, fingerCount) {
					if (!self.state.animating) {
						self._onArrows( null, self.ui.arrowBack );
					}
				},
				click:function (event, target) {
					$(target).click();
				},
				fingers:$.fn.swipe.fingers.ALL,
				excludedElements: ''
			});
		}
	},

	/**
	 * Unbind events for all interactions
	 */
	_unBindEvents: function() {
		var self = this,
			elNavPagination = this.ui.paginationWrapper ? this.ui.paginationWrapper.children('li') : null,
				elNavArrows = this.ui.arrowsWrapper ? this.ui.arrowsWrapper.children('li') : null;

		// unbind click to cycle control
		if (this.options.autoCycle) {
			this.ui.wrapper.find('.nav-cycle').off();
		}

		// unbind click to all pagination/tab buttons
		if (elNavPagination) {
			elNavPagination.off();
		}

		// unbind click to arrow buttons
		if (elNavArrows) {
			elNavArrows.off();
		}

		// make panel items focusable once interacted with
		this.ui.panels.off();

		this.ui.body.off('.' + this.namespace);
	},

	/**
	 * On auto cycle button toggle
	 *
	 * @param {Object} $event
	 */
	_onCycle: function( $event ) {
		$event.preventDefault();

		if (this.state.cycling) {
			this._cycleStop();
		} else {
			this._cycleStart();
		}
	},

	/**
	 * On pagination button trigger
	 *
	 * @param {Object} $event
	 */
	_onPagination: function( $event ) {
		$event.preventDefault();
		var elTarget = $($event.currentTarget);

		if (!this.state.animating && !elTarget.hasClass(this.options.strActiveClass)) {
			this._setPanel(elTarget.index(), null);

			// fire pagination callback
			if (typeof this.options.onPaginationClick === 'function') {
				this.options.onPaginationClick(this);
			}

			this._cycleStop();
		}
	},

	/**
	 * On back / next button trigger
	 *
	 * @param {Object} $event  - when coming from clicking on arrows 
	 * @param {Object} $target - jQuery object of next/prev button (used on swipe event)
	 */
	_onArrows: function( $event, $target ) {
		var elTarget;
		
		if ( $event ) {
			$event.preventDefault();
			elTarget = $($event.currentTarget);
		} else {
			elTarget = $target;
		}

		var elTip = elTarget.find('.tip'),
			direction,
			index;

		if (!this.state.animating && !elTarget.hasClass(this.options.strDisabledClass)) {
			index = this.state.curIndex;
			direction = elTarget.hasClass('btn-back') ? 'back' : 'next';

			// Fire analytics callback
			ABV.Analytics.onCarouselArrows( direction );
			
			if (direction === 'back') {
				if (index > 0) {
					index -= 1;
				} else if (this.options.isInfinite) {
					index = this.constant.numPanelGroups - 1;
				}
			} else if (direction === 'next') {
				if (index < this.constant.numPanelGroups - 1) {
					index += 1;
				} else if (this.options.isInfinite) {
					index = 0;
				}
			}

			if (this.constant.numPanelGroups > index) {
				if (elTip.length) {
					elTip.remove();
				}

				this._setPanel(index, direction);

				// fire pagination callback
				if (typeof this.options.onPaginationClick === 'function') {
					this.options.onPaginationClick(this);
				}

				this._cycleStop();
			}
		}

	},

	/**
	 * On back / next button mouseover
	 *
	 * @param {Object} $event
	 */
	_onArrowsOver: function( $event ) {
		var elTarget = $($event.currentTarget),
			direction,
			index;

		if (!this.state.animating && !elTarget.hasClass(this.options.strActiveClass) && this.options.strTitleSelector) {
			index = this.ui.currentPanels.prevAll('li').length;
			direction = elTarget.hasClass('btn-back') ? 'back' : 'next';

			if (direction === 'back' && index > 0) {
				index = index - 1;
			} else if (direction === 'next' && index < this.ui.panels.length - 1) {
				index = index + 1;
			}

			this._addTip(elTarget, direction, this.ui.panels.eq(index).find(this.options.strTitleSelector).text());
		}
	},

	/**
	 * On back / next button mouseout
	 *
	 * @param {Object} $event
	 */
	_onArrowsOut: function( $event ) {
		var elTarget = $($event.currentTarget);

		this._removeTip(elTarget);
	},

	/**
	 * On panel item focus
	 *
	 * @param {Object} $event
	 */
	_onPanelItemFocus: function( $event ) {
		this._cycleStop();
	},

	/**
	 * Auto cycle through panels
	 */
	_autoCycle: function() {
		var self = this;

		(function cycleNode() {
			var index = self.state.curIndex,
				direction = null;

			if (index < self.constant.numPanelGroups - 1) {
				index += 1;
			} else {
				index = 0;

				direction = 'next';
			}

			self._setPanel(index, direction, false);

			self.progressInterval = setTimeout(cycleNode, self.options.cycleSpeed);

			self.state.cycling = true;
		})();
	},

	/**
	 * Start auto cycle
	 */
	_cycleStart: function() {
		if (this.ui.cycleButton) {
			this.ui.cycleButton.text( this.options.autoCycleStopText );
		}

		this._autoCycle();
	},

	/**
	 * Stop auto cycle
	 */
	_cycleStop: function() {
		var self = this;

		if (this.ui.cycleButton) {
			this.ui.cycleButton.text( this.options.autoCycleStartText );
		}

		clearTimeout(self.progressInterval);

		this.state.cycling = false;
	},

	/**
	 * Add new tool tip for button element
	 *
	 * @param {Object} $elTarget element to embed tooltip in
	 * @param {String} $strDirection indicates direction on button click
	 * @param {String} $strCopy copy to display in tooltip
	 */
	_addTip: function($elTarget, $strDirection, $strCopy) {
		var strDirection = $strDirection === 'back' ? 'Previous:' : 'Next:',
			elHeader = $('<h6 />').text(strDirection),
			elTip = $('<div class="tip" />').text($strCopy),
			strButtonElement = this.options.strButtonElement ? this.options.strButtonElement : 'button';

		elTip.prepend(elHeader);

		$elTarget.find(strButtonElement).append(elTip);

		elTip.css('top', -1 * elTip.outerHeight());

		elTip.fadeIn();
	},

	/**
	 * Remove new tool tip for button element
	 *
	 * @param {Object} $elTarget element to remove tooltip from
	 */
	_removeTip: function($elTarget) {
		var elTip = $elTarget.find('.tip');

		elTip.remove();
	},

	/**
	 * Slide to target panel
	 *
	 * @param {Object} $el target element panel
	 * @param {Number} $index index of target panel
	 * @param {Boolean} $setFocus set focus on first element on panel
	 */
	_slideToPanel: function($el, $index, $setFocus) {
		var self = this,
			elTargetPanel = $el,
			height = 0;

		$.each( this.ui.panels, function() {
			$(this).removeAttr('tabIndex').attr('aria-hidden', 'true').removeClass(self.options.strActiveClass).children().show();
		});

		// Adjust height to current panel
		if ( this.state.maxHeight === null ) {
			
			this.ui.carousel.css('height', 'auto');

			var $activePanel = this.ui.targetPanels;

			// Preload images
			var imgLoad = imagesLoaded( $activePanel, function() {

					$.each( $activePanel, function() {
						var curHeight = $(this).outerHeight(true);

						if ( curHeight > height ) {
							height = curHeight;
						}
					});
					self.ui.carousel.css('height', height);
				});	
		}

		TweenMax.to( this.ui.carousel, this.options.transitionSpeed, {
			left: (100 * ($index * -1)) + '%',
			ease: this.options.transitionEase,
			onComplete: function() {
				
				$.each( self.ui.panels, function() {
					$(this).children().hide();
				});
				$.each( self.ui.targetPanels, function(){
					$(this).attr('tabIndex', '-1').attr('aria-hidden', 'false').addClass(self.options.strActiveClass).children().show();
				});

				self._onAnimationComplete( $index, $setFocus);
			}
		});
	},

	/**
	 * Fade to target panel
	 *
	 * @param {Object} $el target element panel
	 * @param {Number} $index index of target panel
	 * @param {Boolean} $setFocus set focus on first element on panel
	 */
	_fadeToPanel: function($el, $index, $setFocus) {
		var self = this;

		$.each( this.ui.panels, function() {
			$(this).removeAttr('tabIndex').removeClass(self.options.strActiveClass).show();
		});

		TweenMax.to( this.ui.panels, this.options.transitionSpeed, {
			opacity: 0,
			position: 'absolute',
			ease: this.options.transitionEase
		});

		TweenMax.to( this.ui.targetPanels, this.options.transitionSpeed, {
			opacity: 1,
			position: 'relative',
			ease: this.options.transitionEase,
			onComplete: function() {
				$.each( self.ui.panels, function() {
					$(this).hide();
				});
				$.each( self.ui.targetPanels, function(){
					$(this).attr('tabIndex', '-1').addClass(self.options.strActiveClass).show();
				});

				self._onAnimationComplete( $index, $setFocus);
			}
		});
	},

	_onAnimationComplete: function( $index, $setFocus ) {
		var self = this;

		self._setCurPanels( $index );
		self.state.curIndex = $index;

		if ($setFocus) {
			self._setActiveFocus();
			self._setActiveFocusable();
		}

		// fire panel load callback
		if (typeof self.options.onPanelLoad === 'function') {
			self.options.onPanelLoad(self);
		}

		self.state.animating = false;

		self._setArrowsPosition();
	},

	_setArrowsPosition: function() {
		if ( this.ui.arrowsWrapper ) {
			var carouselHeight = parseInt(this.ui.carousel[0].style['height']),
				top = carouselHeight / 2,
				arrowHeight = this.ui.arrowNext.outerHeight(true) || this.ui.arrowBack.outerHeight(true);

			top -= arrowHeight / 2;
			this.ui.arrowsWrapper.css('top', top);
		}
	},

	/**
	 * Set new panel to display
	 *
	 * @param {Number} $index index of target panel
	 * @param {String} $direction indicates direction to move to
	 * @param {Boolean} $setFocus set focus on first element on panel
	 */
	_setPanel: function($index, $direction, $setFocus) {
		var self = this,
			elCurrentPanel = this.ui.currentPanels,
			boolSetFocus = typeof $setFocus === 'boolean' ? $setFocus : true;

		this._setTargetPanels( $index );

		if (!this.state.animating) {
			this.state.animating = true;

			if (this.options.isSlider) {
				this._slideToPanel(this.ui.targetPanels, $index, boolSetFocus);
			} else {
				this._fadeToPanel(this.ui.targetPanels, $index, boolSetFocus);
			}

			//this.ui.currentPanels = elTargetPanel;

			this._updateUI( $index );
		}
	},

	/**
	 * Set focus to active panel
	 */
	_setActiveFocus: function() {
		var self = this;

		$(this.ui.currentPanels[0]).focus();

		// Use this to set focus to element within panel
		//$(this.ui.currentPanels[0]).find( self.constant.arrFocusables.join(',') ).eq(0).focus();
		
	},

	/**
	 * Set all elements within active panel as focusable
	 * Remove focusabilty from non-active panel elements
	 */
	_setActiveFocusable: function() {
		var strFocusable,
			i;

		for (i = 0; i < this.constant.arrFocusables.length; i += 1) {
			strFocusable = this.constant.arrFocusables[i];

			this.ui.panels.find(strFocusable).attr('tabindex', -1);
			$.each( this.ui.currentPanels, function() {
				$(this).find(strFocusable).attr('tabindex', 0);
			});
		}
	},

	/**
	 * Check to see if the widget is in an animating state
	 * @return {Boolean} Animating, true or false
	 */
	_checkAnimating: function() {
		return this.state.animating;
	},

	/**
	 * Unbind events (used when modal window closes)
	 */
	kill: function() {
		this._unBindEvents();
	}
};
/* Accordion.js */
var ABV = ABV || {};

/**
 * Accordion
 * 
 * @description
 * - Collapses content into a drawer
 * 		
 * @requires jQuery
 * @requires ABV.Constants
 * @requires ABV.Analytics
 *
 * @constructor
 * @author      zake <zak.eddington@popagency.com>
 * @copyright   Copyright (c) 2015 Target Brands, Inc.
 */

ABV.Accordion = function( $container, objOptions ) {
	
	this.options = $.extend({
		selectorItems   : '> li',                 // selector of all drawers
		selectorTrigger : '.accordion-trigger',   // selector of the drawer trigger
		selectorContent : '.accordion-content',   // selector of the drawer content
		selectorLabel   : '.offscreen',           // selector of accessibility open/close label
		classClosed     : 'closed',               // class of the closed state
		classWideContent: 'wide',                 // class added to layout when image column is empty
		labelOpen       : ': expand panel',       // accessibility label to open drawer
		labelClose      : ': minimize panel',     // accessibility label to close drawer
		wideOption      : false,                  // should we check for the wide layout
		multipleOpen    : false,                  // can multiple drawers be opened
		scrollToTrigger : false,                  // should we auto scroll to opened drawer
		animSpeed       : 400,                    // (ms) speed of open/close animation
		animEase        : 'swing',                // jQuery animation ease 
	}, objOptions || {});

	this.ui = {
		htmlBody        : $('html,body'),
		container       : $container,
		trigger         : $container.find(this.options.selectorTrigger),
		items           : $container.find(this.options.selectorItems)
	}

	this.state = {
		isAnimating     : false
	}

	this._initialize();
};


ABV.Accordion.prototype = {
	
	_initialize: function() {
		if ( this.options.wideOption ) {
			this._checkWideContent();
		}
		this._closeAll();
		this._addEventListeners();
	},

	/**
	 * Add custom classes based on content
	 */
	_checkWideContent: function() {
		var self = this;

		// Add wide class when .accordion-secondary does not contain an image
		// Image is optional in webpart so this column will be empty
		this.ui.items.each( function() {
			var $curItem = $(this),
				$image = $curItem.find('.accordion-secondary img');

			if ( !$image.length ) {
				$curItem.addClass( self.options.classWideContent );
			}
		});
	},

	/**
	 * Toggle drawer open/close
	 * @param  {Object} $trigger - jQuery object of trigger element
	 */
	_toggle: function( $trigger ) {
		var	$elItem  = $trigger.parent(),
			curTitle = $trigger.text(),
			$content = $elItem.find( this.options.selectorContent );

		if ( !this.state.isAnimating ) {
			this.state.isAnimating = true;

			// Fire analytics callback
			ABV.Analytics.onAccordion( curTitle );

			// If drawer is already open, close it
			if ( !$elItem.hasClass( this.options.classClosed ) ) {
			    this._slideClose( $elItem );
			}
			// Drawer is closed
			else {
				// If multiple drawers can be opened, open it
				if ( this.options.multipleOpen ) {

					if ( $elItem.hasClass( this.options.classClosed ) ) {
						this._slideOpen( $elItem );
					} else {
						this._slideClose( $elItem );
					}
				}
				// Otherwise, close all drawers and open current one
				else {
				    this._closeAll();

					if ( $elItem.hasClass( this.options.classClosed ) ) {
						this._slideOpen( $elItem );
					} else {
						this._slideClose( $elItem );
					}
				}
			}
		}
	},

	// Close all drawers
	_closeAll: function() {
		var self = this;

		this.ui.items.each( function() {
			var $curItem = $(this);

			self._slideClose( $curItem );
		});
	},

	/**
	 * Close single drawer
	 * @param  {Object} $elItem - jQuery object of current drawer
	 */
	_slideClose: function( $elItem ) {
		var self = this;

		$elItem.addClass( this.options.classClosed )
			.find( this.options.selectorContent )
			.slideUp( this.options.animSpeed, this.options.animEase, function() {
				self._slideCallback( $elItem );
			});
	},

	/**
	 * Open single drawer
	 * @param  {Object} $elItem - jQuery object of current drawer
	 */
	_slideOpen: function( $elItem ) {
		var self = this;

		$elItem.removeClass( this.options.classClosed )
			.find( this.options.selectorContent )
			.slideDown( this.options.animSpeed, this.options.animEase, function() {
				self._slideCallback( $elItem );
			});
	},

	/**
	 * Callback after drawer opens/closes
	 * @param  {Object} $elItem - jQuery object of current drawer
	 */
	_slideCallback: function( $elItem ) {
		this.state.isAnimating = false;

		this._toggleLabel( $elItem );

		if ( this.options.scrollToTrigger ) {
			this._scrollToTrigger( $elItem );
		}
	},

	/**
	 * Toggle accessibility label
	 * @param  {Object} $elItem - jQuery object of current drawer
	 */
	_toggleLabel: function( $elItem ) {
		var $label = $elItem.find( this.options.selectorTrigger ).find( this.options.selectorLabel );

		if ( $elItem.hasClass( this.options.classClosed ) ) {
			$label.text( this.options.labelOpen );
		} else {
			$label.text( this.options.labelClose );
		}
	},

	/**
	 * Scroll to the open drawer
	 * @param  {Object} $elItem - jQuery object of current drawer
	 */
	_scrollToTrigger: function( $elItem ) {
		var scrollYPos = $elItem.offset().top;		

		this.ui.htmlBody.animate({ 
			scrollTop: scrollYPos 
		}, this.options.animSpeed, this.options.animEase);
	},

	_addEventListeners: function() {
		var self = this;

		this.ui.container.on('click', this.options.selectorTrigger, function( $event ){
			$event.preventDefault();
			self._toggle( $(this) );
		});
	}
};
/* TabSwitcher.js */
var ABV = ABV || {};

/**
 * Tab Switcher
 * 
 * @description
 * - Show/hide content elements within a parent container
 * - Can have multiple navigation menus (eg. nav at the top and bottom of content)
 * - Navs MUST be ul/li/a format and/or select menu
 * - Can have multiple content containers so you can update content in multiple places on the page
 * - Content containers should have one child per nav item (ul/li or .tab-content with multiple child .tab-content-item)
 * - Can have next/prev nav items
 * 		
 * @requires jQuery
 * @requires TweenMax
 * @requires ABV.Constants
 * @requires ABV.Analytics
 *
 * @example
 * new ABV.TabSwitcher( $('.tab-switcher'), {options} );
 *
 * @constructor
 * @author      zake <zak.eddington@popagency.com>
 * @copyright   Copyright (c) 2015 Target Brands, Inc.
 */

ABV.TabSwitcher = function( $container, $objOptions ) {
	
	/**
	 * Default configuration for component
	 */
	this.options = $.extend({
		classNav             : 'tab-nav',           // class of nav menus
		classPrev            : 'tab-prev',          // class of prev buttons
		classNext            : 'tab-next',          // class of next buttons
		classContent         : 'tab-content',       // class of content containers
		classActive          : 'active',            // class set for active state
		selectorItem         : '.tab-content-item', // selector of content child items that map to nav items 
												    // -> could be "> li" if content container is a list
		deepLink             : false,               // should we enable deep linking to content
		setActiveItemOnInit  : true,                // should we trigger an active state on init
		animSpeed            : 0.5,                 // (seconds) time taken to transition content
		animEase             : 'Expo.easeInOut',    // TweenMax easing function to use on transitions
		onStartCallback      : null,                // callback when animation starts
		onCompleteCallback   : null                 // callback when animation ends
	}, $objOptions || {});

	this.ui = {
		window               : $(window),
		tabSwitcher          : $container,
		nav                  : null,
		prev                 : null,
		next                 : null,
		content              : null
	},

	/**
	 * Values specific to current tab switcher
	 */
	this.instance = {
		numNav               : 0,    // number of nav menus
		numContent           : 0,    // number of content parents
		allContentItems      : [],   // array of all content elements
		maxIndex             : null  // max number of content elements
	},

	this.state = {
		hash                 : window.location.hash,
		index                : 0,
		prevIndex            : null,
		isAnimating          : false
	},

	this._initialize();
};


ABV.TabSwitcher.prototype = {

	/**
	 * Initialize the tab switcher
	 * Sets number of content parents and nav menus to update
	 * Create array of all content child elements to animate
	 */
	_initialize: function() {

		// el refs
		this.ui.nav     = this.ui.tabSwitcher.find( '.' + this.options.classNav );
		this.ui.prev    = this.ui.tabSwitcher.find( '.' + this.options.classPrev );
		this.ui.next    = this.ui.tabSwitcher.find( '.' + this.options.classNext );
		this.ui.content = this.ui.tabSwitcher.find( '.' + this.options.classContent );

		// number of items
		this.instance.numNav      = this.ui.nav.length;     // Number of nav menus
		this.instance.numContent  = this.ui.content.length; // Number of content containers

		// set this.instance.maxIndex to max number of child content elements
		for ( var i = 0; i < this.instance.numContent; i++ ) {
			this.instance.maxIndex = this.ui.content.eq(i).find( this.options.selectorItem ).length - 1;
			this.instance.allContentItems.push( this.ui.content.eq(i).find( this.options.selectorItem ) );
		}

		this._addEventListeners();

		if ( this.options.setActiveItemOnInit ) {
			if ( this.state.hash && this.options.deepLink ) {
				this.setActiveHash( this.state.hash );
			} else {
				this.setActiveItem( this.state.index );
			}
		}
	},

	/**
	 * Update the current index to the element with the this.state.hash id
	 * @param  {String} strHash - Window this.state.hash
	 */
	setActiveHash: function( strHash ) {

		var curIndex = $( strHash ).index();

		window.location.hash = strHash;

		this.setActiveItem( curIndex );
	},

	/**
	 * If it's not animating, fire _setItem to update active states
	 * @param {Number} numToIndex - Index of current child elements
	 */
	setActiveItem: function( numToIndex ) {
		if ( !this.state.isAnimating ) {
			this._setItem( numToIndex );
		}
	},

	/**
	 * Set active classes on current child elements
	 * Create arrays of elements to animate
	 * @param {Number} numToIndex - Index of current child elements
	 */
	_setItem: function( numToIndex ) {
		var curItems = [];

		// Loop through content parents to find all child elements
		for ( var i = 0; i < this.instance.numContent; i++ ) {

			var contentItems = $( this.ui.content[i] ).find( this.options.selectorItem ),
				curContentItem = contentItems.eq( numToIndex );

			// Remove all active classes
			contentItems.removeClass( this.options.classActive );

			// Add active class to current elements
			curContentItem.addClass( this.options.classActive );

			// Add current elements to animation array
			curItems.push( curContentItem );

		}

		// Loop through nav menus to find all child elements
		for ( var j = 0; j < this.instance.numNav; j++ ) {

			var	navItems = $( this.ui.nav[j] ).children(),
				curNavItem = navItems.eq( numToIndex );

			// Remove all active classes
			navItems.removeClass( this.options.classActive );

			// Add active class to current elements
			curNavItem.addClass( this.options.classActive );

		}

		this.state.index = numToIndex;

		this._animateItems( curItems, this.instance.allContentItems, this.state.prevIndex, this.state.index );

		this.state.prevIndex = this.state.index;
	},

	/**
	 * Animate all elements
	 * On animation complete fire optional callback
	 * @param  {Object} $curItems    - jQuery object of elements with active class
	 * @param  {Object} $allItems    - jQuery object of all content elements
	 * @param  {Number} numPrevIndex - previous active index
	 * @param  {Number} numCurIndex  - current active index
	 */
	_animateItems: function( $curItems, $allItems, numPrevIndex, numCurIndex ) {
		var self = this;

		// Hide all items
		$( $allItems ).each(function() {
			$(this).css({ 'display': 'none' });
		});
		TweenMax.to( $allItems, this.options.animSpeed, {
			opacity: 0,
			ease: self.options.animEase
		});

		// Show current items
		$( $curItems ).each(function() {
			$(this).css({ 'display': 'block' });
		});
		TweenMax.to( $curItems , this.options.animSpeed, {
			opacity: 1,
			ease: self.options.animEase,
			onStart: function(){
				self.state.isAnimating = true;

				if ( self.options.onStartCallback ) {
					self.options.onStartCallback( numPrevIndex, numCurIndex );
				}
			},
			onComplete:	function(){
				self.state.isAnimating = false;

				if ( self.options.onCompleteCallback ) {
					self.options.onCompleteCallback( numPrevIndex, numCurIndex );
				}
			}
		});
	},

	/**
	 * Update the current index based on prev/next selection
	 * @param  {Number} numDirection - A number which indicates next (1) or prev (-1)
	 */
	_setDirection: function( numDirection ) {

		this.state.index += numDirection;

		if ( this.state.index > this.instance.maxIndex ) {
			this.state.index = 0;
		} else if ( this.state.index < 0 ) {
			this.state.index = this.instance.maxIndex;
		}

		this.setActiveItem( this.state.index );
	},

	/**
	 * Get the current this.state.hash value
	 * @param  {Event} $event
	 */
	_onHashChange: function( $event ) {
		this.state.hash = window.location.hash;

		if ( this.state.hash ) {
		 	this.setActiveHash( this.state.hash );
		}
	},

	/**
	 * Update the current index to selected nav item index
	 * @param  {Object} $event
	 */
	_onNavAction: function( $event ) {
		var curTarget = $( $event.currentTarget ),
			curTitle  = curTarget.text(),
			curIndex;

		$event.preventDefault();

		if ( $event.type === 'click' ) {
			curIndex = curTarget.parent().index();

			// Fire analytics callback
			ABV.Analytics.onTabSwitcher( curTitle );

		}

		if ( $event.type === 'change' ) {
			curIndex = curTarget.find(':selected').index();

			// Fire analytics callback
			ABV.Analytics.onTabSwitcher( curTitle );
		}
		
		if ( curIndex >= 0 ) {
			this.setActiveItem( curIndex );
		}
	},

	/**
	 * Selects the previous item
	 * @param  {Object} $event
	 */
	_prev: function( $event ) {
		$event.preventDefault();

		this._setDirection( -1 );
	},

	/**
	 * Selects the next item
	 * @param  {Object} $event
	 */
	_next: function( $event ) {
		$event.preventDefault();

		this._setDirection( 1 );
	},

	/**
	 * Event Listeners
	 */
	_addEventListeners: function() {

		this.ui.prev.on('click', $.proxy(this._prev, this));
		this.ui.next.on('click', $.proxy(this._next, this));

		if ( this.options.deepLink ) {
			this.ui.window.on('hashchange', $.proxy(this._onHashChange, this) );
		}
		
		this.ui.nav.on('click', 'li a', $.proxy(this._onNavAction, this) );
		this.ui.nav.on('change', $.proxy(this._onNavAction, this) );
	}
};
/* SocialWall.js */
var ABV = ABV || {};

/**
 * Social Wall
 * 
 * @description
 * - Displays social media items from a JSON endpoint in a Masonry layout.
 * - Includes a load more button that adds X number of items.
 * - JSON url and X number to load are data attr on $container
 * 		
 * @requires jQuery
 * @requires jQuery imagesLoaded plugin
 * @requires Masonry
 * @requires Handlebars
 * @requires ABV.Constants
 * @requires ABV.Utils
 * @requires ABV.Analytics (fire callback on load more button click)
 *
 * @example
 * new ABV.SocialWall($('.social-wall'), {options})
 *
 * @constructor
 * @author      zake <zak.eddington@popagency.com>
 * @copyright   Copyright (c) 2015 Target Brands, Inc.
 *
 * @param {Object} $container - jQuery element for widget
 * @param {Object} objOptions - Optional object of properties to mixin to the instance
 */
ABV.SocialWall = function ( $container, objOptions ) {

	this.options = $.extend({
		dataAttrUrl          : 'url',                          // name of data attr on container for ajax url
		dataAttrLimit        : 'limit',                        // name of data attr on container for num of items to load
		selectorList         : '.wall-listing',                // selector of container element of all items
		selectorItem         : '.grid-cell',                   // selector of items
		selectorItemFocus    : '> h3:first-child',             // selector of element within first new item to send focus
		selectorLoadContainer: '.btn-container',               // selector of load more button container
		selectorLoadButton   : '.btn-load-more',               // selector of load more button
		selectorLoadLabel    : '.label',                       // selector of load more button inner text element
		classItemsLoading    : 'loading',                      // class set for loading state
		animSpeed            : 400,                            // (ms) speed of masonry and error/end msg animation
		masonryWidth         : 300,                            // masonry item width
		masonryGutter        : 20,                             // masonry gutter width
		ajaxErrorMsg         : ABV.Constants.labels.ajaxError, // global string of html for ajax error messaging
		ajaxEndMsg           : ABV.Constants.labels.ajaxEnd,   // global string of html for ajax end messaging
		strButtonLabel       : ABV.Constants.labels.loadMore,  // global string of load more button default state
		strButtonLoading     : ABV.Constants.labels.loading,   // global string of load more button loading state
		htmlWallTemplate     : '/assets/abv/templates/social-wall.html'  // Handlebars template for gallery wall items
	}, objOptions || {});

	this.constant = {
		dataUrl              : null,        // placeholder for ajax data url
		dataLimit            : null,        // placeholder for number of items to request
		getAjaxContent       : ABV.Utils.getAjaxContent,  // global ajax request utility
		template             : null,        // placeholder for compiled Handlebars template
		namespace            : null         // dynamically created namespace for this instance
	};

	this.state = {
		userInteraction      : false,       // has user clicked the load more button
		startId              : null,        // id of first data item to request
		postCount            : 0            // number of posts that have been loaded
	};

	this.ui = {
		window               : $(window),
		wall                 : $container,  // container element
		list                 : null,        // content container
		loadContainer        : null,        // load more button container
		loadButton           : null,        // load more button
		loadLabel            : null         // load more button inner text element
	};

	this._initialize();
};

ABV.SocialWall.prototype = {

	_initialize: function() {

		// Set element references
		this.ui.list            = this.ui.wall.find( this.options.selectorList ).addClass( this.options.classItemsLoading );
		this.ui.loadContainer   = this.ui.wall.find( this.options.selectorLoadContainer );
		this.ui.loadButton      = this.ui.wall.find( this.options.selectorLoadButton );
		this.ui.loadLabel       = this.ui.loadButton.find( this.options.selectorLoadLabel );

		// Set data url
		this.constant.dataUrl   = this.ui.wall.data( this.options.dataAttrUrl );
		this.constant.dataLimit = this.ui.wall.data( this.options.dataAttrLimit );
		this.constant.dataUrl  += '?limit=' + this.constant.dataLimit;

		// set namespace for this instance of the social wall
		this.constant.namespace = Date.now();

		// Kickoff widget
		this._bindEvents();
	},

	/**
	 * Add event handlers to load more button
	 * Fired on init
	 */
	_bindEvents: function() {
		this.ui.loadButton.on('click.' + this.constant.namespace, $.proxy(this.__onLoadBtnClick, this));
		this.ui.window.on('scroll.' + this.constant.namespace, $.proxy(this.__onWindowScroll, this) );
	},

	/**
	 * Remove event handlers on load more button
	 * Fired when no more items are available to load
	 */
	_unbindLoadButton: function() {
		this.ui.loadButton.off('.' + this.constant.namespace);
	},
	/**
	 * Remove event handlers on window scroll
	 * Fired when widget has been displayed
	 */
	_unbindScroll: function() {
		this.ui.window.off('.' + this.constant.namespace);
	},

	/**
	 * Start all actions to load more content
	 * @param  {Event} $event]
	 */
	__onLoadBtnClick: function( $event ) {
		$event.preventDefault();

		// fire analytics callback
		ABV.Analytics.onLoadMoreButton();
		
		this.state.userInteraction = true;
		this._hideBtn();

		// Get more content
		this._getContent( this.constant.dataUrl );
	},

	/**
	 * Display social wall only when it is in view
	 */
	__onWindowScroll: function() {
		var scrollTop = this.ui.window.scrollTop(),
			winHeight = this.ui.window.height(),
			wallTop   = this.ui.wall.offset().top;

		if ( wallTop <= scrollTop + winHeight ) {
			this._unbindScroll();
			this._initMasonry();
			this._getTemplate();
		}
	},

	/**
	 * Show the load more button
	 */
	_showBtn: function() {
		this.ui.loadButton.fadeIn().removeAttr('disabled').css('display', 'block');
		this.ui.loadLabel.text( this.options.strButtonLabel );
	},

	/**
	 * Hide the load more button and remove error message
	 */
	_hideBtn: function() {
		this.ui.loadButton.attr('disabled', 'disabled');
		this.ui.loadLabel.text( this.options.strButtonLoading );
		this.ui.loadContainer.find( $(this.options.ajaxErrorMsg) ).remove();
	},

	/**
	 * Remove the load more button and display end message
	 */
	_removeBtn: function() {
		var endMsg = $( this.options.ajaxEndMsg ).hide();

		this._unbindLoadButton();
		this.ui.loadButton.remove();

		this.ui.loadContainer.append( endMsg );
		endMsg.delay( this.options.animSpeed ).fadeIn();
	},

	/**
	 * Show error message on ajax request failure
	 */
	_showError: function() {
		var errorMsg = $( this.options.ajaxErrorMsg ).hide();

		this.ui.loadContainer.append( errorMsg );
		errorMsg.delay( this.options.animSpeed ).fadeIn();

		this.ui.list.removeClass( this.options.classItemsLoading );

		this._showBtn();
	},

	_getTemplate: function() {
		var self = this;

		// Get the content
		$.when( this.constant.getAjaxContent( self.options.htmlWallTemplate, 'text' )).done( function( response ) {

			self.constant.template = Handlebars.compile(response);
			self._getContent();

		}).fail(function() {
			console.log('error with ajax call');
		});
	},

	/**
	 * Init the masonry layout of items
	 */
	_initMasonry: function() {
		var duration = (this.options.animSpeed / 1000).toString();

		duration += 's';

		// disable animations for iOS
		if ( ABV.Constants.isIDevice ) {
			duration = 0;
		}

		this.ui.list.masonry({
			columnWidth        : this.options.masonryWidth,
			gutter             : this.options.masonryGutter,
			itemSelector       : this.options.selectorItem,
			transitionDuration : duration
		});
	},

	/**
	 * Fire ajax request for more content
	 */
	_getContent: function() {
		var self = this
			dataUrl = this.constant.dataUrl;

		// If we have a ajax url, get the content
		if ( this.constant.dataUrl ) {

			// Append the start id query parameter to the request url
			if ( this.state.startId ) {
				dataUrl += '&start_id=' + this.state.startId;
			}			

			// Get the content
			$.when( this.constant.getAjaxContent( dataUrl, 'jsonp', true )).done( function( response ) {
				self._processData( response );
			}).fail(function() {
				self._showError();
			});
		}
		// Otherwise, show the error message
		else {
			this._showError();
		}
	},

	/**
	 * Normalize the data for each social platform.
	 * Convert timestamp, add anchors in content, etc
	 * @param  {Object} data - ajax response data
	 */
	_processData: function( data ) {
		// console.log(data);

		for (var i = 0, len = data.length; i < len; i++) {

			// Facebook
			if (data[i].network === 'facebook') {
				this.state.postCount++;
				data[i].postNum     = this.state.postCount;
				data[i].fullName    = data[i].from.name || null;
				data[i].screenName  = data[i].from.broadcast_name || null;
				data[i].avatarSrc   = null;
				data[i].postHref    = 'https://www.facebook.com/' + data[i].facebook_id.split('_')[0] + '/posts/' + data[i].facebook_id.split('_')[1];
				data[i].contentText = data[i].message || null;
				data[i].isVideo     = (data[i].type === 'video');
				data[i].date        = data[i].created_time || null;

				// Convert to friendly date
				data[i].date = this.getTime(data[i].date);

				// Set image to 320px version if images node exists
				if ( data[i].images ) {
					for (var j = 0, jlen = data[i].images.length; j < jlen; j++) {
						if ( data[i].images[j].width === 320 ) {
							data[i].imgSrc = this.replaceImgSrc( data[i].images[j].source );
						}
					}
				}
				// Or set image to 480px version if format node exists (video posts)
				else if ( data[i].format ) {
					for (var k = 0, klen = data[i].format.length; k < klen; k++) {
						if ( data[i].format[k].width === 480 ) {
							data[i].imgSrc = this.replaceImgSrc( data[i].format[k].picture );
						}
					}
				}
				// Otherwise fallback to the default image
				// and remove the "safe_image.php" query param to get the full size version
				else {
					data[i].imgSrc = data[i].picture || null;
					data[i].imgSrc = this.replaceFacebookImg( data[i].imgSrc );
					data[i].imgSrc = this.replaceImgSrc( data[i].imgSrc );
				}

				// Add anchors to content
				if (data[i].contentText) {
					data[i].contentText = this.replaceURL(  data[i].contentText );
					data[i].contentText = this.replaceHash( data[i].contentText, 'https://www.facebook.com/hashtag/' );
					data[i].contentText = this.replaceAt(   data[i].contentText, 'https://www.facebook.com/' );
				}
			}

			// Twitter
			if (data[i].network === 'twitter') {
				this.state.postCount++;
				data[i].postNum     = this.state.postCount;
				data[i].fullName    = data[i].user.name || null;
				data[i].screenName  = data[i].user.screen_name || null;
				data[i].avatarSrc   = this.replaceImgSrc( data[i].user.profile_image_url || null );
				data[i].postHref    = 'https://twitter.com/' + data[i].user.screen_name + '/status/' + data[i].id_str;
				data[i].contentText = data[i].text || null;
				data[i].imgSrc      = this.replaceImgSrc( !!(data[i].entities.media && data[i].entities.media[0].media_url) ? data[i].entities.media[0].media_url : null );
				data[i].isVideo     = (data[i].kind === 'video');
				data[i].date        = data[i].created_at || null;

				// Convert to friendly date
				data[i].date = this.getTime(data[i].date);

				// Add anchors to content
				if (data[i].contentText) {
					data[i].contentText = this.replaceURL(  data[i].contentText );
					data[i].contentText = this.replaceHash( data[i].contentText, 'https://twitter.com/search?q=%23' );
					data[i].contentText = this.replaceAt(   data[i].contentText, 'https://twitter.com/' );
				}
			}

			// Instagram
			if (data[i].network === 'instagram') {
				this.state.postCount++;
				data[i].postNum     = this.state.postCount;
				data[i].fullName    = data[i].user.full_name || null;
				data[i].screenName  = data[i].user.username || null;
				data[i].avatarSrc   = this.replaceImgSrc( data[i].user.profile_picture || null );
				data[i].postHref    = data[i].link;
				data[i].contentText = (data[i].caption) ? data[i].caption.text : null;
				data[i].imgSrc      = this.replaceImgSrc( data[i].images.low_resolution.url || null );
				data[i].isVideo     = (data[i].type === 'video');
				data[i].date        = (data[i].caption) ? data[i].caption.created_time : null;

				// Convert to friendly date
				data[i].date = this.getTime(data[i].date, true);

				// Add anchors to content
				if (data[i].contentText) {
					data[i].contentText = this.replaceURL(  data[i].contentText );
					//data[i].contentText = this.replaceHash( data[i].contentText, 'http://instagram.com/' );
					data[i].contentText = this.replaceAt(   data[i].contentText, 'http://instagram.com/' );
				}
			}

			// Pinterest
			if (data[i].network === 'pinterest') {
				this.state.postCount++;
				data[i].postNum     = this.state.postCount;
				data[i].fullName    = data[i].actor.displayName || null;
				data[i].screenName  = data[i].actor.id || null;
				data[i].postHref    = data[i].object.url;
				data[i].contentText = data[i].object.content || null;
				data[i].imgSrc      = this.replaceImgSrc( data[i].object.image.url || null );
				data[i].isVideo     = data[i].isVideo;
				data[i].date        = data[i].published || null;

				// Convert to friendly date
				data[i].date = this.getTime(data[i].date);

				// Add anchors to content
				if (data[i].contentText) {
					data[i].contentText = this.replaceURL(  data[i].contentText );
					data[i].contentText = this.replaceHash( data[i].contentText, 'https://www.pinterest.com/search/?q=' );
					//data[i].contentText = this.replaceAt(   data[i].contentText, 'https://www.pinterest.com/' );
				}
			}
		}

		this._render(data);
	},

	/**
	 * Convert timestamp to friendly date
	 * @param  {String}  time            - timestamp from JSON data
	 * @param  {Boolean} isUnixTimeStamp - is the string a unix timestamp (instagram)
	 * @return {String}                  - a new string of the friendly date
	 */
	 getTime: function(time, isUnixTimeStamp) {
		var timeNow = new Date(),
			timeStamp;

		if ( isUnixTimeStamp ) {
			timeStamp = new Date( parseInt(time) * 1000 );
		} else {
			timeStamp = new Date( time );
		}
		
		var secondsPast = ( timeNow.getTime() - timeStamp.getTime() ) / 1000;

		if ( secondsPast < 60 ) {
		  return parseInt( secondsPast ) + 's';
		}
		if ( secondsPast < 3600 ) {
		  return parseInt( secondsPast / 60 ) + 'm';
		}
		if ( secondsPast <= 86400 ) {
		  return parseInt( secondsPast / 3600 ) + 'h';
		}
		if ( secondsPast > 86400 ) {
			var day   = timeStamp.getDate(),
				month = timeStamp.toDateString().match(/ [a-zA-Z]*/)[0].replace(" ","");
				
			return month + " " + day;
		}
  },

	/**
	 * function to replace text urls with anchor
	 * @param  {String} stringToParse - a string representing the string we want to replace
	 * @return {String}               - a new string value with text replaced
	 */
	replaceURL: function( stringToParse ) {
		// look for link references beginning with http:// https:// or tgt.biz
		var urlRegEx      = /(https?:\/\/[^\s]+|tgt\.biz[^\s]+)/gi, 
			newString     = ' <a href="$1" target="_blank" title="opens in a new window">$1</a>',
			anchorsResult = stringToParse.replace(urlRegEx, newString);
		
		// append http:// to tgt.biz anchors
		var hrefRegEx     = /(href="tgt+)/gi,
			newHrefString = 'href="http://tgt';

		var result = anchorsResult.replace(hrefRegEx, newHrefString);
		return result;
	},

	/**
	 * function to replace hashtags (#) with url
	 * @param  {String} stringToParse - a string representing the string we want to replace
	 * @return {String}               - a new string value with text replaced
	 */
	replaceHash: function( stringToParse, baseURL ) {
		var hashRegEx = /(^|\s)(#)([a-z\d_-][\w-]*)/gi, 
			newString = ' <a href="' + baseURL + '$3" target="_blank" title="opens in a new window">$2$3</a>',
			result    = stringToParse.replace(hashRegEx, newString);

		return result;
	},

	/**
	 * function to replace at symbol (@) with url
	 * @param  {String} stringToParse - a string representing the string we want to replace
	 * @return {String}               - a new string value with text replaced
	 */
	replaceAt: function( stringToParse, baseURL ) {
		var hashRegEx = /(^|\s)(\@)([a-z\d_-][\w-]*)/gi,
			newString = ' <a href="' + baseURL + '$3" target="_blank" title="opens in a new window">$2$3</a>',
			result    = stringToParse.replace(hashRegEx, newString);

		return result;
	},

	/**
	 * function to replace the "safe_image.php" query param to get the full size version
	 * @param  {String} stringToParse - a string representing the string we want to replace
	 * @return {String}               - a new string value with text replaced or the original string if nothing to replace
	 */
	replaceFacebookImg: function( stringToParse ) {
		var match = /\/safe_image\.php?.*url=([^&]+)(?:&|$)/g.exec(stringToParse);

		if ( match ) {
			var newString = decodeURIComponent(match[1]); // need to URL decode the string
			return newString;
		} else {
			return stringToParse;
		}
	},

	/**
	 * function to replace http with https
	 * @param  {String} url - image src url
	 * @return {String}     - image src url with https
	 */
	replaceImgSrc: function( url ) {
		if ( url ) {
			return url.replace('http:', 'https:');
		}
		return url;
	},

	/**
	 * Display the new content
	 * @param  {Object} objData     - ajax response data
	 * @param  {[type]} strTemplate - Handlebars template to render the data
	 */
	_render: function( objData ) {
		var data       = objData,
			html       = this.constant.template({ items:data }),
			$items     = $(html).filter( this.options.selectorItem ).addClass( this.options.classItemsLoading ),
			$firstItem = $items.first();

		// If we've reached the end of the content available, remove the load more button
		if ( data.length !== this.constant.dataLimit ) {
			this._removeBtn();
		}
		// Otherwise, update the start id for the next request
		else {
			this.state.startId = data[data.length-1].entity_id;
		}

		// Wait for images to load before displaying items
		this.ui.list.append( $items ).imagesLoaded( function() {
			$items.removeClass( this.options.classItemsLoading );

			this.ui.list.masonry('appended', $items);

			// Set focus to first new item added
			if ( this.state.userInteraction ) {
				$firstItem.find( this.options.selectorItemFocus ).focus();
			}

			this._showBtn();
			this.ui.list.removeClass( this.options.classItemsLoading );
		}.bind(this));
	}
};
/* GalleryWall.js */
var ABV = ABV || {};

/**
 * Handlebars template for the gallery wall items
 * @type {String}
 */
ABV.GalleryWallTemplate = 
'{{#each items}}' +
'	<article class="article-item gallery">' +
/*'		{{#if category}}' +
'		<a class="category" href="{{categoryURL}}">{{category}}</a>' +
'		{{/if}}' +*/
'       <a class="article-link" href="{{shareURL}}">' +	
'			<img src="{{imgSrc}}" alt="{{imgAlt}}" />' +
'		</a>' +
'	</article>' +
'{{/each}}';

/**
 * Handlebars template for gallery carousels
 * @type {[String}
 */
ABV.GalleryCarouselTemplate = 
'<ul class="carousel">' +
'	{{#each items}}' +
'	<li class="gtm-parent">' +
'		<div class="media"><img src="{{imgSrc}}" alt="{{imgAlt}}" /></div>' +
'       <div class="desc">' +
'			<h3 class="hidden gtm-title">{{imgAlt}}</h3>' +
'			<p>' +
'               {{{content}}}' +
'		        {{#if url}} <a href="{{url}}" class="read-more">{{urlText}}</a>{{/if}}' +
'           </p>' +
'		</div>' +
'       <div class="share">' +
'       	<ul class="social-group">' +
'				<li><a href="#" class="icon icon-facebook addthis_button_facebook gtm-social-facebook-share" target="_blank" title="Share on Facebook" '+
'					addthis:url="{{shareURL}}" ' +
'					addthis:title="{{shareTitle}}"></a></li>' +
'				<li><a href="#" class="icon icon-twitter addthis_button_twitter gtm-social-twitter-tweet" target="_blank" title="Share on Twitter" '+
'					addthis:url="{{shareURL}}" ' +
'					addthis:title="{{shareTitle}}"></a></li>' +
'				<li><a href="#" class="icon icon-pinterest addthis_button_pinterest_share gtm-social-pinterest-pin" target="_blank" title="Share on Pinterest" '+
'					addthis:url="{{shareURL}}" ' +
'					addthis:title="{{shareTitle}}"></a></li>' +
'			</ul>' +
'		</div>' +
'	</li>' +
'	{{/each}}' +
'</ul>';

/**
 * Gallery Wall
 * 
 * @description
 * - Displays gallery items from a JSON endpoint in a Masonry layout.
 * - Includes a load more button that adds X number of items.
 * - JSON url and X number to load are data attr on $container
 * - Clicking an item opens a modal window with a carousel of each currently loaded item.
 * 		
 * @requires jQuery
 * @requires jQuery imagesLoaded plugin
 * @requires Masonry
 * @requires Handlebars
 * @requires Handlebars template = ABV.GalleryWallTemplate
 * @requires Handlebars template = ABV.GalleryCarouselTemplate
 * @requires ABV.ModalWindow
 * @requires ABV.Constants
 * @requires ABV.Utils
 * @requires ABV.Analytics (fire callback on load more button click)
 *
 * @example
 * new ABV.GalleryWall($('.gallery-wall'), {options})
 *
 * @constructor
 * @author      zake <zak.eddington@popagency.com>
 * @copyright   Copyright (c) 2015 Target Brands, Inc.
 *
 * @param {Object} $container - jQuery element for widget
 * @param {Object} objOptions - Optional object of properties to mixin to the instance
 */
ABV.GalleryWall = function ( $container, objOptions ) {

	this.options = $.extend({
		dataAttrUrl          : 'url',                          // name of data attr on container for ajax url
		dataAttrLimit        : 'limit',                        // name of data attr on container for num of items to load
		selectorList         : '.wall-listing',                // selector of container element of all items
		selectorItem         : '.article-item',                // selector of items
		selectorItemFocus    : '> a:first-child',              // selector of element within first new item to send focus
		selectorModalTrigger : '.article-link',                // selector of modal trigger element in each item
		selectorLoadContainer: '.btn-container',               // selector of load more button container
		selectorLoadButton   : '.btn-load-more',               // selector of load more button
		selectorLoadLabel    : '.label',                       // selector of load more button inner text element
		classItemsLoading    : 'loading',                      // class set for loading state
		animSpeed            : 400,                            // (ms) speed of masonry and error/end msg animation
		masonryWidth         : 300,                            // masonry item width
		masonryGutter        : 20,                             // masonry gutter width
		ajaxErrorMsg         : ABV.Constants.labels.ajaxError, // global string of html for ajax error messaging
		ajaxEndMsg           : ABV.Constants.labels.ajaxEnd,   // global string of html for ajax end messaging
		strButtonLabel       : ABV.Constants.labels.loadMore,  // global string of load more button default state
		strButtonLoading     : ABV.Constants.labels.loading,   // global string of load more button loading state
		htmlWallTemplate     : ABV.GalleryWallTemplate,        // Handlebars template for gallery wall items
		htmlCarouselTemplate : ABV.GalleryCarouselTemplate     // Handlebars template for gallery content
	}, objOptions || {});

	this.constant = {
		dataUrl              : null,        // placeholder for ajax data url
		dataLimit            : null,        // placeholder for number of items to request
		getAjaxContent       : ABV.Utils.getAjaxContent  // global ajax request utility
	};

	this.state = {
		userInteraction      : false,       // has user clicked the load more button
		startIndex           : 0,           // index of first data item to request
		modalGallery         : null,        // placeholder for modal window widget
		arrData              : []           // placeholder for all item data collected
	};

	this.ui = {
		wall                 : $container,  // container element
		list                 : null,        // content container
		loadContainer        : null,        // load more button container
		loadButton           : null,        // load more button
		loadLabel            : null         // load more button inner text element
	};

	this._initialize();
};

ABV.GalleryWall.prototype = {

	_initialize: function() {

		// Set element references
		this.ui.list            = this.ui.wall.find( this.options.selectorList ).addClass( this.options.classItemsLoading );
		this.ui.loadContainer   = this.ui.wall.find( this.options.selectorLoadContainer );
		this.ui.loadButton      = this.ui.wall.find( this.options.selectorLoadButton );
		this.ui.loadLabel       = this.ui.loadButton.find( this.options.selectorLoadLabel );

		// Set data url
		this.constant.dataUrl   = this.ui.wall.data( this.options.dataAttrUrl );
		this.constant.dataLimit = this.ui.wall.data( this.options.dataAttrLimit );
		this.constant.dataUrl  += '?limit=' + this.constant.dataLimit;

		// Kickoff widget
		this._bindLoadButton();
		this._bindModalTriggers();
		this._initMasonry();
		this._getContent( this.constant.dataUrl, this.options.htmlWallTemplate );
	},

	/**
	 * Add event handlers to modal window trigger elements
	 * Used to instantiate modal window
	 */
	_bindModalTriggers: function() {
		this.ui.list.on('click', this.options.selectorModalTrigger, $.proxy(this.__onModalTriggerClick, this));
	},
	/**
	 * Remove event handlers on modal window trigger elements
	 * Used to remove events once modal window is created since modal widget events take over from here
	 */
	_unbindModalTriggers: function() {
		this.ui.list.off('click');
	},

	/**
	 * Add event handlers to load more button
	 * Fired on init
	 */
	_bindLoadButton: function() {
		this.ui.loadButton.on('click', $.proxy(this.__onLoadBtnClick, this));
	},
	/**
	 * Remove event handlers on load more button
	 * Fired when no more items are available to load
	 */
	_unbindLoadButton: function() {
		this.ui.loadButton.off('click');
	},

	/**
	 * Start all actions to load more content
	 * @param  {Event} $event]
	 */
	__onLoadBtnClick: function( $event ) {
		$event.preventDefault();

		// fire analytics callback
		ABV.Analytics.onLoadMoreButton();

		this.state.userInteraction = true;
		this._hideBtn();

		// If a ModalWidget has been created
		if ( this.state.modalGallery ) {
			// Remove ModalWindow and its trigger events 
			this.state.modalGallery.removeTriggerEvents();
			this.state.modalGallery = null;

			// Add trigger events back to GalleryWall
			this._bindModalTriggers();
		}

		// Get more content
		this._getContent( this.constant.dataUrl, this.options.htmlWallTemplate );
	},

	/**
	 * Set the index of the item to display in the modal
	 * and create new ModalWindow widget
	 * @param  {Event} $event
	 */
	__onModalTriggerClick: function( $event ) {
		$event.preventDefault();

		var curTarget = $($event.currentTarget),
			curIndex  = curTarget.parent().index();

		this._createModal( curIndex );
	},

	/**
	 * Create a new ModalWindow widget
	 * @param  {Number} numIndex - index of gallery slide to display in modal
	 */
	_createModal: function( numIndex ) {
		var self = this;

		this.state.modalGallery = new ABV.ModalWindow( this.ui.list.find( this.options.selectorModalTrigger ), {
			showSocialButtons   : true,
			isGallery           : true,
			modalID             : 'modal-gallery'
			//ajaxUrl             : this.constant.dataUrl,
			//cacheAjaxResponse   : false
		}, this.state.arrData );

		this.state.modalGallery.openToGalleryIndex( numIndex );
		this._unbindModalTriggers();
		
	},

	/**
	 * Show the load more button
	 */
	_showBtn: function() {
		this.ui.loadButton.fadeIn().removeAttr('disabled').css('display', 'block');
		this.ui.loadLabel.text( this.options.strButtonLabel );
	},

	/**
	 * Hide the load more button and remove error message
	 */
	_hideBtn: function() {
		this.ui.loadButton.attr('disabled', 'disabled');
		this.ui.loadLabel.text( this.options.strButtonLoading );
		this.ui.loadContainer.find( $(this.options.ajaxErrorMsg) ).remove();
	},

	/**
	 * Remove the load more button and display end message
	 */
	_removeBtn: function() {
		var endMsg = $( this.options.ajaxEndMsg ).hide();

		this._unbindLoadButton();
		this.ui.loadButton.remove();

		this.ui.loadContainer.append( endMsg );
		endMsg.delay( this.options.animSpeed ).fadeIn();
	},

	/**
	 * Show error message on ajax request failure
	 */
	_showError: function() {
		var errorMsg = $( this.options.ajaxErrorMsg ).hide();

		this.ui.loadContainer.append( errorMsg );
		errorMsg.delay( this.options.animSpeed ).fadeIn();

		this.ui.list.removeClass( this.options.classItemsLoading );

		this._showBtn();
	},

	/**
	 * Init the masonry layout of items
	 */
	_initMasonry: function() {
		var duration = (this.options.animSpeed / 1000).toString();

		duration += 's';

		// disable animations for iOS
		if ( ABV.Constants.isIDevice ) {
			duration = 0;
		}

		this.ui.list.masonry({
			columnWidth        : this.options.masonryWidth,
			gutter             : this.options.masonryGutter,
			itemSelector       : this.options.selectorItem,
			transitionDuration : duration
		});
	},

	/**
	 * Fire ajax request for more content
	 * @param  {String} strDataSrc  - url for ajax request
	 * @param  {String} strTemplate - Handlebars template for response
	 */
	_getContent: function( strDataSrc, strTemplate ) {
		var self     = this,
			dataUrl  = strDataSrc;

		// If we have a ajax url, get the content
		if ( dataUrl) {

			// Append the start index query parameter to the request url
			if ( this.state.startIndex ) {
				dataUrl += '&index=' + this.state.startIndex;
			}

			// Get the content
			$.when( this.constant.getAjaxContent( dataUrl, 'json' )).done( function( response ) {

				self._render( response, strTemplate );
				self._updateData( response );

			}).fail(function() {
				self._showError();
			});
		}
		// Otherwise, show the error message
		else {
			this._showError();
		}
	},

	/**
	 * Update JSON data with new items
	 * @param  {Object} objNewData - ajax JSON data from load more response
	 */
	_updateData: function( objNewData ) {
		if ( objNewData ) {
			for ( var i = 0, len = objNewData.length; i < len; i++ ) {
				this.state.arrData.push( objNewData[i] );
			}
		}
	},

	/**
	 * Display the new content
	 * @param  {Object} objData     - ajax response data
	 * @param  {[type]} strTemplate - Handlebars template to render the data
	 */
	_render: function( objData, strTemplate ) {
		var data       = objData,
			template   = Handlebars.compile( strTemplate ),
			html       = template({ items:data }),
			$items     = $(html).filter( this.options.selectorItem ).addClass( this.options.classItemsLoading ),
			$firstItem = $items.first();

		// If we've reached the end of the content available, remove the load more button
		if ( data.length < this.constant.dataLimit ) {
			this._removeBtn();
		}
		// Otherwise, update the start index for the next request
		else {
			this.state.startIndex += this.constant.dataLimit;
		}

		// Wait for images to load before displaying items
		this.ui.list.append( $items ).imagesLoaded( function() {
			$items.removeClass( this.options.classItemsLoading );

			this.ui.list.masonry('appended', $items);

			// Set focus to first new item added
			if ( this.state.userInteraction ) {
				$firstItem.find( this.options.selectorItemFocus ).focus();
			}

			this._showBtn();
			this.ui.list.removeClass( this.options.classItemsLoading );
		}.bind(this));
	}
};
/* ModalWindow.js */
var ABV = ABV || {};

/**
 * Modal Window
 * 
 * @description
 * - Display content in a modal window
 * - Content can be:
 * -- hidden element on the page referenced via href id
 * -- ajax content referenced via data attr on trigger
 * -- ajax content referenced via dataUrl option
 * 		
 * @requires jQuery
 * @requires Handlebars
 * @requires ABV.Utils
 * @requires ABV.Carousel - if loading gallery via ajax
 * @requires Handlebars template = ABV.GalleryCarouselTemplate
 * @requires ABV.VideoItem - if loading video via ajax
 * @requires Handlebars template = ABV.ModalVideoTemplate
 *
 * @example
 * new ABV.ModalWindow($('.modal-trigger'), {options})
 *
 * @constructor
 * @author      zake <zak.eddington@popagency.com>
 * @copyright   Copyright (c) 2015 Target Brands, Inc.
 *
 * @param {Object} $trigger   - jQuery element for widget
 * @param {Object} objOptions - Optional object of properties to mixin to the instance
 * @param {Object} objData    - Optional JSON object of content to display
 *
 */
ABV.ModalWindow = function( $trigger, objOptions, objData ) {

	/**
	 * Default configuration for component
	 */
	this.options = $.extend({
		ariaHideElements  : '#wrapper, body > iframe',   // elements to add attribute aria-hidden=true when modal is open
		modalID           : 'modal',                     // id of the modal window container 
		modalClass        : 'modal-window',              // class of the modal window container 
		contentClass      : 'modal-content',             // class of the content container in the modal
		modalOverlayID    : 'modal-overlay',             // id of the overlay
		closeBtnClass     : 'icon-close',                // class of the close button
		closeBtnText      : 'close modal window',        // inner text and title attribute of the close button
		activeClass       : 'active',                    // class for setting active states
		animSpeed         : 300,                         // (ms) speed of open/close animation
		animEase          : 'swing',                     // jQuery animation ease 
		ajaxDataAttr      : null,                        // name of data attr on trigger if used for ajax url (ex: 'ajaxurl')
		ajaxUrl           : null,                        // ajax url if set directly on instantiation (ex: 'http://url.com/content')
		ajaxDataType      : null,                        // type of ajax response (ex: 'json')
		ajaxErrorMsg      : '<div class="error"><p>Sorry. Ajax request failed.</p></div>',
		cacheAjaxResponse : true,                        // should we cache the data or make a new request each time
		isGallery         : false,                       // is the content a gallery carousel
		isVideo           : false,                       // is the content a video
		galleryTemplate   : ABV.GalleryCarouselTemplate, // Handlebars template for gallery content
		videoTemplate     : ABV.ModalVideoTemplate,      // Handlebars template for video
		customEventPrfx   : 'ABV:ModalWindow'            // name for modal events
	}, objOptions || {});

	/**
	 * UI elements
	 *
	 * @type {Object}
	 */
	this.ui = {
		document          : $(document),
		window            : $(window),
		body              : $('body'),
		triggers          : $trigger,
		curTrigger        : null,
		modal             : null,
		content           : null,
		closeButton       : null,
		overlay           : null,
		ariaHideElements  : null
	};

	/**
	 * Values specific to current modal window instance
	 */
	this.instance = {
		data              : objData,
		namespace         : null,  // dynamically created namespace for this instance
		getAjaxContent    : ABV.Utils.getAjaxContent,  // global ajax request utility
		cacheAjaxContent  : [],    // placeholder for caching ajax requests
		contentLoader     : null,  // placeholder for global loading icon utility
		imageGallery      : null,  // placeholder for gallery carousel widget
		videoItem         : null   // placeholder for video player
	};

	/**
	 * Widget states
	 *
	 * @type {Object}
	 */
	this.state = {
		isOpen            : false, // is the modal open
		isAjaxContent     : false, // is the content from an ajax request
		curIndex          : null,  // current index of the trigger element
		yPos              : null   // y pos of the modal
	};

	this._initialize();
};

ABV.ModalWindow.prototype = {
	/**
	 * Initializes the widget
	 */
	_initialize: function() {
		var self = this;

		// create overlay if it doesn't exist
		this.ui.overlay = $('#' + this.options.modalOverlayID);
		if (!this.ui.overlay.length) {
			this.ui.overlay = $('<div></div>',{
				'id': this.options.modalOverlayID
			}).appendTo(this.ui.body).hide().attr('tabindex', 0);
		}

		// create modal container if it doesn't exist
		this.ui.modal = $('#' + this.options.modalID);
		if (!this.ui.modal.length) {
			this.ui.modal = $('<div/>', {
				'id': this.options.modalID,
				'class': this.options.modalClass,
				'tabindex': '-1'
			}).insertBefore( this.ui.overlay )/*.hide()*/;
		}

		// non modal elements that need to be hidden from screen readers when modal is open
		this.ui.ariaHideElements = $( this.options.ariaHideElements );

		// set namespace for this instance of the modal window
		this.instance.namespace = Date.now();

		// set global loader utility
		this.instance.contentLoader = new ABV.Utils.Loader( this.ui.modal );

		// add event handlers to trigger elements
		if ( this.ui.triggers ) {
			this.addTriggerEvents();
		}
	},

	/**
	 * Add event handlers to trigger elements
	 */
	addTriggerEvents: function() {
		this.ui.triggers.on('click', $.proxy(this._onTriggerClick, this));
	},

	/**
	 * Remove event handlers on trigger elements
	 * (Used in GalleryWall when content for modal is dynamically updated)
	 */
	removeTriggerEvents: function() {
		this.ui.triggers.off('click');
	},

	/**
	 * Open modal and jump to carousel index
	 * (Used in GalleryWall when modal is dynamically created)
	 * @param  {Number} numIndex - index of carousel slide to start on
	 */
	openToGalleryIndex: function( numIndex ) {
		this.ui.curTrigger = $(this.ui.triggers[numIndex]);
		this.state.curIndex = numIndex;
		this._openModal();
	},

	/**
	 * Set the current trigger element and its index
	 * (Used to cache ajax content)
	 * Then open the modal
	 * @param  {Event} $event
	 */
	_onTriggerClick: function( $event ) {
		$event.preventDefault();

		this.ui.curTrigger = $( $event.currentTarget );

		this.state.curIndex = this.ui.triggers.index( this.ui.curTrigger );
		
		this._openModal();
	},

	/**
	 * Start all actions to open modal window
	 */
	_openModal: function() {
		this.ui.modal.attr( 'aria-hidden', 'false' );
		this.ui.ariaHideElements.attr( 'aria-hidden', 'true' );
		this._addEventHandlers();
		this._getContent();
	},

	/**
	 * Start all actions to close modal window
	 */
	_closeModal: function() {
		this.ui.modal.attr( 'aria-hidden', 'true' );
		this.ui.ariaHideElements.attr( 'aria-hidden', 'false' );
		this._removeEventHandlers();
		this._animateClose();
	},

	/**
	 * Add all modal interaction handlers, namespaced to this instance
	 */
	_addEventHandlers: function() {
		var self = this;

		this.ui.closeButton = $('<a />');
		this.ui.closeButton.addClass( this.options.closeBtnClass );
		this.ui.closeButton.attr('href', '#close');
		this.ui.closeButton.attr('title', this.options.closeBtnText );
		this.ui.closeButton.text( this.options.closeBtnText );
		this.ui.modal.prepend( this.ui.closeButton );
		this.ui.modal.on('click.' + this.instance.namespace, '.' + this.options.closeBtnClass, $.proxy(this._onCloseBtnClick, this));
		
		this.ui.overlay.on('click.' + this.instance.namespace, function() {
			if ( self.state.isOpen ) {
				self._closeModal();
			}
		});

		this.ui.window.on('keydown.' + this.instance.namespace, $.proxy(this._onWindowKeydown, this));
		this.ui.window.on('resize.'  + this.instance.namespace, $.proxy(this._onWindowResize, this));

		this.ui.document.on('focusin.' + this.instance.namespace, function( $event ) {
			// If modal is open and the focus leaves the modal
			if ( self.state.isOpen && !self.ui.modal.find( $($event.target) ).length ) {
				// Return focus to the close button
				self.ui.closeButton.focus();
			}
		});
	},

	/**
	 * Remove all modal interaction handlers attached to this instance
	 */
	_removeEventHandlers: function() {
		if ( this.options.isGallery ) {
			this.instance.imageGallery.kill();
		}
		this.ui.document.off('.' + this.instance.namespace);
		this.ui.window.off('.' + this.instance.namespace);
		this.ui.modal.off('.' + this.instance.namespace);
		this.ui.overlay.off('.' + this.instance.namespace);
	},

	/**
	 * Close popup when clicking close button
	 * @param  {Event} $event
	 */
	_onCloseBtnClick: function( $event ) {
		$event.preventDefault();

		this._closeModal();
	},

	/**
	 * Close popup on ESC key down
	 * @param  {Event} $event
	 */
	_onWindowKeydown: function( $event ) {
		if ( $event.keyCode === 27 && this.state.isOpen ) {
			this._closeModal();
		}
	},

	/**
	 * Center the popup and resize the overlay
	 * @param  {Event} $event
	 */
	_onWindowResize: function( $event ) {
		if ( this.state.isOpen ) {
			this._closeModal();
		}
	},

	/**
	 * Set the size and position of the modal window
	 */
	_setPosition: function() {

		var winWidth    = this.ui.window.width(),
			winHeight   = this.ui.window.height(),
			modalWidth  = this.ui.modal.outerWidth(true),
			modalHeight = this.ui.modal.outerHeight(true),
			height      = 'auto',
			position    = 'fixed',
			overflow    = '',
			xPos        = (winWidth - modalWidth) / 2;

		this.state.yPos = ((winHeight - modalHeight) / 2 );

		//console.log('winHeight:', winHeight, 'modalHeight:', modalHeight, 'this.state.yPos:', this.state.yPos);

		// If the modal is taller than window, set it to 100% height
		// overflow scroll added in css on modal content
		if ( this.state.yPos < 0 ) {
			this.state.yPos = 0;
			height = '100%';
			overflow = 'scroll';

			this.ui.closeButton.css({ top: 0 });
		} else {
			this.ui.closeButton.removeAttr('style');
		}

		this.ui.modal.css({
			height   : height,
			left     : xPos,
			position : position,
			top      : this.state.yPos,
			overflow : overflow
		});

		// Open modal if it's not already visibile
		if ( !this.state.isOpen ) {
			this._animateOpen();
		}
	},

	/**
	 * Fired from _setPosition
	 * Get the content that is either currently on the page or via ajax call
	 */
	_getContent: function() {
		var self = this,
			target;

		// If content is from ajax call
		if ( this.options.ajaxUrl || this.options.ajaxDataAttr ) {
			this.state.isAjaxContent = true;
			
			// Get the ajax url from either a data attr or url provided in options
			if ( this.options.ajaxUrl ) {
				target = this.options.ajaxUrl;
			} else {
				target = this.ui.curTrigger.data( this.options.ajaxDataAttr );
			}

			// If we haven't cached the ajax response, make the request
			if ( !this.instance.cacheAjaxContent[ this.state.curIndex ] ) {

				// Add a loader
				this.instance.contentLoader.addLoader();
				
				// Get the content
				$.when( this.instance.getAjaxContent( target, this.options.ajaxDataType )).done( function( response ) {
					
					// Remove loader
					self.instance.contentLoader.removeLoader();

					// If we're caching the response, do it
					if ( self.options.cacheAjaxResponse ) {
						self.instance.cacheAjaxContent[self.state.curIndex] = response;
					}

					// Display the content
					self._setContent( response );

				}).fail(function() {
					// If the call failed, remove the loader and show error message
					self.instance.contentLoader.removeLoader();
					self.ui.modal.html( self.options.ajaxErrorMsg );
				});
			}
			// If we have cached content, display it
			else {
				this._setContent( this.instance.cacheAjaxContent[ this.state.curIndex ] );
			}
		}
		// If content is provided in a JSON object on init
		else if ( this.instance.data ) {
			// Display the content
			this._setContent( this.instance.data );
		}
		// If content is hidden on the page, get it 
		else {
			target = $( this.ui.curTrigger.attr('href') );
			this._setContent( target );
		}
	},

	/**
	 * Fired from _getContent
	 * Display the content in the modal window 
	 * @param {Object or String}  content - jQuery element, HTML string or JSON object
	 */
	_setContent: function( content ) {

		// If content is from an ajax call or is a JSON gallery object
		if ( this.state.isAjaxContent || this.instance.data ) {

			// Create modal content container
			this.ui.content = $('<div/>', {
				'class': this.options.contentClass
			}).appendTo( this.ui.modal );

			//  If it is a JSON gallery object
			if ( this.options.isGallery ) {
				// Render the HTML using the Handlebars template
				var template  = Handlebars.compile( this.options.galleryTemplate ),
					html      = template({ items:content });

				this.ui.content.append( html ).css({'opacity': 0});

				// Instantiate the carousel
				this.instance.imageGallery = new ABV.Carousel( this.ui.content.find('.carousel'), {
					showSocialButtons: true,
					startIndex       : this.state.curIndex,
					onInitialize     : $.proxy(this._setPosition, this)
				});
			}
			//  If it is a JSON video object
			else if ( this.options.isVideo ) {
				
				// Render the HTML using the Handlebars template
				var template  = Handlebars.compile( this.options.videoTemplate ),
					html      = template( content );

				this.ui.content.append( html ).css({'opacity': 0});

				// Instantiate the video
				this.instance.videoItem = new ABV.VideoItem( this.ui.content.find('.video-container'), {
					// options
				});
				this._setPosition();
			}
			// Otherwise, append the html string
			else {
				this.ui.content.append( content ).css({'opacity': 0});
				this._setPosition();
			}
		}
		// Otherwise, render the jQuery element
		else {
			this.ui.content = content.clone().appendTo( this.ui.modal ).css({'opacity': 0});
			this._setPosition();
		}
	},

	/**
	 * Animation for opening modal window
	 */
	_animateOpen: function() {
		var self = this;

		// Fade in the overlay
		this.ui.overlay.fadeIn( this.options.animSpeed / 2 );

		// Fire custom event
		$.event.trigger(this.options.customEventPrfx + ':preOpenModal', [this.options.modalID]);

		// Set open bool
		this.state.isOpen = true;

		// Animate modal into view
		this.ui.modal.css({
			'display': 'block'
		});
		this.ui.modal.css({
			'top'    : this.state.yPos + 100
		}).animate({
			'top'    : this.state.yPos,
			'opacity': 1
		}, this.options.animSpeed, this.options.animEase, function() {

			// Set focus and fade in content 
			self.ui.modal.addClass( self.options.activeClass );
			self.ui.closeButton.focus();
			self.ui.content.delay( self.options.animSpeed ).animate({
				'opacity': 1
			}, self.options.animSpeed, self.options.animEase);

			// Fire custom event
			$.event.trigger(self.options.customEventPrfx + ':modalOpened', [self.options.modalID]);
		});
	},

	/**
	 * Animation for closing modal window
	 */
	_animateClose: function() {
		var self = this;

		// Fade out the overlay
		this.ui.overlay.fadeOut( this.options.animSpeed / 2 );

		// Animate modal out of view
		this.ui.modal.animate({
			'top'    : this.state.yPos + 100,
			'opacity': 0
		}, this.options.animSpeed, this.options.animEase, function() {
			
			// Reset position
			// self.ui.modal.css({
			// 	display  : 'none',
			// 	top      : self.state.yPos
			// });
			self.ui.modal.removeAttr('style');
			// Reset focus, remove content and fire custom event
			self.ui.modal.removeClass( self.options.activeClass );
			self.ui.curTrigger.focus();
			self.state.isOpen = false;

			self.ui.modal.empty();
			self.instance.imageGallery = null;

			$.event.trigger(self.options.customEventPrfx + ':preCloseModal', [self.options.modalID]);
		});
	}
};
/* VideoItem.js */

/**
 * Handlebars template for the modal video items
 * @type {String}
 */
ABV.ModalVideoTemplate = 
'	<div class="video-container"' +
'		data-poster="{{PosterImage}}"' +
'		data-url="{{URL}}"' +
'		data-mp4="{{MP4Path}}"' +
'		data-cc="{{ClosedCaptionUrl}}"' +
'		data-title="{{Title}}">' +
'		<div class="video-player">' +
'			<div class="player"></div>' +
'		</div>' +
'       <div class="offscreen controls">' +
'			<a class="play" href="#">play video</a>' +
'			<a class="pause" href="#">pause video</a>' +
'			<a class="stop" href="#">stop video</a>' +
'		</div>' +
'		<div class="video-caption">' +
'			<h3>{{Caption}}</h3>' +
'			<p>{{SubCaption}}</p>' +
'		</div>' +
'		<div class="video-transcript">' +
'			<p><a href="{{TranscriptUrl}}">read full transcript</a></p>' +
'		</div>' +
'	</div>';


ABV.VideoItem = function(target, options) {
	var self = this;

	this.elWrapper = $(target);

	this.options = {
		elPlayer         : '.player',
		elControls       : '.controls a',
		minFlashVersion  : '9.0.0',
		title            : this.elWrapper.data('title'),
		source           : this.elWrapper.data('url'),
		mp4Source        : this.elWrapper.data('mp4'),
		poster           : this.elWrapper.data('poster'),
		captions         : this.elWrapper.data('cc'),
		autoplay         : false,
		callback         : function() {
						     GlobalFlashVideoReady();
						   }
	};
	if(typeof options == 'object') {
		$.extend(this.options, options);
	}

	this.elFlashPlayerID = 'video-' + Date.now();
	this.elWrapper.find(this.options.elPlayer).attr('id', this.elFlashPlayerID);
	this.elControls = this.elWrapper.find( this.options.elControls );

	// keyboard navigation
	$(document).bind('keydown', function(e){
		// listen for ESC key
		if(e.keyCode === 27) {
			self.isFlash === true ? self.videoPlayer.stop() : self.videoPlayer.pause();
		}
	});

	this.init();
};
ABV.VideoItem.prototype = {
	init: function () {
		var self = this;

		if (swfobject.hasFlashPlayerVersion(this.options.minFlashVersion) /*&& ABV.Util.isMobile() !== true*/) {
			this.embedFlashPlayer();
		} else {
			this.embedHTML5Player();
		}

		this.elControls.unbind('click').bind('click', function (e) {
			e.preventDefault();
			var elBtn = $(this);
			//var btnID = elBtn.attr('id');

			if (elBtn.hasClass('play')) {
				self.videoPlayer.play();
			} else if (elBtn.hasClass('pause')) {
				self.videoPlayer.pause();
			} else if (elBtn.hasClass('stop')) {
				self.isFlash === true ? self.videoPlayer.stop() : self.videoPlayer.pause();
			}
		});
	},
	embedFlashPlayer: function () {
		var self = this;
		var timestamp = new Date().getTime(); // create a new timestamp so we can get around caching issues in IE
		var swfPath = "/assets/abv/swf/EverestDispatcher.swf" + "?" + timestamp;
		this.videoPlayer = new ABV.EverestVideoPlayer(this.elFlashPlayerID, "100%", "100%", swfPath, 'videoPlayer', this.options);
		this.isFlash = true;
	},
	embedHTML5Player: function (data) {
		var self = this;

		if (!data) {
			data = this.options;
		};

		data.PosterImage = (data.PosterImage)? data.PosterImage : data.poster;
		data.MP4Path = (data.MP4Path)? data.MP4Path : data.mp4Source;

		var html5Player = $('<video controls="controls" poster="' + data.PosterImage + '" autobuffer="autobuffer"><source src="' + data.mp4Source + '" type="video/mp4" />Sorry! Your browser can\'t play our HTML5 videos. Please enable Flash.</video>');

		this.elWrapper.find(this.options.elPlayer).append(html5Player);

		this.videoPlayer = html5Player[0];

		if (Modernizr.video) {
			this.videoPlayer.addEventListener('play', function(){
				// only track play events if user is just starting to watch video
				// give 1 second buffer since event usually takes a few ms to fire
				if (self.videoPlayer.currentTime < 1) {
					var title = GlobalTitleScrub(data.title);
					if ($(this).attr('data-played-title') !== title) {
						dataLayer.push({ 'event': 'videoPlay', 'videoTitle': title });
						$(this).attr('data-played-title', title);
					}
				}
			});
			this.videoPlayer.addEventListener('ended', function () {
				var title = GlobalTitleScrub(data.title);
				if ($(this).attr('data-completed-title') !== title) {
					dataLayer.push({ 'event': 'videoComplete', 'videoTitle': title });
					$(this).attr('data-completed-title', title);
				}
			});
			this.videoPlayer.load();
		}
		this.isFlash = false;
	}
};
function GlobalFlashVideoReady() {
	var player = GlobalFlashFindPlayer();
	player.addVideoPlayerEventListener('eventPlay', 'GlobalFlashVideoPlay');
	player.addVideoPlayerEventListener('eventPause', 'GlobalFlashVideoPause');
	player.addVideoPlayerEventListener('eventComplete', 'GlobalFlashVideoComplete');
}
function GlobalFlashVideoPlay() {
	var $player = $(GlobalFlashFindPlayer());
	var title = GlobalFlashFindTitle();

	if ($player.attr('data-played-title') !== title) {
		dataLayer.push({ 'event': 'videoPlay', 'videoTitle': title });
		$player.attr('data-played-title', title);
	}
}
function GlobalFlashVideoPause() {
}
function GlobalFlashVideoComplete() {
	var $player = $(GlobalFlashFindPlayer());
	var title = GlobalFlashFindTitle();

	if ($player.attr('data-completed-title') !== title) {
		dataLayer.push({ 'event': 'videoComplete', 'videoTitle': title });
		$player.attr('data-completed-title', title);
	}
}
function GlobalFlashFindPlayer() {
	var wrapper = $('.video-player.single')[0] || $('.video-player')[0]; // prefers modal over embedded
	return $(wrapper).find('object')[0];
}
function GlobalFlashFindTitle() {
	var $player = $(GlobalFlashFindPlayer());
	var title = 'undefined';

	// first, attempt to get from flash object param
	var flashvars = $player.find("[name='flashvars']").attr('value');
	if (flashvars) {
		var match = flashvars.match(/title=(.*?)&/);
		if (match) {
			title = match[1]; // sometimes yields string 'undefined'
		}
	}

	// second, attempt to get from first active thumbnail in carousel
	if (title === 'undefined') {
		title = $('.playlist-thumbs .active .video-title').first().text() || title;
	}

	return GlobalTitleScrub(title);
}
function GlobalTitleScrub(title) {
	// because GA does weird things to these 4 chars: ! * ) '
	return title.replace(/[!*)']/g, '-');
}

/* LoadMore.js */
var ABV = ABV || {};

/**
 * Load More Button
 * 
 * @description
 * - Display additional content items when clicking load more button.
 * 
 * - Option 1: (Article listing page - /App_/Templates/ArticleList.aspx)
 * -- Load items via ajax until no more are available.
 * -- Data returned is JSON array of html strings.
 * -- Each index in array is a child container.
 * -- JSON url is data attr on load more button (?ajax=true&page=X).
 * -- Initial page index to request is data attr on load more button (0 base index).
 * -- Page index gets updated & appended to url with each call.
 *
 * - Option 2: (News & Features page - /App_/Webparts/TwoColumnWithSidebar.ascx & /App_/Webparts/Sidebar/CategoryFilter.ascx)
 * -- Combined with LoadMoreFilter.js
 * -- Multiple Option 1 widgets are dynamically created based on presence of CategoryFilter webpart
 * -- Selecting a filter removes widget currently on the page and re-inits a new widget with updated options
 * 
 * - Option 3: (Various tile lists - /App_/Webparts/TwoColumnWithSidebar.ascx)
 * -- All items are on page load but only a fraction of the total are visible.
 * -- Number of times to load (and how many to initially show) is based on data attr on container (dataAttrTimes option)  
 * -- Load more can only be clicked X number of times to display remaining items.  (default is 2 based on option above)
 * 		
 * @requires jQuery
 * @requires jQuery imagesLoaded plugin
 * @requires Masonry
 * @requires ABV.Constants
 * @requires ABV.Utils
 * @requires ABV.LoadMoreFilter (when used with Option 2)
 * @requires ABV.Analytics (fire callback on load more button click)
 *
 * @example
 * new ABV.LoadMore($('.load-more-container'), {options})
 *
 * @constructor
 * @author      zake <zak.eddington@popagency.com>
 * @copyright   Copyright (c) 2015 Target Brands, Inc.
 *
 * @param {Object} $container - jQuery element for widget
 * @param {Object} objOptions - Optional object of properties to mixin to the instance
 */
ABV.LoadMore = function ( $container, objOptions ) {

	this.options = $.extend({
		dataCuratedItems     : null,                           // array of data items that already exist on init (curated tiles)
		getContentOnInit     : false,                          // should we get ajax content on init
		setFocusOnInit       : false,                          // should we set focus to first item on init (vs only when load more is clicked)
		isAjaxContent        : false,                          // is the content from ajax request
		dataBaseUrl          : null,                           // ajax url minus page index to request (used when creating widget dynamically)
		dataAttrUrl          : 'url',                          // name of data attr on button for ajax url
		dataAttrIndex        : 'page-index',                   // name of data attr on button for ajax page index to request
		dataAttrTimes        : 'load-times',                   // name of data attr on container for how many times to load static items
		maxRequests          : null,                           // max number of pages to load (null is infinite)
		classColumn          : 'column',                       // class of element(s) to append items
		selectorItem         : '.article-item',                // selector of content items
		selectorItemFocus    : '> a:first-child',              // selector of element within first new item to send focus
		selectorLoadContainer: '.btn-container',               // selector of load more button container
		selectorLoadButton   : '.btn-load-more',               // selector of load more button
		selectorLoadLabel    : '.label',                       // selector of load more button inner text element
		classItemsLoading    : 'loading',                      // class set for loading state
		animSpeed            : 400,                            // (ms) speed of animations
		masonryWidth         : [360, 227, 320],                // masonry item width [desktop, tablet, mobile]
		masonryGutter        : [20, 15, 0],                    // masonry gutter width [desktop, tablet, mobile]
		ajaxErrorMsg         : ABV.Constants.labels.ajaxError, // global string of html for ajax error messaging
		ajaxEndMsg           : ABV.Constants.labels.ajaxEnd,   // global string of html for ajax end messaging
		strButtonLabel       : ABV.Constants.labels.loadMore,  // global string of load more button default state
		strButtonLoading     : ABV.Constants.labels.loading    // global string of load more button loading state
	}, objOptions || {});

	this.constant = {
		dataUrl              : null,        // placeholder for ajax data url
		getAjaxContent       : ABV.Utils.getAjaxContent,  // global ajax request utility
		numTimesToLoad       : 2,           // placeholder (and fallback) for how many times to load more static content
		arrayStaticContent   : null,        // placeholder for static content references
		namespace            : null         // dynamically created namespace for this instance
	};

	this.state = {
		mergeInitContent     : false,
		userInteraction      : false,       // has user clicked the load more button
		pageIndex            : 0,           // page of results to request
		masonryWidth         : null,        // placeholder for current masonry width based on breakpoint
		masonryGutter        : null         // placeholder for current masonry gutter based on breakpoint
	};

	this.ui = {
		body                 : $('body'),
		container            : $container,  // container element
		loadContainer        : null,        // load more button container
		loadButton           : null,        // load more button
		loadLabel            : null         // load more button inner text element
	};

	this._initialize();
};

ABV.LoadMore.prototype = {

	_initialize: function() {
		// set namespace for this instance of the widget
		this.constant.namespace = Date.now();

		// Set element references
		this.ui.columns         = this.ui.container.find( '.' + this.options.classColumn );
		this.ui.loadContainer   = this.ui.container.find( this.options.selectorLoadContainer );

		// If load button exists, set element references
		if ( this.ui.loadContainer.length ) {
			this.ui.loadButton  = this.ui.loadContainer.find( this.options.selectorLoadButton );
			this.ui.loadLabel   = this.ui.loadButton.find( this.options.selectorLoadLabel );
		}
		// Otherwise, create the button
		else {
			this._createLoadButton();
		}

		// Set data url for ajax widget
		if ( this.options.isAjaxContent ) {

			// Use url defined in options if it exists (dynamically created widgets - News & Features)
			if ( this.options.dataBaseUrl ) {
				this.constant.dataUrl   = this.options.dataBaseUrl;
			}
			// Othewise, get url from data attr (single widget - Article Category Listing)
			else {
				this.constant.dataUrl   = this.ui.loadButton.data( this.options.dataAttrUrl );
				this.state.pageIndex    = this.ui.loadButton.data( this.options.dataAttrIndex );
			}
		}

		// Set the number of times to load static content
		if ( this.ui.container.data( this.options.dataAttrTimes ) ) {
			this.constant.numTimesToLoad = this.ui.container.data( this.options.dataAttrTimes );
		}

		this._addEventHandlers();

		// Should we set focus to first item on init (dynamically created widgets - News & Features)
		if ( this.options.setFocusOnInit ) {
			this.state.userInteraction = true;
		}

		// Setup ajax widget
		if ( this.options.isAjaxContent ) {
			this._setMasonryOptions();
			this._initMasonry();
		}
		// Otherwise, hide additional content until load more
		else {
			this._initStaticLayout();
		}
	},

	/**
	 * Create a load more button
	 */
	_createLoadButton: function() {
		var button = 
		'<div class="btn-container">' +
		'	<button class="btn-load-more">' +
		'		<span class="label">show me more</span><span class="icon"></span>' +
		'	</button>' +
		'</div>';

		this.ui.container.append( button );

		this.ui.loadContainer   = this.ui.container.find( this.options.selectorLoadContainer );
		this.ui.loadButton      = this.ui.loadContainer.find( this.options.selectorLoadButton );
		this.ui.loadLabel       = this.ui.loadButton.find( this.options.selectorLoadLabel );

		this.ui.loadButton.hide();
	},

	/**
	 * Bind events for this instance of the widget
	 */
	_addEventHandlers: function() {
		this._bindLoadButton();
		this.ui.body.on('breakpoint.'  + this.constant.namespace, $.proxy(this._onBreakpoint, this));
	},

	/**
	 * Perform tasks when the window breakpoint is triggered
	 */
	_onBreakpoint: function() {
		// Update the masonry column width
		if ( this.options.isAjaxContent ) {
			this._setMasonryOptions();
			this.ui.columns.masonry( 'option', { 
				columnWidth : this.state.masonryWidth,
				gutter      : this.state.masonryGutter
			});
		}
	},

	/**
	 * Remove event handlers on load more button
	 * Fired when no more items are available to load or widget is removed
	 */
	_unbindBreakpoint: function() {
		this.ui.body.off('.' + this.constant.namespace);
	},

	/**
	 * Add event handlers to load more button
	 * Fired on init
	 */
	_bindLoadButton: function() {
		this.ui.loadButton.on('click', $.proxy(this.__onLoadBtnClick, this));
	},
	/**
	 * Remove event handlers on load more button
	 * Fired when no more items are available to load or widget is removed
	 */
	_unbindLoadButton: function() {
		this.ui.loadButton.off('click');
	},

	/**
	 * Start all actions to load more content
	 * @param  {Event} $event]
	 */
	__onLoadBtnClick: function( $event ) {
		$event.preventDefault();

		// fire analytics callback
		ABV.Analytics.onLoadMoreButton();

		this.state.userInteraction = true;
		this._hideBtn();

		if ( this.options.isAjaxContent ) {
			this._getContent();
		} else {
			this._showStaticItems();
		}
	},

	/**
	 * Show the load more button
	 */
	_showBtn: function() {
		this.ui.loadButton.fadeIn().removeAttr('disabled').css('display', 'block');
		this.ui.loadLabel.text( this.options.strButtonLabel );
	},

	/**
	 * Hide the load more button and remove error message
	 */
	_hideBtn: function() {
		this.ui.loadButton.attr('disabled', 'disabled');
		this.ui.loadLabel.text( this.options.strButtonLoading );
		this.ui.loadContainer.find( $(this.options.ajaxErrorMsg) ).remove();
	},

	/**
	 * Remove the load more button and display end message
	 */
	_removeBtn: function() {
		var endMsg = $( this.options.ajaxEndMsg ).hide();

		this._unbindLoadButton();
		this.ui.loadButton.remove();

		this.ui.loadContainer.append( endMsg );
		endMsg.delay( this.options.animSpeed ).fadeIn();

		this.ui.container.removeClass( this.options.classItemsLoading );
	},

	/**
	 * Show error message on ajax request failure
	 */
	_showError: function() {
		var errorMsg = $( this.options.ajaxErrorMsg ).hide();

		this.ui.loadContainer.append( errorMsg );
		errorMsg.delay( this.options.animSpeed ).fadeIn();

		this.ui.container.removeClass( this.options.classItemsLoading );

		this._showBtn();
	},

	/**
	 * Set width for masonry based on breakpoint sizes in options
	 */
	_setMasonryOptions: function() {
		if ( ABV.Constants.breakpoint === 'desktop' ) {
			this.state.masonryWidth  = this.options.masonryWidth[0];
			this.state.masonryGutter = this.options.masonryGutter[0];
		}

		if ( ABV.Constants.breakpoint === 'tablet' ) {
			this.state.masonryWidth  = this.options.masonryWidth[1];
			this.state.masonryGutter = this.options.masonryGutter[1];
		}

		if ( ABV.Constants.breakpoint === 'mobile' ) {
			this.state.masonryWidth  = this.options.masonryWidth[2];
			this.state.masonryGutter = this.options.masonryGutter[2];
		}
	},

	/**
	 * Init the masonry layout for ajax content
	 */
	_initMasonry: function() {
		var duration = (this.options.animSpeed / 1000).toString();

		duration += 's';

		// disable animations for iOS
		if ( ABV.Constants.isIDevice ) {
			duration = 0;
		}

		// Preload images
		var imgLoad = imagesLoaded( this.ui.columns );

		// Hide broken images
		imgLoad.on('progress', function( instance, image ) {
			var result = image.isLoaded ? 'loaded' : 'broken';

			if ( result === 'broken' ) {
				$(image.img).hide();
			}
		});

		// Init masonry when images are loaded
		imgLoad.on('always', function( instance ) {
			this.ui.columns.masonry({
				columnWidth        : this.state.masonryWidth,
				gutter             : this.state.masonryGutter,
				itemSelector       : this.options.selectorItem,
				transitionDuration : duration
			});

			// Get content if none exists
			if ( this.options.getContentOnInit ) {
				this.state.mergeInitContent = true;
				this._getContent();
			}
		}.bind(this));
	},

	/**
	 * Fire ajax request for more content
	 */
	_getContent: function() {
		var self     = this,
			dataUrl  = this.constant.dataUrl;

		this.ui.container.addClass( this.options.classItemsLoading );

		// If we have a ajax url, get the content
		if ( dataUrl ) {

			// Append the page index query parameter to the request url
			dataUrl += this.state.pageIndex;

			// Update page number to request for the next call
			this.state.pageIndex++;

			// Get the content
			$.when( this.constant.getAjaxContent( dataUrl, 'json' )).done( function( response ) {
				self._processData( response );
			}).fail(function() {
				self._showError();
			});
		}
		// Otherwise, show the error message
		else {
			this._showError();
		}
	},

	/**
	 * Group data based on which column they get appended to
	 * @param  {Object} objData - ajax response data
	 */
	_processData: function( objData ) {
		var data = objData,
			arrayContent = [];

		// If we have data for curated items and this is the initial load
		if ( this.options.dataCuratedItems && this.state.mergeInitContent ) {
			// Merge curated content into local array 
			arrayContent = arrayContent.concat( this.options.dataCuratedItems );
			this.state.mergeInitContent = false;
		}

		// If we've reached the end of the content available, remove the load more button
		if ( data[0].length === 0 ) {
			this._removeBtn();
		} 
		// Otherwise, merge data into local array
		else {
			// Loop through each set of data and render the content
			for ( var i = 0, len = data.length; i < len; i++ ) {

				var $html  = $( data[i] ),
					$items = $html.filter( this.options.selectorItem ).addClass( this.options.classItemsLoading ),
					items  = $items.toArray();

				// Merge response data into local array
				arrayContent = arrayContent.concat( items );
			}
			// Display the items
			this._render( arrayContent );
		}
	},

	/**
	 * Display the new content
	 * @param  {Array} arrayContent - array of items to display
	 */
	_render: function( arrayContent ) {
		var data = arrayContent;

		// Convert array to jQuery elements
		var $items     = $(data).filter( this.options.selectorItem ).addClass( this.options.classItemsLoading ),
			$firstItem = $items.first();

		// Append the items
		this.ui.columns.append( $items );

		// Preload images
		var imgLoad = imagesLoaded( $items );

		// Hide broken images
		imgLoad.on('progress', function( instance, image ) {
			var result = image.isLoaded ? 'loaded' : 'broken';

			if ( result === 'broken' ) {
				$(image.img).hide();
			}
		});

		// Display content using masonry when images are loaded
		imgLoad.on('always', function( instance ) {
			$items.removeClass( this.options.classItemsLoading );

			this.ui.columns.masonry('appended', $items);

			// Set focus to first new item added
			if ( this.state.userInteraction ) {
				$firstItem.find( this.options.selectorItemFocus ).focus();
			}

			this._showBtn();
			this.ui.container.removeClass( this.options.classItemsLoading );
		}.bind(this));
	},

	/**
	 * Find all static content and put them in grouped arrays based on num of times to load more
	 * as well as how many columns they are in 
	 */
	_initStaticLayout: function() {
		var numCols    = this.ui.columns.length,
			$colItems  = this.ui.columns.eq(0).find( this.options.selectorItem ),
			numItems   = $colItems.length,
			numGroups  = this.constant.numTimesToLoad + 1,
			numInGroup = Math.ceil( numItems / numGroups);

		this.constant.arrayStaticContent = [];

		// Loop through each column
		for ( var i = 0, len = numCols; i < len; i++ ) {

			// Create arrays for each column
			this.constant.arrayStaticContent.push([]);

			// Find items in it
			var $curColItems = this.ui.columns.eq(i).find( this.options.selectorItem );

			// Loop through num of groups in a column
			for ( var j = 0, jlen = numGroups; j < jlen; j++ ) {

				// Create arrays for each group
				this.constant.arrayStaticContent[i].push([]);

				// Loop through each item in the column
				for ( var k = 0, klen = numItems; k < klen; k++ ) {

					var $curItem = this.ui.columns.eq(i).find( this.options.selectorItem ).eq(k);

					// Push items into grouped arrays and hide items not in first group
					if ( k >= numInGroup * j && k <= (numInGroup * j) + numInGroup - 1 ) {

						this.constant.arrayStaticContent[i][j].push( $curItem );

						if ( k >= numInGroup ) {
							$curItem.hide();
						}
					}
				}
			}
		}
	},

	/**
	 * Display the static items
	 */
	_showStaticItems: function() {
		var targetGroup = this.state.pageIndex + 1,
			maxGroups   = this.constant.numTimesToLoad + 1;

		// If we have more groups to load, display them
		if ( targetGroup < maxGroups ) {

			// Loop through each column
			for ( var i = 0, len = this.constant.arrayStaticContent.length; i < len; i ++ ) {

				// Loop through each group
				for ( var j = 0; j < maxGroups; j++ ) {

					// Find the current group to show
					if ( j === targetGroup ) {
						
						// Display each item in the group
						for ( var k = 0, klen = this.constant.arrayStaticContent[i][j].length; k < klen; k++ ) {
							this.constant.arrayStaticContent[i][j][k].fadeIn();

							// Set focus to first item in first group
							if ( i === 0 && j === targetGroup && k === 0 ) {
								this.constant.arrayStaticContent[i][j][k].find( this.options.selectorItemFocus ).focus();
							}
						}
					}
				}
			}

			// If we've reached the max times to load more, remove the button
			if ( targetGroup === maxGroups - 1 ) {
				this._removeBtn();
			} 
			// Otherwise, show it again
			else {
				this._showBtn();
			}
		}

		this.state.pageIndex++;
	},

	/**
	 * Remove all content, load button and events
	 */
	kill: function() {
		this._unbindLoadButton();
		this._unbindBreakpoint();
		this.ui.loadContainer.remove();
		this.ui.columns.remove();
	}
};
/* LoadMoreFilter.js */
var ABV = ABV || {};

/**
 * Load More Filter
 * 
 * @description
 * - Create ABV.LoadMore ajax content widgets based on filter selections.
 * - Default filter on page load has curated items as well as dynamic items.
 * - On init, we grab those items from the dom, cache them and pass them to the LoadMore widget.
 * - That widget takes over to fetch and display the content until new filter is selected.
 * - Selecting a different filter, removes current LoadMore widget/content and inits new version with updated options.
 * - Selecting default filter again, repeats the process but also passes the cached curated items to the new LoadMore widget.
 * - JSON url is combination of href and query params defined in constant.dataUrl and passed to LoadMore widget.
 * 		
 * @requires ABV.LoadMore
 * @requires jQuery
 *
 * @example
 * new ABV.LoadMore($('.load-more-container'), {options})
 *
 * @constructor
 * @author      zake <zak.eddington@popagency.com>
 * @copyright   Copyright (c) 2015 Target Brands, Inc.
 *
 * @param {Object} $container - jQuery element for widget
 * @param {Object} objOptions - Optional object of properties to mixin to the instance
 */
ABV.LoadMoreFilter = function ( $container, objOptions ) {

	this.options = $.extend({
		selectorTriggers     : 'a',                 // selector of filter triggers
		selectorTarget       : '.primary',          // selector of element to create load more widgets within
		classTarget          : 'load-more-filter',  // class to add on target container element
		classColumn          : 'column',            // class of element(s) to append items
		selectorItem         : '.article-item',     // selector of content items
		classActive          : 'active',            // class set for active state
		createSkipLink       : true,                // should we create a skip to category link
		elSkipLink           : '<a href="#category-filter" class="skip-link filter-jump">Skip to category filters</a>'
	}, objOptions || {});

	this.constant = {
		dataUrl              : '?ajax=true&page=',  // placeholder for ajax data url query params
		content              : null,                // placeholder for load more widget
		curatedContent       : []                   // placeholder for curated tiles on page load
	};

	this.state = {
		curTrigger           : null,        // placeholder for current trigger element
		baseUrl              : null,        // placeholder for current trigger href
		showCuratedContent   : true         // does the active filter have curated content
	};

	this.ui = {
		container            : $container,  // container element of triggers
		triggers             : null,        // filter triggers
		target               : null,        // content container
		columns              : null,        // element(s) in the target container that items are appended to 
		skipLink             : null         // placeholder for skip to category link
	};

	this._initialize();
};

ABV.LoadMoreFilter.prototype = {

	_initialize: function() {

		// Set element references
		this.ui.triggers = this.ui.container.find( this.options.selectorTriggers );
		this.ui.target   = $( this.options.selectorTarget ).addClass( this.options.classTarget );
		this.ui.columns  = this.ui.target.find( '.' + this.options.classColumn );

		// Create a skip to category filter link
		// Functionality is handled in Application.js when all skip link events are added
		if ( this.options.createSkipLink ) {
			var skip = $( this.options.elSkipLink );
			this.ui.target.prepend( skip );
			this.ui.skipLink = skip; 
		}

		this._addEventListeners();

		// Set current trigger to the first filter and get content
		this.state.curTrigger = this.ui.triggers.first();
		this.state.baseUrl    = this.state.curTrigger.attr('href');

		this._getCuratedTiles();
	},

	/**
	 * Initial page view can have curated content on page load
	 * Cache those elements and then get more content
	 */
	_getCuratedTiles: function() {		
		// Loop through columns
		for ( var i = 0, len = this.ui.columns.length; i < len; i++ ) {
			
			// Create an array of items in each column
			var $items = this.ui.columns.eq(i).find( this.options.selectorItem ),
				items  = $items.toArray();

			// Merge all items into a single array
			this.constant.curatedContent = this.constant.curatedContent.concat( items );
		}
		// Get more content
		this._updateLayout( false );
	},

	/**
	 * Update active states and get new content
	 * @param {Boolean} setFocus - added _onTriggerClick to send focus to new content 
	 */
	_updateLayout: function( setFocus ) {
		this.ui.triggers.removeClass( this.options.classActive );
		this.state.curTrigger.addClass( this.options.classActive );

		this._removeContent();
		this._getContent( setFocus );
	},

	/**
	 * Update the active states and replace content with a new load more widget
	 * @param  {Event} $event
	 */
	_onTriggerClick: function( $event ) {
		$event.preventDefault();
		
		// If filter is not already selected
		if ( !$($event.currentTarget).hasClass( this.options.classActive ) ) {
			
			// Update the trigger reference and ajax url
			this.state.curTrigger = $($event.currentTarget);
			this.state.baseUrl    = this.state.curTrigger.attr('href');

			// Update boolean for showing curated content
			if ( this.state.curTrigger.is( this.ui.triggers.first() ) ) {
				this.state.showCuratedContent = true;
			} else {
				this.state.showCuratedContent = false;
			}

			// Get more content and send focus to first item
			this._updateLayout( true );
		}
	},

	/**
	 * Remove the current content and load more widget
	 */
	_removeContent: function() {

		// Remove elements from the page
		this.ui.columns.remove();

		// Create a new empty column
		var $newColumn = $('<div class="' + this.options.classColumn + '" />');

		if ( this.options.createSkipLink ) {
			this.ui.skipLink.after( $newColumn );
		} else {
			this.ui.target.prepend( $newColumn );
		}

		// Remove load more widget
		if ( this.constant.content ) {
			this.constant.content.kill();
		}
	},

	/**
	 * Create new load more widget with the content of the selected filter
	 * @param {Boolean} setFocus - added _onTriggerClick to send focus to new content 
	 */
	_getContent: function( setFocus ) {
		// If we should send focus to first item pass that to the load more widget
		if ( setFocus ) {
			var focus = true;
		} else {
			var focus = false;
		}

		// If we have curated content pass that to the load more widget
		if ( this.state.showCuratedContent ) {
			var data = this.constant.curatedContent;
		} else {
			var data = null;
		}

		// Create new load more widget with appropriate options
		this.constant.content = new ABV.LoadMore( this.ui.target, {
			dataCuratedItems : data,
			getContentOnInit : true,
			setFocusOnInit   : focus,
			isAjaxContent    : true,
			dataBaseUrl      : this.state.baseUrl + this.constant.dataUrl
		});
	},

	/**
	 * Event listeners
	 */
	_addEventListeners: function() {
		this.ui.triggers.on('click', $.proxy(this._onTriggerClick, this));
	}
};
/* ReportBuilder.js */
var ABV = ABV || {};

/**
 * Report Builder
 * 
 * @description
 * - Build a custom PDF from individual sections
 * - Adds frontend functionality and analytics to backend ReportBuilder webpart
 * 		
 * @requires jQuery
 * @requires ABV.Analytics
 *
 * @example
 * new ABV.ReportBuilder( $('.report-builder'), {options} );
 *
 * @constructor
 * @author      zake <zak.eddington@popagency.com>
 * @copyright   Copyright (c) 2015 Target Brands, Inc.
 */

ABV.ReportBuilder = function( $container, $objOptions ) {
	
	/**
	 * Default configuration for component
	 */
	this.options = $.extend({
		analyticsTitle       : 'crr:',                       // name for this report used in analytics tracking 
		classDisabled        : 'disabled',                   // class set for disabled state
		selectorLabels       : 'label',                      // selector of checkbox labels
		selectorCheckboxes   : 'input[type=checkbox]',       // selector of section checkboxes
		selectorBtnCustom    : '.btn-report-custom',         // selector of custom report download button
		selectorBtnFull      : '.btn-report-full',           // selector of full report download button
		selectorBtnLabel     : '.offscreen',                 // accessibility label for buttons
		btnTitle             : 'link opens in a new window', // offscreen text of active state of button
		btnTitleDisabled     : 'link is currently disabled'  // offscreen text of disabled state of button
	}, $objOptions || {});

	this.ui = {
		reportBuilder        : $container,
		btnCustom            : null,
		btnFull              : null,
		checkboxes           : null,
		labels               : null
	},

	/**
	 * Values specific to current report builder
	 */
	this.instance = {
		url                  : null,  // base url of custom report download button
		numCheckboxes        : 0,
	},

	this.state = {
		values               : [],   // placeholder for selected checkbox values
		labels               : []    // placeholder for selected checkbox labels
	},

	this._initialize();
};


ABV.ReportBuilder.prototype = {

	/**
	 * Initialize the report builder
	 */
	_initialize: function() {

		// el refs
		this.ui.labels      = this.ui.reportBuilder.find( this.options.selectorLabels );
		this.ui.checkboxes  = this.ui.reportBuilder.find( this.options.selectorCheckboxes );
		this.ui.btnCustom   = this.ui.reportBuilder.find( this.options.selectorBtnCustom );
		this.ui.btnFull     = this.ui.reportBuilder.find( this.options.selectorBtnFull );

		this.instance.url            = this.ui.btnCustom.attr('href');
		this.instance.numCheckboxes  = this.ui.checkboxes.length;

		this._addEventListeners();

		this._updateBuilder();
	},

	/**
	 * Create arrays of selected checkbox values/labels
	 * Update download button display and url
	 */
	_updateBuilder: function() {
		var $checkbox,
			$label;

		// Reset arrays
		this.state.values = [];
		this.state.labels = [];

		// Push values/labels of selected checkboxes into arrays
		for ( var i = 0; i < this.instance.numCheckboxes; i++ ) {
			$checkbox = this.ui.checkboxes.eq(i);
			$label    = this.ui.labels.eq(i);

			if ( $checkbox.is(':checked') ) {
				this.state.values.push( $checkbox.val() );
				this.state.labels.push( $label.text() );
			}
		}

		// If checkboxes are selected, enable button and update url
		if ( this.state.values.length ) {
			this.ui.btnCustom.removeClass( this.options.classDisabled );
			this.ui.btnCustom.find( this.options.selectorBtnLabel ).text( this.options.btnTitle );
			this.ui.btnCustom.attr({ 'href': this.instance.url + this.state.values.join('-') });
		}
		// Otherwise, disable it
		else {
			this.ui.btnCustom.addClass( this.options.classDisabled );
			this.ui.btnCustom.find( this.options.selectorBtnLabel ).text( this.options.btnTitleDisabled );
			this.ui.btnCustom.attr({ 'href': '#' });
		}
	},

	// Fire ABV.Analytics call for the custom report button
	_downloadCustom: function( $event ) {
		var labels = this.options.analyticsTitle;

		if ( this.ui.btnCustom.hasClass( this.options.classDisabled ) ) {
			$event.preventDefault();
		} else {
			for ( var i = 0; i < this.state.labels.length; i++ ) {
				labels += ' | ' + this.state.labels[i];
			}
			ABV.Analytics.onReportBuilderDownload( labels );
		}
	},

	// Fire ABV.Analytics call for the full report button
	_downloadFull: function() {
		ABV.Analytics.onReportBuilderDownload( this.options.analyticsTitle + ' full report' );
	},

	/**
	 * Event Listeners
	 */
	_addEventListeners: function() {

		this.ui.checkboxes.on('click', $.proxy(this._updateBuilder, this));
		this.ui.btnCustom.on('click',  $.proxy(this._downloadCustom, this));
		this.ui.btnFull.on('click',    $.proxy(this._downloadFull, this));
	}
};
/* Application.js */
var ABV = ABV || {};

/**
 * @module      Application
 * @description Defines the application and instantiates views and widgets (excluding header & footer which is in abv-chrome)
 * 
 * @requires jQuery
 * 
 * @author      zake <zak.eddington@popagency.com>
 * @copyright   Copyright (c) 2015 Target Brands, Inc.
 */

/**
 * @constructor
 * @alias       module:Application
 */
ABV.Application = {

	/* PUBLIC METHODS */

	/**
	 * Initializes the application
	 */
	init: function () {
		// Register Custom Handlebars Helpers
		new HandlebarsHelpers();

		this._initCarousels();

		this._initAccordions();

		this._initTabSwitchers();

		this._initModals();

		this._initLoadMore();

		this._initInlineVideos();

		this._initPinElement();

		this._initFormValidation();

		this._initFormSubmit();

		this._initFBCommentsTrigger();

		this._initReportBuilder();

		this._addEventListeners();

		ABV.Analytics.init();
	},


	/* PRIVATE METHODS */

	/**
	 * General init of carousels
	 */
	_initCarousels: function() {
		if ( $('.carousel').length ) {
			$('.carousel').each( function() {
				var carousel;
				
				if ( $(this).parents().hasClass('carousel-multi-col') ) {
					carousel = new ABV.Carousel( $(this), {
						numVisiblePanels       : 3,
						numVisiblePanelsTablet : 2,
						numVisiblePanelsMobile : 1,
						maxHeight              : 'tallest',
						maxHeightMobile        : 1
					});
				} else if ( $(this).parents().hasClass('carousel-with-desc') ) {
					carousel = new ABV.Carousel( $(this), {
						maxHeight       : 'tallest',
						maxHeightMobile : 1
					});
				} else {
					carousel = new ABV.Carousel( $(this), {
						maxHeight       : 'landscape',
						maxHeightMobile : 1
					});
				}
			});
		}
	},

	/**
	 * General init of accordions
	 */
	_initAccordions: function() {
		if ( $('.accordion').length ) {
			$('.accordion').each( function() {
				var accordion;

				if ( $(this).hasClass('wide-option') ) {
					accordion = new ABV.Accordion( $(this), {
						wideOption: true
					});
				} else {
					accordion = new ABV.Accordion( $(this), {
						// options
					});
				}
			});
		}
	},

	/**
	 * General init of tab switchers
	 */
	_initTabSwitchers: function() {
		if ( $('.tab-switcher').length ) {
			$('.tab-switcher').each( function() {
				var tabSwitcher = new ABV.TabSwitcher( $(this), {
						// options
					});
			});
		}
	},

	/**
	 * General init of modal windows
	 */
	_initModals: function() {
		// Image gallery carousel (not in a gallery wall)
		if ($('.modal-gallery-trigger').length) {
			$('.modal-gallery-trigger').each( function() {
				var gallery = new ABV.ModalWindow( $(this), {
						isGallery    : true,
						ajaxDataAttr : 'url',
						ajaxDataType : 'json'
					});
			});
		}
		
		// Ajax html content
		if ($('.modal-ajax-trigger').length) {
			$('.modal-ajax-trigger').each( function() {
				var ajax = new ABV.ModalWindow( $(this), {
						ajaxDataAttr : 'url',
						ajaxDataType : 'html'
					});
			});
		}
		
		// Ajax html content
		if ($('.modal-video-trigger').length) {
			$('.modal-video-trigger').each( function() {
				var video = new ABV.ModalWindow( $(this), {
						isVideo      : true,
						ajaxDataAttr : 'url',
						ajaxDataType : 'json'
					});
			});
		}
		
		// Standard modal of hidden content on the page
		if ($('.modal-trigger').length) {
			$('.modal-trigger').each( function() {
				var modal = new ABV.ModalWindow( $(this), {
						// options
					});
			});
		}
	},

	/**
	 * General init of inline videos
	 */
	_initInlineVideos: function() {
		// Video items
		if ($('#main-content .video-container').length) {
			$('#main-content .video-container').each( function() {
				var video = new ABV.VideoItem( $(this), {
						// options
					});
			});
		}
	},

	/**
	 * General init of modal videos
	 * Fired on resize end so we can make videos "responsive" by re-embedding them
	 */
	_initModalVideos: function() {
		// Video items
		if ($('.modal-window .video-container').length) {
			$('.modal-window .video-container').each( function() {
				var modalVideo = new ABV.VideoItem( $(this), {
					// options
				} );
			});
		}
	},

	/**
	 * Remove inline videos
	 * Fired on breakpoint change so we can make videos "responsive" by re-embedding them
	 */
	_removeInlineVideos: function() {
		if ($('.video-container').length) {
			$('.video-container').each( function() {
				var $videoPlayer = $(this).find('.video-player').empty();
				
				$videoPlayer.append('<div class="player"></div>');
			});
		}
	},

	/**
	 * Remove modal videos
	 * Fired on resize end so we can make videos "responsive" by re-embedding them
	 */
	_removeModalVideos: function() {
		if ($('.modal-window .video-container').length) {
			$('.modal-window .video-container').each( function() {
				var $modalVideoPlayer = $(this).find('.video-player').empty();
				
				$modalVideoPlayer.append('<div class="player"></div>');
			});
		}
	},

	/**
	 * Pin element below main nav
	 * (Article detail page title)
	 */
	_initPinElement: function() {
		if ( $('#sticky-title').length ) {
			var pin = new ABV.PinElement( $('#sticky-title'), {
				// options
			});
		}
	},

	/**
	 * General init of load more content sections
	 */
	_initLoadMore: function() {

		// Social media widgets
		if ($('.social-wall').length) {
			$('.social-wall').each( function() {
				var socialWall = new ABV.SocialWall( $(this), {
					// options
				});
			});
		}

		// Gallery page
		if ($('.gallery-wall').length) {	
			$('.gallery-wall').each( function() {
				var galleryWall = new ABV.GalleryWall( $(this), {
					// options
				});
			});
		}

		// General content sections:

		// All items are on page but only half of the total are visible
		// This can be overridden using numTimesToLoad option
		if ( $('.load-more-static').length ) {
			$('.load-more-static').each( function() {
				var loadMore = new ABV.LoadMore( $('.load-more-static'), {
					// options
				});
			});
		}

		// Subsequent items are loaded via ajax requests until no more are available
		if ( $('.load-more-ajax').length ) {
			$('.load-more-ajax').each( function() {
				var loadMore = new ABV.LoadMore( $('.load-more-ajax'), {
					isAjaxContent: true
				});
			});
		}

		// Multiple ajax widgets controlled by filters (News & Features page)
		if ( $('#category-filter').length ) {

			// If we're in CMS edit mode, don't load the widget
			if ( $('#category-filter').parents('.EditorWidgets').length ) {
				// Also, hide right column so CMS order is less confusing
				$('.primary .column:last-child').hide();
			}
			// Othewise, load the widget
			else {
				var filter = new ABV.LoadMoreFilter( $('#category-filter'), {
					// options
				});
			}
		}
	},

	/**
	 * Manually trigger form submit on enter key for IE8
	 */
	_initFormSubmit: function() {
		if ( ABV.Constants.isIE8 ) {
			var $form = $('.abv-form');

			// e.g. Join our Team on /careers
			if ( $form.length ) {
				$form.on('keydown', function( $event ) {
					if ( $event.type === 'keydown' && $event.keyCode === 13 ) {
						$event.preventDefault();
						$form.find('input[type="submit"]').click();
					}
				});
			}
		}
	},

	/**
	 * General init of forms that need front end validation 
	 */
	_initFormValidation: function() {
		// Add custom email validation rule (must contain min of x@x.xx)
		$.validator.addMethod("customemail", 
		    function(value, element) {
		        return /^([\w-\.]+@([\w-]+\.)+[\w-]{2,4})?$/.test(value);
		    }, 
		    "Please enter a valid email address."
		);

		// /subscription
		if ( $('#form-email-signup').length ) {
			$('#form-email-signup').validate({
				rules: {
					// add custom validation to element with name="EMAIL"
	                EMAIL: {
	                    customemail: true
	                }
	            },
				errorPlacement: function(error, element) {
					if ( element.parent().hasClass('checkbox-area') ) {
						error.insertAfter( element.next('label') );
					} else {
						error.insertAfter( element );
					}
				}
			});
		}
	},

	/**
	 * Perform tasks when the window resize end is triggered
	 */
	_onResizeEnd: function() {
		this._removeModalVideos();
		this._initModalVideos();
	},

	/**
	 * Perform tasks when the window breakpoint is triggered
	 */
	_onPageBreakpoint: function() {
		this._removeInlineVideos();
		this._initInlineVideos();
	},

	/**
	 * Show/Hide jump link to facebook comments in iOS
	 */
	_initFBCommentsTrigger: function() {
		var $jumpLink = $('.fb-comments-jump'),    // offscreen jump link for iOS
			$title    = $('.fb-comments-title'); // default offscreen title when not in iOS

		if ( ABV.Constants.isIDevice ) {
			$jumpLink.addClass('visible');
			$title.addClass('hidden');
		} else {
			$jumpLink.addClass('hidden');
			$title.addClass('visible');
		}
	},

	/**
	 * General init of report builder
	 */
	_initReportBuilder: function() {
		if ( $('.report-builder').length ) {
			$('.report-builder').each( function() {
				var builder = new ABV.ReportBuilder( $(this), {
						// options
					});
			});
		}
	},

	/**
	 * Functionality for single offscreen skip links within the content
	 * (NOT the nav.skip-links at top of page which is handled in abv-chrome NavigationView.js)
	 * Show skip to content links on focus
	 * Jump to element when selected
	 * @param  {Event} $event
	 */
	_onSkipLink: function( $event ) {
		var $curTarget = $( $event.currentTarget );
				
		if ( $event.type === 'focus') {
			$curTarget.css({ 'left': 0, 'top': 0 }); 
		}
		if ( $event.type === 'blur') { 
			$curTarget.removeAttr('style');
		}
		if ( $event.type === 'click') {
			$event.preventDefault();

			// On the News & Features page, 
			// Skip to first category filter
			if ( $curTarget.hasClass('filter-jump') ) {
				$( $curTarget.attr('href') ).find('a').first().focus();
			}
			// On Article detail page, 
			// Bug fix for iOS voice over skipping facebook comments iframe
			// Set focus to iframe when user clicks jump link
			// Note: another bug is if the iframe is in view it won't accept focus
			// so the skip link is set to top of article content so page scrolls iframe out of view
			else if ( $curTarget.hasClass('fb-comments-jump') && ABV.Constants.isIDevice ) {
				var $iframe = $('.facebook-comments iframe');
				$iframe.focus();
			}
			// Otherwise, just go to the href target
			else {
				$( $curTarget.attr('href') ).focus();
			}
		}
	},

	_onBackTopLink: function( $event ) {
		$event.preventDefault();

		var $curTarget   = $( $event.currentTarget ),
			$focusTarget = $( $curTarget.attr('href') ),
			scrollYPos   = 0;

		if ( $focusTarget.length ) {
			scrollYPos = $focusTarget.offset().top - 70; // account for pinned nav
		}

		$('html,body').animate({ 
			scrollTop: scrollYPos 
		}, 400, 'swing');
	},

	/**
	 * Event Listeners
	 */
	_addEventListeners: function() {
		// Add global pseudo resize and scroll end events
		ABV.Utils.resizeEndEvent();
		ABV.Utils.scrollEndEvent();
		$(window).on('resizeEnd', $.proxy(this._onResizeEnd, this) );

		$('body').on('breakpoint', $.proxy(this._onPageBreakpoint, this) );

		$('a.skip-link').on('focus blur click', $.proxy(this._onSkipLink, this) );

		$('a.btn-back-top').on('click', $.proxy(this._onBackTopLink, this) );
	}
};
/* abv.js */
/**
 * @namespace   ABV
 * @description Global namespace for the A Bullseye View application
 * 
 * @global
 * @author      zake <zak.eddington@popagency.com>
 * @copyright   Copyright (c) 2015 Target Brands, Inc.
 */
var ABV = ABV || {};

/**
 * @module      ABV Application
 * @description Initializes the app for all content (excluding header & footer which is in abv-chrome)
 *
 * @requires    jQuery
 * 
 * @author      zake <zak.eddington@popagency.com>
 * @copyright   Copyright (c) 2015 Target Brands, Inc.
 */
$(document).ready( function() {
	// Initialize Application
	ABV.Application.init();
});
