phcthemes_web_theme_pack 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (250) hide show
  1. checksums.yaml +7 -0
  2. data/MIT-LICENSE +20 -0
  3. data/README.md +0 -0
  4. data/Rakefile +32 -0
  5. data/app/assets/config/phcthemes_web_theme_pack_manifest.js +3 -0
  6. data/app/assets/javascripts/common/backstretch/jquery.backstretch.js +1602 -0
  7. data/app/assets/javascripts/common/bootstrap-datepicker/bootstrap-datepicker.js +2039 -0
  8. data/app/assets/javascripts/common/bootstrap-markdown/bootstrap-markdown.js +1390 -0
  9. data/app/assets/javascripts/common/bootstrap-select/bootstrap-select.js +3139 -0
  10. data/app/assets/javascripts/common/bootstrap-select/i18n/defaults-am_ET.js +46 -0
  11. data/app/assets/javascripts/common/bootstrap-select/i18n/defaults-am_ET.js.map +1 -0
  12. data/app/assets/javascripts/common/bootstrap-select/i18n/defaults-am_ET.min.js +8 -0
  13. data/app/assets/javascripts/common/bootstrap-select/i18n/defaults-ar_AR.js +51 -0
  14. data/app/assets/javascripts/common/bootstrap-select/i18n/defaults-ar_AR.js.map +1 -0
  15. data/app/assets/javascripts/common/bootstrap-select/i18n/defaults-ar_AR.min.js +8 -0
  16. data/app/assets/javascripts/common/bootstrap-select/i18n/defaults-bg_BG.js +46 -0
  17. data/app/assets/javascripts/common/bootstrap-select/i18n/defaults-bg_BG.js.map +1 -0
  18. data/app/assets/javascripts/common/bootstrap-select/i18n/defaults-bg_BG.min.js +8 -0
  19. data/app/assets/javascripts/common/bootstrap-select/i18n/defaults-cs_CZ.js +39 -0
  20. data/app/assets/javascripts/common/bootstrap-select/i18n/defaults-cs_CZ.js.map +1 -0
  21. data/app/assets/javascripts/common/bootstrap-select/i18n/defaults-cs_CZ.min.js +8 -0
  22. data/app/assets/javascripts/common/bootstrap-select/i18n/defaults-da_DK.js +46 -0
  23. data/app/assets/javascripts/common/bootstrap-select/i18n/defaults-da_DK.js.map +1 -0
  24. data/app/assets/javascripts/common/bootstrap-select/i18n/defaults-da_DK.min.js +8 -0
  25. data/app/assets/javascripts/common/bootstrap-select/i18n/defaults-de_DE.js +46 -0
  26. data/app/assets/javascripts/common/bootstrap-select/i18n/defaults-de_DE.js.map +1 -0
  27. data/app/assets/javascripts/common/bootstrap-select/i18n/defaults-de_DE.min.js +8 -0
  28. data/app/assets/javascripts/common/bootstrap-select/i18n/defaults-en_US.js +46 -0
  29. data/app/assets/javascripts/common/bootstrap-select/i18n/defaults-en_US.js.map +1 -0
  30. data/app/assets/javascripts/common/bootstrap-select/i18n/defaults-en_US.min.js +8 -0
  31. data/app/assets/javascripts/common/bootstrap-select/i18n/defaults-es_CL.js +39 -0
  32. data/app/assets/javascripts/common/bootstrap-select/i18n/defaults-es_CL.js.map +1 -0
  33. data/app/assets/javascripts/common/bootstrap-select/i18n/defaults-es_CL.min.js +8 -0
  34. data/app/assets/javascripts/common/bootstrap-select/i18n/defaults-es_ES.js +39 -0
  35. data/app/assets/javascripts/common/bootstrap-select/i18n/defaults-es_ES.js.map +1 -0
  36. data/app/assets/javascripts/common/bootstrap-select/i18n/defaults-es_ES.min.js +8 -0
  37. data/app/assets/javascripts/common/bootstrap-select/i18n/defaults-et_EE.js +46 -0
  38. data/app/assets/javascripts/common/bootstrap-select/i18n/defaults-et_EE.js.map +1 -0
  39. data/app/assets/javascripts/common/bootstrap-select/i18n/defaults-et_EE.min.js +8 -0
  40. data/app/assets/javascripts/common/bootstrap-select/i18n/defaults-eu.js +39 -0
  41. data/app/assets/javascripts/common/bootstrap-select/i18n/defaults-eu.js.map +1 -0
  42. data/app/assets/javascripts/common/bootstrap-select/i18n/defaults-eu.min.js +8 -0
  43. data/app/assets/javascripts/common/bootstrap-select/i18n/defaults-fa_IR.js +39 -0
  44. data/app/assets/javascripts/common/bootstrap-select/i18n/defaults-fa_IR.js.map +1 -0
  45. data/app/assets/javascripts/common/bootstrap-select/i18n/defaults-fa_IR.min.js +8 -0
  46. data/app/assets/javascripts/common/bootstrap-select/i18n/defaults-fi_FI.js +46 -0
  47. data/app/assets/javascripts/common/bootstrap-select/i18n/defaults-fi_FI.js.map +1 -0
  48. data/app/assets/javascripts/common/bootstrap-select/i18n/defaults-fi_FI.min.js +8 -0
  49. data/app/assets/javascripts/common/bootstrap-select/i18n/defaults-fr_FR.js +46 -0
  50. data/app/assets/javascripts/common/bootstrap-select/i18n/defaults-fr_FR.js.map +1 -0
  51. data/app/assets/javascripts/common/bootstrap-select/i18n/defaults-fr_FR.min.js +8 -0
  52. data/app/assets/javascripts/common/bootstrap-select/i18n/defaults-hr_HR.js +46 -0
  53. data/app/assets/javascripts/common/bootstrap-select/i18n/defaults-hr_HR.js.map +1 -0
  54. data/app/assets/javascripts/common/bootstrap-select/i18n/defaults-hr_HR.min.js +8 -0
  55. data/app/assets/javascripts/common/bootstrap-select/i18n/defaults-hu_HU.js +46 -0
  56. data/app/assets/javascripts/common/bootstrap-select/i18n/defaults-hu_HU.js.map +1 -0
  57. data/app/assets/javascripts/common/bootstrap-select/i18n/defaults-hu_HU.min.js +8 -0
  58. data/app/assets/javascripts/common/bootstrap-select/i18n/defaults-id_ID.js +39 -0
  59. data/app/assets/javascripts/common/bootstrap-select/i18n/defaults-id_ID.js.map +1 -0
  60. data/app/assets/javascripts/common/bootstrap-select/i18n/defaults-id_ID.min.js +8 -0
  61. data/app/assets/javascripts/common/bootstrap-select/i18n/defaults-it_IT.js +41 -0
  62. data/app/assets/javascripts/common/bootstrap-select/i18n/defaults-it_IT.js.map +1 -0
  63. data/app/assets/javascripts/common/bootstrap-select/i18n/defaults-it_IT.min.js +8 -0
  64. data/app/assets/javascripts/common/bootstrap-select/i18n/defaults-ja_JP.js +39 -0
  65. data/app/assets/javascripts/common/bootstrap-select/i18n/defaults-ja_JP.js.map +1 -0
  66. data/app/assets/javascripts/common/bootstrap-select/i18n/defaults-ja_JP.min.js +8 -0
  67. data/app/assets/javascripts/common/bootstrap-select/i18n/defaults-kh_KM.js +46 -0
  68. data/app/assets/javascripts/common/bootstrap-select/i18n/defaults-kh_KM.js.map +1 -0
  69. data/app/assets/javascripts/common/bootstrap-select/i18n/defaults-kh_KM.min.js +8 -0
  70. data/app/assets/javascripts/common/bootstrap-select/i18n/defaults-ko_KR.js +46 -0
  71. data/app/assets/javascripts/common/bootstrap-select/i18n/defaults-ko_KR.js.map +1 -0
  72. data/app/assets/javascripts/common/bootstrap-select/i18n/defaults-ko_KR.min.js +8 -0
  73. data/app/assets/javascripts/common/bootstrap-select/i18n/defaults-lt_LT.js +46 -0
  74. data/app/assets/javascripts/common/bootstrap-select/i18n/defaults-lt_LT.js.map +1 -0
  75. data/app/assets/javascripts/common/bootstrap-select/i18n/defaults-lt_LT.min.js +8 -0
  76. data/app/assets/javascripts/common/bootstrap-select/i18n/defaults-lv_LV.js +46 -0
  77. data/app/assets/javascripts/common/bootstrap-select/i18n/defaults-lv_LV.js.map +1 -0
  78. data/app/assets/javascripts/common/bootstrap-select/i18n/defaults-lv_LV.min.js +8 -0
  79. data/app/assets/javascripts/common/bootstrap-select/i18n/defaults-nb_NO.js +46 -0
  80. data/app/assets/javascripts/common/bootstrap-select/i18n/defaults-nb_NO.js.map +1 -0
  81. data/app/assets/javascripts/common/bootstrap-select/i18n/defaults-nb_NO.min.js +8 -0
  82. data/app/assets/javascripts/common/bootstrap-select/i18n/defaults-nl_NL.js +39 -0
  83. data/app/assets/javascripts/common/bootstrap-select/i18n/defaults-nl_NL.js.map +1 -0
  84. data/app/assets/javascripts/common/bootstrap-select/i18n/defaults-nl_NL.min.js +8 -0
  85. data/app/assets/javascripts/common/bootstrap-select/i18n/defaults-pl_PL.js +39 -0
  86. data/app/assets/javascripts/common/bootstrap-select/i18n/defaults-pl_PL.js.map +1 -0
  87. data/app/assets/javascripts/common/bootstrap-select/i18n/defaults-pl_PL.min.js +8 -0
  88. data/app/assets/javascripts/common/bootstrap-select/i18n/defaults-pt_BR.js +39 -0
  89. data/app/assets/javascripts/common/bootstrap-select/i18n/defaults-pt_BR.js.map +1 -0
  90. data/app/assets/javascripts/common/bootstrap-select/i18n/defaults-pt_BR.min.js +8 -0
  91. data/app/assets/javascripts/common/bootstrap-select/i18n/defaults-pt_PT.js +39 -0
  92. data/app/assets/javascripts/common/bootstrap-select/i18n/defaults-pt_PT.js.map +1 -0
  93. data/app/assets/javascripts/common/bootstrap-select/i18n/defaults-pt_PT.min.js +8 -0
  94. data/app/assets/javascripts/common/bootstrap-select/i18n/defaults-ro_RO.js +40 -0
  95. data/app/assets/javascripts/common/bootstrap-select/i18n/defaults-ro_RO.js.map +1 -0
  96. data/app/assets/javascripts/common/bootstrap-select/i18n/defaults-ro_RO.min.js +8 -0
  97. data/app/assets/javascripts/common/bootstrap-select/i18n/defaults-ru_RU.js +40 -0
  98. data/app/assets/javascripts/common/bootstrap-select/i18n/defaults-ru_RU.js.map +1 -0
  99. data/app/assets/javascripts/common/bootstrap-select/i18n/defaults-ru_RU.min.js +8 -0
  100. data/app/assets/javascripts/common/bootstrap-select/i18n/defaults-sk_SK.js +39 -0
  101. data/app/assets/javascripts/common/bootstrap-select/i18n/defaults-sk_SK.js.map +1 -0
  102. data/app/assets/javascripts/common/bootstrap-select/i18n/defaults-sk_SK.min.js +8 -0
  103. data/app/assets/javascripts/common/bootstrap-select/i18n/defaults-sl_SI.js +44 -0
  104. data/app/assets/javascripts/common/bootstrap-select/i18n/defaults-sl_SI.js.map +1 -0
  105. data/app/assets/javascripts/common/bootstrap-select/i18n/defaults-sl_SI.min.js +8 -0
  106. data/app/assets/javascripts/common/bootstrap-select/i18n/defaults-sv_SE.js +46 -0
  107. data/app/assets/javascripts/common/bootstrap-select/i18n/defaults-sv_SE.js.map +1 -0
  108. data/app/assets/javascripts/common/bootstrap-select/i18n/defaults-sv_SE.min.js +8 -0
  109. data/app/assets/javascripts/common/bootstrap-select/i18n/defaults-tr_TR.js +46 -0
  110. data/app/assets/javascripts/common/bootstrap-select/i18n/defaults-tr_TR.js.map +1 -0
  111. data/app/assets/javascripts/common/bootstrap-select/i18n/defaults-tr_TR.min.js +8 -0
  112. data/app/assets/javascripts/common/bootstrap-select/i18n/defaults-ua_UA.js +39 -0
  113. data/app/assets/javascripts/common/bootstrap-select/i18n/defaults-ua_UA.js.map +1 -0
  114. data/app/assets/javascripts/common/bootstrap-select/i18n/defaults-ua_UA.min.js +8 -0
  115. data/app/assets/javascripts/common/bootstrap-select/i18n/defaults-vi_VN.js +46 -0
  116. data/app/assets/javascripts/common/bootstrap-select/i18n/defaults-vi_VN.js.map +1 -0
  117. data/app/assets/javascripts/common/bootstrap-select/i18n/defaults-vi_VN.min.js +8 -0
  118. data/app/assets/javascripts/common/bootstrap-select/i18n/defaults-zh_CN.js +39 -0
  119. data/app/assets/javascripts/common/bootstrap-select/i18n/defaults-zh_CN.js.map +1 -0
  120. data/app/assets/javascripts/common/bootstrap-select/i18n/defaults-zh_CN.min.js +8 -0
  121. data/app/assets/javascripts/common/bootstrap-select/i18n/defaults-zh_TW.js +39 -0
  122. data/app/assets/javascripts/common/bootstrap-select/i18n/defaults-zh_TW.js.map +1 -0
  123. data/app/assets/javascripts/common/bootstrap-select/i18n/defaults-zh_TW.min.js +8 -0
  124. data/app/assets/javascripts/common/bootstrap/bootstrap.bundle.js +7013 -0
  125. data/app/assets/javascripts/common/custom/custom.js +0 -0
  126. data/app/assets/javascripts/common/daterangepicker/daterangepicker.js +1565 -0
  127. data/app/assets/javascripts/common/flexslider/jquery.flexslider.js +1252 -0
  128. data/app/assets/javascripts/common/greenstock/greensock.js +36 -0
  129. data/app/assets/javascripts/common/icheck/icheck.js +509 -0
  130. data/app/assets/javascripts/common/imagesloaded/imagesloaded.pkgd.js +497 -0
  131. data/app/assets/javascripts/common/isotope/isotope.pkgd.js +3563 -0
  132. data/app/assets/javascripts/common/jquery-countdown/jquery.countdown.js +246 -0
  133. data/app/assets/javascripts/common/jquery-filterizer/jquery.filterizr.min.js +1 -0
  134. data/app/assets/javascripts/common/jquery-placeholder/jquery.placeholder.js +281 -0
  135. data/app/assets/javascripts/common/jquery-validation/jquery.validate.js +1650 -0
  136. data/app/assets/javascripts/common/jqvmap/jquery.vmap.js +1281 -0
  137. data/app/assets/javascripts/common/jqvmap/jquery.vmap.min.js +10 -0
  138. data/app/assets/javascripts/common/jqvmap/maps/continents/jquery.vmap.africa.js +2 -0
  139. data/app/assets/javascripts/common/jqvmap/maps/continents/jquery.vmap.asia.js +2 -0
  140. data/app/assets/javascripts/common/jqvmap/maps/continents/jquery.vmap.australia.js +2 -0
  141. data/app/assets/javascripts/common/jqvmap/maps/continents/jquery.vmap.europe.js +2 -0
  142. data/app/assets/javascripts/common/jqvmap/maps/continents/jquery.vmap.north-america.js +2 -0
  143. data/app/assets/javascripts/common/jqvmap/maps/continents/jquery.vmap.south-america.js +2 -0
  144. data/app/assets/javascripts/common/jqvmap/maps/jquery.vmap.algeria.js +2 -0
  145. data/app/assets/javascripts/common/jqvmap/maps/jquery.vmap.argentina.js +1 -0
  146. data/app/assets/javascripts/common/jqvmap/maps/jquery.vmap.brazil.js +2 -0
  147. data/app/assets/javascripts/common/jqvmap/maps/jquery.vmap.canada.js +2 -0
  148. data/app/assets/javascripts/common/jqvmap/maps/jquery.vmap.europe.js +2 -0
  149. data/app/assets/javascripts/common/jqvmap/maps/jquery.vmap.france.js +1 -0
  150. data/app/assets/javascripts/common/jqvmap/maps/jquery.vmap.germany.js +2 -0
  151. data/app/assets/javascripts/common/jqvmap/maps/jquery.vmap.greece.js +1 -0
  152. data/app/assets/javascripts/common/jqvmap/maps/jquery.vmap.iran.js +6 -0
  153. data/app/assets/javascripts/common/jqvmap/maps/jquery.vmap.iraq.js +1 -0
  154. data/app/assets/javascripts/common/jqvmap/maps/jquery.vmap.russia.js +2 -0
  155. data/app/assets/javascripts/common/jqvmap/maps/jquery.vmap.tunisia.js +2 -0
  156. data/app/assets/javascripts/common/jqvmap/maps/jquery.vmap.turkey.js +11 -0
  157. data/app/assets/javascripts/common/jqvmap/maps/jquery.vmap.usa.js +2 -0
  158. data/app/assets/javascripts/common/jqvmap/maps/jquery.vmap.world.js +2 -0
  159. data/app/assets/javascripts/common/js-cookie/js.cookie.js +165 -0
  160. data/app/assets/javascripts/common/layerslider/layerslider.kreaturamedia.jquery.js +13 -0
  161. data/app/assets/javascripts/common/layerslider/layerslider.origami.js +13 -0
  162. data/app/assets/javascripts/common/layerslider/layerslider.timeline.js +13 -0
  163. data/app/assets/javascripts/common/layerslider/layerslider.transitions.js +13 -0
  164. data/app/assets/javascripts/common/leaflet/leaflet.js +5 -0
  165. data/app/assets/javascripts/common/magnific-popup/jquery.magnific-popup.js +1860 -0
  166. data/app/assets/javascripts/common/mapbox/mapbox.js +51 -0
  167. data/app/assets/javascripts/common/moderizer/modernizr.js +11 -0
  168. data/app/assets/javascripts/common/owl-carousel/owl.carousel.js +3448 -0
  169. data/app/assets/javascripts/common/pace/pace.js +935 -0
  170. data/app/assets/javascripts/common/paroller/jquery.paroller.js +228 -0
  171. data/app/assets/javascripts/common/particlejs/particles.js +1541 -0
  172. data/app/assets/javascripts/common/plyr/plyr.js +9137 -0
  173. data/app/assets/javascripts/common/rangeslider/rangeslider.js +498 -0
  174. data/app/assets/javascripts/common/retina/retina.js +100 -0
  175. data/app/assets/javascripts/common/rev-slider/extensions/revolution.extension.actions.js +386 -0
  176. data/app/assets/javascripts/common/rev-slider/extensions/revolution.extension.carousel.js +365 -0
  177. data/app/assets/javascripts/common/rev-slider/extensions/revolution.extension.kenburn.js +199 -0
  178. data/app/assets/javascripts/common/rev-slider/extensions/revolution.extension.layeranimation.js +2524 -0
  179. data/app/assets/javascripts/common/rev-slider/extensions/revolution.extension.migration.js +260 -0
  180. data/app/assets/javascripts/common/rev-slider/extensions/revolution.extension.navigation.js +1156 -0
  181. data/app/assets/javascripts/common/rev-slider/extensions/revolution.extension.parallax.js +465 -0
  182. data/app/assets/javascripts/common/rev-slider/extensions/revolution.extension.slideanims.js +1447 -0
  183. data/app/assets/javascripts/common/rev-slider/extensions/revolution.extension.video.js +1464 -0
  184. data/app/assets/javascripts/common/rev-slider/jquery.themepunch.revolution.js +3286 -0
  185. data/app/assets/javascripts/common/rev-slider/jquery.themepunch.tools.min.js +8710 -0
  186. data/app/assets/javascripts/common/scrollup/jquery.scrollUp.js +168 -0
  187. data/app/assets/javascripts/common/select2/select2.full.js +6597 -0
  188. data/app/assets/javascripts/common/selectbox/jquery.selectBox.js +1092 -0
  189. data/app/assets/javascripts/common/smooth-scroll/SmoothScroll.js +788 -0
  190. data/app/assets/javascripts/common/spectrum/spectrum.js +2323 -0
  191. data/app/assets/javascripts/common/stepper/jquery.fs.stepper.js +339 -0
  192. data/app/assets/javascripts/common/swiper/swiper.js +8124 -0
  193. data/app/assets/javascripts/common/typed/typed.js +1045 -0
  194. data/app/assets/javascripts/common/visable/jquery.visible.js +68 -0
  195. data/app/assets/javascripts/common/waypoints/jquery.waypoints.js +662 -0
  196. data/app/assets/javascripts/phcthemes_web_theme_pack_appstrap.js +11 -0
  197. data/app/assets/javascripts/phcthemes_web_theme_pack_basic.js +39 -0
  198. data/app/assets/javascripts/phcthemes_web_theme_pack_bold.js +34 -0
  199. data/app/assets/javascripts/phcthemes_web_theme_pack_coloradmin.js +12 -0
  200. data/app/assets/javascripts/phcthemes_web_theme_pack_devine_villas.js +20 -0
  201. data/app/assets/javascripts/phcthemes_web_theme_pack_smarty.js +57 -0
  202. data/app/assets/javascripts/phcthemes_web_theme_pack_xero.js +18 -0
  203. data/app/assets/javascripts/phcthemes_web_theme_pack_zoner.js +24 -0
  204. data/app/assets/javascripts/themes/appstrap/custom/custom.js +0 -0
  205. data/app/assets/javascripts/themes/appstrap/theme/custom-script.js +69 -0
  206. data/app/assets/javascripts/themes/appstrap/theme/script.js +3096 -0
  207. data/app/assets/javascripts/themes/basic/custom/custom.js +0 -0
  208. data/app/assets/javascripts/themes/bold/custom/custom.js +0 -0
  209. data/app/assets/javascripts/themes/coloradmin/custom/custom.js +0 -0
  210. data/app/assets/javascripts/themes/coloradmin/theme/apps.js +236 -0
  211. data/app/assets/javascripts/themes/devine_villas/custom/custom.js +0 -0
  212. data/app/assets/javascripts/themes/devine_villas/theme/dashboard.js +19 -0
  213. data/app/assets/javascripts/themes/devine_villas/theme/main.js +384 -0
  214. data/app/assets/javascripts/themes/devine_villas/theme/map.js +563 -0
  215. data/app/assets/javascripts/themes/devine_villas/theme/searchmap.js +69 -0
  216. data/app/assets/javascripts/themes/smarty/custom/custom.js +0 -0
  217. data/app/assets/javascripts/themes/smarty/theme/scripts.js +4271 -0
  218. data/app/assets/javascripts/themes/xero/custom/custom.js +0 -0
  219. data/app/assets/javascripts/themes/xero/theme/app.js +696 -0
  220. data/app/assets/javascripts/themes/zoner/custom-maps/custom-map.js +289 -0
  221. data/app/assets/javascripts/themes/zoner/custom/custom.js +0 -0
  222. data/app/assets/javascripts/themes/zoner/draggable/draggable.js +196 -0
  223. data/app/assets/javascripts/themes/zoner/jquery-dependclass/dependclass.js +56 -0
  224. data/app/assets/javascripts/themes/zoner/jquery-slider/jquery.slider.js +700 -0
  225. data/app/assets/javascripts/themes/zoner/jquery-vanillabox/jquery.vanillabox.min.js +24 -0
  226. data/app/assets/javascripts/themes/zoner/jshashtable/hashtable.js +402 -0
  227. data/app/assets/javascripts/themes/zoner/numberformatter/numberformatter.js +566 -0
  228. data/app/assets/javascripts/themes/zoner/simple-js-templating/tmpl.js +35 -0
  229. data/app/assets/javascripts/themes/zoner/theme/main.js +667 -0
  230. data/app/assets/stylesheets/common/custom/custom.scss +0 -0
  231. data/app/assets/stylesheets/phcthemes_web_theme_pack_appstrap.scss +28 -0
  232. data/app/assets/stylesheets/phcthemes_web_theme_pack_basic.scss +0 -0
  233. data/app/assets/stylesheets/phcthemes_web_theme_pack_bold.scss +21 -0
  234. data/app/assets/stylesheets/phcthemes_web_theme_pack_coloradmin.scss +22 -0
  235. data/app/assets/stylesheets/phcthemes_web_theme_pack_devine_villas.scss +28 -0
  236. data/app/assets/stylesheets/phcthemes_web_theme_pack_smarty.scss +47 -0
  237. data/app/assets/stylesheets/phcthemes_web_theme_pack_xero.scss +28 -0
  238. data/app/assets/stylesheets/phcthemes_web_theme_pack_zoner.scss +22 -0
  239. data/app/assets/stylesheets/themes/appstrap/custom/custom.scss +0 -0
  240. data/app/assets/stylesheets/themes/bold/custom/custom.scss +0 -0
  241. data/app/assets/stylesheets/themes/coloradmin/custom/custom.scss +0 -0
  242. data/app/assets/stylesheets/themes/devine_villas/custom/custom.scss +0 -0
  243. data/app/assets/stylesheets/themes/smarty/custom/custom.scss +0 -0
  244. data/app/assets/stylesheets/themes/xero/custom/custom.scss +0 -0
  245. data/app/assets/stylesheets/themes/zoner/custom/custom.scss +0 -0
  246. data/lib/phcthemes_web_theme_pack.rb +5 -0
  247. data/lib/phcthemes_web_theme_pack/engine.rb +13 -0
  248. data/lib/phcthemes_web_theme_pack/version.rb +3 -0
  249. data/lib/tasks/phcthemes_web_theme_pack_tasks.rake +4 -0
  250. metadata +375 -0
