{"version":3,"sources":["webpack:///webpack/bootstrap","webpack:///../app_ashleystewart/cartridges/app_ashleystewart/cartridge/client/default/js/components/collapsibleSizeChart.js","webpack:///../app_ashleystewart/cartridges/app_ashleystewart/cartridge/client/default/js/components/globalComponents.js","webpack:///../app_ashleystewart/cartridges/app_ashleystewart/cartridge/client/default/js/components/toolTip.js","webpack:///../app_ashleystewart/cartridges/app_ashleystewart/cartridge/client/default/js/product/base.js","webpack:///../app_ashleystewart/cartridges/app_ashleystewart/cartridge/client/default/js/product/detail.js","webpack:///../app_ashleystewart/cartridges/app_ashleystewart/cartridge/client/default/js/product/quickView.js","webpack:///../app_ashleystewart/cartridges/app_ashleystewart/cartridge/client/default/js/productDetail.js","webpack:///../app_ashleystewart/cartridges/app_ashleystewart/cartridge/client/default/js/storeLocator/storeLocator.js","webpack:///../app_ashleystewart/node_modules/ez-plus/src/jquery.ez-plus.js","webpack:///../app_ashleystewart/node_modules/pinch-zoom-js/src/pinch-zoom.js","webpack:///../int_valuelink/cartridges/int_valuelink/cartridge/client/default/js/product/pdpGiftCard.js","webpack:///../plugin_instorepickup/cartridges/plugin_instorepickup/cartridge/client/default/js/product/pdpInstoreInventory.js","webpack:///../plugin_wishlists/cartridges/plugin_wishlists/cartridge/client/default/js/product/wishlist.js","webpack:///../storefront-reference-architecture/cartridges/app_storefront_base/cartridge/client/default/js/components/focus.js","webpack:///../storefront-reference-architecture/cartridges/app_storefront_base/cartridge/client/default/js/product/base.js","webpack:///../storefront-reference-architecture/cartridges/app_storefront_base/cartridge/client/default/js/product/quickView.js","webpack:///../storefront-reference-architecture/cartridges/app_storefront_base/cartridge/client/default/js/util.js"],"names":[],"mappings":";QAAA;QACA;;QAEA;QACA;;QAEA;QACA;QACA;QACA;QACA;QACA;QACA;QACA;QACA;QACA;;QAEA;QACA;;QAEA;QACA;;QAEA;QACA;QACA;;;QAGA;QACA;;QAEA;QACA;;QAEA;QACA;QACA;QACA,0CAA0C,gCAAgC;QAC1E;QACA;;QAEA;QACA;QACA;QACA,wDAAwD,kBAAkB;QAC1E;QACA,iDAAiD,cAAc;QAC/D;;QAEA;QACA;QACA;QACA;QACA;QACA;QACA;QACA;QACA;QACA;QACA;QACA,yCAAyC,iCAAiC;QAC1E,gHAAgH,mBAAmB,EAAE;QACrI;QACA;;QAEA;QACA;QACA;QACA,2BAA2B,0BAA0B,EAAE;QACvD,iCAAiC,eAAe;QAChD;QACA;QACA;;QAEA;QACA,sDAAsD,+DAA+D;;QAErH;QACA;;;QAGA;QACA;;;;;;;;;;;;;AClFa;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA,KAAK;AACL;AACA;AACA;AACA,E;;;;;;;;;;;ACvBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA,KAAK;;AAEL;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT,KAAK;AACL;AACA;;AAEA;AACA;AACA,KAAK;;AAEL;AACA;AACA,KAAK;AACL;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA,C;;;;;;;;;;;;ACpFa;;AAEb;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA,SAAS;AACT;AACA;AACA,KAAK;AACL;AACA;AACA;AACA,KAAK;;AAEL;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA,KAAK;AACL;;;;;;;;;;;;;ACjCa;;AAEb,kBAAkB,mBAAO,CAAC,kJAAuB;;AAEjD;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,KAAK;AACL;;AAEA;AACA;AACA,WAAW,OAAO;AAClB;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,WAAW,OAAO;AAClB,YAAY,OAAO;AACnB;AACA;AACA;;AAEA;AACA;AACA,KAAK;AACL;AACA,KAAK;AACL;AACA,KAAK;AACL;AACA;;AAEA;AACA;;AAEA;AACA;AACA,WAAW,OAAO;AAClB,YAAY,OAAO;AACnB;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;;AAEA;AACA;AACA,WAAW,OAAO;AAClB,YAAY,OAAO;AACnB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,WAAW,OAAO;AAClB,WAAW,OAAO;AAClB,WAAW,SAAS;AACpB,WAAW,OAAO;AAClB,WAAW,OAAO;AAClB,WAAW,QAAQ;AACnB;AACA;AACA,WAAW,OAAO;AAClB,WAAW,OAAO;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;;AAEA;AACA;AACA,SAAS;AACT;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA,KAAK;AACL;;AAEA;AACA;AACA;AACA,WAAW,OAAO;AAClB,WAAW,OAAO;AAClB,WAAW,SAAS;AACpB,WAAW,OAAO;AAClB,WAAW,OAAO;AAClB,WAAW,QAAQ;AACnB;AACA;AACA,WAAW,OAAO;AAClB;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,KAAK;AACL;;AAEA;AACA;AACA;AACA;AACA,WAAW,OAAO;AAClB,WAAW,OAAO;AAClB,WAAW,OAAO;AAClB,WAAW,OAAO;AAClB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA,KAAK;AACL;;AAEA;AACA;AACA;AACA,WAAW,OAAO;AAClB;AACA,WAAW,OAAO;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;;AAEA;AACA;AACA;AACA,WAAW,MAAM;AACjB,YAAY,OAAO;AACnB;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA,KAAK;;AAEL;AACA;;AAEA;AACA;AACA;AACA,cAAc,OAAO;AACrB,cAAc,OAAO;AACrB;;AAEA;AACA;AACA;AACA,cAAc,OAAO;AACrB,cAAc,OAAO;AACrB,cAAc,OAAO;AACrB,cAAc,qBAAqB;AACnC;;AAEA;AACA;AACA;AACA,WAAW,wBAAwB;AACnC,WAAW,OAAO;AAClB;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,WAAW,SAAS;AACpB,WAAW,QAAQ;AACnB,WAAW,QAAQ;AACnB,WAAW,OAAO;AAClB,WAAW,OAAO;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mBAAmB,iBAAiB;AACpC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA,WAAW,OAAO;AAClB,WAAW,OAAO;AAClB,WAAW,OAAO;AAClB;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;;AAEA;AACA;AACA,WAAW,OAAO;AAClB,WAAW,OAAO;AAClB,WAAW,OAAO;AAClB,WAAW,SAAS;AACpB,WAAW,SAAS;AACpB,WAAW,QAAQ;AACnB;AACA;AACA,WAAW,OAAO;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA,SAAS;AACT,KAAK;AACL;AACA;AACA;AACA,SAAS;AACT;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,cAAc,QAAQ;AACtB,cAAc,OAAO;AACrB,cAAc,OAAO;AACrB;AACA;;AAEA;AACA;AACA,WAAW,kBAAkB;AAC7B,WAAW,OAAO;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,WAAW,OAAO;AAClB,WAAW,OAAO;AAClB,WAAW,QAAQ;AACnB;AACA;AACA;AACA;AACA;AACA,aAAa,sDAAsD;AACnE;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb,SAAS;AACT;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,qBAAqB,+EAA+E;AACpG;AACA,aAAa;AACb;AACA;AACA;AACA,SAAS;AACT;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,KAAK;;AAEL;AACA;AACA;AACA;AACA;AACA,KAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;;AAEA;AACA;AACA;AACA;AACA;AACA,KAAK;;AAEL;;AAEA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA,YAAY,OAAO;AACnB;AACA;AACA;AACA;;AAEA;AACA;AACA,WAAW,OAAO;AAClB;AACA,YAAY,OAAO;AACnB;AACA;AACA;;AAEA;AACA;;AAEA,YAAY;AACZ;;AAEA;AACA;AACA;AACA,WAAW,OAAO;AAClB;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mDAAmD;AACnD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,KAAK;AACL;;AAEA;AACA;AACA,WAAW,OAAO;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,YAAY,SAAS;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT,KAAK;;AAEL;AACA;;AAEA;AACA;AACA;AACA,WAAW,OAAO;AAClB,YAAY,OAAO;AACnB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;;AAET;AACA;;AAEA;AACA;AACA;AACA,WAAW,iBAAiB;AAC5B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA,SAAS;AACT;AACA;;AAEA;AACA;AACA;AACA;AACA,uBAAuB,mBAAmB;AAC1C;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA,KAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;;AAET;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT,KAAK;;AAEL;AACA;AACA;AACA;AACA,SAAS;AACT,KAAK;;AAEL;AACA;AACA;AACA,SAAS;AACT,KAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT,KAAK;;AAEL;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,SAAS;AACT,KAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,SAAS;AACT,KAAK;;AAEL;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT,KAAK;;AAEL;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA,SAAS;AACT,KAAK;;AAEL;AACA;AACA;AACA,SAAS;AACT,KAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,6BAA6B;AAC7B;AACA,qBAAqB;AACrB;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,6BAA6B;AAC7B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iCAAiC;AACjC;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,yBAAyB;AACzB;AACA;AACA;AACA,qBAAqB;AACrB;;AAEA,aAAa;AACb;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA;;AAEA;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB;AACrB;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,yBAAyB;AACzB;AACA;AACA;AACA,SAAS;AACT,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA,SAAS;AACT,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB;;AAEA;AACA;AACA,SAAS;AACT,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA,aAAa;AACb,SAAS;AACT,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB;AACrB;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,yBAAyB;AACzB,qBAAqB;AACrB;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,yBAAyB;AACzB;AACA,iBAAiB;AACjB;AACA;AACA;AACA,aAAa;AACb,SAAS;AACT,KAAK;;AAEL;;AAEA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;ACnrCa;AACb,WAAW,mBAAO,CAAC,6GAAQ;AAC3B,gBAAgB,mBAAO,CAAC,wFAAe;AACvC,gBAAgB,mBAAO,CAAC,uHAAa;AACrC,uBAAuB,mBAAO,CAAC,oJAAgC;AAC/D,mBAAO,CAAC,gFAAS;AACjB,mBAAO,CAAC,kIAAuB;;AAE/B;AACA;AACA,WAAW,QAAQ;AACnB;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,WAAW,OAAO;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;;AAEA;AACA;AACA,WAAW,OAAO;AAClB,WAAW,EAAE;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,WAAW,eAAe;AAC1B;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA,KAAK;AACL;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;;AAEA;AACA;AACA,WAAW,eAAe;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;;AAEL;AACA;AACA;AACA;AACA,KAAK;;AAEL;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA,SAAS;AACT,KAAK;AACL;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;;AAEA;AACA,gCAAgC;AAChC;AACA,KAAK,OAAO;AACZ;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA,KAAK;AACL;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,KAAK;;AAEL;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb,SAAS;AACT;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA,KAAK;;AAEL;AACA;AACA;AACA;AACA,SAAS;AACT,KAAK;;AAEL;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA,SAAS;AACT,KAAK;;AAEL;AACA;AACA;AACA,SAAS;AACT,KAAK;AACL;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA,aAAa;AACb;AACA;AACA;;AAEA;AACA;AACA;AACA,aAAa;AACb;AACA;;;AAGA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA,wGAAwG;AACxG;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,yBAAyB;AACzB;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA,SAAS;AACT,KAAK;AACL;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,4CAA4C,kCAAkC,EAAE;;AAEhF;AACA,4CAA4C,uCAAuC,EAAE;;AAErF;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,SAAS;AACT,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb,SAAS;AACT,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;;AAEA,SAAS;AACT,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT,KAAK;AACL;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB;AACrB;AACA;AACA;AACA,iBAAiB;AACjB,aAAa;;AAEb;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB,aAAa;AACb,SAAS;AACT,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB;AACrB;AACA,aAAa;;AAEb;;AAEA;AACA;AACA;AACA,SAAS;AACT;AACA;;;;;;;;;;;;AC3kBA,oBAAoB,mBAAO,CAAC,oJAAwB;AACpD,uBAAuB,mBAAO,CAAC,qKAA2C;AAC1E,2BAA2B,mBAAO,CAAC,4JAAoC;AACvE,WAAW,mBAAO,CAAC,6GAAQ;;;AAG3B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,WAAW,OAAO;AAClB,WAAW,OAAO;AAClB,WAAW,OAAO;AAClB,WAAW,OAAO;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;;AAEA;AACA;AACA;AACA,WAAW,OAAO;AAClB,YAAY,cAAc;AAC1B;AACA;AACA;;AAEA;AACA;;AAEA,YAAY;AACZ;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,WAAW,OAAO;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA,kCAAkC;AAClC;AACA;AACA;;AAEA;;AAEA;AACA,SAAS;AACT;AACA;AACA;AACA,KAAK;AACL;;AAEA;AACA;AACA;AACA,KAAK;AACL,CAAC;AACD;AACA;AACA;AACA,KAAK;AACL,CAAC;AACD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,wCAAwC,kCAAkC,EAAE;;AAE5E;AACA,wCAAwC,uCAAuC,EAAE;;AAEjF;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;;;;;;;;;;;;ACtUa;;AAEb,qBAAqB,mBAAO,CAAC,0HAAW;;AAExC;AACA,mBAAmB,mBAAO,CAAC,yHAAkB;AAC7C,mBAAmB,mBAAO,CAAC,2JAAmC;AAC9D,mBAAmB,mBAAO,CAAC,mIAA4B;AACvD,mBAAmB,mBAAO,CAAC,qKAA2C;AACtE,mBAAmB,mBAAO,CAAC,mIAA+B;AAC1D,CAAC,E;;;;;;;;;;;;ACVD;AACa;;AAEb;AACA;AACA;AACA,WAAW,OAAO;AAClB,WAAW,OAAO;AAClB,aAAa,OAAO;AACpB;AACA;AACA;AACA;AACA;AACA,KAAK;;AAEL;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB;AACpB,SAAS;AACT;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA,aAAa;AACb;;AAEA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,IAAI;AACJ;AACA,uCAAuC;AACvC;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;;AAEA;AACA;AACA,WAAW,OAAO;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,OAAO;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA,KAAK;AACL;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;;AAEA;AACA,uBAAuB,oCAAoC;AAC3D;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,YAAY;AACvB,aAAa,QAAQ;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,WAAW,YAAY;AACvB,aAAa,QAAQ;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB;;AAErB,0DAA0D;;AAE1D;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;;AAEA;AACA;AACA,WAAW,OAAO;AAClB,aAAa,QAAQ;AACrB;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,OAAO;AAClB,aAAa,QAAQ;AACrB;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB;AACrB;AACA;AACA;AACA,iBAAiB;AACjB;;AAEA;AACA,yCAAyC,SAAS,KAAK,YAAY;AACnE,yBAAyB,YAAY;AACrC;AACA;;AAEA;AACA,SAAS;AACT,KAAK;;AAEL;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA,aAAa;AACb;AACA;AACA,SAAS;AACT,KAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb,SAAS;AACT,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,SAAS;AACT,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB;AACrB;AACA;;AAEA;AACA,aAAa;AACb,SAAS;AACT,KAAK;AACL;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb,SAAS;AACT,KAAK;AACL;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb,SAAS;AACT;AACA;;;;;;;;;;;;AC/iBA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA,sCAAsC,0DAA0D;;AAEhG;;AAEA;AACA;AACA;;AAEA;AACA;AACA,wDAAwD;AACxD,+CAA+C;AAC/C;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;;AAEb;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA,SAAS;AACT;AACA;;AAEA;AACA;;AAEA,aAAa;AACb,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gDAAgD;;AAEhD;AACA,SAAS;AACT;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,4FAA4F,6BAA6B;AACzH;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA,sCAAsC;AACtC,wCAAwC;AACxC,iCAAiC;AACjC,6EAA6E;AAC7E,2EAA2E;AAC3E,wCAAwC;AACxC,+GAA+G;AAC/G,2IAA2I;AAC3I,kDAAkD;AAClD,kDAAkD;AAClD,uFAAuF;AACvF,sCAAsC;AACtC,kCAAkC;AAClC;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA,sCAAsC;AACtC,wCAAwC;AACxC,iCAAiC;AACjC,6DAA6D;AAC7D,2DAA2D;AAC3D,6DAA6D;AAC7D,8DAA8D;AAC9D,+GAA+G;AAC/G,kDAAkD;AAClD,kDAAkD;AAClD,0DAA0D;AAC1D,sCAAsC;AACtC,yDAAyD;AACzD;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,sCAAsC;AACtC,wCAAwC;AACxC,kCAAkC;AAClC,uDAAuD;AACvD,qDAAqD;AACrD,wHAAwH;AACxH,kDAAkD;AAClD,kDAAkD;AAClD,yEAAyE;AACzE,iEAAiE;AACjE,uFAAuF;AACvF,6BAA6B;AAC7B,0DAA0D;AAC1D,kCAAkC;AAClC,sCAAsC;AACtC;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA,gCAAgC;AAChC,oCAAoC;AACpC,iDAAiD;AACjD,+CAA+C;AAC/C,mEAAmE;AACnE,0CAA0C;AAC1C,4BAA4B;;AAE5B;AACA;;AAEA;AACA;AACA,mCAAmC;AACnC,wCAAwC;AACxC,iCAAiC;AACjC,oEAAoE;AACpE,mEAAmE;AACnE,+GAA+G;AAC/G,kDAAkD;AAClD,kDAAkD;AAClD,uEAAuE;AACvE,0DAA0D;AAC1D;;AAEA;AACA;AACA;AACA,0GAA0G;AAC1G;;AAEA;AACA,8EAA8E,oEAAoE;;AAElJ;AACA;AACA;AACA;AACA,oCAAoC;AACpC,kDAAkD;AAClD,oDAAoD;AACpD,iDAAiD;AACjD,+CAA+C;AAC/C;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,+GAA+G;AAC/G;AACA;AACA;AACA,qBAAqB;;AAErB;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA,wCAAwC;AACxC,8BAA8B;AAC9B,+BAA+B;AAC/B,qDAAqD;AACrD,mDAAmD;AACnD,qCAAqC;AACrC;AACA;AACA;AACA;AACA,yBAAyB;AACzB;AACA;;AAEA;AACA;AACA;AACA,0BAA0B;AAC1B,mDAAmD;AACnD,qDAAqD;AACrD,+DAA+D;AAC/D;AACA;AACA,iBAAiB;AACjB;AACA;;AAEA,sDAAsD,wBAAwB;AAC9E,6BAA6B,kBAAkB,cAAc,wBAAwB;AACrF;AACA,2DAA2D,cAAc;;AAEzE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA;AACA;;AAEA,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;;AAEjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA;;AAEA;AACA;AACA;AACA,qBAAqB;;AAErB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,aAAa;;AAEb;;AAEA;AACA;AACA;AACA;AACA;AACA,aAAa;;AAEb;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA,aAAa;AACb;;AAEA;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA,iBAAiB;AACjB;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB;;AAErB;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,yBAAyB;;AAEzB;AACA;AACA;AACA;AACA,6BAA6B;AAC7B;;AAEA;AACA;AACA;AACA;AACA;AACA,yBAAyB;AACzB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB;AACrB;;AAEA,aAAa;AACb,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,yBAAyB;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;;AAET;AACA,SAAS;;AAET;AACA;AACA;;AAEA;;AAEA;AACA;AACA,gFAAgF;AAChF,gEAAgE;AAChE;AACA;AACA,4EAA4E;;AAE5E;AACA,mEAAmE;AACnE;AACA,8BAA8B;AAC9B;AACA;AACA;AACA;AACA,0HAA0H;AAC1H,+DAA+D;AAC/D;AACA;AACA,+DAA+D;AAC/D,+DAA+D;AAC/D;AACA;AACA,+DAA+D;AAC/D,yHAAyH;AACzH;AACA;AACA,4EAA4E;AAC5E,mEAAmE;;AAEnE;AACA;AACA,8BAA8B;AAC9B;AACA;;AAEA;AACA;AACA,+DAA+D;AAC/D,kDAAkD;AAClD;AACA;AACA,+DAA+D;AAC/D,iHAAiH;AACjH;AACA;AACA,0HAA0H;AAC1H,iHAAiH;AACjH;AACA;AACA,4EAA4E;;AAE5E;AACA,qHAAqH;AACrH;AACA,8BAA8B;AAC9B;AACA;AACA;AACA;AACA;AACA,iHAAiH;AACjH;AACA;AACA,iHAAiH;AACjH,iHAAiH;AACjH;AACA;AACA,iHAAiH;AACjH,oDAAoD;AACpD;AACA;AACA,4EAA4E;AAC5E,qHAAqH;;AAErH;AACA;AACA,8BAA8B;AAC9B;AACA;AACA;AACA;AACA,iHAAiH;AACjH,yHAAyH;AACzH;AACA;AACA,iHAAiH;AACjH,+DAA+D;AAC/D;AACA;AACA,gFAAgF;AAChF,+DAA+D;AAC/D;AACA,aAAa;AACb;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA,wEAAwE;AACxE,0EAA0E;;AAE1E;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,aAAa;;AAEb;AACA;AACA;AACA;AACA,iBAAiB;;AAEjB;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,oDAAoD;AACpD,oDAAoD;AACpD;AACA;;AAEA;AACA;;AAEA;;;AAGA,sCAAsC;;AAEtC;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,yBAAyB;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,SAAS;;AAET;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA,SAAS;;AAET;AACA;AACA;;AAEA;AACA,wGAAwG;AACxG,oDAAoD;AACpD,kDAAkD;AAClD,mCAAmC;AACnC,wCAAwC;AACxC,wDAAwD;AACxD;AACA,2CAA2C;AAC3C;AACA;AACA;AACA,aAAa;AACb;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,oDAAoD;AACpD,SAAS;;AAET;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;;AAEjB;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB;;AAErB;;AAEA;;AAEA;AACA;AACA;AACA;AACA,qBAAqB;AACrB;;AAEA;AACA;AACA;AACA,iBAAiB;;AAEjB;AACA;AACA;AACA;AACA;AACA,yBAAyB;;AAEzB;AACA;AACA;AACA,yBAAyB;AACzB;AACA;;AAEA;AACA;AACA;AACA;AACA,qBAAqB;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,iBAAiB;;AAEjB;AACA;AACA;AACA;AACA,qBAAqB;AACrB;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;;AAET;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,qBAAqB;AACrB;AACA;AACA,SAAS;;AAET;AACA;AACA;AACA,SAAS;;AAET;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,yBAAyB;AACzB;AACA;AACA;AACA;AACA;AACA,yBAAyB;AACzB;AACA,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA,SAAS;;AAET;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB;AACrB;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,qBAAqB;AACrB;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA,qBAAqB;AACrB;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA,qBAAqB;AACrB;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;;AAEb;AACA;AACA;AACA,SAAS;;AAET;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;;AAEA,aAAa;AACb;AACA;AACA,SAAS;;AAET;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;;AAET;AACA;AACA,kCAAkC;AAClC;AACA;AACA,SAAS;;AAET;AACA;;AAEA;AACA;AACA;AACA,aAAa;;AAEb;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA,SAAS;AACT;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,CAAC;;;;;;;;;;;;;ACn6DD;AAAA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA,6CAA6C;AAC7C,2BAA2B;AAC3B;AACA;;AAEA;;AAEA,yBAAyB,0BAA0B;AACnD;;AAEA,iCAAiC;AACjC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA,GAAG;AACH;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,2CAA2C;AAC3C;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA,SAAS;AACT;AACA;AACA,SAAS;AACT;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;;AAET;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;;AAET;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;;AAET;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;;AAET;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;;AAET;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,SAAS;;AAET;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;;AAET;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;;AAEjB;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,SAAS;;AAET;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;;AAET;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;;AAET;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA,SAAS;;AAET;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA,SAAS;;AAET;AACA;AACA;AACA,oBAAoB,OAAO;AAC3B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,SAAS;;AAET;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;;AAET;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA,SAAS;;AAET;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;;AAET;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB;AACpB;AACA;AACA;AACA,SAAS;;AAET;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mBAAmB;AACnB;AACA;AACA;AACA;AACA;AACA,mBAAmB;AACnB;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;;AAET;AACA;AACA;AACA,oBAAoB;AACpB;AACA;AACA;AACA,SAAS;;AAET;AACA;AACA;AACA;AACA;AACA,6CAA6C,YAAY,EAAE;AAC3D,6CAA6C,YAAY,EAAE;AAC3D;AACA,SAAS;;AAET;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;;AAET;AACA;AACA;AACA,aAAa;AACb;AACA;AACA,SAAS;;AAET;AACA;AACA;AACA,oBAAoB;AACpB;AACA;AACA;AACA;AACA;AACA,SAAS;;AAET;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA;AACA,iBAAiB;;AAEjB;AACA;AACA;AACA;AACA;AACA,SAAS;;AAET;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,iBAAiB;;AAEjB;AACA;AACA;AACA;AACA;AACA,SAAS;;AAET;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;;AAET;AACA;AACA,oBAAoB,OAAO;AAC3B;AACA;AACA;AACA;;AAEA;AACA,SAAS;;AAET;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;;AAET;AACA;AACA;AACA,oBAAoB,OAAO;AAC3B;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA,SAAS;;AAET;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb,SAAS;;AAET;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4CAA4C,QAAQ;AACpD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA,SAAS;;AAET;AACA;AACA;AACA;AACA;AACA,SAAS;;AAET;AACA;AACA;AACA,oBAAoB;AACpB;AACA;AACA;AACA,SAAS;;AAET;AACA;AACA,SAAS;;AAET;AACA;AACA,SAAS;;AAET;AACA;AACA,SAAS;;AAET;AACA;AACA,SAAS;;AAET;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA,SAAS;;AAET;AACA;AACA;AACA;AACA,SAAS;;AAET;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,aAAa;;AAEb;AACA;AACA;AACA,SAAS;;AAET;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB;;AAErB;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,aAAa;AACb,SAAS;;AAET;AACA;AACA;AACA;AACA;AACA,SAAS;;AAET;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;;AAEb;AACA;AACA;AACA,iBAAiB;AACjB;AACA,iBAAiB;AACjB;AACA;AACA,aAAa;;AAEb;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB,aAAa;;AAEb;AACA;AACA;AACA;AACA;AACA,aAAa;;AAEb;AACA;AACA;AACA;AACA,aAAa;;AAEb;AACA;AACA;AACA,aAAa;;AAEb;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA;;AAEA;AACA;AACA;AACA,aAAa;AACb;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;;AAET;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,SAAS;;AAET;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;;AAEA;AACA;;AAEA;;AAEe,wEAAS,EAAC;;;;;;;;;;;;ACh5BzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA,SAAS;AACT,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,yBAAyB;AACzB;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB;AACrB;AACA,aAAa;AACb;AACA;AACA;AACA,SAAS;AACT;AACA,C;;;;;;;;;;;;ACxFa;;AAEb,mBAAmB,mBAAO,CAAC,2JAAyC;AACpE;AACA;AACA,WAAW,YAAY;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,WAAW,YAAY;AACvB;AACA;AACA;AACA;AACA,KAAK;AACL;;AAEA;AACA;AACA,WAAW,OAAO;AAClB,WAAW,OAAO;AAClB,WAAW,OAAO;AAClB;AACA;AACA;AACA;AACA,sDAAsD,sBAAsB;AAC5E;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,0BAA0B;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,WAAW,OAAO;AAClB,WAAW,OAAO;AAClB,WAAW,OAAO;AAClB,WAAW,OAAO;AAClB;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,KAAK;AACL;;AAEA;AACA;AACA,WAAW,YAAY;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,WAAW,MAAM;AACjB,WAAW,OAAO;AAClB;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;;AAEb;AACA;AACA,aAAa;;AAEb;AACA;AACA,KAAK;AACL;;AAEA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA,SAAS;AACT,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;;AAEjB,uDAAuD;AACvD,aAAa;AACb;AACA;AACA;;AAEA;AACA,2CAA2C;AAC3C;AACA;AACA;AACA;AACA,SAAS;AACT,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;;AAET;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;;AAET,KAAK;AACL;AACA;AACA;AACA;AACA,SAAS;AACT,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB;AACrB;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA,aAAa;AACb,SAAS;AACT,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;;;;;;;;;;;;;AC3Ua;;AAEb;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA,iBAAiB;AACjB;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB;AACrB;AACA;AACA;AACA;AACA;AACA,yBAAyB;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB;AACrB;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB,aAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb,SAAS;AACT;AACA;;;;;;;;;;;;;AClFa;;AAEb;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT,kDAAkD;AAClD;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;AClCa;AACb,kBAAkB,mBAAO,CAAC,gJAAqB;;AAE/C;AACA;AACA,WAAW,OAAO;AAClB,YAAY,OAAO;AACnB;AACA;AACA;;AAEA;AACA;AACA,KAAK;AACL;AACA,KAAK;AACL;AACA;;AAEA;AACA;;AAEA;AACA;AACA,WAAW,OAAO;AAClB,YAAY,OAAO;AACnB;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;;AAEA;AACA;AACA,WAAW,OAAO;AAClB,YAAY,OAAO;AACnB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,WAAW,OAAO;AAClB,WAAW,OAAO;AAClB,WAAW,SAAS;AACpB,WAAW,OAAO;AAClB,WAAW,OAAO;AAClB,WAAW,QAAQ;AACnB;AACA;AACA,WAAW,OAAO;AAClB,WAAW,OAAO;AAClB;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;;AAEA;AACA;AACA,SAAS;AACT;AACA;;AAEA;AACA;;AAEA;AACA,KAAK;AACL;;AAEA;AACA;AACA;AACA,WAAW,OAAO;AAClB,WAAW,OAAO;AAClB,WAAW,SAAS;AACpB,WAAW,OAAO;AAClB,WAAW,OAAO;AAClB,WAAW,QAAQ;AACnB;AACA;AACA,WAAW,OAAO;AAClB;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,KAAK;AACL;;AAEA;AACA;AACA;AACA;AACA,WAAW,OAAO;AAClB,WAAW,OAAO;AAClB,WAAW,OAAO;AAClB,WAAW,OAAO;AAClB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA,KAAK;AACL;;AAEA;AACA;AACA;AACA,WAAW,OAAO;AAClB;AACA,WAAW,OAAO;AAClB;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA,SAAS;AACT;;AAEA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;;AAEA;AACA;AACA;AACA,WAAW,MAAM;AACjB,YAAY,OAAO;AACnB;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA,KAAK;;AAEL;AACA;;AAEA;AACA;AACA;AACA,cAAc,OAAO;AACrB,cAAc,OAAO;AACrB;;AAEA;AACA;AACA;AACA,cAAc,OAAO;AACrB,cAAc,OAAO;AACrB,cAAc,OAAO;AACrB,cAAc,qBAAqB;AACnC;;AAEA;AACA;AACA;AACA,WAAW,wBAAwB;AACnC,WAAW,OAAO;AAClB;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,WAAW,SAAS;AACpB,WAAW,OAAO;AAClB;AACA;AACA;AACA;AACA;AACA;AACA,mBAAmB,iBAAiB;AACpC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,WAAW,OAAO;AAClB,WAAW,OAAO;AAClB,WAAW,OAAO;AAClB,WAAW,SAAS;AACpB,WAAW,SAAS;AACpB,WAAW,QAAQ;AACnB;AACA;AACA,WAAW,OAAO;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA,SAAS;AACT,KAAK;AACL;AACA;AACA;AACA,SAAS;AACT;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,cAAc,QAAQ;AACtB,cAAc,OAAO;AACrB,cAAc,OAAO;AACrB;AACA;;AAEA;AACA;AACA,WAAW,kBAAkB;AAC7B,WAAW,OAAO;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;;AAEA;AACA;AACA;AACA,WAAW,OAAO;AAClB,WAAW,OAAO;AAClB;AACA;AACA;AACA;AACA,aAAa,sDAAsD;;AAEnE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB,2CAA2C;AAChE;AACA,aAAa;AACb;AACA;AACA;AACA,SAAS;AACT;AACA;;AAEA;AACA;AACA;AACA,YAAY,OAAO;AACnB;AACA;AACA;AACA;;AAEA;AACA;AACA,WAAW,OAAO;AAClB;AACA,YAAY,OAAO;AACnB;AACA;AACA;;AAEA;AACA;;AAEA,YAAY;AACZ;;AAEA;AACA;AACA;AACA,WAAW,OAAO;AAClB;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mDAAmD;AACnD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,KAAK;AACL;;AAEA;AACA;AACA,WAAW,OAAO;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,SAAS;AACT;AACA;;AAEA;AACA;AACA;AACA;AACA,YAAY,SAAS;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT,KAAK;;AAEL;AACA;;AAEA;AACA;AACA;AACA,WAAW,OAAO;AAClB,YAAY,OAAO;AACnB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;;AAET;AACA;;AAEA;AACA;AACA;AACA,WAAW,iBAAiB;AAC5B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA,SAAS;AACT;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;;AAEL;AACA;AACA;AACA;AACA,SAAS;AACT,KAAK;;AAEL;AACA;AACA;AACA,SAAS;AACT,KAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT,KAAK;;AAEL;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,SAAS;AACT,KAAK;;AAEL;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT,KAAK;;AAEL;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,SAAS;AACT,KAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,yBAAyB;AACzB;AACA,iBAAiB;AACjB;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB;AACrB;AACA;AACA;AACA,iBAAiB;AACjB;AACA,SAAS;AACT,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA,SAAS;AACT,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB;;AAEA;AACA;AACA,SAAS;AACT,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA,aAAa;AACb,SAAS;AACT,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB;AACrB;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,yBAAyB;AACzB,qBAAqB;AACrB;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,yBAAyB;AACzB;AACA,iBAAiB;AACjB;AACA;AACA;AACA,aAAa;AACb,SAAS;AACT,KAAK;;AAEL;AACA;AACA;AACA;;;;;;;;;;;;;AC/0Ba;AACb,WAAW,mBAAO,CAAC,+HAAQ;AAC3B,kBAAkB,mBAAO,CAAC,gJAAqB;;AAE/C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mDAAmD;AACnD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,aAAa,OAAO;AACpB,cAAc,OAAO;AACrB,cAAc,OAAO;AACrB;;AAEA;AACA;AACA;AACA,WAAW,OAAO;AAClB,YAAY,cAAc;AAC1B;AACA;AACA;;AAEA;AACA;;AAEA,YAAY;AACZ;;AAEA;AACA;AACA,WAAW,OAAO;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,SAAS;AACT;AACA;AACA;AACA,KAAK;AACL;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT,KAAK;AACL;AACA;AACA;AACA,SAAS;AACT,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT,KAAK;AACL;AACA;AACA;AACA;AACA;AACA,SAAS;AACT,KAAK;AACL;AACA;AACA;AACA,SAAS;AACT,KAAK;AACL;AACA;AACA;AACA,SAAS;AACT,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA,aAAa;AACb;AACA;AACA;AACA;AACA,SAAS;AACT,KAAK;AACL;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,SAAS;AACT,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAGA;AACA;;AAEA;AACA;AACA;AACA,4CAA4C,kCAAkC,EAAE;;AAEhF;AACA,4CAA4C,uCAAuC,EAAE;;AAErF;AACA;AACA;;AAEA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;;;;;;;;;;;;;ACxMa;;AAEb;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA,SAAS;AACT;AACA","file":"default/js/productDetail.js","sourcesContent":[" \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId]) {\n \t\t\treturn installedModules[moduleId].exports;\n \t\t}\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// define getter function for harmony exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tif(!__webpack_require__.o(exports, name)) {\n \t\t\tObject.defineProperty(exports, name, { enumerable: true, get: getter });\n \t\t}\n \t};\n\n \t// define __esModule on exports\n \t__webpack_require__.r = function(exports) {\n \t\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n \t\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n \t\t}\n \t\tObject.defineProperty(exports, '__esModule', { value: true });\n \t};\n\n \t// create a fake namespace object\n \t// mode & 1: value is a module id, require it\n \t// mode & 2: merge all properties of value into the ns\n \t// mode & 4: return value when already ns object\n \t// mode & 8|1: behave like require\n \t__webpack_require__.t = function(value, mode) {\n \t\tif(mode & 1) value = __webpack_require__(value);\n \t\tif(mode & 8) return value;\n \t\tif((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;\n \t\tvar ns = Object.create(null);\n \t\t__webpack_require__.r(ns);\n \t\tObject.defineProperty(ns, 'default', { enumerable: true, value: value });\n \t\tif(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));\n \t\treturn ns;\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(__webpack_require__.s = \"../app_ashleystewart/cartridges/app_ashleystewart/cartridge/client/default/js/productDetail.js\");\n","'use strict';\n/**\n * load and collapse/uncollapse the size chart section\n */\nfunction sizeChartCollaps(){\n $('body').on('click', '.size-chart a',function (e) {\n e.preventDefault();\n var url = $(this).attr('href');\n var $prodSizeChart = $(this).closest('.size-chart').find('.size-chart-content');\n if ($prodSizeChart.is(':empty')) {\n $.ajax({\n url: url,\n type: 'get',\n dataType: 'json',\n success: function (data) {\n $prodSizeChart.append(data.content);\n }\n });\n }\n });\n}\nmodule.exports = {\n sizeChartCollaps: sizeChartCollaps\n};","function showMaxQuantityMsg($qtnBtn) {\n const itemuuid = $qtnBtn.data('uuid')\n const $maxMsgSection = $('.max-qtn-reached[data-itemuuid='+ itemuuid +']');\n $maxMsgSection.removeClass('d-none');\n}\nfunction hideMaxQuantityMsg($qtnBtn) {\n const itemuuid = $qtnBtn.data('uuid')\n const $maxMsgSection = $('.max-qtn-reached[data-itemuuid='+ itemuuid +']');\n $maxMsgSection.addClass('d-none');\n}\n\nfunction customNumberInput () {\n $('body').on('click', '.number-input .qty-btn-minus, .number-input .qty-btn-plus', function(e) {\n var $direction = $(this);\n var $numberInput = $direction.siblings('input');\n const isReachedMax = $numberInput.val() >= parseInt($numberInput.attr('max'));\n if($direction.data('direction') === \"plus\") {\n if (isReachedMax) {\n e.preventDefault();\n showMaxQuantityMsg($(this));\n return;\n }\n $numberInput[0].stepUp();\n } else {\n if (isReachedMax) {\n hideMaxQuantityMsg($(this));\n }\n $numberInput[0].stepDown();\n }\n $numberInput.change();\n });\n}\n\nfunction adjustHeader() {\n var dynamicMargin = $('header').height();\n if(dynamicMargin) {\n $('.main').css('padding-top', dynamicMargin);\n }\n}\n\nfunction smartResize(callback) {\n var timeout;\n\n $(window).on('resize', function () {\n clearTimeout(timeout);\n timeout = setTimeout(callback, 100);\n }).resize();\n\n return callback;\n};\n\nfunction headerListeners () {\n var mediaQuery = '(min-width: 1024px)';\n var mediaQueryList = window.matchMedia(mediaQuery);\n\n // Some versions if iOS on iPad dont' support addEventListener, have to use deprecated addListener\n // More here: https://github.com/mdn/sprints/issues/858\n if (mediaQueryList.addEventListener) {\n mediaQueryList.addEventListener('change', event => {\n adjustHeader();\n });\n } else {\n mediaQueryList.addListener(adjustHeader);\n }\n \n $('body').on('header:resize', function(){\n adjustHeader();\n })\n\n smartResize(function () {\n adjustHeader();\n });\n}\n\nmodule.exports = {\n customNumberInput: customNumberInput,\n header: function() {\n var $staticHeader = $('.main.static-header');\n if(!$staticHeader.length) {\n adjustHeader();\n headerListeners();\n }\n },\n smartResize: smartResize\n}","'use strict';\n\nmodule.exports = function () {\n $('body').on('mouseenter focusin touchend', '.info-icon', function (e) {\n e.preventDefault();\n var $toolTip = $(this);\n var $content = $toolTip.closest('.tooltip-wrapper').find('.tooltip');\n var contentWidth = $content.outerWidth();\n var $offsetLeft = $toolTip.offset().left;\n var windowWidth = $(window).outerWidth();\n\n $toolTip.closest('.tooltip-wrapper').find('.tooltip').removeClass('d-none');\n\n if (windowWidth / 2 < $offsetLeft) {\n $content.css('left', -contentWidth);\n } else {\n $content.css('left', 0);\n }\n });\n $('body').on('click touchend mouseenter focusin', '.close-tooltip', function (e) {\n e.preventDefault();\n $(this).closest('.tooltip').addClass('d-none');\n });\n\n $('body').on('mouseleave focusout', '.info-icon', function (e) {\n e.preventDefault();\n $(this).closest('.tooltip-wrapper').find('.tooltip').addClass('d-none');\n });\n $(document).on('click', function(e){\n if (!$(e.target).closest('.tooltip-content').length) {\n $('.tooltip-wrapper').find('.tooltip').addClass('d-none');\n }\n });\n};\n","'use strict';\n\nvar focusHelper = require('base/components/focus');\n\nfunction displayToastNotification(toastType, toastMessage) {\n if ($('.add-to-cart-messages').length === 0) {\n $('body').append(\n '
'\n );\n }\n\n $('.add-to-cart-messages').append(\n '
'\n + toastMessage\n + '
'\n );\n\n setTimeout(function () {\n $('.add-to-basket-alert').remove();\n }, 5000);\n}\n\n/**\n * Show add to bag modal\n * @param {Object} data - DOM container for a given add to cart button\n */\nfunction showAddToBagModal(data) {\n if (!data.error) {\n var $addToBagModal = $('#addToBagModal');\n $addToBagModal.find('.product-added').html(data.addedProductCardHtml);\n $addToBagModal.modal('show');\n\n const addToBagTimer = setInterval(removeModal, 5000);\n\n function removeModal() {\n if ($('#addToBagModal .modal-dialog:hover').length === 0) {\n $addToBagModal.modal('hide');\n clearInterval(addToBagTimer);\n }\n }\n }\n}\n\n/**\n * Retrieves the relevant pid value\n * @param {jquery} $el - DOM container for a given add to cart button\n * @return {string} - value to be used when adding product to cart\n */\nfunction getPidValue($el) {\n var pid;\n\n if ($('#quickViewModal').hasClass('show') && !$('.product-set').length) {\n pid = $($el).closest('.modal-content').find('.product-quickview').data('pid');\n } else if ($('.product-set-detail').length || $('.product-set').length) {\n pid = $($el).closest('.product-detail').find('.product-id').text();\n } else if ($($el).hasClass('btn-update-wishlist-product')) {\n pid = $($el).data('pid');\n }else {\n pid = $('.product-detail:not(\".bundle-item\")').attr('data-pid');\n }\n\n return pid;\n}\n\n/**\n * Retrieve contextual quantity selector\n * @param {jquery} $el - DOM container for the relevant quantity\n * @return {jquery} - quantity selector DOM container\n */\nfunction getQuantitySelector($el) {\n var quantitySelected;\n if ($el && $('.set-items').length) {\n quantitySelected = $($el).closest('.product-detail').find('.quantity-select');\n } else if ($el && $('.product-bundle').length) {\n var quantitySelectedModal = $($el).closest('.modal-footer').find('.quantity-select');\n var quantitySelectedPDP = $($el).closest('.bundle-footer').find('.quantity-select');\n if (quantitySelectedModal.val() === undefined) {\n quantitySelected = quantitySelectedPDP;\n } else {\n quantitySelected = quantitySelectedModal;\n }\n } else {\n quantitySelected = $('.quantity-select');\n }\n return quantitySelected;\n}\n\n/**\n * Retrieves the value associated with the Quantity pull-down menu\n * @param {jquery} $el - DOM container for the relevant quantity\n * @return {string} - value found in the quantity input\n */\nfunction getQuantitySelected($el) {\n return getQuantitySelector($el).val();\n}\n\n/**\n * Process the attribute values for an attribute that has image swatches\n *\n * @param {Object} attr - Attribute\n * @param {string} attr.id - Attribute ID\n * @param {Object[]} attr.values - Array of attribute value objects\n * @param {string} attr.values.value - Attribute coded value\n * @param {string} attr.values.url - URL to de/select an attribute value of the product\n * @param {boolean} attr.values.isSelectable - Flag as to whether an attribute value can be\n * selected. If there is no variant that corresponds to a specific combination of attribute\n * values, an attribute may be disabled in the Product Detail Page\n * @param {jQuery} $productContainer - DOM container for a given product\n * @param {Object} msgs - object containing resource messages\n */\nfunction processSwatchValues(attr, $productContainer, msgs) {\n attr.values.forEach(function (attrValue) {\n var $attrValue = $productContainer.find('[data-attr=\"' + attr.id + '\"] [data-attr-value=\"' +\n attrValue.value + '\"]');\n var $btnSwatch = $attrValue.closest('.base-swatch');\n var $swatchButton = $attrValue.parent();\n var $valueLabel = $productContainer.find('[data-attr=\"' + attr.id + '\"] .' + attr.id + '-selected-value');\n\n if (attrValue.selected) {\n $attrValue.addClass('selected');\n $btnSwatch.addClass('selected');\n $attrValue.siblings('.selected-assistive-text').text(msgs.assistiveSelectedText);\n $valueLabel.text(attrValue.displayValue);\n } else {\n $attrValue.removeClass('selected');\n $btnSwatch.removeClass('selected');\n $attrValue.siblings('.selected-assistive-text').empty();\n }\n\n if (attrValue.url) {\n $swatchButton.attr('data-url', attrValue.url);\n } else {\n $swatchButton.removeAttr('data-url');\n }\n\n // Disable if not selectable\n $attrValue.removeClass('selectable unselectable');\n $btnSwatch.removeAttr('disabled');\n\n $attrValue.addClass(attrValue.selectable ? 'selectable' : 'unselectable');\n if (attrValue.selectable) {\n $btnSwatch.removeAttr('disabled');\n } else {\n $btnSwatch.attr('disabled', true);\n }\n });\n}\n\n/**\n * Process attribute values associated with an attribute that does not have image swatches\n *\n * @param {Object} attr - Attribute\n * @param {string} attr.id - Attribute ID\n * @param {Object[]} attr.values - Array of attribute value objects\n * @param {string} attr.values.value - Attribute coded value\n * @param {string} attr.values.url - URL to de/select an attribute value of the product\n * @param {boolean} attr.values.isSelectable - Flag as to whether an attribute value can be\n * selected. If there is no variant that corresponds to a specific combination of attribute\n * values, an attribute may be disabled in the Product Detail Page\n * @param {jQuery} $productContainer - DOM container for a given product\n */\nfunction processNonSwatchValues(attr, $productContainer) {\n var $attr = '[data-attr=\"' + attr.id + '\"]';\n var $defaultOption = $productContainer.find($attr + ' .select-' + attr.id + ' option:first');\n $defaultOption.attr('value', attr.resetUrl);\n\n attr.values.forEach(function (attrValue) {\n var $attrValue = $productContainer\n .find($attr + ' [data-attr-value=\"' + attrValue.value + '\"]');\n $attrValue.attr('value', attrValue.url)\n .removeAttr('disabled');\n\n if (!attrValue.selectable) {\n $attrValue.attr('disabled', true);\n }\n });\n}\n\n/**\n * Routes the handling of attribute processing depending on whether the attribute has image\n * swatches or not\n *\n * @param {Object} attrs - Attribute\n * @param {string} attr.id - Attribute ID\n * @param {jQuery} $productContainer - DOM element for a given product\n * @param {Object} msgs - object containing resource messages\n */\nfunction updateAttrs(attrs, $productContainer, msgs) {\n // Currently, the only attribute type that has image swatches is Color.\n var attrsWithSwatches = ['color', 'length', 'size'];\n\n attrs.forEach(function (attr) {\n if (attrsWithSwatches.indexOf(attr.id) > -1) {\n processSwatchValues(attr, $productContainer, msgs);\n } else {\n processNonSwatchValues(attr, $productContainer);\n }\n });\n}\n\n/**\n * Updates the availability status in the Product Detail Page\n *\n * @param {Object} response - Ajax response object after an\n * attribute value has been [de]selected\n * @param {jQuery} $productContainer - DOM element for a given product\n */\nfunction updateAvailability(response, $productContainer) {\n var shipToStore = response.storeAvailability;\n if (response.product.available && response.product.availableForInStorePickup && response.product.readyToOrder) {\n if (shipToStore) {\n $('.selected-store').attr('data-store-id', response.store.ID);\n $('.pickup-in-store').addClass('has-store');\n }\n $productContainer.find('.shipToStoreRadio').attr('disabled', false);\n $productContainer.find('.pickup-in-store').removeClass('pickup-in-store-unavailable');\n } else {\n $productContainer.find('.shipToStoreRadio').attr('disabled', true);\n $productContainer.find('.pickup-in-store').addClass('pickup-in-store-unavailable');\n }\n\n $($productContainer).trigger('product:updateAvailability', {\n product: response.product,\n $productContainer: $productContainer,\n resources: response.resources,\n shipToStore: shipToStore\n });\n}\n\n/**\n * Generates html for product attributes section\n *\n * @param {array} attributes - list of attributes\n * @return {string} - Compiled HTML\n */\nfunction getAttributesHtml(attributes) {\n if (!attributes) {\n return '';\n }\n\n var html = '';\n\n attributes.forEach(function (attributeGroup) {\n if (attributeGroup.ID === 'mainAttributes') {\n attributeGroup.attributes.forEach(function (attribute) {\n html += '
' + attribute.label + ': '\n + attribute.value + '
';\n });\n }\n });\n\n return html;\n}\n\n/**\n * @typedef UpdatedOptionValue\n * @type Object\n * @property {string} id - Option value ID for look up\n * @property {string} url - Updated option value selection URL\n */\n\n/**\n * @typedef OptionSelectionResponse\n * @type Object\n * @property {string} priceHtml - Updated price HTML code\n * @property {Object} options - Updated Options\n * @property {string} options.id - Option ID\n * @property {UpdatedOptionValue[]} options.values - Option values\n */\n\n/**\n * Updates DOM using post-option selection Ajax response\n *\n * @param {OptionSelectionResponse} optionsHtml - Ajax response optionsHtml from selecting a product option\n * @param {jQuery} $productContainer - DOM element for current product\n */\nfunction updateOptions(optionsHtml, $productContainer) {\n\t// Update options\n $productContainer.find('.product-options').empty().html(optionsHtml);\n}\n\n/**\n * Dynamically creates Bootstrap carousel from response containing images\n * @param {Object[]} allImgs - Array of product images,along with related information\n * @param {Boolean} showFitBadge - Boolean indicating if fit badge should be displayed\n * @param {Boolean} fitBadgeText - Text to display if fit badge is shown\n * @param {Object} resources - Resource messages from the response\n * @param {jQuery} $productContainer - DOM element for a given product\n */\nfunction createCarousel(allImgs, showFitBadge, fitBadgeText, resources, $productContainer) {\n var imgs = allImgs['large'];\n var zoomImgs = allImgs['1428x2000'];\n var altImgs = allImgs['small'];\n var $carousel = $productContainer.find('.product-content-top .carousel');\n var $altImageContainer = $productContainer.find('.alt-images ul');\n $carousel.carousel('dispose');\n var carouselId = $carousel.attr('id');\n $carousel.empty()\n .attr('data-items', imgs.length.toString())\n .append('
');\n $altImageContainer.empty();\n for (var i = 0; i < imgs.length; i++) {\n var imageBadgeHTML = imgs[i].badgeText ? '' + imgs[i].badgeText + '' : '';\n $('
\"'' + imageBadgeHTML + '
').appendTo($carousel.find('.carousel-inner'));\n $('
  • ').appendTo($carousel.find('.carousel-indicators'));\n $('
  • \"'
  • ').appendTo($altImageContainer);\n }\n $carousel.find('.carousel-item').first().addClass('active');\n $carousel.carousel();\n $carousel.find('.carousel-indicators').attr('aria-hidden', true);\n\n // fit badging\n if(showFitBadge) {\n $('
    ' + fitBadgeText + '
    ').appendTo($carousel);\n }\n\n}\n\n/**\n * @param {String} badgeName - Name of badge to update or null of no badge exists\n * @param {Object} resources - Resource messages from the response\n * @param {jQuery} $productContainer - DOM element for a given product.\n */\nfunction updateBadging(badgeName, resources, $productContainer) {\n let $badgeContainer = $productContainer.find('.product-badge');\n\n if(badgeName) {\n if($badgeContainer.length) {\n // update existing badge div with new info\n $badgeContainer.empty().text(resources[badgeName]).attr('data-badge-type', badgeName);\n } else {\n // create badge div\n $badgeContainer = $('
    ' + resources[badgeName] + '
    ');\n const $imgWrapper = $productContainer.find('.image-layout-container');\n const $activeimage = $imgWrapper.find('.carousel-item.active');\n $activeimage.prepend($badgeContainer);\n }\n } else if($badgeContainer.length) {\n // set badge type to none\n $badgeContainer.attr('data-badge-type', 'none');\n }\n}\n\n/**\n * Parses JSON from Ajax call made whenever an attribute value is [de]selected\n * @param {Object} response - response from Ajax call\n * @param {Object} response.product - Product object\n * @param {string} response.product.id - Product ID\n * @param {Object[]} response.product.variationAttributes - Product attributes\n * @param {Object[]} response.product.images - Product images\n * @param {boolean} response.product.hasRequiredAttrsSelected - Flag as to whether all required\n * attributes have been selected. Used partially to\n * determine whether the Add to Cart button can be enabled\n * @param {jQuery} $productContainer - DOM element for a given product.\n */\nfunction handleVariantResponse(response, $productContainer) {\n var isChoiceOfBonusProducts =\n $productContainer.parents('.choose-bonus-product-dialog').length > 0;\n var isVaraint;\n if (response.product.variationAttributes) {\n updateAttrs(response.product.variationAttributes, $productContainer, response.resources);\n isVaraint = response.product.productType === 'variant';\n if (isChoiceOfBonusProducts && isVaraint) {\n $productContainer.parent('.bonus-product-item')\n .data('pid', response.product.id);\n\n $productContainer.parent('.bonus-product-item')\n .data('ready-to-order', response.product.readyToOrder);\n }\n }\n\n // Update image carousel\n createCarousel(response.product.images,\n response.product.showFitBadge,\n response.product.fitBadgeText,\n response.resources,\n $productContainer);\n\n // Update product badging\n updateBadging(response.product.productBadge, response.resources, $productContainer);\n\n // Update pricing\n if (!isChoiceOfBonusProducts) {\n var $priceSelector = $('.prices .price', $productContainer).length\n ? $('.prices .price', $productContainer)\n : $('.prices .price');\n $priceSelector.replaceWith(response.product.price.html);\n }\n\n // Update promotions\n $productContainer.find('.promotions').empty().html(response.product.promotionsHtml);\n\n updateAvailability(response, $productContainer);\n\n if (isChoiceOfBonusProducts) {\n var $selectButton = $productContainer.find('.select-bonus-product');\n $selectButton.trigger('bonusproduct:updateSelectButton', {\n product: response.product, $productContainer: $productContainer\n });\n } else {\n // Enable \"Add to Cart\" button if all required attributes have been selected\n $('button.add-to-cart, button.add-to-cart-global, button.update-cart-product-global').trigger('product:updateAddToCart', {\n product: response.product, $productContainer: $productContainer\n }).trigger('product:statusUpdate', response.product);\n }\n\n // Update attributes\n $productContainer.find('.main-attributes').empty()\n .html(getAttributesHtml(response.product.attributes));\n}\n\n/**\n * @typespec UpdatedQuantity\n * @type Object\n * @property {boolean} selected - Whether the quantity has been selected\n * @property {string} value - The number of products to purchase\n * @property {string} url - Compiled URL that specifies variation attributes, product ID, options,\n * etc.\n */\n\n/**\n * Updates the quantity DOM elements post Ajax call\n * @param {UpdatedQuantity[]} quantities -\n * @param {jQuery} $productContainer - DOM container for a given product\n */\nfunction updateQuantities(quantities, $productContainer) {\n if ($productContainer.parent('.bonus-product-item').length <= 0) {\n var selectedQuantity = 1;\n var optionsHtml = quantities.map(function (quantity) {\n var selected = quantity.selected ? ' selected ' : '';\n if (quantity.selected) {\n selectedQuantity = quantity.value;\n }\n return '';\n }).join('');\n getQuantitySelector($productContainer).empty().html(optionsHtml);\n $('.product-content-top .qty-number-input').val(selectedQuantity).data('url', quantities[0].url);\n }\n}\n\n/**\n * updates the product view when a product attribute is selected or deselected or when\n * changing quantity\n * @param {string} selectedValueUrl - the Url for the selected variation value\n * @param {jQuery} $productContainer - DOM element for current product\n * @param {boolean} fromModal - flag - when a attr was selected from the attributes pop-up\n */\nfunction attributeSelect(selectedValueUrl, $productContainer, fromModal) {\n var selecteFromModal = fromModal;\n if (selectedValueUrl) {\n $('body').trigger('product:beforeAttributeSelect',\n { url: selectedValueUrl, container: $productContainer });\n if ($('.update-cart-url').length != 0) {\n selectedValueUrl += '&uuid=' + $('.update-cart-url').data('uuid');\n }\n\n var storeId = $('.selected-store').attr('data-store-id');\n if (storeId) {\n selectedValueUrl += '&storeId=' + storeId;\n }\n var $pickupMethods = $('.pickup-method').find('input[type=radio]');\n var $checkedMethod;\n if ($pickupMethods.length > 1) {\n $pickupMethods.each(function(){\n if ($(this).is(\":checked\")) {\n $checkedMethod = $(this);\n return false;\n }\n })\n } else {\n $checkedMethod = $pickupMethods;\n }\n\n if ($checkedMethod) {\n selectedValueUrl += '&pickupMethod=' + $checkedMethod.val();\n }\n $.ajax({\n url: selectedValueUrl,\n method: 'GET',\n success: function (data) {\n handleVariantResponse(data, $productContainer);\n updateOptions(data.product.optionsHtml, $productContainer);\n updateQuantities(data.product.quantities, $productContainer);\n\n // if ($('.update-cart-url').length != 0) {\n // updateEditButton(data);\n // }\n $('body').trigger('product:afterAttributeSelect',\n { data: data, container: $productContainer , selecteFromModal: selecteFromModal});\n $.spinner().stop();\n },\n error: function () {\n $.spinner().stop();\n }\n });\n }\n}\n\n/**\n * check color / size / length variations to make sure there is a selection from each before they can add to cart\n */\n function checkVariationSelections($container) {\n var selectedColorVars = 0;\n var selectedSizeVars = 0;\n var selectedLengthVars = 0;\n var attributesSelectedData = [];\n var hasLength = $container.find('[data-attr=\"length\"]').length > 0;\n \n // Check color swatches\n $container.find('[data-attr=\"color\"] button').each(function () {\n if ($(this).find('span.selected').length > 0) {\n selectedColorVars++;\n }\n });\n\n // Check size options\n $container.find('[data-attr=\"size\"] button').each(function () {\n if ($(this).find('span.selected').length > 0) {\n selectedSizeVars++;\n }\n });\n\n // Check length options (if applicable)\n if (hasLength) {\n $container.find('[data-attr=\"length\"] button').each(function () {\n if ($(this).find('span.selected').length > 0) {\n selectedLengthVars++;\n }\n });\n }\n\n attributesSelectedData.push({\n allAttributesSelected: selectedColorVars > 0 && selectedSizeVars > 0 && ((hasLength && selectedLengthVars > 0) || !hasLength) ? true : false,\n selectedColorVars: selectedColorVars,\n selectedSizeVars: selectedSizeVars,\n selectedLengthVars: selectedLengthVars\n });\n\n return attributesSelectedData;\n\n }\n\n\nfunction updateEditButton(data) {\n var $updateBtn = $('.update-cart-product-global, .update-cart-product-global-back-to-pdp');\n if (!data.hasAvailability) {\n $updateBtn.html(\"Update Shipment\");\n $updateBtn.removeClass('update-cart-product-global');\n $updateBtn.addClass('update-cart-product-global-back-to-pdp');\n if ($('.out-of-stock-msg-edit').length == 0) {\n $('.add-to-cart-actions').append('
    This selection is currently unavailable with the selected shipment. Please update your shipment or choose a different stlye.
    ');\n }\n } else {\n $updateBtn.html(\"Update\");\n $updateBtn.addClass('update-cart-product-global');\n $updateBtn.removeClass('update-cart-product-global-back-to-pdp');\n if ($('.out-of-stock-msg-edit').length > 0) {\n $('.out-of-stock-msg-edit').remove();\n }\n }\n\n}\n\n/**\n * Retrieves url to use when adding a product to the cart\n *\n * @return {string} - The provided URL to use when adding a product to the cart\n */\nfunction getAddToCartUrl() {\n return $('.add-to-cart-url').val();\n}\n\n/**\n * Parses the html for a modal window\n * @param {string} html - representing the body and footer of the modal window\n *\n * @return {Object} - Object with properties body and footer.\n */\nfunction parseHtml(html) {\n var $html = $('
    ').append($.parseHTML(html));\n\n var body = $html.find('.choice-of-bonus-product');\n var footer = $html.find('.modal-footer').children();\n\n return { body: body, footer: footer };\n}\n\n/**\n * Retrieves url to use when adding a product to the cart\n *\n * @param {Object} data - data object used to fill in dynamic portions of the html\n */\nfunction chooseBonusProducts(data) {\n $('.modal-body').spinner().start();\n\n if ($('#chooseBonusProductModal').length !== 0) {\n $('#chooseBonusProductModal').remove();\n }\n var bonusUrl;\n if (data.bonusChoiceRuleBased) {\n bonusUrl = data.showProductsUrlRuleBased;\n } else {\n bonusUrl = data.showProductsUrlListBased;\n }\n\n var htmlString = ''\n + '
    '\n + ''\n + '
    '\n + ''\n + '
    '\n + '
    '\n + ' ' + data.labels.selectprods + ''\n + ' '\n + '
    '\n + '
    '\n + '
    '\n + '
    '\n + '
    '\n + '
    ';\n $('body').append(htmlString);\n\n $.ajax({\n url: bonusUrl,\n method: 'GET',\n dataType: 'json',\n success: function (response) {\n var parsedHtml = parseHtml(response.renderedTemplate);\n $('#chooseBonusProductModal .modal-body').empty();\n $('#chooseBonusProductModal .enter-message').text(response.enterDialogMessage);\n $('#chooseBonusProductModal .modal-header .close .sr-only').text(response.closeButtonText);\n $('#chooseBonusProductModal .modal-body').html(parsedHtml.body);\n $('#chooseBonusProductModal .modal-footer').html(parsedHtml.footer);\n $('#chooseBonusProductModal').modal('show');\n $.spinner().stop();\n },\n error: function () {\n $.spinner().stop();\n }\n });\n}\n\n/**\n * Updates the Mini-Cart quantity value after the customer has pressed the \"Add to Cart\" button\n * @param {string} response - ajax response from clicking the add to cart button\n */\nfunction handlePostCartAdd(response) {\n $('.minicart').trigger('count:update', response);\n var messageType = response.error ? 'alert-danger' : 'alert-success';\n // show add to cart toast\n if (response.newBonusDiscountLineItem\n && Object.keys(response.newBonusDiscountLineItem).length !== 0) {\n chooseBonusProducts(response.newBonusDiscountLineItem);\n } else if (response.error) {\n displayToastNotification(messageType, response.message);\n }\n}\n\n/**\n * Retrieves the bundle product item ID's for the Controller to replace bundle master product\n * items with their selected variants\n *\n * @return {string[]} - List of selected bundle product item ID's\n */\nfunction getChildProducts() {\n var childProducts = [];\n $('.bundle-item').each(function () {\n childProducts.push({\n pid: $(this).find('.product-id').text(),\n quantity: parseInt($(this).find('label.quantity').data('quantity'), 10)\n });\n });\n\n return childProducts.length ? JSON.stringify(childProducts) : [];\n}\n\n/**\n * Retrieve product options\n *\n * @param {jQuery} $productContainer - DOM element for current product\n * @return {string} - Product options and their selected values\n */\nfunction getOptions($productContainer) {\n var options = $productContainer\n .find('.product-option')\n .map(function () {\n var $elOption = $(this).find('.options-select');\n var urlValue = $elOption.val();\n var selectedValueId = $elOption.find('option[value=\"' + urlValue + '\"]')\n .data('value-id');\n return {\n optionId: $(this).data('option-id'),\n selectedValueId: selectedValueId\n };\n }).toArray();\n\n return JSON.stringify(options);\n}\n\n/**\n * Makes a call to the server to report the event of adding an item to the cart\n *\n * @param {string | boolean} url - a string representing the end point to hit so that the event can be recorded, or false\n */\nfunction miniCartReportingUrl(url) {\n if (url) {\n $.ajax({\n url: url,\n method: 'GET',\n success: function () {\n // reporting urls hit on the server\n },\n error: function () {\n // no reporting urls hit on the server\n }\n });\n }\n}\n\nfunction showDiscountMsg ($discounts, object) {\n $discounts.empty();\n if (object.length > 0) {\n $discounts.html('
    ');\n for (var i = 0; object.length > i; i++) {\n $('.minibag-discount-msg').append(object[i].discountMsg);\n }\n }\n}\n\nmodule.exports = {\n attributeSelect: attributeSelect,\n methods: {\n editBonusProducts: function (data) {\n chooseBonusProducts(data);\n },\n handlePostCartAdd: handlePostCartAdd\n },\n\n carouselAltImages: function () {\n // handle clicking on alt images\n $('body').off('click', '.alt-images li').on('click', '.alt-images li', function (e) {\n var $imagesContainer = $(e.target).closest('.primary-images .image-layout-container');\n if ($imagesContainer.find('.carousel').length) {\n var $selectedImageContainer = $(this);\n $imagesContainer.find('li.active').removeClass('active');\n $selectedImageContainer.addClass('active');\n $imagesContainer.find('.carousel').carousel($selectedImageContainer.data('index'));\n }\n });\n\n // handle updating alt images when carousel updates\n $('body').off('slid.bs.carousel', '.carousel').on('slid.bs.carousel', '.carousel', function(e) {\n var $altImageContainer = $(this).siblings('.alt-images');\n if ($altImageContainer.length) {\n $altImageContainer.find('li.active').removeClass('active');\n $altImageContainer.find('li[data-index=\"' + e.to + '\"]').addClass('active');\n }\n })\n },\n\n focusChooseBonusProductModal: function () {\n $('body').on('shown.bs.modal', '#chooseBonusProductModal', function () {\n $('#chooseBonusProductModal').siblings().attr('aria-hidden', 'true');\n $('#chooseBonusProductModal .close').focus();\n });\n },\n\n onClosingChooseBonusProductModal: function () {\n $('body').on('hidden.bs.modal', '#chooseBonusProductModal', function () {\n $('#chooseBonusProductModal').siblings().attr('aria-hidden', 'false');\n });\n },\n\n trapChooseBonusProductModalFocus: function () {\n $('body').on('keydown', '#chooseBonusProductModal', function (e) {\n var focusParams = {\n event: e,\n containerSelector: '#chooseBonusProductModal',\n firstElementSelector: '.close',\n lastElementSelector: '.add-bonus-products'\n };\n focusHelper.setTabNextFocus(focusParams);\n });\n },\n\n colorAttribute: function () {\n $(document).off('click', '[data-attr=\"color\"] button').on('click', '[data-attr=\"color\"] button', function (e) {\n e.preventDefault();\n\n if ($(this).attr('disabled')) {\n return;\n }\n var $productContainer = $(this).closest('.set-item');\n if (!$productContainer.length) {\n $productContainer = $(this).closest('.product-detail');\n }\n\n attributeSelect($(this).attr('data-url'), $productContainer);\n });\n },\n\n genericSwatchAttribute: function () {\n $(document).off('click', '[data-attr=\"size\"] button, [data-attr=\"length\"] button').on('click', '[data-attr=\"size\"] button, [data-attr=\"length\"] button', function (e) {\n e.preventDefault();\n var attributeModal = $('.cart-and-ipay .popover-top');\n var currentTarget = e.currentTarget;\n attributeModal.removeClass('show');\n var selectedFromModal = false;\n if ($(currentTarget).hasClass('modal-attr')) {\n selectedFromModal = true;\n }\n if ($(this).attr('disabled')) {\n return;\n }\n var $productContainer = $(this).closest('.set-item');\n if (!$productContainer.length) {\n $productContainer = $(this).closest('.product-detail');\n }\n\n attributeSelect($(this).attr('data-url'), $productContainer, selectedFromModal);\n });\n },\n\n selectAttribute: function () {\n $(document).off('change', 'select[class*=\"select-\"], .options-select').on('change', 'select[class*=\"select-\"], .options-select', function (e) {\n e.preventDefault();\n\n var $productContainer = $(this).closest('.set-item');\n if (!$productContainer.length) {\n $productContainer = $(this).closest('.product-detail');\n }\n attributeSelect(e.currentTarget.value, $productContainer);\n });\n },\n\n availability: function () {\n $(document).off('change', '.quantity-select').on('change', '.quantity-select', function (e) {\n e.preventDefault();\n\n var $productContainer = $(this).closest('.product-detail');\n if (!$productContainer.length) {\n $productContainer = $(this).closest('.modal-content').find('.product-quickview');\n }\n\n if ($('.bundle-items', $productContainer).length === 0) {\n if ($(this).hasClass('qty-number-input')) {\n var $numberInput = $(e.currentTarget);\n var updatedUrl = $numberInput.data('url').replace('quantity=1', 'quantity='+$numberInput.val());\n attributeSelect(updatedUrl, $productContainer);\n } else {\n attributeSelect($(e.currentTarget).find('option:selected').data('url'), $productContainer);\n }\n }\n });\n },\n\n closeVariationsModal: function () {\n $(document).off('.cart-and-ipay .popover-top .svg-icon-close').on('click', '.cart-and-ipay .popover-top .svg-icon-close', function () {\n $('.cart-and-ipay .popover-top').removeClass('show');\n });\n },\n\n addToCart: function () {\n $(document).off('click', 'button.add-to-cart, button.add-to-cart-global').on('click', 'button.add-to-cart, button.add-to-cart-global', function () {\n var addToCartUrl;\n var pid;\n var pidsObj;\n var setPids;\n var $container = $(this).closest('.product-detail');\n var hasLength = $container.find('[data-attr=\"length\"]').length > 0;\n var attributeModal = $('.cart-and-ipay .popover-top');\n attributeModal.find('.content').html('');\n\n var variationsSelected = checkVariationSelections($container);\n\n // If each attribute type has an active selection, let the user continue and add to cart\n // Otherwise show a popover with the attribute they need to select in it\n if (variationsSelected[0].allAttributesSelected || $(this).hasClass('gift-card-add-to-cart')) {\n\n $('body').trigger('product:beforeAddToCart', this);\n\n $('.add-to-bag-error-msg').addClass('d-none');\n\n if ($('.set-items').length && $(this).hasClass('add-to-cart-global')) {\n setPids = [];\n\n $('.product-detail').each(function () {\n if (!$(this).hasClass('product-set-detail')) {\n setPids.push({\n pid: $(this).find('.product-id').text(),\n qty: $(this).find('.quantity-select').val(),\n options: getOptions($(this))\n });\n }\n });\n pidsObj = JSON.stringify(setPids);\n }\n\n pid = getPidValue($(this));\n\n var $productContainer = $(this).closest('.product-detail');\n if (!$productContainer.length) {\n $productContainer = $(this).closest('.quick-view-dialog').find('.product-detail');\n }\n\n addToCartUrl = getAddToCartUrl();\n\n var form = {\n pid: pid,\n pidsObj: pidsObj,\n childProducts: getChildProducts(),\n quantity: getQuantitySelected($(this)),\n container: $productContainer\n };\n\n if (!$('.bundle-item').length) {\n form.options = getOptions($productContainer);\n }\n\n if ($(this).data('uuid')) {\n form.uuid =$(this).data('uuid');\n }\n\n $(this).trigger('updateAddToCartFormData', form);\n delete form.container;\n $('body').trigger('tagmanager:blast:addItemListNameToForm', form);\n if (addToCartUrl) {\n $.ajax({\n url: addToCartUrl,\n method: 'POST',\n data: form,\n success: function (data) {\n if (data.error) {\n handlePostCartAdd(data);\n $.spinner().stop();\n } else {\n if ($('#quickViewModal').length > 0 && $('#quickViewModal').hasClass('show')) {\n $('#quickViewModal').modal('hide');\n }\n handlePostCartAdd(data);\n $('body').trigger('product:afterAddToCart', data);\n $('body').trigger('tagmanager:addtocart', data);\n showAddToBagModal(data);\n if ($('.page').hasClass('basket')) {\n $('body').trigger('updateBasketView');\n }\n $('.minicart .add-to-bag-modal-cart-link .cart-quantity').html('(' + data.cart.numItems + ')');\n if (data.cartInventoryMessage) {\n $('.add-to-bag-modal-info-message').css('display', 'block');\n $('.add-to-bag-modal-info-copy').html(data.cartInventoryMessage);\n } else {\n $('.add-to-bag-modal-info-message').css('display', 'none');\n }\n \n if ($('.minicart-link').hasClass('minicart-empty')) {\n $('.minicart-link').removeClass('minicart-empty');\n }\n \n showDiscountMsg($('.add-to-bag-modal-discounts'), data.cart.totals.approachingAndUnlockedDiscounts);\n \n if ($('form.giftcard').length && !data.error) {\n $('form.giftcard').trigger('reset');\n }\n $.spinner().stop();\n miniCartReportingUrl(data.reportingURL);\n }\n },\n error: function () {\n $.spinner().stop();\n }\n });\n }\n\n } else {\n var $content = attributeModal.find('.content');\n // If there is an attribute that doesn't have a selection, clone that attribute's selection boxes into the popover and display above the add to cart button\n if (variationsSelected[0].selectedColorVars == 0) {\n $('[data-attr=\"color\"]').clone().appendTo($content);\n attributeModal.find('.attribute-container').prepend('
    What color do you need?
    ');\n } else if (variationsSelected[0].selectedSizeVars == 0) {\n $('[data-attr=\"size\"]').clone().appendTo($content);\n attributeModal.find('.attribute-container').prepend('
    What size do you need?
    ');\n\n if (attributeModal.find('.size-chart').length > 0) {\n attributeModal.find('.size-chart').remove();\n }\n } else if (hasLength && variationsSelected[0].selectedLengthVars == 0) {\n $('[data-attr=\"length\"]').clone().appendTo($content);\n attributeModal.find('.attribute-container').prepend('
    What length do you need?
    ');\n }\n var buttons = $content.find('button');\n if (buttons.length) {\n buttons.each(function(i, el){\n $(el).addClass('modal-attr');\n });\n }\n\n attributeModal.css('top', -(attributeModal.height()+50))\n attributeModal.addClass('show');\n\n var unselectedAttributes = '';\n if (variationsSelected[0].selectedColorVars == 0) {\n unselectedAttributes = 'Color';\n }\n if (variationsSelected[0].selectedSizeVars == 0) {\n unselectedAttributes += !unselectedAttributes ? 'Size' : ' and Size';\n }\n if (hasLength && variationsSelected[0].selectedLengthVars == 0) {\n unselectedAttributes += !unselectedAttributes ? 'Fit' : ' and Fit';\n }\n\n if (unselectedAttributes.length > 0) {\n $('.add-to-bag-error-msg').html('Select ' + unselectedAttributes);\n $('.add-to-bag-error-msg').removeClass('d-none');\n\n if (window.innerWidth < 1025) {\n var scrollPosition = $('.add-to-bag-error-msg').offset().top - document.documentElement.clientHeight / 2;\n $('html, body').animate({\n scrollTop: scrollPosition\n }, 1000);\n }\n }\n }\n });\n },\n selectBonusProduct: function () {\n $(document).off('click', '.select-bonus-product').on('click', '.select-bonus-product', function () {\n var $choiceOfBonusProduct = $(this).parents('.choice-of-bonus-product');\n var pid = $(this).data('pid');\n var maxPids = $('.choose-bonus-product-dialog').data('total-qty');\n var submittedQty = parseInt($choiceOfBonusProduct.find('.qty-number-input').val(), 10);\n var totalQty = 0;\n $.each($('#chooseBonusProductModal .selected-bonus-products .selected-pid'), function () {\n totalQty += $(this).data('qty');\n });\n totalQty += submittedQty;\n var optionID = $choiceOfBonusProduct.find('.product-option').data('option-id');\n var valueId = $choiceOfBonusProduct.find('.options-select option:selected').data('valueId');\n if (totalQty <= maxPids) {\n var selectedBonusProductHtml = ''\n + '
    '\n + '
    '\n + $choiceOfBonusProduct.find('.product-name').html()\n + '
    '\n + '
    '\n + '
    '\n ;\n $('#chooseBonusProductModal .selected-bonus-products').append(selectedBonusProductHtml);\n $('.pre-cart-products').html(totalQty);\n $('.selected-bonus-products .bonus-summary').removeClass('alert-danger');\n $('.selected-bonus-products .bonus-summary .qty-error-msg').remove();\n } else {\n $('.selected-bonus-products .bonus-summary').addClass('alert-danger');\n $('.bonus-summary.alert-danger').append('Please adjust your quantity. Max is ' + maxPids + '')\n }\n });\n },\n removeBonusProduct: function () {\n $(document).off('click', '.selected-pid').on('click', '.selected-pid', function () {\n $(this).remove();\n var $selected = $('#chooseBonusProductModal .selected-bonus-products .selected-pid');\n var count = 0;\n if ($selected.length) {\n $selected.each(function () {\n count += parseInt($(this).data('qty'), 10);\n });\n }\n\n $('.pre-cart-products').html(count);\n $('.selected-bonus-products .bonus-summary').removeClass('alert-danger');\n });\n },\n enableBonusProductSelection: function () {\n $('body').off('bonusproduct:updateSelectButton').on('bonusproduct:updateSelectButton', function (e, response) {\n $('button.select-bonus-product', response.$productContainer).attr('disabled',\n (!response.product.readyToOrder || !response.product.available));\n var pid = response.product.id;\n $('button.select-bonus-product', response.$productContainer).data('pid', pid);\n });\n },\n showMoreBonusProducts: function () {\n $(document).off('click', '.show-more-bonus-products').on('click', '.show-more-bonus-products', function () {\n var url = $(this).data('url');\n $('.modal-content').spinner().start();\n $.ajax({\n url: url,\n method: 'GET',\n success: function (html) {\n var parsedHtml = parseHtml(html);\n $('.modal-body').append(parsedHtml.body);\n $('.show-more-bonus-products:first').remove();\n $('.modal-content').spinner().stop();\n },\n error: function () {\n $('.modal-content').spinner().stop();\n }\n });\n });\n },\n addBonusProductsToCart: function () {\n $(document).off('click', '.add-bonus-products').on('click', '.add-bonus-products', function () {\n var $readyToOrderBonusProducts = $('.choose-bonus-product-dialog .selected-pid');\n var queryString = '?pids=';\n var url = $('.choose-bonus-product-dialog').data('addtocarturl');\n var pidsObject = {\n bonusProducts: []\n };\n\n $.each($readyToOrderBonusProducts, function () {\n var qtyOption =\n parseInt($(this)\n .data('qty'), 10);\n\n var option = null;\n if (qtyOption > 0) {\n if ($(this).data('optionid') && $(this).data('option-selected-value')) {\n option = {};\n option.optionId = $(this).data('optionid');\n option.productId = $(this).data('pid');\n option.selectedValueId = $(this).data('option-selected-value');\n }\n pidsObject.bonusProducts.push({\n pid: $(this).data('pid'),\n qty: qtyOption,\n options: [option]\n });\n pidsObject.totalQty = parseInt($('.pre-cart-products').html(), 10);\n }\n });\n queryString += JSON.stringify(pidsObject);\n queryString = queryString + '&uuid=' + $('.choose-bonus-product-dialog').data('uuid');\n queryString = queryString + '&pliuuid=' + $('.choose-bonus-product-dialog').data('pliuuid');\n $.spinner().start();\n $.ajax({\n url: url + queryString,\n method: 'POST',\n success: function (data) {\n $.spinner().stop();\n if (data.error) {\n $('#chooseBonusProductModal').modal('hide');\n if ($('.add-to-cart-messages').length === 0) {\n $('body').append('
    ');\n }\n $('.add-to-cart-messages').append(\n '
    '\n + data.errorMessage + '
    '\n );\n setTimeout(function () {\n $('.add-to-basket-alert').remove();\n }, 3000);\n } else {\n $('.configure-bonus-product-attributes').html(data);\n $('.bonus-products-step2').removeClass('hidden-xl-down');\n $('#chooseBonusProductModal').modal('hide');\n\n if ($('.add-to-cart-messages').length === 0) {\n $('body').append('
    ');\n }\n $('.minicart-quantity').html(data.totalQty);\n $('.add-to-cart-messages').append(\n '
    '\n + data.msgSuccess + '
    '\n );\n setTimeout(function () {\n $('.add-to-basket-alert').remove();\n if ($('.cart-page').length) {\n location.reload();\n }\n }, 1500);\n }\n },\n error: function () {\n $.spinner().stop();\n }\n });\n });\n },\n\n showDiscountMsg: showDiscountMsg,\n\n getPidValue: getPidValue,\n getQuantitySelected: getQuantitySelected,\n miniCartReportingUrl: miniCartReportingUrl,\n checkVariationSelections: checkVariationSelections\n};\n","'use strict';\nvar base = require('./base');\nvar PinchZoom = require('pinch-zoom-js');\nvar quickview = require('./quickView');\nvar globalComponents = require('../components/globalComponents');\nrequire('ez-plus');\nrequire('../components/toolTip');\n\n/**\n * Enable/disable UI elements\n * @param {boolean} enableOrDisable - true or false\n */\nfunction updateAddToCartEnableDisableOtherElements(enableOrDisable, id) {\n $('button.add-to-cart-global').attr('disabled', enableOrDisable);\n if(id) {\n $('.dw-apple-pay-button').attr('sku', id);\n }\n}\n\n/**\n * Update availability on change event on quantity selector and on store:afterRemoveStoreSelection event.\n * If store has been selected, exit function otherwise proceed to update attributes.\n * @param {Object} element DOM Element.\n */\n function updateAvailability(element) {\n var searchPID = $(element).closest('.product-detail').attr('data-pid');\n var selectorPrefix = '.product-detail[data-pid=\"' + searchPID + '\"]';\n if ($(selectorPrefix + ' .selected-store-with-inventory').is(':visible')) {\n return;\n }\n\n var $productContainer = $(element).closest('.product-detail');\n if (!$productContainer.length) {\n $productContainer = $(element).closest('.modal-content').find('.product-quickview');\n }\n\n if ($('.bundle-items', $productContainer).length === 0) {\n if ($(element).hasClass('qty-number-input')) {\n var $numberInput = $(element);\n var updatedUrl = $numberInput.data('url').replace('quantity=1', 'quantity='+$numberInput.val());\n base.attributeSelect(updatedUrl, $productContainer);\n } else {\n base.attributeSelect($(element).find('option:selected').data('url'), $productContainer);\n }\n }\n}\n\n/**\n * Cleanup method for easyZoom-plus\n * @param {Jquery} $image - image easyzoom has been initialized on\n * @param {*} ezObject - easyzoom object\n */\nfunction cleanUpEzZoom($image, ezObject) {\n ezObject.showHideZoomContainer('hide');\n ezObject.showHideWindow('hide');\n ezObject.showHideTint('hide');\n ezObject.showHideLens('hide');\n ezObject.destroy();\n $image.data('ezPlus', '');\n}\n\n/**\n * Initialize desktop zoom listeners\n * @param {MediaQueryList} mediaQueryList - media query object initialized to project breakpoint\n */\nfunction initDesktopZoom(mediaQueryList) {\n $(document).on('click', '.carousel-item, .product-zoom-icon', function(e){\n if(mediaQueryList.matches) {\n\n // Introducing this $activeImage variable because they can get in this event handler\n // by either clicking the zoom icon or by just clicking the image itself - either way we want to be able to grab the image\n var $activeImage = $('[id*=\"pdpCarousel-\"] .carousel-item.active');\n\n var $image = $activeImage.find('img');\n var ezObject = $image.data('ezPlus');\n if(ezObject) {\n cleanUpEzZoom($image, ezObject);\n } else {\n $image.ezPlus({\n zoomType: 'inner',\n cursor: 'crosshair',\n borderSize: 0,\n scrollZoom: true\n });\n }\n }\n });\n}\n\n/**\n * Cleanup for all destokop zoom related items\n */\nfunction destroyDesktopZoom() {\n $('.carousel-item').each(function() {\n var $image = $(this).find('img');\n var ezObject = $image.data('ezPlus');\n if(ezObject){\n cleanUpEzZoom($image, ezObject);\n }\n })\n}\n\n/**\n * Initialize pinch-zoom on active carousel item\n */\nfunction pinchZoomInitActive() {\n $('.primary-images .carousel-item.active').each(function() {\n var $container = $(this);\n if(!$container.find('.pinchZoomContainer').length) {\n var zoomSrc = $container.find('img').data('zoom-image');\n $container.append('
    \"\"
    ');\n new PinchZoom.default(\n $container.find('.pinchZoomContainer')[0],\n {\n draggableUnzoomed: false\n }\n );\n }\n });\n}\n\n/**\n * Initialize mobile zoom listeners\n * @param {MediaQueryList} mediaQueryList - media query object initialized to project breakpoint\n */\nfunction initMobileZoom(mediaQueryList) {\n $(document).on('slid.bs.carousel', '.carousel', function() {\n if(!mediaQueryList.matches) {\n pinchZoomInitActive();\n }\n })\n\n $(document).on('product:statusUpdate', function(){\n if(!mediaQueryList.matches) {\n pinchZoomInitActive();\n }\n })\n\n $('.carousel').on('touchstart', function(event){\n const xClick = event.originalEvent.touches[0].pageX;\n $(this).one('touchmove', function(event){\n const xMove = event.originalEvent.touches[0].pageX;\n const sensitivityInPx = 10;\n \n if( Math.floor(xClick - xMove) > sensitivityInPx ){\n $(this).carousel('next');\n }\n else if( Math.floor(xClick - xMove) < -sensitivityInPx ){\n $(this).carousel('prev');\n }\n });\n $(this).on('touchend', function(){\n $(this).off('touchmove');\n });\n });\n}\n\n/**\n * Cleanup for all mobile zoom related items\n */\nfunction destroyMobileZoom() {\n $('.carousel-item').each(function() {\n var $container = $(this).find('.pinch-zoom-container');\n if($container.length) {\n $container.remove();\n }\n });\n}\n\nfunction setupZoomEvents(event) {\n if(event && event.matches) { //went from mobile/tablet to desktop\n destroyMobileZoom();\n } else { //went from desktop to mobile/tablet\n destroyDesktopZoom();\n pinchZoomInitActive();\n }\n}\n\nfunction stickyElement(elementPosition, $element) {\n $(window).on('scroll', function () {\n if (window.innerWidth < 1025) {\n var windowScrollPosition = window.scrollY;\n if (elementPosition < windowScrollPosition) {\n $element.addClass('sticky');\n } else {\n $element.removeClass('sticky');\n }\n }\n });\n}\n\nfunction initStickyAddToBag(){\n var $addToCard = $('.cart-and-ipay.inline-add-to-bag');\n var $addToCardSticky = $('.add-to-cart-sticky');\n var $liveChatContainer = $('.livechat-container');\n var $pdpNavHeight = $('.pdp-nav').outerHeight();\n var addToCardPosition = $addToCard.position().top;\n var windowScrollPosition = $(window).scrollTop() + $pdpNavHeight - $addToCard.outerHeight();\n if (addToCardPosition < windowScrollPosition) {\n $addToCardSticky.addClass('sticky');\n $liveChatContainer.addClass('added-add-to-bag-sticky');\n } else {\n $addToCardSticky.removeClass('sticky');\n $liveChatContainer.removeClass('added-add-to-bag-sticky');\n }\n}\n\nmodule.exports = {\n methods: {\n updateAddToCartEnableDisableOtherElements: updateAddToCartEnableDisableOtherElements\n },\n\n productZoom: function() {\n //set mediaquery to handle desktop/mobile zoom transitions\n var mediaQuery = '(min-width: 1024px)';\n var mediaQueryList = window.matchMedia(mediaQuery);\n \n // Some versions if iOS on iPad don't support addEventListener, have to use deprecated addListener\n // More here: https://github.com/mdn/sprints/issues/858\n if (mediaQueryList.addEventListener) {\n mediaQueryList.addEventListener('change', event => {\n setupZoomEvents();\n });\n } else {\n mediaQueryList.addListener(setupZoomEvents);\n }\n\n // initialize zoom listeners\n initDesktopZoom(mediaQueryList);\n initMobileZoom(mediaQueryList);\n\n // initialize mobile zoom if needed\n if(!mediaQueryList.matches) {\n $(function() {\n pinchZoomInitActive(PinchZoom);\n })\n }\n },\n\n availability: function () {\n $(document).on('store:afterRemoveStoreSelection', function (e, element) {\n e.preventDefault();\n updateAvailability(element);\n });\n },\n\n addToCart: base.addToCart,\n\n updateAttributesAndDetails: function () {\n $('body').on('product:statusUpdate', function (e, data) {\n var $productContainer = $('.product-detail[data-pid=\"' + data.id + '\"]');\n\n $productContainer.find('.description-and-detail .product-attributes')\n .empty()\n .html(data.attributesHtml);\n\n if (data.shortDescription) {\n $productContainer.find('.description-and-detail .description')\n .removeClass('hidden-xl-down');\n $productContainer.find('.description-and-detail .description .content')\n .empty()\n .html(data.shortDescription);\n } else {\n $productContainer.find('.description-and-detail .description')\n .addClass('hidden-xl-down');\n }\n\n if (data.longDescription) {\n $productContainer.find('.description-and-detail .details')\n .removeClass('hidden-xl-down');\n $productContainer.find('.description-and-detail .details .content')\n .empty()\n .html(data.longDescription);\n } else {\n $productContainer.find('.description-and-detail .details')\n .addClass('hidden-xl-down');\n }\n });\n },\n\n showSpinner: function () {\n $('body').on('product:beforeAddToCart product:beforeAttributeSelect', function () {\n $.spinner().start();\n });\n },\n updateAttribute: function () {\n $('body').on('product:afterAttributeSelect', function (e, response) {\n if ($('.product-detail>.bundle-items').length) {\n response.container.data('pid', response.data.product.id);\n response.container.find('.product-id').text(response.data.product.id);\n } else if ($('.product-set-detail').eq(0)) {\n response.container.attr('data-pid', response.data.product.id);\n response.container.find('.product-id').text(response.data.product.id);\n } else {\n $('.product-id').text(response.data.product.id);\n $('.product-detail:not(\".bundle-item\")').data('pid', response.data.product.id);\n }\n\n var availability;\n if (response.data.store) {\n availability = response.data.storeAvailability && !response.data.product.clearance;\n } else {\n availability = response.data.product.availableForInStorePickup && !response.data.product.clearance;\n }\n\n\n $('.storeInfo', response.container).attr('data-availability', availability ? 'available' : 'unavailable');\n availability\n ? $('.svg-icon-bopis', response.container).removeClass('unavailable').addClass('available')\n : $('.svg-icon-bopis', response.container).removeClass('available').addClass('unavailable');\n\n if (response.data.bopisHtml) {\n $('.storeInfo-wrapper', response.container)\n .replaceWith(response.data.bopisHtml);\n }\n\n $('.shipToStoreRadio', response.container)\n .attr('disabled', !response.data.product.readyToOrder || !response.data.product.available || !availability || response.data.product.clearance);\n\n // clear out previously selected store if not set\n if(!response.data.store) {\n $('.selected-store',response.container).attr('data-store-id', '');\n }\n //adds a product to the cart automatically in the case when attributes were selected from the modal and all attrs selected\n var variationSelected = base.checkVariationSelections($(response.container));\n if (variationSelected[0].allAttributesSelected && response.selecteFromModal) {\n var addToCartBtn = $(response.container).find('.add-to-cart');\n addToCartBtn.click();\n }\n if (variationSelected[0].allAttributesSelected) {\n $('.add-to-bag-error-msg').addClass('d-none');\n }\n });\n },\n updateAddToCart: function () {\n $('body').on('product:updateAddToCart', function (e, response) {\n if (response.product.readyToOrder) {\n var applePayButton = $('.apple-pay-pdp', response.$productContainer);\n if (applePayButton.length !== 0) {\n applePayButton.attr('sku', response.product.id);\n } else {\n var showApplePay = true;\n if (typeof $('.cart-and-ipay').data('ipay-enabled') !== 'undefined') {\n showApplePay = $('.cart-and-ipay').data('ipay-enabled');\n }\n\n var disablePDPApplePayButton = false;\n if (typeof $('.apple-pay-custom').data('disable-pdp-apple-pay-button') !== 'undefined') {\n disablePDPApplePayButton = $('.apple-pay-custom').data('disable-pdp-apple-pay-button');\n }\n\n if ($('.apple-pay-pdp').length === 0 && showApplePay && !disablePDPApplePayButton) { // eslint-disable-line no-lonely-if\n var applePayButtonIsmlString = '
    ' +\n '' +\n '
    ';\n $('.cart-and-ipay .row').append(applePayButtonIsmlString);\n if ($('.cart-and-ipay').data('is-apple-session') === true) {\n $('.pdp-checkout-button').removeClass('col-12');\n $('.pdp-checkout-button').addClass('col col-sm-5');\n $('.quickpay-options-wrapper').removeClass('d-none');\n } else {\n $('.quickpay-options-wrapper').addClass('d-none');\n }\n }\n }\n } else {\n $('.pdp-apple-pay-button').remove();\n $('.pdp-checkout-button').removeClass('col col-sm-5');\n $('.pdp-checkout-button').addClass('col-12');\n $('.quickpay-options-wrapper').addClass('d-none');\n }\n\n var shipToHomeChecked = $('.shipToHomeRadio', response.$productContainer).is(':checked');\n var shipToStoreChecked = $('.shipToStoreRadio', response.$productContainer).is(':checked');\n // update local add to cart (for sets)\n $('button.add-to-cart', response.$productContainer)\n .attr(\n 'disabled',\n (\n !response.product.available\n || (!response.product.availableForShipToHome && shipToHomeChecked)\n || (!response.product.availableForInStorePickup && shipToStoreChecked)\n )\n );\n\n var enable = true;\n $('.product-detail .add-to-cart').each(function(index) {\n if($(this).prop('disabled')) {\n enable = false;\n }\n });\n module.exports.methods.updateAddToCartEnableDisableOtherElements(!enable, response.product.id);\n });\n },\n updateAvailability: function () {\n $('body').on('product:updateAvailability', function (e, response) {\n $('div.availability', response.$productContainer)\n .attr('data-ready-to-order', response.product.readyToOrder)\n .data('data-available', response.product.available);\n\n if ($('.global-availability').length) {\n var allAvailable = $('.product-availability').toArray()\n .every(function (item) { return $(item).data('available'); });\n\n var allReady = $('.product-availability').toArray()\n .every(function (item) { return $(item).data('ready-to-order'); });\n\n $('.global-availability')\n .data('ready-to-order', allReady)\n .data('available', allAvailable);\n\n $('.global-availability .availability-msg').empty()\n .html(allReady ? response.message : response.resources.info_selectforstock);\n }\n\n $('.storeInfo',response.$productContainer)\n .attr('data-availability', response.product.availableForInStorePickup ? 'available' : 'unavailable');\n $('.ship-to-home-availability-container',response.$productContainer)\n .attr('data-availability', response.product.availableForShipToHome ? 'available' : 'unavailable');\n $('.ship-to-home-availability',response.$productContainer)\n .text(response.product.availableForShipToHome ? response.resources.inventory_available : response.resources.inventory_unavailable_address);\n\n if(!response.shipToStore) {\n $('.shipToHomeRadio',response.$productContainer).click();\n }\n });\n },\n copyProductLink: function () {\n $('body').on('click', '#fa-link', function (event) {\n event.preventDefault();\n var $container = $(event.target).closest('.container.product-detail');\n var $temp = $('');\n $('body').append($temp);\n $temp.val($container.find('#shareUrl').val()).select();\n document.execCommand('copy');\n $temp.remove();\n $container.find('.copy-link-message').attr('role', 'alert');\n $container.find('.copy-link-message').removeClass('d-none');\n setTimeout(function () {\n $container.find('.copy-link-message').addClass('d-none');\n }, 3000);\n });\n },\n selectShippingOption: function () {\n $('body').on('click', '.shipToHomeRadio, .shipToStoreRadio', function (e) {\n var $productContainer = $(e.target).closest('.product-detail');\n var shipToHomeChecked = $('.shipToHomeRadio', $productContainer).is(':checked');\n var shipToHomeAvailable = $('.ship-to-home-availability-container', $productContainer).attr('data-availability') === 'available';\n var shipToStoreChecked = $('.shipToStoreRadio', $productContainer).is(':checked');\n if ((shipToHomeChecked && shipToHomeAvailable) || shipToStoreChecked) {\n $('button.add-to-cart', $productContainer).removeAttr('disabled');\n } else {\n $('button.add-to-cart', $productContainer).attr('disabled', 'disabled');\n }\n\n var enable = true;\n $('.product-detail .add-to-cart').each(function(index) {\n if($(this).prop('disabled')) {\n enable = false;\n }\n });\n module.exports.methods.updateAddToCartEnableDisableOtherElements(!enable, null);\n\n });\n },\n focusChooseBonusProductModal: base.focusChooseBonusProductModal(),\n carouselAltImages: base.carouselAltImages(),\n showQuickview: quickview.showQuickview(),\n imageClickRedirect: quickview.imageClickRedirect(),\n ratingsClickRedirect: quickview.ratingsClickRedirect(),\n storeSearchParam: function () {\n $(document).ready(function () {\n //look for url param to trigger store search modal\n var currentParams = new URL(window.location.href).searchParams;\n var targetPID = currentParams.get('loadSearchModal');\n if(targetPID){\n var $productContainer = $('.product-detail[data-pid=\"' + targetPID + '\"]');\n $('.shipToStoreRadio', $productContainer).click()\n }\n });\n },\n stickyAddToBag: function () {\n if ($(window).width() < 1025) {\n initStickyAddToBag();\n $(window).on('scroll', function () {\n initStickyAddToBag();\n });\n }\n },\n pdpNav: function () {\n $(document).ready( function () {\n var $header = $('header');\n var headerHeight = $header.outerHeight();\n var $pdpNav = $('.pdp-nav');\n stickyElement(headerHeight, $pdpNav);\n globalComponents.smartResize(function () {\n if ($(window).width() < 1025) {\n $('#maincontent').addClass('pt-0');\n $header.addClass('static-header');\n headerHeight = $header.outerHeight();\n stickyElement(headerHeight, $pdpNav);\n } else {\n $('#maincontent').removeClass('pt-0');\n $header.removeClass('static-header');\n }\n });\n if ($(window).width() < 1025) {\n $header.addClass('static-header');\n $('#maincontent').addClass('pt-0');\n } else {\n $header.removeClass('static-header');\n $('#maincontent').removeClass('pt-0');\n }\n\n var $sections = $('.pdp-nav-section');\n var navbarHeight = $pdpNav.height();\n\n $.fn.isInViewport = function() {\n var elementTop = $(this).offset().top - navbarHeight * 3.5;\n var elementBottom = elementTop + $(this).outerHeight() - navbarHeight * 3.5;\n \n var viewportTop = $(window).scrollTop() - navbarHeight;\n var viewportBottom = viewportTop + $(window).height();\n \n return elementBottom > viewportTop && elementTop < viewportBottom;\n };\n \n $(window).on('resize scroll', function() {\n var flag = true;\n $sections.each(function() {\n var $section = $(this);\n var $navItem = $('[data-section-id=' + $section.attr('id') + ']');\n if ($(this).isInViewport() && flag) {\n $navItem.addClass('active');\n flag = false;\n } else {\n $navItem.removeClass('active');\n flag = true;\n }\n });\n });\n\n var url = window.location.href;\n var anchor = url.indexOf('#') > -1 ? url.substring(url.indexOf('#')) : '';\n if (anchor === '#pdpNavReviews') {\n var scrollPosition = $(anchor).offset().top - navbarHeight * 3;\n $('html, body').animate({\n scrollTop: scrollPosition\n }, 1000);\n }\n\n $('body').on('click', '.pdp-nav .pdp-nav-label', function(e) {\n e.preventDefault();\n var selectedElement = $(this).attr('href');\n var scrollPosition = $(selectedElement).offset().top - navbarHeight * 3;\n $('html, body').animate({\n scrollTop: scrollPosition\n }, 1000);\n });\n });\n },\n initPDPCarousrel: function () {\n document.addEventListener('load-pdp-carousel-recommendations', function() {\n var main = new Splide( '.pdp-recommendations-carousel', {\n type: 'slide',\n pagination: false,\n arrows: false,\n cover: true,\n perPage: 4,\n perMove: 1,\n gap: '1.5rem',\n breakpoints: {\n 1024: {\n perPage: 3,\n gap: '1rem'\n },\n }\n });\n \n main.mount();\n \n if (typeof yotpo !== 'undefined') {\n yotpo.initWidgets();\n }\n }, false);\n }\n};\n","var baseQuickView = require('base/product/quickView');\nvar inStoreInventory = require('instorepickup/product/pdpInstoreInventory');\nvar sizeChartCollapsible = require('../components/collapsibleSizeChart');\nvar base = require('./base');\n\n\n/**\n * Generates the modal window on the first call.\n *\n */\n function getModalHtmlElement() {\n if ($('#quickViewModal').length !== 0) {\n $('#quickViewModal').remove();\n }\n var htmlString = ''\n + '
    '\n + ''\n + '
    '\n + ''\n + '
    '\n + '
    '\n + ' '\n + '
    '\n + '
    '\n + '
    '\n + '
    '\n + '
    '\n + '
    ';\n $('body').append(htmlString);\n}\n\n/**\n * Redirect on click\n *\n * @param {string} clickedElement - clicked element\n * @param {string} target - element with link attribute\n * @param {string} attr - element with link attribute\n * @param {string} anchor - element with link attribute\n */\nfunction QVRedirect(clickedElement, target, attr, anchor, deviceWidth) {\n $('body').off('click', clickedElement).on('click', clickedElement, function () {\n var mediaQuery = deviceWidth ? deviceWidth : null;\n var condition = mediaQuery ? $(window).width() < mediaQuery : true;\n if (condition) {\n var productUrl = $(this).closest('.product-quickview').find(target).attr(attr);\n productUrl = anchor ? productUrl + anchor : productUrl;\n if (productUrl && productUrl.length > 0) {\n window.location.href = productUrl;\n }\n }\n });\n}\n\n/**\n * Parse HTML code in Ajax response\n *\n * @param {string} html - Rendered HTML from quickview template\n * @return {QuickViewHtml} - QuickView content components\n */\nfunction parseHtml(html) {\n var $html = $('
    ').append($.parseHTML(html));\n\n var body = $html.find('.product-quickview');\n var footer = $html.find('.modal-footer').children();\n\n return { body: body, footer: footer };\n}\n\nfunction initYotpoWidgets() {\n if (typeof yotpo !== 'undefined') {\n yotpo.initWidgets();\n }\n}\n\n/**\n * replaces the content in the modal window on for the selected product variation.\n * @param {string} selectedValueUrl - url to be used to retrieve a new product model\n */\nfunction fillModalElement(selectedValueUrl) {\n $('#quickViewModal .modal-body').spinner().start();\n $.ajax({\n url: selectedValueUrl,\n method: 'GET',\n dataType: 'json',\n success: function (data) {\n var parsedHtml = parseHtml(data.renderedTemplate);\n\n $('#quickViewModal .modal-body').empty();\n $('#quickViewModal .modal-body').html(parsedHtml.body);\n $('#quickViewModal .modal-footer').html(parsedHtml.footer);\n $('#quickViewModal .full-pdp-link').text(data.quickViewFullDetailMsg);\n $('#quickViewModal .full-pdp-link').attr('href', data.productUrl);\n $('#quickViewModal .size-chart').attr('href', data.productUrl);\n $('#quickViewModal .modal-header .close .sr-only').text(data.closeButtonText);\n $('#quickViewModal .enter-message').text(data.enterDialogMessage);\n $('#quickViewModal').modal('show');\n $('body').trigger('quickview:ready');\n if (window.BreadPayments) {\n window.BreadPayments.registerPlacements(allPlacements);\n }\n\n if (data.action == 'Product-ShowQuickView') {\n window.dataLayer[1].pdp_type = 'Quick View';\n\n var dlLayer = $('.product-quickview').data('gtmdata');\n if (dlLayer != '{}') {\n dataLayer.push(dlLayer);\n }\n }\n\n initYotpoWidgets();\n\n $.spinner().stop();\n },\n error: function () {\n $.spinner().stop();\n }\n });\n}\n\nbaseQuickView.beforeUpdateAttribute = function () {\n $('body').off('product:beforeAttributeSelect').on('product:beforeAttributeSelect', function () {\n $('.modal.show .modal-content').spinner().start();\n });\n},\nbaseQuickView.showSpinner = function () {\n $('body').off('product:beforeAddToCart').on('product:beforeAddToCart', function (e, data) {\n $(data).closest('.modal-content').spinner().start();\n });\n},\nbaseQuickView.carouselAltImages = base.carouselAltImages();\nbaseQuickView.copyProductLink = function () {\n $('body').on('click', '#fa-link', function (event) {\n event.preventDefault();\n var $temp = $('');\n $('body').append($temp);\n $temp.val($('#shareUrl').val()).select();\n document.execCommand('copy');\n $temp.remove();\n $('.copy-link-message').attr('role', 'alert');\n $('.copy-link-message').removeClass('d-none');\n setTimeout(function () {\n $('.copy-link-message').addClass('d-none');\n }, 3000);\n });\n}\nbaseQuickView.updateAvailability = function updateAvailability() {\n $('body').on('product:updateAvailability', function (e, response) {\n $('div.availability', response.$productContainer)\n .attr('data-ready-to-order', response.product.readyToOrder)\n .data('data-available', response.product.available);\n\n if ($('.global-availability').length) {\n var allAvailable = $('.product-availability').toArray()\n .every(function (item) { return $(item).data('available'); });\n\n var allReady = $('.product-availability').toArray()\n .every(function (item) { return $(item).data('ready-to-order'); });\n\n $('.global-availability')\n .data('ready-to-order', allReady)\n .data('available', allAvailable);\n\n $('.global-availability .availability-msg').empty()\n .html(allReady ? response.message : response.resources.info_selectforstock);\n }\n\n $('.storeInfo',response.$productContainer)\n .attr('data-availability', response.product.availableForInStorePickup ? 'available' : 'unavailable');\n $('.ship-to-home-availability-container',response.$productContainer)\n .attr('data-availability', response.product.availableForShipToHome ? 'available' : 'unavailable');\n $('.ship-to-home-availability',response.$productContainer)\n .text(response.product.availableForShipToHome ? response.resources.inventory_available : response.resources.inventory_unavailable_address);\n\n if(!response.shipToStore) {\n $('.shipToHomeRadio',response.$productContainer).click();\n }\n });\n}\nbaseQuickView.updateAttribute = function () {\n $('body').on('product:afterAttributeSelect', function (e, response) {\n if ($('.modal.show .product-quickview').length) {\n if ($('.modal.show .product-quickview>.bundle-items').length) {\n $('.modal.show').find(response.container).data('pid', response.data.product.id);\n $('.modal.show').find(response.container)\n .find('.product-id').text(response.data.product.id);\n } else if ($('.set-items').length) {\n response.container.attr('data-pid', response.data.product.id);\n response.container.find('.product-id').text(response.data.product.id);\n response.container.find('.full-pdp-link').attr('href', response.data.product.selectedProductUrl);\n } else {\n $('.modal.show .product-quickview').data('pid', response.data.product.id);\n $('.modal.show .full-pdp-link')\n .attr('href', response.data.product.selectedProductUrl);\n }\n\n var availability;\n if (response.data.store) {\n availability = response.data.storeAvailability;\n } else {\n availability = response.data.product.availableForInStorePickup;\n }\n //set input status\n $('.storeInfo', response.container)\n .attr('data-availability', availability ? 'available' : 'unavailable');\n availability\n ? $('.svg-icon-bopis', response.container).removeClass('unavailable').addClass('available')\n : $('.svg-icon-bopis', response.container).removeClass('available').addClass('unavailable');\n $('.storeInfo-wrapper', response.container)\n .replaceWith(response.data.bopisHtml);\n $('.shipToStoreRadio', response.container).attr('disabled', !response.data.product.readyToOrder || !response.data.product.available || !availability);\n \n // clear out previously selected store if not set\n if(!response.data.store) {\n $('.selected-store',response.container).attr('data-store-id', '');\n }\n var variationSelected = base.checkVariationSelections($(response.container));\n\n if (variationSelected[0].allAttributesSelected) {\n $('.add-to-bag-error-msg').addClass('d-none');\n }\n }\n });\n}\nbaseQuickView.selectShippingOption = function () {\n $('body').on('click', '.shipToHomeRadio, .shipToStoreRadio', function (e) {\n var $productContainer = $(e.target).closest('.product-detail');\n var shipToHomeChecked = $('.shipToHomeRadio', $productContainer).is(':checked');\n var shipToHomeAvailable = $('.ship-to-home-availability-container', $productContainer).attr('data-availability') === 'available';\n var shipToStoreChecked = $('.shipToStoreRadio', $productContainer).is(':checked');\n if ((shipToHomeChecked && shipToHomeAvailable) || shipToStoreChecked) {\n $('button.add-to-cart', $productContainer).removeAttr('disabled');\n } else {\n $('button.add-to-cart', $productContainer).attr('disabled', 'disabled');\n }\n\n var enable = true;\n $('#quickViewModal .add-to-cart').each(function(index) {\n if($(this).prop('disabled')) {\n enable = false;\n }\n });\n $('#quickViewModal button.add-to-cart-global').attr('disabled', !enable);\n });\n}\nbaseQuickView.updateAddToCartFormData = inStoreInventory.updateAddToCartFormData\nbaseQuickView.openInventoryPDP = function () {\n $('body').on('click', '.modal.show .btn-get-in-store-inventory', function (e) {\n var $productContainer = $(e.target).closest('.product-detail');\n var url = $productContainer.hasClass('set-item')\n ? $('.full-pdp-link', $productContainer).attr('href')\n : $('#quickViewModal .full-pdp-link').attr('href')\n var storeSelected = $('.selected-store', $productContainer)\n .attr('data-store-id');\n\n //redirect to PDP if no store selected\n if(url && !storeSelected) {\n $('#quickViewModal .modal-content').spinner().start();\n var urlObj = new URL(url, window.location.origin);\n urlObj.searchParams.append('loadSearchModal', $productContainer.data('pid'));\n location.href = urlObj.href;\n }\n e.stopPropagation();\n });\n $('body').on('click', '.modal.show .change-store-pdp', function (e) {\n var $productContainer = $(e.target).closest('.product-detail');\n var url = $productContainer.hasClass('set-item')\n ? $('.full-pdp-link', $productContainer).attr('href')\n : $('#quickViewModal .full-pdp-link').attr('href')\n if(url) {\n $('#quickViewModal .modal-content').spinner().start();\n var urlObj = new URL(url, window.location.origin);\n urlObj.searchParams.append('loadSearchModal', $productContainer.data('pid'));\n location.href = urlObj.href;\n }\n e.preventDefault();\n });\n}\nbaseQuickView.availability = base.availability,\nbaseQuickView.addToCart = base.addToCart;\nbaseQuickView.updateAddToCart = function () {\n $('body').on('product:updateAddToCart', function (e, response) {\n var shipToHomeChecked = $('.shipToHomeRadio', response.$productContainer).is(':checked');\n var shipToStoreChecked = $('.shipToStoreRadio', response.$productContainer).is(':checked');\n // update local add to cart (for sets)\n $('button.add-to-cart', response.$productContainer)\n .attr(\n 'disabled',\n (\n !response.product.available\n || (!response.product.availableForShipToHome && shipToHomeChecked)\n || (!response.product.availableForInStorePickup && shipToStoreChecked)\n )\n );\n\n var enable = true;\n $('#quickViewModal .add-to-cart').each(function(index) {\n if($(this).prop('disabled')) {\n enable = false;\n }\n });\n $('#quickViewModal button.add-to-cart-global').attr('disabled', !enable);\n });\n}\nbaseQuickView.showQuickview = function () {\n $('body').off('click', '.quickview').on('click', '.quickview', function (e) {\n e.preventDefault();\n var selectedValueUrl = $(this).closest('a.quickview').attr('data-href');\n $(e.target).trigger('quickview:show');\n getModalHtmlElement();\n fillModalElement(selectedValueUrl);\n });\n}\n\nbaseQuickView.imageClickRedirect = function () {\n QVRedirect('.product-quickview .primary-images', '.full-pdp-link', 'href', null, 1025);\n}\n\nbaseQuickView.ratingsClickRedirect = function () {\n QVRedirect('.product-quickview .product-number-rating', '.yotpo', 'data-url', '#pdpNavReviews');\n}\n\nbaseQuickView.sizeChartCollapsible = sizeChartCollapsible.sizeChartCollaps;\nbaseQuickView.initYotpoWidgets = initYotpoWidgets;\nmodule.exports = baseQuickView;\n","'use strict';\n\nvar processInclude = require('base/util');\n\n$(document).ready(function () {\n processInclude(require('./product/detail'));\n processInclude(require('./components/collapsibleSizeChart'));\n processInclude(require('wishlists/product/wishlist'));\n processInclude(require('instorepickup/product/pdpInstoreInventory'));\n processInclude(require('valuelink/product/pdpGiftCard'));\n});","/* globals google */\n'use strict';\n\nvar geocoder, spinner;\n/**\n * appends params to a url\n * @param {string} url - Original url\n * @param {Object} params - Parameters to append\n * @returns {string} result url with appended parameters\n */\nfunction appendToUrl(url, params) {\n var newUrl = url;\n newUrl += (newUrl.indexOf('?') !== -1 ? '&' : '?') + Object.keys(params).map(function (key) {\n return key + '=' + encodeURIComponent(params[key]);\n }).join('&');\n\n return newUrl;\n}\n\n/**\n * Uses google maps api to render a map\n */\nfunction maps() {\n var map;\n var infowindow = new google.maps.InfoWindow();\n\n // Init U.S. Map in the center of the viewport\n var latlng = new google.maps.LatLng(37.09024, -95.712891);\n var mapOptions = {\n scrollwheel: false,\n zoom: 4,\n center: latlng\n };\n\n map = new google.maps.Map($('.map-canvas')[0], mapOptions);\n var mapdiv = $('.map-canvas').attr('data-locations');\n\n mapdiv = JSON.parse(mapdiv);\n\n var bounds = new google.maps.LatLngBounds();\n\n // Customized google map marker icon with svg format\n var markerImg = {\n path: 'M0.167969 13.125C0.167969 5.87686 6.03777 0 13.2772 0C20.5167 0 26.3865 5.87686 26.3865 13.125C26.3865 18.4167 24.545 19.8946 14.6223 34.2959C13.9715 35.2372 12.5801 35.2372 11.9294 34.2959C2.00941 19.8926 0.167969 18.416 0.167969 13.125Z',\n fillColor: '#313131',\n fillOpacity: 1,\n scale: 1.5,\n strokeColor: 'white',\n strokeWeight: 1,\n anchor: new google.maps.Point(13, 30),\n labelOrigin: new google.maps.Point(14, 15)\n };\n\n Object.keys(mapdiv).forEach(function (key) {\n var item = mapdiv[key];\n var lable = parseInt(key, 10) + 1;\n var storeLocation = new google.maps.LatLng(item.latitude, item.longitude);\n var marker = new google.maps.Marker({\n position: storeLocation,\n map: map,\n title: item.name,\n icon: markerImg,\n label: { text: lable.toString(), color: 'white', fontSize: '16px' }\n });\n if ($('.map-canvas.single-store').length == 0) {\n marker.addListener('click', function () {\n infowindow.setOptions({\n content: item.infoWindowHtml\n });\n infowindow.open(map, marker);\n });\n }\n\n // Create a minimum bound based on a set of storeLocations\n bounds.extend(marker.position);\n });\n // Fit the all the store marks in the center of a minimum bounds when any store has been found.\n if (mapdiv && mapdiv.length !== 0) {\n map.fitBounds(bounds);\n }\n\n var listener = google.maps.event.addListener(map, \"idle\", function() {\n if ($('.map-canvas.single-store').length > 0) {\n map.setZoom(13);\n }\n google.maps.event.removeListener(listener);\n });\n}\nfunction loadFieldsError(fieldErrors) { // eslint-disable-line\n // Display error messages and highlight form fields with errors.\n $.each(fieldErrors, function (attr) {\n const $el = $('*[name=' + attr + ']');\n $el.addClass('is-invalid')\n .siblings('.invalid-feedback')\n .html(fieldErrors[attr]);\n $el.closest('.form-field').addClass('error');\n });\n}\n\n/**\n * Clear the form errors.\n * @param {JQuery} $selector - the selector.\n */\nfunction clearFieldsError($selector) {\n const $el = $selector.find('.form-control.is-invalid');\n $el.removeClass('is-invalid');\n $el.closest('.form-field').removeClass('error');\n}\n/**\n * Renders the results of the search and updates the map\n * @param {Object} data - Response from the server\n */\nfunction updateStoresResults(data) {\n const isAccess = $('.page').hasClass('basket') || $('.page').hasClass('productPage');\n if(isAccess && !data) {\n //TODO : case when customer write wrong location, google has sent error\n return;\n }\n var $resultsDiv = $('.results');\n var $mapDiv = $('.map-canvas');\n var hasResults = data ? data.storesModel.stores.length > 0 : false;\n $('.change-store-modal__footer').attr('data-hasstores', hasResults)\n\n if (!hasResults) {\n $('.store-locator-no-results').show();\n $('.store-listing-heading').hide().text('');\n if ($('.store-listing').length > 0) {\n $('.store-listing').addClass('no-results');\n $('.store-listing .card-body').addClass('no-results');\n }\n } else {\n $('.store-locator-no-results').hide();\n $('.store-listing-heading').show().text(data.storesModel.stores.length + ' store(s) within ' + data.storesModel.radius + ' miles of ' + data.storesModel.searchKey.postalCode);\n\n if ($('.store-listing').length > 0) {\n $('.store-listing').removeClass('no-results');\n $('.store-listing .card-body').removeClass('no-results');\n }\n }\n\n $resultsDiv.empty()\n .data('has-results', hasResults)\n .data('radius', data.storesModel.radius)\n .data('search-key', data.storesModel.searchKey);\n\n $mapDiv.attr('data-locations', data.storesModel.locations);\n\n if ($mapDiv.data('has-google-api')) {\n maps();\n } else {\n $('.store-locator-no-apiKey').show();\n }\n\n if (data.storesModel.storesResultsHtml) {\n $resultsDiv.append(data.storesModel.storesResultsHtml);\n }\n\n // Add back \"make this my store\" buttons\n $('.results .card-body').find('.set-store').addClass('show');\n\n // If there's an already-preferred store, adjust styling for those listings\n if ($('.card-body.new-preferred').length > 0) {\n var storeId = $('.card-body.new-preferred').attr('id');\n var matchingStore = $('.results #' + storeId + '.card-body');\n\n matchingStore.find('.my-store-indicator').addClass('show');\n matchingStore.find('.set-store').removeClass('show');\n }\n}\n\nfunction initializeGeocoder() {\n // In checkout page there is no googlemaps api\n if (typeof google !== 'undefined' && !$('.page').hasClass('checkout')) {\n geocoder = new google.maps.Geocoder();\n }\n}\n\nfunction initializeSpinner() {\n var isSLP = $('.store-locator-page').length;\n if (!isSLP) {\n var dialog = $('.in-store-inventory-dialog');\n spinner = dialog.spinner();\n } else {\n spinner = $.spinner();\n }\n}\n\nfunction codeAddress(address, $form) {\n geocoder.geocode( { 'address': address, 'region': 'US'}, findStoreCall.bind(this, $form));\n}\n\nfunction findStoreCall($form, results, status) {\n if (status == 'OK') {\n var url = $form.attr('action');\n var type = $form.attr('method');\n var radius = $form.find('.radius').val();\n var location = results[0].geometry.location;\n var urlParams = {\n radius: radius,\n lat: location.lat(),\n long: location.lng()\n }\n url = appendToUrl(url, urlParams);\n $.ajax({\n url: url,\n type: type,\n dataType: 'json',\n success: function (data) {\n spinner.stop();\n updateStoresResults(data);\n $('.select-store').prop('disabled', true);\n }\n });\n } else {\n updateStoresResults(null);\n spinner.stop();\n }\n}\n/**\n * Search for stores with new zip code\n * @param {HTMLElement} element - the target html element\n * @returns {boolean} false to prevent default event\n */\nfunction searchByCoordinate() {\n initializeSpinner();\n spinner.start();\n var $form = $('#storeLocatorForm');\n var address = $('input#searchStore').val();\n if (!address.length) {\n spinner.stop();\n return false;\n }\n codeAddress(address, $form);\n return false;\n}\n\n/**\n * Search for stores with new zip code\n * @param {HTMLElement} element - the target html element\n * @returns {boolean} false to prevent default event\n */\n function search(element) {\n initializeSpinner();\n spinner.start();\n var $form = element.closest('.store-locator');\n var radius = $('.results').data('radius');\n var url = $form.attr('action');\n var urlParams = { radius: radius };\n\n var payload = $form.is('form') ? $form.serialize() : { postalCode: $form.find('[name=\"postalCode\"]').val() };\n\n url = appendToUrl(url, urlParams);\n\n $.ajax({\n url: url,\n type: $form.attr('method'),\n data: payload,\n dataType: 'json',\n success: function (data) {\n spinner.stop();\n updateStoresResults(data);\n $('.select-store').prop('disabled', true);\n }\n });\n return false;\n}\n\n/**\n * Displays the \"My Store\" icon / text on the new preferred store, replaces preferred store info at top of left pane\n * @param {string} storeId - the storeId of new preferred store\n * @returns {boolean} false to prevent default event\n */\nfunction updatePreferredStoreDisplay(storeId) {\n // Grab previous preferred store (if there is one) and new preferred store\n var prevPreferredStore = $('.results .my-store-indicator.show').closest('.card-body');\n var newPreferredStore = $('#'+storeId+'.card-body');\n\n // Remove My Store icon / text from previous preferred store (if there is one)\n // Show Make This My Store button on previous preferred store (if there is one)\n\n if (prevPreferredStore.length > 0) {\n prevPreferredStore.find('.my-store-indicator.show').removeClass('show');\n prevPreferredStore.find('.set-store').addClass('show');\n }\n\n // Put My Store icon / text on new preferred store\n // Remove Make This My Store button on new preferred store\n // Clone new preferred store up on top of left pane\n newPreferredStore.find('.my-store-indicator').addClass('show');\n newPreferredStore.find('.set-store').removeClass('show');\n\n // Change storeid so that it's unique (so clicking on More Store Info link won't fire the lower store's panel too)\n newPreferredStore.find('.more-store-link .info-link').attr('href').replace('-preferred', '');\n newPreferredStore.find('.more-store-link .day-hour-container').attr('id').replace('-preferred', '');\n\n newPreferredStore.find('.more-store-link .info-link').attr('href', newPreferredStore.find('.more-store-link .info-link').attr('href') + '-preferred');\n newPreferredStore.find('.more-store-link .day-hour-container').attr('id', newPreferredStore.find('.more-store-link .day-hour-container').attr('id') + '-preferred');\n\n if ($('.find-store-form > .card-body:first-child').length > 0) {\n $('.find-store-form > .card-body:first-child').remove();\n }\n\n $('.search-form > .card-body').prepend($('.my-store-indicator.show').closest('.card-body').clone());\n\n $('.store-results-section').spinner().stop();\n}\nfunction updatePreferredStoreInCards(storeId) {\n const storeID = storeId;\n $('.my-store-section').attr('data-status', '');\n $('.store-js-container-' + storeID).find('.my-store-section').attr('data-status', 'preferred');\n}\n/**\n * Displays the \"My Store\" icon / text on the new preferred store, replaces preferred store info at top of left pane\n * @param {string} storeId - the storeId of new preferred store\n * @returns {boolean} false to prevent default event\n */\n function updatePreferredStoreDetailsDisplay(storeId) {\n\n $('.store-locator-details .set-store').removeClass('show');\n }\n\nmodule.exports = {\n init: function () {\n if ($('.map-canvas').data('has-google-api')) {\n maps();\n } else {\n $('.store-locator-no-apiKey').show();\n }\n\n // If user is logged in and has a preferred store in listing, clone it to the top of the left pane\n // Also tweak the storeid so that it's unique\n if (($('.results .my-store-indicator.show').length > 0) && ($('.map-canvas').data('locations') != null)) {\n var $newClonedEl = $('.results .my-store-indicator.show').closest('.card-body').clone().addClass('new-preferred');\n $('.search-form > .card-body:first-child').prepend($newClonedEl);\n\n $('.card-body.new-preferred').find('.more-store-link .info-link').attr('href').replace('-preferred', '');\n $('.card-body.new-preferred').find('.more-store-link .day-hour-container').attr('id').replace('-preferred', '');\n\n $('.card-body.new-preferred').find('.more-store-link .info-link').attr('href', $('.search-form > .card-body').find('.more-store-link .info-link').attr('href') + '-preferred');\n $('.card-body.new-preferred').find('.more-store-link .day-hour-container').attr('id', $('.search-form > .card-body').find('.more-store-link .day-hour-container').attr('id') + '-preferred');\n }\n },\n initGeocoder: function () {\n initializeGeocoder();\n },\n detectLocation: function () {\n // clicking on detect location.\n $('.detect-location').on('click', function () {\n $.spinner().start();\n \n if (!navigator.geolocation) {\n $.spinner().stop();\n return;\n }\n\n function success(position) {\n var $detectLocationButton = $('.detect-location');\n var url = $detectLocationButton.data('action');\n var radius = $('.results').data('radius');\n var urlParams = {\n radius: radius,\n lat: position.coords.latitude,\n long: position.coords.longitude\n };\n\n url = appendToUrl(url, urlParams);\n $.ajax({\n url: url,\n type: 'get',\n dataType: 'json',\n success: function (data) {\n $.spinner().stop();\n updateStoresResults(data);\n $('.select-store').prop('disabled', true);\n $.spinner().stop();\n },\n error: function (e) {\n console.log(e);\n }\n });\n }\n\n function error(err) {\n // console.warn(`ERROR(${err.code}): ${err.message}`);\n alert(`${err.message}. Please enable location services on your device.`)\n $.spinner().stop();\n }\n\n navigator.geolocation.getCurrentPosition(success, error);\n });\n },\n\n search: function () {\n $('.store-locator-container form.store-locator').not('#storeLocatorForm').submit(function (e) {\n e.preventDefault();\n search($(this));\n });\n $('.store-locator-container .btn-storelocator-search[type=\"button\"]').not('#storeLocatorForm').click(function (e) {\n e.preventDefault();\n search($(this));\n });\n $('.store-locator-container form#storeLocatorForm').submit(function (e) {\n e.preventDefault();\n searchByCoordinate();\n });\n $('.store-locator-container #storeLocatorForm .btn-storelocator-search[type=\"button\"]').click(function (e) {\n e.preventDefault();\n searchByCoordinate();\n });\n $('.pickup-stores .search-form .btn-stores-search[type=\"button\"]').click(function (e) {\n e.preventDefault();\n const $form = $('#storeLocatorForm');\n const $requiredFields = $form.find('.form-control.required');\n let invalidFields = {};\n $requiredFields.each(function(i,el){\n if (!$(el).val()) {\n invalidFields[el.name] = $(el).attr('data-miss');\n }\n })\n if(!Object.keys(invalidFields).length) {\n searchByCoordinate();\n clearFieldsError($form);\n } else {\n loadFieldsError(invalidFields);\n }\n });\n },\n\n changeRadius: function () {\n $('.store-locator-container .radius').change(function () {\n //TODO : for PDP\n const isAccess = $('.page').hasClass('basket') || $('.page').hasClass('productPage');\n if (isAccess) {\n const $container = $(this).closest('.inputs__wrapper');\n const $locationInput = $container.find('.input-location__wrapper input');\n const value = $locationInput.val();\n if (value.length) {\n return;\n }\n }\n var radius = $(this).val();\n var searchKeys = $('.results').data('search-key');\n var url = $(this).data('action-url');\n var urlParams = {};\n\n if (searchKeys.postalCode) {\n urlParams = {\n radius: radius,\n postalCode: searchKeys.postalCode\n };\n } else if (searchKeys.lat && searchKeys.long) {\n urlParams = {\n radius: radius,\n lat: searchKeys.lat,\n long: searchKeys.long\n };\n }\n\n url = appendToUrl(url, urlParams);\n var dialog = $(this).closest('.in-store-inventory-dialog');\n var spinner = dialog.length ? dialog.spinner() : $.spinner();\n spinner.start();\n $.ajax({\n url: url,\n type: 'get',\n dataType: 'json',\n success: function (data) {\n spinner.stop();\n updateStoresResults(data);\n $('.select-store').prop('disabled', true);\n }\n });\n });\n },\n selectStore: function () {\n //TODO : change selector for event\n $('body').off('click', '.pdp-inventory-modal .select-store').on('click', '.pdp-inventory-modal .select-store', function (e) {\n e.preventDefault();\n //TODO: change selector for selected Store\n const $selectedStore = $('.select-store-input:checked');\n const pid = $('.modal-body .select-store').attr('data-container-pid');\n const containerPID = pid;\n const storeID = $selectedStore.val();\n const pickupMethod = $('input[name=\"'+storeID+'-PickupMethod\"]:checked').val();\n const data = {\n storeID: storeID,\n searchRadius: $('#radius').val(),\n searchPostalCode: $('.results').data('search-key').postalCode,\n storeDetailsHtml: $selectedStore.siblings('label').find('.store-details').html(),\n event: e,\n pid: pid,\n containerPID: containerPID,\n pickupMethod: pickupMethod\n };\n\n $('body').trigger('store:selected', data);\n });\n },\n updateSelectStoreButton: function () {\n $('body').on('change', '.select-store-input', (function (e) {\n var $target = $(e.target);\n $target.closest('.results').find('.card-body.selected').removeClass('selected');\n $target.closest('.card-body').addClass('selected');\n $('.select-store').prop('disabled', false);\n }));\n },\n setPreferredStoreButton: function () {\n $('body').on('click', '.store-details button.set-preferred-store, .pickup-in-store button.set-preferred-store', '.action-buttons button.set-preferred-store', (function () {\n const $self = $(this);\n const url = $self.attr('data-action');\n if ($self.closest('.store-details').length) {\n $('.store-results-section').spinner().start();\n }\n\n $.ajax({\n url: url,\n type: 'post',\n dataType: 'json',\n success: function (data) {\n if ($self.closest('.store-details').length) {\n updatePreferredStoreDisplay(data.storeId);\n } else {\n updatePreferredStoreInCards(data.storeId);\n }\n\n }\n });\n }));\n },\n setPreferredStoreButtonInModal: function () {\n $('body').on('click', '.action-buttons button.set-preferred-store', (function () {\n const $self = $(this);\n const url = $self.attr('data-action');\n\n $.ajax({\n url: url,\n type: 'post',\n dataType: 'json',\n success: function (data) {\n updatePreferredStoreInCards(data.storeId);\n }\n });\n }));\n },\n setPreferredStoreButtonDetails: function () {\n $('body').on('click', '.store-locator-details button.set-preferred-store', (function () {\n var url = $(this).data('action');\n $('.store-results-section').spinner().start();\n\n $.ajax({\n url: url,\n type: 'post',\n dataType: 'json',\n success: function (data) {\n updatePreferredStoreDetailsDisplay(data.storeId);\n }\n });\n }));\n }\n};\n","/* jshint -W071, -W074 */\r\n/* global jQuery:false */\r\n\r\n/* Disabled options are:\r\n * W071: This function has too many statements\r\n * W074: This function's cyclomatic complexity is too high\r\n */\r\n\r\n/*\r\n *\tjQuery ezPlus 1.1.21\r\n *\tDemo's and documentation:\r\n *\thttp://igorlino.github.io/elevatezoom-plus/\r\n *\r\n *\tlicensed under MIT license.\r\n *\thttp://en.wikipedia.org/wiki/MIT_License\r\n *\r\n */\r\n\r\nif (typeof Object.create !== 'function') {\r\n Object.create = function (obj) {\r\n function F() {\r\n }\r\n\r\n F.prototype = obj;\r\n return new F();\r\n };\r\n}\r\n\r\n(function ($, window, document, undefined) {\r\n var EZP = {\r\n init: function (options, elem) {\r\n var self = this;\r\n var $galleries;\r\n\r\n self.elem = elem;\r\n self.$elem = $(elem);\r\n\r\n self.options = $.extend({}, $.fn.ezPlus.options, self.responsiveConfig(options || {}));\r\n\r\n self.imageSrc = self.$elem.data(self.options.attrImageZoomSrc) ? self.$elem.data(self.options.attrImageZoomSrc) : self.$elem.attr('src');\r\n\r\n if (!self.options.enabled) {\r\n return;\r\n }\r\n\r\n //TINT OVERRIDE SETTINGS\r\n if (self.options.tint) {\r\n self.options.lensColour = 'transparent'; //colour of the lens background\r\n self.options.lensOpacity = '1'; //opacity of the lens\r\n }\r\n //INNER OVERRIDE SETTINGS\r\n if (self.options.zoomType === 'inner') {\r\n self.options.showLens = false;\r\n }\r\n\r\n // LENS OVERRIDE SETTINGS\r\n if (self.options.zoomType === 'lens') {\r\n self.options.zoomWindowWidth = 0;\r\n }\r\n\r\n //UUID WHEN MISSING IDENTIFIER\r\n if (self.options.zoomId === -1) {\r\n self.options.zoomId = generateUUID();\r\n }\r\n\r\n //Remove alt on hover\r\n\r\n self.$elem.parent().removeAttr('title').removeAttr('alt');\r\n\r\n self.zoomImage = self.imageSrc;\r\n\r\n self.refresh(1);\r\n\r\n //Create the image swap from the gallery\r\n $galleries = $(self.options.gallery ? ('#' + self.options.gallery) : self.options.gallerySelector);\r\n $galleries.on('click.zoom', self.options.galleryItem, function (e) {\r\n\r\n //Set a class on the currently active gallery image\r\n if (self.options.galleryActiveClass) {\r\n $(self.options.galleryItem, $galleries).removeClass(self.options.galleryActiveClass);\r\n $(this).addClass(self.options.galleryActiveClass);\r\n }\r\n //stop any link on the a tag from working\r\n if (this.tagName === 'A') {\r\n e.preventDefault();\r\n }\r\n\r\n //call the swap image function\r\n if ($(this).data(self.options.attrImageZoomSrc)) {\r\n self.zoomImagePre = $(this).data(self.options.attrImageZoomSrc);\r\n }\r\n else {\r\n self.zoomImagePre = $(this).data('image');\r\n }\r\n self.swaptheimage($(this).data('image'), self.zoomImagePre);\r\n if (this.tagName === 'A') {\r\n return false;\r\n }\r\n });\r\n\r\n function generateUUID() {\r\n var d = new Date().getTime();\r\n var uuid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {\r\n var r = (d + Math.random() * 16) % 16 | 0;\r\n d = Math.floor(d / 16);\r\n return (c == 'x' ? r : (r & 0x3 | 0x8)).toString(16);\r\n });\r\n return uuid;\r\n }\r\n },\r\n refresh: function (length) {\r\n var self = this;\r\n\r\n setTimeout(function () {\r\n self.fetch(self.imageSrc, self.$elem, self.options.minZoomLevel);\r\n\r\n }, length || self.options.refresh);\r\n },\r\n fetch: function (imgsrc, element, minZoom) {\r\n //get the image\r\n var self = this;\r\n var newImg = new Image();\r\n newImg.onload = function () {\r\n //set the large image dimensions - used to calculte ratio's\r\n if (newImg.width / element.width() <= minZoom) {\r\n self.largeWidth = element.width() * minZoom;\r\n } else {\r\n self.largeWidth = newImg.width;\r\n }\r\n if (newImg.height / element.height() <= minZoom) {\r\n self.largeHeight = element.height() * minZoom;\r\n } else {\r\n self.largeHeight = newImg.height;\r\n }\r\n //once image is loaded start the calls\r\n self.startZoom();\r\n self.currentImage = self.imageSrc;\r\n //let caller know image has been loaded\r\n self.options.onZoomedImageLoaded(self.$elem);\r\n };\r\n self.setImageSource(newImg, imgsrc); // this must be done AFTER setting onload\r\n\r\n return;\r\n },\r\n setImageSource: function (image, src) {\r\n //sets an image's source.\r\n image.src = src;\r\n },\r\n startZoom: function () {\r\n var self = this;\r\n //get dimensions of the non zoomed image\r\n self.nzWidth = self.$elem.width();\r\n self.nzHeight = self.$elem.height();\r\n\r\n //activated elements\r\n self.isWindowActive = false;\r\n self.isLensActive = false;\r\n self.isTintActive = false;\r\n self.overWindow = false;\r\n\r\n //CrossFade Wrapper\r\n if (self.options.imageCrossfade) {\r\n self.zoomWrap = self.$elem.wrap('
    ');\r\n self.$elem.css('position', 'absolute');\r\n }\r\n\r\n self.zoomLock = 1;\r\n self.scrollingLock = false;\r\n self.changeBgSize = false;\r\n self.currentZoomLevel = self.options.zoomLevel;\r\n\r\n //get offset of the non zoomed image\r\n self.updateOffset(self);\r\n //calculate the width ratio of the large/small image\r\n self.widthRatio = (self.largeWidth / self.currentZoomLevel) / self.nzWidth;\r\n self.heightRatio = (self.largeHeight / self.currentZoomLevel) / self.nzHeight;\r\n\r\n function getWindowZoomStyle() {\r\n return 'display: none;' +\r\n 'position: absolute;' +\r\n 'float: left;' +\r\n 'height: ' + String(self.options.zoomWindowHeight) + 'px;' +\r\n 'width: ' + String(self.options.zoomWindowWidth) + 'px;' +\r\n 'text-align: center;' +\r\n 'border: ' + String(self.options.borderSize) + 'px solid ' + self.options.borderColour + ';' +\r\n 'background-size: ' + self.largeWidth / self.currentZoomLevel + 'px ' + self.largeHeight / self.currentZoomLevel + 'px;' +\r\n 'background-position: 0px 0px;' +\r\n 'background-repeat: no-repeat;' +\r\n 'background-color: ' + String(self.options.zoomWindowBgColour) + ';' +\r\n 'overflow: hidden;' +\r\n 'z-index: 100;';\r\n }\r\n\r\n //if window zoom\r\n if (self.options.zoomType === 'window') {\r\n self.zoomWindowStyle = getWindowZoomStyle();\r\n }\r\n\r\n function getInnerZoomStyle() {\r\n //has a border been put on the image? Lets cater for this\r\n var borderWidth = self.$elem.css('border-left-width');\r\n\r\n return 'display: none;' +\r\n 'position: absolute;' +\r\n 'float: left;' +\r\n 'height: ' + String(self.nzHeight) + 'px;' +\r\n 'width: ' + String(self.nzWidth) + 'px;' +\r\n 'margin-top: ' + String(borderWidth) + ';' +\r\n 'margin-left: ' + String(borderWidth) + ';' +\r\n 'border: ' + String(self.options.borderSize) + 'px solid ' + self.options.borderColour + ';' +\r\n 'background-position: 0px 0px;' +\r\n 'background-repeat: no-repeat;' +\r\n 'cursor:' + (self.options.cursor) + ';' +\r\n 'overflow: hidden;' +\r\n 'zindex: ' + self.options.zIndex + \";\";\r\n }\r\n\r\n //if inner zoom\r\n if (self.options.zoomType === 'inner') {\r\n self.zoomWindowStyle = getInnerZoomStyle();\r\n }\r\n\r\n function getWindowLensStyle() {\r\n // adjust images less than the window height\r\n\r\n if (self.nzHeight < self.options.zoomWindowHeight / self.heightRatio) {\r\n self.lensHeight = self.nzHeight;\r\n }\r\n else {\r\n self.lensHeight = String(self.options.zoomWindowHeight / self.heightRatio);\r\n }\r\n if (self.largeWidth < self.options.zoomWindowWidth) {\r\n self.lensWidth = self.nzWidth;\r\n }\r\n else {\r\n self.lensWidth = String(self.options.zoomWindowWidth / self.widthRatio);\r\n }\r\n\r\n return 'display: none;' +\r\n 'position: absolute;' +\r\n 'float: right;' +\r\n 'height: ' + self.lensHeight + 'px;' +\r\n 'width: ' + self.lensWidth + 'px;' +\r\n 'border: ' + (self.options.lensBorderSize) + 'px' + ' solid ' + (self.options.lensBorderColour) + ';' +\r\n 'background-position: 0px 0px;' +\r\n 'background-repeat: no-repeat;' +\r\n 'background-color: ' + (self.options.lensColour) + ';' +\r\n 'opacity: ' + (self.options.lensOpacity) + ';' +\r\n 'filter: alpha(opacity = ' + (self.options.lensOpacity * 100) + ');' +\r\n 'zoom: 1;' +\r\n 'cursor:' + (self.options.cursor) + ';' +\r\n 'z-index: 999;' +\r\n 'overflow: hidden;';\r\n }\r\n\r\n //lens style for window zoom\r\n if (self.options.zoomType === 'window') {\r\n self.lensStyle = getWindowLensStyle();\r\n }\r\n\r\n //tint style\r\n self.tintStyle =\r\n 'display: block;' +\r\n 'position: absolute;' +\r\n 'height: ' + self.nzHeight + 'px;' +\r\n 'width: ' + self.nzWidth + 'px;' +\r\n 'background-color: ' + self.options.tintColour + ';' +\r\n 'filter: alpha(opacity=0);' +\r\n 'opacity: 0;';\r\n\r\n //lens style for lens zoom with optional round for modern browsers\r\n self.lensRound = '';\r\n\r\n if (self.options.zoomType === 'lens') {\r\n self.lensStyle =\r\n 'display: none;' +\r\n 'position: absolute;' +\r\n 'float: left;' +\r\n 'height:' + String(self.options.lensSize) + 'px;' +\r\n 'width:' + String(self.options.lensSize) + 'px;' +\r\n 'border: ' + String(self.options.borderSize) + 'px solid ' + self.options.borderColour + ';' +\r\n 'background-position: 0px 0px;' +\r\n 'background-repeat: no-repeat;' +\r\n 'background-color: ' + self.options.lensColour + \";\" +\r\n 'cursor:' + (self.options.cursor) + ';';\r\n }\r\n\r\n //does not round in all browsers\r\n if (self.options.lensShape === 'round') {\r\n self.lensRound =\r\n 'border-radius: ' + String(self.options.lensSize / 2 + self.options.borderSize) + 'px;';\r\n }\r\n\r\n //create the div's + \"\"\r\n //self.zoomContainer = $('
    ').addClass('zoomContainer').css({\"position\":\"relative\", \"height\":self.nzHeight, \"width\":self.nzWidth});\r\n\r\n self.zoomContainer =\r\n $('
    ');\r\n if (self.$elem.attr('id')) {\r\n self.zoomContainer.attr('id', self.$elem.attr('id') + '-zoomContainer');\r\n }\r\n $(self.options.zoomContainerAppendTo).append(self.zoomContainer);\r\n\r\n //this will add overflow hidden and contrain the lens on lens mode\r\n if (self.options.containLensZoom && self.options.zoomType === 'lens') {\r\n self.zoomContainer.css('overflow', 'hidden');\r\n }\r\n if (self.options.zoomType !== 'inner') {\r\n self.zoomLens = $('
     
    ')\r\n .appendTo(self.zoomContainer)\r\n .click(function () {\r\n self.$elem.trigger('click');\r\n });\r\n\r\n if (self.options.tint) {\r\n self.tintContainer = $('
    ').addClass('tintContainer');\r\n self.zoomTint = $('
    ');\r\n\r\n self.zoomLens.wrap(self.tintContainer);\r\n\r\n self.zoomTintcss = self.zoomLens.after(self.zoomTint);\r\n\r\n //if tint enabled - set an image to show over the tint\r\n\r\n self.zoomTintImage = $('')\r\n .appendTo(self.zoomLens)\r\n .click(function () {\r\n self.$elem.trigger('click');\r\n });\r\n }\r\n }\r\n\r\n //create zoom window\r\n var targetZoomContainer = isNaN(self.options.zoomWindowPosition) ? 'body' : self.zoomContainer;\r\n self.zoomWindow = $('
     
    ')\r\n .appendTo(targetZoomContainer).click(function () {\r\n self.$elem.trigger('click');\r\n });\r\n self.zoomWindowContainer = $('
    ').addClass('zoomWindowContainer').css('width', self.options.zoomWindowWidth);\r\n self.zoomWindow.wrap(self.zoomWindowContainer);\r\n\r\n // self.captionStyle = \"text-align: left;background-color: black;'+\r\n // 'color: white;font-weight: bold;padding: 10px;font-family: sans-serif;font-size: 11px\";\r\n // self.zoomCaption = $('
    INSERT ALT TAG
    ').appendTo(self.zoomWindow.parent());\r\n\r\n if (self.options.zoomType === 'lens') {\r\n self.zoomLens.css('background-image', 'url(\"' + self.imageSrc + '\")');\r\n }\r\n if (self.options.zoomType === 'window') {\r\n self.zoomWindow.css('background-image', 'url(\"' + self.imageSrc + '\")');\r\n }\r\n if (self.options.zoomType === 'inner') {\r\n self.zoomWindow.css('background-image', 'url(\"' + self.imageSrc + '\")');\r\n }\r\n\r\n /*-------------------END THE ZOOM WINDOW AND LENS----------------------------------*/\r\n if (self.options.touchEnabled) {\r\n //touch events\r\n self.$elem.bind('touchmove.ezpspace', function (e) {\r\n e.preventDefault();\r\n var touch = e.originalEvent.touches[0] || e.originalEvent.changedTouches[0];\r\n self.setPosition(touch);\r\n });\r\n self.zoomContainer.bind('touchmove.ezpspace', function (e) {\r\n self.setElements('show');\r\n e.preventDefault();\r\n var touch = e.originalEvent.touches[0] || e.originalEvent.changedTouches[0];\r\n self.setPosition(touch);\r\n\r\n });\r\n self.zoomContainer.bind('touchend.ezpspace', function (e) {\r\n self.showHideWindow('hide');\r\n if (self.options.showLens) {\r\n self.showHideLens('hide');\r\n }\r\n if (self.options.tint && self.options.zoomType !== 'inner') {\r\n self.showHideTint('hide');\r\n }\r\n });\r\n\r\n self.$elem.bind('touchend.ezpspace', function (e) {\r\n self.showHideWindow('hide');\r\n if (self.options.showLens) {\r\n self.showHideLens('hide');\r\n }\r\n if (self.options.tint && self.options.zoomType !== 'inner') {\r\n self.showHideTint('hide');\r\n }\r\n });\r\n if (self.options.showLens) {\r\n self.zoomLens.bind('touchmove.ezpspace', function (e) {\r\n\r\n e.preventDefault();\r\n var touch = e.originalEvent.touches[0] || e.originalEvent.changedTouches[0];\r\n self.setPosition(touch);\r\n });\r\n\r\n self.zoomLens.bind('touchend.ezpspace', function (e) {\r\n self.showHideWindow('hide');\r\n if (self.options.showLens) {\r\n self.showHideLens('hide');\r\n }\r\n if (self.options.tint && self.options.zoomType !== 'inner') {\r\n self.showHideTint('hide');\r\n }\r\n });\r\n }\r\n }\r\n //Needed to work in IE\r\n self.$elem.bind('mousemove.ezpspace', function (e) {\r\n if (self.overWindow === false) {\r\n self.setElements('show');\r\n }\r\n //make sure on orientation change the setposition is not fired\r\n if (self.lastX !== e.clientX || self.lastY !== e.clientY) {\r\n self.setPosition(e);\r\n self.currentLoc = e;\r\n }\r\n self.lastX = e.clientX;\r\n self.lastY = e.clientY;\r\n\r\n });\r\n\r\n self.zoomContainer.bind('click.ezpspace touchstart.ezpspace', self.options.onImageClick);\r\n\r\n self.zoomContainer.bind('mousemove.ezpspace', function (e) {\r\n if (self.overWindow === false) {\r\n self.setElements('show');\r\n }\r\n mouseMoveZoomHandler(e);\r\n });\r\n\r\n function mouseMoveZoomHandler(e) {\r\n //self.overWindow = true;\r\n //make sure on orientation change the setposition is not fired\r\n if (self.lastX !== e.clientX || self.lastY !== e.clientY) {\r\n self.setPosition(e);\r\n self.currentLoc = e;\r\n }\r\n self.lastX = e.clientX;\r\n self.lastY = e.clientY;\r\n }\r\n\r\n var elementToTrack = null;\r\n if (self.options.zoomType !== 'inner') {\r\n elementToTrack = self.zoomLens;\r\n }\r\n if (self.options.tint && self.options.zoomType !== 'inner') {\r\n elementToTrack = self.zoomTint;\r\n }\r\n if (self.options.zoomType === 'inner') {\r\n elementToTrack = self.zoomWindow;\r\n }\r\n\r\n //register the mouse tracking\r\n if (elementToTrack) {\r\n elementToTrack.bind('mousemove.ezpspace', mouseMoveZoomHandler);\r\n }\r\n\r\n // lensFadeOut: 500, zoomTintFadeIn\r\n self.zoomContainer.add(self.$elem).mouseenter(function () {\r\n if (self.overWindow === false) {\r\n self.setElements('show');\r\n }\r\n }).mouseleave(function () {\r\n if (!self.scrollLock) {\r\n self.setElements('hide');\r\n self.options.onDestroy(self.$elem);\r\n }\r\n });\r\n //end ove image\r\n\r\n if (self.options.zoomType !== 'inner') {\r\n self.zoomWindow.mouseenter(function () {\r\n self.overWindow = true;\r\n self.setElements('hide');\r\n }).mouseleave(function () {\r\n self.overWindow = false;\r\n });\r\n }\r\n //end ove image\r\n\r\n // var delta = parseInt(e.originalEvent.wheelDelta || -e.originalEvent.detail);\r\n\r\n // $(this).empty();\r\n // return false;\r\n\r\n //fix for initial zoom setting\r\n //if (self.options.zoomLevel !== 1) {\r\n // \tself.changeZoomLevel(self.currentZoomLevel);\r\n //}\r\n //set the min zoomlevel\r\n if (self.options.minZoomLevel) {\r\n self.minZoomLevel = self.options.minZoomLevel;\r\n }\r\n else {\r\n self.minZoomLevel = self.options.scrollZoomIncrement * 2;\r\n }\r\n\r\n if (self.options.scrollZoom) {\r\n //see compatibility of mouse events at https://developer.mozilla.org/en-US/docs/Web/Events/mousewheel\r\n self.zoomContainer.add(self.$elem).bind('wheel DOMMouseScroll MozMousePixelScroll', function (e) {\r\n // in IE there is issue with firing of mouseleave - So check whether still scrolling\r\n // and on mouseleave check if scrolllock\r\n self.scrollLock = true;\r\n clearTimeout($.data(this, 'timer'));\r\n $.data(this, 'timer', setTimeout(function () {\r\n self.scrollLock = false;\r\n //do something\r\n }, 250));\r\n\r\n var theEvent = e.originalEvent.deltaY || e.originalEvent.detail * -1;\r\n\r\n //this.scrollTop += ( delta < 0 ? 1 : -1 ) * 30;\r\n // e.preventDefault();\r\n\r\n e.stopImmediatePropagation();\r\n e.stopPropagation();\r\n e.preventDefault();\r\n\r\n if (theEvent == 0) {\r\n // fixes last event inversion bug\r\n return false;\r\n }\r\n\r\n if (theEvent / 120 > 0) {\r\n var nextZoomLevel = parseFloat(self.currentZoomLevel) - self.options.scrollZoomIncrement;\r\n //scrolling up\r\n if (nextZoomLevel >= parseFloat(self.minZoomLevel)) {\r\n self.changeZoomLevel(nextZoomLevel);\r\n }\r\n }\r\n else {\r\n //scrolling down\r\n\r\n //Check if it has to maintain original zoom window aspect ratio or not\r\n if ((!self.fullheight && !self.fullwidth) || !self.options.mantainZoomAspectRatio) {\r\n var nextZoomLevel = parseFloat(self.currentZoomLevel) + self.options.scrollZoomIncrement;\r\n\r\n if (self.options.maxZoomLevel) {\r\n if (nextZoomLevel <= self.options.maxZoomLevel) {\r\n self.changeZoomLevel(nextZoomLevel);\r\n }\r\n }\r\n else {\r\n //andy\r\n self.changeZoomLevel(nextZoomLevel);\r\n }\r\n }\r\n }\r\n return false;\r\n });\r\n }\r\n },\r\n destroy: function () {\r\n var self = this;\r\n self.$elem.unbind('ezpspace');\r\n $(self.zoomContainer).remove();\r\n if (self.options.loadingIcon && !!self.spinner && !!self.spinner.length) {\r\n self.spinner.remove();\r\n delete self.spinner;\r\n }\r\n },\r\n getIdentifier: function () {\r\n var self = this;\r\n return self.options.zoomId;\r\n },\r\n setElements: function (type) {\r\n var self = this;\r\n if (!self.options.zoomEnabled) {\r\n return false;\r\n }\r\n if (type === 'show') {\r\n if (self.isWindowSet) {\r\n if (self.options.zoomType === 'inner') {\r\n self.showHideWindow('show');\r\n }\r\n if (self.options.zoomType === 'window') {\r\n self.showHideWindow('show');\r\n }\r\n if (self.options.showLens) {\r\n self.showHideLens('show');\r\n }\r\n if (self.options.tint && self.options.zoomType !== 'inner') {\r\n self.showHideTint('show');\r\n }\r\n }\r\n }\r\n\r\n if (type === 'hide') {\r\n if (self.options.zoomType === 'window') {\r\n self.showHideWindow('hide');\r\n }\r\n if (!self.options.tint) {\r\n self.showHideWindow('hide');\r\n }\r\n if (self.options.showLens) {\r\n self.showHideLens('hide');\r\n }\r\n if (self.options.tint) {\r\n self.showHideTint('hide');\r\n }\r\n }\r\n },\r\n setPosition: function (e) {\r\n\r\n var self = this;\r\n\r\n if (!self.options.zoomEnabled) {\r\n return false;\r\n }\r\n\r\n //recaclc offset each time in case the image moves\r\n //this can be caused by other on page elements\r\n self.nzHeight = self.$elem.height();\r\n self.nzWidth = self.$elem.width();\r\n self.updateOffset(self);\r\n\r\n if (self.options.tint && self.options.zoomType !== 'inner') {\r\n self.zoomTint.css({\r\n top: 0,\r\n left: 0\r\n });\r\n }\r\n //set responsive\r\n //will checking if the image needs changing before running this code work faster?\r\n if (self.options.responsive && !self.options.scrollZoom) {\r\n if (self.options.showLens) {\r\n var lensHeight, lensWidth;\r\n if (self.nzHeight < self.options.zoomWindowWidth / self.widthRatio) {\r\n self.lensHeight = self.nzHeight;\r\n }\r\n else {\r\n self.lensHeight = String((self.options.zoomWindowHeight / self.heightRatio));\r\n }\r\n if (self.largeWidth < self.options.zoomWindowWidth) {\r\n self.lensWidth = self.nzWidth;\r\n }\r\n else {\r\n self.lensWidth = (self.options.zoomWindowWidth / self.widthRatio);\r\n }\r\n self.widthRatio = self.largeWidth / self.nzWidth;\r\n self.heightRatio = self.largeHeight / self.nzHeight;\r\n if (self.options.zoomType !== 'lens') {\r\n //possibly dont need to keep recalcalculating\r\n //if the lens is heigher than the image, then set lens size to image size\r\n if (self.nzHeight < self.options.zoomWindowWidth / self.widthRatio) {\r\n self.lensHeight = self.nzHeight;\r\n\r\n }\r\n else {\r\n self.lensHeight = String((self.options.zoomWindowHeight / self.heightRatio));\r\n }\r\n\r\n if (self.nzWidth < self.options.zoomWindowHeight / self.heightRatio) {\r\n self.lensWidth = self.nzWidth;\r\n }\r\n else {\r\n self.lensWidth = String((self.options.zoomWindowWidth / self.widthRatio));\r\n }\r\n\r\n self.zoomLens.css({\r\n 'width': self.lensWidth,\r\n 'height': self.lensHeight\r\n });\r\n\r\n if (self.options.tint) {\r\n self.zoomTintImage.css({\r\n 'width': self.nzWidth,\r\n 'height': self.nzHeight\r\n });\r\n }\r\n\r\n }\r\n if (self.options.zoomType === 'lens') {\r\n self.zoomLens.css({\r\n width: String(self.options.lensSize) + 'px',\r\n height: String(self.options.lensSize) + 'px'\r\n });\r\n }\r\n //end responsive image change\r\n }\r\n }\r\n\r\n //container fix\r\n self.zoomContainer.css({\r\n top: self.nzOffset.top,\r\n left: self.nzOffset.left,\r\n width: self.nzWidth, // new code\r\n height: self.nzHeight // new code\r\n });\r\n self.mouseLeft = parseInt(e.pageX - self.nzOffset.left);\r\n self.mouseTop = parseInt(e.pageY - self.nzOffset.top);\r\n //calculate the Location of the Lens\r\n\r\n //calculate the bound regions - but only if zoom window\r\n if (self.options.zoomType === 'window') {\r\n var zoomLensHeight = self.zoomLens.height() / 2;\r\n var zoomLensWidth = self.zoomLens.width() / 2;\r\n self.Etoppos = (self.mouseTop < 0 + zoomLensHeight);\r\n self.Eboppos = (self.mouseTop > self.nzHeight - zoomLensHeight - (self.options.lensBorderSize * 2));\r\n self.Eloppos = (self.mouseLeft < 0 + zoomLensWidth);\r\n self.Eroppos = (self.mouseLeft > (self.nzWidth - zoomLensWidth - (self.options.lensBorderSize * 2)));\r\n }\r\n //calculate the bound regions - but only for inner zoom\r\n if (self.options.zoomType === 'inner') {\r\n self.Etoppos = (self.mouseTop < ((self.nzHeight / 2) / self.heightRatio));\r\n self.Eboppos = (self.mouseTop > (self.nzHeight - ((self.nzHeight / 2) / self.heightRatio)));\r\n self.Eloppos = (self.mouseLeft < 0 + (((self.nzWidth / 2) / self.widthRatio)));\r\n self.Eroppos = (self.mouseLeft > (self.nzWidth - (self.nzWidth / 2) / self.widthRatio - (self.options.lensBorderSize * 2)));\r\n }\r\n\r\n // if the mouse position of the slider is one of the outerbounds, then hide window and lens\r\n if (self.mouseLeft < 0 || self.mouseTop < 0 || self.mouseLeft > self.nzWidth || self.mouseTop > self.nzHeight) {\r\n self.setElements('hide');\r\n return;\r\n }\r\n //else continue with operations\r\n else {\r\n //lens options\r\n if (self.options.showLens) {\r\n //\t\tself.showHideLens('show');\r\n //set background position of lens\r\n self.lensLeftPos = String(Math.floor(self.mouseLeft - self.zoomLens.width() / 2));\r\n self.lensTopPos = String(Math.floor(self.mouseTop - self.zoomLens.height() / 2));\r\n }\r\n //adjust the background position if the mouse is in one of the outer regions\r\n\r\n //Top region\r\n if (self.Etoppos) {\r\n self.lensTopPos = 0;\r\n }\r\n //Left Region\r\n if (self.Eloppos) {\r\n self.windowLeftPos = 0;\r\n self.lensLeftPos = 0;\r\n self.tintpos = 0;\r\n }\r\n //Set bottom and right region for window mode\r\n if (self.options.zoomType === 'window') {\r\n if (self.Eboppos) {\r\n self.lensTopPos = Math.max((self.nzHeight) - self.zoomLens.height() - (self.options.lensBorderSize * 2), 0);\r\n }\r\n if (self.Eroppos) {\r\n self.lensLeftPos = (self.nzWidth - (self.zoomLens.width()) - (self.options.lensBorderSize * 2));\r\n }\r\n }\r\n //Set bottom and right region for inner mode\r\n if (self.options.zoomType === 'inner') {\r\n if (self.Eboppos) {\r\n self.lensTopPos = Math.max(((self.nzHeight) - (self.options.lensBorderSize * 2)), 0);\r\n }\r\n if (self.Eroppos) {\r\n self.lensLeftPos = (self.nzWidth - (self.nzWidth) - (self.options.lensBorderSize * 2));\r\n }\r\n }\r\n //if lens zoom\r\n if (self.options.zoomType === 'lens') {\r\n\r\n self.windowLeftPos = String(((e.pageX - self.nzOffset.left) * self.widthRatio - self.zoomLens.width() / 2) * (-1));\r\n self.windowTopPos = String(((e.pageY - self.nzOffset.top) * self.heightRatio - self.zoomLens.height() / 2) * (-1));\r\n self.zoomLens.css('background-position', self.windowLeftPos + 'px ' + self.windowTopPos + 'px');\r\n\r\n if (self.changeBgSize) {\r\n if (self.nzHeight > self.nzWidth) {\r\n if (self.options.zoomType === 'lens') {\r\n self.zoomLens.css('background-size',\r\n self.largeWidth / self.newvalueheight + 'px ' +\r\n self.largeHeight / self.newvalueheight + 'px');\r\n }\r\n\r\n self.zoomWindow.css('background-size',\r\n self.largeWidth / self.newvalueheight + 'px ' +\r\n self.largeHeight / self.newvalueheight + 'px');\r\n }\r\n else {\r\n if (self.options.zoomType === 'lens') {\r\n self.zoomLens.css('background-size',\r\n self.largeWidth / self.newvaluewidth + 'px ' +\r\n self.largeHeight / self.newvaluewidth + 'px');\r\n }\r\n self.zoomWindow.css('background-size',\r\n self.largeWidth / self.newvaluewidth + 'px ' +\r\n self.largeHeight / self.newvaluewidth + 'px');\r\n }\r\n self.changeBgSize = false;\r\n }\r\n\r\n self.setWindowPosition(e);\r\n }\r\n //if tint zoom\r\n if (self.options.tint && self.options.zoomType !== 'inner') {\r\n self.setTintPosition(e);\r\n }\r\n //set the css background position\r\n if (self.options.zoomType === 'window') {\r\n self.setWindowPosition(e);\r\n }\r\n if (self.options.zoomType === 'inner') {\r\n self.setWindowPosition(e);\r\n }\r\n if (self.options.showLens) {\r\n if (self.fullwidth && self.options.zoomType !== 'lens') {\r\n self.lensLeftPos = 0;\r\n }\r\n self.zoomLens.css({\r\n left: self.lensLeftPos + 'px',\r\n top: self.lensTopPos + 'px'\r\n });\r\n }\r\n\r\n } //end else\r\n },\r\n showHideZoomContainer: function (change) {\r\n var self = this;\r\n if (change === 'show') {\r\n if (self.zoomContainer) {\r\n self.zoomContainer.show();\r\n }\r\n }\r\n if (change === 'hide') {\r\n if (self.zoomContainer) {\r\n self.zoomContainer.hide();\r\n }\r\n }\r\n },\r\n showHideWindow: function (change) {\r\n var self = this;\r\n if (change === 'show') {\r\n if (!self.isWindowActive && self.zoomWindow) {\r\n self.options.onShow(self);\r\n if (self.options.zoomWindowFadeIn) {\r\n self.zoomWindow.stop(true, true, false).fadeIn(self.options.zoomWindowFadeIn);\r\n }\r\n else {\r\n self.zoomWindow.show();\r\n }\r\n self.isWindowActive = true;\r\n }\r\n }\r\n if (change === 'hide') {\r\n if (self.isWindowActive) {\r\n if (self.options.zoomWindowFadeOut) {\r\n self.zoomWindow.stop(true, true).fadeOut(self.options.zoomWindowFadeOut, function () {\r\n if (self.loop) {\r\n //stop moving the zoom window when zoom window is faded out\r\n clearInterval(self.loop);\r\n self.loop = false;\r\n }\r\n });\r\n }\r\n else {\r\n self.zoomWindow.hide();\r\n }\r\n self.isWindowActive = false;\r\n }\r\n }\r\n },\r\n showHideLens: function (change) {\r\n var self = this;\r\n if (change === 'show') {\r\n if (!self.isLensActive) {\r\n if (self.zoomLens) {\r\n if (self.options.lensFadeIn) {\r\n self.zoomLens.stop(true, true, false).fadeIn(self.options.lensFadeIn);\r\n }\r\n else {\r\n self.zoomLens.show();\r\n }\r\n }\r\n self.isLensActive = true;\r\n }\r\n }\r\n if (change === 'hide') {\r\n if (self.isLensActive) {\r\n if (self.zoomLens) {\r\n if (self.options.lensFadeOut) {\r\n self.zoomLens.stop(true, true).fadeOut(self.options.lensFadeOut);\r\n }\r\n else {\r\n self.zoomLens.hide();\r\n }\r\n }\r\n self.isLensActive = false;\r\n }\r\n }\r\n },\r\n showHideTint: function (change) {\r\n var self = this;\r\n if (change === 'show') {\r\n if (!self.isTintActive && self.zoomTint) {\r\n\r\n if (self.options.zoomTintFadeIn) {\r\n self.zoomTint.css('opacity', self.options.tintOpacity).animate().stop(true, true).fadeIn('slow');\r\n }\r\n else {\r\n self.zoomTint.css('opacity', self.options.tintOpacity).animate();\r\n self.zoomTint.show();\r\n }\r\n self.isTintActive = true;\r\n }\r\n }\r\n if (change === 'hide') {\r\n if (self.isTintActive) {\r\n\r\n if (self.options.zoomTintFadeOut) {\r\n self.zoomTint.stop(true, true).fadeOut(self.options.zoomTintFadeOut);\r\n }\r\n else {\r\n self.zoomTint.hide();\r\n }\r\n self.isTintActive = false;\r\n }\r\n }\r\n },\r\n\r\n setLensPosition: function (e) {\r\n },\r\n\r\n setWindowPosition: function (e) {\r\n //return obj.slice( 0, count );\r\n var self = this;\r\n\r\n if (!isNaN(self.options.zoomWindowPosition)) {\r\n\r\n switch (self.options.zoomWindowPosition) {\r\n case 1: //done\r\n self.windowOffsetTop = (self.options.zoomWindowOffsetY);//DONE - 1\r\n self.windowOffsetLeft = (+self.nzWidth); //DONE 1, 2, 3, 4, 16\r\n break;\r\n case 2:\r\n if (self.options.zoomWindowHeight > self.nzHeight) { //positive margin\r\n\r\n self.windowOffsetTop = ((self.options.zoomWindowHeight / 2) - (self.nzHeight / 2)) * (-1);\r\n self.windowOffsetLeft = (self.nzWidth); //DONE 1, 2, 3, 4, 16\r\n }\r\n else { //negative margin\r\n $.noop();\r\n }\r\n break;\r\n case 3: //done\r\n self.windowOffsetTop = (self.nzHeight - self.zoomWindow.height() - (self.options.borderSize * 2)); //DONE 3,9\r\n self.windowOffsetLeft = (self.nzWidth); //DONE 1, 2, 3, 4, 16\r\n break;\r\n case 4: //done\r\n self.windowOffsetTop = (self.nzHeight); //DONE - 4,5,6,7,8\r\n self.windowOffsetLeft = (self.nzWidth); //DONE 1, 2, 3, 4, 16\r\n break;\r\n case 5: //done\r\n self.windowOffsetTop = (self.nzHeight); //DONE - 4,5,6,7,8\r\n self.windowOffsetLeft = (self.nzWidth - self.zoomWindow.width() - (self.options.borderSize * 2)); //DONE - 5,15\r\n break;\r\n case 6:\r\n if (self.options.zoomWindowHeight > self.nzHeight) { //positive margin\r\n self.windowOffsetTop = (self.nzHeight); //DONE - 4,5,6,7,8\r\n\r\n self.windowOffsetLeft = ((self.options.zoomWindowWidth / 2) - (self.nzWidth / 2) + (self.options.borderSize * 2)) * (-1);\r\n }\r\n else { //negative margin\r\n $.noop();\r\n }\r\n\r\n break;\r\n case 7: //done\r\n self.windowOffsetTop = (self.nzHeight); //DONE - 4,5,6,7,8\r\n self.windowOffsetLeft = 0; //DONE 7, 13\r\n break;\r\n case 8: //done\r\n self.windowOffsetTop = (self.nzHeight); //DONE - 4,5,6,7,8\r\n self.windowOffsetLeft = (self.zoomWindow.width() + (self.options.borderSize * 2)) * (-1); //DONE 8,9,10,11,12\r\n break;\r\n case 9: //done\r\n self.windowOffsetTop = (self.nzHeight - self.zoomWindow.height() - (self.options.borderSize * 2)); //DONE 3,9\r\n self.windowOffsetLeft = (self.zoomWindow.width() + (self.options.borderSize * 2)) * (-1); //DONE 8,9,10,11,12\r\n break;\r\n case 10:\r\n if (self.options.zoomWindowHeight > self.nzHeight) { //positive margin\r\n\r\n self.windowOffsetTop = ((self.options.zoomWindowHeight / 2) - (self.nzHeight / 2)) * (-1);\r\n self.windowOffsetLeft = (self.zoomWindow.width() + (self.options.borderSize * 2)) * (-1); //DONE 8,9,10,11,12\r\n }\r\n else { //negative margin\r\n $.noop();\r\n }\r\n break;\r\n case 11:\r\n self.windowOffsetTop = (self.options.zoomWindowOffsetY);\r\n self.windowOffsetLeft = (self.zoomWindow.width() + (self.options.borderSize * 2)) * (-1); //DONE 8,9,10,11,12\r\n break;\r\n case 12: //done\r\n self.windowOffsetTop = (self.zoomWindow.height() + (self.options.borderSize * 2)) * (-1); //DONE 12,13,14,15,16\r\n self.windowOffsetLeft = (self.zoomWindow.width() + (self.options.borderSize * 2)) * (-1); //DONE 8,9,10,11,12\r\n break;\r\n case 13: //done\r\n self.windowOffsetTop = (self.zoomWindow.height() + (self.options.borderSize * 2)) * (-1); //DONE 12,13,14,15,16\r\n self.windowOffsetLeft = (0); //DONE 7, 13\r\n break;\r\n case 14:\r\n if (self.options.zoomWindowHeight > self.nzHeight) { //positive margin\r\n self.windowOffsetTop = (self.zoomWindow.height() + (self.options.borderSize * 2)) * (-1); //DONE 12,13,14,15,16\r\n\r\n self.windowOffsetLeft = ((self.options.zoomWindowWidth / 2) - (self.nzWidth / 2) + (self.options.borderSize * 2)) * (-1);\r\n }\r\n else { //negative margin\r\n $.noop();\r\n }\r\n break;\r\n case 15://done\r\n self.windowOffsetTop = (self.zoomWindow.height() + (self.options.borderSize * 2)) * (-1); //DONE 12,13,14,15,16\r\n self.windowOffsetLeft = (self.nzWidth - self.zoomWindow.width() - (self.options.borderSize * 2)); //DONE - 5,15\r\n break;\r\n case 16: //done\r\n self.windowOffsetTop = (self.zoomWindow.height() + (self.options.borderSize * 2)) * (-1); //DONE 12,13,14,15,16\r\n self.windowOffsetLeft = (self.nzWidth); //DONE 1, 2, 3, 4, 16\r\n break;\r\n default: //done\r\n self.windowOffsetTop = (self.options.zoomWindowOffsetY);//DONE - 1\r\n self.windowOffsetLeft = (self.nzWidth); //DONE 1, 2, 3, 4, 16\r\n }\r\n } //end isNAN\r\n else {\r\n // For BC purposes, treat passed element as ID if element not found\r\n self.externalContainer = $(self.options.zoomWindowPosition);\r\n if (!self.externalContainer.length) {\r\n self.externalContainer = $('#' + self.options.zoomWindowPosition);\r\n }\r\n\r\n self.externalContainerWidth = self.externalContainer.width();\r\n self.externalContainerHeight = self.externalContainer.height();\r\n self.externalContainerOffset = self.externalContainer.offset();\r\n\r\n self.windowOffsetTop = self.externalContainerOffset.top;//DONE - 1\r\n self.windowOffsetLeft = self.externalContainerOffset.left; //DONE 1, 2, 3, 4, 16\r\n\r\n }\r\n self.isWindowSet = true;\r\n self.windowOffsetTop = self.windowOffsetTop + self.options.zoomWindowOffsetY;\r\n self.windowOffsetLeft = self.windowOffsetLeft + self.options.zoomWindowOffsetX;\r\n\r\n self.zoomWindow.css({\r\n top: self.windowOffsetTop,\r\n left: self.windowOffsetLeft\r\n });\r\n\r\n if (self.options.zoomType === 'inner') {\r\n self.zoomWindow.css({\r\n top: 0,\r\n left: 0\r\n });\r\n\r\n }\r\n\r\n self.windowLeftPos = String(((e.pageX - self.nzOffset.left) * self.widthRatio - self.zoomWindow.width() / 2) * (-1));\r\n self.windowTopPos = String(((e.pageY - self.nzOffset.top) * self.heightRatio - self.zoomWindow.height() / 2) * (-1));\r\n if (self.Etoppos) {\r\n self.windowTopPos = 0;\r\n }\r\n if (self.Eloppos) {\r\n self.windowLeftPos = 0;\r\n }\r\n if (self.Eboppos) {\r\n self.windowTopPos = (self.largeHeight / self.currentZoomLevel - self.zoomWindow.height()) * (-1);\r\n }\r\n if (self.Eroppos) {\r\n self.windowLeftPos = ((self.largeWidth / self.currentZoomLevel - self.zoomWindow.width()) * (-1));\r\n }\r\n\r\n //stops micro movements\r\n if (self.fullheight) {\r\n self.windowTopPos = 0;\r\n }\r\n if (self.fullwidth) {\r\n self.windowLeftPos = 0;\r\n }\r\n\r\n //set the css background position\r\n if (self.options.zoomType === 'window' || self.options.zoomType === 'inner') {\r\n\r\n if (self.zoomLock === 1) {\r\n //overrides for images not zoomable\r\n if (self.widthRatio <= 1) {\r\n self.windowLeftPos = 0;\r\n }\r\n if (self.heightRatio <= 1) {\r\n self.windowTopPos = 0;\r\n }\r\n }\r\n // adjust images less than the window height\r\n\r\n if (self.options.zoomType === 'window') {\r\n if (self.largeHeight < self.options.zoomWindowHeight) {\r\n self.windowTopPos = 0;\r\n }\r\n if (self.largeWidth < self.options.zoomWindowWidth) {\r\n self.windowLeftPos = 0;\r\n }\r\n }\r\n //set the zoomwindow background position\r\n if (self.options.easing) {\r\n\r\n // if(self.changeZoom){\r\n // clearInterval(self.loop);\r\n // self.changeZoom = false;\r\n // self.loop = false;\r\n\r\n // }\r\n //set the pos to 0 if not set\r\n if (!self.xp) {\r\n self.xp = 0;\r\n }\r\n if (!self.yp) {\r\n self.yp = 0;\r\n }\r\n var interval = 16;\r\n if (Number.isInteger(parseInt(self.options.easing))) {\r\n interval = parseInt(self.options.easing);\r\n }\r\n //if loop not already started, then run it\r\n if (!self.loop) {\r\n self.loop = setInterval(function () {\r\n //using zeno's paradox\r\n\r\n self.xp += (self.windowLeftPos - self.xp) / self.options.easingAmount;\r\n self.yp += (self.windowTopPos - self.yp) / self.options.easingAmount;\r\n if (self.scrollingLock) {\r\n\r\n clearInterval(self.loop);\r\n self.xp = self.windowLeftPos;\r\n self.yp = self.windowTopPos;\r\n\r\n self.xp = ((e.pageX - self.nzOffset.left) * self.widthRatio - self.zoomWindow.width() / 2) * (-1);\r\n self.yp = (((e.pageY - self.nzOffset.top) * self.heightRatio - self.zoomWindow.height() / 2) * (-1));\r\n\r\n if (self.changeBgSize) {\r\n if (self.nzHeight > self.nzWidth) {\r\n if (self.options.zoomType === 'lens') {\r\n self.zoomLens.css('background-size',\r\n self.largeWidth / self.newvalueheight + 'px ' +\r\n self.largeHeight / self.newvalueheight + 'px');\r\n }\r\n self.zoomWindow.css('background-size',\r\n self.largeWidth / self.newvalueheight + 'px ' +\r\n self.largeHeight / self.newvalueheight + 'px');\r\n }\r\n else {\r\n if (self.options.zoomType !== 'lens') {\r\n self.zoomLens.css('background-size',\r\n self.largeWidth / self.newvaluewidth + 'px ' +\r\n self.largeHeight / self.newvalueheight + 'px');\r\n }\r\n self.zoomWindow.css('background-size',\r\n self.largeWidth / self.newvaluewidth + 'px ' +\r\n self.largeHeight / self.newvaluewidth + 'px');\r\n }\r\n\r\n /*\r\n if(!self.bgxp){self.bgxp = self.largeWidth/self.newvalue;}\r\n if(!self.bgyp){self.bgyp = self.largeHeight/self.newvalue ;}\r\n if (!self.bgloop){\r\n self.bgloop = setInterval(function(){\r\n\r\n self.bgxp += (self.largeWidth/self.newvalue - self.bgxp) / self.options.easingAmount;\r\n self.bgyp += (self.largeHeight/self.newvalue - self.bgyp) / self.options.easingAmount;\r\n\r\n self.zoomWindow.css('background-size', self.bgxp + 'px ' + self.bgyp + 'px' );\r\n\r\n\r\n }, 16);\r\n\r\n }\r\n */\r\n self.changeBgSize = false;\r\n }\r\n\r\n self.zoomWindow.css('background-position', self.windowLeftPos + 'px ' + self.windowTopPos + 'px');\r\n self.scrollingLock = false;\r\n self.loop = false;\r\n\r\n }\r\n else if (Math.round(Math.abs(self.xp - self.windowLeftPos) + Math.abs(self.yp - self.windowTopPos)) < 1) {\r\n //stops micro movements\r\n clearInterval(self.loop);\r\n self.zoomWindow.css('background-position', self.windowLeftPos + 'px ' + self.windowTopPos + 'px');\r\n self.loop = false;\r\n }\r\n else {\r\n if (self.changeBgSize) {\r\n if (self.nzHeight > self.nzWidth) {\r\n if (self.options.zoomType === 'lens') {\r\n self.zoomLens.css('background-size',\r\n self.largeWidth / self.newvalueheight + 'px ' +\r\n self.largeHeight / self.newvalueheight + 'px');\r\n }\r\n self.zoomWindow.css('background-size',\r\n self.largeWidth / self.newvalueheight + 'px ' +\r\n self.largeHeight / self.newvalueheight + 'px');\r\n }\r\n else {\r\n if (self.options.zoomType !== 'lens') {\r\n self.zoomLens.css('background-size',\r\n self.largeWidth / self.newvaluewidth + 'px ' +\r\n self.largeHeight / self.newvaluewidth + 'px');\r\n }\r\n self.zoomWindow.css('background-size',\r\n self.largeWidth / self.newvaluewidth + 'px ' +\r\n self.largeHeight / self.newvaluewidth + 'px');\r\n }\r\n self.changeBgSize = false;\r\n }\r\n\r\n self.zoomWindow.css('background-position', self.xp + 'px ' + self.yp + 'px');\r\n }\r\n }, interval);\r\n }\r\n }\r\n else {\r\n if (self.changeBgSize) {\r\n if (self.nzHeight > self.nzWidth) {\r\n if (self.options.zoomType === 'lens') {\r\n self.zoomLens.css('background-size',\r\n self.largeWidth / self.newvalueheight + 'px ' +\r\n self.largeHeight / self.newvalueheight + 'px');\r\n }\r\n\r\n self.zoomWindow.css('background-size',\r\n self.largeWidth / self.newvalueheight + 'px ' +\r\n self.largeHeight / self.newvalueheight + 'px');\r\n }\r\n else {\r\n if (self.options.zoomType === 'lens') {\r\n self.zoomLens.css('background-size',\r\n self.largeWidth / self.newvaluewidth + 'px ' +\r\n self.largeHeight / self.newvaluewidth + 'px');\r\n }\r\n if ((self.largeHeight / self.newvaluewidth) < self.options.zoomWindowHeight) {\r\n\r\n self.zoomWindow.css('background-size',\r\n self.largeWidth / self.newvaluewidth + 'px ' +\r\n self.largeHeight / self.newvaluewidth + 'px');\r\n }\r\n else {\r\n\r\n self.zoomWindow.css('background-size',\r\n self.largeWidth / self.newvalueheight + 'px ' +\r\n self.largeHeight / self.newvalueheight + 'px');\r\n }\r\n\r\n }\r\n self.changeBgSize = false;\r\n }\r\n\r\n self.zoomWindow.css('background-position',\r\n self.windowLeftPos + 'px ' +\r\n self.windowTopPos + 'px');\r\n }\r\n }\r\n },\r\n\r\n setTintPosition: function (e) {\r\n var self = this;\r\n var zoomLensWidth = self.zoomLens.width();\r\n var zoomLensHeight = self.zoomLens.height();\r\n self.updateOffset(self);\r\n self.tintpos = String(((e.pageX - self.nzOffset.left) - (zoomLensWidth / 2)) * (-1));\r\n self.tintposy = String(((e.pageY - self.nzOffset.top) - zoomLensHeight / 2) * (-1));\r\n if (self.Etoppos) {\r\n self.tintposy = 0;\r\n }\r\n if (self.Eloppos) {\r\n self.tintpos = 0;\r\n }\r\n if (self.Eboppos) {\r\n self.tintposy = (self.nzHeight - zoomLensHeight - (self.options.lensBorderSize * 2)) * (-1);\r\n }\r\n if (self.Eroppos) {\r\n self.tintpos = ((self.nzWidth - zoomLensWidth - (self.options.lensBorderSize * 2)) * (-1));\r\n }\r\n if (self.options.tint) {\r\n //stops micro movements\r\n if (self.fullheight) {\r\n self.tintposy = 0;\r\n\r\n }\r\n if (self.fullwidth) {\r\n self.tintpos = 0;\r\n\r\n }\r\n self.zoomTintImage.css({\r\n 'left': self.tintpos + 'px',\r\n 'top': self.tintposy + 'px'\r\n });\r\n }\r\n },\r\n\r\n swaptheimage: function (smallimage, largeimage) {\r\n var self = this;\r\n var newImg = new Image();\r\n\r\n if (self.options.loadingIcon && !self.spinner) {\r\n var styleAttr = 'background: url(\\'' + self.options.loadingIcon + '\\') no-repeat center;' +\r\n 'height:' + self.nzHeight + 'px;' +\r\n 'width:' + self.nzWidth + 'px;' +\r\n 'z-index: 2000;' +\r\n 'position: absolute; ' +\r\n 'background-position: center center;';\r\n if (self.options.zoomType === 'inner') {\r\n styleAttr += 'top: 0px;';\r\n }\r\n self.spinner = $('
    ');\r\n self.$elem.after(self.spinner);\r\n } else if (self.spinner) {\r\n self.spinner.show();\r\n }\r\n\r\n self.options.onImageSwap(self.$elem);\r\n\r\n newImg.onload = function () {\r\n self.largeWidth = newImg.width;\r\n self.largeHeight = newImg.height;\r\n self.zoomImage = largeimage;\r\n self.zoomWindow.css('background-size', self.largeWidth + 'px ' + self.largeHeight + 'px');\r\n\r\n self.swapAction(smallimage, largeimage);\r\n return;\r\n };\r\n self.setImageSource(newImg, largeimage); // this must be done AFTER setting onload\r\n },\r\n\r\n swapAction: function (smallimage, largeimage) {\r\n var self = this;\r\n var elemWidth = self.$elem.width();\r\n var elemHeight = self.$elem.height();\r\n var newImg2 = new Image();\r\n newImg2.onload = function () {\r\n //re-calculate values\r\n self.nzHeight = newImg2.height;\r\n self.nzWidth = newImg2.width;\r\n self.options.onImageSwapComplete(self.$elem);\r\n\r\n self.doneCallback();\r\n return;\r\n };\r\n self.setImageSource(newImg2, smallimage);\r\n\r\n //reset the zoomlevel to that initially set in options\r\n self.currentZoomLevel = self.options.zoomLevel;\r\n self.options.maxZoomLevel = false;\r\n\r\n //swaps the main image\r\n //self.$elem.attr('src',smallimage);\r\n //swaps the zoom image\r\n if (self.options.zoomType === 'lens') {\r\n self.zoomLens.css('background-image', 'url(\"' + largeimage + '\")');\r\n }\r\n if (self.options.zoomType === 'window') {\r\n self.zoomWindow.css('background-image', 'url(\"' + largeimage + '\")');\r\n }\r\n if (self.options.zoomType === 'inner') {\r\n self.zoomWindow.css('background-image', 'url(\"' + largeimage + '\")');\r\n }\r\n\r\n self.currentImage = largeimage;\r\n\r\n if (self.options.imageCrossfade) {\r\n var oldImg = self.$elem;\r\n var newImg = oldImg.clone();\r\n self.$elem.attr('src', smallimage);\r\n self.$elem.after(newImg);\r\n newImg.stop(true).fadeOut(self.options.imageCrossfade, function () {\r\n $(this).remove();\r\n });\r\n\r\n // if(self.options.zoomType === 'inner'){\r\n //remove any attributes on the cloned image so we can resize later\r\n self.$elem.width('auto').removeAttr('width');\r\n self.$elem.height('auto').removeAttr('height');\r\n // }\r\n\r\n oldImg.fadeIn(self.options.imageCrossfade);\r\n\r\n if (self.options.tint && self.options.zoomType !== 'inner') {\r\n\r\n var oldImgTint = self.zoomTintImage;\r\n var newImgTint = oldImgTint.clone();\r\n self.zoomTintImage.attr('src', largeimage);\r\n self.zoomTintImage.after(newImgTint);\r\n newImgTint.stop(true).fadeOut(self.options.imageCrossfade, function () {\r\n $(this).remove();\r\n });\r\n\r\n oldImgTint.fadeIn(self.options.imageCrossfade);\r\n\r\n //self.zoomTintImage.attr('width',elem.data('image'));\r\n\r\n //resize the tint window\r\n self.zoomTint.css({\r\n height: elemHeight,\r\n width: elemWidth\r\n });\r\n }\r\n\r\n self.zoomContainer.css({\r\n 'height': elemHeight,\r\n 'width': elemWidth\r\n });\r\n\r\n if (self.options.zoomType === 'inner') {\r\n if (!self.options.constrainType) {\r\n self.zoomWrap.parent().css({\r\n 'height': elemHeight,\r\n 'width': elemWidth\r\n });\r\n\r\n self.zoomWindow.css({\r\n 'height': elemHeight,\r\n 'width': elemWidth\r\n });\r\n }\r\n }\r\n\r\n if (self.options.imageCrossfade) {\r\n self.zoomWrap.css({\r\n 'height': elemHeight,\r\n 'width': elemWidth\r\n });\r\n }\r\n }\r\n else {\r\n self.$elem.attr('src', smallimage);\r\n if (self.options.tint) {\r\n self.zoomTintImage.attr('src', largeimage);\r\n //self.zoomTintImage.attr('width',elem.data('image'));\r\n self.zoomTintImage.attr('height', elemHeight);\r\n //self.zoomTintImage.attr('src') = elem.data('image');\r\n self.zoomTintImage.css('height', elemHeight);\r\n self.zoomTint.css('height', elemHeight);\r\n\r\n }\r\n self.zoomContainer.css({\r\n 'height': elemHeight,\r\n 'width': elemWidth\r\n });\r\n\r\n if (self.options.imageCrossfade) {\r\n self.zoomWrap.css({\r\n 'height': elemHeight,\r\n 'width': elemWidth\r\n });\r\n }\r\n }\r\n if (self.options.constrainType) {\r\n\r\n //This will contrain the image proportions\r\n if (self.options.constrainType === 'height') {\r\n\r\n var autoWDimension = {\r\n 'height': self.options.constrainSize,\r\n 'width': 'auto'\r\n };\r\n self.zoomContainer.css(autoWDimension);\r\n\r\n if (self.options.imageCrossfade) {\r\n self.zoomWrap.css(autoWDimension);\r\n self.constwidth = self.zoomWrap.width();\r\n }\r\n else {\r\n self.$elem.css(autoWDimension);\r\n self.constwidth = elemWidth;\r\n }\r\n\r\n var constWDim = {\r\n 'height': self.options.constrainSize,\r\n 'width': self.constwidth\r\n };\r\n if (self.options.zoomType === 'inner') {\r\n\r\n self.zoomWrap.parent().css(constWDim);\r\n self.zoomWindow.css(constWDim);\r\n }\r\n if (self.options.tint) {\r\n self.tintContainer.css(constWDim);\r\n self.zoomTint.css(constWDim);\r\n self.zoomTintImage.css(constWDim);\r\n }\r\n\r\n }\r\n if (self.options.constrainType === 'width') {\r\n var autoHDimension = {\r\n 'height': 'auto',\r\n 'width': self.options.constrainSize\r\n };\r\n self.zoomContainer.css(autoHDimension);\r\n\r\n if (self.options.imageCrossfade) {\r\n self.zoomWrap.css(autoHDimension);\r\n self.constheight = self.zoomWrap.height();\r\n }\r\n else {\r\n self.$elem.css(autoHDimension);\r\n self.constheight = elemHeight;\r\n }\r\n\r\n var constHDim = {\r\n 'height': self.constheight,\r\n 'width': self.options.constrainSize\r\n };\r\n if (self.options.zoomType === 'inner') {\r\n self.zoomWrap.parent().css(constHDim);\r\n self.zoomWindow.css(constHDim);\r\n }\r\n if (self.options.tint) {\r\n self.tintContainer.css(constHDim);\r\n self.zoomTint.css(constHDim);\r\n self.zoomTintImage.css(constHDim);\r\n }\r\n }\r\n }\r\n },\r\n\r\n doneCallback: function () {\r\n var self = this;\r\n if (self.options.loadingIcon && !!self.spinner && !!self.spinner.length) {\r\n self.spinner.hide();\r\n }\r\n\r\n self.updateOffset(self);\r\n self.nzWidth = self.$elem.width();\r\n self.nzHeight = self.$elem.height();\r\n\r\n // reset the zoomlevel back to default\r\n self.currentZoomLevel = self.options.zoomLevel;\r\n\r\n //ratio of the large to small image\r\n self.widthRatio = self.largeWidth / self.nzWidth;\r\n self.heightRatio = self.largeHeight / self.nzHeight;\r\n\r\n //NEED TO ADD THE LENS SIZE FOR ROUND\r\n // adjust images less than the window height\r\n if (self.options.zoomType === 'window') {\r\n\r\n if (self.nzHeight < self.options.zoomWindowHeight / self.heightRatio) {\r\n self.lensHeight = self.nzHeight;\r\n\r\n }\r\n else {\r\n self.lensHeight = String((self.options.zoomWindowHeight / self.heightRatio));\r\n }\r\n\r\n if (self.nzWidth < self.options.zoomWindowWidth) {\r\n self.lensWidth = self.nzWidth;\r\n }\r\n else {\r\n self.lensWidth = (self.options.zoomWindowWidth / self.widthRatio);\r\n }\r\n\r\n if (self.zoomLens) {\r\n self.zoomLens.css({\r\n 'width': self.lensWidth,\r\n 'height': self.lensHeight\r\n });\r\n }\r\n }\r\n },\r\n\r\n getCurrentImage: function () {\r\n var self = this;\r\n return self.zoomImage;\r\n },\r\n\r\n getGalleryList: function () {\r\n var self = this;\r\n //loop through the gallery options and set them in list for fancybox\r\n self.gallerylist = [];\r\n if (self.options.gallery) {\r\n $('#' + self.options.gallery + ' a').each(function () {\r\n\r\n var imgSrc = '';\r\n if ($(this).data(self.options.attrImageZoomSrc)) {\r\n imgSrc = $(this).data(self.options.attrImageZoomSrc);\r\n }\r\n else if ($(this).data('image')) {\r\n imgSrc = $(this).data('image');\r\n }\r\n //put the current image at the start\r\n if (imgSrc === self.zoomImage) {\r\n self.gallerylist.unshift({\r\n href: '' + imgSrc + '',\r\n title: $(this).find('img').attr('title')\r\n });\r\n }\r\n else {\r\n self.gallerylist.push({\r\n href: '' + imgSrc + '',\r\n title: $(this).find('img').attr('title')\r\n });\r\n }\r\n });\r\n }\r\n //if no gallery - return current image\r\n else {\r\n self.gallerylist.push({\r\n href: '' + self.zoomImage + '',\r\n title: $(this).find('img').attr('title')\r\n });\r\n }\r\n return self.gallerylist;\r\n },\r\n\r\n changeZoomLevel: function (value) {\r\n var self = this;\r\n\r\n //flag a zoom, so can adjust the easing during setPosition\r\n self.scrollingLock = true;\r\n\r\n //round to two decimal places\r\n self.newvalue = parseFloat(value).toFixed(2);\r\n var newvalue = self.newvalue;\r\n\r\n //maxwidth & Maxheight of the image\r\n var maxheightnewvalue = self.largeHeight / ((self.options.zoomWindowHeight / self.nzHeight) * self.nzHeight);\r\n var maxwidthtnewvalue = self.largeWidth / ((self.options.zoomWindowWidth / self.nzWidth) * self.nzWidth);\r\n\r\n //calculate new heightratio\r\n if (self.options.zoomType !== 'inner') {\r\n if (maxheightnewvalue <= newvalue) {\r\n self.heightRatio = (self.largeHeight / maxheightnewvalue) / self.nzHeight;\r\n self.newvalueheight = maxheightnewvalue;\r\n self.fullheight = true;\r\n }\r\n else {\r\n self.heightRatio = (self.largeHeight / newvalue) / self.nzHeight;\r\n self.newvalueheight = newvalue;\r\n self.fullheight = false;\r\n }\r\n\r\n // calculate new width ratio\r\n\r\n if (maxwidthtnewvalue <= newvalue) {\r\n self.widthRatio = (self.largeWidth / maxwidthtnewvalue) / self.nzWidth;\r\n self.newvaluewidth = maxwidthtnewvalue;\r\n self.fullwidth = true;\r\n }\r\n else {\r\n self.widthRatio = (self.largeWidth / newvalue) / self.nzWidth;\r\n self.newvaluewidth = newvalue;\r\n self.fullwidth = false;\r\n }\r\n if (self.options.zoomType === 'lens') {\r\n if (maxheightnewvalue <= newvalue) {\r\n self.fullwidth = true;\r\n self.newvaluewidth = maxheightnewvalue;\r\n } else {\r\n self.widthRatio = (self.largeWidth / newvalue) / self.nzWidth;\r\n self.newvaluewidth = newvalue;\r\n\r\n self.fullwidth = false;\r\n }\r\n }\r\n }\r\n\r\n if (self.options.zoomType === 'inner') {\r\n maxheightnewvalue = parseFloat(self.largeHeight / self.nzHeight).toFixed(2);\r\n maxwidthtnewvalue = parseFloat(self.largeWidth / self.nzWidth).toFixed(2);\r\n if (newvalue > maxheightnewvalue) {\r\n newvalue = maxheightnewvalue;\r\n }\r\n if (newvalue > maxwidthtnewvalue) {\r\n newvalue = maxwidthtnewvalue;\r\n }\r\n\r\n if (maxheightnewvalue <= newvalue) {\r\n self.heightRatio = (self.largeHeight / newvalue) / self.nzHeight;\r\n if (newvalue > maxheightnewvalue) {\r\n self.newvalueheight = maxheightnewvalue;\r\n } else {\r\n self.newvalueheight = newvalue;\r\n }\r\n self.fullheight = true;\r\n }\r\n else {\r\n self.heightRatio = (self.largeHeight / newvalue) / self.nzHeight;\r\n\r\n if (newvalue > maxheightnewvalue) {\r\n\r\n self.newvalueheight = maxheightnewvalue;\r\n } else {\r\n self.newvalueheight = newvalue;\r\n }\r\n self.fullheight = false;\r\n }\r\n\r\n if (maxwidthtnewvalue <= newvalue) {\r\n\r\n self.widthRatio = (self.largeWidth / newvalue) / self.nzWidth;\r\n if (newvalue > maxwidthtnewvalue) {\r\n\r\n self.newvaluewidth = maxwidthtnewvalue;\r\n } else {\r\n self.newvaluewidth = newvalue;\r\n }\r\n\r\n self.fullwidth = true;\r\n }\r\n else {\r\n self.widthRatio = (self.largeWidth / newvalue) / self.nzWidth;\r\n self.newvaluewidth = newvalue;\r\n self.fullwidth = false;\r\n }\r\n } //end inner\r\n var scrcontinue = false;\r\n\r\n if (self.options.zoomType === 'inner') {\r\n if (self.nzWidth >= self.nzHeight) {\r\n if (self.newvaluewidth <= maxwidthtnewvalue) {\r\n scrcontinue = true;\r\n }\r\n else {\r\n scrcontinue = false;\r\n self.fullheight = true;\r\n self.fullwidth = true;\r\n }\r\n }\r\n if (self.nzHeight > self.nzWidth) {\r\n if (self.newvaluewidth <= maxwidthtnewvalue) {\r\n scrcontinue = true;\r\n }\r\n else {\r\n scrcontinue = false;\r\n self.fullheight = true;\r\n self.fullwidth = true;\r\n }\r\n }\r\n }\r\n\r\n if (self.options.zoomType !== 'inner') {\r\n scrcontinue = true;\r\n }\r\n\r\n if (scrcontinue) {\r\n self.zoomLock = 0;\r\n self.changeZoom = true;\r\n\r\n //if lens height is less than image height\r\n if (((self.options.zoomWindowHeight) / self.heightRatio) <= self.nzHeight) {\r\n self.currentZoomLevel = self.newvalueheight;\r\n if (self.options.zoomType !== 'lens' && self.options.zoomType !== 'inner') {\r\n self.changeBgSize = true;\r\n self.zoomLens.css('height', String(self.options.zoomWindowHeight / self.heightRatio) + 'px');\r\n }\r\n if (self.options.zoomType === 'lens' || self.options.zoomType === 'inner') {\r\n self.changeBgSize = true;\r\n }\r\n }\r\n\r\n if ((self.options.zoomWindowWidth / self.widthRatio) <= self.nzWidth) {\r\n if (self.options.zoomType !== 'inner') {\r\n if (self.newvaluewidth > self.newvalueheight) {\r\n self.currentZoomLevel = self.newvaluewidth;\r\n }\r\n }\r\n\r\n if (self.options.zoomType !== 'lens' && self.options.zoomType !== 'inner') {\r\n self.changeBgSize = true;\r\n\r\n self.zoomLens.css('width', String(self.options.zoomWindowWidth / self.widthRatio) + 'px');\r\n }\r\n if (self.options.zoomType === 'lens' || self.options.zoomType === 'inner') {\r\n self.changeBgSize = true;\r\n }\r\n\r\n }\r\n if (self.options.zoomType === 'inner') {\r\n self.changeBgSize = true;\r\n\r\n if (self.nzWidth > self.nzHeight) {\r\n self.currentZoomLevel = self.newvaluewidth;\r\n }\r\n else if (self.nzHeight >= self.nzWidth) {\r\n self.currentZoomLevel = self.newvaluewidth;\r\n }\r\n }\r\n } //under\r\n\r\n //sets the boundry change, called in setWindowPos\r\n self.setPosition(self.currentLoc);\r\n //\r\n },\r\n\r\n closeAll: function () {\r\n var self = this;\r\n if (self.zoomWindow) {\r\n self.zoomWindow.hide();\r\n }\r\n if (self.zoomLens) {\r\n self.zoomLens.hide();\r\n }\r\n if (self.zoomTint) {\r\n self.zoomTint.hide();\r\n }\r\n },\r\n updateOffset: function (self) {\r\n if (self.options.zoomContainerAppendTo != 'body') {\r\n self.nzOffset = self.$elem.offset();\r\n appendedPosition = $(self.options.zoomContainerAppendTo).offset();\r\n self.nzOffset.top = self.$elem.offset().top - appendedPosition.top;\r\n self.nzOffset.left = self.$elem.offset().left - appendedPosition.left;\r\n\r\n } else {\r\n self.nzOffset = self.$elem.offset();\r\n }\r\n },\r\n\r\n changeState: function (value) {\r\n var self = this;\r\n if (value === 'enable') {\r\n self.options.zoomEnabled = true;\r\n }\r\n if (value === 'disable') {\r\n self.options.zoomEnabled = false;\r\n }\r\n },\r\n\r\n responsiveConfig: function (options) {\r\n if (options.respond && options.respond.length > 0) {\r\n return $.extend({}, options, this.configByScreenWidth(options));\r\n }\r\n return options;\r\n },\r\n\r\n configByScreenWidth: function (options) {\r\n var screenWidth = $(window).width();\r\n\r\n var config = $.grep(options.respond, function (item) {\r\n var range = item.range.split('-');\r\n return (screenWidth >= range[0]) && (screenWidth <= range[1]);\r\n });\r\n\r\n if (config.length > 0) {\r\n return config[0];\r\n } else {\r\n return options;\r\n }\r\n }\r\n };\r\n\r\n $.fn.ezPlus = function (options) {\r\n return this.each(function () {\r\n var elevate = Object.create(EZP);\r\n\r\n elevate.init(options, this);\r\n\r\n $.data(this, 'ezPlus', elevate);\r\n\r\n });\r\n };\r\n\r\n $.fn.ezPlus.options = {\r\n attrImageZoomSrc: 'zoom-image', // attribute to plugin use for zoom\r\n borderColour: '#888',\r\n borderSize: 4,\r\n constrainSize: false, //in pixels the dimensions you want to constrain on\r\n constrainType: false, //width or height\r\n containLensZoom: false,\r\n cursor: 'inherit', // user should set to what they want the cursor as, if they have set a click function\r\n debug: false,\r\n easing: false,\r\n easingAmount: 12,\r\n enabled: true,\r\n\r\n gallery: false,\r\n galleryActiveClass: 'zoomGalleryActive',\r\n gallerySelector: false,\r\n galleryItem: 'a',\r\n\r\n imageCrossfade: false,\r\n\r\n lensBorderColour: '#000',\r\n lensBorderSize: 1,\r\n lensColour: 'white', //colour of the lens background\r\n lensFadeIn: false,\r\n lensFadeOut: false,\r\n lensOpacity: 0.4, //opacity of the lens\r\n lensShape: 'square', //can be 'round'\r\n lensSize: 200,\r\n lenszoom: false,\r\n\r\n loadingIcon: false, //http://www.example.com/spinner.gif\r\n\r\n // This change will allow to decide if you want to decrease\r\n // zoom of one of the dimensions once the other reached it's top value,\r\n // or keep the aspect ratio, default behaviour still being as always,\r\n // allow to continue zooming out, so it keeps retrocompatibility.\r\n mantainZoomAspectRatio: false,\r\n maxZoomLevel: false,\r\n minZoomLevel: 1.01,\r\n\r\n onComplete: $.noop,\r\n onDestroy: $.noop,\r\n onImageClick: $.noop,\r\n onImageSwap: $.noop,\r\n onImageSwapComplete: $.noop,\r\n onShow: $.noop,\r\n onZoomedImageLoaded: $.noop,\r\n\r\n preloading: 1, //by default, load all the images, if 0, then only load images after activated (PLACEHOLDER FOR NEXT VERSION)\r\n respond: [],\r\n responsive: true,\r\n scrollZoom: false, //allow zoom on mousewheel, true to activate\r\n scrollZoomIncrement: 0.1, //steps of the scrollzoom\r\n showLens: true,\r\n tint: false, //enable the tinting\r\n tintColour: '#333', //default tint color, can be anything, red, #ccc, rgb(0,0,0)\r\n tintOpacity: 0.4, //opacity of the tint\r\n touchEnabled: true,\r\n\r\n zoomActivation: 'hover', // Can also be click (PLACEHOLDER FOR NEXT VERSION)\r\n zoomContainerAppendTo: 'body', //zoom container parent selector\r\n zoomId: -1, // identifier for the zoom container\r\n zoomLevel: 1, //default zoom level of image\r\n zoomTintFadeIn: false,\r\n zoomTintFadeOut: false,\r\n zoomType: 'window', //window is default, also 'lens' available -\r\n zoomWindowAlwaysShow: false,\r\n zoomWindowBgColour: '#fff',\r\n zoomWindowFadeIn: false,\r\n zoomWindowFadeOut: false,\r\n zoomWindowHeight: 400,\r\n zoomWindowOffsetX: 0,\r\n zoomWindowOffsetY: 0,\r\n zoomWindowPosition: 1, //Possible values: 1-16, but we can also position with a selector string.\r\n zoomWindowWidth: 400,\r\n zoomEnabled: true, //false disables zoomwindow from showing\r\n zIndex: 999\r\n };\r\n\r\n})(jQuery, window, document);\r\n","/*\n\n PinchZoom.js\n Copyright (c) Manuel Stofer 2013 - today\n\n Author: Manuel Stofer (mst@rtp.ch)\n Version: 2.3.4\n\n Permission is hereby granted, free of charge, to any person obtaining a copy\n of this software and associated documentation files (the \"Software\"), to deal\n in the Software without restriction, including without limitation the rights\n to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n copies of the Software, and to permit persons to whom the Software is\n furnished to do so, subject to the following conditions:\n\n The above copyright notice and this permission notice shall be included in\n all copies or substantial portions of the Software.\n\n THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n THE SOFTWARE.\n\n*/\n\n// polyfills\nif (typeof Object.assign != 'function') {\n // Must be writable: true, enumerable: false, configurable: true\n Object.defineProperty(Object, \"assign\", {\n value: function assign(target, varArgs) { // .length of function is 2\n if (target == null) { // TypeError if undefined or null\n throw new TypeError('Cannot convert undefined or null to object');\n }\n\n var to = Object(target);\n\n for (var index = 1; index < arguments.length; index++) {\n var nextSource = arguments[index];\n\n if (nextSource != null) { // Skip over if undefined or null\n for (var nextKey in nextSource) {\n // Avoid bugs when hasOwnProperty is shadowed\n if (Object.prototype.hasOwnProperty.call(nextSource, nextKey)) {\n to[nextKey] = nextSource[nextKey];\n }\n }\n }\n }\n return to;\n },\n writable: true,\n configurable: true\n });\n}\n\nif (typeof Array.from != 'function') {\n Array.from = function (object) {\n return [].slice.call(object);\n };\n}\n\n// utils\nvar buildElement = function(str) {\n // empty string as title argument required by IE and Edge\n var tmp = document.implementation.createHTMLDocument('');\n tmp.body.innerHTML = str;\n return Array.from(tmp.body.children)[0];\n};\n\nvar triggerEvent = function(el, name) {\n var event = document.createEvent('HTMLEvents');\n event.initEvent(name, true, false);\n el.dispatchEvent(event);\n};\n\nvar definePinchZoom = function () {\n\n /**\n * Pinch zoom\n * @param el\n * @param options\n * @constructor\n */\n var PinchZoom = function (el, options) {\n this.el = el;\n this.zoomFactor = 1;\n this.lastScale = 1;\n this.offset = {\n x: 0,\n y: 0\n };\n this.initialOffset = {\n x: 0,\n y: 0,\n };\n this.options = Object.assign({}, this.defaults, options);\n this.setupMarkup();\n this.bindEvents();\n this.update();\n\n // The image may already be loaded when PinchZoom is initialized,\n // and then the load event (which trigger update) will never fire.\n if (this.isImageLoaded(this.el)) {\n this.updateAspectRatio();\n this.setupOffsets();\n }\n\n this.enable();\n\n },\n sum = function (a, b) {\n return a + b;\n },\n isCloseTo = function (value, expected) {\n return value > expected - 0.01 && value < expected + 0.01;\n };\n\n PinchZoom.prototype = {\n\n defaults: {\n tapZoomFactor: 2,\n zoomOutFactor: 1.3,\n animationDuration: 300,\n maxZoom: 4,\n minZoom: 0.5,\n draggableUnzoomed: true,\n lockDragAxis: false,\n setOffsetsOnce: false,\n use2d: true,\n zoomStartEventName: 'pz_zoomstart',\n zoomUpdateEventName: 'pz_zoomupdate',\n zoomEndEventName: 'pz_zoomend',\n dragStartEventName: 'pz_dragstart',\n dragUpdateEventName: 'pz_dragupdate',\n dragEndEventName: 'pz_dragend',\n doubleTapEventName: 'pz_doubletap',\n verticalPadding: 0,\n horizontalPadding: 0,\n onZoomStart: null,\n onZoomEnd: null,\n onZoomUpdate: null,\n onDragStart: null,\n onDragEnd: null,\n onDragUpdate: null,\n onDoubleTap: null\n },\n\n /**\n * Event handler for 'dragstart'\n * @param event\n */\n handleDragStart: function (event) {\n triggerEvent(this.el, this.options.dragStartEventName);\n if(typeof this.options.onDragStart == \"function\"){\n this.options.onDragStart(this, event)\n }\n this.stopAnimation();\n this.lastDragPosition = false;\n this.hasInteraction = true;\n this.handleDrag(event);\n },\n\n /**\n * Event handler for 'drag'\n * @param event\n */\n handleDrag: function (event) {\n var touch = this.getTouches(event)[0];\n this.drag(touch, this.lastDragPosition);\n this.offset = this.sanitizeOffset(this.offset);\n this.lastDragPosition = touch;\n },\n\n handleDragEnd: function () {\n triggerEvent(this.el, this.options.dragEndEventName);\n if(typeof this.options.onDragEnd == \"function\"){\n this.options.onDragEnd(this, event)\n }\n this.end();\n },\n\n /**\n * Event handler for 'zoomstart'\n * @param event\n */\n handleZoomStart: function (event) {\n triggerEvent(this.el, this.options.zoomStartEventName);\n if(typeof this.options.onZoomStart == \"function\"){\n this.options.onZoomStart(this, event)\n }\n this.stopAnimation();\n this.lastScale = 1;\n this.nthZoom = 0;\n this.lastZoomCenter = false;\n this.hasInteraction = true;\n },\n\n /**\n * Event handler for 'zoom'\n * @param event\n */\n handleZoom: function (event, newScale) {\n // a relative scale factor is used\n var touchCenter = this.getTouchCenter(this.getTouches(event)),\n scale = newScale / this.lastScale;\n this.lastScale = newScale;\n\n // the first touch events are thrown away since they are not precise\n this.nthZoom += 1;\n if (this.nthZoom > 3) {\n\n this.scale(scale, touchCenter);\n this.drag(touchCenter, this.lastZoomCenter);\n }\n this.lastZoomCenter = touchCenter;\n },\n\n handleZoomEnd: function () {\n triggerEvent(this.el, this.options.zoomEndEventName);\n if(typeof this.options.onZoomEnd == \"function\"){\n this.options.onZoomEnd(this, event)\n }\n this.end();\n },\n\n /**\n * Event handler for 'doubletap'\n * @param event\n */\n handleDoubleTap: function (event) {\n var center = this.getTouches(event)[0],\n zoomFactor = this.zoomFactor > 1 ? 1 : this.options.tapZoomFactor,\n startZoomFactor = this.zoomFactor,\n updateProgress = (function (progress) {\n this.scaleTo(startZoomFactor + progress * (zoomFactor - startZoomFactor), center);\n }).bind(this);\n\n if (this.hasInteraction) {\n return;\n }\n\n this.isDoubleTap = true;\n\n if (startZoomFactor > zoomFactor) {\n center = this.getCurrentZoomCenter();\n }\n\n this.animate(this.options.animationDuration, updateProgress, this.swing);\n triggerEvent(this.el, this.options.doubleTapEventName);\n if(typeof this.options.onDoubleTap == \"function\"){\n this.options.onDoubleTap(this, event)\n }\n },\n\n /**\n * Compute the initial offset\n *\n * the element should be centered in the container upon initialization\n */\n computeInitialOffset: function () {\n this.initialOffset = {\n x: -Math.abs(this.el.offsetWidth * this.getInitialZoomFactor() - this.container.offsetWidth) / 2,\n y: -Math.abs(this.el.offsetHeight * this.getInitialZoomFactor() - this.container.offsetHeight) / 2,\n };\n },\n\n /**\n * Reset current image offset to that of the initial offset\n */\n resetOffset: function() {\n this.offset.x = this.initialOffset.x;\n this.offset.y = this.initialOffset.y;\n },\n\n /**\n * Determine if image is loaded\n */\n isImageLoaded: function (el) {\n if (el.nodeName === 'IMG') {\n return el.complete && el.naturalHeight !== 0;\n } else {\n return Array.from(el.querySelectorAll('img')).every(this.isImageLoaded);\n }\n },\n\n setupOffsets: function() {\n if (this.options.setOffsetsOnce && this._isOffsetsSet) {\n return;\n }\n\n this._isOffsetsSet = true;\n\n this.computeInitialOffset();\n this.resetOffset();\n },\n\n /**\n * Max / min values for the offset\n * @param offset\n * @return {Object} the sanitized offset\n */\n sanitizeOffset: function (offset) {\n var elWidth = this.el.offsetWidth * this.getInitialZoomFactor() * this.zoomFactor;\n var elHeight = this.el.offsetHeight * this.getInitialZoomFactor() * this.zoomFactor;\n var maxX = elWidth - this.getContainerX() + this.options.horizontalPadding,\n maxY = elHeight - this.getContainerY() + this.options.verticalPadding,\n maxOffsetX = Math.max(maxX, 0),\n maxOffsetY = Math.max(maxY, 0),\n minOffsetX = Math.min(maxX, 0) - this.options.horizontalPadding,\n minOffsetY = Math.min(maxY, 0) - this.options.verticalPadding;\n\n return {\n x: Math.min(Math.max(offset.x, minOffsetX), maxOffsetX),\n y: Math.min(Math.max(offset.y, minOffsetY), maxOffsetY)\n };\n },\n\n /**\n * Scale to a specific zoom factor (not relative)\n * @param zoomFactor\n * @param center\n */\n scaleTo: function (zoomFactor, center) {\n this.scale(zoomFactor / this.zoomFactor, center);\n },\n\n /**\n * Scales the element from specified center\n * @param scale\n * @param center\n */\n scale: function (scale, center) {\n scale = this.scaleZoomFactor(scale);\n this.addOffset({\n x: (scale - 1) * (center.x + this.offset.x),\n y: (scale - 1) * (center.y + this.offset.y)\n });\n triggerEvent(this.el, this.options.zoomUpdateEventName);\n if(typeof this.options.onZoomUpdate == \"function\"){\n this.options.onZoomUpdate(this, event)\n }\n },\n\n /**\n * Scales the zoom factor relative to current state\n * @param scale\n * @return the actual scale (can differ because of max min zoom factor)\n */\n scaleZoomFactor: function (scale) {\n var originalZoomFactor = this.zoomFactor;\n this.zoomFactor *= scale;\n this.zoomFactor = Math.min(this.options.maxZoom, Math.max(this.zoomFactor, this.options.minZoom));\n return this.zoomFactor / originalZoomFactor;\n },\n\n /**\n * Determine if the image is in a draggable state\n *\n * When the image can be dragged, the drag event is acted upon and cancelled.\n * When not draggable, the drag event bubbles through this component.\n *\n * @return {Boolean}\n */\n canDrag: function () {\n return this.options.draggableUnzoomed || !isCloseTo(this.zoomFactor, 1);\n },\n\n /**\n * Drags the element\n * @param center\n * @param lastCenter\n */\n drag: function (center, lastCenter) {\n if (lastCenter) {\n if(this.options.lockDragAxis) {\n // lock scroll to position that was changed the most\n if(Math.abs(center.x - lastCenter.x) > Math.abs(center.y - lastCenter.y)) {\n this.addOffset({\n x: -(center.x - lastCenter.x),\n y: 0\n });\n }\n else {\n this.addOffset({\n y: -(center.y - lastCenter.y),\n x: 0\n });\n }\n }\n else {\n this.addOffset({\n y: -(center.y - lastCenter.y),\n x: -(center.x - lastCenter.x)\n });\n }\n triggerEvent(this.el, this.options.dragUpdateEventName);\n if(typeof this.options.onDragUpdate == \"function\"){\n this.options.onDragUpdate(this, event)\n }\n }\n },\n\n /**\n * Calculates the touch center of multiple touches\n * @param touches\n * @return {Object}\n */\n getTouchCenter: function (touches) {\n return this.getVectorAvg(touches);\n },\n\n /**\n * Calculates the average of multiple vectors (x, y values)\n */\n getVectorAvg: function (vectors) {\n return {\n x: vectors.map(function (v) { return v.x; }).reduce(sum) / vectors.length,\n y: vectors.map(function (v) { return v.y; }).reduce(sum) / vectors.length\n };\n },\n\n /**\n * Adds an offset\n * @param offset the offset to add\n * @return return true when the offset change was accepted\n */\n addOffset: function (offset) {\n this.offset = {\n x: this.offset.x + offset.x,\n y: this.offset.y + offset.y\n };\n },\n\n sanitize: function () {\n if (this.zoomFactor < this.options.zoomOutFactor) {\n this.zoomOutAnimation();\n } else if (this.isInsaneOffset(this.offset)) {\n this.sanitizeOffsetAnimation();\n }\n },\n\n /**\n * Checks if the offset is ok with the current zoom factor\n * @param offset\n * @return {Boolean}\n */\n isInsaneOffset: function (offset) {\n var sanitizedOffset = this.sanitizeOffset(offset);\n return sanitizedOffset.x !== offset.x ||\n sanitizedOffset.y !== offset.y;\n },\n\n /**\n * Creates an animation moving to a sane offset\n */\n sanitizeOffsetAnimation: function () {\n var targetOffset = this.sanitizeOffset(this.offset),\n startOffset = {\n x: this.offset.x,\n y: this.offset.y\n },\n updateProgress = (function (progress) {\n this.offset.x = startOffset.x + progress * (targetOffset.x - startOffset.x);\n this.offset.y = startOffset.y + progress * (targetOffset.y - startOffset.y);\n this.update();\n }).bind(this);\n\n this.animate(\n this.options.animationDuration,\n updateProgress,\n this.swing\n );\n },\n\n /**\n * Zooms back to the original position,\n * (no offset and zoom factor 1)\n */\n zoomOutAnimation: function () {\n if (this.zoomFactor === 1) {\n return;\n }\n\n var startZoomFactor = this.zoomFactor,\n zoomFactor = 1,\n center = this.getCurrentZoomCenter(),\n updateProgress = (function (progress) {\n this.scaleTo(startZoomFactor + progress * (zoomFactor - startZoomFactor), center);\n }).bind(this);\n\n this.animate(\n this.options.animationDuration,\n updateProgress,\n this.swing\n );\n },\n\n /**\n * Updates the container aspect ratio\n *\n * Any previous container height must be cleared before re-measuring the\n * parent height, since it depends implicitly on the height of any of its children\n */\n updateAspectRatio: function () {\n this.unsetContainerY();\n this.setContainerY(this.container.parentElement.offsetHeight);\n },\n\n /**\n * Calculates the initial zoom factor (for the element to fit into the container)\n * @return {number} the initial zoom factor\n */\n getInitialZoomFactor: function () {\n var xZoomFactor = this.container.offsetWidth / this.el.offsetWidth;\n var yZoomFactor = this.container.offsetHeight / this.el.offsetHeight;\n\n return Math.min(xZoomFactor, yZoomFactor);\n },\n\n /**\n * Calculates the aspect ratio of the element\n * @return the aspect ratio\n */\n getAspectRatio: function () {\n return this.el.offsetWidth / this.el.offsetHeight;\n },\n\n /**\n * Calculates the virtual zoom center for the current offset and zoom factor\n * (used for reverse zoom)\n * @return {Object} the current zoom center\n */\n getCurrentZoomCenter: function () {\n var offsetLeft = this.offset.x - this.initialOffset.x;\n var centerX = -1 * this.offset.x - offsetLeft / (1 / this.zoomFactor - 1);\n\n var offsetTop = this.offset.y - this.initialOffset.y;\n var centerY = -1 * this.offset.y - offsetTop / (1 / this.zoomFactor - 1);\n\n return {\n x: centerX,\n y: centerY\n };\n },\n\n /**\n * Returns the touches of an event relative to the container offset\n * @param event\n * @return array touches\n */\n getTouches: function (event) {\n var rect = this.container.getBoundingClientRect();\n var scrollTop = document.documentElement.scrollTop || document.body.scrollTop;\n var scrollLeft = document.documentElement.scrollLeft || document.body.scrollLeft;\n var posTop = rect.top + scrollTop;\n var posLeft = rect.left + scrollLeft;\n\n return Array.prototype.slice.call(event.touches).map(function (touch) {\n return {\n x: touch.pageX - posLeft,\n y: touch.pageY - posTop,\n };\n });\n },\n\n /**\n * Animation loop\n * does not support simultaneous animations\n * @param duration\n * @param framefn\n * @param timefn\n * @param callback\n */\n animate: function (duration, framefn, timefn, callback) {\n var startTime = new Date().getTime(),\n renderFrame = (function () {\n if (!this.inAnimation) { return; }\n var frameTime = new Date().getTime() - startTime,\n progress = frameTime / duration;\n if (frameTime >= duration) {\n framefn(1);\n if (callback) {\n callback();\n }\n this.update();\n this.stopAnimation();\n this.update();\n } else {\n if (timefn) {\n progress = timefn(progress);\n }\n framefn(progress);\n this.update();\n requestAnimationFrame(renderFrame);\n }\n }).bind(this);\n this.inAnimation = true;\n requestAnimationFrame(renderFrame);\n },\n\n /**\n * Stops the animation\n */\n stopAnimation: function () {\n this.inAnimation = false;\n },\n\n /**\n * Swing timing function for animations\n * @param p\n * @return {Number}\n */\n swing: function (p) {\n return -Math.cos(p * Math.PI) / 2 + 0.5;\n },\n\n getContainerX: function () {\n return this.container.offsetWidth;\n },\n\n getContainerY: function () {\n return this.container.offsetHeight;\n },\n\n setContainerY: function (y) {\n return this.container.style.height = y + 'px';\n },\n\n unsetContainerY: function () {\n this.container.style.height = null;\n },\n\n /**\n * Creates the expected html structure\n */\n setupMarkup: function () {\n this.container = buildElement('
    ');\n this.el.parentNode.insertBefore(this.container, this.el);\n this.container.appendChild(this.el);\n\n this.container.style.overflow = 'hidden';\n this.container.style.position = 'relative';\n\n this.el.style.webkitTransformOrigin = '0% 0%';\n this.el.style.mozTransformOrigin = '0% 0%';\n this.el.style.msTransformOrigin = '0% 0%';\n this.el.style.oTransformOrigin = '0% 0%';\n this.el.style.transformOrigin = '0% 0%';\n\n this.el.style.position = 'absolute';\n },\n\n end: function () {\n this.hasInteraction = false;\n this.sanitize();\n this.update();\n },\n\n /**\n * Binds all required event listeners\n */\n bindEvents: function () {\n var self = this;\n detectGestures(this.container, this);\n\n window.addEventListener('resize', this.update.bind(this));\n Array.from(this.el.querySelectorAll('img')).forEach(function(imgEl) {\n imgEl.addEventListener('load', self.update.bind(self));\n });\n\n if (this.el.nodeName === 'IMG') {\n this.el.addEventListener('load', this.update.bind(this));\n }\n },\n\n /**\n * Updates the css values according to the current zoom factor and offset\n */\n update: function (event) {\n if (this.updatePlaned) {\n return;\n }\n this.updatePlaned = true;\n\n window.setTimeout((function () {\n this.updatePlaned = false;\n\n if (event && event.type === 'resize') {\n this.updateAspectRatio();\n this.setupOffsets();\n }\n\n if (event && event.type === 'load') {\n this.updateAspectRatio();\n this.setupOffsets();\n }\n\n var zoomFactor = this.getInitialZoomFactor() * this.zoomFactor,\n offsetX = -this.offset.x / zoomFactor,\n offsetY = -this.offset.y / zoomFactor,\n transform3d = 'scale3d(' + zoomFactor + ', ' + zoomFactor + ',1) ' +\n 'translate3d(' + offsetX + 'px,' + offsetY + 'px,0px)',\n transform2d = 'scale(' + zoomFactor + ', ' + zoomFactor + ') ' +\n 'translate(' + offsetX + 'px,' + offsetY + 'px)',\n removeClone = (function () {\n if (this.clone) {\n this.clone.parentNode.removeChild(this.clone);\n delete this.clone;\n }\n }).bind(this);\n\n // Scale 3d and translate3d are faster (at least on ios)\n // but they also reduce the quality.\n // PinchZoom uses the 3d transformations during interactions\n // after interactions it falls back to 2d transformations\n if (!this.options.use2d || this.hasInteraction || this.inAnimation) {\n this.is3d = true;\n removeClone();\n\n this.el.style.webkitTransform = transform3d;\n this.el.style.mozTransform = transform2d;\n this.el.style.msTransform = transform2d;\n this.el.style.oTransform = transform2d;\n this.el.style.transform = transform3d;\n } else {\n // When changing from 3d to 2d transform webkit has some glitches.\n // To avoid this, a copy of the 3d transformed element is displayed in the\n // foreground while the element is converted from 3d to 2d transform\n if (this.is3d) {\n this.clone = this.el.cloneNode(true);\n this.clone.style.pointerEvents = 'none';\n this.container.appendChild(this.clone);\n window.setTimeout(removeClone, 200);\n }\n\n this.el.style.webkitTransform = transform2d;\n this.el.style.mozTransform = transform2d;\n this.el.style.msTransform = transform2d;\n this.el.style.oTransform = transform2d;\n this.el.style.transform = transform2d;\n\n this.is3d = false;\n }\n }).bind(this), 0);\n },\n\n /**\n * Enables event handling for gestures\n */\n enable: function() {\n this.enabled = true;\n },\n\n /**\n * Disables event handling for gestures\n */\n disable: function() {\n this.enabled = false;\n }\n };\n\n var detectGestures = function (el, target) {\n var interaction = null,\n fingers = 0,\n lastTouchStart = null,\n startTouches = null,\n\n setInteraction = function (newInteraction, event) {\n if (interaction !== newInteraction) {\n\n if (interaction && !newInteraction) {\n switch (interaction) {\n case \"zoom\":\n target.handleZoomEnd(event);\n break;\n case 'drag':\n target.handleDragEnd(event);\n break;\n }\n }\n\n switch (newInteraction) {\n case 'zoom':\n target.handleZoomStart(event);\n break;\n case 'drag':\n target.handleDragStart(event);\n break;\n }\n }\n interaction = newInteraction;\n },\n\n updateInteraction = function (event) {\n if (fingers === 2) {\n setInteraction('zoom');\n } else if (fingers === 1 && target.canDrag()) {\n setInteraction('drag', event);\n } else {\n setInteraction(null, event);\n }\n },\n\n targetTouches = function (touches) {\n return Array.from(touches).map(function (touch) {\n return {\n x: touch.pageX,\n y: touch.pageY\n };\n });\n },\n\n getDistance = function (a, b) {\n var x, y;\n x = a.x - b.x;\n y = a.y - b.y;\n return Math.sqrt(x * x + y * y);\n },\n\n calculateScale = function (startTouches, endTouches) {\n var startDistance = getDistance(startTouches[0], startTouches[1]),\n endDistance = getDistance(endTouches[0], endTouches[1]);\n return endDistance / startDistance;\n },\n\n cancelEvent = function (event) {\n event.stopPropagation();\n event.preventDefault();\n },\n\n detectDoubleTap = function (event) {\n var time = (new Date()).getTime();\n\n if (fingers > 1) {\n lastTouchStart = null;\n }\n\n if (time - lastTouchStart < 300) {\n cancelEvent(event);\n\n target.handleDoubleTap(event);\n switch (interaction) {\n case \"zoom\":\n target.handleZoomEnd(event);\n break;\n case 'drag':\n target.handleDragEnd(event);\n break;\n }\n } else {\n target.isDoubleTap = false;\n }\n\n if (fingers === 1) {\n lastTouchStart = time;\n }\n },\n firstMove = true;\n\n el.addEventListener('touchstart', function (event) {\n if(target.enabled) {\n firstMove = true;\n fingers = event.touches.length;\n detectDoubleTap(event);\n }\n });\n\n el.addEventListener('touchmove', function (event) {\n if(target.enabled && !target.isDoubleTap) {\n if (firstMove) {\n updateInteraction(event);\n if (interaction) {\n cancelEvent(event);\n }\n startTouches = targetTouches(event.touches);\n } else {\n switch (interaction) {\n case 'zoom':\n if (startTouches.length == 2 && event.touches.length == 2) {\n target.handleZoom(event, calculateScale(startTouches, targetTouches(event.touches)));\n }\n break;\n case 'drag':\n target.handleDrag(event);\n break;\n }\n if (interaction) {\n cancelEvent(event);\n target.update();\n }\n }\n\n firstMove = false;\n }\n });\n\n el.addEventListener('touchend', function (event) {\n if(target.enabled) {\n fingers = event.touches.length;\n updateInteraction(event);\n }\n });\n };\n\n return PinchZoom;\n};\n\nvar PinchZoom = definePinchZoom();\n\nexport default PinchZoom;\n","module.exports = {\n pdpGiftCard: function(){\n $('body').on('updateAddToCartFormData', function (e, form) {\n e.preventDefault();\n // gift card form data\n if($('button.add-to-cart, button.add-to-cart-global').data('isgiftcard')){\n var dataObj = {};\n dataObj.gcAmount = $('.giftCardAmount').val();\n dataObj.gcTo = $('.giftCardTo').val();\n dataObj.gcFrom = $('.giftCardFrom').val();\n dataObj.gcEmail = $('.giftCardFriendsEmail').val();\n dataObj.gcConfirmEmail = $('.giftCardConfirmFriendsEmail').val();\n dataObj.gcMessage = $('.giftCardMessage').val();\n dataObj.gcSelectedImageIndex = $('.giftCardSelectedImage').val();\n dataObj.gcCopyMe = $('.giftCardCopyMe').prop('checked');;\n form.data = JSON.stringify(dataObj);\n }\n });\n $('body').on('cart:beforeUpdate', function (e, form) {\n e.preventDefault();\n // gift card form data\n if($('button.update-cart-product-global').data('isgiftcard')){\n var dataObj = {};\n dataObj.gcAmount = $('.giftCardAmount').val();\n dataObj.gcTo = $('.giftCardTo').val();\n dataObj.gcFrom = $('.giftCardFrom').val();\n dataObj.gcEmail = $('.giftCardFriendsEmail').val();\n dataObj.gcConfirmEmail = $('.giftCardConfirmFriendsEmail').val();\n dataObj.gcMessage = $('.giftCardMessage').val();\n dataObj.gcSelectedImageIndex = $('.giftCardSelectedImage').val();\n dataObj.gcCopyMe = $('.giftCardCopyMe').prop('checked');\n if (typeof form !== 'undefined') {\n form.data = JSON.stringify(dataObj);\n }\n }\n });\n },\n pdpGiftCardImageSelect: function(){\n $('body').on('click', '.gift-card-variation-button', function (e){\n // set value\n var $selectedImage = $(this);\n var index = $selectedImage.data('index');\n $('.giftCardSelectedImage').val(index);\n\n // update selected button styles\n var $selectedSpan = $(this).find('span');\n $('.gift-card-variation-button').find('span').removeClass('selected');\n $selectedSpan.addClass('selected');\n\n // display selected image\n $('.carousel').carousel(index);\n });\n },\n pdpGiftCardCheckBalance: function(){\n $('body').on('giftCard:checkBalance', function (e, formObj) {\n e.preventDefault();\n var form = $(formObj);\n var gcNumber = form.find('.giftCardNumber').val();\n var giftCardBalanceUrl = form.find('.check-balance-button').data('url');\n var data = form.serialize() + '&gcNumber=' + gcNumber;\n\n if(gcNumber && gcNumber.trim().length) {\n if (giftCardBalanceUrl) {\n $('.responseContainer').text('');\n $.ajax({\n url: giftCardBalanceUrl,\n method: 'POST',\n data: data,\n success: function (data) {\n // update output container\n form.find('.responseContainer').text(data.message);\n $.spinner().stop();\n grecaptcha.reset();\n },\n error: function (error) {\n console.log(error)\n form.find('.responseContainer').text(data.message);\n $.spinner().stop();\n grecaptcha.reset();\n }\n });\n }\n } else {\n form.find('.responseContainer').text(\"Please enter a gift card number\");\n grecaptcha.reset();\n }\n });\n }\n}","'use strict';\n\nvar storeLocator = require('ashleystewart/storeLocator/storeLocator');\n/**\n * Restores Quantity Selector to its original state.\n * @param {HTMLElement} $quantitySelect - The Quantity Select Element\n */\nfunction restoreQuantityOptions($quantitySelect) {\n var originalHTML = $quantitySelect.data('originalHTML');\n if (originalHTML) {\n $quantitySelect.html(originalHTML);\n }\n}\n\n/**\n * Sets the data attribute of Quantity Selector to save its original state.\n * @param {HTMLElement} $quantitySelect - The Quantity Select Element\n */\nfunction setOriginalQuantitySelect($quantitySelect) {\n if (!$quantitySelect.data('originalHTML')) {\n $quantitySelect.data('originalHTML', $quantitySelect.html());\n } // If it's already there, don't re-set it\n}\n\n/**\n * Updates the Quantity Selector based on the In Store Quantity.\n * @param {string} quantitySelector - Quantity Selector\n * @param {string} quantityOptionSelector - Quantity Option Selector\n * @param {number} productAtsValue - Inventory in the selected store\n */\nfunction updateQOptions(quantitySelector, quantityOptionSelector, productAtsValue) {\n var selectedQuantity = $(quantitySelector).val();\n restoreQuantityOptions($(quantitySelector));\n for (var i = $(quantityOptionSelector).length - 1; i >= productAtsValue; i--) {\n $(quantityOptionSelector).eq(i).remove();\n }\n $(quantitySelector + ' option[value=\"' + selectedQuantity + '\"]').attr('selected', 'selected');\n}\n\n/**\n * Generates the modal window on the first call.\n */\nfunction getModalHtmlElement() {\n if ($('#inStoreInventoryModal').length !== 0) {\n $('#inStoreInventoryModal').remove();\n }\n var htmlString = ''\n + '
    '\n + '
    '\n + ''\n + '
    '\n + '
    '\n + '
    Find a pick up location
    '\n + '
    Please enter a location to check availability
    '\n + ' '\n + '
    '\n + '
    '\n + '
    '\n + '
    '\n + '
    ';\n $('body').append(htmlString);\n $('#inStoreInventoryModal').modal('show');\n}\n\n/**\n * Replaces the content in the modal window with find stores components and\n * the result store list.\n * @param {string} pid - The product ID to search for\n * @param {number} quantity - Number of products to search inventory for\n * @param {number} selectedPostalCode - The postal code to search for inventory\n * @param {number} selectedRadius - The radius to search for inventory\n */\nfunction fillModalElement(pid, quantity, selectedPostalCode, selectedRadius, containerPID) {\n var requestData = {\n products: pid + ':' + quantity\n };\n\n if (selectedRadius) {\n requestData.radius = selectedRadius;\n }\n\n if (selectedPostalCode) {\n requestData.postalCode = selectedPostalCode;\n }\n\n $('#inStoreInventoryModal').spinner().start();\n $.ajax({\n url: $('.btn-get-in-store-inventory').data('action-url'),\n data: requestData,\n method: 'GET',\n success: function (response) {\n $('#inStoreInventoryModal .modal-body').empty();\n $('#inStoreInventoryModal .modal-body').html(response.storesModel.storesResultsHtml);\n storeLocator.search();\n storeLocator.changeRadius();\n storeLocator.selectStore();\n storeLocator.updateSelectStoreButton();\n storeLocator.setPreferredStoreButtonInModal();\n\n $('#inStoreInventoryModal .modal-body .btn-storelocator-search').attr('data-search-pid', pid);\n if (containerPID) {\n $('#inStoreInventoryModal .modal-body .select-store').attr('data-container-pid', containerPID);\n }\n\n if (selectedRadius) {\n $('#inStoreInventoryModal #radius').val(selectedRadius);\n }\n\n if (selectedPostalCode) {\n $('#inStoreInventoryModal #store-postal-code').val(selectedPostalCode);\n }\n\n if (!$('.results').data('has-results')) {\n $('#inStoreInventoryModal .store-locator-no-results').show();\n }\n\n $('#inStoreInventoryModal').modal('show');\n $('#inStoreInventoryModal').spinner().stop();\n },\n error: function () {\n $('#inStoreInventoryModal').spinner().stop();\n }\n });\n}\n\n/**\n * Remove the selected store.\n * @param {HTMLElement} $container - the target html element\n */\nfunction deselectStore($container) {\n var storeElement = $($container).find('.selected-store-with-inventory');\n $(storeElement).find('.card-body').empty();\n $(storeElement).addClass('display-none');\n $($container).find('.btn-get-in-store-inventory').show();\n $($container).find('.quantity-select').removeData('originalHTML');\n}\n\n/**\n * Update quantity options. Only display quantity options that are available for the store.\n * @param {sring} searchPID - The product ID of the selected product.\n * @param {number} storeId - The store ID selected for in store pickup.\n */\nfunction updateQuantityOptions(searchPID, storeId) {\n var selectorPrefix = '.product-detail[data-pid=\"' + searchPID + '\"]';\n var productIdSelector = selectorPrefix + ' .product-id';\n var quantitySelector = selectorPrefix + ' .quantity-select';\n var quantityOptionSelector = quantitySelector + ' option';\n\n setOriginalQuantitySelect($(quantitySelector));\n\n var requestData = {\n pid: $(productIdSelector).first().text(),\n quantitySelected: $(quantitySelector).val(),\n storeId: storeId\n };\n\n $.ajax({\n url: $('.btn-get-in-store-inventory').data('ats-action-url'),\n data: requestData,\n method: 'GET',\n success: function (response) {\n // Update Quantity dropdown, Remove quantity greater than inventory\n var productAtsValue = response.atsValue;\n var availabilityValue = '';\n\n var $productContainer = $('.product-detail[data-pid=\"' + searchPID + '\"]');\n\n if (!('availableForShipToHome' in response.product)) {\n response.product.availableForShipToHome = $('.ship-to-home-availability-container', $productContainer).attr('data-availability') === 'available' ? true : false;\n }\n\n $($productContainer).trigger('product:updateAvailability', {\n product: response.product,\n $productContainer: $productContainer,\n message: availabilityValue,\n resources: response.resources,\n shipToStore: true\n });\n\n $('button.add-to-cart, button.add-to-cart-global, button.update-cart-product-global').trigger('product:updateAddToCart', {\n product: response.product, $productContainer: $productContainer\n });\n\n updateQOptions(quantitySelector, quantityOptionSelector, productAtsValue);\n }\n });\n}\n\nmodule.exports = {\n init: function () {\n storeLocator.initGeocoder();\n },\n updateSelectStore: function () {\n $('body').on('product:updateAddToCart', function (e, response) {\n $('.btn-get-in-store-inventory', response.$productContainer).attr('disabled',\n (!response.product.readyToOrder || !response.product.available ||\n !response.product.availableForInStorePickup));\n });\n },\n removeSelectedStoreOnAttributeChange: function () {\n $('body').on('product:afterAttributeSelect', function (e, response) {\n if (!response.data.product.available || !response.data.product.availableForInStorePickup || !response.data.product.readyToOrder || !response.data.storeAvailability) {\n response.container.attr('data-pid', response.data.product.id);\n deselectStore(response.container);\n }\n });\n },\n updateAddToCartFormData: function () {\n $('body').on('updateAddToCartFormData', function (e, form) {\n if (form.pidsObj) {\n var pidsObj = JSON.parse(form.pidsObj);\n pidsObj.forEach(function (product) {\n var $productContainer = $('.product-detail[data-pid=\"' + product.pid + '\"]');\n var $storeElement = $('.selected-store', $productContainer);\n var isStoreSelected = $('.shipToStoreRadio', $productContainer).is(':checked');\n if ($storeElement.length && isStoreSelected) {\n product.storeId = $storeElement.attr('data-store-id');\n var pickupMethod = $('input[name=\"'+product.storeId+'-PickupMethod\"]:checked', $productContainer).val();\n product.pickupMethod = pickupMethod;\n }\n });\n\n form.pidsObj = JSON.stringify(pidsObj);// eslint-disable-line no-param-reassign\n } else {\n var $storeElement = $('.selected-store', form.container);\n var storeID = $storeElement.attr('data-store-id');\n var isStoreSelected = $('.shipToStoreRadio', form.container).is(':checked');\n\n if ($storeElement.length && isStoreSelected) {\n form.storeId = storeID; // eslint-disable-line\n var pickupMethod = $('input[name=\"'+storeID+'-PickupMethod\"]:checked', form.container).val();\n form.pickupMethod = pickupMethod;\n }\n }\n });\n },\n showInStoreInventory: function () {\n $('body').on('click', '.btn-get-in-store-inventory', function (e) {\n var selectedStore = $('.selected-store');\n var storeId;\n if (selectedStore.length) {\n storeId = selectedStore.attr('data-store-id');\n }\n if (!storeId) {\n var $productContainer = $(this).closest('.product-detail');\n var pid = $('.product-id', $productContainer).text();\n var quantity = $('.quantity-select', $productContainer).val();\n getModalHtmlElement();\n fillModalElement(pid, quantity, null, null, pid);\n e.stopPropagation();\n }\n });\n\n // do not allow selection of checkbox if no store selected\n $('body').on('hide.bs.modal', '#inStoreInventoryModal', function() {\n var $productContainer = null;\n var containerPID = $('.modal.show .select-store').data('container-pid');\n if (containerPID) {\n $productContainer = $('.product-detail[data-pid=\"' + containerPID + '\"]');\n }\n if (!$('.selected-store', $productContainer).attr('data-store-id')\n && $('.shipToStoreRadio', $productContainer).prop('checked')) {\n $('.shipToHomeRadio', $productContainer).click();\n }\n });\n\n },\n removeStoreSelection: function () {\n $('body').on('click', '#remove-store-selection', (function () {\n deselectStore($(this).closest('.product-detail'));\n $(document).trigger('store:afterRemoveStoreSelection', $(this).closest('.product-detail').find('.quantity-select'));\n }));\n },\n selectStoreWithInventory: function () {\n $('body').on('store:selected', function (e, data) {\n var requestData = {\n storeId: data.storeID,\n pid: data.pid,\n pickupMethod: data.pickupMethod\n };\n\n var $productContainer = null;\n if (data.containerPID) {\n $productContainer = $('.product-detail[data-pid=\"' + data.containerPID + '\"]');\n }\n\n $.ajax({\n url: $('.modal-body .select-store').data('action'),\n data: requestData,\n method: 'GET',\n success: function (response) {\n if ($productContainer) {\n response.container = $productContainer;\n }\n var $pdpInstore = response.container.find('.pdp-in-store-inventory');\n $pdpInstore.addClass('has-store');\n if (response.product.availableForInStorePickup) {\n $pdpInstore.removeClass('pickup-in-store-unavailable');\n } else {\n $pdpInstore.addClass('pickup-in-store-unavailable');\n }\n\n $('.storeInfo', response.container)\n .attr('data-availability', response.product.availableForInStorePickup ? 'available' : 'unavailable');\n $('.storeInfo-wrapper', response.container)\n .replaceWith(response.bopisHtml);\n\n var searchPID = response.product.id;\n $('.selected-store', response.container).attr('data-store-id', response.storeID);\n $('.shipToStoreRadio', response.container).prop('checked', true);\n\n updateQuantityOptions(searchPID, data.storeID);\n\n $('#inStoreInventoryModal').modal('hide');\n $('#inStoreInventoryModal').remove();\n }\n });\n });\n },\n changeStore: function () {\n $('body').on('click', '.change-store-pdp', (function (e) {\n e.preventDefault();\n var pid = $(this).attr('data-pid');\n var quantity = $(this).closest('.product-detail').find('.quantity-select').val();\n getModalHtmlElement();\n fillModalElement(pid, quantity, $(this).data('postal'), $(this).data('radius'), pid);\n }));\n }\n};\n","'use strict';\n\nmodule.exports = {\n addToWishlist: function () {\n $('body').on('click', '.add-to-wish-list', function (e) {\n e.preventDefault();\n var customerType = $('#product-search-results').attr('data-customer-type');\n\n if (!customerType) {\n customerType = $(this).attr('data-customer-type');\n }\n\n var $wishlistModal = $('#addToWishlistModal');\n\n // Only allow adding to wishlist for registered / logged-in users\n // If guest user, display message that they must login first\n if (customerType == 'registered') {\n var url = $(this).data('href');\n var button = $(this);\n var pid = $(this).closest('.product-detail').find('.product-id').html();\n var optionId = $(this).closest('.product-detail').find('.product-option').attr('data-option-id');\n var optionVal = $(this).closest('.product-detail').find('.options-select option:selected').attr('data-value-id');\n optionId = optionId || null;\n optionVal = optionVal || null;\n if (!url || !pid) {\n return;\n }\n\n var type;\n var isInWishlist = button.hasClass('wishlist-product-remove');\n\n if (isInWishlist) {\n type = 'get';\n url = button.data('remove-product');\n } else {\n type = 'post';\n }\n\n $wishlistModal.find('.add-to-wishlist-modal-link').addClass('d-none');\n\n $.spinner().start();\n $(this).attr('disabled', true);\n $.ajax({\n url: url,\n type: type,\n dataType: 'json',\n data: {\n pid: pid,\n optionId: optionId,\n optionVal: optionVal\n },\n success: function (data) {\n $('.wishlist-header .plain').html('');\n if (!isInWishlist) {\n $('.add-to-wish-list').addClass('wishlist-product-remove');\n $('body').trigger('tagmanager:addToWishList', data);\n } else {\n $('.add-to-wish-list').removeClass('wishlist-product-remove');\n $('body').trigger('tagmanagerremoveFromWishList', data);\n }\n $wishlistModal.find('.modal-body').html(data.msg);\n $wishlistModal.find('.wishlist-link').removeClass('d-none');\n $wishlistModal.modal('show');\n $.spinner().stop();\n },\n error: function (err) {\n $wishlistModal.find('.modal-body').html(err.msg);\n $wishlistModal.modal('show');\n $.spinner().stop();\n }\n });\n } else {\n $wishlistModal.find('.add-to-wishlist-modal-link').addClass('d-none');\n $wishlistModal.find('.modal-body').html('Please sign in or sign up to save this item.');\n $wishlistModal.find('.login-link').removeClass('d-none');\n $wishlistModal.modal('show');\n }\n setTimeout(function () {\n $wishlistModal.modal('hide');\n }, 5000);\n });\n }\n};\n","'use strict';\n\nmodule.exports = {\n setTabNextFocus: function (focusParams) {\n var KEYCODE_TAB = 9;\n var isTabPressed = (focusParams.event.key === 'Tab' || focusParams.event.keyCode === KEYCODE_TAB);\n\n if (!isTabPressed) {\n return;\n }\n\n var firstFocusableEl = $(focusParams.containerSelector + ' ' + focusParams.firstElementSelector);\n var lastFocusableEl = $(focusParams.containerSelector + ' ' + focusParams.lastElementSelector);\n\n if ($(focusParams.containerSelector + ' ' + focusParams.lastElementSelector).is(':disabled')) {\n lastFocusableEl = $(focusParams.containerSelector + ' ' + focusParams.nextToLastElementSelector);\n if ($('.product-quickview.product-set').length > 0) {\n var linkElements = $(focusParams.containerSelector + ' a#fa-link.share-icons');\n lastFocusableEl = linkElements[linkElements.length - 1];\n }\n }\n\n if (focusParams.event.shiftKey) /* shift + tab */ {\n if ($(':focus').is(firstFocusableEl)) {\n lastFocusableEl.focus();\n focusParams.event.preventDefault();\n }\n } else /* tab */ {\n if ($(':focus').is(lastFocusableEl)) { // eslint-disable-line\n firstFocusableEl.focus();\n focusParams.event.preventDefault();\n }\n }\n }\n};\n","'use strict';\nvar focusHelper = require('../components/focus');\n\n/**\n * Retrieves the relevant pid value\n * @param {jquery} $el - DOM container for a given add to cart button\n * @return {string} - value to be used when adding product to cart\n */\nfunction getPidValue($el) {\n var pid;\n\n if ($('#quickViewModal').hasClass('show') && !$('.product-set').length) {\n pid = $($el).closest('.modal-content').find('.product-quickview').data('pid');\n } else if ($('.product-set-detail').length || $('.product-set').length) {\n pid = $($el).closest('.product-detail').find('.product-id').text();\n } else {\n pid = $('.product-detail:not(\".bundle-item\")').data('pid');\n }\n\n return pid;\n}\n\n/**\n * Retrieve contextual quantity selector\n * @param {jquery} $el - DOM container for the relevant quantity\n * @return {jquery} - quantity selector DOM container\n */\nfunction getQuantitySelector($el) {\n var quantitySelected;\n if ($el && $('.set-items').length) {\n quantitySelected = $($el).closest('.product-detail').find('.quantity-select');\n } else if ($el && $('.product-bundle').length) {\n var quantitySelectedModal = $($el).closest('.modal-footer').find('.quantity-select');\n var quantitySelectedPDP = $($el).closest('.bundle-footer').find('.quantity-select');\n if (quantitySelectedModal.val() === undefined) {\n quantitySelected = quantitySelectedPDP;\n } else {\n quantitySelected = quantitySelectedModal;\n }\n } else {\n quantitySelected = $('.quantity-select');\n }\n return quantitySelected;\n}\n\n/**\n * Retrieves the value associated with the Quantity pull-down menu\n * @param {jquery} $el - DOM container for the relevant quantity\n * @return {string} - value found in the quantity input\n */\nfunction getQuantitySelected($el) {\n return getQuantitySelector($el).val();\n}\n\n/**\n * Process the attribute values for an attribute that has image swatches\n *\n * @param {Object} attr - Attribute\n * @param {string} attr.id - Attribute ID\n * @param {Object[]} attr.values - Array of attribute value objects\n * @param {string} attr.values.value - Attribute coded value\n * @param {string} attr.values.url - URL to de/select an attribute value of the product\n * @param {boolean} attr.values.isSelectable - Flag as to whether an attribute value can be\n * selected. If there is no variant that corresponds to a specific combination of attribute\n * values, an attribute may be disabled in the Product Detail Page\n * @param {jQuery} $productContainer - DOM container for a given product\n * @param {Object} msgs - object containing resource messages\n */\nfunction processSwatchValues(attr, $productContainer, msgs) {\n attr.values.forEach(function (attrValue) {\n var $attrValue = $productContainer.find('[data-attr=\"' + attr.id + '\"] [data-attr-value=\"' +\n attrValue.value + '\"]');\n var $swatchButton = $attrValue.parent();\n\n if (attrValue.selected) {\n $attrValue.addClass('selected');\n $attrValue.siblings('.selected-assistive-text').text(msgs.assistiveSelectedText);\n } else {\n $attrValue.removeClass('selected');\n $attrValue.siblings('.selected-assistive-text').empty();\n }\n\n if (attrValue.url) {\n $swatchButton.attr('data-url', attrValue.url);\n } else {\n $swatchButton.removeAttr('data-url');\n }\n\n // Disable if not selectable\n $attrValue.removeClass('selectable unselectable');\n\n $attrValue.addClass(attrValue.selectable ? 'selectable' : 'unselectable');\n });\n}\n\n/**\n * Process attribute values associated with an attribute that does not have image swatches\n *\n * @param {Object} attr - Attribute\n * @param {string} attr.id - Attribute ID\n * @param {Object[]} attr.values - Array of attribute value objects\n * @param {string} attr.values.value - Attribute coded value\n * @param {string} attr.values.url - URL to de/select an attribute value of the product\n * @param {boolean} attr.values.isSelectable - Flag as to whether an attribute value can be\n * selected. If there is no variant that corresponds to a specific combination of attribute\n * values, an attribute may be disabled in the Product Detail Page\n * @param {jQuery} $productContainer - DOM container for a given product\n */\nfunction processNonSwatchValues(attr, $productContainer) {\n var $attr = '[data-attr=\"' + attr.id + '\"]';\n var $defaultOption = $productContainer.find($attr + ' .select-' + attr.id + ' option:first');\n $defaultOption.attr('value', attr.resetUrl);\n\n attr.values.forEach(function (attrValue) {\n var $attrValue = $productContainer\n .find($attr + ' [data-attr-value=\"' + attrValue.value + '\"]');\n $attrValue.attr('value', attrValue.url)\n .removeAttr('disabled');\n\n if (!attrValue.selectable) {\n $attrValue.attr('disabled', true);\n }\n });\n}\n\n/**\n * Routes the handling of attribute processing depending on whether the attribute has image\n * swatches or not\n *\n * @param {Object} attrs - Attribute\n * @param {string} attr.id - Attribute ID\n * @param {jQuery} $productContainer - DOM element for a given product\n * @param {Object} msgs - object containing resource messages\n */\nfunction updateAttrs(attrs, $productContainer, msgs) {\n // Currently, the only attribute type that has image swatches is Color.\n var attrsWithSwatches = ['color'];\n\n attrs.forEach(function (attr) {\n if (attrsWithSwatches.indexOf(attr.id) > -1) {\n processSwatchValues(attr, $productContainer, msgs);\n } else {\n processNonSwatchValues(attr, $productContainer);\n }\n });\n}\n\n/**\n * Updates the availability status in the Product Detail Page\n *\n * @param {Object} response - Ajax response object after an\n * attribute value has been [de]selected\n * @param {jQuery} $productContainer - DOM element for a given product\n */\nfunction updateAvailability(response, $productContainer) {\n var availabilityValue = '';\n var availabilityMessages = response.product.availability.messages;\n if (!response.product.readyToOrder) {\n availabilityValue = '
  • ' + response.resources.info_selectforstock + '
  • ';\n } else {\n availabilityMessages.forEach(function (message) {\n availabilityValue += '
  • ' + message + '
  • ';\n });\n }\n\n $($productContainer).trigger('product:updateAvailability', {\n product: response.product,\n $productContainer: $productContainer,\n message: availabilityValue,\n resources: response.resources\n });\n}\n\n/**\n * Generates html for product attributes section\n *\n * @param {array} attributes - list of attributes\n * @return {string} - Compiled HTML\n */\nfunction getAttributesHtml(attributes) {\n if (!attributes) {\n return '';\n }\n\n var html = '';\n\n attributes.forEach(function (attributeGroup) {\n if (attributeGroup.ID === 'mainAttributes') {\n attributeGroup.attributes.forEach(function (attribute) {\n html += '
    ' + attribute.label + ': '\n + attribute.value + '
    ';\n });\n }\n });\n\n return html;\n}\n\n/**\n * @typedef UpdatedOptionValue\n * @type Object\n * @property {string} id - Option value ID for look up\n * @property {string} url - Updated option value selection URL\n */\n\n/**\n * @typedef OptionSelectionResponse\n * @type Object\n * @property {string} priceHtml - Updated price HTML code\n * @property {Object} options - Updated Options\n * @property {string} options.id - Option ID\n * @property {UpdatedOptionValue[]} options.values - Option values\n */\n\n/**\n * Updates DOM using post-option selection Ajax response\n *\n * @param {OptionSelectionResponse} optionsHtml - Ajax response optionsHtml from selecting a product option\n * @param {jQuery} $productContainer - DOM element for current product\n */\nfunction updateOptions(optionsHtml, $productContainer) {\n\t// Update options\n $productContainer.find('.product-options').empty().html(optionsHtml);\n}\n\n/**\n * Dynamically creates Bootstrap carousel from response containing images\n * @param {Object[]} imgs - Array of large product images,along with related information\n * @param {jQuery} $productContainer - DOM element for a given product\n */\nfunction createCarousel(imgs, $productContainer) {\n var carousel = $productContainer.find('.carousel');\n $(carousel).carousel('dispose');\n var carouselId = $(carousel).attr('id');\n $(carousel).empty().append('
      ' + $(carousel).data('prev') + '' + $(carousel).data('next') + '');\n for (var i = 0; i < imgs.length; i++) {\n $('
      \"'
      ').appendTo($(carousel).find('.carousel-inner'));\n $('
    1. ').appendTo($(carousel).find('.carousel-indicators'));\n }\n $($(carousel).find('.carousel-item')).first().addClass('active');\n $($(carousel).find('.carousel-indicators > li')).first().addClass('active');\n if (imgs.length === 1) {\n $($(carousel).find('.carousel-indicators, a[class^=\"carousel-control-\"]')).detach();\n }\n $(carousel).carousel();\n $($(carousel).find('.carousel-indicators')).attr('aria-hidden', true);\n}\n\n/**\n * Parses JSON from Ajax call made whenever an attribute value is [de]selected\n * @param {Object} response - response from Ajax call\n * @param {Object} response.product - Product object\n * @param {string} response.product.id - Product ID\n * @param {Object[]} response.product.variationAttributes - Product attributes\n * @param {Object[]} response.product.images - Product images\n * @param {boolean} response.product.hasRequiredAttrsSelected - Flag as to whether all required\n * attributes have been selected. Used partially to\n * determine whether the Add to Cart button can be enabled\n * @param {jQuery} $productContainer - DOM element for a given product.\n */\nfunction handleVariantResponse(response, $productContainer) {\n var isChoiceOfBonusProducts =\n $productContainer.parents('.choose-bonus-product-dialog').length > 0;\n var isVaraint;\n if (response.product.variationAttributes) {\n updateAttrs(response.product.variationAttributes, $productContainer, response.resources);\n isVaraint = response.product.productType === 'variant';\n if (isChoiceOfBonusProducts && isVaraint) {\n $productContainer.parent('.bonus-product-item')\n .data('pid', response.product.id);\n\n $productContainer.parent('.bonus-product-item')\n .data('ready-to-order', response.product.readyToOrder);\n }\n }\n\n // Update primary images\n var primaryImageUrls = response.product.images.large;\n createCarousel(primaryImageUrls, $productContainer);\n\n // Update pricing\n if (!isChoiceOfBonusProducts) {\n var $priceSelector = $('.prices .price', $productContainer).length\n ? $('.prices .price', $productContainer)\n : $('.prices .price');\n $priceSelector.replaceWith(response.product.price.html);\n }\n\n // Update promotions\n $productContainer.find('.promotions').empty().html(response.product.promotionsHtml);\n\n updateAvailability(response, $productContainer);\n\n if (isChoiceOfBonusProducts) {\n var $selectButton = $productContainer.find('.select-bonus-product');\n $selectButton.trigger('bonusproduct:updateSelectButton', {\n product: response.product, $productContainer: $productContainer\n });\n } else {\n // Enable \"Add to Cart\" button if all required attributes have been selected\n $('button.add-to-cart, button.add-to-cart-global, button.update-cart-product-global').trigger('product:updateAddToCart', {\n product: response.product, $productContainer: $productContainer\n }).trigger('product:statusUpdate', response.product);\n }\n\n // Update attributes\n $productContainer.find('.main-attributes').empty()\n .html(getAttributesHtml(response.product.attributes));\n}\n\n/**\n * @typespec UpdatedQuantity\n * @type Object\n * @property {boolean} selected - Whether the quantity has been selected\n * @property {string} value - The number of products to purchase\n * @property {string} url - Compiled URL that specifies variation attributes, product ID, options,\n * etc.\n */\n\n/**\n * Updates the quantity DOM elements post Ajax call\n * @param {UpdatedQuantity[]} quantities -\n * @param {jQuery} $productContainer - DOM container for a given product\n */\nfunction updateQuantities(quantities, $productContainer) {\n if ($productContainer.parent('.bonus-product-item').length <= 0) {\n var optionsHtml = quantities.map(function (quantity) {\n var selected = quantity.selected ? ' selected ' : '';\n return '';\n }).join('');\n getQuantitySelector($productContainer).empty().html(optionsHtml);\n }\n}\n\n/**\n * updates the product view when a product attribute is selected or deselected or when\n * changing quantity\n * @param {string} selectedValueUrl - the Url for the selected variation value\n * @param {jQuery} $productContainer - DOM element for current product\n */\nfunction attributeSelect(selectedValueUrl, $productContainer) {\n if (selectedValueUrl) {\n $('body').trigger('product:beforeAttributeSelect',\n { url: selectedValueUrl, container: $productContainer });\n\n $.ajax({\n url: selectedValueUrl,\n method: 'GET',\n success: function (data) {\n handleVariantResponse(data, $productContainer);\n updateOptions(data.product.optionsHtml, $productContainer);\n updateQuantities(data.product.quantities, $productContainer);\n $('body').trigger('product:afterAttributeSelect',\n { data: data, container: $productContainer });\n $.spinner().stop();\n },\n error: function () {\n $.spinner().stop();\n }\n });\n }\n}\n\n/**\n * Retrieves url to use when adding a product to the cart\n *\n * @return {string} - The provided URL to use when adding a product to the cart\n */\nfunction getAddToCartUrl() {\n return $('.add-to-cart-url').val();\n}\n\n/**\n * Parses the html for a modal window\n * @param {string} html - representing the body and footer of the modal window\n *\n * @return {Object} - Object with properties body and footer.\n */\nfunction parseHtml(html) {\n var $html = $('
      ').append($.parseHTML(html));\n\n var body = $html.find('.choice-of-bonus-product');\n var footer = $html.find('.modal-footer').children();\n\n return { body: body, footer: footer };\n}\n\n/**\n * Retrieves url to use when adding a product to the cart\n *\n * @param {Object} data - data object used to fill in dynamic portions of the html\n */\nfunction chooseBonusProducts(data) {\n $('.modal-body').spinner().start();\n\n if ($('#chooseBonusProductModal').length !== 0) {\n $('#chooseBonusProductModal').remove();\n }\n var bonusUrl;\n if (data.bonusChoiceRuleBased) {\n bonusUrl = data.showProductsUrlRuleBased;\n } else {\n bonusUrl = data.showProductsUrlListBased;\n }\n\n var htmlString = ''\n + '
      '\n + ''\n + '
      '\n + ''\n + '
      '\n + '
      '\n + ' ' + data.labels.selectprods + ''\n + ' '\n + '
      '\n + '
      '\n + '
      '\n + '
      '\n + '
      '\n + '
      ';\n $('body').append(htmlString);\n $('.modal-body').spinner().start();\n\n $.ajax({\n url: bonusUrl,\n method: 'GET',\n dataType: 'json',\n success: function (response) {\n var parsedHtml = parseHtml(response.renderedTemplate);\n $('#chooseBonusProductModal .modal-body').empty();\n $('#chooseBonusProductModal .enter-message').text(response.enterDialogMessage);\n $('#chooseBonusProductModal .modal-header .close .sr-only').text(response.closeButtonText);\n $('#chooseBonusProductModal .modal-body').html(parsedHtml.body);\n $('#chooseBonusProductModal .modal-footer').html(parsedHtml.footer);\n $('#chooseBonusProductModal').modal('show');\n $.spinner().stop();\n },\n error: function () {\n $.spinner().stop();\n }\n });\n}\n\n/**\n * Updates the Mini-Cart quantity value after the customer has pressed the \"Add to Cart\" button\n * @param {string} response - ajax response from clicking the add to cart button\n */\nfunction handlePostCartAdd(response) {\n $('.minicart').trigger('count:update', response);\n var messageType = response.error ? 'alert-danger' : 'alert-success';\n // show add to cart toast\n if (response.newBonusDiscountLineItem\n && Object.keys(response.newBonusDiscountLineItem).length !== 0) {\n chooseBonusProducts(response.newBonusDiscountLineItem);\n } else {\n if ($('.add-to-cart-messages').length === 0) {\n $('body').append(\n '
      '\n );\n }\n\n $('.add-to-cart-messages').append(\n '
      '\n + response.message\n + '
      '\n );\n\n setTimeout(function () {\n $('.add-to-basket-alert').remove();\n }, 5000);\n }\n}\n\n/**\n * Retrieves the bundle product item ID's for the Controller to replace bundle master product\n * items with their selected variants\n *\n * @return {string[]} - List of selected bundle product item ID's\n */\nfunction getChildProducts() {\n var childProducts = [];\n $('.bundle-item').each(function () {\n childProducts.push({\n pid: $(this).find('.product-id').text(),\n quantity: parseInt($(this).find('label.quantity').data('quantity'), 10)\n });\n });\n\n return childProducts.length ? JSON.stringify(childProducts) : [];\n}\n\n/**\n * Retrieve product options\n *\n * @param {jQuery} $productContainer - DOM element for current product\n * @return {string} - Product options and their selected values\n */\nfunction getOptions($productContainer) {\n var options = $productContainer\n .find('.product-option')\n .map(function () {\n var $elOption = $(this).find('.options-select');\n var urlValue = $elOption.val();\n var selectedValueId = $elOption.find('option[value=\"' + urlValue + '\"]')\n .data('value-id');\n return {\n optionId: $(this).data('option-id'),\n selectedValueId: selectedValueId\n };\n }).toArray();\n\n return JSON.stringify(options);\n}\n\n/**\n * Makes a call to the server to report the event of adding an item to the cart\n *\n * @param {string | boolean} url - a string representing the end point to hit so that the event can be recorded, or false\n */\nfunction miniCartReportingUrl(url) {\n if (url) {\n $.ajax({\n url: url,\n method: 'GET',\n success: function () {\n // reporting urls hit on the server\n },\n error: function () {\n // no reporting urls hit on the server\n }\n });\n }\n}\n\nmodule.exports = {\n attributeSelect: attributeSelect,\n methods: {\n editBonusProducts: function (data) {\n chooseBonusProducts(data);\n }\n },\n\n focusChooseBonusProductModal: function () {\n $('body').on('shown.bs.modal', '#chooseBonusProductModal', function () {\n $('#chooseBonusProductModal').siblings().attr('aria-hidden', 'true');\n $('#chooseBonusProductModal .close').focus();\n });\n },\n\n onClosingChooseBonusProductModal: function () {\n $('body').on('hidden.bs.modal', '#chooseBonusProductModal', function () {\n $('#chooseBonusProductModal').siblings().attr('aria-hidden', 'false');\n });\n },\n\n trapChooseBonusProductModalFocus: function () {\n $('body').on('keydown', '#chooseBonusProductModal', function (e) {\n var focusParams = {\n event: e,\n containerSelector: '#chooseBonusProductModal',\n firstElementSelector: '.close',\n lastElementSelector: '.add-bonus-products'\n };\n focusHelper.setTabNextFocus(focusParams);\n });\n },\n\n colorAttribute: function () {\n $(document).on('click', '[data-attr=\"color\"] button', function (e) {\n e.preventDefault();\n\n if ($(this).attr('disabled')) {\n return;\n }\n var $productContainer = $(this).closest('.set-item');\n if (!$productContainer.length) {\n $productContainer = $(this).closest('.product-detail');\n }\n\n attributeSelect($(this).attr('data-url'), $productContainer);\n });\n },\n\n selectAttribute: function () {\n $(document).on('change', 'select[class*=\"select-\"], .options-select', function (e) {\n e.preventDefault();\n\n var $productContainer = $(this).closest('.set-item');\n if (!$productContainer.length) {\n $productContainer = $(this).closest('.product-detail');\n }\n attributeSelect(e.currentTarget.value, $productContainer);\n });\n },\n\n availability: function () {\n $(document).on('change', '.quantity-select', function (e) {\n e.preventDefault();\n\n var $productContainer = $(this).closest('.product-detail');\n if (!$productContainer.length) {\n $productContainer = $(this).closest('.modal-content').find('.product-quickview');\n }\n\n if ($('.bundle-items', $productContainer).length === 0) {\n attributeSelect($(e.currentTarget).find('option:selected').data('url'),\n $productContainer);\n }\n });\n },\n\n addToCart: function () {\n $(document).on('click', 'button.add-to-cart, button.add-to-cart-global', function () {\n var addToCartUrl;\n var pid;\n var pidsObj;\n var setPids;\n\n $('body').trigger('product:beforeAddToCart', this);\n\n if ($('.set-items').length && $(this).hasClass('add-to-cart-global')) {\n setPids = [];\n\n $('.product-detail').each(function () {\n if (!$(this).hasClass('product-set-detail')) {\n setPids.push({\n pid: $(this).find('.product-id').text(),\n qty: $(this).find('.quantity-select').val(),\n options: getOptions($(this))\n });\n }\n });\n pidsObj = JSON.stringify(setPids);\n }\n\n pid = getPidValue($(this));\n\n var $productContainer = $(this).closest('.product-detail');\n if (!$productContainer.length) {\n $productContainer = $(this).closest('.quick-view-dialog').find('.product-detail');\n }\n\n addToCartUrl = getAddToCartUrl();\n\n var form = {\n pid: pid,\n pidsObj: pidsObj,\n childProducts: getChildProducts(),\n quantity: getQuantitySelected($(this))\n };\n\n if (!$('.bundle-item').length) {\n form.options = getOptions($productContainer);\n }\n\n $(this).trigger('updateAddToCartFormData', form);\n if (addToCartUrl) {\n $.ajax({\n url: addToCartUrl,\n method: 'POST',\n data: form,\n success: function (data) {\n handlePostCartAdd(data);\n $('body').trigger('product:afterAddToCart', data);\n $.spinner().stop();\n miniCartReportingUrl(data.reportingURL);\n },\n error: function () {\n $.spinner().stop();\n }\n });\n }\n });\n },\n selectBonusProduct: function () {\n $(document).on('click', '.select-bonus-product', function () {\n var $choiceOfBonusProduct = $(this).parents('.choice-of-bonus-product');\n var pid = $(this).data('pid');\n var maxPids = $('.choose-bonus-product-dialog').data('total-qty');\n var submittedQty = parseInt($choiceOfBonusProduct.find('.bonus-quantity-select').val(), 10);\n var totalQty = 0;\n $.each($('#chooseBonusProductModal .selected-bonus-products .selected-pid'), function () {\n totalQty += $(this).data('qty');\n });\n totalQty += submittedQty;\n var optionID = $choiceOfBonusProduct.find('.product-option').data('option-id');\n var valueId = $choiceOfBonusProduct.find('.options-select option:selected').data('valueId');\n if (totalQty <= maxPids) {\n var selectedBonusProductHtml = ''\n + '
      '\n + '
      '\n + $choiceOfBonusProduct.find('.product-name').html()\n + '
      '\n + '
      '\n + '
      '\n ;\n $('#chooseBonusProductModal .selected-bonus-products').append(selectedBonusProductHtml);\n $('.pre-cart-products').html(totalQty);\n $('.selected-bonus-products .bonus-summary').removeClass('alert-danger');\n } else {\n $('.selected-bonus-products .bonus-summary').addClass('alert-danger');\n }\n });\n },\n removeBonusProduct: function () {\n $(document).on('click', '.selected-pid', function () {\n $(this).remove();\n var $selected = $('#chooseBonusProductModal .selected-bonus-products .selected-pid');\n var count = 0;\n if ($selected.length) {\n $selected.each(function () {\n count += parseInt($(this).data('qty'), 10);\n });\n }\n\n $('.pre-cart-products').html(count);\n $('.selected-bonus-products .bonus-summary').removeClass('alert-danger');\n });\n },\n enableBonusProductSelection: function () {\n $('body').on('bonusproduct:updateSelectButton', function (e, response) {\n $('button.select-bonus-product', response.$productContainer).attr('disabled',\n (!response.product.readyToOrder || !response.product.available));\n var pid = response.product.id;\n $('button.select-bonus-product', response.$productContainer).data('pid', pid);\n });\n },\n showMoreBonusProducts: function () {\n $(document).on('click', '.show-more-bonus-products', function () {\n var url = $(this).data('url');\n $('.modal-content').spinner().start();\n $.ajax({\n url: url,\n method: 'GET',\n success: function (html) {\n var parsedHtml = parseHtml(html);\n $('.modal-body').append(parsedHtml.body);\n $('.show-more-bonus-products:first').remove();\n $('.modal-content').spinner().stop();\n },\n error: function () {\n $('.modal-content').spinner().stop();\n }\n });\n });\n },\n addBonusProductsToCart: function () {\n $(document).on('click', '.add-bonus-products', function () {\n var $readyToOrderBonusProducts = $('.choose-bonus-product-dialog .selected-pid');\n var queryString = '?pids=';\n var url = $('.choose-bonus-product-dialog').data('addtocarturl');\n var pidsObject = {\n bonusProducts: []\n };\n\n $.each($readyToOrderBonusProducts, function () {\n var qtyOption =\n parseInt($(this)\n .data('qty'), 10);\n\n var option = null;\n if (qtyOption > 0) {\n if ($(this).data('optionid') && $(this).data('option-selected-value')) {\n option = {};\n option.optionId = $(this).data('optionid');\n option.productId = $(this).data('pid');\n option.selectedValueId = $(this).data('option-selected-value');\n }\n pidsObject.bonusProducts.push({\n pid: $(this).data('pid'),\n qty: qtyOption,\n options: [option]\n });\n pidsObject.totalQty = parseInt($('.pre-cart-products').html(), 10);\n }\n });\n queryString += JSON.stringify(pidsObject);\n queryString = queryString + '&uuid=' + $('.choose-bonus-product-dialog').data('uuid');\n queryString = queryString + '&pliuuid=' + $('.choose-bonus-product-dialog').data('pliuuid');\n $.spinner().start();\n $.ajax({\n url: url + queryString,\n method: 'POST',\n success: function (data) {\n $.spinner().stop();\n if (data.error) {\n $('#chooseBonusProductModal').modal('hide');\n if ($('.add-to-cart-messages').length === 0) {\n $('body').append('
      ');\n }\n $('.add-to-cart-messages').append(\n '
      '\n + data.errorMessage + '
      '\n );\n setTimeout(function () {\n $('.add-to-basket-alert').remove();\n }, 3000);\n } else {\n $('.configure-bonus-product-attributes').html(data);\n $('.bonus-products-step2').removeClass('hidden-xl-down');\n $('#chooseBonusProductModal').modal('hide');\n\n if ($('.add-to-cart-messages').length === 0) {\n $('body').append('
      ');\n }\n $('.minicart-quantity').html(data.totalQty);\n $('.add-to-cart-messages').append(\n '
      '\n + data.msgSuccess + '
      '\n );\n setTimeout(function () {\n $('.add-to-basket-alert').remove();\n if ($('.cart-page').length) {\n location.reload();\n }\n }, 1500);\n }\n },\n error: function () {\n $.spinner().stop();\n }\n });\n });\n },\n\n getPidValue: getPidValue,\n getQuantitySelected: getQuantitySelected,\n miniCartReportingUrl: miniCartReportingUrl\n};\n","'use strict';\nvar base = require('./base');\nvar focusHelper = require('../components/focus');\n\n/**\n * Generates the modal window on the first call.\n *\n */\nfunction getModalHtmlElement() {\n if ($('#quickViewModal').length !== 0) {\n $('#quickViewModal').remove();\n }\n var htmlString = ''\n + '
      '\n + ''\n + '
      '\n + ''\n + '
      '\n + '
      '\n + ' '\n + ' '\n + '
      '\n + '
      '\n + '
      '\n + '
      '\n + '
      '\n + '
      ';\n $('body').append(htmlString);\n}\n\n/**\n * @typedef {Object} QuickViewHtml\n * @property {string} body - Main Quick View body\n * @property {string} footer - Quick View footer content\n */\n\n/**\n * Parse HTML code in Ajax response\n *\n * @param {string} html - Rendered HTML from quickview template\n * @return {QuickViewHtml} - QuickView content components\n */\nfunction parseHtml(html) {\n var $html = $('
      ').append($.parseHTML(html));\n\n var body = $html.find('.product-quickview');\n var footer = $html.find('.modal-footer').children();\n\n return { body: body, footer: footer };\n}\n\n/**\n * replaces the content in the modal window on for the selected product variation.\n * @param {string} selectedValueUrl - url to be used to retrieve a new product model\n */\nfunction fillModalElement(selectedValueUrl) {\n $('.modal-body').spinner().start();\n $.ajax({\n url: selectedValueUrl,\n method: 'GET',\n dataType: 'json',\n success: function (data) {\n var parsedHtml = parseHtml(data.renderedTemplate);\n\n $('.modal-body').empty();\n $('.modal-body').html(parsedHtml.body);\n $('.modal-footer').html(parsedHtml.footer);\n $('.full-pdp-link').text(data.quickViewFullDetailMsg);\n $('#quickViewModal .full-pdp-link').attr('href', data.productUrl);\n $('#quickViewModal .size-chart').attr('href', data.productUrl);\n $('#quickViewModal .modal-header .close .sr-only').text(data.closeButtonText);\n $('#quickViewModal .enter-message').text(data.enterDialogMessage);\n $('#quickViewModal').modal('show');\n $('body').trigger('quickview:ready');\n\n $.spinner().stop();\n },\n error: function () {\n $.spinner().stop();\n }\n });\n}\n\nmodule.exports = {\n showQuickview: function () {\n $('body').on('click', '.quickview', function (e) {\n e.preventDefault();\n var selectedValueUrl = $(this).closest('a.quickview').attr('href');\n $(e.target).trigger('quickview:show');\n getModalHtmlElement();\n fillModalElement(selectedValueUrl);\n });\n },\n focusQuickview: function () {\n $('body').on('shown.bs.modal', '#quickViewModal', function () {\n $('#quickViewModal .close').focus();\n });\n },\n trapQuickviewFocus: function () {\n $('body').on('keydown', '#quickViewModal', function (e) {\n var focusParams = {\n event: e,\n containerSelector: '#quickViewModal',\n firstElementSelector: '.full-pdp-link',\n lastElementSelector: '.add-to-cart-global',\n nextToLastElementSelector: '.modal-footer .quantity-select'\n };\n focusHelper.setTabNextFocus(focusParams);\n });\n },\n availability: base.availability,\n addToCart: base.addToCart,\n showSpinner: function () {\n $('body').on('product:beforeAddToCart', function (e, data) {\n $(data).closest('.modal-content').spinner().start();\n });\n },\n hideDialog: function () {\n $('body').on('product:afterAddToCart', function () {\n $('#quickViewModal').modal('hide');\n });\n },\n beforeUpdateAttribute: function () {\n $('body').on('product:beforeAttributeSelect', function () {\n $('.modal.show .modal-content').spinner().start();\n });\n },\n updateAttribute: function () {\n $('body').on('product:afterAttributeSelect', function (e, response) {\n if ($('.modal.show .product-quickview>.bundle-items').length) {\n $('.modal.show').find(response.container).data('pid', response.data.product.id);\n $('.modal.show').find(response.container)\n .find('.product-id').text(response.data.product.id);\n } else if ($('.set-items').length) {\n response.container.find('.product-id').text(response.data.product.id);\n } else {\n $('.modal.show .product-quickview').data('pid', response.data.product.id);\n $('.modal.show .full-pdp-link')\n .attr('href', response.data.product.selectedProductUrl);\n }\n });\n },\n updateAddToCart: function () {\n $('body').on('product:updateAddToCart', function (e, response) {\n // update local add to cart (for sets)\n $('button.add-to-cart', response.$productContainer).attr('disabled',\n (!response.product.readyToOrder || !response.product.available));\n\n // update global add to cart (single products, bundles)\n var dialog = $(response.$productContainer)\n .closest('.quick-view-dialog');\n\n $('.add-to-cart-global', dialog).attr('disabled',\n !$('.global-availability', dialog).data('ready-to-order')\n || !$('.global-availability', dialog).data('available')\n );\n });\n },\n updateAvailability: function () {\n $('body').on('product:updateAvailability', function (e, response) {\n // bundle individual products\n $('.product-availability', response.$productContainer)\n .data('ready-to-order', response.product.readyToOrder)\n .data('available', response.product.available)\n .find('.availability-msg')\n .empty()\n .html(response.message);\n\n\n var dialog = $(response.$productContainer)\n .closest('.quick-view-dialog');\n\n if ($('.product-availability', dialog).length) {\n // bundle all products\n var allAvailable = $('.product-availability', dialog).toArray()\n .every(function (item) { return $(item).data('available'); });\n\n var allReady = $('.product-availability', dialog).toArray()\n .every(function (item) { return $(item).data('ready-to-order'); });\n\n $('.global-availability', dialog)\n .data('ready-to-order', allReady)\n .data('available', allAvailable);\n\n $('.global-availability .availability-msg', dialog).empty()\n .html(allReady ? response.message : response.resources.info_selectforstock);\n } else {\n // single product\n $('.global-availability', dialog)\n .data('ready-to-order', response.product.readyToOrder)\n .data('available', response.product.available)\n .find('.availability-msg')\n .empty()\n .html(response.message);\n }\n });\n }\n};\n","'use strict';\n\nmodule.exports = function (include) {\n if (typeof include === 'function') {\n include();\n } else if (typeof include === 'object') {\n Object.keys(include).forEach(function (key) {\n if (typeof include[key] === 'function') {\n include[key]();\n }\n });\n }\n};\n"],"sourceRoot":""}