jekyll-theme-ici3d 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (330) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE.txt +21 -0
  3. data/README.md +50 -0
  4. data/_data/publications/pulliam2012.yml +12 -0
  5. data/_data/team/ackley.yml +25 -0
  6. data/_data/team/are.yml +22 -0
  7. data/_data/team/beauclair.yml +14 -0
  8. data/_data/team/bekele.yml +14 -0
  9. data/_data/team/bellan.yml +46 -0
  10. data/_data/team/bolton.yml +33 -0
  11. data/_data/team/borchering.yml +65 -0
  12. data/_data/team/brook.yml +15 -0
  13. data/_data/team/brown.yml +18 -0
  14. data/_data/team/bruce.yml +26 -0
  15. data/_data/team/brucePA.yml +9 -0
  16. data/_data/team/deleo.yml +49 -0
  17. data/_data/team/delva.yml +15 -0
  18. data/_data/team/dushoff.yml +52 -0
  19. data/_data/team/ervin.yml +10 -0
  20. data/_data/team/faikah.yml +26 -0
  21. data/_data/team/grebe.yml +36 -0
  22. data/_data/team/hargrove.yml +36 -0
  23. data/_data/team/hitchcock.yml +10 -0
  24. data/_data/team/hladish.yml +45 -0
  25. data/_data/team/january.yml +9 -0
  26. data/_data/team/kassanjee.yml +20 -0
  27. data/_data/team/li.yml +45 -0
  28. data/_data/team/lord.yml +20 -0
  29. data/_data/team/marx.yml +14 -0
  30. data/_data/team/mcintosh.yml +20 -0
  31. data/_data/team/mhlanga.yml +22 -0
  32. data/_data/team/mthombothi.yml +23 -0
  33. data/_data/team/mugwagwa.yml +18 -0
  34. data/_data/team/mwangi.yml +24 -0
  35. data/_data/team/mwebaze.yml +20 -0
  36. data/_data/team/ndifon.yml +18 -0
  37. data/_data/team/ngonghala.yml +30 -0
  38. data/_data/team/nondi.yml +14 -0
  39. data/_data/team/nyamai.yml +18 -0
  40. data/_data/team/october.yml +9 -0
  41. data/_data/team/paradza.yml +19 -0
  42. data/_data/team/pearson.yml +58 -0
  43. data/_data/team/porco.yml +14 -0
  44. data/_data/team/pulliam.yml +51 -0
  45. data/_data/team/reiner.yml +18 -0
  46. data/_data/team/scheepers.yml +9 -0
  47. data/_data/team/scott.yml +51 -0
  48. data/_data/team/sempa.yml +32 -0
  49. data/_data/team/sikhondze.yml +14 -0
  50. data/_data/team/template.yml +18 -0
  51. data/_data/team/ujeneza.yml +38 -0
  52. data/_data/team/vanschalkwyk.yml +32 -0
  53. data/_data/team/welte.yml +18 -0
  54. data/_data/team/williams.yml +28 -0
  55. data/_data/team/ying.yml +21 -0
  56. data/_includes/MedPH/.DS_Store +0 -0
  57. data/_includes/MedPH/assignments.md +42 -0
  58. data/_includes/MedPH/assignmentsStandard.md +74 -0
  59. data/_includes/MedPH/computerlabs.md +38 -0
  60. data/_includes/MedPH/computerlabsStandard.md +38 -0
  61. data/_includes/MedPH/lectures.md +12 -0
  62. data/_includes/MedPH/references.md +71 -0
  63. data/_includes/MedPH/schedule.md +85 -0
  64. data/_includes/MedPH/scheduleStandard.md +93 -0
  65. data/_includes/bottomTable.html +5 -0
  66. data/_includes/centerTable.html +5 -0
  67. data/_includes/clinicNavbar.html +46 -0
  68. data/_includes/contact.html +12 -0
  69. data/_includes/directors.html +47 -0
  70. data/_includes/footer.html +23 -0
  71. data/_includes/head.html +28 -0
  72. data/_includes/header.html +31 -0
  73. data/_includes/hero.html +14 -0
  74. data/_includes/index.md +9 -0
  75. data/_includes/mission.html +13 -0
  76. data/_includes/navStructure.html +70 -0
  77. data/_includes/navbar.html +65 -0
  78. data/_includes/outputs.html +74 -0
  79. data/_includes/partners.html +75 -0
  80. data/_includes/profile.html +67 -0
  81. data/_includes/publications/faculty.md +13 -0
  82. data/_includes/publications/instructional.md +5 -0
  83. data/_includes/publications/participant.md +33 -0
  84. data/_includes/talk.html +12 -0
  85. data/_includes/topTable.html +6 -0
  86. data/_includes/upcoming.html +43 -0
  87. data/_layouts/clinic.liquid +43 -0
  88. data/_layouts/example.liquid +601 -0
  89. data/_layouts/main.liquid +34 -0
  90. data/_layouts/medph.page.liquid +60 -0
  91. data/_layouts/page.liquid +41 -0
  92. data/_layouts/people.page.liquid +27 -0
  93. data/_layouts/profile.liquid +44 -0
  94. data/_layouts/redirect.liquid +15 -0
  95. data/_layouts/talk.liquid +42 -0
  96. data/assets/css/academicons.css +249 -0
  97. data/assets/css/academicons.min.css +1 -0
  98. data/assets/css/bootstrap.css +6760 -0
  99. data/assets/css/bootstrap.css.map +1 -0
  100. data/assets/css/bootstrap.min.css +6 -0
  101. data/assets/css/font-awesome.css +2086 -0
  102. data/assets/css/font-awesome.min.css +4 -0
  103. data/assets/css/ie.css +5 -0
  104. data/assets/css/main-one-page.css +6433 -0
  105. data/assets/css/main.css +7160 -0
  106. data/assets/css/my-custom-styles.css +14 -0
  107. data/assets/css/shop-main.css +3117 -0
  108. data/assets/css/skins/brown.css +299 -0
  109. data/assets/css/skins/deepskyblue.css +299 -0
  110. data/assets/css/skins/goldenrod.css +299 -0
  111. data/assets/css/skins/ici3dBlue.css +229 -0
  112. data/assets/css/skins/ici3dBlue.css.map +7 -0
  113. data/assets/css/skins/ici3dIndigo.css +229 -0
  114. data/assets/css/skins/ici3dIndigo.css.map +7 -0
  115. data/assets/css/skins/indianred.css +299 -0
  116. data/assets/css/skins/lightgreen.css +299 -0
  117. data/assets/css/skins/orange.css +299 -0
  118. data/assets/css/skins/seagreen.css +299 -0
  119. data/assets/css/skins/slategray.css +299 -0
  120. data/assets/fonts/academicons.eot +0 -0
  121. data/assets/fonts/academicons.svg +66 -0
  122. data/assets/fonts/academicons.ttf +0 -0
  123. data/assets/fonts/academicons.woff +0 -0
  124. data/assets/fonts/fontawesome-webfont.eot +0 -0
  125. data/assets/fonts/fontawesome-webfont.svg +655 -0
  126. data/assets/fonts/fontawesome-webfont.ttf +0 -0
  127. data/assets/fonts/fontawesome-webfont.woff +0 -0
  128. data/assets/fonts/fontawesome-webfont.woff2 +0 -0
  129. data/assets/fonts/glyphicons-halflings-regular.eot +0 -0
  130. data/assets/fonts/glyphicons-halflings-regular.svg +288 -0
  131. data/assets/fonts/glyphicons-halflings-regular.ttf +0 -0
  132. data/assets/fonts/glyphicons-halflings-regular.woff +0 -0
  133. data/assets/fonts/glyphicons-halflings-regular.woff2 +0 -0
  134. data/assets/ico/favicon.ico +0 -0
  135. data/assets/ico/favicon.png +0 -0
  136. data/assets/ico/ici3d114x114.png +0 -0
  137. data/assets/ico/ici3d144x144.png +0 -0
  138. data/assets/ico/ici3d57x57.png +0 -0
  139. data/assets/ico/ici3d72x72.png +0 -0
  140. data/assets/img/8hearts.png +0 -0
  141. data/assets/img/MMED2015_tutorials.jpg +0 -0
  142. data/assets/img/badge.png +0 -0
  143. data/assets/img/blog/balloon-med.jpg +0 -0
  144. data/assets/img/blog/balloon.jpg +0 -0
  145. data/assets/img/blog/buildings-med.jpg +0 -0
  146. data/assets/img/blog/buildings.jpg +0 -0
  147. data/assets/img/blog/people-med.jpg +0 -0
  148. data/assets/img/blog/people.jpg +0 -0
  149. data/assets/img/bx_loader.gif +0 -0
  150. data/assets/img/clients/logo1.png +0 -0
  151. data/assets/img/clients/logo2.png +0 -0
  152. data/assets/img/clients/logo3.png +0 -0
  153. data/assets/img/clients/logo4.png +0 -0
  154. data/assets/img/clients/logo5.png +0 -0
  155. data/assets/img/flags/China.png +0 -0
  156. data/assets/img/flags/Germany.png +0 -0
  157. data/assets/img/flags/Japan.png +0 -0
  158. data/assets/img/flags/South-Africa.png +0 -0
  159. data/assets/img/flags/United-Kingdom.png +0 -0
  160. data/assets/img/flags/United-States.png +0 -0
  161. data/assets/img/free.png +0 -0
  162. data/assets/img/fullscreen-bg.jpg +0 -0
  163. data/assets/img/gray_jean.png +0 -0
  164. data/assets/img/hero-unit-bg.png +0 -0
  165. data/assets/img/hero-unit-obj.png +0 -0
  166. data/assets/img/hero-unit-obj2.png +0 -0
  167. data/assets/img/hero-unit-obj3.png +0 -0
  168. data/assets/img/intro-img.png +0 -0
  169. data/assets/img/location-pin.png +0 -0
  170. data/assets/img/logo/ici3d-logo-light.png +0 -0
  171. data/assets/img/logo/ici3d-logo-nav.png +0 -0
  172. data/assets/img/logo/ici3d-logo-white.png +0 -0
  173. data/assets/img/logo/ici3d-logo-white_v2.png +0 -0
  174. data/assets/img/logo/ici3d-logo-white_v3.png +0 -0
  175. data/assets/img/logo/repute-logo-light-brown.png +0 -0
  176. data/assets/img/logo/repute-logo-light-deepskyblue.png +0 -0
  177. data/assets/img/logo/repute-logo-light-goldenrod.png +0 -0
  178. data/assets/img/logo/repute-logo-light-indianred.png +0 -0
  179. data/assets/img/logo/repute-logo-light-lightgreen.png +0 -0
  180. data/assets/img/logo/repute-logo-light-orange.png +0 -0
  181. data/assets/img/logo/repute-logo-light-seagreen.png +0 -0
  182. data/assets/img/logo/repute-logo-light-slategray.png +0 -0
  183. data/assets/img/logo/repute-logo-light.png +0 -0
  184. data/assets/img/logo/repute-logo-nav-brown.png +0 -0
  185. data/assets/img/logo/repute-logo-nav-deepskyblue.png +0 -0
  186. data/assets/img/logo/repute-logo-nav-goldenrod.png +0 -0
  187. data/assets/img/logo/repute-logo-nav-indianred.png +0 -0
  188. data/assets/img/logo/repute-logo-nav-light.png +0 -0
  189. data/assets/img/logo/repute-logo-nav-lightgreen.png +0 -0
  190. data/assets/img/logo/repute-logo-nav-orange.png +0 -0
  191. data/assets/img/logo/repute-logo-nav-seagreen.png +0 -0
  192. data/assets/img/logo/repute-logo-nav-slategray.png +0 -0
  193. data/assets/img/logo/repute-logo-nav.png +0 -0
  194. data/assets/img/mentors/are.jpg +0 -0
  195. data/assets/img/mentors/bolton.jpg +0 -0
  196. data/assets/img/mentors/brown.jpg +0 -0
  197. data/assets/img/mentors/kassanjee.jpg +0 -0
  198. data/assets/img/mentors/mhlanga.jpg +0 -0
  199. data/assets/img/mentors/nyamai.png +0 -0
  200. data/assets/img/news/featured-news.png +0 -0
  201. data/assets/img/news/news1.png +0 -0
  202. data/assets/img/news/news2.png +0 -0
  203. data/assets/img/news/news3.png +0 -0
  204. data/assets/img/news/news4.png +0 -0
  205. data/assets/img/news/news5.png +0 -0
  206. data/assets/img/other/snoep.jpg +0 -0
  207. data/assets/img/page-header-bg.png +0 -0
  208. data/assets/img/participants/SempaJB.jpg +0 -0
  209. data/assets/img/partners/AIMS-SA.jpg +0 -0
  210. data/assets/img/partners/CEMA_UN.pdf +0 -0
  211. data/assets/img/partners/CEMA_UN.png +0 -0
  212. data/assets/img/partners/CIDID.png +0 -0
  213. data/assets/img/partners/CIDID_long.png +0 -0
  214. data/assets/img/partners/Colby.png +0 -0
  215. data/assets/img/partners/MIDAS.png +0 -0
  216. data/assets/img/partners/McMaster.jpg +0 -0
  217. data/assets/img/partners/PSU.png +0 -0
  218. data/assets/img/partners/Proctor.png +0 -0
  219. data/assets/img/partners/SACEMA_228.png +0 -0
  220. data/assets/img/partners/UCSF.png +0 -0
  221. data/assets/img/partners/UF.png +0 -0
  222. data/assets/img/partners/UGA_228.png +0 -0
  223. data/assets/img/pattern-geometry.png +0 -0
  224. data/assets/img/portfolio/800x500/work1.png +0 -0
  225. data/assets/img/portfolio/800x500/work2.png +0 -0
  226. data/assets/img/portfolio/800x500/work3.png +0 -0
  227. data/assets/img/portfolio/800x500/work4.png +0 -0
  228. data/assets/img/portfolio/800x500/work5.png +0 -0
  229. data/assets/img/portfolio/800x500/work6.png +0 -0
  230. data/assets/img/portfolio/800x500/work7.png +0 -0
  231. data/assets/img/portfolio/800x500/work8.png +0 -0
  232. data/assets/img/portfolio/800x800/work1.png +0 -0
  233. data/assets/img/portfolio/800x800/work2.png +0 -0
  234. data/assets/img/portfolio/800x800/work3.png +0 -0
  235. data/assets/img/portfolio/800x800/work4.png +0 -0
  236. data/assets/img/portfolio/800x800/work5.png +0 -0
  237. data/assets/img/portfolio/800x800/work6.png +0 -0
  238. data/assets/img/portfolio/800x800/work7.png +0 -0
  239. data/assets/img/portfolio/800x800/work8.png +0 -0
  240. data/assets/img/portfolio/single/bicycle.jpg +0 -0
  241. data/assets/img/portfolio/single/blurred_lines.jpg +0 -0
  242. data/assets/img/portfolio/single/edge.jpg +0 -0
  243. data/assets/img/scholars/ackley.jpg +0 -0
  244. data/assets/img/scholars/beauclair.jpg +0 -0
  245. data/assets/img/scholars/beauclair.png +0 -0
  246. data/assets/img/scholars/bekele.jpg +0 -0
  247. data/assets/img/scholars/lord.jpg +0 -0
  248. data/assets/img/scholars/marx.jpg +0 -0
  249. data/assets/img/scholars/mcintosh.jpg +0 -0
  250. data/assets/img/scholars/mwebaze.jpg +0 -0
  251. data/assets/img/scholars/nondi.jpg +0 -0
  252. data/assets/img/scholars/sempa.jpg +0 -0
  253. data/assets/img/scholars/ying.jpg +0 -0
  254. data/assets/img/sliders/full-slide-color.jpg +0 -0
  255. data/assets/img/sliders/full-slide-color2.jpg +0 -0
  256. data/assets/img/sliders/full-slide-color3.jpg +0 -0
  257. data/assets/img/sliders/full-slide.jpg +0 -0
  258. data/assets/img/sliders/full-slide2.jpg +0 -0
  259. data/assets/img/sliders/full-slide3.jpg +0 -0
  260. data/assets/img/sliders/slider1-h500.png +0 -0
  261. data/assets/img/sliders/slider2-h500.png +0 -0
  262. data/assets/img/sliders/slider3-h500.png +0 -0
  263. data/assets/img/team/bellan.jpg +0 -0
  264. data/assets/img/team/borchering.jpg +0 -0
  265. data/assets/img/team/brook.jpg +0 -0
  266. data/assets/img/team/bruce.jpg +0 -0
  267. data/assets/img/team/deleo.jpg +0 -0
  268. data/assets/img/team/delva.jpg +0 -0
  269. data/assets/img/team/dushoff.jpg +0 -0
  270. data/assets/img/team/ervin.jpg +0 -0
  271. data/assets/img/team/grebe.jpg +0 -0
  272. data/assets/img/team/hargrove.jpg +0 -0
  273. data/assets/img/team/hitchcock.jpg +0 -0
  274. data/assets/img/team/hladish.jpg +0 -0
  275. data/assets/img/team/january.jpg +0 -0
  276. data/assets/img/team/li.jpg +0 -0
  277. data/assets/img/team/mthombothi.jpg +0 -0
  278. data/assets/img/team/mugwagwa.jpg +0 -0
  279. data/assets/img/team/mwangi.png +0 -0
  280. data/assets/img/team/ndifon.jpg +0 -0
  281. data/assets/img/team/ngonghala.jpg +0 -0
  282. data/assets/img/team/october.jpg +0 -0
  283. data/assets/img/team/paradza.jpg +0 -0
  284. data/assets/img/team/pearson.jpg +0 -0
  285. data/assets/img/team/porco.jpg +0 -0
  286. data/assets/img/team/pulliam.jpg +0 -0
  287. data/assets/img/team/reiner.jpg +0 -0
  288. data/assets/img/team/scheepers.jpg +0 -0
  289. data/assets/img/team/scott.jpg +0 -0
  290. data/assets/img/team/ujeneza.jpg +0 -0
  291. data/assets/img/team/vanschalkwyk.jpg +0 -0
  292. data/assets/img/team/welte.jpg +0 -0
  293. data/assets/img/team/williams.jpg +0 -0
  294. data/assets/img/testimonial-bg.png +0 -0
  295. data/assets/img/transmission.png +0 -0
  296. data/assets/js/bootstrap.js +2363 -0
  297. data/assets/js/bootstrap.min.js +7 -0
  298. data/assets/js/jquery-2.1.1.min.js +4 -0
  299. data/assets/js/plugins/autohidingnavbar/jquery.bootstrap-autohidingnavbar.js +213 -0
  300. data/assets/js/plugins/autohidingnavbar/jquery.bootstrap-autohidingnavbar.min.js +9 -0
  301. data/assets/js/plugins/bootstrap-datepicker/bootstrap-datepicker.js +474 -0
  302. data/assets/js/plugins/bootstrap-multiselect/bootstrap-multiselect.js +994 -0
  303. data/assets/js/plugins/daterangepicker/daterangepicker.js +868 -0
  304. data/assets/js/plugins/easing/jquery.easing.js +205 -0
  305. data/assets/js/plugins/easing/jquery.easing.min.js +71 -0
  306. data/assets/js/plugins/fitvids/jquery.fitvids.js +83 -0
  307. data/assets/js/plugins/google-map/google-map.js +160 -0
  308. data/assets/js/plugins/isotope/isotope.pkgd.js +4049 -0
  309. data/assets/js/plugins/isotope/isotope.pkgd.min.js +8 -0
  310. data/assets/js/plugins/jquery-cycle/jquery.cycle.all.js +1543 -0
  311. data/assets/js/plugins/jquery-easypiechart/jquery.easypiechart.js +359 -0
  312. data/assets/js/plugins/jquery-easypiechart/jquery.easypiechart.min.js +9 -0
  313. data/assets/js/plugins/jquery-maskedinput/jquery.masked-input.js +338 -0
  314. data/assets/js/plugins/jquery-maskedinput/jquery.masked-input.min.js +7 -0
  315. data/assets/js/plugins/maximage/jquery.maximage.js +697 -0
  316. data/assets/js/plugins/maximage/jquery.maximage.min.js +4 -0
  317. data/assets/js/plugins/moment/moment.js +1662 -0
  318. data/assets/js/plugins/moment/moment.min.js +6 -0
  319. data/assets/js/plugins/parsley-validation/parsley.js +2074 -0
  320. data/assets/js/plugins/parsley-validation/parsley.min.js +9 -0
  321. data/assets/js/plugins/scrollto/jquery.localscroll-1.2.7-min.js +9 -0
  322. data/assets/js/plugins/scrollto/jquery.localscroll-1.2.7.js +133 -0
  323. data/assets/js/plugins/scrollto/jquery.scrollTo-1.4.3.1-min.js +7 -0
  324. data/assets/js/plugins/scrollto/jquery.scrollTo-1.4.3.1.js +218 -0
  325. data/assets/js/plugins/slick/slick.js +2643 -0
  326. data/assets/js/plugins/slick/slick.min.js +18 -0
  327. data/assets/js/plugins/stellar/jquery.stellar.js +660 -0
  328. data/assets/js/plugins/stellar/jquery.stellar.min.js +2 -0
  329. data/assets/js/repute-scripts.js +539 -0
  330. metadata +385 -0