@@ -0,0 +1,3563 @@
1
+ /*!
2
+ * Isotope PACKAGED v3.0.6
3
+ *
4
+ * Licensed GPLv3 for open source use
5
+ * or Isotope Commercial License for commercial use
6
+ *
7
+ * https://isotope.metafizzy.co
8
+ * Copyright 2010-2018 Metafizzy
9
+ */
10
+
11
+ /**
12
+ * Bridget makes jQuery widgets
13
+ * v2.0.1
14
+ * MIT license
15
+ */
16
+
17
+ /* jshint browser: true, strict: true, undef: true, unused: true */
18
+
19
+ ( function( window, factory ) {
20
+ // universal module definition
21
+ /*jshint strict: false */ /* globals define, module, require */
22
+ if ( typeof define == 'function' && define.amd ) {
23
+ // AMD
24
+ define( 'jquery-bridget/jquery-bridget',[ 'jquery' ], function( jQuery ) {
25
+ return factory( window, jQuery );
26
+ });
27
+ } else if ( typeof module == 'object' && module.exports ) {
28
+ // CommonJS
29
+ module.exports = factory(
30
+ window,
31
+ require('jquery')
32
+ );
33
+ } else {
34
+ // browser global
35
+ window.jQueryBridget = factory(
36
+ window,
37
+ window.jQuery
38
+ );
39
+ }
40
+
41
+ }( window, function factory( window, jQuery ) {
42
+ 'use strict';
43
+
44
+ // ----- utils ----- //
45
+
46
+ var arraySlice = Array.prototype.slice;
47
+
48
+ // helper function for logging errors
49
+ // $.error breaks jQuery chaining
50
+ var console = window.console;
51
+ var logError = typeof console == 'undefined' ? function() {} :
52
+ function( message ) {
53
+ console.error( message );
54
+ };
55
+
56
+ // ----- jQueryBridget ----- //
57
+
58
+ function jQueryBridget( namespace, PluginClass, $ ) {
59
+ $ = $ || jQuery || window.jQuery;
60
+ if ( !$ ) {
61
+ return;
62
+ }
63
+
64
+ // add option method -> $().plugin('option', {...})
65
+ if ( !PluginClass.prototype.option ) {
66
+ // option setter
67
+ PluginClass.prototype.option = function( opts ) {
68
+ // bail out if not an object
69
+ if ( !$.isPlainObject( opts ) ){
70
+ return;
71
+ }
72
+ this.options = $.extend( true, this.options, opts );
73
+ };
74
+ }
75
+
76
+ // make jQuery plugin
77
+ $.fn[ namespace ] = function( arg0 /*, arg1 */ ) {
78
+ if ( typeof arg0 == 'string' ) {
79
+ // method call $().plugin( 'methodName', { options } )
80
+ // shift arguments by 1
81
+ var args = arraySlice.call( arguments, 1 );
82
+ return methodCall( this, arg0, args );
83
+ }
84
+ // just $().plugin({ options })
85
+ plainCall( this, arg0 );
86
+ return this;
87
+ };
88
+
89
+ // $().plugin('methodName')
90
+ function methodCall( $elems, methodName, args ) {
91
+ var returnValue;
92
+ var pluginMethodStr = '$().' + namespace + '("' + methodName + '")';
93
+
94
+ $elems.each( function( i, elem ) {
95
+ // get instance
96
+ var instance = $.data( elem, namespace );
97
+ if ( !instance ) {
98
+ logError( namespace + ' not initialized. Cannot call methods, i.e. ' +
99
+ pluginMethodStr );
100
+ return;
101
+ }
102
+
103
+ var method = instance[ methodName ];
104
+ if ( !method || methodName.charAt(0) == '_' ) {
105
+ logError( pluginMethodStr + ' is not a valid method' );
106
+ return;
107
+ }
108
+
109
+ // apply method, get return value
110
+ var value = method.apply( instance, args );
111
+ // set return value if value is returned, use only first value
112
+ returnValue = returnValue === undefined ? value : returnValue;
113
+ });
114
+
115
+ return returnValue !== undefined ? returnValue : $elems;
116
+ }
117
+
118
+ function plainCall( $elems, options ) {
119
+ $elems.each( function( i, elem ) {
120
+ var instance = $.data( elem, namespace );
121
+ if ( instance ) {
122
+ // set options & init
123
+ instance.option( options );
124
+ instance._init();
125
+ } else {
126
+ // initialize new instance
127
+ instance = new PluginClass( elem, options );
128
+ $.data( elem, namespace, instance );
129
+ }
130
+ });
131
+ }
132
+
133
+ updateJQuery( $ );
134
+
135
+ }
136
+
137
+ // ----- updateJQuery ----- //
138
+
139
+ // set $.bridget for v1 backwards compatibility
140
+ function updateJQuery( $ ) {
141
+ if ( !$ || ( $ && $.bridget ) ) {
142
+ return;
143
+ }
144
+ $.bridget = jQueryBridget;
145
+ }
146
+
147
+ updateJQuery( jQuery || window.jQuery );
148
+
149
+ // ----- ----- //
150
+
151
+ return jQueryBridget;
152
+
153
+ }));
154
+
155
+ /**
156
+ * EvEmitter v1.1.0
157
+ * Lil' event emitter
158
+ * MIT License
159
+ */
160
+
161
+ /* jshint unused: true, undef: true, strict: true */
162
+
163
+ ( function( global, factory ) {
164
+ // universal module definition
165
+ /* jshint strict: false */ /* globals define, module, window */
166
+ if ( typeof define == 'function' && define.amd ) {
167
+ // AMD - RequireJS
168
+ define( 'ev-emitter/ev-emitter',factory );
169
+ } else if ( typeof module == 'object' && module.exports ) {
170
+ // CommonJS - Browserify, Webpack
171
+ module.exports = factory();
172
+ } else {
173
+ // Browser globals
174
+ global.EvEmitter = factory();
175
+ }
176
+
177
+ }( typeof window != 'undefined' ? window : this, function() {
178
+
179
+
180
+
181
+ function EvEmitter() {}
182
+
183
+ var proto = EvEmitter.prototype;
184
+
185
+ proto.on = function( eventName, listener ) {
186
+ if ( !eventName || !listener ) {
187
+ return;
188
+ }
189
+ // set events hash
190
+ var events = this._events = this._events || {};
191
+ // set listeners array
192
+ var listeners = events[ eventName ] = events[ eventName ] || [];
193
+ // only add once
194
+ if ( listeners.indexOf( listener ) == -1 ) {
195
+ listeners.push( listener );
196
+ }
197
+
198
+ return this;
199
+ };
200
+
201
+ proto.once = function( eventName, listener ) {
202
+ if ( !eventName || !listener ) {
203
+ return;
204
+ }
205
+ // add event
206
+ this.on( eventName, listener );
207
+ // set once flag
208
+ // set onceEvents hash
209
+ var onceEvents = this._onceEvents = this._onceEvents || {};
210
+ // set onceListeners object
211
+ var onceListeners = onceEvents[ eventName ] = onceEvents[ eventName ] || {};
212
+ // set flag
213
+ onceListeners[ listener ] = true;
214
+
215
+ return this;
216
+ };
217
+
218
+ proto.off = function( eventName, listener ) {
219
+ var listeners = this._events && this._events[ eventName ];
220
+ if ( !listeners || !listeners.length ) {
221
+ return;
222
+ }
223
+ var index = listeners.indexOf( listener );
224
+ if ( index != -1 ) {
225
+ listeners.splice( index, 1 );
226
+ }
227
+
228
+ return this;
229
+ };
230
+
231
+ proto.emitEvent = function( eventName, args ) {
232
+ var listeners = this._events && this._events[ eventName ];
233
+ if ( !listeners || !listeners.length ) {
234
+ return;
235
+ }
236
+ // copy over to avoid interference if .off() in listener
237
+ listeners = listeners.slice(0);
238
+ args = args || [];
239
+ // once stuff
240
+ var onceListeners = this._onceEvents && this._onceEvents[ eventName ];
241
+
242
+ for ( var i=0; i < listeners.length; i++ ) {
243
+ var listener = listeners[i]
244
+ var isOnce = onceListeners && onceListeners[ listener ];
245
+ if ( isOnce ) {
246
+ // remove listener
247
+ // remove before trigger to prevent recursion
248
+ this.off( eventName, listener );
249
+ // unset once flag
250
+ delete onceListeners[ listener ];
251
+ }
252
+ // trigger listener
253
+ listener.apply( this, args );
254
+ }
255
+
256
+ return this;
257
+ };
258
+
259
+ proto.allOff = function() {
260
+ delete this._events;
261
+ delete this._onceEvents;
262
+ };
263
+
264
+ return EvEmitter;
265
+
266
+ }));
267
+
268
+ /*!
269
+ * getSize v2.0.3
270
+ * measure size of elements
271
+ * MIT license
272
+ */
273
+
274
+ /* jshint browser: true, strict: true, undef: true, unused: true */
275
+ /* globals console: false */
276
+
277
+ ( function( window, factory ) {
278
+ /* jshint strict: false */ /* globals define, module */
279
+ if ( typeof define == 'function' && define.amd ) {
280
+ // AMD
281
+ define( 'get-size/get-size',factory );
282
+ } else if ( typeof module == 'object' && module.exports ) {
283
+ // CommonJS
284
+ module.exports = factory();
285
+ } else {
286
+ // browser global
287
+ window.getSize = factory();
288
+ }
289
+
290
+ })( window, function factory() {
291
+ 'use strict';
292
+
293
+ // -------------------------- helpers -------------------------- //
294
+
295
+ // get a number from a string, not a percentage
296
+ function getStyleSize( value ) {
297
+ var num = parseFloat( value );
298
+ // not a percent like '100%', and a number
299
+ var isValid = value.indexOf('%') == -1 && !isNaN( num );
300
+ return isValid && num;
301
+ }
302
+
303
+ function noop() {}
304
+
305
+ var logError = typeof console == 'undefined' ? noop :
306
+ function( message ) {
307
+ console.error( message );
308
+ };
309
+
310
+ // -------------------------- measurements -------------------------- //
311
+
312
+ var measurements = [
313
+ 'paddingLeft',
314
+ 'paddingRight',
315
+ 'paddingTop',
316
+ 'paddingBottom',
317
+ 'marginLeft',
318
+ 'marginRight',
319
+ 'marginTop',
320
+ 'marginBottom',
321
+ 'borderLeftWidth',
322
+ 'borderRightWidth',
323
+ 'borderTopWidth',
324
+ 'borderBottomWidth'
325
+ ];
326
+
327
+ var measurementsLength = measurements.length;
328
+
329
+ function getZeroSize() {
330
+ var size = {
331
+ width: 0,
332
+ height: 0,
333
+ innerWidth: 0,
334
+ innerHeight: 0,
335
+ outerWidth: 0,
336
+ outerHeight: 0
337
+ };
338
+ for ( var i=0; i < measurementsLength; i++ ) {
339
+ var measurement = measurements[i];
340
+ size[ measurement ] = 0;
341
+ }
342
+ return size;
343
+ }
344
+
345
+ // -------------------------- getStyle -------------------------- //
346
+
347
+ /**
348
+ * getStyle, get style of element, check for Firefox bug
349
+ * https://bugzilla.mozilla.org/show_bug.cgi?id=548397
350
+ */
351
+ function getStyle( elem ) {
352
+ var style = getComputedStyle( elem );
353
+ if ( !style ) {
354
+ logError( 'Style returned ' + style +
355
+ '. Are you running this code in a hidden iframe on Firefox? ' +
356
+ 'See https://bit.ly/getsizebug1' );
357
+ }
358
+ return style;
359
+ }
360
+
361
+ // -------------------------- setup -------------------------- //
362
+
363
+ var isSetup = false;
364
+
365
+ var isBoxSizeOuter;
366
+
367
+ /**
368
+ * setup
369
+ * check isBoxSizerOuter
370
+ * do on first getSize() rather than on page load for Firefox bug
371
+ */
372
+ function setup() {
373
+ // setup once
374
+ if ( isSetup ) {
375
+ return;
376
+ }
377
+ isSetup = true;
378
+
379
+ // -------------------------- box sizing -------------------------- //
380
+
381
+ /**
382
+ * Chrome & Safari measure the outer-width on style.width on border-box elems
383
+ * IE11 & Firefox<29 measures the inner-width
384
+ */
385
+ var div = document.createElement('div');
386
+ div.style.width = '200px';
387
+ div.style.padding = '1px 2px 3px 4px';
388
+ div.style.borderStyle = 'solid';
389
+ div.style.borderWidth = '1px 2px 3px 4px';
390
+ div.style.boxSizing = 'border-box';
391
+
392
+ var body = document.body || document.documentElement;
393
+ body.appendChild( div );
394
+ var style = getStyle( div );
395
+ // round value for browser zoom. desandro/masonry#928
396
+ isBoxSizeOuter = Math.round( getStyleSize( style.width ) ) == 200;
397
+ getSize.isBoxSizeOuter = isBoxSizeOuter;
398
+
399
+ body.removeChild( div );
400
+ }
401
+
402
+ // -------------------------- getSize -------------------------- //
403
+
404
+ function getSize( elem ) {
405
+ setup();
406
+
407
+ // use querySeletor if elem is string
408
+ if ( typeof elem == 'string' ) {
409
+ elem = document.querySelector( elem );
410
+ }
411
+
412
+ // do not proceed on non-objects
413
+ if ( !elem || typeof elem != 'object' || !elem.nodeType ) {
414
+ return;
415
+ }
416
+
417
+ var style = getStyle( elem );
418
+
419
+ // if hidden, everything is 0
420
+ if ( style.display == 'none' ) {
421
+ return getZeroSize();
422
+ }
423
+
424
+ var size = {};
425
+ size.width = elem.offsetWidth;
426
+ size.height = elem.offsetHeight;
427
+
428
+ var isBorderBox = size.isBorderBox = style.boxSizing == 'border-box';
429
+
430
+ // get all measurements
431
+ for ( var i=0; i < measurementsLength; i++ ) {
432
+ var measurement = measurements[i];
433
+ var value = style[ measurement ];
434
+ var num = parseFloat( value );
435
+ // any 'auto', 'medium' value will be 0
436
+ size[ measurement ] = !isNaN( num ) ? num : 0;
437
+ }
438
+
439
+ var paddingWidth = size.paddingLeft + size.paddingRight;
440
+ var paddingHeight = size.paddingTop + size.paddingBottom;
441
+ var marginWidth = size.marginLeft + size.marginRight;
442
+ var marginHeight = size.marginTop + size.marginBottom;
443
+ var borderWidth = size.borderLeftWidth + size.borderRightWidth;
444
+ var borderHeight = size.borderTopWidth + size.borderBottomWidth;
445
+
446
+ var isBorderBoxSizeOuter = isBorderBox && isBoxSizeOuter;
447
+
448
+ // overwrite width and height if we can get it from style
449
+ var styleWidth = getStyleSize( style.width );
450
+ if ( styleWidth !== false ) {
451
+ size.width = styleWidth +
452
+ // add padding and border unless it's already including it
453
+ ( isBorderBoxSizeOuter ? 0 : paddingWidth + borderWidth );
454
+ }
455
+
456
+ var styleHeight = getStyleSize( style.height );
457
+ if ( styleHeight !== false ) {
458
+ size.height = styleHeight +
459
+ // add padding and border unless it's already including it
460
+ ( isBorderBoxSizeOuter ? 0 : paddingHeight + borderHeight );
461
+ }
462
+
463
+ size.innerWidth = size.width - ( paddingWidth + borderWidth );
464
+ size.innerHeight = size.height - ( paddingHeight + borderHeight );
465
+
466
+ size.outerWidth = size.width + marginWidth;
467
+ size.outerHeight = size.height + marginHeight;
468
+
469
+ return size;
470
+ }
471
+
472
+ return getSize;
473
+
474
+ });
475
+
476
+ /**
477
+ * matchesSelector v2.0.2
478
+ * matchesSelector( element, '.selector' )
479
+ * MIT license
480
+ */
481
+
482
+ /*jshint browser: true, strict: true, undef: true, unused: true */
483
+
484
+ ( function( window, factory ) {
485
+ /*global define: false, module: false */
486
+ 'use strict';
487
+ // universal module definition
488
+ if ( typeof define == 'function' && define.amd ) {
489
+ // AMD
490
+ define( 'desandro-matches-selector/matches-selector',factory );
491
+ } else if ( typeof module == 'object' && module.exports ) {
492
+ // CommonJS
493
+ module.exports = factory();
494
+ } else {
495
+ // browser global
496
+ window.matchesSelector = factory();
497
+ }
498
+
499
+ }( window, function factory() {
500
+ 'use strict';
501
+
502
+ var matchesMethod = ( function() {
503
+ var ElemProto = window.Element.prototype;
504
+ // check for the standard method name first
505
+ if ( ElemProto.matches ) {
506
+ return 'matches';
507
+ }
508
+ // check un-prefixed
509
+ if ( ElemProto.matchesSelector ) {
510
+ return 'matchesSelector';
511
+ }
512
+ // check vendor prefixes
513
+ var prefixes = [ 'webkit', 'moz', 'ms', 'o' ];
514
+
515
+ for ( var i=0; i < prefixes.length; i++ ) {
516
+ var prefix = prefixes[i];
517
+ var method = prefix + 'MatchesSelector';
518
+ if ( ElemProto[ method ] ) {
519
+ return method;
520
+ }
521
+ }
522
+ })();
523
+
524
+ return function matchesSelector( elem, selector ) {
525
+ return elem[ matchesMethod ]( selector );
526
+ };
527
+
528
+ }));
529
+
530
+ /**
531
+ * Fizzy UI utils v2.0.7
532
+ * MIT license
533
+ */
534
+
535
+ /*jshint browser: true, undef: true, unused: true, strict: true */
536
+
537
+ ( function( window, factory ) {
538
+ // universal module definition
539
+ /*jshint strict: false */ /*globals define, module, require */
540
+
541
+ if ( typeof define == 'function' && define.amd ) {
542
+ // AMD
543
+ define( 'fizzy-ui-utils/utils',[
544
+ 'desandro-matches-selector/matches-selector'
545
+ ], function( matchesSelector ) {
546
+ return factory( window, matchesSelector );
547
+ });
548
+ } else if ( typeof module == 'object' && module.exports ) {
549
+ // CommonJS
550
+ module.exports = factory(
551
+ window,
552
+ require('desandro-matches-selector')
553
+ );
554
+ } else {
555
+ // browser global
556
+ window.fizzyUIUtils = factory(
557
+ window,
558
+ window.matchesSelector
559
+ );
560
+ }
561
+
562
+ }( window, function factory( window, matchesSelector ) {
563
+
564
+
565
+
566
+ var utils = {};
567
+
568
+ // ----- extend ----- //
569
+
570
+ // extends objects
571
+ utils.extend = function( a, b ) {
572
+ for ( var prop in b ) {
573
+ a[ prop ] = b[ prop ];
574
+ }
575
+ return a;
576
+ };
577
+
578
+ // ----- modulo ----- //
579
+
580
+ utils.modulo = function( num, div ) {
581
+ return ( ( num % div ) + div ) % div;
582
+ };
583
+
584
+ // ----- makeArray ----- //
585
+
586
+ var arraySlice = Array.prototype.slice;
587
+
588
+ // turn element or nodeList into an array
589
+ utils.makeArray = function( obj ) {
590
+ if ( Array.isArray( obj ) ) {
591
+ // use object if already an array
592
+ return obj;
593
+ }
594
+ // return empty array if undefined or null. #6
595
+ if ( obj === null || obj === undefined ) {
596
+ return [];
597
+ }
598
+
599
+ var isArrayLike = typeof obj == 'object' && typeof obj.length == 'number';
600
+ if ( isArrayLike ) {
601
+ // convert nodeList to array
602
+ return arraySlice.call( obj );
603
+ }
604
+
605
+ // array of single index
606
+ return [ obj ];
607
+ };
608
+
609
+ // ----- removeFrom ----- //
610
+
611
+ utils.removeFrom = function( ary, obj ) {
612
+ var index = ary.indexOf( obj );
613
+ if ( index != -1 ) {
614
+ ary.splice( index, 1 );
615
+ }
616
+ };
617
+
618
+ // ----- getParent ----- //
619
+
620
+ utils.getParent = function( elem, selector ) {
621
+ while ( elem.parentNode && elem != document.body ) {
622
+ elem = elem.parentNode;
623
+ if ( matchesSelector( elem, selector ) ) {
624
+ return elem;
625
+ }
626
+ }
627
+ };
628
+
629
+ // ----- getQueryElement ----- //
630
+
631
+ // use element as selector string
632
+ utils.getQueryElement = function( elem ) {
633
+ if ( typeof elem == 'string' ) {
634
+ return document.querySelector( elem );
635
+ }
636
+ return elem;
637
+ };
638
+
639
+ // ----- handleEvent ----- //
640
+
641
+ // enable .ontype to trigger from .addEventListener( elem, 'type' )
642
+ utils.handleEvent = function( event ) {
643
+ var method = 'on' + event.type;
644
+ if ( this[ method ] ) {
645
+ this[ method ]( event );
646
+ }
647
+ };
648
+
649
+ // ----- filterFindElements ----- //
650
+
651
+ utils.filterFindElements = function( elems, selector ) {
652
+ // make array of elems
653
+ elems = utils.makeArray( elems );
654
+ var ffElems = [];
655
+
656
+ elems.forEach( function( elem ) {
657
+ // check that elem is an actual element
658
+ if ( !( elem instanceof HTMLElement ) ) {
659
+ return;
660
+ }
661
+ // add elem if no selector
662
+ if ( !selector ) {
663
+ ffElems.push( elem );
664
+ return;
665
+ }
666
+ // filter & find items if we have a selector
667
+ // filter
668
+ if ( matchesSelector( elem, selector ) ) {
669
+ ffElems.push( elem );
670
+ }
671
+ // find children
672
+ var childElems = elem.querySelectorAll( selector );
673
+ // concat childElems to filterFound array
674
+ for ( var i=0; i < childElems.length; i++ ) {
675
+ ffElems.push( childElems[i] );
676
+ }
677
+ });
678
+
679
+ return ffElems;
680
+ };
681
+
682
+ // ----- debounceMethod ----- //
683
+
684
+ utils.debounceMethod = function( _class, methodName, threshold ) {
685
+ threshold = threshold || 100;
686
+ // original method
687
+ var method = _class.prototype[ methodName ];
688
+ var timeoutName = methodName + 'Timeout';
689
+
690
+ _class.prototype[ methodName ] = function() {
691
+ var timeout = this[ timeoutName ];
692
+ clearTimeout( timeout );
693
+
694
+ var args = arguments;
695
+ var _this = this;
696
+ this[ timeoutName ] = setTimeout( function() {
697
+ method.apply( _this, args );
698
+ delete _this[ timeoutName ];
699
+ }, threshold );
700
+ };
701
+ };
702
+
703
+ // ----- docReady ----- //
704
+
705
+ utils.docReady = function( callback ) {
706
+ var readyState = document.readyState;
707
+ if ( readyState == 'complete' || readyState == 'interactive' ) {
708
+ // do async to allow for other scripts to run. metafizzy/flickity#441
709
+ setTimeout( callback );
710
+ } else {
711
+ document.addEventListener( 'DOMContentLoaded', callback );
712
+ }
713
+ };
714
+
715
+ // ----- htmlInit ----- //
716
+
717
+ // http://jamesroberts.name/blog/2010/02/22/string-functions-for-javascript-trim-to-camel-case-to-dashed-and-to-underscore/
718
+ utils.toDashed = function( str ) {
719
+ return str.replace( /(.)([A-Z])/g, function( match, $1, $2 ) {
720
+ return $1 + '-' + $2;
721
+ }).toLowerCase();
722
+ };
723
+
724
+ var console = window.console;
725
+ /**
726
+ * allow user to initialize classes via [data-namespace] or .js-namespace class
727
+ * htmlInit( Widget, 'widgetName' )
728
+ * options are parsed from data-namespace-options
729
+ */
730
+ utils.htmlInit = function( WidgetClass, namespace ) {
731
+ utils.docReady( function() {
732
+ var dashedNamespace = utils.toDashed( namespace );
733
+ var dataAttr = 'data-' + dashedNamespace;
734
+ var dataAttrElems = document.querySelectorAll( '[' + dataAttr + ']' );
735
+ var jsDashElems = document.querySelectorAll( '.js-' + dashedNamespace );
736
+ var elems = utils.makeArray( dataAttrElems )
737
+ .concat( utils.makeArray( jsDashElems ) );
738
+ var dataOptionsAttr = dataAttr + '-options';
739
+ var jQuery = window.jQuery;
740
+
741
+ elems.forEach( function( elem ) {
742
+ var attr = elem.getAttribute( dataAttr ) ||
743
+ elem.getAttribute( dataOptionsAttr );
744
+ var options;
745
+ try {
746
+ options = attr && JSON.parse( attr );
747
+ } catch ( error ) {
748
+ // log error, do not initialize
749
+ if ( console ) {
750
+ console.error( 'Error parsing ' + dataAttr + ' on ' + elem.className +
751
+ ': ' + error );
752
+ }
753
+ return;
754
+ }
755
+ // initialize
756
+ var instance = new WidgetClass( elem, options );
757
+ // make available via $().data('namespace')
758
+ if ( jQuery ) {
759
+ jQuery.data( elem, namespace, instance );
760
+ }
761
+ });
762
+
763
+ });
764
+ };
765
+
766
+ // ----- ----- //
767
+
768
+ return utils;
769
+
770
+ }));
771
+
772
+ /**
773
+ * Outlayer Item
774
+ */
775
+
776
+ ( function( window, factory ) {
777
+ // universal module definition
778
+ /* jshint strict: false */ /* globals define, module, require */
779
+ if ( typeof define == 'function' && define.amd ) {
780
+ // AMD - RequireJS
781
+ define( 'outlayer/item',[
782
+ 'ev-emitter/ev-emitter',
783
+ 'get-size/get-size'
784
+ ],
785
+ factory
786
+ );
787
+ } else if ( typeof module == 'object' && module.exports ) {
788
+ // CommonJS - Browserify, Webpack
789
+ module.exports = factory(
790
+ require('ev-emitter'),
791
+ require('get-size')
792
+ );
793
+ } else {
794
+ // browser global
795
+ window.Outlayer = {};
796
+ window.Outlayer.Item = factory(
797
+ window.EvEmitter,
798
+ window.getSize
799
+ );
800
+ }
801
+
802
+ }( window, function factory( EvEmitter, getSize ) {
803
+ 'use strict';
804
+
805
+ // ----- helpers ----- //
806
+
807
+ function isEmptyObj( obj ) {
808
+ for ( var prop in obj ) {
809
+ return false;
810
+ }
811
+ prop = null;
812
+ return true;
813
+ }
814
+
815
+ // -------------------------- CSS3 support -------------------------- //
816
+
817
+
818
+ var docElemStyle = document.documentElement.style;
819
+
820
+ var transitionProperty = typeof docElemStyle.transition == 'string' ?
821
+ 'transition' : 'WebkitTransition';
822
+ var transformProperty = typeof docElemStyle.transform == 'string' ?
823
+ 'transform' : 'WebkitTransform';
824
+
825
+ var transitionEndEvent = {
826
+ WebkitTransition: 'webkitTransitionEnd',
827
+ transition: 'transitionend'
828
+ }[ transitionProperty ];
829
+
830
+ // cache all vendor properties that could have vendor prefix
831
+ var vendorProperties = {
832
+ transform: transformProperty,
833
+ transition: transitionProperty,
834
+ transitionDuration: transitionProperty + 'Duration',
835
+ transitionProperty: transitionProperty + 'Property',
836
+ transitionDelay: transitionProperty + 'Delay'
837
+ };
838
+
839
+ // -------------------------- Item -------------------------- //
840
+
841
+ function Item( element, layout ) {
842
+ if ( !element ) {
843
+ return;
844
+ }
845
+
846
+ this.element = element;
847
+ // parent layout class, i.e. Masonry, Isotope, or Packery
848
+ this.layout = layout;
849
+ this.position = {
850
+ x: 0,
851
+ y: 0
852
+ };
853
+
854
+ this._create();
855
+ }
856
+
857
+ // inherit EvEmitter
858
+ var proto = Item.prototype = Object.create( EvEmitter.prototype );
859
+ proto.constructor = Item;
860
+
861
+ proto._create = function() {
862
+ // transition objects
863
+ this._transn = {
864
+ ingProperties: {},
865
+ clean: {},
866
+ onEnd: {}
867
+ };
868
+
869
+ this.css({
870
+ position: 'absolute'
871
+ });
872
+ };
873
+
874
+ // trigger specified handler for event type
875
+ proto.handleEvent = function( event ) {
876
+ var method = 'on' + event.type;
877
+ if ( this[ method ] ) {
878
+ this[ method ]( event );
879
+ }
880
+ };
881
+
882
+ proto.getSize = function() {
883
+ this.size = getSize( this.element );
884
+ };
885
+
886
+ /**
887
+ * apply CSS styles to element
888
+ * @param {Object} style
889
+ */
890
+ proto.css = function( style ) {
891
+ var elemStyle = this.element.style;
892
+
893
+ for ( var prop in style ) {
894
+ // use vendor property if available
895
+ var supportedProp = vendorProperties[ prop ] || prop;
896
+ elemStyle[ supportedProp ] = style[ prop ];
897
+ }
898
+ };
899
+
900
+ // measure position, and sets it
901
+ proto.getPosition = function() {
902
+ var style = getComputedStyle( this.element );
903
+ var isOriginLeft = this.layout._getOption('originLeft');
904
+ var isOriginTop = this.layout._getOption('originTop');
905
+ var xValue = style[ isOriginLeft ? 'left' : 'right' ];
906
+ var yValue = style[ isOriginTop ? 'top' : 'bottom' ];
907
+ var x = parseFloat( xValue );
908
+ var y = parseFloat( yValue );
909
+ // convert percent to pixels
910
+ var layoutSize = this.layout.size;
911
+ if ( xValue.indexOf('%') != -1 ) {
912
+ x = ( x / 100 ) * layoutSize.width;
913
+ }
914
+ if ( yValue.indexOf('%') != -1 ) {
915
+ y = ( y / 100 ) * layoutSize.height;
916
+ }
917
+ // clean up 'auto' or other non-integer values
918
+ x = isNaN( x ) ? 0 : x;
919
+ y = isNaN( y ) ? 0 : y;
920
+ // remove padding from measurement
921
+ x -= isOriginLeft ? layoutSize.paddingLeft : layoutSize.paddingRight;
922
+ y -= isOriginTop ? layoutSize.paddingTop : layoutSize.paddingBottom;
923
+
924
+ this.position.x = x;
925
+ this.position.y = y;
926
+ };
927
+
928
+ // set settled position, apply padding
929
+ proto.layoutPosition = function() {
930
+ var layoutSize = this.layout.size;
931
+ var style = {};
932
+ var isOriginLeft = this.layout._getOption('originLeft');
933
+ var isOriginTop = this.layout._getOption('originTop');
934
+
935
+ // x
936
+ var xPadding = isOriginLeft ? 'paddingLeft' : 'paddingRight';
937
+ var xProperty = isOriginLeft ? 'left' : 'right';
938
+ var xResetProperty = isOriginLeft ? 'right' : 'left';
939
+
940
+ var x = this.position.x + layoutSize[ xPadding ];
941
+ // set in percentage or pixels
942
+ style[ xProperty ] = this.getXValue( x );
943
+ // reset other property
944
+ style[ xResetProperty ] = '';
945
+
946
+ // y
947
+ var yPadding = isOriginTop ? 'paddingTop' : 'paddingBottom';
948
+ var yProperty = isOriginTop ? 'top' : 'bottom';
949
+ var yResetProperty = isOriginTop ? 'bottom' : 'top';
950
+
951
+ var y = this.position.y + layoutSize[ yPadding ];
952
+ // set in percentage or pixels
953
+ style[ yProperty ] = this.getYValue( y );
954
+ // reset other property
955
+ style[ yResetProperty ] = '';
956
+
957
+ this.css( style );
958
+ this.emitEvent( 'layout', [ this ] );
959
+ };
960
+
961
+ proto.getXValue = function( x ) {
962
+ var isHorizontal = this.layout._getOption('horizontal');
963
+ return this.layout.options.percentPosition && !isHorizontal ?
964
+ ( ( x / this.layout.size.width ) * 100 ) + '%' : x + 'px';
965
+ };
966
+
967
+ proto.getYValue = function( y ) {
968
+ var isHorizontal = this.layout._getOption('horizontal');
969
+ return this.layout.options.percentPosition && isHorizontal ?
970
+ ( ( y / this.layout.size.height ) * 100 ) + '%' : y + 'px';
971
+ };
972
+
973
+ proto._transitionTo = function( x, y ) {
974
+ this.getPosition();
975
+ // get current x & y from top/left
976
+ var curX = this.position.x;
977
+ var curY = this.position.y;
978
+
979
+ var didNotMove = x == this.position.x && y == this.position.y;
980
+
981
+ // save end position
982
+ this.setPosition( x, y );
983
+
984
+ // if did not move and not transitioning, just go to layout
985
+ if ( didNotMove && !this.isTransitioning ) {
986
+ this.layoutPosition();
987
+ return;
988
+ }
989
+
990
+ var transX = x - curX;
991
+ var transY = y - curY;
992
+ var transitionStyle = {};
993
+ transitionStyle.transform = this.getTranslate( transX, transY );
994
+
995
+ this.transition({
996
+ to: transitionStyle,
997
+ onTransitionEnd: {
998
+ transform: this.layoutPosition
999
+ },
1000
+ isCleaning: true
1001
+ });
1002
+ };
1003
+
1004
+ proto.getTranslate = function( x, y ) {
1005
+ // flip cooridinates if origin on right or bottom
1006
+ var isOriginLeft = this.layout._getOption('originLeft');
1007
+ var isOriginTop = this.layout._getOption('originTop');
1008
+ x = isOriginLeft ? x : -x;
1009
+ y = isOriginTop ? y : -y;
1010
+ return 'translate3d(' + x + 'px, ' + y + 'px, 0)';
1011
+ };
1012
+
1013
+ // non transition + transform support
1014
+ proto.goTo = function( x, y ) {
1015
+ this.setPosition( x, y );
1016
+ this.layoutPosition();
1017
+ };
1018
+
1019
+ proto.moveTo = proto._transitionTo;
1020
+
1021
+ proto.setPosition = function( x, y ) {
1022
+ this.position.x = parseFloat( x );
1023
+ this.position.y = parseFloat( y );
1024
+ };
1025
+
1026
+ // ----- transition ----- //
1027
+
1028
+ /**
1029
+ * @param {Object} style - CSS
1030
+ * @param {Function} onTransitionEnd
1031
+ */
1032
+
1033
+ // non transition, just trigger callback
1034
+ proto._nonTransition = function( args ) {
1035
+ this.css( args.to );
1036
+ if ( args.isCleaning ) {
1037
+ this._removeStyles( args.to );
1038
+ }
1039
+ for ( var prop in args.onTransitionEnd ) {
1040
+ args.onTransitionEnd[ prop ].call( this );
1041
+ }
1042
+ };
1043
+
1044
+ /**
1045
+ * proper transition
1046
+ * @param {Object} args - arguments
1047
+ * @param {Object} to - style to transition to
1048
+ * @param {Object} from - style to start transition from
1049
+ * @param {Boolean} isCleaning - removes transition styles after transition
1050
+ * @param {Function} onTransitionEnd - callback
1051
+ */
1052
+ proto.transition = function( args ) {
1053
+ // redirect to nonTransition if no transition duration
1054
+ if ( !parseFloat( this.layout.options.transitionDuration ) ) {
1055
+ this._nonTransition( args );
1056
+ return;
1057
+ }
1058
+
1059
+ var _transition = this._transn;
1060
+ // keep track of onTransitionEnd callback by css property
1061
+ for ( var prop in args.onTransitionEnd ) {
1062
+ _transition.onEnd[ prop ] = args.onTransitionEnd[ prop ];
1063
+ }
1064
+ // keep track of properties that are transitioning
1065
+ for ( prop in args.to ) {
1066
+ _transition.ingProperties[ prop ] = true;
1067
+ // keep track of properties to clean up when transition is done
1068
+ if ( args.isCleaning ) {
1069
+ _transition.clean[ prop ] = true;
1070
+ }
1071
+ }
1072
+
1073
+ // set from styles
1074
+ if ( args.from ) {
1075
+ this.css( args.from );
1076
+ // force redraw. http://blog.alexmaccaw.com/css-transitions
1077
+ var h = this.element.offsetHeight;
1078
+ // hack for JSHint to hush about unused var
1079
+ h = null;
1080
+ }
1081
+ // enable transition
1082
+ this.enableTransition( args.to );
1083
+ // set styles that are transitioning
1084
+ this.css( args.to );
1085
+
1086
+ this.isTransitioning = true;
1087
+
1088
+ };
1089
+
1090
+ // dash before all cap letters, including first for
1091
+ // WebkitTransform => -webkit-transform
1092
+ function toDashedAll( str ) {
1093
+ return str.replace( /([A-Z])/g, function( $1 ) {
1094
+ return '-' + $1.toLowerCase();
1095
+ });
1096
+ }
1097
+
1098
+ var transitionProps = 'opacity,' + toDashedAll( transformProperty );
1099
+
1100
+ proto.enableTransition = function(/* style */) {
1101
+ // HACK changing transitionProperty during a transition
1102
+ // will cause transition to jump
1103
+ if ( this.isTransitioning ) {
1104
+ return;
1105
+ }
1106
+
1107
+ // make `transition: foo, bar, baz` from style object
1108
+ // HACK un-comment this when enableTransition can work
1109
+ // while a transition is happening
1110
+ // var transitionValues = [];
1111
+ // for ( var prop in style ) {
1112
+ // // dash-ify camelCased properties like WebkitTransition
1113
+ // prop = vendorProperties[ prop ] || prop;
1114
+ // transitionValues.push( toDashedAll( prop ) );
1115
+ // }
1116
+ // munge number to millisecond, to match stagger
1117
+ var duration = this.layout.options.transitionDuration;
1118
+ duration = typeof duration == 'number' ? duration + 'ms' : duration;
1119
+ // enable transition styles
1120
+ this.css({
1121
+ transitionProperty: transitionProps,
1122
+ transitionDuration: duration,
1123
+ transitionDelay: this.staggerDelay || 0
1124
+ });
1125
+ // listen for transition end event
1126
+ this.element.addEventListener( transitionEndEvent, this, false );
1127
+ };
1128
+
1129
+ // ----- events ----- //
1130
+
1131
+ proto.onwebkitTransitionEnd = function( event ) {
1132
+ this.ontransitionend( event );
1133
+ };
1134
+
1135
+ proto.onotransitionend = function( event ) {
1136
+ this.ontransitionend( event );
1137
+ };
1138
+
1139
+ // properties that I munge to make my life easier
1140
+ var dashedVendorProperties = {
1141
+ '-webkit-transform': 'transform'
1142
+ };
1143
+
1144
+ proto.ontransitionend = function( event ) {
1145
+ // disregard bubbled events from children
1146
+ if ( event.target !== this.element ) {
1147
+ return;
1148
+ }
1149
+ var _transition = this._transn;
1150
+ // get property name of transitioned property, convert to prefix-free
1151
+ var propertyName = dashedVendorProperties[ event.propertyName ] || event.propertyName;
1152
+
1153
+ // remove property that has completed transitioning
1154
+ delete _transition.ingProperties[ propertyName ];
1155
+ // check if any properties are still transitioning
1156
+ if ( isEmptyObj( _transition.ingProperties ) ) {
1157
+ // all properties have completed transitioning
1158
+ this.disableTransition();
1159
+ }
1160
+ // clean style
1161
+ if ( propertyName in _transition.clean ) {
1162
+ // clean up style
1163
+ this.element.style[ event.propertyName ] = '';
1164
+ delete _transition.clean[ propertyName ];
1165
+ }
1166
+ // trigger onTransitionEnd callback
1167
+ if ( propertyName in _transition.onEnd ) {
1168
+ var onTransitionEnd = _transition.onEnd[ propertyName ];
1169
+ onTransitionEnd.call( this );
1170
+ delete _transition.onEnd[ propertyName ];
1171
+ }
1172
+
1173
+ this.emitEvent( 'transitionEnd', [ this ] );
1174
+ };
1175
+
1176
+ proto.disableTransition = function() {
1177
+ this.removeTransitionStyles();
1178
+ this.element.removeEventListener( transitionEndEvent, this, false );
1179
+ this.isTransitioning = false;
1180
+ };
1181
+
1182
+ /**
1183
+ * removes style property from element
1184
+ * @param {Object} style
1185
+ **/
1186
+ proto._removeStyles = function( style ) {
1187
+ // clean up transition styles
1188
+ var cleanStyle = {};
1189
+ for ( var prop in style ) {
1190
+ cleanStyle[ prop ] = '';
1191
+ }
1192
+ this.css( cleanStyle );
1193
+ };
1194
+
1195
+ var cleanTransitionStyle = {
1196
+ transitionProperty: '',
1197
+ transitionDuration: '',
1198
+ transitionDelay: ''
1199
+ };
1200
+
1201
+ proto.removeTransitionStyles = function() {
1202
+ // remove transition
1203
+ this.css( cleanTransitionStyle );
1204
+ };
1205
+
1206
+ // ----- stagger ----- //
1207
+
1208
+ proto.stagger = function( delay ) {
1209
+ delay = isNaN( delay ) ? 0 : delay;
1210
+ this.staggerDelay = delay + 'ms';
1211
+ };
1212
+
1213
+ // ----- show/hide/remove ----- //
1214
+
1215
+ // remove element from DOM
1216
+ proto.removeElem = function() {
1217
+ this.element.parentNode.removeChild( this.element );
1218
+ // remove display: none
1219
+ this.css({ display: '' });
1220
+ this.emitEvent( 'remove', [ this ] );
1221
+ };
1222
+
1223
+ proto.remove = function() {
1224
+ // just remove element if no transition support or no transition
1225
+ if ( !transitionProperty || !parseFloat( this.layout.options.transitionDuration ) ) {
1226
+ this.removeElem();
1227
+ return;
1228
+ }
1229
+
1230
+ // start transition
1231
+ this.once( 'transitionEnd', function() {
1232
+ this.removeElem();
1233
+ });
1234
+ this.hide();
1235
+ };
1236
+
1237
+ proto.reveal = function() {
1238
+ delete this.isHidden;
1239
+ // remove display: none
1240
+ this.css({ display: '' });
1241
+
1242
+ var options = this.layout.options;
1243
+
1244
+ var onTransitionEnd = {};
1245
+ var transitionEndProperty = this.getHideRevealTransitionEndProperty('visibleStyle');
1246
+ onTransitionEnd[ transitionEndProperty ] = this.onRevealTransitionEnd;
1247
+
1248
+ this.transition({
1249
+ from: options.hiddenStyle,
1250
+ to: options.visibleStyle,
1251
+ isCleaning: true,
1252
+ onTransitionEnd: onTransitionEnd
1253
+ });
1254
+ };
1255
+
1256
+ proto.onRevealTransitionEnd = function() {
1257
+ // check if still visible
1258
+ // during transition, item may have been hidden
1259
+ if ( !this.isHidden ) {
1260
+ this.emitEvent('reveal');
1261
+ }
1262
+ };
1263
+
1264
+ /**
1265
+ * get style property use for hide/reveal transition end
1266
+ * @param {String} styleProperty - hiddenStyle/visibleStyle
1267
+ * @returns {String}
1268
+ */
1269
+ proto.getHideRevealTransitionEndProperty = function( styleProperty ) {
1270
+ var optionStyle = this.layout.options[ styleProperty ];
1271
+ // use opacity
1272
+ if ( optionStyle.opacity ) {
1273
+ return 'opacity';
1274
+ }
1275
+ // get first property
1276
+ for ( var prop in optionStyle ) {
1277
+ return prop;
1278
+ }
1279
+ };
1280
+
1281
+ proto.hide = function() {
1282
+ // set flag
1283
+ this.isHidden = true;
1284
+ // remove display: none
1285
+ this.css({ display: '' });
1286
+
1287
+ var options = this.layout.options;
1288
+
1289
+ var onTransitionEnd = {};
1290
+ var transitionEndProperty = this.getHideRevealTransitionEndProperty('hiddenStyle');
1291
+ onTransitionEnd[ transitionEndProperty ] = this.onHideTransitionEnd;
1292
+
1293
+ this.transition({
1294
+ from: options.visibleStyle,
1295
+ to: options.hiddenStyle,
1296
+ // keep hidden stuff hidden
1297
+ isCleaning: true,
1298
+ onTransitionEnd: onTransitionEnd
1299
+ });
1300
+ };
1301
+
1302
+ proto.onHideTransitionEnd = function() {
1303
+ // check if still hidden
1304
+ // during transition, item may have been un-hidden
1305
+ if ( this.isHidden ) {
1306
+ this.css({ display: 'none' });
1307
+ this.emitEvent('hide');
1308
+ }
1309
+ };
1310
+
1311
+ proto.destroy = function() {
1312
+ this.css({
1313
+ position: '',
1314
+ left: '',
1315
+ right: '',
1316
+ top: '',
1317
+ bottom: '',
1318
+ transition: '',
1319
+ transform: ''
1320
+ });
1321
+ };
1322
+
1323
+ return Item;
1324
+
1325
+ }));
1326
+
1327
+ /*!
1328
+ * Outlayer v2.1.1
1329
+ * the brains and guts of a layout library
1330
+ * MIT license
1331
+ */
1332
+
1333
+ ( function( window, factory ) {
1334
+ 'use strict';
1335
+ // universal module definition
1336
+ /* jshint strict: false */ /* globals define, module, require */
1337
+ if ( typeof define == 'function' && define.amd ) {
1338
+ // AMD - RequireJS
1339
+ define( 'outlayer/outlayer',[
1340
+ 'ev-emitter/ev-emitter',
1341
+ 'get-size/get-size',
1342
+ 'fizzy-ui-utils/utils',
1343
+ './item'
1344
+ ],
1345
+ function( EvEmitter, getSize, utils, Item ) {
1346
+ return factory( window, EvEmitter, getSize, utils, Item);
1347
+ }
1348
+ );
1349
+ } else if ( typeof module == 'object' && module.exports ) {
1350
+ // CommonJS - Browserify, Webpack
1351
+ module.exports = factory(
1352
+ window,
1353
+ require('ev-emitter'),
1354
+ require('get-size'),
1355
+ require('fizzy-ui-utils'),
1356
+ require('./item')
1357
+ );
1358
+ } else {
1359
+ // browser global
1360
+ window.Outlayer = factory(
1361
+ window,
1362
+ window.EvEmitter,
1363
+ window.getSize,
1364
+ window.fizzyUIUtils,
1365
+ window.Outlayer.Item
1366
+ );
1367
+ }
1368
+
1369
+ }( window, function factory( window, EvEmitter, getSize, utils, Item ) {
1370
+ 'use strict';
1371
+
1372
+ // ----- vars ----- //
1373
+
1374
+ var console = window.console;
1375
+ var jQuery = window.jQuery;
1376
+ var noop = function() {};
1377
+
1378
+ // -------------------------- Outlayer -------------------------- //
1379
+
1380
+ // globally unique identifiers
1381
+ var GUID = 0;
1382
+ // internal store of all Outlayer intances
1383
+ var instances = {};
1384
+
1385
+
1386
+ /**
1387
+ * @param {Element, String} element
1388
+ * @param {Object} options
1389
+ * @constructor
1390
+ */
1391
+ function Outlayer( element, options ) {
1392
+ var queryElement = utils.getQueryElement( element );
1393
+ if ( !queryElement ) {
1394
+ if ( console ) {
1395
+ console.error( 'Bad element for ' + this.constructor.namespace +
1396
+ ': ' + ( queryElement || element ) );
1397
+ }
1398
+ return;
1399
+ }
1400
+ this.element = queryElement;
1401
+ // add jQuery
1402
+ if ( jQuery ) {
1403
+ this.$element = jQuery( this.element );
1404
+ }
1405
+
1406
+ // options
1407
+ this.options = utils.extend( {}, this.constructor.defaults );
1408
+ this.option( options );
1409
+
1410
+ // add id for Outlayer.getFromElement
1411
+ var id = ++GUID;
1412
+ this.element.outlayerGUID = id; // expando
1413
+ instances[ id ] = this; // associate via id
1414
+
1415
+ // kick it off
1416
+ this._create();
1417
+
1418
+ var isInitLayout = this._getOption('initLayout');
1419
+ if ( isInitLayout ) {
1420
+ this.layout();
1421
+ }
1422
+ }
1423
+
1424
+ // settings are for internal use only
1425
+ Outlayer.namespace = 'outlayer';
1426
+ Outlayer.Item = Item;
1427
+
1428
+ // default options
1429
+ Outlayer.defaults = {
1430
+ containerStyle: {
1431
+ position: 'relative'
1432
+ },
1433
+ initLayout: true,
1434
+ originLeft: true,
1435
+ originTop: true,
1436
+ resize: true,
1437
+ resizeContainer: true,
1438
+ // item options
1439
+ transitionDuration: '0.4s',
1440
+ hiddenStyle: {
1441
+ opacity: 0,
1442
+ transform: 'scale(0.001)'
1443
+ },
1444
+ visibleStyle: {
1445
+ opacity: 1,
1446
+ transform: 'scale(1)'
1447
+ }
1448
+ };
1449
+
1450
+ var proto = Outlayer.prototype;
1451
+ // inherit EvEmitter
1452
+ utils.extend( proto, EvEmitter.prototype );
1453
+
1454
+ /**
1455
+ * set options
1456
+ * @param {Object} opts
1457
+ */
1458
+ proto.option = function( opts ) {
1459
+ utils.extend( this.options, opts );
1460
+ };
1461
+
1462
+ /**
1463
+ * get backwards compatible option value, check old name
1464
+ */
1465
+ proto._getOption = function( option ) {
1466
+ var oldOption = this.constructor.compatOptions[ option ];
1467
+ return oldOption && this.options[ oldOption ] !== undefined ?
1468
+ this.options[ oldOption ] : this.options[ option ];
1469
+ };
1470
+
1471
+ Outlayer.compatOptions = {
1472
+ // currentName: oldName
1473
+ initLayout: 'isInitLayout',
1474
+ horizontal: 'isHorizontal',
1475
+ layoutInstant: 'isLayoutInstant',
1476
+ originLeft: 'isOriginLeft',
1477
+ originTop: 'isOriginTop',
1478
+ resize: 'isResizeBound',
1479
+ resizeContainer: 'isResizingContainer'
1480
+ };
1481
+
1482
+ proto._create = function() {
1483
+ // get items from children
1484
+ this.reloadItems();
1485
+ // elements that affect layout, but are not laid out
1486
+ this.stamps = [];
1487
+ this.stamp( this.options.stamp );
1488
+ // set container style
1489
+ utils.extend( this.element.style, this.options.containerStyle );
1490
+
1491
+ // bind resize method
1492
+ var canBindResize = this._getOption('resize');
1493
+ if ( canBindResize ) {
1494
+ this.bindResize();
1495
+ }
1496
+ };
1497
+
1498
+ // goes through all children again and gets bricks in proper order
1499
+ proto.reloadItems = function() {
1500
+ // collection of item elements
1501
+ this.items = this._itemize( this.element.children );
1502
+ };
1503
+
1504
+
1505
+ /**
1506
+ * turn elements into Outlayer.Items to be used in layout
1507
+ * @param {Array or NodeList or HTMLElement} elems
1508
+ * @returns {Array} items - collection of new Outlayer Items
1509
+ */
1510
+ proto._itemize = function( elems ) {
1511
+
1512
+ var itemElems = this._filterFindItemElements( elems );
1513
+ var Item = this.constructor.Item;
1514
+
1515
+ // create new Outlayer Items for collection
1516
+ var items = [];
1517
+ for ( var i=0; i < itemElems.length; i++ ) {
1518
+ var elem = itemElems[i];
1519
+ var item = new Item( elem, this );
1520
+ items.push( item );
1521
+ }
1522
+
1523
+ return items;
1524
+ };
1525
+
1526
+ /**
1527
+ * get item elements to be used in layout
1528
+ * @param {Array or NodeList or HTMLElement} elems
1529
+ * @returns {Array} items - item elements
1530
+ */
1531
+ proto._filterFindItemElements = function( elems ) {
1532
+ return utils.filterFindElements( elems, this.options.itemSelector );
1533
+ };
1534
+
1535
+ /**
1536
+ * getter method for getting item elements
1537
+ * @returns {Array} elems - collection of item elements
1538
+ */
1539
+ proto.getItemElements = function() {
1540
+ return this.items.map( function( item ) {
1541
+ return item.element;
1542
+ });
1543
+ };
1544
+
1545
+ // ----- init & layout ----- //
1546
+
1547
+ /**
1548
+ * lays out all items
1549
+ */
1550
+ proto.layout = function() {
1551
+ this._resetLayout();
1552
+ this._manageStamps();
1553
+
1554
+ // don't animate first layout
1555
+ var layoutInstant = this._getOption('layoutInstant');
1556
+ var isInstant = layoutInstant !== undefined ?
1557
+ layoutInstant : !this._isLayoutInited;
1558
+ this.layoutItems( this.items, isInstant );
1559
+
1560
+ // flag for initalized
1561
+ this._isLayoutInited = true;
1562
+ };
1563
+
1564
+ // _init is alias for layout
1565
+ proto._init = proto.layout;
1566
+
1567
+ /**
1568
+ * logic before any new layout
1569
+ */
1570
+ proto._resetLayout = function() {
1571
+ this.getSize();
1572
+ };
1573
+
1574
+
1575
+ proto.getSize = function() {
1576
+ this.size = getSize( this.element );
1577
+ };
1578
+
1579
+ /**
1580
+ * get measurement from option, for columnWidth, rowHeight, gutter
1581
+ * if option is String -> get element from selector string, & get size of element
1582
+ * if option is Element -> get size of element
1583
+ * else use option as a number
1584
+ *
1585
+ * @param {String} measurement
1586
+ * @param {String} size - width or height
1587
+ * @private
1588
+ */
1589
+ proto._getMeasurement = function( measurement, size ) {
1590
+ var option = this.options[ measurement ];
1591
+ var elem;
1592
+ if ( !option ) {
1593
+ // default to 0
1594
+ this[ measurement ] = 0;
1595
+ } else {
1596
+ // use option as an element
1597
+ if ( typeof option == 'string' ) {
1598
+ elem = this.element.querySelector( option );
1599
+ } else if ( option instanceof HTMLElement ) {
1600
+ elem = option;
1601
+ }
1602
+ // use size of element, if element
1603
+ this[ measurement ] = elem ? getSize( elem )[ size ] : option;
1604
+ }
1605
+ };
1606
+
1607
+ /**
1608
+ * layout a collection of item elements
1609
+ * @api public
1610
+ */
1611
+ proto.layoutItems = function( items, isInstant ) {
1612
+ items = this._getItemsForLayout( items );
1613
+
1614
+ this._layoutItems( items, isInstant );
1615
+
1616
+ this._postLayout();
1617
+ };
1618
+
1619
+ /**
1620
+ * get the items to be laid out
1621
+ * you may want to skip over some items
1622
+ * @param {Array} items
1623
+ * @returns {Array} items
1624
+ */
1625
+ proto._getItemsForLayout = function( items ) {
1626
+ return items.filter( function( item ) {
1627
+ return !item.isIgnored;
1628
+ });
1629
+ };
1630
+
1631
+ /**
1632
+ * layout items
1633
+ * @param {Array} items
1634
+ * @param {Boolean} isInstant
1635
+ */
1636
+ proto._layoutItems = function( items, isInstant ) {
1637
+ this._emitCompleteOnItems( 'layout', items );
1638
+
1639
+ if ( !items || !items.length ) {
1640
+ // no items, emit event with empty array
1641
+ return;
1642
+ }
1643
+
1644
+ var queue = [];
1645
+
1646
+ items.forEach( function( item ) {
1647
+ // get x/y object from method
1648
+ var position = this._getItemLayoutPosition( item );
1649
+ // enqueue
1650
+ position.item = item;
1651
+ position.isInstant = isInstant || item.isLayoutInstant;
1652
+ queue.push( position );
1653
+ }, this );
1654
+
1655
+ this._processLayoutQueue( queue );
1656
+ };
1657
+
1658
+ /**
1659
+ * get item layout position
1660
+ * @param {Outlayer.Item} item
1661
+ * @returns {Object} x and y position
1662
+ */
1663
+ proto._getItemLayoutPosition = function( /* item */ ) {
1664
+ return {
1665
+ x: 0,
1666
+ y: 0
1667
+ };
1668
+ };
1669
+
1670
+ /**
1671
+ * iterate over array and position each item
1672
+ * Reason being - separating this logic prevents 'layout invalidation'
1673
+ * thx @paul_irish
1674
+ * @param {Array} queue
1675
+ */
1676
+ proto._processLayoutQueue = function( queue ) {
1677
+ this.updateStagger();
1678
+ queue.forEach( function( obj, i ) {
1679
+ this._positionItem( obj.item, obj.x, obj.y, obj.isInstant, i );
1680
+ }, this );
1681
+ };
1682
+
1683
+ // set stagger from option in milliseconds number
1684
+ proto.updateStagger = function() {
1685
+ var stagger = this.options.stagger;
1686
+ if ( stagger === null || stagger === undefined ) {
1687
+ this.stagger = 0;
1688
+ return;
1689
+ }
1690
+ this.stagger = getMilliseconds( stagger );
1691
+ return this.stagger;
1692
+ };
1693
+
1694
+ /**
1695
+ * Sets position of item in DOM
1696
+ * @param {Outlayer.Item} item
1697
+ * @param {Number} x - horizontal position
1698
+ * @param {Number} y - vertical position
1699
+ * @param {Boolean} isInstant - disables transitions
1700
+ */
1701
+ proto._positionItem = function( item, x, y, isInstant, i ) {
1702
+ if ( isInstant ) {
1703
+ // if not transition, just set CSS
1704
+ item.goTo( x, y );
1705
+ } else {
1706
+ item.stagger( i * this.stagger );
1707
+ item.moveTo( x, y );
1708
+ }
1709
+ };
1710
+
1711
+ /**
1712
+ * Any logic you want to do after each layout,
1713
+ * i.e. size the container
1714
+ */
1715
+ proto._postLayout = function() {
1716
+ this.resizeContainer();
1717
+ };
1718
+
1719
+ proto.resizeContainer = function() {
1720
+ var isResizingContainer = this._getOption('resizeContainer');
1721
+ if ( !isResizingContainer ) {
1722
+ return;
1723
+ }
1724
+ var size = this._getContainerSize();
1725
+ if ( size ) {
1726
+ this._setContainerMeasure( size.width, true );
1727
+ this._setContainerMeasure( size.height, false );
1728
+ }
1729
+ };
1730
+
1731
+ /**
1732
+ * Sets width or height of container if returned
1733
+ * @returns {Object} size
1734
+ * @param {Number} width
1735
+ * @param {Number} height
1736
+ */
1737
+ proto._getContainerSize = noop;
1738
+
1739
+ /**
1740
+ * @param {Number} measure - size of width or height
1741
+ * @param {Boolean} isWidth
1742
+ */
1743
+ proto._setContainerMeasure = function( measure, isWidth ) {
1744
+ if ( measure === undefined ) {
1745
+ return;
1746
+ }
1747
+
1748
+ var elemSize = this.size;
1749
+ // add padding and border width if border box
1750
+ if ( elemSize.isBorderBox ) {
1751
+ measure += isWidth ? elemSize.paddingLeft + elemSize.paddingRight +
1752
+ elemSize.borderLeftWidth + elemSize.borderRightWidth :
1753
+ elemSize.paddingBottom + elemSize.paddingTop +
1754
+ elemSize.borderTopWidth + elemSize.borderBottomWidth;
1755
+ }
1756
+
1757
+ measure = Math.max( measure, 0 );
1758
+ this.element.style[ isWidth ? 'width' : 'height' ] = measure + 'px';
1759
+ };
1760
+
1761
+ /**
1762
+ * emit eventComplete on a collection of items events
1763
+ * @param {String} eventName
1764
+ * @param {Array} items - Outlayer.Items
1765
+ */
1766
+ proto._emitCompleteOnItems = function( eventName, items ) {
1767
+ var _this = this;
1768
+ function onComplete() {
1769
+ _this.dispatchEvent( eventName + 'Complete', null, [ items ] );
1770
+ }
1771
+
1772
+ var count = items.length;
1773
+ if ( !items || !count ) {
1774
+ onComplete();
1775
+ return;
1776
+ }
1777
+
1778
+ var doneCount = 0;
1779
+ function tick() {
1780
+ doneCount++;
1781
+ if ( doneCount == count ) {
1782
+ onComplete();
1783
+ }
1784
+ }
1785
+
1786
+ // bind callback
1787
+ items.forEach( function( item ) {
1788
+ item.once( eventName, tick );
1789
+ });
1790
+ };
1791
+
1792
+ /**
1793
+ * emits events via EvEmitter and jQuery events
1794
+ * @param {String} type - name of event
1795
+ * @param {Event} event - original event
1796
+ * @param {Array} args - extra arguments
1797
+ */
1798
+ proto.dispatchEvent = function( type, event, args ) {
1799
+ // add original event to arguments
1800
+ var emitArgs = event ? [ event ].concat( args ) : args;
1801
+ this.emitEvent( type, emitArgs );
1802
+
1803
+ if ( jQuery ) {
1804
+ // set this.$element
1805
+ this.$element = this.$element || jQuery( this.element );
1806
+ if ( event ) {
1807
+ // create jQuery event
1808
+ var $event = jQuery.Event( event );
1809
+ $event.type = type;
1810
+ this.$element.trigger( $event, args );
1811
+ } else {
1812
+ // just trigger with type if no event available
1813
+ this.$element.trigger( type, args );
1814
+ }
1815
+ }
1816
+ };
1817
+
1818
+ // -------------------------- ignore & stamps -------------------------- //
1819
+
1820
+
1821
+ /**
1822
+ * keep item in collection, but do not lay it out
1823
+ * ignored items do not get skipped in layout
1824
+ * @param {Element} elem
1825
+ */
1826
+ proto.ignore = function( elem ) {
1827
+ var item = this.getItem( elem );
1828
+ if ( item ) {
1829
+ item.isIgnored = true;
1830
+ }
1831
+ };
1832
+
1833
+ /**
1834
+ * return item to layout collection
1835
+ * @param {Element} elem
1836
+ */
1837
+ proto.unignore = function( elem ) {
1838
+ var item = this.getItem( elem );
1839
+ if ( item ) {
1840
+ delete item.isIgnored;
1841
+ }
1842
+ };
1843
+
1844
+ /**
1845
+ * adds elements to stamps
1846
+ * @param {NodeList, Array, Element, or String} elems
1847
+ */
1848
+ proto.stamp = function( elems ) {
1849
+ elems = this._find( elems );
1850
+ if ( !elems ) {
1851
+ return;
1852
+ }
1853
+
1854
+ this.stamps = this.stamps.concat( elems );
1855
+ // ignore
1856
+ elems.forEach( this.ignore, this );
1857
+ };
1858
+
1859
+ /**
1860
+ * removes elements to stamps
1861
+ * @param {NodeList, Array, or Element} elems
1862
+ */
1863
+ proto.unstamp = function( elems ) {
1864
+ elems = this._find( elems );
1865
+ if ( !elems ){
1866
+ return;
1867
+ }
1868
+
1869
+ elems.forEach( function( elem ) {
1870
+ // filter out removed stamp elements
1871
+ utils.removeFrom( this.stamps, elem );
1872
+ this.unignore( elem );
1873
+ }, this );
1874
+ };
1875
+
1876
+ /**
1877
+ * finds child elements
1878
+ * @param {NodeList, Array, Element, or String} elems
1879
+ * @returns {Array} elems
1880
+ */
1881
+ proto._find = function( elems ) {
1882
+ if ( !elems ) {
1883
+ return;
1884
+ }
1885
+ // if string, use argument as selector string
1886
+ if ( typeof elems == 'string' ) {
1887
+ elems = this.element.querySelectorAll( elems );
1888
+ }
1889
+ elems = utils.makeArray( elems );
1890
+ return elems;
1891
+ };
1892
+
1893
+ proto._manageStamps = function() {
1894
+ if ( !this.stamps || !this.stamps.length ) {
1895
+ return;
1896
+ }
1897
+
1898
+ this._getBoundingRect();
1899
+
1900
+ this.stamps.forEach( this._manageStamp, this );
1901
+ };
1902
+
1903
+ // update boundingLeft / Top
1904
+ proto._getBoundingRect = function() {
1905
+ // get bounding rect for container element
1906
+ var boundingRect = this.element.getBoundingClientRect();
1907
+ var size = this.size;
1908
+ this._boundingRect = {
1909
+ left: boundingRect.left + size.paddingLeft + size.borderLeftWidth,
1910
+ top: boundingRect.top + size.paddingTop + size.borderTopWidth,
1911
+ right: boundingRect.right - ( size.paddingRight + size.borderRightWidth ),
1912
+ bottom: boundingRect.bottom - ( size.paddingBottom + size.borderBottomWidth )
1913
+ };
1914
+ };
1915
+
1916
+ /**
1917
+ * @param {Element} stamp
1918
+ **/
1919
+ proto._manageStamp = noop;
1920
+
1921
+ /**
1922
+ * get x/y position of element relative to container element
1923
+ * @param {Element} elem
1924
+ * @returns {Object} offset - has left, top, right, bottom
1925
+ */
1926
+ proto._getElementOffset = function( elem ) {
1927
+ var boundingRect = elem.getBoundingClientRect();
1928
+ var thisRect = this._boundingRect;
1929
+ var size = getSize( elem );
1930
+ var offset = {
1931
+ left: boundingRect.left - thisRect.left - size.marginLeft,
1932
+ top: boundingRect.top - thisRect.top - size.marginTop,
1933
+ right: thisRect.right - boundingRect.right - size.marginRight,
1934
+ bottom: thisRect.bottom - boundingRect.bottom - size.marginBottom
1935
+ };
1936
+ return offset;
1937
+ };
1938
+
1939
+ // -------------------------- resize -------------------------- //
1940
+
1941
+ // enable event handlers for listeners
1942
+ // i.e. resize -> onresize
1943
+ proto.handleEvent = utils.handleEvent;
1944
+
1945
+ /**
1946
+ * Bind layout to window resizing
1947
+ */
1948
+ proto.bindResize = function() {
1949
+ window.addEventListener( 'resize', this );
1950
+ this.isResizeBound = true;
1951
+ };
1952
+
1953
+ /**
1954
+ * Unbind layout to window resizing
1955
+ */
1956
+ proto.unbindResize = function() {
1957
+ window.removeEventListener( 'resize', this );
1958
+ this.isResizeBound = false;
1959
+ };
1960
+
1961
+ proto.onresize = function() {
1962
+ this.resize();
1963
+ };
1964
+
1965
+ utils.debounceMethod( Outlayer, 'onresize', 100 );
1966
+
1967
+ proto.resize = function() {
1968
+ // don't trigger if size did not change
1969
+ // or if resize was unbound. See #9
1970
+ if ( !this.isResizeBound || !this.needsResizeLayout() ) {
1971
+ return;
1972
+ }
1973
+
1974
+ this.layout();
1975
+ };
1976
+
1977
+ /**
1978
+ * check if layout is needed post layout
1979
+ * @returns Boolean
1980
+ */
1981
+ proto.needsResizeLayout = function() {
1982
+ var size = getSize( this.element );
1983
+ // check that this.size and size are there
1984
+ // IE8 triggers resize on body size change, so they might not be
1985
+ var hasSizes = this.size && size;
1986
+ return hasSizes && size.innerWidth !== this.size.innerWidth;
1987
+ };
1988
+
1989
+ // -------------------------- methods -------------------------- //
1990
+
1991
+ /**
1992
+ * add items to Outlayer instance
1993
+ * @param {Array or NodeList or Element} elems
1994
+ * @returns {Array} items - Outlayer.Items
1995
+ **/
1996
+ proto.addItems = function( elems ) {
1997
+ var items = this._itemize( elems );
1998
+ // add items to collection
1999
+ if ( items.length ) {
2000
+ this.items = this.items.concat( items );
2001
+ }
2002
+ return items;
2003
+ };
2004
+
2005
+ /**
2006
+ * Layout newly-appended item elements
2007
+ * @param {Array or NodeList or Element} elems
2008
+ */
2009
+ proto.appended = function( elems ) {
2010
+ var items = this.addItems( elems );
2011
+ if ( !items.length ) {
2012
+ return;
2013
+ }
2014
+ // layout and reveal just the new items
2015
+ this.layoutItems( items, true );
2016
+ this.reveal( items );
2017
+ };
2018
+
2019
+ /**
2020
+ * Layout prepended elements
2021
+ * @param {Array or NodeList or Element} elems
2022
+ */
2023
+ proto.prepended = function( elems ) {
2024
+ var items = this._itemize( elems );
2025
+ if ( !items.length ) {
2026
+ return;
2027
+ }
2028
+ // add items to beginning of collection
2029
+ var previousItems = this.items.slice(0);
2030
+ this.items = items.concat( previousItems );
2031
+ // start new layout
2032
+ this._resetLayout();
2033
+ this._manageStamps();
2034
+ // layout new stuff without transition
2035
+ this.layoutItems( items, true );
2036
+ this.reveal( items );
2037
+ // layout previous items
2038
+ this.layoutItems( previousItems );
2039
+ };
2040
+
2041
+ /**
2042
+ * reveal a collection of items
2043
+ * @param {Array of Outlayer.Items} items
2044
+ */
2045
+ proto.reveal = function( items ) {
2046
+ this._emitCompleteOnItems( 'reveal', items );
2047
+ if ( !items || !items.length ) {
2048
+ return;
2049
+ }
2050
+ var stagger = this.updateStagger();
2051
+ items.forEach( function( item, i ) {
2052
+ item.stagger( i * stagger );
2053
+ item.reveal();
2054
+ });
2055
+ };
2056
+
2057
+ /**
2058
+ * hide a collection of items
2059
+ * @param {Array of Outlayer.Items} items
2060
+ */
2061
+ proto.hide = function( items ) {
2062
+ this._emitCompleteOnItems( 'hide', items );
2063
+ if ( !items || !items.length ) {
2064
+ return;
2065
+ }
2066
+ var stagger = this.updateStagger();
2067
+ items.forEach( function( item, i ) {
2068
+ item.stagger( i * stagger );
2069
+ item.hide();
2070
+ });
2071
+ };
2072
+
2073
+ /**
2074
+ * reveal item elements
2075
+ * @param {Array}, {Element}, {NodeList} items
2076
+ */
2077
+ proto.revealItemElements = function( elems ) {
2078
+ var items = this.getItems( elems );
2079
+ this.reveal( items );
2080
+ };
2081
+
2082
+ /**
2083
+ * hide item elements
2084
+ * @param {Array}, {Element}, {NodeList} items
2085
+ */
2086
+ proto.hideItemElements = function( elems ) {
2087
+ var items = this.getItems( elems );
2088
+ this.hide( items );
2089
+ };
2090
+
2091
+ /**
2092
+ * get Outlayer.Item, given an Element
2093
+ * @param {Element} elem
2094
+ * @param {Function} callback
2095
+ * @returns {Outlayer.Item} item
2096
+ */
2097
+ proto.getItem = function( elem ) {
2098
+ // loop through items to get the one that matches
2099
+ for ( var i=0; i < this.items.length; i++ ) {
2100
+ var item = this.items[i];
2101
+ if ( item.element == elem ) {
2102
+ // return item
2103
+ return item;
2104
+ }
2105
+ }
2106
+ };
2107
+
2108
+ /**
2109
+ * get collection of Outlayer.Items, given Elements
2110
+ * @param {Array} elems
2111
+ * @returns {Array} items - Outlayer.Items
2112
+ */
2113
+ proto.getItems = function( elems ) {
2114
+ elems = utils.makeArray( elems );
2115
+ var items = [];
2116
+ elems.forEach( function( elem ) {
2117
+ var item = this.getItem( elem );
2118
+ if ( item ) {
2119
+ items.push( item );
2120
+ }
2121
+ }, this );
2122
+
2123
+ return items;
2124
+ };
2125
+
2126
+ /**
2127
+ * remove element(s) from instance and DOM
2128
+ * @param {Array or NodeList or Element} elems
2129
+ */
2130
+ proto.remove = function( elems ) {
2131
+ var removeItems = this.getItems( elems );
2132
+
2133
+ this._emitCompleteOnItems( 'remove', removeItems );
2134
+
2135
+ // bail if no items to remove
2136
+ if ( !removeItems || !removeItems.length ) {
2137
+ return;
2138
+ }
2139
+
2140
+ removeItems.forEach( function( item ) {
2141
+ item.remove();
2142
+ // remove item from collection
2143
+ utils.removeFrom( this.items, item );
2144
+ }, this );
2145
+ };
2146
+
2147
+ // ----- destroy ----- //
2148
+
2149
+ // remove and disable Outlayer instance
2150
+ proto.destroy = function() {
2151
+ // clean up dynamic styles
2152
+ var style = this.element.style;
2153
+ style.height = '';
2154
+ style.position = '';
2155
+ style.width = '';
2156
+ // destroy items
2157
+ this.items.forEach( function( item ) {
2158
+ item.destroy();
2159
+ });
2160
+
2161
+ this.unbindResize();
2162
+
2163
+ var id = this.element.outlayerGUID;
2164
+ delete instances[ id ]; // remove reference to instance by id
2165
+ delete this.element.outlayerGUID;
2166
+ // remove data for jQuery
2167
+ if ( jQuery ) {
2168
+ jQuery.removeData( this.element, this.constructor.namespace );
2169
+ }
2170
+
2171
+ };
2172
+
2173
+ // -------------------------- data -------------------------- //
2174
+
2175
+ /**
2176
+ * get Outlayer instance from element
2177
+ * @param {Element} elem
2178
+ * @returns {Outlayer}
2179
+ */
2180
+ Outlayer.data = function( elem ) {
2181
+ elem = utils.getQueryElement( elem );
2182
+ var id = elem && elem.outlayerGUID;
2183
+ return id && instances[ id ];
2184
+ };
2185
+
2186
+
2187
+ // -------------------------- create Outlayer class -------------------------- //
2188
+
2189
+ /**
2190
+ * create a layout class
2191
+ * @param {String} namespace
2192
+ */
2193
+ Outlayer.create = function( namespace, options ) {
2194
+ // sub-class Outlayer
2195
+ var Layout = subclass( Outlayer );
2196
+ // apply new options and compatOptions
2197
+ Layout.defaults = utils.extend( {}, Outlayer.defaults );
2198
+ utils.extend( Layout.defaults, options );
2199
+ Layout.compatOptions = utils.extend( {}, Outlayer.compatOptions );
2200
+
2201
+ Layout.namespace = namespace;
2202
+
2203
+ Layout.data = Outlayer.data;
2204
+
2205
+ // sub-class Item
2206
+ Layout.Item = subclass( Item );
2207
+
2208
+ // -------------------------- declarative -------------------------- //
2209
+
2210
+ utils.htmlInit( Layout, namespace );
2211
+
2212
+ // -------------------------- jQuery bridge -------------------------- //
2213
+
2214
+ // make into jQuery plugin
2215
+ if ( jQuery && jQuery.bridget ) {
2216
+ jQuery.bridget( namespace, Layout );
2217
+ }
2218
+
2219
+ return Layout;
2220
+ };
2221
+
2222
+ function subclass( Parent ) {
2223
+ function SubClass() {
2224
+ Parent.apply( this, arguments );
2225
+ }
2226
+
2227
+ SubClass.prototype = Object.create( Parent.prototype );
2228
+ SubClass.prototype.constructor = SubClass;
2229
+
2230
+ return SubClass;
2231
+ }
2232
+
2233
+ // ----- helpers ----- //
2234
+
2235
+ // how many milliseconds are in each unit
2236
+ var msUnits = {
2237
+ ms: 1,
2238
+ s: 1000
2239
+ };
2240
+
2241
+ // munge time-like parameter into millisecond number
2242
+ // '0.4s' -> 40
2243
+ function getMilliseconds( time ) {
2244
+ if ( typeof time == 'number' ) {
2245
+ return time;
2246
+ }
2247
+ var matches = time.match( /(^\d*\.?\d*)(\w*)/ );
2248
+ var num = matches && matches[1];
2249
+ var unit = matches && matches[2];
2250
+ if ( !num.length ) {
2251
+ return 0;
2252
+ }
2253
+ num = parseFloat( num );
2254
+ var mult = msUnits[ unit ] || 1;
2255
+ return num * mult;
2256
+ }
2257
+
2258
+ // ----- fin ----- //
2259
+
2260
+ // back in global
2261
+ Outlayer.Item = Item;
2262
+
2263
+ return Outlayer;
2264
+
2265
+ }));
2266
+
2267
+ /**
2268
+ * Isotope Item
2269
+ **/
2270
+
2271
+ ( function( window, factory ) {
2272
+ // universal module definition
2273
+ /* jshint strict: false */ /*globals define, module, require */
2274
+ if ( typeof define == 'function' && define.amd ) {
2275
+ // AMD
2276
+ define( 'isotope-layout/js/item',[
2277
+ 'outlayer/outlayer'
2278
+ ],
2279
+ factory );
2280
+ } else if ( typeof module == 'object' && module.exports ) {
2281
+ // CommonJS
2282
+ module.exports = factory(
2283
+ require('outlayer')
2284
+ );
2285
+ } else {
2286
+ // browser global
2287
+ window.Isotope = window.Isotope || {};
2288
+ window.Isotope.Item = factory(
2289
+ window.Outlayer
2290
+ );
2291
+ }
2292
+
2293
+ }( window, function factory( Outlayer ) {
2294
+ 'use strict';
2295
+
2296
+ // -------------------------- Item -------------------------- //
2297
+
2298
+ // sub-class Outlayer Item
2299
+ function Item() {
2300
+ Outlayer.Item.apply( this, arguments );
2301
+ }
2302
+
2303
+ var proto = Item.prototype = Object.create( Outlayer.Item.prototype );
2304
+
2305
+ var _create = proto._create;
2306
+ proto._create = function() {
2307
+ // assign id, used for original-order sorting
2308
+ this.id = this.layout.itemGUID++;
2309
+ _create.call( this );
2310
+ this.sortData = {};
2311
+ };
2312
+
2313
+ proto.updateSortData = function() {
2314
+ if ( this.isIgnored ) {
2315
+ return;
2316
+ }
2317
+ // default sorters
2318
+ this.sortData.id = this.id;
2319
+ // for backward compatibility
2320
+ this.sortData['original-order'] = this.id;
2321
+ this.sortData.random = Math.random();
2322
+ // go thru getSortData obj and apply the sorters
2323
+ var getSortData = this.layout.options.getSortData;
2324
+ var sorters = this.layout._sorters;
2325
+ for ( var key in getSortData ) {
2326
+ var sorter = sorters[ key ];
2327
+ this.sortData[ key ] = sorter( this.element, this );
2328
+ }
2329
+ };
2330
+
2331
+ var _destroy = proto.destroy;
2332
+ proto.destroy = function() {
2333
+ // call super
2334
+ _destroy.apply( this, arguments );
2335
+ // reset display, #741
2336
+ this.css({
2337
+ display: ''
2338
+ });
2339
+ };
2340
+
2341
+ return Item;
2342
+
2343
+ }));
2344
+
2345
+ /**
2346
+ * Isotope LayoutMode
2347
+ */
2348
+
2349
+ ( function( window, factory ) {
2350
+ // universal module definition
2351
+ /* jshint strict: false */ /*globals define, module, require */
2352
+ if ( typeof define == 'function' && define.amd ) {
2353
+ // AMD
2354
+ define( 'isotope-layout/js/layout-mode',[
2355
+ 'get-size/get-size',
2356
+ 'outlayer/outlayer'
2357
+ ],
2358
+ factory );
2359
+ } else if ( typeof module == 'object' && module.exports ) {
2360
+ // CommonJS
2361
+ module.exports = factory(
2362
+ require('get-size'),
2363
+ require('outlayer')
2364
+ );
2365
+ } else {
2366
+ // browser global
2367
+ window.Isotope = window.Isotope || {};
2368
+ window.Isotope.LayoutMode = factory(
2369
+ window.getSize,
2370
+ window.Outlayer
2371
+ );
2372
+ }
2373
+
2374
+ }( window, function factory( getSize, Outlayer ) {
2375
+ 'use strict';
2376
+
2377
+ // layout mode class
2378
+ function LayoutMode( isotope ) {
2379
+ this.isotope = isotope;
2380
+ // link properties
2381
+ if ( isotope ) {
2382
+ this.options = isotope.options[ this.namespace ];
2383
+ this.element = isotope.element;
2384
+ this.items = isotope.filteredItems;
2385
+ this.size = isotope.size;
2386
+ }
2387
+ }
2388
+
2389
+ var proto = LayoutMode.prototype;
2390
+
2391
+ /**
2392
+ * some methods should just defer to default Outlayer method
2393
+ * and reference the Isotope instance as `this`
2394
+ **/
2395
+ var facadeMethods = [
2396
+ '_resetLayout',
2397
+ '_getItemLayoutPosition',
2398
+ '_manageStamp',
2399
+ '_getContainerSize',
2400
+ '_getElementOffset',
2401
+ 'needsResizeLayout',
2402
+ '_getOption'
2403
+ ];
2404
+
2405
+ facadeMethods.forEach( function( methodName ) {
2406
+ proto[ methodName ] = function() {
2407
+ return Outlayer.prototype[ methodName ].apply( this.isotope, arguments );
2408
+ };
2409
+ });
2410
+
2411
+ // ----- ----- //
2412
+
2413
+ // for horizontal layout modes, check vertical size
2414
+ proto.needsVerticalResizeLayout = function() {
2415
+ // don't trigger if size did not change
2416
+ var size = getSize( this.isotope.element );
2417
+ // check that this.size and size are there
2418
+ // IE8 triggers resize on body size change, so they might not be
2419
+ var hasSizes = this.isotope.size && size;
2420
+ return hasSizes && size.innerHeight != this.isotope.size.innerHeight;
2421
+ };
2422
+
2423
+ // ----- measurements ----- //
2424
+
2425
+ proto._getMeasurement = function() {
2426
+ this.isotope._getMeasurement.apply( this, arguments );
2427
+ };
2428
+
2429
+ proto.getColumnWidth = function() {
2430
+ this.getSegmentSize( 'column', 'Width' );
2431
+ };
2432
+
2433
+ proto.getRowHeight = function() {
2434
+ this.getSegmentSize( 'row', 'Height' );
2435
+ };
2436
+
2437
+ /**
2438
+ * get columnWidth or rowHeight
2439
+ * segment: 'column' or 'row'
2440
+ * size 'Width' or 'Height'
2441
+ **/
2442
+ proto.getSegmentSize = function( segment, size ) {
2443
+ var segmentName = segment + size;
2444
+ var outerSize = 'outer' + size;
2445
+ // columnWidth / outerWidth // rowHeight / outerHeight
2446
+ this._getMeasurement( segmentName, outerSize );
2447
+ // got rowHeight or columnWidth, we can chill
2448
+ if ( this[ segmentName ] ) {
2449
+ return;
2450
+ }
2451
+ // fall back to item of first element
2452
+ var firstItemSize = this.getFirstItemSize();
2453
+ this[ segmentName ] = firstItemSize && firstItemSize[ outerSize ] ||
2454
+ // or size of container
2455
+ this.isotope.size[ 'inner' + size ];
2456
+ };
2457
+
2458
+ proto.getFirstItemSize = function() {
2459
+ var firstItem = this.isotope.filteredItems[0];
2460
+ return firstItem && firstItem.element && getSize( firstItem.element );
2461
+ };
2462
+
2463
+ // ----- methods that should reference isotope ----- //
2464
+
2465
+ proto.layout = function() {
2466
+ this.isotope.layout.apply( this.isotope, arguments );
2467
+ };
2468
+
2469
+ proto.getSize = function() {
2470
+ this.isotope.getSize();
2471
+ this.size = this.isotope.size;
2472
+ };
2473
+
2474
+ // -------------------------- create -------------------------- //
2475
+
2476
+ LayoutMode.modes = {};
2477
+
2478
+ LayoutMode.create = function( namespace, options ) {
2479
+
2480
+ function Mode() {
2481
+ LayoutMode.apply( this, arguments );
2482
+ }
2483
+
2484
+ Mode.prototype = Object.create( proto );
2485
+ Mode.prototype.constructor = Mode;
2486
+
2487
+ // default options
2488
+ if ( options ) {
2489
+ Mode.options = options;
2490
+ }
2491
+
2492
+ Mode.prototype.namespace = namespace;
2493
+ // register in Isotope
2494
+ LayoutMode.modes[ namespace ] = Mode;
2495
+
2496
+ return Mode;
2497
+ };
2498
+
2499
+ return LayoutMode;
2500
+
2501
+ }));
2502
+
2503
+ /*!
2504
+ * Masonry v4.2.1
2505
+ * Cascading grid layout library
2506
+ * https://masonry.desandro.com
2507
+ * MIT License
2508
+ * by David DeSandro
2509
+ */
2510
+
2511
+ ( function( window, factory ) {
2512
+ // universal module definition
2513
+ /* jshint strict: false */ /*globals define, module, require */
2514
+ if ( typeof define == 'function' && define.amd ) {
2515
+ // AMD
2516
+ define( 'masonry-layout/masonry',[
2517
+ 'outlayer/outlayer',
2518
+ 'get-size/get-size'
2519
+ ],
2520
+ factory );
2521
+ } else if ( typeof module == 'object' && module.exports ) {
2522
+ // CommonJS
2523
+ module.exports = factory(
2524
+ require('outlayer'),
2525
+ require('get-size')
2526
+ );
2527
+ } else {
2528
+ // browser global
2529
+ window.Masonry = factory(
2530
+ window.Outlayer,
2531
+ window.getSize
2532
+ );
2533
+ }
2534
+
2535
+ }( window, function factory( Outlayer, getSize ) {
2536
+
2537
+
2538
+
2539
+ // -------------------------- masonryDefinition -------------------------- //
2540
+
2541
+ // create an Outlayer layout class
2542
+ var Masonry = Outlayer.create('masonry');
2543
+ // isFitWidth -> fitWidth
2544
+ Masonry.compatOptions.fitWidth = 'isFitWidth';
2545
+
2546
+ var proto = Masonry.prototype;
2547
+
2548
+ proto._resetLayout = function() {
2549
+ this.getSize();
2550
+ this._getMeasurement( 'columnWidth', 'outerWidth' );
2551
+ this._getMeasurement( 'gutter', 'outerWidth' );
2552
+ this.measureColumns();
2553
+
2554
+ // reset column Y
2555
+ this.colYs = [];
2556
+ for ( var i=0; i < this.cols; i++ ) {
2557
+ this.colYs.push( 0 );
2558
+ }
2559
+
2560
+ this.maxY = 0;
2561
+ this.horizontalColIndex = 0;
2562
+ };
2563
+
2564
+ proto.measureColumns = function() {
2565
+ this.getContainerWidth();
2566
+ // if columnWidth is 0, default to outerWidth of first item
2567
+ if ( !this.columnWidth ) {
2568
+ var firstItem = this.items[0];
2569
+ var firstItemElem = firstItem && firstItem.element;
2570
+ // columnWidth fall back to item of first element
2571
+ this.columnWidth = firstItemElem && getSize( firstItemElem ).outerWidth ||
2572
+ // if first elem has no width, default to size of container
2573
+ this.containerWidth;
2574
+ }
2575
+
2576
+ var columnWidth = this.columnWidth += this.gutter;
2577
+
2578
+ // calculate columns
2579
+ var containerWidth = this.containerWidth + this.gutter;
2580
+ var cols = containerWidth / columnWidth;
2581
+ // fix rounding errors, typically with gutters
2582
+ var excess = columnWidth - containerWidth % columnWidth;
2583
+ // if overshoot is less than a pixel, round up, otherwise floor it
2584
+ var mathMethod = excess && excess < 1 ? 'round' : 'floor';
2585
+ cols = Math[ mathMethod ]( cols );
2586
+ this.cols = Math.max( cols, 1 );
2587
+ };
2588
+
2589
+ proto.getContainerWidth = function() {
2590
+ // container is parent if fit width
2591
+ var isFitWidth = this._getOption('fitWidth');
2592
+ var container = isFitWidth ? this.element.parentNode : this.element;
2593
+ // check that this.size and size are there
2594
+ // IE8 triggers resize on body size change, so they might not be
2595
+ var size = getSize( container );
2596
+ this.containerWidth = size && size.innerWidth;
2597
+ };
2598
+
2599
+ proto._getItemLayoutPosition = function( item ) {
2600
+ item.getSize();
2601
+ // how many columns does this brick span
2602
+ var remainder = item.size.outerWidth % this.columnWidth;
2603
+ var mathMethod = remainder && remainder < 1 ? 'round' : 'ceil';
2604
+ // round if off by 1 pixel, otherwise use ceil
2605
+ var colSpan = Math[ mathMethod ]( item.size.outerWidth / this.columnWidth );
2606
+ colSpan = Math.min( colSpan, this.cols );
2607
+ // use horizontal or top column position
2608
+ var colPosMethod = this.options.horizontalOrder ?
2609
+ '_getHorizontalColPosition' : '_getTopColPosition';
2610
+ var colPosition = this[ colPosMethod ]( colSpan, item );
2611
+ // position the brick
2612
+ var position = {
2613
+ x: this.columnWidth * colPosition.col,
2614
+ y: colPosition.y
2615
+ };
2616
+ // apply setHeight to necessary columns
2617
+ var setHeight = colPosition.y + item.size.outerHeight;
2618
+ var setMax = colSpan + colPosition.col;
2619
+ for ( var i = colPosition.col; i < setMax; i++ ) {
2620
+ this.colYs[i] = setHeight;
2621
+ }
2622
+
2623
+ return position;
2624
+ };
2625
+
2626
+ proto._getTopColPosition = function( colSpan ) {
2627
+ var colGroup = this._getTopColGroup( colSpan );
2628
+ // get the minimum Y value from the columns
2629
+ var minimumY = Math.min.apply( Math, colGroup );
2630
+
2631
+ return {
2632
+ col: colGroup.indexOf( minimumY ),
2633
+ y: minimumY,
2634
+ };
2635
+ };
2636
+
2637
+ /**
2638
+ * @param {Number} colSpan - number of columns the element spans
2639
+ * @returns {Array} colGroup
2640
+ */
2641
+ proto._getTopColGroup = function( colSpan ) {
2642
+ if ( colSpan < 2 ) {
2643
+ // if brick spans only one column, use all the column Ys
2644
+ return this.colYs;
2645
+ }
2646
+
2647
+ var colGroup = [];
2648
+ // how many different places could this brick fit horizontally
2649
+ var groupCount = this.cols + 1 - colSpan;
2650
+ // for each group potential horizontal position
2651
+ for ( var i = 0; i < groupCount; i++ ) {
2652
+ colGroup[i] = this._getColGroupY( i, colSpan );
2653
+ }
2654
+ return colGroup;
2655
+ };
2656
+
2657
+ proto._getColGroupY = function( col, colSpan ) {
2658
+ if ( colSpan < 2 ) {
2659
+ return this.colYs[ col ];
2660
+ }
2661
+ // make an array of colY values for that one group
2662
+ var groupColYs = this.colYs.slice( col, col + colSpan );
2663
+ // and get the max value of the array
2664
+ return Math.max.apply( Math, groupColYs );
2665
+ };
2666
+
2667
+ // get column position based on horizontal index. #873
2668
+ proto._getHorizontalColPosition = function( colSpan, item ) {
2669
+ var col = this.horizontalColIndex % this.cols;
2670
+ var isOver = colSpan > 1 && col + colSpan > this.cols;
2671
+ // shift to next row if item can't fit on current row
2672
+ col = isOver ? 0 : col;
2673
+ // don't let zero-size items take up space
2674
+ var hasSize = item.size.outerWidth && item.size.outerHeight;
2675
+ this.horizontalColIndex = hasSize ? col + colSpan : this.horizontalColIndex;
2676
+
2677
+ return {
2678
+ col: col,
2679
+ y: this._getColGroupY( col, colSpan ),
2680
+ };
2681
+ };
2682
+
2683
+ proto._manageStamp = function( stamp ) {
2684
+ var stampSize = getSize( stamp );
2685
+ var offset = this._getElementOffset( stamp );
2686
+ // get the columns that this stamp affects
2687
+ var isOriginLeft = this._getOption('originLeft');
2688
+ var firstX = isOriginLeft ? offset.left : offset.right;
2689
+ var lastX = firstX + stampSize.outerWidth;
2690
+ var firstCol = Math.floor( firstX / this.columnWidth );
2691
+ firstCol = Math.max( 0, firstCol );
2692
+ var lastCol = Math.floor( lastX / this.columnWidth );
2693
+ // lastCol should not go over if multiple of columnWidth #425
2694
+ lastCol -= lastX % this.columnWidth ? 0 : 1;
2695
+ lastCol = Math.min( this.cols - 1, lastCol );
2696
+ // set colYs to bottom of the stamp
2697
+
2698
+ var isOriginTop = this._getOption('originTop');
2699
+ var stampMaxY = ( isOriginTop ? offset.top : offset.bottom ) +
2700
+ stampSize.outerHeight;
2701
+ for ( var i = firstCol; i <= lastCol; i++ ) {
2702
+ this.colYs[i] = Math.max( stampMaxY, this.colYs[i] );
2703
+ }
2704
+ };
2705
+
2706
+ proto._getContainerSize = function() {
2707
+ this.maxY = Math.max.apply( Math, this.colYs );
2708
+ var size = {
2709
+ height: this.maxY
2710
+ };
2711
+
2712
+ if ( this._getOption('fitWidth') ) {
2713
+ size.width = this._getContainerFitWidth();
2714
+ }
2715
+
2716
+ return size;
2717
+ };
2718
+
2719
+ proto._getContainerFitWidth = function() {
2720
+ var unusedCols = 0;
2721
+ // count unused columns
2722
+ var i = this.cols;
2723
+ while ( --i ) {
2724
+ if ( this.colYs[i] !== 0 ) {
2725
+ break;
2726
+ }
2727
+ unusedCols++;
2728
+ }
2729
+ // fit container to columns that have been used
2730
+ return ( this.cols - unusedCols ) * this.columnWidth - this.gutter;
2731
+ };
2732
+
2733
+ proto.needsResizeLayout = function() {
2734
+ var previousWidth = this.containerWidth;
2735
+ this.getContainerWidth();
2736
+ return previousWidth != this.containerWidth;
2737
+ };
2738
+
2739
+ return Masonry;
2740
+
2741
+ }));
2742
+
2743
+ /*!
2744
+ * Masonry layout mode
2745
+ * sub-classes Masonry
2746
+ * https://masonry.desandro.com
2747
+ */
2748
+
2749
+ ( function( window, factory ) {
2750
+ // universal module definition
2751
+ /* jshint strict: false */ /*globals define, module, require */
2752
+ if ( typeof define == 'function' && define.amd ) {
2753
+ // AMD
2754
+ define( 'isotope-layout/js/layout-modes/masonry',[
2755
+ '../layout-mode',
2756
+ 'masonry-layout/masonry'
2757
+ ],
2758
+ factory );
2759
+ } else if ( typeof module == 'object' && module.exports ) {
2760
+ // CommonJS
2761
+ module.exports = factory(
2762
+ require('../layout-mode'),
2763
+ require('masonry-layout')
2764
+ );
2765
+ } else {
2766
+ // browser global
2767
+ factory(
2768
+ window.Isotope.LayoutMode,
2769
+ window.Masonry
2770
+ );
2771
+ }
2772
+
2773
+ }( window, function factory( LayoutMode, Masonry ) {
2774
+ 'use strict';
2775
+
2776
+ // -------------------------- masonryDefinition -------------------------- //
2777
+
2778
+ // create an Outlayer layout class
2779
+ var MasonryMode = LayoutMode.create('masonry');
2780
+
2781
+ var proto = MasonryMode.prototype;
2782
+
2783
+ var keepModeMethods = {
2784
+ _getElementOffset: true,
2785
+ layout: true,
2786
+ _getMeasurement: true
2787
+ };
2788
+
2789
+ // inherit Masonry prototype
2790
+ for ( var method in Masonry.prototype ) {
2791
+ // do not inherit mode methods
2792
+ if ( !keepModeMethods[ method ] ) {
2793
+ proto[ method ] = Masonry.prototype[ method ];
2794
+ }
2795
+ }
2796
+
2797
+ var measureColumns = proto.measureColumns;
2798
+ proto.measureColumns = function() {
2799
+ // set items, used if measuring first item
2800
+ this.items = this.isotope.filteredItems;
2801
+ measureColumns.call( this );
2802
+ };
2803
+
2804
+ // point to mode options for fitWidth
2805
+ var _getOption = proto._getOption;
2806
+ proto._getOption = function( option ) {
2807
+ if ( option == 'fitWidth' ) {
2808
+ return this.options.isFitWidth !== undefined ?
2809
+ this.options.isFitWidth : this.options.fitWidth;
2810
+ }
2811
+ return _getOption.apply( this.isotope, arguments );
2812
+ };
2813
+
2814
+ return MasonryMode;
2815
+
2816
+ }));
2817
+
2818
+ /**
2819
+ * fitRows layout mode
2820
+ */
2821
+
2822
+ ( function( window, factory ) {
2823
+ // universal module definition
2824
+ /* jshint strict: false */ /*globals define, module, require */
2825
+ if ( typeof define == 'function' && define.amd ) {
2826
+ // AMD
2827
+ define( 'isotope-layout/js/layout-modes/fit-rows',[
2828
+ '../layout-mode'
2829
+ ],
2830
+ factory );
2831
+ } else if ( typeof exports == 'object' ) {
2832
+ // CommonJS
2833
+ module.exports = factory(
2834
+ require('../layout-mode')
2835
+ );
2836
+ } else {
2837
+ // browser global
2838
+ factory(
2839
+ window.Isotope.LayoutMode
2840
+ );
2841
+ }
2842
+
2843
+ }( window, function factory( LayoutMode ) {
2844
+ 'use strict';
2845
+
2846
+ var FitRows = LayoutMode.create('fitRows');
2847
+
2848
+ var proto = FitRows.prototype;
2849
+
2850
+ proto._resetLayout = function() {
2851
+ this.x = 0;
2852
+ this.y = 0;
2853
+ this.maxY = 0;
2854
+ this._getMeasurement( 'gutter', 'outerWidth' );
2855
+ };
2856
+
2857
+ proto._getItemLayoutPosition = function( item ) {
2858
+ item.getSize();
2859
+
2860
+ var itemWidth = item.size.outerWidth + this.gutter;
2861
+ // if this element cannot fit in the current row
2862
+ var containerWidth = this.isotope.size.innerWidth + this.gutter;
2863
+ if ( this.x !== 0 && itemWidth + this.x > containerWidth ) {
2864
+ this.x = 0;
2865
+ this.y = this.maxY;
2866
+ }
2867
+
2868
+ var position = {
2869
+ x: this.x,
2870
+ y: this.y
2871
+ };
2872
+
2873
+ this.maxY = Math.max( this.maxY, this.y + item.size.outerHeight );
2874
+ this.x += itemWidth;
2875
+
2876
+ return position;
2877
+ };
2878
+
2879
+ proto._getContainerSize = function() {
2880
+ return { height: this.maxY };
2881
+ };
2882
+
2883
+ return FitRows;
2884
+
2885
+ }));
2886
+
2887
+ /**
2888
+ * vertical layout mode
2889
+ */
2890
+
2891
+ ( function( window, factory ) {
2892
+ // universal module definition
2893
+ /* jshint strict: false */ /*globals define, module, require */
2894
+ if ( typeof define == 'function' && define.amd ) {
2895
+ // AMD
2896
+ define( 'isotope-layout/js/layout-modes/vertical',[
2897
+ '../layout-mode'
2898
+ ],
2899
+ factory );
2900
+ } else if ( typeof module == 'object' && module.exports ) {
2901
+ // CommonJS
2902
+ module.exports = factory(
2903
+ require('../layout-mode')
2904
+ );
2905
+ } else {
2906
+ // browser global
2907
+ factory(
2908
+ window.Isotope.LayoutMode
2909
+ );
2910
+ }
2911
+
2912
+ }( window, function factory( LayoutMode ) {
2913
+ 'use strict';
2914
+
2915
+ var Vertical = LayoutMode.create( 'vertical', {
2916
+ horizontalAlignment: 0
2917
+ });
2918
+
2919
+ var proto = Vertical.prototype;
2920
+
2921
+ proto._resetLayout = function() {
2922
+ this.y = 0;
2923
+ };
2924
+
2925
+ proto._getItemLayoutPosition = function( item ) {
2926
+ item.getSize();
2927
+ var x = ( this.isotope.size.innerWidth - item.size.outerWidth ) *
2928
+ this.options.horizontalAlignment;
2929
+ var y = this.y;
2930
+ this.y += item.size.outerHeight;
2931
+ return { x: x, y: y };
2932
+ };
2933
+
2934
+ proto._getContainerSize = function() {
2935
+ return { height: this.y };
2936
+ };
2937
+
2938
+ return Vertical;
2939
+
2940
+ }));
2941
+
2942
+ /*!
2943
+ * Isotope v3.0.6
2944
+ *
2945
+ * Licensed GPLv3 for open source use
2946
+ * or Isotope Commercial License for commercial use
2947
+ *
2948
+ * https://isotope.metafizzy.co
2949
+ * Copyright 2010-2018 Metafizzy
2950
+ */
2951
+
2952
+ ( function( window, factory ) {
2953
+ // universal module definition
2954
+ /* jshint strict: false */ /*globals define, module, require */
2955
+ if ( typeof define == 'function' && define.amd ) {
2956
+ // AMD
2957
+ define( [
2958
+ 'outlayer/outlayer',
2959
+ 'get-size/get-size',
2960
+ 'desandro-matches-selector/matches-selector',
2961
+ 'fizzy-ui-utils/utils',
2962
+ 'isotope-layout/js/item',
2963
+ 'isotope-layout/js/layout-mode',
2964
+ // include default layout modes
2965
+ 'isotope-layout/js/layout-modes/masonry',
2966
+ 'isotope-layout/js/layout-modes/fit-rows',
2967
+ 'isotope-layout/js/layout-modes/vertical'
2968
+ ],
2969
+ function( Outlayer, getSize, matchesSelector, utils, Item, LayoutMode ) {
2970
+ return factory( window, Outlayer, getSize, matchesSelector, utils, Item, LayoutMode );
2971
+ });
2972
+ } else if ( typeof module == 'object' && module.exports ) {
2973
+ // CommonJS
2974
+ module.exports = factory(
2975
+ window,
2976
+ require('outlayer'),
2977
+ require('get-size'),
2978
+ require('desandro-matches-selector'),
2979
+ require('fizzy-ui-utils'),
2980
+ require('isotope-layout/js/item'),
2981
+ require('isotope-layout/js/layout-mode'),
2982
+ // include default layout modes
2983
+ require('isotope-layout/js/layout-modes/masonry'),
2984
+ require('isotope-layout/js/layout-modes/fit-rows'),
2985
+ require('isotope-layout/js/layout-modes/vertical')
2986
+ );
2987
+ } else {
2988
+ // browser global
2989
+ window.Isotope = factory(
2990
+ window,
2991
+ window.Outlayer,
2992
+ window.getSize,
2993
+ window.matchesSelector,
2994
+ window.fizzyUIUtils,
2995
+ window.Isotope.Item,
2996
+ window.Isotope.LayoutMode
2997
+ );
2998
+ }
2999
+
3000
+ }( window, function factory( window, Outlayer, getSize, matchesSelector, utils,
3001
+ Item, LayoutMode ) {
3002
+
3003
+
3004
+
3005
+ // -------------------------- vars -------------------------- //
3006
+
3007
+ var jQuery = window.jQuery;
3008
+
3009
+ // -------------------------- helpers -------------------------- //
3010
+
3011
+ var trim = String.prototype.trim ?
3012
+ function( str ) {
3013
+ return str.trim();
3014
+ } :
3015
+ function( str ) {
3016
+ return str.replace( /^\s+|\s+$/g, '' );
3017
+ };
3018
+
3019
+ // -------------------------- isotopeDefinition -------------------------- //
3020
+
3021
+ // create an Outlayer layout class
3022
+ var Isotope = Outlayer.create( 'isotope', {
3023
+ layoutMode: 'masonry',
3024
+ isJQueryFiltering: true,
3025
+ sortAscending: true
3026
+ });
3027
+
3028
+ Isotope.Item = Item;
3029
+ Isotope.LayoutMode = LayoutMode;
3030
+
3031
+ var proto = Isotope.prototype;
3032
+
3033
+ proto._create = function() {
3034
+ this.itemGUID = 0;
3035
+ // functions that sort items
3036
+ this._sorters = {};
3037
+ this._getSorters();
3038
+ // call super
3039
+ Outlayer.prototype._create.call( this );
3040
+
3041
+ // create layout modes
3042
+ this.modes = {};
3043
+ // start filteredItems with all items
3044
+ this.filteredItems = this.items;
3045
+ // keep of track of sortBys
3046
+ this.sortHistory = [ 'original-order' ];
3047
+ // create from registered layout modes
3048
+ for ( var name in LayoutMode.modes ) {
3049
+ this._initLayoutMode( name );
3050
+ }
3051
+ };
3052
+
3053
+ proto.reloadItems = function() {
3054
+ // reset item ID counter
3055
+ this.itemGUID = 0;
3056
+ // call super
3057
+ Outlayer.prototype.reloadItems.call( this );
3058
+ };
3059
+
3060
+ proto._itemize = function() {
3061
+ var items = Outlayer.prototype._itemize.apply( this, arguments );
3062
+ // assign ID for original-order
3063
+ for ( var i=0; i < items.length; i++ ) {
3064
+ var item = items[i];
3065
+ item.id = this.itemGUID++;
3066
+ }
3067
+ this._updateItemsSortData( items );
3068
+ return items;
3069
+ };
3070
+
3071
+
3072
+ // -------------------------- layout -------------------------- //
3073
+
3074
+ proto._initLayoutMode = function( name ) {
3075
+ var Mode = LayoutMode.modes[ name ];
3076
+ // set mode options
3077
+ // HACK extend initial options, back-fill in default options
3078
+ var initialOpts = this.options[ name ] || {};
3079
+ this.options[ name ] = Mode.options ?
3080
+ utils.extend( Mode.options, initialOpts ) : initialOpts;
3081
+ // init layout mode instance
3082
+ this.modes[ name ] = new Mode( this );
3083
+ };
3084
+
3085
+
3086
+ proto.layout = function() {
3087
+ // if first time doing layout, do all magic
3088
+ if ( !this._isLayoutInited && this._getOption('initLayout') ) {
3089
+ this.arrange();
3090
+ return;
3091
+ }
3092
+ this._layout();
3093
+ };
3094
+
3095
+ // private method to be used in layout() & magic()
3096
+ proto._layout = function() {
3097
+ // don't animate first layout
3098
+ var isInstant = this._getIsInstant();
3099
+ // layout flow
3100
+ this._resetLayout();
3101
+ this._manageStamps();
3102
+ this.layoutItems( this.filteredItems, isInstant );
3103
+
3104
+ // flag for initalized
3105
+ this._isLayoutInited = true;
3106
+ };
3107
+
3108
+ // filter + sort + layout
3109
+ proto.arrange = function( opts ) {
3110
+ // set any options pass
3111
+ this.option( opts );
3112
+ this._getIsInstant();
3113
+ // filter, sort, and layout
3114
+
3115
+ // filter
3116
+ var filtered = this._filter( this.items );
3117
+ this.filteredItems = filtered.matches;
3118
+
3119
+ this._bindArrangeComplete();
3120
+
3121
+ if ( this._isInstant ) {
3122
+ this._noTransition( this._hideReveal, [ filtered ] );
3123
+ } else {
3124
+ this._hideReveal( filtered );
3125
+ }
3126
+
3127
+ this._sort();
3128
+ this._layout();
3129
+ };
3130
+ // alias to _init for main plugin method
3131
+ proto._init = proto.arrange;
3132
+
3133
+ proto._hideReveal = function( filtered ) {
3134
+ this.reveal( filtered.needReveal );
3135
+ this.hide( filtered.needHide );
3136
+ };
3137
+
3138
+ // HACK
3139
+ // Don't animate/transition first layout
3140
+ // Or don't animate/transition other layouts
3141
+ proto._getIsInstant = function() {
3142
+ var isLayoutInstant = this._getOption('layoutInstant');
3143
+ var isInstant = isLayoutInstant !== undefined ? isLayoutInstant :
3144
+ !this._isLayoutInited;
3145
+ this._isInstant = isInstant;
3146
+ return isInstant;
3147
+ };
3148
+
3149
+ // listen for layoutComplete, hideComplete and revealComplete
3150
+ // to trigger arrangeComplete
3151
+ proto._bindArrangeComplete = function() {
3152
+ // listen for 3 events to trigger arrangeComplete
3153
+ var isLayoutComplete, isHideComplete, isRevealComplete;
3154
+ var _this = this;
3155
+ function arrangeParallelCallback() {
3156
+ if ( isLayoutComplete && isHideComplete && isRevealComplete ) {
3157
+ _this.dispatchEvent( 'arrangeComplete', null, [ _this.filteredItems ] );
3158
+ }
3159
+ }
3160
+ this.once( 'layoutComplete', function() {
3161
+ isLayoutComplete = true;
3162
+ arrangeParallelCallback();
3163
+ });
3164
+ this.once( 'hideComplete', function() {
3165
+ isHideComplete = true;
3166
+ arrangeParallelCallback();
3167
+ });
3168
+ this.once( 'revealComplete', function() {
3169
+ isRevealComplete = true;
3170
+ arrangeParallelCallback();
3171
+ });
3172
+ };
3173
+
3174
+ // -------------------------- filter -------------------------- //
3175
+
3176
+ proto._filter = function( items ) {
3177
+ var filter = this.options.filter;
3178
+ filter = filter || '*';
3179
+ var matches = [];
3180
+ var hiddenMatched = [];
3181
+ var visibleUnmatched = [];
3182
+
3183
+ var test = this._getFilterTest( filter );
3184
+
3185
+ // test each item
3186
+ for ( var i=0; i < items.length; i++ ) {
3187
+ var item = items[i];
3188
+ if ( item.isIgnored ) {
3189
+ continue;
3190
+ }
3191
+ // add item to either matched or unmatched group
3192
+ var isMatched = test( item );
3193
+ // item.isFilterMatched = isMatched;
3194
+ // add to matches if its a match
3195
+ if ( isMatched ) {
3196
+ matches.push( item );
3197
+ }
3198
+ // add to additional group if item needs to be hidden or revealed
3199
+ if ( isMatched && item.isHidden ) {
3200
+ hiddenMatched.push( item );
3201
+ } else if ( !isMatched && !item.isHidden ) {
3202
+ visibleUnmatched.push( item );
3203
+ }
3204
+ }
3205
+
3206
+ // return collections of items to be manipulated
3207
+ return {
3208
+ matches: matches,
3209
+ needReveal: hiddenMatched,
3210
+ needHide: visibleUnmatched
3211
+ };
3212
+ };
3213
+
3214
+ // get a jQuery, function, or a matchesSelector test given the filter
3215
+ proto._getFilterTest = function( filter ) {
3216
+ if ( jQuery && this.options.isJQueryFiltering ) {
3217
+ // use jQuery
3218
+ return function( item ) {
3219
+ return jQuery( item.element ).is( filter );
3220
+ };
3221
+ }
3222
+ if ( typeof filter == 'function' ) {
3223
+ // use filter as function
3224
+ return function( item ) {
3225
+ return filter( item.element );
3226
+ };
3227
+ }
3228
+ // default, use filter as selector string
3229
+ return function( item ) {
3230
+ return matchesSelector( item.element, filter );
3231
+ };
3232
+ };
3233
+
3234
+ // -------------------------- sorting -------------------------- //
3235
+
3236
+ /**
3237
+ * @params {Array} elems
3238
+ * @public
3239
+ */
3240
+ proto.updateSortData = function( elems ) {
3241
+ // get items
3242
+ var items;
3243
+ if ( elems ) {
3244
+ elems = utils.makeArray( elems );
3245
+ items = this.getItems( elems );
3246
+ } else {
3247
+ // update all items if no elems provided
3248
+ items = this.items;
3249
+ }
3250
+
3251
+ this._getSorters();
3252
+ this._updateItemsSortData( items );
3253
+ };
3254
+
3255
+ proto._getSorters = function() {
3256
+ var getSortData = this.options.getSortData;
3257
+ for ( var key in getSortData ) {
3258
+ var sorter = getSortData[ key ];
3259
+ this._sorters[ key ] = mungeSorter( sorter );
3260
+ }
3261
+ };
3262
+
3263
+ /**
3264
+ * @params {Array} items - of Isotope.Items
3265
+ * @private
3266
+ */
3267
+ proto._updateItemsSortData = function( items ) {
3268
+ // do not update if no items
3269
+ var len = items && items.length;
3270
+
3271
+ for ( var i=0; len && i < len; i++ ) {
3272
+ var item = items[i];
3273
+ item.updateSortData();
3274
+ }
3275
+ };
3276
+
3277
+ // ----- munge sorter ----- //
3278
+
3279
+ // encapsulate this, as we just need mungeSorter
3280
+ // other functions in here are just for munging
3281
+ var mungeSorter = ( function() {
3282
+ // add a magic layer to sorters for convienent shorthands
3283
+ // `.foo-bar` will use the text of .foo-bar querySelector
3284
+ // `[foo-bar]` will use attribute
3285
+ // you can also add parser
3286
+ // `.foo-bar parseInt` will parse that as a number
3287
+ function mungeSorter( sorter ) {
3288
+ // if not a string, return function or whatever it is
3289
+ if ( typeof sorter != 'string' ) {
3290
+ return sorter;
3291
+ }
3292
+ // parse the sorter string
3293
+ var args = trim( sorter ).split(' ');
3294
+ var query = args[0];
3295
+ // check if query looks like [an-attribute]
3296
+ var attrMatch = query.match( /^\[(.+)\]$/ );
3297
+ var attr = attrMatch && attrMatch[1];
3298
+ var getValue = getValueGetter( attr, query );
3299
+ // use second argument as a parser
3300
+ var parser = Isotope.sortDataParsers[ args[1] ];
3301
+ // parse the value, if there was a parser
3302
+ sorter = parser ? function( elem ) {
3303
+ return elem && parser( getValue( elem ) );
3304
+ } :
3305
+ // otherwise just return value
3306
+ function( elem ) {
3307
+ return elem && getValue( elem );
3308
+ };
3309
+
3310
+ return sorter;
3311
+ }
3312
+
3313
+ // get an attribute getter, or get text of the querySelector
3314
+ function getValueGetter( attr, query ) {
3315
+ // if query looks like [foo-bar], get attribute
3316
+ if ( attr ) {
3317
+ return function getAttribute( elem ) {
3318
+ return elem.getAttribute( attr );
3319
+ };
3320
+ }
3321
+
3322
+ // otherwise, assume its a querySelector, and get its text
3323
+ return function getChildText( elem ) {
3324
+ var child = elem.querySelector( query );
3325
+ return child && child.textContent;
3326
+ };
3327
+ }
3328
+
3329
+ return mungeSorter;
3330
+ })();
3331
+
3332
+ // parsers used in getSortData shortcut strings
3333
+ Isotope.sortDataParsers = {
3334
+ 'parseInt': function( val ) {
3335
+ return parseInt( val, 10 );
3336
+ },
3337
+ 'parseFloat': function( val ) {
3338
+ return parseFloat( val );
3339
+ }
3340
+ };
3341
+
3342
+ // ----- sort method ----- //
3343
+
3344
+ // sort filteredItem order
3345
+ proto._sort = function() {
3346
+ if ( !this.options.sortBy ) {
3347
+ return;
3348
+ }
3349
+ // keep track of sortBy History
3350
+ var sortBys = utils.makeArray( this.options.sortBy );
3351
+ if ( !this._getIsSameSortBy( sortBys ) ) {
3352
+ // concat all sortBy and sortHistory, add to front, oldest goes in last
3353
+ this.sortHistory = sortBys.concat( this.sortHistory );
3354
+ }
3355
+ // sort magic
3356
+ var itemSorter = getItemSorter( this.sortHistory, this.options.sortAscending );
3357
+ this.filteredItems.sort( itemSorter );
3358
+ };
3359
+
3360
+ // check if sortBys is same as start of sortHistory
3361
+ proto._getIsSameSortBy = function( sortBys ) {
3362
+ for ( var i=0; i < sortBys.length; i++ ) {
3363
+ if ( sortBys[i] != this.sortHistory[i] ) {
3364
+ return false;
3365
+ }
3366
+ }
3367
+ return true;
3368
+ };
3369
+
3370
+ // returns a function used for sorting
3371
+ function getItemSorter( sortBys, sortAsc ) {
3372
+ return function sorter( itemA, itemB ) {
3373
+ // cycle through all sortKeys
3374
+ for ( var i = 0; i < sortBys.length; i++ ) {
3375
+ var sortBy = sortBys[i];
3376
+ var a = itemA.sortData[ sortBy ];
3377
+ var b = itemB.sortData[ sortBy ];
3378
+ if ( a > b || a < b ) {
3379
+ // if sortAsc is an object, use the value given the sortBy key
3380
+ var isAscending = sortAsc[ sortBy ] !== undefined ? sortAsc[ sortBy ] : sortAsc;
3381
+ var direction = isAscending ? 1 : -1;
3382
+ return ( a > b ? 1 : -1 ) * direction;
3383
+ }
3384
+ }
3385
+ return 0;
3386
+ };
3387
+ }
3388
+
3389
+ // -------------------------- methods -------------------------- //
3390
+
3391
+ // get layout mode
3392
+ proto._mode = function() {
3393
+ var layoutMode = this.options.layoutMode;
3394
+ var mode = this.modes[ layoutMode ];
3395
+ if ( !mode ) {
3396
+ // TODO console.error
3397
+ throw new Error( 'No layout mode: ' + layoutMode );
3398
+ }
3399
+ // HACK sync mode's options
3400
+ // any options set after init for layout mode need to be synced
3401
+ mode.options = this.options[ layoutMode ];
3402
+ return mode;
3403
+ };
3404
+
3405
+ proto._resetLayout = function() {
3406
+ // trigger original reset layout
3407
+ Outlayer.prototype._resetLayout.call( this );
3408
+ this._mode()._resetLayout();
3409
+ };
3410
+
3411
+ proto._getItemLayoutPosition = function( item ) {
3412
+ return this._mode()._getItemLayoutPosition( item );
3413
+ };
3414
+
3415
+ proto._manageStamp = function( stamp ) {
3416
+ this._mode()._manageStamp( stamp );
3417
+ };
3418
+
3419
+ proto._getContainerSize = function() {
3420
+ return this._mode()._getContainerSize();
3421
+ };
3422
+
3423
+ proto.needsResizeLayout = function() {
3424
+ return this._mode().needsResizeLayout();
3425
+ };
3426
+
3427
+ // -------------------------- adding & removing -------------------------- //
3428
+
3429
+ // HEADS UP overwrites default Outlayer appended
3430
+ proto.appended = function( elems ) {
3431
+ var items = this.addItems( elems );
3432
+ if ( !items.length ) {
3433
+ return;
3434
+ }
3435
+ // filter, layout, reveal new items
3436
+ var filteredItems = this._filterRevealAdded( items );
3437
+ // add to filteredItems
3438
+ this.filteredItems = this.filteredItems.concat( filteredItems );
3439
+ };
3440
+
3441
+ // HEADS UP overwrites default Outlayer prepended
3442
+ proto.prepended = function( elems ) {
3443
+ var items = this._itemize( elems );
3444
+ if ( !items.length ) {
3445
+ return;
3446
+ }
3447
+ // start new layout
3448
+ this._resetLayout();
3449
+ this._manageStamps();
3450
+ // filter, layout, reveal new items
3451
+ var filteredItems = this._filterRevealAdded( items );
3452
+ // layout previous items
3453
+ this.layoutItems( this.filteredItems );
3454
+ // add to items and filteredItems
3455
+ this.filteredItems = filteredItems.concat( this.filteredItems );
3456
+ this.items = items.concat( this.items );
3457
+ };
3458
+
3459
+ proto._filterRevealAdded = function( items ) {
3460
+ var filtered = this._filter( items );
3461
+ this.hide( filtered.needHide );
3462
+ // reveal all new items
3463
+ this.reveal( filtered.matches );
3464
+ // layout new items, no transition
3465
+ this.layoutItems( filtered.matches, true );
3466
+ return filtered.matches;
3467
+ };
3468
+
3469
+ /**
3470
+ * Filter, sort, and layout newly-appended item elements
3471
+ * @param {Array or NodeList or Element} elems
3472
+ */
3473
+ proto.insert = function( elems ) {
3474
+ var items = this.addItems( elems );
3475
+ if ( !items.length ) {
3476
+ return;
3477
+ }
3478
+ // append item elements
3479
+ var i, item;
3480
+ var len = items.length;
3481
+ for ( i=0; i < len; i++ ) {
3482
+ item = items[i];
3483
+ this.element.appendChild( item.element );
3484
+ }
3485
+ // filter new stuff
3486
+ var filteredInsertItems = this._filter( items ).matches;
3487
+ // set flag
3488
+ for ( i=0; i < len; i++ ) {
3489
+ items[i].isLayoutInstant = true;
3490
+ }
3491
+ this.arrange();
3492
+ // reset flag
3493
+ for ( i=0; i < len; i++ ) {
3494
+ delete items[i].isLayoutInstant;
3495
+ }
3496
+ this.reveal( filteredInsertItems );
3497
+ };
3498
+
3499
+ var _remove = proto.remove;
3500
+ proto.remove = function( elems ) {
3501
+ elems = utils.makeArray( elems );
3502
+ var removeItems = this.getItems( elems );
3503
+ // do regular thing
3504
+ _remove.call( this, elems );
3505
+ // bail if no items to remove
3506
+ var len = removeItems && removeItems.length;
3507
+ // remove elems from filteredItems
3508
+ for ( var i=0; len && i < len; i++ ) {
3509
+ var item = removeItems[i];
3510
+ // remove item from collection
3511
+ utils.removeFrom( this.filteredItems, item );
3512
+ }
3513
+ };
3514
+
3515
+ proto.shuffle = function() {
3516
+ // update random sortData
3517
+ for ( var i=0; i < this.items.length; i++ ) {
3518
+ var item = this.items[i];
3519
+ item.sortData.random = Math.random();
3520
+ }
3521
+ this.options.sortBy = 'random';
3522
+ this._sort();
3523
+ this._layout();
3524
+ };
3525
+
3526
+ /**
3527
+ * trigger fn without transition
3528
+ * kind of hacky to have this in the first place
3529
+ * @param {Function} fn
3530
+ * @param {Array} args
3531
+ * @returns ret
3532
+ * @private
3533
+ */
3534
+ proto._noTransition = function( fn, args ) {
3535
+ // save transitionDuration before disabling
3536
+ var transitionDuration = this.options.transitionDuration;
3537
+ // disable transition
3538
+ this.options.transitionDuration = 0;
3539
+ // do it
3540
+ var returnValue = fn.apply( this, args );
3541
+ // re-enable transition for reveal
3542
+ this.options.transitionDuration = transitionDuration;
3543
+ return returnValue;
3544
+ };
3545
+
3546
+ // ----- helper methods ----- //
3547
+
3548
+ /**
3549
+ * getter method for getting filtered item elements
3550
+ * @returns {Array} elems - collection of item elements
3551
+ */
3552
+ proto.getFilteredItemElements = function() {
3553
+ return this.filteredItems.map( function( item ) {
3554
+ return item.element;
3555
+ });
3556
+ };
3557
+
3558
+ // ----- ----- //
3559
+
3560
+ return Isotope;
3561
+
3562
+ }));
3563
+