2 * Materialize v0.97.0 (http://materializecss.com)
3 * Copyright 2014-2015 Materialize
4 * MIT License (https://raw.githubusercontent.com/Dogfalo/materialize/master/LICENSE)
7 * jQuery Easing v1.3 - http://gsgd.co.uk/sandbox/jquery/easing/
9 * Uses the built in easing capabilities added In jQuery 1.1
10 * to offer multiple easing options
12 * TERMS OF USE - jQuery Easing
14 * Open source under the BSD License.
16 * Copyright © 2008 George McGinley Smith
17 * All rights reserved.
19 * Redistribution and use in source and binary forms, with or without modification,
20 * are permitted provided that the following conditions are met:
22 * Redistributions of source code must retain the above copyright notice, this list of
23 * conditions and the following disclaimer.
24 * Redistributions in binary form must reproduce the above copyright notice, this list
25 * of conditions and the following disclaimer in the documentation and/or other materials
26 * provided with the distribution.
28 * Neither the name of the author nor the names of contributors may be used to endorse
29 * or promote products derived from this software without specific prior written permission.
31 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
32 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
33 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
34 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
35 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
36 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
37 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
38 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
39 * OF THE POSSIBILITY OF SUCH DAMAGE.
43 // t: current time, b: begInnIng value, c: change In value, d: duration
44 jQuery
.easing
['jswing'] = jQuery
.easing
['swing'];
46 jQuery
.extend( jQuery
.easing
,
49 swing: function (x
, t
, b
, c
, d
) {
50 //alert(jQuery.easing.default);
51 return jQuery
.easing
[jQuery
.easing
.def
](x
, t
, b
, c
, d
);
53 easeInQuad: function (x
, t
, b
, c
, d
) {
54 return c
*(t
/=d
)*t
+ b
;
56 easeOutQuad: function (x
, t
, b
, c
, d
) {
57 return -c
*(t
/=d
)*(t
-2) + b
;
59 easeInOutQuad: function (x
, t
, b
, c
, d
) {
60 if ((t
/=d/2) < 1) return c
/2*t
*t
+ b
;
61 return -c
/2 * ((--t
)*(t
-2) - 1) + b
;
63 easeInCubic: function (x
, t
, b
, c
, d
) {
64 return c
*(t
/=d
)*t
*t
+ b
;
66 easeOutCubic: function (x
, t
, b
, c
, d
) {
67 return c
*((t
=t
/d
-1)*t
*t
+ 1) + b
;
69 easeInOutCubic: function (x
, t
, b
, c
, d
) {
70 if ((t
/=d/2) < 1) return c
/2*t
*t
*t
+ b
;
71 return c
/2*((t
-=2)*t
*t
+ 2) + b
;
73 easeInQuart: function (x
, t
, b
, c
, d
) {
74 return c
*(t
/=d
)*t
*t
*t
+ b
;
76 easeOutQuart: function (x
, t
, b
, c
, d
) {
77 return -c
* ((t
=t
/d
-1)*t
*t
*t
- 1) + b
;
79 easeInOutQuart: function (x
, t
, b
, c
, d
) {
80 if ((t
/=d/2) < 1) return c
/2*t
*t
*t
*t
+ b
;
81 return -c
/2 * ((t
-=2)*t
*t
*t
- 2) + b
;
83 easeInQuint: function (x
, t
, b
, c
, d
) {
84 return c
*(t
/=d
)*t
*t
*t
*t
+ b
;
86 easeOutQuint: function (x
, t
, b
, c
, d
) {
87 return c
*((t
=t
/d
-1)*t
*t
*t
*t
+ 1) + b
;
89 easeInOutQuint: function (x
, t
, b
, c
, d
) {
90 if ((t
/=d/2) < 1) return c
/2*t
*t
*t
*t
*t
+ b
;
91 return c
/2*((t
-=2)*t
*t
*t
*t
+ 2) + b
;
93 easeInSine: function (x
, t
, b
, c
, d
) {
94 return -c
* Math
.cos(t
/d
* (Math
.PI
/2)) + c
+ b
;
96 easeOutSine: function (x
, t
, b
, c
, d
) {
97 return c
* Math
.sin(t
/d
* (Math
.PI
/2)) + b
;
99 easeInOutSine: function (x
, t
, b
, c
, d
) {
100 return -c
/2 * (Math
.cos(Math
.PI
*t
/d
) - 1) + b
;
102 easeInExpo: function (x
, t
, b
, c
, d
) {
103 return (t
==0) ? b : c
* Math
.pow(2, 10 * (t
/d
- 1)) + b
;
105 easeOutExpo: function (x
, t
, b
, c
, d
) {
106 return (t
==d
) ? b
+c : c
* (-Math
.pow(2, -10 * t
/d
) + 1) + b
;
108 easeInOutExpo: function (x
, t
, b
, c
, d
) {
110 if (t
==d
) return b
+c
;
111 if ((t
/=d/2) < 1) return c
/2 * Math
.pow(2, 10 * (t
- 1)) + b
;
112 return c
/2 * (-Math
.pow(2, -10 * --t
) + 2) + b
;
114 easeInCirc: function (x
, t
, b
, c
, d
) {
115 return -c
* (Math
.sqrt(1 - (t
/=d
)*t
) - 1) + b
;
117 easeOutCirc: function (x
, t
, b
, c
, d
) {
118 return c
* Math
.sqrt(1 - (t
=t
/d
-1)*t
) + b
;
120 easeInOutCirc: function (x
, t
, b
, c
, d
) {
121 if ((t
/=d/2) < 1) return -c
/2 * (Math
.sqrt(1 - t
*t
) - 1) + b
;
122 return c
/2 * (Math
.sqrt(1 - (t
-=2)*t
) + 1) + b
;
124 easeInElastic: function (x
, t
, b
, c
, d
) {
125 var s
=1.70158;var p
=0;var a
=c
;
126 if (t
==0) return b
; if ((t
/=d
)==1) return b
+c
; if (!p
) p
=d
*.3;
127 if (a
< Math
.abs(c
)) { a
=c
; var s
=p
/4; }
128 else var s
= p
/(2*Math
.PI
) * Math
.asin (c
/a
);
129 return -(a
*Math
.pow(2,10*(t
-=1)) * Math
.sin( (t
*d
-s
)*(2*Math
.PI
)/p
)) + b
;
131 easeOutElastic: function (x
, t
, b
, c
, d
) {
132 var s
=1.70158;var p
=0;var a
=c
;
133 if (t
==0) return b
; if ((t
/=d
)==1) return b
+c
; if (!p
) p
=d
*.3;
134 if (a
< Math
.abs(c
)) { a
=c
; var s
=p
/4; }
135 else var s
= p
/(2*Math
.PI
) * Math
.asin (c
/a
);
136 return a
*Math
.pow(2,-10*t
) * Math
.sin( (t
*d
-s
)*(2*Math
.PI
)/p
) + c
+ b
;
138 easeInOutElastic: function (x
, t
, b
, c
, d
) {
139 var s
=1.70158;var p
=0;var a
=c
;
140 if (t
==0) return b
; if ((t
/=d/2)==2) return b
+c
; if (!p
) p
=d
*(.3*1.5);
141 if (a
< Math
.abs(c
)) { a
=c
; var s
=p
/4; }
142 else var s
= p
/(2*Math
.PI
) * Math
.asin (c
/a
);
143 if (t
< 1) return -.5*(a
*Math
.pow(2,10*(t
-=1)) * Math
.sin( (t
*d
-s
)*(2*Math
.PI
)/p
)) + b
;
144 return a
*Math
.pow(2,-10*(t
-=1)) * Math
.sin( (t
*d
-s
)*(2*Math
.PI
)/p
)*.5 + c
+ b
;
146 easeInBack: function (x
, t
, b
, c
, d
, s
) {
147 if (s
== undefined) s
= 1.70158;
148 return c
*(t
/=d
)*t
*((s
+1)*t
- s
) + b
;
150 easeOutBack: function (x
, t
, b
, c
, d
, s
) {
151 if (s
== undefined) s
= 1.70158;
152 return c
*((t
=t
/d
-1)*t
*((s
+1)*t
+ s
) + 1) + b
;
154 easeInOutBack: function (x
, t
, b
, c
, d
, s
) {
155 if (s
== undefined) s
= 1.70158;
156 if ((t
/=d/2) < 1) return c
/2*(t
*t
*(((s
*=(1.525))+1)*t
- s
)) + b
;
157 return c
/2*((t
-=2)*t
*(((s
*=(1.525))+1)*t
+ s
) + 2) + b
;
159 easeInBounce: function (x
, t
, b
, c
, d
) {
160 return c
- jQuery
.easing
.easeOutBounce (x
, d
-t
, 0, c
, d
) + b
;
162 easeOutBounce: function (x
, t
, b
, c
, d
) {
163 if ((t
/=d
) < (1/2.75)) {
164 return c
*(7.5625*t
*t
) + b
;
165 } else if (t
< (2/2.75)) {
166 return c
*(7.5625*(t
-=(1.5/2.75))*t
+ .75) + b
;
167 } else if (t
< (2.5/2.75)) {
168 return c
*(7.5625*(t
-=(2.25/2.75))*t
+ .9375) + b
;
170 return c
*(7.5625*(t
-=(2.625/2.75))*t
+ .984375) + b
;
173 easeInOutBounce: function (x
, t
, b
, c
, d
) {
174 if (t
< d
/2) return jQuery
.easing
.easeInBounce (x
, t
*2, 0, c
, d
) * .5 + b
;
175 return jQuery
.easing
.easeOutBounce (x
, t
*2-d
, 0, c
, d
) * .5 + c
*.5 + b
;
181 * TERMS OF USE - EASING EQUATIONS
183 * Open source under the BSD License.
185 * Copyright © 2001 Robert Penner
186 * All rights reserved.
188 * Redistribution and use in source and binary forms, with or without modification,
189 * are permitted provided that the following conditions are met:
191 * Redistributions of source code must retain the above copyright notice, this list of
192 * conditions and the following disclaimer.
193 * Redistributions in binary form must reproduce the above copyright notice, this list
194 * of conditions and the following disclaimer in the documentation and/or other materials
195 * provided with the distribution.
197 * Neither the name of the author nor the names of contributors may be used to endorse
198 * or promote products derived from this software without specific prior written permission.
200 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
201 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
202 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
203 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
204 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
205 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
206 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
207 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
208 * OF THE POSSIBILITY OF SUCH DAMAGE.
211 jQuery
.extend( jQuery
.easing
,
213 easeInOutMaterial: function (x
, t
, b
, c
, d
) {
214 if ((t
/=d/2) < 1) return c
/2*t
*t
+ b
;
215 return c
/4*((t
-=2)*t
*t
+ 2) + b
;
219 ;/*! VelocityJS.org (1.2.2). (C) 2014 Julian Shapiro. MIT @license: en.wikipedia.org/wiki/MIT_License */
220 /*! VelocityJS.org jQuery Shim (1.0.1). (C) 2014 The jQuery Foundation. MIT @license: en.wikipedia.org/wiki/MIT_License. */
221 !function(e
){function t(e
){var t
=e
.length
,r
=$.type(e
);return"function"===r
||$.isWindow(e
)?!1:1===e
.nodeType
&&t
?!0:"array"===r
||0===t
||"number"==typeof t
&&t
>0&&t
-1 in e
}if(!e
.jQuery
){var $=function(e
,t
){return new $.fn
.init(e
,t
)};$.isWindow=function(e
){return null!=e
&&e
==e
.window
},$.type=function(e
){return null==e
?e
+"":"object"==typeof e
||"function"==typeof e
?a
[o
.call(e
)]||"object":typeof e
},$.isArray
=Array
.isArray
||function(e
){return"array"===$.type(e
)},$.isPlainObject=function(e
){var t
;if(!e
||"object"!==$.type(e
)||e
.nodeType
||$.isWindow(e
))return!1;try{if(e
.constructor&&!n
.call(e
,"constructor")&&!n
.call(e
.constructor.prototype,"isPrototypeOf"))return!1}catch(r
){return!1}for(t
in e
);return void 0===t
||n
.call(e
,t
)},$.each=function(e
,r
,a
){var n
,o
=0,i
=e
.length
,s
=t(e
);if(a
){if(s
)for(;i
>o
&&(n
=r
.apply(e
[o
],a
),n
!==!1);o
++);else for(o
in e
)if(n
=r
.apply(e
[o
],a
),n
===!1)break}else if(s
)for(;i
>o
&&(n
=r
.call(e
[o
],o
,e
[o
]),n
!==!1);o
++);else for(o
in e
)if(n
=r
.call(e
[o
],o
,e
[o
]),n
===!1)break;return e
},$.data=function(e
,t
,a
){if(void 0===a
){var n
=e
[$.expando
],o
=n
&&r
[n
];if(void 0===t
)return o
;if(o
&&t
in o
)return o
[t
]}else if(void 0!==t
){var n
=e
[$.expando
]||(e
[$.expando
]=++$.uuid
);return r
[n
]=r
[n
]||{},r
[n
][t
]=a
,a
}},$.removeData=function(e
,t
){var a
=e
[$.expando
],n
=a
&&r
[a
];n
&&$.each(t
,function(e
,t
){delete n
[t
]})},$.extend=function(){var e
,t
,r
,a
,n
,o
,i
=arguments
[0]||{},s
=1,l
=arguments
.length
,u
=!1;for("boolean"==typeof i
&&(u
=i
,i
=arguments
[s
]||{},s
++),"object"!=typeof i
&&"function"!==$.type(i
)&&(i
={}),s
===l
&&(i
=this,s
--);l
>s
;s
++)if(null!=(n
=arguments
[s
]))for(a
in n
)e
=i
[a
],r
=n
[a
],i
!==r
&&(u
&&r
&&($.isPlainObject(r
)||(t
=$.isArray(r
)))?(t
?(t
=!1,o
=e
&&$.isArray(e
)?e:[]):o
=e
&&$.isPlainObject(e
)?e:{},i
[a
]=$.extend(u
,o
,r
)):void 0!==r
&&(i
[a
]=r
));return i
},$.queue=function(e
,r
,a
){function n(e
,r
){var a
=r
||[];return null!=e
&&(t(Object(e
))?!function(e
,t
){for(var r
=+t
.length
,a
=0,n
=e
.length
;r
>a
;)e
[n
++]=t
[a
++];if(r
!==r
)for(;void 0!==t
[a
];)e
[n
++]=t
[a
++];return e
.length
=n
,e
}(a
,"string"==typeof e
?[e
]:e
):[].push
.call(a
,e
)),a
}if(e
){r
=(r
||"fx")+"queue";var o
=$.data(e
,r
);return a
?(!o
||$.isArray(a
)?o
=$.data(e
,r
,n(a
)):o
.push(a
),o
):o
||[]}},$.dequeue=function(e
,t
){$.each(e
.nodeType
?[e
]:e
,function(e
,r
){t
=t
||"fx";var a
=$.queue(r
,t
),n
=a
.shift();"inprogress"===n
&&(n
=a
.shift()),n
&&("fx"===t
&&a
.unshift("inprogress"),n
.call(r
,function(){$.dequeue(r
,t
)}))})},$.fn
=$.prototype={init:function(e
){if(e
.nodeType
)return this[0]=e
,this;throw new Error("Not a DOM node.")},offset:function(){var t
=this[0].getBoundingClientRect
?this[0].getBoundingClientRect():{top:0,left:0};return{top:t
.top
+(e
.pageYOffset
||document
.scrollTop
||0)-(document
.clientTop
||0),left:t
.left
+(e
.pageXOffset
||document
.scrollLeft
||0)-(document
.clientLeft
||0)}},position:function(){function e(){for(var e
=this.offsetParent
||document
;e
&&"html"===!e
.nodeType
.toLowerCase
&&"static"===e
.style
.position
;)e
=e
.offsetParent
;return e
||document
}var t
=this[0],e
=e
.apply(t
),r
=this.offset(),a
=/^(?:body|html)$/i.test(e
.nodeName
)?{top:0,left:0}:$(e
).offset();return r
.top
-=parseFloat(t
.style
.marginTop
)||0,r
.left
-=parseFloat(t
.style
.marginLeft
)||0,e
.style
&&(a
.top
+=parseFloat(e
.style
.borderTopWidth
)||0,a
.left
+=parseFloat(e
.style
.borderLeftWidth
)||0),{top:r
.top
-a
.top
,left:r
.left
-a
.left
}}};var r
={};$.expando
="velocity"+(new Date
).getTime(),$.uuid
=0;for(var a
={},n
=a
.hasOwnProperty
,o
=a
.toString
,i
="Boolean Number String Function Array Date RegExp Object Error".split(" "),s
=0;s
<i
.length
;s
++)a
["[object "+i
[s
]+"]"]=i
[s
].toLowerCase();$.fn
.init
.prototype=$.fn
,e
.Velocity
={Utilities:$}}}(window
),function(e
){"object"==typeof module
&&"object"==typeof module
.exports
?module
.exports
=e():"function"==typeof define
&&define
.amd
?define(e
):e()}(function(){return function(e
,t
,r
,a
){function n(e
){for(var t
=-1,r
=e
?e
.length:0,a
=[];++t
<r
;){var n
=e
[t
];n
&&a
.push(n
)}return a
}function o(e
){return g
.isWrapped(e
)?e
=[].slice
.call(e
):g
.isNode(e
)&&(e
=[e
]),e
}function i(e
){var t
=$.data(e
,"velocity");return null===t
?a:t
}function s(e
){return function(t
){return Math
.round(t
*e
)*(1/e
)}}function l(e
,r
,a
,n
){function o(e
,t
){return 1-3*t
+3*e
}function i(e
,t
){return 3*t
-6*e
}function s(e
){return 3*e
}function l(e
,t
,r
){return((o(t
,r
)*e
+i(t
,r
))*e
+s(t
))*e
}function u(e
,t
,r
){return 3*o(t
,r
)*e
*e
+2*i(t
,r
)*e
+s(t
)}function c(t
,r
){for(var n
=0;m
>n
;++n
){var o
=u(r
,e
,a
);if(0===o
)return r
;var i
=l(r
,e
,a
)-t
;r
-=i
/o
}return r
}function p(){for(var t
=0;b
>t
;++t
)w
[t
]=l(t
*x
,e
,a
)}function f(t
,r
,n
){var o
,i
,s
=0;do i
=r
+(n
-r
)/2,o
=l(i
,e
,a
)-t
,o
>0?n
=i:r
=i
;while(Math
.abs(o
)>h
&&++s
<v
);return i
}function d(t
){for(var r
=0,n
=1,o
=b
-1;n
!=o
&&w
[n
]<=t
;++n
)r
+=x
;--n
;var i
=(t
-w
[n
])/(w
[n
+1]-w
[n
]),s
=r
+i
*x
,l
=u(s
,e
,a
);return l
>=y
?c(t
,s
):0==l
?s:f(t
,r
,r
+x
)}function g(){V
=!0,(e
!=r
||a
!=n
)&&p()}var m
=4,y
=.001,h
=1e-7,v
=10,b
=11,x
=1/(b
-1),S
="Float32Array"in t
;if(4!==arguments
.length
)return!1;for(var P
=0;4>P
;++P
)if("number"!=typeof arguments
[P
]||isNaN(arguments
[P
])||!isFinite(arguments
[P
]))return!1;e
=Math
.min(e
,1),a
=Math
.min(a
,1),e
=Math
.max(e
,0),a
=Math
.max(a
,0);var w
=S
?new Float32Array(b
):new Array(b
),V
=!1,C=function(t
){return V
||g(),e
===r
&&a
===n
?t:0===t
?0:1===t
?1:l(d(t
),r
,n
)};C
.getControlPoints=function(){return[{x:e
,y:r
},{x:a
,y:n
}]};var T
="generateBezier("+[e
,r
,a
,n
]+")";return C
.toString=function(){return T
},C
}function u(e
,t
){var r
=e
;return g
.isString(e
)?v
.Easings
[e
]||(r
=!1):r
=g
.isArray(e
)&&1===e
.length
?s
.apply(null,e
):g
.isArray(e
)&&2===e
.length
?b
.apply(null,e
.concat([t
])):g
.isArray(e
)&&4===e
.length
?l
.apply(null,e
):!1,r
===!1&&(r
=v
.Easings
[v
.defaults
.easing
]?v
.defaults
.easing:h
),r
}function c(e
){if(e
){var t
=(new Date
).getTime(),r
=v
.State
.calls
.length
;r
>1e4
&&(v
.State
.calls
=n(v
.State
.calls
));for(var o
=0;r
>o
;o
++)if(v
.State
.calls
[o
]){var s
=v
.State
.calls
[o
],l
=s
[0],u
=s
[2],f
=s
[3],d
=!!f
,m
=null;f
||(f
=v
.State
.calls
[o
][3]=t
-16);for(var y
=Math
.min((t
-f
)/u
.duration
,1),h
=0,b
=l
.length
;b
>h
;h
++){var S
=l
[h
],w
=S
.element
;if(i(w
)){var V
=!1;if(u
.display
!==a
&&null!==u
.display
&&"none"!==u
.display
){if("flex"===u
.display
){var C
=["-webkit-box","-moz-box","-ms-flexbox","-webkit-flex"];$.each(C
,function(e
,t
){x
.setPropertyValue(w
,"display",t
)})}x
.setPropertyValue(w
,"display",u
.display
)}u
.visibility
!==a
&&"hidden"!==u
.visibility
&&x
.setPropertyValue(w
,"visibility",u
.visibility
);for(var T
in S
)if("element"!==T
){var k
=S
[T
],A
,F
=g
.isString(k
.easing
)?v
.Easings
[k
.easing
]:k
.easing
;if(1===y
)A
=k
.endValue
;else{var E
=k
.endValue
-k
.startValue
;if(A
=k
.startValue
+E
*F(y
,u
,E
),!d
&&A
===k
.currentValue
)continue}if(k
.currentValue
=A
,"tween"===T
)m
=A
;else{if(x
.Hooks
.registered
[T
]){var j
=x
.Hooks
.getRoot(T
),H
=i(w
).rootPropertyValueCache
[j
];H
&&(k
.rootPropertyValue
=H
)}var N
=x
.setPropertyValue(w
,T
,k
.currentValue
+(0===parseFloat(A
)?"":k
.unitType
),k
.rootPropertyValue
,k
.scrollData
);x
.Hooks
.registered
[T
]&&(i(w
).rootPropertyValueCache
[j
]=x
.Normalizations
.registered
[j
]?x
.Normalizations
.registered
[j
]("extract",null,N
[1]):N
[1]),"transform"===N
[0]&&(V
=!0)}}u
.mobileHA
&&i(w
).transformCache
.translate3d
===a
&&(i(w
).transformCache
.translate3d
="(0px, 0px, 0px)",V
=!0),V
&&x
.flushTransformCache(w
)}}u
.display
!==a
&&"none"!==u
.display
&&(v
.State
.calls
[o
][2].display
=!1),u
.visibility
!==a
&&"hidden"!==u
.visibility
&&(v
.State
.calls
[o
][2].visibility
=!1),u
.progress
&&u
.progress
.call(s
[1],s
[1],y
,Math
.max(0,f
+u
.duration
-t
),f
,m
),1===y
&&p(o
)}}v
.State
.isTicking
&&P(c
)}function p(e
,t
){if(!v
.State
.calls
[e
])return!1;for(var r
=v
.State
.calls
[e
][0],n
=v
.State
.calls
[e
][1],o
=v
.State
.calls
[e
][2],s
=v
.State
.calls
[e
][4],l
=!1,u
=0,c
=r
.length
;c
>u
;u
++){var p
=r
[u
].element
;if(t
||o
.loop
||("none"===o
.display
&&x
.setPropertyValue(p
,"display",o
.display
),"hidden"===o
.visibility
&&x
.setPropertyValue(p
,"visibility",o
.visibility
)),o
.loop
!==!0&&($.queue(p
)[1]===a
||!/\.velocityQueueEntryFlag/i.test($.queue(p
)[1]))&&i(p
)){i(p
).isAnimating
=!1,i(p
).rootPropertyValueCache
={};var f
=!1;$.each(x
.Lists
.transforms3D
,function(e
,t
){var r
=/^scale/.test(t
)?1:0,n
=i(p
).transformCache
[t
];i(p
).transformCache
[t
]!==a
&&new RegExp("^\\("+r
+"[^.]").test(n
)&&(f
=!0,delete i(p
).transformCache
[t
])}),o
.mobileHA
&&(f
=!0,delete i(p
).transformCache
.translate3d
),f
&&x
.flushTransformCache(p
),x
.Values
.removeClass(p
,"velocity-animating")}if(!t
&&o
.complete
&&!o
.loop
&&u
===c
-1)try{o
.complete
.call(n
,n
)}catch(d
){setTimeout(function(){throw d
},1)}s
&&o
.loop
!==!0&&s(n
),i(p
)&&o
.loop
===!0&&!t
&&($.each(i(p
).tweensContainer
,function(e
,t
){/^rotate/.test(e
)&&360===parseFloat(t
.endValue
)&&(t
.endValue
=0,t
.startValue
=360),/^backgroundPosition/.test(e
)&&100===parseFloat(t
.endValue
)&&"%"===t
.unitType
&&(t
.endValue
=0,t
.startValue
=100)}),v(p
,"reverse",{loop:!0,delay:o
.delay
})),o
.queue
!==!1&&$.dequeue(p
,o
.queue
)}v
.State
.calls
[e
]=!1;for(var g
=0,m
=v
.State
.calls
.length
;m
>g
;g
++)if(v
.State
.calls
[g
]!==!1){l
=!0;break}l
===!1&&(v
.State
.isTicking
=!1,delete v
.State
.calls
,v
.State
.calls
=[])}var f=function(){if(r
.documentMode
)return r
.documentMode
;for(var e
=7;e
>4;e
--){var t
=r
.createElement("div");if(t
.innerHTML
="<!--[if IE "+e
+"]><span></span><![endif]-->",t
.getElementsByTagName("span").length
)return t
=null,e
}return a
}(),d=function(){var e
=0;return t
.webkitRequestAnimationFrame
||t
.mozRequestAnimationFrame
||function(t
){var r
=(new Date
).getTime(),a
;return a
=Math
.max(0,16-(r
-e
)),e
=r
+a
,setTimeout(function(){t(r
+a
)},a
)}}(),g
={isString:function(e
){return"string"==typeof e
},isArray:Array
.isArray
||function(e
){return"[object Array]"===Object
.prototype.toString
.call(e
)},isFunction:function(e
){return"[object Function]"===Object
.prototype.toString
.call(e
)},isNode:function(e
){return e
&&e
.nodeType
},isNodeList:function(e
){return"object"==typeof e
&&/^\[object (HTMLCollection
|NodeList
|Object
)\]$/.test(Object
.prototype.toString
.call(e
))&&e
.length
!==a
&&(0===e
.length
||"object"==typeof e
[0]&&e
[0].nodeType
>0)},isWrapped:function(e
){return e
&&(e
.jquery
||t
.Zepto
&&t
.Zepto
.zepto
.isZ(e
))},isSVG:function(e
){return t
.SVGElement
&&e
instanceof t
.SVGElement
},isEmptyObject:function(e
){for(var t
in e
)return!1;return!0}},$,m
=!1;if(e
.fn
&&e
.fn
.jquery
?($=e
,m
=!0):$=t
.Velocity
.Utilities
,8>=f
&&!m
)throw new Error("Velocity: IE8 and below require jQuery to be loaded before Velocity.");if(7>=f
)return void(jQuery
.fn
.velocity
=jQuery
.fn
.animate
);var y
=400,h
="swing",v
={State:{isMobile:/Android
|webOS
|iPhone
|iPad
|iPod
|BlackBerry
|IEMobile
|Opera Mini
/i.test(navigator.userAgent),isAndroid:/Android
/i.test(navigator.userAgent),isGingerbread:/Android
2\.3\.[3-7]/i.test(navigator.userAgent),isChrome:t.chrome,isFirefox:/Firefox
/i
.test(navigator
.userAgent
),prefixElement:r
.createElement("div"),prefixMatches:{},scrollAnchor:null,scrollPropertyLeft:null,scrollPropertyTop:null,isTicking:!1,calls:[]},CSS:{},Utilities:$,Redirects:{},Easings:{},Promise:t
.Promise
,defaults:{queue:"",duration:y
,easing:h
,begin:a
,complete:a
,progress:a
,display:a
,visibility:a
,loop:!1,delay:!1,mobileHA:!0,_cacheValues:!0},init:function(e
){$.data(e
,"velocity",{isSVG:g
.isSVG(e
),isAnimating:!1,computedStyle:null,tweensContainer:null,rootPropertyValueCache:{},transformCache:{}})},hook:null,mock:!1,version:{major:1,minor:2,patch:2},debug:!1};t
.pageYOffset
!==a
?(v
.State
.scrollAnchor
=t
,v
.State
.scrollPropertyLeft
="pageXOffset",v
.State
.scrollPropertyTop
="pageYOffset"):(v
.State
.scrollAnchor
=r
.documentElement
||r
.body
.parentNode
||r
.body
,v
.State
.scrollPropertyLeft
="scrollLeft",v
.State
.scrollPropertyTop
="scrollTop");var b=function(){function e(e
){return-e
.tension
*e
.x
-e
.friction
*e
.v
}function t(t
,r
,a
){var n
={x:t
.x
+a
.dx
*r
,v:t
.v
+a
.dv
*r
,tension:t
.tension
,friction:t
.friction
};return{dx:n
.v
,dv:e(n
)}}function r(r
,a
){var n
={dx:r
.v
,dv:e(r
)},o
=t(r
,.5*a
,n
),i
=t(r
,.5*a
,o
),s
=t(r
,a
,i
),l
=1/6*(n.dx+2*(o.dx+i.dx)+s.dx),u=1/6*(n
.dv
+2*(o
.dv
+i
.dv
)+s
.dv
);return r
.x
=r
.x
+l
*a
,r
.v
=r
.v
+u
*a
,r
}return function a(e
,t
,n
){var o
={x:-1,v:0,tension:null,friction:null},i
=[0],s
=0,l
=1e-4,u
=.016,c
,p
,f
;for(e
=parseFloat(e
)||500,t
=parseFloat(t
)||20,n
=n
||null,o
.tension
=e
,o
.friction
=t
,c
=null!==n
,c
?(s
=a(e
,t
),p
=s
/n
*u
):p
=u
;;)if(f
=r(f
||o
,p
),i
.push(1+f
.x
),s
+=16,!(Math
.abs(f
.x
)>l
&&Math
.abs(f
.v
)>l
))break;return c
?function(e
){return i
[e
*(i
.length
-1)|0]}:s
}}();v
.Easings
={linear:function(e
){return e
},swing:function(e
){return.5-Math
.cos(e
*Math
.PI
)/2},spring:function(e
){return 1-Math
.cos(4.5*e
*Math
.PI
)*Math
.exp(6*-e
)}},$.each([["ease",[.25,.1,.25,1]],["ease-in",[.42,0,1,1]],["ease-out",[0,0,.58,1]],["ease-in-out",[.42,0,.58,1]],["easeInSine",[.47,0,.745,.715]],["easeOutSine",[.39,.575,.565,1]],["easeInOutSine",[.445,.05,.55,.95]],["easeInQuad",[.55,.085,.68,.53]],["easeOutQuad",[.25,.46,.45,.94]],["easeInOutQuad",[.455,.03,.515,.955]],["easeInCubic",[.55,.055,.675,.19]],["easeOutCubic",[.215,.61,.355,1]],["easeInOutCubic",[.645,.045,.355,1]],["easeInQuart",[.895,.03,.685,.22]],["easeOutQuart",[.165,.84,.44,1]],["easeInOutQuart",[.77,0,.175,1]],["easeInQuint",[.755,.05,.855,.06]],["easeOutQuint",[.23,1,.32,1]],["easeInOutQuint",[.86,0,.07,1]],["easeInExpo",[.95,.05,.795,.035]],["easeOutExpo",[.19,1,.22,1]],["easeInOutExpo",[1,0,0,1]],["easeInCirc",[.6,.04,.98,.335]],["easeOutCirc",[.075,.82,.165,1]],["easeInOutCirc",[.785,.135,.15,.86]]],function(e
,t
){v
.Easings
[t
[0]]=l
.apply(null,t
[1])});var x
=v
.CSS
={RegEx:{isHex:/^#([A-f\d]{3}){1,2}$/i,valueUnwrap:/^[A-z]+\((.*)\)$/i,wrappedValueAlreadyExtracted:/[0-9.]+ [0-9.]+ [0-9.]+( [0-9.]+)?/,valueSplit:/([A
-z
]+\(.+\))|(([A
-z0
-9#-.]+?)(?=\s
|$))/gi
},Lists:{colors:["fill","stroke","stopColor","color","backgroundColor","borderColor","borderTopColor","borderRightColor","borderBottomColor","borderLeftColor","outlineColor"],transformsBase:["translateX","translateY","scale","scaleX","scaleY","skewX","skewY","rotateZ"],transforms3D:["transformPerspective","translateZ","scaleZ","rotateX","rotateY"]},Hooks:{templates:{textShadow:["Color X Y Blur","black 0px 0px 0px"],boxShadow:["Color X Y Blur Spread","black 0px 0px 0px 0px"],clip:["Top Right Bottom Left","0px 0px 0px 0px"],backgroundPosition:["X Y","0% 0%"],transformOrigin:["X Y Z","50% 50% 0px"],perspectiveOrigin:["X Y","50% 50%"]},registered:{},register:function(){for(var e
=0;e
<x
.Lists
.colors
.length
;e
++){var t
="color"===x
.Lists
.colors
[e
]?"0 0 0 1":"255 255 255 1";x
.Hooks
.templates
[x
.Lists
.colors
[e
]]=["Red Green Blue Alpha",t
]}var r
,a
,n
;if(f
)for(r
in x
.Hooks
.templates
){a
=x
.Hooks
.templates
[r
],n
=a
[0].split(" ");var o
=a
[1].match(x
.RegEx
.valueSplit
);"Color"===n
[0]&&(n
.push(n
.shift()),o
.push(o
.shift()),x
.Hooks
.templates
[r
]=[n
.join(" "),o
.join(" ")])}for(r
in x
.Hooks
.templates
){a
=x
.Hooks
.templates
[r
],n
=a
[0].split(" ");for(var e
in n
){var i
=r
+n
[e
],s
=e
;x
.Hooks
.registered
[i
]=[r
,s
]}}},getRoot:function(e
){var t
=x
.Hooks
.registered
[e
];return t
?t
[0]:e
},cleanRootPropertyValue:function(e
,t
){return x
.RegEx
.valueUnwrap
.test(t
)&&(t
=t
.match(x
.RegEx
.valueUnwrap
)[1]),x
.Values
.isCSSNullValue(t
)&&(t
=x
.Hooks
.templates
[e
][1]),t
},extractValue:function(e
,t
){var r
=x
.Hooks
.registered
[e
];if(r
){var a
=r
[0],n
=r
[1];return t
=x
.Hooks
.cleanRootPropertyValue(a
,t
),t
.toString().match(x
.RegEx
.valueSplit
)[n
]}return t
},injectValue:function(e
,t
,r
){var a
=x
.Hooks
.registered
[e
];if(a
){var n
=a
[0],o
=a
[1],i
,s
;return r
=x
.Hooks
.cleanRootPropertyValue(n
,r
),i
=r
.toString().match(x
.RegEx
.valueSplit
),i
[o
]=t
,s
=i
.join(" ")}return r
}},Normalizations:{registered:{clip:function(e
,t
,r
){switch(e
){case"name":return"clip";case"extract":var a
;return x
.RegEx
.wrappedValueAlreadyExtracted
.test(r
)?a
=r:(a
=r
.toString().match(x
.RegEx
.valueUnwrap
),a
=a
?a
[1].replace(/,(\s+)?/g," "):r
),a
;case"inject":return"rect("+r
+")"}},blur:function(e
,t
,r
){switch(e
){case"name":return v
.State
.isFirefox
?"filter":"-webkit-filter";case"extract":var a
=parseFloat(r
);if(!a
&&0!==a
){var n
=r
.toString().match(/blur\(([0-9]+[A-z]+)\)/i);a
=n
?n
[1]:0}return a
;case"inject":return parseFloat(r
)?"blur("+r
+")":"none"}},opacity:function(e
,t
,r
){if(8>=f
)switch(e
){case"name":return"filter";case"extract":var a
=r
.toString().match(/alpha\(opacity=(.*)\)/i);return r
=a
?a
[1]/100:1;case"inject":return t
.style
.zoom
=1,parseFloat(r
)>=1?"":"alpha(opacity="+parseInt(100*parseFloat(r
),10)+")"}else switch(e
){case"name":return"opacity";case"extract":return r
;case"inject":return r
}}},register:function(){9>=f
||v
.State
.isGingerbread
||(x
.Lists
.transformsBase
=x
.Lists
.transformsBase
.concat(x
.Lists
.transforms3D
));for(var e
=0;e
<x
.Lists
.transformsBase
.length
;e
++)!function(){var t
=x
.Lists
.transformsBase
[e
];x
.Normalizations
.registered
[t
]=function(e
,r
,n
){switch(e
){case"name":return"transform";case"extract":return i(r
)===a
||i(r
).transformCache
[t
]===a
?/^scale/i.test(t
)?1:0:i(r
).transformCache
[t
].replace(/[()]/g,"");case"inject":var o
=!1;switch(t
.substr(0,t
.length
-1)){case"translate":o
=!/(%|px|em|rem|vw|vh|\d)$/i.test(n
);break;case"scal":case"scale":v
.State
.isAndroid
&&i(r
).transformCache
[t
]===a
&&1>n
&&(n
=1),o
=!/(\d)$/i.test(n
);break;case"skew":o
=!/(deg|\d)$/i.test(n
);break;case"rotate":o
=!/(deg|\d)$/i.test(n
)}return o
||(i(r
).transformCache
[t
]="("+n
+")"),i(r
).transformCache
[t
]}}}();for(var e
=0;e
<x
.Lists
.colors
.length
;e
++)!function(){var t
=x
.Lists
.colors
[e
];x
.Normalizations
.registered
[t
]=function(e
,r
,n
){switch(e
){case"name":return t
;case"extract":var o
;if(x
.RegEx
.wrappedValueAlreadyExtracted
.test(n
))o
=n
;else{var i
,s
={black:"rgb(0, 0, 0)",blue:"rgb(0, 0, 255)",gray:"rgb(128, 128, 128)",green:"rgb(0, 128, 0)",red:"rgb(255, 0, 0)",white:"rgb(255, 255, 255)"};/^[A-z]+$/i.test(n
)?i
=s
[n
]!==a
?s
[n
]:s
.black:x
.RegEx
.isHex
.test(n
)?i
="rgb("+x
.Values
.hexToRgb(n
).join(" ")+")":/^rgba?\(/i.test(n
)||(i
=s
.black
),o
=(i
||n
).toString().match(x
.RegEx
.valueUnwrap
)[1].replace(/,(\s+)?/g," ")}return 8>=f
||3!==o
.split(" ").length
||(o
+=" 1"),o
;case"inject":return 8>=f
?4===n
.split(" ").length
&&(n
=n
.split(/\s+/).slice(0,3).join(" ")):3===n
.split(" ").length
&&(n
+=" 1"),(8>=f
?"rgb":"rgba")+"("+n
.replace(/\s+/g,",").replace(/\.(\d)+(?=,)/g,"")+")"}}}()}},Names:{camelCase:function(e
){return e
.replace(/-(\w)/g,function(e
,t
){return t
.toUpperCase()})},SVGAttribute:function(e
){var t
="width|height|x|y|cx|cy|r|rx|ry|x1|x2|y1|y2";return(f
||v
.State
.isAndroid
&&!v
.State
.isChrome
)&&(t
+="|transform"),new RegExp("^("+t
+")$","i").test(e
)},prefixCheck:function(e
){if(v
.State
.prefixMatches
[e
])return[v
.State
.prefixMatches
[e
],!0];for(var t
=["","Webkit","Moz","ms","O"],r
=0,a
=t
.length
;a
>r
;r
++){var n
;if(n
=0===r
?e:t
[r
]+e
.replace(/^\w/,function(e
){return e
.toUpperCase()}),g
.isString(v
.State
.prefixElement
.style
[n
]))return v
.State
.prefixMatches
[e
]=n
,[n
,!0]}return[e
,!1]}},Values:{hexToRgb:function(e
){var t
=/^#?([a-f\d])([a-f\d])([a-f\d])$/i,r
=/^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i,a
;return e
=e
.replace(t
,function(e
,t
,r
,a
){return t
+t
+r
+r
+a
+a
}),a
=r
.exec(e
),a
?[parseInt(a
[1],16),parseInt(a
[2],16),parseInt(a
[3],16)]:[0,0,0]},isCSSNullValue:function(e
){return 0==e
||/^(none
|auto
|transparent
|(rgba
\(0, ?0, ?0, ?0\)))$/i.test(e)},getUnitType:function(e){return/^(rotate
|skew
)/i.test(e)?"deg":/(^(scale
|scaleX
|scaleY
|scaleZ
|alpha
|flexGrow
|flexHeight
|zIndex
|fontWeight
)$)|((opacity
|red
|green
|blue
|alpha
)$)/i
.test(e
)?"":"px"},getDisplayType:function(e
){var t
=e
&&e
.tagName
.toString().toLowerCase();return/^(b|big|i|small|tt|abbr|acronym|cite|code|dfn|em|kbd|strong|samp|var|a|bdo|br|img|map|object|q|script|span|sub|sup|button|input|label|select|textarea)$/i.test(t
)?"inline":/^(li)$/i.test(t
)?"list-item":/^(tr)$/i.test(t
)?"table-row":/^(table)$/i.test(t
)?"table":/^(tbody)$/i.test(t
)?"table-row-group":"block"},addClass:function(e
,t
){e
.classList
?e
.classList
.add(t
):e
.className
+=(e
.className
.length
?" ":"")+t
},removeClass:function(e
,t
){e
.classList
?e
.classList
.remove(t
):e
.className
=e
.className
.toString().replace(new RegExp("(^|\\s)"+t
.split(" ").join("|")+"(\\s|$)","gi")," ")}},getPropertyValue:function(e
,r
,n
,o
){function s(e
,r
){function n(){u
&&x
.setPropertyValue(e
,"display","none")}var l
=0;if(8>=f
)l
=$.css(e
,r
);else{var u
=!1;if(/^(width|height)$/.test(r
)&&0===x
.getPropertyValue(e
,"display")&&(u
=!0,x
.setPropertyValue(e
,"display",x
.Values
.getDisplayType(e
))),!o
){if("height"===r
&&"border-box"!==x
.getPropertyValue(e
,"boxSizing").toString().toLowerCase()){var c
=e
.offsetHeight
-(parseFloat(x
.getPropertyValue(e
,"borderTopWidth"))||0)-(parseFloat(x
.getPropertyValue(e
,"borderBottomWidth"))||0)-(parseFloat(x
.getPropertyValue(e
,"paddingTop"))||0)-(parseFloat(x
.getPropertyValue(e
,"paddingBottom"))||0);return n(),c
}if("width"===r
&&"border-box"!==x
.getPropertyValue(e
,"boxSizing").toString().toLowerCase()){var p
=e
.offsetWidth
-(parseFloat(x
.getPropertyValue(e
,"borderLeftWidth"))||0)-(parseFloat(x
.getPropertyValue(e
,"borderRightWidth"))||0)-(parseFloat(x
.getPropertyValue(e
,"paddingLeft"))||0)-(parseFloat(x
.getPropertyValue(e
,"paddingRight"))||0);return n(),p
}}var d
;d
=i(e
)===a
?t
.getComputedStyle(e
,null):i(e
).computedStyle
?i(e
).computedStyle:i(e
).computedStyle
=t
.getComputedStyle(e
,null),"borderColor"===r
&&(r
="borderTopColor"),l
=9===f
&&"filter"===r
?d
.getPropertyValue(r
):d
[r
],(""===l
||null===l
)&&(l
=e
.style
[r
]),n()}if("auto"===l
&&/^(top|right|bottom|left)$/i.test(r
)){var g
=s(e
,"position");("fixed"===g
||"absolute"===g
&&/top|left/i.test(r
))&&(l
=$(e
).position()[r
]+"px")}return l
}var l
;if(x
.Hooks
.registered
[r
]){var u
=r
,c
=x
.Hooks
.getRoot(u
);n
===a
&&(n
=x
.getPropertyValue(e
,x
.Names
.prefixCheck(c
)[0])),x
.Normalizations
.registered
[c
]&&(n
=x
.Normalizations
.registered
[c
]("extract",e
,n
)),l
=x
.Hooks
.extractValue(u
,n
)}else if(x
.Normalizations
.registered
[r
]){var p
,d
;p
=x
.Normalizations
.registered
[r
]("name",e
),"transform"!==p
&&(d
=s(e
,x
.Names
.prefixCheck(p
)[0]),x
.Values
.isCSSNullValue(d
)&&x
.Hooks
.templates
[r
]&&(d
=x
.Hooks
.templates
[r
][1])),l
=x
.Normalizations
.registered
[r
]("extract",e
,d
)}if(!/^[\d-]/.test(l
))if(i(e
)&&i(e
).isSVG
&&x
.Names
.SVGAttribute(r
))if(/^(height|width)$/i.test(r
))try{l
=e
.getBBox()[r
]}catch(g
){l
=0}else l
=e
.getAttribute(r
);else l
=s(e
,x
.Names
.prefixCheck(r
)[0]);return x
.Values
.isCSSNullValue(l
)&&(l
=0),v
.debug
>=2&&console
.log("Get "+r
+": "+l
),l
},setPropertyValue:function(e
,r
,a
,n
,o
){var s
=r
;if("scroll"===r
)o
.container
?o
.container
["scroll"+o
.direction
]=a:"Left"===o
.direction
?t
.scrollTo(a
,o
.alternateValue
):t
.scrollTo(o
.alternateValue
,a
);else if(x
.Normalizations
.registered
[r
]&&"transform"===x
.Normalizations
.registered
[r
]("name",e
))x
.Normalizations
.registered
[r
]("inject",e
,a
),s
="transform",a
=i(e
).transformCache
[r
];else{if(x
.Hooks
.registered
[r
]){var l
=r
,u
=x
.Hooks
.getRoot(r
);n
=n
||x
.getPropertyValue(e
,u
),a
=x
.Hooks
.injectValue(l
,a
,n
),r
=u
}if(x
.Normalizations
.registered
[r
]&&(a
=x
.Normalizations
.registered
[r
]("inject",e
,a
),r
=x
.Normalizations
.registered
[r
]("name",e
)),s
=x
.Names
.prefixCheck(r
)[0],8>=f
)try{e
.style
[s
]=a
}catch(c
){v
.debug
&&console
.log("Browser does not support ["+a
+"] for ["+s
+"]")}else i(e
)&&i(e
).isSVG
&&x
.Names
.SVGAttribute(r
)?e
.setAttribute(r
,a
):e
.style
[s
]=a
;v
.debug
>=2&&console
.log("Set "+r
+" ("+s
+"): "+a
)}return[s
,a
]},flushTransformCache:function(e
){function t(t
){return parseFloat(x
.getPropertyValue(e
,t
))}var r
="";if((f
||v
.State
.isAndroid
&&!v
.State
.isChrome
)&&i(e
).isSVG
){var a
={translate:[t("translateX"),t("translateY")],skewX:[t("skewX")],skewY:[t("skewY")],scale:1!==t("scale")?[t("scale"),t("scale")]:[t("scaleX"),t("scaleY")],rotate:[t("rotateZ"),0,0]};$.each(i(e
).transformCache
,function(e
){/^translate/i.test(e
)?e
="translate":/^scale/i.test(e
)?e
="scale":/^rotate/i.test(e
)&&(e
="rotate"),a
[e
]&&(r
+=e
+"("+a
[e
].join(" ")+") ",delete a
[e
])})}else{var n
,o
;$.each(i(e
).transformCache
,function(t
){return n
=i(e
).transformCache
[t
],"transformPerspective"===t
?(o
=n
,!0):(9===f
&&"rotateZ"===t
&&(t
="rotate"),void(r
+=t
+n
+" "))}),o
&&(r
="perspective"+o
+" "+r
)}x
.setPropertyValue(e
,"transform",r
)}};x
.Hooks
.register(),x
.Normalizations
.register(),v
.hook=function(e
,t
,r
){var n
=a
;return e
=o(e
),$.each(e
,function(e
,o
){if(i(o
)===a
&&v
.init(o
),r
===a
)n
===a
&&(n
=v
.CSS
.getPropertyValue(o
,t
));else{var s
=v
.CSS
.setPropertyValue(o
,t
,r
);"transform"===s
[0]&&v
.CSS
.flushTransformCache(o
),n
=s
}}),n
};var S=function(){function e(){return l
?T
.promise
||null:f
}function n(){function e(e
){function p(e
,t
){var r
=a
,i
=a
,s
=a
;return g
.isArray(e
)?(r
=e
[0],!g
.isArray(e
[1])&&/^[\d-]/.test(e
[1])||g
.isFunction(e
[1])||x
.RegEx
.isHex
.test(e
[1])?s
=e
[1]:(g
.isString(e
[1])&&!x
.RegEx
.isHex
.test(e
[1])||g
.isArray(e
[1]))&&(i
=t
?e
[1]:u(e
[1],o
.duration
),e
[2]!==a
&&(s
=e
[2]))):r
=e
,t
||(i
=i
||o
.easing
),g
.isFunction(r
)&&(r
=r
.call(n
,w
,P
)),g
.isFunction(s
)&&(s
=s
.call(n
,w
,P
)),[r
||0,i
,s
]}function f(e
,t
){var r
,a
;return a
=(t
||"0").toString().toLowerCase().replace(/[%A-z]+$/,function(e
){return r
=e
,""}),r
||(r
=x
.Values
.getUnitType(e
)),[a
,r
]}function d(){var e
={myParent:n
.parentNode
||r
.body
,position:x
.getPropertyValue(n
,"position"),fontSize:x
.getPropertyValue(n
,"fontSize")},a
=e
.position
===N
.lastPosition
&&e
.myParent
===N
.lastParent
,o
=e
.fontSize
===N
.lastFontSize
;N
.lastParent
=e
.myParent
,N
.lastPosition
=e
.position
,N
.lastFontSize
=e
.fontSize
;var s
=100,l
={};if(o
&&a
)l
.emToPx
=N
.lastEmToPx
,l
.percentToPxWidth
=N
.lastPercentToPxWidth
,l
.percentToPxHeight
=N
.lastPercentToPxHeight
;else{var u
=i(n
).isSVG
?r
.createElementNS("http://www.w3.org/2000/svg","rect"):r
.createElement("div");v
.init(u
),e
.myParent
.appendChild(u
),$.each(["overflow","overflowX","overflowY"],function(e
,t
){v
.CSS
.setPropertyValue(u
,t
,"hidden")}),v
.CSS
.setPropertyValue(u
,"position",e
.position
),v
.CSS
.setPropertyValue(u
,"fontSize",e
.fontSize
),v
.CSS
.setPropertyValue(u
,"boxSizing","content-box"),$.each(["minWidth","maxWidth","width","minHeight","maxHeight","height"],function(e
,t
){v
.CSS
.setPropertyValue(u
,t
,s
+"%")}),v
.CSS
.setPropertyValue(u
,"paddingLeft",s
+"em"),l
.percentToPxWidth
=N
.lastPercentToPxWidth
=(parseFloat(x
.getPropertyValue(u
,"width",null,!0))||1)/s
,l
.percentToPxHeight
=N
.lastPercentToPxHeight
=(parseFloat(x
.getPropertyValue(u
,"height",null,!0))||1)/s,l.emToPx=N.lastEmToPx=(parseFloat(x.getPropertyValue(u,"paddingLeft"))||1)/s,e
.myParent
.removeChild(u
)}return null===N
.remToPx
&&(N
.remToPx
=parseFloat(x
.getPropertyValue(r
.body
,"fontSize"))||16),null===N
.vwToPx
&&(N
.vwToPx
=parseFloat(t
.innerWidth
)/100,N.vhToPx=parseFloat(t.innerHeight)/100),l
.remToPx
=N
.remToPx
,l
.vwToPx
=N
.vwToPx
,l
.vhToPx
=N
.vhToPx
,v
.debug
>=1&&console
.log("Unit ratios: "+JSON
.stringify(l
),n
),l
}if(o
.begin
&&0===w
)try{o
.begin
.call(m
,m
)}catch(y
){setTimeout(function(){throw y
},1)}if("scroll"===k
){var S
=/^x$/i.test(o
.axis
)?"Left":"Top",V
=parseFloat(o
.offset
)||0,C
,A
,F
;o
.container
?g
.isWrapped(o
.container
)||g
.isNode(o
.container
)?(o
.container
=o
.container
[0]||o
.container
,C
=o
.container
["scroll"+S
],F
=C
+$(n
).position()[S
.toLowerCase()]+V
):o
.container
=null:(C
=v
.State
.scrollAnchor
[v
.State
["scrollProperty"+S
]],A
=v
.State
.scrollAnchor
[v
.State
["scrollProperty"+("Left"===S
?"Top":"Left")]],F
=$(n
).offset()[S
.toLowerCase()]+V
),s
={scroll:{rootPropertyValue:!1,startValue:C
,currentValue:C
,endValue:F
,unitType:"",easing:o
.easing
,scrollData:{container:o
.container
,direction:S
,alternateValue:A
}},element:n
},v
.debug
&&console
.log("tweensContainer (scroll): ",s
.scroll
,n
)}else if("reverse"===k
){if(!i(n
).tweensContainer
)return void $.dequeue(n
,o
.queue
);"none"===i(n
).opts
.display
&&(i(n
).opts
.display
="auto"),"hidden"===i(n
).opts
.visibility
&&(i(n
).opts
.visibility
="visible"),i(n
).opts
.loop
=!1,i(n
).opts
.begin
=null,i(n
).opts
.complete
=null,b
.easing
||delete o
.easing
,b
.duration
||delete o
.duration
,o
=$.extend({},i(n
).opts
,o
);var E
=$.extend(!0,{},i(n
).tweensContainer
);for(var j
in E
)if("element"!==j
){var H
=E
[j
].startValue
;E
[j
].startValue
=E
[j
].currentValue
=E
[j
].endValue
,E
[j
].endValue
=H
,g
.isEmptyObject(b
)||(E
[j
].easing
=o
.easing
),v
.debug
&&console
.log("reverse tweensContainer ("+j
+"): "+JSON
.stringify(E
[j
]),n
)}s
=E
}else if("start"===k
){var E
;i(n
).tweensContainer
&&i(n
).isAnimating
===!0&&(E
=i(n
).tweensContainer
),$.each(h
,function(e
,t
){if(RegExp("^"+x
.Lists
.colors
.join("$|^")+"$").test(e
)){var r
=p(t
,!0),n
=r
[0],o
=r
[1],i
=r
[2];if(x
.RegEx
.isHex
.test(n
)){for(var s
=["Red","Green","Blue"],l
=x
.Values
.hexToRgb(n
),u
=i
?x
.Values
.hexToRgb(i
):a
,c
=0;c
<s
.length
;c
++){var f
=[l
[c
]];o
&&f
.push(o
),u
!==a
&&f
.push(u
[c
]),h
[e
+s
[c
]]=f
}delete h
[e
]}}});for(var R
in h
){var O
=p(h
[R
]),z
=O
[0],q
=O
[1],M
=O
[2];R
=x
.Names
.camelCase(R
);var I
=x
.Hooks
.getRoot(R
),B
=!1;if(i(n
).isSVG
||"tween"===I
||x
.Names
.prefixCheck(I
)[1]!==!1||x
.Normalizations
.registered
[I
]!==a
){(o
.display
!==a
&&null!==o
.display
&&"none"!==o
.display
||o
.visibility
!==a
&&"hidden"!==o
.visibility
)&&/opacity|filter/.test(R
)&&!M
&&0!==z
&&(M
=0),o
._cacheValues
&&E
&&E
[R
]?(M
===a
&&(M
=E
[R
].endValue
+E
[R
].unitType
),B
=i(n
).rootPropertyValueCache
[I
]):x
.Hooks
.registered
[R
]?M
===a
?(B
=x
.getPropertyValue(n
,I
),M
=x
.getPropertyValue(n
,R
,B
)):B
=x
.Hooks
.templates
[I
][1]:M
===a
&&(M
=x
.getPropertyValue(n
,R
));var W
,G
,D
,X
=!1;if(W
=f(R
,M
),M
=W
[0],D
=W
[1],W
=f(R
,z
),z
=W
[0].replace(/^([+-\/*])=/,function(e
,t
){return X
=t
,""}),G
=W
[1],M
=parseFloat(M
)||0,z
=parseFloat(z
)||0,"%"===G
&&(/^(fontSize|lineHeight)$/.test(R
)?(z
/=100,G="em"):/^scale
/.test(R)?(z/=100,G
=""):/(Red|Green|Blue)$/i.test(R
)&&(z
=z
/100*255,G="")),/[\/*]/.test(X))G=D;else if(D!==G&&0!==M)if(0===z)G=D;else{l=l||d();var Y=/margin|padding|left|right|width|text|word|letter/i.test(R)||/X$/.test(R)||"x"===R?"x":"y";switch(D){case"%":M*="x"===Y?l.percentToPxWidth:l.percentToPxHeight;break;case"px":break;default:M*=l[D+"ToPx"]}switch(G){case"%":M*=1/("x"===Y?l.percentToPxWidth:l.percentToPxHeight);break;case"px":break;default:M*=1/l[G+"ToPx"]}}switch(X){case"+":z=M+z;break;case"-":z=M-z;break;case"*":z=M*z;break;case"/":z=M/z}s[R]={rootPropertyValue:B,startValue:M,currentValue:M,endValue:z,unitType:G,easing:q},v.debug&&console.log("tweensContainer ("+R+"): "+JSON.stringify(s[R]),n)}else v.debug&&console.log("Skipping ["+I+"] due to a lack of browser support.")}s.element=n}s.element&&(x.Values.addClass(n,"velocity-animating"),L.push(s),""===o.queue&&(i(n).tweensContainer=s,i(n).opts=o),i(n).isAnimating=!0,w===P-1?(v.State.calls.push([L,m,o,null,T.resolver]),v.State.isTicking===!1&&(v.State.isTicking=!0,c())):w++)}var n=this,o=$.extend({},v.defaults,b),s={},l;switch(i(n)===a&&v.init(n),parseFloat(o.delay)&&o.queue!==!1&&$.queue(n,o.queue,function(e){v.velocityQueueEntryFlag=!0,i(n).delayTimer={setTimeout:setTimeout(e,parseFloat(o.delay)),next:e}}),o.duration.toString().toLowerCase()){case"fast":o.duration=200;break;case"normal":o.duration=y;break;case"slow":o.duration=600;break;default:o.duration=parseFloat(o.duration)||1}v.mock!==!1&&(v.mock===!0?o.duration=o.delay=1:(o.duration*=parseFloat(v.mock)||1,o.delay*=parseFloat(v.mock)||1)),o.easing=u(o.easing,o.duration),o.begin&&!g.isFunction(o.begin)&&(o.begin=null),o.progress&&!g.isFunction(o.progress)&&(o.progress=null),o.complete&&!g.isFunction(o.complete)&&(o.complete=null),o.display!==a&&null!==o.display&&(o.display=o.display.toString().toLowerCase(),"auto"===o.display&&(o.display=v.CSS.Values.getDisplayType(n))),o.visibility!==a&&null!==o.visibility&&(o.visibility=o.visibility.toString().toLowerCase()),o.mobileHA=o.mobileHA&&v.State.isMobile&&!v.State.isGingerbread,o.queue===!1?o.delay?setTimeout(e,o.delay):e():$.queue(n,o.queue,function(t,r){return r===!0?(T.promise&&T.resolver(m),!0):(v.velocityQueueEntryFlag=!0,void e(t))}),""!==o.queue&&"fx"!==o.queue||"inprogress"===$.queue(n)[0]||$.dequeue(n)}var s=arguments[0]&&(arguments[0].p||$.isPlainObject(arguments[0].properties)&&!arguments[0].properties.names||g.isString(arguments[0].properties)),l,f,d,m,h,b;if(g.isWrapped(this)?(l=!1,d=0,m=this,f=this):(l=!0,d=1,m=s?arguments[0].elements||arguments[0].e:arguments[0]),m=o(m)){s?(h=arguments[0].properties||arguments[0].p,b=arguments[0].options||arguments[0].o):(h=arguments[d],b=arguments[d+1]);var P=m.length,w=0;if(!/^(stop|finish)$/i.test(h)&&!$.isPlainObject(b)){var V=d+1;b={};for(var C=V;C<arguments.length;C++)g.isArray(arguments[C])||!/^(fast|normal|slow)$/i.test(arguments[C])&&!/^\d/.test(arguments[C])?g.isString(arguments[C])||g.isArray(arguments[C])?b.easing=arguments[C]:g.isFunction(arguments[C])&&(b.complete=arguments[C]):b.duration=arguments[C]}var T={promise:null,resolver:null,rejecter:null};l&&v.Promise&&(T.promise=new v.Promise(function(e,t){T.resolver=e,T.rejecter=t}));var k;switch(h){case"scroll":k="scroll";break;case"reverse":k="reverse";break;case"finish":case"stop":$.each(m,function(e,t){i(t)&&i(t).delayTimer&&(clearTimeout(i(t).delayTimer.setTimeout),i(t).delayTimer.next&&i(t).delayTimer.next(),delete i(t).delayTimer)});var A=[];return $.each(v.State.calls,function(e,t){t&&$.each(t[1],function(r,n){var o=b===a?"":b;return o===!0||t[2].queue===o||b===a&&t[2].queue===!1?void $.each(m,function(r,a){a===n&&((b===!0||g.isString(b))&&($.each($.queue(a,g.isString(b)?b:""),function(e,t){g.isFunction(t)&&t(null,!0)}),$.queue(a,g.isString(b)?b:"",[])),"stop"===h?(i(a)&&i(a).tweensContainer&&o!==!1&&$.each(i(a).tweensContainer,function(e,t){t.endValue=t.currentValue
222 }),A.push(e)):"finish"===h&&(t[2].duration=1))}):!0})}),"stop"===h&&($.each(A,function(e,t){p(t,!0)}),T.promise&&T.resolver(m)),e();default:if(!$.isPlainObject(h)||g.isEmptyObject(h)){if(g.isString(h)&&v.Redirects[h]){var F=$.extend({},b),E=F.duration,j=F.delay||0;return F.backwards===!0&&(m=$.extend(!0,[],m).reverse()),$.each(m,function(e,t){parseFloat(F.stagger)?F.delay=j+parseFloat(F.stagger)*e:g.isFunction(F.stagger)&&(F.delay=j+F.stagger.call(t,e,P)),F.drag&&(F.duration=parseFloat(E)||(/^(callout|transition)/.test(h)?1e3:y),F.duration=Math.max(F.duration*(F.backwards?1-e/P:(e+1)/P),.75*F.duration,200)),v.Redirects[h].call(t,t,F||{},e,P,m,T.promise?T:a)}),e()}var H="Velocity: First argument ("+h+") was not a property map, a known action, or a registered redirect. Aborting.";return T.promise?T.rejecter(new Error(H)):console.log(H),e()}k="start"}var N={lastParent:null,lastPosition:null,lastFontSize:null,lastPercentToPxWidth:null,lastPercentToPxHeight:null,lastEmToPx:null,remToPx:null,vwToPx:null,vhToPx:null},L=[];$.each(m,function(e,t){g.isNode(t)&&n.call(t)});var F=$.extend({},v.defaults,b),R;if(F.loop=parseInt(F.loop),R=2*F.loop-1,F.loop)for(var O=0;R>O;O++){var z={delay:F.delay,progress:F.progress};O===R-1&&(z.display=F.display,z.visibility=F.visibility,z.complete=F.complete),S(m,"reverse",z)}return e()}};v=$.extend(S,v),v.animate=S;var P=t.requestAnimationFrame||d;return v.State.isMobile||r.hidden===a||r.addEventListener("visibilitychange",function(){r.hidden?(P=function(e){return setTimeout(function(){e(!0)},16)},c()):P=t.requestAnimationFrame||d}),e.Velocity=v,e!==t&&(e.fn.velocity=S,e.fn.velocity.defaults=v.defaults),$.each(["Down","Up"],function(e,t){v.Redirects["slide"+t]=function(e,r,n,o,i,s){var l=$.extend({},r),u=l.begin,c=l.complete,p={height:"",marginTop:"",marginBottom:"",paddingTop:"",paddingBottom:""},f={};l.display===a&&(l.display="Down"===t?"inline"===v.CSS.Values.getDisplayType(e)?"inline-block":"block":"none"),l.begin=function(){u&&u.call(i,i);for(var r in p){f[r]=e.style[r];var a=v.CSS.getPropertyValue(e,r);p[r]="Down"===t?[a,0]:[0,a]}f.overflow=e.style.overflow,e.style.overflow="hidden"},l.complete=function(){for(var t in f)e.style[t]=f[t];c&&c.call(i,i),s&&s.resolver(i)},v(e,p,l)}}),$.each(["In","Out"],function(e,t){v.Redirects["fade"+t]=function(e,r,n,o,i,s){var l=$.extend({},r),u={opacity:"In"===t?1:0},c=l.complete;l.complete=n!==o-1?l.begin=null:function(){c&&c.call(i,i),s&&s.resolver(i)},l.display===a&&(l.display="In"===t?"auto":"none"),v(this,u,l)}}),v}(window.jQuery||window.Zepto||window,window,document)});;!function(a,b,c,d){"use strict";function k(a,b,c){return setTimeout(q(a,c),b)}function l(a,b,c){return Array.isArray(a)?(m(a,c[b],c),!0):!1}function m(a,b,c){var e;if(a)if(a.forEach)a.forEach(b,c);else if(a.length!==d)for(e=0;e<a.length;)b.call(c,a[e],e,a),e++;else for(e in a)a.hasOwnProperty(e)&&b.call(c,a[e],e,a)}function n(a,b,c){for(var e=Object.keys(b),f=0;f<e.length;)(!c||c&&a[e[f]]===d)&&(a[e[f]]=b[e[f]]),f++;return a}function o(a,b){return n(a,b,!0)}function p(a,b,c){var e,d=b.prototype;e=a.prototype=Object.create(d),e.constructor=a,e._super=d,c&&n(e,c)}function q(a,b){return function(){return a.apply(b,arguments)}}function r(a,b){return typeof a==g?a.apply(b?b[0]||d:d,b):a}function s(a,b){return a===d?b:a}function t(a,b,c){m(x(b),function(b){a.addEventListener(b,c,!1)})}function u(a,b,c){m(x(b),function(b){a.removeEventListener(b,c,!1)})}function v(a,b){for(;a;){if(a==b)return!0;a=a.parentNode}return!1}function w(a,b){return a.indexOf(b)>-1}function x(a){return a.trim().split(/\s+/g)}function y(a,b,c){if(a.indexOf&&!c)return a.indexOf(b);for(var d=0;d<a.length;){if(c&&a[d][c]==b||!c&&a[d]===b)return d;d++}return-1}function z(a){return Array.prototype.slice.call(a,0)}function A(a,b,c){for(var d=[],e=[],f=0;f<a.length;){var g=b?a[f][b]:a[f];y(e,g)<0&&d.push(a[f]),e[f]=g,f++}return c&&(d=b?d.sort(function(a,c){return a[b]>c[b]}):d.sort()),d}function B(a,b){for(var c,f,g=b[0].toUpperCase()+b.slice(1),h=0;h<e.length;){if(c=e[h],f=c?c+g:b,f in a)return f;h++}return d}function D(){return C++}function E(a){var b=a.ownerDocument;return b.defaultView||b.parentWindow}function ab(a,b){var c=this;this.manager=a,this.callback=b,this.element=a.element,this.target=a.options.inputTarget,this.domHandler=function(b){r(a.options.enable,[a])&&c.handler(b)},this.init()}function bb(a){var b,c=a.options.inputClass;return b=c?c:H?wb:I?Eb:G?Gb:rb,new b(a,cb)}function cb(a,b,c){var d=c.pointers.length,e=c.changedPointers.length,f=b&O&&0===d-e,g=b&(Q|R)&&0===d-e;c.isFirst=!!f,c.isFinal=!!g,f&&(a.session={}),c.eventType=b,db(a,c),a.emit("hammer.input",c),a.recognize(c),a.session.prevInput=c}function db(a,b){var c=a.session,d=b.pointers,e=d.length;c.firstInput||(c.firstInput=gb(b)),e>1&&!c.firstMultiple?c.firstMultiple=gb(b):1===e&&(c.firstMultiple=!1);var f=c.firstInput,g=c.firstMultiple,h=g?g.center:f.center,i=b.center=hb(d);b.timeStamp=j(),b.deltaTime=b.timeStamp-f.timeStamp,b.angle=lb(h,i),b.distance=kb(h,i),eb(c,b),b.offsetDirection=jb(b.deltaX,b.deltaY),b.scale=g?nb(g.pointers,d):1,b.rotation=g?mb(g.pointers,d):0,fb(c,b);var k=a.element;v(b.srcEvent.target,k)&&(k=b.srcEvent.target),b.target=k}function eb(a,b){var c=b.center,d=a.offsetDelta||{},e=a.prevDelta||{},f=a.prevInput||{};(b.eventType===O||f.eventType===Q)&&(e=a.prevDelta={x:f.deltaX||0,y:f.deltaY||0},d=a.offsetDelta={x:c.x,y:c.y}),b.deltaX=e.x+(c.x-d.x),b.deltaY=e.y+(c.y-d.y)}function fb(a,b){var f,g,h,j,c=a.lastInterval||b,e=b.timeStamp-c.timeStamp;if(b.eventType!=R&&(e>N||c.velocity===d)){var k=c.deltaX-b.deltaX,l=c.deltaY-b.deltaY,m=ib(e,k,l);g=m.x,h=m.y,f=i(m.x)>i(m.y)?m.x:m.y,j=jb(k,l),a.lastInterval=b}else f=c.velocity,g=c.velocityX,h=c.velocityY,j=c.direction;b.velocity=f,b.velocityX=g,b.velocityY=h,b.direction=j}function gb(a){for(var b=[],c=0;c<a.pointers.length;)b[c]={clientX:h(a.pointers[c].clientX),clientY:h(a.pointers[c].clientY)},c++;return{timeStamp:j(),pointers:b,center:hb(b),deltaX:a.deltaX,deltaY:a.deltaY}}function hb(a){var b=a.length;if(1===b)return{x:h(a[0].clientX),y:h(a[0].clientY)};for(var c=0,d=0,e=0;b>e;)c+=a[e].clientX,d+=a[e].clientY,e++;return{x:h(c/b),y:h(d/b)}}function ib(a,b,c){return{x:b/a||0,y:c/a||0}}function jb(a,b){return a===b?S:i(a)>=i(b)?a>0?T:U:b>0?V:W}function kb(a,b,c){c||(c=$);var d=b[c[0]]-a[c[0]],e=b[c[1]]-a[c[1]];return Math.sqrt(d*d+e*e)}function lb(a,b,c){c||(c=$);var d=b[c[0]]-a[c[0]],e=b[c[1]]-a[c[1]];return 180*Math.atan2(e,d)/Math.PI}function mb(a,b){return lb(b[1],b[0],_)-lb(a[1],a[0],_)}function nb(a,b){return kb(b[0],b[1],_)/kb(a[0],a[1],_)}function rb(){this.evEl=pb,this.evWin=qb,this.allow=!0,this.pressed=!1,ab.apply(this,arguments)}function wb(){this.evEl=ub,this.evWin=vb,ab.apply(this,arguments),this.store=this.manager.session.pointerEvents=[]}function Ab(){this.evTarget=yb,this.evWin=zb,this.started=!1,ab.apply(this,arguments)}function Bb(a,b){var c=z(a.touches),d=z(a.changedTouches);return b&(Q|R)&&(c=A(c.concat(d),"identifier",!0)),[c,d]}function Eb(){this.evTarget=Db,this.targetIds={},ab.apply(this,arguments)}function Fb(a,b){var c=z(a.touches),d=this.targetIds;if(b&(O|P)&&1===c.length)return d[c[0].identifier]=!0,[c,c];var e,f,g=z(a.changedTouches),h=[],i=this.target;if(f=c.filter(function(a){return v(a.target,i)}),b===O)for(e=0;e<f.length;)d[f[e].identifier]=!0,e++;for(e=0;e<g.length;)d[g[e].identifier]&&h.push(g[e]),b&(Q|R)&&delete d[g[e].identifier],e++;return h.length?[A(f.concat(h),"identifier",!0),h]:void 0}function Gb(){ab.apply(this,arguments);var a=q(this.handler,this);this.touch=new Eb(this.manager,a),this.mouse=new rb(this.manager,a)}function Pb(a,b){this.manager=a,this.set(b)}function Qb(a){if(w(a,Mb))return Mb;var b=w(a,Nb),c=w(a,Ob);return b&&c?Nb+" "+Ob:b||c?b?Nb:Ob:w(a,Lb)?Lb:Kb}function Yb(a){this.id=D(),this.manager=null,this.options=o(a||{},this.defaults),this.options.enable=s(this.options.enable,!0),this.state=Rb,this.simultaneous={},this.requireFail=[]}function Zb(a){return a&Wb?"cancel":a&Ub?"end":a&Tb?"move":a&Sb?"start":""}function $b(a){return a==W?"down":a==V?"up":a==T?"left":a==U?"right":""}function _b(a,b){var c=b.manager;return c?c.get(a):a}function ac(){Yb.apply(this,arguments)}function bc(){ac.apply(this,arguments),this.pX=null,this.pY=null}function cc(){ac.apply(this,arguments)}function dc(){Yb.apply(this,arguments),this._timer=null,this._input=null}function ec(){ac.apply(this,arguments)}function fc(){ac.apply(this,arguments)}function gc(){Yb.apply(this,arguments),this.pTime=!1,this.pCenter=!1,this._timer=null,this._input=null,this.count=0}function hc(a,b){return b=b||{},b.recognizers=s(b.recognizers,hc.defaults.preset),new kc(a,b)}function kc(a,b){b=b||{},this.options=o(b,hc.defaults),this.options.inputTarget=this.options.inputTarget||a,this.handlers={},this.session={},this.recognizers=[],this.element=a,this.input=bb(this),this.touchAction=new Pb(this,this.options.touchAction),lc(this,!0),m(b.recognizers,function(a){var b=this.add(new a[0](a[1]));a[2]&&b.recognizeWith(a[2]),a[3]&&b.requireFailure(a[3])},this)}function lc(a,b){var c=a.element;m(a.options.cssProps,function(a,d){c.style[B(c.style,d)]=b?a:""})}function mc(a,c){var d=b.createEvent("Event");d.initEvent(a,!0,!0),d.gesture=c,c.target.dispatchEvent(d)}var e=["","webkit","moz","MS","ms","o"],f=b.createElement("div"),g="function",h=Math.round,i=Math.abs,j=Date.now,C=1,F=/mobile|tablet|ip(ad|hone|od)|android/i,G="ontouchstart"in a,H=B(a,"PointerEvent")!==d,I=G&&F.test(navigator.userAgent),J="touch",K="pen",L="mouse",M="kinect",N=25,O=1,P=2,Q=4,R=8,S=1,T=2,U=4,V=8,W=16,X=T|U,Y=V|W,Z=X|Y,$=["x","y"],_=["clientX","clientY"];ab.prototype={handler:function(){},init:function(){this.evEl&&t(this.element,this.evEl,this.domHandler),this.evTarget&&t(this.target,this.evTarget,this.domHandler),this.evWin&&t(E(this.element),this.evWin,this.domHandler)},destroy:function(){this.evEl&&u(this.element,this.evEl,this.domHandler),this.evTarget&&u(this.target,this.evTarget,this.domHandler),this.evWin&&u(E(this.element),this.evWin,this.domHandler)}};var ob={mousedown:O,mousemove:P,mouseup:Q},pb="mousedown",qb="mousemove mouseup";p(rb,ab,{handler:function(a){var b=ob[a.type];b&O&&0===a.button&&(this.pressed=!0),b&P&&1!==a.which&&(b=Q),this.pressed&&this.allow&&(b&Q&&(this.pressed=!1),this.callback(this.manager,b,{pointers:[a],changedPointers:[a],pointerType:L,srcEvent:a}))}});var sb={pointerdown:O,pointermove:P,pointerup:Q,pointercancel:R,pointerout:R},tb={2:J,3:K,4:L,5:M},ub="pointerdown",vb="pointermove pointerup pointercancel";a.MSPointerEvent&&(ub="MSPointerDown",vb="MSPointerMove MSPointerUp MSPointerCancel"),p(wb,ab,{handler:function(a){var b=this.store,c=!1,d=a.type.toLowerCase().replace("ms",""),e=sb[d],f=tb[a.pointerType]||a.pointerType,g=f==J,h=y(b,a.pointerId,"pointerId");e&O&&(0===a.button||g)?0>h&&(b.push(a),h=b.length-1):e&(Q|R)&&(c=!0),0>h||(b[h]=a,this.callback(this.manager,e,{pointers:b,changedPointers:[a],pointerType:f,srcEvent:a}),c&&b.splice(h,1))}});var xb={touchstart:O,touchmove:P,touchend:Q,touchcancel:R},yb="touchstart",zb="touchstart touchmove touchend touchcancel";p(Ab,ab,{handler:function(a){var b=xb[a.type];if(b===O&&(this.started=!0),this.started){var c=Bb.call(this,a,b);b&(Q|R)&&0===c[0].length-c[1].length&&(this.started=!1),this.callback(this.manager,b,{pointers:c[0],changedPointers:c[1],pointerType:J,srcEvent:a})}}});var Cb={touchstart:O,touchmove:P,touchend:Q,touchcancel:R},Db="touchstart touchmove touchend touchcancel";p(Eb,ab,{handler:function(a){var b=Cb[a.type],c=Fb.call(this,a,b);c&&this.callback(this.manager,b,{pointers:c[0],changedPointers:c[1],pointerType:J,srcEvent:a})}}),p(Gb,ab,{handler:function(a,b,c){var d=c.pointerType==J,e=c.pointerType==L;if(d)this.mouse.allow=!1;else if(e&&!this.mouse.allow)return;b&(Q|R)&&(this.mouse.allow=!0),this.callback(a,b,c)},destroy:function(){this.touch.destroy(),this.mouse.destroy()}});var Hb=B(f.style,"touchAction"),Ib=Hb!==d,Jb="compute",Kb="auto",Lb="manipulation",Mb="none",Nb="pan-x",Ob="pan-y";Pb.prototype={set:function(a){a==Jb&&(a=this.compute()),Ib&&(this.manager.element.style[Hb]=a),this.actions=a.toLowerCase().trim()},update:function(){this.set(this.manager.options.touchAction)},compute:function(){var a=[];return m(this.manager.recognizers,function(b){r(b.options.enable,[b])&&(a=a.concat(b.getTouchAction()))}),Qb(a.join(" "))},preventDefaults:function(a){if(!Ib){var b=a.srcEvent,c=a.offsetDirection;if(this.manager.session.prevented)return b.preventDefault(),void 0;var d=this.actions,e=w(d,Mb),f=w(d,Ob),g=w(d,Nb);return e||f&&c&X||g&&c&Y?this.preventSrc(b):void 0}},preventSrc:function(a){this.manager.session.prevented=!0,a.preventDefault()}};var Rb=1,Sb=2,Tb=4,Ub=8,Vb=Ub,Wb=16,Xb=32;Yb.prototype={defaults:{},set:function(a){return n(this.options,a),this.manager&&this.manager.touchAction.update(),this},recognizeWith:function(a){if(l(a,"recognizeWith",this))return this;var b=this.simultaneous;return a=_b(a,this),b[a.id]||(b[a.id]=a,a.recognizeWith(this)),this},dropRecognizeWith:function(a){return l(a,"dropRecognizeWith",this)?this:(a=_b(a,this),delete this.simultaneous[a.id],this)},requireFailure:function(a){if(l(a,"requireFailure",this))return this;var b=this.requireFail;return a=_b(a,this),-1===y(b,a)&&(b.push(a),a.requireFailure(this)),this},dropRequireFailure:function(a){if(l(a,"dropRequireFailure",this))return this;a=_b(a,this);var b=y(this.requireFail,a);return b>-1&&this.requireFail.splice(b,1),this},hasRequireFailures:function(){return this.requireFail.length>0},canRecognizeWith:function(a){return!!this.simultaneous[a.id]},emit:function(a){function d(d){b.manager.emit(b.options.event+(d?Zb(c):""),a)}var b=this,c=this.state;Ub>c&&d(!0),d(),c>=Ub&&d(!0)},tryEmit:function(a){return this.canEmit()?this.emit(a):(this.state=Xb,void 0)},canEmit:function(){for(var a=0;a<this.requireFail.length;){if(!(this.requireFail[a].state&(Xb|Rb)))return!1;a++}return!0},recognize:function(a){var b=n({},a);return r(this.options.enable,[this,b])?(this.state&(Vb|Wb|Xb)&&(this.state=Rb),this.state=this.process(b),this.state&(Sb|Tb|Ub|Wb)&&this.tryEmit(b),void 0):(this.reset(),this.state=Xb,void 0)},process:function(){},getTouchAction:function(){},reset:function(){}},p(ac,Yb,{defaults:{pointers:1},attrTest:function(a){var b=this.options.pointers;return 0===b||a.pointers.length===b},process:function(a){var b=this.state,c=a.eventType,d=b&(Sb|Tb),e=this.attrTest(a);return d&&(c&R||!e)?b|Wb:d||e?c&Q?b|Ub:b&Sb?b|Tb:Sb:Xb}}),p(bc,ac,{defaults:{event:"pan",threshold:10,pointers:1,direction:Z},getTouchAction:function(){var a=this.options.direction,b=[];return a&X&&b.push(Ob),a&Y&&b.push(Nb),b},directionTest:function(a){var b=this.options,c=!0,d=a.distance,e=a.direction,f=a.deltaX,g=a.deltaY;return e&b.direction||(b.direction&X?(e=0===f?S:0>f?T:U,c=f!=this.pX,d=Math.abs(a.deltaX)):(e=0===g?S:0>g?V:W,c=g!=this.pY,d=Math.abs(a.deltaY))),a.direction=e,c&&d>b.threshold&&e&b.direction},attrTest:function(a){return ac.prototype.attrTest.call(this,a)&&(this.state&Sb||!(this.state&Sb)&&this.directionTest(a))},emit:function(a){this.pX=a.deltaX,this.pY=a.deltaY;var b=$b(a.direction);b&&this.manager.emit(this.options.event+b,a),this._super.emit.call(this,a)}}),p(cc,ac,{defaults:{event:"pinch",threshold:0,pointers:2},getTouchAction:function(){return[Mb]},attrTest:function(a){return this._super.attrTest.call(this,a)&&(Math.abs(a.scale-1)>this.options.threshold||this.state&Sb)},emit:function(a){if(this._super.emit.call(this,a),1!==a.scale){var b=a.scale<1?"in":"out";this.manager.emit(this.options.event+b,a)}}}),p(dc,Yb,{defaults:{event:"press",pointers:1,time:500,threshold:5},getTouchAction:function(){return[Kb]},process:function(a){var b=this.options,c=a.pointers.length===b.pointers,d=a.distance<b.threshold,e=a.deltaTime>b.time;if(this._input=a,!d||!c||a.eventType&(Q|R)&&!e)this.reset();else if(a.eventType&O)this.reset(),this._timer=k(function(){this.state=Vb,this.tryEmit()},b.time,this);else if(a.eventType&Q)return Vb;return Xb},reset:function(){clearTimeout(this._timer)},emit:function(a){this.state===Vb&&(a&&a.eventType&Q?this.manager.emit(this.options.event+"up",a):(this._input.timeStamp=j(),this.manager.emit(this.options.event,this._input)))}}),p(ec,ac,{defaults:{event:"rotate",threshold:0,pointers:2},getTouchAction:function(){return[Mb]},attrTest:function(a){return this._super.attrTest.call(this,a)&&(Math.abs(a.rotation)>this.options.threshold||this.state&Sb)}}),p(fc,ac,{defaults:{event:"swipe",threshold:10,velocity:.65,direction:X|Y,pointers:1},getTouchAction:function(){return bc.prototype.getTouchAction.call(this)},attrTest:function(a){var c,b=this.options.direction;return b&(X|Y)?c=a.velocity:b&X?c=a.velocityX:b&Y&&(c=a.velocityY),this._super.attrTest.call(this,a)&&b&a.direction&&a.distance>this.options.threshold&&i(c)>this.options.velocity&&a.eventType&Q},emit:function(a){var b=$b(a.direction);b&&this.manager.emit(this.options.event+b,a),this.manager.emit(this.options.event,a)}}),p(gc,Yb,{defaults:{event:"tap",pointers:1,taps:1,interval:300,time:250,threshold:2,posThreshold:10},getTouchAction:function(){return[Lb]},process:function(a){var b=this.options,c=a.pointers.length===b.pointers,d=a.distance<b.threshold,e=a.deltaTime<b.time;if(this.reset(),a.eventType&O&&0===this.count)return this.failTimeout();if(d&&e&&c){if(a.eventType!=Q)return this.failTimeout();var f=this.pTime?a.timeStamp-this.pTime<b.interval:!0,g=!this.pCenter||kb(this.pCenter,a.center)<b.posThreshold;this.pTime=a.timeStamp,this.pCenter=a.center,g&&f?this.count+=1:this.count=1,this._input=a;var h=this.count%b.taps;if(0===h)return this.hasRequireFailures()?(this._timer=k(function(){this.state=Vb,this.tryEmit()},b.interval,this),Sb):Vb}return Xb},failTimeout:function(){return this._timer=k(function(){this.state=Xb},this.options.interval,this),Xb},reset:function(){clearTimeout(this._timer)},emit:function(){this.state==Vb&&(this._input.tapCount=this.count,this.manager.emit(this.options.event,this._input))}}),hc.VERSION="2.0.4",hc.defaults={domEvents:!1,touchAction:Jb,enable:!0,inputTarget:null,inputClass:null,preset:[[ec,{enable:!1}],[cc,{enable:!1},["rotate"]],[fc,{direction:X}],[bc,{direction:X},["swipe"]],[gc],[gc,{event:"doubletap",taps:2},["tap"]],[dc]],cssProps:{userSelect:"default",touchSelect:"none",touchCallout:"none",contentZooming:"none",userDrag:"none",tapHighlightColor:"rgba(0,0,0,0)"}};var ic=1,jc=2;kc.prototype={set:function(a){return n(this.options,a),a.touchAction&&this.touchAction.update(),a.inputTarget&&(this.input.destroy(),this.input.target=a.inputTarget,this.input.init()),this},stop:function(a){this.session.stopped=a?jc:ic},recognize:function(a){var b=this.session;if(!b.stopped){this.touchAction.preventDefaults(a);var c,d=this.recognizers,e=b.curRecognizer;(!e||e&&e.state&Vb)&&(e=b.curRecognizer=null);for(var f=0;f<d.length;)c=d[f],b.stopped===jc||e&&c!=e&&!c.canRecognizeWith(e)?c.reset():c.recognize(a),!e&&c.state&(Sb|Tb|Ub)&&(e=b.curRecognizer=c),f++}},get:function(a){if(a instanceof Yb)return a;for(var b=this.recognizers,c=0;c<b.length;c++)if(b[c].options.event==a)return b[c];return null},add:function(a){if(l(a,"add",this))return this;var b=this.get(a.options.event);return b&&this.remove(b),this.recognizers.push(a),a.manager=this,this.touchAction.update(),a},remove:function(a){if(l(a,"remove",this))return this;var b=this.recognizers;return a=this.get(a),b.splice(y(b,a),1),this.touchAction.update(),this},on:function(a,b){var c=this.handlers;return m(x(a),function(a){c[a]=c[a]||[],c[a].push(b)}),this},off:function(a,b){var c=this.handlers;return m(x(a),function(a){b?c[a].splice(y(c[a],b),1):delete c[a]}),this},emit:function(a,b){this.options.domEvents&&mc(a,b);var c=this.handlers[a]&&this.handlers[a].slice();if(c&&c.length){b.type=a,b.preventDefault=function(){b.srcEvent.preventDefault()};for(var d=0;d<c.length;)c[d](b),d++}},destroy:function(){this.element&&lc(this,!1),this.handlers={},this.session={},this.input.destroy(),this.element=null}},n(hc,{INPUT_START:O,INPUT_MOVE:P,INPUT_END:Q,INPUT_CANCEL:R,STATE_POSSIBLE:Rb,STATE_BEGAN:Sb,STATE_CHANGED:Tb,STATE_ENDED:Ub,STATE_RECOGNIZED:Vb,STATE_CANCELLED:Wb,STATE_FAILED:Xb,DIRECTION_NONE:S,DIRECTION_LEFT:T,DIRECTION_RIGHT:U,DIRECTION_UP:V,DIRECTION_DOWN:W,DIRECTION_HORIZONTAL:X,DIRECTION_VERTICAL:Y,DIRECTION_ALL:Z,Manager:kc,Input:ab,TouchAction:Pb,TouchInput:Eb,MouseInput:rb,PointerEventInput:wb,TouchMouseInput:Gb,SingleTouchInput:Ab,Recognizer:Yb,AttrRecognizer:ac,Tap:gc,Pan:bc,Swipe:fc,Pinch:cc,Rotate:ec,Press:dc,on:t,off:u,each:m,merge:o,extend:n,inherit:p,bindFn:q,prefixed:B}),typeof define==g&&define.amd?define(function(){return hc}):"undefined"!=typeof module&&module.exports?module.exports=hc:a[c]=hc}(window,document,"Hammer");;(function(factory) {
223 if (typeof define === 'function' && define.amd) {
224 define(['jquery', 'hammerjs'], factory);
225 } else if (typeof exports === 'object') {
226 factory(require('jquery'), require('hammerjs'));
228 factory(jQuery, Hammer);
230 }(function($, Hammer) {
231 function hammerify(el, options) {
233 if(!$el.data("hammer")) {
234 $el.data("hammer", new Hammer($el[0], options));
238 $.fn.hammer = function(options) {
239 return this.each(function() {
240 hammerify(this, options);
244 // extend the emit method to also trigger jQuery events
245 Hammer.Manager.prototype.emit = (function(originalEmit) {
246 return function(type, data) {
247 originalEmit.call(this, type, data);
248 $(this.element).trigger({
253 })(Hammer.Manager.prototype.emit);
258 Materialize.guid = (function() {
260 return Math.floor((1 + Math.random()) * 0x10000)
265 return s4() + s4() + '-' + s4() + '-' + s4() + '-' +
266 s4() + '-' + s4() + s4() + s4();
270 Materialize.elementOrParentIsFixed = function(element) {
271 var $element = $(element);
272 var $checkElements = $element.add($element.parents());
274 $checkElements.each(function(){
275 if ($(this).css("position") === "fixed") {
283 // Velocity has conflicts when loaded with jQuery, this will check for it
292 $.fn.collapsible = function(options) {
297 options = $.extend(defaults, options);
300 return this.each(function() {
304 var $panel_headers = $(this).find('> li > .collapsible-header');
306 var collapsible_type = $this.data("collapsible");
308 // Turn off any existing event handlers
309 $this.off('click.collapse', '.collapsible-header');
310 $panel_headers.off('click.collapse');
318 function accordionOpen(object
) {
319 $panel_headers
= $this.find('> li > .collapsible-header');
320 if (object
.hasClass('active')) {
321 object
.parent().addClass('active');
324 object
.parent().removeClass('active');
326 if (object
.parent().hasClass('active')){
327 object
.siblings('.collapsible-body').stop(true,false).slideDown({ duration: 350, easing: "easeOutQuart", queue: false, complete: function() {$(this).css('height', '');}});
330 object
.siblings('.collapsible-body').stop(true,false).slideUp({ duration: 350, easing: "easeOutQuart", queue: false, complete: function() {$(this).css('height', '');}});
333 $panel_headers
.not(object
).removeClass('active').parent().removeClass('active');
334 $panel_headers
.not(object
).parent().children('.collapsible-body').stop(true,false).slideUp(
337 easing: "easeOutQuart",
341 $(this).css('height', '');
347 function expandableOpen(object
) {
348 if (object
.hasClass('active')) {
349 object
.parent().addClass('active');
352 object
.parent().removeClass('active');
354 if (object
.parent().hasClass('active')){
355 object
.siblings('.collapsible-body').stop(true,false).slideDown({ duration: 350, easing: "easeOutQuart", queue: false, complete: function() {$(this).css('height', '');}});
358 object
.siblings('.collapsible-body').stop(true,false).slideUp({ duration: 350, easing: "easeOutQuart", queue: false, complete: function() {$(this).css('height', '');}});
363 * Check if object is children of panel header
364 * @param {Object} object Jquery object
365 * @return {Boolean} true if it is children
367 function isChildrenOfPanelHeader(object
) {
369 var panelHeader
= getPanelHeader(object
);
371 return panelHeader
.length
> 0;
375 * Get panel header from a children element
376 * @param {Object} object Jquery object
377 * @return {Object} panel header object
379 function getPanelHeader(object
) {
381 return object
.closest('li > .collapsible-header');
384 /***** End Helper Functions *****/
388 if (options
.accordion
|| collapsible_type
=== "accordion" || collapsible_type
=== undefined) { // Handle Accordion
389 // Add click handler to only direct collapsible header children
390 $panel_headers
= $this.find('> li > .collapsible-header');
391 $panel_headers
.on('click.collapse', function (e
) {
392 var element
= $(e
.target
);
394 if (isChildrenOfPanelHeader(element
)) {
395 element
= getPanelHeader(element
);
398 element
.toggleClass('active');
399 accordionOpen(element
);
402 accordionOpen($panel_headers
.filter('.active').first());
404 else { // Handle Expandables
405 $panel_headers
.each(function () {
406 // Add click handler to only direct collapsible header children
407 $(this).on('click.collapse', function (e
) {
408 var element
= $(e
.target
);
409 if (isChildrenOfPanelHeader(element
)) {
410 element
= getPanelHeader(element
);
412 element
.toggleClass('active');
413 expandableOpen(element
);
415 // Open any bodies that have the active class
416 if ($(this).hasClass('active')) {
417 expandableOpen($(this));
426 $(document
).ready(function(){
427 $('.collapsible').collapsible();
429 }( jQuery
));;(function ($) {
431 // Add posibility to scroll to selected option
432 // usefull for select for example
433 $.fn
.scrollTo = function(elem
) {
434 $(this).scrollTop($(this).scrollTop() - $(this).offset().top
+ $(elem
).offset().top
);
438 $.fn
.dropdown = function (option
) {
442 constrain_width: true, // Constrains width of dropdown to the activator
444 gutter: 0, // Spacing from edge
448 this.each(function(){
449 var origin
= $(this);
450 var options
= $.extend({}, defaults
, option
);
453 var activates
= $("#"+ origin
.attr('data-activates'));
455 function updateOptions() {
456 if (origin
.data('induration') !== undefined)
457 options
.inDuration
= origin
.data('inDuration');
458 if (origin
.data('outduration') !== undefined)
459 options
.outDuration
= origin
.data('outDuration');
460 if (origin
.data('constrainwidth') !== undefined)
461 options
.constrain_width
= origin
.data('constrainwidth');
462 if (origin
.data('hover') !== undefined)
463 options
.hover
= origin
.data('hover');
464 if (origin
.data('gutter') !== undefined)
465 options
.gutter
= origin
.data('gutter');
466 if (origin
.data('beloworigin') !== undefined)
467 options
.belowOrigin
= origin
.data('beloworigin');
472 // Attach dropdown to its activator
473 origin
.after(activates
);
476 Helper function to position and resize dropdown.
477 Used in hover and click handler.
479 function placeDropdown() {
480 // Check html data attributes
483 // Set Dropdown state
484 activates
.addClass('active');
487 if (options
.constrain_width
=== true) {
488 activates
.css('width', origin
.outerWidth());
491 if (options
.belowOrigin
=== true) {
492 offset
= origin
.height();
495 // Handle edge alignment
496 var offsetLeft
= origin
.offset().left
;
497 var width_difference
= 0;
498 var gutter_spacing
= options
.gutter
;
501 if (offsetLeft
+ activates
.innerWidth() > $(window
).width()) {
502 width_difference
= origin
.innerWidth() - activates
.innerWidth();
503 gutter_spacing
= gutter_spacing
* -1;
508 position: 'absolute',
509 top: origin
.position().top
+ offset
,
510 left: origin
.position().left
+ width_difference
+ gutter_spacing
516 activates
.stop(true, true).css('opacity', 0)
519 duration: options
.inDuration
,
520 easing: 'easeOutCubic',
521 complete: function() {
522 $(this).css('height', '');
525 .animate( {opacity: 1}, {queue: false, duration: options
.inDuration
, easing: 'easeOutSine'});
528 function hideDropdown() {
529 activates
.fadeOut(options
.outDuration
);
530 activates
.removeClass('active');
536 origin
.unbind('click.' + origin
.attr('id'));
537 // Hover handler to show dropdown
538 origin
.on('mouseenter', function(e
){ // Mouse over
539 if (open
=== false) {
544 origin
.on('mouseleave', function(e
){
545 // If hover on origin then to something other than dropdown content, then close
546 var toEl
= e
.toElement
|| e
.relatedTarget
; // added browser compatibility for target element
547 if(!$(toEl
).closest('.dropdown-content').is(activates
)) {
548 activates
.stop(true, true);
554 activates
.on('mouseleave', function(e
){ // Mouse out
555 var toEl
= e
.toElement
|| e
.relatedTarget
;
556 if(!$(toEl
).closest('.dropdown-button').is(origin
)) {
557 activates
.stop(true, true);
566 // Click handler to show dropdown
567 origin
.unbind('click.' + origin
.attr('id'));
568 origin
.bind('click.'+origin
.attr('id'), function(e
){
570 if ( origin
[0] == e
.currentTarget
&& ($(e
.target
).closest('.dropdown-content').length
=== 0) ) {
571 e
.preventDefault(); // Prevents button click from moving window
575 // If origin is clicked and menu is open, close menu
577 if (origin
.hasClass('active')) {
579 $(document
).unbind('click.' + activates
.attr('id'));
582 // If menu open, add click close handler to document
583 if (activates
.hasClass('active')) {
584 $(document
).bind('click.'+ activates
.attr('id'), function (e
) {
585 if (!activates
.is(e
.target
) && !origin
.is(e
.target
) && (!origin
.find(e
.target
).length
> 0) ) {
587 $(document
).unbind('click.' + activates
.attr('id'));
595 // Listen to open and close event - useful for select component
596 origin
.on('open', placeDropdown
);
597 origin
.on('close', hideDropdown
);
601 }; // End dropdown plugin
603 $(document
).ready(function(){
604 $('.dropdown-button').dropdown();
610 _generateID = function() {
612 return 'materialize-lean-overlay-' + _lastID
;
616 openModal: function(options
) {
618 $('body').css('overflow', 'hidden');
629 overlayID
= _generateID(),
631 $overlay
= $('<div class="lean-overlay"></div>'),
634 // Store a reference of the overlay
635 $overlay
.attr('id', overlayID
).css('z-index', 1000 + lStack
* 2);
636 $modal
.data('overlay-id', overlayID
).css('z-index', 1000 + lStack
* 2 + 1);
638 $("body").append($overlay
);
641 options
= $.extend(defaults
, options
);
643 if (options
.dismissible
) {
644 $overlay
.click(function() {
645 $modal
.closeModal(options
);
648 $(document
).on('keyup.leanModal' + overlayID
, function(e
) {
649 if (e
.keyCode
=== 27) { // ESC key
650 $modal
.closeModal(options
);
655 $modal
.find(".modal-close").on('click.close', function(e
) {
656 $modal
.closeModal(options
);
659 $overlay
.css({ display : "block", opacity : 0 });
666 $overlay
.velocity({opacity: options
.opacity
}, {duration: options
.in_duration
, queue: false, ease: "easeOutCubic"});
667 $modal
.data('associated-overlay', $overlay
[0]);
669 // Define Bottom Sheet animation
670 if ($modal
.hasClass('bottom-sheet')) {
671 $modal
.velocity({bottom: "0", opacity: 1}, {
672 duration: options
.in_duration
,
674 ease: "easeOutCubic",
675 // Handle modal ready callback
676 complete: function() {
677 if (typeof(options
.ready
) === "function") {
684 $.Velocity
.hook($modal
, "scaleX", 0.7);
685 $modal
.css({ top: options
.starting_top
});
686 $modal
.velocity({top: "10%", opacity: 1, scaleX: '1'}, {
687 duration: options
.in_duration
,
689 ease: "easeOutCubic",
690 // Handle modal ready callback
691 complete: function() {
692 if (typeof(options
.ready
) === "function") {
704 closeModal: function(options
) {
710 overlayID
= $modal
.data('overlay-id'),
711 $overlay
= $('#' + overlayID
);
713 options
= $.extend(defaults
, options
);
716 $('body').css('overflow', '');
718 $modal
.find('.modal-close').off('click.close');
719 $(document
).off('keyup.leanModal' + overlayID
);
721 $overlay
.velocity( { opacity: 0}, {duration: options
.out_duration
, queue: false, ease: "easeOutQuart"});
724 // Define Bottom Sheet animation
725 if ($modal
.hasClass('bottom-sheet')) {
726 $modal
.velocity({bottom: "-100%", opacity: 0}, {
727 duration: options
.out_duration
,
729 ease: "easeOutCubic",
730 // Handle modal ready callback
731 complete: function() {
732 $overlay
.css({display:"none"});
734 // Call complete callback
735 if (typeof(options
.complete
) === "function") {
745 { top: options
.starting_top
, opacity: 0, scaleX: 0.7}, {
746 duration: options
.out_duration
,
750 $(this).css('display', 'none');
751 // Call complete callback
752 if (typeof(options
.complete
) === "function") {
765 leanModal: function(option
) {
766 return this.each(function() {
772 options
= $.extend(defaults
, option
);
775 $(this).click(function(e
) {
776 options
.starting_top
= ($(this).offset().top
- $(window
).scrollTop()) /1.15;
777 var modal_id
= $(this).attr("href") || '#' + $(this).data('target');
778 $(modal_id
).openModal(options
);
780 }); // done set on click
787 $.fn
.materialbox = function () {
789 return this.each(function() {
791 if ($(this).hasClass('initialized')) {
795 $(this).addClass('initialized');
797 var overlayActive
= false;
798 var doneAnimating
= true;
799 var inDuration
= 275;
800 var outDuration
= 200;
801 var origin
= $(this);
802 var placeholder
= $('<div></div>').addClass('material-placeholder');
803 var originalWidth
= 0;
804 var originalHeight
= 0;
805 origin
.wrap(placeholder
);
808 origin
.on('click', function(){
809 var placeholder
= origin
.parent('.material-placeholder');
810 var windowWidth
= window
.innerWidth
;
811 var windowHeight
= window
.innerHeight
;
812 var originalWidth
= origin
.width();
813 var originalHeight
= origin
.height();
816 // If already modal, return to original
817 if (doneAnimating
=== false) {
821 else if (overlayActive
&& doneAnimating
===true) {
828 doneAnimating
= false;
829 origin
.addClass('active');
830 overlayActive
= true;
832 // Set positioning for placeholder
835 width: placeholder
[0].getBoundingClientRect().width
,
836 height: placeholder
[0].getBoundingClientRect().height
,
837 position: 'relative',
845 origin
.css({position: 'absolute', 'z-index': 1000})
846 .data('width', originalWidth
)
847 .data('height', originalHeight
);
850 var overlay
= $('<div id="materialbox-overlay"></div>')
855 if (doneAnimating
=== true)
859 $('body').append(overlay
);
860 overlay
.velocity({opacity: 1}, {duration: inDuration
, queue: false, easing: 'easeOutQuad'}
864 // Add and animate caption if it exists
865 if (origin
.data('caption') !== "") {
866 var $photo_caption
= $('<div class="materialbox-caption"></div>');
867 $photo_caption
.text(origin
.data('caption'));
868 $('body').append($photo_caption
);
869 $photo_caption
.css({ "display": "inline" });
870 $photo_caption
.velocity({opacity: 1}, {duration: inDuration
, queue: false, easing: 'easeOutQuad'});
877 var widthPercent
= originalWidth
/ windowWidth
;
878 var heightPercent
= originalHeight
/ windowHeight
;
882 if (widthPercent
> heightPercent
) {
883 ratio
= originalHeight
/ originalWidth
;
884 newWidth
= windowWidth
* 0.9;
885 newHeight
= windowWidth
* 0.9 * ratio
;
888 ratio
= originalWidth
/ originalHeight
;
889 newWidth
= (windowHeight
* 0.9) * ratio
;
890 newHeight
= windowHeight
* 0.9;
893 // Animate image + set z-index
894 if(origin
.hasClass('responsive-img')) {
895 origin
.velocity({'max-width': newWidth
, 'width': originalWidth
}, {duration: 0, queue: false,
896 complete: function(){
897 origin
.css({left: 0, top: 0})
902 left: $(document
).scrollLeft() + windowWidth
/2 - origin
.parent('.material-placeholder').offset().left
- newWidth
/2,
903 top: $(document
).scrollTop() + windowHeight
/2 - origin
.parent('.material-placeholder').offset().top
- newHeight
/ 2
906 duration: inDuration
,
908 easing: 'easeOutQuad',
909 complete: function(){doneAnimating
= true;}
916 origin
.css('left', 0)
922 left: $(document
).scrollLeft() + windowWidth
/2 - origin
.parent('.material-placeholder').offset().left
- newWidth
/2,
923 top: $(document
).scrollTop() + windowHeight
/2 - origin
.parent('.material-placeholder').offset().top
- newHeight
/ 2
926 duration: inDuration
,
928 easing: 'easeOutQuad',
929 complete: function(){doneAnimating
= true;}
934 }); // End origin on click
938 $(window
).scroll(function() {
939 if (overlayActive
) {
945 $(document
).keyup(function(e
) {
947 if (e
.keyCode
=== 27 && doneAnimating
=== true) { // ESC key
955 // This function returns the modaled image to the original spot
956 function returnToOriginal() {
958 doneAnimating
= false;
960 var placeholder
= origin
.parent('.material-placeholder');
961 var windowWidth
= window
.innerWidth
;
962 var windowHeight
= window
.innerHeight
;
963 var originalWidth
= origin
.data('width');
964 var originalHeight
= origin
.data('height');
966 origin
.velocity("stop", true);
967 $('#materialbox-overlay').velocity("stop", true);
968 $('.materialbox-caption').velocity("stop", true);
971 $('#materialbox-overlay').velocity({opacity: 0}, {
972 duration: outDuration
, // Delay prevents animation overlapping
973 queue: false, easing: 'easeOutQuad',
974 complete: function(){
976 overlayActive
= false;
984 width: originalWidth
,
985 height: originalHeight
,
990 duration: outDuration
,
991 queue: false, easing: 'easeOutQuad'
995 // Remove Caption + reset css settings on image
996 $('.materialbox-caption').velocity({opacity: 0}, {
997 duration: outDuration
, // Delay prevents animation overlapping
998 queue: false, easing: 'easeOutQuad',
999 complete: function(){
1019 origin
.removeClass('active');
1020 doneAnimating
= true;
1029 $(document
).ready(function(){
1030 $('.materialboxed').materialbox();
1036 $.fn
.parallax = function () {
1037 var window_width
= $(window
).width();
1039 return this.each(function(i
) {
1040 var $this = $(this);
1041 $this.addClass('parallax');
1043 function updateParallax(initial
) {
1044 var container_height
;
1045 if (window_width
< 601) {
1046 container_height
= ($this.height() > 0) ? $this.height() : $this.children("img").height();
1049 container_height
= ($this.height() > 0) ? $this.height() : 500;
1051 var $img
= $this.children("img").first();
1052 var img_height
= $img
.height();
1053 var parallax_dist
= img_height
- container_height
;
1054 var bottom
= $this.offset().top
+ container_height
;
1055 var top
= $this.offset().top
;
1056 var scrollTop
= $(window
).scrollTop();
1057 var windowHeight
= window
.innerHeight
;
1058 var windowBottom
= scrollTop
+ windowHeight
;
1059 var percentScrolled
= (windowBottom
- top
) / (container_height
+ windowHeight
);
1060 var parallax
= Math
.round((parallax_dist
* percentScrolled
));
1063 $img
.css('display', 'block');
1065 if ((bottom
> scrollTop
) && (top
< (scrollTop
+ windowHeight
))) {
1066 $img
.css('transform', "translate3D(-50%," + parallax
+ "px, 0)");
1071 // Wait for image load
1072 $this.children("img").one("load", function() {
1073 updateParallax(true);
1074 }).each(function() {
1075 if(this.complete
) $(this).load();
1078 $(window
).scroll(function() {
1079 window_width
= $(window
).width();
1080 updateParallax(false);
1083 $(window
).resize(function() {
1084 window_width
= $(window
).width();
1085 updateParallax(false);
1091 }( jQuery
));;(function ($) {
1095 return this.each(function() {
1097 // For each set of tabs, we want to keep track of
1098 // which tab is active and its associated content
1099 var $this = $(this),
1100 window_width
= $(window
).width();
1102 $this.width('100%');
1103 // Set Tab Width for each tab
1104 var $num_tabs
= $(this).children('li').length
;
1105 $this.children('li').each(function() {
1106 $(this).width((100/$num_tabs
)+'%');
1108 var $active
, $content
, $links
= $this.find('li.tab a'),
1109 $tabs_width
= $this.width(),
1110 $tab_width
= $this.find('li').first().outerWidth(),
1113 // If the location.hash matches one of the links, use that as the active tab.
1114 $active
= $($links
.filter('[href="'+location
.hash
+'"]'));
1116 // If no match is found, use the first link or any with class 'active' as the initial active tab.
1117 if ($active
.length
=== 0) {
1118 $active
= $(this).find('li.tab a.active').first();
1120 if ($active
.length
=== 0) {
1121 $active
= $(this).find('li.tab a').first();
1124 $active
.addClass('active');
1125 $index
= $links
.index($active
);
1130 $content
= $($active
[0].hash
);
1132 // append indicator then set indicator width to tab width
1133 $this.append('<div class="indicator"></div>');
1134 var $indicator
= $this.find('.indicator');
1135 if ($this.is(":visible")) {
1136 $indicator
.css({"right": $tabs_width
- (($index
+ 1) * $tab_width
)});
1137 $indicator
.css({"left": $index
* $tab_width
});
1139 $(window
).resize(function () {
1140 $tabs_width
= $this.width();
1141 $tab_width
= $this.find('li').first().outerWidth();
1145 if ($tab_width
!== 0 && $tabs_width
!== 0) {
1146 $indicator
.css({"right": $tabs_width
- (($index
+ 1) * $tab_width
)});
1147 $indicator
.css({"left": $index
* $tab_width
});
1151 // Hide the remaining content
1152 $links
.not($active
).each(function () {
1153 $(this.hash
).hide();
1157 // Bind the click event handler
1158 $this.on('click', 'a', function(e
){
1159 if ($(this).parent().hasClass('disabled')) {
1164 $tabs_width
= $this.width();
1165 $tab_width
= $this.find('li').first().outerWidth();
1167 // Make the old tab inactive.
1168 $active
.removeClass('active');
1171 // Update the variables with the new link and content
1173 $content
= $(this.hash
);
1174 $links
= $this.find('li.tab a');
1176 // Make the tab active.
1177 $active
.addClass('active');
1178 var $prev_index
= $index
;
1179 $index
= $links
.index($(this));
1183 // Change url to current tab
1184 // window.location.hash = $active.attr('href');
1189 if (($index
- $prev_index
) >= 0) {
1190 $indicator
.velocity({"right": $tabs_width
- (($index
+ 1) * $tab_width
)}, { duration: 300, queue: false, easing: 'easeOutQuad'});
1191 $indicator
.velocity({"left": $index
* $tab_width
}, {duration: 300, queue: false, easing: 'easeOutQuad', delay: 90});
1195 $indicator
.velocity({"left": $index
* $tab_width
}, { duration: 300, queue: false, easing: 'easeOutQuad'});
1196 $indicator
.velocity({"right": $tabs_width
- (($index
+ 1) * $tab_width
)}, {duration: 300, queue: false, easing: 'easeOutQuad', delay: 90});
1199 // Prevent the anchor's default click action
1205 select_tab : function( id
) {
1206 this.find('a[href="#' + id
+ '"]').trigger('click');
1210 $.fn
.tabs = function(methodOrOptions
) {
1211 if ( methods
[methodOrOptions
] ) {
1212 return methods
[ methodOrOptions
].apply( this, Array
.prototype.slice
.call( arguments
, 1 ));
1213 } else if ( typeof methodOrOptions
=== 'object' || ! methodOrOptions
) {
1214 // Default to "init"
1215 return methods
.init
.apply( this, arguments
);
1217 $.error( 'Method ' + methodOrOptions
+ ' does not exist on jQuery.tooltip' );
1221 $(document
).ready(function(){
1222 $('ul.tabs').tabs();
1226 $.fn
.tooltip = function (options
) {
1230 counterInterval
= null,
1237 options
= $.extend(defaults
, options
);
1239 //Remove previously created html
1240 $('.material-tooltip').remove();
1242 return this.each(function(){
1243 var origin
= $(this);
1246 var tooltip_text
= $('<span></span>').text(origin
.attr('data-tooltip'));
1249 var newTooltip
= $('<div></div>');
1250 newTooltip
.addClass('material-tooltip').append(tooltip_text
);
1251 newTooltip
.appendTo($('body'));
1253 var backdrop
= $('<div></div>').addClass('backdrop');
1254 backdrop
.appendTo(newTooltip
);
1255 backdrop
.css({ top: 0, left:0 });
1258 //Destroy previously binded events
1259 $(this).off('mouseenter mouseleave');
1262 mouseenter: function(e
) {
1263 var tooltip_delay
= origin
.data("delay");
1264 tooltip_delay
= (tooltip_delay
=== undefined || tooltip_delay
=== '') ? options
.delay : tooltip_delay
;
1266 counterInterval
= setInterval(function(){
1268 if (counter
>= tooltip_delay
&& started
=== false) {
1270 newTooltip
.css({ display: 'block', left: '0px', top: '0px' });
1273 newTooltip
.children('span').text(origin
.attr('data-tooltip'));
1275 // Tooltip positioning
1276 var originWidth
= origin
.outerWidth();
1277 var originHeight
= origin
.outerHeight();
1278 var tooltipPosition
= origin
.attr('data-position');
1279 var tooltipHeight
= newTooltip
.outerHeight();
1280 var tooltipWidth
= newTooltip
.outerWidth();
1281 var tooltipVerticalMovement
= '0px';
1282 var tooltipHorizontalMovement
= '0px';
1283 var scale_factor
= 8;
1285 if (tooltipPosition
=== "top") {
1288 top: origin
.offset().top
- tooltipHeight
- margin
,
1289 left: origin
.offset().left
+ originWidth
/2 - tooltipWidth
/2
1291 tooltipVerticalMovement
= '-10px';
1293 borderRadius: '14px 14px 0 0',
1294 transformOrigin: '50% 90%',
1295 marginTop: tooltipHeight
,
1296 marginLeft: (tooltipWidth
/2) - (backdrop
.width()/2)
1301 else if (tooltipPosition
=== "left") {
1303 top: origin
.offset().top
+ originHeight
/2 - tooltipHeight
/2,
1304 left: origin
.offset().left
- tooltipWidth
- margin
1306 tooltipHorizontalMovement
= '-10px';
1310 borderRadius: '14px 0 0 14px',
1311 transformOrigin: '95% 50%',
1312 marginTop: tooltipHeight
/2,
1313 marginLeft: tooltipWidth
1317 else if (tooltipPosition
=== "right") {
1319 top: origin
.offset().top
+ originHeight
/2 - tooltipHeight
/2,
1320 left: origin
.offset().left
+ originWidth
+ margin
1322 tooltipHorizontalMovement
= '+10px';
1326 borderRadius: '0 14px 14px 0',
1327 transformOrigin: '5% 50%',
1328 marginTop: tooltipHeight
/2,
1335 top: origin
.offset().top
+ origin
.outerHeight() + margin
,
1336 left: origin
.offset().left
+ originWidth
/2 - tooltipWidth
/2
1338 tooltipVerticalMovement
= '+10px';
1340 marginLeft: (tooltipWidth
/2) - (backdrop
.width()/2)
1344 // Calculate Scale to fill
1345 scale_factor
= tooltipWidth
/ 8;
1346 if (scale_factor
< 8) {
1349 if (tooltipPosition
=== "right" || tooltipPosition
=== "left") {
1350 scale_factor
= tooltipWidth
/ 10;
1351 if (scale_factor
< 6)
1355 newTooltip
.velocity({ opacity: 1, marginTop: tooltipVerticalMovement
, marginLeft: tooltipHorizontalMovement
}, { duration: 350, queue: false });
1356 backdrop
.css({ display: 'block' })
1357 .velocity({opacity:1},{duration: 55, delay: 0, queue: false})
1358 .velocity({scale: scale_factor
}, {duration: 300, delay: 0, queue: false, easing: 'easeInOutQuad'});
1361 }, 10); // End Interval
1365 mouseleave: function(){
1367 clearInterval(counterInterval
);
1371 newTooltip
.velocity({
1372 opacity: 0, marginTop: 0, marginLeft: 0}, { duration: 225, queue: false, delay: 275 }
1374 backdrop
.velocity({opacity: 0, scale: 1}, {
1376 delay: 275, queue: false,
1377 complete: function(){
1378 backdrop
.css('display', 'none');
1379 newTooltip
.css('display', 'none');
1387 $(document
).ready(function(){
1388 $('.tooltipped').tooltip();
1393 * http://fian.my.id/Waves
1395 * Copyright 2014 Alfiana E. Sibuea and other contributors
1396 * Released under the MIT license
1397 * https://github.com/fians/Waves/blob/master/LICENSE
1400 ;(function(window
) {
1403 var Waves
= Waves
|| {};
1404 var $$ = document
.querySelectorAll
.bind(document
);
1406 // Find exact position of element
1407 function isWindow(obj
) {
1408 return obj
!== null && obj
=== obj
.window
;
1411 function getWindow(elem
) {
1412 return isWindow(elem
) ? elem : elem
.nodeType
=== 9 && elem
.defaultView
;
1415 function offset(elem
) {
1417 box
= {top: 0, left: 0},
1418 doc
= elem
&& elem
.ownerDocument
;
1420 docElem
= doc
.documentElement
;
1422 if (typeof elem
.getBoundingClientRect
!== typeof undefined) {
1423 box
= elem
.getBoundingClientRect();
1425 win
= getWindow(doc
);
1427 top: box
.top
+ win
.pageYOffset
- docElem
.clientTop
,
1428 left: box
.left
+ win
.pageXOffset
- docElem
.clientLeft
1432 function convertStyle(obj
) {
1435 for (var a
in obj
) {
1436 if (obj
.hasOwnProperty(a
)) {
1437 style
+= (a
+ ':' + obj
[a
] + ';');
1449 show: function(e
, element
) {
1451 // Disable right click
1452 if (e
.button
=== 2) {
1456 var el
= element
|| this;
1459 var ripple
= document
.createElement('div');
1460 ripple
.className
= 'waves-ripple';
1461 el
.appendChild(ripple
);
1463 // Get click coordinate and element witdh
1464 var pos
= offset(el
);
1465 var relativeY
= (e
.pageY
- pos
.top
);
1466 var relativeX
= (e
.pageX
- pos
.left
);
1467 var scale
= 'scale('+((el
.clientWidth
/ 100) * 10)+')';
1469 // Support for touch devices
1470 if ('touches' in e
) {
1471 relativeY
= (e
.touches
[0].pageY
- pos
.top
);
1472 relativeX
= (e
.touches
[0].pageX
- pos
.left
);
1475 // Attach data to element
1476 ripple
.setAttribute('data-hold', Date
.now());
1477 ripple
.setAttribute('data-scale', scale
);
1478 ripple
.setAttribute('data-x', relativeX
);
1479 ripple
.setAttribute('data-y', relativeY
);
1481 // Set ripple position
1483 'top': relativeY
+'px',
1484 'left': relativeX
+'px'
1487 ripple
.className
= ripple
.className
+ ' waves-notransition';
1488 ripple
.setAttribute('style', convertStyle(rippleStyle
));
1489 ripple
.className
= ripple
.className
.replace('waves-notransition', '');
1492 rippleStyle
['-webkit-transform'] = scale
;
1493 rippleStyle
['-moz-transform'] = scale
;
1494 rippleStyle
['-ms-transform'] = scale
;
1495 rippleStyle
['-o-transform'] = scale
;
1496 rippleStyle
.transform
= scale
;
1497 rippleStyle
.opacity
= '1';
1499 rippleStyle
['-webkit-transition-duration'] = Effect
.duration
+ 'ms';
1500 rippleStyle
['-moz-transition-duration'] = Effect
.duration
+ 'ms';
1501 rippleStyle
['-o-transition-duration'] = Effect
.duration
+ 'ms';
1502 rippleStyle
['transition-duration'] = Effect
.duration
+ 'ms';
1504 rippleStyle
['-webkit-transition-timing-function'] = 'cubic-bezier(0.250, 0.460, 0.450, 0.940)';
1505 rippleStyle
['-moz-transition-timing-function'] = 'cubic-bezier(0.250, 0.460, 0.450, 0.940)';
1506 rippleStyle
['-o-transition-timing-function'] = 'cubic-bezier(0.250, 0.460, 0.450, 0.940)';
1507 rippleStyle
['transition-timing-function'] = 'cubic-bezier(0.250, 0.460, 0.450, 0.940)';
1509 ripple
.setAttribute('style', convertStyle(rippleStyle
));
1513 TouchHandler
.touchup(e
);
1516 var width
= el
.clientWidth
* 1.4;
1520 var ripples
= el
.getElementsByClassName('waves-ripple');
1521 if (ripples
.length
> 0) {
1522 ripple
= ripples
[ripples
.length
- 1];
1527 var relativeX
= ripple
.getAttribute('data-x');
1528 var relativeY
= ripple
.getAttribute('data-y');
1529 var scale
= ripple
.getAttribute('data-scale');
1531 // Get delay beetween mousedown and mouse leave
1532 var diff
= Date
.now() - Number(ripple
.getAttribute('data-hold'));
1533 var delay
= 350 - diff
;
1539 // Fade out ripple after delay
1540 setTimeout(function() {
1542 'top': relativeY
+'px',
1543 'left': relativeX
+'px',
1547 '-webkit-transition-duration': Effect
.duration
+ 'ms',
1548 '-moz-transition-duration': Effect
.duration
+ 'ms',
1549 '-o-transition-duration': Effect
.duration
+ 'ms',
1550 'transition-duration': Effect
.duration
+ 'ms',
1551 '-webkit-transform': scale
,
1552 '-moz-transform': scale
,
1553 '-ms-transform': scale
,
1554 '-o-transform': scale
,
1558 ripple
.setAttribute('style', convertStyle(style
));
1560 setTimeout(function() {
1562 el
.removeChild(ripple
);
1566 }, Effect
.duration
);
1570 // Little hack to make <input> can perform waves effect
1571 wrapInput: function(elements
) {
1572 for (var a
= 0; a
< elements
.length
; a
++) {
1573 var el
= elements
[a
];
1575 if (el
.tagName
.toLowerCase() === 'input') {
1576 var parent
= el
.parentNode
;
1578 // If input already have parent just pass through
1579 if (parent
.tagName
.toLowerCase() === 'i' && parent
.className
.indexOf('waves-effect') !== -1) {
1583 // Put element class and style to the specified parent
1584 var wrapper
= document
.createElement('i');
1585 wrapper
.className
= el
.className
+ ' waves-input-wrapper';
1587 var elementStyle
= el
.getAttribute('style');
1589 if (!elementStyle
) {
1593 wrapper
.setAttribute('style', elementStyle
);
1595 el
.className
= 'waves-button-input';
1596 el
.removeAttribute('style');
1598 // Put element as child
1599 parent
.replaceChild(wrapper
, el
);
1600 wrapper
.appendChild(el
);
1608 * Disable mousedown event for 500ms during and after touch
1610 var TouchHandler
= {
1611 /* uses an integer rather than bool so there's no issues with
1612 * needing to clear timeouts if another touch event occurred
1613 * within the 500ms. Cannot mouseup between touchstart and
1614 * touchend, nor in the 500ms after touchend. */
1616 allowEvent: function(e
) {
1619 if (e
.type
=== 'touchstart') {
1620 TouchHandler
.touches
+= 1; //push
1621 } else if (e
.type
=== 'touchend' || e
.type
=== 'touchcancel') {
1622 setTimeout(function() {
1623 if (TouchHandler
.touches
> 0) {
1624 TouchHandler
.touches
-= 1; //pop after 500ms
1627 } else if (e
.type
=== 'mousedown' && TouchHandler
.touches
> 0) {
1633 touchup: function(e
) {
1634 TouchHandler
.allowEvent(e
);
1640 * Delegated click handler for .waves-effect element.
1641 * returns null when .waves-effect element not in "click tree"
1643 function getWavesEffectElement(e
) {
1644 if (TouchHandler
.allowEvent(e
) === false) {
1649 var target
= e
.target
|| e
.srcElement
;
1651 while (target
.parentElement
!== null) {
1652 if (!(target
instanceof SVGElement
) && target
.className
.indexOf('waves-effect') !== -1) {
1655 } else if (target
.classList
.contains('waves-effect')) {
1659 target
= target
.parentElement
;
1666 * Bubble the click and show effect if .waves-effect elem was found
1668 function showEffect(e
) {
1669 var element
= getWavesEffectElement(e
);
1671 if (element
!== null) {
1672 Effect
.show(e
, element
);
1674 if ('ontouchstart' in window
) {
1675 element
.addEventListener('touchend', Effect
.hide
, false);
1676 element
.addEventListener('touchcancel', Effect
.hide
, false);
1679 element
.addEventListener('mouseup', Effect
.hide
, false);
1680 element
.addEventListener('mouseleave', Effect
.hide
, false);
1684 Waves
.displayEffect = function(options
) {
1685 options
= options
|| {};
1687 if ('duration' in options
) {
1688 Effect
.duration
= options
.duration
;
1691 //Wrap input inside <i> tag
1692 Effect
.wrapInput($$('.waves-effect'));
1694 if ('ontouchstart' in window
) {
1695 document
.body
.addEventListener('touchstart', showEffect
, false);
1698 document
.body
.addEventListener('mousedown', showEffect
, false);
1702 * Attach Waves to an input element (or any element which doesn't
1703 * bubble mouseup/mousedown events).
1704 * Intended to be used with dynamically loaded forms/inputs, or
1705 * where the user doesn't want a delegated click handler.
1707 Waves
.attach = function(element
) {
1708 //FUTURE: automatically add waves classes and allow users
1709 // to specify them with an options param? Eg. light/classic/button
1710 if (element
.tagName
.toLowerCase() === 'input') {
1711 Effect
.wrapInput([element
]);
1712 element
= element
.parentElement
;
1715 if ('ontouchstart' in window
) {
1716 element
.addEventListener('touchstart', showEffect
, false);
1719 element
.addEventListener('mousedown', showEffect
, false);
1722 window
.Waves
= Waves
;
1724 document
.addEventListener('DOMContentLoaded', function() {
1725 Waves
.displayEffect();
1729 ;Materialize
.toast = function (message
, displayLength
, className
, completeCallback
) {
1730 className
= className
|| "";
1732 var container
= document
.getElementById('toast-container');
1734 // Create toast container if it does not exist
1735 if (container
=== null) {
1736 // create notification container
1737 container
= document
.createElement('div');
1738 container
.id
= 'toast-container';
1739 document
.body
.appendChild(container
);
1742 // Select and append toast
1743 var newToast
= createToast(message
);
1745 // only append toast if message is not undefined
1747 container
.appendChild(newToast
);
1750 newToast
.style
.top
= '35px';
1751 newToast
.style
.opacity
= 0;
1754 Vel(newToast
, { "top" : "0px", opacity: 1 }, {duration: 300,
1755 easing: 'easeOutCubic',
1758 // Allows timer to be pause while being panned
1759 var timeLeft
= displayLength
;
1760 var counterInterval
= setInterval (function(){
1763 if (newToast
.parentNode
=== null)
1764 window
.clearInterval(counterInterval
);
1766 // If toast is not being dragged, decrease its time remaining
1767 if (!newToast
.classList
.contains('panning')) {
1771 if (timeLeft
<= 0) {
1772 // Animate toast out
1773 Vel(newToast
, {"opacity": 0, marginTop: '-40px'}, { duration: 375,
1774 easing: 'easeOutExpo',
1776 complete: function(){
1777 // Call the optional callback
1778 if(typeof(completeCallback
) === "function")
1780 // Remove toast after it times out
1781 this[0].parentNode
.removeChild(this[0]);
1784 window
.clearInterval(counterInterval
);
1790 function createToast(html
) {
1793 var toast
= document
.createElement('div');
1794 toast
.classList
.add('toast');
1796 var classes
= className
.split(' ');
1798 for (var i
= 0, count
= classes
.length
; i
< count
; i
++) {
1799 toast
.classList
.add(classes
[i
]);
1802 toast
.innerHTML
= html
;
1805 var hammerHandler
= new Hammer(toast
, {prevent_default: false});
1806 hammerHandler
.on('pan', function(e
) {
1807 var deltaX
= e
.deltaX
;
1808 var activationDistance
= 80;
1810 // Change toast state
1811 if (!toast
.classList
.contains('panning')){
1812 toast
.classList
.add('panning');
1815 var opacityPercent
= 1-Math
.abs(deltaX
/ activationDistance
);
1816 if (opacityPercent
< 0)
1819 Vel(toast
, {left: deltaX
, opacity: opacityPercent
}, {duration: 50, queue: false, easing: 'easeOutQuad'});
1823 hammerHandler
.on('panend', function(e
) {
1824 var deltaX
= e
.deltaX
;
1825 var activationDistance
= 80;
1827 // If toast dragged past activation point
1828 if (Math
.abs(deltaX
) > activationDistance
) {
1829 Vel(toast
, {marginTop: '-40px'}, { duration: 375,
1830 easing: 'easeOutExpo',
1832 complete: function(){
1833 if(typeof(completeCallback
) === "function") {
1836 toast
.parentNode
.removeChild(toast
);
1841 toast
.classList
.remove('panning');
1842 // Put toast back into original position
1843 Vel(toast
, { left: 0, opacity: 1 }, { duration: 300,
1844 easing: 'easeOutExpo',
1857 init : function(options
) {
1863 options
= $.extend(defaults
, options
);
1865 $(this).each(function(){
1866 var $this = $(this);
1867 var menu_id
= $("#"+ $this.attr('data-activates'));
1870 if (options
.menuWidth
!= 240) {
1871 menu_id
.css('width', options
.menuWidth
);
1875 $('body').append($('<div class="drag-target"></div>'));
1877 if (options
.edge
== 'left') {
1878 menu_id
.css('left', -1 * (options
.menuWidth
+ 10));
1879 $('.drag-target').css({'left': 0}); // Add Touch Area
1882 menu_id
.addClass('right-aligned') // Change text-alignment to right
1883 .css('right', -1 * (options
.menuWidth
+ 10))
1885 $('.drag-target').css({'right': 0}); // Add Touch Area
1888 // If fixed sidenav, bring menu out
1889 if (menu_id
.hasClass('fixed')) {
1890 if (window
.innerWidth
> 992) {
1891 menu_id
.css('left', 0);
1895 // Window resize to reset on large screens fixed
1896 if (menu_id
.hasClass('fixed')) {
1897 $(window
).resize( function() {
1898 if (window
.innerWidth
> 992) {
1899 // Close menu if window is resized bigger than 992 and user has fixed sidenav
1900 if ($('#sidenav-overlay').css('opacity') !== 0 && menuOut
) {
1904 menu_id
.removeAttr('style');
1905 menu_id
.css('width', options
.menuWidth
);
1908 else if (menuOut
=== false){
1909 if (options
.edge
=== 'left')
1910 menu_id
.css('left', -1 * (options
.menuWidth
+ 10));
1912 menu_id
.css('right', -1 * (options
.menuWidth
+ 10));
1918 // if closeOnClick, then add close event for all a tags in side sideNav
1919 if (options
.closeOnClick
=== true) {
1920 menu_id
.on("click.itemclick", "a:not(.collapsible-header)", function(){
1925 function removeMenu(restoreNav
) {
1929 // Reenable scrolling
1930 $('body').css('overflow', '');
1932 $('#sidenav-overlay').velocity({opacity: 0}, {duration: 200, queue: false, easing: 'easeOutQuad',
1933 complete: function() {
1936 if (options
.edge
=== 'left') {
1937 // Reset phantom div
1938 $('.drag-target').css({width: '', right: '', left: '0'});
1940 {left: -1 * (options
.menuWidth
+ 10)},
1943 easing: 'easeOutCubic',
1944 complete: function() {
1945 if (restoreNav
=== true) {
1946 // Restore Fixed sidenav
1947 menu_id
.removeAttr('style');
1948 menu_id
.css('width', options
.menuWidth
);
1955 // Reset phantom div
1956 $('.drag-target').css({width: '', right: '0', left: ''});
1958 {right: -1 * (options
.menuWidth
+ 10)},
1961 easing: 'easeOutCubic',
1962 complete: function() {
1963 if (restoreNav
=== true) {
1964 // Restore Fixed sidenav
1965 menu_id
.removeAttr('style');
1966 menu_id
.css('width', options
.menuWidth
);
1976 var panning
= false;
1977 var menuOut
= false;
1979 $('.drag-target').on('click', function(){
1983 $('.drag-target').hammer({
1984 prevent_default: false
1985 }).bind('pan', function(e
) {
1987 if (e
.gesture
.pointerType
== "touch") {
1989 var direction
= e
.gesture
.direction
;
1990 var x
= e
.gesture
.center
.x
;
1991 var y
= e
.gesture
.center
.y
;
1992 var velocityX
= e
.gesture
.velocityX
;
1994 // Disable Scrolling
1995 $('body').css('overflow', 'hidden');
1997 // If overlay does not exist, create one and if it is clicked, close menu
1998 if ($('#sidenav-overlay').length
=== 0) {
1999 var overlay
= $('<div id="sidenav-overlay"></div>');
2000 overlay
.css('opacity', 0).click( function(){
2003 $('body').append(overlay
);
2006 // Keep within boundaries
2007 if (options
.edge
=== 'left') {
2008 if (x
> options
.menuWidth
) { x
= options
.menuWidth
; }
2009 else if (x
< 0) { x
= 0; }
2012 if (options
.edge
=== 'left') {
2014 if (x
< (options
.menuWidth
/ 2)) { menuOut
= false; }
2016 else if (x
>= (options
.menuWidth
/ 2)) { menuOut
= true; }
2018 menu_id
.css('left', (x
- options
.menuWidth
));
2022 if (x
< (window
.innerWidth
- options
.menuWidth
/ 2)) {
2026 else if (x
>= (window
.innerWidth
- options
.menuWidth
/ 2)) {
2029 var rightPos
= -1 *(x
- options
.menuWidth
/ 2);
2034 menu_id
.css('right', rightPos
);
2040 // Percentage overlay
2042 if (options
.edge
=== 'left') {
2043 overlayPerc
= x
/ options
.menuWidth
;
2044 $('#sidenav-overlay').velocity({opacity: overlayPerc
}, {duration: 50, queue: false, easing: 'easeOutQuad'});
2047 overlayPerc
= Math
.abs((x
- window
.innerWidth
) / options
.menuWidth
);
2048 $('#sidenav-overlay').velocity({opacity: overlayPerc
}, {duration: 50, queue: false, easing: 'easeOutQuad'});
2052 }).bind('panend', function(e
) {
2054 if (e
.gesture
.pointerType
== "touch") {
2055 var velocityX
= e
.gesture
.velocityX
;
2057 if (options
.edge
=== 'left') {
2058 // If velocityX <= 0.3 then the user is flinging the menu closed so ignore menuOut
2059 if ((menuOut
&& velocityX
<= 0.3) || velocityX
< -0.5) {
2060 menu_id
.velocity({left: 0}, {duration: 300, queue: false, easing: 'easeOutQuad'});
2061 $('#sidenav-overlay').velocity({opacity: 1 }, {duration: 50, queue: false, easing: 'easeOutQuad'});
2062 $('.drag-target').css({width: '50%', right: 0, left: ''});
2064 else if (!menuOut
|| velocityX
> 0.3) {
2066 $('body').css('overflow', '');
2067 // Slide menu closed
2068 menu_id
.velocity({left: -1 * (options
.menuWidth
+ 10)}, {duration: 200, queue: false, easing: 'easeOutQuad'});
2069 $('#sidenav-overlay').velocity({opacity: 0 }, {duration: 200, queue: false, easing: 'easeOutQuad',
2070 complete: function () {
2073 $('.drag-target').css({width: '10px', right: '', left: 0});
2077 if ((menuOut
&& velocityX
>= -0.3) || velocityX
> 0.5) {
2078 menu_id
.velocity({right: 0}, {duration: 300, queue: false, easing: 'easeOutQuad'});
2079 $('#sidenav-overlay').velocity({opacity: 1 }, {duration: 50, queue: false, easing: 'easeOutQuad'});
2080 $('.drag-target').css({width: '50%', right: '', left: 0});
2082 else if (!menuOut
|| velocityX
< -0.3) {
2084 $('body').css('overflow', '');
2085 // Slide menu closed
2086 menu_id
.velocity({right: -1 * (options
.menuWidth
+ 10)}, {duration: 200, queue: false, easing: 'easeOutQuad'});
2087 $('#sidenav-overlay').velocity({opacity: 0 }, {duration: 200, queue: false, easing: 'easeOutQuad',
2088 complete: function () {
2091 $('.drag-target').css({width: '10px', right: 0, left: ''});
2098 $this.click(function() {
2099 if (menuOut
=== true) {
2106 // Disable Scrolling
2107 $('body').css('overflow', 'hidden');
2109 if (options
.edge
=== 'left') {
2110 $('.drag-target').css({width: '50%', right: 0, left: ''});
2111 menu_id
.velocity({left: 0}, {duration: 300, queue: false, easing: 'easeOutQuad'});
2114 $('.drag-target').css({width: '50%', right: '', left: 0});
2115 menu_id
.velocity({right: 0}, {duration: 300, queue: false, easing: 'easeOutQuad'});
2116 menu_id
.css('left','');
2119 var overlay
= $('<div id="sidenav-overlay"></div>');
2120 overlay
.css('opacity', 0)
2125 overlay
.velocity({opacity: 0}, {duration: 300, queue: false, easing: 'easeOutQuad',
2126 complete: function() {
2131 $('body').append(overlay
);
2132 overlay
.velocity({opacity: 1}, {duration: 300, queue: false, easing: 'easeOutQuad',
2133 complete: function () {
2147 this.trigger('click');
2150 $('#sidenav-overlay').trigger('click');
2155 $.fn
.sideNav = function(methodOrOptions
) {
2156 if ( methods
[methodOrOptions
] ) {
2157 return methods
[ methodOrOptions
].apply( this, Array
.prototype.slice
.call( arguments
, 1 ));
2158 } else if ( typeof methodOrOptions
=== 'object' || ! methodOrOptions
) {
2159 // Default to "init"
2160 return methods
.init
.apply( this, arguments
);
2162 $.error( 'Method ' + methodOrOptions
+ ' does not exist on jQuery.sideNav' );
2167 * Extend jquery with a scrollspy plugin.
2168 * This watches the window scroll and fires events when elements are scrolled into viewport.
2170 * throttle() and getTime() taken from Underscore.js
2171 * https://github.com/jashkenas/underscore
2173 * @author Copyright 2013 John Smart
2174 * @license https://raw.github.com/thesmart/jquery-scrollspy/master/LICENSE
2175 * @see https://github.com/thesmart
2180 var jWindow
= $(window
);
2182 var elementsInView
= [];
2183 var isSpying
= false;
2194 * Find elements that are within the boundary
2195 * @param {number} top
2196 * @param {number} right
2197 * @param {number} bottom
2198 * @param {number} left
2199 * @return {jQuery} A collection of elements
2201 function findElements(top
, right
, bottom
, left
) {
2203 $.each(elements
, function(i
, element
) {
2204 if (element
.height() > 0) {
2205 var elTop
= element
.offset().top
,
2206 elLeft
= element
.offset().left
,
2207 elRight
= elLeft
+ element
.width(),
2208 elBottom
= elTop
+ element
.height();
2210 var isIntersect
= !(elLeft
> right
||
2226 * Called when the user scrolls the window
2228 function onScroll() {
2232 // viewport rectangle
2233 var top
= jWindow
.scrollTop(),
2234 left
= jWindow
.scrollLeft(),
2235 right
= left
+ jWindow
.width(),
2236 bottom
= top
+ jWindow
.height();
2238 // determine which elements are in view
2239 // + 60 accounts for fixed nav
2240 var intersections
= findElements(top
+offset
.top
+ 200, right
+offset
.right
, bottom
+offset
.bottom
, left
+offset
.left
);
2241 $.each(intersections
, function(i
, element
) {
2243 var lastTick
= element
.data('scrollSpy:ticks');
2244 if (typeof lastTick
!= 'number') {
2245 // entered into view
2246 element
.triggerHandler('scrollSpy:enter');
2250 element
.data('scrollSpy:ticks', ticks
);
2253 // determine which elements are no longer in view
2254 $.each(elementsInView
, function(i
, element
) {
2255 var lastTick
= element
.data('scrollSpy:ticks');
2256 if (typeof lastTick
== 'number' && lastTick
!== ticks
) {
2258 element
.triggerHandler('scrollSpy:exit');
2259 element
.data('scrollSpy:ticks', null);
2263 // remember elements in view for next tick
2264 elementsInView
= intersections
;
2268 * Called when window is resized
2270 function onWinSize() {
2271 jWindow
.trigger('scrollSpy:winSize');
2276 * @license https://raw.github.com/jashkenas/underscore/master/LICENSE
2280 var getTime
= (Date
.now
|| function () {
2281 return new Date().getTime();
2285 * Returns a function, that, when invoked, will only be triggered at most once
2286 * during a given window of time. Normally, the throttled function will run
2287 * as much as it can, without ever going more than once per `wait` duration;
2288 * but if you'd like to disable the execution on the leading edge, pass
2289 * `{leading: false}`. To disable execution on the trailing edge, ditto.
2290 * @license https://raw.github.com/jashkenas/underscore/master/LICENSE
2291 * @param {function} func
2292 * @param {number} wait
2293 * @param {Object=} options
2294 * @returns {Function}
2296 function throttle(func
, wait
, options
) {
2297 var context
, args
, result
;
2300 options
|| (options
= {});
2301 var later = function () {
2302 previous
= options
.leading
=== false ? 0 : getTime();
2304 result
= func
.apply(context
, args
);
2305 context
= args
= null;
2307 return function () {
2308 var now
= getTime();
2309 if (!previous
&& options
.leading
=== false) previous
= now
;
2310 var remaining
= wait
- (now
- previous
);
2313 if (remaining
<= 0) {
2314 clearTimeout(timeout
);
2317 result
= func
.apply(context
, args
);
2318 context
= args
= null;
2319 } else if (!timeout
&& options
.trailing
!== false) {
2320 timeout
= setTimeout(later
, remaining
);
2327 * Enables ScrollSpy using a selector
2328 * @param {jQuery|string} selector The elements collection, or a selector
2329 * @param {Object=} options Optional.
2330 throttle : number -> scrollspy throttling. Default: 100 ms
2331 offsetTop : number -> offset from top. Default: 0
2332 offsetRight : number -> offset from right. Default: 0
2333 offsetBottom : number -> offset from bottom. Default: 0
2334 offsetLeft : number -> offset from left. Default: 0
2337 $.scrollSpy = function(selector
, options
) {
2339 selector
= $(selector
);
2340 selector
.each(function(i
, element
) {
2341 elements
.push($(element
));
2342 $(element
).data("scrollSpy:id", i
);
2343 // Smooth scroll to section
2344 $('a[href=#' + $(element
).attr('id') + ']').click(function(e
) {
2346 var offset
= $(this.hash
).offset().top
+ 1;
2348 // offset - 200 allows elements near bottom of page to scroll
2350 $('html, body').animate({ scrollTop: offset
- 200 }, {duration: 400, queue: false, easing: 'easeOutCubic'});
2354 options
= options
|| {
2358 offset
.top
= options
.offsetTop
|| 0;
2359 offset
.right
= options
.offsetRight
|| 0;
2360 offset
.bottom
= options
.offsetBottom
|| 0;
2361 offset
.left
= options
.offsetLeft
|| 0;
2363 var throttledScroll
= throttle(onScroll
, options
.throttle
|| 100);
2364 var readyScroll = function(){
2365 $(document
).ready(throttledScroll
);
2369 jWindow
.on('scroll', readyScroll
);
2370 jWindow
.on('resize', readyScroll
);
2374 // perform a scan once, after current execution context, and after dom is ready
2375 setTimeout(readyScroll
, 0);
2378 selector
.on('scrollSpy:enter', function() {
2379 visible
= $.grep(visible
, function(value
) {
2380 return value
.height() != 0;
2383 var $this = $(this);
2386 $('a[href=#' + visible
[0].attr('id') + ']').removeClass('active');
2387 if ($this.data('scrollSpy:id') < visible
[0].data('scrollSpy:id')) {
2388 visible
.unshift($(this));
2391 visible
.push($(this));
2395 visible
.push($(this));
2399 $('a[href=#' + visible
[0].attr('id') + ']').addClass('active');
2401 selector
.on('scrollSpy:exit', function() {
2402 visible
= $.grep(visible
, function(value
) {
2403 return value
.height() != 0;
2407 $('a[href=#' + visible
[0].attr('id') + ']').removeClass('active');
2408 var $this = $(this);
2409 visible
= $.grep(visible
, function(value
) {
2410 return value
.attr('id') != $this.attr('id');
2412 if (visible
[0]) { // Check if empty
2413 $('a[href=#' + visible
[0].attr('id') + ']').addClass('active');
2422 * Listen for window resize events
2423 * @param {Object=} options Optional. Set { throttle: number } to change throttling. Default: 100 ms
2424 * @returns {jQuery} $(window)
2426 $.winSizeSpy = function(options
) {
2427 $.winSizeSpy = function() { return jWindow
; }; // lock from multiple calls
2428 options
= options
|| {
2431 return jWindow
.on('resize', throttle(onWinSize
, options
.throttle
|| 100));
2435 * Enables ScrollSpy on a collection of elements
2436 * e.g. $('.scrollSpy').scrollSpy()
2437 * @param {Object=} options Optional.
2438 throttle : number -> scrollspy throttling. Default: 100 ms
2439 offsetTop : number -> offset from top. Default: 0
2440 offsetRight : number -> offset from right. Default: 0
2441 offsetBottom : number -> offset from bottom. Default: 0
2442 offsetLeft : number -> offset from left. Default: 0
2445 $.fn
.scrollSpy = function(options
) {
2446 return $.scrollSpy($(this), options
);
2449 })(jQuery
);;(function ($) {
2450 $(document
).ready(function() {
2452 // Function to update labels of text fields
2453 Materialize
.updateTextFields = function() {
2454 var input_selector
= 'input[type=text], input[type=password], input[type=email], input[type=url], input[type=tel], input[type=number], input[type=search], textarea';
2455 $(input_selector
).each(function(index
, element
) {
2456 if ($(element
).val().length
> 0 || $(this).attr('placeholder') !== undefined || $(element
)[0].validity
.badInput
=== true) {
2457 $(this).siblings('label, i').addClass('active');
2460 $(this).siblings('label, i').removeClass('active');
2465 // Text based inputs
2466 var input_selector
= 'input[type=text], input[type=password], input[type=email], input[type=url], input[type=tel], input[type=number], input[type=search], textarea';
2468 // Handle HTML5 autofocus
2469 $('input[autofocus]').siblings('label, i').addClass('active');
2471 // Add active if form auto complete
2472 $(document
).on('change', input_selector
, function () {
2473 if($(this).val().length
!== 0 || $(this).attr('placeholder') !== undefined) {
2474 $(this).siblings('label, i').addClass('active');
2476 validate_field($(this));
2479 // Add active if input element has been pre-populated on document ready
2480 $(document
).ready(function() {
2481 Materialize
.updateTextFields();
2484 // HTML DOM FORM RESET handling
2485 $(document
).on('reset', function(e
) {
2486 var formReset
= $(e
.target
);
2487 if (formReset
.is('form')) {
2488 formReset
.find(input_selector
).removeClass('valid').removeClass('invalid');
2489 formReset
.find(input_selector
).each(function () {
2490 if ($(this).attr('value') === '') {
2491 $(this).siblings('label, i').removeClass('active');
2496 formReset
.find('select.initialized').each(function () {
2497 var reset_text
= formReset
.find('option[selected]').text();
2498 formReset
.siblings('input.select-dropdown').val(reset_text
);
2503 // Add active when element has focus
2504 $(document
).on('focus', input_selector
, function () {
2505 $(this).siblings('label, i').addClass('active');
2508 $(document
).on('blur', input_selector
, function () {
2509 var $inputElement
= $(this);
2510 if ($inputElement
.val().length
=== 0 && $inputElement
[0].validity
.badInput
!== true && $inputElement
.attr('placeholder') === undefined) {
2511 $inputElement
.siblings('label, i').removeClass('active');
2513 validate_field($inputElement
);
2516 validate_field = function(object
) {
2517 var hasLength
= object
.attr('length') !== undefined;
2518 var lenAttr
= parseInt(object
.attr('length'));
2519 var len
= object
.val().length
;
2521 if (object
.val().length
=== 0 && object
[0].validity
.badInput
=== false) {
2522 if (object
.hasClass('validate')) {
2523 object
.removeClass('valid');
2524 object
.removeClass('invalid');
2528 if (object
.hasClass('validate')) {
2529 // Check for character counter attributes
2530 if ((object
.is(':valid') && hasLength
&& (len
< lenAttr
)) || (object
.is(':valid') && !hasLength
)) {
2531 object
.removeClass('invalid');
2532 object
.addClass('valid');
2535 object
.removeClass('valid');
2536 object
.addClass('invalid');
2543 // Textarea Auto Resize
2544 var hiddenDiv
= $('.hiddendiv').first();
2545 if (!hiddenDiv
.length
) {
2546 hiddenDiv
= $('<div class="hiddendiv common"></div>');
2547 $('body').append(hiddenDiv
);
2549 var text_area_selector
= '.materialize-textarea';
2551 function textareaAutoResize($textarea
) {
2552 // Set font properties of hiddenDiv
2554 var fontFamily
= $textarea
.css('font-family');
2555 var fontSize
= $textarea
.css('font-size');
2557 if (fontSize
) { hiddenDiv
.css('font-size', fontSize
); }
2558 if (fontFamily
) { hiddenDiv
.css('font-family', fontFamily
); }
2560 if ($textarea
.attr('wrap') === "off") {
2561 hiddenDiv
.css('overflow-wrap', "normal")
2562 .css('white-space', "pre");
2568 hiddenDiv
.text($textarea
.val() + '\n');
2569 var content
= hiddenDiv
.html().replace(/\n/g, '<br>');
2570 hiddenDiv
.html(content
);
2573 // When textarea is hidden, width goes crazy.
2574 // Approximate with half of window size
2576 if ($textarea
.is(':visible')) {
2577 hiddenDiv
.css('width', $textarea
.width());
2580 hiddenDiv
.css('width', $(window
).width()/2);
2583 $textarea
.css('height', hiddenDiv
.height());
2586 $(text_area_selector
).each(function () {
2587 var $textarea
= $(this);
2588 if ($textarea
.val().length
) {
2589 textareaAutoResize($textarea
);
2593 $('body').on('keyup keydown', text_area_selector
, function () {
2594 textareaAutoResize($(this));
2599 $('.file-field').each(function() {
2600 var path_input
= $(this).find('input.file-path');
2601 $(this).find('input[type="file"]').change(function () {
2602 path_input
.val($(this)[0].files
[0].name
);
2603 path_input
.trigger('change');
2613 var range_type
= 'input[type=range]';
2614 var range_mousedown
= false;
2617 $(range_type
).each(function () {
2618 var thumb
= $('<span class="thumb"><span class="value"></span></span>');
2619 $(this).after(thumb
);
2622 var range_wrapper
= '.range-field';
2623 $(document
).on('change', range_type
, function(e
) {
2624 var thumb
= $(this).siblings('.thumb');
2625 thumb
.find('.value').html($(this).val());
2628 $(document
).on('mousedown touchstart', range_type
, function(e
) {
2629 var thumb
= $(this).siblings('.thumb');
2631 // If thumb indicator does not exist yet, create it
2632 if (thumb
.length
<= 0) {
2633 thumb
= $('<span class="thumb"><span class="value"></span></span>');
2634 $(this).append(thumb
);
2637 // Set indicator value
2638 thumb
.find('.value').html($(this).val());
2640 range_mousedown
= true;
2641 $(this).addClass('active');
2643 if (!thumb
.hasClass('active')) {
2644 thumb
.velocity({ height: "30px", width: "30px", top: "-20px", marginLeft: "-15px"}, { duration: 300, easing: 'easeOutExpo' });
2647 if(e
.pageX
=== undefined || e
.pageX
=== null){//mobile
2648 left
= e
.originalEvent
.touches
[0].pageX
- $(this).offset().left
;
2651 left
= e
.pageX
- $(this).offset().left
;
2653 var width
= $(this).outerWidth();
2658 else if (left
> width
) {
2661 thumb
.addClass('active').css('left', left
);
2662 thumb
.find('.value').html($(this).val());
2667 $(document
).on('mouseup touchend', range_wrapper
, function() {
2668 range_mousedown
= false;
2669 $(this).removeClass('active');
2672 $(document
).on('mousemove touchmove', range_wrapper
, function(e
) {
2673 var thumb
= $(this).children('.thumb');
2675 if (range_mousedown
) {
2676 if (!thumb
.hasClass('active')) {
2677 thumb
.velocity({ height: '30px', width: '30px', top: '-20px', marginLeft: '-15px'}, { duration: 300, easing: 'easeOutExpo' });
2679 if (e
.pageX
=== undefined || e
.pageX
=== null) { //mobile
2680 left
= e
.originalEvent
.touches
[0].pageX
- $(this).offset().left
;
2683 left
= e
.pageX
- $(this).offset().left
;
2685 var width
= $(this).outerWidth();
2690 else if (left
> width
) {
2693 thumb
.addClass('active').css('left', left
);
2699 $(document
).on('mouseout touchleave', range_wrapper
, function() {
2700 if (!range_mousedown
) {
2702 var thumb
= $(this).children('.thumb');
2704 if (thumb
.hasClass('active')) {
2705 thumb
.velocity({ height: '0', width: '0', top: '10px', marginLeft: '-6px'}, { duration: 100 });
2707 thumb
.removeClass('active');
2711 }); // End of $(document).ready
2717 $.fn
.material_select = function (callback
) {
2718 $(this).each(function(){
2721 if ( $select
.hasClass('browser-default')) {
2722 return; // Continue to next (return false breaks out of entire loop)
2725 // Tear down structure if Select needs to be rebuilt
2726 var lastID
= $select
.data('select-id');
2728 $select
.parent().find('i').remove();
2729 $select
.parent().find('input').remove();
2732 $('ul#select-options-'+lastID
).remove();
2735 // If destroying the select, remove the selelct-id and reset it to it's uninitialized state.
2736 if(callback
=== 'destroy') {
2737 $select
.data('select-id', null).removeClass('initialized');
2741 var uniqueID
= Materialize
.guid();
2742 $select
.data('select-id', uniqueID
);
2743 var wrapper
= $('<div class="select-wrapper"></div>');
2744 wrapper
.addClass($select
.attr('class'));
2745 var options
= $('<ul id="select-options-' + uniqueID
+'" class="dropdown-content select-dropdown"></ul>');
2746 var selectOptions
= $select
.children('option');
2749 if ($select
.find('option:selected') !== undefined) {
2750 label
= $select
.find('option:selected');
2753 label
= options
.first();
2757 // Create Dropdown structure
2758 selectOptions
.each(function () {
2759 // Add disabled attr if disabled
2760 options
.append($('<li class="' + (($(this).is(':disabled')) ? 'disabled' : '') + '"><span>' + $(this).html() + '</span></li>'));
2764 options
.find('li').each(function (i
) {
2765 var $curr_select
= $select
;
2766 $(this).click(function () {
2767 // Check if option element is disabled
2768 if (!$(this).hasClass('disabled')) {
2769 $curr_select
.find('option').eq(i
).prop('selected', true);
2770 // Trigger onchange() event
2771 $curr_select
.trigger('change');
2772 $curr_select
.siblings('input.select-dropdown').val($(this).text());
2773 if (typeof callback
!== 'undefined') callback();
2780 $select
.wrap(wrapper
);
2781 // Add Select Display Element
2782 var dropdownIcon
= $('<span class="caret">▼</span>');
2783 if ( $select
.is(':disabled') )
2784 dropdownIcon
.addClass('disabled');
2786 var $newSelect
= $('<input type="text" class="select-dropdown" readonly="true" ' + (($select
.is(':disabled')) ? 'disabled' : '') + ' data-activates="select-options-' + uniqueID
+'" value="'+ label
.html() +'"/>');
2787 $select
.before($newSelect
);
2788 $newSelect
.before(dropdownIcon
);
2790 $('body').append(options
);
2791 // Check if section element is disabled
2792 if (!$select
.is(':disabled')) {
2793 $newSelect
.dropdown({"hover": false});
2797 if ($select
.attr('tabindex')) {
2798 $($newSelect
[0]).attr('tabindex', $select
.attr('tabindex'));
2801 $select
.addClass('initialized');
2803 $newSelect
.on('focus', function(){
2804 $(this).trigger('open');
2805 label
= $(this).val();
2806 selectedOption
= options
.find('li').filter(function() {
2807 return $(this).text().toLowerCase() === label
.toLowerCase();
2809 activateOption(options
, selectedOption
);
2812 $newSelect
.on('blur', function(){
2813 $(this).trigger('close');
2816 // Make option as selected and scroll to selected position
2817 activateOption = function(collection
, newOption
) {
2818 collection
.find('li.active').removeClass('active');
2819 $(newOption
).addClass('active');
2820 collection
.scrollTo(newOption
);
2823 // Allow user to search by typing
2824 // this array is cleared after 1 second
2827 onKeyDown = function(event
){
2828 // TAB - switch to another input
2829 if(event
.which
== 9){
2830 $newSelect
.trigger('close');
2834 // ARROW DOWN WHEN SELECT IS CLOSED - open select options
2835 if(event
.which
== 40 && !options
.is(":visible")){
2836 $newSelect
.trigger('open');
2840 // ENTER WHEN SELECT IS CLOSED - submit form
2841 if(event
.which
== 13 && !options
.is(":visible")){
2845 event
.preventDefault();
2847 // CASE WHEN USER TYPE LETTERS
2848 letter
= String
.fromCharCode(event
.which
).toLowerCase();
2849 var nonLetters
= [9,13,27,38,40];
2850 if (letter
&& (nonLetters
.indexOf(event
.which
) === -1)){
2851 filterQuery
.push(letter
);
2853 string
= filterQuery
.join("");
2855 newOption
= options
.find('li').filter(function() {
2856 return $(this).text().toLowerCase().indexOf(string
) === 0;
2860 activateOption(options
, newOption
);
2864 // ENTER - select option and close when select options are opened
2865 if(event
.which
== 13){
2866 activeOption
= options
.find('li.active:not(.disabled)')[0];
2868 $(activeOption
).trigger('click');
2869 $newSelect
.trigger('close');
2873 // ARROW DOWN - move to next not disabled option
2874 if(event
.which
== 40){
2875 newOption
= options
.find('li.active').next('li:not(.disabled)')[0];
2877 activateOption(options
, newOption
);
2881 // ESC - close options
2882 if(event
.which
== 27){
2883 $newSelect
.trigger('close');
2886 // ARROW UP - move to previous not disabled option
2887 if(event
.which
== 38){
2888 newOption
= options
.find('li.active').prev('li:not(.disabled)')[0];
2890 activateOption(options
, newOption
);
2894 // Automaticaly clean filter query so user can search again by starting letters
2895 setTimeout(function(){ filterQuery
= []; }, 1000);
2898 $newSelect
.on('keydown', onKeyDown
);
2907 init : function(options
) {
2914 options
= $.extend(defaults
, options
);
2916 return this.each(function() {
2918 // For each slider, we want to keep track of
2919 // which slide is active and its associated content
2920 var $this = $(this);
2921 var $slider
= $this.find('ul.slides').first();
2922 var $slides
= $slider
.find('li');
2923 var $active_index
= $slider
.find('.active').index();
2925 if ($active_index
!= -1) { $active
= $slides
.eq($active_index
); }
2927 // Transitions the caption depending on alignment
2928 function captionTransition(caption
, duration
) {
2929 if (caption
.hasClass("center-align")) {
2930 caption
.velocity({opacity: 0, translateY: -100}, {duration: duration
, queue: false});
2932 else if (caption
.hasClass("right-align")) {
2933 caption
.velocity({opacity: 0, translateX: 100}, {duration: duration
, queue: false});
2935 else if (caption
.hasClass("left-align")) {
2936 caption
.velocity({opacity: 0, translateX: -100}, {duration: duration
, queue: false});
2940 // This function will transition the slide to any index of the next slide
2941 function moveToSlide(index
) {
2942 if (index
>= $slides
.length
) index
= 0;
2943 else if (index
< 0) index
= $slides
.length
-1;
2945 $active_index
= $slider
.find('.active').index();
2947 // Only do if index changes
2948 if ($active_index
!= index
) {
2949 $active
= $slides
.eq($active_index
);
2950 $caption
= $active
.find('.caption');
2952 $active
.removeClass('active');
2953 $active
.velocity({opacity: 0}, {duration: options
.transition
, queue: false, easing: 'easeOutQuad',
2954 complete: function() {
2955 $slides
.not('.active').velocity({opacity: 0, translateX: 0, translateY: 0}, {duration: 0, queue: false});
2957 captionTransition($caption
, options
.transition
);
2960 // Update indicators
2961 if (options
.indicators
) {
2962 $indicators
.eq($active_index
).removeClass('active');
2965 $slides
.eq(index
).velocity({opacity: 1}, {duration: options
.transition
, queue: false, easing: 'easeOutQuad'});
2966 $slides
.eq(index
).find('.caption').velocity({opacity: 1, translateX: 0, translateY: 0}, {duration: options
.transition
, delay: options
.transition
, queue: false, easing: 'easeOutQuad'});
2967 $slides
.eq(index
).addClass('active');
2970 // Update indicators
2971 if (options
.indicators
) {
2972 $indicators
.eq(index
).addClass('active');
2977 // Set height of slider
2978 // If fullscreen, do nothing
2979 if (!$this.hasClass('fullscreen')) {
2980 if (options
.indicators
) {
2981 // Add height if indicators are present
2982 $this.height(options
.height
+ 40);
2985 $this.height(options
.height
);
2987 $slider
.height(options
.height
);
2991 // Set initial positions of captions
2992 $slides
.find('.caption').each(function () {
2993 captionTransition($(this), 0);
2996 // Move img src into background-image
2997 $slides
.find('img').each(function () {
2998 $(this).css('background-image', 'url(' + $(this).attr('src') + ')' );
2999 $(this).attr('src', 'data:image/gif;base64,R0lGODlhAQABAIABAP///wAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==');
3002 // dynamically add indicators
3003 if (options
.indicators
) {
3004 var $indicators
= $('<ul class="indicators"></ul>');
3005 $slides
.each(function( index
) {
3006 var $indicator
= $('<li class="indicator-item"></li>');
3008 // Handle clicks on indicators
3009 $indicator
.click(function () {
3010 var $parent
= $slider
.parent();
3011 var curr_index
= $parent
.find($(this)).index();
3012 moveToSlide(curr_index
);
3015 clearInterval($interval
);
3016 $interval
= setInterval(
3018 $active_index
= $slider
.find('.active').index();
3019 if ($slides
.length
== $active_index
+ 1) $active_index
= 0; // loop to start
3020 else $active_index
+= 1;
3022 moveToSlide($active_index
);
3024 }, options
.transition
+ options
.interval
3027 $indicators
.append($indicator
);
3029 $this.append($indicators
);
3030 $indicators
= $this.find('ul.indicators').find('li.indicator-item');
3037 $slides
.first().addClass('active').velocity({opacity: 1}, {duration: options
.transition
, queue: false, easing: 'easeOutQuad'});
3040 $active
= $slides
.eq($active_index
);
3042 // Update indicators
3043 if (options
.indicators
) {
3044 $indicators
.eq($active_index
).addClass('active');
3048 // Adjust height to current slide
3049 $active
.find('img').each(function() {
3050 $active
.find('.caption').velocity({opacity: 1, translateX: 0, translateY: 0}, {duration: options
.transition
, queue: false, easing: 'easeOutQuad'});
3054 $interval
= setInterval(
3056 $active_index
= $slider
.find('.active').index();
3057 moveToSlide($active_index
+ 1);
3059 }, options
.transition
+ options
.interval
3063 // HammerJS, Swipe navigation
3066 var panning
= false;
3067 var swipeLeft
= false;
3068 var swipeRight
= false;
3071 prevent_default: false
3072 }).bind('pan', function(e
) {
3073 if (e
.gesture
.pointerType
=== "touch") {
3076 clearInterval($interval
);
3078 var direction
= e
.gesture
.direction
;
3079 var x
= e
.gesture
.deltaX
;
3080 var velocityX
= e
.gesture
.velocityX
;
3082 $curr_slide
= $slider
.find('.active');
3083 $curr_slide
.velocity({ translateX: x
3084 }, {duration: 50, queue: false, easing: 'easeOutQuad'});
3087 if (direction
=== 4 && (x
> ($this.innerWidth() / 2) || velocityX
< -0.65)) {
3091 else if (direction
=== 2 && (x
< (-1 * $this.innerWidth() / 2) || velocityX
> 0.65)) {
3095 // Make Slide Behind active slide visible
3098 next_slide
= $curr_slide
.next();
3099 if (next_slide
.length
=== 0) {
3100 next_slide
= $slides
.first();
3102 next_slide
.velocity({ opacity: 1
3103 }, {duration: 300, queue: false, easing: 'easeOutQuad'});
3106 next_slide
= $curr_slide
.prev();
3107 if (next_slide
.length
=== 0) {
3108 next_slide
= $slides
.last();
3110 next_slide
.velocity({ opacity: 1
3111 }, {duration: 300, queue: false, easing: 'easeOutQuad'});
3117 }).bind('panend', function(e
) {
3118 if (e
.gesture
.pointerType
=== "touch") {
3120 $curr_slide
= $slider
.find('.active');
3122 curr_index
= $slider
.find('.active').index();
3124 if (!swipeRight
&& !swipeLeft
) {
3125 // Return to original spot
3126 $curr_slide
.velocity({ translateX: 0
3127 }, {duration: 300, queue: false, easing: 'easeOutQuad'});
3129 else if (swipeLeft
) {
3130 moveToSlide(curr_index
+ 1);
3131 $curr_slide
.velocity({translateX: -1 * $this.innerWidth() }, {duration: 300, queue: false, easing: 'easeOutQuad',
3132 complete: function() {
3133 $curr_slide
.velocity({opacity: 0, translateX: 0}, {duration: 0, queue: false});
3136 else if (swipeRight
) {
3137 moveToSlide(curr_index
- 1);
3138 $curr_slide
.velocity({translateX: $this.innerWidth() }, {duration: 300, queue: false, easing: 'easeOutQuad',
3139 complete: function() {
3140 $curr_slide
.velocity({opacity: 0, translateX: 0}, {duration: 0, queue: false});
3147 clearInterval($interval
);
3148 $interval
= setInterval(
3150 $active_index
= $slider
.find('.active').index();
3151 if ($slides
.length
== $active_index
+ 1) $active_index
= 0; // loop to start
3152 else $active_index
+= 1;
3154 moveToSlide($active_index
);
3156 }, options
.transition
+ options
.interval
3161 $this.on('sliderPause', function() {
3162 clearInterval($interval
);
3165 $this.on('sliderStart', function() {
3166 clearInterval($interval
);
3167 $interval
= setInterval(
3169 $active_index
= $slider
.find('.active').index();
3170 if ($slides
.length
== $active_index
+ 1) $active_index
= 0; // loop to start
3171 else $active_index
+= 1;
3173 moveToSlide($active_index
);
3175 }, options
.transition
+ options
.interval
3184 pause : function() {
3185 $(this).trigger('sliderPause');
3187 start : function() {
3188 $(this).trigger('sliderStart');
3193 $.fn
.slider = function(methodOrOptions
) {
3194 if ( methods
[methodOrOptions
] ) {
3195 return methods
[ methodOrOptions
].apply( this, Array
.prototype.slice
.call( arguments
, 1 ));
3196 } else if ( typeof methodOrOptions
=== 'object' || ! methodOrOptions
) {
3197 // Default to "init"
3198 return methods
.init
.apply( this, arguments
);
3200 $.error( 'Method ' + methodOrOptions
+ ' does not exist on jQuery.tooltip' );
3203 }( jQuery
));;(function ($) {
3204 $(document
).ready(function() {
3206 $(document
).on('click.card', '.card', function (e
) {
3207 if ($(this).find('.card-reveal').length
) {
3208 if ($(e
.target
).is($('.card-reveal .card-title')) || $(e
.target
).is($('.card-reveal .card-title i'))) {
3209 // Make Reveal animate down and display none
3210 $(this).find('.card-reveal').velocity(
3214 easing: 'easeInOutQuad',
3215 complete: function() { $(this).css({ display: 'none'}); }
3219 else if ($(e
.target
).is($('.card .activator')) ||
3220 $(e
.target
).is($('.card .activator i')) ) {
3221 $(this).find('.card-reveal').css({ display: 'block'}).velocity("stop", false).velocity({translateY: '-100%'}, {duration: 300, queue: false, easing: 'easeInOutQuad'});
3229 }( jQuery
));;(function ($) {
3230 $(document
).ready(function() {
3232 $.fn
.pushpin = function (options
) {
3239 options
= $.extend(defaults
, options
);
3242 return this.each(function() {
3243 var $uniqueId
= Materialize
.guid(),
3245 $original_offset
= $(this).offset().top
;
3247 function removePinClasses(object
) {
3248 object
.removeClass('pin-top');
3249 object
.removeClass('pinned');
3250 object
.removeClass('pin-bottom');
3253 function updateElements(objects
, scrolled
) {
3254 objects
.each(function () {
3255 // Add position fixed (because its between top and bottom)
3256 if (options
.top
<= scrolled
&& options
.bottom
>= scrolled
&& !$(this).hasClass('pinned')) {
3257 removePinClasses($(this));
3258 $(this).css('top', options
.offset
);
3259 $(this).addClass('pinned');
3262 // Add pin-top (when scrolled position is above top)
3263 if (scrolled
< options
.top
&& !$(this).hasClass('pin-top')) {
3264 removePinClasses($(this));
3265 $(this).css('top', 0);
3266 $(this).addClass('pin-top');
3269 // Add pin-bottom (when scrolled position is below bottom)
3270 if (scrolled
> options
.bottom
&& !$(this).hasClass('pin-bottom')) {
3271 removePinClasses($(this));
3272 $(this).addClass('pin-bottom');
3273 $(this).css('top', options
.bottom
- $original_offset
);
3278 updateElements($this, $(window
).scrollTop());
3279 $(window
).on('scroll.' + $uniqueId
, function () {
3280 var $scrolled
= $(window
).scrollTop() + options
.offset
;
3281 updateElements($this, $scrolled
);
3290 }( jQuery
));;(function ($) {
3291 $(document
).ready(function() {
3294 $.fn
.reverse
= [].reverse
;
3296 $(document
).on('mouseenter.fixedActionBtn', '.fixed-action-btn', function(e
) {
3297 var $this = $(this);
3302 $(document
).on('mouseleave.fixedActionBtn', '.fixed-action-btn', function(e
) {
3303 var $this = $(this);
3304 closeFABMenu($this);
3310 openFAB: function() {
3311 var $this = $(this);
3314 closeFAB: function() {
3315 closeFABMenu($this);
3320 var openFABMenu = function (btn
) {
3322 if ($this.hasClass('active') === false) {
3323 $this.addClass('active');
3324 $this.find('ul .btn-floating').velocity(
3325 { scaleY: ".4", scaleX: ".4", translateY: "40px"},
3329 $this.find('ul .btn-floating').reverse().each(function () {
3331 { opacity: "1", scaleX: "1", scaleY: "1", translateY: "0"},
3332 { duration: 80, delay: time
});
3338 var closeFABMenu = function (btn
) {
3340 $this.removeClass('active');
3342 $this.find('ul .btn-floating').velocity("stop", true);
3343 $this.find('ul .btn-floating').velocity(
3344 { opacity: "0", scaleX: ".4", scaleY: ".4", translateY: "40px"},
3352 // Image transition function
3353 Materialize
.fadeInImage = function(selector
){
3354 var element
= $(selector
);
3355 element
.css({opacity: 0});
3356 $(element
).velocity({opacity: 1}, {
3359 easing: 'easeOutSine'
3361 $(element
).velocity({opacity: 1}, {
3365 step: function(now
, fx
) {
3367 var grayscale_setting
= now
/100;
3368 var brightness_setting
= 150 - (100 - now
)/1.75;
3370 if (brightness_setting
< 100) {
3371 brightness_setting
= 100;
3375 "-webkit-filter": "grayscale("+grayscale_setting
+")" + "brightness("+brightness_setting
+"%)",
3376 "filter": "grayscale("+grayscale_setting
+")" + "brightness("+brightness_setting
+"%)"
3383 // Horizontal staggered list
3384 Materialize
.showStaggeredList = function(selector
) {
3386 $(selector
).find('li').velocity(
3387 { translateX: "-100px"},
3390 $(selector
).find('li').each(function() {
3392 { opacity: "1", translateX: "0"},
3393 { duration: 800, delay: time
, easing: [60, 10] });
3399 $(document
).ready(function() {
3400 // Hardcoded .staggered-list scrollFire
3401 // var staggeredListOptions = [];
3402 // $('ul.staggered-list').each(function (i) {
3404 // var label = 'scrollFire-' + i;
3405 // $(this).addClass(label);
3406 // staggeredListOptions.push(
3407 // {selector: 'ul.staggered-list.' + label,
3409 // callback: 'showStaggeredList("ul.staggered-list.' + label + '")'});
3411 // scrollFire(staggeredListOptions);
3413 // HammerJS, Swipe navigation
3416 var swipeLeft
= false;
3417 var swipeRight
= false;
3420 // Dismissible Collections
3421 $('.dismissable').each(function() {
3423 prevent_default: false
3424 }).bind('pan', function(e
) {
3425 if (e
.gesture
.pointerType
=== "touch") {
3426 var $this = $(this);
3427 var direction
= e
.gesture
.direction
;
3428 var x
= e
.gesture
.deltaX
;
3429 var velocityX
= e
.gesture
.velocityX
;
3431 $this.velocity({ translateX: x
3432 }, {duration: 50, queue: false, easing: 'easeOutQuad'});
3435 if (direction
=== 4 && (x
> ($this.innerWidth() / 2) || velocityX
< -0.75)) {
3440 if (direction
=== 2 && (x
< (-1 * $this.innerWidth() / 2) || velocityX
> 0.75)) {
3444 }).bind('panend', function(e
) {
3445 // Reset if collection is moved back into original position
3446 if (Math
.abs(e
.gesture
.deltaX
) < ($(this).innerWidth() / 2)) {
3451 if (e
.gesture
.pointerType
=== "touch") {
3452 var $this = $(this);
3453 if (swipeLeft
|| swipeRight
) {
3455 if (swipeLeft
) { fullWidth
= $this.innerWidth(); }
3456 else { fullWidth
= -1 * $this.innerWidth(); }
3458 $this.velocity({ translateX: fullWidth
,
3459 }, {duration: 100, queue: false, easing: 'easeOutQuad', complete:
3461 $this.css('border', 'none');
3462 $this.velocity({ height: 0, padding: 0,
3463 }, {duration: 200, queue: false, easing: 'easeOutQuad', complete:
3464 function() { $this.remove(); }
3470 $this.velocity({ translateX: 0,
3471 }, {duration: 100, queue: false, easing: 'easeOutQuad'});
3482 // // Vertical Staggered list
3483 // $('ul.staggered-list.vertical li').velocity(
3484 // { translateY: "100px"},
3485 // { duration: 0 });
3487 // $('ul.staggered-list.vertical li').each(function() {
3488 // $(this).velocity(
3489 // { opacity: "1", translateY: "0"},
3490 // { duration: 800, delay: time, easing: [60, 25] });
3494 // // Fade in and Scale
3495 // $('.fade-in.scale').velocity(
3496 // { scaleX: .4, scaleY: .4, translateX: -600},
3498 // $('.fade-in').each(function() {
3499 // $(this).velocity(
3500 // { opacity: "1", scaleX: 1, scaleY: 1, translateX: 0},
3501 // { duration: 800, easing: [60, 10] });
3507 // Input: Array of JSON objects {selector, offset, callback}
3509 Materialize
.scrollFire = function(options
) {
3511 var didScroll
= false;
3513 window
.addEventListener("scroll", function() {
3517 // Rate limit to 100ms
3518 setInterval(function() {
3522 var windowScroll
= window
.pageYOffset
+ window
.innerHeight
;
3524 for (var i
= 0 ; i
< options
.length
; i
++) {
3525 // Get options from each line
3526 var value
= options
[i
];
3527 var selector
= value
.selector
,
3528 offset
= value
.offset
,
3529 callback
= value
.callback
;
3531 var currentElement
= document
.querySelector(selector
);
3532 if ( currentElement
!== null) {
3533 var elementOffset
= currentElement
.getBoundingClientRect().top
+ document
.body
.scrollTop
;
3535 if (windowScroll
> (elementOffset
+ offset
)) {
3536 if (value
.done
!== true) {
3537 var callbackFunc
= new Function(callback
);
3549 * pickadate.js v3.5.0, 2014/04/13
3550 * By Amsul, http://amsul.ca
3551 * Hosted on http://amsul.github.io/pickadate.js
3552 * Licensed under MIT
3555 (function ( factory
) {
3558 if ( typeof define
== 'function' && define
.amd
)
3559 define( 'picker', ['jquery'], factory
)
3561 // Node.js/browserify.
3562 else if ( typeof exports
== 'object' )
3563 module
.exports
= factory( require('jquery') )
3566 else this.Picker
= factory( jQuery
)
3570 var $window
= $( window
)
3571 var $document
= $( document
)
3572 var $html
= $( document
.documentElement
)
3576 * The picker constructor that creates a blank picker.
3578 function PickerConstructor( ELEMENT
, NAME
, COMPONENT
, OPTIONS
) {
3580 // If there’s no element, return the picker constructor.
3581 if ( !ELEMENT
) return PickerConstructor
3585 IS_DEFAULT_THEME
= false,
3588 // The state of the picker.
3590 id: ELEMENT
.id
|| 'P' + Math
.abs( ~~(Math
.random() * new Date()) )
3594 // Merge the defaults and options passed.
3595 SETTINGS
= COMPONENT
? $.extend( true, {}, COMPONENT
.defaults
, OPTIONS
) : OPTIONS
|| {},
3598 // Merge the default classes with the settings classes.
3599 CLASSES
= $.extend( {}, PickerConstructor
.klasses(), SETTINGS
.klass
),
3602 // The element node wrapper into a jQuery object.
3603 $ELEMENT
= $( ELEMENT
),
3606 // Pseudo picker constructor.
3607 PickerInstance = function() {
3612 // The picker prototype.
3613 P
= PickerInstance
.prototype = {
3615 constructor: PickerInstance
,
3621 * Initialize everything
3625 // If it’s already started, do nothing.
3626 if ( STATE
&& STATE
.start
) return P
3629 // Update the picker states.
3633 STATE
.type
= ELEMENT
.type
3636 // Confirm focus state, convert into text input to remove UA stylings,
3637 // and set as readonly to prevent keyboard popup.
3638 ELEMENT
.autofocus
= ELEMENT
== getActiveElement()
3639 ELEMENT
.readOnly
= !SETTINGS
.editable
3640 ELEMENT
.id
= ELEMENT
.id
|| STATE
.id
3641 if ( ELEMENT
.type
!= 'text' ) {
3642 ELEMENT
.type
= 'text'
3646 // Create a new picker component with the settings.
3647 P
.component
= new COMPONENT(P
, SETTINGS
)
3650 // Create the picker root with a holder and then prepare it.
3651 P
.$root
= $( PickerConstructor
._
.node('div', createWrappedComponent(), CLASSES
.picker
, 'id="' + ELEMENT
.id
+ '_root" tabindex="0"') )
3652 prepareElementRoot()
3655 // If there’s a format for the hidden input element, create the element.
3656 if ( SETTINGS
.formatSubmit
) {
3657 prepareElementHidden()
3661 // Prepare the input element.
3665 // Insert the root as specified in the settings.
3666 if ( SETTINGS
.container
) $( SETTINGS
.container
).append( P
.$root
)
3667 else $ELEMENT
.after( P
.$root
)
3670 // Bind the default component and settings events.
3672 start: P
.component
.onStart
,
3673 render: P
.component
.onRender
,
3674 stop: P
.component
.onStop
,
3675 open: P
.component
.onOpen
,
3676 close: P
.component
.onClose
,
3677 set: P
.component
.onSet
3679 start: SETTINGS
.onStart
,
3680 render: SETTINGS
.onRender
,
3681 stop: SETTINGS
.onStop
,
3682 open: SETTINGS
.onOpen
,
3683 close: SETTINGS
.onClose
,
3688 // Once we’re all set, check the theme in use.
3689 IS_DEFAULT_THEME
= isUsingDefaultTheme( P
.$root
.children()[ 0 ] )
3692 // If the element has autofocus, open the picker.
3693 if ( ELEMENT
.autofocus
) {
3698 // Trigger queued the “start” and “render” events.
3699 return P
.trigger( 'start' ).trigger( 'render' )
3704 * Render a new picker
3706 render: function( entireComponent
) {
3708 // Insert a new component holder in the root or box.
3709 if ( entireComponent
) P
.$root
.html( createWrappedComponent() )
3710 else P
.$root
.find( '.' + CLASSES
.box
).html( P
.component
.nodes( STATE
.open
) )
3712 // Trigger the queued “render” events.
3713 return P
.trigger( 'render' )
3718 * Destroy everything
3722 // If it’s already stopped, do nothing.
3723 if ( !STATE
.start
) return P
3725 // Then close the picker.
3728 // Remove the hidden field.
3730 P
._hidden
.parentNode
.removeChild( P
._hidden
)
3736 // Remove the input class, remove the stored data, and unbind
3737 // the events (after a tick for IE - see `P.close`).
3738 $ELEMENT
.removeClass( CLASSES
.input
).removeData( NAME
)
3739 setTimeout( function() {
3740 $ELEMENT
.off( '.' + STATE
.id
)
3743 // Restore the element state
3744 ELEMENT
.type
= STATE
.type
3745 ELEMENT
.readOnly
= false
3747 // Trigger the queued “stop” events.
3750 // Reset the picker states.
3759 * Open up the picker
3761 open: function( dontGiveFocus
) {
3763 // If it’s already open, do nothing.
3764 if ( STATE
.open
) return P
3766 // Add the “active” class.
3767 $ELEMENT
.addClass( CLASSES
.active
)
3768 aria( ELEMENT
, 'expanded', true )
3770 // * A Firefox bug, when `html` has `overflow:hidden`, results in
3771 // killing transitions :(. So add the “opened” state on the next tick.
3772 // Bug: https://bugzilla.mozilla.org/show_bug.cgi?id=625289
3773 setTimeout( function() {
3775 // Add the “opened” class to the picker root.
3776 P
.$root
.addClass( CLASSES
.opened
)
3777 aria( P
.$root
[0], 'hidden', false )
3781 // If we have to give focus, bind the element and doc events.
3782 if ( dontGiveFocus
!== false ) {
3787 // Prevent the page from scrolling.
3788 if ( IS_DEFAULT_THEME
) {
3790 css( 'overflow', 'hidden' ).
3791 css( 'padding-right', '+=' + getScrollbarWidth() )
3794 // Pass focus to the root element’s jQuery object.
3795 // * Workaround for iOS8 to bring the picker’s root into view.
3798 // Bind the document events.
3799 $document
.on( 'click.' + STATE
.id
+ ' focusin.' + STATE
.id
, function( event
) {
3801 var target
= event
.target
3803 // If the target of the event is not the element, close the picker picker.
3804 // * Don’t worry about clicks or focusins on the root because those don’t bubble up.
3805 // Also, for Firefox, a click on an `option` element bubbles up directly
3806 // to the doc. So make sure the target wasn't the doc.
3807 // * In Firefox stopPropagation() doesn’t prevent right-click events from bubbling,
3808 // which causes the picker to unexpectedly close when right-clicking it. So make
3809 // sure the event wasn’t a right-click.
3810 if ( target
!= ELEMENT
&& target
!= document
&& event
.which
!= 3 ) {
3812 // If the target was the holder that covers the screen,
3813 // keep the element focused to maintain tabindex.
3814 P
.close( target
=== P
.$root
.children()[0] )
3817 }).on( 'keydown.' + STATE
.id
, function( event
) {
3821 keycode
= event
.keyCode
,
3823 // Translate that to a selection change.
3824 keycodeToMove
= P
.component
.key
[ keycode
],
3827 target
= event
.target
3830 // On escape, close the picker and give focus.
3831 if ( keycode
== 27 ) {
3836 // Check if there is a key movement or “enter” keypress on the element.
3837 else if ( target
== P
.$root
[0] && ( keycodeToMove
|| keycode
== 13 ) ) {
3839 // Prevent the default action to stop page movement.
3840 event
.preventDefault()
3842 // Trigger the key movement action.
3843 if ( keycodeToMove
) {
3844 PickerConstructor
._
.trigger( P
.component
.key
.go
, P
, [ PickerConstructor
._
.trigger( keycodeToMove
) ] )
3847 // On “enter”, if the highlighted item isn’t disabled, set the value and close.
3848 else if ( !P
.$root
.find( '.' + CLASSES
.highlighted
).hasClass( CLASSES
.disabled
) ) {
3849 P
.set( 'select', P
.component
.item
.highlight
).close()
3854 // If the target is within the root and “enter” is pressed,
3855 // prevent the default action and trigger a click on the target instead.
3856 else if ( $.contains( P
.$root
[0], target
) && keycode
== 13 ) {
3857 event
.preventDefault()
3863 // Trigger the queued “open” events.
3864 return P
.trigger( 'open' )
3871 close: function( giveFocus
) {
3873 // If we need to give focus, do it before changing states.
3875 // ....ah yes! It would’ve been incomplete without a crazy workaround for IE :|
3876 // The focus is triggered *after* the close has completed - causing it
3877 // to open again. So unbind and rebind the event at the next tick.
3878 P
.$root
.off( 'focus.toOpen' )[0].focus()
3879 setTimeout( function() {
3880 P
.$root
.on( 'focus.toOpen', handleFocusToOpenEvent
)
3884 // Remove the “active” class.
3885 $ELEMENT
.removeClass( CLASSES
.active
)
3886 aria( ELEMENT
, 'expanded', false )
3888 // * A Firefox bug, when `html` has `overflow:hidden`, results in
3889 // killing transitions :(. So remove the “opened” state on the next tick.
3890 // Bug: https://bugzilla.mozilla.org/show_bug.cgi?id=625289
3891 setTimeout( function() {
3893 // Remove the “opened” and “focused” class from the picker root.
3894 P
.$root
.removeClass( CLASSES
.opened
+ ' ' + CLASSES
.focused
)
3895 aria( P
.$root
[0], 'hidden', true )
3899 // If it’s already closed, do nothing more.
3900 if ( !STATE
.open
) return P
3902 // Set it as closed.
3905 // Allow the page to scroll.
3906 if ( IS_DEFAULT_THEME
) {
3908 css( 'overflow', '' ).
3909 css( 'padding-right', '-=' + getScrollbarWidth() )
3912 // Unbind the document events.
3913 $document
.off( '.' + STATE
.id
)
3915 // Trigger the queued “close” events.
3916 return P
.trigger( 'close' )
3923 clear: function( options
) {
3924 return P
.set( 'clear', null, options
)
3931 set: function( thing
, value
, options
) {
3933 var thingItem
, thingValue
,
3934 thingIsObject
= $.isPlainObject( thing
),
3935 thingObject
= thingIsObject
? thing : {}
3937 // Make sure we have usable options.
3938 options
= thingIsObject
&& $.isPlainObject( value
) ? value : options
|| {}
3942 // If the thing isn’t an object, make it one.
3943 if ( !thingIsObject
) {
3944 thingObject
[ thing
] = value
3947 // Go through the things of items to set.
3948 for ( thingItem
in thingObject
) {
3950 // Grab the value of the thing.
3951 thingValue
= thingObject
[ thingItem
]
3953 // First, if the item exists and there’s a value, set it.
3954 if ( thingItem
in P
.component
.item
) {
3955 if ( thingValue
=== undefined ) thingValue
= null
3956 P
.component
.set( thingItem
, thingValue
, options
)
3959 // Then, check to update the element value and broadcast a change.
3960 if ( thingItem
== 'select' || thingItem
== 'clear' ) {
3962 val( thingItem
== 'clear' ? '' : P
.get( thingItem
, SETTINGS
.format
) ).
3967 // Render a new picker.
3971 // When the method isn’t muted, trigger queued “set” events and pass the `thingObject`.
3972 return options
.muted
? P : P
.trigger( 'set', thingObject
)
3979 get: function( thing
, format
) {
3981 // Make sure there’s something to get.
3982 thing
= thing
|| 'value'
3984 // If a picker state exists, return that.
3985 if ( STATE
[ thing
] != null ) {
3986 return STATE
[ thing
]
3989 // Return the submission value, if that.
3990 if ( thing
== 'valueSubmit' ) {
3992 return P
._hidden
.value
3997 // Return the value, if that.
3998 if ( thing
== 'value' ) {
3999 return ELEMENT
.value
4002 // Check if a component item exists, return that.
4003 if ( thing
in P
.component
.item
) {
4004 if ( typeof format
== 'string' ) {
4005 var thingValue
= P
.component
.get( thing
)
4007 PickerConstructor
._
.trigger(
4008 P
.component
.formats
.toString
,
4010 [ format
, thingValue
]
4013 return P
.component
.get( thing
)
4020 * Bind events on the things.
4022 on: function( thing
, method
, internal ) {
4024 var thingName
, thingMethod
,
4025 thingIsObject
= $.isPlainObject( thing
),
4026 thingObject
= thingIsObject
? thing : {}
4030 // If the thing isn’t an object, make it one.
4031 if ( !thingIsObject
) {
4032 thingObject
[ thing
] = method
4035 // Go through the things to bind to.
4036 for ( thingName
in thingObject
) {
4038 // Grab the method of the thing.
4039 thingMethod
= thingObject
[ thingName
]
4041 // If it was an internal binding, prefix it.
4043 thingName
= '_' + thingName
4046 // Make sure the thing methods collection exists.
4047 STATE
.methods
[ thingName
] = STATE
.methods
[ thingName
] || []
4049 // Add the method to the relative method collection.
4050 STATE
.methods
[ thingName
].push( thingMethod
)
4060 * Unbind events on the things.
4065 for ( i
= 0, namesCount
= names
.length
; i
< namesCount
; i
+= 1 ) {
4066 thingName
= names
[i
]
4067 if ( thingName
in STATE
.methods
) {
4068 delete STATE
.methods
[thingName
]
4076 * Fire off method events.
4078 trigger: function( name
, data
) {
4079 var _trigger = function( name
) {
4080 var methodList
= STATE
.methods
[ name
]
4082 methodList
.map( function( method
) {
4083 PickerConstructor
._
.trigger( method
, P
, [ data
] )
4087 _trigger( '_' + name
)
4091 } //PickerInstance.prototype
4095 * Wrap the picker holder components together.
4097 function createWrappedComponent() {
4099 // Create a picker wrapper holder
4100 return PickerConstructor
._
.node( 'div',
4102 // Create a picker wrapper node
4103 PickerConstructor
._
.node( 'div',
4105 // Create a picker frame
4106 PickerConstructor
._
.node( 'div',
4108 // Create a picker box node
4109 PickerConstructor
._
.node( 'div',
4111 // Create the components nodes.
4112 P
.component
.nodes( STATE
.open
),
4114 // The picker box class
4118 // Picker wrap class
4122 // Picker frame class
4126 // Picker holder class
4129 } //createWrappedComponent
4134 * Prepare the input element with all bindings.
4136 function prepareElement() {
4140 // Store the picker data by component name.
4143 // Add the “input” class name.
4144 addClass(CLASSES
.input
).
4146 // Remove the tabindex.
4147 attr('tabindex', -1).
4149 // If there’s a `data-value`, update the value of the element.
4150 val( $ELEMENT
.data('value') ?
4151 P
.get('select', SETTINGS
.format
) :
4156 // Only bind keydown events if the element isn’t editable.
4157 if ( !SETTINGS
.editable
) {
4161 // On focus/click, focus onto the root to open it up.
4162 on( 'focus.' + STATE
.id
+ ' click.' + STATE
.id
, function( event
) {
4163 event
.preventDefault()
4167 // Handle keyboard event based on the picker being opened or not.
4168 on( 'keydown.' + STATE
.id
, handleKeydownEvent
)
4172 // Update the aria attributes.
4177 owns: ELEMENT
.id
+ '_root'
4183 * Prepare the root picker element with all bindings.
4185 function prepareElementRoot() {
4192 keydown: handleKeydownEvent
,
4194 // When something within the root is focused, stop from bubbling
4195 // to the doc and remove the “focused” state from the root.
4196 focusin: function( event
) {
4197 P
.$root
.removeClass( CLASSES
.focused
)
4198 event
.stopPropagation()
4201 // When something within the root holder is clicked, stop it
4202 // from bubbling to the doc.
4203 'mousedown click': function( event
) {
4205 var target
= event
.target
4207 // Make sure the target isn’t the root holder so it can bubble up.
4208 if ( target
!= P
.$root
.children()[ 0 ] ) {
4210 event
.stopPropagation()
4212 // * For mousedown events, cancel the default action in order to
4213 // prevent cases where focus is shifted onto external elements
4214 // when using things like jQuery mobile or MagnificPopup (ref: #249 & #120).
4215 // Also, for Firefox, don’t prevent action on the `option` element.
4216 if ( event
.type
== 'mousedown' && !$( target
).is( 'input, select, textarea, button, option' )) {
4218 event
.preventDefault()
4220 // Re-focus onto the root so that users can click away
4221 // from elements focused within the picker.
4228 // Add/remove the “target” class on focus and blur.
4231 $ELEMENT
.addClass( CLASSES
.target
)
4234 $ELEMENT
.removeClass( CLASSES
.target
)
4238 // Open the picker and adjust the root “focused” state
4239 on( 'focus.toOpen', handleFocusToOpenEvent
).
4241 // If there’s a click on an actionable element, carry out the actions.
4242 on( 'click', '[data-pick], [data-nav], [data-clear], [data-close]', function() {
4244 var $target
= $( this ),
4245 targetData
= $target
.data(),
4246 targetDisabled
= $target
.hasClass( CLASSES
.navDisabled
) || $target
.hasClass( CLASSES
.disabled
),
4248 // * For IE, non-focusable elements can be active elements as well
4249 // (http://stackoverflow.com/a/2684561).
4250 activeElement
= getActiveElement()
4251 activeElement
= activeElement
&& ( activeElement
.type
|| activeElement
.href
)
4253 // If it’s disabled or nothing inside is actively focused, re-focus the element.
4254 if ( targetDisabled
|| activeElement
&& !$.contains( P
.$root
[0], activeElement
) ) {
4258 // If something is superficially changed, update the `highlight` based on the `nav`.
4259 if ( !targetDisabled
&& targetData
.nav
) {
4260 P
.set( 'highlight', P
.component
.item
.highlight
, { nav: targetData
.nav
} )
4263 // If something is picked, set `select` then close with focus.
4264 else if ( !targetDisabled
&& 'pick' in targetData
) {
4265 P
.set( 'select', targetData
.pick
)
4268 // If a “clear” button is pressed, empty the values and close with focus.
4269 else if ( targetData
.clear
) {
4270 P
.clear().close( true )
4273 else if ( targetData
.close
) {
4279 aria( P
.$root
[0], 'hidden', true )
4284 * Prepare the hidden input element along with all bindings.
4286 function prepareElementHidden() {
4290 if ( SETTINGS
.hiddenName
=== true ) {
4296 typeof SETTINGS
.hiddenPrefix
== 'string' ? SETTINGS
.hiddenPrefix : '',
4297 typeof SETTINGS
.hiddenSuffix
== 'string' ? SETTINGS
.hiddenSuffix : '_submit'
4299 name
= name
[0] + ELEMENT
.name
+ name
[1]
4306 // Create the name using the original input’s with a prefix and suffix.
4307 'name="' + name
+ '"' +
4309 // If the element has a value, set the hidden value as well.
4311 $ELEMENT
.data('value') || ELEMENT
.value
?
4312 ' value="' + P
.get('select', SETTINGS
.formatSubmit
) + '"' :
4320 // If the value changes, update the hidden input with the correct format.
4321 on('change.' + STATE
.id
, function() {
4322 P
._hidden
.value
= ELEMENT
.value
?
4323 P
.get('select', SETTINGS
.formatSubmit
) :
4328 // Insert the hidden input as specified in the settings.
4329 if ( SETTINGS
.container
) $( SETTINGS
.container
).append( P
._hidden
)
4330 else $ELEMENT
.after( P
._hidden
)
4335 function handleKeydownEvent( event
) {
4337 var keycode
= event
.keyCode
,
4339 // Check if one of the delete keys was pressed.
4340 isKeycodeDelete
= /^(8|46)$/.test(keycode
)
4342 // For some reason IE clears the input value on “escape”.
4343 if ( keycode
== 27 ) {
4348 // Check if `space` or `delete` was pressed or the picker is closed with a key movement.
4349 if ( keycode
== 32 || isKeycodeDelete
|| !STATE
.open
&& P
.component
.key
[keycode
] ) {
4351 // Prevent it from moving the page and bubbling to doc.
4352 event
.preventDefault()
4353 event
.stopPropagation()
4355 // If `delete` was pressed, clear the values and close the picker.
4356 // Otherwise open the picker.
4357 if ( isKeycodeDelete
) { P
.clear().close() }
4364 function handleFocusToOpenEvent( event
) {
4366 // Stop the event from propagating to the doc.
4367 event
.stopPropagation()
4369 // If it’s a focus event, add the “focused” class to the root.
4370 if ( event
.type
== 'focus' ) {
4371 P
.$root
.addClass( CLASSES
.focused
)
4374 // And then finally open the picker.
4379 // Return a new picker instance.
4380 return new PickerInstance()
4381 } //PickerConstructor
4386 * The default classes and prefix to use for the HTML classes.
4388 PickerConstructor
.klasses = function( prefix
) {
4389 prefix
= prefix
|| 'picker'
4393 opened: prefix
+ '--opened',
4394 focused: prefix
+ '--focused',
4396 input: prefix
+ '__input',
4397 active: prefix
+ '__input--active',
4398 target: prefix
+ '__input--target',
4400 holder: prefix
+ '__holder',
4402 frame: prefix
+ '__frame',
4403 wrap: prefix
+ '__wrap',
4405 box: prefix
+ '__box'
4407 } //PickerConstructor.klasses
4412 * Check if the default theme is being used.
4414 function isUsingDefaultTheme( element
) {
4420 if ( element
.currentStyle
) {
4421 theme
= element
.currentStyle
[prop
]
4424 // For normal browsers.
4425 else if ( window
.getComputedStyle
) {
4426 theme
= getComputedStyle( element
)[prop
]
4429 return theme
== 'fixed'
4435 * Get the width of the browser’s scrollbar.
4436 * Taken from: https://github.com/VodkaBears/Remodal/blob/master/src/jquery.remodal.js
4438 function getScrollbarWidth() {
4440 if ( $html
.height() <= $window
.height() ) {
4444 var $outer
= $( '<div style="visibility:hidden;width:100px" />' ).
4447 // Get the width without scrollbars.
4448 var widthWithoutScroll
= $outer
[0].offsetWidth
4450 // Force adding scrollbars.
4451 $outer
.css( 'overflow', 'scroll' )
4453 // Add the inner div.
4454 var $inner
= $( '<div style="width:100%" />' ).appendTo( $outer
)
4456 // Get the width with scrollbars.
4457 var widthWithScroll
= $inner
[0].offsetWidth
4462 // Return the difference between the widths.
4463 return widthWithoutScroll
- widthWithScroll
4469 * PickerConstructor helper methods.
4471 PickerConstructor
._
= {
4474 * Create a group of nodes. Expects:
4485 group: function( groupObject
) {
4488 // Scope for the looped object
4491 // Create the nodes list
4494 // The counter starts from the `min`
4495 counter
= PickerConstructor
._
.trigger( groupObject
.min
, groupObject
)
4498 // Loop from the `min` to `max`, incrementing by `i`
4499 for ( ; counter
<= PickerConstructor
._
.trigger( groupObject
.max
, groupObject
, [ counter
] ); counter
+= groupObject
.i
) {
4501 // Trigger the `item` function within scope of the object
4502 loopObjectScope
= PickerConstructor
._
.trigger( groupObject
.item
, groupObject
, [ counter
] )
4504 // Splice the subgroup and create nodes out of the sub nodes
4505 nodesList
+= PickerConstructor
._
.node(
4507 loopObjectScope
[ 0 ], // the node
4508 loopObjectScope
[ 1 ], // the classes
4509 loopObjectScope
[ 2 ] // the attributes
4513 // Return the list of nodes
4519 * Create a dom node string
4521 node: function( wrapper
, item
, klass
, attribute
) {
4523 // If the item is false-y, just return an empty string
4524 if ( !item
) return ''
4526 // If the item is an array, do a join
4527 item
= $.isArray( item
) ? item
.join( '' ) : item
4529 // Check for the class
4530 klass
= klass
? ' class="' + klass
+ '"' : ''
4532 // Check for any attributes
4533 attribute
= attribute
? ' ' + attribute : ''
4535 // Return the wrapped item
4536 return '<' + wrapper
+ klass
+ attribute
+ '>' + item
+ '</' + wrapper
+ '>'
4541 * Lead numbers below 10 with a zero.
4543 lead: function( number
) {
4544 return ( number
< 10 ? '0': '' ) + number
4549 * Trigger a function otherwise return the value.
4551 trigger: function( callback
, scope
, args
) {
4552 return typeof callback
== 'function' ? callback
.apply( scope
, args
|| [] ) : callback
4557 * If the second character is a digit, length is 2 otherwise 1.
4559 digits: function( string
) {
4560 return ( /\d/ ).test( string
[ 1 ] ) ? 2 : 1
4565 * Tell if something is a date object.
4567 isDate: function( value
) {
4568 return {}.toString
.call( value
).indexOf( 'Date' ) > -1 && this.isInteger( value
.getDate() )
4573 * Tell if something is an integer.
4575 isInteger: function( value
) {
4576 return {}.toString
.call( value
).indexOf( 'Number' ) > -1 && value
% 1 === 0
4581 * Create ARIA attribute strings.
4584 } //PickerConstructor._
4589 * Extend the picker with a component and defaults.
4591 PickerConstructor
.extend = function( name
, Component
) {
4594 $.fn
[ name
] = function( options
, action
) {
4596 // Grab the component data.
4597 var componentData
= this.data( name
)
4599 // If the picker is requested, return the data object.
4600 if ( options
== 'picker' ) {
4601 return componentData
4604 // If the component data exists and `options` is a string, carry out the action.
4605 if ( componentData
&& typeof options
== 'string' ) {
4606 return PickerConstructor
._
.trigger( componentData
[ options
], componentData
, [ action
] )
4609 // Otherwise go through each matched element and if the component
4610 // doesn’t exist, create a new picker using `this` element
4611 // and merging the defaults and options with a deep copy.
4612 return this.each( function() {
4613 var $this = $( this )
4614 if ( !$this.data( name
) ) {
4615 new PickerConstructor( this, name
, Component
, options
)
4620 // Set the defaults.
4621 $.fn
[ name
].defaults
= Component
.defaults
4622 } //PickerConstructor.extend
4626 function aria(element
, attribute
, value
) {
4627 if ( $.isPlainObject(attribute
) ) {
4628 for ( var key
in attribute
) {
4629 ariaSet(element
, key
, attribute
[key
])
4633 ariaSet(element
, attribute
, value
)
4636 function ariaSet(element
, attribute
, value
) {
4637 element
.setAttribute(
4638 (attribute
== 'role' ? '' : 'aria-') + attribute
,
4642 function ariaAttr(attribute
, data
) {
4643 if ( !$.isPlainObject(attribute
) ) {
4644 attribute
= { attribute: data
}
4647 for ( var key
in attribute
) {
4648 var attr
= (key
== 'role' ? '' : 'aria-') + key
,
4649 attrVal
= attribute
[key
]
4650 data
+= attrVal
== null ? '' : attr
+ '="' + attribute
[key
] + '"'
4655 // IE8 bug throws an error for activeElements within iframes.
4656 function getActiveElement() {
4658 return document
.activeElement
4664 // Expose the picker constructor.
4665 return PickerConstructor
4672 * Date picker for pickadate.js v3.5.0
4673 * http://amsul.github.io/pickadate.js/date.htm
4676 (function ( factory
) {
4679 if ( typeof define
== 'function' && define
.amd
)
4680 define( ['picker', 'jquery'], factory
)
4682 // Node.js/browserify.
4683 else if ( typeof exports
== 'object' )
4684 module
.exports
= factory( require('./picker.js'), require('jquery') )
4687 else factory( Picker
, jQuery
)
4689 }(function( Picker
, $ ) {
4693 * Globals and constants
4695 var DAYS_IN_WEEK
= 7,
4696 WEEKS_IN_CALENDAR
= 6,
4702 * The date picker constructor
4704 function DatePicker( picker
, settings
) {
4706 var calendar
= this,
4707 element
= picker
.$node
[ 0 ],
4708 elementValue
= element
.value
,
4709 elementDataValue
= picker
.$node
.data( 'value' ),
4710 valueString
= elementDataValue
|| elementValue
,
4711 formatString
= elementDataValue
? settings
.formatSubmit : settings
.format
,
4712 isRTL = function() {
4714 return element
.currentStyle
?
4717 element
.currentStyle
.direction
== 'rtl' :
4719 // For normal browsers.
4720 getComputedStyle( picker
.$root
[0] ).direction
== 'rtl'
4723 calendar
.settings
= settings
4724 calendar
.$node
= picker
.$node
4726 // The queue of methods that will be used to build item objects.
4728 min: 'measure create',
4729 max: 'measure create',
4731 select: 'parse create validate',
4732 highlight: 'parse navigate create validate',
4733 view: 'parse create validate viewset',
4734 disable: 'deactivate',
4738 // The component's item object.
4741 calendar
.item
.clear
= null
4742 calendar
.item
.disable
= ( settings
.disable
|| [] ).slice( 0 )
4743 calendar
.item
.enable
= -(function( collectionDisabled
) {
4744 return collectionDisabled
[ 0 ] === true ? collectionDisabled
.shift() : -1
4745 })( calendar
.item
.disable
)
4748 set( 'min', settings
.min
).
4749 set( 'max', settings
.max
).
4752 // When there’s a value, set the `select`, which in turn
4753 // also sets the `highlight` and `view`.
4754 if ( valueString
) {
4755 calendar
.set( 'select', valueString
, { format: formatString
})
4758 // If there’s no value, default to highlighting “today”.
4761 set( 'select', null ).
4762 set( 'highlight', calendar
.item
.now
)
4766 // The keycode to movement mapping.
4770 39: function() { return isRTL() ? -1 : 1 }, // Right
4771 37: function() { return isRTL() ? 1 : -1 }, // Left
4772 go: function( timeChange
) {
4773 var highlightedObject
= calendar
.item
.highlight
,
4774 targetDate
= new Date( highlightedObject
.year
, highlightedObject
.month
, highlightedObject
.date
+ timeChange
)
4778 { interval: timeChange
}
4785 // Bind some picker events.
4787 on( 'render', function() {
4788 picker
.$root
.find( '.' + settings
.klass
.selectMonth
).on( 'change', function() {
4789 var value
= this.value
4791 picker
.set( 'highlight', [ picker
.get( 'view' ).year
, value
, picker
.get( 'highlight' ).date
] )
4792 picker
.$root
.find( '.' + settings
.klass
.selectMonth
).trigger( 'focus' )
4795 picker
.$root
.find( '.' + settings
.klass
.selectYear
).on( 'change', function() {
4796 var value
= this.value
4798 picker
.set( 'highlight', [ value
, picker
.get( 'view' ).month
, picker
.get( 'highlight' ).date
] )
4799 picker
.$root
.find( '.' + settings
.klass
.selectYear
).trigger( 'focus' )
4803 on( 'open', function() {
4804 var includeToday
= ''
4805 if ( calendar
.disabled( calendar
.get('now') ) ) {
4806 includeToday
= ':not(.' + settings
.klass
.buttonToday
+ ')'
4808 picker
.$root
.find( 'button' + includeToday
+ ', select' ).attr( 'disabled', false )
4810 on( 'close', function() {
4811 picker
.$root
.find( 'button, select' ).attr( 'disabled', true )
4818 * Set a datepicker item object.
4820 DatePicker
.prototype.set = function( type
, value
, options
) {
4822 var calendar
= this,
4823 calendarItem
= calendar
.item
4825 // If the value is `null` just set it immediately.
4826 if ( value
=== null ) {
4827 if ( type
== 'clear' ) type
= 'select'
4828 calendarItem
[ type
] = value
4832 // Otherwise go through the queue of methods, and invoke the functions.
4833 // Update this as the time unit, and set the final value as this item.
4834 // * In the case of `enable`, keep the queue but set `disable` instead.
4835 // And in the case of `flip`, keep the queue but set `enable` instead.
4836 calendarItem
[ ( type
== 'enable' ? 'disable' : type
== 'flip' ? 'enable' : type
) ] = calendar
.queue
[ type
].split( ' ' ).map( function( method
) {
4837 value
= calendar
[ method
]( type
, value
, options
)
4841 // Check if we need to cascade through more updates.
4842 if ( type
== 'select' ) {
4843 calendar
.set( 'highlight', calendarItem
.select
, options
)
4845 else if ( type
== 'highlight' ) {
4846 calendar
.set( 'view', calendarItem
.highlight
, options
)
4848 else if ( type
.match( /^(flip|min|max|disable|enable)$/ ) ) {
4849 if ( calendarItem
.select
&& calendar
.disabled( calendarItem
.select
) ) {
4850 calendar
.set( 'select', calendarItem
.select
, options
)
4852 if ( calendarItem
.highlight
&& calendar
.disabled( calendarItem
.highlight
) ) {
4853 calendar
.set( 'highlight', calendarItem
.highlight
, options
)
4858 } //DatePicker.prototype.set
4862 * Get a datepicker item object.
4864 DatePicker
.prototype.get = function( type
) {
4865 return this.item
[ type
]
4866 } //DatePicker.prototype.get
4870 * Create a picker date object.
4872 DatePicker
.prototype.create = function( type
, value
, options
) {
4874 var isInfiniteValue
,
4877 // If there’s no value, use the type as the value.
4878 value
= value
=== undefined ? type : value
4881 // If it’s infinity, update the value.
4882 if ( value
== -Infinity
|| value
== Infinity
) {
4883 isInfiniteValue
= value
4886 // If it’s an object, use the native date object.
4887 else if ( $.isPlainObject( value
) && _
.isInteger( value
.pick
) ) {
4891 // If it’s an array, convert it into a date and make sure
4892 // that it’s a valid date – otherwise default to today.
4893 else if ( $.isArray( value
) ) {
4894 value
= new Date( value
[ 0 ], value
[ 1 ], value
[ 2 ] )
4895 value
= _
.isDate( value
) ? value : calendar
.create().obj
4898 // If it’s a number or date object, make a normalized date.
4899 else if ( _
.isInteger( value
) || _
.isDate( value
) ) {
4900 value
= calendar
.normalize( new Date( value
), options
)
4903 // If it’s a literal true or any other case, set it to now.
4904 else /*if ( value === true )*/ {
4905 value
= calendar
.now( type
, value
, options
)
4908 // Return the compiled object.
4910 year: isInfiniteValue
|| value
.getFullYear(),
4911 month: isInfiniteValue
|| value
.getMonth(),
4912 date: isInfiniteValue
|| value
.getDate(),
4913 day: isInfiniteValue
|| value
.getDay(),
4914 obj: isInfiniteValue
|| value
,
4915 pick: isInfiniteValue
|| value
.getTime()
4917 } //DatePicker.prototype.create
4921 * Create a range limit object using an array, date object,
4922 * literal “true”, or integer relative to another time.
4924 DatePicker
.prototype.createRange = function( from, to
) {
4926 var calendar
= this,
4927 createDate = function( date
) {
4928 if ( date
=== true || $.isArray( date
) || _
.isDate( date
) ) {
4929 return calendar
.create( date
)
4934 // Create objects if possible.
4935 if ( !_
.isInteger( from ) ) {
4936 from = createDate( from )
4938 if ( !_
.isInteger( to
) ) {
4939 to
= createDate( to
)
4942 // Create relative dates.
4943 if ( _
.isInteger( from ) && $.isPlainObject( to
) ) {
4944 from = [ to
.year
, to
.month
, to
.date
+ from ];
4946 else if ( _
.isInteger( to
) && $.isPlainObject( from ) ) {
4947 to
= [ from.year
, from.month
, from.date
+ to
];
4951 from: createDate( from ),
4952 to: createDate( to
)
4954 } //DatePicker.prototype.createRange
4958 * Check if a date unit falls within a date range object.
4960 DatePicker
.prototype.withinRange = function( range
, dateUnit
) {
4961 range
= this.createRange(range
.from, range
.to
)
4962 return dateUnit
.pick
>= range
.from.pick
&& dateUnit
.pick
<= range
.to
.pick
4967 * Check if two date range objects overlap.
4969 DatePicker
.prototype.overlapRanges = function( one
, two
) {
4973 // Convert the ranges into comparable dates.
4974 one
= calendar
.createRange( one
.from, one
.to
)
4975 two
= calendar
.createRange( two
.from, two
.to
)
4977 return calendar
.withinRange( one
, two
.from ) || calendar
.withinRange( one
, two
.to
) ||
4978 calendar
.withinRange( two
, one
.from ) || calendar
.withinRange( two
, one
.to
)
4983 * Get the date today.
4985 DatePicker
.prototype.now = function( type
, value
, options
) {
4987 if ( options
&& options
.rel
) {
4988 value
.setDate( value
.getDate() + options
.rel
)
4990 return this.normalize( value
, options
)
4995 * Navigate to next/prev month.
4997 DatePicker
.prototype.navigate = function( type
, value
, options
) {
4999 var targetDateObject
,
5003 isTargetArray
= $.isArray( value
),
5004 isTargetObject
= $.isPlainObject( value
),
5005 viewsetObject
= this.item
.view
/*,
5009 if ( isTargetArray
|| isTargetObject
) {
5011 if ( isTargetObject
) {
5012 targetYear
= value
.year
5013 targetMonth
= value
.month
5014 targetDate
= value
.date
5017 targetYear
= +value
[0]
5018 targetMonth
= +value
[1]
5019 targetDate
= +value
[2]
5022 // If we’re navigating months but the view is in a different
5023 // month, navigate to the view’s year and month.
5024 if ( options
&& options
.nav
&& viewsetObject
&& viewsetObject
.month
!== targetMonth
) {
5025 targetYear
= viewsetObject
.year
5026 targetMonth
= viewsetObject
.month
5029 // Figure out the expected target year and month.
5030 targetDateObject
= new Date( targetYear
, targetMonth
+ ( options
&& options
.nav
? options
.nav : 0 ), 1 )
5031 targetYear
= targetDateObject
.getFullYear()
5032 targetMonth
= targetDateObject
.getMonth()
5034 // If the month we’re going to doesn’t have enough days,
5035 // keep decreasing the date until we reach the month’s last date.
5036 while ( /*safety &&*/ new Date( targetYear
, targetMonth
, targetDate
).getMonth() !== targetMonth
) {
5040 throw 'Fell into an infinite loop while navigating to ' + new Date( targetYear, targetMonth, targetDate ) + '.'
5044 value
= [ targetYear
, targetMonth
, targetDate
]
5048 } //DatePicker.prototype.navigate
5052 * Normalize a date by setting the hours to midnight.
5054 DatePicker
.prototype.normalize = function( value
/*, options*/ ) {
5055 value
.setHours( 0, 0, 0, 0 )
5061 * Measure the range of dates.
5063 DatePicker
.prototype.measure = function( type
, value
/*, options*/ ) {
5067 // If it’s anything false-y, remove the limits.
5069 value
= type
== 'min' ? -Infinity : Infinity
5072 // If it’s a string, parse it.
5073 else if ( typeof value
== 'string' ) {
5074 value
= calendar
.parse( type
, value
)
5077 // If it's an integer, get a date relative to today.
5078 else if ( _
.isInteger( value
) ) {
5079 value
= calendar
.now( type
, value
, { rel: value
} )
5083 } ///DatePicker.prototype.measure
5087 * Create a viewset object based on navigation.
5089 DatePicker
.prototype.viewset = function( type
, dateObject
/*, options*/ ) {
5090 return this.create([ dateObject
.year
, dateObject
.month
, 1 ])
5095 * Validate a date as enabled and shift if needed.
5097 DatePicker
.prototype.validate = function( type
, dateObject
, options
) {
5099 var calendar
= this,
5101 // Keep a reference to the original date.
5102 originalDateObject
= dateObject
,
5104 // Make sure we have an interval.
5105 interval
= options
&& options
.interval
? options
.interval : 1,
5107 // Check if the calendar enabled dates are inverted.
5108 isFlippedBase
= calendar
.item
.enable
=== -1,
5110 // Check if we have any enabled dates after/before now.
5111 hasEnabledBeforeTarget
, hasEnabledAfterTarget
,
5113 // The min & max limits.
5114 minLimitObject
= calendar
.item
.min
,
5115 maxLimitObject
= calendar
.item
.max
,
5117 // Check if we’ve reached the limit during shifting.
5118 reachedMin
, reachedMax
,
5120 // Check if the calendar is inverted and at least one weekday is enabled.
5121 hasEnabledWeekdays
= isFlippedBase
&& calendar
.item
.disable
.filter( function( value
) {
5123 // If there’s a date, check where it is relative to the target.
5124 if ( $.isArray( value
) ) {
5125 var dateTime
= calendar
.create( value
).pick
5126 if ( dateTime
< dateObject
.pick
) hasEnabledBeforeTarget
= true
5127 else if ( dateTime
> dateObject
.pick
) hasEnabledAfterTarget
= true
5130 // Return only integers for enabled weekdays.
5131 return _
.isInteger( value
)
5138 // Cases to validate for:
5139 // [1] Not inverted and date disabled.
5140 // [2] Inverted and some dates enabled.
5141 // [3] Not inverted and out of range.
5143 // Cases to **not** validate for:
5144 // • Navigating months.
5145 // • Not inverted and date enabled.
5146 // • Inverted and all dates disabled.
5147 // • ..and anything else.
5148 if ( !options
|| !options
.nav
) if (
5149 /* 1 */ ( !isFlippedBase
&& calendar
.disabled( dateObject
) ) ||
5150 /* 2 */ ( isFlippedBase
&& calendar
.disabled( dateObject
) && ( hasEnabledWeekdays
|| hasEnabledBeforeTarget
|| hasEnabledAfterTarget
) ) ||
5151 /* 3 */ ( !isFlippedBase
&& (dateObject
.pick
<= minLimitObject
.pick
|| dateObject
.pick
>= maxLimitObject
.pick
) )
5155 // When inverted, flip the direction if there aren’t any enabled weekdays
5156 // and there are no enabled dates in the direction of the interval.
5157 if ( isFlippedBase
&& !hasEnabledWeekdays
&& ( ( !hasEnabledAfterTarget
&& interval
> 0 ) || ( !hasEnabledBeforeTarget
&& interval
< 0 ) ) ) {
5162 // Keep looping until we reach an enabled date.
5163 while ( /*safety &&*/ calendar
.disabled( dateObject
) ) {
5167 throw 'Fell into an infinite loop while validating ' + dateObject.obj + '.'
5171 // If we’ve looped into the next/prev month with a large interval, return to the original date and flatten the interval.
5172 if ( Math
.abs( interval
) > 1 && ( dateObject
.month
< originalDateObject
.month
|| dateObject
.month
> originalDateObject
.month
) ) {
5173 dateObject
= originalDateObject
5174 interval
= interval
> 0 ? 1 : -1
5178 // If we’ve reached the min/max limit, reverse the direction, flatten the interval and set it to the limit.
5179 if ( dateObject
.pick
<= minLimitObject
.pick
) {
5182 dateObject
= calendar
.create([
5183 minLimitObject
.year
,
5184 minLimitObject
.month
,
5185 minLimitObject
.date
+ (dateObject
.pick
=== minLimitObject
.pick
? 0 : -1)
5188 else if ( dateObject
.pick
>= maxLimitObject
.pick
) {
5191 dateObject
= calendar
.create([
5192 maxLimitObject
.year
,
5193 maxLimitObject
.month
,
5194 maxLimitObject
.date
+ (dateObject
.pick
=== maxLimitObject
.pick
? 0 : 1)
5199 // If we’ve reached both limits, just break out of the loop.
5200 if ( reachedMin
&& reachedMax
) {
5205 // Finally, create the shifted date using the interval and keep looping.
5206 dateObject
= calendar
.create([ dateObject
.year
, dateObject
.month
, dateObject
.date
+ interval
])
5212 // Return the date object settled on.
5214 } //DatePicker.prototype.validate
5218 * Check if a date is disabled.
5220 DatePicker
.prototype.disabled = function( dateToVerify
) {
5225 // Filter through the disabled dates to check if this is one.
5226 isDisabledMatch
= calendar
.item
.disable
.filter( function( dateToDisable
) {
5228 // If the date is a number, match the weekday with 0index and `firstDay` check.
5229 if ( _
.isInteger( dateToDisable
) ) {
5230 return dateToVerify
.day
=== ( calendar
.settings
.firstDay
? dateToDisable : dateToDisable
- 1 ) % 7
5233 // If it’s an array or a native JS date, create and match the exact date.
5234 if ( $.isArray( dateToDisable
) || _
.isDate( dateToDisable
) ) {
5235 return dateToVerify
.pick
=== calendar
.create( dateToDisable
).pick
5238 // If it’s an object, match a date within the “from” and “to” range.
5239 if ( $.isPlainObject( dateToDisable
) ) {
5240 return calendar
.withinRange( dateToDisable
, dateToVerify
)
5244 // If this date matches a disabled date, confirm it’s not inverted.
5245 isDisabledMatch
= isDisabledMatch
.length
&& !isDisabledMatch
.filter(function( dateToDisable
) {
5246 return $.isArray( dateToDisable
) && dateToDisable
[3] == 'inverted' ||
5247 $.isPlainObject( dateToDisable
) && dateToDisable
.inverted
5250 // Check the calendar “enabled” flag and respectively flip the
5251 // disabled state. Then also check if it’s beyond the min/max limits.
5252 return calendar
.item
.enable
=== -1 ? !isDisabledMatch : isDisabledMatch
||
5253 dateToVerify
.pick
< calendar
.item
.min
.pick
||
5254 dateToVerify
.pick
> calendar
.item
.max
.pick
5256 } //DatePicker.prototype.disabled
5260 * Parse a string into a usable type.
5262 DatePicker
.prototype.parse = function( type
, value
, options
) {
5264 var calendar
= this,
5267 // If it’s already parsed, we’re good.
5268 if ( !value
|| typeof value
!= 'string' ) {
5272 // We need a `.format` to parse the value with.
5273 if ( !( options
&& options
.format
) ) {
5274 options
= options
|| {}
5275 options
.format
= calendar
.settings
.format
5278 // Convert the format into an array and then map through it.
5279 calendar
.formats
.toArray( options
.format
).map( function( label
) {
5282 // Grab the formatting label.
5283 formattingLabel
= calendar
.formats
[ label
],
5285 // The format length is from the formatting label function or the
5286 // label length without the escaping exclamation (!) mark.
5287 formatLength
= formattingLabel
? _
.trigger( formattingLabel
, calendar
, [ value
, parsingObject
] ) : label
.replace( /^!/, '' ).length
5289 // If there's a format label, split the value up to the format length.
5290 // Then add it to the parsing object with appropriate label.
5291 if ( formattingLabel
) {
5292 parsingObject
[ label
] = value
.substr( 0, formatLength
)
5295 // Update the value as the substring from format length to end.
5296 value
= value
.substr( formatLength
)
5299 // Compensate for month 0index.
5301 parsingObject
.yyyy
|| parsingObject
.yy
,
5302 +( parsingObject
.mm
|| parsingObject
.m
) - 1,
5303 parsingObject
.dd
|| parsingObject
.d
5305 } //DatePicker.prototype.parse
5309 * Various formats to display the object in.
5311 DatePicker
.prototype.formats
= (function() {
5313 // Return the length of the first word in a collection.
5314 function getWordLengthFromCollection( string
, collection
, dateObject
) {
5316 // Grab the first word from the string.
5317 var word
= string
.match( /\w+/ )[ 0 ]
5319 // If there's no month index, add it to the date object
5320 if ( !dateObject
.mm
&& !dateObject
.m
) {
5321 dateObject
.m
= collection
.indexOf( word
) + 1
5324 // Return the length of the word.
5328 // Get the length of the first word in a string.
5329 function getFirstWordLength( string
) {
5330 return string
.match( /\w+/ )[ 0 ].length
5335 d: function( string
, dateObject
) {
5337 // If there's string, then get the digits length.
5338 // Otherwise return the selected date.
5339 return string
? _
.digits( string
) : dateObject
.date
5341 dd: function( string
, dateObject
) {
5343 // If there's a string, then the length is always 2.
5344 // Otherwise return the selected date with a leading zero.
5345 return string
? 2 : _
.lead( dateObject
.date
)
5347 ddd: function( string
, dateObject
) {
5349 // If there's a string, then get the length of the first word.
5350 // Otherwise return the short selected weekday.
5351 return string
? getFirstWordLength( string
) : this.settings
.weekdaysShort
[ dateObject
.day
]
5353 dddd: function( string
, dateObject
) {
5355 // If there's a string, then get the length of the first word.
5356 // Otherwise return the full selected weekday.
5357 return string
? getFirstWordLength( string
) : this.settings
.weekdaysFull
[ dateObject
.day
]
5359 m: function( string
, dateObject
) {
5361 // If there's a string, then get the length of the digits
5362 // Otherwise return the selected month with 0index compensation.
5363 return string
? _
.digits( string
) : dateObject
.month
+ 1
5365 mm: function( string
, dateObject
) {
5367 // If there's a string, then the length is always 2.
5368 // Otherwise return the selected month with 0index and leading zero.
5369 return string
? 2 : _
.lead( dateObject
.month
+ 1 )
5371 mmm: function( string
, dateObject
) {
5373 var collection
= this.settings
.monthsShort
5375 // If there's a string, get length of the relevant month from the short
5376 // months collection. Otherwise return the selected month from that collection.
5377 return string
? getWordLengthFromCollection( string
, collection
, dateObject
) : collection
[ dateObject
.month
]
5379 mmmm: function( string
, dateObject
) {
5381 var collection
= this.settings
.monthsFull
5383 // If there's a string, get length of the relevant month from the full
5384 // months collection. Otherwise return the selected month from that collection.
5385 return string
? getWordLengthFromCollection( string
, collection
, dateObject
) : collection
[ dateObject
.month
]
5387 yy: function( string
, dateObject
) {
5389 // If there's a string, then the length is always 2.
5390 // Otherwise return the selected year by slicing out the first 2 digits.
5391 return string
? 2 : ( '' + dateObject
.year
).slice( 2 )
5393 yyyy: function( string
, dateObject
) {
5395 // If there's a string, then the length is always 4.
5396 // Otherwise return the selected year.
5397 return string
? 4 : dateObject
.year
5400 // Create an array by splitting the formatting string passed.
5401 toArray: function( formatString
) { return formatString
.split( /(d{1,4}|m{1,4}|y{4}|yy|!.)/g ) },
5403 // Format an object into a string using the formatting options.
5404 toString: function ( formatString
, itemObject
) {
5406 return calendar
.formats
.toArray( formatString
).map( function( label
) {
5407 return _
.trigger( calendar
.formats
[ label
], calendar
, [ 0, itemObject
] ) || label
.replace( /^!/, '' )
5411 })() //DatePicker.prototype.formats
5417 * Check if two date units are the exact.
5419 DatePicker
.prototype.isDateExact = function( one
, two
) {
5423 // When we’re working with weekdays, do a direct comparison.
5425 ( _
.isInteger( one
) && _
.isInteger( two
) ) ||
5426 ( typeof one
== 'boolean' && typeof two
== 'boolean' )
5431 // When we’re working with date representations, compare the “pick” value.
5433 ( _
.isDate( one
) || $.isArray( one
) ) &&
5434 ( _
.isDate( two
) || $.isArray( two
) )
5436 return calendar
.create( one
).pick
=== calendar
.create( two
).pick
5439 // When we’re working with range objects, compare the “from” and “to”.
5440 if ( $.isPlainObject( one
) && $.isPlainObject( two
) ) {
5441 return calendar
.isDateExact( one
.from, two
.from ) && calendar
.isDateExact( one
.to
, two
.to
)
5449 * Check if two date units overlap.
5451 DatePicker
.prototype.isDateOverlap = function( one
, two
) {
5453 var calendar
= this,
5454 firstDay
= calendar
.settings
.firstDay
? 1 : 0
5456 // When we’re working with a weekday index, compare the days.
5457 if ( _
.isInteger( one
) && ( _
.isDate( two
) || $.isArray( two
) ) ) {
5458 one
= one
% 7 + firstDay
5459 return one
=== calendar
.create( two
).day
+ 1
5461 if ( _
.isInteger( two
) && ( _
.isDate( one
) || $.isArray( one
) ) ) {
5462 two
= two
% 7 + firstDay
5463 return two
=== calendar
.create( one
).day
+ 1
5466 // When we’re working with range objects, check if the ranges overlap.
5467 if ( $.isPlainObject( one
) && $.isPlainObject( two
) ) {
5468 return calendar
.overlapRanges( one
, two
)
5476 * Flip the “enabled” state.
5478 DatePicker
.prototype.flipEnable = function(val
) {
5479 var itemObject
= this.item
5480 itemObject
.enable
= val
|| (itemObject
.enable
== -1 ? 1 : -1)
5485 * Mark a collection of dates as “disabled”.
5487 DatePicker
.prototype.deactivate = function( type
, datesToDisable
) {
5489 var calendar
= this,
5490 disabledItems
= calendar
.item
.disable
.slice(0)
5493 // If we’re flipping, that’s all we need to do.
5494 if ( datesToDisable
== 'flip' ) {
5495 calendar
.flipEnable()
5498 else if ( datesToDisable
=== false ) {
5499 calendar
.flipEnable(1)
5503 else if ( datesToDisable
=== true ) {
5504 calendar
.flipEnable(-1)
5508 // Otherwise go through the dates to disable.
5511 datesToDisable
.map(function( unitToDisable
) {
5515 // When we have disabled items, check for matches.
5516 // If something is matched, immediately break out.
5517 for ( var index
= 0; index
< disabledItems
.length
; index
+= 1 ) {
5518 if ( calendar
.isDateExact( unitToDisable
, disabledItems
[index
] ) ) {
5524 // If nothing was found, add the validated unit to the collection.
5525 if ( !matchFound
) {
5527 _
.isInteger( unitToDisable
) ||
5528 _
.isDate( unitToDisable
) ||
5529 $.isArray( unitToDisable
) ||
5530 ( $.isPlainObject( unitToDisable
) && unitToDisable
.from && unitToDisable
.to
)
5532 disabledItems
.push( unitToDisable
)
5538 // Return the updated collection.
5539 return disabledItems
5540 } //DatePicker.prototype.deactivate
5544 * Mark a collection of dates as “enabled”.
5546 DatePicker
.prototype.activate = function( type
, datesToEnable
) {
5548 var calendar
= this,
5549 disabledItems
= calendar
.item
.disable
,
5550 disabledItemsCount
= disabledItems
.length
5552 // If we’re flipping, that’s all we need to do.
5553 if ( datesToEnable
== 'flip' ) {
5554 calendar
.flipEnable()
5557 else if ( datesToEnable
=== true ) {
5558 calendar
.flipEnable(1)
5562 else if ( datesToEnable
=== false ) {
5563 calendar
.flipEnable(-1)
5567 // Otherwise go through the disabled dates.
5570 datesToEnable
.map(function( unitToEnable
) {
5577 // Go through the disabled items and try to find a match.
5578 for ( index
= 0; index
< disabledItemsCount
; index
+= 1 ) {
5580 disabledUnit
= disabledItems
[index
]
5582 // When an exact match is found, remove it from the collection.
5583 if ( calendar
.isDateExact( disabledUnit
, unitToEnable
) ) {
5584 matchFound
= disabledItems
[index
] = null
5589 // When an overlapped match is found, add the “inverted” state to it.
5590 else if ( calendar
.isDateOverlap( disabledUnit
, unitToEnable
) ) {
5591 if ( $.isPlainObject( unitToEnable
) ) {
5592 unitToEnable
.inverted
= true
5593 matchFound
= unitToEnable
5595 else if ( $.isArray( unitToEnable
) ) {
5596 matchFound
= unitToEnable
5597 if ( !matchFound
[3] ) matchFound
.push( 'inverted' )
5599 else if ( _
.isDate( unitToEnable
) ) {
5600 matchFound
= [ unitToEnable
.getFullYear(), unitToEnable
.getMonth(), unitToEnable
.getDate(), 'inverted' ]
5606 // If a match was found, remove a previous duplicate entry.
5607 if ( matchFound
) for ( index
= 0; index
< disabledItemsCount
; index
+= 1 ) {
5608 if ( calendar
.isDateExact( disabledItems
[index
], unitToEnable
) ) {
5609 disabledItems
[index
] = null
5614 // In the event that we’re dealing with an exact range of dates,
5615 // make sure there are no “inverted” dates because of it.
5616 if ( isExactRange
) for ( index
= 0; index
< disabledItemsCount
; index
+= 1 ) {
5617 if ( calendar
.isDateOverlap( disabledItems
[index
], unitToEnable
) ) {
5618 disabledItems
[index
] = null
5623 // If something is still matched, add it into the collection.
5625 disabledItems
.push( matchFound
)
5630 // Return the updated collection.
5631 return disabledItems
.filter(function( val
) { return val
!= null })
5632 } //DatePicker.prototype.activate
5636 * Create a string for the nodes in the picker.
5638 DatePicker
.prototype.nodes = function( isOpen
) {
5642 settings
= calendar
.settings
,
5643 calendarItem
= calendar
.item
,
5644 nowObject
= calendarItem
.now
,
5645 selectedObject
= calendarItem
.select
,
5646 highlightedObject
= calendarItem
.highlight
,
5647 viewsetObject
= calendarItem
.view
,
5648 disabledCollection
= calendarItem
.disable
,
5649 minLimitObject
= calendarItem
.min
,
5650 maxLimitObject
= calendarItem
.max
,
5653 // Create the calendar table head using a copy of weekday labels collection.
5654 // * We do a copy so we don't mutate the original array.
5655 tableHead
= (function( collection
, fullCollection
) {
5657 // If the first day should be Monday, move Sunday to the end.
5658 if ( settings
.firstDay
) {
5659 collection
.push( collection
.shift() )
5660 fullCollection
.push( fullCollection
.shift() )
5663 // Create and return the table head group.
5670 max: DAYS_IN_WEEK
- 1,
5673 item: function( counter
) {
5675 collection
[ counter
],
5676 settings
.klass
.weekdays
,
5677 'scope=col title="' + fullCollection
[ counter
] + '"'
5684 // Materialize modified
5685 })( ( settings
.showWeekdaysFull
? settings
.weekdaysFull : settings
.weekdaysLetter
).slice( 0 ), settings
.weekdaysFull
.slice( 0 ) ), //tableHead
5688 // Create the nav for next/prev month.
5689 createMonthNav = function( next
) {
5691 // Otherwise, return the created month tag.
5695 settings
.klass
[ 'nav' + ( next
? 'Next' : 'Prev' ) ] + (
5697 // If the focused month is outside the range, disabled the button.
5698 ( next
&& viewsetObject
.year
>= maxLimitObject
.year
&& viewsetObject
.month
>= maxLimitObject
.month
) ||
5699 ( !next
&& viewsetObject
.year
<= minLimitObject
.year
&& viewsetObject
.month
<= minLimitObject
.month
) ?
5700 ' ' + settings
.klass
.navDisabled : ''
5702 'data-nav=' + ( next
|| -1 ) + ' ' +
5705 controls: calendar
.$node
[0].id
+ '_table'
5707 'title="' + (next
? settings
.labelMonthNext : settings
.labelMonthPrev
) + '"'
5712 // Create the month label.
5713 //Materialize modified
5714 createMonthLabel = function(override
) {
5716 var monthsCollection
= settings
.showMonthsShort
? settings
.monthsShort : settings
.monthsFull
5718 // Materialize modified
5719 if (override
== "short_months") {
5720 monthsCollection
= settings
.monthsShort
;
5723 // If there are months to select, add a dropdown menu.
5724 if ( settings
.selectMonths
&& override
== undefined) {
5726 return _
.node( 'select',
5732 item: function( loopedMonth
) {
5736 // The looped month and no classes.
5737 monthsCollection
[ loopedMonth
], 0,
5739 // Set the value and selected index.
5740 'value=' + loopedMonth
+
5741 ( viewsetObject
.month
== loopedMonth
? ' selected' : '' ) +
5744 ( viewsetObject
.year
== minLimitObject
.year
&& loopedMonth
< minLimitObject
.month
) ||
5745 ( viewsetObject
.year
== maxLimitObject
.year
&& loopedMonth
> maxLimitObject
.month
)
5752 settings
.klass
.selectMonth
+ ' browser-default',
5753 ( isOpen
? '' : 'disabled' ) + ' ' +
5754 _
.ariaAttr({ controls: calendar
.$node
[0].id
+ '_table' }) + ' ' +
5755 'title="' + settings
.labelMonthSelect
+ '"'
5759 // Materialize modified
5760 if (override
== "short_months")
5761 if (selectedObject
!= null)
5762 return _
.node( 'div', monthsCollection
[ selectedObject
.month
] );
5763 else return _
.node( 'div', monthsCollection
[ viewsetObject
.month
] );
5765 // If there's a need for a month selector
5766 return _
.node( 'div', monthsCollection
[ viewsetObject
.month
], settings
.klass
.month
)
5767 }, //createMonthLabel
5770 // Create the year label.
5771 // Materialize modified
5772 createYearLabel = function(override
) {
5774 var focusedYear
= viewsetObject
.year
,
5776 // If years selector is set to a literal "true", set it to 5. Otherwise
5777 // divide in half to get half before and half after focused year.
5778 numberYears
= settings
.selectYears
=== true ? 5 : ~~( settings
.selectYears
/ 2 )
5780 // If there are years to select, add a dropdown menu.
5781 if ( numberYears
) {
5784 minYear
= minLimitObject
.year
,
5785 maxYear
= maxLimitObject
.year
,
5786 lowestYear
= focusedYear
- numberYears
,
5787 highestYear
= focusedYear
+ numberYears
5789 // If the min year is greater than the lowest year, increase the highest year
5790 // by the difference and set the lowest year to the min year.
5791 if ( minYear
> lowestYear
) {
5792 highestYear
+= minYear
- lowestYear
5793 lowestYear
= minYear
5796 // If the max year is less than the highest year, decrease the lowest year
5797 // by the lower of the two: available and needed years. Then set the
5798 // highest year to the max year.
5799 if ( maxYear
< highestYear
) {
5801 var availableYears
= lowestYear
- minYear
,
5802 neededYears
= highestYear
- maxYear
5804 lowestYear
-= availableYears
> neededYears
? neededYears : availableYears
5805 highestYear
= maxYear
5808 if ( settings
.selectYears
&& override
== undefined ) {
5809 return _
.node( 'select',
5815 item: function( loopedYear
) {
5818 // The looped year and no classes.
5821 // Set the value and selected index.
5822 'value=' + loopedYear
+ ( focusedYear
== loopedYear
? ' selected' : '' )
5826 settings
.klass
.selectYear
+ ' browser-default',
5827 ( isOpen
? '' : 'disabled' ) + ' ' + _
.ariaAttr({ controls: calendar
.$node
[0].id
+ '_table' }) + ' ' +
5828 'title="' + settings
.labelYearSelect
+ '"'
5833 // Materialize modified
5834 if (override
== "raw")
5835 return _
.node( 'div', focusedYear
)
5837 // Otherwise just return the year focused
5838 return _
.node( 'div', focusedYear
, settings
.klass
.year
)
5842 // Materialize modified
5843 createDayLabel = function() {
5844 if (selectedObject
!= null)
5845 return _
.node( 'div', selectedObject
.date
)
5846 else return _
.node( 'div', nowObject
.date
)
5848 createWeekdayLabel = function() {
5851 if (selectedObject
!= null)
5852 display_day
= selectedObject
.day
;
5854 display_day
= nowObject
.day
;
5855 var weekday
= settings
.weekdaysFull
[ display_day
]
5860 // Create and return the entire calendar.
5862 // Date presentation View
5866 createWeekdayLabel(),
5867 "picker__weekday-display"
5870 // Div for short Month
5872 createMonthLabel("short_months"),
5873 settings
.klass
.month_display
5879 settings
.klass
.day_display
5884 createYearLabel("raw") ,
5885 settings
.klass
.year_display
5887 settings
.klass
.date_display
5889 // Calendar container
5892 ( settings
.selectYears
? createMonthLabel() + createYearLabel() : createMonthLabel() + createYearLabel() ) +
5893 createMonthNav() + createMonthNav( 1 ),
5894 settings
.klass
.header
5902 max: WEEKS_IN_CALENDAR
- 1,
5905 item: function( rowCounter
) {
5907 // If Monday is the first day and the month starts on Sunday, shift the date back a week.
5908 var shiftDateBy
= settings
.firstDay
&& calendar
.create([ viewsetObject
.year
, viewsetObject
.month
, 1 ]).day
=== 0 ? -7 : 0
5912 min: DAYS_IN_WEEK
* rowCounter
- viewsetObject
.day
+ shiftDateBy
+ 1, // Add 1 for weekday 0index
5914 return this.min
+ DAYS_IN_WEEK
- 1
5918 item: function( targetDate
) {
5920 // Convert the time date from a relative date to a target date.
5921 targetDate
= calendar
.create([ viewsetObject
.year
, viewsetObject
.month
, targetDate
+ ( settings
.firstDay
? 1 : 0 ) ])
5923 var isSelected
= selectedObject
&& selectedObject
.pick
== targetDate
.pick
,
5924 isHighlighted
= highlightedObject
&& highlightedObject
.pick
== targetDate
.pick
,
5925 isDisabled
= disabledCollection
&& calendar
.disabled( targetDate
) || targetDate
.pick
< minLimitObject
.pick
|| targetDate
.pick
> maxLimitObject
.pick
,
5926 formattedDate
= _
.trigger( calendar
.formats
.toString
, calendar
, [ settings
.format
, targetDate
] )
5932 (function( klasses
) {
5934 // Add the `infocus` or `outfocus` classes based on month in view.
5935 klasses
.push( viewsetObject
.month
== targetDate
.month
? settings
.klass
.infocus : settings
.klass
.outfocus
)
5937 // Add the `today` class if needed.
5938 if ( nowObject
.pick
== targetDate
.pick
) {
5939 klasses
.push( settings
.klass
.now
)
5942 // Add the `selected` class if something's selected and the time matches.
5944 klasses
.push( settings
.klass
.selected
)
5947 // Add the `highlighted` class if something's highlighted and the time matches.
5948 if ( isHighlighted
) {
5949 klasses
.push( settings
.klass
.highlighted
)
5952 // Add the `disabled` class if something's disabled and the object matches.
5954 klasses
.push( settings
.klass
.disabled
)
5957 return klasses
.join( ' ' )
5958 })([ settings
.klass
.day
]),
5959 'data-pick=' + targetDate
.pick
+ ' ' + _
.ariaAttr({
5961 label: formattedDate
,
5962 selected: isSelected
&& calendar
.$node
.val() === formattedDate
? true : null,
5963 activedescendant: isHighlighted
? true : null,
5964 disabled: isDisabled
? true : null
5968 _
.ariaAttr({ role: 'presentation' })
5976 settings
.klass
.table
,
5977 'id="' + calendar
.$node
[0].id
+ '_table' + '" ' + _
.ariaAttr({
5979 controls: calendar
.$node
[0].id
,
5983 , settings
.klass
.calendar_container
) // end calendar
5987 // * For Firefox forms to submit, make sure to set the buttons’ `type` attributes as “button”.
5990 _
.node( 'button', settings
.today
, "btn-flat picker__today",
5991 'type=button data-pick=' + nowObject
.pick
+
5992 ( isOpen
&& !calendar
.disabled(nowObject
) ? '' : ' disabled' ) + ' ' +
5993 _
.ariaAttr({ controls: calendar
.$node
[0].id
}) ) +
5994 _
.node( 'button', settings
.clear
, "btn-flat picker__clear",
5995 'type=button data-clear=1' +
5996 ( isOpen
? '' : ' disabled' ) + ' ' +
5997 _
.ariaAttr({ controls: calendar
.$node
[0].id
}) ) +
5998 _
.node('button', settings
.close
, "btn-flat picker__close",
5999 'type=button data-close=true ' +
6000 ( isOpen
? '' : ' disabled' ) + ' ' +
6001 _
.ariaAttr({ controls: calendar
.$node
[0].id
}) ),
6002 settings
.klass
.footer
6004 } //DatePicker.prototype.nodes
6010 * The date picker defaults.
6012 DatePicker
.defaults
= (function( prefix
) {
6016 // The title label to use for the month nav buttons
6017 labelMonthNext: 'Next month',
6018 labelMonthPrev: 'Previous month',
6020 // The title label to use for the dropdown selectors
6021 labelMonthSelect: 'Select a month',
6022 labelYearSelect: 'Select a year',
6024 // Months and weekdays
6025 monthsFull: [ 'January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December' ],
6026 monthsShort: [ 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec' ],
6027 weekdaysFull: [ 'Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday' ],
6028 weekdaysShort: [ 'Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat' ],
6030 // Materialize modified
6031 weekdaysLetter: [ 'S', 'M', 'T', 'W', 'T', 'F', 'S' ],
6038 // The format to show on the `input` element
6039 format: 'd mmmm, yyyy',
6044 table: prefix
+ 'table',
6046 header: prefix
+ 'header',
6049 // Materialize Added klasses
6050 date_display: prefix
+ 'date-display',
6051 day_display: prefix
+ 'day-display',
6052 month_display: prefix
+ 'month-display',
6053 year_display: prefix
+ 'year-display',
6054 calendar_container: prefix
+ 'calendar-container',
6059 navPrev: prefix
+ 'nav--prev',
6060 navNext: prefix
+ 'nav--next',
6061 navDisabled: prefix
+ 'nav--disabled',
6063 month: prefix
+ 'month',
6064 year: prefix
+ 'year',
6066 selectMonth: prefix
+ 'select--month',
6067 selectYear: prefix
+ 'select--year',
6069 weekdays: prefix
+ 'weekday',
6071 day: prefix
+ 'day',
6072 disabled: prefix
+ 'day--disabled',
6073 selected: prefix
+ 'day--selected',
6074 highlighted: prefix
+ 'day--highlighted',
6075 now: prefix
+ 'day--today',
6076 infocus: prefix
+ 'day--infocus',
6077 outfocus: prefix
+ 'day--outfocus',
6079 footer: prefix
+ 'footer',
6081 buttonClear: prefix
+ 'button--clear',
6082 buttonToday: prefix
+ 'button--today',
6083 buttonClose: prefix
+ 'button--close'
6086 })( Picker
.klasses().picker
+ '__' )
6093 * Extend the picker to add the date picker.
6095 Picker
.extend( 'pickadate', DatePicker
)
6103 $.fn
.characterCounter = function(){
6104 return this.each(function(){
6106 var itHasLengthAttribute
= $(this).attr('length') !== undefined;
6108 if(itHasLengthAttribute
){
6109 $(this).on('input', updateCounter
);
6110 $(this).on('focus', updateCounter
);
6111 $(this).on('blur', removeCounterElement
);
6113 addCounterElement($(this));
6119 function updateCounter(){
6120 var maxLength
= +$(this).attr('length'),
6121 actualLength
= +$(this).val().length
,
6122 isValidLength
= actualLength
<= maxLength
;
6124 $(this).parent().find('span[class="character-counter"]')
6125 .html( actualLength
+ '/' + maxLength
);
6127 addInputStyle(isValidLength
, $(this));
6130 function addCounterElement($input
){
6131 var $counterElement
= $('<span/>')
6132 .addClass('character-counter')
6133 .css('float','right')
6134 .css('font-size','12px')
6137 $input
.parent().append($counterElement
);
6140 function removeCounterElement(){
6141 $(this).parent().find('span[class="character-counter"]').html('');
6144 function addInputStyle(isValidLength
, $input
){
6145 var inputHasInvalidClass
= $input
.hasClass('invalid');
6146 if (isValidLength
&& inputHasInvalidClass
) {
6147 $input
.removeClass('invalid');
6149 else if(!isValidLength
&& !inputHasInvalidClass
){
6150 $input
.removeClass('valid');
6151 $input
.addClass('invalid');
6155 $(document
).ready(function(){
6156 $('input, textarea').characterCounter();