{"version":3,"file":"jwsdw-productDetail.js","sources":["../../../../../../../webfrontend/assets/vendor/squarelovin.js","../../../../../../../webfrontend/assets/vendor/angularjs/youtube-embed.js","../../../../../../../webfrontend/assets/vendor/angularjs/angular-touch.js","../../../../../../../temp/ngAnnotate/assets/modules/productDetail/app.module.js","../../../../../../../temp/ngAnnotate/assets/modules/productDetail/app.constants.js","../../../../../../../temp/ngAnnotate/assets/modules/productDetail/app.controller.js","../../../../../../../temp/ngAnnotate/assets/modules/productDetail/data.service.js","../../../../../../../temp/ngAnnotate/assets/modules/productDetail/thumbGallery.directive.js","../../../../../../../temp/ngAnnotate/assets/modules/productDetail/imageViewer.directive.js","../../../../../../../temp/ngAnnotate/assets/modules/productDetail/productImageGallery.directive.js","../../../../../../../temp/ngAnnotate/assets/modules/productDetail/detailInfo.controller.js","../../../../../../../temp/ngAnnotate/assets/modules/productDetail/youtubeVideo.directive.js","../../../../../../../temp/ngAnnotate/assets/jwsdw-productDetail.js","../../../../../../../temp/ngAnnotate/assets/jwsdw-notifyme.js"],"sourcesContent":["(function () {\r\n if (window.jwsdwSquarelovinSettings) {\r\n var widgetId = window.jwsdwSquarelovinSettings.squarelovinId;\r\n var widgetLang = window.jwsdwSquarelovinSettings.languageCode;\r\n var widgetType = window.jwsdwSquarelovinSettings.squarelovinType;\r\n var lastURL = '';\r\n var baseURL = location.href.substring(0, location.href.lastIndexOf('/'));\r\n var colors = window.jwsdwProductDetailSettings.data.allVariations.attributes.filter(function (color) {\r\n return color.id === 'color';\r\n });\r\n var productIds = colors && colors.length === 1 ? colors[0].vals.map(function(color) {\r\n return window.jwsdwProductDetailSettings.data.masterID + '_' + color.id;\r\n }) : [];\r\n\r\n // First run\r\n loadWidget();\r\n\r\n // Wait for Angular to render the colorSelection and set the event listeners\r\n var colorSelectionInterval = setInterval(function () {\r\n var colorSelection = document.querySelector('.jwsdw-pdp-colorSelection');\r\n if (colorSelection) {\r\n setEvents(colorSelection);\r\n clearInterval(colorSelectionInterval);\r\n }\r\n }, 100);\r\n }\r\n\r\n function loadWidget() {\r\n setTimeout(function () {\r\n var url = baseURL + '/' + location.href.substr(location.href.lastIndexOf('/') + 1);\r\n if (lastURL !== location.href) {\r\n var target = document.getElementById('squarelovin-slot');\r\n var js = document.getElementById('squarelovin-js');\r\n lastURL = location.href;\r\n\r\n // Cleanup the widget code and script\r\n if (target) {\r\n target.innerHTML = '';\r\n }\r\n if (js) {\r\n js.parentElement.removeChild(js);\r\n }\r\n\r\n // The placeholder script (used by Squarelovin to render the widget)\r\n if (target) {\r\n var s1 = document.createElement('script');\r\n s1.id = 'sqln-' + widgetId;\r\n s1.type = 'text/javascript';\r\n s1.datastream = widgetId;\r\n target.appendChild(s1);\r\n }\r\n\r\n // The Squarelovin widget code\r\n var s = document.createElement('script');\r\n s.id = 'squarelovin-js';\r\n s.type = 'text/javascript';\r\n s.async = true;\r\n s.src = 'https://squarelovin.com/squarelovin.js?stream=' + widgetId +\r\n '&t=' + widgetType +\r\n '&l=' + widgetLang +\r\n '&pid=' + productIds.join(',') +\r\n '&u=' + url;\r\n\r\n var sc = document.getElementsByTagName('script')[0];\r\n sc.parentNode.insertBefore(s, sc);\r\n }\r\n }, 300); // A little delay is added to wait for the URL to change\r\n }\r\n\r\n function setEvents(el) {\r\n el.addEventListener('mouseup', loadWidget);\r\n el.addEventListener('touchend', loadWidget);\r\n }\r\n})();\r\n","/*\r\n * Source: https://github.com/brandly/angular-youtube-embed\r\n * By Matthew Brandly\r\n*/\r\n\r\n/* global YT */\r\nangular.module('youtube-embed', [])\r\n.service ('youtubeEmbedUtils', ['$window', '$rootScope', function ($window, $rootScope) {\r\n var Service = {}\r\n\r\n // adapted from http://stackoverflow.com/a/5831191/1614967\r\n var youtubeRegexp = /https?:\\/\\/(?:[0-9A-Z-]+\\.)?(?:youtu\\.be\\/|youtube(?:-nocookie)?\\.com\\S*[^\\w\\s-])([\\w-]{11})(?=[^\\w-]|$)(?![?=&+%\\w.-]*(?:['\"][^<>]*>|<\\/a>))[?=&+%\\w.-]*/ig;\r\n var timeRegexp = /t=(\\d+)[ms]?(\\d+)?s?/;\r\n\r\n function contains(str, substr) {\r\n return (str.indexOf(substr) > -1);\r\n }\r\n\r\n Service.getIdFromURL = function getIdFromURL(url) {\r\n var id = url.replace(youtubeRegexp, '$1');\r\n\r\n if (contains(id, ';')) {\r\n var pieces = id.split(';');\r\n\r\n if (contains(pieces[1], '%')) {\r\n // links like this:\r\n // \"http://www.youtube.com/attribution_link?a=pxa6goHqzaA&u=%2Fwatch%3Fv%3DdPdgx30w9sU%26feature%3Dshare\"\r\n // have the real query string URI encoded behind a ';'.\r\n // at this point, `id is 'pxa6goHqzaA;u=%2Fwatch%3Fv%3DdPdgx30w9sU%26feature%3Dshare'\r\n var uriComponent = decodeURIComponent(pieces[1]);\r\n id = ('http://youtube.com' + uriComponent)\r\n .replace(youtubeRegexp, '$1');\r\n } else {\r\n // https://www.youtube.com/watch?v=VbNF9X1waSc&feature=youtu.be\r\n // `id` looks like 'VbNF9X1waSc;feature=youtu.be' currently.\r\n // strip the ';feature=youtu.be'\r\n id = pieces[0];\r\n }\r\n } else if (contains(id, '#')) {\r\n // id might look like '93LvTKF_jW0#t=1'\r\n // and we want '93LvTKF_jW0'\r\n id = id.split('#')[0];\r\n }\r\n\r\n return id;\r\n };\r\n\r\n Service.getTimeFromURL = function getTimeFromURL(url) {\r\n url = url || '';\r\n\r\n // t=4m20s\r\n // returns ['t=4m20s', '4', '20']\r\n // t=46s\r\n // returns ['t=46s', '46']\r\n // t=46\r\n // returns ['t=46', '46']\r\n var times = url.match(timeRegexp);\r\n\r\n if (!times) {\r\n // zero seconds\r\n return 0;\r\n }\r\n\r\n // assume the first\r\n var full = times[0],\r\n minutes = times[1],\r\n seconds = times[2];\r\n\r\n // t=4m20s\r\n if (typeof seconds !== 'undefined') {\r\n seconds = parseInt(seconds, 10);\r\n minutes = parseInt(minutes, 10);\r\n\r\n // t=4m\r\n } else if (contains(full, 'm')) {\r\n minutes = parseInt(minutes, 10);\r\n seconds = 0;\r\n\r\n // t=4s\r\n // t=4\r\n } else {\r\n seconds = parseInt(minutes, 10);\r\n minutes = 0;\r\n }\r\n\r\n // in seconds\r\n return seconds + (minutes * 60);\r\n };\r\n\r\n Service.ready = false;\r\n\r\n function applyServiceIsReady() {\r\n $rootScope.$apply(function () {\r\n Service.ready = true;\r\n });\r\n };\r\n\r\n // If the library isn't here at all,\r\n if (typeof YT === \"undefined\") {\r\n // ...grab on to global callback, in case it's eventually loaded\r\n $window.onYouTubeIframeAPIReady = applyServiceIsReady;\r\n console.log('Unable to find YouTube iframe library on this page.')\r\n } else if (YT.loaded) {\r\n Service.ready = true;\r\n } else {\r\n YT.ready(applyServiceIsReady);\r\n }\r\n\r\n return Service;\r\n}])\r\n.directive('youtubeVideo', ['$window', 'youtubeEmbedUtils', function ($window, youtubeEmbedUtils) {\r\n var uniqId = 1;\r\n\r\n // from YT.PlayerState\r\n var stateNames = {\r\n '-1': 'unstarted',\r\n 0: 'ended',\r\n 1: 'playing',\r\n 2: 'paused',\r\n 3: 'buffering',\r\n 5: 'queued'\r\n };\r\n\r\n var eventPrefix = 'youtube.player.';\r\n\r\n $window.YTConfig = {\r\n host: 'https://www.youtube.com'\r\n };\r\n\r\n return {\r\n restrict: 'EA',\r\n scope: {\r\n videoId: '=?',\r\n videoUrl: '=?',\r\n player: '=?',\r\n playerVars: '=?',\r\n playerHeight: '=?',\r\n playerWidth: '=?'\r\n },\r\n link: function (scope, element, attrs) {\r\n // allows us to $watch `ready`\r\n scope.utils = youtubeEmbedUtils;\r\n\r\n // player-id attr > id attr > directive-generated ID\r\n var playerId = attrs.playerId || element[0].id || 'unique-youtube-embed-id-' + uniqId++;\r\n element[0].id = playerId;\r\n\r\n // Attach to element\r\n scope.playerHeight = scope.playerHeight || 390;\r\n scope.playerWidth = scope.playerWidth || 640;\r\n scope.playerVars = scope.playerVars || {};\r\n\r\n // YT calls callbacks outside of digest cycle\r\n function applyBroadcast () {\r\n var args = Array.prototype.slice.call(arguments);\r\n scope.$apply(function () {\r\n scope.$emit.apply(scope, args);\r\n });\r\n }\r\n\r\n function onPlayerStateChange (event) {\r\n var state = stateNames[event.data];\r\n if (typeof state !== 'undefined') {\r\n applyBroadcast(eventPrefix + state, scope.player, event);\r\n }\r\n scope.$apply(function () {\r\n scope.player.currentState = state;\r\n });\r\n }\r\n\r\n function onPlayerReady (event) {\r\n applyBroadcast(eventPrefix + 'ready', scope.player, event);\r\n }\r\n\r\n function onPlayerError (event) {\r\n applyBroadcast(eventPrefix + 'error', scope.player, event);\r\n }\r\n\r\n function createPlayer () {\r\n var playerVars = angular.copy(scope.playerVars);\r\n playerVars.start = playerVars.start || scope.urlStartTime;\r\n var player = new YT.Player(playerId, {\r\n height: scope.playerHeight,\r\n width: scope.playerWidth,\r\n videoId: scope.videoId,\r\n playerVars: playerVars,\r\n events: {\r\n onReady: onPlayerReady,\r\n onStateChange: onPlayerStateChange,\r\n onError: onPlayerError\r\n }\r\n });\r\n\r\n player.id = playerId;\r\n return player;\r\n }\r\n\r\n function loadPlayer () {\r\n if (scope.videoId || scope.playerVars.list) {\r\n if (scope.player && typeof scope.player.destroy === 'function') {\r\n scope.player.destroy();\r\n }\r\n\r\n scope.player = createPlayer();\r\n }\r\n };\r\n\r\n var stopWatchingReady = scope.$watch(\r\n function () {\r\n return scope.utils.ready\r\n // Wait until one of them is defined...\r\n && (typeof scope.videoUrl !== 'undefined'\r\n || typeof scope.videoId !== 'undefined'\r\n || typeof scope.playerVars.list !== 'undefined');\r\n },\r\n function (ready) {\r\n if (ready) {\r\n stopWatchingReady();\r\n\r\n // URL takes first priority\r\n if (typeof scope.videoUrl !== 'undefined') {\r\n scope.$watch('videoUrl', function (url) {\r\n scope.videoId = scope.utils.getIdFromURL(url);\r\n scope.urlStartTime = scope.utils.getTimeFromURL(url);\r\n\r\n loadPlayer();\r\n });\r\n\r\n // then, a video ID\r\n } else if (typeof scope.videoId !== 'undefined') {\r\n scope.$watch('videoId', function () {\r\n scope.urlStartTime = null;\r\n loadPlayer();\r\n });\r\n\r\n // finally, a list\r\n } else {\r\n scope.$watch('playerVars.list', function () {\r\n scope.urlStartTime = null;\r\n loadPlayer();\r\n });\r\n }\r\n }\r\n });\r\n\r\n scope.$watchCollection(['playerHeight', 'playerWidth'], function() {\r\n if (scope.player) {\r\n scope.player.setSize(scope.playerWidth, scope.playerHeight);\r\n }\r\n });\r\n\r\n scope.$on('$destroy', function () {\r\n scope.player && scope.player.destroy();\r\n });\r\n }\r\n };\r\n}]);","/**\r\n * @license AngularJS v1.8.0\r\n * (c) 2010-2020 Google, Inc. http://angularjs.org\r\n * License: MIT\r\n */\r\n(function(window, angular) {'use strict';\r\n\r\n/**\r\n * @ngdoc module\r\n * @name ngTouch\r\n * @description\r\n *\r\n * The `ngTouch` module provides helpers for touch-enabled devices.\r\n * The implementation is based on jQuery Mobile touch event handling\r\n * ([jquerymobile.com](http://jquerymobile.com/)). *\r\n *\r\n * See {@link ngTouch.$swipe `$swipe`} for usage.\r\n *\r\n * @deprecated\r\n * sinceVersion=\"1.7.0\"\r\n * The ngTouch module with the {@link ngTouch.$swipe `$swipe`} service and\r\n * the {@link ngTouch.ngSwipeLeft} and {@link ngTouch.ngSwipeRight} directives are\r\n * deprecated. Instead, stand-alone libraries for touch handling and gesture interaction\r\n * should be used, for example [HammerJS](https://hammerjs.github.io/) (which is also used by\r\n * Angular).\r\n */\r\n\r\n// define ngTouch module\r\n/* global ngTouch */\r\nvar ngTouch = angular.module('ngTouch', []);\r\n\r\nngTouch.info({ angularVersion: '1.8.0' });\r\n\r\nfunction nodeName_(element) {\r\n return angular.$$lowercase(element.nodeName || (element[0] && element[0].nodeName));\r\n}\r\n\r\n/* global ngTouch: false */\r\n\r\n /**\r\n * @ngdoc service\r\n * @name $swipe\r\n *\r\n * @deprecated\r\n * sinceVersion=\"1.7.0\"\r\n *\r\n * See the {@link ngTouch module} documentation for more information.\r\n *\r\n * @description\r\n * The `$swipe` service is a service that abstracts the messier details of hold-and-drag swipe\r\n * behavior, to make implementing swipe-related directives more convenient.\r\n *\r\n * Requires the {@link ngTouch `ngTouch`} module to be installed.\r\n *\r\n * `$swipe` is used by the `ngSwipeLeft` and `ngSwipeRight` directives in `ngTouch`.\r\n *\r\n * # Usage\r\n * The `$swipe` service is an object with a single method: `bind`. `bind` takes an element\r\n * which is to be watched for swipes, and an object with four handler functions. See the\r\n * documentation for `bind` below.\r\n */\r\n\r\nngTouch.factory('$swipe', [function() {\r\n // The total distance in any direction before we make the call on swipe vs. scroll.\r\n var MOVE_BUFFER_RADIUS = 10;\r\n\r\n var POINTER_EVENTS = {\r\n 'mouse': {\r\n start: 'mousedown',\r\n move: 'mousemove',\r\n end: 'mouseup'\r\n },\r\n 'touch': {\r\n start: 'touchstart',\r\n move: 'touchmove',\r\n end: 'touchend',\r\n cancel: 'touchcancel'\r\n },\r\n 'pointer': {\r\n start: 'pointerdown',\r\n move: 'pointermove',\r\n end: 'pointerup',\r\n cancel: 'pointercancel'\r\n }\r\n };\r\n\r\n function getCoordinates(event) {\r\n var originalEvent = event.originalEvent || event;\r\n var touches = originalEvent.touches && originalEvent.touches.length ? originalEvent.touches : [originalEvent];\r\n var e = (originalEvent.changedTouches && originalEvent.changedTouches[0]) || touches[0];\r\n\r\n return {\r\n x: e.clientX,\r\n y: e.clientY\r\n };\r\n }\r\n\r\n function getEvents(pointerTypes, eventType) {\r\n var res = [];\r\n angular.forEach(pointerTypes, function(pointerType) {\r\n var eventName = POINTER_EVENTS[pointerType][eventType];\r\n if (eventName) {\r\n res.push(eventName);\r\n }\r\n });\r\n return res.join(' ');\r\n }\r\n\r\n return {\r\n /**\r\n * @ngdoc method\r\n * @name $swipe#bind\r\n *\r\n * @description\r\n * The main method of `$swipe`. It takes an element to be watched for swipe motions, and an\r\n * object containing event handlers.\r\n * The pointer types that should be used can be specified via the optional\r\n * third argument, which is an array of strings `'mouse'`, `'touch'` and `'pointer'`. By default,\r\n * `$swipe` will listen for `mouse`, `touch` and `pointer` events.\r\n *\r\n * The four events are `start`, `move`, `end`, and `cancel`. `start`, `move`, and `end`\r\n * receive as a parameter a coordinates object of the form `{ x: 150, y: 310 }` and the raw\r\n * `event`. `cancel` receives the raw `event` as its single parameter.\r\n *\r\n * `start` is called on either `mousedown`, `touchstart` or `pointerdown`. After this event, `$swipe` is\r\n * watching for `touchmove`, `mousemove` or `pointermove` events. These events are ignored until the total\r\n * distance moved in either dimension exceeds a small threshold.\r\n *\r\n * Once this threshold is exceeded, either the horizontal or vertical delta is greater.\r\n * - If the horizontal distance is greater, this is a swipe and `move` and `end` events follow.\r\n * - If the vertical distance is greater, this is a scroll, and we let the browser take over.\r\n * A `cancel` event is sent.\r\n *\r\n * `move` is called on `mousemove`, `touchmove` and `pointermove` after the above logic has determined that\r\n * a swipe is in progress.\r\n *\r\n * `end` is called when a swipe is successfully completed with a `touchend`, `mouseup` or `pointerup`.\r\n *\r\n * `cancel` is called either on a `touchcancel` or `pointercancel` from the browser, or when we begin scrolling\r\n * as described above.\r\n *\r\n */\r\n bind: function(element, eventHandlers, pointerTypes) {\r\n // Absolute total movement, used to control swipe vs. scroll.\r\n var totalX, totalY;\r\n // Coordinates of the start position.\r\n var startCoords;\r\n // Last event's position.\r\n var lastPos;\r\n // Whether a swipe is active.\r\n var active = false;\r\n\r\n pointerTypes = pointerTypes || ['mouse', 'touch', 'pointer'];\r\n element.on(getEvents(pointerTypes, 'start'), function(event) {\r\n startCoords = getCoordinates(event);\r\n active = true;\r\n totalX = 0;\r\n totalY = 0;\r\n lastPos = startCoords;\r\n if (eventHandlers['start']) {\r\n eventHandlers['start'](startCoords, event);\r\n }\r\n });\r\n var events = getEvents(pointerTypes, 'cancel');\r\n if (events) {\r\n element.on(events, function(event) {\r\n active = false;\r\n if (eventHandlers['cancel']) {\r\n eventHandlers['cancel'](event);\r\n }\r\n });\r\n }\r\n\r\n element.on(getEvents(pointerTypes, 'move'), function(event) {\r\n if (!active) return;\r\n\r\n // Android will send a touchcancel if it thinks we're starting to scroll.\r\n // So when the total distance (+ or - or both) exceeds 10px in either direction,\r\n // we either:\r\n // - On totalX > totalY, we send preventDefault() and treat this as a swipe.\r\n // - On totalY > totalX, we let the browser handle it as a scroll.\r\n\r\n if (!startCoords) return;\r\n var coords = getCoordinates(event);\r\n\r\n totalX += Math.abs(coords.x - lastPos.x);\r\n totalY += Math.abs(coords.y - lastPos.y);\r\n\r\n lastPos = coords;\r\n\r\n if (totalX < MOVE_BUFFER_RADIUS && totalY < MOVE_BUFFER_RADIUS) {\r\n return;\r\n }\r\n\r\n // One of totalX or totalY has exceeded the buffer, so decide on swipe vs. scroll.\r\n if (totalY > totalX) {\r\n // Allow native scrolling to take over.\r\n active = false;\r\n if (eventHandlers['cancel']) {\r\n eventHandlers['cancel'](event);\r\n }\r\n return;\r\n } else {\r\n // Prevent the browser from scrolling.\r\n event.preventDefault();\r\n if (eventHandlers['move']) {\r\n eventHandlers['move'](coords, event);\r\n }\r\n }\r\n });\r\n\r\n element.on(getEvents(pointerTypes, 'end'), function(event) {\r\n if (!active) return;\r\n active = false;\r\n if (eventHandlers['end']) {\r\n eventHandlers['end'](getCoordinates(event), event);\r\n }\r\n });\r\n }\r\n };\r\n}]);\r\n\r\n/* global ngTouch: false */\r\n\r\n/**\r\n * @ngdoc directive\r\n * @name ngSwipeLeft\r\n *\r\n * @deprecated\r\n * sinceVersion=\"1.7.0\"\r\n *\r\n * See the {@link ngTouch module} documentation for more information.\r\n *\r\n * @description\r\n * Specify custom behavior when an element is swiped to the left on a touchscreen device.\r\n * A leftward swipe is a quick, right-to-left slide of the finger.\r\n * Though ngSwipeLeft is designed for touch-based devices, it will work with a mouse click and drag\r\n * too.\r\n *\r\n * To disable the mouse click and drag functionality, add `ng-swipe-disable-mouse` to\r\n * the `ng-swipe-left` or `ng-swipe-right` DOM Element.\r\n *\r\n * Requires the {@link ngTouch `ngTouch`} module to be installed.\r\n *\r\n * @element ANY\r\n * @param {expression} ngSwipeLeft {@link guide/expression Expression} to evaluate\r\n * upon left swipe. (Event object is available as `$event`)\r\n *\r\n * @example\r\n \r\n \r\n
\r\n Some list content, like an email in the inbox\r\n
\r\n
\r\n \r\n \r\n
\r\n
\r\n \r\n angular.module('ngSwipeLeftExample', ['ngTouch']);\r\n \r\n
\r\n */\r\n\r\n/**\r\n * @ngdoc directive\r\n * @name ngSwipeRight\r\n *\r\n * @deprecated\r\n * sinceVersion=\"1.7.0\"\r\n *\r\n * See the {@link ngTouch module} documentation for more information.\r\n *\r\n * @description\r\n * Specify custom behavior when an element is swiped to the right on a touchscreen device.\r\n * A rightward swipe is a quick, left-to-right slide of the finger.\r\n * Though ngSwipeRight is designed for touch-based devices, it will work with a mouse click and drag\r\n * too.\r\n *\r\n * Requires the {@link ngTouch `ngTouch`} module to be installed.\r\n *\r\n * @element ANY\r\n * @param {expression} ngSwipeRight {@link guide/expression Expression} to evaluate\r\n * upon right swipe. (Event object is available as `$event`)\r\n *\r\n * @example\r\n \r\n \r\n
\r\n Some list content, like an email in the inbox\r\n
\r\n
\r\n \r\n \r\n
\r\n
\r\n \r\n angular.module('ngSwipeRightExample', ['ngTouch']);\r\n \r\n
\r\n */\r\n\r\nfunction makeSwipeDirective(directiveName, direction, eventName) {\r\n ngTouch.directive(directiveName, ['$parse', '$swipe', function($parse, $swipe) {\r\n // The maximum vertical delta for a swipe should be less than 75px.\r\n var MAX_VERTICAL_DISTANCE = 75;\r\n // Vertical distance should not be more than a fraction of the horizontal distance.\r\n var MAX_VERTICAL_RATIO = 0.3;\r\n // At least a 30px lateral motion is necessary for a swipe.\r\n var MIN_HORIZONTAL_DISTANCE = 30;\r\n\r\n return function(scope, element, attr) {\r\n var swipeHandler = $parse(attr[directiveName]);\r\n\r\n var startCoords, valid;\r\n\r\n function validSwipe(coords) {\r\n // Check that it's within the coordinates.\r\n // Absolute vertical distance must be within tolerances.\r\n // Horizontal distance, we take the current X - the starting X.\r\n // This is negative for leftward swipes and positive for rightward swipes.\r\n // After multiplying by the direction (-1 for left, +1 for right), legal swipes\r\n // (ie. same direction as the directive wants) will have a positive delta and\r\n // illegal ones a negative delta.\r\n // Therefore this delta must be positive, and larger than the minimum.\r\n if (!startCoords) return false;\r\n var deltaY = Math.abs(coords.y - startCoords.y);\r\n var deltaX = (coords.x - startCoords.x) * direction;\r\n return valid && // Short circuit for already-invalidated swipes.\r\n deltaY < MAX_VERTICAL_DISTANCE &&\r\n deltaX > 0 &&\r\n deltaX > MIN_HORIZONTAL_DISTANCE &&\r\n deltaY / deltaX < MAX_VERTICAL_RATIO;\r\n }\r\n\r\n var pointerTypes = ['touch'];\r\n if (!angular.isDefined(attr['ngSwipeDisableMouse'])) {\r\n pointerTypes.push('mouse');\r\n }\r\n $swipe.bind(element, {\r\n 'start': function(coords, event) {\r\n startCoords = coords;\r\n valid = true;\r\n },\r\n 'cancel': function(event) {\r\n valid = false;\r\n },\r\n 'end': function(coords, event) {\r\n if (validSwipe(coords)) {\r\n scope.$apply(function() {\r\n element.triggerHandler(eventName);\r\n swipeHandler(scope, {$event: event});\r\n });\r\n }\r\n }\r\n }, pointerTypes);\r\n };\r\n }]);\r\n}\r\n\r\n// Left is negative X-coordinate, right is positive.\r\nmakeSwipeDirective('ngSwipeLeft', -1, 'swipeleft');\r\nmakeSwipeDirective('ngSwipeRight', 1, 'swiperight');\r\n\r\n\r\n\r\n})(window, window.angular);","/**\r\n * @namespace jwsdwProductDetail\r\n */\r\n'use strict';\r\n\r\n(function (angular) {\r\n\r\n config.$inject = ['$locationProvider', '$compileProvider'];\r\n angular.module('jwsdw.productDetail', [\r\n 'jwsdw.ocapi',\r\n 'jwsdw.tracking',\r\n 'jwsdw.util',\r\n 'jwsdw.breadcrumbs',\r\n 'jwsdw.stickyAddToCart',\r\n 'jwsp.picture',\r\n 'jwsp.util',\r\n 'youtube-embed',\r\n 'svg-embed',\r\n 'ngTouch',\r\n 'ngSanitize'\r\n ]).config(config);\r\n\r\n /**\r\n * Config function that specifies configuration for the jwsdw product detail module.\r\n * @param {Object} $locationProvider location provider to access the window.location property.\r\n * @param {Object} $compileProvider compile provider disables adding of internal debug info.\r\n * @returns {void}\r\n */\r\n function config($locationProvider, $compileProvider) {\r\n $locationProvider.html5Mode({ 'enabled': true, 'requireBase': false, 'rewriteLinks': false });\r\n $compileProvider.debugInfoEnabled(false);\r\n }\r\n}(angular));","'use strict';\r\n\r\n(function (angular) {\r\n angular\r\n .module('jwsdw.productDetail')\r\n .constant('PRODUCT_DATA', window.jwsdwProductDetailSettings.data)\r\n .constant('BAZAARVOICE_ACTIVE', window.jwsdwProductDetailSettings.isBazaarVoiceActive)\r\n .constant('BASE_URL', window.jwsdwSettings.baseUrl)\r\n .constant('IMAGE_BASE_URL', window.jwsdwSettings.productGetImageBaseUrl)\r\n .constant('DISABLE_HISTORY_API', window.jwsdwProductDetailSettings.disableHistoryApi)\r\n .constant('DEACTIVATE_AVAILABILITY_DIALOG_FOR_SALES', window.jwsdwProductDetailSettings.deactivateAvailabilityDialogForSales)\r\n .constant('IS_BAZAARVOICE_ACTIVE', window.jwsdwProductDetailSettings.isBazaarVoiceActive)\r\n .constant('DISPLAY_VIDEO', window.jwsdwProductDetailSettings.displayVideo)\r\n .constant('SIZEGUIDE', window.jwsdwSizeGuide)\r\n .constant('NOTIFY_ME_ENABLED', window.jwsdwProductDetailSettings.notifyMeEnabled)\r\n .constant('SETTINGS', window.jwsdwSettings);\r\n}(angular));","'use strict';\r\n\r\n(function (angular) {\r\n\r\n ProductDetailController.$inject = ['$window', '$scope', '$location', '$timeout', 'dataService', 'productService', 'ocapiBasketService', 'trackSwatchChange', 'generalTracking', 'util', 'PRODUCT_DATA', 'IMAGE_BASE_URL', 'DISABLE_HISTORY_API', 'DEACTIVATE_AVAILABILITY_DIALOG_FOR_SALES', 'DISPLAY_VIDEO', 'IS_BAZAARVOICE_ACTIVE', 'NOTIFY_ME_ENABLED', 'SETTINGS'];\r\n angular\r\n .module('jwsdw.productDetail')\r\n .controller('ProductDetailController', ProductDetailController);\r\n\r\n /**\r\n * @class jwsdwProductDetail.ProductDetailController\r\n * @description Initializes product detail page functionalities\r\n * @param {Object} $window browser window object\r\n * @param {Object} $scope current scope\r\n * @param {Object} $location location object to access the window.location property.\r\n * @param {Object} $timeout timeout service provided through angular\r\n * @param {Object} dataService data service that provides access to the product data layer\r\n * @param {Object} productService service to provide product information (used for creation of variants item)\r\n * @param {Object} ocapiBasketService ocapi basket service that provides access to the basket resource\r\n * @param {Object} trackSwatchChange tracking service that listens to swatch change events\r\n * @param {Object} generalTracking tracking service that provides access to the genral tracking functionality\r\n * @param {Object} util util service that provides access to global functions\r\n * @param {Object} PRODUCT_DATA object holding all product data provided trough jwsdwProductDetailSettings\r\n * @param {String} IMAGE_BASE_URL base url to retrieve product images in a specific size\r\n * @param {Boolean} DISABLE_HISTORY_API true if client does not allow for use of history api\r\n * (provided through jwsdwProductDetailSettings)\r\n * @param {Boolean} DEACTIVATE_AVAILABILITY_DIALOG_FOR_SALES true if availability dialog should be disabled for sale products\r\n * (provided through jwsdwProductDetailSettings)\r\n * @param {Boolean} DISPLAY_VIDEO boolean if video should be shown on pdp (provided through jwsdwProductDetailSettings)\r\n * @param {Boolean} IS_BAZAARVOICE_ACTIVE true if bazaarvoice should be activated on pdp (provided though jwsdwProductDetailSettings)\r\n * @param {Boolean} NOTIFY_ME_ENABLED true if notify me should be shown\r\n * @param {Object} SETTINGS global settings\r\n * @constructor\r\n */\r\n function ProductDetailController($window, $scope, $location, $timeout, dataService, productService, ocapiBasketService, trackSwatchChange, generalTracking, util, PRODUCT_DATA, IMAGE_BASE_URL, DISABLE_HISTORY_API, DEACTIVATE_AVAILABILITY_DIALOG_FOR_SALES, DISPLAY_VIDEO, IS_BAZAARVOICE_ACTIVE, NOTIFY_ME_ENABLED, SETTINGS) { // eslint-disable-line\r\n var vm = this,\r\n _oldSize,\r\n _oldColor;\r\n\r\n vm.dataService = dataService;\r\n //constants mapping\r\n vm.productGetImageBaseUrl = IMAGE_BASE_URL;\r\n vm.deactivateAvailabilityDialogForSales = DEACTIVATE_AVAILABILITY_DIALOG_FOR_SALES;\r\n vm.isBazaarVoiceActive = IS_BAZAARVOICE_ACTIVE;\r\n vm.displayVideo = DISPLAY_VIDEO;\r\n vm.isGiftcard = PRODUCT_DATA.isGiftcard;\r\n\r\n vm.masterID = PRODUCT_DATA.masterID;\r\n vm.mediaId = 'image0';\r\n vm.selectedSize = null;\r\n vm.selectedColor = null;\r\n vm.imageViewerVisible = false;\r\n vm.contentVisible = true;\r\n vm.reservationStore = null;\r\n vm.giftcardInput = null;\r\n vm.giftcardDefaultPrices = window.jwsdwProductDetailSettings.giftcardDefaultPrices;\r\n vm.currency = window.jwsdwSettings.priceFormat.replace(/[\\d\\s,.]/g, '');\r\n vm.displayNoSizeSelectedWarning = false;\r\n vm.addingProductToBasket = false;\r\n vm.addingProductToBasketExpress = false;\r\n vm.expressCheckout = false;\r\n vm.notifyMeEnabled = NOTIFY_ME_ENABLED;\r\n vm.scrollToSizes = scrollToSizes;\r\n\r\n vm.imageViewerEnabled = false;\r\n vm.selectNextMediaItem = selectNextMediaItem;\r\n vm.selectPrevMediaItem = selectPrevMediaItem;\r\n vm.showStickyCartButton = false;\r\n\r\n vm.wishlistCount = SETTINGS.wishlistCount || 0;\r\n vm.maxWishlistItemsForGuest = SETTINGS.maxWishlistItemsForGuest || 0;\r\n vm.wishlist = SETTINGS.wishlist;\r\n\r\n // holds viewport string of directive jwsp/util/matchMedia ('small', 'medium', 'large')\r\n vm.viewport = '';\r\n\r\n //public methods\r\n vm.openStoreAvailabilityListPicker = openStoreAvailabilityListPicker;\r\n vm.openGiftcardAmountPicker = openGiftcardAmountPicker;\r\n vm.addToBasket = addToBasket;\r\n vm.openNotifyMe = openNotifyMe;\r\n vm.addToWishlist = addToWishlist;\r\n vm.removeFromWishlist = removeFromWishlist;\r\n vm.addToWishlistLoading = false;\r\n vm.isWishlisted = false;\r\n vm.showImageViewer = showImageViewer;\r\n vm.getFormattedAddress = getFormattedAddress;\r\n vm.setGiftcardPrice = setGiftcardPrice;\r\n vm.formatPriceWithCurency = formatPriceWithCurency;\r\n vm.giftcardPriceIsZero = giftcardPriceIsZero;\r\n vm.onSubmitGiftcardInput = onSubmitGiftcardInput;\r\n\r\n vm.currentId = currentId;\r\n vm.notifyMeFallbackColor = null;\r\n\r\n vm.getProductFlatIndex = getProductFlatIndex;\r\n vm.openSizeGuide = openSizeGuide;\r\n vm.openFitGuide = openFitGuide;\r\n\r\n $window.jwsdwProductDetailCtrl = {\r\n 'openSizeGuide': openSizeGuide,\r\n 'openFitGuide': openFitGuide\r\n };\r\n\r\n /**\r\n * @description Method to run the initialization of the product detail module\r\n * @returns {void}\r\n */\r\n this.$onInit = function () {\r\n var fixedCartButton = $(document).find(\".jwsdw-pdp-cartOptions .jwsdw-pdp-cartButton\");\r\n\r\n dataService.update();\r\n\r\n vm.selectedSize = dataService.sizes().length > 1 ? null : dataService.initialSize();\r\n vm.selectedColor = dataService.initialColor();\r\n vm.mediaData = vm.dataService.mediaData();\r\n vm.notifyMeFallbackColor = vm.dataService.availabilityId() === 'NOT_AVAILABLE' ? dataService.initialColor() : null;\r\n\r\n _updateProductPromotion();\r\n\r\n $window.jwsdwMediator.publish(\r\n 'updateBreadcrumbs',\r\n PRODUCT_DATA.categoryPath.concat({\r\n 'text': PRODUCT_DATA.name,\r\n 'url': $window.location.pathname\r\n })\r\n );\r\n\r\n setTimeout(function () {\r\n fixedCartButton = $(document).find(\".jwsdw-pdp-cartOptions .jwsdw-pdp-cartButton\");\r\n vm.showStickyCartButton = _elementIsAboveViewport(fixedCartButton);\r\n updateStickyAddToCart();\r\n }, 0);\r\n\r\n vm.isWishlisted = _isWishlisted();\r\n\r\n // watch selected size and color\r\n $scope.$watch('vm.selectedColor', window.jwsdwUtil.debounce(50, function(newValue) {\r\n var newColor = newValue || vm.selectedColor;\r\n\r\n $timeout(function () {\r\n $scope.$apply(function() {\r\n swatchChange(_oldSize, newColor);\r\n });\r\n });\r\n\r\n _oldColor = newColor;\r\n }));\r\n\r\n $scope.$watch('vm.selectedSize', window.jwsdwUtil.debounce(50, function(newValue) {\r\n var newSize = newValue || vm.selectedSize;\r\n $scope.$apply(function() {\r\n swatchChange(newSize, _oldColor || vm.notifyMeFallbackColor, true);\r\n });\r\n _oldSize = newSize;\r\n }));\r\n\r\n /* Sync scoped wishlist with window wishlist */\r\n $scope.$watch('vm.wishlist.products', function(products) {\r\n SETTINGS.wishlist.products = products;\r\n }, true);\r\n\r\n /**\r\n * @description Method to execute swatch change logic\r\n * @param {String} newSize new size\r\n * @param {String} newColor new color\r\n * @param {Boolean} preventImageReload Boolean value for determing if images need to reload\r\n * @returns {void}\r\n */\r\n function swatchChange(newSize, newColor, preventImageReload) {\r\n updateStickyAddToCart();\r\n\r\n if (!_oldSize) {\r\n _oldSize = dataService.initialSize().id;\r\n }\r\n if (!_oldColor) {\r\n _oldColor = dataService.initialColor().id;\r\n }\r\n if (newSize && newColor && _oldSize && _oldColor) {\r\n vm.mediaId = null;\r\n dataService.update(newSize.id, newColor.id, preventImageReload);\r\n\r\n // reset current media id if it is not available anymore\r\n // e. g. when the new color hasnt got this image\r\n if (!dataService.mediaById(vm.mediaId) && dataService.allMedia()[0]) {\r\n vm.mediaId = dataService.allMedia()[0].id;\r\n }\r\n\r\n // update the browser history and url to new variation\r\n _updateMeta(newSize, newColor);\r\n\r\n if (newSize.id !== _oldSize.id || newColor.id !== _oldColor.id) {\r\n // send swatch changes to the tag manager\r\n trackSwatchChange.send({\r\n 'productName': dataService.productName(),\r\n 'id': dataService.productId(),\r\n 'ats': dataService.ats(),\r\n 'colorName': newColor.name,\r\n 'sizeName': newSize.id,\r\n 'priceWithoutVAT': dataService.priceWithoutVAT()\r\n });\r\n\r\n // publish event for storeAvailabilityPicker\r\n window.jwsdwMediator.publish('changeProductId', currentId());\r\n }\r\n _updateProductPromotion();\r\n } else {\r\n dataService.update((newSize || dataService.initialSize()).id, (newColor || dataService.initialColor()).id);\r\n\r\n // update the browser history and url to new variation\r\n _updateMeta(\r\n newSize || dataService.initialSize(),\r\n newColor || dataService.initialColor()\r\n );\r\n dataService.update(\r\n newSize ? newSize.id : null,\r\n newColor ? newColor.id : null\r\n );\r\n _updateProductPromotion();\r\n }\r\n _handleOpenNotifyMe();\r\n\r\n /* Update wishlisted status */\r\n vm.isWishlisted = _isWishlisted();\r\n }\r\n\r\n // watch zoom availability\r\n $scope.$watchGroup(['vm.mediaId'], function(values) {\r\n var mediaId = values[0],\r\n media;\r\n\r\n if (mediaId) {\r\n media = dataService.mediaById(mediaId);\r\n\r\n vm.imageViewerEnabled = media.type === 'image';\r\n }\r\n });\r\n\r\n // watch image viewer visibility\r\n $scope.$watch('vm.imageViewerVisible', function(visible) {\r\n vm.contentVisible = !visible;\r\n $window.jwsdwMediator.publish('toggleSiteVisibility', !visible);\r\n });\r\n\r\n $window.jwsdwMediator.subscribe('closePicker', function(type) {\r\n if (type === 'loginPicker') {\r\n $scope.$apply(function() {\r\n vm.addToWishlistLoading = false;\r\n });\r\n }\r\n });\r\n\r\n $window.jwsdwMediator.subscribe('closeOverlay', function(type) {\r\n if (type === 'loginPicker') {\r\n $scope.$apply(function() {\r\n vm.addToWishlistLoading = false;\r\n });\r\n }\r\n });\r\n\r\n $window.jwsdwMediator.subscribe('scrollToSizes', function() {\r\n vm.displayNoSizeSelectedWarning = true;\r\n if (screen.width < 600) {\r\n $('html, body').animate({\r\n 'scrollTop': angular.element('.jwsdw-product-swatchSelection').offset().top - 100\r\n });\r\n }\r\n });\r\n\r\n if ($location.search().addToWishlist) {\r\n addToWishlist(dataService.productId(vm.selectedSize.id, vm.selectedColor.id));\r\n $location.search('addToWishlist', null);\r\n }\r\n\r\n // listen to pop state events to react to history changes\r\n if (_browserSupportsHistoryAPI()) {\r\n $window.addEventListener('popstate', function(event) {\r\n if (event.state && event.state.size && event.state.color) {\r\n $scope.$apply(function() {\r\n vm.selectedSize = vm.dataService.sizeById(event.state.size);\r\n vm.selectedColor = vm.dataService.colorById(event.state.color);\r\n });\r\n }\r\n });\r\n }\r\n\r\n $window.jwsdwMediator.subscribe('changeSettings', function(settings) {\r\n $scope.$apply(function() {\r\n // currently this just watches and processes 'imageViewType'\r\n // but could be extended by something like a SettingsService to\r\n // be responsible for all changes\r\n if (settings.imageViewType) {\r\n $window.jwsdwSettings.imageViewType = settings.imageViewType;\r\n }\r\n });\r\n });\r\n $window.jwsdwMediator.subscribe('showImageViewer', function() {\r\n if (vm.imageViewerEnabled && dataService.mediaById(vm.mediaId).type === 'image') {\r\n vm.imageViewerVisible = true;\r\n }\r\n });\r\n\r\n $window.jwsdwMediator.subscribe('addToBasket', function() {\r\n if (!vm.addingProductToBasket &&\r\n !vm.addingProductToBasketExpress &&\r\n vm.selectedColor.orderable &&\r\n vm.dataService.price() !== 'N/A' ||\r\n (vm.isGiftcard && vm.giftcardpricing)) {\r\n setGiftcardPrice(vm.giftcardpricing);\r\n addToBasket();\r\n }\r\n });\r\n\r\n $window.jwsdwMediator.subscribe('setGiftcardAmount', function(giftCardAmount) {\r\n $timeout(function() {\r\n $scope.$apply(function() {\r\n setGiftcardPrice(giftCardAmount);\r\n });\r\n });\r\n });\r\n\r\n $window.jwsdwMediator.subscribe('setWishlistCount', function(count) {\r\n $timeout(function() {\r\n $scope.$apply(function() {\r\n vm.wishlistCount = count;\r\n });\r\n });\r\n });\r\n\r\n\r\n $window.addEventListener('scroll', $window.jwsdwUtil.throttle(_updateStickyCartButton, 50), window.jwsdwUtil.supportsPassiveEvents() ? { 'passive': true } : false);\r\n $window.addEventListener('mousewheel', $window.jwsdwUtil.throttle(_updateStickyCartButton, 50), window.jwsdwUtil.supportsPassiveEvents() ? { 'passive': true } : false);\r\n\r\n /**\r\n * @description Method to update sticky cart button\r\n * @returns {void}\r\n */\r\n function _updateStickyCartButton() {\r\n $scope.$apply(function() {\r\n fixedCartButton = $(document).find(\".jwsdw-pdp-cartOptions .jwsdw-pdp-cartButton\");\r\n vm.showStickyCartButton = _elementIsAboveViewport(fixedCartButton);\r\n updateStickyAddToCart();\r\n });\r\n }\r\n };\r\n\r\n\r\n /**\r\n * @description Method to detect if element is visible in viewport\r\n * @param {Object} element DOM element\r\n * @returns {Boolean} true if element is visible\r\n */\r\n function _elementIsAboveViewport(element) {\r\n var scrollTop = angular.element($window).scrollTop();\r\n\r\n if (element.length) {\r\n if (scrollTop > element.offset().top + element.height()) {\r\n $('#jwsdw-backToTop-sticky').addClass('jwsdw-backToTop-sticky-move');\r\n return true;\r\n }\r\n }\r\n $('#jwsdw-backToTop-sticky').removeClass('jwsdw-backToTop-sticky-move');\r\n return false;\r\n }\r\n\r\n /**\r\n * @description Method to switch to the next thumbnail\r\n * @returns {void}\r\n * @memberOf jwsdwProductDetail.jwsdwThumbGallery.ThumbGalleryController\r\n */\r\n function selectNextMediaItem() {\r\n var media = dataService.allMedia(vm.hideMedia),\r\n currentIndex = dataService.mediaIndexById(vm.mediaId),\r\n nextIndex;\r\n\r\n nextIndex = currentIndex + 1;\r\n\r\n if (nextIndex < media.length) {\r\n vm.mediaId = media[nextIndex].id;\r\n } else {\r\n vm.mediaId = media[0].id;\r\n }\r\n }\r\n\r\n /**\r\n * @description Method to switch to the previous thumbnail\r\n * @returns {void}\r\n * @memberOf jwsdwProductDetail.jwsdwThumbGallery.ThumbGalleryController\r\n */\r\n function selectPrevMediaItem() {\r\n var media = dataService.allMedia(vm.hideMedia),\r\n currentIndex = dataService.mediaIndexById(vm.mediaId),\r\n prevIndex;\r\n\r\n prevIndex = currentIndex - 1;\r\n\r\n if (prevIndex >= 0) {\r\n vm.mediaId = media[prevIndex].id;\r\n } else {\r\n vm.mediaId = media[media.length - 1].id;\r\n }\r\n }\r\n\r\n /**\r\n * @description Metho to get index of flat images\r\n * @returns {Number} indexFlat\r\n */\r\n function getProductFlatIndex() {\r\n var length = dataService.imageData().length;\r\n\r\n // determine default image that only shows the flat\r\n if (length >= 6) {\r\n return 5;\r\n }\r\n\r\n return length - 1;\r\n }\r\n\r\n /**\r\n * @description Method to open fit guide picker\r\n * @param {number} level the level in which the picker is opened (1, 2 or 3)\r\n * @returns {Number} indexFlat\r\n */\r\n function openFitGuide(level) {\r\n $window.jwsdwMediator.publish('openPicker', 'fitGuidePicker', {\r\n 'gender': $window.jwsdwSizeGuide.gender,\r\n 'type': $window.jwsdwSizeGuide.type,\r\n 'level': level || 1,\r\n 'availableSizes': dataService.sizes().map(function(size) {\r\n return size.id.replace('B', '');\r\n })\r\n });\r\n }\r\n\r\n /**\r\n * @description Method to open size guide picker\r\n * @param {number} level the level in which the picker is opened (1, 2 or 3)\r\n * @returns {Number} indexFlat\r\n */\r\n function openSizeGuide(level) {\r\n $window.jwsdwMediator.publish('openPicker', 'sizeGuidePicker', {\r\n 'gender': $window.jwsdwSizeGuide.gender,\r\n 'type': $window.jwsdwSizeGuide.type,\r\n 'level': level || 1,\r\n 'availableSizes': dataService.sizes().map(function(size) {\r\n return size.id.replace('B', '');\r\n })\r\n });\r\n }\r\n\r\n /**\r\n * @description Method to get the id of the current product.\r\n * @returns {String} the id of the current product\r\n */\r\n function currentId() {\r\n return dataService.productId();\r\n }\r\n\r\n /**\r\n * @description Method to open notifyme\r\n * @returns {void}\r\n */\r\n function openNotifyMe () {\r\n let selectedColor = vm.notifyMeFallbackColor && vm.notifyMeFallbackColor.id || vm.selectedColor.id;\r\n\r\n if (!vm.selectedSize) {\r\n vm.displayNoSizeSelectedWarning = true;\r\n return;\r\n }\r\n\r\n $window.jwsdwMediator.publish('openPicker', 'notifyMePicker', {\r\n 'width': 1,\r\n 'productID': dataService.productId(vm.selectedSize.id, selectedColor),\r\n 'productName': dataService.productName(vm.selectedSize.id, selectedColor),\r\n 'productSize': vm.selectedSize.name,\r\n 'isGiftCard': vm.isGiftcard,\r\n 'productColor': vm.notifyMeFallbackColor && vm.notifyMeFallbackColor.name || vm.selectedColor.name,\r\n 'image': vm.dataService.imageUrl(dataService.productId(vm.selectedSize.id, selectedColor), 0, vm.dataService.transforms[vm.viewport], 'bone5'),\r\n 'isVisible': true,\r\n 'level': 2\r\n });\r\n\r\n // Script Notify Me Button Click (open)\r\n window.dataLayer = window.dataLayer || [];\r\n window.dataLayer.push({\r\n 'event': 'ce.misc',\r\n 'eventCategory': 'MISC',\r\n 'eventAction': 'Notify Me',\r\n 'eventLabel': 'open',\r\n 'eventValue': undefined,\r\n 'nonInteraction': false,\r\n 'selection': undefined\r\n });\r\n return true;\r\n }\r\n\r\n /**\r\n * @description Method to open notifyme\r\n * @returns {undefined}\r\n */\r\n function _handleOpenNotifyMe () {\r\n if (vm.dataService.availabilityId() === 'NOT_AVAILABLE') {\r\n openNotifyMe();\r\n }\r\n }\r\n\r\n /**\r\n * @description Method to add the current product to the basket using jwsdw.ocapi.ocapiBasketService\r\n * @param {Boolean} expressCheckout true if it is an express buying process\r\n * @returns {void}\r\n * @memberOf jwsdwProductDetail.ProductDetailController\r\n */\r\n function addToBasket(expressCheckout) {\r\n var productData = {},\r\n product = {},\r\n isExpressCheckout = expressCheckout;\r\n\r\n\r\n if (!vm.selectedSize) {\r\n vm.displayNoSizeSelectedWarning = true;\r\n return;\r\n }\r\n\r\n vm.addingProductToBasket = true;\r\n\r\n product = {\r\n 'id': dataService.productId(),\r\n 'name': dataService.productName(),\r\n 'isBonusProduct': false,\r\n 'price': vm.dataService.price() || vm.giftcardpricing,\r\n 'size': vm.selectedSize.name,\r\n 'color': vm.selectedColor.name\r\n },\r\n productData.products = [\r\n product\r\n ];\r\n\r\n if (vm.isGiftcard) {\r\n productData.price = vm.priceOld;\r\n }\r\n\r\n productData.actionArgs = 'productDetail';\r\n ocapiBasketService.addViaPipeline([dataService.productId()], productData, isExpressCheckout).then(success, error);\r\n\r\n /**\r\n * @description Method on success\r\n * @returns {void}\r\n */\r\n function success() {\r\n vm.addingProductToBasket = false;\r\n vm.addingProductToBasketExpress = false;\r\n updateStickyAddToCart();\r\n }\r\n\r\n /**\r\n * @description Method on error\r\n * @returns {void}\r\n */\r\n function error() {\r\n vm.addingProductToBasket = false;\r\n vm.addingProductToBasketExpress = false;\r\n updateStickyAddToCart();\r\n }\r\n }\r\n\r\n /**\r\n * @description Method to update sticky add to cart button via mediator\r\n * @returns {void}\r\n * @memberOf jwsdwProductDetail.ProductDetailController\r\n */\r\n function updateStickyAddToCart() {\r\n $window.jwsdwMediator.publish('updateStickyAddToCart', {\r\n 'addingProductToBasket': vm.addingProductToBasket,\r\n 'addingProductToBasketExpress': vm.addingProductToBasketExpress = false,\r\n 'isGiftcard': vm.isGiftcard,\r\n 'giftcardpricing': vm.giftcardpricing,\r\n 'selectedSize': vm.selectedSize,\r\n 'dataService': vm.dataService,\r\n 'showStickyCartButton': vm.showStickyCartButton\r\n });\r\n }\r\n\r\n /**\r\n * @description Method to shows the fullscreen image viewer as long as the current media item is an image\r\n * @returns {void}\r\n * @memberOf jwsdwProductDetail.ProductDetailController\r\n */\r\n function showImageViewer() {\r\n if (vm.imageViewerEnabled && dataService.mediaById(vm.mediaId).type === 'image') {\r\n vm.imageViewerVisible = true;\r\n }\r\n }\r\n\r\n /**\r\n * @description Method to open store availability list picker\r\n * @returns {void}\r\n * @memberOf jwsdwProductDetail.ProductDetailController\r\n */\r\n function openStoreAvailabilityListPicker() {\r\n if (!vm.selectedSize) {\r\n vm.displayNoSizeSelectedWarning = true;\r\n return;\r\n }\r\n\r\n window.jwsdwMediator.publish('openPicker', 'storeAvailabilityListPicker', {\r\n 'productId': currentId(),\r\n 'variants': dataService.variants()\r\n }, true);\r\n\r\n generalTracking.send({\r\n 'action': 'openAvailabilityDialog',\r\n 'type': 'openAvailabilityDialog'\r\n });\r\n\r\n window.dataLayer = window.dataLayer || [];\r\n window.dataLayer.push({\r\n 'event': 'ce.misc',\r\n 'eventCategory': 'MISC',\r\n 'eventAction': 'Product Availability',\r\n 'eventLabel': 'open',\r\n 'eventValue': undefined,\r\n 'nonInteraction': false,\r\n 'selection': undefined\r\n });\r\n }\r\n\r\n /**\r\n * @description Method to open the giftcard picker\r\n * @returns {void}\r\n * @memberOf jwsdwProductDetail.ProductDetailController\r\n */\r\n function openGiftcardAmountPicker() {\r\n window.jwsdwMediator.publish('openPicker', 'giftcardAmountPicker', {\r\n 'isVisible': true\r\n });\r\n }\r\n\r\n /**\r\n * @description Method to set the gift card price and hide the giftcard picker\r\n * @param {String} amount actual price as clean number\r\n * @returns {void}\r\n * @memberOf jwsdwProductDetail.ProductDetailController\r\n */\r\n function setGiftcardPrice(amount) {\r\n vm.priceOld = amount;\r\n vm.giftcardpricing = formatPriceWithCurency(amount, false);\r\n updateStickyAddToCart();\r\n }\r\n\r\n /**\r\n * @description Method to format the price with the locale currency\r\n * @param {String} price actual price as clean number\r\n * @param {Boolean} noSpace if the space between the amount and the currency is not needed\r\n * @returns {String} formated price with the currency\r\n * @memberOf jwsdwProductDetail.ProductDetailController\r\n */\r\n function formatPriceWithCurency(price, noSpace) {\r\n let positionOfCurrency = window.jwsdwSettings.priceFormat.indexOf(vm.currency),\r\n firstDigit = window.jwsdwSettings.priceFormat.search(/\\d/),\r\n formatedPrice = positionOfCurrency < firstDigit ? `${vm.currency} ${price}` : `${price} ${vm.currency}`;\r\n if (noSpace) {\r\n formatedPrice = formatedPrice.replace(/\\s/g, '');\r\n }\r\n return formatedPrice;\r\n }\r\n\r\n /**\r\n * @description Method to format the price with the locale currency\r\n * @returns {Boolean} if the price is 0\r\n * @memberOf jwsdwProductDetail.ProductDetailController\r\n */\r\n function giftcardPriceIsZero() {\r\n let regEx = /^(?!.*\\d.*\\d)(?=.*\\d)0(?=\\D|$)/;\r\n return regEx.test(vm.giftcardpricing);\r\n }\r\n\r\n /**\r\n * @description Method for submitting the giftcard input.\r\n * @param {Object} form form object with validation information\r\n * @param {String} giftCardAmount current user input of giftcard amount\r\n * @returns {void}\r\n * @memberOf jwsdwProductDetail.ProductDetailController\r\n */\r\n function onSubmitGiftcardInput(form, giftCardAmount) {\r\n if (giftCardAmount && form.$valid) {\r\n setGiftcardPrice(giftCardAmount);\r\n }\r\n }\r\n\r\n /**\r\n * @description Method to add product to wishlist\r\n * @param {String} productId the product id\r\n * @returns {void}\r\n * @memberOf jwsdwProductDetail.ProductDetailController\r\n */\r\n function addToWishlist(productId) {\r\n vm.addToWishlistLoading = true;\r\n\r\n if (!window.jwsdwSettings.customerAuthenticated && vm.wishlistCount === vm.maxWishlistItemsForGuest) {\r\n window.jwsdwMediator.publish('openPicker', 'loginPicker', {\r\n 'showMaxGuestWishlistMessage': true,\r\n 'callback': function() {\r\n addToWishlist(productId);\r\n }\r\n });\r\n return;\r\n }\r\n productService.addToWishlist(productId).then(addToWishlistSuccess, addToWishlistError);\r\n\r\n /**\r\n * @description Method on success\r\n * @param {Object} data response data\r\n * @returns {void}\r\n */\r\n function addToWishlistSuccess(data) {\r\n vm.addToWishlistLoading = false;\r\n vm.isWishlisted = true;\r\n vm.wishlist.products.push({\r\n 'id': data.itemId,\r\n 'pid': data.productId,\r\n 'color': data.color\r\n });\r\n\r\n window.jwsdwMediator.publish('setWishlistCount', data.items);\r\n }\r\n\r\n /**\r\n * @description Method on error\r\n * @returns {void}\r\n */\r\n function addToWishlistError() {\r\n vm.addToWishlistLoading = false;\r\n // error handling\r\n }\r\n }\r\n\r\n /**\r\n * @description Method to remove product from wishlist\r\n * @returns {void}\r\n * @memberOf jwsdwProductDetail.ProductDetailController\r\n */\r\n function removeFromWishlist() {\r\n vm.addToWishlistLoading = true;\r\n\r\n let productListId = vm.wishlist.id;\r\n let color = vm.selectedColor.id;\r\n let itemIndex = vm.wishlist.products.findIndex((product) => product.pid === vm.masterID && product.color === color);\r\n let itemId = vm.wishlist.products[itemIndex].id;\r\n\r\n productService.removeFromWishlist(productListId, itemId).then(removeFromWishlistSuccess, removeFromWishlistError);\r\n\r\n /**\r\n * @description Method on success\r\n * @param {Object} data response data\r\n * @returns {void}\r\n */\r\n function removeFromWishlistSuccess(data) {\r\n vm.addToWishlistLoading = false;\r\n vm.isWishlisted = false;\r\n vm.wishlist.products.splice(itemIndex, 1);\r\n window.jwsdwMediator.publish('setWishlistCount', data.items);\r\n }\r\n\r\n /**\r\n * @description Method on error\r\n * @returns {void}\r\n */\r\n function removeFromWishlistError() {\r\n vm.addToWishlistLoading = false;\r\n // error handling\r\n }\r\n }\r\n\r\n /**\r\n * @description Method to get a formatted representation of adress1 and adress2.\r\n * @param {Object} store object with store data (e.g. address)\r\n * @param {String} store.address1 address 1\r\n * @param {String} store.address2 address 2\r\n * @returns {String} formatted adress (concatenation of adress1 and adress2)\r\n * @memberOf jwsdwProductDetail.ProductDetailController\r\n */\r\n function getFormattedAddress(store) {\r\n var formattedAddress = '';\r\n\r\n if (!store) {\r\n return '';\r\n }\r\n\r\n if (store.address1) {\r\n formattedAddress += store.address1;\r\n }\r\n\r\n if (store.address1 && store.address2) {\r\n formattedAddress += ', ';\r\n }\r\n\r\n if (store.address2) {\r\n formattedAddress += store.address2;\r\n }\r\n\r\n return formattedAddress;\r\n }\r\n\r\n /**\r\n * @description Method to update the URL if size or color changes (without reloading the page)\r\n * @param {Object} size current size\r\n * @param {Object} color current color\r\n * @returns {void}\r\n * @memberOf jwsdwProductDetail.ProductDetailController\r\n */\r\n function _updateMeta(size, color) {\r\n var newUrl,\r\n state,\r\n path,\r\n productId = vm.dataService.productId(),\r\n titleParts = document.title.split(' - ');\r\n\r\n titleParts[1] = color.name + ' ' + size.id;\r\n document.title = titleParts.join(' - ');\r\n\r\n if (_browserSupportsHistoryAPI()) {\r\n // only replace state if product id has changed\r\n if ($window.location.pathname.indexOf(productId) === -1) {\r\n\r\n // Create new URL (preserve product name in URL Path)\r\n path = $location.path().split('/')[1];\r\n newUrl = path + '/' + productId + '.html' + $window.location.search;\r\n\r\n $location.url(newUrl);\r\n $location.replace();\r\n\r\n state = {\r\n 'size': size.id,\r\n 'color': color.id\r\n };\r\n $window.history.replaceState(state, '', $location.absUrl());\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * @description Method to check if the browser supports HTML5 HistoryAPI.\r\n * @returns {Boolean} true if the browser supports the html 5 history API false otherwise\r\n * @memberOf jwsdwProductDetail.ProductDetailController\r\n */\r\n function _browserSupportsHistoryAPI() {\r\n return !DISABLE_HISTORY_API && $window.history && $window.history.pushState;\r\n }\r\n /**\r\n * @description Method to scroll to size select\r\n * @returns {void}\r\n * @memberOf jwsdwProductDetail.ProductDetailController\r\n */\r\n function scrollToSizes() {\r\n $window.jwsdwMediator.publish('scrollToSizes');\r\n }\r\n\r\n /**\r\n * @description Method which determines if the currently selected product is on the customer's wishlist.\r\n * @returns {Boolean} true if the currently selected product is on the customer's wishlist.\r\n * @memberOf jwsdwProductDetail.ProductDetailController\r\n */\r\n function _isWishlisted() {\r\n return vm.wishlist.count && vm.wishlist.products.find((product) => product.pid === vm.masterID && product.color === vm.selectedColor.id);\r\n }\r\n /**\r\n * @description Method which updates the currently selected product if has product promotion.\r\n * @returns {void}\r\n * @memberOf jwsdwProductDetail.ProductDetailController\r\n */\r\n function _updateProductPromotion() {\r\n if (dataService.productPromotions()) {\r\n $scope.promotionName = dataService.productPromotions().promotionName;\r\n $scope.calloutMsg = dataService.productPromotions().calloutMsg;\r\n $scope.specialCalloutMessage = dataService.productPromotions().specialCalloutMessage;\r\n }\r\n }\r\n }\r\n}(angular));\r\n","'use strict';\r\n\r\n(function (angular) {\r\n\r\n dataService.$inject = ['$log', 'productService', 'PRODUCT_DATA', 'BAZAARVOICE_ACTIVE', 'DISPLAY_VIDEO', 'SIZE_SORTING_ORDER'];\r\n angular\r\n .module('jwsdw.productDetail')\r\n .factory('dataService', dataService);\r\n\r\n /**\r\n * @class jwsdwProductDetail.dataService\r\n * @description Data service that allows access to the data layer of the product details\r\n * @param {Object} $log log service that provides logging in angluar\r\n * @param {Object} productService service to provide product information (used for creation of variants item)\r\n * @param {Object} PRODUCT_DATA object holding all product data provided trough jwsdwProductDetailSettings\r\n * @param {Boolean} BAZAARVOICE_ACTIVE true if bazaarvoice is active\r\n * @param {Boolean} DISPLAY_VIDEO boolean if video should be shown on pdp (provided through jwsdwProductDetailSettings)\r\n * @param {Object} SIZE_SORTING_ORDER size ids in sorting order\r\n * @returns {Object} service object that returns public methods\r\n */\r\n function dataService($log, productService, PRODUCT_DATA, BAZAARVOICE_ACTIVE, DISPLAY_VIDEO, SIZE_SORTING_ORDER) { /* eslint max-statements: [\"error\", 60] */\r\n var service,\r\n _imageData,\r\n _mediaData,\r\n _360Data,\r\n _sizes,\r\n _sizeGuideSizeMap,\r\n _sizeType = PRODUCT_DATA.sizeType,\r\n _colors,\r\n _size,\r\n _color,\r\n _variant,\r\n _isSale,\r\n _productRating,\r\n _sale,\r\n _standard,\r\n _bestPrice,\r\n _priceReduction,\r\n _productId,\r\n _priceWithoutVAT,\r\n _ats,\r\n _availabilityId,\r\n _freeShipping,\r\n _activeFlags,\r\n _coBrandingLogo,\r\n _productPromotions = null;\r\n\r\n\r\n PRODUCT_DATA.size = PRODUCT_DATA.size.replace('B', '');\r\n PRODUCT_DATA.variants = PRODUCT_DATA.variants.map(function(variant) {\r\n variant.attributes.size.id = variant.attributes.size.id.replace('B', '');\r\n return variant;\r\n });\r\n\r\n $log.debug('jwsdw.productDetail.dataService: Using following data to built the page: ', PRODUCT_DATA);\r\n\r\n // define public methods\r\n service = {\r\n 'productName': productName,\r\n 'productType': productType,\r\n 'productRating': productRating,\r\n 'price': price,\r\n 'priceOld': priceOld,\r\n 'bestPrice': bestPrice,\r\n 'isSale': isSale,\r\n 'priceReduction': priceReduction,\r\n 'productId': productId,\r\n 'colorCode': colorCode,\r\n 'imageData': imageData,\r\n 'mediaData': mediaData,\r\n 'threeSixtyData': threeSixtyData,\r\n 'variants': variants,\r\n 'sizes': sizes,\r\n 'sizeMap': sizeMap,\r\n 'hasSizes': hasSizes,\r\n 'sizeType': sizeType,\r\n 'colors': colors,\r\n 'sizeById': sizeById,\r\n 'colorById': colorById,\r\n 'initialSize': initialSize,\r\n 'initialColor': initialColor,\r\n 'freeShipping': freeShipping,\r\n 'availabilityId': availabilityId,\r\n 'availabilityMessage': availabilityMessage,\r\n 'getProductFlags': getProductFlags,\r\n 'getCoBrandingProductFlag': getCoBrandingProductFlag,\r\n 'priceWithoutVAT': priceWithoutVAT,\r\n 'ats': ats,\r\n 'imageUrl': window.jwsdwUtil.urlUtils.imageUrl,\r\n 'videoUrl': window.jwsdwUtil.urlUtils.videoUrl,\r\n 'productImageUrl': window.jwsdwUtil.urlUtils.productImageUrl,\r\n 'productImageUrlObject': window.jwsdwProductDetailSettings.productImages,\r\n 'update': update,\r\n 'allMedia': allMedia,\r\n 'mediaIndexById': mediaIndexById,\r\n 'mediaById': mediaById,\r\n 'transforms': {\r\n 'full': {'scaleWidth': 1800, 'scaleHeight': 2600, 'format': 'jpg'},\r\n 'sfull': {'scaleWidth': 1400, 'scaleHeight': 2200, 'format': 'jpg'},\r\n 'xlarge': {'scaleWidth': 612, 'scaleHeight': 882, 'format': 'jpg'},\r\n 'large': {'scaleWidth': 372, 'scaleHeight': 536, 'format': 'jpg'},\r\n 'medium': {'scaleWidth': 425, 'scaleHeight': 612, 'format': 'jpg'},\r\n 'small': {'scaleWidth': 600, 'scaleHeight': 864, 'format': 'jpg'},\r\n 'thumbGallery': {'scaleWidth': 80, 'format': 'jpg'},\r\n 'productDescription': {'scaleWidth': 600, 'format': 'jpg'},\r\n 'techLab-large': {'scaleWidth': 700, 'scaleHeight': 830, 'format': 'jpg'},\r\n 'techLab-medium': {'scaleWidth': 1280, 'scaleHeight': 1520, 'format': 'jpg'},\r\n 'techLab-small': {'scaleWidth': 960, 'scaleHeight': 1140, 'format': 'jpg'},\r\n 'primaloft-large': {'scaleWidth': 700, 'scaleHeight': 830, 'format': 'jpg'},\r\n 'primaloft-medium': {'scaleWidth': 1280, 'scaleHeight': 1520, 'format': 'jpg'},\r\n 'primaloft-small': {'scaleWidth': 960, 'scaleHeight': 1140, 'format': 'jpg'},\r\n 'polartec-large': {'scaleWidth': 700, 'scaleHeight': 830, 'format': 'jpg'},\r\n 'polartec-medium': {'scaleWidth': 1280, 'scaleHeight': 1520, 'format': 'jpg'},\r\n 'polartec-small': {'scaleWidth': 960, 'scaleHeight': 1140, 'format': 'jpg'},\r\n 'swatch': {'scaleWidth': 50, 'format': 'jpg'}\r\n },\r\n 'productPromotions': productPromotions\r\n };\r\n\r\n window.dataService = service;\r\n\r\n if (BAZAARVOICE_ACTIVE) {\r\n window.jwsdwMediator.subscribe('ratingLoaded', function(productFeebdack) {\r\n _productRating = {\r\n 'averageRating': productFeebdack.rating,\r\n 'reviewCount': productFeebdack.count\r\n };\r\n });\r\n }\r\n\r\n return service;\r\n\r\n /**\r\n * @description Method to update of all values\r\n * @param {String} size Size Id\r\n * @param {String} color Color Id\r\n * @param {Boolean} preventImageReload Boolean value for determing if images need to reload\r\n * @returns {void}\r\n * @memberOf jwsdwProductDetail.dataService\r\n */\r\n function update(size, color, preventImageReload) {\r\n size = size || _initialSize();\r\n color = color || _initialColor();\r\n\r\n if (size !== _size || color !== _color) {\r\n _size = size;\r\n _color = color;\r\n\r\n // variant\r\n _variant = _getVariant(size, color);\r\n\r\n // if color of spezific size is not available, get first available size\r\n if (!_variant) {\r\n _variant = _getVariant(null, color);\r\n if (_variant) {\r\n _size = _variant.attributes.size.id;\r\n window.jwsdwMediator.publish('changeSize', _size);\r\n }\r\n }\r\n\r\n // sizes\r\n _initSizes();\r\n\r\n // colors\r\n _initColors();\r\n\r\n // isSale\r\n _isSale = _variant ? _variant.pricing.sale !== _variant.pricing.standard : false;\r\n\r\n // prices and priceReduction\r\n _sale = _variant ? _variant.pricing.sale : PRODUCT_DATA.pricing.sale;\r\n _standard = _variant ? _variant.pricing.standard : PRODUCT_DATA.pricing.standard;\r\n _priceReduction = Math.round(100 - _sale / _standard * 100);\r\n _bestPrice = _variant ? _variant.pricing.bestPrice : PRODUCT_DATA.pricing.bestPrice;\r\n\r\n // productId\r\n _productId = _variant ? _variant.id : PRODUCT_DATA.ID;\r\n\r\n // priceWithoutVAT\r\n _priceWithoutVAT = _variant ? _variant.pricing.priceWithoutVAT : PRODUCT_DATA.pricing.priceWithoutVAT;\r\n\r\n // ats\r\n _ats = _variant ? _variant.availability.ats : PRODUCT_DATA.availability.ats;\r\n\r\n // availabilityId\r\n _availabilityId = _variant ? _variant.availability.status : PRODUCT_DATA.availability.status;\r\n\r\n // activeFlag\r\n _activeFlags = _variant ? _variant.activeFlags : PRODUCT_DATA.activeFlags;\r\n\r\n // cobranding flag\r\n _coBrandingLogo = _variant ? _variant.coBrandingLogo : PRODUCT_DATA.coBrandingLogo;\r\n\r\n // productsPromotions\r\n _productPromotions = PRODUCT_DATA.productsPromotions[_variant.id];\r\n\r\n // free shipping info\r\n _freeShipping =\r\n (PRODUCT_DATA.freeShipping.freeShippingFrom && _variant && (_sale || _standard) > PRODUCT_DATA.freeShipping.freeShippingFrom) ||\r\n PRODUCT_DATA.freeShipping.isEA;\r\n\r\n // image data\r\n if (!preventImageReload) {\r\n _parseImageData();\r\n _parseMediaData();\r\n _parse360Data();\r\n _includeVideo();\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * @description Method to return the product name\r\n * @returns {String} productName\r\n * @memberOf jwsdwProductDetail.dataService\r\n */\r\n function productName() {\r\n return PRODUCT_DATA.displayedName || PRODUCT_DATA.name;\r\n }\r\n\r\n /**\r\n * @description Method to return the product type (this is the SEO name of the product)\r\n * @returns {String} productType\r\n * @memberOf jwsdwProductDetail.dataService\r\n */\r\n function productType() {\r\n return PRODUCT_DATA.type;\r\n }\r\n\r\n /**\r\n * @description Method to check if its a reduced product\r\n * @returns {String} isSale\r\n * @memberOf jwsdwProductDetail.dataService\r\n */\r\n function isSale() {\r\n return _isSale;\r\n }\r\n\r\n /**\r\n * @description Method to return the product rating\r\n * @returns {Object} productRatings\r\n * @memberOf jwsdwProductDetail.dataService\r\n */\r\n function productRating() {\r\n return _productRating;\r\n }\r\n\r\n /**\r\n * @description Method to return the products sale price or standard price if no sale is available\r\n * @returns {String} price\r\n * @memberOf jwsdwProductDetail.dataService\r\n */\r\n function price() {\r\n return _sale;\r\n }\r\n\r\n /**\r\n * @description Method to return the products promotions\r\n * @returns {Object} promotions\r\n * @memberOf jwsdwProductDetail.dataService\r\n */\r\n function productPromotions() {\r\n return _productPromotions.length ? _productPromotions[0] : null;\r\n }\r\n\r\n /**\r\n * @description Method to return the products standard price if sale is available\r\n * @returns {String} priceOld\r\n * @memberOf jwsdwProductDetail.dataService\r\n */\r\n function priceOld() {\r\n return _standard;\r\n }\r\n\r\n /**\r\n * @description Method to return the products standard price if sale is available\r\n * @returns {String} priceOld\r\n * @memberOf jwsdwProductDetail.dataService\r\n */\r\n function bestPrice() {\r\n return _bestPrice;\r\n }\r\n\r\n /**\r\n * @description Method to return the products price reduction in percent\r\n * @returns {Number} priceReduction\r\n * @memberOf jwsdwProductDetail.dataService\r\n */\r\n function priceReduction() {\r\n return _priceReduction;\r\n }\r\n\r\n /**\r\n * @description Method to return full productid/style\r\n * @returns {String} Full productid/style for given size and color\r\n * @memberOf jwsdwProductDetail.dataService\r\n */\r\n function productId() {\r\n return _productId;\r\n }\r\n\r\n /**\r\n * @description Method to return full productid/style\r\n * @returns {String} Full productid/style for given size and color\r\n * @memberOf jwsdwProductDetail.dataService\r\n */\r\n function colorCode() {\r\n return _color;\r\n }\r\n\r\n /**\r\n * @description Method to return product price without VAT\r\n * @returns {String} priceWithoutVAT\r\n * @memberOf jwsdwProductDetail.dataService\r\n */\r\n function priceWithoutVAT() {\r\n return _priceWithoutVAT;\r\n }\r\n\r\n /**\r\n * @description Method to return number of available products for this size/color variant\r\n * @returns {String} ats\r\n * @memberOf jwsdwProductDetail.dataService\r\n */\r\n function ats() {\r\n return _ats;\r\n }\r\n\r\n\r\n /**\r\n * @description Method to return availability ID\r\n * @returns {String} availabilityId\r\n * @memberOf jwsdwProductDetail.dataService\r\n */\r\n function availabilityId() {\r\n return _availabilityId;\r\n }\r\n\r\n /**\r\n * @description Method to return the product's ID of the flag or null\r\n * @returns {String} activeFlag\r\n * @memberOf jwsdwProductDetail.dataService\r\n */\r\n function getProductFlags() {\r\n return _activeFlags;\r\n }\r\n\r\n /**\r\n * @description Method to return the cobranding product flag\r\n * @returns {String} coBrandingLogo\r\n * @memberOf jwsdwProductDetail.dataService\r\n */\r\n function getCoBrandingProductFlag() {\r\n return _coBrandingLogo;\r\n }\r\n\r\n /**\r\n * @description Method to return an availability message\r\n * @returns {String} availability message\r\n * @memberOf jwsdwProductDetail.dataService\r\n */\r\n function availabilityMessage() {\r\n switch (_availabilityId) {\r\n case 'IN_STOCK':\r\n return PRODUCT_DATA.availability.inStockMsg;\r\n case 'NOT_AVAILABLE':\r\n return null;\r\n default:\r\n return null;\r\n }\r\n }\r\n\r\n /**\r\n * @description Method to return all variants\r\n * @returns {Object[]} variants\r\n * @memberOf jwsdwProductDetail.dataService\r\n */\r\n function variants() {\r\n return PRODUCT_DATA.variants;\r\n }\r\n\r\n /**\r\n * @description Method to return all available sizes for this product\r\n * @returns {Object[]} sizes\r\n * @memberOf jwsdwProductDetail.dataService\r\n */\r\n function sizes() {\r\n return _sizes;\r\n }\r\n\r\n /**\r\n * @description Method to return all available sizes for this product\r\n * @returns {Object[]} sizes\r\n * @memberOf jwsdwProductDetail.dataService\r\n */\r\n function sizeMap() {\r\n return _sizeGuideSizeMap.sizes;\r\n }\r\n\r\n /**\r\n * @description Method to check if product has sizes\r\n * @returns {Boolean} true if product has sizes\r\n * @memberOf jwsdwProductDetail.dataService\r\n */\r\n function hasSizes() {\r\n return Object.keys(_sizeGuideSizeMap.sizes).some(function(type) {\r\n return _sizeGuideSizeMap.sizes[type].length > 0;\r\n });\r\n }\r\n\r\n /**\r\n * @description Method to return size type of product\r\n * @returns {String} sizeType\r\n * @memberOf jwsdwProductDetail.dataService\r\n */\r\n function sizeType() {\r\n return _sizeType;\r\n }\r\n\r\n /**\r\n * @description Method to return all available colors for this product\r\n * @returns {Object[]} colors\r\n * @memberOf jwsdwProductDetail.dataService\r\n */\r\n function colors() {\r\n return _colors;\r\n }\r\n\r\n /**\r\n * @description Method to get size by ID\r\n * @param {String} id id\r\n * @returns {Object} size\r\n * @memberOf jwsdwProductDetail.dataService\r\n */\r\n function sizeById(id) {\r\n if (_sizes) {\r\n return _sizes.find(function(size) {\r\n return id === size.id;\r\n });\r\n }\r\n }\r\n\r\n /**\r\n * @description Method to get color by ID\r\n * @param {String} id id\r\n * @returns {Object} color\r\n * @memberOf jwsdwProductDetail.dataService\r\n */\r\n function colorById(id) {\r\n if (colors()) {\r\n return colors().find(function(color) {\r\n return id === color.id;\r\n });\r\n }\r\n }\r\n\r\n /**\r\n * @description Method to set initally selected size\r\n * @returns {Object} size\r\n * @memberOf jwsdwProductDetail.dataService\r\n */\r\n function initialSize() {\r\n return sizeById(_initialSize());\r\n }\r\n\r\n /**\r\n * @description Method to set initally selected color\r\n * @returns {Object} color\r\n * @memberOf jwsdwProductDetail.dataService\r\n */\r\n function initialColor() {\r\n return colorById(_initialColor());\r\n }\r\n\r\n /**\r\n * @description Method to determine whether product has free shipping\r\n * @returns {Boolean} true if shipping is free\r\n */\r\n function freeShipping() {\r\n return _freeShipping;\r\n }\r\n\r\n /**\r\n * @description Method to parse and returns the image data\r\n * @returns {Object} Parsed data\r\n * @memberOf jwsdwProductDetail.dataService\r\n */\r\n function imageData() {\r\n return _imageData.map(function(data, index) {\r\n data.index = index;\r\n return data;\r\n });\r\n }\r\n\r\n /**\r\n * @description Method to parse and returns the media data\r\n * @returns {Object} Parsed data\r\n * @memberOf jwsdwProductDetail.dataService\r\n */\r\n function mediaData() {\r\n return _mediaData;\r\n }\r\n\r\n /**\r\n * @description Method to parse and returns the 360 data\r\n * @returns {Object} Parsed data\r\n * @memberOf jwsdwProductDetail.dataService\r\n */\r\n function threeSixtyData() {\r\n return _360Data;\r\n }\r\n\r\n /**\r\n * @description Method to return an array of all media objects\r\n * @param {Boolean} [onlyImages] onlyImages\r\n * @returns {Object} all media\r\n * @memberOf jwsdwProductDetail.dataService\r\n */\r\n function allMedia(onlyImages) {\r\n if (onlyImages) {\r\n return _imageData;\r\n }\r\n return _imageData.concat(_360Data).filter(function(data) {\r\n return data;\r\n });\r\n }\r\n\r\n /**\r\n * @description Method to return the index of a media entry with the given id\r\n * @param {String} id media id\r\n * @returns {Number} media index\r\n * @memberOf jwsdwProductDetail.dataService\r\n */\r\n function mediaIndexById(id) {\r\n var media = allMedia(),\r\n i = 0;\r\n\r\n for (i; i < media.length; i += 1) {\r\n if (media[i].id === id) {\r\n return i;\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * @description Method to return the media item\r\n * @param {String} id media id\r\n * @returns {Object} media\r\n * @memberOf jwsdwProductDetail.dataService\r\n */\r\n function mediaById(id) {\r\n var media = allMedia(),\r\n i;\r\n\r\n for (i = 0; i < media.length; i++) {\r\n if (media[i].id === id) {\r\n return media[i];\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * @description Method to return an array of containing image and video objects\r\n * @returns {Object} imeges and videos\r\n * @memberOf jwsdwProductDetail.dataService\r\n */\r\n function _includeVideo() {\r\n if (_mediaData.videos && (_mediaData.videos.name || _mediaData.videos.source === 'youtube')) {\r\n if (!_mediaData.videos.sortOrder || _mediaData.videos.sortOrder === \"\") {\r\n _mediaData.videos.sortOrder = \"0\";\r\n }\r\n return _imageData.splice(_mediaData.videos.sortOrder, 0, _mediaData.videos);\r\n }\r\n }\r\n\r\n /**\r\n * @description Method to return variation of size/color pair\r\n * @param {String} size Size id\r\n * @param {String} color Color id\r\n * @returns {Object} Info regarding the variant matching size and color\r\n * @memberOf jwsdwProductDetail.dataService\r\n */\r\n function _getVariant(size, color) {\r\n if (!PRODUCT_DATA || PRODUCT_DATA.length <= 0 || !PRODUCT_DATA.variants || (!size && !color)) {\r\n return null;\r\n }\r\n\r\n if (!color) {\r\n return PRODUCT_DATA.variants.find(function (variant) {\r\n return variant.attributes.size.id === size;\r\n });\r\n } else if (!size) {\r\n return PRODUCT_DATA.variants.find(function (variant) {\r\n return variant.attributes.color.id === color;\r\n });\r\n }\r\n\r\n return PRODUCT_DATA.variants.find(function (variant) {\r\n return variant.attributes.size.id === size && variant.attributes.color.id === color;\r\n });\r\n }\r\n\r\n /**\r\n * @description Method to return if color variation of a product is on sale\r\n * @param {String} color Color id\r\n * @returns {Boolean} true if color variation is on sale\r\n * @memberOf jwsdwProductDetail.dataService\r\n */\r\n function _isColorOnSale(color) {\r\n if (!PRODUCT_DATA || PRODUCT_DATA.length <= 0 || !PRODUCT_DATA.variants || !color) {\r\n return null;\r\n }\r\n\r\n for (let i = 0; i < PRODUCT_DATA.variants.length; i++) {\r\n if (PRODUCT_DATA.variants[i].attributes.color.id === color && PRODUCT_DATA.variants[i].pricing.sale !== PRODUCT_DATA.variants[i].pricing.standard) {\r\n return true;\r\n }\r\n }\r\n\r\n return false;\r\n }\r\n\r\n /**\r\n * @description Method to return first available variation of size/color pair\r\n * @param {String} size Size id\r\n * @param {String} color Color id\r\n * @returns {Object} Info regarding the variant matching size and color\r\n * @memberOf jwsdwProductDetail.dataService\r\n */\r\n function _getFirstAvailableVariant(size, color) {\r\n if (!PRODUCT_DATA || PRODUCT_DATA.length <= 0 || !PRODUCT_DATA.variants || (!size && !color)) {\r\n return null;\r\n }\r\n\r\n if (!color) {\r\n return PRODUCT_DATA.variants.find(function (variant) {\r\n return variant.attributes.size.id === size && variant.pricing.standard && variant.availability.ats > 0;\r\n });\r\n } else if (!size) {\r\n return PRODUCT_DATA.variants.find(function (variant) {\r\n return variant.attributes.color.id === color && variant.pricing.standard && variant.availability.ats > 0;\r\n });\r\n }\r\n\r\n return PRODUCT_DATA.variants.find(function (variant) {\r\n return variant.attributes.size.id === size && variant.attributes.color.id === color;\r\n });\r\n }\r\n\r\n /**\r\n * @description Method to initialize sizes of a variant\r\n * @returns {void}\r\n * @private\r\n * @memberOf jwsdwProductDetail.dataService\r\n */\r\n function _initSizes() {\r\n if (_variant && !_sizes) {\r\n _sizes = _parseSizes();\r\n } else if (_variant) {\r\n _updateSizes(_sizes);\r\n } else {\r\n _sizes = [];\r\n }\r\n\r\n _sizeGuideSizeMap = productService.getSizeMap(_sizes, PRODUCT_DATA);\r\n }\r\n\r\n /**\r\n * @description Method to initialize colors of a variant\r\n * @returns {void}\r\n * @private\r\n * @memberOf jwsdwProductDetail.dataService\r\n */\r\n function _initColors() {\r\n if (_variant && !_colors) {\r\n _colors = _parseColors();\r\n } else if (_variant) {\r\n _updateColors(_colors);\r\n } else {\r\n _colors = [];\r\n }\r\n }\r\n\r\n /**\r\n * @description Method to parse sizes and availability from a variant\r\n * @returns {Object[]} size objects with id and availability\r\n * @private\r\n * @memberOf jwsdwProductDetail.dataService\r\n */\r\n function _parseSizes() {\r\n var list = PRODUCT_DATA.variants\r\n .map(function(variant) {\r\n return variant.attributes.size;\r\n })\r\n .filter(window.jwsdwUtil.arrayUtils.unique('id'))\r\n .sort(function(a, b) {\r\n if (SIZE_SORTING_ORDER.indexOf(a.id) !== -1 &&\r\n SIZE_SORTING_ORDER.indexOf(b.id) !== -1) {\r\n return SIZE_SORTING_ORDER.indexOf(a.id) > SIZE_SORTING_ORDER.indexOf(b.id) ? 1 : -1;\r\n }\r\n\r\n let sizeA = Number(a.id);\r\n let sizeB = Number(b.id);\r\n\r\n if ((isNaN(sizeA) || isNaN(sizeB))) {\r\n let splitSizeA = a.id.split('-');\r\n let splitSizeB = b.id.split('-');\r\n\r\n /* Special sorting case for socks */\r\n if (splitSizeA.length === 2 && !isNaN(Number(splitSizeA[0])) && splitSizeB.length === 2 && !isNaN(Number(splitSizeB[0]))) {\r\n return Number(splitSizeA[0]) - Number(splitSizeB[0]);\r\n }\r\n }\r\n\r\n return sizeA > sizeB ? 1 : -1;\r\n });\r\n\r\n return _updateSizes(list);\r\n }\r\n\r\n /**\r\n * @description Method to update the size list with availability information\r\n * @param {Object[]} list array of size objects with size and availability\r\n * @returns {Object[]} array of size objects with id and updated availability\r\n * @private\r\n * @memberOf jwsdwProductDetail.dataService\r\n */\r\n function _updateSizes(list) {\r\n list = list.map(function(size) {\r\n var variant = _getVariant(size.id, _color);\r\n\r\n size.display = !!variant;\r\n size.orderable = variant ? variant.pricing.standard && variant.availability.ats > 0 : false;\r\n return size;\r\n });\r\n\r\n return list;\r\n }\r\n\r\n /**\r\n * @description Method to parse color and availability from a variant\r\n * @returns {Object[]} color objects with id, name and availability\r\n * @private\r\n * @memberOf jwsdwProductDetail.dataService\r\n */\r\n function _parseColors() {\r\n var list = PRODUCT_DATA.variants\r\n .map(function(variant) {\r\n var color = variant.attributes.color;\r\n\r\n color.imageUrl = window.jwsdwUtil.urlUtils.productImageUrl(variant.id, 0, service.transforms.swatch, color.name);\r\n return color;\r\n })\r\n .filter(window.jwsdwUtil.arrayUtils.unique('id'));\r\n\r\n return _updateColors(list);\r\n }\r\n\r\n /**\r\n * @description Method to update the color list with availability information\r\n * @param {Object[]} list color objects with id, name and availability\r\n * @returns {Object[]} color objects with id, name and updated availability\r\n * @private\r\n * @memberOf jwsdwProductDetail.dataService\r\n */\r\n function _updateColors(list) {\r\n list = list\r\n .map(function (color) {\r\n var variant = _getFirstAvailableVariant(null, color.id) || _getVariant(null, color.id);\r\n\r\n if (!variant) {\r\n return null;\r\n }\r\n color.rgb = variant.rgb;\r\n color.isBright = window.jwsdwUtil.colorUtils.isBrightColor(color.rgb);\r\n color.orderable = variant ? variant.pricing.standard && variant.availability.ats > 0 : false;\r\n return color;\r\n })\r\n .filter(function (color) {\r\n return color;\r\n })\r\n .sort(function (firstColor, secondColor) {\r\n if (_isColorOnSale(firstColor.id) && !_isColorOnSale(secondColor.id)) {\r\n return 1;\r\n }\r\n if (!_isColorOnSale(firstColor.id) && _isColorOnSale(secondColor.id)) {\r\n return -1;\r\n }\r\n return 0;\r\n });\r\n\r\n return list;\r\n }\r\n\r\n /**\r\n * @description Method to parse image data from product variation data\r\n * @returns {void}\r\n * @private\r\n * @memberOf jwsdwProductDetail.dataService\r\n */\r\n function _parseImageData() {\r\n var colorAttribute,\r\n parsedData = [],\r\n colorData;\r\n\r\n if (PRODUCT_DATA.allVariations && PRODUCT_DATA.allVariations.attributes && PRODUCT_DATA.allVariations.attributes[0]) {\r\n colorAttribute = PRODUCT_DATA.allVariations.attributes.find(function (attribute) {\r\n return attribute.id === 'color';\r\n });\r\n\r\n if (!colorAttribute) {\r\n return;\r\n }\r\n\r\n colorData = colorAttribute.vals.find(function(color) {\r\n return color.id === _color;\r\n });\r\n\r\n // // do nothing if image count hasn't changed\r\n // if (_imageData && colorData.images.meta.length === _imageData.length || !colorData) {\r\n // return;\r\n // }\r\n\r\n parsedData = colorData.images.meta.map(function(image, index) {\r\n return {\r\n 'id': 'image' + index,\r\n 'type': 'image',\r\n 'imageIndex': index,\r\n 'url': window.jwsdwUtil.urlUtils.imageUrl(_productId, index, service.transforms.large, 'grey6'),\r\n 'color': _color,\r\n 'specialMessage': colorData.images.specialMessage[index]\r\n };\r\n });\r\n }\r\n\r\n _imageData = parsedData;\r\n }\r\n\r\n /**\r\n * @description Method to parse media data (videos, 360 videos, instructions, suspensionSystem)\r\n * @returns {void}\r\n * @private\r\n * @memberOf jwsdwProductDetail.dataService\r\n */\r\n function _parseMediaData() {\r\n var parsedData = {},\r\n videoData,\r\n instructionData,\r\n suspensionData,\r\n videoObject;\r\n\r\n // add videos\r\n parsedData.videos = [];\r\n videoObject = _variant ? _variant : PRODUCT_DATA;\r\n\r\n if (videoObject.video && DISPLAY_VIDEO) {\r\n videoData = JSON.parse(videoObject.video.replace(new RegExp('\\'', 'g'), '\"'));\r\n parsedData.videos = videoData;\r\n }\r\n\r\n // add instruction\r\n parsedData.instruction = [];\r\n\r\n if (PRODUCT_DATA.instruction) {\r\n instructionData = JSON.parse(PRODUCT_DATA.instruction.replace(new RegExp('\\'', 'g'), '\"'));\r\n parsedData.instruction = instructionData.items.map(function(instruction, index) {\r\n return {\r\n 'id': 'instruction' + index,\r\n 'type': 'instruction',\r\n 'title': instruction.name,\r\n 'description': instruction.description,\r\n 'url': instruction.link,\r\n 'thumbnail': PRODUCT_DATA.instructionThumbnail || null\r\n };\r\n });\r\n }\r\n\r\n // add suspensionSystem information\r\n parsedData.suspension = [];\r\n\r\n if (PRODUCT_DATA.suspensionSystem) {\r\n suspensionData = JSON.parse(PRODUCT_DATA.suspensionSystem.replace(new RegExp('\\'', 'g'), '\"'));\r\n parsedData.suspension = suspensionData.items.map(function(suspension, index) {\r\n return {\r\n 'id': 'suspension' + index,\r\n 'type': 'suspension',\r\n 'title': suspension.name,\r\n 'description': suspension.description,\r\n 'url': suspension.link,\r\n 'thumbnail': PRODUCT_DATA.suspensionSystemThumbnail || null\r\n };\r\n });\r\n }\r\n\r\n _mediaData = parsedData;\r\n }\r\n\r\n /**\r\n * @description Method to parse image data from product variation data\r\n * @returns {void}\r\n * @private\r\n * @memberOf jwsdwProductDetail.dataService\r\n */\r\n function _parse360Data() {\r\n var colorAttribute,\r\n parsedData = [],\r\n colorData;\r\n\r\n if (PRODUCT_DATA.allVariations && PRODUCT_DATA.allVariations.attributes && PRODUCT_DATA.allVariations.attributes[0]) {\r\n colorAttribute = PRODUCT_DATA.allVariations.attributes.find(function (attribute) {\r\n return attribute.id === 'color';\r\n });\r\n\r\n if (!colorAttribute) {\r\n return;\r\n }\r\n\r\n colorData = colorAttribute.vals.find(function(color) {\r\n return color.id === _color;\r\n });\r\n\r\n // do nothing if image count hasn't changed\r\n if (_imageData && colorData.images['360'].length === _imageData.length || !colorData) {\r\n return;\r\n }\r\n\r\n parsedData = colorData.images['360'].map(function(image, index) {\r\n return {\r\n 'id': 'image-360-' + index,\r\n 'type': '360',\r\n 'url': image,\r\n 'color': _color\r\n };\r\n }).pop();\r\n }\r\n\r\n _360Data = parsedData;\r\n }\r\n\r\n /**\r\n * @description Method to get initial size for a variant or alternatively for the first variant\r\n * @returns {String|null} size for the current variant, the first variant or null\r\n * @private\r\n * @memberOf jwsdwProductDetail.dataService\r\n */\r\n function _initialSize() {\r\n var variant = _getVariant(PRODUCT_DATA.size, PRODUCT_DATA.color),\r\n firstVariant = PRODUCT_DATA.variants[0];\r\n\r\n return variant ? PRODUCT_DATA.size : (firstVariant ? firstVariant.attributes.size : null);\r\n }\r\n\r\n /**\r\n * @description Method to get the initial color for a product\r\n * @returns {String|null} color id if a variant or first variant can be found otherwise null\r\n * @private\r\n * @memberOf jwsdwProductDetail.dataService\r\n */\r\n function _initialColor() {\r\n var variant = _getVariant(PRODUCT_DATA.size, PRODUCT_DATA.color);\r\n return variant ? PRODUCT_DATA.color : PRODUCT_DATA.variants[0].attributes.color.id;\r\n }\r\n }\r\n\r\n}(angular));\r\n","'use strict';\r\n\r\n(function (angular) {\r\n\r\n ThumbGalleryController.$inject = ['$scope', 'dataService'];\r\n jwsdwThumbGallery.$inject = ['$timeout', '$window'];\r\n angular\r\n .module('jwsdw.productDetail')\r\n .directive('jwsdwThumbGallery', jwsdwThumbGallery);\r\n\r\n /**\r\n * @class jwsdwProductDetail.jwsdwThumbGallery\r\n * @description Gallery of images - one can be selected\r\n * @param {Object} $timeout timeout service provided through angular\r\n * @param {Object} $window browser window object\r\n * @returns {Object} directive\r\n */\r\n function jwsdwThumbGallery($timeout, $window) {\r\n var directive = {\r\n 'restrict': 'A',\r\n 'templateUrl': 'thumbGallery.html',\r\n 'replace': true,\r\n 'scope': {\r\n 'mediaId': '=',\r\n 'hideMedia': '=', // whether or not 'media' type entries should be displayed (required for full screen imageviewer, as there videos and docs shouldn't be displayed)\r\n 'isActive': '='\r\n },\r\n 'link': link,\r\n 'controller': ThumbGalleryController,\r\n 'controllerAs': 'vm',\r\n 'bindToController': true\r\n };\r\n\r\n return directive;\r\n\r\n /**\r\n * @description Method that is connected to the directive and is triggered when directive loads\r\n * @param {Object} scope current scope\r\n * @param {Object[]} element dom element that is linked to the directive\r\n * @returns {void}\r\n */\r\n function link(scope, element) {\r\n scope.$watch('vm.isActive', function(isActive) {\r\n if (isActive === true) {\r\n _activate();\r\n } else {\r\n _disable();\r\n }\r\n });\r\n\r\n // only do the manual init if no isActive attribute is available\r\n if (scope.vm.isActive === undefined) {\r\n _activate();\r\n }\r\n\r\n /**\r\n * @description Method to run the initialization of the thumb gallery directive\r\n * @returns {void}\r\n * @private\r\n */\r\n function _activate() {\r\n // listen to mouse wheel interaction\r\n element[0].addEventListener('mousewheel', _onMouseWheel, false);\r\n // listen to browser size changes\r\n $window.addEventListener('resize', function() {\r\n scope.vm.selectThumb(scope.vm.mediaId);\r\n }, false);\r\n }\r\n\r\n /**\r\n * @description Method to disable the thumb gallery directive\r\n * @returns {void}\r\n * @private\r\n */\r\n function _disable() {\r\n element[0].removeEventListener('mousewheel', _onMouseWheel);\r\n }\r\n\r\n /**\r\n * @description Callback method to handle mouse wheel events\r\n * @param {Object} event the event triggered by the mouse wheel listener\r\n * @returns {void}\r\n * @private\r\n */\r\n function _onMouseWheel(event) {\r\n event.preventDefault();\r\n\r\n scope.$apply(function() {\r\n if (event.wheelDelta > 0) {\r\n // move up\r\n scope.vm.selectPrevThumb();\r\n } else {\r\n // move down\r\n scope.vm.selectNextThumb();\r\n }\r\n });\r\n }\r\n\r\n /**\r\n * @description Method to update the wrapper dimensions for the selected thumb\r\n * @returns {void}\r\n * @private\r\n */\r\n scope.vm.getDimensions = function () {\r\n var galleryItem = element[0].querySelector('.jwsdw-pdp-thumbGallery-item'),\r\n style;\r\n\r\n scope.vm.wrapperHeight = element[0].querySelector('.jwsdw-pdp-thumbGalleryContainer').offsetHeight;\r\n if (galleryItem) {\r\n style = galleryItem.currentStyle || window.getComputedStyle(galleryItem);\r\n scope.vm.thumbHeight = galleryItem.clientHeight;\r\n scope.vm.vSpace = parseInt(style.marginBottom);\r\n }\r\n };\r\n }\r\n }\r\n\r\n /* @ngInject */\r\n /**\r\n * @class jwsdwProductDetail.jwsdwThumbGallery.ThumbGalleryController\r\n * @description Controls the thumbs list user interface\r\n * @param {Object} $scope current scope\r\n * @param {Object} dataService data service that provides access to the product data layer\r\n * @constructor\r\n */\r\n function ThumbGalleryController($scope, dataService) {\r\n var vm = this;\r\n\r\n vm.dataService = dataService;\r\n vm.mediaData = vm.dataService.mediaData();\r\n vm.threeSixtyData = vm.dataService.threeSixtyData();\r\n\r\n // count number of visible thumbs\r\n vm.thumbCount = vm.dataService.imageData().length;\r\n if (!vm.hideMedia) {\r\n vm.thumbCount += vm.mediaData.videos.length;\r\n vm.thumbCount += vm.threeSixtyData ? vm.threeSixtyData.length : 0;\r\n }\r\n\r\n // media id of currently selected item\r\n if (!vm.mediaId) {\r\n vm.mediaId = dataService.allMedia(vm.hideMedia)[0] ? dataService.allMedia(vm.hideMedia)[0].id : '';\r\n }\r\n\r\n vm.vOffset = 0;\r\n vm.isArrowUpVisible = false;\r\n vm.isArrowDownVisible = true;\r\n vm.wrapperHeight = 0;\r\n vm.thumbHeight = 0;\r\n vm.vSpace = 0; // vertical space between thumbs in pixel - required to calc height of gallery\r\n\r\n vm.selectThumb = selectThumb;\r\n vm.selectNextThumb = selectNextThumb;\r\n vm.selectPrevThumb = selectPrevThumb;\r\n\r\n $scope.$watch('vm.mediaId', function(newId) {\r\n selectThumb(newId);\r\n });\r\n\r\n /**\r\n * @description Method to select the thumb with the given index and updates scrolling position\r\n * @param {Number} mediaId Id of the thumb to be selected\r\n * @returns {void}\r\n * @memberOf jwsdwProductDetail.jwsdwThumbGallery.ThumbGalleryController\r\n */\r\n function selectThumb(mediaId) {\r\n var media = dataService.allMedia(vm.hideMedia),\r\n thumbSpace,\r\n index,\r\n thumbY,\r\n maxY,\r\n moveUp,\r\n moveDown,\r\n completeHeight;\r\n\r\n vm.getDimensions();\r\n thumbSpace = vm.thumbHeight + vm.vSpace;\r\n index = dataService.mediaIndexById(mediaId) || 0;\r\n\r\n thumbY = thumbSpace * index;\r\n moveUp = thumbY + vm.vOffset + thumbSpace >= vm.wrapperHeight;\r\n moveDown = thumbY + vm.vOffset <= 0;\r\n vm.isArrowUpVisible = index > 0;\r\n vm.isArrowDownVisible = index + 1 < vm.thumbCount;\r\n\r\n if (!vm.wrapperHeight || !vm.thumbHeight || index < 0 || index > media.length) {\r\n return;\r\n }\r\n\r\n // calculate complete thumbs height\r\n completeHeight = thumbSpace * media.length;\r\n\r\n // calculate max y value\r\n maxY = vm.wrapperHeight - completeHeight;\r\n\r\n // adjust maxY to thumbSpace\r\n maxY = Math.ceil(maxY / thumbSpace) * thumbSpace - thumbSpace;\r\n\r\n if (moveUp) {\r\n vm.vOffset -= thumbSpace;\r\n } else if (moveDown) {\r\n vm.vOffset += thumbSpace;\r\n }\r\n\r\n vm.vOffset = Math.min(vm.vOffset, 0);\r\n vm.vOffset = Math.max(vm.vOffset, maxY);\r\n }\r\n\r\n /**\r\n * @description Method to switch to the next thumbnail\r\n * @returns {void}\r\n * @memberOf jwsdwProductDetail.jwsdwThumbGallery.ThumbGalleryController\r\n */\r\n function selectNextThumb() {\r\n var media = dataService.allMedia(vm.hideMedia),\r\n currentIndex = dataService.mediaIndexById(vm.mediaId),\r\n nextIndex;\r\n\r\n nextIndex = currentIndex + 1;\r\n\r\n if (nextIndex < media.length) {\r\n vm.mediaId = media[nextIndex].id;\r\n }\r\n }\r\n\r\n /**\r\n * @description Method to switch to the previous thumbnail\r\n * @returns {void}\r\n * @memberOf jwsdwProductDetail.jwsdwThumbGallery.ThumbGalleryController\r\n */\r\n function selectPrevThumb() {\r\n var media = dataService.allMedia(vm.hideMedia),\r\n currentIndex = dataService.mediaIndexById(vm.mediaId),\r\n prevIndex;\r\n\r\n prevIndex = currentIndex - 1;\r\n\r\n if (prevIndex >= 0) {\r\n vm.mediaId = media[prevIndex].id;\r\n }\r\n }\r\n }\r\n}(angular));","'use strict';\r\n\r\n(function (angular) {\r\n\r\n ImageViewerController.$inject = ['$window', '$document', '$scope', 'util', 'dataService'];\r\n angular\r\n .module('jwsdw.productDetail')\r\n .directive('jwsdwImageViewer', jwsdwImageViewer);\r\n\r\n /**\r\n * @class jwsdwProductDetail.jwsdwImageViewer\r\n * @description Full screen image viewer\r\n * @returns {Object} directive\r\n */\r\n function jwsdwImageViewer() {\r\n var directive = {\r\n 'restrict': 'A',\r\n 'templateUrl': 'imageViewer.html',\r\n 'replace': true,\r\n 'scope': {\r\n 'mediaId': '=',\r\n 'isVisible': '=',\r\n 'currentId': '='\r\n },\r\n 'controller': ImageViewerController,\r\n 'controllerAs': 'vm',\r\n 'bindToController': true\r\n };\r\n\r\n return directive;\r\n }\r\n\r\n /* @ngInject */\r\n /**\r\n * @class jwsdwProductDetail.jwsdwImageViewer.ImageViewerController\r\n * @description Controller for image viewer. Disables and enables features like 'close via ESC'\r\n * @constructor\r\n * @param {Object} $window browser window object\r\n * @param {Object} $document document object\r\n * @param {Object} $scope current scope\r\n * @param {Object} util util service that provides access to global functions\r\n * @param {Object} dataService data service that provides access to the product data layer\r\n * @constructor\r\n */\r\n function ImageViewerController($window, $document, $scope, util, dataService) {\r\n var vm = this;\r\n\r\n vm.thumbGalleryHeight = 20;\r\n vm.dataService = dataService;\r\n vm.body = $document.find('body');\r\n\r\n /**\r\n * @description Method to run the initialization of the image viewer directive\r\n * @returns {void}\r\n */\r\n this.$onInit = function () {\r\n $scope.$watch('vm.isVisible', function(isVisible) {\r\n if (isVisible) {\r\n _enable();\r\n vm.body.addClass('jws-overflowYHidden');\r\n window.initProductImageSwiper();\r\n _enablePinchZoomListeners();\r\n } else {\r\n _disable();\r\n vm.body.removeClass('jws-overflowYHidden');\r\n if (window.productImageSlider) {\r\n // destroy image slider and panzoom\r\n window.productImageSlider.destroy(true, true);\r\n _clearZoomListeners();\r\n $window.jwsdwMediator.publish('unloadZoom');\r\n }\r\n }\r\n });\r\n };\r\n\r\n /**\r\n * @description Method to register listener for key up event.\r\n * @returns {void}\r\n * @private\r\n */\r\n function _enable() {\r\n $window.addEventListener('keyup', _onKeyUp, false);\r\n $window.scrollTo(0, 0);\r\n }\r\n\r\n /**\r\n * @description Method to register listener for key up event.\r\n * @returns {void}\r\n * @private\r\n */\r\n function _disable() {\r\n $window.removeEventListener('keyup', _onKeyUp);\r\n $window.scrollTo(0, 0);\r\n }\r\n\r\n /**\r\n * @description Method to listen to key press on 'ESC'\r\n * @param {Object} event key up event data\r\n * @returns {void}\r\n * @private\r\n */\r\n function _onKeyUp(event) {\r\n if (util.getKeyCode(event) === 27) {\r\n $scope.$apply(function() {\r\n vm.isVisible = false;\r\n });\r\n }\r\n }\r\n\r\n /**\r\n * @description Method user to re-register rezise listeners on window for zoom pinch.\r\n * @returns {undefined}\r\n */\r\n function _enablePinchZoomListeners() {\r\n if (window.pz && window.pz.length) {\r\n window.pz.forEach((pzElem) => window.addEventListener('resize', pzElem.resizeHandler));\r\n }\r\n }\r\n\r\n /**\r\n * @description Method used to deregister event listeners related to zoom elements.\r\n * @returns {Promise} a promise that fulfills once all of the zoom elements have been cleared.\r\n */\r\n function _clearZoomListeners() {\r\n return Promise.all(\r\n [\r\n new Promise((resolve) => {\r\n if (window.pz && window.pz.length) {\r\n window.pz.forEach((pzElem) => window.removeEventListener('resize', pzElem.resizeHandler));\r\n window.pz = [];\r\n }\r\n resolve();\r\n }),\r\n new Promise((resolve) => {\r\n if (window.dz && window.dz.length) {\r\n window.dz.forEach((dzElem) => dzElem.destroy());\r\n window.dz = [];\r\n }\r\n resolve();\r\n })\r\n ]\r\n );\r\n }\r\n }\r\n}(angular));","'use strict';\r\n\r\n(function (angular) {\r\n ProductImageGalleryController.$inject = ['dataService', '$window', '$scope'];\r\n angular\r\n .module('jwsdw.productDetail')\r\n .directive('jwsdwProductImageGallery', jwsdwProductImageGallery);\r\n\r\n /**\r\n * @class jwsdwProductDetail.jwsdwProductImageGallery\r\n * @description Main image gallery\r\n * @returns {Object} directive\r\n */\r\n function jwsdwProductImageGallery() {\r\n var directive = {\r\n 'restrict': 'A',\r\n 'templateUrl': 'productImageGallery.html',\r\n 'replace': true,\r\n 'scope': {\r\n 'mediaId': '=',\r\n '': '=',\r\n 'viewport': '=',\r\n 'active': '='\r\n },\r\n 'controller': ProductImageGalleryController,\r\n 'controllerAs': 'vm',\r\n 'bindToController': true\r\n };\r\n\r\n return directive;\r\n }\r\n\r\n /* @ngInject */\r\n /**\r\n * @class jwsdwProductDetail.jwsdwProductImageGallery.ProductImageGalleryController\r\n * @description Controller for product image gallery takes care of features like swiping\r\n * @param {Object} dataService data service that provides access to the product data layer\r\n * @param {Object} $window current window wrapped as jquery element\r\n * @param {Object} $scope current scope\r\n * @constructor\r\n */\r\n function ProductImageGalleryController(dataService, $window, $scope) {\r\n var vm = this;\r\n\r\n vm.mobileZoomEnabled = false;\r\n vm.dataService = dataService;\r\n\r\n vm.next = next;\r\n vm.prev = prev;\r\n vm.showImageViewer = showImageViewer;\r\n\r\n if (window.visualViewport) {\r\n // supported for Webkit browsers (Chrome, Safari, Edge)\r\n $scope.$watch(function () {\r\n return window.visualViewport.scale;\r\n }, function () {\r\n vm.mobileZoomEnabled = window.visualViewport.scale > 1;\r\n });\r\n }\r\n\r\n $scope.$watchGroup(['vm.mediaId'], function(values) {\r\n var mediaId = values[0],\r\n media;\r\n\r\n if (mediaId) {\r\n media = dataService.mediaById(mediaId);\r\n if (media.type === '360') {\r\n _init360Viewer();\r\n }\r\n }\r\n });\r\n\r\n /**\r\n * @description Method to get to the next media item.\r\n * @param {Object} item media item\r\n * @param {String} item.id media item id\r\n * @returns {String | void} returns the media id of the current item if the mobile zoom is enabled nothing otherwise\r\n * @memberOf jwsdw.ProductDetail.jwsdwProductImageGallery.ProductImageGalleryController\r\n */\r\n function next(item) {\r\n var index = dataService.mediaIndexById(item.id),\r\n mediaItems = dataService.allMedia();\r\n\r\n if (vm.mobileZoomEnabled) {\r\n return vm.mediaId;\r\n }\r\n\r\n index = (index + 1 >= mediaItems.length) ? 0 : index + 1;\r\n\r\n vm.mediaId = mediaItems[index].id;\r\n }\r\n\r\n /**\r\n * @description Method to get to the previous media item.\r\n * @param {Object} item media item\r\n * @param {String} item.id media item id\r\n * @returns {String | void} returns the media id of the current item if the mobile zoom is enabled nothing otherwise\r\n * @memberOf jwsdw.ProductDetail.jwsdwProductImageGallery.ProductImageGalleryController\r\n */\r\n function prev(item) {\r\n var index = dataService.mediaIndexById(item.id),\r\n mediaItems = dataService.allMedia();\r\n\r\n if (vm.mobileZoomEnabled) {\r\n return vm.mediaId;\r\n }\r\n\r\n index = (index <= 0) ? mediaItems.length - 1 : index - 1;\r\n\r\n vm.mediaId = mediaItems[index].id;\r\n }\r\n\r\n\r\n /**\r\n * @description Method to shows the fullscreen image viewer as long as the current media item is an image\r\n * @returns {void}\r\n * @memberOf jwsdwProductDetail.ProductDetailController\r\n */\r\n function showImageViewer() {\r\n $window.jwsdwMediator.publish('showImageViewer');\r\n }\r\n\r\n /**\r\n * @description Method to init canvas\r\n * @param {object} opt options\r\n * @returns {Object} canvas\r\n */\r\n function _createCanvas (opt) {\r\n var canvas = opt.canvas || document.createElement('canvas');\r\n var viewport = [0, 0];\r\n var resizeCanvas = function() {\r\n var width = typeof viewport[2] === 'number' ? viewport[2] : canvas.clientWidth;\r\n var height = typeof viewport[3] === 'number' ? viewport[3] : canvas.clientHeight;\r\n var dpr = window.devicePixelRatio;\r\n canvas.width = width * dpr;\r\n canvas.height = height * dpr;\r\n };\r\n\r\n window.addEventListener('resize', resizeCanvas);\r\n resizeCanvas();\r\n return canvas;\r\n }\r\n\r\n /**\r\n * @description Method to init 360 viewer\r\n * @returns {void}\r\n */\r\n function _init360Viewer() {\r\n let script;\r\n\r\n if (!window.create360Viewer) {\r\n script = document.createElement('script');\r\n script.type = 'text/javascript';\r\n script.src = document.getElementById('jwsdw-360Viewer-script').getAttribute('data-src');\r\n script.setAttribute('defer', '');\r\n document.body.append(script);\r\n script.onload = _activate360View;\r\n } else {\r\n // workaround to call function async\r\n setTimeout(_activate360View, 0);\r\n }\r\n\r\n /**\r\n * @description Method to init 360 viewer\r\n * @returns {void}\r\n */\r\n function _activate360View() {\r\n var canvas = _createCanvas({\r\n 'canvas': document.querySelector('#jwsdw-productDetail-360Viewer')\r\n });\r\n var autoSpin = false;\r\n var image = new Image();\r\n image.src = canvas.getAttribute('data-ng-src');\r\n image.onload = function() {\r\n var viewer = window.create360Viewer({\r\n 'fov': 80 * Math.PI / 180,\r\n 'image': image,\r\n 'canvas': canvas\r\n });\r\n\r\n viewer.start();\r\n\r\n viewer.on('tick', function (dt) {\r\n if (autoSpin && !viewer.controls.dragging) {\r\n viewer.controls.theta -= dt * 0.00005;\r\n }\r\n });\r\n };\r\n }\r\n }\r\n }\r\n}(angular));","'use strict';\r\n\r\n(function (angular) {\r\n angular\r\n .module('jwsdw.productDetail')\r\n .controller('DetailInfoController', DetailInfoController);\r\n\r\n /**\r\n * @class jwsdwProductDetail.DetailInfoController\r\n * @description Controller for product detail infos\r\n * @constructor\r\n */\r\n function DetailInfoController() {\r\n var detailCtrl = this;\r\n\r\n detailCtrl.furtherDetailsVisible = false;\r\n }\r\n}(angular));","'use strict';\r\n/* eslint-disable */\r\n\r\n(function (angular) {\r\n\r\n angular\r\n .module('jwsdw.productDetail')\r\n .directive('jwsdwYoutubeVideo', jwsdwYoutubeVideo);\r\n\r\n /**\r\n * @class jwsdwProductDetail.jwsdwYoutubeVideo\r\n * @description Directive used to initialise youtube videos\r\n * @returns {Object} directive\r\n */\r\n function jwsdwYoutubeVideo() {\r\n var directive = {\r\n 'link': function($scope, element, attrs) {\r\n $scope.$watch(function() {\r\n return element;\r\n }, function() {\r\n $scope.$evalAsync(function() {\r\n const videoId = attrs.videoId,\r\n options = {\r\n 'width': parseInt(attrs.videoWidth),\r\n 'height': parseInt(attrs.videoHeight),\r\n 'playerVars': {\r\n 'autoplay': parseInt(attrs.videoAutoplay),\r\n 'controls': parseInt(attrs.videoControls),\r\n 'showinfo': parseInt(attrs.videoShowinfo),\r\n 'modestbranding': parseInt(attrs.videoModestbranding),\r\n 'loop': parseInt(attrs.videoLoop)\r\n }\r\n },\r\n iframe =\r\n `\r\n `;\r\n\r\n element.append(iframe);\r\n });\r\n });\r\n }\r\n };\r\n\r\n return directive;\r\n }\r\n}(angular));","'use strict';\r\n\r\n(function (angular) {\r\n // initialize product detail angular app\r\n // bootstrap app manually as only the first app on a page can be initialized by data-ng-app (which is the framework/header)\r\n angular.bootstrap(document.getElementById('jwsdw-pdp-module'), ['jwsdw.productDetail']);\r\n}(angular));\r\n\r\n(function () {\r\n var x;\r\n /**\r\n * @description Check if explicit consent\r\n * @returns {Boolean} true if loaded\r\n */\r\n function checkConsent() {\r\n return window.dataLayer.some(function (event) {\r\n return event['consent_status']; // eslint-disable-line\r\n });\r\n }\r\n\r\n /**\r\n * @description Run auto events\r\n * @returns {Void} void\r\n */\r\n function runAutoEvent() {\r\n var oldLayer = window.dynamic_tm_data;\r\n var categoryPath = window.jwsdwProductDetailSettings.data.categoryPath;\r\n\r\n window.dataLayer.push({\r\n 'event': 'eec.productDetailImpression',\r\n 'eventCategory': 'ecommerce',\r\n 'eventAction': 'product detail impression',\r\n 'eventLabel': 'product detail page',\r\n 'eventValue': oldLayer.productPriceWithVAT,\r\n 'nonInteraction': true,\r\n 'ecommerce': {\r\n 'currencyCode': oldLayer.currency,\r\n 'detail': {\r\n 'actionField': {\r\n 'list': 'product detail page'\r\n },\r\n 'products': [{\r\n 'name': oldLayer.productname,\r\n 'id': oldLayer.productid,\r\n 'price': oldLayer.productPriceWithVAT,\r\n 'brand': (oldLayer.productbrand || '').replace('&', '&'),\r\n 'category': oldLayer.categoryid,\r\n 'variant': oldLayer.productColorName,\r\n 'list': 'product detail page',\r\n 'dimension13': oldLayer.productid.split('_').shift(),\r\n 'dimension14': categoryPath[categoryPath.length - 1].id\r\n }]\r\n }\r\n }\r\n });\r\n }\r\n if (!!window.google_tag_manager) {\r\n if (checkConsent()) {\r\n runAutoEvent();\r\n return;\r\n }\r\n x = window.dataLayer.push;\r\n window.dataLayer.push = function (obj) {\r\n x(obj);\r\n if (obj.event === 'consent_status' && obj.type === 'explicit') {\r\n runAutoEvent();\r\n }\r\n };\r\n } else {\r\n window.addEventListener('gtm_loaded', function() {\r\n if (checkConsent()) {\r\n runAutoEvent();\r\n return;\r\n }\r\n x = window.dataLayer.push;\r\n window.dataLayer.push = function (obj) {\r\n x(obj);\r\n if (obj.event === 'consent_status' && obj.type === 'explicit') {\r\n runAutoEvent();\r\n }\r\n };\r\n });\r\n }\r\n}());\r\n\r\n(function (window, document, $) {\r\n var isCustomSize = window.location.hash.length && window.location.hash.indexOf('size') > -1;\r\n if (isCustomSize) {\r\n let hash = decodeURIComponent(window.location.hash).replace('#size=', '').split('|');\r\n for (let i = 0; i < $('.jwsdw-pdp-size .jwsdw-product-swatch-selectable span').length; i++) {\r\n for (let j = 0; j < hash.length; j++) {\r\n if ($($('.jwsdw-pdp-size .jwsdw-product-swatch-selectable span')[i]).text().trim() === hash[j]) {\r\n $($('.jwsdw-pdp-size .jwsdw-product-swatch-selectable span')[i]).click();\r\n break;\r\n }\r\n }\r\n }\r\n }\r\n $(document).on('click', '.jwsdw-pdp-social-twitter', function() {\r\n updateMetaDataSocial();\r\n\r\n window.open($(this).data('href'), '', 'width=700, height=700');\r\n\r\n /**\r\n * @description Method to update social meta data\r\n * @returns {Boolean} true\r\n */\r\n function updateMetaDataSocial() {\r\n var metaImage = $('head meta[property=\"og:image\"]'),\r\n firstThumbnail = $(document).find('.jwsdw-pdp-thumbGalleryContainer img').first(),\r\n ogimageurl = firstThumbnail.length > 0 && firstThumbnail.attr('src') ? firstThumbnail.attr('src') : '',\r\n newMetaImage = $('');\r\n\r\n if (metaImage.length > 0) {\r\n metaImage.replaceWith(newMetaImage);\r\n } else {\r\n $('head').append(newMetaImage);\r\n }\r\n\r\n if ($('head meta[property=\"og:type\"]').length === 0) {\r\n $('head').append($(''));\r\n }\r\n\r\n return true;\r\n }\r\n });\r\n}(window, document, jQuery));\r\n\r\n$('#jws-pdp-showLess').on('click', function () {\r\n document.getElementById('jwsdw-pdp-productShortDesc').classList.toggle('jws-hidden');\r\n document.getElementById('jwsdw-pdp-productLongDesc').classList.toggle('jws-hidden');\r\n});\r\n$('#jws-pdp-showMore').on('click', function () {\r\n document.getElementById('jwsdw-pdp-productShortDesc').classList.toggle('jws-hidden');\r\n document.getElementById('jwsdw-pdp-productLongDesc').classList.toggle('jws-hidden');\r\n});\r\n\r\n// Displays Zoom icons on Img veriwe open\r\n$('.jwsdw-pdp-mediaItem').on('click', function () {\r\n if (window.innerWidth < 900) {\r\n $('.jwsdw-pdp-zoomIcon-mobile').show();\r\n } else {\r\n $('.jwsdw-pdp-zoomIcon-desktop').show();\r\n }\r\n});\r\n\r\n$('.jwsdw-pdp-productImageGaleryItem').on('click', function () {\r\n setTimeout(function() {\r\n if (window.innerWidth < 900) {\r\n $('.jwsdw-pdp-zoomIcon-mobile').hide();\r\n } else {\r\n $('.jwsdw-pdp-zoomIcon-desktop').hide();\r\n }\r\n }, 3000);\r\n});\r\n\r\n$('.jwsdw-pdp-mobileImageGallery').on('click', function () {\r\n setTimeout(function() {\r\n $('.jwsdw-pdp-zoomIcon-mobile').hide();\r\n }, 3000);\r\n});\r\n\r\n$('.jwsdw-pdp-imageViewer').on('click', function () {\r\n $('.jwsdw-pdp-zoomIcon-desktop').hide();\r\n});\r\n\r\n$('.jwsdw-pdp-imageViewer').on('touchstart', function () {\r\n $('.jwsdw-pdp-zoomIcon-mobile').hide();\r\n});","'use strict';\r\n(function (window, $) {\r\n var $notifyMeForm = $('form.jwsdw-notifyme-form'),\r\n $submitButton = $notifyMeForm.find('.jwsdw-notifyme-submit-container button'),\r\n $formErrorMessage = $notifyMeForm.find('.jwsdw-notificationFormErrorMessage'),\r\n $submitButtonText = $submitButton.find('.jwsdw-buttonText'),\r\n $submitButtonSpinner = $submitButton.find('.jwsdw-spinner'),\r\n xhr;\r\n\r\n $.validator.setDefaults({\r\n 'rules': {\r\n 'email': {\r\n 'invalidvalue': true,\r\n 'customemail': true\r\n }\r\n }\r\n });\r\n\r\n // initialize form validation\r\n $notifyMeForm.validate();\r\n\r\n /**\r\n * Method to handle form submits\r\n * @param {Object} event the event that triggered the handler\r\n * @param {function} successCallback the callback that is triggered when the ajax call was successful\r\n * @param {function} errorCallback the callback that is triggered when the ajax call was unsuccessful\r\n * @param {function} beforeSendCallback the callback that is triggered before the ajax call is made\r\n * @param {function} completeCallback the callback that is triggered after the ajax call was made\r\n * @returns {void}\r\n */\r\n function formSubmit (event, successCallback, errorCallback, beforeSendCallback, completeCallback) {\r\n var $this = $(this),\r\n $captcha = $this.find('.g-recaptcha');\r\n\r\n var validateCaptcha = $captcha.length > 0;\r\n\r\n event.preventDefault();\r\n\r\n // only submit form if frontend validation is successful and no other call is executed\r\n if (!$this.valid() || (xhr && xhr.readyState !== 4)) {\r\n return;\r\n }\r\n\r\n if (window.jwsdwRecaptchaSettings.captchaDisabled === false && validateCaptcha === true) {\r\n if (!window.grecaptcha || window.jwsdwUtil.captcha.getResponse($captcha.attr('id')).length !== 0) {\r\n return;\r\n }\r\n window.jwsdwUtil.captcha.execute($captcha.attr('id')).then(submitFormHandler);\r\n } else {\r\n submitFormHandler();\r\n }\r\n\r\n /**\r\n * @function\r\n * @description Handler to trigger submit again when form is valid\r\n * @return {void}\r\n */\r\n function submitFormHandler() {\r\n if (window.jwsdwRecaptchaSettings.captchaDisabled === false &&\r\n validateCaptcha === true && window.jwsdwUtil.captcha.getResponse($captcha.attr('id')).length === 0) {\r\n // no response yet, check again in 200ms\r\n setTimeout(submitFormHandler, 200);\r\n return;\r\n }\r\n\r\n // XHR request to form action url with form fields as parameters\r\n xhr = $.ajax($this.attr('action'), {\r\n 'method': $this.attr('method') || 'GET',\r\n 'data': $this.serialize(),\r\n 'beforeSend': beforeSendCallback,\r\n 'success': successCallback,\r\n 'error': errorCallback,\r\n 'complete': completeCallback\r\n });\r\n }\r\n }\r\n\r\n /**\r\n * Method to execute the before send logic before the ajax call is made\r\n * @returns {void}\r\n */\r\n function notifyMeBeforeSendCallback () {\r\n $formErrorMessage.addClass('jws-hidden');\r\n $submitButton.attr('disabled', 'disabled');\r\n $submitButtonText.addClass('jwsdw-invisible');\r\n $submitButtonSpinner.removeClass('jws-hidden');\r\n }\r\n\r\n /**\r\n * Method to execute after the ajax call was made\r\n * @returns {void}\r\n */\r\n function notifyMeCompleteCallback () {\r\n var $captcha;\r\n if (window.jwsdwRecaptchaSettings.captchaDisabled === false) {\r\n $captcha = $notifyMeForm.find('.g-recaptcha');\r\n window.grecaptcha.reset(window.jwsdwRecaptcha[$captcha.attr('id')]);\r\n }\r\n }\r\n\r\n /**\r\n * Method to execute if login was handled successfully\r\n * @returns {void}\r\n */\r\n function notifyMeSuccessCallback () {\r\n $submitButton.removeAttr('disabled');\r\n $submitButtonText.removeClass('jwsdw-invisible');\r\n $submitButtonSpinner.addClass('jws-hidden');\r\n\r\n $('#jwsdw-notifyMePicker').find('.jws-initial-view').addClass('jws-hidden');\r\n $('#jwsdw-notifyMePicker').find('.jws-success-view').removeClass('jws-hidden');\r\n\r\n // Script Notify Me Button Click (success)\r\n window.dataLayer = window.dataLayer || [];\r\n window.dataLayer.push({\r\n 'event': 'ce.misc',\r\n 'eventCategory': 'MISC',\r\n 'eventAction': 'Notify Me',\r\n 'eventLabel': 'success',\r\n 'eventValue': undefined,\r\n 'nonInteraction': false,\r\n 'selection': undefined\r\n });\r\n }\r\n\r\n /**\r\n * Method to execute if login was not handled successfully\r\n * @param {object} data the response object containing the error\r\n * @returns {void}\r\n */\r\n function notifyMeErorCallback (data) {\r\n $submitButton.removeAttr('disabled');\r\n $submitButtonText.removeClass('jwsdw-invisible');\r\n $submitButtonSpinner.addClass('jws-hidden');\r\n\r\n // jquery ajax returns a wrapped result\r\n data = data.responseJSON ? data.responseJSON : {};\r\n\r\n if (data.code && data.code === 'GENERAL_ERROR') {\r\n $formErrorMessage.find('.jws-notificationMessage').text(data.details.message);\r\n $formErrorMessage.removeClass('jws-hidden');\r\n }\r\n }\r\n\r\n // notifyme form submit listener\r\n $notifyMeForm.on('submit', function (e) {\r\n formSubmit.call(this, e, notifyMeSuccessCallback, notifyMeErorCallback, notifyMeBeforeSendCallback, notifyMeCompleteCallback);\r\n });\r\n}(window, jQuery));"],"names":["widgetId","widgetLang","widgetType","lastURL","baseURL","colors","productIds","colorSelectionInterval","loadWidget","setTimeout","s","sc","url","location","href","substr","lastIndexOf","target","document","getElementById","js","innerHTML","parentElement","removeChild","s1","createElement","id","type","datastream","appendChild","async","src","join","getElementsByTagName","parentNode","insertBefore","window","jwsdwSquarelovinSettings","squarelovinId","languageCode","squarelovinType","substring","jwsdwProductDetailSettings","data","allVariations","attributes","filter","color","length","vals","map","masterID","setInterval","colorSelection","querySelector","el","addEventListener","clearInterval","angular","module","service","$window","$rootScope","Service","youtubeRegexp","timeRegexp","contains","str","indexOf","applyServiceIsReady","$apply","ready","getIdFromURL","pieces","replace","split","decodeURIComponent","getTimeFromURL","full","minutes","times","match","seconds","parseInt","YT","onYouTubeIframeAPIReady","console","log","loaded","directive","youtubeEmbedUtils","uniqId","stateNames","-1","0","1","2","3","5","eventPrefix","YTConfig","host","restrict","scope","videoId","videoUrl","player","playerVars","playerHeight","playerWidth","link","element","attrs","utils","playerId","applyBroadcast","args","Array","prototype","slice","call","arguments","$emit","apply","onPlayerStateChange","event","state","currentState","onPlayerReady","onPlayerError","loadPlayer","list","destroy","copy","start","urlStartTime","Player","height","width","events","onReady","onStateChange","onError","stopWatchingReady","$watch","$watchCollection","setSize","$on","ngTouch","makeSwipeDirective","directiveName","direction","eventName","$parse","$swipe","attr","startCoords","valid","swipeHandler","pointerTypes","isDefined","push","bind","coords","cancel","end","validSwipe","deltaY","Math","abs","y","deltaX","x","triggerHandler","$event","info","angularVersion","factory","POINTER_EVENTS","mouse","move","touch","pointer","getCoordinates","originalEvent","touches","e","changedTouches","clientX","clientY","getEvents","eventType","res","forEach","pointerType","eventHandlers","totalX","totalY","lastPos","active","on","preventDefault","config","$locationProvider","$compileProvider","html5Mode","enabled","requireBase","rewriteLinks","debugInfoEnabled","$inject","constant","isBazaarVoiceActive","jwsdwSettings","baseUrl","productGetImageBaseUrl","disableHistoryApi","deactivateAvailabilityDialogForSales","displayVideo","jwsdwSizeGuide","notifyMeEnabled","ProductDetailController","$scope","$location","$timeout","dataService","productService","ocapiBasketService","trackSwatchChange","generalTracking","util","PRODUCT_DATA","IMAGE_BASE_URL","DISABLE_HISTORY_API","DEACTIVATE_AVAILABILITY_DIALOG_FOR_SALES","DISPLAY_VIDEO","IS_BAZAARVOICE_ACTIVE","NOTIFY_ME_ENABLED","SETTINGS","_oldSize","_oldColor","vm","this","_elementIsAboveViewport","scrollTop","offset","top","$","addClass","removeClass","openFitGuide","level","jwsdwMediator","publish","gender","availableSizes","sizes","size","openSizeGuide","currentId","productId","openNotifyMe","let","selectedColor","notifyMeFallbackColor","selectedSize","productID","productName","productSize","name","isGiftCard","isGiftcard","productColor","image","imageUrl","transforms","viewport","isVisible","dataLayer","eventCategory","eventAction","eventLabel","eventValue","undefined","nonInteraction","selection","displayNoSizeSelectedWarning","_handleOpenNotifyMe","availabilityId","addToBasket","expressCheckout","product","productData","addingProductToBasket","isBonusProduct","price","giftcardpricing","products","priceOld","actionArgs","addViaPipeline","isExpressCheckout","then","addingProductToBasketExpress","updateStickyAddToCart","showStickyCartButton","setGiftcardPrice","amount","formatPriceWithCurency","noSpace","positionOfCurrency","priceFormat","currency","firstDigit","search","formatedPrice","addToWishlist","addToWishlistLoading","customerAuthenticated","wishlistCount","maxWishlistItemsForGuest","isWishlisted","wishlist","itemId","pid","items","showMaxGuestWishlistMessage","callback","_updateMeta","titleParts","title","_browserSupportsHistoryAPI","pathname","newUrl","path","history","replaceState","absUrl","pushState","_isWishlisted","count","find","_updateProductPromotion","productPromotions","promotionName","calloutMsg","specialCalloutMessage","mediaId","imageViewerVisible","contentVisible","reservationStore","giftcardInput","giftcardDefaultPrices","scrollToSizes","imageViewerEnabled","selectNextMediaItem","media","allMedia","hideMedia","currentIndex","mediaIndexById","nextIndex","selectPrevMediaItem","prevIndex","openStoreAvailabilityListPicker","variants","send","action","openGiftcardAmountPicker","removeFromWishlist","productListId","itemIndex","findIndex","splice","showImageViewer","mediaById","getFormattedAddress","store","formattedAddress","address1","address2","giftcardPriceIsZero","test","onSubmitGiftcardInput","form","giftCardAmount","$valid","getProductFlatIndex","imageData","jwsdwProductDetailCtrl","$onInit","fixedCartButton","swatchChange","newSize","newColor","preventImageReload","initialSize","initialColor","update","ats","colorName","sizeName","priceWithoutVAT","_updateStickyCartButton","mediaData","categoryPath","concat","text","jwsdwUtil","debounce","newValue","$watchGroup","values","visible","subscribe","screen","animate","sizeById","colorById","settings","imageViewType","orderable","throttle","supportsPassiveEvents","passive","controller","$log","BAZAARVOICE_ACTIVE","SIZE_SORTING_ORDER","_imageData","_mediaData","_360Data","_sizes","_sizeGuideSizeMap","_colors","_size","_color","_variant","_isSale","_productRating","_sale","_standard","_bestPrice","_priceReduction","_productId","_priceWithoutVAT","_ats","_availabilityId","_freeShipping","_activeFlags","_coBrandingLogo","_sizeType","sizeType","_productPromotions","variant","debug","displayedName","productType","productRating","bestPrice","isSale","priceReduction","colorCode","index","threeSixtyData","sizeMap","hasSizes","Object","keys","some","_initialSize","_initialColor","freeShipping","availabilityMessage","availability","inStockMsg","getProductFlags","getCoBrandingProductFlag","urlUtils","productImageUrl","productImageUrlObject","productImages","_getVariant","_initSizes","_initColors","pricing","sale","standard","round","ID","status","activeFlags","coBrandingLogo","productsPromotions","freeShippingFrom","isEA","_parseImageData","_parseMediaData","_parse360Data","_includeVideo","i","scaleWidth","scaleHeight","format","sfull","xlarge","large","medium","small","thumbGallery","productDescription","techLab-large","techLab-medium","techLab-small","primaloft-large","primaloft-medium","primaloft-small","polartec-large","polartec-medium","polartec-small","swatch","productFeebdack","averageRating","rating","reviewCount","onlyImages","videos","source","sortOrder","_isColorOnSale","_getFirstAvailableVariant","_parseSizes","_updateSizes","getSizeMap","_parseColors","_updateColors","arrayUtils","unique","sort","a","b","sizeA","Number","sizeB","isNaN","splitSizeA","splitSizeB","display","rgb","isBright","colorUtils","isBrightColor","firstColor","secondColor","colorAttribute","colorData","parsedData","attribute","images","meta","imageIndex","specialMessage","videoObject","video","videoData","JSON","parse","RegExp","instruction","instructionData","description","thumbnail","instructionThumbnail","suspension","suspensionSystem","suspensionData","suspensionSystemThumbnail","pop","firstVariant","jwsdwThumbGallery","templateUrl","isActive","_activate","_disable","_onMouseWheel","selectThumb","removeEventListener","wheelDelta","selectPrevThumb","selectNextThumb","getDimensions","style","galleryItem","wrapperHeight","offsetHeight","currentStyle","getComputedStyle","thumbHeight","clientHeight","vSpace","marginBottom","ThumbGalleryController","controllerAs","bindToController","thumbSpace","moveUp","moveDown","thumbY","vOffset","isArrowUpVisible","isArrowDownVisible","thumbCount","completeHeight","maxY","ceil","min","max","newId","ImageViewerController","$document","_enable","_onKeyUp","scrollTo","getKeyCode","_enablePinchZoomListeners","pz","pzElem","resizeHandler","_clearZoomListeners","Promise","all","resolve","dz","dzElem","thumbGalleryHeight","body","initProductImageSwiper","productImageSlider","ProductImageGalleryController","_createCanvas","opt","resizeCanvas","canvas","clientWidth","dpr","devicePixelRatio","_init360Viewer","script","_activate360View","Image","getAttribute","onload","viewer","create360Viewer","fov","PI","dt","setAttribute","append","mobileZoomEnabled","next","item","mediaItems","prev","visualViewport","scale","","furtherDetailsVisible","$evalAsync","options","videoWidth","videoHeight","autoplay","videoAutoplay","controls","videoControls","showinfo","videoShowinfo","modestbranding","videoModestbranding","loop","videoLoop","iframe","bootstrap","checkConsent","runAutoEvent","oldLayer","dynamic_tm_data","productPriceWithVAT","ecommerce","currencyCode","detail","actionField","productname","productid","brand","productbrand","category","categoryid","productColorName","dimension13","shift","dimension14","google_tag_manager","obj","hash","j","trim","click","metaImage","ogimageurl","firstThumbnail","first","newMetaImage","replaceWith","open","jQuery","classList","toggle","innerWidth","show","hide","xhr","$notifyMeForm","$submitButton","$formErrorMessage","$submitButtonText","$submitButtonSpinner","formSubmit","successCallback","errorCallback","beforeSendCallback","completeCallback","$this","$captcha","validateCaptcha","submitFormHandler","jwsdwRecaptchaSettings","captchaDisabled","captcha","getResponse","ajax","method","serialize","beforeSend","success","error","complete","readyState","grecaptcha","execute","notifyMeBeforeSendCallback","notifyMeCompleteCallback","reset","jwsdwRecaptcha","notifyMeSuccessCallback","removeAttr","notifyMeErorCallback","responseJSON","code","details","message","validator","setDefaults","rules","email","invalidvalue","customemail","validate"],"mappings":"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"}