PageSourceSearch

https://secure.keylife.org/jquery/plugins/jquery.studioonline.js

js keylife.org collected 2026-10-04 00:26:07 UTC 96,680 bytes, 2,740 lines download raw bytes

1
2(function ($) {
3	$.extend($.fn, {
4		safeValue: function (_defaultValue) {
5			return ($(this).val() || _defaultValue || '');
6		},
7		disableOnClick: function (options) {
8			return this.each(function (index, Element) {
9				var $this = $(Element);
10				var settings = $.extend(
11					{
12						'attribute': ($this.attr('soattribute') !== undefined ? $this.attr('soattribute') : 'sodisableonclick'),
13						'group': ($this.attr('sogroup') !== undefined ? $this.attr('sogroup') : 'all')
14					}, options);
15				settings.group = $("[" + settings.attribute + "][sogroup" + (settings.group === "all" ? "" : "='") + settings.group + "'" + "]");
16				settings.group.click(function (event) {
17					if (settings.group.hasClass('disabled')) {
18						event.preventDefault();
19					}
20					settings.group.addClass('disabled');
21				});
22			});
23		},
24		showErrorMessage: function (options) {
25			// http://craigsworks.com/projects/qtip2/
26
27			if ($('#soEventDetailPageBottomDiv') && $('#soEventDetailPageBottomDiv').length) {
28				document.getElementById('soEventDetailPageBottomDiv').scrollIntoView();
29			}
30
31			var $this = $(this),
32				$element = $(($this.attr('name') ? "[name='" + $this.attr('name') + "']:last" : this));
33			var width = $(window).width();
34			var settings = $.extend(
35				{
36					'errorType': $(this).attr('data-error-type') || 'soerror',
37					'errorClasses': $(this).attr('data-error-class') || 'ui-tooltip-red ui-tooltip-rounded',
38					'my': $(this).attr('data-error-position-my') || (width > 1000 ? 'left center' : 'top middle'),
39					'at': $(this).attr('data-error-position-at') || (width > 1000 ? 'right center' : 'bottom middle'),
40					'target': $(this).attr('data-error-position-target') || $element,
41					'event': $(this).attr('data-error-event') || 'change',
42				}, options);
43
44			var adjustX = 0;
45			var adjustY = 0;
46
47			if (options.frame) {
48				adjustX = options.frame.offset().left;
49				adjustY = options.frame.offset().top;
50			}
51
52			$element.qtip({
53				content: {
54					text: $(this).attr(settings.errorType + '-message')
55				},
56				position: {
57					my: settings.my,
58					at: settings.at,
59					target: settings.target,
60					adjust: {
61						x: adjustX,
62						y: adjustY
63					}
64				},
65				show: {
66					event: false,
67					ready: true
68				},
69				hide: {
70					target: $("[name='" + $(this).attr('name') + "']"),
71					event: settings.event
72				},
73				style: {
74					classes: settings.errorClasses
75				},
76				solo: true
77			});
78		},
79		isRequired: function () {
80			return ($(this).attr('sorequired') !== undefined) || ($(this).attr('data-required') !== undefined);
81		},
82		inRange: function () {
83			var value = $(this).val(),
84				minimum = $(this).attr('data-range-minimum'),
85				maximum = $(this).attr('data-range-maximum');
86			if (value && ((minimum && value.toFloat() < minimum.toFloat()) || (maximum && maximum.toFloat() && value.toFloat() > maximum.toFloat()))) {
87				return false;
88			}
89			return true;
90		},
91		hasValidPaymentDetails: function () {
92			var $this = $(this);
93			if ($this.attr("data-payment-fieldtype") === 'number') {
94				return $.validateCreditCard($this);
95			}
96			return true;
97		},
98		isChecked: function () {
99			if ($(this).is(':radio, :checkbox')) {
100				return $(this).is(':checked');
101			} else {
102				return $(this).prop('checked');
103			}
104		},
105		isVisible: function () {
106			return $(this).is(':visible');
107		},
108		isGroupChecked: function () {
109			return ($("input[name='" + $(this).attr('name') + "']:checked").length > 0);
110		},
111		hasValue: function () {
112			if (!$(this).length) {
113				return false;
114			}
115			if ($(this).is(':radio, :checkbox') && !$(this).isGroupChecked()) {
116				return false;
117			}
118			else if (!$(this).safeValue().trim()) {
119				return false;
120			}
121			return true;
122		},
123		isValid: function (options) {
124			var settings = $.extend(
125				{
126					'showError': false,
127					'errorClasses': 'ui-tooltip-red ui-tooltip-rounded'
128				}, options);
129
130			var $this = $(this);
131			$this.removeClass("valid");
132			$($this.attr("data-dependencies")).each(function () {
133				if (!$(this).hasValue() && $this.isRequired()) {
134					if (settings.showErrors) {
135						var errorType = 'sorequired';
136						if ($this.attr('data-required-message')) {
137							errorType = 'data-required';
138						}
139						$this.showErrorMessage({ 'errorType': errorType, 'errorClasses': settings.errorClasses });
140					}
141					return false;
142				}
143			});
144			if (!$(this).hasValue() && $(this).isRequired()) {
145				if (settings.showErrors) {
146					var errorType = 'sorequired';
147					if ($(this).attr('data-required-message')) {
148						errorType = 'data-required';
149					}
150					$(this).showErrorMessage({ 'errorType': errorType, 'errorClasses': settings.errorClasses });
151				}
152				return false;
153			}
154			else if (!$(this).inRange()) {
155				if (settings.showErrors) {
156					$(this).showErrorMessage({ 'errorType': 'data-range', 'errorClasses': settings.errorClasses });
157				}
158				return false;
159			}
160			else if (!$(this).hasValidPaymentDetails()) {
161				if (settings.showErrors) {
162					var _errorType = 'sorequired';
163					if ($this.attr('data-payment-message')) {
164						_errorType = 'data-required';
165					}
166					else if ($this.attr('data-required-message')) {
167						_errorType = 'data-required';
168					}
169					$this.showErrorMessage({ 'errorType': _errorType, 'errorClasses': settings.errorClasses });
170				}
171				return false;
172			}
173
174			if ($(this).attr('data-validation-regex') && $(this).isRequired()) {
175				var regex = new RegExp($(this).attr('data-validation-regex'));
176				if (!regex.test($(this).val())) {
177					settings.showErrors = true;
178					$(this).showErrorMessage({ 'errorType': 'data-validation', 'errorClasses': settings.errorClasses });
179					return false;
180				}
181			}
182			$this.addClass("valid");
183			return true;
184		},
185		validate: function (options) {
186			var settings = $.extend(
187				{
188					'showErrors': false,
189					'errorClasses': 'ui-tooltip-red ui-tooltip-rounded'
190				}, options);
191			var valid = true;
192			$(this).find("input, select, textarea").each(function () {
193				if (!$(this).isValid({ 'showErrors': settings.showErrors, 'errorClasses': settings.errorClasses })) {
194					valid = false;
195				}
196			});
197			return valid;
198		},
199		wizardTabs: function (options) {
200			return this.each(function (index, Element) {
201				var parent = $(Element);
202				var settings = $.extend(
203					{
204						'validateSteps': true,
205						'showValidationErrors': true,
206						'errorClasses': 'ui-tooltip-red ui-tooltip-rounded'
207					}, options);
208
209				$(parent).tabs({
210					activate: function (event, ui) {
211						if (settings.validateSteps) {
212							$(parent).find("div.ui-tabs-panel").each(function (index, Element) {
213								if (!$(Element).validate({ 'errorClasses': settings.errorClasses, 'showErrors': settings.showValidationErrors && (ui.index !== index) }) && ui.index > index) {
214									event.preventDefault();
215                                    $(parent).tabs("option", "active", index);
216									return false;
217								}
218							});
219						}
220					},
221					show: function (event, ui) {
222						$(parent).find('div.ui-tabs-hide').find('*').qtip('destroy');
223						if (settings.validateSteps) {
224							$("a[sobuttontype='next']:not([solocked]), a[sobuttontype='submit']:not([solocked])").toggleClass('disabled', !$(ui.panel).validate());
225						}
226					}
227				});
228
229				$("a[sobuttontype='next'], a[sobuttontype='previous']").click(function (event) {
230                    if (!$(this).hasClass('disabled')) {
231                        var index = $(parent).find($(this).attr('sotab')).index() - 1;
232                        $(parent).tabs("option", "active", index);
233					}
234				});
235
236				$("a[sobuttontype='submit']").click(function (event) {
237					if ($(this).hasClass('disabled')) {
238						event.preventDefault();
239					}
240				});
241
242				if (settings.validateSteps) {
243					$(parent).change(function () {
244						var panels = $(parent).find("div.ui-tabs-panel");
245						var index = $(parent).tabs('option', 'active');
246						$("a[sobuttontype='next']:not([solocked]), a[sobuttontype='submit']:not([solocked])").toggleClass('disabled', !$(panels).eq(index).validate({ 'showErrors': false }));
247					});
248
249					var tab_index = $(parent).tabs('option', 'active');
250					var panels = $(parent).find("div.ui-tabs-panel");
251
252					$(panels).each(function (index, Element) {
253						if (!$(Element).validate({ 'showErrors': false }) && tab_index > index) {
254							event.preventDefault();
255                            $(parent).tabs("option", "active", index);
256							return false;
257						}
258					});
259					tab_index = $(parent).tabs('option', 'active');
260					$("a[sobuttontype='next']:not([solocked]), a[sobuttontype='submit']:not([solocked])").toggleClass('disabled', !$(panels).eq(tab_index).validate() && $(this).attr);
261				}
262			});
263		},
264		HoverDialog: function (hoverDivClassName) {
265			return this.each(function (index, Element) {
266				var $this = $(Element);
267				if ($this.data('HoverDialog') != null)
268					return;
269				$this.data('HoverDialog', true);
270				var $hoverDiv = $this.find(".soPopupWindowContainer");
271				var $hoverDivPopup = $this.find(".soPopupWindow");
272
273				// mouseover event
274				$this.mouseover(function () {
275					// .position() uses position relative to the offset parent,
276					var pos = $(this).position();
277
278					// .outerWidth() takes into account border and padding.
279					var width = $(this).outerWidth();
280
281
282					$hoverDivPopup.stop(true, true).fadeIn("fast");
283				});
284				// mouseleave event
285				$this.mouseleave(function () {
286					$(this).find(".soPopupWindow").delay(300).fadeOut();
287				});
288			});
289		},
290		checkedToggle: function (options) {
291			return this.each(function (index, Element) {
292				var $this = $(this);
293				var settings = $.extend({
294					'child': ($this.attr('sotogglechild') !== undefined ? $this.attr('sotogglechild') : ''),
295					'type': ($this.attr('socheckedtoggle') !== undefined ? $this.attr('socheckedtoggle') : 'showHide'),
296					'checkedClass': ($this.attr('sotogglecheckedclass') !== undefined ? $this.attr('sotogglecheckedclass') : 'checked'),
297					'unCheckedClass': ($this.attr('sotoggleuncheckedclass') !== undefined ? $this.attr('sotoggleuncheckedclass') : 'unchecked')
298				}, options);
299
300				if (settings.child === '') {
301					settings.child = $this.next('div');
302				}
303
304				if (settings.type === 'socheckedtoggle') {
305					settings.type = 'showHide';
306				}
307
308				settings.child = $(settings.child);
309
310				$(this).change(function () {
311					var $this = $(this);
312					if ($this.isChecked()) {
313						settings.child.removeAttr('solocked');
314						if (settings.type === 'showHide') {
315							settings.child.slideDown();
316						}
317						else {
318							settings.child.removeClass(settings.unCheckedClass);
319							settings.child.addClass(settings.checkedClass);
320						}
321					}
322					else {
323						settings.child.attr('solocked', '');
324						if (settings.type === 'showHide') {
325							settings.child.slideUp();
326						}
327						else {
328							settings.child.removeClass(settings.checkedClass);
329							settings.child.addClass(settings.unCheckedClass);
330						}
331					}
332					return true;
333				});
334
335				if ($this.isChecked()) {
336					if (settings.type === 'showHide') {
337						settings.child.show();
338					}
339					else {
340						settings.child.addClass(settings.checkedClass);
341						settings.child.removeClass(settings.unCheckedClass);
342					}
343				}
344				else {
345					if (settings.type === 'showHide') {
346						settings.child.hide();
347					}
348					else {
349						settings.child.removeClass(settings.checkedClass);
350						settings.child.addClass(settings.unCheckedClass);
351					}
352				}
353			});
354		},
355		moveTo: function (selector) {
356			if ($(selector) !== undefined) {
357				return this.each(function () {
358					$(this).appendTo($(selector));
359				});
360			}
361		},
362		listPager: function (options) {
363			return this.each(function (index, Element) {
364				var parent = $(Element);
365				if (parent.attr("id") === "") {
366					parent.attr("id", "soautolistpager" + (index + 1).toString());
367				}
368				var parentID = parent.attr("id");
369				parent.attr("role", "listpager");
370				var settings = $.extend(
371					{
372						'ellipse': (parent.attr('soellipse') !== undefined ? parent.attr('soellipse') : '...'),
373						'nexttext': (parent.attr('sonexttext') !== undefined ? parent.attr('sonexttext') : 'Next'),
374						'previoustext': (parent.attr('soprevioustext') !== undefined ? parent.attr('soprevioustext') : 'Previous'),
375						'pagesizeoptions': (parent.attr('sopagesizeoptions') !== undefined
376							? $.parseJSON('[' + parent.attr('sopagesizeoptions').replace('[', '').replace(']', '') + ']')
377							: [10, 20, 30])
378					}, options);
379
380				var listpageritems = $("#" + parentID + " [solistpageritem]");
381				var count = listpageritems.length;
382				if (count <= settings.pagesizeoptions.min()) {
383					return;
384				}
385				var html = '';
386				var paginationTopID = $(parent).attr("id") + '_PaginationTop';
387				var ddlItemsPerPageID = $(parent).attr("id") + '_ItemsPerPage';
388				var currentPageID = $(parent).attr("id") + '_CurrentPage';
389				var pagelistID = $(parent).attr("id") + '_PageList';
390				var paginationBottomID = $(parent).attr("id") + '_PaginationBottom';
391				if ($(parent).find(currentPageID).length === 0) {
392					$(parent).prepend('<div id="' + pagelistID + '" class="pagelist" />');
393					if ($(parent).find(paginationTopID).length === 0) {
394						html = '<div id="' + paginationTopID + '" class="PagedContainer"><div class="page-sizer">' +
395							'<label for="' + ddlItemsPerPageID + '" class="page-sizer-description">Show:</label> ' +
396							'<select id="' + ddlItemsPerPageID + '" name="' + ddlItemsPerPageID + '">';
397						for (var i = 0; i < settings.pagesizeoptions.length; i++) {
398							html += '<option Value="' + settings.pagesizeoptions[i].toString() + '">' +
399								settings.pagesizeoptions[i].toString() + ' Per Page</option>';
400						}
401						html += '<option Value="' + count.toString() + '">All Items</option>';
402						html += '</select></div></div>';
403						$(parent).prepend(html);
404					}
405					$(parent).prepend('<div class="soPageDisplayItems"><span class="page-display-items-title">Displaying items </span>' +
406						'<span id="' + currentPageID + '" class="page-display-items-nbr"></span>' +
407						'<span class="page-display-items-title"> of </span><span class="page-display-items-nbr">' + listpageritems.length.toString() + '</span></div>');
408				}
409				$($('#' + pagelistID).next()).moveTo('#' + pagelistID);
410				if ($(parent).find(paginationBottomID).length === 0) {
411					$(parent).append('<div id="' + paginationBottomID + '" class="pagination"></div>');
412					$(parent).append(html.replace(ddlItemsPerPageID, ddlItemsPerPageID + '2') + '<div class="dsclear"></div>');
413				}
414
415				var opt = {
416					items_per_page: $('#' + ddlItemsPerPageID).val(),
417					num_display_entries: 10,
418					current_page: 0,
419					num_edge_entries: 2,
420					link_to: "#",
421					prev_text: settings.previoustext,
422					next_text: settings.nexttext,
423					ellipse_text: settings.ellipsetext,
424					prev_show_always: false,
425					next_show_always: false,
426					callback: function (page_index, Element) {
427						var items_per_page = $('#' + ddlItemsPerPageID).val();
428						var max_elem = Math.min((page_index + 1) * items_per_page, listpageritems.length);
429						var min_elem = page_index * items_per_page;
430						listpageritems.hide();
431						$('#' + currentPageID).text((min_elem + 1).toString() + ' - ' + (max_elem).toString());
432						for (var i = min_elem; i < max_elem; i++) {
433							$(listpageritems[i]).show();
434						}
435						return false;
436					}
437				};
438				$("#" + paginationBottomID).pagination(listpageritems.length, opt);
439				$('#' + ddlItemsPerPageID + ', #' + ddlItemsPerPageID + '2').change(function () {
440					$('#' + ddlItemsPerPageID + ', #' + ddlItemsPerPageID + '2').val($(this).val());
441					if (opt.items_per_page !== $(this).val()) {
442						opt.items_per_page = $(this).val();
443						$("#" + paginationBottomID).pagination(listpageritems.length, opt);
444					}
445				});
446			});
447		},
448		decimal: function (options) {
449			return this.each(function (index, Element) {
450				var $this = $(Element);
451
452				var settings = $.extend(
453					{
454						'precision': ($this.attr('data-decimal-precision') || $this.attr('soprecision') || '2').toInt(),
455						'minAmount': ($this.attr('data-decimal-minamount') || $this.attr('sominamount') || '0').toFloat(),
456						'maxAmount': ($this.attr('data-decimal-maxamount') || $this.attr('somaxamount') || '1000000').toFloat(),
457						'toolTip': ($this.attr('data-decimal-tooltip') || $this.attr('sotooltip') || '')
458					}, options);
459
460				if (isNaN(settings.precision) || settings.precision < 0) {
461					settings.precision = 2;
462				}
463				if (isNaN(settings.minAmount) || settings.minAmount < 0) {
464					settings.minAmount = 0;
465				}
466				if (isNaN(settings.maxAmount) || settings.maxAmount < 0) {
467					settings.maxAmount = 1000000;
468				}
469
470				var maxlength = settings.maxAmount.toString().length + settings.precision;
471
472				if (settings.precision) {
473					maxlength++;
474				}
475				if (settings.toolTip) {
476					$this.attr("title", settings.toolTip);
477				}
478				$this.attr("maxlength", maxlength);
479				$this.attr("size", maxlength);
480
481				$this.on('update', function () {
482					var amount = $this.val().toFloat();
483					if (isNaN(amount) || amount < 0 || amount < settings.minAmount) {
484						amount = settings.minAmount;
485					}
486					else if (amount > settings.maxAmount) {
487						amount = settings.maxAmount;
488					}
489					$this.val(amount.toFixed(settings.precision));
490				});
491
492				$this.blur(function () {
493					$this.trigger("update");
494				});
495
496				$(document).ready(function () {
497					$this.trigger("update");
498				});
499			});
500		},
501		emailDialog: function (options) {
502			return this.each(function (index, Element) {
503				var $this = $(Element);
504
505				var settings = $.extend(
506					{
507						'solink': ($this.attr('solink') !== undefined ? $this.attr('solink') : ''),
508						'solinktitle': ($this.attr('solinktitle') !== undefined ? $this.attr('solinktitle') : ''),
509						'sotitle': ($this.attr('sotitle') !== undefined ? $this.attr('sotitle') : 'Send Email')
510					}, options);
511
512				var $emaildialog = $("[sodialog][sodialogname='email']");
513				// var dialogHeight = $(window).height() * .7;
514				// var dialogWidth = $(window).width() *.75;
515				$this.on('show', function () {
516
517					var width = 1050;
518					if ($(window).width() * .9 < width) {
519						width = $(window).width() * .9;
520					}
521
522					$emaildialog.dialog({
523						modal: false,
524						autoOpen: true,
525						position: {
526							my: "center",
527							at: "center",
528							of: window,
529							collision: "fit",
530							using: function (pos) {
531								var topOffset = $(this).css(pos).offset().top;
532								if (topOffset < 0) {
533									$(this).css("top", pos.top - topOffset);
534								}
535							}
536						},
537						height: $(window).height() * .7,
538						width: width,
539						minHeight: 300,
540						minWidth: 200,
541						title: settings.sotitle,
542						open: function (event, ui) {
543							$(this).parent().appendTo("form:first");
544							if ($('input[id$="ShowEmailDialog"]').val() === 'false') {
545								$("[sodialog][sodialogname='email'] [sohtmlarea]").val('<a href="' + settings.solink + '">' + settings.solinktitle + '</a>');
546								$('div[id$="ValEmailDialog"]').hide();
547								$emaildialog.find('input').val('');
548							}
549							else {
550								$('input[id$="ShowEmailDialog"]').val('false');
551							}
552						},
553						close: function (event, ui) {
554							$('input[id$="ShowEmailDialog"]').val('false');
555						}
556					});
557				});
558
559				$("[sodialog][sodialogname='email'] [soclosedialog]").click(function (event) {
560					event.preventDefault();
561					$emaildialog.dialog('close');
562				});
563
564				$this.click(function (event) {
565					event.preventDefault();
566					$this.trigger("show");
567				});
568
569				$(document).ready(function () {
570					if ($('input[id$="ShowEmailDialog"]').val() === 'true') {
571						$this.trigger("show");
572					}
573				});
574
575			});
576		},
577		nodeToggle: function (options) {
578			return this.each(function (index, Element) {
579				var $this = $(Element);
580				if ($this.data('nodeToggle') != null)
581					return;
582				$this.data('nodeToggle', true);
583				$this.addClass('ui-icon');
584				var settings = $.extend(
585					{
586						'child': $this.attr('sonodetogglechild') || '',
587						'display': $this.attr('sonodetoggledisplay') || 'collapsed'
588					}, options);
589
590				if (!['collapsed', 'expanded'].contains(settings.display)) {
591					settings.display = 'collapsed';
592				}
593
594				if (settings.child === '') {
595					settings.child = $this.next('div');
596				}
597
598				settings.child = $(settings.child);
599
600				$this.on('update', function () {
601					if ($this.isChecked()) {
602						$this.prop('checked', false);
603						settings.child.removeAttr('solocked');
604						settings.child.slideDown();
605						$this.removeClass('ui-icon-plusthick');
606						$this.addClass('ui-icon-minusthick');
607					}
608					else {
609						$this.prop('checked', true);
610						settings.child.attr('solocked', '');
611						settings.child.slideUp();
612						$this.addClass('ui-icon-plusthick');
613						$this.removeClass('ui-icon-minusthick');
614					}
615				});
616
617				if (settings.display === 'collapsed') {
618					settings.child.hide();
619				}
620				else {
621					$this.prop('checked', true);
622				}
623				$this.trigger("update");
624				$this.click(function () {
625					$this.trigger("update");
626				});
627
628				//custom node toggle icon
629				var customIcon = $this.parent().find('.expandCollapseIcon');
630				if (customIcon.length > 0) {
631					var initialStatus = typeof $this.attr('sonodetoggledisplay') == 'undefined' ? 'collapsed' : $this.attr('sonodetoggledisplay');
632					customIcon.addClass(initialStatus);
633				}
634
635				$this.click(function () {
636					if (customIcon.length > 0) {
637						if (customIcon.hasClass('expanded'))
638							customIcon.removeClass('expanded').addClass('collapsed');
639						else
640							customIcon.removeClass('collapsed').addClass('expanded');
641					}
642				});
643			});
644		},
645		soAutoComplete: function (options) {
646			return this.each(function (index, Element) {
647				var $this = $(Element);
648				var data = '';
649				if ($this.attr('soautocompleteparametername') !== undefined
650					&& $this.attr('soautocompleteargumentattribute') !== undefined
651					&& $this.attr($this.attr('soautocompleteargumentattribute')) !== undefined) {
652					data = ", '" + $this.attr('soautocompleteparametername') + "': '" + $this.attr($this.attr('soautocompleteargumentattribute')) + "'";
653				}
654				var settings = $.extend({
655					'minLength': ($this.attr('sominlength') !== undefined ? $this.attr('sominlength') : 2),
656					'maxResults': ($this.attr('somaxresults') !== undefined ? $this.attr('somaxresults') : 10),
657					'method': ($this.attr('soautocompletetype') !== undefined ? $this.attr('soautocompletetype') : ''),
658					'data': ($this.attr('sodata') !== undefined ? $this.attr('sodata') : data)
659				}, options);
660				$this.autocomplete({
661					source: function (request, response) {
662						$.ajax({
663							url: "ClientScriptHelper.asmx/" + settings.method,
664							data: "{ 'prefix': '" + request.term + "', 'maxResults':" + settings.maxResults + settings.data + " }",
665							dataType: "json",
666							type: "POST",
667							contentType: "application/json; charset=utf-8",
668							dataFilter: function (data) { return data; },
669							success: function (data) {
670								response($.map(data.d, function (item) {
671									return {
672										value: item
673									};
674								}));
675							}
676						});
677					},
678					minLength: settings.minLength
679				});
680			});
681		},
682		soCascadingDropDown: function (options) {
683			return this.each(function (index, Element) {
684				var $this = $(Element);
685				var settings = $.extend({
686					'section': ($this.attr('sosection') !== undefined ? $this.attr('sosection') : ''),
687					'method': ($this.attr('socascadingdropdowntype') !== undefined ? $this.attr('socascadingdropdowntype') : ''),
688					'selectOption': ($this.attr('soselectoption') !== undefined ? $this.attr('soselectoption') : ''),
689					'parameterName': ($this.attr('socascadingdropdownparametername') !== undefined ? $this.attr('socascadingdropdownparametername') : ''),
690					'argumentAttribute': ($this.attr('socascadingdropdownargumentattribute') !== undefined ? $this.attr('socascadingdropdownargumentattribute') : ''),
691					'parentParameterName': ($this.attr('socascadingdropdownparentparametername') !== undefined ? $this.attr('socascadingdropdownparentparametername') : ''),
692					'parentValueParameter': ($this.attr('socascadingdropdownparentvalueparameter') !== undefined ? $this.attr('socascadingdropdownparentvalueparameter') : ''),
693					'parentArgumentAttribute': ($this.attr('socascadingdropdownparentargumentattribute') !== undefined ? $this.attr('socascadingdropdownparentargumentattribute') : ''),
694					'parent': ($this.attr('socascadingdropdownparent') !== undefined ? $.parseJSON($this.attr('socascadingdropdownparent')) : '')
695				}, options);
696
697				$(document).ready(function () {
698					var value = $this.val();
699					$.each(settings.parent, function (index, parent) {
700						var $parent = settings.section !== '' ? $('[sosection ="' + settings.section + '"]' + parent) : $(parent);
701						if ($parent.length) {
702							$this.prop('disabled', true).children().remove().end();
703						}
704						if (settings.selectOption !== '' && index === 0) {
705							$this.append($('<option></option>').val('').html(settings.selectOption.trim()));
706						}
707						$parent.change(function () {
708							$.ajax({
709								type: "POST",
710								url: "ClientScriptHelper.asmx/" + settings.method,
711								data: "{ '" + settings.parentValueParameter + "': '" + $parent.val() + "', '"
712								+ settings.parentParameterName + "': '" + $parent.attr(settings.parentArgumentAttribute) + "', '"
713								+ settings.parameterName + "': '" + $this.attr(settings.argumentAttribute) + "' }",
714								contentType: "application/json; charset=utf-8",
715								dataType: "json",
716								success: function (data) {
717									//clear list
718									$this.prop('disabled', true).children().remove().end();
719									if (settings.selectOption !== '') {
720										$this.append($('<option></option>').val('').html(settings.selectOption.trim()));
721									}
722									if ($parent.val() === '') {
723										return;
724									}
725									$.each(data.d, function (i, item) {
726										//add items
727										$this.prop('disabled', false);
728										$this.append($('<option></option>').val(item.Value.trim()).html(item.Text.trim()));
729									});
730									if (value !== '') {
731										$this.val(value);
732									}
733								}
734							});
735						});
736						$parent.trigger('change');
737					});
738				});
739
740			});
741		},
742		changeElementType: function (newType) {
743			var newElements = [];
744			$(this).each(function () {
745				var attrs = {};
746				$.each(this.attributes, function (idx, attr) {
747					attrs[attr.nodeName] = attr.nodeValue;
748				});
749
750				var newElement = $("<" + newType + "/>", attrs).html($(this).html());
751				$(this).replaceWith(newElement);
752				newElements.push(newElement);
753			});
754			return $(newElements);
755		},
756		soCountryCascadingDropDown: function (options) {
757			return this.each(function (index, Element) {
758				var $this = $(Element);
759				var settings = $.extend({
760					'section': ($this.attr('data-section') !== undefined ? $this.attr('data-section') : ''),
761					'childSelector': ($this.attr('data-child-selector') !== undefined ? $this.attr('data-child-selector') : "[data-address-fieldtype='State']")
762				}, options);
763
764				settings.childSelector = settings.section !== '' ? '[data-section ="' + settings.section + '"]' + settings.childSelector : settings.childSelector;
765
766				var $child = $(this).parents(".addressInfoMainDiv").find(settings.childSelector),
767					orginalValue = ((options && options.country) || $this.val() || ''),
768					orginalChildValue = ((options && options.state) || $child.val() || '');
769
770				$child.prop('disabled', true).children().remove().end();
771				$.ajax({
772					type: "POST",
773					url: "ClientScriptHelper.asmx/GetCountries",
774					contentType: "application/json; charset=utf-8",
775					dataType: "json",
776					data: '{}',
777					success: function (data) {
778						//clear list
779						$this.children().remove().end();
780						if (($this.attr('so-watermark-text') || '').length)
781							$this.append($('<option></option>').val('').html($this.attr('so-watermark-text')));
782						$.each(data.d, function (i, item) {
783							//add items
784							$this.prop('disabled', false);
785							$this.append(
786								$('<option></option>')
787									.val(item.Country_Name.trim())
788									.html(item.Country_Name.trim())
789									.attr('data-country-id', item.Country_ID)
790									.attr('data-country-name', item.Country_Name)
791									.attr('data-isocode-twoletter', item.ISOCode_TwoLetter)
792									.attr('data-isocode-threeletter', item.ISOCode_ThreeLetter)
793									.attr('data-isocode-numeric', item.ISOCode_Numeric)
794									.attr('data-postalcode-required', item.PostalCode_Required)
795									.attr('data-postalcode-regex', item.PostalCode_Regex)
796									.attr('data-postalcode-example', item.PostalCode_Example)
797									.attr('data-qas-layout', item.Qas_Layout)
798									.data("country-states", item.States)
799							);
800
801						});
802						$this.change(function () {
803							$("[data-address-fieldtype]").qtip('destroy');
804
805							var $selectedCountry = $("option:selected", $("[data-address-fieldtype='Country']"));
806							var countryIso3Code = $selectedCountry.attr("data-isocode-threeletter");
807
808							if (countryIso3Code !== "USA" && countryIso3Code !== "CAN" && countryIso3Code !== "GBR") {
809								$("input[id=QAS_BYPASS]").val("true");
810							}
811							else {
812								$("input[id=QAS_BYPASS]").val("false");
813							}
814
815							var stateDropDown = $(this).parents(".addressInfoMainDiv").find("select[data-address-fieldtype='State']");
816							if (stateDropDown.length == 0)
817								stateDropDown = $("option:selected", this).data('countryStates');
818
819							if (stateDropDown && stateDropDown.length > 0) {
820								var states = $("option:selected", this).data('countryStates');
821								var classes = $child.attr('class');
822								//clear list
823								$child.children().remove().end();
824								if (($child.attr('so-watermark-text') || '').length)
825									$child.append($('<option></option>').val('').html($child.attr('so-watermark-text')));
826
827								if (states && states.length) {
828									//  $child.changeElementType('select');
829									$child = $(this).parents(".addressInfoMainDiv").find(settings.childSelector);
830									$.each(states, function (i, item) {
831										//add items
832										$child.prop('disabled', false);
833										$child.append($('<option></option>').val(item.Abbreviation.trim()).html(item.Name.trim()));
834									});
835								}
836								else {
837									// $child.changeElementType('input');
838									$child = $(this).parents(".addressInfoMainDiv").find(settings.childSelector);
839									$child.prop('disabled', true);
840								}
841								if (($child.attr('so-watermark-class-name') || '').length)
842									$child.removeClass($child.attr('so-watermark-class-name'));
843								if (($child.attr('so-watermark-text') || '').length && ($child.attr('so-watermark-text') || '').toLowerCase() !== 'select')
844									$child.soWatermark();
845								if (orginalChildValue.length) {
846									$child.val(orginalChildValue);
847								}
848								else {
849									$child.val('');
850									$("option:first", $child).prop('selected', true);
851								}
852								$child.addClass(classes);
853								$child.trigger('change');
854							}
855
856							var zipCode = $(this).parents(".addressInfoMainDiv").find("input[data-address-fieldtype='Zip']");
857
858							if (zipCode.length > 0)
859								zipCode.attr('data-validation-regex', $("option:selected", this).attr("data-postalcode-regex"));
860
861							var $uiRequired = $('[id*=Asterisk]');
862							var isValidationRequired = ($("option:selected", this).attr("data-postalcode-required") == "true");
863
864							if (isValidationRequired) {
865								$uiRequired.text("*");
866								$('[CountryDependent]').each(function () {
867									$(this).attr("data-required", "true");
868								});
869								$('.stateNotRequired').css('display', 'none');
870							}
871							else {
872								$uiRequired.text(" ");
873								$('[CountryDependent]').each(function () {
874									$(this).removeAttr("data-required");
875								});
876								$('.stateNotRequired').css('display', 'block');
877							}
878
879						});
880						if (orginalValue.length) {
881							$this.val(orginalValue);
882						}
883						else {
884							$("option:first", this).prop('selected', true);
885						}
886						$this.trigger('change');
887						$child.trigger('change');
888						orginalChildValue = orginalValue = '';
889					},
890				});
891			});
892		},
893		soAccordion: function (options) {
894			return this.each(function (index, Element) {
895				var $this = $(Element);
896				var settings = $.extend({
897					'icons': ($this.attr('data-accordion-icons') !== undefined ? $this.attr('data-accordion-icons') : '{ "header": "default", "headerSelected": "default" }'),
898					'collapsible': ($this.attr('data-accordion-collapsible') !== undefined ? $.parseJSON($this.attr('data-accordion-collapsible')) : false),
899					'active': ($this.attr('data-accordion-active') !== undefined ? $this.attr('data-accordion-active').toInt() : 0),
900					'heightStyle': ($this.attr('data-accordion-height-style') !== undefined ? $this.attr('data-accordion-height-style') : "auto"),
901					'header': ($this.attr('data-accordion-header') !== undefined ? $this.attr('data-accordion-header') : 'h3'),
902					'sortable': ($this.attr('data-accordion-sortable') !== undefined ? $.parseJSON($this.attr('data-accordion-sortable')) : false)
903				}, options);
904
905				if (settings.icons.toLowerCase() === 'none') {
906					settings.icons = false;
907				}
908				else {
909					settings.icons = $.parseJSON(settings.icons);
910				}
911
912				$this.accordion({
913					autoHeight: false,
914					navigation: true,
915					icons: settings.icons,
916					collapsible: settings.collapsible,
917					active: settings.active,
918					heightStyle: settings.heightStyle,
919					header: settings.header,
920					create: function (event, ui) {
921						$this.find(".ui-accordion-header").prop('checked', false);
922						$(ui.Header).prop('checked', true);
923						$this.find(".ui-accordion-header").trigger('change');
924					},
925					change: function (event, ui) {
926						$this.find(".ui-accordion-header").prop('checked', false);
927						$(ui.newHeader).prop('checked', true);
928						$this.find(".ui-accordion-header").trigger('change');
929					}
930				});
931				if (settings.sortable) {
932					$this.sortable({
933						axis: "y",
934						handle: "h3",
935						stop: function (event, ui) {
936							ui.item.children("h3").triggerHandler("focusout");
937						}
938					});
939				}
940			});
941		},
942		imageDialog: function (options) {
943			return this.each(function (index, Element) {
944				var $this = $(Element);
945				var $imagewidth = $(window).width() * .6;
946				var settings = $.extend(
947					{
948						'title': ($this.attr('data-dialog-title') !== undefined ? $this.attr('data-dialog-title') : null),
949						'id': ($this.attr('data-dialog-id') !== undefined ? $this.attr('data-dialog-id') : 'None'),
950						'resizable': ($this.attr('data-dialog-resizable') !== undefined ? $this.attr('data-dialog-resizable') : false),
951						'modal': ($this.attr('data-dialog-modal') !== undefined ? $this.attr('data-dialog-modal') : true),
952						'position': ($this.attr('data-dialog-position') !== undefined ? $this.attr('data-dialog-position') : "center"),
953						'height': ($this.attr('data-dialog-height') !== undefined && $this.attr('data-dialog-height').isNumber() ? $this.attr('data-dialog-height') : 'auto'),
954						'width': ($this.attr('data-dialog-width') !== undefined && $this.attr('data-dialog-width').isNumber() ? $this.attr('data-dialog-width') : 'auto'),
955						'show': ($this.attr('data-dialog-show-effect') !== undefined ? $.parseJSON($this.attr('data-dialog-show-effect')) : null),
956						'hide': ($this.attr('data-dialog-hide-effect') !== undefined ? $.parseJSON($this.attr('data-dialog-hide-effect')) : null),
957						'action': ($this.attr('data-dialog-action') !== undefined ? $this.attr('data-dialog-action') : 'open')
958					}, options);
959
960				var $imagedialog = $("[data-role='dialog'][data-dialog-name='image'][data-dialog-id='" + settings.id + "']");
961				if (settings.id === 'None') {
962					$imagedialog = $("[data-role='dialog'][data-dialog-name='image']");
963				}
964
965				$this.click(function (event) {
966					if (settings.action === 'close') {
967						$imagedialog.dialog("close");
968					}
969					else {
970						$imagedialog.dialog("option",
971							{
972								resizable: settings.resizable,
973								modal: settings.modal,
974								position: settings.position
975							});
976						if (settings.hide !== null) {
977							$imagedialog.dialog("option", { hide: settings.hide });
978						}
979						if (settings.show !== null) {
980							$imagedialog.dialog("option", { show: settings.show });
981						}
982						if (settings.title !== null) {
983							$imagedialog.dialog("option", { title: settings.title });
984						}
985						if (settings.height !== null) {
986							$imagedialog.dialog("option", { height: settings.height });
987						}
988						if (settings.width !== null) {
989							$imagedialog.dialog("option", { width: settings.width });
990						}
991						$imagedialog.dialog("open");
992					}
993					event.preventDefault();
994				});
995
996			});
997		},
998		qasControl: function (options) {
999			function GetStringResource(key) {
1000				var stringResource = key;
1001
1002				$.ajax({
1003					type: "POST",
1004					url: "ClientScriptHelper.asmx/GetString",
1005					contentType: "application/json; charset=utf-8",
1006					dataType: "json",
1007					data: '{"key":"' + key + '"}',
1008					async: false,
1009					timeout: 5000,
1010					success: function (data) {
1011						stringResource = data.d.toString();
1012					}
1013				});
1014
1015				return stringResource;
1016			}
1017
1018			function addressHash() {
1019				return md5($("[data-address-fieldtype]").serialize());
1020			}
1021			if ($("#QASEnabled").val() !== 'true') {
1022				return;
1023			}
1024			return this.each(function (index, Element) {
1025				var $this = $(Element);
1026				$this.attr("id", "qas_ondemand_wgt");
1027
1028				var settings = $.extend({
1029					'selectorSubmit': ($this.attr('data-selector-submit') !== undefined ? $this.attr('data-selector-submit') : null),
1030					'selectorEnabled': ($this.attr('data-selector-enabled') !== undefined ? $this.attr('data-selector-enabled') : null)
1031				}, options);
1032
1033				if (settings.selectorSubmit !== null && settings.selectorSubmit.length) {
1034					settings.selectorSubmit = $(settings.selectorSubmit);
1035				}
1036
1037				if (settings.selectorEnabled !== null && settings.selectorEnabled.length) {
1038					settings.selectorEnabled = $(settings.selectorEnabled);
1039				}
1040
1041				$this.append('<input type="hidden" id="QAS_BYPASS" value="false" />');
1042				$this.append('<input type="hidden" id="QAS_VERIFIED" value="false" />');
1043				$this.append('<link href="qas/ondemand/qas.css" rel="stylesheet" type="text/css" />');
1044
1045				var inputFields = [
1046					{
1047						"type": "Street1",
1048						"selector": "[data-address-fieldtype='Street1']",
1049						"autoCreate": true,
1050						"required": true,
1051						"qasRequired": true,
1052						"errorMessage": GetStringResource("SO.Account.Address1.Required.ErrorMessage"),
1053						"exists": function () {
1054							return $(this.selector)
1055								.length > 0;
1056						},
1057						"create": function () {
1058							if (this.exists()) {
1059								return;
1060							} else {
1061								$this.append("<input type='hidden' data-address-fieldtype='" + this.type + "' id='QAS_" + this.type + "' />");
1062							}
1063						},
1064						"id": function () {
1065							if (this.autoCreate) {
1066								this.create();
1067							}
1068							return $(this.selector)
1069								.attr("id");
1070						}
1071					}, {
1072						"type": "Street2",
1073						"selector": "[data-address-fieldtype='Street2']",
1074						"autoCreate": true,
1075						"required": false,
1076						"qasRequired": false,
1077						"errorMessage": GetStringResource("SO.Account.Address2.Required.ErrorMessage"),
1078						"exists": function () {
1079							return $(this.selector)
1080								.length > 0;
1081						},
1082						"create": function () {
1083							if (this.exists()) {
1084								return;
1085							} else {
1086								$this.append("<input type='hidden' data-address-fieldtype='" + this.type + "' id='QAS_" + this.type + "' />");
1087							}
1088						},
1089						"id": function () {
1090							if (this.autoCreate) {
1091								this.create();
1092							}
1093							return $(this.selector)
1094								.attr("id");
1095						}
1096					}, {
1097						"type": "Street3",
1098						"selector": "[data-address-fieldtype='Street3']",
1099						"autoCreate": false,
1100						"required": false,
1101						"qasRequired": false,
1102						"errorMessage": GetStringResource("SO.Account.Address3.Required.ErrorMessage"),
1103						"exists": function () {
1104							return $(this.selector)
1105								.length > 0;
1106						},
1107						"create": function () {
1108							if (this.exists()) {
1109								return;
1110							} else {
1111								$this.append("<input type='hidden' data-address-fieldtype='" + this.type + "' id='QAS_" + this.type + "' />");
1112							}
1113						},
1114						"id": function () {
1115							if (this.autoCreate) {
1116								this.create();
1117							}
1118							return $(this.selector)
1119								.attr("id");
1120						}
1121					}, {
1122						"type": "City",
1123						"selector": "[data-address-fieldtype='City']",
1124						"autoCreate": true,
1125						"required": true,
1126						"errorMessage": GetStringResource("SO.Account.City.Required.ErrorMessage"),
1127						"exists": function () {
1128							return $(this.selector)
1129								.length > 0;
1130						},
1131						"create": function () {
1132							if (this.exists()) {
1133								return;
1134							} else {
1135								$this.append("<input type='hidden' data-address-fieldtype='" + this.type + "' id='QAS_" + this.type + "' />");
1136							}
1137						},
1138						"id": function () {
1139							if (this.autoCreate) {
1140								this.create();
1141							}
1142							return $(this.selector)
1143								.attr("id");
1144						}
1145					}, {
1146						"type": "State",
1147						"selector": "[data-address-fieldtype='State']",
1148						"autoCreate": true,
1149						"required": true,
1150						"qasRequired": false,
1151						"errorMessage": GetStringResource("SO.Account.State.Required.ErrorMessage"),
1152						"exists": function () {
1153							return $(this.selector)
1154								.length > 0;
1155						},
1156						"create": function () {
1157							if (this.exists()) {
1158								return;
1159							} else {
1160								$this.append("<input type='hidden' data-address-fieldtype='" + this.type + "' id='QAS_" + this.type + "' />");
1161							}
1162						},
1163						"id": function () {
1164							if (this.autoCreate) {
1165								this.create();
1166							}
1167							return $(this.selector)
1168								.attr("id");
1169						}
1170					}, {
1171						"type": "Zip",
1172						"selector": "[data-address-fieldtype='Zip']",
1173						"autoCreate": true,
1174						"required": true,
1175						"qasRequired": true,
1176						"errorMessage": GetStringResource("SO.Account.Zip.Required.ErrorMessage"),
1177                        "exists": function () {
1178                            //Filter out input fields from the subscription widget
1179                            var zips = $(this.selector).not('[id*=WidgetSubscribe]');
1180                            return zips.length > 0;
1181						},
1182						"create": function () {
1183							if (this.exists()) {
1184								return;
1185							} else {
1186								$this.append("<input type='hidden' data-address-fieldtype='" + this.type + "' id='QAS_" + this.type + "' />");
1187							}
1188						},
1189						"id": function () {
1190							if (this.autoCreate) {
1191								this.create();
1192							}
1193							return $(this.selector)
1194								.attr("id");
1195						}
1196					}, {
1197						"type": "Country",
1198						"selector": "[data-address-fieldtype='Country']",
1199						"autoCreate": true,
1200						"required": true,
1201						"qasRequired": true,
1202						"errorMessage": GetStringResource("SO.Account.Country.Required.ErrorMessage"),
1203                        "exists": function () {
1204                            //Filter out input fields from the subscription widget
1205                            var countries = $(this.selector).not('[id*=WidgetSubscribe]');
1206                            return countries.length > 0;
1207						},
1208						"create": function () {
1209							if (this.exists()) {
1210								return;
1211							} else {
1212								$this.append("<input type='hidden' data-address-fieldtype='" + this.type + "' id='QAS_" + this.type + "' />");
1213							}
1214						},
1215						"id": function () {
1216							if (this.autoCreate) {
1217								this.create();
1218							}
1219							return $(this.selector)
1220								.attr("id");
1221						}
1222					}
1223				];
1224				$.getScript("qas/ondemand/qas.js", function () {
1225					PROXY_PATH = "qas/ondemand/qas_proxy.ashx";
1226					$.ajax({
1227						type: "POST",
1228						url: PROXY_PATH,
1229						async: true,
1230						data: { "action": "getlayouts" },
1231						dataType: "xml",
1232						success: function (xml) {
1233							DATA_SETS = [];
1234							$(xml).find("dataset").each(function () {
1235								var dataset = $(this).attr('id');
1236								DATA_SETS.push(dataset);
1237							});
1238							$("[data-address-fieldtype='Country']").change(function () {
1239								if (typeof DATA_SETS !== 'undefined' && DATA_SETS !== null && DATA_SETS.length) {
1240									$("[data-address-fieldtype]").qtip('destroy');
1241									$("#QAS_BYPASS").val(!DATA_SETS.contains($("option:selected", $(this)).attr("data-isocode-threeletter")));
1242								}
1243							});
1244						}
1245					});
1246
1247					ADDRESS_FIELD_IDS[0] = [];
1248					COUNTRY_FIELD_IDS[0] = [];
1249					$.each(inputFields, function (index, inputField) {
1250						//Since we cannot determine ISO 3 Code for our selected Country until soCountryCascadingDropDown completes,
1251						//and since the QAS_LAYOUT has not been explicitly set by StudioOnline,
1252						//then only test if Street3 to short circuit.
1253						if (inputField.type === "Street3") {
1254							return;
1255						}
1256						if (inputField.autoCreate) {
1257							inputField.create();
1258						}
1259                        if (inputField.exists()) {
1260                            //Filter out input fields from the subscription widget
1261                            var $inputField = $(this.selector).not('[id*=WidgetSubscribe]');
1262							$inputField.data('inputField', inputField);
1263							if (inputField.required) {
1264								var fieldId = inputField.id();
1265								var fieldType = $('#' + fieldId).attr('data-address-fieldtype');
1266								var zipReq = $("[data-address-fieldtype='Country'] option:selected").attr("data-postalcode-required");
1267
1268								if (fieldType == 'City' || fieldType == 'State' || fieldType == 'Zip') {
1269									if (zipReq == 'true' || $('#' + fieldId).attr('data-required') == 'true') {
1270										$inputField.attr(
1271											{
1272												"sorequired": "sorequired",
1273												"sorequired-message": inputField.errorMessage
1274											});
1275									}
1276								}
1277								else {
1278									$inputField.attr(
1279										{
1280											"sorequired": "sorequired",
1281											"sorequired-message": inputField.errorMessage
1282										});
1283								}
1284							}
1285							if (inputField.qasRequired) {
1286								$inputField.attr("data-qas-required", "true");
1287							}
1288							if (inputField.type !== "Country") {
1289								ADDRESS_FIELD_IDS[0].push(inputField.id());
1290							}
1291							else {
1292								COUNTRY_FIELD_IDS[0].push(inputField.id());
1293							}
1294						}
1295					});
1296
1297				});
1298
1299				$(document).on('change', '[data-address-fieldtype]', function (e) {
1300					$("#QAS_VERIFIED").val($("#QAS_VERIFIED").attr("data-address-hash") == addressHash());
1301				});
1302
1303				if (settings.selectorSubmit !== null && settings.selectorSubmit.length) {
1304
1305					settings.selectorSubmit.each(function (index, element) {
1306						var $element = $(element);
1307						if ($element.is('a') && $element.attr('href') != null && $element.attr('href').indexOf("#") === -1) {
1308							$element.data('href', $element.attr('href'));
1309							$element.attr('href', '#');
1310							$element.data('qas-handler', function () {
1311								location.href = $(arguments[0]).data('href');
1312							});
1313						}
1314						else if ($element.attr('onclick') !== null) {
1315							$element.data('qas-handler', window[$element.attr('onclick').replace("(", "").replace(")", "")]);
1316							$element.removeAttr('onclick');
1317						}
1318						else {
1319							$element.data('qas-handler', function () {
1320								$element.trigger('click');
1321							});
1322						}
1323					});
1324
1325					settings.selectorSubmit.on('click', function (e) {
1326						$("[data-address-fieldtype]").qtip('destroy');
1327						var valid = true;
1328
1329						var $element = $(e.target);
1330						var onClick = eval($element.data('qasHandler'));
1331						if ($("#QAS_BYPASS").val() !== 'true' && $("#QAS_VERIFIED").val() !== 'true') {
1332							$("[data-address-fieldtype]:visible").each(function () {
1333								if (!$(this).isValid({ 'showErrors': true }) && ($(this).attr("data-qas-required") === 'true')) {
1334									valid = false;
1335								}
1336							});
1337							if (!valid) {
1338                            	if (onClick !== null)
1339                            	{
1340									onClick($element);
1341								}
1342								return;
1343							}
1344							$("[data-address-fieldtype]").qtip('destroy');
1345
1346							var $selectedCountry = $("option:selected", $("[data-address-fieldtype='Country']"));
1347							var countryIso3Code = $selectedCountry.attr("data-isocode-threeletter");
1348
1349							QAS_LAYOUT = $selectedCountry.attr("data-qas-layout");
1350							if (!QAS_LAYOUT || (countryIso3Code !== "USA" && countryIso3Code !== "CAN" && countryIso3Code !== "GBR")) {
1351								if (onClick !== null) {
1352									onClick($element);
1353								}
1354								return;
1355							}
1356
1357							if (countryIso3Code === "USA" && $("[data-address-fieldtype='Street3']").hasValue()) {
1358								var $line2 = $("[data-address-fieldtype='Street2']"),
1359									$line3 = $("[data-address-fieldtype='Street3']"),
1360									line2 = $line2.val().trim() || '',
1361									line3 = ' ' + $line3.val().trim();
1362
1363								line2 = (line2 + line3).trim();
1364								$line2.val(line2);
1365								$line3.val('');
1366							}
1367
1368							var m = new Main(function () {
1369								$("[data-address-fieldtype]:visible").each(function () {
1370									if (!$(this).isValid({ 'showErrors': true })) {
1371										valid = false;
1372									}
1373								});
1374								if (valid) {
1375									$("#QAS_VERIFIED").val(true).attr("data-address-hash", addressHash());
1376									if (onClick !== null) {
1377										onClick($element);
1378									}
1379									else {
1380										$('[id*=continueAction]').val("continue");
1381										$('form').submit();
1382									}
1383								}
1384								else
1385								{
1386									if (onClick !== null)
1387									{
1388										onClick($element);
1389									}
1390								}
1391							}, '');
1392							m.process();
1393							e.preventDefault();
1394						}
1395						else {
1396							if (onClick !== null) {
1397								onClick($element);
1398							}
1399						}
1400						if ($element.is('a')) {
1401							e.preventDefault();
1402						}
1403					});
1404				}
1405
1406				if (settings.selectorEnabled !== null && settings.selectorEnabled.length) {
1407					settings.selectorEnabled.on('change', function () {
1408						var $this = $(this);
1409						$("#QAS_BYPASS").val(!$this.isChecked());
1410						return true;
1411					});
1412					settings.selectorEnabled.trigger('change');
1413				}
1414			});
1415		},
1416		soWatermark: function (options) {
1417			return this.each(function (index, Element) {
1418				var $this = $(Element);
1419
1420				var settings = $.extend(
1421					{
1422						'text': ($this.attr('so-watermark-text') !== undefined ? $this.attr('so-watermark-text') : null),
1423						'className': ($this.attr('so-watermark-class-name') !== undefined ? $this.attr('so-watermark-class-name') : null),
1424						'useNative': ($this.attr('so-watermark-use-native') !== undefined ? $this.attr('so-watermark-use-native').toBoolean() : false),
1425						'hideBeforeUnload': ($this.attr('so-watermark-hide-before-unload') !== undefined ? $this.attr('so-watermark-hide-before-unload').toBoolean() : false)
1426					}, options);
1427
1428				if (settings.text.length) {
1429					var watermarkOptions = null;
1430
1431					if (settings.className && settings.className.length) {
1432						watermarkOptions = {
1433							className: settings.className,
1434							useNative: settings.useNative,
1435							hideBeforeUnload: settings.hideBeforeUnload
1436						};
1437					}
1438					else {
1439						watermarkOptions = {
1440							useNative: settings.useNative,
1441							hideBeforeUnload: settings.hideBeforeUnload
1442						};
1443					}
1444					$this.watermark(settings.text, watermarkOptions);
1445				}
1446			});
1447		},
1448		shoppingCart: function (method) {
1449			var isAjaxAddToCartGiftCatalogEnabled = window.location.pathname.toLowerCase() === '/catalog.aspx' && $('[id$="hdnAjaxAddToCartGiftCatalogEnabled"]').val() === 'true';
1450
1451			if ($("#AjaxAddToCartEnabled").val() !== 'true' && $(this).attr('data-search-page') !== 'true' && !isAjaxAddToCartGiftCatalogEnabled) {
1452				return;
1453			}
1454			var methods = {
1455				create: function (options) {
1456					return this.each(function () {
1457						var $this = $(this),
1458							data = $this.data('shoppingcart');
1459						if (!data) {
1460							$this.data('shoppingcart',
1461								{
1462									'target': $this,
1463									'settings': $.extend(
1464										{
1465											'action': $this.attr('data-role') || "addtocart",
1466											'productType': $this.attr('data-product-type') || "Product",
1467											'productID': $this.attr('data-product-id') || 0,
1468											'variantID': $this.attr('data-variant-id') || 0,
1469											'doCallback': $this.attr('data-do-callback') || false
1470										}, options),
1471									'quantitySelector': String.format('[data-role="quantity"][data-product-id="{0}"][data-variant-id="{1}"]', $this.attr('data-product-id') || 0, $this.attr('data-variant-id') || 0),
1472									'customerEnteredPriceSelector': String.format('[data-role="price"][data-product-id="{0}"][data-variant-id="{1}"]', $this.attr('data-product-id') || 0, $this.attr('data-variant-id') || 0)
1473								});
1474							data = $this.data('shoppingcart');
1475							$this.on('click.shoppingcart', methods.click);
1476						}
1477					});
1478				},
1479				destroy: function () {
1480					return this.each(function () {
1481						var $this = $(this),
1482							data = $this.data('shoppingcart');
1483						$this.off('.shoppingcart');
1484						$this.removeData('shoppingcart');
1485					});
1486				},
1487				click: function (e) {
1488					var $this = $(this),
1489						settings = $this.data('shoppingcart').settings,
1490						quantitySelector = $this.data('shoppingcart').quantitySelector,
1491						customerEnteredPriceSelector = $this.data('shoppingcart').customerEnteredPriceSelector;
1492					e.preventDefault();
1493					e.stopPropagation();
1494
1495					var productTerms = $this.parent().find('[data-product-terms="message"]').val();
1496					var acceptTerms = productTermsAgreement(productTerms);
1497					if (!acceptTerms) {
1498						return false;
1499					}
1500
1501					$.ajax({
1502						type: "POST",
1503						url: "ClientScriptHelper.asmx/AddProductToShoppingCart",
1504						contentType: "application/json; charset=utf-8",
1505						dataType: "json",
1506						data: "{'variantID':'" + (settings.variantID || 0).toString() + "','quantity':'" + ($(quantitySelector).val() || 1) + "','price':'" + ($(customerEnteredPriceSelector).val() || -1) + "'}",
1507						success: function (data) {
1508							$("#soMiniCart").load("ExecXMLPackage.ashx?xmlpackage=Widgets/MiniCart.xml.config", function () {
1509								$("[data-id='ItemAddedDialog']").remove();
1510								var $dialog = $("<div data-id='ItemAddedDialog'></div>");
1511								if (data && data.d)
1512									$dialog.html(data.d);
1513								$dialog.appendTo($("body"));
1514								$("[data-role='addtocart']").shoppingCart('destroy');
1515								$("[data-role='addtocart']").shoppingCart();
1516
1517								var width = 650;
1518								if ($(window).width() * .9 < width) {
1519									width = $(window).width() * .9;
1520								}
1521
1522								$dialog.dialog(
1523									{
1524										modal: true,
1525										title: "Item added to cart",
1526										autoOpen: true,
1527										position: {
1528											my: "center",
1529											at: "center",
1530											of: window,
1531											collision: "fit",
1532											using: function (pos) {
1533												var topOffset = $(this).css(pos).offset().top;
1534												if (topOffset < 0) {
1535													$(this).css("top", pos.top - topOffset);
1536												}
1537											}
1538										},
1539										height: 'auto',
1540										width: width,
1541										minHeight: 300,
1542										minWidth: 200,
1543										open: function () {
1544										if (settings.doCallback)
1545										{
1546												AddToCartActionCallback($this.data('shoppingcart'));
1547											}
1548										},
1549										close: function () {
1550											//$dialog.dialog('destory');
1551										},
1552										buttons: {
1553											'Continue Shopping': function (event, ui) {
1554												$dialog.dialog('close');
1555											},
1556											'Checkout Now': function (event, ui) {
1557												if (isAjaxAddToCartGiftCatalogEnabled && $('[id$="hdnAjaxAddToCartGiftCatalogGoToPaymentEnabled"]').val() === 'true') {
1558													document.location.href = 'CheckoutPayment.aspx';
1559												}
1560												else {
1561													document.location.href = 'ShoppingCart.aspx';
1562												}
1563											}
1564										}
1565									});
1566							});
1567						}
1568					});
1569					return false;
1570				}
1571			};
1572
1573			if (methods[method]) {
1574				return methods[method].apply(this, Array.prototype.slice.call(arguments, 1));
1575			} else if (typeof method === 'object' || !method) {
1576				return methods.create.apply(this, arguments);
1577			} else {
1578				$.error('Method ' + method + ' does not exist on jQuery.shoppingCart');
1579			}
1580		},
1581		imageGallery: function (options) {
1582			imageGallery = {
1583				//pDem parent deminsions
1584				//iDem img deminsions
1585				resize: function (pDem, iDem) {
1586					if (iDem.w > pDem.w) {
1587						iDem.h = iDem.h * (pDem.w / iDem.w);
1588						iDem.w = pDem.w;
1589						if (iDem.h > pDem.w) {
1590							iDem.w = iDem.w * (pDem.h / iDem.h);
1591							iDem.h = pDem.h;
1592						}
1593					} else if (iDem.h > pDem.h) {
1594						iDem.w = iDem.w * (pDem.h / iDem.h);
1595						iDem.h = pDem.h;
1596						if (iDem.w > pDem.w) {
1597							iDem.h = iDem.h * (pDem.w / iDem.w);
1598							iDem.w = pDem.w;
1599						}
1600					}
1601
1602					return iDem;
1603				},
1604				center: function (pDem, iDem) {
1605					return { "l": (pDem.w - iDem.w) * 0.5, "t": (pDem.h - iDem.h) * 0.5 };
1606				},
1607				swapOut: function (el) {
1608					return $('<div id="jqGallery' + el.index + '">');
1609				},
1610				view: function (img, el) {
1611					if (typeof img.altImg === 'undefined') return false;
1612					var url = img.altImg;
1613					if (/picasa/.test(url)) {
1614						url = /\?/.test(img.altImg) ? '&imgmax=800' : '?imgmax=800';
1615					}
1616
1617					el.loader.show();
1618
1619					image = new Image();
1620					image.onload = function () {
1621						image.onload = null;
1622						el.loader.fadeOut('fast');
1623						el.altTextBox.fadeTo('fast', 0.1);
1624						el.image.fadeOut('fast', function () {
1625							el.image.attr('src', url).fadeIn();
1626							if (typeof img.altTxt !== 'undefined') {
1627								el.altTextBox.fadeTo("fast", el.opts.titleOpacity).text(img.altTxt);
1628							}
1629						});
1630					};
1631					image.src = url;
1632
1633					// Scroll the selected image to the center
1634					var galleryItem = $(img).parent();
1635					var galleryHolder = $(img).parent().parent();
1636					var scrollAmount = galleryItem.width() - galleryHolder.parent().width();
1637					var currentPos = Math.abs(parseInt(galleryHolder.css('left')));
1638					var remainingScroll = scrollAmount - currentPos;
1639
1640					var desiredPosition = (galleryHolder.width() / 2) - $(img).position().left - ($(img).width() / 2);
1641					var position = Math.min(0, desiredPosition);
1642					galleryHolder.animate({ 'left': position }, /* duration: */ 400);
1643
1644					galleryHolder.children('.GalleryItem').removeClass('selected');
1645					galleryItem.addClass('selected');
1646				},
1647				defaults: {
1648					getUrlBy: 2, // 0 == from parent A tag | 1 == the full size resides in another folder
1649					fullSizePath: null,
1650					prefix: null,
1651					titleOpacity: 0.60
1652				}
1653			};
1654			return this.each(function (i) {
1655				var el = this;
1656				el.jqthis = $(this);
1657				el.jqchildren = el.jqthis.find('img');
1658				el.opts = $.extend({}, imageGallery.defaults, options);
1659				el.index = i;
1660				el.totalChildren = el.jqchildren.size();
1661				el.jqImageGallery = imageGallery.swapOut(el);
1662
1663				var length = el.jqchildren.length;
1664
1665				el.container = $('<div class="GalleryContainer">').appendTo(el.jqImageGallery);
1666
1667				el.mainImgContainer = $('<div class="GalleryImgContainer">').appendTo(el.container);
1668				el.image = $('<img style="display:none;"/>').appendTo(el.mainImgContainer);
1669				el.loader = $('<div class="GalleryLoader"/>').appendTo(el.mainImgContainer);
1670				el.altTextBox = $('<div class="GalleryAltText"/>').appendTo(el.mainImgContainer);
1671				el.holder = $('<div class="GalleryHolder"/>').appendTo(el.container);
1672				el.arrowContainer = $('<div class="galleryNavigation">').appendTo(el.mainImgContainer);
1673				el.leftArrowContainer = $('<div class="leftArrow">').appendTo(el.arrowContainer);
1674				el.leftArrow = $('<a class="leftArrowLink">').appendTo(el.leftArrowContainer).click(function () {
1675					var selectedItem = $('.GalleryItem.selected')[0];
1676					var id = selectedItem.id.replace('GalleryID', '');
1677					// JS modulo doesn't handle negative well, so instead of id-1, we add (length-1)
1678					// (length-1) % length will result in a decrement of 1
1679					var nextId = (id.toInt() + (length - 1)) % length;
1680					var nextSelectedItem = $('#GalleryID' + nextId + ' img')[0];
1681					imageGallery.view(nextSelectedItem, el);
1682				});
1683				el.rightArrowContainer = $('<div class="rightArrow">').appendTo(el.arrowContainer);
1684				el.rightArrow = $('<a class="rightArrowLink">').appendTo(el.rightArrowContainer).click(function () {
1685					var selectedItem = $('.GalleryItem.selected')[0];
1686					var id = selectedItem.id.replace('GalleryID', '');
1687					var nextId = (id.toInt() + 1) % length;
1688					var nextSelectedItem = $('#GalleryID' + nextId + ' img')[0];
1689					imageGallery.view(nextSelectedItem, el);
1690				});
1691
1692				if (length < 2) {
1693					el.holder.hide();
1694					el.arrowContainer.hide();
1695					el.container.addClass("GallerySingleImage");
1696				} else {
1697					el.container.addClass("GalleryMultiImage");
1698				}
1699
1700				if (length == 0) {
1701					el.jqthis.parent().addClass("GalleryNoImage");
1702				}
1703
1704				el.jqthis.after(el.jqImageGallery).remove();
1705
1706				el.imgCw = el.mainImgContainer.width();
1707				el.imgCh = el.mainImgContainer.height();
1708
1709				el.jqchildren.each(function (j) {
1710					var jqimage = $(this);
1711					var tmpimage = this;
1712
1713					tmpimage.index = j;
1714
1715					var jqdiv = $('<div id="GalleryID' + j + '" class="GalleryItem">')
1716						.appendTo(el.holder)
1717						.append('<div class="GalleryLoaderMini">');// end : $div
1718
1719					if (el.opts.getUrlBy === 0) {
1720						tmpimage.altImg = jqimage.parent().attr('href');
1721					}
1722					else if (el.opts.getUrlBy === 1) {
1723						tmpimage.altImg = el.opts.fullSizePath + tmpimage.src.split('/').pop();
1724					}
1725					else if (el.opts.getUrlBy === 2) {
1726						tmpimage.altImg = tmpimage.src.replace(el.opts.prefix, '');
1727					}
1728
1729					this.altTxt = jqimage.attr('alt');
1730
1731					var image = new Image();
1732					image.onload = function () {
1733						image.onload = null;
1734						jqdiv.empty().append(jqimage);
1735						var largeImage = new Image();
1736						largeImage.onload = function () {
1737							largeImage.onload = null;
1738
1739							$('<div class="GalleryFlash">').appendTo(jqdiv).css({ opacity: ".01" })
1740								.mouseover(
1741								function () {
1742									var $f = $(this);
1743									$f.css({ opacity: ".75" }).stop().animate({ opacity: ".01" }, 500);
1744								}
1745								)
1746								.click(function () {
1747									jqimage.trigger('click');
1748								}).trigger('mouseover');
1749
1750							jqimage.click(function () {
1751								imageGallery.view(this, el);
1752							});
1753
1754							if (tmpimage.index === 0) {
1755								jqimage.trigger('click');
1756								jqimage.siblings().trigger('mouseover');
1757							}
1758						};  // end : largeImage.onload 
1759						largeImage.src = tmpimage.altImg;
1760					};// end : image.onload 
1761					image.src = tmpimage.src;
1762				});
1763			});
1764		},
1765		placeHolder: function (options) {
1766			return this.each(function (index, Element) {
1767				var $this = $(Element);
1768				var settings = $.extend(
1769					{
1770						'childselector': ($this.attr('data-placeholder-for') !== undefined ? $this.attr('data-placeholder-for') : null)
1771					}, options);
1772
1773				settings.childselector = $(settings.childselector);
1774				if (settings.childselector.length) {
1775					settings.childselector.moveTo($this);
1776				}
1777			});
1778		},
1779		parseQueryString: function () {
1780			var nvpair = {};
1781			var qs = window.location.search.replace('?', '');
1782			var pairs = qs.split('&');
1783			$.each(pairs, function (i, v) {
1784				var pair = v.split('=');
1785				nvpair[pair[0]] = pair[1];
1786			});
1787			return nvpair;
1788		},
1789		parseQuery: function (query) {
1790			var nvpair = {};
1791			var qs = query.search.replace('?', '');
1792			var pairs = qs.split('&');
1793			$.each(pairs, function (i, v) {
1794				var pair = v.split('=');
1795				nvpair[pair[0]] = pair[1];
1796			});
1797			return nvpair;
1798		},
1799		viewMode: function (options) {
1800			return this.each(function (index, Element) {
1801				var $this = $(this);
1802				var settings = $.extend({
1803					'changeto': $this.attr('data-viewmode-changeto') || '',
1804					'_default': $this.attr('data-viewmode-default') || '',
1805					'group': $this.attr('data-viewmode-group') || 'all',
1806					'preventDefault': ($this.attr('data-viewmode-preventdefault') || 'true').toBoolean()
1807				}, options);
1808				settings.group = settings.group === "all" ? "" : "[data-viewmode-group='" + settings.group + "']";
1809				if (settings.changeto) {
1810					$("[data-viewmode]" + settings.group).hide();
1811					if (settings._default) {
1812						$("[data-viewmode='" + settings._default + "']" + settings.group).show();
1813					}
1814					$this.click(function (e) {
1815						$("[data-viewmode]" + settings.group).hide();
1816						$("[data-viewmode='" + settings.changeto + "']" + settings.group).show();
1817						if (settings.preventDefault) {
1818							e.preventDefault();
1819						}
1820					});
1821				}
1822			});
1823		},
1824		soDatePicker: function (options) {
1825			return this.each(function (index, Element) {
1826				var $this = $(this);
1827				var settings = $.extend({
1828					'yearRange': $this.attr('data-datepicker-year-range') || '-20:+20',
1829					'changeYear': ($this.attr('data-datepicker-change-year') || 'true').toBoolean(),
1830					'changeMonth': ($this.attr('data-datepicker-change-month') || 'true').toBoolean(),
1831					'showOn': $this.attr('data-datepicker-show-on') || 'focus',
1832					'minDate': $this.attr('data-datepicker-min-date') || '',
1833					'maxDate': $this.attr('data-datepicker-max-date') || ''
1834				}, options);
1835				$this.datepicker(settings);
1836			});
1837		},
1838		googlePlacesAutocomplete: function (options) {
1839			if ($("#GooglePlacesAutocomplete").val() !== 'true') {
1840				return;
1841			}
1842			return this.each(function (index, Element) {
1843				var $this = $(this), data = $this.data('googlePlacesAutocomplete');
1844				if (!data) {
1845					var placeSearch, autocomplete;
1846					var componentForm = {
1847						street_number: 'long_name',
1848						route: 'long_name',
1849						locality: 'long_name',
1850						administrative_area_level_1: 'short_name',
1851						country: 'long_name',
1852						postal_code: 'short_name'
1853					};
1854					$this.attr("placeholder", "")
1855						.attr("autocomplete", "off")
1856						.focus(function () {
1857							geolocate()
1858						});
1859					autocomplete = new google.maps.places.Autocomplete($this[0], { types: ['geocode'] });
1860					google.maps.event.addListener(autocomplete, 'place_changed', function () {
1861						fillInAddress();
1862					});
1863					function fillInAddress() {
1864						var place = autocomplete.getPlace();
1865						$("[data-address-fieldtype]").val("").prop('disabled', false);
1866						for (var i = 0; i < place.address_components.length; i++) {
1867							var addressType = place.address_components[i].types[0];
1868							if (componentForm[addressType]) {
1869								var val = place.address_components[i][componentForm[addressType]];
1870								switch (addressType) {
1871									case "street_number":
1872										$("[data-address-fieldtype='Street1']").val(val);
1873										break;
1874									case "route":
1875										$("[data-address-fieldtype='Street1']").val(String.format("{0} {1}", $("[data-address-fieldtype='Street1']").val(), val));
1876										break;
1877									case "locality":
1878										$("[data-address-fieldtype='City']").val(val);
1879										break;
1880									case "administrative_area_level_1":
1881										$("[data-address-fieldtype='State']").val(val);
1882										break;
1883									case "country":
1884										$("[data-address-fieldtype='Country']").val(val);
1885										break;
1886									case "postal_code":
1887										$("[data-address-fieldtype='Zip']").val(val);
1888										break;
1889								}
1890							}
1891						}
1892					}
1893					function geolocate() {
1894						if (navigator.geolocation) {
1895							navigator.geolocation.getCurrentPosition(function (position) {
1896								var geolocation = new google.maps.LatLng(position.coords.latitude, position.coords.longitude);
1897								autocomplete.setBounds(new google.maps.LatLngBounds(geolocation, geolocation));
1898							});
1899						}
1900					}
1901				}
1902			}
1903			);
1904		},
1905		roleSecurity: function (method) {
1906			roles = roles || [];
1907			if ($("#RolesKey").val() !== md5((roles || []).join(","))) {
1908				$("[data-required-role]").hide();
1909				return;
1910			}
1911			var methods = {
1912				create: function (options) {
1913					return this.each(function () {
1914						var $this = $(this),
1915							data = $this.data('roleSecurity');
1916						if (!$this.attr('data-required-role'))
1917							return;
1918						if (!data) {
1919							var visible = false;
1920							var requiredRoles = ($this.attr('data-required-role') || "").replace(" ", "").split(",");
1921							requiredRoles.forEach(function (item) {
1922								if (roles.contains(btoa(item))) {
1923									visible = true;
1924								}
1925							});
1926							$this.data('roleSecurity',
1927								{
1928									'target': $this,
1929									'settings': $.extend(
1930										{
1931											'roles': requiredRoles,
1932											'visible': $this.isVisible()
1933										}, options),
1934									'visible': visible,
1935								});
1936							data = $this.data('roleSecurity');
1937						}
1938						if (data.visible) {
1939							$this.show();
1940						}
1941						else {
1942							$this.hide();
1943						}
1944					});
1945				},
1946				destroy: function () {
1947					return this.each(function () {
1948						var $this = $(this),
1949							settings = ($this.data('roleSecurity') || {
1950								settings:
1951								{ "visible": true }
1952							}).settings || { "visible": true };
1953						$this.off('.roleSecurity');
1954						$this.removeData('roleSecurity');
1955						if (settings.visible) {
1956							$this.show();
1957						}
1958						else {
1959							$this.hide();
1960						}
1961					});
1962				},
1963				update: function () {
1964					var $this = $(this),
1965						data = ($this.data('roleSecurity') || { "visible": true });
1966					if (data.visible) {
1967						$this.show();
1968					}
1969					else {
1970						$this.hide();
1971					}
1972				}
1973			};
1974			if (methods[method]) {
1975				return methods[method].apply(this, Array.prototype.slice.call(arguments, 1));
1976			} else if (typeof method === 'object' || !method) {
1977				return methods.create.apply(this, arguments);
1978			} else {
1979				$.error('Method ' + method + ' does not exist on jQuery.roleSecurity');
1980			}
1981		},
1982		infiniteScroll: function (options) {
1983			return this.each(function (index, Element) {
1984				var pagesize = 5;
1985				var pgindex, reset;
1986				var $sliders = $(this).hasClass('.sliderContainer') ? $(this) : $(this).find('.sliderContainer');
1987				var $slider, $sliderItems, $items, width, scroll, itemsize, empty = 0;
1988
1989				function setSliderVariables($container) {
1990					$slider = $container.find('.slider');
1991					$sliderItems = $slider.find('.sliderItems');
1992					$items = $sliderItems.find('.sliderItem');
1993					width = $sliderItems.width();
1994				}
1995				function deleteAttr(item) {
1996					var input = item.find("[data-role='quantity']");
1997					input.removeAttr('name');
1998					input.removeAttr('data-role');
1999					input.addClass('quantityRemoved');
2000				}
2001				function addAttr(item) {
2002					var input = item.find(".quantityRemoved");
2003					var id = input.attr('id');
2004					input.attr('name', id);
2005					input.attr('data-role', 'quantity');
2006					input.removeClass('quantityRemoved');
2007				}
2008
2009				function resetSlider($container, clonedItems) { //setup of initial pages
2010					setSliderVariables($container);
2011
2012					//workaround for odd spacing due to asp product items
2013					if (clonedItems.length) {
2014						$sliderItems.empty();
2015						$.each(clonedItems, function () {
2016							$sliderItems.append($(this));
2017						});
2018					}
2019					var $items = $sliderItems.find('.sliderItem');
2020
2021					//set itemsize
2022					$items = $sliderItems.find('.sliderItem');
2023					var margins = parseFloat($items.first().css('margin-left').replace('px', '')) + parseFloat($items.first().css('margin-right').replace('px', ''));
2024					itemsize = (width / pagesize) - (margins);
2025					$items.width(itemsize);
2026
2027					if ($items.length % pagesize > 0) { //items to append
2028						empty = pagesize - ($items.length % pagesize);
2029						for (var i = 0; i < empty; i++) {
2030							var $add = $sliderItems.find('*[original="' + i + '"]').clone();
2031							$add.removeAttr('original');
2032							$sliderItems.append($add);
2033						}
2034					}
2035
2036					var idx = $items.length - 1;
2037					for (var i = 0; i < pagesize; i++) { //items to prepend
2038						var $item = $sliderItems.find('*[original="' + idx + '"]').clone();
2039						$item.removeAttr('original');
2040						$sliderItems.prepend($item);
2041						$items = $sliderItems.find('.sliderItem');
2042						idx--;
2043					}
2044					$items = $sliderItems.find('.sliderItem');
2045					$sliderItems.css('left', -width);
2046
2047					//create infinite loop
2048					var origItems = $sliderItems.find('.sliderItem[original]').length;
2049					var addedItems = $items.length - origItems;
2050					if (addedItems % origItems != 0 || addedItems < origItems || addedItems < empty + pagesize) {
2051						//add missing items
2052						var indexStart = empty; //index to start on
2053						var indexEnd = origItems - pagesize - 1; //index to end on
2054						var itemsToAdd = 0;
2055
2056						if (indexEnd < indexStart) {
2057							itemsToAdd = (origItems - indexStart) + indexEnd;
2058						}
2059						else if (indexStart > indexEnd) {
2060							itemsToAdd = indexStart - indexEnd;
2061						}
2062
2063						if (itemsToAdd > 0) {
2064							for (var i = 0; i <= itemsToAdd; i++) {
2065								var $item = $sliderItems.find('*[original="' + indexStart + '"]').clone();
2066								$item.removeAttr('original');
2067								$sliderItems.append($item);
2068								$items = $sliderItems.find('.sliderItem');
2069
2070								indexStart++;
2071								if (indexStart >= origItems)
2072									indexStart = 0;
2073							}
2074						}
2075					}
2076
2077					//make only second page visible
2078					for (var i = 0; i < $items.length; i++) {
2079						if (i < pagesize || i >= pagesize * 2) {
2080							deleteAttr($($items[i]));
2081						}
2082					}
2083				}
2084
2085				function slide($container, direction) {
2086					pgindex = typeof pgindex == 'undefined' ? 1 : pgindex;
2087					setSliderVariables($container);
2088					var left, $item; //item to append
2089
2090					width = direction == 'right' ? width : -width;
2091					$sliderItems.filter(':not(:animated)').animate({ //animate
2092						left: '+=' + width
2093					}, 500, function () {
2094						left = parseInt($sliderItems.css('left').replace('px', ''))
2095
2096						for (var i = pagesize; i < pagesize * 2; i++) {
2097							deleteAttr($($items[i]));
2098						}
2099
2100						if (direction == 'left') {  //left
2101							for (var i = pagesize * 2; i < pagesize * 3; i++) {
2102								addAttr($($items[i]));
2103							}
2104
2105							pgindex = pagesize * (pgindex + 1) <= $items.length - pagesize ? pgindex + 1 : pgindex;
2106							if (pagesize * (pgindex + 1) > $items.length - pagesize) {
2107								for (var i = 0; i < pagesize; i++) {
2108									$item = $items.first();
2109									$sliderItems.append($item);
2110									$items = $sliderItems.find('.sliderItem');
2111								}
2112								$sliderItems.css('left', left - width);
2113							}
2114						}
2115						else {                      //right
2116							for (var i = 0; i < pagesize; i++) {
2117								addAttr($($items[i]));
2118							}
2119
2120							pgindex = pgindex > 1 ? pgindex - 1 : 1;
2121							if (pgindex <= 1) {
2122								for (var i = 0; i < pagesize; i++) {
2123									$item = $items.last();
2124									$sliderItems.prepend($item);
2125									$items = $sliderItems.find('.sliderItem');
2126								}
2127								$sliderItems.css('left', left - width);
2128							}
2129						}
2130					});
2131				}
2132
2133				$.each($sliders, function () {
2134					var $container = $(this);
2135					var clonedItems = new Array();
2136					var index = 0;
2137
2138					if ($container.find('.sliderItem').length > pagesize && $container.find('.left').length && $container.find('.right').length && $(window).width() > 900)
2139						$container.addClass('active');
2140					else //remove sliderItem class if there is no slider
2141						var remove = $container.find('.sliderItem').removeClass('sliderItem');
2142
2143					$container = $(this).closest('.sliderContainer.active');
2144
2145					if ($container.length) {
2146						$container.find('.left').addClass('sliderArrow');
2147						$container.find('.right').addClass('sliderArrow');
2148
2149						//workaround for odd spacing due to asp product items
2150						$.each($container.find('.sliderItem'), function () {
2151							var $clone = $(this).clone();
2152							$clone.attr('original', index);
2153							clonedItems.push($clone);
2154							index++;
2155						});
2156
2157						resetSlider($container, clonedItems);
2158					}
2159				});
2160
2161				$('.sliderArrow').click(function () {
2162					var $container = $(this).closest('.sliderContainer.active');
2163					var direction = $(this).hasClass('right') ? 'left' : 'right';
2164
2165					if ($container.length) {
2166						slide($container, direction);
2167					}
2168
2169				});
2170			});
2171		},
2172		loadExternalMarkup: function (options) {
2173			return this.each(function (index, Element) {
2174				var $this = $(Element);
2175				$this.hide();
2176				var settings = $.extend(
2177					{
2178						'src': $this.attr('data-src') || "",
2179						'xpath': $this.attr('data-xpath') || ""
2180					}, options);
2181
2182				if (settings.src.length && settings.xpath.length) {
2183					var html = GetStringResource("SO.OneNav.NavigationHTML");
2184					$this.html(html);
2185					$this.show();
2186				}
2187			});
2188		},
2189		maskField: function (options) {
2190			return this.each(function (index, Element) {
2191				var $this = $(Element);
2192
2193				$this.watermark('MM/DD/YYYY');
2194				$this.setMask('19/39/2999');
2195			});
2196		},
2197		switchVariant: function (options) {
2198			return this.each(function (index, Element) {
2199				var $this = $(Element);
2200
2201				function varswitch(e) {
2202					var variantid = $this.val() || $this.attr('variantid');
2203					if (!variantid.length)
2204						return
2205
2206					var $variantelements = $('[data-variant-role][variantid="' + variantid + '"]');
2207
2208					$.each($variantelements, function () {
2209						var role = $(this).attr('data-variant-role');
2210						var $productelement = $('[data-product-role="' + role + '"]');
2211
2212						if ($(this).attr('variant-role') == 'hide')
2213							$productelement.css('display', 'none'); //use the css display property instead of show() and hide()
2214						else if ($(this).attr('variant-role') == 'show')
2215							$productelement.css('display', 'block');
2216						else {
2217							var varianthtml = $(this).html();
2218							var producthtml = $productelement.html();
2219
2220							$productelement.html(varianthtml);
2221							$(this).html(producthtml);
2222							$(this).attr('variantid', currentProductId);
2223						}
2224					});
2225
2226					$('.variantpanel .selected').removeClass('selected'); //for skinning purposes
2227					$this.addClass('selected');
2228
2229					currentProductId = variantid;
2230					if ($this.attr('variantid'))
2231						$this.attr('variantid', currentProductId);
2232				}
2233
2234				if ($this.attr('data-variant-type') == 'select') {
2235					$this.change(varswitch);
2236				} else if ($this.attr('data-variant-type') == 'button') {
2237					$this.click(varswitch);
2238				}
2239			});
2240		}
2241	});
2242	$(document).ready(function () {
2243		$("[data-role='placeholder']").placeHolder();
2244		$("[data-role='imagegallery']").imageGallery();
2245		$('[sodisableonclick]').disableOnClick();
2246		$('[socascadingdropdown]').soCascadingDropDown();
2247		$('[solistpager]').listPager();
2248		// $('[sohtmlarea]').markItUp(mySettings);
2249		$('[soemaildialog]').emailDialog();
2250		$("[data-role='imagedialog']").imageDialog();
2251		$("div[data-role='qascontrol']").qasControl();
2252		$("[data-address-fieldtype='Country']").soCountryCascadingDropDown();
2253		// Hidden Container slide toggle - Used in TOC show/hide
2254		$('a.HiddenContainerLink').click(function () {
2255			$('a.HiddenContainerLink ~ div.HiddenContainer').slideToggle("normal");
2256		});
2257		$('a.HiddenContainerCloseLink').click(function () {
2258			$(this).parent('.HiddenContainer').slideToggle("normal");
2259		});
2260		loadWidgets();
2261		if (typeof Sys !== 'undefined' && Sys !== null && Sys.WebForms !== 'undefined' && Sys.WebForms !== null && Sys.WebForms.PageRequestManager !== 'undefined' && Sys.WebForms.PageRequestManager !== null) {
2262			pageRequestManager = Sys.WebForms.PageRequestManager.getInstance()
2263			if (typeof pageRequestManager !== 'undefined' && pageRequestManager !== null) {
2264				pageRequestManager.add_endRequest(loadWidgets);
2265			}
2266		}
2267	});
2268	function loadWidgets() {
2269		$("[somasktype]").maskField();
2270		$("[data-role='infiniteScroll']").infiniteScroll();
2271		$('[socheckedtoggle]').checkedToggle();
2272		$("[data-role='addtocart']").shoppingCart('destroy');
2273		$("[data-role='addtocart']").shoppingCart();
2274		$("[data-role='watermark']").soWatermark();
2275		$("[data-role='viewmode']").viewMode();
2276		$('[sotabs]').tabs();
2277		$("[data-role='accordion']").soAccordion();
2278		$('[soautocomplete]').soAutoComplete();
2279		$("[data-role='dialog'],[sodialog]").dialog({
2280			modal: true,
2281			autoOpen: false,
2282			open: function () {
2283				$(this).parent().appendTo("form:first");
2284			},
2285			minWidth: 250,
2286			width: 300
2287		});
2288		$('input[data-mask]').each(function () {
2289			var $this = $(this);
2290			$this.setMask($this.attr('data-mask'));
2291		});
2292		$('[sonodetoggle]').nodeToggle();
2293		$("[data-role='GooglePlacesAutocomplete']").googlePlacesAutocomplete();
2294		$("[data-required-role]").roleSecurity('destroy');
2295		$("[data-required-role]").roleSecurity();
2296		$("[sodecimal], [data-role='decimal']").decimal();
2297		$("[sodatepicker], [data-role='datepicker']").soDatePicker();
2298		$("[data-role='LoadExternalMarkup']").loadExternalMarkup();
2299		$("[data-role='productvariant']").switchVariant();
2300	}
2301})(jQuery);
2302
2303function isNumber(n) {
2304	return !isNaN(parseFloat(n)) && isFinite(n);
2305}
2306
2307String.prototype.repeat = function (num) {
2308	return new Array(num + 1).join(this);
2309};
2310
2311String.prototype.isNumber = function () {
2312	return isNumber(this);
2313};
2314
2315String.prototype.toInt = function (defaultValue) {
2316	if (this.isNumber()) {
2317		return parseInt(this, 10);
2318	}
2319	else {
2320		return defaultValue;
2321	}
2322};
2323
2324String.prototype.toInt = function () {
2325	if (this.isNumber()) {
2326		return parseInt(this, 10);
2327	}
2328	else {
2329		return 0;
2330	}
2331};
2332
2333String.prototype.toFloat = function (defaultValue) {
2334	if (this.isNumber()) {
2335		return parseFloat(this);
2336	}
2337	else {
2338		return defaultValue;
2339	}
2340};
2341
2342String.prototype.toFloat = function () {
2343	if (this.isNumber()) {
2344		return parseFloat(this);
2345	}
2346	else {
2347		return 0;
2348	}
2349};
2350
2351String.prototype.toBoolean = function () {
2352	return ["t", "y", "true", "yes", "1"].contains(this.toLowerCase().trim());
2353};
2354
2355String.prototype.trim = function () {
2356	return this.replace(/^\s+|\s+$/g, "");
2357};
2358
2359String.prototype.ltrim = function () {
2360	return this.replace(/^\s+/, "");
2361};
2362
2363String.prototype.rtrim = function () {
2364	return this.replace(/\s+$/, "");
2365};
2366
2367String.format = function () {
2368	// The string containing the format items (e.g. "{0}")
2369	// will and always has to be the first argument.
2370	var theString = arguments[0];
2371	// start with the second argument (i = 1)
2372	for (var i = 1; i < arguments.length; i++) {
2373		// "gm" = RegEx options for Global search (more than one instance)
2374		// and for Multiline search
2375		var regEx = new RegExp("\\{" + (i - 1) + "\\}", "gm");
2376		theString = theString.replace(regEx, arguments[i]);
2377	}
2378
2379	return theString;
2380};
2381
2382Array.prototype.max = function () {
2383	return Math.max.apply(null, this);
2384};
2385
2386Array.prototype.min = function () {
2387	return Math.min.apply(null, this);
2388};
2389
2390Array.prototype.take = function (count) {
2391	return this.slice(0, count);
2392};
2393
2394Array.prototype.remove = function (from, to) {
2395	var rest = this.slice((to || from) + 1 || this.length);
2396	this.length = from < 0 ? this.length + from : from;
2397	return this.push.apply(this, rest);
2398};
2399
2400Array.prototype.toEnumerable = function () {
2401	return Enumerable.From(this);
2402};
2403
2404Array.prototype.contains = function (obj) {
2405	var i = this.length;
2406	while (i--) {
2407		if (this[i] === obj) {
2408			return true;
2409		}
2410	}
2411	return false;
2412};
2413
2414window.CreateDelegate = function (object, method) {
2415	return function () {
2416		return method.apply(object, arguments);
2417	};
2418};
2419
2420var CHARS = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'.split('');
2421
2422/*jslint bitwise: true*/
2423
2424Math.uuid = function (len, radix) {
2425	var chars = CHARS, uuid = [], i;
2426	radix = radix || chars.length;
2427
2428	if (len) {
2429		// Compact form
2430		for (i = 0; i < len; i++) uuid[i] = chars[0 | Math.random() * radix];
2431	} else {
2432		var r;
2433
2434		uuid[8] = uuid[13] = uuid[18] = uuid[23] = '-';
2435		uuid[14] = '4';
2436
2437		for (i = 0; i < 36; i++) {
2438			if (!uuid[i]) {
2439				r = 0 | Math.random() * 16;
2440				uuid[i] = chars[(i === 19) ? (r & 0x3) | 0x8 : r];
2441			}
2442		}
2443	}
2444
2445	return uuid.join('');
2446};
2447
2448Math.uuidFast = function () {
2449	var chars = CHARS, uuid = new Array(36), rnd = 0, r;
2450	for (var i = 0; i < 36; i++) {
2451		if (i === 8 || i === 13 || i === 18 || i === 23) {
2452			uuid[i] = '-';
2453		} else if (i === 14) {
2454			uuid[i] = '4';
2455		} else {
2456			if (rnd <= 0x02) rnd = 0x2000000 + (Math.random() * 0x1000000) | 0;
2457			r = rnd & 0xf;
2458			rnd = rnd >> 4;
2459			uuid[i] = chars[(i === 19) ? (r & 0x3) | 0x8 : r];
2460		}
2461	}
2462	return uuid.join('');
2463};
2464
2465Math.uuidCompact = function () {
2466	return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
2467		var r = Math.random() * 16 | 0, v = c === 'x' ? r : (r & 0x3 | 0x8);
2468		return v.toString(16);
2469	});
2470};
2471
2472/*jslint bitwise: false*/
2473
2474window.RegisterAsyncPostBackTrigger = function () {
2475	var $this = Sys.WebForms.PageRequestManager.getInstance();
2476	if (typeof $this !== 'undefined' && $this !== null) {
2477		for (var i = 0; i < arguments.length; i++) {
2478			var eventName = arguments[i];
2479			if (typeof $this._asyncPostBackControlIDs === 'undefined' || $this._asyncPostBackControlIDs === null) {
2480				$this._asyncPostBackControlIDs = [];
2481			}
2482			if (typeof $this._asyncPostBackControlClientIDs === 'undefined' || $this._asyncPostBackControlClientIDs === null) {
2483				$this._asyncPostBackControlClientIDs = [];
2484			}
2485
2486			if (!Array.contains($this._asyncPostBackControlIDs, eventName)) {
2487				$this._asyncPostBackControlIDs.push(eventName);
2488			}
2489			if (!Array.contains($this._asyncPostBackControlClientIDs, eventName)) {
2490				$this._asyncPostBackControlClientIDs.push(eventName);
2491			}
2492		}
2493	}
2494};
2495
2496window.RegisterAsyncPostBackControl = function (controlId, controlName) {
2497	var $this = Sys.WebForms.PageRequestManager.getInstance();
2498	if (typeof $this !== 'undefined' && $this !== null) {
2499		if (typeof $this._asyncPostBackControlIDs === 'undefined' || $this._asyncPostBackControlIDs === null) {
2500			$this._asyncPostBackControlIDs = [];
2501		}
2502		if (typeof $this._asyncPostBackControlClientIDs === 'undefined' || $this._asyncPostBackControlClientIDs === null) {
2503			$this._asyncPostBackControlClientIDs = [];
2504		}
2505		if (controlName && !Array.contains($this._asyncPostBackControlIDs, controlName)) {
2506			$this._asyncPostBackControlIDs.push(controlName);
2507		}
2508		if (controlId && !Array.contains($this._asyncPostBackControlClientIDs, controlId)) {
2509			$this._asyncPostBackControlClientIDs.push(controlId);
2510		}
2511	}
2512};
2513
2514window.PageScroll = function () {
2515	var xScroll, yScroll;
2516	if (self.pageYOffset) {
2517		yScroll = self.pageYOffset;
2518		xScroll = self.pageXOffset;
2519	} else if (document.documentElement && document.documentElement.scrollTop) {
2520		yScroll = document.documentElement.scrollTop;
2521		xScroll = document.documentElement.scrollLeft;
2522	} else if (document.body) {// all other Explorers
2523		yScroll = document.body.scrollTop;
2524		xScroll = document.body.scrollLeft;
2525	}
2526	return { 'x': xScroll, 'y': yScroll };
2527};
2528
2529window.PageHeight = function () {
2530	var windowHeight
2531	if (self.innerHeight) { // all except Explorer
2532		windowHeight = self.innerHeight;
2533	} else if (document.documentElement && document.documentElement.clientHeight) {
2534		windowHeight = document.documentElement.clientHeight;
2535	} else if (document.body) { // other Explorers
2536		windowHeight = document.body.clientHeight;
2537	}
2538	return windowHeight;
2539};
2540
2541var md5 = function (string) {
2542
2543	function RotateLeft(lValue, iShiftBits) {
2544		return (lValue << iShiftBits) | (lValue >>> (32 - iShiftBits));
2545	}
2546
2547	function AddUnsigned(lX, lY) {
2548		var lX4, lY4, lX8, lY8, lResult;
2549		lX8 = (lX & 0x80000000);
2550		lY8 = (lY & 0x80000000);
2551		lX4 = (lX & 0x40000000);
2552		lY4 = (lY & 0x40000000);
2553		lResult = (lX & 0x3FFFFFFF) + (lY & 0x3FFFFFFF);
2554		if (lX4 & lY4) {
2555			return (lResult ^ 0x80000000 ^ lX8 ^ lY8);
2556		}
2557		if (lX4 | lY4) {
2558			if (lResult & 0x40000000) {
2559				return (lResult ^ 0xC0000000 ^ lX8 ^ lY8);
2560			} else {
2561				return (lResult ^ 0x40000000 ^ lX8 ^ lY8);
2562			}
2563		} else {
2564			return (lResult ^ lX8 ^ lY8);
2565		}
2566	}
2567
2568	function F(x, y, z) { return (x & y) | ((~x) & z); }
2569	function G(x, y, z) { return (x & z) | (y & (~z)); }
2570	function H(x, y, z) { return (x ^ y ^ z); }
2571	function I(x, y, z) { return (y ^ (x | (~z))); }
2572
2573	function FF(a, b, c, d, x, s, ac) {
2574		a = AddUnsigned(a, AddUnsigned(AddUnsigned(F(b, c, d), x), ac));
2575		return AddUnsigned(RotateLeft(a, s), b);
2576	};
2577
2578	function GG(a, b, c, d, x, s, ac) {
2579		a = AddUnsigned(a, AddUnsigned(AddUnsigned(G(b, c, d), x), ac));
2580		return AddUnsigned(RotateLeft(a, s), b);
2581	};
2582
2583	function HH(a, b, c, d, x, s, ac) {
2584		a = AddUnsigned(a, AddUnsigned(AddUnsigned(H(b, c, d), x), ac));
2585		return AddUnsigned(RotateLeft(a, s), b);
2586	};
2587
2588	function II(a, b, c, d, x, s, ac) {
2589		a = AddUnsigned(a, AddUnsigned(AddUnsigned(I(b, c, d), x), ac));
2590		return AddUnsigned(RotateLeft(a, s), b);
2591	};
2592
2593	function ConvertToWordArray(string) {
2594		var lWordCount;
2595		var lMessageLength = string.length;
2596		var lNumberOfWords_temp1 = lMessageLength + 8;
2597		var lNumberOfWords_temp2 = (lNumberOfWords_temp1 - (lNumberOfWords_temp1 % 64)) / 64;
2598		var lNumberOfWords = (lNumberOfWords_temp2 + 1) * 16;
2599		var lWordArray = Array(lNumberOfWords - 1);
2600		var lBytePosition = 0;
2601		var lByteCount = 0;
2602		while (lByteCount < lMessageLength) {
2603			lWordCount = (lByteCount - (lByteCount % 4)) / 4;
2604			lBytePosition = (lByteCount % 4) * 8;
2605			lWordArray[lWordCount] = (lWordArray[lWordCount] | (string.charCodeAt(lByteCount) << lBytePosition));
2606			lByteCount++;
2607		}
2608		lWordCount = (lByteCount - (lByteCount % 4)) / 4;
2609		lBytePosition = (lByteCount % 4) * 8;
2610		lWordArray[lWordCount] = lWordArray[lWordCount] | (0x80 << lBytePosition);
2611		lWordArray[lNumberOfWords - 2] = lMessageLength << 3;
2612		lWordArray[lNumberOfWords - 1] = lMessageLength >>> 29;
2613		return lWordArray;
2614	};
2615
2616	function WordToHex(lValue) {
2617		var WordToHexValue = "", WordToHexValue_temp = "", lByte, lCount;
2618		for (lCount = 0; lCount <= 3; lCount++) {
2619			lByte = (lValue >>> (lCount * 8)) & 255;
2620			WordToHexValue_temp = "0" + lByte.toString(16);
2621			WordToHexValue = WordToHexValue + WordToHexValue_temp.substr(WordToHexValue_temp.length - 2, 2);
2622		}
2623		return WordToHexValue;
2624	};
2625
2626	function Utf8Encode(string) {
2627		string = string.replace(/\r\n/g, "\n");
2628		var utftext = "";
2629
2630		for (var n = 0; n < string.length; n++) {
2631
2632			var c = string.charCodeAt(n);
2633
2634			if (c < 128) {
2635				utftext += String.fromCharCode(c);
2636			}
2637			else if ((c > 127) && (c < 2048)) {
2638				utftext += String.fromCharCode((c >> 6) | 192);
2639				utftext += String.fromCharCode((c & 63) | 128);
2640			}
2641			else {
2642				utftext += String.fromCharCode((c >> 12) | 224);
2643				utftext += String.fromCharCode(((c >> 6) & 63) | 128);
2644				utftext += String.fromCharCode((c & 63) | 128);
2645			}
2646
2647		}
2648
2649		return utftext;
2650	};
2651
2652	var x = Array();
2653	var k, AA, BB, CC, DD, a, b, c, d;
2654	var S11 = 7, S12 = 12, S13 = 17, S14 = 22;
2655	var S21 = 5, S22 = 9, S23 = 14, S24 = 20;
2656	var S31 = 4, S32 = 11, S33 = 16, S34 = 23;
2657	var S41 = 6, S42 = 10, S43 = 15, S44 = 21;
2658
2659	string = Utf8Encode(string);
2660
2661	x = ConvertToWordArray(string);
2662
2663	a = 0x67452301; b = 0xEFCDAB89; c = 0x98BADCFE; d = 0x10325476;
2664
2665	for (k = 0; k < x.length; k += 16) {
2666		AA = a; BB = b; CC = c; DD = d;
2667		a = FF(a, b, c, d, x[k + 0], S11, 0xD76AA478);
2668		d = FF(d, a, b, c, x[k + 1], S12, 0xE8C7B756);
2669		c = FF(c, d, a, b, x[k + 2], S13, 0x242070DB);
2670		b = FF(b, c, d, a, x[k + 3], S14, 0xC1BDCEEE);
2671		a = FF(a, b, c, d, x[k + 4], S11, 0xF57C0FAF);
2672		d = FF(d, a, b, c, x[k + 5], S12, 0x4787C62A);
2673		c = FF(c, d, a, b, x[k + 6], S13, 0xA8304613);
2674		b = FF(b, c, d, a, x[k + 7], S14, 0xFD469501);
2675		a = FF(a, b, c, d, x[k + 8], S11, 0x698098D8);
2676		d = FF(d, a, b, c, x[k + 9], S12, 0x8B44F7AF);
2677		c = FF(c, d, a, b, x[k + 10], S13, 0xFFFF5BB1);
2678		b = FF(b, c, d, a, x[k + 11], S14, 0x895CD7BE);
2679		a = FF(a, b, c, d, x[k + 12], S11, 0x6B901122);
2680		d = FF(d, a, b, c, x[k + 13], S12, 0xFD987193);
2681		c = FF(c, d, a, b, x[k + 14], S13, 0xA679438E);
2682		b = FF(b, c, d, a, x[k + 15], S14, 0x49B40821);
2683		a = GG(a, b, c, d, x[k + 1], S21, 0xF61E2562);
2684		d = GG(d, a, b, c, x[k + 6], S22, 0xC040B340);
2685		c = GG(c, d, a, b, x[k + 11], S23, 0x265E5A51);
2686		b = GG(b, c, d, a, x[k + 0], S24, 0xE9B6C7AA);
2687		a = GG(a, b, c, d, x[k + 5], S21, 0xD62F105D);
2688		d = GG(d, a, b, c, x[k + 10], S22, 0x2441453);
2689		c = GG(c, d, a, b, x[k + 15], S23, 0xD8A1E681);
2690		b = GG(b, c, d, a, x[k + 4], S24, 0xE7D3FBC8);
2691		a = GG(a, b, c, d, x[k + 9], S21, 0x21E1CDE6);
2692		d = GG(d, a, b, c, x[k + 14], S22, 0xC33707D6);
2693		c = GG(c, d, a, b, x[k + 3], S23, 0xF4D50D87);
2694		b = GG(b, c, d, a, x[k + 8], S24, 0x455A14ED);
2695		a = GG(a, b, c, d, x[k + 13], S21, 0xA9E3E905);
2696		d = GG(d, a, b, c, x[k + 2], S22, 0xFCEFA3F8);
2697		c = GG(c, d, a, b, x[k + 7], S23, 0x676F02D9);
2698		b = GG(b, c, d, a, x[k + 12], S24, 0x8D2A4C8A);
2699		a = HH(a, b, c, d, x[k + 5], S31, 0xFFFA3942);
2700		d = HH(d, a, b, c, x[k + 8], S32, 0x8771F681);
2701		c = HH(c, d, a, b, x[k + 11], S33, 0x6D9D6122);
2702		b = HH(b, c, d, a, x[k + 14], S34, 0xFDE5380C);
2703		a = HH(a, b, c, d, x[k + 1], S31, 0xA4BEEA44);
2704		d = HH(d, a, b, c, x[k + 4], S32, 0x4BDECFA9);
2705		c = HH(c, d, a, b, x[k + 7], S33, 0xF6BB4B60);
2706		b = HH(b, c, d, a, x[k + 10], S34, 0xBEBFBC70);
2707		a = HH(a, b, c, d, x[k + 13], S31, 0x289B7EC6);
2708		d = HH(d, a, b, c, x[k + 0], S32, 0xEAA127FA);
2709		c = HH(c, d, a, b, x[k + 3], S33, 0xD4EF3085);
2710		b = HH(b, c, d, a, x[k + 6], S34, 0x4881D05);
2711		a = HH(a, b, c, d, x[k + 9], S31, 0xD9D4D039);
2712		d = HH(d, a, b, c, x[k + 12], S32, 0xE6DB99E5);
2713		c = HH(c, d, a, b, x[k + 15], S33, 0x1FA27CF8);
2714		b = HH(b, c, d, a, x[k + 2], S34, 0xC4AC5665);
2715		a = II(a, b, c, d, x[k + 0], S41, 0xF4292244);
2716		d = II(d, a, b, c, x[k + 7], S42, 0x432AFF97);
2717		c = II(c, d, a, b, x[k + 14], S43, 0xAB9423A7);
2718		b = II(b, c, d, a, x[k + 5], S44, 0xFC93A039);
2719		a = II(a, b, c, d, x[k + 12], S41, 0x655B59C3);
2720		d = II(d, a, b, c, x[k + 3], S42, 0x8F0CCC92);
2721		c = II(c, d, a, b, x[k + 10], S43, 0xFFEFF47D);
2722		b = II(b, c, d, a, x[k + 1], S44, 0x85845DD1);
2723		a = II(a, b, c, d, x[k + 8], S41, 0x6FA87E4F);
2724		d = II(d, a, b, c, x[k + 15], S42, 0xFE2CE6E0);
2725		c = II(c, d, a, b, x[k + 6], S43, 0xA3014314);
2726		b = II(b, c, d, a, x[k + 13], S44, 0x4E0811A1);
2727		a = II(a, b, c, d, x[k + 4], S41, 0xF7537E82);
2728		d = II(d, a, b, c, x[k + 11], S42, 0xBD3AF235);
2729		c = II(c, d, a, b, x[k + 2], S43, 0x2AD7D2BB);
2730		b = II(b, c, d, a, x[k + 9], S44, 0xEB86D391);
2731		a = AddUnsigned(a, AA);
2732		b = AddUnsigned(b, BB);
2733		c = AddUnsigned(c, CC);
2734		d = AddUnsigned(d, DD);
2735	}
2736
2737	var temp = WordToHex(a) + WordToHex(b) + WordToHex(c) + WordToHex(d);
2738
2739	return temp.toLowerCase();
2740}

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.