@@ -0,0 +1,4049 @@
1
+ /*!
2
+ * Isotope PACKAGED v2.1.0
3
+ * Filter & sort magical layouts
4
+ * http://isotope.metafizzy.co
5
+ */
6
+
7
+ /**
8
+ * Bridget makes jQuery widgets
9
+ * v1.1.0
10
+ * MIT license
11
+ */
12
+
13
+ ( function( window ) {
14
+
15
+
16
+
17
+ // -------------------------- utils -------------------------- //
18
+
19
+ var slice = Array.prototype.slice;
20
+
21
+ function noop() {}
22
+
23
+ // -------------------------- definition -------------------------- //
24
+
25
+ function defineBridget( $ ) {
26
+
27
+ // bail if no jQuery
28
+ if ( !$ ) {
29
+ return;
30
+ }
31
+
32
+ // -------------------------- addOptionMethod -------------------------- //
33
+
34
+ /**
35
+ * adds option method -> $().plugin('option', {...})
36
+ * @param {Function} PluginClass - constructor class
37
+ */
38
+ function addOptionMethod( PluginClass ) {
39
+ // don't overwrite original option method
40
+ if ( PluginClass.prototype.option ) {
41
+ return;
42
+ }
43
+
44
+ // option setter
45
+ PluginClass.prototype.option = function( opts ) {
46
+ // bail out if not an object
47
+ if ( !$.isPlainObject( opts ) ){
48
+ return;
49
+ }
50
+ this.options = $.extend( true, this.options, opts );
51
+ };
52
+ }
53
+
54
+ // -------------------------- plugin bridge -------------------------- //
55
+
56
+ // helper function for logging errors
57
+ // $.error breaks jQuery chaining
58
+ var logError = typeof console === 'undefined' ? noop :
59
+ function( message ) {
60
+ console.error( message );
61
+ };
62
+
63
+ /**
64
+ * jQuery plugin bridge, access methods like $elem.plugin('method')
65
+ * @param {String} namespace - plugin name
66
+ * @param {Function} PluginClass - constructor class
67
+ */
68
+ function bridge( namespace, PluginClass ) {
69
+ // add to jQuery fn namespace
70
+ $.fn[ namespace ] = function( options ) {
71
+ if ( typeof options === 'string' ) {
72
+ // call plugin method when first argument is a string
73
+ // get arguments for method
74
+ var args = slice.call( arguments, 1 );
75
+
76
+ for ( var i=0, len = this.length; i < len; i++ ) {
77
+ var elem = this[i];
78
+ var instance = $.data( elem, namespace );
79
+ if ( !instance ) {
80
+ logError( "cannot call methods on " + namespace + " prior to initialization; " +
81
+ "attempted to call '" + options + "'" );
82
+ continue;
83
+ }
84
+ if ( !$.isFunction( instance[options] ) || options.charAt(0) === '_' ) {
85
+ logError( "no such method '" + options + "' for " + namespace + " instance" );
86
+ continue;
87
+ }
88
+
89
+ // trigger method with arguments
90
+ var returnValue = instance[ options ].apply( instance, args );
91
+
92
+ // break look and return first value if provided
93
+ if ( returnValue !== undefined ) {
94
+ return returnValue;
95
+ }
96
+ }
97
+ // return this if no return value
98
+ return this;
99
+ } else {
100
+ return this.each( function() {
101
+ var instance = $.data( this, namespace );
102
+ if ( instance ) {
103
+ // apply options & init
104
+ instance.option( options );
105
+ instance._init();
106
+ } else {
107
+ // initialize new instance
108
+ instance = new PluginClass( this, options );
109
+ $.data( this, namespace, instance );
110
+ }
111
+ });
112
+ }
113
+ };
114
+
115
+ }
116
+
117
+ // -------------------------- bridget -------------------------- //
118
+
119
+ /**
120
+ * converts a Prototypical class into a proper jQuery plugin
121
+ * the class must have a ._init method
122
+ * @param {String} namespace - plugin name, used in $().pluginName
123
+ * @param {Function} PluginClass - constructor class
124
+ */
125
+ $.bridget = function( namespace, PluginClass ) {
126
+ addOptionMethod( PluginClass );
127
+ bridge( namespace, PluginClass );
128
+ };
129
+
130
+ return $.bridget;
131
+
132
+ }
133
+
134
+ // transport
135
+ if ( typeof define === 'function' && define.amd ) {
136
+ // AMD
137
+ define( 'jquery-bridget/jquery.bridget',[ 'jquery' ], defineBridget );
138
+ } else if ( typeof exports === 'object' ) {
139
+ defineBridget( require('jquery') );
140
+ } else {
141
+ // get jquery from browser global
142
+ defineBridget( window.jQuery );
143
+ }
144
+
145
+ })( window );
146
+
147
+ /*!
148
+ * eventie v1.0.5
149
+ * event binding helper
150
+ * eventie.bind( elem, 'click', myFn )
151
+ * eventie.unbind( elem, 'click', myFn )
152
+ * MIT license
153
+ */
154
+
155
+ /*jshint browser: true, undef: true, unused: true */
156
+ /*global define: false, module: false */
157
+
158
+ ( function( window ) {
159
+
160
+
161
+
162
+ var docElem = document.documentElement;
163
+
164
+ var bind = function() {};
165
+
166
+ function getIEEvent( obj ) {
167
+ var event = window.event;
168
+ // add event.target
169
+ event.target = event.target || event.srcElement || obj;
170
+ return event;
171
+ }
172
+
173
+ if ( docElem.addEventListener ) {
174
+ bind = function( obj, type, fn ) {
175
+ obj.addEventListener( type, fn, false );
176
+ };
177
+ } else if ( docElem.attachEvent ) {
178
+ bind = function( obj, type, fn ) {
179
+ obj[ type + fn ] = fn.handleEvent ?
180
+ function() {
181
+ var event = getIEEvent( obj );
182
+ fn.handleEvent.call( fn, event );
183
+ } :
184
+ function() {
185
+ var event = getIEEvent( obj );
186
+ fn.call( obj, event );
187
+ };
188
+ obj.attachEvent( "on" + type, obj[ type + fn ] );
189
+ };
190
+ }
191
+
192
+ var unbind = function() {};
193
+
194
+ if ( docElem.removeEventListener ) {
195
+ unbind = function( obj, type, fn ) {
196
+ obj.removeEventListener( type, fn, false );
197
+ };
198
+ } else if ( docElem.detachEvent ) {
199
+ unbind = function( obj, type, fn ) {
200
+ obj.detachEvent( "on" + type, obj[ type + fn ] );
201
+ try {
202
+ delete obj[ type + fn ];
203
+ } catch ( err ) {
204
+ // can't delete window object properties
205
+ obj[ type + fn ] = undefined;
206
+ }
207
+ };
208
+ }
209
+
210
+ var eventie = {
211
+ bind: bind,
212
+ unbind: unbind
213
+ };
214
+
215
+ // ----- module definition ----- //
216
+
217
+ if ( typeof define === 'function' && define.amd ) {
218
+ // AMD
219
+ define( 'eventie/eventie',eventie );
220
+ } else if ( typeof exports === 'object' ) {
221
+ // CommonJS
222
+ module.exports = eventie;
223
+ } else {
224
+ // browser global
225
+ window.eventie = eventie;
226
+ }
227
+
228
+ })( this );
229
+
230
+ /*!
231
+ * docReady v1.0.4
232
+ * Cross browser DOMContentLoaded event emitter
233
+ * MIT license
234
+ */
235
+
236
+ /*jshint browser: true, strict: true, undef: true, unused: true*/
237
+ /*global define: false, require: false, module: false */
238
+
239
+ ( function( window ) {
240
+
241
+
242
+
243
+ var document = window.document;
244
+ // collection of functions to be triggered on ready
245
+ var queue = [];
246
+
247
+ function docReady( fn ) {
248
+ // throw out non-functions
249
+ if ( typeof fn !== 'function' ) {
250
+ return;
251
+ }
252
+
253
+ if ( docReady.isReady ) {
254
+ // ready now, hit it
255
+ fn();
256
+ } else {
257
+ // queue function when ready
258
+ queue.push( fn );
259
+ }
260
+ }
261
+
262
+ docReady.isReady = false;
263
+
264
+ // triggered on various doc ready events
265
+ function onReady( event ) {
266
+ // bail if already triggered or IE8 document is not ready just yet
267
+ var isIE8NotReady = event.type === 'readystatechange' && document.readyState !== 'complete';
268
+ if ( docReady.isReady || isIE8NotReady ) {
269
+ return;
270
+ }
271
+
272
+ trigger();
273
+ }
274
+
275
+ function trigger() {
276
+ docReady.isReady = true;
277
+ // process queue
278
+ for ( var i=0, len = queue.length; i < len; i++ ) {
279
+ var fn = queue[i];
280
+ fn();
281
+ }
282
+ }
283
+
284
+ function defineDocReady( eventie ) {
285
+ // trigger ready if page is ready
286
+ if ( document.readyState === 'complete' ) {
287
+ trigger();
288
+ } else {
289
+ // listen for events
290
+ eventie.bind( document, 'DOMContentLoaded', onReady );
291
+ eventie.bind( document, 'readystatechange', onReady );
292
+ eventie.bind( window, 'load', onReady );
293
+ }
294
+
295
+ return docReady;
296
+ }
297
+
298
+ // transport
299
+ if ( typeof define === 'function' && define.amd ) {
300
+ // AMD
301
+ define( 'doc-ready/doc-ready',[ 'eventie/eventie' ], defineDocReady );
302
+ } else if ( typeof exports === 'object' ) {
303
+ module.exports = defineDocReady( require('eventie') );
304
+ } else {
305
+ // browser global
306
+ window.docReady = defineDocReady( window.eventie );
307
+ }
308
+
309
+ })( window );
310
+
311
+ /*!
312
+ * EventEmitter v4.2.9 - git.io/ee
313
+ * Oliver Caldwell
314
+ * MIT license
315
+ * @preserve
316
+ */
317
+
318
+ (function () {
319
+
320
+
321
+ /**
322
+ * Class for managing events.
323
+ * Can be extended to provide event functionality in other classes.
324
+ *
325
+ * @class EventEmitter Manages event registering and emitting.
326
+ */
327
+ function EventEmitter() {}
328
+
329
+ // Shortcuts to improve speed and size
330
+ var proto = EventEmitter.prototype;
331
+ var exports = this;
332
+ var originalGlobalValue = exports.EventEmitter;
333
+
334
+ /**
335
+ * Finds the index of the listener for the event in its storage array.
336
+ *
337
+ * @param {Function[]} listeners Array of listeners to search through.
338
+ * @param {Function} listener Method to look for.
339
+ * @return {Number} Index of the specified listener, -1 if not found
340
+ * @api private
341
+ */
342
+ function indexOfListener(listeners, listener) {
343
+ var i = listeners.length;
344
+ while (i--) {
345
+ if (listeners[i].listener === listener) {
346
+ return i;
347
+ }
348
+ }
349
+
350
+ return -1;
351
+ }
352
+
353
+ /**
354
+ * Alias a method while keeping the context correct, to allow for overwriting of target method.
355
+ *
356
+ * @param {String} name The name of the target method.
357
+ * @return {Function} The aliased method
358
+ * @api private
359
+ */
360
+ function alias(name) {
361
+ return function aliasClosure() {
362
+ return this[name].apply(this, arguments);
363
+ };
364
+ }
365
+
366
+ /**
367
+ * Returns the listener array for the specified event.
368
+ * Will initialise the event object and listener arrays if required.
369
+ * Will return an object if you use a regex search. The object contains keys for each matched event. So /ba[rz]/ might return an object containing bar and baz. But only if you have either defined them with defineEvent or added some listeners to them.
370
+ * Each property in the object response is an array of listener functions.
371
+ *
372
+ * @param {String|RegExp} evt Name of the event to return the listeners from.
373
+ * @return {Function[]|Object} All listener functions for the event.
374
+ */
375
+ proto.getListeners = function getListeners(evt) {
376
+ var events = this._getEvents();
377
+ var response;
378
+ var key;
379
+
380
+ // Return a concatenated array of all matching events if
381
+ // the selector is a regular expression.
382
+ if (evt instanceof RegExp) {
383
+ response = {};
384
+ for (key in events) {
385
+ if (events.hasOwnProperty(key) && evt.test(key)) {
386
+ response[key] = events[key];
387
+ }
388
+ }
389
+ }
390
+ else {
391
+ response = events[evt] || (events[evt] = []);
392
+ }
393
+
394
+ return response;
395
+ };
396
+
397
+ /**
398
+ * Takes a list of listener objects and flattens it into a list of listener functions.
399
+ *
400
+ * @param {Object[]} listeners Raw listener objects.
401
+ * @return {Function[]} Just the listener functions.
402
+ */
403
+ proto.flattenListeners = function flattenListeners(listeners) {
404
+ var flatListeners = [];
405
+ var i;
406
+
407
+ for (i = 0; i < listeners.length; i += 1) {
408
+ flatListeners.push(listeners[i].listener);
409
+ }
410
+
411
+ return flatListeners;
412
+ };
413
+
414
+ /**
415
+ * Fetches the requested listeners via getListeners but will always return the results inside an object. This is mainly for internal use but others may find it useful.
416
+ *
417
+ * @param {String|RegExp} evt Name of the event to return the listeners from.
418
+ * @return {Object} All listener functions for an event in an object.
419
+ */
420
+ proto.getListenersAsObject = function getListenersAsObject(evt) {
421
+ var listeners = this.getListeners(evt);
422
+ var response;
423
+
424
+ if (listeners instanceof Array) {
425
+ response = {};
426
+ response[evt] = listeners;
427
+ }
428
+
429
+ return response || listeners;
430
+ };
431
+
432
+ /**
433
+ * Adds a listener function to the specified event.
434
+ * The listener will not be added if it is a duplicate.
435
+ * If the listener returns true then it will be removed after it is called.
436
+ * If you pass a regular expression as the event name then the listener will be added to all events that match it.
437
+ *
438
+ * @param {String|RegExp} evt Name of the event to attach the listener to.
439
+ * @param {Function} listener Method to be called when the event is emitted. If the function returns true then it will be removed after calling.
440
+ * @return {Object} Current instance of EventEmitter for chaining.
441
+ */
442
+ proto.addListener = function addListener(evt, listener) {
443
+ var listeners = this.getListenersAsObject(evt);
444
+ var listenerIsWrapped = typeof listener === 'object';
445
+ var key;
446
+
447
+ for (key in listeners) {
448
+ if (listeners.hasOwnProperty(key) && indexOfListener(listeners[key], listener) === -1) {
449
+ listeners[key].push(listenerIsWrapped ? listener : {
450
+ listener: listener,
451
+ once: false
452
+ });
453
+ }
454
+ }
455
+
456
+ return this;
457
+ };
458
+
459
+ /**
460
+ * Alias of addListener
461
+ */
462
+ proto.on = alias('addListener');
463
+
464
+ /**
465
+ * Semi-alias of addListener. It will add a listener that will be
466
+ * automatically removed after its first execution.
467
+ *
468
+ * @param {String|RegExp} evt Name of the event to attach the listener to.
469
+ * @param {Function} listener Method to be called when the event is emitted. If the function returns true then it will be removed after calling.
470
+ * @return {Object} Current instance of EventEmitter for chaining.
471
+ */
472
+ proto.addOnceListener = function addOnceListener(evt, listener) {
473
+ return this.addListener(evt, {
474
+ listener: listener,
475
+ once: true
476
+ });
477
+ };
478
+
479
+ /**
480
+ * Alias of addOnceListener.
481
+ */
482
+ proto.once = alias('addOnceListener');
483
+
484
+ /**
485
+ * Defines an event name. This is required if you want to use a regex to add a listener to multiple events at once. If you don't do this then how do you expect it to know what event to add to? Should it just add to every possible match for a regex? No. That is scary and bad.
486
+ * You need to tell it what event names should be matched by a regex.
487
+ *
488
+ * @param {String} evt Name of the event to create.
489
+ * @return {Object} Current instance of EventEmitter for chaining.
490
+ */
491
+ proto.defineEvent = function defineEvent(evt) {
492
+ this.getListeners(evt);
493
+ return this;
494
+ };
495
+
496
+ /**
497
+ * Uses defineEvent to define multiple events.
498
+ *
499
+ * @param {String[]} evts An array of event names to define.
500
+ * @return {Object} Current instance of EventEmitter for chaining.
501
+ */
502
+ proto.defineEvents = function defineEvents(evts) {
503
+ for (var i = 0; i < evts.length; i += 1) {
504
+ this.defineEvent(evts[i]);
505
+ }
506
+ return this;
507
+ };
508
+
509
+ /**
510
+ * Removes a listener function from the specified event.
511
+ * When passed a regular expression as the event name, it will remove the listener from all events that match it.
512
+ *
513
+ * @param {String|RegExp} evt Name of the event to remove the listener from.
514
+ * @param {Function} listener Method to remove from the event.
515
+ * @return {Object} Current instance of EventEmitter for chaining.
516
+ */
517
+ proto.removeListener = function removeListener(evt, listener) {
518
+ var listeners = this.getListenersAsObject(evt);
519
+ var index;
520
+ var key;
521
+
522
+ for (key in listeners) {
523
+ if (listeners.hasOwnProperty(key)) {
524
+ index = indexOfListener(listeners[key], listener);
525
+
526
+ if (index !== -1) {
527
+ listeners[key].splice(index, 1);
528
+ }
529
+ }
530
+ }
531
+
532
+ return this;
533
+ };
534
+
535
+ /**
536
+ * Alias of removeListener
537
+ */
538
+ proto.off = alias('removeListener');
539
+
540
+ /**
541
+ * Adds listeners in bulk using the manipulateListeners method.
542
+ * If you pass an object as the second argument you can add to multiple events at once. The object should contain key value pairs of events and listeners or listener arrays. You can also pass it an event name and an array of listeners to be added.
543
+ * You can also pass it a regular expression to add the array of listeners to all events that match it.
544
+ * Yeah, this function does quite a bit. That's probably a bad thing.
545
+ *
546
+ * @param {String|Object|RegExp} evt An event name if you will pass an array of listeners next. An object if you wish to add to multiple events at once.
547
+ * @param {Function[]} [listeners] An optional array of listener functions to add.
548
+ * @return {Object} Current instance of EventEmitter for chaining.
549
+ */
550
+ proto.addListeners = function addListeners(evt, listeners) {
551
+ // Pass through to manipulateListeners
552
+ return this.manipulateListeners(false, evt, listeners);
553
+ };
554
+
555
+ /**
556
+ * Removes listeners in bulk using the manipulateListeners method.
557
+ * If you pass an object as the second argument you can remove from multiple events at once. The object should contain key value pairs of events and listeners or listener arrays.
558
+ * You can also pass it an event name and an array of listeners to be removed.
559
+ * You can also pass it a regular expression to remove the listeners from all events that match it.
560
+ *
561
+ * @param {String|Object|RegExp} evt An event name if you will pass an array of listeners next. An object if you wish to remove from multiple events at once.
562
+ * @param {Function[]} [listeners] An optional array of listener functions to remove.
563
+ * @return {Object} Current instance of EventEmitter for chaining.
564
+ */
565
+ proto.removeListeners = function removeListeners(evt, listeners) {
566
+ // Pass through to manipulateListeners
567
+ return this.manipulateListeners(true, evt, listeners);
568
+ };
569
+
570
+ /**
571
+ * Edits listeners in bulk. The addListeners and removeListeners methods both use this to do their job. You should really use those instead, this is a little lower level.
572
+ * The first argument will determine if the listeners are removed (true) or added (false).
573
+ * If you pass an object as the second argument you can add/remove from multiple events at once. The object should contain key value pairs of events and listeners or listener arrays.
574
+ * You can also pass it an event name and an array of listeners to be added/removed.
575
+ * You can also pass it a regular expression to manipulate the listeners of all events that match it.
576
+ *
577
+ * @param {Boolean} remove True if you want to remove listeners, false if you want to add.
578
+ * @param {String|Object|RegExp} evt An event name if you will pass an array of listeners next. An object if you wish to add/remove from multiple events at once.
579
+ * @param {Function[]} [listeners] An optional array of listener functions to add/remove.
580
+ * @return {Object} Current instance of EventEmitter for chaining.
581
+ */
582
+ proto.manipulateListeners = function manipulateListeners(remove, evt, listeners) {
583
+ var i;
584
+ var value;
585
+ var single = remove ? this.removeListener : this.addListener;
586
+ var multiple = remove ? this.removeListeners : this.addListeners;
587
+
588
+ // If evt is an object then pass each of its properties to this method
589
+ if (typeof evt === 'object' && !(evt instanceof RegExp)) {
590
+ for (i in evt) {
591
+ if (evt.hasOwnProperty(i) && (value = evt[i])) {
592
+ // Pass the single listener straight through to the singular method
593
+ if (typeof value === 'function') {
594
+ single.call(this, i, value);
595
+ }
596
+ else {
597
+ // Otherwise pass back to the multiple function
598
+ multiple.call(this, i, value);
599
+ }
600
+ }
601
+ }
602
+ }
603
+ else {
604
+ // So evt must be a string
605
+ // And listeners must be an array of listeners
606
+ // Loop over it and pass each one to the multiple method
607
+ i = listeners.length;
608
+ while (i--) {
609
+ single.call(this, evt, listeners[i]);
610
+ }
611
+ }
612
+
613
+ return this;
614
+ };
615
+
616
+ /**
617
+ * Removes all listeners from a specified event.
618
+ * If you do not specify an event then all listeners will be removed.
619
+ * That means every event will be emptied.
620
+ * You can also pass a regex to remove all events that match it.
621
+ *
622
+ * @param {String|RegExp} [evt] Optional name of the event to remove all listeners for. Will remove from every event if not passed.
623
+ * @return {Object} Current instance of EventEmitter for chaining.
624
+ */
625
+ proto.removeEvent = function removeEvent(evt) {
626
+ var type = typeof evt;
627
+ var events = this._getEvents();
628
+ var key;
629
+
630
+ // Remove different things depending on the state of evt
631
+ if (type === 'string') {
632
+ // Remove all listeners for the specified event
633
+ delete events[evt];
634
+ }
635
+ else if (evt instanceof RegExp) {
636
+ // Remove all events matching the regex.
637
+ for (key in events) {
638
+ if (events.hasOwnProperty(key) && evt.test(key)) {
639
+ delete events[key];
640
+ }
641
+ }
642
+ }
643
+ else {
644
+ // Remove all listeners in all events
645
+ delete this._events;
646
+ }
647
+
648
+ return this;
649
+ };
650
+
651
+ /**
652
+ * Alias of removeEvent.
653
+ *
654
+ * Added to mirror the node API.
655
+ */
656
+ proto.removeAllListeners = alias('removeEvent');
657
+
658
+ /**
659
+ * Emits an event of your choice.
660
+ * When emitted, every listener attached to that event will be executed.
661
+ * If you pass the optional argument array then those arguments will be passed to every listener upon execution.
662
+ * Because it uses `apply`, your array of arguments will be passed as if you wrote them out separately.
663
+ * So they will not arrive within the array on the other side, they will be separate.
664
+ * You can also pass a regular expression to emit to all events that match it.
665
+ *
666
+ * @param {String|RegExp} evt Name of the event to emit and execute listeners for.
667
+ * @param {Array} [args] Optional array of arguments to be passed to each listener.
668
+ * @return {Object} Current instance of EventEmitter for chaining.
669
+ */
670
+ proto.emitEvent = function emitEvent(evt, args) {
671
+ var listeners = this.getListenersAsObject(evt);
672
+ var listener;
673
+ var i;
674
+ var key;
675
+ var response;
676
+
677
+ for (key in listeners) {
678
+ if (listeners.hasOwnProperty(key)) {
679
+ i = listeners[key].length;
680
+
681
+ while (i--) {
682
+ // If the listener returns true then it shall be removed from the event
683
+ // The function is executed either with a basic call or an apply if there is an args array
684
+ listener = listeners[key][i];
685
+
686
+ if (listener.once === true) {
687
+ this.removeListener(evt, listener.listener);
688
+ }
689
+
690
+ response = listener.listener.apply(this, args || []);
691
+
692
+ if (response === this._getOnceReturnValue()) {
693
+ this.removeListener(evt, listener.listener);
694
+ }
695
+ }
696
+ }
697
+ }
698
+
699
+ return this;
700
+ };
701
+
702
+ /**
703
+ * Alias of emitEvent
704
+ */
705
+ proto.trigger = alias('emitEvent');
706
+
707
+ /**
708
+ * Subtly different from emitEvent in that it will pass its arguments on to the listeners, as opposed to taking a single array of arguments to pass on.
709
+ * As with emitEvent, you can pass a regex in place of the event name to emit to all events that match it.
710
+ *
711
+ * @param {String|RegExp} evt Name of the event to emit and execute listeners for.
712
+ * @param {...*} Optional additional arguments to be passed to each listener.
713
+ * @return {Object} Current instance of EventEmitter for chaining.
714
+ */
715
+ proto.emit = function emit(evt) {
716
+ var args = Array.prototype.slice.call(arguments, 1);
717
+ return this.emitEvent(evt, args);
718
+ };
719
+
720
+ /**
721
+ * Sets the current value to check against when executing listeners. If a
722
+ * listeners return value matches the one set here then it will be removed
723
+ * after execution. This value defaults to true.
724
+ *
725
+ * @param {*} value The new value to check for when executing listeners.
726
+ * @return {Object} Current instance of EventEmitter for chaining.
727
+ */
728
+ proto.setOnceReturnValue = function setOnceReturnValue(value) {
729
+ this._onceReturnValue = value;
730
+ return this;
731
+ };
732
+
733
+ /**
734
+ * Fetches the current value to check against when executing listeners. If
735
+ * the listeners return value matches this one then it should be removed
736
+ * automatically. It will return true by default.
737
+ *
738
+ * @return {*|Boolean} The current value to check for or the default, true.
739
+ * @api private
740
+ */
741
+ proto._getOnceReturnValue = function _getOnceReturnValue() {
742
+ if (this.hasOwnProperty('_onceReturnValue')) {
743
+ return this._onceReturnValue;
744
+ }
745
+ else {
746
+ return true;
747
+ }
748
+ };
749
+
750
+ /**
751
+ * Fetches the events object and creates one if required.
752
+ *
753
+ * @return {Object} The events storage object.
754
+ * @api private
755
+ */
756
+ proto._getEvents = function _getEvents() {
757
+ return this._events || (this._events = {});
758
+ };
759
+
760
+ /**
761
+ * Reverts the global {@link EventEmitter} to its previous value and returns a reference to this version.
762
+ *
763
+ * @return {Function} Non conflicting EventEmitter class.
764
+ */
765
+ EventEmitter.noConflict = function noConflict() {
766
+ exports.EventEmitter = originalGlobalValue;
767
+ return EventEmitter;
768
+ };
769
+
770
+ // Expose the class either via AMD, CommonJS or the global object
771
+ if (typeof define === 'function' && define.amd) {
772
+ define('eventEmitter/EventEmitter',[],function () {
773
+ return EventEmitter;
774
+ });
775
+ }
776
+ else if (typeof module === 'object' && module.exports){
777
+ module.exports = EventEmitter;
778
+ }
779
+ else {
780
+ exports.EventEmitter = EventEmitter;
781
+ }
782
+ }.call(this));
783
+
784
+ /*!
785
+ * getStyleProperty v1.0.4
786
+ * original by kangax
787
+ * http://perfectionkills.com/feature-testing-css-properties/
788
+ * MIT license
789
+ */
790
+
791
+ /*jshint browser: true, strict: true, undef: true */
792
+ /*global define: false, exports: false, module: false */
793
+
794
+ ( function( window ) {
795
+
796
+
797
+
798
+ var prefixes = 'Webkit Moz ms Ms O'.split(' ');
799
+ var docElemStyle = document.documentElement.style;
800
+
801
+ function getStyleProperty( propName ) {
802
+ if ( !propName ) {
803
+ return;
804
+ }
805
+
806
+ // test standard property first
807
+ if ( typeof docElemStyle[ propName ] === 'string' ) {
808
+ return propName;
809
+ }
810
+
811
+ // capitalize
812
+ propName = propName.charAt(0).toUpperCase() + propName.slice(1);
813
+
814
+ // test vendor specific properties
815
+ var prefixed;
816
+ for ( var i=0, len = prefixes.length; i < len; i++ ) {
817
+ prefixed = prefixes[i] + propName;
818
+ if ( typeof docElemStyle[ prefixed ] === 'string' ) {
819
+ return prefixed;
820
+ }
821
+ }
822
+ }
823
+
824
+ // transport
825
+ if ( typeof define === 'function' && define.amd ) {
826
+ // AMD
827
+ define( 'get-style-property/get-style-property',[],function() {
828
+ return getStyleProperty;
829
+ });
830
+ } else if ( typeof exports === 'object' ) {
831
+ // CommonJS for Component
832
+ module.exports = getStyleProperty;
833
+ } else {
834
+ // browser global
835
+ window.getStyleProperty = getStyleProperty;
836
+ }
837
+
838
+ })( window );
839
+
840
+ /*!
841
+ * getSize v1.2.2
842
+ * measure size of elements
843
+ * MIT license
844
+ */
845
+
846
+ /*jshint browser: true, strict: true, undef: true, unused: true */
847
+ /*global define: false, exports: false, require: false, module: false, console: false */
848
+
849
+ ( function( window, undefined ) {
850
+
851
+
852
+
853
+ // -------------------------- helpers -------------------------- //
854
+
855
+ // get a number from a string, not a percentage
856
+ function getStyleSize( value ) {
857
+ var num = parseFloat( value );
858
+ // not a percent like '100%', and a number
859
+ var isValid = value.indexOf('%') === -1 && !isNaN( num );
860
+ return isValid && num;
861
+ }
862
+
863
+ function noop() {}
864
+
865
+ var logError = typeof console === 'undefined' ? noop :
866
+ function( message ) {
867
+ console.error( message );
868
+ };
869
+
870
+ // -------------------------- measurements -------------------------- //
871
+
872
+ var measurements = [
873
+ 'paddingLeft',
874
+ 'paddingRight',
875
+ 'paddingTop',
876
+ 'paddingBottom',
877
+ 'marginLeft',
878
+ 'marginRight',
879
+ 'marginTop',
880
+ 'marginBottom',
881
+ 'borderLeftWidth',
882
+ 'borderRightWidth',
883
+ 'borderTopWidth',
884
+ 'borderBottomWidth'
885
+ ];
886
+
887
+ function getZeroSize() {
888
+ var size = {
889
+ width: 0,
890
+ height: 0,
891
+ innerWidth: 0,
892
+ innerHeight: 0,
893
+ outerWidth: 0,
894
+ outerHeight: 0
895
+ };
896
+ for ( var i=0, len = measurements.length; i < len; i++ ) {
897
+ var measurement = measurements[i];
898
+ size[ measurement ] = 0;
899
+ }
900
+ return size;
901
+ }
902
+
903
+
904
+
905
+ function defineGetSize( getStyleProperty ) {
906
+
907
+ // -------------------------- setup -------------------------- //
908
+
909
+ var isSetup = false;
910
+
911
+ var getStyle, boxSizingProp, isBoxSizeOuter;
912
+
913
+ /**
914
+ * setup vars and functions
915
+ * do it on initial getSize(), rather than on script load
916
+ * For Firefox bug https://bugzilla.mozilla.org/show_bug.cgi?id=548397
917
+ */
918
+ function setup() {
919
+ // setup once
920
+ if ( isSetup ) {
921
+ return;
922
+ }
923
+ isSetup = true;
924
+
925
+ var getComputedStyle = window.getComputedStyle;
926
+ getStyle = ( function() {
927
+ var getStyleFn = getComputedStyle ?
928
+ function( elem ) {
929
+ return getComputedStyle( elem, null );
930
+ } :
931
+ function( elem ) {
932
+ return elem.currentStyle;
933
+ };
934
+
935
+ return function getStyle( elem ) {
936
+ var style = getStyleFn( elem );
937
+ if ( !style ) {
938
+ logError( 'Style returned ' + style +
939
+ '. Are you running this code in a hidden iframe on Firefox? ' +
940
+ 'See http://bit.ly/getsizebug1' );
941
+ }
942
+ return style;
943
+ };
944
+ })();
945
+
946
+ // -------------------------- box sizing -------------------------- //
947
+
948
+ boxSizingProp = getStyleProperty('boxSizing');
949
+
950
+ /**
951
+ * WebKit measures the outer-width on style.width on border-box elems
952
+ * IE & Firefox measures the inner-width
953
+ */
954
+ if ( boxSizingProp ) {
955
+ var div = document.createElement('div');
956
+ div.style.width = '200px';
957
+ div.style.padding = '1px 2px 3px 4px';
958
+ div.style.borderStyle = 'solid';
959
+ div.style.borderWidth = '1px 2px 3px 4px';
960
+ div.style[ boxSizingProp ] = 'border-box';
961
+
962
+ var body = document.body || document.documentElement;
963
+ body.appendChild( div );
964
+ var style = getStyle( div );
965
+
966
+ isBoxSizeOuter = getStyleSize( style.width ) === 200;
967
+ body.removeChild( div );
968
+ }
969
+
970
+ }
971
+
972
+ // -------------------------- getSize -------------------------- //
973
+
974
+ function getSize( elem ) {
975
+ setup();
976
+
977
+ // use querySeletor if elem is string
978
+ if ( typeof elem === 'string' ) {
979
+ elem = document.querySelector( elem );
980
+ }
981
+
982
+ // do not proceed on non-objects
983
+ if ( !elem || typeof elem !== 'object' || !elem.nodeType ) {
984
+ return;
985
+ }
986
+
987
+ var style = getStyle( elem );
988
+
989
+ // if hidden, everything is 0
990
+ if ( style.display === 'none' ) {
991
+ return getZeroSize();
992
+ }
993
+
994
+ var size = {};
995
+ size.width = elem.offsetWidth;
996
+ size.height = elem.offsetHeight;
997
+
998
+ var isBorderBox = size.isBorderBox = !!( boxSizingProp &&
999
+ style[ boxSizingProp ] && style[ boxSizingProp ] === 'border-box' );
1000
+
1001
+ // get all measurements
1002
+ for ( var i=0, len = measurements.length; i < len; i++ ) {
1003
+ var measurement = measurements[i];
1004
+ var value = style[ measurement ];
1005
+ value = mungeNonPixel( elem, value );
1006
+ var num = parseFloat( value );
1007
+ // any 'auto', 'medium' value will be 0
1008
+ size[ measurement ] = !isNaN( num ) ? num : 0;
1009
+ }
1010
+
1011
+ var paddingWidth = size.paddingLeft + size.paddingRight;
1012
+ var paddingHeight = size.paddingTop + size.paddingBottom;
1013
+ var marginWidth = size.marginLeft + size.marginRight;
1014
+ var marginHeight = size.marginTop + size.marginBottom;
1015
+ var borderWidth = size.borderLeftWidth + size.borderRightWidth;
1016
+ var borderHeight = size.borderTopWidth + size.borderBottomWidth;
1017
+
1018
+ var isBorderBoxSizeOuter = isBorderBox && isBoxSizeOuter;
1019
+
1020
+ // overwrite width and height if we can get it from style
1021
+ var styleWidth = getStyleSize( style.width );
1022
+ if ( styleWidth !== false ) {
1023
+ size.width = styleWidth +
1024
+ // add padding and border unless it's already including it
1025
+ ( isBorderBoxSizeOuter ? 0 : paddingWidth + borderWidth );
1026
+ }
1027
+
1028
+ var styleHeight = getStyleSize( style.height );
1029
+ if ( styleHeight !== false ) {
1030
+ size.height = styleHeight +
1031
+ // add padding and border unless it's already including it
1032
+ ( isBorderBoxSizeOuter ? 0 : paddingHeight + borderHeight );
1033
+ }
1034
+
1035
+ size.innerWidth = size.width - ( paddingWidth + borderWidth );
1036
+ size.innerHeight = size.height - ( paddingHeight + borderHeight );
1037
+
1038
+ size.outerWidth = size.width + marginWidth;
1039
+ size.outerHeight = size.height + marginHeight;
1040
+
1041
+ return size;
1042
+ }
1043
+
1044
+ // IE8 returns percent values, not pixels
1045
+ // taken from jQuery's curCSS
1046
+ function mungeNonPixel( elem, value ) {
1047
+ // IE8 and has percent value
1048
+ if ( window.getComputedStyle || value.indexOf('%') === -1 ) {
1049
+ return value;
1050
+ }
1051
+ var style = elem.style;
1052
+ // Remember the original values
1053
+ var left = style.left;
1054
+ var rs = elem.runtimeStyle;
1055
+ var rsLeft = rs && rs.left;
1056
+
1057
+ // Put in the new values to get a computed value out
1058
+ if ( rsLeft ) {
1059
+ rs.left = elem.currentStyle.left;
1060
+ }
1061
+ style.left = value;
1062
+ value = style.pixelLeft;
1063
+
1064
+ // Revert the changed values
1065
+ style.left = left;
1066
+ if ( rsLeft ) {
1067
+ rs.left = rsLeft;
1068
+ }
1069
+
1070
+ return value;
1071
+ }
1072
+
1073
+ return getSize;
1074
+
1075
+ }
1076
+
1077
+ // transport
1078
+ if ( typeof define === 'function' && define.amd ) {
1079
+ // AMD for RequireJS
1080
+ define( 'get-size/get-size',[ 'get-style-property/get-style-property' ], defineGetSize );
1081
+ } else if ( typeof exports === 'object' ) {
1082
+ // CommonJS for Component
1083
+ module.exports = defineGetSize( require('desandro-get-style-property') );
1084
+ } else {
1085
+ // browser global
1086
+ window.getSize = defineGetSize( window.getStyleProperty );
1087
+ }
1088
+
1089
+ })( window );
1090
+
1091
+ /**
1092
+ * matchesSelector v1.0.2
1093
+ * matchesSelector( element, '.selector' )
1094
+ * MIT license
1095
+ */
1096
+
1097
+ /*jshint browser: true, strict: true, undef: true, unused: true */
1098
+ /*global define: false, module: false */
1099
+
1100
+ ( function( ElemProto ) {
1101
+
1102
+
1103
+
1104
+ var matchesMethod = ( function() {
1105
+ // check un-prefixed
1106
+ if ( ElemProto.matchesSelector ) {
1107
+ return 'matchesSelector';
1108
+ }
1109
+ // check vendor prefixes
1110
+ var prefixes = [ 'webkit', 'moz', 'ms', 'o' ];
1111
+
1112
+ for ( var i=0, len = prefixes.length; i < len; i++ ) {
1113
+ var prefix = prefixes[i];
1114
+ var method = prefix + 'MatchesSelector';
1115
+ if ( ElemProto[ method ] ) {
1116
+ return method;
1117
+ }
1118
+ }
1119
+ })();
1120
+
1121
+ // ----- match ----- //
1122
+
1123
+ function match( elem, selector ) {
1124
+ return elem[ matchesMethod ]( selector );
1125
+ }
1126
+
1127
+ // ----- appendToFragment ----- //
1128
+
1129
+ function checkParent( elem ) {
1130
+ // not needed if already has parent
1131
+ if ( elem.parentNode ) {
1132
+ return;
1133
+ }
1134
+ var fragment = document.createDocumentFragment();
1135
+ fragment.appendChild( elem );
1136
+ }
1137
+
1138
+ // ----- query ----- //
1139
+
1140
+ // fall back to using QSA
1141
+ // thx @jonathantneal https://gist.github.com/3062955
1142
+ function query( elem, selector ) {
1143
+ // append to fragment if no parent
1144
+ checkParent( elem );
1145
+
1146
+ // match elem with all selected elems of parent
1147
+ var elems = elem.parentNode.querySelectorAll( selector );
1148
+ for ( var i=0, len = elems.length; i < len; i++ ) {
1149
+ // return true if match
1150
+ if ( elems[i] === elem ) {
1151
+ return true;
1152
+ }
1153
+ }
1154
+ // otherwise return false
1155
+ return false;
1156
+ }
1157
+
1158
+ // ----- matchChild ----- //
1159
+
1160
+ function matchChild( elem, selector ) {
1161
+ checkParent( elem );
1162
+ return match( elem, selector );
1163
+ }
1164
+
1165
+ // ----- matchesSelector ----- //
1166
+
1167
+ var matchesSelector;
1168
+
1169
+ if ( matchesMethod ) {
1170
+ // IE9 supports matchesSelector, but doesn't work on orphaned elems
1171
+ // check for that
1172
+ var div = document.createElement('div');
1173
+ var supportsOrphans = match( div, 'div' );
1174
+ matchesSelector = supportsOrphans ? match : matchChild;
1175
+ } else {
1176
+ matchesSelector = query;
1177
+ }
1178
+
1179
+ // transport
1180
+ if ( typeof define === 'function' && define.amd ) {
1181
+ // AMD
1182
+ define( 'matches-selector/matches-selector',[],function() {
1183
+ return matchesSelector;
1184
+ });
1185
+ } else if ( typeof exports === 'object' ) {
1186
+ module.exports = matchesSelector;
1187
+ }
1188
+ else {
1189
+ // browser global
1190
+ window.matchesSelector = matchesSelector;
1191
+ }
1192
+
1193
+ })( Element.prototype );
1194
+
1195
+ /**
1196
+ * Outlayer Item
1197
+ */
1198
+
1199
+ ( function( window ) {
1200
+
1201
+
1202
+
1203
+ // ----- get style ----- //
1204
+
1205
+ var getComputedStyle = window.getComputedStyle;
1206
+ var getStyle = getComputedStyle ?
1207
+ function( elem ) {
1208
+ return getComputedStyle( elem, null );
1209
+ } :
1210
+ function( elem ) {
1211
+ return elem.currentStyle;
1212
+ };
1213
+
1214
+
1215
+ // extend objects
1216
+ function extend( a, b ) {
1217
+ for ( var prop in b ) {
1218
+ a[ prop ] = b[ prop ];
1219
+ }
1220
+ return a;
1221
+ }
1222
+
1223
+ function isEmptyObj( obj ) {
1224
+ for ( var prop in obj ) {
1225
+ return false;
1226
+ }
1227
+ prop = null;
1228
+ return true;
1229
+ }
1230
+
1231
+ // http://jamesroberts.name/blog/2010/02/22/string-functions-for-javascript-trim-to-camel-case-to-dashed-and-to-underscore/
1232
+ function toDash( str ) {
1233
+ return str.replace( /([A-Z])/g, function( $1 ){
1234
+ return '-' + $1.toLowerCase();
1235
+ });
1236
+ }
1237
+
1238
+ // -------------------------- Outlayer definition -------------------------- //
1239
+
1240
+ function outlayerItemDefinition( EventEmitter, getSize, getStyleProperty ) {
1241
+
1242
+ // -------------------------- CSS3 support -------------------------- //
1243
+
1244
+ var transitionProperty = getStyleProperty('transition');
1245
+ var transformProperty = getStyleProperty('transform');
1246
+ var supportsCSS3 = transitionProperty && transformProperty;
1247
+ var is3d = !!getStyleProperty('perspective');
1248
+
1249
+ var transitionEndEvent = {
1250
+ WebkitTransition: 'webkitTransitionEnd',
1251
+ MozTransition: 'transitionend',
1252
+ OTransition: 'otransitionend',
1253
+ transition: 'transitionend'
1254
+ }[ transitionProperty ];
1255
+
1256
+ // properties that could have vendor prefix
1257
+ var prefixableProperties = [
1258
+ 'transform',
1259
+ 'transition',
1260
+ 'transitionDuration',
1261
+ 'transitionProperty'
1262
+ ];
1263
+
1264
+ // cache all vendor properties
1265
+ var vendorProperties = ( function() {
1266
+ var cache = {};
1267
+ for ( var i=0, len = prefixableProperties.length; i < len; i++ ) {
1268
+ var prop = prefixableProperties[i];
1269
+ var supportedProp = getStyleProperty( prop );
1270
+ if ( supportedProp && supportedProp !== prop ) {
1271
+ cache[ prop ] = supportedProp;
1272
+ }
1273
+ }
1274
+ return cache;
1275
+ })();
1276
+
1277
+ // -------------------------- Item -------------------------- //
1278
+
1279
+ function Item( element, layout ) {
1280
+ if ( !element ) {
1281
+ return;
1282
+ }
1283
+
1284
+ this.element = element;
1285
+ // parent layout class, i.e. Masonry, Isotope, or Packery
1286
+ this.layout = layout;
1287
+ this.position = {
1288
+ x: 0,
1289
+ y: 0
1290
+ };
1291
+
1292
+ this._create();
1293
+ }
1294
+
1295
+ // inherit EventEmitter
1296
+ extend( Item.prototype, EventEmitter.prototype );
1297
+
1298
+ Item.prototype._create = function() {
1299
+ // transition objects
1300
+ this._transn = {
1301
+ ingProperties: {},
1302
+ clean: {},
1303
+ onEnd: {}
1304
+ };
1305
+
1306
+ this.css({
1307
+ position: 'absolute'
1308
+ });
1309
+ };
1310
+
1311
+ // trigger specified handler for event type
1312
+ Item.prototype.handleEvent = function( event ) {
1313
+ var method = 'on' + event.type;
1314
+ if ( this[ method ] ) {
1315
+ this[ method ]( event );
1316
+ }
1317
+ };
1318
+
1319
+ Item.prototype.getSize = function() {
1320
+ this.size = getSize( this.element );
1321
+ };
1322
+
1323
+ /**
1324
+ * apply CSS styles to element
1325
+ * @param {Object} style
1326
+ */
1327
+ Item.prototype.css = function( style ) {
1328
+ var elemStyle = this.element.style;
1329
+
1330
+ for ( var prop in style ) {
1331
+ // use vendor property if available
1332
+ var supportedProp = vendorProperties[ prop ] || prop;
1333
+ elemStyle[ supportedProp ] = style[ prop ];
1334
+ }
1335
+ };
1336
+
1337
+ // measure position, and sets it
1338
+ Item.prototype.getPosition = function() {
1339
+ var style = getStyle( this.element );
1340
+ var layoutOptions = this.layout.options;
1341
+ var isOriginLeft = layoutOptions.isOriginLeft;
1342
+ var isOriginTop = layoutOptions.isOriginTop;
1343
+ var x = parseInt( style[ isOriginLeft ? 'left' : 'right' ], 10 );
1344
+ var y = parseInt( style[ isOriginTop ? 'top' : 'bottom' ], 10 );
1345
+
1346
+ // clean up 'auto' or other non-integer values
1347
+ x = isNaN( x ) ? 0 : x;
1348
+ y = isNaN( y ) ? 0 : y;
1349
+ // remove padding from measurement
1350
+ var layoutSize = this.layout.size;
1351
+ x -= isOriginLeft ? layoutSize.paddingLeft : layoutSize.paddingRight;
1352
+ y -= isOriginTop ? layoutSize.paddingTop : layoutSize.paddingBottom;
1353
+
1354
+ this.position.x = x;
1355
+ this.position.y = y;
1356
+ };
1357
+
1358
+ // set settled position, apply padding
1359
+ Item.prototype.layoutPosition = function() {
1360
+ var layoutSize = this.layout.size;
1361
+ var layoutOptions = this.layout.options;
1362
+ var style = {};
1363
+
1364
+ if ( layoutOptions.isOriginLeft ) {
1365
+ style.left = ( this.position.x + layoutSize.paddingLeft ) + 'px';
1366
+ // reset other property
1367
+ style.right = '';
1368
+ } else {
1369
+ style.right = ( this.position.x + layoutSize.paddingRight ) + 'px';
1370
+ style.left = '';
1371
+ }
1372
+
1373
+ if ( layoutOptions.isOriginTop ) {
1374
+ style.top = ( this.position.y + layoutSize.paddingTop ) + 'px';
1375
+ style.bottom = '';
1376
+ } else {
1377
+ style.bottom = ( this.position.y + layoutSize.paddingBottom ) + 'px';
1378
+ style.top = '';
1379
+ }
1380
+
1381
+ this.css( style );
1382
+ this.emitEvent( 'layout', [ this ] );
1383
+ };
1384
+
1385
+
1386
+ // transform translate function
1387
+ var translate = is3d ?
1388
+ function( x, y ) {
1389
+ return 'translate3d(' + x + 'px, ' + y + 'px, 0)';
1390
+ } :
1391
+ function( x, y ) {
1392
+ return 'translate(' + x + 'px, ' + y + 'px)';
1393
+ };
1394
+
1395
+
1396
+ Item.prototype._transitionTo = function( x, y ) {
1397
+ this.getPosition();
1398
+ // get current x & y from top/left
1399
+ var curX = this.position.x;
1400
+ var curY = this.position.y;
1401
+
1402
+ var compareX = parseInt( x, 10 );
1403
+ var compareY = parseInt( y, 10 );
1404
+ var didNotMove = compareX === this.position.x && compareY === this.position.y;
1405
+
1406
+ // save end position
1407
+ this.setPosition( x, y );
1408
+
1409
+ // if did not move and not transitioning, just go to layout
1410
+ if ( didNotMove && !this.isTransitioning ) {
1411
+ this.layoutPosition();
1412
+ return;
1413
+ }
1414
+
1415
+ var transX = x - curX;
1416
+ var transY = y - curY;
1417
+ var transitionStyle = {};
1418
+ // flip cooridinates if origin on right or bottom
1419
+ var layoutOptions = this.layout.options;
1420
+ transX = layoutOptions.isOriginLeft ? transX : -transX;
1421
+ transY = layoutOptions.isOriginTop ? transY : -transY;
1422
+ transitionStyle.transform = translate( transX, transY );
1423
+
1424
+ this.transition({
1425
+ to: transitionStyle,
1426
+ onTransitionEnd: {
1427
+ transform: this.layoutPosition
1428
+ },
1429
+ isCleaning: true
1430
+ });
1431
+ };
1432
+
1433
+ // non transition + transform support
1434
+ Item.prototype.goTo = function( x, y ) {
1435
+ this.setPosition( x, y );
1436
+ this.layoutPosition();
1437
+ };
1438
+
1439
+ // use transition and transforms if supported
1440
+ Item.prototype.moveTo = supportsCSS3 ?
1441
+ Item.prototype._transitionTo : Item.prototype.goTo;
1442
+
1443
+ Item.prototype.setPosition = function( x, y ) {
1444
+ this.position.x = parseInt( x, 10 );
1445
+ this.position.y = parseInt( y, 10 );
1446
+ };
1447
+
1448
+ // ----- transition ----- //
1449
+
1450
+ /**
1451
+ * @param {Object} style - CSS
1452
+ * @param {Function} onTransitionEnd
1453
+ */
1454
+
1455
+ // non transition, just trigger callback
1456
+ Item.prototype._nonTransition = function( args ) {
1457
+ this.css( args.to );
1458
+ if ( args.isCleaning ) {
1459
+ this._removeStyles( args.to );
1460
+ }
1461
+ for ( var prop in args.onTransitionEnd ) {
1462
+ args.onTransitionEnd[ prop ].call( this );
1463
+ }
1464
+ };
1465
+
1466
+ /**
1467
+ * proper transition
1468
+ * @param {Object} args - arguments
1469
+ * @param {Object} to - style to transition to
1470
+ * @param {Object} from - style to start transition from
1471
+ * @param {Boolean} isCleaning - removes transition styles after transition
1472
+ * @param {Function} onTransitionEnd - callback
1473
+ */
1474
+ Item.prototype._transition = function( args ) {
1475
+ // redirect to nonTransition if no transition duration
1476
+ if ( !parseFloat( this.layout.options.transitionDuration ) ) {
1477
+ this._nonTransition( args );
1478
+ return;
1479
+ }
1480
+
1481
+ var _transition = this._transn;
1482
+ // keep track of onTransitionEnd callback by css property
1483
+ for ( var prop in args.onTransitionEnd ) {
1484
+ _transition.onEnd[ prop ] = args.onTransitionEnd[ prop ];
1485
+ }
1486
+ // keep track of properties that are transitioning
1487
+ for ( prop in args.to ) {
1488
+ _transition.ingProperties[ prop ] = true;
1489
+ // keep track of properties to clean up when transition is done
1490
+ if ( args.isCleaning ) {
1491
+ _transition.clean[ prop ] = true;
1492
+ }
1493
+ }
1494
+
1495
+ // set from styles
1496
+ if ( args.from ) {
1497
+ this.css( args.from );
1498
+ // force redraw. http://blog.alexmaccaw.com/css-transitions
1499
+ var h = this.element.offsetHeight;
1500
+ // hack for JSHint to hush about unused var
1501
+ h = null;
1502
+ }
1503
+ // enable transition
1504
+ this.enableTransition( args.to );
1505
+ // set styles that are transitioning
1506
+ this.css( args.to );
1507
+
1508
+ this.isTransitioning = true;
1509
+
1510
+ };
1511
+
1512
+ var itemTransitionProperties = transformProperty && ( toDash( transformProperty ) +
1513
+ ',opacity' );
1514
+
1515
+ Item.prototype.enableTransition = function(/* style */) {
1516
+ // only enable if not already transitioning
1517
+ // bug in IE10 were re-setting transition style will prevent
1518
+ // transitionend event from triggering
1519
+ if ( this.isTransitioning ) {
1520
+ return;
1521
+ }
1522
+
1523
+ // make transition: foo, bar, baz from style object
1524
+ // TODO uncomment this bit when IE10 bug is resolved
1525
+ // var transitionValue = [];
1526
+ // for ( var prop in style ) {
1527
+ // // dash-ify camelCased properties like WebkitTransition
1528
+ // transitionValue.push( toDash( prop ) );
1529
+ // }
1530
+ // enable transition styles
1531
+ // HACK always enable transform,opacity for IE10
1532
+ this.css({
1533
+ transitionProperty: itemTransitionProperties,
1534
+ transitionDuration: this.layout.options.transitionDuration
1535
+ });
1536
+ // listen for transition end event
1537
+ this.element.addEventListener( transitionEndEvent, this, false );
1538
+ };
1539
+
1540
+ Item.prototype.transition = Item.prototype[ transitionProperty ? '_transition' : '_nonTransition' ];
1541
+
1542
+ // ----- events ----- //
1543
+
1544
+ Item.prototype.onwebkitTransitionEnd = function( event ) {
1545
+ this.ontransitionend( event );
1546
+ };
1547
+
1548
+ Item.prototype.onotransitionend = function( event ) {
1549
+ this.ontransitionend( event );
1550
+ };
1551
+
1552
+ // properties that I munge to make my life easier
1553
+ var dashedVendorProperties = {
1554
+ '-webkit-transform': 'transform',
1555
+ '-moz-transform': 'transform',
1556
+ '-o-transform': 'transform'
1557
+ };
1558
+
1559
+ Item.prototype.ontransitionend = function( event ) {
1560
+ // disregard bubbled events from children
1561
+ if ( event.target !== this.element ) {
1562
+ return;
1563
+ }
1564
+ var _transition = this._transn;
1565
+ // get property name of transitioned property, convert to prefix-free
1566
+ var propertyName = dashedVendorProperties[ event.propertyName ] || event.propertyName;
1567
+
1568
+ // remove property that has completed transitioning
1569
+ delete _transition.ingProperties[ propertyName ];
1570
+ // check if any properties are still transitioning
1571
+ if ( isEmptyObj( _transition.ingProperties ) ) {
1572
+ // all properties have completed transitioning
1573
+ this.disableTransition();
1574
+ }
1575
+ // clean style
1576
+ if ( propertyName in _transition.clean ) {
1577
+ // clean up style
1578
+ this.element.style[ event.propertyName ] = '';
1579
+ delete _transition.clean[ propertyName ];
1580
+ }
1581
+ // trigger onTransitionEnd callback
1582
+ if ( propertyName in _transition.onEnd ) {
1583
+ var onTransitionEnd = _transition.onEnd[ propertyName ];
1584
+ onTransitionEnd.call( this );
1585
+ delete _transition.onEnd[ propertyName ];
1586
+ }
1587
+
1588
+ this.emitEvent( 'transitionEnd', [ this ] );
1589
+ };
1590
+
1591
+ Item.prototype.disableTransition = function() {
1592
+ this.removeTransitionStyles();
1593
+ this.element.removeEventListener( transitionEndEvent, this, false );
1594
+ this.isTransitioning = false;
1595
+ };
1596
+
1597
+ /**
1598
+ * removes style property from element
1599
+ * @param {Object} style
1600
+ **/
1601
+ Item.prototype._removeStyles = function( style ) {
1602
+ // clean up transition styles
1603
+ var cleanStyle = {};
1604
+ for ( var prop in style ) {
1605
+ cleanStyle[ prop ] = '';
1606
+ }
1607
+ this.css( cleanStyle );
1608
+ };
1609
+
1610
+ var cleanTransitionStyle = {
1611
+ transitionProperty: '',
1612
+ transitionDuration: ''
1613
+ };
1614
+
1615
+ Item.prototype.removeTransitionStyles = function() {
1616
+ // remove transition
1617
+ this.css( cleanTransitionStyle );
1618
+ };
1619
+
1620
+ // ----- show/hide/remove ----- //
1621
+
1622
+ // remove element from DOM
1623
+ Item.prototype.removeElem = function() {
1624
+ this.element.parentNode.removeChild( this.element );
1625
+ this.emitEvent( 'remove', [ this ] );
1626
+ };
1627
+
1628
+ Item.prototype.remove = function() {
1629
+ // just remove element if no transition support or no transition
1630
+ if ( !transitionProperty || !parseFloat( this.layout.options.transitionDuration ) ) {
1631
+ this.removeElem();
1632
+ return;
1633
+ }
1634
+
1635
+ // start transition
1636
+ var _this = this;
1637
+ this.on( 'transitionEnd', function() {
1638
+ _this.removeElem();
1639
+ return true; // bind once
1640
+ });
1641
+ this.hide();
1642
+ };
1643
+
1644
+ Item.prototype.reveal = function() {
1645
+ delete this.isHidden;
1646
+ // remove display: none
1647
+ this.css({ display: '' });
1648
+
1649
+ var options = this.layout.options;
1650
+ this.transition({
1651
+ from: options.hiddenStyle,
1652
+ to: options.visibleStyle,
1653
+ isCleaning: true
1654
+ });
1655
+ };
1656
+
1657
+ Item.prototype.hide = function() {
1658
+ // set flag
1659
+ this.isHidden = true;
1660
+ // remove display: none
1661
+ this.css({ display: '' });
1662
+
1663
+ var options = this.layout.options;
1664
+ this.transition({
1665
+ from: options.visibleStyle,
1666
+ to: options.hiddenStyle,
1667
+ // keep hidden stuff hidden
1668
+ isCleaning: true,
1669
+ onTransitionEnd: {
1670
+ opacity: function() {
1671
+ // check if still hidden
1672
+ // during transition, item may have been un-hidden
1673
+ if ( this.isHidden ) {
1674
+ this.css({ display: 'none' });
1675
+ }
1676
+ }
1677
+ }
1678
+ });
1679
+ };
1680
+
1681
+ Item.prototype.destroy = function() {
1682
+ this.css({
1683
+ position: '',
1684
+ left: '',
1685
+ right: '',
1686
+ top: '',
1687
+ bottom: '',
1688
+ transition: '',
1689
+ transform: ''
1690
+ });
1691
+ };
1692
+
1693
+ return Item;
1694
+
1695
+ }
1696
+
1697
+ // -------------------------- transport -------------------------- //
1698
+
1699
+ if ( typeof define === 'function' && define.amd ) {
1700
+ // AMD
1701
+ define( 'outlayer/item',[
1702
+ 'eventEmitter/EventEmitter',
1703
+ 'get-size/get-size',
1704
+ 'get-style-property/get-style-property'
1705
+ ],
1706
+ outlayerItemDefinition );
1707
+ } else if (typeof exports === 'object') {
1708
+ // CommonJS
1709
+ module.exports = outlayerItemDefinition(
1710
+ require('wolfy87-eventemitter'),
1711
+ require('get-size'),
1712
+ require('desandro-get-style-property')
1713
+ );
1714
+ } else {
1715
+ // browser global
1716
+ window.Outlayer = {};
1717
+ window.Outlayer.Item = outlayerItemDefinition(
1718
+ window.EventEmitter,
1719
+ window.getSize,
1720
+ window.getStyleProperty
1721
+ );
1722
+ }
1723
+
1724
+ })( window );
1725
+
1726
+ /*!
1727
+ * Outlayer v1.3.0
1728
+ * the brains and guts of a layout library
1729
+ * MIT license
1730
+ */
1731
+
1732
+ ( function( window ) {
1733
+
1734
+
1735
+
1736
+ // ----- vars ----- //
1737
+
1738
+ var document = window.document;
1739
+ var console = window.console;
1740
+ var jQuery = window.jQuery;
1741
+ var noop = function() {};
1742
+
1743
+ // -------------------------- helpers -------------------------- //
1744
+
1745
+ // extend objects
1746
+ function extend( a, b ) {
1747
+ for ( var prop in b ) {
1748
+ a[ prop ] = b[ prop ];
1749
+ }
1750
+ return a;
1751
+ }
1752
+
1753
+
1754
+ var objToString = Object.prototype.toString;
1755
+ function isArray( obj ) {
1756
+ return objToString.call( obj ) === '[object Array]';
1757
+ }
1758
+
1759
+ // turn element or nodeList into an array
1760
+ function makeArray( obj ) {
1761
+ var ary = [];
1762
+ if ( isArray( obj ) ) {
1763
+ // use object if already an array
1764
+ ary = obj;
1765
+ } else if ( obj && typeof obj.length === 'number' ) {
1766
+ // convert nodeList to array
1767
+ for ( var i=0, len = obj.length; i < len; i++ ) {
1768
+ ary.push( obj[i] );
1769
+ }
1770
+ } else {
1771
+ // array of single index
1772
+ ary.push( obj );
1773
+ }
1774
+ return ary;
1775
+ }
1776
+
1777
+ // http://stackoverflow.com/a/384380/182183
1778
+ var isElement = ( typeof HTMLElement === 'function' || typeof HTMLElement === 'object' ) ?
1779
+ function isElementDOM2( obj ) {
1780
+ return obj instanceof HTMLElement;
1781
+ } :
1782
+ function isElementQuirky( obj ) {
1783
+ return obj && typeof obj === 'object' &&
1784
+ obj.nodeType === 1 && typeof obj.nodeName === 'string';
1785
+ };
1786
+
1787
+ // index of helper cause IE8
1788
+ var indexOf = Array.prototype.indexOf ? function( ary, obj ) {
1789
+ return ary.indexOf( obj );
1790
+ } : function( ary, obj ) {
1791
+ for ( var i=0, len = ary.length; i < len; i++ ) {
1792
+ if ( ary[i] === obj ) {
1793
+ return i;
1794
+ }
1795
+ }
1796
+ return -1;
1797
+ };
1798
+
1799
+ function removeFrom( obj, ary ) {
1800
+ var index = indexOf( ary, obj );
1801
+ if ( index !== -1 ) {
1802
+ ary.splice( index, 1 );
1803
+ }
1804
+ }
1805
+
1806
+ // http://jamesroberts.name/blog/2010/02/22/string-functions-for-javascript-trim-to-camel-case-to-dashed-and-to-underscore/
1807
+ function toDashed( str ) {
1808
+ return str.replace( /(.)([A-Z])/g, function( match, $1, $2 ) {
1809
+ return $1 + '-' + $2;
1810
+ }).toLowerCase();
1811
+ }
1812
+
1813
+
1814
+ function outlayerDefinition( eventie, docReady, EventEmitter, getSize, matchesSelector, Item ) {
1815
+
1816
+ // -------------------------- Outlayer -------------------------- //
1817
+
1818
+ // globally unique identifiers
1819
+ var GUID = 0;
1820
+ // internal store of all Outlayer intances
1821
+ var instances = {};
1822
+
1823
+
1824
+ /**
1825
+ * @param {Element, String} element
1826
+ * @param {Object} options
1827
+ * @constructor
1828
+ */
1829
+ function Outlayer( element, options ) {
1830
+ // use element as selector string
1831
+ if ( typeof element === 'string' ) {
1832
+ element = document.querySelector( element );
1833
+ }
1834
+
1835
+ // bail out if not proper element
1836
+ if ( !element || !isElement( element ) ) {
1837
+ if ( console ) {
1838
+ console.error( 'Bad ' + this.constructor.namespace + ' element: ' + element );
1839
+ }
1840
+ return;
1841
+ }
1842
+
1843
+ this.element = element;
1844
+
1845
+ // options
1846
+ this.options = extend( {}, this.constructor.defaults );
1847
+ this.option( options );
1848
+
1849
+ // add id for Outlayer.getFromElement
1850
+ var id = ++GUID;
1851
+ this.element.outlayerGUID = id; // expando
1852
+ instances[ id ] = this; // associate via id
1853
+
1854
+ // kick it off
1855
+ this._create();
1856
+
1857
+ if ( this.options.isInitLayout ) {
1858
+ this.layout();
1859
+ }
1860
+ }
1861
+
1862
+ // settings are for internal use only
1863
+ Outlayer.namespace = 'outlayer';
1864
+ Outlayer.Item = Item;
1865
+
1866
+ // default options
1867
+ Outlayer.defaults = {
1868
+ containerStyle: {
1869
+ position: 'relative'
1870
+ },
1871
+ isInitLayout: true,
1872
+ isOriginLeft: true,
1873
+ isOriginTop: true,
1874
+ isResizeBound: true,
1875
+ isResizingContainer: true,
1876
+ // item options
1877
+ transitionDuration: '0.4s',
1878
+ hiddenStyle: {
1879
+ opacity: 0,
1880
+ transform: 'scale(0.001)'
1881
+ },
1882
+ visibleStyle: {
1883
+ opacity: 1,
1884
+ transform: 'scale(1)'
1885
+ }
1886
+ };
1887
+
1888
+ // inherit EventEmitter
1889
+ extend( Outlayer.prototype, EventEmitter.prototype );
1890
+
1891
+ /**
1892
+ * set options
1893
+ * @param {Object} opts
1894
+ */
1895
+ Outlayer.prototype.option = function( opts ) {
1896
+ extend( this.options, opts );
1897
+ };
1898
+
1899
+ Outlayer.prototype._create = function() {
1900
+ // get items from children
1901
+ this.reloadItems();
1902
+ // elements that affect layout, but are not laid out
1903
+ this.stamps = [];
1904
+ this.stamp( this.options.stamp );
1905
+ // set container style
1906
+ extend( this.element.style, this.options.containerStyle );
1907
+
1908
+ // bind resize method
1909
+ if ( this.options.isResizeBound ) {
1910
+ this.bindResize();
1911
+ }
1912
+ };
1913
+
1914
+ // goes through all children again and gets bricks in proper order
1915
+ Outlayer.prototype.reloadItems = function() {
1916
+ // collection of item elements
1917
+ this.items = this._itemize( this.element.children );
1918
+ };
1919
+
1920
+
1921
+ /**
1922
+ * turn elements into Outlayer.Items to be used in layout
1923
+ * @param {Array or NodeList or HTMLElement} elems
1924
+ * @returns {Array} items - collection of new Outlayer Items
1925
+ */
1926
+ Outlayer.prototype._itemize = function( elems ) {
1927
+
1928
+ var itemElems = this._filterFindItemElements( elems );
1929
+ var Item = this.constructor.Item;
1930
+
1931
+ // create new Outlayer Items for collection
1932
+ var items = [];
1933
+ for ( var i=0, len = itemElems.length; i < len; i++ ) {
1934
+ var elem = itemElems[i];
1935
+ var item = new Item( elem, this );
1936
+ items.push( item );
1937
+ }
1938
+
1939
+ return items;
1940
+ };
1941
+
1942
+ /**
1943
+ * get item elements to be used in layout
1944
+ * @param {Array or NodeList or HTMLElement} elems
1945
+ * @returns {Array} items - item elements
1946
+ */
1947
+ Outlayer.prototype._filterFindItemElements = function( elems ) {
1948
+ // make array of elems
1949
+ elems = makeArray( elems );
1950
+ var itemSelector = this.options.itemSelector;
1951
+ var itemElems = [];
1952
+
1953
+ for ( var i=0, len = elems.length; i < len; i++ ) {
1954
+ var elem = elems[i];
1955
+ // check that elem is an actual element
1956
+ if ( !isElement( elem ) ) {
1957
+ continue;
1958
+ }
1959
+ // filter & find items if we have an item selector
1960
+ if ( itemSelector ) {
1961
+ // filter siblings
1962
+ if ( matchesSelector( elem, itemSelector ) ) {
1963
+ itemElems.push( elem );
1964
+ }
1965
+ // find children
1966
+ var childElems = elem.querySelectorAll( itemSelector );
1967
+ // concat childElems to filterFound array
1968
+ for ( var j=0, jLen = childElems.length; j < jLen; j++ ) {
1969
+ itemElems.push( childElems[j] );
1970
+ }
1971
+ } else {
1972
+ itemElems.push( elem );
1973
+ }
1974
+ }
1975
+
1976
+ return itemElems;
1977
+ };
1978
+
1979
+ /**
1980
+ * getter method for getting item elements
1981
+ * @returns {Array} elems - collection of item elements
1982
+ */
1983
+ Outlayer.prototype.getItemElements = function() {
1984
+ var elems = [];
1985
+ for ( var i=0, len = this.items.length; i < len; i++ ) {
1986
+ elems.push( this.items[i].element );
1987
+ }
1988
+ return elems;
1989
+ };
1990
+
1991
+ // ----- init & layout ----- //
1992
+
1993
+ /**
1994
+ * lays out all items
1995
+ */
1996
+ Outlayer.prototype.layout = function() {
1997
+ this._resetLayout();
1998
+ this._manageStamps();
1999
+
2000
+ // don't animate first layout
2001
+ var isInstant = this.options.isLayoutInstant !== undefined ?
2002
+ this.options.isLayoutInstant : !this._isLayoutInited;
2003
+ this.layoutItems( this.items, isInstant );
2004
+
2005
+ // flag for initalized
2006
+ this._isLayoutInited = true;
2007
+ };
2008
+
2009
+ // _init is alias for layout
2010
+ Outlayer.prototype._init = Outlayer.prototype.layout;
2011
+
2012
+ /**
2013
+ * logic before any new layout
2014
+ */
2015
+ Outlayer.prototype._resetLayout = function() {
2016
+ this.getSize();
2017
+ };
2018
+
2019
+
2020
+ Outlayer.prototype.getSize = function() {
2021
+ this.size = getSize( this.element );
2022
+ };
2023
+
2024
+ /**
2025
+ * get measurement from option, for columnWidth, rowHeight, gutter
2026
+ * if option is String -> get element from selector string, & get size of element
2027
+ * if option is Element -> get size of element
2028
+ * else use option as a number
2029
+ *
2030
+ * @param {String} measurement
2031
+ * @param {String} size - width or height
2032
+ * @private
2033
+ */
2034
+ Outlayer.prototype._getMeasurement = function( measurement, size ) {
2035
+ var option = this.options[ measurement ];
2036
+ var elem;
2037
+ if ( !option ) {
2038
+ // default to 0
2039
+ this[ measurement ] = 0;
2040
+ } else {
2041
+ // use option as an element
2042
+ if ( typeof option === 'string' ) {
2043
+ elem = this.element.querySelector( option );
2044
+ } else if ( isElement( option ) ) {
2045
+ elem = option;
2046
+ }
2047
+ // use size of element, if element
2048
+ this[ measurement ] = elem ? getSize( elem )[ size ] : option;
2049
+ }
2050
+ };
2051
+
2052
+ /**
2053
+ * layout a collection of item elements
2054
+ * @api public
2055
+ */
2056
+ Outlayer.prototype.layoutItems = function( items, isInstant ) {
2057
+ items = this._getItemsForLayout( items );
2058
+
2059
+ this._layoutItems( items, isInstant );
2060
+
2061
+ this._postLayout();
2062
+ };
2063
+
2064
+ /**
2065
+ * get the items to be laid out
2066
+ * you may want to skip over some items
2067
+ * @param {Array} items
2068
+ * @returns {Array} items
2069
+ */
2070
+ Outlayer.prototype._getItemsForLayout = function( items ) {
2071
+ var layoutItems = [];
2072
+ for ( var i=0, len = items.length; i < len; i++ ) {
2073
+ var item = items[i];
2074
+ if ( !item.isIgnored ) {
2075
+ layoutItems.push( item );
2076
+ }
2077
+ }
2078
+ return layoutItems;
2079
+ };
2080
+
2081
+ /**
2082
+ * layout items
2083
+ * @param {Array} items
2084
+ * @param {Boolean} isInstant
2085
+ */
2086
+ Outlayer.prototype._layoutItems = function( items, isInstant ) {
2087
+ var _this = this;
2088
+ function onItemsLayout() {
2089
+ _this.emitEvent( 'layoutComplete', [ _this, items ] );
2090
+ }
2091
+
2092
+ if ( !items || !items.length ) {
2093
+ // no items, emit event with empty array
2094
+ onItemsLayout();
2095
+ return;
2096
+ }
2097
+
2098
+ // emit layoutComplete when done
2099
+ this._itemsOn( items, 'layout', onItemsLayout );
2100
+
2101
+ var queue = [];
2102
+
2103
+ for ( var i=0, len = items.length; i < len; i++ ) {
2104
+ var item = items[i];
2105
+ // get x/y object from method
2106
+ var position = this._getItemLayoutPosition( item );
2107
+ // enqueue
2108
+ position.item = item;
2109
+ position.isInstant = isInstant || item.isLayoutInstant;
2110
+ queue.push( position );
2111
+ }
2112
+
2113
+ this._processLayoutQueue( queue );
2114
+ };
2115
+
2116
+ /**
2117
+ * get item layout position
2118
+ * @param {Outlayer.Item} item
2119
+ * @returns {Object} x and y position
2120
+ */
2121
+ Outlayer.prototype._getItemLayoutPosition = function( /* item */ ) {
2122
+ return {
2123
+ x: 0,
2124
+ y: 0
2125
+ };
2126
+ };
2127
+
2128
+ /**
2129
+ * iterate over array and position each item
2130
+ * Reason being - separating this logic prevents 'layout invalidation'
2131
+ * thx @paul_irish
2132
+ * @param {Array} queue
2133
+ */
2134
+ Outlayer.prototype._processLayoutQueue = function( queue ) {
2135
+ for ( var i=0, len = queue.length; i < len; i++ ) {
2136
+ var obj = queue[i];
2137
+ this._positionItem( obj.item, obj.x, obj.y, obj.isInstant );
2138
+ }
2139
+ };
2140
+
2141
+ /**
2142
+ * Sets position of item in DOM
2143
+ * @param {Outlayer.Item} item
2144
+ * @param {Number} x - horizontal position
2145
+ * @param {Number} y - vertical position
2146
+ * @param {Boolean} isInstant - disables transitions
2147
+ */
2148
+ Outlayer.prototype._positionItem = function( item, x, y, isInstant ) {
2149
+ if ( isInstant ) {
2150
+ // if not transition, just set CSS
2151
+ item.goTo( x, y );
2152
+ } else {
2153
+ item.moveTo( x, y );
2154
+ }
2155
+ };
2156
+
2157
+ /**
2158
+ * Any logic you want to do after each layout,
2159
+ * i.e. size the container
2160
+ */
2161
+ Outlayer.prototype._postLayout = function() {
2162
+ this.resizeContainer();
2163
+ };
2164
+
2165
+ Outlayer.prototype.resizeContainer = function() {
2166
+ if ( !this.options.isResizingContainer ) {
2167
+ return;
2168
+ }
2169
+ var size = this._getContainerSize();
2170
+ if ( size ) {
2171
+ this._setContainerMeasure( size.width, true );
2172
+ this._setContainerMeasure( size.height, false );
2173
+ }
2174
+ };
2175
+
2176
+ /**
2177
+ * Sets width or height of container if returned
2178
+ * @returns {Object} size
2179
+ * @param {Number} width
2180
+ * @param {Number} height
2181
+ */
2182
+ Outlayer.prototype._getContainerSize = noop;
2183
+
2184
+ /**
2185
+ * @param {Number} measure - size of width or height
2186
+ * @param {Boolean} isWidth
2187
+ */
2188
+ Outlayer.prototype._setContainerMeasure = function( measure, isWidth ) {
2189
+ if ( measure === undefined ) {
2190
+ return;
2191
+ }
2192
+
2193
+ var elemSize = this.size;
2194
+ // add padding and border width if border box
2195
+ if ( elemSize.isBorderBox ) {
2196
+ measure += isWidth ? elemSize.paddingLeft + elemSize.paddingRight +
2197
+ elemSize.borderLeftWidth + elemSize.borderRightWidth :
2198
+ elemSize.paddingBottom + elemSize.paddingTop +
2199
+ elemSize.borderTopWidth + elemSize.borderBottomWidth;
2200
+ }
2201
+
2202
+ measure = Math.max( measure, 0 );
2203
+ this.element.style[ isWidth ? 'width' : 'height' ] = measure + 'px';
2204
+ };
2205
+
2206
+ /**
2207
+ * trigger a callback for a collection of items events
2208
+ * @param {Array} items - Outlayer.Items
2209
+ * @param {String} eventName
2210
+ * @param {Function} callback
2211
+ */
2212
+ Outlayer.prototype._itemsOn = function( items, eventName, callback ) {
2213
+ var doneCount = 0;
2214
+ var count = items.length;
2215
+ // event callback
2216
+ var _this = this;
2217
+ function tick() {
2218
+ doneCount++;
2219
+ if ( doneCount === count ) {
2220
+ callback.call( _this );
2221
+ }
2222
+ return true; // bind once
2223
+ }
2224
+ // bind callback
2225
+ for ( var i=0, len = items.length; i < len; i++ ) {
2226
+ var item = items[i];
2227
+ item.on( eventName, tick );
2228
+ }
2229
+ };
2230
+
2231
+ // -------------------------- ignore & stamps -------------------------- //
2232
+
2233
+
2234
+ /**
2235
+ * keep item in collection, but do not lay it out
2236
+ * ignored items do not get skipped in layout
2237
+ * @param {Element} elem
2238
+ */
2239
+ Outlayer.prototype.ignore = function( elem ) {
2240
+ var item = this.getItem( elem );
2241
+ if ( item ) {
2242
+ item.isIgnored = true;
2243
+ }
2244
+ };
2245
+
2246
+ /**
2247
+ * return item to layout collection
2248
+ * @param {Element} elem
2249
+ */
2250
+ Outlayer.prototype.unignore = function( elem ) {
2251
+ var item = this.getItem( elem );
2252
+ if ( item ) {
2253
+ delete item.isIgnored;
2254
+ }
2255
+ };
2256
+
2257
+ /**
2258
+ * adds elements to stamps
2259
+ * @param {NodeList, Array, Element, or String} elems
2260
+ */
2261
+ Outlayer.prototype.stamp = function( elems ) {
2262
+ elems = this._find( elems );
2263
+ if ( !elems ) {
2264
+ return;
2265
+ }
2266
+
2267
+ this.stamps = this.stamps.concat( elems );
2268
+ // ignore
2269
+ for ( var i=0, len = elems.length; i < len; i++ ) {
2270
+ var elem = elems[i];
2271
+ this.ignore( elem );
2272
+ }
2273
+ };
2274
+
2275
+ /**
2276
+ * removes elements to stamps
2277
+ * @param {NodeList, Array, or Element} elems
2278
+ */
2279
+ Outlayer.prototype.unstamp = function( elems ) {
2280
+ elems = this._find( elems );
2281
+ if ( !elems ){
2282
+ return;
2283
+ }
2284
+
2285
+ for ( var i=0, len = elems.length; i < len; i++ ) {
2286
+ var elem = elems[i];
2287
+ // filter out removed stamp elements
2288
+ removeFrom( elem, this.stamps );
2289
+ this.unignore( elem );
2290
+ }
2291
+
2292
+ };
2293
+
2294
+ /**
2295
+ * finds child elements
2296
+ * @param {NodeList, Array, Element, or String} elems
2297
+ * @returns {Array} elems
2298
+ */
2299
+ Outlayer.prototype._find = function( elems ) {
2300
+ if ( !elems ) {
2301
+ return;
2302
+ }
2303
+ // if string, use argument as selector string
2304
+ if ( typeof elems === 'string' ) {
2305
+ elems = this.element.querySelectorAll( elems );
2306
+ }
2307
+ elems = makeArray( elems );
2308
+ return elems;
2309
+ };
2310
+
2311
+ Outlayer.prototype._manageStamps = function() {
2312
+ if ( !this.stamps || !this.stamps.length ) {
2313
+ return;
2314
+ }
2315
+
2316
+ this._getBoundingRect();
2317
+
2318
+ for ( var i=0, len = this.stamps.length; i < len; i++ ) {
2319
+ var stamp = this.stamps[i];
2320
+ this._manageStamp( stamp );
2321
+ }
2322
+ };
2323
+
2324
+ // update boundingLeft / Top
2325
+ Outlayer.prototype._getBoundingRect = function() {
2326
+ // get bounding rect for container element
2327
+ var boundingRect = this.element.getBoundingClientRect();
2328
+ var size = this.size;
2329
+ this._boundingRect = {
2330
+ left: boundingRect.left + size.paddingLeft + size.borderLeftWidth,
2331
+ top: boundingRect.top + size.paddingTop + size.borderTopWidth,
2332
+ right: boundingRect.right - ( size.paddingRight + size.borderRightWidth ),
2333
+ bottom: boundingRect.bottom - ( size.paddingBottom + size.borderBottomWidth )
2334
+ };
2335
+ };
2336
+
2337
+ /**
2338
+ * @param {Element} stamp
2339
+ **/
2340
+ Outlayer.prototype._manageStamp = noop;
2341
+
2342
+ /**
2343
+ * get x/y position of element relative to container element
2344
+ * @param {Element} elem
2345
+ * @returns {Object} offset - has left, top, right, bottom
2346
+ */
2347
+ Outlayer.prototype._getElementOffset = function( elem ) {
2348
+ var boundingRect = elem.getBoundingClientRect();
2349
+ var thisRect = this._boundingRect;
2350
+ var size = getSize( elem );
2351
+ var offset = {
2352
+ left: boundingRect.left - thisRect.left - size.marginLeft,
2353
+ top: boundingRect.top - thisRect.top - size.marginTop,
2354
+ right: thisRect.right - boundingRect.right - size.marginRight,
2355
+ bottom: thisRect.bottom - boundingRect.bottom - size.marginBottom
2356
+ };
2357
+ return offset;
2358
+ };
2359
+
2360
+ // -------------------------- resize -------------------------- //
2361
+
2362
+ // enable event handlers for listeners
2363
+ // i.e. resize -> onresize
2364
+ Outlayer.prototype.handleEvent = function( event ) {
2365
+ var method = 'on' + event.type;
2366
+ if ( this[ method ] ) {
2367
+ this[ method ]( event );
2368
+ }
2369
+ };
2370
+
2371
+ /**
2372
+ * Bind layout to window resizing
2373
+ */
2374
+ Outlayer.prototype.bindResize = function() {
2375
+ // bind just one listener
2376
+ if ( this.isResizeBound ) {
2377
+ return;
2378
+ }
2379
+ eventie.bind( window, 'resize', this );
2380
+ this.isResizeBound = true;
2381
+ };
2382
+
2383
+ /**
2384
+ * Unbind layout to window resizing
2385
+ */
2386
+ Outlayer.prototype.unbindResize = function() {
2387
+ if ( this.isResizeBound ) {
2388
+ eventie.unbind( window, 'resize', this );
2389
+ }
2390
+ this.isResizeBound = false;
2391
+ };
2392
+
2393
+ // original debounce by John Hann
2394
+ // http://unscriptable.com/index.php/2009/03/20/debouncing-javascript-methods/
2395
+
2396
+ // this fires every resize
2397
+ Outlayer.prototype.onresize = function() {
2398
+ if ( this.resizeTimeout ) {
2399
+ clearTimeout( this.resizeTimeout );
2400
+ }
2401
+
2402
+ var _this = this;
2403
+ function delayed() {
2404
+ _this.resize();
2405
+ delete _this.resizeTimeout;
2406
+ }
2407
+
2408
+ this.resizeTimeout = setTimeout( delayed, 100 );
2409
+ };
2410
+
2411
+ // debounced, layout on resize
2412
+ Outlayer.prototype.resize = function() {
2413
+ // don't trigger if size did not change
2414
+ // or if resize was unbound. See #9
2415
+ if ( !this.isResizeBound || !this.needsResizeLayout() ) {
2416
+ return;
2417
+ }
2418
+
2419
+ this.layout();
2420
+ };
2421
+
2422
+ /**
2423
+ * check if layout is needed post layout
2424
+ * @returns Boolean
2425
+ */
2426
+ Outlayer.prototype.needsResizeLayout = function() {
2427
+ var size = getSize( this.element );
2428
+ // check that this.size and size are there
2429
+ // IE8 triggers resize on body size change, so they might not be
2430
+ var hasSizes = this.size && size;
2431
+ return hasSizes && size.innerWidth !== this.size.innerWidth;
2432
+ };
2433
+
2434
+ // -------------------------- methods -------------------------- //
2435
+
2436
+ /**
2437
+ * add items to Outlayer instance
2438
+ * @param {Array or NodeList or Element} elems
2439
+ * @returns {Array} items - Outlayer.Items
2440
+ **/
2441
+ Outlayer.prototype.addItems = function( elems ) {
2442
+ var items = this._itemize( elems );
2443
+ // add items to collection
2444
+ if ( items.length ) {
2445
+ this.items = this.items.concat( items );
2446
+ }
2447
+ return items;
2448
+ };
2449
+
2450
+ /**
2451
+ * Layout newly-appended item elements
2452
+ * @param {Array or NodeList or Element} elems
2453
+ */
2454
+ Outlayer.prototype.appended = function( elems ) {
2455
+ var items = this.addItems( elems );
2456
+ if ( !items.length ) {
2457
+ return;
2458
+ }
2459
+ // layout and reveal just the new items
2460
+ this.layoutItems( items, true );
2461
+ this.reveal( items );
2462
+ };
2463
+
2464
+ /**
2465
+ * Layout prepended elements
2466
+ * @param {Array or NodeList or Element} elems
2467
+ */
2468
+ Outlayer.prototype.prepended = function( elems ) {
2469
+ var items = this._itemize( elems );
2470
+ if ( !items.length ) {
2471
+ return;
2472
+ }
2473
+ // add items to beginning of collection
2474
+ var previousItems = this.items.slice(0);
2475
+ this.items = items.concat( previousItems );
2476
+ // start new layout
2477
+ this._resetLayout();
2478
+ this._manageStamps();
2479
+ // layout new stuff without transition
2480
+ this.layoutItems( items, true );
2481
+ this.reveal( items );
2482
+ // layout previous items
2483
+ this.layoutItems( previousItems );
2484
+ };
2485
+
2486
+ /**
2487
+ * reveal a collection of items
2488
+ * @param {Array of Outlayer.Items} items
2489
+ */
2490
+ Outlayer.prototype.reveal = function( items ) {
2491
+ var len = items && items.length;
2492
+ if ( !len ) {
2493
+ return;
2494
+ }
2495
+ for ( var i=0; i < len; i++ ) {
2496
+ var item = items[i];
2497
+ item.reveal();
2498
+ }
2499
+ };
2500
+
2501
+ /**
2502
+ * hide a collection of items
2503
+ * @param {Array of Outlayer.Items} items
2504
+ */
2505
+ Outlayer.prototype.hide = function( items ) {
2506
+ var len = items && items.length;
2507
+ if ( !len ) {
2508
+ return;
2509
+ }
2510
+ for ( var i=0; i < len; i++ ) {
2511
+ var item = items[i];
2512
+ item.hide();
2513
+ }
2514
+ };
2515
+
2516
+ /**
2517
+ * get Outlayer.Item, given an Element
2518
+ * @param {Element} elem
2519
+ * @param {Function} callback
2520
+ * @returns {Outlayer.Item} item
2521
+ */
2522
+ Outlayer.prototype.getItem = function( elem ) {
2523
+ // loop through items to get the one that matches
2524
+ for ( var i=0, len = this.items.length; i < len; i++ ) {
2525
+ var item = this.items[i];
2526
+ if ( item.element === elem ) {
2527
+ // return item
2528
+ return item;
2529
+ }
2530
+ }
2531
+ };
2532
+
2533
+ /**
2534
+ * get collection of Outlayer.Items, given Elements
2535
+ * @param {Array} elems
2536
+ * @returns {Array} items - Outlayer.Items
2537
+ */
2538
+ Outlayer.prototype.getItems = function( elems ) {
2539
+ if ( !elems || !elems.length ) {
2540
+ return;
2541
+ }
2542
+ var items = [];
2543
+ for ( var i=0, len = elems.length; i < len; i++ ) {
2544
+ var elem = elems[i];
2545
+ var item = this.getItem( elem );
2546
+ if ( item ) {
2547
+ items.push( item );
2548
+ }
2549
+ }
2550
+
2551
+ return items;
2552
+ };
2553
+
2554
+ /**
2555
+ * remove element(s) from instance and DOM
2556
+ * @param {Array or NodeList or Element} elems
2557
+ */
2558
+ Outlayer.prototype.remove = function( elems ) {
2559
+ elems = makeArray( elems );
2560
+
2561
+ var removeItems = this.getItems( elems );
2562
+ // bail if no items to remove
2563
+ if ( !removeItems || !removeItems.length ) {
2564
+ return;
2565
+ }
2566
+
2567
+ this._itemsOn( removeItems, 'remove', function() {
2568
+ this.emitEvent( 'removeComplete', [ this, removeItems ] );
2569
+ });
2570
+
2571
+ for ( var i=0, len = removeItems.length; i < len; i++ ) {
2572
+ var item = removeItems[i];
2573
+ item.remove();
2574
+ // remove item from collection
2575
+ removeFrom( item, this.items );
2576
+ }
2577
+ };
2578
+
2579
+ // ----- destroy ----- //
2580
+
2581
+ // remove and disable Outlayer instance
2582
+ Outlayer.prototype.destroy = function() {
2583
+ // clean up dynamic styles
2584
+ var style = this.element.style;
2585
+ style.height = '';
2586
+ style.position = '';
2587
+ style.width = '';
2588
+ // destroy items
2589
+ for ( var i=0, len = this.items.length; i < len; i++ ) {
2590
+ var item = this.items[i];
2591
+ item.destroy();
2592
+ }
2593
+
2594
+ this.unbindResize();
2595
+
2596
+ var id = this.element.outlayerGUID;
2597
+ delete instances[ id ]; // remove reference to instance by id
2598
+ delete this.element.outlayerGUID;
2599
+ // remove data for jQuery
2600
+ if ( jQuery ) {
2601
+ jQuery.removeData( this.element, this.constructor.namespace );
2602
+ }
2603
+
2604
+ };
2605
+
2606
+ // -------------------------- data -------------------------- //
2607
+
2608
+ /**
2609
+ * get Outlayer instance from element
2610
+ * @param {Element} elem
2611
+ * @returns {Outlayer}
2612
+ */
2613
+ Outlayer.data = function( elem ) {
2614
+ var id = elem && elem.outlayerGUID;
2615
+ return id && instances[ id ];
2616
+ };
2617
+
2618
+
2619
+ // -------------------------- create Outlayer class -------------------------- //
2620
+
2621
+ /**
2622
+ * create a layout class
2623
+ * @param {String} namespace
2624
+ */
2625
+ Outlayer.create = function( namespace, options ) {
2626
+ // sub-class Outlayer
2627
+ function Layout() {
2628
+ Outlayer.apply( this, arguments );
2629
+ }
2630
+ // inherit Outlayer prototype, use Object.create if there
2631
+ if ( Object.create ) {
2632
+ Layout.prototype = Object.create( Outlayer.prototype );
2633
+ } else {
2634
+ extend( Layout.prototype, Outlayer.prototype );
2635
+ }
2636
+ // set contructor, used for namespace and Item
2637
+ Layout.prototype.constructor = Layout;
2638
+
2639
+ Layout.defaults = extend( {}, Outlayer.defaults );
2640
+ // apply new options
2641
+ extend( Layout.defaults, options );
2642
+ // keep prototype.settings for backwards compatibility (Packery v1.2.0)
2643
+ Layout.prototype.settings = {};
2644
+
2645
+ Layout.namespace = namespace;
2646
+
2647
+ Layout.data = Outlayer.data;
2648
+
2649
+ // sub-class Item
2650
+ Layout.Item = function LayoutItem() {
2651
+ Item.apply( this, arguments );
2652
+ };
2653
+
2654
+ Layout.Item.prototype = new Item();
2655
+
2656
+ // -------------------------- declarative -------------------------- //
2657
+
2658
+ /**
2659
+ * allow user to initialize Outlayer via .js-namespace class
2660
+ * options are parsed from data-namespace-option attribute
2661
+ */
2662
+ docReady( function() {
2663
+ var dashedNamespace = toDashed( namespace );
2664
+ var elems = document.querySelectorAll( '.js-' + dashedNamespace );
2665
+ var dataAttr = 'data-' + dashedNamespace + '-options';
2666
+
2667
+ for ( var i=0, len = elems.length; i < len; i++ ) {
2668
+ var elem = elems[i];
2669
+ var attr = elem.getAttribute( dataAttr );
2670
+ var options;
2671
+ try {
2672
+ options = attr && JSON.parse( attr );
2673
+ } catch ( error ) {
2674
+ // log error, do not initialize
2675
+ if ( console ) {
2676
+ console.error( 'Error parsing ' + dataAttr + ' on ' +
2677
+ elem.nodeName.toLowerCase() + ( elem.id ? '#' + elem.id : '' ) + ': ' +
2678
+ error );
2679
+ }
2680
+ continue;
2681
+ }
2682
+ // initialize
2683
+ var instance = new Layout( elem, options );
2684
+ // make available via $().data('layoutname')
2685
+ if ( jQuery ) {
2686
+ jQuery.data( elem, namespace, instance );
2687
+ }
2688
+ }
2689
+ });
2690
+
2691
+ // -------------------------- jQuery bridge -------------------------- //
2692
+
2693
+ // make into jQuery plugin
2694
+ if ( jQuery && jQuery.bridget ) {
2695
+ jQuery.bridget( namespace, Layout );
2696
+ }
2697
+
2698
+ return Layout;
2699
+ };
2700
+
2701
+ // ----- fin ----- //
2702
+
2703
+ // back in global
2704
+ Outlayer.Item = Item;
2705
+
2706
+ return Outlayer;
2707
+
2708
+ }
2709
+
2710
+ // -------------------------- transport -------------------------- //
2711
+
2712
+ if ( typeof define === 'function' && define.amd ) {
2713
+ // AMD
2714
+ define( 'outlayer/outlayer',[
2715
+ 'eventie/eventie',
2716
+ 'doc-ready/doc-ready',
2717
+ 'eventEmitter/EventEmitter',
2718
+ 'get-size/get-size',
2719
+ 'matches-selector/matches-selector',
2720
+ './item'
2721
+ ],
2722
+ outlayerDefinition );
2723
+ } else if ( typeof exports === 'object' ) {
2724
+ // CommonJS
2725
+ module.exports = outlayerDefinition(
2726
+ require('eventie'),
2727
+ require('doc-ready'),
2728
+ require('wolfy87-eventemitter'),
2729
+ require('get-size'),
2730
+ require('desandro-matches-selector'),
2731
+ require('./item')
2732
+ );
2733
+ } else {
2734
+ // browser global
2735
+ window.Outlayer = outlayerDefinition(
2736
+ window.eventie,
2737
+ window.docReady,
2738
+ window.EventEmitter,
2739
+ window.getSize,
2740
+ window.matchesSelector,
2741
+ window.Outlayer.Item
2742
+ );
2743
+ }
2744
+
2745
+ })( window );
2746
+
2747
+ /**
2748
+ * Isotope Item
2749
+ **/
2750
+
2751
+ ( function( window ) {
2752
+
2753
+
2754
+
2755
+ // -------------------------- Item -------------------------- //
2756
+
2757
+ function itemDefinition( Outlayer ) {
2758
+
2759
+ // sub-class Outlayer Item
2760
+ function Item() {
2761
+ Outlayer.Item.apply( this, arguments );
2762
+ }
2763
+
2764
+ Item.prototype = new Outlayer.Item();
2765
+
2766
+ Item.prototype._create = function() {
2767
+ // assign id, used for original-order sorting
2768
+ this.id = this.layout.itemGUID++;
2769
+ Outlayer.Item.prototype._create.call( this );
2770
+ this.sortData = {};
2771
+ };
2772
+
2773
+ Item.prototype.updateSortData = function() {
2774
+ if ( this.isIgnored ) {
2775
+ return;
2776
+ }
2777
+ // default sorters
2778
+ this.sortData.id = this.id;
2779
+ // for backward compatibility
2780
+ this.sortData['original-order'] = this.id;
2781
+ this.sortData.random = Math.random();
2782
+ // go thru getSortData obj and apply the sorters
2783
+ var getSortData = this.layout.options.getSortData;
2784
+ var sorters = this.layout._sorters;
2785
+ for ( var key in getSortData ) {
2786
+ var sorter = sorters[ key ];
2787
+ this.sortData[ key ] = sorter( this.element, this );
2788
+ }
2789
+ };
2790
+
2791
+ var _destroy = Item.prototype.destroy;
2792
+ Item.prototype.destroy = function() {
2793
+ // call super
2794
+ _destroy.apply( this, arguments );
2795
+ // reset display, #741
2796
+ this.css({
2797
+ display: ''
2798
+ });
2799
+ };
2800
+
2801
+ return Item;
2802
+
2803
+ }
2804
+
2805
+ // -------------------------- transport -------------------------- //
2806
+
2807
+ if ( typeof define === 'function' && define.amd ) {
2808
+ // AMD
2809
+ define( 'isotope/js/item',[
2810
+ 'outlayer/outlayer'
2811
+ ],
2812
+ itemDefinition );
2813
+ } else if ( typeof exports === 'object' ) {
2814
+ // CommonJS
2815
+ module.exports = itemDefinition(
2816
+ require('outlayer')
2817
+ );
2818
+ } else {
2819
+ // browser global
2820
+ window.Isotope = window.Isotope || {};
2821
+ window.Isotope.Item = itemDefinition(
2822
+ window.Outlayer
2823
+ );
2824
+ }
2825
+
2826
+ })( window );
2827
+
2828
+ ( function( window ) {
2829
+
2830
+
2831
+
2832
+ // -------------------------- -------------------------- //
2833
+
2834
+ function layoutModeDefinition( getSize, Outlayer ) {
2835
+
2836
+ // layout mode class
2837
+ function LayoutMode( isotope ) {
2838
+ this.isotope = isotope;
2839
+ // link properties
2840
+ if ( isotope ) {
2841
+ this.options = isotope.options[ this.namespace ];
2842
+ this.element = isotope.element;
2843
+ this.items = isotope.filteredItems;
2844
+ this.size = isotope.size;
2845
+ }
2846
+ }
2847
+
2848
+ /**
2849
+ * some methods should just defer to default Outlayer method
2850
+ * and reference the Isotope instance as `this`
2851
+ **/
2852
+ ( function() {
2853
+ var facadeMethods = [
2854
+ '_resetLayout',
2855
+ '_getItemLayoutPosition',
2856
+ '_manageStamp',
2857
+ '_getContainerSize',
2858
+ '_getElementOffset',
2859
+ 'needsResizeLayout'
2860
+ ];
2861
+
2862
+ for ( var i=0, len = facadeMethods.length; i < len; i++ ) {
2863
+ var methodName = facadeMethods[i];
2864
+ LayoutMode.prototype[ methodName ] = getOutlayerMethod( methodName );
2865
+ }
2866
+
2867
+ function getOutlayerMethod( methodName ) {
2868
+ return function() {
2869
+ return Outlayer.prototype[ methodName ].apply( this.isotope, arguments );
2870
+ };
2871
+ }
2872
+ })();
2873
+
2874
+ // ----- ----- //
2875
+
2876
+ // for horizontal layout modes, check vertical size
2877
+ LayoutMode.prototype.needsVerticalResizeLayout = function() {
2878
+ // don't trigger if size did not change
2879
+ var size = getSize( this.isotope.element );
2880
+ // check that this.size and size are there
2881
+ // IE8 triggers resize on body size change, so they might not be
2882
+ var hasSizes = this.isotope.size && size;
2883
+ return hasSizes && size.innerHeight !== this.isotope.size.innerHeight;
2884
+ };
2885
+
2886
+ // ----- measurements ----- //
2887
+
2888
+ LayoutMode.prototype._getMeasurement = function() {
2889
+ this.isotope._getMeasurement.apply( this, arguments );
2890
+ };
2891
+
2892
+ LayoutMode.prototype.getColumnWidth = function() {
2893
+ this.getSegmentSize( 'column', 'Width' );
2894
+ };
2895
+
2896
+ LayoutMode.prototype.getRowHeight = function() {
2897
+ this.getSegmentSize( 'row', 'Height' );
2898
+ };
2899
+
2900
+ /**
2901
+ * get columnWidth or rowHeight
2902
+ * segment: 'column' or 'row'
2903
+ * size 'Width' or 'Height'
2904
+ **/
2905
+ LayoutMode.prototype.getSegmentSize = function( segment, size ) {
2906
+ var segmentName = segment + size;
2907
+ var outerSize = 'outer' + size;
2908
+ // columnWidth / outerWidth // rowHeight / outerHeight
2909
+ this._getMeasurement( segmentName, outerSize );
2910
+ // got rowHeight or columnWidth, we can chill
2911
+ if ( this[ segmentName ] ) {
2912
+ return;
2913
+ }
2914
+ // fall back to item of first element
2915
+ var firstItemSize = this.getFirstItemSize();
2916
+ this[ segmentName ] = firstItemSize && firstItemSize[ outerSize ] ||
2917
+ // or size of container
2918
+ this.isotope.size[ 'inner' + size ];
2919
+ };
2920
+
2921
+ LayoutMode.prototype.getFirstItemSize = function() {
2922
+ var firstItem = this.isotope.filteredItems[0];
2923
+ return firstItem && firstItem.element && getSize( firstItem.element );
2924
+ };
2925
+
2926
+ // ----- methods that should reference isotope ----- //
2927
+
2928
+ LayoutMode.prototype.layout = function() {
2929
+ this.isotope.layout.apply( this.isotope, arguments );
2930
+ };
2931
+
2932
+ LayoutMode.prototype.getSize = function() {
2933
+ this.isotope.getSize();
2934
+ this.size = this.isotope.size;
2935
+ };
2936
+
2937
+ // -------------------------- create -------------------------- //
2938
+
2939
+ LayoutMode.modes = {};
2940
+
2941
+ LayoutMode.create = function( namespace, options ) {
2942
+
2943
+ function Mode() {
2944
+ LayoutMode.apply( this, arguments );
2945
+ }
2946
+
2947
+ Mode.prototype = new LayoutMode();
2948
+
2949
+ // default options
2950
+ if ( options ) {
2951
+ Mode.options = options;
2952
+ }
2953
+
2954
+ Mode.prototype.namespace = namespace;
2955
+ // register in Isotope
2956
+ LayoutMode.modes[ namespace ] = Mode;
2957
+
2958
+ return Mode;
2959
+ };
2960
+
2961
+
2962
+ return LayoutMode;
2963
+
2964
+ }
2965
+
2966
+ if ( typeof define === 'function' && define.amd ) {
2967
+ // AMD
2968
+ define( 'isotope/js/layout-mode',[
2969
+ 'get-size/get-size',
2970
+ 'outlayer/outlayer'
2971
+ ],
2972
+ layoutModeDefinition );
2973
+ } else if ( typeof exports === 'object' ) {
2974
+ // CommonJS
2975
+ module.exports = layoutModeDefinition(
2976
+ require('get-size'),
2977
+ require('outlayer')
2978
+ );
2979
+ } else {
2980
+ // browser global
2981
+ window.Isotope = window.Isotope || {};
2982
+ window.Isotope.LayoutMode = layoutModeDefinition(
2983
+ window.getSize,
2984
+ window.Outlayer
2985
+ );
2986
+ }
2987
+
2988
+
2989
+ })( window );
2990
+
2991
+ /*!
2992
+ * Masonry v3.2.1
2993
+ * Cascading grid layout library
2994
+ * http://masonry.desandro.com
2995
+ * MIT License
2996
+ * by David DeSandro
2997
+ */
2998
+
2999
+ ( function( window ) {
3000
+
3001
+
3002
+
3003
+ // -------------------------- helpers -------------------------- //
3004
+
3005
+ var indexOf = Array.prototype.indexOf ?
3006
+ function( items, value ) {
3007
+ return items.indexOf( value );
3008
+ } :
3009
+ function ( items, value ) {
3010
+ for ( var i=0, len = items.length; i < len; i++ ) {
3011
+ var item = items[i];
3012
+ if ( item === value ) {
3013
+ return i;
3014
+ }
3015
+ }
3016
+ return -1;
3017
+ };
3018
+
3019
+ // -------------------------- masonryDefinition -------------------------- //
3020
+
3021
+ // used for AMD definition and requires
3022
+ function masonryDefinition( Outlayer, getSize ) {
3023
+ // create an Outlayer layout class
3024
+ var Masonry = Outlayer.create('masonry');
3025
+
3026
+ Masonry.prototype._resetLayout = function() {
3027
+ this.getSize();
3028
+ this._getMeasurement( 'columnWidth', 'outerWidth' );
3029
+ this._getMeasurement( 'gutter', 'outerWidth' );
3030
+ this.measureColumns();
3031
+
3032
+ // reset column Y
3033
+ var i = this.cols;
3034
+ this.colYs = [];
3035
+ while (i--) {
3036
+ this.colYs.push( 0 );
3037
+ }
3038
+
3039
+ this.maxY = 0;
3040
+ };
3041
+
3042
+ Masonry.prototype.measureColumns = function() {
3043
+ this.getContainerWidth();
3044
+ // if columnWidth is 0, default to outerWidth of first item
3045
+ if ( !this.columnWidth ) {
3046
+ var firstItem = this.items[0];
3047
+ var firstItemElem = firstItem && firstItem.element;
3048
+ // columnWidth fall back to item of first element
3049
+ this.columnWidth = firstItemElem && getSize( firstItemElem ).outerWidth ||
3050
+ // if first elem has no width, default to size of container
3051
+ this.containerWidth;
3052
+ }
3053
+
3054
+ this.columnWidth += this.gutter;
3055
+
3056
+ this.cols = Math.floor( ( this.containerWidth + this.gutter ) / this.columnWidth );
3057
+ this.cols = Math.max( this.cols, 1 );
3058
+ };
3059
+
3060
+ Masonry.prototype.getContainerWidth = function() {
3061
+ // container is parent if fit width
3062
+ var container = this.options.isFitWidth ? this.element.parentNode : this.element;
3063
+ // check that this.size and size are there
3064
+ // IE8 triggers resize on body size change, so they might not be
3065
+ var size = getSize( container );
3066
+ this.containerWidth = size && size.innerWidth;
3067
+ };
3068
+
3069
+ Masonry.prototype._getItemLayoutPosition = function( item ) {
3070
+ item.getSize();
3071
+ // how many columns does this brick span
3072
+ var remainder = item.size.outerWidth % this.columnWidth;
3073
+ var mathMethod = remainder && remainder < 1 ? 'round' : 'ceil';
3074
+ // round if off by 1 pixel, otherwise use ceil
3075
+ var colSpan = Math[ mathMethod ]( item.size.outerWidth / this.columnWidth );
3076
+ colSpan = Math.min( colSpan, this.cols );
3077
+
3078
+ var colGroup = this._getColGroup( colSpan );
3079
+ // get the minimum Y value from the columns
3080
+ var minimumY = Math.min.apply( Math, colGroup );
3081
+ var shortColIndex = indexOf( colGroup, minimumY );
3082
+
3083
+ // position the brick
3084
+ var position = {
3085
+ x: this.columnWidth * shortColIndex,
3086
+ y: minimumY
3087
+ };
3088
+
3089
+ // apply setHeight to necessary columns
3090
+ var setHeight = minimumY + item.size.outerHeight;
3091
+ var setSpan = this.cols + 1 - colGroup.length;
3092
+ for ( var i = 0; i < setSpan; i++ ) {
3093
+ this.colYs[ shortColIndex + i ] = setHeight;
3094
+ }
3095
+
3096
+ return position;
3097
+ };
3098
+
3099
+ /**
3100
+ * @param {Number} colSpan - number of columns the element spans
3101
+ * @returns {Array} colGroup
3102
+ */
3103
+ Masonry.prototype._getColGroup = function( colSpan ) {
3104
+ if ( colSpan < 2 ) {
3105
+ // if brick spans only one column, use all the column Ys
3106
+ return this.colYs;
3107
+ }
3108
+
3109
+ var colGroup = [];
3110
+ // how many different places could this brick fit horizontally
3111
+ var groupCount = this.cols + 1 - colSpan;
3112
+ // for each group potential horizontal position
3113
+ for ( var i = 0; i < groupCount; i++ ) {
3114
+ // make an array of colY values for that one group
3115
+ var groupColYs = this.colYs.slice( i, i + colSpan );
3116
+ // and get the max value of the array
3117
+ colGroup[i] = Math.max.apply( Math, groupColYs );
3118
+ }
3119
+ return colGroup;
3120
+ };
3121
+
3122
+ Masonry.prototype._manageStamp = function( stamp ) {
3123
+ var stampSize = getSize( stamp );
3124
+ var offset = this._getElementOffset( stamp );
3125
+ // get the columns that this stamp affects
3126
+ var firstX = this.options.isOriginLeft ? offset.left : offset.right;
3127
+ var lastX = firstX + stampSize.outerWidth;
3128
+ var firstCol = Math.floor( firstX / this.columnWidth );
3129
+ firstCol = Math.max( 0, firstCol );
3130
+ var lastCol = Math.floor( lastX / this.columnWidth );
3131
+ // lastCol should not go over if multiple of columnWidth #425
3132
+ lastCol -= lastX % this.columnWidth ? 0 : 1;
3133
+ lastCol = Math.min( this.cols - 1, lastCol );
3134
+ // set colYs to bottom of the stamp
3135
+ var stampMaxY = ( this.options.isOriginTop ? offset.top : offset.bottom ) +
3136
+ stampSize.outerHeight;
3137
+ for ( var i = firstCol; i <= lastCol; i++ ) {
3138
+ this.colYs[i] = Math.max( stampMaxY, this.colYs[i] );
3139
+ }
3140
+ };
3141
+
3142
+ Masonry.prototype._getContainerSize = function() {
3143
+ this.maxY = Math.max.apply( Math, this.colYs );
3144
+ var size = {
3145
+ height: this.maxY
3146
+ };
3147
+
3148
+ if ( this.options.isFitWidth ) {
3149
+ size.width = this._getContainerFitWidth();
3150
+ }
3151
+
3152
+ return size;
3153
+ };
3154
+
3155
+ Masonry.prototype._getContainerFitWidth = function() {
3156
+ var unusedCols = 0;
3157
+ // count unused columns
3158
+ var i = this.cols;
3159
+ while ( --i ) {
3160
+ if ( this.colYs[i] !== 0 ) {
3161
+ break;
3162
+ }
3163
+ unusedCols++;
3164
+ }
3165
+ // fit container to columns that have been used
3166
+ return ( this.cols - unusedCols ) * this.columnWidth - this.gutter;
3167
+ };
3168
+
3169
+ Masonry.prototype.needsResizeLayout = function() {
3170
+ var previousWidth = this.containerWidth;
3171
+ this.getContainerWidth();
3172
+ return previousWidth !== this.containerWidth;
3173
+ };
3174
+
3175
+ return Masonry;
3176
+ }
3177
+
3178
+ // -------------------------- transport -------------------------- //
3179
+
3180
+ if ( typeof define === 'function' && define.amd ) {
3181
+ // AMD
3182
+ define( 'masonry/masonry',[
3183
+ 'outlayer/outlayer',
3184
+ 'get-size/get-size'
3185
+ ],
3186
+ masonryDefinition );
3187
+ } else if (typeof exports === 'object') {
3188
+ module.exports = masonryDefinition(
3189
+ require('outlayer'),
3190
+ require('get-size')
3191
+ );
3192
+ } else {
3193
+ // browser global
3194
+ window.Masonry = masonryDefinition(
3195
+ window.Outlayer,
3196
+ window.getSize
3197
+ );
3198
+ }
3199
+
3200
+ })( window );
3201
+
3202
+ /*!
3203
+ * Masonry layout mode
3204
+ * sub-classes Masonry
3205
+ * http://masonry.desandro.com
3206
+ */
3207
+
3208
+ ( function( window ) {
3209
+
3210
+
3211
+
3212
+ // -------------------------- helpers -------------------------- //
3213
+
3214
+ // extend objects
3215
+ function extend( a, b ) {
3216
+ for ( var prop in b ) {
3217
+ a[ prop ] = b[ prop ];
3218
+ }
3219
+ return a;
3220
+ }
3221
+
3222
+ // -------------------------- masonryDefinition -------------------------- //
3223
+
3224
+ // used for AMD definition and requires
3225
+ function masonryDefinition( LayoutMode, Masonry ) {
3226
+ // create an Outlayer layout class
3227
+ var MasonryMode = LayoutMode.create('masonry');
3228
+
3229
+ // save on to these methods
3230
+ var _getElementOffset = MasonryMode.prototype._getElementOffset;
3231
+ var layout = MasonryMode.prototype.layout;
3232
+ var _getMeasurement = MasonryMode.prototype._getMeasurement;
3233
+
3234
+ // sub-class Masonry
3235
+ extend( MasonryMode.prototype, Masonry.prototype );
3236
+
3237
+ // set back, as it was overwritten by Masonry
3238
+ MasonryMode.prototype._getElementOffset = _getElementOffset;
3239
+ MasonryMode.prototype.layout = layout;
3240
+ MasonryMode.prototype._getMeasurement = _getMeasurement;
3241
+
3242
+ var measureColumns = MasonryMode.prototype.measureColumns;
3243
+ MasonryMode.prototype.measureColumns = function() {
3244
+ // set items, used if measuring first item
3245
+ this.items = this.isotope.filteredItems;
3246
+ measureColumns.call( this );
3247
+ };
3248
+
3249
+ // HACK copy over isOriginLeft/Top options
3250
+ var _manageStamp = MasonryMode.prototype._manageStamp;
3251
+ MasonryMode.prototype._manageStamp = function() {
3252
+ this.options.isOriginLeft = this.isotope.options.isOriginLeft;
3253
+ this.options.isOriginTop = this.isotope.options.isOriginTop;
3254
+ _manageStamp.apply( this, arguments );
3255
+ };
3256
+
3257
+ return MasonryMode;
3258
+ }
3259
+
3260
+ // -------------------------- transport -------------------------- //
3261
+
3262
+ if ( typeof define === 'function' && define.amd ) {
3263
+ // AMD
3264
+ define( 'isotope/js/layout-modes/masonry',[
3265
+ '../layout-mode',
3266
+ 'masonry/masonry'
3267
+ ],
3268
+ masonryDefinition );
3269
+ } else if ( typeof exports === 'object' ) {
3270
+ // CommonJS
3271
+ module.exports = masonryDefinition(
3272
+ require('../layout-mode'),
3273
+ require('masonry-layout')
3274
+ );
3275
+ } else {
3276
+ // browser global
3277
+ masonryDefinition(
3278
+ window.Isotope.LayoutMode,
3279
+ window.Masonry
3280
+ );
3281
+ }
3282
+
3283
+ })( window );
3284
+
3285
+ ( function( window ) {
3286
+
3287
+
3288
+
3289
+ function fitRowsDefinition( LayoutMode ) {
3290
+
3291
+ var FitRows = LayoutMode.create('fitRows');
3292
+
3293
+ FitRows.prototype._resetLayout = function() {
3294
+ this.x = 0;
3295
+ this.y = 0;
3296
+ this.maxY = 0;
3297
+ this._getMeasurement( 'gutter', 'outerWidth' );
3298
+ };
3299
+
3300
+ FitRows.prototype._getItemLayoutPosition = function( item ) {
3301
+ item.getSize();
3302
+
3303
+ var itemWidth = item.size.outerWidth + this.gutter;
3304
+ // if this element cannot fit in the current row
3305
+ var containerWidth = this.isotope.size.innerWidth + this.gutter;
3306
+ if ( this.x !== 0 && itemWidth + this.x > containerWidth ) {
3307
+ this.x = 0;
3308
+ this.y = this.maxY;
3309
+ }
3310
+
3311
+ var position = {
3312
+ x: this.x,
3313
+ y: this.y
3314
+ };
3315
+
3316
+ this.maxY = Math.max( this.maxY, this.y + item.size.outerHeight );
3317
+ this.x += itemWidth;
3318
+
3319
+ return position;
3320
+ };
3321
+
3322
+ FitRows.prototype._getContainerSize = function() {
3323
+ return { height: this.maxY };
3324
+ };
3325
+
3326
+ return FitRows;
3327
+
3328
+ }
3329
+
3330
+ if ( typeof define === 'function' && define.amd ) {
3331
+ // AMD
3332
+ define( 'isotope/js/layout-modes/fit-rows',[
3333
+ '../layout-mode'
3334
+ ],
3335
+ fitRowsDefinition );
3336
+ } else if ( typeof exports === 'object' ) {
3337
+ // CommonJS
3338
+ module.exports = fitRowsDefinition(
3339
+ require('../layout-mode')
3340
+ );
3341
+ } else {
3342
+ // browser global
3343
+ fitRowsDefinition(
3344
+ window.Isotope.LayoutMode
3345
+ );
3346
+ }
3347
+
3348
+ })( window );
3349
+
3350
+ ( function( window ) {
3351
+
3352
+
3353
+
3354
+ function verticalDefinition( LayoutMode ) {
3355
+
3356
+ var Vertical = LayoutMode.create( 'vertical', {
3357
+ horizontalAlignment: 0
3358
+ });
3359
+
3360
+ Vertical.prototype._resetLayout = function() {
3361
+ this.y = 0;
3362
+ };
3363
+
3364
+ Vertical.prototype._getItemLayoutPosition = function( item ) {
3365
+ item.getSize();
3366
+ var x = ( this.isotope.size.innerWidth - item.size.outerWidth ) *
3367
+ this.options.horizontalAlignment;
3368
+ var y = this.y;
3369
+ this.y += item.size.outerHeight;
3370
+ return { x: x, y: y };
3371
+ };
3372
+
3373
+ Vertical.prototype._getContainerSize = function() {
3374
+ return { height: this.y };
3375
+ };
3376
+
3377
+ return Vertical;
3378
+
3379
+ }
3380
+
3381
+ if ( typeof define === 'function' && define.amd ) {
3382
+ // AMD
3383
+ define( 'isotope/js/layout-modes/vertical',[
3384
+ '../layout-mode'
3385
+ ],
3386
+ verticalDefinition );
3387
+ } else if ( typeof exports === 'object' ) {
3388
+ // CommonJS
3389
+ module.exports = verticalDefinition(
3390
+ require('../layout-mode')
3391
+ );
3392
+ } else {
3393
+ // browser global
3394
+ verticalDefinition(
3395
+ window.Isotope.LayoutMode
3396
+ );
3397
+ }
3398
+
3399
+ })( window );
3400
+
3401
+ /*!
3402
+ * Isotope v2.1.0
3403
+ * Filter & sort magical layouts
3404
+ * http://isotope.metafizzy.co
3405
+ */
3406
+
3407
+ ( function( window ) {
3408
+
3409
+
3410
+
3411
+ // -------------------------- vars -------------------------- //
3412
+
3413
+ var jQuery = window.jQuery;
3414
+
3415
+ // -------------------------- helpers -------------------------- //
3416
+
3417
+ // extend objects
3418
+ function extend( a, b ) {
3419
+ for ( var prop in b ) {
3420
+ a[ prop ] = b[ prop ];
3421
+ }
3422
+ return a;
3423
+ }
3424
+
3425
+ var trim = String.prototype.trim ?
3426
+ function( str ) {
3427
+ return str.trim();
3428
+ } :
3429
+ function( str ) {
3430
+ return str.replace( /^\s+|\s+$/g, '' );
3431
+ };
3432
+
3433
+ var docElem = document.documentElement;
3434
+
3435
+ var getText = docElem.textContent ?
3436
+ function( elem ) {
3437
+ return elem.textContent;
3438
+ } :
3439
+ function( elem ) {
3440
+ return elem.innerText;
3441
+ };
3442
+
3443
+ var objToString = Object.prototype.toString;
3444
+ function isArray( obj ) {
3445
+ return objToString.call( obj ) === '[object Array]';
3446
+ }
3447
+
3448
+ // index of helper cause IE8
3449
+ var indexOf = Array.prototype.indexOf ? function( ary, obj ) {
3450
+ return ary.indexOf( obj );
3451
+ } : function( ary, obj ) {
3452
+ for ( var i=0, len = ary.length; i < len; i++ ) {
3453
+ if ( ary[i] === obj ) {
3454
+ return i;
3455
+ }
3456
+ }
3457
+ return -1;
3458
+ };
3459
+
3460
+ // turn element or nodeList into an array
3461
+ function makeArray( obj ) {
3462
+ var ary = [];
3463
+ if ( isArray( obj ) ) {
3464
+ // use object if already an array
3465
+ ary = obj;
3466
+ } else if ( obj && typeof obj.length === 'number' ) {
3467
+ // convert nodeList to array
3468
+ for ( var i=0, len = obj.length; i < len; i++ ) {
3469
+ ary.push( obj[i] );
3470
+ }
3471
+ } else {
3472
+ // array of single index
3473
+ ary.push( obj );
3474
+ }
3475
+ return ary;
3476
+ }
3477
+
3478
+ function removeFrom( obj, ary ) {
3479
+ var index = indexOf( ary, obj );
3480
+ if ( index !== -1 ) {
3481
+ ary.splice( index, 1 );
3482
+ }
3483
+ }
3484
+
3485
+ // -------------------------- isotopeDefinition -------------------------- //
3486
+
3487
+ // used for AMD definition and requires
3488
+ function isotopeDefinition( Outlayer, getSize, matchesSelector, Item, LayoutMode ) {
3489
+ // create an Outlayer layout class
3490
+ var Isotope = Outlayer.create( 'isotope', {
3491
+ layoutMode: "masonry",
3492
+ isJQueryFiltering: true,
3493
+ sortAscending: true
3494
+ });
3495
+
3496
+ Isotope.Item = Item;
3497
+ Isotope.LayoutMode = LayoutMode;
3498
+
3499
+ Isotope.prototype._create = function() {
3500
+ this.itemGUID = 0;
3501
+ // functions that sort items
3502
+ this._sorters = {};
3503
+ this._getSorters();
3504
+ // call super
3505
+ Outlayer.prototype._create.call( this );
3506
+
3507
+ // create layout modes
3508
+ this.modes = {};
3509
+ // start filteredItems with all items
3510
+ this.filteredItems = this.items;
3511
+ // keep of track of sortBys
3512
+ this.sortHistory = [ 'original-order' ];
3513
+ // create from registered layout modes
3514
+ for ( var name in LayoutMode.modes ) {
3515
+ this._initLayoutMode( name );
3516
+ }
3517
+ };
3518
+
3519
+ Isotope.prototype.reloadItems = function() {
3520
+ // reset item ID counter
3521
+ this.itemGUID = 0;
3522
+ // call super
3523
+ Outlayer.prototype.reloadItems.call( this );
3524
+ };
3525
+
3526
+ Isotope.prototype._itemize = function() {
3527
+ var items = Outlayer.prototype._itemize.apply( this, arguments );
3528
+ // assign ID for original-order
3529
+ for ( var i=0, len = items.length; i < len; i++ ) {
3530
+ var item = items[i];
3531
+ item.id = this.itemGUID++;
3532
+ }
3533
+ this._updateItemsSortData( items );
3534
+ return items;
3535
+ };
3536
+
3537
+
3538
+ // -------------------------- layout -------------------------- //
3539
+
3540
+ Isotope.prototype._initLayoutMode = function( name ) {
3541
+ var Mode = LayoutMode.modes[ name ];
3542
+ // set mode options
3543
+ // HACK extend initial options, back-fill in default options
3544
+ var initialOpts = this.options[ name ] || {};
3545
+ this.options[ name ] = Mode.options ?
3546
+ extend( Mode.options, initialOpts ) : initialOpts;
3547
+ // init layout mode instance
3548
+ this.modes[ name ] = new Mode( this );
3549
+ };
3550
+
3551
+
3552
+ Isotope.prototype.layout = function() {
3553
+ // if first time doing layout, do all magic
3554
+ if ( !this._isLayoutInited && this.options.isInitLayout ) {
3555
+ this.arrange();
3556
+ return;
3557
+ }
3558
+ this._layout();
3559
+ };
3560
+
3561
+ // private method to be used in layout() & magic()
3562
+ Isotope.prototype._layout = function() {
3563
+ // don't animate first layout
3564
+ var isInstant = this._getIsInstant();
3565
+ // layout flow
3566
+ this._resetLayout();
3567
+ this._manageStamps();
3568
+ this.layoutItems( this.filteredItems, isInstant );
3569
+
3570
+ // flag for initalized
3571
+ this._isLayoutInited = true;
3572
+ };
3573
+
3574
+ // filter + sort + layout
3575
+ Isotope.prototype.arrange = function( opts ) {
3576
+ // set any options pass
3577
+ this.option( opts );
3578
+ this._getIsInstant();
3579
+ // filter, sort, and layout
3580
+ this.filteredItems = this._filter( this.items );
3581
+ this._sort();
3582
+ this._layout();
3583
+ };
3584
+ // alias to _init for main plugin method
3585
+ Isotope.prototype._init = Isotope.prototype.arrange;
3586
+
3587
+ // HACK
3588
+ // Don't animate/transition first layout
3589
+ // Or don't animate/transition other layouts
3590
+ Isotope.prototype._getIsInstant = function() {
3591
+ var isInstant = this.options.isLayoutInstant !== undefined ?
3592
+ this.options.isLayoutInstant : !this._isLayoutInited;
3593
+ this._isInstant = isInstant;
3594
+ return isInstant;
3595
+ };
3596
+
3597
+ // -------------------------- filter -------------------------- //
3598
+
3599
+ Isotope.prototype._filter = function( items ) {
3600
+ var filter = this.options.filter;
3601
+ filter = filter || '*';
3602
+ var matches = [];
3603
+ var hiddenMatched = [];
3604
+ var visibleUnmatched = [];
3605
+
3606
+ var test = this._getFilterTest( filter );
3607
+
3608
+ // test each item
3609
+ for ( var i=0, len = items.length; i < len; i++ ) {
3610
+ var item = items[i];
3611
+ if ( item.isIgnored ) {
3612
+ continue;
3613
+ }
3614
+ // add item to either matched or unmatched group
3615
+ var isMatched = test( item );
3616
+ // item.isFilterMatched = isMatched;
3617
+ // add to matches if its a match
3618
+ if ( isMatched ) {
3619
+ matches.push( item );
3620
+ }
3621
+ // add to additional group if item needs to be hidden or revealed
3622
+ if ( isMatched && item.isHidden ) {
3623
+ hiddenMatched.push( item );
3624
+ } else if ( !isMatched && !item.isHidden ) {
3625
+ visibleUnmatched.push( item );
3626
+ }
3627
+ }
3628
+
3629
+ var _this = this;
3630
+ function hideReveal() {
3631
+ _this.reveal( hiddenMatched );
3632
+ _this.hide( visibleUnmatched );
3633
+ }
3634
+
3635
+ if ( this._isInstant ) {
3636
+ this._noTransition( hideReveal );
3637
+ } else {
3638
+ hideReveal();
3639
+ }
3640
+
3641
+ return matches;
3642
+ };
3643
+
3644
+ // get a jQuery, function, or a matchesSelector test given the filter
3645
+ Isotope.prototype._getFilterTest = function( filter ) {
3646
+ if ( jQuery && this.options.isJQueryFiltering ) {
3647
+ // use jQuery
3648
+ return function( item ) {
3649
+ return jQuery( item.element ).is( filter );
3650
+ };
3651
+ }
3652
+ if ( typeof filter === 'function' ) {
3653
+ // use filter as function
3654
+ return function( item ) {
3655
+ return filter( item.element );
3656
+ };
3657
+ }
3658
+ // default, use filter as selector string
3659
+ return function( item ) {
3660
+ return matchesSelector( item.element, filter );
3661
+ };
3662
+ };
3663
+
3664
+ // -------------------------- sorting -------------------------- //
3665
+
3666
+ /**
3667
+ * @params {Array} elems
3668
+ * @public
3669
+ */
3670
+ Isotope.prototype.updateSortData = function( elems ) {
3671
+ // get items
3672
+ var items;
3673
+ if ( elems ) {
3674
+ elems = makeArray( elems );
3675
+ items = this.getItems( elems );
3676
+ } else {
3677
+ // update all items if no elems provided
3678
+ items = this.items;
3679
+ }
3680
+
3681
+ this._getSorters();
3682
+ this._updateItemsSortData( items );
3683
+ };
3684
+
3685
+ Isotope.prototype._getSorters = function() {
3686
+ var getSortData = this.options.getSortData;
3687
+ for ( var key in getSortData ) {
3688
+ var sorter = getSortData[ key ];
3689
+ this._sorters[ key ] = mungeSorter( sorter );
3690
+ }
3691
+ };
3692
+
3693
+ /**
3694
+ * @params {Array} items - of Isotope.Items
3695
+ * @private
3696
+ */
3697
+ Isotope.prototype._updateItemsSortData = function( items ) {
3698
+ // do not update if no items
3699
+ var len = items && items.length;
3700
+
3701
+ for ( var i=0; len && i < len; i++ ) {
3702
+ var item = items[i];
3703
+ item.updateSortData();
3704
+ }
3705
+ };
3706
+
3707
+ // ----- munge sorter ----- //
3708
+
3709
+ // encapsulate this, as we just need mungeSorter
3710
+ // other functions in here are just for munging
3711
+ var mungeSorter = ( function() {
3712
+ // add a magic layer to sorters for convienent shorthands
3713
+ // `.foo-bar` will use the text of .foo-bar querySelector
3714
+ // `[foo-bar]` will use attribute
3715
+ // you can also add parser
3716
+ // `.foo-bar parseInt` will parse that as a number
3717
+ function mungeSorter( sorter ) {
3718
+ // if not a string, return function or whatever it is
3719
+ if ( typeof sorter !== 'string' ) {
3720
+ return sorter;
3721
+ }
3722
+ // parse the sorter string
3723
+ var args = trim( sorter ).split(' ');
3724
+ var query = args[0];
3725
+ // check if query looks like [an-attribute]
3726
+ var attrMatch = query.match( /^\[(.+)\]$/ );
3727
+ var attr = attrMatch && attrMatch[1];
3728
+ var getValue = getValueGetter( attr, query );
3729
+ // use second argument as a parser
3730
+ var parser = Isotope.sortDataParsers[ args[1] ];
3731
+ // parse the value, if there was a parser
3732
+ sorter = parser ? function( elem ) {
3733
+ return elem && parser( getValue( elem ) );
3734
+ } :
3735
+ // otherwise just return value
3736
+ function( elem ) {
3737
+ return elem && getValue( elem );
3738
+ };
3739
+
3740
+ return sorter;
3741
+ }
3742
+
3743
+ // get an attribute getter, or get text of the querySelector
3744
+ function getValueGetter( attr, query ) {
3745
+ var getValue;
3746
+ // if query looks like [foo-bar], get attribute
3747
+ if ( attr ) {
3748
+ getValue = function( elem ) {
3749
+ return elem.getAttribute( attr );
3750
+ };
3751
+ } else {
3752
+ // otherwise, assume its a querySelector, and get its text
3753
+ getValue = function( elem ) {
3754
+ var child = elem.querySelector( query );
3755
+ return child && getText( child );
3756
+ };
3757
+ }
3758
+ return getValue;
3759
+ }
3760
+
3761
+ return mungeSorter;
3762
+ })();
3763
+
3764
+ // parsers used in getSortData shortcut strings
3765
+ Isotope.sortDataParsers = {
3766
+ 'parseInt': function( val ) {
3767
+ return parseInt( val, 10 );
3768
+ },
3769
+ 'parseFloat': function( val ) {
3770
+ return parseFloat( val );
3771
+ }
3772
+ };
3773
+
3774
+ // ----- sort method ----- //
3775
+
3776
+ // sort filteredItem order
3777
+ Isotope.prototype._sort = function() {
3778
+ var sortByOpt = this.options.sortBy;
3779
+ if ( !sortByOpt ) {
3780
+ return;
3781
+ }
3782
+ // concat all sortBy and sortHistory
3783
+ var sortBys = [].concat.apply( sortByOpt, this.sortHistory );
3784
+ // sort magic
3785
+ var itemSorter = getItemSorter( sortBys, this.options.sortAscending );
3786
+ this.filteredItems.sort( itemSorter );
3787
+ // keep track of sortBy History
3788
+ if ( sortByOpt !== this.sortHistory[0] ) {
3789
+ // add to front, oldest goes in last
3790
+ this.sortHistory.unshift( sortByOpt );
3791
+ }
3792
+ };
3793
+
3794
+ // returns a function used for sorting
3795
+ function getItemSorter( sortBys, sortAsc ) {
3796
+ return function sorter( itemA, itemB ) {
3797
+ // cycle through all sortKeys
3798
+ for ( var i = 0, len = sortBys.length; i < len; i++ ) {
3799
+ var sortBy = sortBys[i];
3800
+ var a = itemA.sortData[ sortBy ];
3801
+ var b = itemB.sortData[ sortBy ];
3802
+ if ( a > b || a < b ) {
3803
+ // if sortAsc is an object, use the value given the sortBy key
3804
+ var isAscending = sortAsc[ sortBy ] !== undefined ? sortAsc[ sortBy ] : sortAsc;
3805
+ var direction = isAscending ? 1 : -1;
3806
+ return ( a > b ? 1 : -1 ) * direction;
3807
+ }
3808
+ }
3809
+ return 0;
3810
+ };
3811
+ }
3812
+
3813
+ // -------------------------- methods -------------------------- //
3814
+
3815
+ // get layout mode
3816
+ Isotope.prototype._mode = function() {
3817
+ var layoutMode = this.options.layoutMode;
3818
+ var mode = this.modes[ layoutMode ];
3819
+ if ( !mode ) {
3820
+ // TODO console.error
3821
+ throw new Error( 'No layout mode: ' + layoutMode );
3822
+ }
3823
+ // HACK sync mode's options
3824
+ // any options set after init for layout mode need to be synced
3825
+ mode.options = this.options[ layoutMode ];
3826
+ return mode;
3827
+ };
3828
+
3829
+ Isotope.prototype._resetLayout = function() {
3830
+ // trigger original reset layout
3831
+ Outlayer.prototype._resetLayout.call( this );
3832
+ this._mode()._resetLayout();
3833
+ };
3834
+
3835
+ Isotope.prototype._getItemLayoutPosition = function( item ) {
3836
+ return this._mode()._getItemLayoutPosition( item );
3837
+ };
3838
+
3839
+ Isotope.prototype._manageStamp = function( stamp ) {
3840
+ this._mode()._manageStamp( stamp );
3841
+ };
3842
+
3843
+ Isotope.prototype._getContainerSize = function() {
3844
+ return this._mode()._getContainerSize();
3845
+ };
3846
+
3847
+ Isotope.prototype.needsResizeLayout = function() {
3848
+ return this._mode().needsResizeLayout();
3849
+ };
3850
+
3851
+ // -------------------------- adding & removing -------------------------- //
3852
+
3853
+ // HEADS UP overwrites default Outlayer appended
3854
+ Isotope.prototype.appended = function( elems ) {
3855
+ var items = this.addItems( elems );
3856
+ if ( !items.length ) {
3857
+ return;
3858
+ }
3859
+ var filteredItems = this._filterRevealAdded( items );
3860
+ // add to filteredItems
3861
+ this.filteredItems = this.filteredItems.concat( filteredItems );
3862
+ };
3863
+
3864
+ // HEADS UP overwrites default Outlayer prepended
3865
+ Isotope.prototype.prepended = function( elems ) {
3866
+ var items = this._itemize( elems );
3867
+ if ( !items.length ) {
3868
+ return;
3869
+ }
3870
+ // add items to beginning of collection
3871
+ var previousItems = this.items.slice(0);
3872
+ this.items = items.concat( previousItems );
3873
+ // start new layout
3874
+ this._resetLayout();
3875
+ this._manageStamps();
3876
+ // layout new stuff without transition
3877
+ var filteredItems = this._filterRevealAdded( items );
3878
+ // layout previous items
3879
+ this.layoutItems( previousItems );
3880
+ // add to filteredItems
3881
+ this.filteredItems = filteredItems.concat( this.filteredItems );
3882
+ };
3883
+
3884
+ Isotope.prototype._filterRevealAdded = function( items ) {
3885
+ var filteredItems = this._noTransition( function() {
3886
+ return this._filter( items );
3887
+ });
3888
+ // layout and reveal just the new items
3889
+ this.layoutItems( filteredItems, true );
3890
+ this.reveal( filteredItems );
3891
+ return items;
3892
+ };
3893
+
3894
+ /**
3895
+ * Filter, sort, and layout newly-appended item elements
3896
+ * @param {Array or NodeList or Element} elems
3897
+ */
3898
+ Isotope.prototype.insert = function( elems ) {
3899
+ var items = this.addItems( elems );
3900
+ if ( !items.length ) {
3901
+ return;
3902
+ }
3903
+ // append item elements
3904
+ var i, item;
3905
+ var len = items.length;
3906
+ for ( i=0; i < len; i++ ) {
3907
+ item = items[i];
3908
+ this.element.appendChild( item.element );
3909
+ }
3910
+ // filter new stuff
3911
+ /*
3912
+ // this way adds hides new filtered items with NO transition
3913
+ // so user can't see if new hidden items have been inserted
3914
+ var filteredInsertItems;
3915
+ this._noTransition( function() {
3916
+ filteredInsertItems = this._filter( items );
3917
+ // hide all new items
3918
+ this.hide( filteredInsertItems );
3919
+ });
3920
+ // */
3921
+ // this way hides new filtered items with transition
3922
+ // so user at least sees that something has been added
3923
+ var filteredInsertItems = this._filter( items );
3924
+ // hide all newitems
3925
+ this._noTransition( function() {
3926
+ this.hide( filteredInsertItems );
3927
+ });
3928
+ // */
3929
+ // set flag
3930
+ for ( i=0; i < len; i++ ) {
3931
+ items[i].isLayoutInstant = true;
3932
+ }
3933
+ this.arrange();
3934
+ // reset flag
3935
+ for ( i=0; i < len; i++ ) {
3936
+ delete items[i].isLayoutInstant;
3937
+ }
3938
+ this.reveal( filteredInsertItems );
3939
+ };
3940
+
3941
+ var _remove = Isotope.prototype.remove;
3942
+ Isotope.prototype.remove = function( elems ) {
3943
+ elems = makeArray( elems );
3944
+ var removeItems = this.getItems( elems );
3945
+ // do regular thing
3946
+ _remove.call( this, elems );
3947
+ // bail if no items to remove
3948
+ if ( !removeItems || !removeItems.length ) {
3949
+ return;
3950
+ }
3951
+ // remove elems from filteredItems
3952
+ for ( var i=0, len = removeItems.length; i < len; i++ ) {
3953
+ var item = removeItems[i];
3954
+ // remove item from collection
3955
+ removeFrom( item, this.filteredItems );
3956
+ }
3957
+ };
3958
+
3959
+ Isotope.prototype.shuffle = function() {
3960
+ // update random sortData
3961
+ for ( var i=0, len = this.items.length; i < len; i++ ) {
3962
+ var item = this.items[i];
3963
+ item.sortData.random = Math.random();
3964
+ }
3965
+ this.options.sortBy = 'random';
3966
+ this._sort();
3967
+ this._layout();
3968
+ };
3969
+
3970
+ /**
3971
+ * trigger fn without transition
3972
+ * kind of hacky to have this in the first place
3973
+ * @param {Function} fn
3974
+ * @returns ret
3975
+ * @private
3976
+ */
3977
+ Isotope.prototype._noTransition = function( fn ) {
3978
+ // save transitionDuration before disabling
3979
+ var transitionDuration = this.options.transitionDuration;
3980
+ // disable transition
3981
+ this.options.transitionDuration = 0;
3982
+ // do it
3983
+ var returnValue = fn.call( this );
3984
+ // re-enable transition for reveal
3985
+ this.options.transitionDuration = transitionDuration;
3986
+ return returnValue;
3987
+ };
3988
+
3989
+ // ----- helper methods ----- //
3990
+
3991
+ /**
3992
+ * getter method for getting filtered item elements
3993
+ * @returns {Array} elems - collection of item elements
3994
+ */
3995
+ Isotope.prototype.getFilteredItemElements = function() {
3996
+ var elems = [];
3997
+ for ( var i=0, len = this.filteredItems.length; i < len; i++ ) {
3998
+ elems.push( this.filteredItems[i].element );
3999
+ }
4000
+ return elems;
4001
+ };
4002
+
4003
+ // ----- ----- //
4004
+
4005
+ return Isotope;
4006
+ }
4007
+
4008
+ // -------------------------- transport -------------------------- //
4009
+
4010
+ if ( typeof define === 'function' && define.amd ) {
4011
+ // AMD
4012
+ define( [
4013
+ 'outlayer/outlayer',
4014
+ 'get-size/get-size',
4015
+ 'matches-selector/matches-selector',
4016
+ 'isotope/js/item',
4017
+ 'isotope/js/layout-mode',
4018
+ // include default layout modes
4019
+ 'isotope/js/layout-modes/masonry',
4020
+ 'isotope/js/layout-modes/fit-rows',
4021
+ 'isotope/js/layout-modes/vertical'
4022
+ ],
4023
+ isotopeDefinition );
4024
+ } else if ( typeof exports === 'object' ) {
4025
+ // CommonJS
4026
+ module.exports = isotopeDefinition(
4027
+ require('outlayer'),
4028
+ require('get-size'),
4029
+ require('desandro-matches-selector'),
4030
+ require('./item'),
4031
+ require('./layout-mode'),
4032
+ // include default layout modes
4033
+ require('./layout-modes/masonry'),
4034
+ require('./layout-modes/fit-rows'),
4035
+ require('./layout-modes/vertical')
4036
+ );
4037
+ } else {
4038
+ // browser global
4039
+ window.Isotope = isotopeDefinition(
4040
+ window.Outlayer,
4041
+ window.getSize,
4042
+ window.matchesSelector,
4043
+ window.Isotope.Item,
4044
+ window.Isotope.LayoutMode
4045
+ );
4046
+ }
4047
+
4048
+ })( window );
4049
+