PageSourceSearch

https://www.tpf.ch/Resources/libraries/DnnPlugins/09_13_10/dnn.jquery.js?cdv=83

js tpf.ch collected 2026-10-02 10:17:29 UTC 161,186 bytes, 4,927 lines download raw bytes

1(function ($) {
2  $.fn.dnnTabs = function (options) {
3    var opts = $.extend({}, $.fn.dnnTabs.defaultOptions, options),
4      $wrap = this;
5
6    // patch for period in selector - http://jsfiddle.net/9Mst9/2/
7    $.ui.tabs.prototype._sanitizeSelector = function (hash) {
8      return hash.replace(/:/g, "\\:").replace(/\./g, "\\\.");
9    };
10
11    $wrap.each(function () {
12      var showEvent, cookieId;
13      if (this.id) {
14        cookieId = "dnnTabs-" + this.id;
15        if (opts.selected === -1) {
16          var cookieValue = dnn.dom.getCookie(cookieId);
17          if (cookieValue) {
18            opts.selected = cookieValue;
19          }
20          if (opts.selected === -1) {
21            opts.selected = 0;
22          }
23        }
24        showEvent = (function (cid) {
25          return function (event, ui) {
26            dnn.dom.setCookie(
27              cid,
28              ui.newTab.index(),
29              opts.cookieDays,
30              "/",
31              "",
32              false,
33              opts.cookieMilleseconds,
34            );
35          };
36        })(cookieId);
37      } else {
38        showEvent = function () {};
39      }
40
41      $wrap.tabs({
42        activate: showEvent,
43        active: opts.selected,
44        disabled: opts.disabled,
45        fx: {
46          opacity: opts.opacity,
47          duration: opts.duration,
48        },
49      });
50
51      if (window.location.hash && window.location.hash != "#") {
52        var substr = window.location.hash.substr(0, 50);
53        $('a[href="' + encodeURI(substr) + '"]', $wrap).trigger("click");
54      }
55
56      // page validation integration - select tab that contain tripped validators
57      if (
58        typeof window.Page_ClientValidate != "undefined" &&
59        $.isFunction(window.Page_ClientValidate)
60      ) {
61        $wrap.find(opts.validationTriggerSelector).click(function () {
62          if (!window.Page_ClientValidate(opts.validationGroup)) {
63            var invalidControl = $wrap.find(opts.invalidItemSelector).eq(0);
64            var $parent = invalidControl.closest(".ui-tabs-panel");
65            if ($parent.length > 0) {
66              var tabId = $parent.attr("id");
67              $parent
68                .parent()
69                .find("a[href='#" + tabId + "']")
70                .click();
71            }
72          }
73        });
74      }
75    });
76
77    return $wrap;
78  };
79
80  $.fn.dnnTabs.defaultOptions = {
81    opacity: "toggle",
82    duration: "fast",
83    validationTriggerSelector: ".dnnPrimaryAction",
84    validationGroup: "",
85    invalidItemSelector: '.dnnFormError[style*="inline"]',
86    regionToToggleSelector: "fieldset",
87    selected: -1,
88    cookieDays: 0,
89    cookieMilleseconds: 1200000, // twenty minutes
90  };
91})(jQuery);
92
93(function ($) {
94  $.fn.dnnConfirm = function (options) {
95    var opts = $.extend({}, $.fn.dnnConfirm.defaultOptions, options),
96      $wrap = this;
97    $wrap.each(function () {
98      var $this = $(this),
99        defaultAction = $this.attr("href"),
100        $dnnDialog;
101
102      if (defaultAction || opts.isButton) {
103        $dnnDialog = $("<div class='dnnDialog'></div>")
104          .html(opts.text)
105          .dialog(opts);
106        $dnnDialog.parent().find(".ui-dialog-titlebar-close").html("Close");
107        $this.click(function (e, isTrigger) {
108          if (isTrigger) {
109            return true;
110          }
111
112          if ($dnnDialog.is(":visible")) {
113            $dnnDialog.dialog("close");
114            return true;
115          }
116          $dnnDialog.dialog({
117            open: function () {
118              $(".ui-dialog-buttonpane")
119                .find('button:contains("' + opts.noText + '")')
120                .addClass("dnnConfirmCancel");
121            },
122            draggable: false,
123            buttons: [
124              {
125                text: opts.yesText,
126                click: function () {
127                  $dnnDialog.dialog("close");
128                  if ($.isFunction(opts.callbackTrue)) {
129                    opts.callbackTrue.call(this);
130                  } else {
131                    if (opts.isButton) {
132                      $this.trigger("click", [true]);
133                    } else {
134                      window.location.href = defaultAction;
135                    }
136                  }
137                },
138                class: opts.buttonYesClass,
139              },
140              {
141                text: opts.noText,
142                click: function () {
143                  $(this).dialog("close");
144                  if ($.isFunction(opts.callbackFalse)) {
145                    opts.callbackFalse.call(this);
146                  }
147                },
148                class: opts.buttonNoClass,
149              },
150            ],
151          });
152
153          $dnnDialog.dialog("open");
154          e.preventDefault();
155          return false;
156        });
157      }
158    });
159    return $wrap;
160  };
161
162  $.fn.dnnConfirm.defaultOptions = {
163    text: "Are you sure?",
164    yesText: "Yes",
165    noText: "No",
166    buttonYesClass: "dnnPrimaryAction",
167    buttonNoClass: "dnnSecondaryAction",
168    actionUrl: window.location.href,
169    autoOpen: false,
170    resizable: false,
171    modal: true,
172    title: "Confirm",
173    dialogClass: "dnnFormPopup dnnClear",
174    isButton: false,
175  };
176})(jQuery);
177
178(function ($) {
179  if ($.dnnConfirm) return;
180
181  $.dnnConfirm = function (opts) {
182    var defaultAction = opts.actionUrl ? opts.actionUrl : "javascript:void(0);";
183    var shadowLink = $('<a href="' + defaultAction + '" />');
184    shadowLink.dnnConfirm(opts).click();
185  };
186})(jQuery);
187
188(function ($) {
189  $.dnnAlert = function (options) {
190    var opts = $.extend({}, $.dnnAlert.defaultOptions, options),
191      $dnnDialog = $("<div class='dnnDialog'></div>")
192        .html(opts.text)
193        .dialog(opts);
194
195    $dnnDialog.dialog({
196      buttons: [
197        {
198          text: opts.okText,
199          class: opts.buttonOkClass,
200          click: function () {
201            $(this).dialog("close");
202            if ($.isFunction(opts.callback)) {
203              opts.callback.call(this);
204            }
205            return false;
206          },
207        },
208      ],
209    });
210    $dnnDialog.dialog("open");
211  };
212
213  $.dnnAlert.defaultOptions = {
214    okText: "Ok",
215    autoOpen: false,
216    resizable: false,
217    modal: true,
218    buttonOkClass: "dnnPrimaryAction",
219    dialogClass: "dnnFormPopup dnnClear",
220  };
221})(jQuery);
222
223(function ($) {
224  $.fn.dnnPanels = function (options) {
225    var opts = $.extend({}, $.fn.dnnPanels.defaultOptions, options),
226      $wrap = this;
227
228    $wrap.each(function () {
229      var $this = $(this);
230      if (typeof opts.onExpand === "function") {
231        $this.on("onExpand", opts.onExpand);
232      }
233      if (typeof opts.onHide === "function") {
234        $this.on("onHide", opts.onHide);
235      }
236      // wire up click event to perform slide toggle
237      $this.find(opts.clickToToggleSelector).click(function (e) {
238        var toggle = $(this)
239          .toggleClass(opts.toggleClass)
240          .parent()
241          .next(opts.regionToToggleSelector)
242          .slideToggle(function () {
243            var visible = $(this).is(":visible");
244            if (opts.saveState) {
245              var id = $(toggle).prev().attr("id");
246              var cookieId = id ? id.replace(/[^a-zA-Z0-9\-]+/g, "") : "";
247              if (cookieId) {
248                dnn.dom.setCookie(
249                  cookieId,
250                  visible,
251                  opts.cookieDays,
252                  "/",
253                  "",
254                  false,
255                  opts.cookieMilleseconds,
256                );
257              }
258            }
259            if (visible) {
260              $(this).trigger("onExpand");
261            } else {
262              $(this).trigger("onHide");
263            }
264          });
265
266        e.preventDefault();
267        e.stopImmediatePropagation();
268        return false;
269      });
270
271      function collapsePanel($clicker, $region) {
272        $clicker.removeClass(opts.toggleClass);
273        $region.hide();
274        $this.trigger("onHide");
275      }
276
277      function expandPanel($clicker, $region) {
278        $clicker.addClass(opts.toggleClass);
279        $region.show();
280        $this.trigger("onExpand");
281      }
282
283      // walk over each selector and expand or collapse as necessary
284      $this
285        .find(opts.sectionHeadSelector)
286        .each(function (indexInArray, valueOfElement) {
287          var $self = $(valueOfElement),
288            elementId = $self.attr("id"),
289            cookieId = elementId
290              ? elementId.replace(/[^a-zA-Z0-9\-]+/g, "")
291              : "",
292            cookieValue = cookieId ? dnn.dom.getCookie(cookieId) : "",
293            $clicker = $self.find(opts.clickToToggleIsolatedSelector),
294            $region = $self.next(opts.regionToToggleSelector),
295            $parentSeparator = $self.parents(opts.panelSeparatorSelector),
296            groupPanelIndex = $parentSeparator
297              .find(opts.sectionHeadSelector)
298              .index($self);
299
300          // default value
301          var isOpen = false;
302          if (
303            (indexInArray === 0 && opts.defaultState == "first") || // cookie set to true OR first panel
304            ($parentSeparator.length > 0 &&
305              groupPanelIndex === 0 &&
306              opts.defaultState == "first") || // grouping is used & its the first panel in its group
307            opts.defaultState == "open"
308          ) {
309            // default open
310            isOpen = true;
311          }
312          if (opts.saveState) {
313            if (cookieValue == "true") {
314              isOpen = true;
315            } else if (cookieValue == "false") {
316              isOpen = false;
317            }
318          }
319
320          if (isOpen) {
321            expandPanel($clicker, $region);
322          } else {
323            collapsePanel($clicker, $region);
324          }
325        });
326
327      // page validation integration - expand collapsed panels that contain tripped validators
328      $this.find(opts.validationTriggerSelector).click(function () {
329        if (
330          typeof window.Page_ClientValidate != "undefined" &&
331          $.isFunction(window.Page_ClientValidate)
332        ) {
333          if (!window.Page_ClientValidate(opts.validationGroup)) {
334            $this.find(opts.invalidItemSelector).each(function () {
335              var $parent = $(this).closest(opts.regionToToggleSelector);
336              if ($parent.is(":hidden")) {
337                $parent
338                  .prev(opts.sectionHeadSelector)
339                  .find(opts.clickToToggleIsolatedSelector)
340                  .click();
341              }
342            });
343          }
344        }
345      });
346    });
347    return $wrap;
348  };
349
350  $.fn.dnnPanels.defaultOptions = {
351    clickToToggleSelector: "h2.dnnFormSectionHead a",
352    sectionHeadSelector: ".dnnFormSectionHead",
353    regionToToggleSelector: "fieldset",
354    toggleClass: "dnnSectionExpanded",
355    clickToToggleIsolatedSelector: "a",
356    validationTriggerSelector: ".dnnPrimaryAction",
357    invalidItemSelector: '.dnnFormError[style*="inline"]',
358    validationGroup: "",
359    panelSeparatorSelector: ".ui-tabs-panel",
360    cookieDays: 0,
361    cookieMilleseconds: 1200000, // twenty minutes
362    saveState: true,
363    defaultState: "first", // open | closed | first
364  };
365})(jQuery);
366
367(function ($) {
368  $.fn.dnnPreview = function (options) {
369    var opts = $.extend({}, $.fn.dnnPreview.defaultOptions, options),
370      $wrap = this;
371
372    $wrap.each(function () {
373      var $this = $(this);
374      $this.find(opts.linkSelector).click(function (e) {
375        e.preventDefault();
376        var params = "?";
377        var skin, container;
378
379        if (opts.useComboBox) {
380          var skinComboBox = $("#" + opts.skinSelector);
381          var containerComboBox = $("#" + opts.containerSelector);
382
383          skin = skinComboBox.length
384            ? skinComboBox[0].selectize.getValue()
385            : "";
386          container = containerComboBox.length
387            ? containerComboBox[0].selectize.getValue()
388            : "";
389        } else {
390          skin = $this.find(opts.skinSelector).val();
391          container = $this.find(opts.containerSelector).val();
392        }
393        if (skin) {
394          params += "SkinSrc=" + skin;
395        }
396        if (container) {
397          if (skin) {
398            params += "&";
399          }
400          params += "ContainerSrc=" + container;
401        }
402        if (opts.ModuleId) {
403          if (params !== "?") {
404            params += "&ModuleID=" + opts.ModuleId;
405          } else {
406            params += "ModuleID=" + opts.ModuleId;
407          }
408        }
409        if (params != "?") {
410          window.open(
411            encodeURI(opts.baseUrl + params.replace(/.ascx/gi, "")),
412            "skinpreview",
413          );
414        } else {
415          $.dnnAlert({
416            text: opts.noSelectionMessage,
417            okText: opts.alertOkText,
418            closeText: opts.alertCloseText,
419          });
420        }
421      });
422    });
423
424    return $wrap;
425  };
426
427  $.fn.dnnPreview.defaultOptions = {
428    baseUrl:
429      window.location.protocol +
430      "//" +
431      window.location.host +
432      window.location.pathname,
433    linkSelector: "a.dnnSecondaryAction",
434    skinSelector: "",
435    containerSelector: "",
436    noSelectionMessage: "Please select a preview option.",
437    alertOkText: "Ok",
438    alertCloseText: "close",
439    useComboBox: false,
440  };
441})(jQuery);
442
443(function ($) {
444  $.fn.dnnExpandAll = function (options) {
445    var opts = $.extend({}, $.fn.dnnExpandAll.defaultOptions, options),
446      $elem = this;
447
448    if (
449      $(opts.targetArea).find(opts.targetSelector + ":visible").length ===
450        $(opts.targetArea).find(
451          opts.targetSelector + opts.targetExpandedSelector + ":visible",
452        ).length &&
453      !$(this).hasClass("expanded")
454    ) {
455      $(this).addClass("expanded").text(opts.collapseText);
456    }
457
458    $elem.click(function (e) {
459      e.preventDefault();
460      var $this = $(this);
461      if ($this.hasClass("expanded")) {
462        $this.removeClass("expanded").text(opts.expandText);
463        $(opts.targetArea)
464          .find(opts.targetSelector + opts.targetExpandedSelector + ":visible")
465          .click();
466      } else {
467        $this.addClass("expanded").text(opts.collapseText);
468        $(opts.targetArea)
469          .find(opts.targetSelector + ":visible")
470          .not(opts.targetExpandedSelector)
471          .click();
472      }
473
474      //stop event from called again
475      e.stopImmediatePropagation();
476    });
477
478    return $elem;
479  };
480  $.fn.dnnExpandAll.defaultOptions = {
481    expandText: "Expand All",
482    collapseText: "Collapse All",
483    targetArea: "#dnnHostSettings",
484    targetSelector: "h2.dnnFormSectionHead a",
485    targetExpandedSelector: ".dnnSectionExpanded",
486  };
487})(jQuery);
488
489(function ($) {
490  $.fn.dnnTooltip = function (options) {
491    var opts = $.extend({}, $.fn.dnnTooltip.defaultOptions, options),
492      $wrap = this;
493
494    $wrap.each(function () {
495      var $this = $(this),
496        dnnFormHelp = $this.prev();
497      if ($this.data("initialized")) return;
498      dnnFormHelp.on("click", function (e) {
499        e.preventDefault();
500      });
501      var helpSelector = $this.find(opts.helpSelector);
502      $this.parent().css({ position: "relative" });
503      $this.css({ position: "absolute", right: "-29%" });
504      var hoverOnToolTip = false,
505        hoverOnPd = false;
506
507      dnnFormHelp.hoverIntent({
508        over: function () {
509          hoverOnPd = true;
510          var tooltipHeight = helpSelector.height();
511          var top = -(tooltipHeight + 30);
512          if (tooltipHeight + 30 <= $this.parent().offset().top) {
513            helpSelector.parent().css({ top: top + "px" });
514            $this.find("div.dnnFormHelpContent span").addClass("bottomArrow");
515            $this.find("div.dnnFormHelpContent span").removeClass("topArrow");
516          } else {
517            helpSelector.parent().css({ top: 30 + "px" });
518            $this.find("div.dnnFormHelpContent span").addClass("topArrow");
519            $this
520              .find("div.dnnFormHelpContent span")
521              .removeClass("bottomArrow");
522          }
523          helpSelector.css("visibility", "visible");
524        },
525        out: function () {
526          hoverOnPd = false;
527          if (!$this.hasClass(opts.pinnedClass) && !hoverOnToolTip) {
528            helpSelector.css("visibility", "hidden");
529          }
530        },
531        timeout: 200,
532        interval: 200,
533      });
534
535      helpSelector.hover(
536        function () {
537          hoverOnToolTip = true;
538        },
539        function () {
540          hoverOnToolTip = false;
541          if (!$this.hasClass(opts.pinnedClass) && !hoverOnPd) {
542            helpSelector.css("visibility", "hidden");
543          }
544        },
545      );
546
547      var pinHelper = helpSelector.find(opts.pinSelector);
548
549      pinHelper.on("click", function (e) {
550        e.preventDefault();
551        if ($this.hasClass(opts.pinnedClass)) {
552          helpSelector
553            .css({ left: "0", top: "0" })
554            .css("visibility", "hidden")
555            .draggable("destroy");
556          $this.removeClass(opts.pinnedClass);
557        } else {
558          $this.addClass(opts.pinnedClass);
559          if ($.isFunction($().draggable)) {
560            helpSelector.draggable();
561          }
562        }
563      });
564
565      $this.data("initialized", 1);
566    });
567
568    return $wrap;
569  };
570
571  $.fn.dnnTooltip.defaultOptions = {
572    pinSelector: "a.pinHelp",
573    helpSelector: ".dnnFormHelpContent",
574    pinnedClass: "dnnTooltipPinned",
575  };
576})(jQuery);
577
578(function ($) {
579  var cb = function (e) {
580    if (!e) e = window.event;
581    e.cancelBubble = true;
582    if (e.stopPropagation) e.stopPropagation();
583  };
584
585  /* DNN customized checkbox/radiobox */
586  $.fn.dnnCheckbox = function (options) {
587    var settings = {
588      cls: "dnnCheckbox" /* checkbox  */,
589      labelClass: "dnnBoxLabel",
590    };
591    settings = $.extend(settings, options || {});
592
593    var addEvents = function (object) {
594      var checked = object.checked,
595        disabled = object.disabled,
596        $object = $(object);
597
598      if (object.stateInterval) clearInterval(object.stateInterval);
599
600      object.stateInterval = setInterval(function () {
601        if (object.disabled != disabled)
602          $object.trigger(
603            (disabled = !!object.disabled) ? "disable" : "enable",
604          );
605        if (object.checked != checked)
606          $object.trigger((checked = !!object.checked) ? "check" : "uncheck");
607      }, 10 /* in miliseconds.*/);
608      return $object;
609    };
610
611    return this.each(function () {
612      var ch = this;
613
614      if ($(ch).data("checkBoxWrapped")) {
615        return;
616      }
617      $(ch).data("checkBoxWrapped", true);
618
619      if (
620        $(this).hasClass("normalCheckBox") ||
621        $(this).hasClass("normalRadioButton")
622      )
623        return;
624      var parentCheckBoxHolder = $(this).closest(".normalCheckBox");
625      var parentRadioButtonHolder = $(this).closest(".normalRadioButton");
626      if (parentCheckBoxHolder.length || parentRadioButtonHolder.length) return;
627      var $ch = addEvents(ch);
628      if (ch.wrapper) ch.wrapper.remove();
629      ch.wrapper = $(
630        '<span class="' +
631          settings.cls +
632          '"><span class="mark"><img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAMAAAAoyzS7AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAAZQTFRFAAAAAAAApWe5zwAAAAF0Uk5TAEDm2GYAAAAMSURBVHjaYmAACDAAAAIAAU9tWeEAAAAASUVORK5CYII=" alt="checkbox" /></span></span>',
633      );
634      ch.wrapperInner = ch.wrapper.children("span:eq(0)");
635      ch.wrapper.hover(
636        function (e) {
637          ch.wrapperInner.addClass(settings.cls + "-hover");
638          cb(e);
639        },
640        function (e) {
641          ch.wrapperInner.removeClass(settings.cls + "-hover");
642          cb(e);
643        },
644      );
645
646      $ch
647        .css({ position: "absolute", zIndex: -1, opacity: 0 })
648        .after(ch.wrapper);
649
650      var label,
651        parentLabel = false;
652      label = $ch.closest("label");
653      if (!label.length) label = false;
654      else parentLabel = true;
655
656      if (!label && $ch.attr("id")) {
657        label = $('label[for="' + $ch.attr("id") + '"]');
658        if (!label.length) label = false;
659      }
660
661      if (label) {
662        label.addClass(settings.labelClass);
663        if (!parentLabel) {
664          label.click(function (e) {
665            clickHandler(e);
666            return false;
667          });
668        } else {
669          label.children().each(function () {
670            var $this = $(this);
671            if ($this.is("input")) return;
672
673            $this.click(function (e) {
674              clickHandler(e);
675              return false;
676            });
677          });
678        }
679      }
680
681      if (!parentLabel) {
682        ch.wrapper.click(function (e) {
683          clickHandler(e);
684          return false;
685        });
686      }
687
688      function clickHandler(e) {
689        if (ch.disabled) {
690          return;
691        }
692        $ch.triggerHandler("focus");
693        var previousChecked = ch.checked;
694        ch.click();
695        if (ch.checked == previousChecked && ch.type == "checkbox") {
696          ch.checked = !ch.checked; //Fix for Firefox browser
697        }
698        $ch.trigger("change", [e]);
699        cb(e);
700      }
701
702      $ch
703        .on("disable", function () {
704          ch.wrapperInner.addClass(settings.cls + "-disabled");
705        })
706        .on("enable", function () {
707          ch.wrapperInner.removeClass(settings.cls + "-disabled");
708        });
709      $ch
710        .on("check", function () {
711          ch.wrapper.addClass(settings.cls + "-checked");
712        })
713        .on("uncheck", function () {
714          ch.wrapper.removeClass(settings.cls + "-checked");
715        });
716      $ch
717        .on("focus", function (e) {
718          if (!e.isTrigger) ch.wrapper.addClass(settings.cls + "-focus");
719        })
720        .on("blur", function () {
721          ch.wrapper.removeClass(settings.cls + "-focus");
722        });
723
724      /* Applying checkbox state */
725      if (ch.checked) ch.wrapper.addClass(settings.cls + "-checked");
726      if (ch.disabled) ch.wrapperInner.addClass(settings.cls + "-disabled");
727    });
728  };
729
730  $.fn.dnnHelperTipDestroy = function () {
731    return this.each(function () {
732      var pd = this;
733      if (pd.id) {
734        $('div[data-tipholder="' + pd.id + '"]').remove();
735      }
736    });
737  };
738
739  $.fn.dnnHelperTip = function (options) {
740    var settings = {
741      cls: "dnnHelperTip",
742      helpContent: "This is hover helper tooltip",
743      holderId: "",
744      show: false, // immediately show tooltip after call
745    };
746    settings = $.extend(settings, options || {});
747    return this.each(function () {
748      var pd = this,
749        $pd = $(this);
750      if (pd.tooltipWrapper) pd.tooltipWrapper.remove();
751
752      pd.tooltipWrapper = $(
753        '<div class="' +
754          settings.cls +
755          '" data-tipholder="' +
756          settings.holderId +
757          '"> <div class="dnnFormHelpContent dnnClear"><span class="dnnHelpText">' +
758          settings.helpContent +
759          "</span></div></div>",
760      );
761      $("body").append(pd.tooltipWrapper);
762      pd.tooltipWrapper.css({ position: "absolute" });
763      pd.tooltipWrapperInner = $(".dnnFormHelpContent", pd.tooltipWrapper);
764
765      var tooltipHeight = pd.tooltipWrapperInner.height();
766      pd.tooltipWrapperInner.css({
767        left: "-10px",
768        top: -(tooltipHeight + 30) + "px",
769      });
770      var hoverOnPd = false;
771      $pd.hover(
772        function () {
773          hoverOnPd = true;
774          setTimeout(function () {
775            if (hoverOnPd) pd.tooltipWrapperInner.css("visibility", "visible");
776          }, 400);
777        },
778        function () {
779          hoverOnPd = false;
780          setTimeout(function () {
781            if (!hoverOnPd) pd.tooltipWrapperInner.css("visibility", "hidden");
782          }, 400);
783        },
784      );
785
786      if (settings.show) {
787        hoverOnPd = true;
788        setTimeout(function () {
789          pd.tooltipWrapperInner.css("visibility", "visible");
790        }, 400);
791      }
792
793      $pd.on("mousemove", function (e) {
794        var x = e.pageX;
795        var y = e.pageY;
796        var pos = $("body").css("position");
797        if (pos == "relative") y -= 38;
798        pd.tooltipWrapper.css({
799          left: x + "px",
800          top: y + "px",
801          "z-index": "99999",
802        });
803      });
804    });
805  };
806
807  $.fn.dnnProgressbar = function () {
808    var $pd = $(this),
809      pd = this;
810
811    if (pd.tooltipWrapper) pd.tooltipWrapper.remove();
812    pd.tooltipWrapper = $(
813      '<div class="dnnTooltip"> <div class="dnnFormHelpContent dnnClear"><span class="dnnHelpText"></span></div></div>',
814    ).insertAfter($pd);
815    pd.tooltipWrapperInner = $(".dnnFormHelpContent", pd.tooltipWrapper);
816    pd.tooltipWrapperInner.css({ width: "32px", padding: "7px" });
817    $pd.parent().css({ position: "relative" });
818
819    var hoverOnToolTip = false,
820      hoverOnPd = false;
821    $pd.hoverIntent({
822      over: function () {
823        hoverOnPd = true;
824        var val = $(this).children(":first").progressbar("value");
825        pd.update(val);
826        pd.tooltipWrapperInner.css("visibility", "visible");
827      },
828      out: function () {
829        hoverOnPd = false;
830        if (!hoverOnToolTip) {
831          pd.tooltipWrapperInner.css("visibility", "hidden");
832        }
833      },
834      timeout: 200,
835      interval: 200,
836    });
837
838    pd.tooltipWrapperInner.hover(
839      function () {
840        hoverOnToolTip = true;
841      },
842      function () {
843        hoverOnToolTip = false;
844        if (!hoverOnPd) {
845          pd.tooltipWrapperInner.hide();
846        }
847      },
848    );
849
850    pd.update = function (value) {
851      pd.tooltipWrapperInner.find("span").html(value + " %");
852      var pdTop = $pd.position().top,
853        tooltipHeight = pd.tooltipWrapperInner.height();
854
855      pdTop -= tooltipHeight + 10;
856      var pdLeft =
857        value > 50 ? value - 4 + "%" : value > 0 ? value - 2 + "%" : "10px";
858      pd.tooltipWrapper.css({
859        position: "absolute",
860        left: pdLeft,
861        top: pdTop + "px",
862      });
863    };
864
865    return this;
866  };
867
868  $.fn.dnnSpinner = function (options) {
869    var opt = $.extend(
870      {
871        type: "range",
872        typedata: "",
873        width: "150px",
874        looping: false,
875      },
876      options,
877    );
878
879    var otypedata;
880
881    if (options != null && options.typedata != null) {
882      otypedata = $.extend(
883        {
884          min: 1,
885          max: 10,
886          interval: 1,
887          decimalplaces: 0,
888        },
889        options.typedata,
890      );
891    } else {
892      otypedata = $.extend({
893        min: 1,
894        max: 10,
895        interval: 1,
896        decimalplaces: 0,
897      });
898    }
899    opt.typedata = otypedata;
900
901    var inputControl = this;
902    if (!inputControl.is(":text")) return inputControl;
903
904    if (inputControl.hasClass("dnnSpinnerInput")) {
905      return inputControl;
906    } else {
907      inputControl.addClass("dnnSpinnerInput");
908    }
909
910    var strContainerDiv = "";
911    strContainerDiv += '<div class="dnnSpinner">';
912    strContainerDiv += '<div class="dnnSpinnerDisplay"></div>';
913    strContainerDiv += '<div class="dnnSpinnerCtrl">';
914    strContainerDiv += '<a class="dnnSpinnerTopButton"></a>';
915    strContainerDiv += '<a class="dnnSpinnerBotButton"></a>';
916    strContainerDiv += "</div></div>";
917    var objContainerDiv = $(strContainerDiv).insertAfter(inputControl);
918    inputControl.insertAfter($("div.dnnSpinnerDisplay", objContainerDiv));
919    $("div.dnnSpinnerDisplay", objContainerDiv).click(function () {
920      if (opt.type == "range") {
921        var displayCtrl = $(this);
922        var innerInput = $('input[type="text"]', displayCtrl);
923        if (innerInput.length < 1) {
924          var originalVal = displayCtrl.html();
925          innerInput = $('<input type="text" />').val(originalVal);
926          displayCtrl.html(innerInput);
927          innerInput
928            .blur(function () {
929              var newVal = $(this).val();
930              if (newVal > opt.typedata.max) {
931                newVal = opt.typedata.max;
932              }
933              if (newVal < opt.typedata.min) {
934                newVal = opt.typedata.min;
935              }
936              $(this).remove();
937              selectedValue = parseInt(newVal);
938              inputControl.val(newVal);
939              displayCtrl.html(newVal);
940            })
941            .keypress(function (e) {
942              var regex = new RegExp("^[0-9]+$");
943              var key = String.fromCharCode(!e.charCode ? e.which : e.charCode);
944              if (!regex.test(key)) {
945                event.preventDefault();
946                return false;
947              }
948              return true;
949            });
950        }
951        innerInput.focus();
952      }
953
954      inputControl.triggerHandler("focus");
955    });
956    inputControl.css("display", "none");
957
958    switch (opt.type) {
959      case "range":
960        if (
961          opt.defaultVal < opt.typedata.min ||
962          opt.defaultVal > opt.typedata.max
963        ) {
964          opt.defaultVal = opt.typedata.min;
965        }
966        if (opt.defaultVal % opt.typedata.interval > 0) {
967          opt.defaultVal =
968            parseInt((opt.defaultVal / opt.typedata.interval).toFixed(0)) *
969            opt.typedata.interval;
970        }
971        inputControl.val(opt.defaultVal.toFixed(opt.typedata.decimalplaces));
972        $("div.dnnSpinnerDisplay", objContainerDiv).html(
973          opt.defaultVal.toFixed(opt.typedata.decimalplaces),
974        );
975        var selectedValue = opt.defaultVal;
976        if (opt.typedata.max - opt.typedata.min > opt.typedata.interval) {
977          $("a.dnnSpinnerTopButton", objContainerDiv).click(function () {
978            if (
979              selectedValue + opt.typedata.interval <= opt.typedata.max ||
980              opt.looping
981            ) {
982              if (selectedValue + opt.typedata.interval > opt.typedata.max) {
983                selectedValue = opt.typedata.min - opt.typedata.interval;
984              }
985              var valueData = (selectedValue + opt.typedata.interval).toFixed(
986                opt.typedata.decimalplaces,
987              );
988              selectedValue += opt.typedata.interval;
989              $("div.dnnSpinnerDisplay", objContainerDiv).html(valueData);
990              inputControl.val(valueData);
991            }
992            inputControl.triggerHandler("focus");
993            return false;
994          });
995
996          $("a.dnnSpinnerBotButton", objContainerDiv).click(function () {
997            if (
998              selectedValue - opt.typedata.interval >= opt.typedata.min ||
999              opt.looping
1000            ) {
1001              if (selectedValue - opt.typedata.interval < opt.typedata.min) {
1002                selectedValue = opt.typedata.max + opt.typedata.interval;
1003              }
1004              var valueData = (selectedValue - opt.typedata.interval).toFixed(
1005                opt.typedata.decimalplaces,
1006              );
1007              selectedValue -= opt.typedata.interval;
1008              $("div.dnnSpinnerDisplay", objContainerDiv).html(valueData);
1009              inputControl.val(valueData);
1010            }
1011            inputControl.triggerHandler("focus");
1012            return false;
1013          });
1014        }
1015
1016        break;
1017      case "list":
1018        if (!opt.typedata.list || opt.typedata.list.lenght == 0) {
1019          return inputControl;
1020        }
1021
1022        var listItems = opt.typedata.list.split(",");
1023        var selectedIndex = jQuery.inArray(opt.defaultVal, listItems);
1024        if (selectedIndex < 0) {
1025          selectedIndex = 0;
1026          opt.defaultVal = listItems[0];
1027        }
1028
1029        inputControl.val(opt.defaultVal);
1030        $("div.dnnSpinnerDisplay", objContainerDiv).html(opt.defaultVal);
1031
1032        if (listItems.length > 1) {
1033          // attach events;
1034          $("a.dnnSpinnerBotButton", objContainerDiv).click(function () {
1035            if (selectedIndex < listItems.length - 1 || opt.looping) {
1036              if (selectedIndex == listItems.length - 1) {
1037                selectedIndex = -1;
1038              }
1039              selectedIndex++;
1040              var valueData = listItems[selectedIndex];
1041              $("div.dnnSpinnerDisplay", objContainerDiv).html(valueData);
1042              inputControl.val(valueData);
1043            }
1044            inputControl.triggerHandler("focus");
1045            return false;
1046          });
1047
1048          $("a.dnnSpinnerTopButton", objContainerDiv).click(function () {
1049            if (selectedIndex > 0 || opt.looping) {
1050              if (selectedIndex == 0) {
1051                selectedIndex = listItems.length;
1052              }
1053              selectedIndex--;
1054              var valueData = listItems[selectedIndex];
1055              $("div.dnnSpinnerDisplay", objContainerDiv).html(valueData);
1056              inputControl.val(valueData);
1057            }
1058            inputControl.triggerHandler("focus");
1059            return false;
1060          });
1061        }
1062
1063        break;
1064    }
1065    return inputControl;
1066  };
1067})(jQuery);
1068
1069(function ($) {
1070  $.fn.dnnAutocomplete = function (options) {
1071    var url;
1072    if (arguments.length > 1) {
1073      url = options;
1074      options = arguments[1];
1075      options.url = url;
1076    } else if (typeof options === "string") {
1077      url = options;
1078      options = { url: url };
1079    }
1080    var opts = $.extend({}, $.fn.dnnAutocomplete.defaults, options);
1081    return this.each(function () {
1082      var $this = $(this);
1083      $this.data(
1084        "autocompleter",
1085        new $.dnnAutocompleter(
1086          $this,
1087          $.meta ? $.extend({}, opts, $this.data()) : opts,
1088        ),
1089      );
1090    });
1091  };
1092
1093  $.fn.dnnAutocomplete.defaults = {
1094    inputClass: "dnn_acInput",
1095    loadingClass: "dnn_acLoading",
1096    resultsClass: "dnn_acResults",
1097    selectClass: "dnn_acSelect",
1098    queryParamName: "q",
1099    contentTypeParamName: "contentTypeId",
1100    extraParams: {},
1101    remoteDataType: false,
1102    lineSeparator: "\n",
1103    cellSeparator: "|",
1104    minChars: 2,
1105    maxItemsToShow: 10,
1106    delay: 400,
1107    useCache: false,
1108    maxCacheLength: 10,
1109    matchSubset: true,
1110    matchCase: false,
1111    matchInside: true,
1112    mustMatch: false,
1113    selectFirst: false,
1114    selectOnly: false,
1115    showResult: null,
1116    preventDefaultReturn: 1,
1117    preventDefaultTab: 0,
1118    autoFill: false,
1119    filterResults: true,
1120    sortResults: true,
1121    sortFunction: null,
1122    onItemSelect: null,
1123    onNoMatch: null,
1124    onFinish: null,
1125    matchStringConverter: null,
1126    beforeUseConverter: null,
1127    autoWidth: "min-width",
1128    useDelimiter: false,
1129    delimiterChar: ",",
1130    delimiterKeyCode: 188,
1131    processData: null,
1132    onError: null,
1133    moduleId: null, // dnn Module Id context if needed
1134  };
1135
1136  var sanitizeResult = function (result) {
1137    var value, data;
1138    var type = typeof result;
1139    if (type === "string") {
1140      value = result;
1141      data = {};
1142    } else if ($.isArray(result)) {
1143      value = result[0];
1144      data = result.slice(1);
1145    } else if (type === "object") {
1146      value = result.value;
1147      data = result.data;
1148    } else value = "";
1149    value = String(value);
1150    if (typeof data !== "object") {
1151      data = {};
1152    }
1153    return {
1154      value: value,
1155      data: data,
1156    };
1157  };
1158
1159  var sanitizeInteger = function (value, stdValue, options) {
1160    var num = parseInt(value, 10);
1161    options = options || {};
1162    if (isNaN(num) || (options.min && num < options.min)) {
1163      num = stdValue;
1164    }
1165    return num;
1166  };
1167
1168  var makeUrlParam = function (name, value) {
1169    return [name, encodeURIComponent(value)].join("=");
1170  };
1171
1172  var makeUrl = function (url, params) {
1173    var urlAppend = [];
1174    $.each(params, function (index, value) {
1175      urlAppend.push(makeUrlParam(index, value));
1176    });
1177    if (urlAppend.length) {
1178      url += url.indexOf("?") === -1 ? "?" : "&";
1179      url += urlAppend.join("&");
1180    }
1181    return url;
1182  };
1183
1184  var sortValueAlpha = function (a, b, matchCase) {
1185    a = String(a.value);
1186    b = String(b.value);
1187    if (!matchCase) {
1188      a = a.toLowerCase();
1189      b = b.toLowerCase();
1190    }
1191    if (a > b) {
1192      return 1;
1193    }
1194    if (a < b) {
1195      return -1;
1196    }
1197    return 0;
1198  };
1199
1200  $.dnnAutocompleter = function ($elem, options) {
1201    if (
1202      !$elem ||
1203      !($elem instanceof $) ||
1204      $elem.length !== 1 ||
1205      $elem.get(0).tagName.toUpperCase() !== "INPUT"
1206    ) {
1207      throw new Error(
1208        "Invalid parameter for dnnAutocompleter, jQuery object with one element with INPUT tag expected.",
1209      );
1210    }
1211
1212    var self = this;
1213    this.options = options;
1214    this.cacheData_ = {};
1215    this.cacheLength_ = 0;
1216    this.selectClass_ = "jquery-autocomplete-selected-item";
1217    this.keyTimeout_ = null;
1218    this.finishTimeout_ = null;
1219    this.lastKeyPressed_ = null;
1220    this.lastProcessedValue_ = null;
1221    this.lastSelectedValue_ = null;
1222    this.active_ = false;
1223    this.finishOnBlur_ = true;
1224
1225    this.options.minChars = sanitizeInteger(
1226      this.options.minChars,
1227      $.fn.dnnAutocomplete.defaults.minChars,
1228      { min: 0 },
1229    );
1230    this.options.maxItemsToShow = sanitizeInteger(
1231      this.options.maxItemsToShow,
1232      $.fn.dnnAutocomplete.defaults.maxItemsToShow,
1233      { min: 0 },
1234    );
1235    this.options.maxCacheLength = sanitizeInteger(
1236      this.options.maxCacheLength,
1237      $.fn.dnnAutocomplete.defaults.maxCacheLength,
1238      { min: 1 },
1239    );
1240    this.options.delay = sanitizeInteger(
1241      this.options.delay,
1242      $.fn.dnnAutocomplete.defaults.delay,
1243      { min: 0 },
1244    );
1245    if (this.options.preventDefaultReturn != 2) {
1246      this.options.preventDefaultReturn = this.options.preventDefaultReturn
1247        ? 1
1248        : 0;
1249    }
1250    if (this.options.preventDefaultTab != 2) {
1251      this.options.preventDefaultTab = this.options.preventDefaultTab ? 1 : 0;
1252    }
1253
1254    this.dom = {};
1255    this.dom.$elem = $elem;
1256    this.dom.$elem
1257      .attr("autocomplete", "off")
1258      .addClass(this.options.inputClass);
1259    this.dom.$results = $("<div></div>")
1260      .hide()
1261      .addClass(this.options.resultsClass)
1262      .css({
1263        position: "absolute",
1264      });
1265    $("body").append(this.dom.$results);
1266    $elem.keydown(function (e) {
1267      self.lastKeyPressed_ = e.keyCode;
1268      switch (self.lastKeyPressed_) {
1269        case self.options.delimiterKeyCode: // comma = 188
1270          if (self.options.useDelimiter && self.active_) {
1271            self.selectCurrent();
1272          }
1273          break;
1274
1275        // ignore navigational & special keys
1276        case 35: // end
1277        case 36: // home
1278        case 16: // shift
1279        case 17: // ctrl
1280        case 18: // alt
1281        case 37: // left
1282        case 39: // right
1283          break;
1284
1285        case 38: // up
1286          e.preventDefault();
1287          if (self.active_) {
1288            self.focusPrev();
1289          } else {
1290            self.activate();
1291          }
1292          return false;
1293
1294        case 40: // down
1295          e.preventDefault();
1296          if (self.active_) {
1297            self.focusNext();
1298          } else {
1299            self.activate();
1300          }
1301          return false;
1302
1303        case 9: // tab
1304          if (self.active_) {
1305            self.selectCurrent();
1306            if (self.options.preventDefaultTab) {
1307              e.preventDefault();
1308              return false;
1309            }
1310          }
1311          if (self.options.preventDefaultTab === 2) {
1312            e.preventDefault();
1313            return false;
1314          }
1315          break;
1316
1317        case 13: // return
1318          if (self.active_) {
1319            self.selectCurrent();
1320            if (self.options.preventDefaultReturn) {
1321              e.preventDefault();
1322              return false;
1323            }
1324          }
1325          if (self.options.preventDefaultReturn === 2) {
1326            e.preventDefault();
1327            return false;
1328          }
1329          break;
1330
1331        case 27: // escape
1332          if (self.active_) {
1333            e.preventDefault();
1334            self.deactivate(true);
1335            return false;
1336          }
1337          break;
1338
1339        default:
1340          self.activate();
1341      }
1342      return true;
1343    });
1344
1345    var onBlurFunction = function () {
1346      self.deactivate(true);
1347    };
1348    $elem.blur(function () {
1349      if (self.finishOnBlur_) {
1350        self.finishTimeout_ = setTimeout(onBlurFunction, 1000);
1351      }
1352    });
1353
1354    $elem.parents("form").on("submit", onBlurFunction);
1355  };
1356
1357  $.dnnAutocompleter.prototype.position = function () {
1358    var offset = this.dom.$elem.offset();
1359    var height = this.dom.$results.outerHeight();
1360    var totalHeight = window.outerHeight;
1361    var inputBottom = offset.top + this.dom.$elem.outerHeight();
1362    var bottomIfDown = inputBottom + height;
1363    // Set autocomplete results at the bottom of input
1364    var position = { top: inputBottom, left: offset.left };
1365    if (bottomIfDown > totalHeight) {
1366      // Try to set autocomplete results at the top of input
1367      var topIfUp = offset.top - height;
1368      if (topIfUp >= 0) {
1369        position.top = topIfUp;
1370      }
1371    }
1372    this.dom.$results.css(position);
1373  };
1374
1375  $.dnnAutocompleter.prototype.cacheRead = function (filter) {
1376    var filterLength, searchLength, search, maxPos, pos;
1377    if (this.options.useCache) {
1378      filter = String(filter);
1379      filterLength = filter.length;
1380      if (this.options.matchSubset) {
1381        searchLength = 1;
1382      } else {
1383        searchLength = filterLength;
1384      }
1385      while (searchLength <= filterLength) {
1386        if (this.options.matchInside) {
1387          maxPos = filterLength - searchLength;
1388        } else {
1389          maxPos = 0;
1390        }
1391        pos = 0;
1392        while (pos <= maxPos) {
1393          search = filter.substr(0, searchLength);
1394          if (this.cacheData_[search] !== undefined) {
1395            return this.cacheData_[search];
1396          }
1397          pos++;
1398        }
1399        searchLength++;
1400      }
1401    }
1402    return false;
1403  };
1404
1405  $.dnnAutocompleter.prototype.cacheWrite = function (filter, data) {
1406    if (this.options.useCache) {
1407      if (this.cacheLength_ >= this.options.maxCacheLength) {
1408        this.cacheFlush();
1409      }
1410      filter = String(filter);
1411      if (this.cacheData_[filter] !== undefined) {
1412        this.cacheLength_++;
1413      }
1414      this.cacheData_[filter] = data;
1415      return this.cacheData_[filter];
1416    }
1417    return false;
1418  };
1419
1420  $.dnnAutocompleter.prototype.cacheFlush = function () {
1421    this.cacheData_ = {};
1422    this.cacheLength_ = 0;
1423  };
1424
1425  $.dnnAutocompleter.prototype.callHook = function (hook, data) {
1426    var f = this.options[hook];
1427    if (f && $.isFunction(f)) {
1428      return f(data, this);
1429    }
1430    return false;
1431  };
1432
1433  $.dnnAutocompleter.prototype.activate = function () {
1434    var self = this;
1435    if (this.keyTimeout_) {
1436      clearTimeout(this.keyTimeout_);
1437    }
1438    this.keyTimeout_ = setTimeout(function () {
1439      self.activateNow();
1440    }, this.options.delay);
1441  };
1442
1443  $.dnnAutocompleter.prototype.activateNow = function () {
1444    var value = this.beforeUseConverter(this.dom.$elem.val());
1445    if (
1446      value !== this.lastProcessedValue_ &&
1447      value !== this.lastSelectedValue_
1448    ) {
1449      this.fetchData(value);
1450    }
1451  };
1452
1453  $.dnnAutocompleter.prototype.fetchData = function (value) {
1454    var self = this;
1455    var processResults = function (results, filter) {
1456      if (self.options.processData) {
1457        results = self.options.processData(results);
1458      }
1459      self.showResults(self.filterResults(results, filter), filter);
1460    };
1461    this.lastProcessedValue_ = value;
1462    if (value.length < this.options.minChars) {
1463      processResults([], value);
1464    } else if (this.options.data) {
1465      processResults(this.options.data, value);
1466    } else {
1467      this.fetchRemoteData(value, function (remoteData) {
1468        processResults(remoteData, value);
1469      });
1470    }
1471  };
1472
1473  $.dnnAutocompleter.prototype.fetchRemoteData = function (filter, callback) {
1474    var data = this.cacheRead(filter);
1475    if (data) {
1476      callback(data);
1477    } else {
1478      var self = this;
1479      var ajaxCallback = function (d) {
1480        var parsed = false;
1481        if (d !== false) {
1482          parsed = self.parseRemoteData(d);
1483          self.cacheWrite(filter, parsed);
1484        }
1485        self.dom.$elem.removeClass(self.options.loadingClass);
1486        callback(parsed);
1487      };
1488
1489      this.dom.$elem.addClass(this.options.loadingClass);
1490      // DNN service framework attached if needed
1491      var services = self.options.moduleId
1492        ? $.dnnSF
1493          ? $.dnnSF(self.options.moduleId)
1494          : null
1495        : null;
1496      $.ajax({
1497        url: this.makeUrl(filter),
1498        beforeSend: services ? services.setModuleHeaders : null,
1499        success: ajaxCallback,
1500        error: function (jqXhr, textStatus, errorThrown) {
1501          if ($.isFunction(self.options.onError)) {
1502            self.options.onError(jqXhr, textStatus, errorThrown);
1503          } else {
1504            ajaxCallback(false);
1505          }
1506        },
1507        type: "GET",
1508        dataType: "json",
1509        contentType: "application/json",
1510      });
1511    }
1512  };
1513
1514  $.dnnAutocompleter.prototype.setExtraParam = function (name, value) {
1515    var index = $.trim(String(name));
1516    if (index) {
1517      if (!this.options.extraParams) {
1518        this.options.extraParams = {};
1519      }
1520      if (this.options.extraParams[index] !== value) {
1521        this.options.extraParams[index] = value;
1522        this.cacheFlush();
1523      }
1524    }
1525  };
1526
1527  $.dnnAutocompleter.prototype.makeUrl = function (param) {
1528    var url = this.options.url;
1529    var params = {};
1530    params[this.options.queryParamName] = param;
1531    return makeUrl(url, params);
1532  };
1533
1534  $.dnnAutocompleter.prototype.parseRemoteData = function (remoteData) {
1535    var data = remoteData;
1536    if (typeof data["d"] != "undefined") {
1537      data = $.parseJSON(data["d"]);
1538    }
1539    return data;
1540  };
1541
1542  $.dnnAutocompleter.prototype.filterResult = function (result, filter) {
1543    if (!result.value) {
1544      return false;
1545    }
1546    if (this.options.filterResults) {
1547      var pattern = this.matchStringConverter(filter);
1548      var testValue = this.matchStringConverter(result.value);
1549      if (!this.options.matchCase) {
1550        pattern = pattern.toLowerCase();
1551        testValue = testValue.toLowerCase();
1552      }
1553      var patternIndex = testValue.indexOf(pattern);
1554      if (this.options.matchInside) {
1555        return patternIndex > -1;
1556      } else {
1557        return patternIndex === 0;
1558      }
1559    }
1560    return true;
1561  };
1562
1563  $.dnnAutocompleter.prototype.filterResults = function (results, filter) {
1564    var filtered = [];
1565    var i, result;
1566
1567    for (i = 0; i < results.length; i++) {
1568      result = sanitizeResult(results[i]);
1569      if (this.filterResult(result, filter)) {
1570        filtered.push(result);
1571      }
1572    }
1573    if (this.options.sortResults) {
1574      filtered = this.sortResults(filtered, filter);
1575    }
1576    if (
1577      this.options.maxItemsToShow > 0 &&
1578      this.options.maxItemsToShow < filtered.length
1579    ) {
1580      filtered.length = this.options.maxItemsToShow;
1581    }
1582    return filtered;
1583  };
1584
1585  $.dnnAutocompleter.prototype.sortResults = function (results, filter) {
1586    var self = this;
1587    var sortFunction = this.options.sortFunction;
1588    if (!$.isFunction(sortFunction)) {
1589      sortFunction = function (a, b) {
1590        return sortValueAlpha(a, b, self.options.matchCase);
1591      };
1592    }
1593    results.sort(function (a, b) {
1594      return sortFunction(a, b, filter, self.options);
1595    });
1596    return results;
1597  };
1598
1599  $.dnnAutocompleter.prototype.matchStringConverter = function (s, a, b) {
1600    var converter = this.options.matchStringConverter;
1601    if ($.isFunction(converter)) {
1602      s = converter(s, a, b);
1603    }
1604    return s;
1605  };
1606
1607  $.dnnAutocompleter.prototype.beforeUseConverter = function (s, a, b) {
1608    s = this.getValue();
1609    var converter = this.options.beforeUseConverter;
1610    if ($.isFunction(converter)) {
1611      s = converter(s, a, b);
1612    }
1613    return s;
1614  };
1615
1616  $.dnnAutocompleter.prototype.enableFinishOnBlur = function () {
1617    this.finishOnBlur_ = true;
1618  };
1619
1620  $.dnnAutocompleter.prototype.disableFinishOnBlur = function () {
1621    this.finishOnBlur_ = false;
1622  };
1623
1624  $.dnnAutocompleter.prototype.createItemFromResult = function (
1625    result,
1626    filter,
1627  ) {
1628    var self = this;
1629    var $li = $(
1630      "<li>" + this.showResult(result.value, result.data, filter) + "</li>",
1631    );
1632    $li
1633      .data({ value: result.value, data: result.data })
1634      .click(function () {
1635        self.selectItem($li);
1636      })
1637      .mousedown(self.disableFinishOnBlur)
1638      .mouseup(self.enableFinishOnBlur);
1639    return $li;
1640  };
1641
1642  $.dnnAutocompleter.prototype.getItems = function () {
1643    return $(">ul>li", this.dom.$results);
1644  };
1645
1646  $.dnnAutocompleter.prototype.showResults = function (results, filter) {
1647    var numResults = results.length;
1648    var self = this;
1649    var $ul = $("<ul></ul>");
1650    var i,
1651      result,
1652      $li,
1653      autoWidth,
1654      first = false,
1655      $first = false;
1656
1657    if (numResults) {
1658      for (i = 0; i < numResults; i++) {
1659        result = results[i];
1660        $li = this.createItemFromResult(result, filter);
1661        $ul.append($li);
1662        if (first === false) {
1663          first = String(result.value);
1664          $first = $li;
1665          $li.addClass(this.options.firstItemClass);
1666        }
1667        if (i === numResults - 1) {
1668          $li.addClass(this.options.lastItemClass);
1669        }
1670      }
1671
1672      this.dom.$results.html($ul).show();
1673
1674      // Always recalculate position since window size or
1675      // input element location may have changed.
1676      this.position();
1677      if (this.options.autoWidth) {
1678        autoWidth =
1679          this.dom.$elem.outerWidth() -
1680          this.dom.$results.outerWidth() +
1681          this.dom.$results.width();
1682        this.dom.$results.css(this.options.autoWidth, autoWidth);
1683      }
1684      this.getItems().hover(
1685        function () {
1686          self.focusItem(this);
1687        },
1688        function () {
1689          /* void */
1690        },
1691      );
1692      if (
1693        this.autoFill(first, filter) ||
1694        this.options.selectFirst ||
1695        (this.options.selectOnly && numResults === 1)
1696      ) {
1697        this.focusItem($first);
1698      }
1699      this.active_ = true;
1700
1701      //Select the first one as default
1702      this.focusNext();
1703    } else {
1704      this.hideResults();
1705      this.active_ = false;
1706    }
1707  };
1708
1709  $.dnnAutocompleter.prototype.showResult = function (value, data, filter) {
1710    if ($.isFunction(this.options.showResult)) {
1711      return this.options.showResult(value, data);
1712    } else {
1713      // add highlight keywords
1714      var regex = new RegExp("(" + filter + ")", "gi");
1715      return value.replace(regex, function ($0, $1) {
1716        return "<b>" + $1 + "</b>";
1717      });
1718    }
1719  };
1720
1721  $.dnnAutocompleter.prototype.autoFill = function (value, filter) {
1722    var lcValue, lcFilter, valueLength, filterLength;
1723    if (this.options.autoFill && this.lastKeyPressed_ !== 8) {
1724      lcValue = String(value).toLowerCase();
1725      lcFilter = String(filter).toLowerCase();
1726      valueLength = value.length;
1727      filterLength = filter.length;
1728      if (lcValue.substr(0, filterLength) === lcFilter) {
1729        var d = this.getDelimiterOffsets();
1730        var pad = d.start ? " " : ""; // if there is a preceding delimiter
1731        this.setValue(pad + value);
1732        var start = filterLength + d.start + pad.length;
1733        var end = valueLength + d.start + pad.length;
1734        this.selectRange(start, end);
1735        return true;
1736      }
1737    }
1738    return false;
1739  };
1740
1741  $.dnnAutocompleter.prototype.focusNext = function () {
1742    this.focusMove(+1);
1743  };
1744
1745  $.dnnAutocompleter.prototype.focusPrev = function () {
1746    this.focusMove(-1);
1747  };
1748
1749  $.dnnAutocompleter.prototype.focusMove = function (modifier) {
1750    var $items = this.getItems();
1751    modifier = sanitizeInteger(modifier, 0);
1752    if (modifier) {
1753      for (var i = 0; i < $items.length; i++) {
1754        if ($($items[i]).hasClass(this.selectClass_)) {
1755          this.focusItem(i + modifier);
1756          return;
1757        }
1758      }
1759    }
1760    this.focusItem(0);
1761  };
1762
1763  $.dnnAutocompleter.prototype.focusItem = function (item) {
1764    var $item,
1765      $items = this.getItems();
1766    if ($items.length) {
1767      $items
1768        .removeClass(this.selectClass_)
1769        .removeClass(this.options.selectClass);
1770      if (typeof item === "number") {
1771        if (item < 0) {
1772          item = 0;
1773        } else if (item >= $items.length) {
1774          item = $items.length - 1;
1775        }
1776        $item = $($items[item]);
1777      } else {
1778        $item = $(item);
1779      }
1780      if ($item) {
1781        $item.addClass(this.selectClass_).addClass(this.options.selectClass);
1782      }
1783    }
1784  };
1785
1786  $.dnnAutocompleter.prototype.selectCurrent = function () {
1787    var $item = $("li." + this.selectClass_, this.dom.$results);
1788    if ($item.length === 1) {
1789      this.selectItem($item);
1790    } else {
1791      this.deactivate(false);
1792    }
1793  };
1794
1795  $.dnnAutocompleter.prototype.selectItem = function ($li) {
1796    var value = $li.data("value");
1797    var data = $li.data("data");
1798    var displayValue = this.displayValue(value, data);
1799    var processedDisplayValue = this.beforeUseConverter(displayValue);
1800    this.lastProcessedValue_ = processedDisplayValue;
1801    this.lastSelectedValue_ = processedDisplayValue;
1802    var d = this.getDelimiterOffsets();
1803    var delimiter = this.options.delimiterChar;
1804    var elem = this.dom.$elem;
1805    var extraCaretPos = 0;
1806    if (this.options.useDelimiter) {
1807      // if there is a preceding delimiter, add a space after the delimiter
1808      if (
1809        elem.val().substring(d.start - 1, d.start) == delimiter &&
1810        delimiter != " "
1811      ) {
1812        displayValue = " " + displayValue;
1813      }
1814      // if there is not already a delimiter trailing this value, add it
1815      if (
1816        elem.val().substring(d.end, d.end + 1) != delimiter &&
1817        this.lastKeyPressed_ != this.options.delimiterKeyCode
1818      ) {
1819        displayValue = displayValue + delimiter;
1820      } else {
1821        // move the cursor after the existing trailing delimiter
1822        extraCaretPos = 1;
1823      }
1824    }
1825    this.setValue(displayValue);
1826    this.setCaret(d.start + displayValue.length + extraCaretPos);
1827    this.callHook("onItemSelect", { value: value, data: data });
1828    this.deactivate(true);
1829    elem.trigger("result", value);
1830  };
1831
1832  $.dnnAutocompleter.prototype.displayValue = function (value, data) {
1833    if ($.isFunction(this.options.displayValue)) {
1834      return this.options.displayValue(value, data);
1835    }
1836    return value;
1837  };
1838
1839  $.dnnAutocompleter.prototype.hideResults = function () {
1840    this.dom.$results.hide();
1841  };
1842
1843  $.dnnAutocompleter.prototype.deactivate = function (finish) {
1844    if (this.finishTimeout_) {
1845      clearTimeout(this.finishTimeout_);
1846    }
1847    if (this.keyTimeout_) {
1848      clearTimeout(this.keyTimeout_);
1849    }
1850    if (finish) {
1851      if (this.lastProcessedValue_ !== this.lastSelectedValue_) {
1852        if (this.options.mustMatch) {
1853          this.setValue("");
1854        }
1855        this.callHook("onNoMatch");
1856      }
1857      if (this.active_) {
1858        this.callHook("onFinish");
1859      }
1860      this.lastKeyPressed_ = null;
1861      this.lastProcessedValue_ = null;
1862      this.lastSelectedValue_ = null;
1863      this.active_ = false;
1864    }
1865    this.hideResults();
1866  };
1867
1868  $.dnnAutocompleter.prototype.selectRange = function (start, end) {
1869    var input = this.dom.$elem.get(0);
1870    if (input.setSelectionRange) {
1871      input.focus();
1872      input.setSelectionRange(start, end);
1873    } else if (input.createTextRange) {
1874      var range = input.createTextRange();
1875      range.collapse(true);
1876      range.moveEnd("character", end);
1877      range.moveStart("character", start);
1878      range.select();
1879    }
1880  };
1881
1882  $.dnnAutocompleter.prototype.setCaret = function (pos) {
1883    this.selectRange(pos, pos);
1884  };
1885
1886  $.dnnAutocompleter.prototype.getCaret = function () {
1887    var elem = this.dom.$elem,
1888      s,
1889      e,
1890      range;
1891    if (!$.support.cssFloat) {
1892      // ie
1893      var selection = document.selection;
1894      if (elem[0].tagName.toLowerCase() != "textarea") {
1895        var val = elem.val();
1896        range = selection.createRange().duplicate();
1897        range.moveEnd("character", val.length);
1898        s = range.text == "" ? val.length : val.lastIndexOf(range.text);
1899        range = selection.createRange().duplicate();
1900        range.moveStart("character", -val.length);
1901        e = range.text.length;
1902      } else {
1903        range = selection.createRange();
1904        var storedRange = range.duplicate();
1905        storedRange.moveToElementText(elem[0]);
1906        storedRange.setEndPoint("EndToEnd", range);
1907        s = storedRange.text.length - range.text.length;
1908        e = s + range.text.length;
1909      }
1910    } else {
1911      // ff, chrome, safari
1912      s = elem[0].selectionStart;
1913      e = elem[0].selectionEnd;
1914    }
1915    return {
1916      start: s,
1917      end: e,
1918    };
1919  };
1920
1921  $.dnnAutocompleter.prototype.setValue = function (value) {
1922    if (this.options.useDelimiter) {
1923      // set the substring between the current delimiters
1924      var val = this.dom.$elem.val();
1925      var d = this.getDelimiterOffsets();
1926      var preVal = val.substring(0, d.start);
1927      var postVal = val.substring(d.end);
1928      value = preVal + value + postVal;
1929    }
1930    this.dom.$elem.val(value).blur();
1931  };
1932
1933  $.dnnAutocompleter.prototype.getValue = function () {
1934    var val = this.dom.$elem.val();
1935    if (this.options.useDelimiter) {
1936      var d = this.getDelimiterOffsets();
1937      return val.substring(d.start, d.end).trim();
1938    } else {
1939      return val;
1940    }
1941  };
1942
1943  $.dnnAutocompleter.prototype.getDelimiterOffsets = function () {
1944    var val = this.dom.$elem.val();
1945    if (this.options.useDelimiter) {
1946      var preCaretVal = val.substring(0, this.getCaret().start);
1947      var start = preCaretVal.lastIndexOf(this.options.delimiterChar) + 1;
1948      var postCaretVal = val.substring(this.getCaret().start);
1949      var end = postCaretVal.indexOf(this.options.delimiterChar);
1950      if (end == -1) end = val.length;
1951      end += this.getCaret().start;
1952    } else {
1953      start = 0;
1954      end = val.length;
1955    }
1956    return {
1957      start: start,
1958      end: end,
1959    };
1960  };
1961})(jQuery);
1962
1963(function ($) {
1964  // dnn customized tags
1965  var delimiter = new Array();
1966  var tagsCallbacks = new Array();
1967  $.fn.dnnDoAutosize = function (o) {
1968    var minWidth = $(this).data("minwidth"),
1969      maxWidth = $(this).data("maxwidth"),
1970      val = "",
1971      input = $(this),
1972      testSubject = $("#" + $(this).data("tester_id"));
1973
1974    if (val === (val = input.val())) {
1975      return;
1976    }
1977
1978    // Enter new content into testSubject
1979    var escaped = val
1980      .replace(/&/g, "&amp;")
1981      .replace(/\s/g, " ")
1982      .replace(/</g, "&lt;")
1983      .replace(/>/g, "&gt;");
1984    testSubject.html(escaped);
1985    // Calculate new width + whether to change
1986    var testerWidth = testSubject.width(),
1987      newWidth =
1988        testerWidth + o.comfortZone >= minWidth
1989          ? testerWidth + o.comfortZone
1990          : minWidth,
1991      currentWidth = input.width(),
1992      isValidWidthChange =
1993        (newWidth < currentWidth && newWidth >= minWidth) ||
1994        (newWidth > minWidth && newWidth < maxWidth);
1995
1996    // Animate width
1997    if (isValidWidthChange) {
1998      input.width(newWidth);
1999    }
2000  };
2001
2002  $.fn.dnnResetAutosize = function (options) {
2003    var minWidth =
2004        $(this).data("minwidth") || options.minInputWidth || $(this).width(),
2005      maxWidth =
2006        $(this).data("maxwidth") ||
2007        options.maxInputWidth ||
2008        $(this).closest(".dnnTagsInput").width() - options.inputPadding,
2009      $input = $(this);
2010
2011    var left = 0;
2012    var $lastSpan = $(this).closest(".dnnTagsInput").find("> span").last();
2013    if ($lastSpan.length > 0) {
2014      left =
2015        $lastSpan.offset().left -
2016        $lastSpan.parent().offset().left +
2017        $lastSpan.outerWidth();
2018    }
2019    var availableWidth = maxWidth - left;
2020    if (availableWidth < parseInt(minWidth)) {
2021      availableWidth = maxWidth;
2022    }
2023
2024    $input.css("width", availableWidth);
2025  };
2026
2027  $.fn.dnnAddTag = function (value, options) {
2028    options = jQuery.extend({ focus: false, callback: true }, options);
2029    this.each(function () {
2030      var id = $(this).attr("id");
2031      var tagslist = $(this).val().split(delimiter[id]);
2032      if (tagslist[0] == "") {
2033        tagslist = new Array();
2034      }
2035      value = value.replace(/<.*?>/g, "");
2036      value = jQuery.trim(value);
2037      var skipTag;
2038      if (options.unique) {
2039        skipTag = $(this).dnnTagExist(value);
2040        if (skipTag == true) {
2041          //Marks fake input as not_valid to let styling it
2042          $("#" + id + "_tag").addClass("dnnTagsInvalid");
2043        } else $("#" + id + "_tag").removeClass("dnnTagsInvalid");
2044      } else {
2045        skipTag = false;
2046        $("#" + id + "_tag").removeClass("dnnTagsInvalid");
2047      }
2048
2049      if (value != "" && skipTag != true) {
2050        $("<span>")
2051          .addClass("tag")
2052          .append(
2053            $("<span>").text(value).append("&nbsp;&nbsp;"),
2054            $('<a aria-label="remove">', {
2055              href: "#",
2056              title: "Removing tag",
2057            }).click(function () {
2058              return $("#" + id).dnnRemoveTag(escape(value));
2059            }),
2060          )
2061          .insertBefore("#" + id + "_addTag");
2062
2063        tagslist.push(value);
2064
2065        $("#" + id + "_tag").val("");
2066        if (options.focus) {
2067          $("#" + id + "_tag").focus();
2068        } else {
2069          $("#" + id + "_tag").blur();
2070        }
2071
2072        $.fn.dnnTagsInput.updateTagsField(this, tagslist);
2073        var f;
2074        if (
2075          options.callback &&
2076          tagsCallbacks[id] &&
2077          tagsCallbacks[id]["onAddTag"]
2078        ) {
2079          f = tagsCallbacks[id]["onAddTag"];
2080          f.call(this, value);
2081        }
2082        if (tagsCallbacks[id] && tagsCallbacks[id]["onChange"]) {
2083          var i = tagslist.length;
2084          f = tagsCallbacks[id]["onChange"];
2085          f.call(this, $(this), tagslist[i - 1]);
2086        }
2087      }
2088    });
2089    return false;
2090  };
2091
2092  $.fn.dnnRemoveTag = function (value) {
2093    value = unescape(value);
2094    this.each(function () {
2095      var id = $(this).attr("id");
2096      var old = $(this).val().split(delimiter[id]);
2097      $("#" + id + "_tagsinput .tag").remove();
2098      var str = "";
2099      for (var i = 0; i < old.length; i++) {
2100        if (old[i] != value) {
2101          str = str + delimiter[id] + old[i];
2102        }
2103      }
2104      $.fn.dnnTagsInput.importTags(this, str);
2105      if (tagsCallbacks[id] && tagsCallbacks[id]["onRemoveTag"]) {
2106        var f = tagsCallbacks[id]["onRemoveTag"];
2107        f.call(this, value);
2108      }
2109    });
2110
2111    return false;
2112  };
2113
2114  $.fn.dnnTagExist = function (val) {
2115    var id = $(this).attr("id"),
2116      tagslist = $(this).val().split(delimiter[id]);
2117    return jQuery.inArray(val, tagslist) >= 0;
2118  };
2119
2120  $.fn.dnnImportTags = function (str) {
2121    var id = $(this).attr("id");
2122    $("#" + id + "_tagsinput .tag").remove();
2123    $.fn.dnnTagsInput.importTags(this, str);
2124  };
2125
2126  $.fn.dnnTagsInput = function (options) {
2127    var onError = null;
2128    var triggerOnError = function (handler) {
2129      if (!onError) {
2130        onError = setTimeout(function () {
2131          onError = null;
2132          if (handler) handler();
2133        }, 0);
2134      }
2135    };
2136    var settings = jQuery.extend(
2137      {
2138        interactive: true,
2139        defaultText: "Add a tag",
2140        minChars: 0,
2141        maxChars: 50,
2142        maxTags: 16,
2143        lessThanMinCharsErrorText:
2144          "A tag cannot be less than {0} characters long",
2145        lessThanMinCharsErrorTitle: "Tag Length Not Reached",
2146        moreThanMaxCharsErrorText:
2147          "A tag cannot be more than {0} characters long",
2148        moreThanMaxCharsErrorTitle: "Tag Length Exceeded",
2149        moreThanMaxTagsErrorText: "A maximum of {0} tags can be attached here",
2150        moreThanMaxTagsErrorTitle: "Tags limit exceeded",
2151        onErrorLessThanMinChars: function () {
2152          // can be customised by module dev
2153          $.dnnAlert({
2154            text: String.format(
2155              settings.lessThanMinCharsErrorText,
2156              settings.minChars,
2157            ),
2158            title: settings.lessThanMinCharsErrorTitle,
2159          });
2160        },
2161        onErrorMoreThanMaxChars: function () {
2162          // can be customised by module dev
2163          $.dnnAlert({
2164            text: String.format(
2165              settings.moreThanMaxCharsErrorText,
2166              settings.maxChars,
2167            ),
2168            title: settings.moreThanMaxCharsErrorTitle,
2169          });
2170        },
2171        onErrorMoreThanMaxTags: function () {
2172          // can be customised by module dev
2173          $.dnnAlert({
2174            text: String.format(
2175              settings.moreThanMaxTagsErrorText,
2176              settings.maxTags,
2177            ),
2178            title: settings.moreThanMaxTagsErrorTitle,
2179          });
2180        },
2181
2182        width: "45%",
2183        autocomplete: { selectFirst: false },
2184        hide: true,
2185        delimiter: ",",
2186        unique: true,
2187        removeWithBackspace: true,
2188        placeholderColor: "#999",
2189        normalColor: "#666",
2190        autosize: true,
2191        comfortZone: 20,
2192        inputPadding: 6 * 2,
2193      },
2194      options,
2195    );
2196
2197    this.each(function () {
2198      var instance = $(this).data("dnnTagInput");
2199      if (instance) return this;
2200      if (settings.hide) {
2201        $(this).hide();
2202      }
2203      var id = $(this).attr("id");
2204      if (!id || delimiter[$(this).attr("id")]) {
2205        id = $(this)
2206          .attr("id", "tags" + new Date().getTime())
2207          .attr("id");
2208      }
2209      var data = jQuery.extend(
2210        {
2211          pid: id,
2212          real_input: "#" + id,
2213          holder: "#" + id + "_tagsinput",
2214          input_wrapper: "#" + id + "_addTag",
2215          fake_input: "#" + id + "_tag",
2216        },
2217        settings,
2218      );
2219
2220      $(this).data("dnnTagInput", data);
2221
2222      delimiter[id] = data.delimiter;
2223
2224      if (settings.onAddTag || settings.onRemoveTag || settings.onChange) {
2225        tagsCallbacks[id] = new Array();
2226        tagsCallbacks[id]["onAddTag"] = settings.onAddTag;
2227        tagsCallbacks[id]["onRemoveTag"] = settings.onRemoveTag;
2228        tagsCallbacks[id]["onChange"] = settings.onChange;
2229      }
2230
2231      var markup = '<div id="' + id + '_tagsinput" class="dnnTagsInput">';
2232      markup += '<div id="' + id + '_addTag">';
2233
2234      if (settings.interactive) {
2235        markup +=
2236          '<input id="' +
2237          id +
2238          '_tag" value="" data-default="' +
2239          settings.defaultText +
2240          '" autocomplete="off" aria-label="Search" />';
2241      }
2242
2243      markup += "</div>";
2244      markup = markup + '<div class="dnnTagsClear"></div></div>';
2245
2246      $(markup).insertAfter(this);
2247
2248      $(data.holder).css({
2249        width: settings.width,
2250        "min-height": settings.height,
2251      });
2252
2253      $(data.fake_input).attr("maxlength", settings.maxChars);
2254
2255      if ($(data.real_input).val() != "") {
2256        $.fn.dnnTagsInput.importTags(
2257          $(data.real_input),
2258          $(data.real_input).val(),
2259        );
2260      }
2261      if (settings.interactive) {
2262        // placeholder stuff
2263        $(data.fake_input).dnnPlaceholder({
2264          color: [settings.normalColor, settings.placeholderColor],
2265        });
2266
2267        $(data.fake_input).dnnResetAutosize(settings);
2268        $(data.holder).on("click", data, function (event) {
2269          $(event.data.real_input).triggerHandler("focus");
2270          $(event.data.fake_input).triggerHandler("focus");
2271          return false;
2272        });
2273        if (settings.autocomplete_url != undefined) {
2274          if ($.dnnAutocompleter !== undefined) {
2275            if (settings.advanced && settings.advanced.length) {
2276              settings.autocomplete.advanced = settings.advanced;
2277            }
2278
2279            $(data.fake_input).dnnAutocomplete(
2280              settings.autocomplete_url,
2281              settings.autocomplete,
2282            );
2283            $(data.fake_input).on("result", data, function (event, tag) {
2284              if (tag) {
2285                var tagslist = $(event.data.real_input)
2286                  .val()
2287                  .split(delimiter[id]);
2288                if (tagslist[0] == "") {
2289                  tagslist = new Array();
2290                }
2291                if (event.data.maxTags <= tagslist.length) {
2292                  if (event.data.onErrorMoreThanMaxTags)
2293                    triggerOnError(event.data.onErrorMoreThanMaxTags);
2294                  $(data.fake_input).val("");
2295                } else
2296                  $(event.data.real_input).dnnAddTag(tag, {
2297                    focus: true,
2298                    unique: settings.unique,
2299                  });
2300              }
2301            });
2302          }
2303        } else {
2304          // if a user tabs out of the field, create a new tag
2305          // this is only available if autocomplete is not used.
2306          $(data.fake_input).on("blur", data, function (event) {
2307            var d = $(this).attr("data-default");
2308            var tagslist = $(event.data.real_input).val().split(delimiter[id]);
2309            if (tagslist[0] == "") {
2310              tagslist = new Array();
2311            }
2312            if (
2313              $(event.data.fake_input).val() != "" &&
2314              $(event.data.fake_input).val() != d
2315            ) {
2316              if (event.data.minChars > $(event.data.fake_input).val().length) {
2317                if (event.data.onErrorLessThanMinChars)
2318                  triggerOnError(event.data.onErrorLessThanMinChars);
2319                $(data.fake_input).val("");
2320              } else if (
2321                event.data.maxChars < $(event.data.fake_input).val().length
2322              ) {
2323                if (event.data.onErrorMoreThanMaxChars)
2324                  triggerOnError(event.data.onErrorMoreThanMaxChars);
2325                $(data.fake_input).val("");
2326              } else if (event.data.maxTags <= tagslist.length) {
2327                if (event.data.onErrorMoreThanMaxTags)
2328                  triggerOnError(event.data.onErrorMoreThanMaxTags);
2329                $(data.fake_input).val("");
2330              } else {
2331                var tags = $(event.data.fake_input).val().split(delimiter[id]);
2332                for (var i = 0; i < tags.length; i++) {
2333                  $(event.data.real_input).dnnAddTag(tags[i], {
2334                    focus: true,
2335                    unique: settings.unique,
2336                  });
2337                }
2338              }
2339              $(event.data.fake_input).dnnResetAutosize(settings);
2340            }
2341
2342            return false;
2343          });
2344        }
2345
2346        function tagItems(data, event) {
2347          var tagslist = $(event.data.real_input).val().split(delimiter[id]);
2348          if (tagslist[0] == "") {
2349            tagslist = new Array();
2350          }
2351          if (event.data.minChars > $(event.data.fake_input).val().length) {
2352            if (event.data.onErrorLessThanMinChars)
2353              triggerOnError(event.data.onErrorLessThanMinChars);
2354            $(data.fake_input).val("");
2355          } else if (
2356            event.data.maxChars < $(event.data.fake_input).val().length
2357          ) {
2358            if (event.data.onErrorMoreThanMaxChars)
2359              triggerOnError(event.data.onErrorMoreThanMaxChars);
2360            $(data.fake_input).val("");
2361          } else if (event.data.maxTags <= tagslist.length) {
2362            if (event.data.onErrorMoreThanMaxTags)
2363              triggerOnError(event.data.onErrorMoreThanMaxTags);
2364            $(data.fake_input).val("");
2365          } else {
2366            var tags = $(event.data.fake_input).val().split(delimiter[id]);
2367            for (var i = 0; i < tags.length; i++) {
2368              $(event.data.real_input).dnnAddTag(tags[i], {
2369                focus: true,
2370                unique: settings.unique,
2371              });
2372            }
2373          }
2374
2375          $(event.data.fake_input).dnnResetAutosize(settings);
2376          return false;
2377        }
2378
2379        var clickedOnAutoComplete = false;
2380
2381        $(document).mousedown(function (e) {
2382          if (
2383            $(e.target).hasClass("dnn_acSelect") ||
2384            $(e.target).parent().hasClass("dnn_acSelect")
2385          ) {
2386            clickedOnAutoComplete = true;
2387          }
2388        });
2389
2390        var tagTooLongErrMsg = $(
2391          '<span class="dnnFormError dnnFormMessage">' +
2392            String.format(
2393              settings.moreThanMaxCharsErrorText,
2394              settings.maxChars,
2395            ) +
2396            "</span>",
2397        );
2398        // if user types a comma, create a new tag
2399        $(data.fake_input).on("keypress keydown blur", data, function (event) {
2400          if ($(this).val() === "" || clickedOnAutoComplete) {
2401            return;
2402          }
2403          var currValLength = $(this).val().length;
2404          if (
2405            currValLength >= settings.maxChars &&
2406            !(
2407              event.which == event.data.delimiter.charCodeAt(0) ||
2408              event.which == 13 ||
2409              event.which == 9
2410            )
2411          ) {
2412            tagTooLongErrMsg
2413              .insertAfter($(this))
2414              .show()
2415              .delay(1500)
2416              .fadeOut(1000);
2417          }
2418          if (
2419            event.which == event.data.delimiter.charCodeAt(0) ||
2420            event.which == 13 ||
2421            event.which == 9 ||
2422            event.type == "blur"
2423          ) {
2424            event.preventDefault();
2425            if (!clickedOnAutoComplete) {
2426              tagItems(data, event);
2427            }
2428            clickedOnAutoComplete = false;
2429          } else if (event.data.autosize) {
2430            $(event.data.fake_input).dnnDoAutosize(settings);
2431          }
2432          return true;
2433        });
2434        //Delete last tag on backspace
2435        data.removeWithBackspace &&
2436          $(data.fake_input).on("keydown", function (event) {
2437            if (event.keyCode == 8 && $(this).val() == "") {
2438              event.preventDefault();
2439              var lastTag = $(this)
2440                .closest(".dnnTagsInput")
2441                .find(".tag:last")
2442                .text();
2443              var lastTagId = $(this).attr("id").replace(/_tag$/, "");
2444              lastTag = lastTag.replace(/[\s]+$/, "");
2445              $("#" + lastTagId).dnnRemoveTag(escape(lastTag));
2446              $(this).trigger("focus");
2447            }
2448          });
2449        $(data.fake_input).blur();
2450
2451        //Removes the not_valid class when user changes the value of the fake input
2452        if (data.unique) {
2453          $(data.fake_input).keydown(function (event) {
2454            if (
2455              event.keyCode == 8 ||
2456              String.fromCharCode(event.which).match(/\w+|[áéíóúÁÉÍÓÚñÑ,/]+/)
2457            ) {
2458              $(this).removeClass("dnnTagsInvalid");
2459            }
2460          });
2461        }
2462      } // if settings.interactive
2463      return this;
2464    });
2465    return this;
2466  };
2467
2468  $.fn.dnnTagsInput.updateTagsField = function (obj, tagslist) {
2469    var id = $(obj).attr("id");
2470    $(obj).val(tagslist.join(delimiter[id]));
2471  };
2472
2473  $.fn.dnnTagsInput.importTags = function (obj, val) {
2474    $(obj).val("");
2475    var id = $(obj).attr("id");
2476    var tags = val.split(delimiter[id]);
2477    for (var i = 0; i < tags.length; i++) {
2478      $(obj).dnnAddTag(tags[i], { focus: false, callback: false });
2479    }
2480    if (tagsCallbacks[id] && tagsCallbacks[id]["onChange"]) {
2481      var f = tagsCallbacks[id]["onChange"];
2482      f.call(obj, obj, tags[i]);
2483    }
2484  };
2485
2486  $.fn.dnnPlaceholder = function (options) {
2487    options = $.extend(
2488      {},
2489      {
2490        cssClass: "dnnPlaceholder",
2491        color: [],
2492      },
2493      options,
2494    );
2495
2496    this.each(function () {
2497      var $this = $(this);
2498      var instance = $this.data("dnnPlaceHolder");
2499      if (instance) return true;
2500      $this.data("dnnPlaceHolder", true);
2501
2502      var placeholderSupported = "placeholder" in $this[0];
2503      if (placeholderSupported)
2504        $this.attr("placeholder", $this.attr("data-default"));
2505      else {
2506        var $fakeInput = $('<input type="text" />')
2507          .attr("class", $this.attr("class"))
2508          .attr("style", $this.attr("style"))
2509          .val($this.attr("data-default"));
2510
2511        $this.hide().after($fakeInput);
2512        if (options.color.length === 2) {
2513          $fakeInput.css("color", options.color[1]);
2514          $this.css("color", options.color[0]);
2515        } else {
2516          $fakeInput.addClass(options.cssClass);
2517        }
2518
2519        $fakeInput.on("focus", function (event) {
2520          $fakeInput.hide();
2521          $this.show().focus();
2522        });
2523
2524        $this.on("blur", function (event) {
2525          var d = $this.attr("data-default");
2526          if ($this.val() === "") {
2527            $this.hide();
2528            $fakeInput.show();
2529          }
2530        });
2531
2532        var events = $._data(this, "events")["blur"];
2533        var first = events.pop();
2534        events.splice(0, 0, first);
2535      }
2536
2537      return true;
2538    });
2539
2540    return this;
2541  };
2542})(jQuery);
2543
2544(function ($) {
2545  // dnnForm customised client side validation
2546  $.fn.toggleErrorMessage = function (options) {
2547    var defaultOptions = {
2548      errorMessage: "Error message",
2549      errorCls: "dnnFormError",
2550      show: true,
2551      removeErrorMessage: true,
2552    };
2553
2554    options = $.extend(defaultOptions, options);
2555
2556    return this.each(function () {
2557      var dnnFormItem = $(this).closest(".dnnFormItem");
2558      if (options.show) {
2559        var errorSpan = dnnFormItem.find(
2560          "span.dnnFormMessage." + options.errorCls,
2561        );
2562        if (errorSpan.length) {
2563          errorSpan.html(options.errorMessage);
2564        } else {
2565          errorSpan = $(
2566            '<span class="dnnFormMessage ' +
2567              options.errorCls +
2568              '">' +
2569              options.errorMessage +
2570              "</span>",
2571          );
2572          dnnFormItem.append(errorSpan);
2573        }
2574
2575        if (this.tagName.toLowerCase() == "div") {
2576          // customised controls
2577          if ($(this).hasClass("RadComboBox")) {
2578            // RadComboBox
2579            $(this).addClass("dnnError");
2580          }
2581        } else {
2582          if ($(this).parent().hasClass("RadPicker")) {
2583            // RadDate Picker
2584            $(this)
2585              .parent()
2586              .find("input.riTextBox")
2587              .css("border", "1px solid red");
2588          } else if ($(this).hasClass("dnnSpinnerInput")) {
2589            // Spinner
2590            $(this).parent().css("border", "1px solid red");
2591          } else {
2592            // normal ctrl
2593            $(this).css("border", "1px solid red");
2594          }
2595        }
2596      } else {
2597        if (options.removeErrorMessage)
2598          dnnFormItem.find("span." + options.errorCls).remove();
2599        else dnnFormItem.find("span." + options.errorCls).hide();
2600
2601        if (this.tagName.toLowerCase() == "div") {
2602          // customised controls
2603          if ($(this).hasClass("RadComboBox")) {
2604            // RadComboBox
2605            $(this).removeClass("dnnError");
2606          }
2607        } else {
2608          if ($(this).hasClass("dnnSpinnerInput")) {
2609            // Spinner
2610            $(this).parent().css("border", "1px solid #ccc");
2611          } else {
2612            // normal ctrl
2613            $(this).css("border", "1px solid #ccc");
2614          }
2615        }
2616      }
2617    });
2618  };
2619  $.fn.dnnFormSubmit = function (options) {
2620    var defaultOptions = {
2621      validates: [],
2622    };
2623
2624    options = $.extend(defaultOptions, options);
2625
2626    return this.each(function () {
2627      $(this).click(function () {
2628        var formValidate = true;
2629        for (var i = 0; i < options.validates.length; i++) {
2630          var ele = $("#" + options.validates[i].ele);
2631          var func = options.validates[i].func;
2632          if (ele.length) {
2633            var eleVal = ele.val();
2634            var eleError = func.call(ele.get(0), eleVal);
2635            if (eleError) {
2636              ele.toggleErrorMessage({ errorMessage: eleError, show: true });
2637              formValidate = false;
2638            } else {
2639              ele.toggleErrorMessage({ show: false });
2640            }
2641
2642            //ele focus then remove error info
2643            var hideErrorInfo = function () {
2644              $(this).toggleErrorMessage({ show: false });
2645            };
2646
2647            ele.off("focus", hideErrorInfo).on("focus", hideErrorInfo);
2648          }
2649        }
2650
2651        return formValidate;
2652      });
2653    });
2654  };
2655
2656  // fix telerik custom datepicker popup arrow position
2657  $.dnnRadPickerHack = function () {
2658    //when click this icon, hide error info
2659    var hideErrorInfo = function () {
2660      $(this).toggleErrorMessage({ show: false, removeErrorMessage: false });
2661    };
2662    var dnnRadPickerPopupFix = function () {
2663      if ($.support.cssFloat) {
2664        var id = $(this).attr("id");
2665        var popupId = id.replace("popupButton", "calendar_wrapper");
2666        var popupElement = $("#" + popupId);
2667        var wrapperId = id.replace("popupButton", "wrapper");
2668        var wrapperElement = $("#" + wrapperId);
2669
2670        var popupElementTop = popupElement.parent().position().top;
2671        var wrapperElementTop = wrapperElement.offset().top;
2672        var popupTbl = popupElement.find(".RadCalendar_Default");
2673        var nextEle = popupTbl.next();
2674        if (
2675          nextEle.hasClass("RadCalendar_Default_PopupArrow_Down") ||
2676          nextEle.hasClass("RadCalendar_Default_PopupArrow_Up")
2677        )
2678          nextEle.remove();
2679
2680        if (popupElementTop < wrapperElementTop) {
2681          // popup above the calendar ctrl, so show arrow down
2682          popupTbl.after(
2683            '<div class="RadCalendar_Default_PopupArrow_Down"></div>',
2684          );
2685        } else {
2686          // popup below the calendar ctrl, so show arrow up
2687          popupTbl.after(
2688            '<div class="RadCalendar_Default_PopupArrow_Up"></div>',
2689          );
2690        }
2691      }
2692
2693      $(this).toggleErrorMessage({ show: false, removeErrorMessage: false });
2694    };
2695    $(".RadPicker_Default a.rcCalPopup")
2696      .off("click", dnnRadPickerPopupFix)
2697      .on("click", dnnRadPickerPopupFix);
2698    $(".RadPicker_Default .riTextBox")
2699      .off("focus", hideErrorInfo)
2700      .on("focus", hideErrorInfo);
2701  };
2702
2703  // remove combobox inline style
2704  $.dnnComboBoxLoaded = function (sender) {
2705    if (sender.constructor.__typeName == "Telerik.Web.UI.RadComboBox") {
2706      $(sender._inputDomElement).closest(".RadComboBox").removeAttr("style");
2707    }
2708  };
2709
2710  //fix combobox hide error info
2711  $.dnnComboBoxHack = function (sender) {
2712    $(
2713      ("#" + sender._clientStateFieldID).replace("_ClientState", ""),
2714    ).toggleErrorMessage({ show: false, removeErrorMessage: false });
2715  };
2716
2717  //fix combobox scroll
2718  $.dnnComboBoxScroll = function (sender) {
2719    if ($.support.cssFloat) {
2720      var container = $(
2721        ("#" + sender._clientStateFieldID + " .rcbScroll").replace(
2722          "ClientState",
2723          "DropDown",
2724        ),
2725      );
2726      if (container.data("scrollPane")) {
2727        container.data("scrollPane").data("jsp").reinitialise();
2728      } else {
2729        container.data("scrollPane", container.jScrollPane());
2730      }
2731    }
2732  };
2733
2734  $.dnnComboBoxItemRequested = function (sender) {
2735    setTimeout(function () {
2736      var container = $(
2737        ("#" + sender._clientStateFieldID + " .rcbScroll").replace(
2738          "ClientState",
2739          "DropDown",
2740        ),
2741      );
2742      if (container.data("scrollPane")) {
2743        container.data("scrollPane").data("jsp").reinitialise();
2744      }
2745    }, 0);
2746  };
2747
2748  // fix grid issues
2749  $.dnnGridCreated = function (sender) {
2750    var clientId = sender.ClientID;
2751    var $grid = $("#" + clientId);
2752    $("input.rgSortDesc, input.rgSortAsc", $grid).click(function () {
2753      var href = $(this).parent().find("a").get(0).href;
2754      window.location = href;
2755      return false;
2756    });
2757
2758    if ($grid.hasClass("dnnTooltipGrid")) {
2759      $grid.dnnHelperTipDestroy();
2760      $(".rgRow, .rgAltRow", $grid).each(function () {
2761        var info =
2762          "Here is some text will show up and explian more about this information";
2763        $(this).dnnHelperTip({ helpContent: info, holderId: clientId });
2764      });
2765    }
2766
2767    var grid = $find(clientId);
2768
2769    // while using customised checkbox - remove onclick event then attach onchange
2770    var headerCheck = $(".rgCheck", $grid);
2771    if (headerCheck.length) {
2772      headerCheck.each(function () {
2773        var checkbox = $(this).find('input[type="checkbox"]').get(0);
2774        var onclick = checkbox.onclick;
2775        checkbox.onchange = onclick;
2776        checkbox.onclick = null;
2777      });
2778
2779      // when use customised scrollbar and customised checkbox, the row cannot be correctly selected
2780      $('.rgDataDiv input[type="checkbox"]', $grid).change(function () {
2781        var masterTable = grid.get_masterTableView();
2782        var rowIndex = $(this).closest("tr").get(0).rowIndex;
2783        var checked = this.checked;
2784        if (checked) masterTable.selectItem(rowIndex);
2785        else masterTable.deselectItem(rowIndex);
2786      });
2787    }
2788
2789    // initialize dnnGrid customised scrollbar
2790    $(".rgDataDiv").each(function () {
2791      var $this = $(this);
2792      var ele = $this.get(0);
2793      ele.scrollPane = $this.jScrollPane();
2794      var api = ele.scrollPane.data("jsp");
2795      var throttleTimeout;
2796      $(window).on("resize", function () {
2797        if (!$.support.cssFloat) {
2798          if (throttleTimeout) {
2799            clearTimeout(throttleTimeout);
2800            throttleTimeout = null;
2801          }
2802          throttleTimeout = setTimeout(function () {
2803            api.reinitialise();
2804            throttleTimeout = null;
2805          }, 50);
2806        } else {
2807          api.reinitialise();
2808        }
2809      });
2810      if (
2811        window.__rgDataDivScrollTopPersistArray &&
2812        window.__rgDataDivScrollTopPersistArray.length
2813      ) {
2814        var y = window.__rgDataDivScrollTopPersistArray.pop();
2815        api.scrollToY(y);
2816      }
2817    });
2818  };
2819})(jQuery);
2820
2821(function ($) {
2822  var types = ["DOMMouseScroll", "mousewheel"];
2823  if ($.event.fixHooks) {
2824    for (var i = types.length; i; ) {
2825      $.event.fixHooks[types[--i]] = $.event.mouseHooks;
2826    }
2827  }
2828  $.event.special.mousewheel = {
2829    setup: function () {
2830      if (this.addEventListener) {
2831        for (var i = types.length; i; ) {
2832          this.addEventListener(types[--i], handler, false);
2833        }
2834      } else {
2835        this.onmousewheel = handler;
2836      }
2837    },
2838
2839    teardown: function () {
2840      if (this.removeEventListener) {
2841        for (var i = types.length; i; ) {
2842          this.removeEventListener(types[--i], handler, false);
2843        }
2844      } else {
2845        this.onmousewheel = null;
2846      }
2847    },
2848  };
2849
2850  $.fn.extend({
2851    mousewheel: function (fn) {
2852      return fn ? this.on("mousewheel", fn) : this.trigger("mousewheel");
2853    },
2854
2855    unmousewheel: function (fn) {
2856      return this.off("mousewheel", fn);
2857    },
2858  });
2859
2860  function handler(event) {
2861    var orgEvent = event || window.event,
2862      args = [].slice.call(arguments, 1),
2863      delta = 0,
2864      deltaX = 0,
2865      deltaY = 0;
2866    event = $.event.fix(orgEvent);
2867    event.type = "mousewheel";
2868
2869    // Old school scrollwheel delta
2870    if (orgEvent.wheelDelta) {
2871      delta = orgEvent.wheelDelta / 120;
2872    }
2873    if (orgEvent.detail) {
2874      delta = -orgEvent.detail / 3;
2875    }
2876
2877    // New school multidimensional scroll (touchpads) deltas
2878    deltaY = delta;
2879
2880    // Gecko
2881    if (
2882      orgEvent.axis !== undefined &&
2883      orgEvent.axis === orgEvent.HORIZONTAL_AXIS
2884    ) {
2885      deltaY = 0;
2886      deltaX = -1 * delta;
2887    }
2888
2889    // Webkit
2890    if (orgEvent.wheelDeltaY !== undefined) {
2891      deltaY = orgEvent.wheelDeltaY / 120;
2892    }
2893    if (orgEvent.wheelDeltaX !== undefined) {
2894      deltaX = (-1 * orgEvent.wheelDeltaX) / 120;
2895    }
2896
2897    // Add event and delta to the front of the arguments
2898    args.unshift(event, delta, deltaX, deltaY);
2899    return ($.event.dispatch || $.event.handle).apply(this, args);
2900  }
2901})(jQuery);
2902
2903(function ($) {
2904  $.fn.dnnFileInput = function (options) {
2905    var opts = $.extend({}, $.fn.dnnFileInput.defaultOptions, options);
2906
2907    return this.each(function () {
2908      var $ctrl = $(this);
2909      if ($ctrl.hasClass("normalFileUpload")) return;
2910
2911      if (this.wrapper) return;
2912
2913      //ignore decoration for elements in rad control.
2914      if ($ctrl.parents().hasClass("RadUpload")) return;
2915
2916      // if this.wrapper is undefined, then we check if parent node is a wrapper
2917      if (
2918        this.parentNode &&
2919        this.parentNode.tagName.toLowerCase() == "span" &&
2920        $ctrl.parent().hasClass("dnnInputFileWrapper")
2921      ) {
2922        return;
2923      }
2924
2925      this.wrapper = $(
2926        "<span class='dnnInputFileWrapper " + opts.buttonClass + "'></span>",
2927      );
2928      var text = $ctrl.data("text");
2929      text = text || "Choose File";
2930      this.wrapper.text(text);
2931      $ctrl.wrap(this.wrapper);
2932      $ctrl.data("wrapper", $ctrl.parent());
2933
2934      if (opts.showSelectedFileNameAsButtonText) {
2935        $ctrl.change(function () {
2936          var val = $(this).val();
2937          if (val != "") {
2938            var lastIdx = val.lastIndexOf("\\") + 1;
2939            val = val.substring(lastIdx, val.length);
2940          } else {
2941            val = text;
2942          }
2943          $(this).data("wrapper").get(0).childNodes[0].nodeValue = val;
2944        });
2945      }
2946    });
2947  };
2948
2949  $.fn.dnnFileInput.defaultOptions = {
2950    buttonClass: "dnnSecondaryAction",
2951    showSelectedFileNameAsButtonText: true,
2952  };
2953})(jQuery);
2954
2955(function ($) {
2956  var supportAjaxUpload = function () {
2957    var xhr = new XMLHttpRequest();
2958    return !!(xhr && "upload" in xhr && "onprogress" in xhr.upload);
2959  };
2960
2961  $.fn.dnnFileUpload = function (settings) {
2962    return this.each(function () {
2963      // set scope and settings, service
2964      var scope = $(this).attr("id");
2965      window.dnn.dnnFileUpload.setSettings(scope, settings);
2966      var service = $.dnnSF();
2967
2968      // hide progress
2969      $("#" + settings.progressBarId)
2970        .parent()
2971        .hide();
2972      // detect draggable support or not
2973      var droppableSpan = $("#" + settings.dropZoneId + ">span");
2974      if ("draggable" in document.createElement("span")) {
2975        droppableSpan.show();
2976      } else {
2977        droppableSpan.hide();
2978      }
2979
2980      // set file upload
2981      var url =
2982        service.getServiceRoot("internalservices") + "fileupload/postfile";
2983      if (!supportAjaxUpload()) {
2984        var antiForgeryToken = $(
2985          'input[name="__RequestVerificationToken"]',
2986        ).val();
2987        url += "?__RequestVerificationToken=" + antiForgeryToken;
2988      }
2989
2990      $("#" + scope + ' input[type="file"]').fileupload({
2991        url: url,
2992        beforeSend: service.setModuleHeaders,
2993        dropZone: $("#" + settings.dropZoneId),
2994        pasteZone: null,
2995        replaceFileInput: false,
2996        submit: function (e, data) {
2997          data.formData = {
2998            folder: settings.folder,
2999            filter: settings.fileFilter,
3000            overwrite: "true",
3001          };
3002          return true;
3003        },
3004        progressall: function (e, data) {
3005          var progress = parseInt((data.loaded / data.total) * 100, 10);
3006          if (progress < 100) {
3007            $("#" + settings.progressBarId)
3008              .parent()
3009              .show();
3010            $("#" + settings.progressBarId + ">div").css(
3011              "width",
3012              progress + "%",
3013            );
3014          } else
3015            $("#" + settings.progressBarId)
3016              .parent()
3017              .hide();
3018        },
3019        done: function (e, data) {
3020          $("#" + settings.progressBarId)
3021            .parent()
3022            .hide();
3023          var img = new Image();
3024          $(img).on("load", function () {
3025            $("#" + settings.dropZoneId + " img").remove();
3026            $(img)
3027              .css({ "max-width": 180, "max-height": 150 })
3028              .insertBefore($("#" + settings.dropZoneId + " span"));
3029          });
3030          var src;
3031          if (
3032            data.dataType &&
3033            typeof data.result == "object" &&
3034            data.result.length
3035          ) {
3036            data.result = JSON.parse(data.result.text());
3037          } else {
3038            data.result = JSON.parse(data.result);
3039          }
3040          var testContent = $("<pre>" + data.result.FilePath + "</pre>");
3041          if (testContent.length) {
3042            src = testContent.text();
3043          } else src = data.result;
3044
3045          if (src && $.trim(src)) {
3046            var profileImagePath =
3047              dnn.getVar("sf_siteRoot", "/") +
3048              "DnnImageHandler.ashx?mode=securefile&fileId=" +
3049              data.result.FileId +
3050              "&MaxWidth=180&MaxHeight=150";
3051            img.src = profileImagePath;
3052
3053            var fileName = data.result.FilePath.replace("\\", "/");
3054            if (fileName.indexOf("/") > -1) {
3055              fileName = fileName.split("/")[fileName.split("/").length - 1];
3056            }
3057            if (fileName.indexOf("?") > -1) {
3058              fileName = fileName.split("?")[0];
3059            }
3060
3061            dnn[settings.filesComboId].refresh(
3062              dnn[settings.foldersComboId].selectedItem().key,
3063            );
3064            dnn[settings.filesComboId].selectedItem({
3065              key: data.result.FileId,
3066              value: fileName,
3067            });
3068          }
3069        },
3070        fail: function (e, data) {
3071          $("#" + settings.progressBarId)
3072            .parent()
3073            .hide();
3074          var resp = JSON.parse(data.jqXHR.responseText);
3075          alert(resp.Message);
3076        },
3077      });
3078
3079      $("#" + scope + " input[name=uploadFileButton]").click(function () {
3080        var instance = dnn[settings.fileUploadId];
3081
3082        var options = instance.options;
3083        if (dnn[settings.foldersComboId].selectedItem() != null) {
3084          instance.options.folderPicker.initialState.selectedItem =
3085            dnn[settings.foldersComboId].selectedItem();
3086          instance.options.folderPath =
3087            window.dnn.dnnFileUpload.getSelectedPath(
3088              dnn[settings.foldersComboId],
3089            );
3090        }
3091
3092        instance.show(options);
3093
3094        window.dnn.dnnFileUpload.updateExpandPath(
3095          dnn[settings.foldersComboId],
3096          instance._panel._folderPicker.id(),
3097        );
3098
3099        instance._panel.$element.on(
3100          "onfileuploadcomplete",
3101          function (event, data) {
3102            if (typeof data == "string") {
3103              // for modern browsers
3104              data = JSON.parse(data);
3105            } else {
3106              // for IE8-9
3107              var b = data[0];
3108              data = JSON.parse(b.body.innerText);
3109            }
3110            if (data && data.fileId) {
3111              var folderPicker = instance._panel._folderPicker;
3112              dnn[settings.foldersComboId].selectedItem(
3113                folderPicker.selectedItem(),
3114              );
3115              window.dnn.dnnFileUpload.Folders_Changed(
3116                dnn[settings.foldersComboId].selectedItem(),
3117                dnn[settings.foldersComboId].$element,
3118              );
3119              window.dnn.dnnFileUpload.updateExpandPath(
3120                folderPicker,
3121                settings.foldersComboId,
3122              );
3123
3124              dnn[settings.filesComboId].refresh(
3125                dnn[settings.foldersComboId].selectedItem().key,
3126              );
3127              dnn[settings.filesComboId].selectedItem({
3128                key: data.fileId.toString(),
3129                value: data.fileName,
3130              });
3131              window.dnn.dnnFileUpload.Files_Changed(
3132                dnn[settings.filesComboId].selectedItem(),
3133                dnn[settings.filesComboId].$element,
3134              );
3135            }
3136          },
3137        );
3138      });
3139
3140      // set initial thumb image
3141      setTimeout(function () {
3142        dnn[settings.filesComboId].options.services.parameters.parentId =
3143          settings.selectedFolderId;
3144        var filesCombo = dnn[settings.filesComboId];
3145        var selectedFileId = filesCombo.selectedItem()
3146          ? filesCombo.selectedItem().key
3147          : null;
3148        var fileId = selectedFileId ? parseInt(selectedFileId) : 0;
3149        if (fileId > 0) {
3150          var maxWidth = 180,
3151            maxHeight = 150;
3152          var profileImagePath =
3153            dnn.getVar("sf_siteRoot", "/") +
3154            "DnnImageHandler.ashx?mode=securefile&fileId=" +
3155            fileId +
3156            "&MaxWidth=" +
3157            maxWidth +
3158            "&MaxHeight=" +
3159            maxHeight;
3160          var img = new Image();
3161
3162          $(img).on("load", function () {
3163            $("#" + settings.dropZoneId + " img").remove();
3164            $(img)
3165              .css({ "max-width": maxWidth, "max-height": maxHeight })
3166              .insertBefore($("#" + settings.dropZoneId + " span"));
3167          });
3168          img.src = profileImagePath;
3169        }
3170      }, 500);
3171    });
3172  };
3173
3174  if (typeof window.dnn === "undefined") window.dnn = {};
3175  window.dnn.dnnFileUpload = window.dnn.dnnFileUpload || {};
3176  window.dnn.dnnFileUpload.settings = {};
3177  window.dnn.dnnFileUpload.setSettings = function (scope, settings) {
3178    window.dnn.dnnFileUpload.settings[scope] = settings;
3179  };
3180  window.dnn.dnnFileUpload.getSettings = function (sender) {
3181    var scope = sender.closest(".dnnFileUploadScope").attr("id");
3182    return window.dnn.dnnFileUpload.settings[scope];
3183  };
3184  window.dnn.dnnFileUpload.Folders_Changed = function (node, sender) {
3185    var settings = window.dnn.dnnFileUpload.getSettings(sender);
3186    if (!settings) return false;
3187
3188    if (node) {
3189      //get the selected folder path
3190      var selectedPathArray = dnn[settings.foldersComboId].selectedPath();
3191      if (selectedPathArray.length === 0 && settings.folder) {
3192        return settings.folder;
3193      }
3194      var selectedPath = "";
3195      if (selectedPathArray.length > 1) {
3196        for (var i = 1, size = selectedPathArray.length; i < size; i++) {
3197          selectedPath += selectedPathArray[i].name + "/";
3198        }
3199      }
3200      settings.folder = selectedPath;
3201
3202      dnn[settings.filesComboId].refresh(node.key);
3203      dnn[settings.filesComboId].selectedItem(null);
3204      window.dnn.dnnFileUpload.Files_Changed(
3205        { key: null },
3206        $("#" + settings.filesComboId),
3207      );
3208    }
3209  };
3210  window.dnn.dnnFileUpload.Files_Changed = function (node, sender) {
3211    var settings = window.dnn.dnnFileUpload.getSettings(sender);
3212    if (!settings) return;
3213
3214    if (node) {
3215      var fileId = node.key;
3216      if (fileId) {
3217        var maxWidth = 180,
3218          maxHeight = 150;
3219        var profileImagePath =
3220          dnn.getVar("sf_siteRoot", "/") +
3221          "DnnImageHandler.ashx?mode=securefile&fileId=" +
3222          fileId +
3223          "&MaxWidth=" +
3224          maxWidth +
3225          "&MaxHeight=" +
3226          maxHeight;
3227        var img = new Image();
3228
3229        $(img).on("load", function () {
3230          $("#" + settings.dropZoneId + " img").remove();
3231          $(img)
3232            .css({ "max-width": maxWidth, "max-height": maxHeight })
3233            .insertBefore($("#" + settings.dropZoneId + " span"));
3234        });
3235        img.src = profileImagePath;
3236      } else $("#" + settings.dropZoneId + " img").remove();
3237    }
3238  };
3239  window.dnn.dnnFileUpload.updateExpandPath = function (
3240    dropDownList,
3241    targetId,
3242  ) {
3243    //set expand path
3244    var selectedPaths = dropDownList.selectedPath();
3245    var expandPath = "";
3246    if (selectedPaths.length == 0) {
3247      //which means the tree view hasn't opened.
3248      expandPath = dnn.getVar(dropDownList.id() + "_expandPath");
3249    } else if (selectedPaths.length > 1) {
3250      for (var i = 0; i < selectedPaths.length - 1; i++) {
3251        if (expandPath == "") {
3252          expandPath = selectedPaths[i].id;
3253        } else {
3254          expandPath = expandPath + "," + selectedPaths[i].id;
3255        }
3256      }
3257    }
3258
3259    if (expandPath != "") {
3260      dnn.setVar(targetId + "_expandPath", expandPath);
3261    }
3262  };
3263  window.dnn.dnnFileUpload.getSelectedPath = function (dropDownList) {
3264    var selectedPathArray = dropDownList.selectedPath();
3265    var settings = window.dnn.dnnFileUpload.getSettings(dropDownList.$element);
3266    if (selectedPathArray.length === 0 && settings.folder) {
3267      return settings.folder;
3268    }
3269    var selectedPath = "";
3270    if (selectedPathArray.length > 1) {
3271      for (var i = 1, size = selectedPathArray.length; i < size; i++) {
3272        selectedPath += selectedPathArray[i].name + "/";
3273      }
3274    }
3275    return selectedPath;
3276  };
3277})(jQuery);
3278
3279(function ($) {
3280  /* BELOW jscrollPane code */
3281  $.fn.jScrollPane = function (settings) {
3282    // JScrollPane "class" - public methods are available through $('selector').data('jsp')
3283    function JScrollPane(elem, s) {
3284      var settings,
3285        jsp = this,
3286        pane,
3287        paneWidth,
3288        paneHeight,
3289        container,
3290        contentWidth,
3291        contentHeight,
3292        percentInViewH,
3293        percentInViewV,
3294        isScrollableV,
3295        isScrollableH,
3296        verticalDrag,
3297        dragMaxY,
3298        verticalDragPosition,
3299        horizontalDrag,
3300        dragMaxX,
3301        horizontalDragPosition,
3302        verticalBar,
3303        verticalTrack,
3304        scrollbarWidth,
3305        verticalTrackHeight,
3306        verticalDragHeight,
3307        arrowUp,
3308        arrowDown,
3309        horizontalBar,
3310        horizontalTrack,
3311        horizontalTrackWidth,
3312        horizontalDragWidth,
3313        arrowLeft,
3314        arrowRight,
3315        reinitialiseInterval,
3316        originalPadding,
3317        originalPaddingTotalWidth,
3318        previousContentWidth,
3319        wasAtTop = true,
3320        wasAtLeft = true,
3321        wasAtBottom = false,
3322        wasAtRight = false,
3323        originalElement = elem.clone(false, false).empty(),
3324        mwEvent = $.fn.mwheelIntent ? "mwheelIntent.jsp" : "mousewheel.jsp";
3325
3326      originalPadding =
3327        elem.css("paddingTop") +
3328        " " +
3329        elem.css("paddingRight") +
3330        " " +
3331        elem.css("paddingBottom") +
3332        " " +
3333        elem.css("paddingLeft");
3334      originalPaddingTotalWidth =
3335        (parseInt(elem.css("paddingLeft"), 10) || 0) +
3336        (parseInt(elem.css("paddingRight"), 10) || 0);
3337
3338      function initialise(s) {
3339        var /*firstChild, lastChild, */ isMaintainingPositon,
3340          lastContentX,
3341          lastContentY,
3342          hasContainingSpaceChanged,
3343          originalScrollTop,
3344          originalScrollLeft,
3345          maintainAtBottom = false,
3346          maintainAtRight = false;
3347
3348        settings = s;
3349
3350        if (pane === undefined) {
3351          originalScrollTop = elem.scrollTop();
3352          originalScrollLeft = elem.scrollLeft();
3353
3354          elem.css({
3355            overflow: "hidden",
3356            padding: 0,
3357          });
3358          // TODO: Deal with where width/ height is 0 as it probably means the element is hidden and we should
3359          // come back to it later and check once it is unhidden...
3360          paneWidth = elem.innerWidth() + originalPaddingTotalWidth;
3361          paneHeight = elem.innerHeight();
3362
3363          elem.width(paneWidth);
3364
3365          pane = $('<div class="jspPane" />')
3366            .css("padding", originalPadding)
3367            .append(elem.children());
3368          container = $('<div class="jspContainer" />')
3369            .css({
3370              width: paneWidth + "px",
3371              height: paneHeight + "px",
3372            })
3373            .append(pane)
3374            .appendTo(elem);
3375
3376          /*
3377					// Move any margins from the first and last children up to the container so they can still
3378					// collapse with neighbouring elements as they would before jScrollPane 
3379					firstChild = pane.find(':first-child');
3380					lastChild = pane.find(':last-child');
3381					elem.css(
3382						{
3383							'margin-top': firstChild.css('margin-top'),
3384							'margin-bottom': lastChild.css('margin-bottom')
3385						}
3386					);
3387					firstChild.css('margin-top', 0);
3388					lastChild.css('margin-bottom', 0);
3389					*/
3390        } else {
3391          elem.css("width", "");
3392
3393          maintainAtBottom = settings.stickToBottom && isCloseToBottom();
3394          maintainAtRight = settings.stickToRight && isCloseToRight();
3395
3396          hasContainingSpaceChanged =
3397            elem.innerWidth() + originalPaddingTotalWidth != paneWidth ||
3398            elem.outerHeight() != paneHeight;
3399
3400          if (hasContainingSpaceChanged) {
3401            paneWidth = elem.innerWidth() + originalPaddingTotalWidth;
3402            paneHeight = elem.innerHeight();
3403            container.css({
3404              width: paneWidth + "px",
3405              height: paneHeight + "px",
3406            });
3407          }
3408
3409          // If nothing changed since last check...
3410          if (
3411            !hasContainingSpaceChanged &&
3412            previousContentWidth == contentWidth &&
3413            pane.outerHeight() == contentHeight
3414          ) {
3415            elem.width(paneWidth);
3416            return;
3417          }
3418          previousContentWidth = contentWidth;
3419
3420          pane.css("width", "");
3421          elem.width(paneWidth);
3422
3423          container.find(">.jspVerticalBar,>.jspHorizontalBar").remove().end();
3424        }
3425
3426        pane.css("overflow", "auto");
3427        if (s.contentWidth) {
3428          contentWidth = s.contentWidth;
3429        } else {
3430          contentWidth = pane[0].scrollWidth;
3431        }
3432        contentHeight = pane[0].scrollHeight;
3433        pane.css("overflow", "");
3434
3435        percentInViewH = contentWidth / paneWidth;
3436        percentInViewV = contentHeight / paneHeight;
3437        isScrollableV = percentInViewV > 1;
3438
3439        isScrollableH = percentInViewH > 1;
3440
3441        if (!(isScrollableH || isScrollableV)) {
3442          elem.removeClass("jspScrollable");
3443          pane.css({
3444            top: 0,
3445            width: container.width() - originalPaddingTotalWidth,
3446          });
3447          removeMousewheel();
3448          removeFocusHandler();
3449          removeKeyboardNav();
3450          removeClickOnTrack();
3451        } else {
3452          elem.addClass("jspScrollable");
3453
3454          isMaintainingPositon =
3455            settings.maintainPosition &&
3456            (verticalDragPosition || horizontalDragPosition);
3457          if (isMaintainingPositon) {
3458            lastContentX = contentPositionX();
3459            lastContentY = contentPositionY();
3460          }
3461
3462          initialiseVerticalScroll();
3463          initialiseHorizontalScroll();
3464          resizeScrollbars();
3465
3466          if (isMaintainingPositon) {
3467            scrollToX(
3468              maintainAtRight ? contentWidth - paneWidth : lastContentX,
3469              false,
3470            );
3471            scrollToY(
3472              maintainAtBottom ? contentHeight - paneHeight : lastContentY,
3473              false,
3474            );
3475          }
3476
3477          initFocusHandler();
3478          initMousewheel();
3479          initTouch();
3480
3481          if (settings.enableKeyboardNavigation) {
3482            initKeyboardNav();
3483          }
3484          if (settings.clickOnTrack) {
3485            initClickOnTrack();
3486          }
3487
3488          observeHash();
3489          if (settings.hijackInternalLinks) {
3490            hijackInternalLinks();
3491          }
3492        }
3493
3494        if (settings.autoReinitialise && !reinitialiseInterval) {
3495          reinitialiseInterval = setInterval(function () {
3496            initialise(settings);
3497          }, settings.autoReinitialiseDelay);
3498        } else if (!settings.autoReinitialise && reinitialiseInterval) {
3499          clearInterval(reinitialiseInterval);
3500        }
3501
3502        originalScrollTop &&
3503          elem.scrollTop(0) &&
3504          scrollToY(originalScrollTop, false);
3505        originalScrollLeft &&
3506          elem.scrollLeft(0) &&
3507          scrollToX(originalScrollLeft, false);
3508
3509        elem.trigger("jsp-initialised", [isScrollableH || isScrollableV]);
3510      }
3511
3512      function initialiseVerticalScroll() {
3513        if (isScrollableV) {
3514          container.append(
3515            $('<div class="jspVerticalBar" />').append(
3516              $('<div class="jspCap jspCapTop" />'),
3517              $('<div class="jspTrack" />').append(
3518                $('<div class="jspDrag" />').append(
3519                  $('<div class="jspDragTop" />'),
3520                  $('<div class="jspDragBottom" />'),
3521                ),
3522              ),
3523              $('<div class="jspCap jspCapBottom" />'),
3524            ),
3525          );
3526
3527          verticalBar = container.find(">.jspVerticalBar");
3528          verticalTrack = verticalBar.find(">.jspTrack");
3529          verticalDrag = verticalTrack.find(">.jspDrag");
3530
3531          if (settings.showArrows) {
3532            arrowUp = $('<a class="jspArrow jspArrowUp" />')
3533              .on("mousedown.jsp", getArrowScroll(0, -1))
3534              .on("click.jsp", nil);
3535            arrowDown = $('<a class="jspArrow jspArrowDown" />')
3536              .on("mousedown.jsp", getArrowScroll(0, 1))
3537              .on("click.jsp", nil);
3538            if (settings.arrowScrollOnHover) {
3539              arrowUp.on("mouseover.jsp", getArrowScroll(0, -1, arrowUp));
3540              arrowDown.on("mouseover.jsp", getArrowScroll(0, 1, arrowDown));
3541            }
3542
3543            appendArrows(
3544              verticalTrack,
3545              settings.verticalArrowPositions,
3546              arrowUp,
3547              arrowDown,
3548            );
3549          }
3550
3551          verticalTrackHeight = paneHeight;
3552          container
3553            .find(">.jspVerticalBar>.jspCap:visible,>.jspVerticalBar>.jspArrow")
3554            .each(function () {
3555              verticalTrackHeight -= $(this).outerHeight();
3556            });
3557
3558          verticalDrag
3559            .hover(
3560              function () {
3561                verticalDrag.addClass("jspHover");
3562              },
3563              function () {
3564                verticalDrag.removeClass("jspHover");
3565              },
3566            )
3567            .on("mousedown.jsp", function (e) {
3568              // Stop IE from allowing text selection
3569              $("html").on("dragstart.jsp selectstart.jsp", nil);
3570
3571              verticalDrag.addClass("jspActive");
3572
3573              var startY = e.pageY - verticalDrag.position().top;
3574
3575              $("html")
3576                .on("mousemove.jsp", function (e) {
3577                  positionDragY(e.pageY - startY, false);
3578                })
3579                .on("mouseup.jsp mouseleave.jsp", cancelDrag);
3580              return false;
3581            });
3582          sizeVerticalScrollbar();
3583        }
3584      }
3585
3586      function sizeVerticalScrollbar() {
3587        verticalTrack.height(verticalTrackHeight + "px");
3588        verticalDragPosition = 0;
3589        scrollbarWidth = settings.verticalGutter + verticalTrack.outerWidth();
3590
3591        // Make the pane thinner to allow for the vertical scrollbar
3592        pane.width(paneWidth - scrollbarWidth - originalPaddingTotalWidth);
3593
3594        // Add margin to the left of the pane if scrollbars are on that side (to position
3595        // the scrollbar on the left or right set it's left or right property in CSS)
3596        try {
3597          if (verticalBar.position().left === 0) {
3598            pane.css("margin-left", scrollbarWidth + "px");
3599          }
3600        } catch (err) {}
3601      }
3602
3603      function initialiseHorizontalScroll() {
3604        if (isScrollableH) {
3605          container.append(
3606            $('<div class="jspHorizontalBar" />').append(
3607              $('<div class="jspCap jspCapLeft" />'),
3608              $('<div class="jspTrack" />').append(
3609                $('<div class="jspDrag" />').append(
3610                  $('<div class="jspDragLeft" />'),
3611                  $('<div class="jspDragRight" />'),
3612                ),
3613              ),
3614              $('<div class="jspCap jspCapRight" />'),
3615            ),
3616          );
3617
3618          horizontalBar = container.find(">.jspHorizontalBar");
3619          horizontalTrack = horizontalBar.find(">.jspTrack");
3620          horizontalDrag = horizontalTrack.find(">.jspDrag");
3621
3622          if (settings.showArrows) {
3623            arrowLeft = $('<a class="jspArrow jspArrowLeft" />')
3624              .on("mousedown.jsp", getArrowScroll(-1, 0))
3625              .on("click.jsp", nil);
3626            arrowRight = $('<a class="jspArrow jspArrowRight" />')
3627              .on("mousedown.jsp", getArrowScroll(1, 0))
3628              .on("click.jsp", nil);
3629            if (settings.arrowScrollOnHover) {
3630              arrowLeft.on("mouseover.jsp", getArrowScroll(-1, 0, arrowLeft));
3631              arrowRight.on("mouseover.jsp", getArrowScroll(1, 0, arrowRight));
3632            }
3633            appendArrows(
3634              horizontalTrack,
3635              settings.horizontalArrowPositions,
3636              arrowLeft,
3637              arrowRight,
3638            );
3639          }
3640
3641          horizontalDrag
3642            .hover(
3643              function () {
3644                horizontalDrag.addClass("jspHover");
3645              },
3646              function () {
3647                horizontalDrag.removeClass("jspHover");
3648              },
3649            )
3650            .on("mousedown.jsp", function (e) {
3651              // Stop IE from allowing text selection
3652              $("html").on("dragstart.jsp selectstart.jsp", nil);
3653
3654              horizontalDrag.addClass("jspActive");
3655
3656              var startX = e.pageX - horizontalDrag.position().left;
3657
3658              $("html")
3659                .on("mousemove.jsp", function (e) {
3660                  positionDragX(e.pageX - startX, false);
3661                })
3662                .on("mouseup.jsp mouseleave.jsp", cancelDrag);
3663              return false;
3664            });
3665          horizontalTrackWidth = container.innerWidth();
3666          sizeHorizontalScrollbar();
3667        }
3668      }
3669
3670      function sizeHorizontalScrollbar() {
3671        container
3672          .find(
3673            ">.jspHorizontalBar>.jspCap:visible,>.jspHorizontalBar>.jspArrow",
3674          )
3675          .each(function () {
3676            horizontalTrackWidth -= $(this).outerWidth();
3677          });
3678
3679        horizontalTrack.width(horizontalTrackWidth + "px");
3680        horizontalDragPosition = 0;
3681      }
3682
3683      function resizeScrollbars() {
3684        if (isScrollableH && isScrollableV) {
3685          var horizontalTrackHeight = horizontalTrack.outerHeight(),
3686            verticalTrackWidth = verticalTrack.outerWidth();
3687          verticalTrackHeight -= horizontalTrackHeight;
3688          $(horizontalBar)
3689            .find(">.jspCap:visible,>.jspArrow")
3690            .each(function () {
3691              horizontalTrackWidth += $(this).outerWidth();
3692            });
3693          horizontalTrackWidth -= verticalTrackWidth;
3694          paneHeight -= verticalTrackWidth;
3695          paneWidth -= horizontalTrackHeight;
3696          horizontalTrack
3697            .parent()
3698            .append(
3699              $('<div class="jspCorner" />').css(
3700                "width",
3701                horizontalTrackHeight + "px",
3702              ),
3703            );
3704          sizeVerticalScrollbar();
3705          sizeHorizontalScrollbar();
3706        }
3707        // reflow content
3708        if (isScrollableH) {
3709          pane.width(container.outerWidth() - originalPaddingTotalWidth + "px");
3710        }
3711        contentHeight = pane.outerHeight();
3712        percentInViewV = contentHeight / paneHeight;
3713
3714        if (isScrollableH) {
3715          horizontalDragWidth = Math.ceil(
3716            (1 / percentInViewH) * horizontalTrackWidth,
3717          );
3718          if (horizontalDragWidth > settings.horizontalDragMaxWidth) {
3719            horizontalDragWidth = settings.horizontalDragMaxWidth;
3720          } else if (horizontalDragWidth < settings.horizontalDragMinWidth) {
3721            horizontalDragWidth = settings.horizontalDragMinWidth;
3722          }
3723          horizontalDrag.width(horizontalDragWidth + "px");
3724          dragMaxX = horizontalTrackWidth - horizontalDragWidth;
3725          _positionDragX(horizontalDragPosition); // To update the state for the arrow buttons
3726        }
3727        if (isScrollableV) {
3728          verticalDragHeight = Math.ceil(
3729            (1 / percentInViewV) * verticalTrackHeight,
3730          );
3731          if (verticalDragHeight > settings.verticalDragMaxHeight) {
3732            verticalDragHeight = settings.verticalDragMaxHeight;
3733          } else if (verticalDragHeight < settings.verticalDragMinHeight) {
3734            verticalDragHeight = settings.verticalDragMinHeight;
3735          }
3736          verticalDrag.height(verticalDragHeight + "px");
3737          dragMaxY = verticalTrackHeight - verticalDragHeight;
3738          _positionDragY(verticalDragPosition); // To update the state for the arrow buttons
3739        }
3740      }
3741
3742      function appendArrows(ele, p, a1, a2) {
3743        var p1 = "before",
3744          p2 = "after",
3745          aTemp;
3746
3747        // Sniff for mac... Is there a better way to determine whether the arrows would naturally appear
3748        // at the top or the bottom of the bar?
3749        if (p == "os") {
3750          p = /Mac/.test(navigator.platform) ? "after" : "split";
3751        }
3752        if (p == p1) {
3753          p2 = p;
3754        } else if (p == p2) {
3755          p1 = p;
3756          aTemp = a1;
3757          a1 = a2;
3758          a2 = aTemp;
3759        }
3760
3761        ele[p1](a1)[p2](a2);
3762      }
3763
3764      function getArrowScroll(dirX, dirY, ele) {
3765        return function () {
3766          arrowScroll(dirX, dirY, this, ele);
3767          this.blur();
3768          return false;
3769        };
3770      }
3771
3772      function arrowScroll(dirX, dirY, arrow, ele) {
3773        arrow = $(arrow).addClass("jspActive");
3774
3775        var eve,
3776          scrollTimeout,
3777          isFirst = true,
3778          doScroll = function () {
3779            if (dirX !== 0) {
3780              jsp.scrollByX(dirX * settings.arrowButtonSpeed);
3781            }
3782            if (dirY !== 0) {
3783              jsp.scrollByY(dirY * settings.arrowButtonSpeed);
3784            }
3785            scrollTimeout = setTimeout(
3786              doScroll,
3787              isFirst ? settings.initialDelay : settings.arrowRepeatFreq,
3788            );
3789            isFirst = false;
3790          };
3791
3792        doScroll();
3793
3794        eve = ele ? "mouseout.jsp" : "mouseup.jsp";
3795        ele = ele || $("html");
3796        ele.on(eve, function () {
3797          arrow.removeClass("jspActive");
3798          scrollTimeout && clearTimeout(scrollTimeout);
3799          scrollTimeout = null;
3800          ele.off(eve);
3801        });
3802      }
3803
3804      function initClickOnTrack() {
3805        removeClickOnTrack();
3806        if (isScrollableV) {
3807          verticalTrack.on("mousedown.jsp", function (e) {
3808            if (
3809              e.originalTarget === undefined ||
3810              e.originalTarget == e.currentTarget
3811            ) {
3812              var clickedTrack = $(this),
3813                offset = clickedTrack.offset(),
3814                direction = e.pageY - offset.top - verticalDragPosition,
3815                scrollTimeout,
3816                isFirst = true,
3817                doScroll = function () {
3818                  var offset = clickedTrack.offset(),
3819                    pos = e.pageY - offset.top - verticalDragHeight / 2,
3820                    contentDragY = paneHeight * settings.scrollPagePercent,
3821                    dragY =
3822                      (dragMaxY * contentDragY) / (contentHeight - paneHeight);
3823                  if (direction < 0) {
3824                    if (verticalDragPosition - dragY > pos) {
3825                      jsp.scrollByY(-contentDragY);
3826                    } else {
3827                      positionDragY(pos);
3828                    }
3829                  } else if (direction > 0) {
3830                    if (verticalDragPosition + dragY < pos) {
3831                      jsp.scrollByY(contentDragY);
3832                    } else {
3833                      positionDragY(pos);
3834                    }
3835                  } else {
3836                    cancelClick();
3837                    return;
3838                  }
3839                  scrollTimeout = setTimeout(
3840                    doScroll,
3841                    isFirst
3842                      ? settings.initialDelay
3843                      : settings.trackClickRepeatFreq,
3844                  );
3845                  isFirst = false;
3846                },
3847                cancelClick = function () {
3848                  scrollTimeout && clearTimeout(scrollTimeout);
3849                  scrollTimeout = null;
3850                  $(document).off("mouseup.jsp", cancelClick);
3851                };
3852              doScroll();
3853              $(document).on("mouseup.jsp", cancelClick);
3854              return false;
3855            }
3856          });
3857        }
3858
3859        if (isScrollableH) {
3860          horizontalTrack.on("mousedown.jsp", function (e) {
3861            if (
3862              e.originalTarget === undefined ||
3863              e.originalTarget == e.currentTarget
3864            ) {
3865              var clickedTrack = $(this),
3866                offset = clickedTrack.offset(),
3867                direction = e.pageX - offset.left - horizontalDragPosition,
3868                scrollTimeout,
3869                isFirst = true,
3870                doScroll = function () {
3871                  var offset = clickedTrack.offset(),
3872                    pos = e.pageX - offset.left - horizontalDragWidth / 2,
3873                    contentDragX = paneWidth * settings.scrollPagePercent,
3874                    dragX =
3875                      (dragMaxX * contentDragX) / (contentWidth - paneWidth);
3876                  if (direction < 0) {
3877                    if (horizontalDragPosition - dragX > pos) {
3878                      jsp.scrollByX(-contentDragX);
3879                    } else {
3880                      positionDragX(pos);
3881                    }
3882                  } else if (direction > 0) {
3883                    if (horizontalDragPosition + dragX < pos) {
3884                      jsp.scrollByX(contentDragX);
3885                    } else {
3886                      positionDragX(pos);
3887                    }
3888                  } else {
3889                    cancelClick();
3890                    return;
3891                  }
3892                  scrollTimeout = setTimeout(
3893                    doScroll,
3894                    isFirst
3895                      ? settings.initialDelay
3896                      : settings.trackClickRepeatFreq,
3897                  );
3898                  isFirst = false;
3899                },
3900                cancelClick = function () {
3901                  scrollTimeout && clearTimeout(scrollTimeout);
3902                  scrollTimeout = null;
3903                  $(document).off("mouseup.jsp", cancelClick);
3904                };
3905              doScroll();
3906              $(document).on("mouseup.jsp", cancelClick);
3907              return false;
3908            }
3909          });
3910        }
3911      }
3912
3913      function removeClickOnTrack() {
3914        if (horizontalTrack) {
3915          horizontalTrack.off("mousedown.jsp");
3916        }
3917        if (verticalTrack) {
3918          verticalTrack.off("mousedown.jsp");
3919        }
3920      }
3921
3922      function cancelDrag() {
3923        $("html").off(
3924          "dragstart.jsp selectstart.jsp mousemove.jsp mouseup.jsp mouseleave.jsp",
3925        );
3926
3927        if (verticalDrag) {
3928          verticalDrag.removeClass("jspActive");
3929        }
3930        if (horizontalDrag) {
3931          horizontalDrag.removeClass("jspActive");
3932        }
3933      }
3934
3935      function positionDragY(destY, animate) {
3936        if (!isScrollableV) {
3937          return;
3938        }
3939        if (destY < 0) {
3940          destY = 0;
3941        } else if (destY > dragMaxY) {
3942          destY = dragMaxY;
3943        }
3944
3945        // can't just check if(animate) because false is a valid value that could be passed in...
3946        if (animate === undefined) {
3947          animate = settings.animateScroll;
3948        }
3949        if (animate) {
3950          jsp.animate(verticalDrag, "top", destY, _positionDragY);
3951        } else {
3952          verticalDrag.css("top", destY);
3953          _positionDragY(destY);
3954        }
3955      }
3956
3957      function _positionDragY(destY) {
3958        if (destY === undefined) {
3959          destY = verticalDrag.position().top;
3960        }
3961
3962        container.scrollTop(0);
3963        verticalDragPosition = destY;
3964
3965        var isAtTop = verticalDragPosition === 0,
3966          isAtBottom = verticalDragPosition == dragMaxY,
3967          percentScrolled = destY / dragMaxY,
3968          destTop = -percentScrolled * (contentHeight - paneHeight);
3969
3970        if (wasAtTop != isAtTop || wasAtBottom != isAtBottom) {
3971          wasAtTop = isAtTop;
3972          wasAtBottom = isAtBottom;
3973          elem.trigger("jsp-arrow-change", [
3974            wasAtTop,
3975            wasAtBottom,
3976            wasAtLeft,
3977            wasAtRight,
3978          ]);
3979        }
3980
3981        updateVerticalArrows(isAtTop, isAtBottom);
3982        pane.css("top", destTop);
3983        elem
3984          .trigger("jsp-scroll-y", [-destTop, isAtTop, isAtBottom])
3985          .trigger("scroll");
3986      }
3987
3988      function positionDragX(destX, animate) {
3989        if (!isScrollableH) {
3990          return;
3991        }
3992        if (destX < 0) {
3993          destX = 0;
3994        } else if (destX > dragMaxX) {
3995          destX = dragMaxX;
3996        }
3997
3998        if (animate === undefined) {
3999          animate = settings.animateScroll;
4000        }
4001        if (animate) {
4002          jsp.animate(horizontalDrag, "left", destX, _positionDragX);
4003        } else {
4004          horizontalDrag.css("left", destX);
4005          _positionDragX(destX);
4006        }
4007      }
4008
4009      function _positionDragX(destX) {
4010        if (destX === undefined) {
4011          destX = horizontalDrag.position().left;
4012        }
4013
4014        container.scrollTop(0);
4015        horizontalDragPosition = destX;
4016
4017        var isAtLeft = horizontalDragPosition === 0,
4018          isAtRight = horizontalDragPosition == dragMaxX,
4019          percentScrolled = destX / dragMaxX,
4020          destLeft = -percentScrolled * (contentWidth - paneWidth);
4021
4022        if (wasAtLeft != isAtLeft || wasAtRight != isAtRight) {
4023          wasAtLeft = isAtLeft;
4024          wasAtRight = isAtRight;
4025          elem.trigger("jsp-arrow-change", [
4026            wasAtTop,
4027            wasAtBottom,
4028            wasAtLeft,
4029            wasAtRight,
4030          ]);
4031        }
4032
4033        updateHorizontalArrows(isAtLeft, isAtRight);
4034        pane.css("left", destLeft);
4035        elem
4036          .trigger("jsp-scroll-x", [-destLeft, isAtLeft, isAtRight])
4037          .trigger("scroll");
4038      }
4039
4040      function updateVerticalArrows(isAtTop, isAtBottom) {
4041        if (settings.showArrows) {
4042          arrowUp[isAtTop ? "addClass" : "removeClass"]("jspDisabled");
4043          arrowDown[isAtBottom ? "addClass" : "removeClass"]("jspDisabled");
4044        }
4045      }
4046
4047      function updateHorizontalArrows(isAtLeft, isAtRight) {
4048        if (settings.showArrows) {
4049          arrowLeft[isAtLeft ? "addClass" : "removeClass"]("jspDisabled");
4050          arrowRight[isAtRight ? "addClass" : "removeClass"]("jspDisabled");
4051        }
4052      }
4053
4054      function scrollToY(destY, animate) {
4055        var percentScrolled = destY / (contentHeight - paneHeight);
4056        positionDragY(percentScrolled * dragMaxY, animate);
4057      }
4058
4059      function scrollToX(destX, animate) {
4060        var percentScrolled = destX / (contentWidth - paneWidth);
4061        positionDragX(percentScrolled * dragMaxX, animate);
4062      }
4063
4064      function scrollToElement(ele, stickToTop, animate) {
4065        var e,
4066          eleHeight,
4067          eleWidth,
4068          eleTop = 0,
4069          eleLeft = 0,
4070          viewportTop,
4071          viewportLeft,
4072          maxVisibleEleTop,
4073          maxVisibleEleLeft,
4074          destY,
4075          destX;
4076
4077        // Legal hash values aren't necessarily legal jQuery selectors so we need to catch any
4078        // errors from the lookup...
4079        try {
4080          e = $(ele);
4081        } catch (err) {
4082          return;
4083        }
4084        eleHeight = e.outerHeight();
4085        eleWidth = e.outerWidth();
4086
4087        container.scrollTop(0);
4088        container.scrollLeft(0);
4089
4090        // loop through parents adding the offset top of any elements that are relatively positioned between
4091        // the focused element and the jspPane so we can get the true distance from the top
4092        // of the focused element to the top of the scrollpane...
4093        while (!e.is(".jspPane")) {
4094          eleTop += e.position().top;
4095          eleLeft += e.position().left;
4096          e = e.offsetParent();
4097          if (/^body|html$/i.test(e[0].nodeName)) {
4098            // we ended up too high in the document structure. Quit!
4099            return;
4100          }
4101        }
4102
4103        viewportTop = contentPositionY();
4104        maxVisibleEleTop = viewportTop + paneHeight;
4105        if (eleTop < viewportTop || stickToTop) {
4106          // element is above viewport
4107          destY = eleTop - settings.verticalGutter;
4108        } else if (eleTop + eleHeight > maxVisibleEleTop) {
4109          // element is below viewport
4110          destY = eleTop - paneHeight + eleHeight + settings.verticalGutter;
4111        }
4112        if (destY) {
4113          scrollToY(destY, animate);
4114        }
4115
4116        viewportLeft = contentPositionX();
4117        maxVisibleEleLeft = viewportLeft + paneWidth;
4118        if (eleLeft < viewportLeft || stickToTop) {
4119          // element is to the left of viewport
4120          destX = eleLeft - settings.horizontalGutter;
4121        } else if (eleLeft + eleWidth > maxVisibleEleLeft) {
4122          // element is to the right viewport
4123          destX = eleLeft - paneWidth + eleWidth + settings.horizontalGutter;
4124        }
4125        if (destX) {
4126          scrollToX(destX, animate);
4127        }
4128      }
4129
4130      function contentPositionX() {
4131        return -pane.position().left;
4132      }
4133
4134      function contentPositionY() {
4135        return -pane.position().top;
4136      }
4137
4138      function isCloseToBottom() {
4139        var scrollableHeight = contentHeight - paneHeight;
4140        return (
4141          scrollableHeight > 20 && scrollableHeight - contentPositionY() < 10
4142        );
4143      }
4144
4145      function isCloseToRight() {
4146        var scrollableWidth = contentWidth - paneWidth;
4147        return (
4148          scrollableWidth > 20 && scrollableWidth - contentPositionX() < 10
4149        );
4150      }
4151
4152      function initMousewheel() {
4153        container
4154          .off(mwEvent)
4155          .on(mwEvent, function (event, delta, deltaX, deltaY) {
4156            var dX = horizontalDragPosition,
4157              dY = verticalDragPosition;
4158            jsp.scrollBy(
4159              deltaX * settings.mouseWheelSpeed,
4160              -deltaY * settings.mouseWheelSpeed,
4161              false,
4162            );
4163            // return true if there was no movement so rest of screen can scroll
4164            return dX == horizontalDragPosition && dY == verticalDragPosition;
4165          });
4166      }
4167
4168      function removeMousewheel() {
4169        container.off(mwEvent);
4170      }
4171
4172      function nil() {
4173        return false;
4174      }
4175
4176      function initFocusHandler() {
4177        pane
4178          .find(":input,a")
4179          .off("focus.jsp")
4180          .on("focus.jsp", function (e) {
4181            scrollToElement(e.target, false);
4182          });
4183      }
4184
4185      function removeFocusHandler() {
4186        pane.find(":input,a").off("focus.jsp");
4187      }
4188
4189      function initKeyboardNav() {
4190        var keyDown,
4191          elementHasScrolled,
4192          validParents = [];
4193        isScrollableH && validParents.push(horizontalBar[0]);
4194        isScrollableV && validParents.push(verticalBar[0]);
4195
4196        // IE also focuses elements that don't have tabindex set.
4197        pane.focus(function () {
4198          elem.focus();
4199        });
4200
4201        elem
4202          .attr("tabindex", 0)
4203          .off("keydown.jsp keypress.jsp")
4204          .on("keydown.jsp", function (e) {
4205            if (
4206              e.target !== this &&
4207              !(validParents.length && $(e.target).closest(validParents).length)
4208            ) {
4209              return;
4210            }
4211            var dX = horizontalDragPosition,
4212              dY = verticalDragPosition;
4213            switch (e.keyCode) {
4214              case 40: // down
4215              case 38: // up
4216              case 34: // page down
4217              case 32: // space
4218              case 33: // page up
4219              case 39: // right
4220              case 37: // left
4221                keyDown = e.keyCode;
4222                keyDownHandler();
4223                break;
4224              case 35: // end
4225                scrollToY(contentHeight - paneHeight);
4226                keyDown = null;
4227                break;
4228              case 36: // home
4229                scrollToY(0);
4230                keyDown = null;
4231                break;
4232            }
4233
4234            elementHasScrolled =
4235              (e.keyCode == keyDown && dX != horizontalDragPosition) ||
4236              dY != verticalDragPosition;
4237            return !elementHasScrolled;
4238          })
4239          .off(
4240            "keypress.jsp", // For FF/ OSX so that we can cancel the repeat key presses if the JSP scrolls...
4241            function (e) {
4242              if (e.keyCode == keyDown) {
4243                keyDownHandler();
4244              }
4245              return !elementHasScrolled;
4246            },
4247          );
4248
4249        if (settings.hideFocus) {
4250          elem.css("outline", "none");
4251          if ("hideFocus" in container[0]) {
4252            elem.attr("hideFocus", true);
4253          }
4254        } else {
4255          elem.css("outline", "");
4256          if ("hideFocus" in container[0]) {
4257            elem.attr("hideFocus", false);
4258          }
4259        }
4260
4261        function keyDownHandler() {
4262          var dX = horizontalDragPosition,
4263            dY = verticalDragPosition;
4264          switch (keyDown) {
4265            case 40: // down
4266              jsp.scrollByY(settings.keyboardSpeed, false);
4267              break;
4268            case 38: // up
4269              jsp.scrollByY(-settings.keyboardSpeed, false);
4270              break;
4271            case 34: // page down
4272            case 32: // space
4273              jsp.scrollByY(paneHeight * settings.scrollPagePercent, false);
4274              break;
4275            case 33: // page up
4276              jsp.scrollByY(-paneHeight * settings.scrollPagePercent, false);
4277              break;
4278            case 39: // right
4279              jsp.scrollByX(settings.keyboardSpeed, false);
4280              break;
4281            case 37: // left
4282              jsp.scrollByX(-settings.keyboardSpeed, false);
4283              break;
4284          }
4285
4286          elementHasScrolled =
4287            dX != horizontalDragPosition || dY != verticalDragPosition;
4288          return elementHasScrolled;
4289        }
4290      }
4291
4292      function removeKeyboardNav() {
4293        elem
4294          .attr("tabindex", "-1")
4295          .removeAttr("tabindex")
4296          .off("keydown.jsp keypress.jsp");
4297      }
4298
4299      function observeHash() {
4300        if (location.hash && location.hash.length > 1) {
4301          var e,
4302            retryInt,
4303            hash = escape(location.hash.substr(1)); // hash must be escaped to prevent XSS
4304          try {
4305            e = $("#" + hash + ', a[name="' + hash + '"]');
4306          } catch (err) {
4307            return;
4308          }
4309
4310          if (e.length && pane.find(hash)) {
4311            // nasty workaround but it appears to take a little while before the hash has done its thing
4312            // to the rendered page so we just wait until the container's scrollTop has been messed up.
4313            if (container.scrollTop() === 0) {
4314              retryInt = setInterval(function () {
4315                if (container.scrollTop() > 0) {
4316                  scrollToElement(e, true);
4317                  $(document).scrollTop(container.position().top);
4318                  clearInterval(retryInt);
4319                }
4320              }, 50);
4321            } else {
4322              scrollToElement(e, true);
4323              $(document).scrollTop(container.position().top);
4324            }
4325          }
4326        }
4327      }
4328
4329      function hijackInternalLinks() {
4330        // only register the link handler once
4331        if ($(document.body).data("jspHijack")) {
4332          return;
4333        }
4334
4335        // remember that the handler was bound
4336        $(document.body).data("jspHijack", true);
4337
4338        // use live handler to also capture newly created links
4339        $(document.body).delegate("a[href*=#]", "click", function (event) {
4340          // does the link point to the same page?
4341          // this also takes care of cases with a <base>-Tag or Links not starting with the hash #
4342          // e.g. <a href="index.html#test"> when the current url already is index.html
4343          var href = this.href.substr(0, this.href.indexOf("#")),
4344            locationHref = location.href,
4345            hash,
4346            element,
4347            container,
4348            jsp,
4349            scrollTop,
4350            elementTop;
4351          if (location.href.indexOf("#") !== -1) {
4352            locationHref = location.href.substr(0, location.href.indexOf("#"));
4353          }
4354          if (href !== locationHref) {
4355            // the link points to another page
4356            return;
4357          }
4358
4359          // check if jScrollPane should handle this click event
4360          hash = escape(this.href.substr(this.href.indexOf("#") + 1));
4361
4362          // find the element on the page
4363          element;
4364          try {
4365            element = $("#" + hash + ', a[name="' + hash + '"]');
4366          } catch (e) {
4367            // hash is not a valid jQuery identifier
4368            return;
4369          }
4370
4371          if (!element.length) {
4372            // this link does not point to an element on this page
4373            return;
4374          }
4375
4376          container = element.closest(".jspScrollable");
4377          jsp = container.data("jsp");
4378
4379          // jsp might be another jsp instance than the one, that bound this event
4380          // remember: this event is only bound once for all instances.
4381          jsp.scrollToElement(element, true);
4382
4383          if (container[0].scrollIntoView) {
4384            // also scroll to the top of the container (if it is not visible)
4385            scrollTop = $(window).scrollTop();
4386            elementTop = element.offset().top;
4387            if (
4388              elementTop < scrollTop ||
4389              elementTop > scrollTop + $(window).height()
4390            ) {
4391              container[0].scrollIntoView();
4392            }
4393          }
4394
4395          // jsp handled this event, prevent the browser default (scrolling :P)
4396          event.preventDefault();
4397        });
4398      }
4399
4400      // Init touch on iPad, iPhone, iPod, Android
4401      function initTouch() {
4402        var startX,
4403          startY,
4404          touchStartX,
4405          touchStartY,
4406          moved,
4407          moving = false;
4408
4409        container
4410          .off("touchstart.jsp touchmove.jsp touchend.jsp click.jsp-touchclick")
4411          .on("touchstart.jsp", function (e) {
4412            var touch = e.originalEvent.touches[0];
4413            startX = contentPositionX();
4414            startY = contentPositionY();
4415            touchStartX = touch.pageX;
4416            touchStartY = touch.pageY;
4417            moved = false;
4418            moving = true;
4419          })
4420          .on("touchmove.jsp", function (ev) {
4421            if (!moving) {
4422              return;
4423            }
4424
4425            var touchPos = ev.originalEvent.touches[0],
4426              dX = horizontalDragPosition,
4427              dY = verticalDragPosition;
4428
4429            jsp.scrollTo(
4430              startX + touchStartX - touchPos.pageX,
4431              startY + touchStartY - touchPos.pageY,
4432            );
4433
4434            moved =
4435              moved ||
4436              Math.abs(touchStartX - touchPos.pageX) > 5 ||
4437              Math.abs(touchStartY - touchPos.pageY) > 5;
4438
4439            // return true if there was no movement so rest of screen can scroll
4440            return dX == horizontalDragPosition && dY == verticalDragPosition;
4441          })
4442          .on("touchend.jsp", function (e) {
4443            moving = false;
4444            /*if(moved) {
4445							return false;
4446						}*/
4447          })
4448          .on("click.jsp-touchclick", function (e) {
4449            if (moved) {
4450              moved = false;
4451              return false;
4452            }
4453          });
4454      }
4455
4456      function destroy() {
4457        var currentY = contentPositionY(),
4458          currentX = contentPositionX();
4459        elem.removeClass("jspScrollable").off(".jsp");
4460        elem.replaceWith(originalElement.append(pane.children()));
4461        originalElement.scrollTop(currentY);
4462        originalElement.scrollLeft(currentX);
4463
4464        // clear reinitialize timer if active
4465        if (reinitialiseInterval) {
4466          clearInterval(reinitialiseInterval);
4467        }
4468      }
4469
4470      // Public API
4471      $.extend(jsp, {
4472        // Reinitialises the scroll pane (if it's internal dimensions have changed since the last time it
4473        // was initialised). The settings object which is passed in will override any settings from the
4474        // previous time it was initialised - if you don't pass any settings then the ones from the previous
4475        // initialisation will be used.
4476        reinitialise: function (s) {
4477          s = $.extend({}, settings, s);
4478          initialise(s);
4479        },
4480        // Scrolls the specified element (a jQuery object, DOM node or jQuery selector string) into view so
4481        // that it can be seen within the viewport. If stickToTop is true then the element will appear at
4482        // the top of the viewport, if it is false then the viewport will scroll as little as possible to
4483        // show the element. You can also specify if you want animation to occur. If you don't provide this
4484        // argument then the animateScroll value from the settings object is used instead.
4485        scrollToElement: function (ele, stickToTop, animate) {
4486          scrollToElement(ele, stickToTop, animate);
4487        },
4488        // Scrolls the pane so that the specified co-ordinates within the content are at the top left
4489        // of the viewport. animate is optional and if not passed then the value of animateScroll from
4490        // the settings object this jScrollPane was initialised with is used.
4491        scrollTo: function (destX, destY, animate) {
4492          scrollToX(destX, animate);
4493          scrollToY(destY, animate);
4494        },
4495        // Scrolls the pane so that the specified co-ordinate within the content is at the left of the
4496        // viewport. animate is optional and if not passed then the value of animateScroll from the settings
4497        // object this jScrollPane was initialised with is used.
4498        scrollToX: function (destX, animate) {
4499          scrollToX(destX, animate);
4500        },
4501        // Scrolls the pane so that the specified co-ordinate within the content is at the top of the
4502        // viewport. animate is optional and if not passed then the value of animateScroll from the settings
4503        // object this jScrollPane was initialised with is used.
4504        scrollToY: function (destY, animate) {
4505          scrollToY(destY, animate);
4506        },
4507        // Scrolls the pane to the specified percentage of its maximum horizontal scroll position. animate
4508        // is optional and if not passed then the value of animateScroll from the settings object this
4509        // jScrollPane was initialised with is used.
4510        scrollToPercentX: function (destPercentX, animate) {
4511          scrollToX(destPercentX * (contentWidth - paneWidth), animate);
4512        },
4513        // Scrolls the pane to the specified percentage of its maximum vertical scroll position. animate
4514        // is optional and if not passed then the value of animateScroll from the settings object this
4515        // jScrollPane was initialised with is used.
4516        scrollToPercentY: function (destPercentY, animate) {
4517          scrollToY(destPercentY * (contentHeight - paneHeight), animate);
4518        },
4519        // Scrolls the pane by the specified amount of pixels. animate is optional and if not passed then
4520        // the value of animateScroll from the settings object this jScrollPane was initialised with is used.
4521        scrollBy: function (deltaX, deltaY, animate) {
4522          jsp.scrollByX(deltaX, animate);
4523          jsp.scrollByY(deltaY, animate);
4524        },
4525        // Scrolls the pane by the specified amount of pixels. animate is optional and if not passed then
4526        // the value of animateScroll from the settings object this jScrollPane was initialised with is used.
4527        scrollByX: function (deltaX, animate) {
4528          var destX =
4529              contentPositionX() + Math[deltaX < 0 ? "floor" : "ceil"](deltaX),
4530            percentScrolled = destX / (contentWidth - paneWidth);
4531          positionDragX(percentScrolled * dragMaxX, animate);
4532        },
4533        // Scrolls the pane by the specified amount of pixels. animate is optional and if not passed then
4534        // the value of animateScroll from the settings object this jScrollPane was initialised with is used.
4535        scrollByY: function (deltaY, animate) {
4536          var destY =
4537              contentPositionY() + Math[deltaY < 0 ? "floor" : "ceil"](deltaY),
4538            percentScrolled = destY / (contentHeight - paneHeight);
4539          positionDragY(percentScrolled * dragMaxY, animate);
4540        },
4541        // Positions the horizontal drag at the specified x position (and updates the viewport to reflect
4542        // this). animate is optional and if not passed then the value of animateScroll from the settings
4543        // object this jScrollPane was initialised with is used.
4544        positionDragX: function (x, animate) {
4545          positionDragX(x, animate);
4546        },
4547        // Positions the vertical drag at the specified y position (and updates the viewport to reflect
4548        // this). animate is optional and if not passed then the value of animateScroll from the settings
4549        // object this jScrollPane was initialised with is used.
4550        positionDragY: function (y, animate) {
4551          positionDragY(y, animate);
4552        },
4553        // This method is called when jScrollPane is trying to animate to a new position. You can override
4554        // it if you want to provide advanced animation functionality. It is passed the following arguments:
4555        //  * ele          - the element whose position is being animated
4556        //  * prop         - the property that is being animated
4557        //  * value        - the value it's being animated to
4558        //  * stepCallback - a function that you must execute each time you update the value of the property
4559        // You can use the default implementation (below) as a starting point for your own implementation.
4560        animate: function (ele, prop, value, stepCallback) {
4561          var params = {};
4562          params[prop] = value;
4563          ele.animate(params, {
4564            duration: settings.animateDuration,
4565            easing: settings.animateEase,
4566            queue: false,
4567            step: stepCallback,
4568          });
4569        },
4570        // Returns the current x position of the viewport with regards to the content pane.
4571        getContentPositionX: function () {
4572          return contentPositionX();
4573        },
4574        // Returns the current y position of the viewport with regards to the content pane.
4575        getContentPositionY: function () {
4576          return contentPositionY();
4577        },
4578        // Returns the width of the content within the scroll pane.
4579        getContentWidth: function () {
4580          return contentWidth;
4581        },
4582        // Returns the height of the content within the scroll pane.
4583        getContentHeight: function () {
4584          return contentHeight;
4585        },
4586        // Returns the horizontal position of the viewport within the pane content.
4587        getPercentScrolledX: function () {
4588          return contentPositionX() / (contentWidth - paneWidth);
4589        },
4590        // Returns the vertical position of the viewport within the pane content.
4591        getPercentScrolledY: function () {
4592          return contentPositionY() / (contentHeight - paneHeight);
4593        },
4594        // Returns whether or not this scrollpane has a horizontal scrollbar.
4595        getIsScrollableH: function () {
4596          return isScrollableH;
4597        },
4598        // Returns whether or not this scrollpane has a vertical scrollbar.
4599        getIsScrollableV: function () {
4600          return isScrollableV;
4601        },
4602        // Gets a reference to the content pane. It is important that you use this method if you want to
4603        // edit the content of your jScrollPane as if you access the element directly then you may have some
4604        // problems (as your original element has had additional elements for the scrollbars etc added into
4605        // it).
4606        getContentPane: function () {
4607          return pane;
4608        },
4609        // Scrolls this jScrollPane down as far as it can currently scroll. If animate isn't passed then the
4610        // animateScroll value from settings is used instead.
4611        scrollToBottom: function (animate) {
4612          positionDragY(dragMaxY, animate);
4613        },
4614        // Hijacks the links on the page which link to content inside the scrollpane. If you have changed
4615        // the content of your page (e.g. via AJAX) and want to make sure any new anchor links to the
4616        // contents of your scroll pane will work then call this function.
4617        hijackInternalLinks: $.noop,
4618        // Removes the jScrollPane and returns the page to the state it was in before jScrollPane was
4619        // initialised.
4620        destroy: function () {
4621          destroy();
4622        },
4623      });
4624
4625      initialise(s);
4626    }
4627
4628    // Pluginifying code...
4629    settings = $.extend({}, $.fn.jScrollPane.defaults, settings);
4630
4631    // Apply default speed
4632    $.each(
4633      [
4634        "mouseWheelSpeed",
4635        "arrowButtonSpeed",
4636        "trackClickSpeed",
4637        "keyboardSpeed",
4638      ],
4639      function () {
4640        settings[this] = settings[this] || settings.speed;
4641      },
4642    );
4643
4644    return this.each(function () {
4645      var elem = $(this),
4646        jspApi = elem.data("jsp");
4647      if (jspApi) {
4648        jspApi.reinitialise(settings);
4649      } else {
4650        $("script", elem)
4651          .filter('[type="text/javascript"], :not([type])')
4652          .remove();
4653        jspApi = new JScrollPane(elem, settings);
4654        elem.data("jsp", jspApi);
4655      }
4656    });
4657  };
4658
4659  $.fn.jScrollPane.defaults = {
4660    showArrows: false,
4661    maintainPosition: true,
4662    stickToBottom: false,
4663    stickToRight: false,
4664    clickOnTrack: true,
4665    autoReinitialise: false,
4666    autoReinitialiseDelay: 500,
4667    verticalDragMinHeight: 30,
4668    verticalDragMaxHeight: 99999,
4669    horizontalDragMinWidth: 30,
4670    horizontalDragMaxWidth: 99999,
4671    contentWidth: undefined,
4672    animateScroll: false,
4673    animateDuration: 300,
4674    animateEase: "linear",
4675    hijackInternalLinks: false,
4676    verticalGutter: 4,
4677    horizontalGutter: 4,
4678    mouseWheelSpeed: 0,
4679    arrowButtonSpeed: 0,
4680    arrowRepeatFreq: 50,
4681    arrowScrollOnHover: false,
4682    trackClickSpeed: 0,
4683    trackClickRepeatFreq: 70,
4684    verticalArrowPositions: "split",
4685    horizontalArrowPositions: "split",
4686    enableKeyboardNavigation: true,
4687    hideFocus: false,
4688    keyboardSpeed: 0,
4689    initialDelay: 300, // Delay before starting repeating
4690    speed: 30, // Default speed when others falsey
4691    scrollPagePercent: 0.8, // Percent of visible area scrolled when pageUp/Down or track area pressed
4692  };
4693})(jQuery);
4694
4695(function ($) {
4696  $.fn.dnnSettingDropdown = function () {
4697    var clicked = function () {
4698      if ($(this).hasClass("dnnButtonDropdown")) {
4699        $(this)
4700          .removeClass("dnnButtonDropdown")
4701          .addClass("dnnButtonDropdown-clicked");
4702        $(this).next().show();
4703      }
4704    };
4705
4706    var hideDropdown = function () {
4707      var btn = $(this).children(":first");
4708      if (btn.hasClass("dnnButtonDropdown-clicked")) {
4709        btn
4710          .removeClass("dnnButtonDropdown-clicked")
4711          .addClass("dnnButtonDropdown");
4712        btn.next().fadeOut();
4713      }
4714    };
4715
4716    var hoverConfig = {
4717      over: function () {},
4718      out: hideDropdown,
4719      timout: 600,
4720    };
4721
4722    return $(this).each(function () {
4723      $(this).off("click", clicked).on("click", clicked);
4724      $(this).parent().hoverIntent(hoverConfig);
4725    });
4726  };
4727})(jQuery);
4728
4729(function ($) {
4730  $.fn.onEnter = function (fn) {
4731    return this.each(function () {
4732      var $this = $(this);
4733      $this.on("onEnter", fn);
4734      $this.keydown(function (e) {
4735        if ((e.which && e.which === 13) || (e.keyCode && e.keyCode === 13)) {
4736          e.preventDefault();
4737          e.stopPropagation();
4738          $this.trigger("onEnter");
4739        }
4740      });
4741    });
4742  };
4743})(jQuery);
4744
4745(function ($) {
4746  $.extend({
4747    onAjaxError: function (jqXhr, textStatus, errorThrown) {
4748      var title, text;
4749      if (jqXhr && jqXhr.status === 401) {
4750        dnnModal.show(
4751          "../Login.aspx" + "?popUp=true",
4752          true,
4753          300,
4754          650,
4755          true,
4756          "",
4757        );
4758        return;
4759      }
4760      if (jqXhr && jqXhr.responseText && jqXhr.statusText) {
4761        try {
4762          title = jqXhr.statusText + " (" + jqXhr.status + ")";
4763          text = JSON.parse(jqXhr.responseText).Message;
4764        } catch (e) {
4765          text = errorThrown;
4766        }
4767      }
4768      $.dnnAlert({ title: title || "Error", text: text || "Unknown error" });
4769    },
4770  });
4771})(jQuery);
4772
4773(function ($) {
4774  $.fn.dnnSliderInput = function (options) {
4775    var sliderOptions = $.extend({}, $.fn.dnnSliderInput.defaults, options);
4776    return $(this).each(function () {
4777      var $this = $(this);
4778      var value = $this.val();
4779      var $slider = $('<div class="dnnSliderInput"></div>');
4780      $this.hide().after($slider);
4781
4782      $slider.slider(sliderOptions);
4783      $slider.slider("value", value);
4784
4785      var $tooltip = $(
4786        '<span class="dnnTooltip"><span class="dnnFormHelpContent dnnClear"><span class="dnnHelpText bottomArrow"></span></span></span>',
4787      );
4788
4789      var calcTooltipPosition = function () {
4790        setTimeout(function () {
4791          var left = $slider.find(".ui-slider-handle")[0].style.left;
4792          $tooltip.css("left", left);
4793        }, 0);
4794      };
4795
4796      $tooltip.find(".dnnHelpText").html(value);
4797      $tooltip.data("initialized", true);
4798      $slider.append($tooltip);
4799
4800      calcTooltipPosition();
4801      $slider.on("slide", function (event, ui) {
4802        $tooltip.find(".dnnHelpText").html(ui.value);
4803        $this.val(ui.value);
4804        calcTooltipPosition();
4805      });
4806    });
4807  };
4808
4809  $.fn.dnnSliderInput.defaults = {
4810    min: 0,
4811    max: 100,
4812    step: 1,
4813  };
4814})(jQuery);
4815
4816// please keep this func at last of this file, thanks
4817(function ($) {
4818  /* Start customised controls */
4819  var inputFocusFix = function () {
4820    var errorMsg = $(this).next();
4821    if (errorMsg.hasClass("dnnFormError")) errorMsg.hide();
4822  };
4823  var throttle = null;
4824  var dnnInitCustomisedCtrls = function () {
4825    if (throttle != null) {
4826      clearTimeout(throttle);
4827      throttle = null;
4828    }
4829    throttle = setTimeout(function () {
4830      $('.dnnForm input[type="checkbox"]').dnnCheckbox();
4831      $('.dnnForm input[type="radio"]').dnnCheckbox({ cls: "dnnRadiobutton" });
4832      $(".dnnTooltip").dnnTooltip();
4833      $('.dnnForm input[type="text"], .dnnForm input[type="password"]')
4834        .off("focus", inputFocusFix)
4835        .on("focus", inputFocusFix);
4836      $(".dnnForm :file").dnnFileInput();
4837      $(".dnnForm input[data-default]").dnnPlaceholder();
4838    }, 200);
4839    //change the window confirm style to DNN style
4840    $("*[onclick*='return confirm']").each(function () {
4841      var instance = $(this);
4842      var isButton =
4843        this.nodeName.toLowerCase() == "img" ||
4844        this.nodeName.toLowerCase() == "input";
4845      var script = /return confirm\((['"])([\s\S]*?)\1\)/g.exec(
4846        instance.attr("onclick"),
4847      );
4848      if (script != null) {
4849        var confirmContent = script[2].split("\\" + script[1]).join(script[1]);
4850        //restore unicode chars.
4851        confirmContent = confirmContent.replace(
4852          /\\u([\d\w]{4})/gi,
4853          function (match, charCode) {
4854            return String.fromCharCode(parseInt(charCode, 16));
4855          },
4856        );
4857        instance
4858          .attr(
4859            "onclick",
4860            instance.attr("onclick").replace(script[0], "void(0)"),
4861          )
4862          .dnnConfirm({
4863            text: confirmContent,
4864            isButton: isButton,
4865          });
4866      }
4867    });
4868  };
4869  var saveRgDataDivScrollTop = function () {
4870    window.__rgDataDivScrollTopPersistArray = [];
4871    $(".rgDataDiv").each(function () {
4872      var $this = $(this);
4873      var ele = $this.get(0);
4874      if (ele.scrollPane) {
4875        var api = ele.scrollPane.data("jsp");
4876        var y = api.getContentPositionY();
4877        window.__rgDataDivScrollTopPersistArray.push(y);
4878      }
4879    });
4880  };
4881
4882  var handlerSendVerificationMailLink = function () {
4883    $(document.body).on("click", "a.send-verification-mail", function (e) {
4884      e.preventDefault();
4885
4886      var service = $.dnnSF();
4887      var url =
4888        service.getServiceRoot("InternalServices") +
4889        "NewUserNotificationService/SendVerificationMail";
4890      var antiForgeryToken = $(
4891        'input[name="__RequestVerificationToken"]',
4892      ).val();
4893      url += "?__RequestVerificationToken=" + antiForgeryToken;
4894
4895      $.ajax({
4896        url: url,
4897        beforeSend: service ? service.setModuleHeaders : null,
4898        success: function (data) {
4899          $.dnnAlert({ text: data.Result });
4900        },
4901        error: function (xhr, textStatus, errorThrown) {
4902          if (xhr && xhr.responseText) {
4903            $.dnnAlert({ text: JSON.parse(xhr.responseText).Message });
4904          }
4905        },
4906        type: "POST",
4907        dataType: "json",
4908        contentType: "application/json",
4909      });
4910    });
4911  };
4912
4913  function registerEvents() {
4914    Sys.WebForms.PageRequestManager.getInstance().add_beginRequest(
4915      saveRgDataDivScrollTop,
4916    );
4917    Sys.WebForms.PageRequestManager.getInstance().add_endRequest(
4918      dnnInitCustomisedCtrls,
4919    );
4920  }
4921
4922  window.__rgDataDivScrollTopPersistArray = [];
4923  $(document).ajaxComplete(dnnInitCustomisedCtrls);
4924  $(dnnInitCustomisedCtrls);
4925  $(registerEvents);
4926  handlerSendVerificationMailLink();
4927})(jQuery);

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.