PageSourceSearch

https://pyroskin.com/bitrix/templates/semantis/js/semantic.js

js pyroskin.com collected 2026-10-02 19:54:02 UTC 693,878 bytes, 21,465 lines download raw bytes

1 /*
2 * # Semantic UI - 2.1.7
3 * https://github.com/Semantic-Org/Semantic-UI
4 * http://www.semantic-ui.com/
5 *
6 * Copyright 2014 Contributors
7 * Released under the MIT license
8 * http://opensource.org/licenses/MIT
9 *
10 */
11/*!
12 * # Semantic UI 2.1.7 - Site
13 * http://github.com/semantic-org/semantic-ui/
14 *
15 *
16 * Copyright 2015 Contributors
17 * Released under the MIT license
18 * http://opensource.org/licenses/MIT
19 *
20 */
21;(function ( $, window, document, undefined 
vendor: 13,932 bytes, lines 21-500
21) {
22
23$.site = $.fn.site = function(parameters) {
24  var
25    time           = new Date().getTime(),
26    performance    = [],
27
28    query          = arguments[0],
29    methodInvoked  = (typeof query == 'string'),
30    queryArguments = [].slice.call(arguments, 1),
31
32    settings        = ( $.isPlainObject(parameters) )
33      ? $.extend(true, {}, $.site.settings, parameters)
34      : $.extend({}, $.site.settings),
35
36    namespace       = settings.namespace,
37    error           = settings.error,
38
39    eventNamespace  = '.' + namespace,
40    moduleNamespace = 'module-' + namespace,
41
42    $document       = $(document),
43    $module         = $document,
44    element         = this,
45    instance        = $module.data(moduleNamespace),
46
47    module,
48    returnedValue
49  ;
50  module = {
51
52    initialize: function() {
53      module.instantiate();
54    },
55
56    instantiate: function() {
57      module.verbose('Storing instance of site', module);
58      instance = module;
59      $module
60        .data(moduleNamespace, module)
61      ;
62    },
63
64    normalize: function() {
65      module.fix.console();
66      module.fix.requestAnimationFrame();
67    },
68
69    fix: {
70      console: function() {
71        module.debug('Normalizing window.console');
72        if (console === undefined || console.log === undefined) {
73          module.verbose('Console not available, normalizing events');
74          module.disable.console();
75        }
76        if (typeof console.group == 'undefined' || typeof console.groupEnd == 'undefined' || typeof console.groupCollapsed == 'undefined') {
77          module.verbose('Console group not available, normalizing events');
78          window.console.group = function() {};
79          window.console.groupEnd = function() {};
80          window.console.groupCollapsed = function() {};
81        }
82        if (typeof console.markTimeline == 'undefined') {
83          module.verbose('Mark timeline not available, normalizing events');
84          window.console.markTimeline = function() {};
85        }
86      },
87      consoleClear: function() {
88        module.debug('Disabling programmatic console clearing');
89        window.console.clear = function() {};
90      },
91      requestAnimationFrame: function() {
92        module.debug('Normalizing requestAnimationFrame');
93        if(window.requestAnimationFrame === undefined) {
94          module.debug('RequestAnimationFrame not available, normalizing event');
95          window.requestAnimationFrame = window.requestAnimationFrame
96            || window.mozRequestAnimationFrame
97            || window.webkitRequestAnimationFrame
98            || window.msRequestAnimationFrame
99            || function(callback) { setTimeout(callback, 0); }
100          ;
101        }
102      }
103    },
104
105    moduleExists: function(name) {
106      return ($.fn[name] !== undefined && $.fn[name].settings !== undefined);
107    },
108
109    enabled: {
110      modules: function(modules) {
111        var
112          enabledModules = []
113        ;
114        modules = modules || settings.modules;
115        $.each(modules, function(index, name) {
116          if(module.moduleExists(name)) {
117            enabledModules.push(name);
118          }
119        });
120        return enabledModules;
121      }
122    },
123
124    disabled: {
125      modules: function(modules) {
126        var
127          disabledModules = []
128        ;
129        modules = modules || settings.modules;
130        $.each(modules, function(index, name) {
131          if(!module.moduleExists(name)) {
132            disabledModules.push(name);
133          }
134        });
135        return disabledModules;
136      }
137    },
138
139    change: {
140      setting: function(setting, value, modules, modifyExisting) {
141        modules = (typeof modules === 'string')
142          ? (modules === 'all')
143            ? settings.modules
144            : [modules]
145          : modules || settings.modules
146        ;
147        modifyExisting = (modifyExisting !== undefined)
148          ? modifyExisting
149          : true
150        ;
151        $.each(modules, function(index, name) {
152          var
153            namespace = (module.moduleExists(name))
154              ? $.fn[name].settings.namespace || false
155              : true,
156            $existingModules
157          ;
158          if(module.moduleExists(name)) {
159            module.verbose('Changing default setting', setting, value, name);
160            $.fn[name].settings[setting] = value;
161            if(modifyExisting && namespace) {
162              $existingModules = $(':data(module-' + namespace + ')');
163              if($existingModules.length > 0) {
164                module.verbose('Modifying existing settings', $existingModules);
165                $existingModules[name]('setting', setting, value);
166              }
167            }
168          }
169        });
170      },
171      settings: function(newSettings, modules, modifyExisting) {
172        modules = (typeof modules === 'string')
173          ? [modules]
174          : modules || settings.modules
175        ;
176        modifyExisting = (modifyExisting !== undefined)
177          ? modifyExisting
178          : true
179        ;
180        $.each(modules, function(index, name) {
181          var
182            $existingModules
183          ;
184          if(module.moduleExists(name)) {
185            module.verbose('Changing default setting', newSettings, name);
186            $.extend(true, $.fn[name].settings, newSettings);
187            if(modifyExisting && namespace) {
188              $existingModules = $(':data(module-' + namespace + ')');
189              if($existingModules.length > 0) {
190                module.verbose('Modifying existing settings', $existingModules);
191                $existingModules[name]('setting', newSettings);
192              }
193            }
194          }
195        });
196      }
197    },
198
199    enable: {
200      console: function() {
201        module.console(true);
202      },
203      debug: function(modules, modifyExisting) {
204        modules = modules || settings.modules;
205        module.debug('Enabling debug for modules', modules);
206        module.change.setting('debug', true, modules, modifyExisting);
207      },
208      verbose: function(modules, modifyExisting) {
209        modules = modules || settings.modules;
210        module.debug('Enabling verbose debug for modules', modules);
211        module.change.setting('verbose', true, modules, modifyExisting);
212      }
213    },
214    disable: {
215      console: function() {
216        module.console(false);
217      },
218      debug: function(modules, modifyExisting) {
219        modules = modules || settings.modules;
220        module.debug('Disabling debug for modules', modules);
221        module.change.setting('debug', false, modules, modifyExisting);
222      },
223      verbose: function(modules, modifyExisting) {
224        modules = modules || settings.modules;
225        module.debug('Disabling verbose debug for modules', modules);
226        module.change.setting('verbose', false, modules, modifyExisting);
227      }
228    },
229
230    console: function(enable) {
231      if(enable) {
232        if(instance.cache.console === undefined) {
233          module.error(error.console);
234          return;
235        }
236        module.debug('Restoring console function');
237        window.console = instance.cache.console;
238      }
239      else {
240        module.debug('Disabling console function');
241        instance.cache.console = window.console;
242        window.console = {
243          clear          : function(){},
244          error          : function(){},
245          group          : function(){},
246          groupCollapsed : function(){},
247          groupEnd       : function(){},
248          info           : function(){},
249          log            : function(){},
250          markTimeline   : function(){},
251          warn           : function(){}
252        };
253      }
254    },
255
256    destroy: function() {
257      module.verbose('Destroying previous site for', $module);
258      $module
259        .removeData(moduleNamespace)
260      ;
261    },
262
263    cache: {},
264
265    setting: function(name, value) {
266      if( $.isPlainObject(name) ) {
267        $.extend(true, settings, name);
268      }
269      else if(value !== undefined) {
270        settings[name] = value;
271      }
272      else {
273        return settings[name];
274      }
275    },
276    internal: function(name, value) {
277      if( $.isPlainObject(name) ) {
278        $.extend(true, module, name);
279      }
280      else if(value !== undefined) {
281        module[name] = value;
282      }
283      else {
284        return module[name];
285      }
286    },
287    debug: function() {
288      if(settings.debug) {
289        if(settings.performance) {
290          module.performance.log(arguments);
291        }
292        else {
293          module.debug = Function.prototype.bind.call(console.info, console, settings.name + ':');
294          module.debug.apply(console, arguments);
295        }
296      }
297    },
298    verbose: function() {
299      if(settings.verbose && settings.debug) {
300        if(settings.performance) {
301          module.performance.log(arguments);
302        }
303        else {
304          module.verbose = Function.prototype.bind.call(console.info, console, settings.name + ':');
305          module.verbose.apply(console, arguments);
306        }
307      }
308    },
309    error: function() {
310      module.error = Function.prototype.bind.call(console.error, console, settings.name + ':');
311      module.error.apply(console, arguments);
312    },
313    performance: {
314      log: function(message) {
315        var
316          currentTime,
317          executionTime,
318          previousTime
319        ;
320        if(settings.performance) {
321          currentTime   = new Date().getTime();
322          previousTime  = time || currentTime;
323          executionTime = currentTime - previousTime;
324          time          = currentTime;
325          performance.push({
326            'Element'        : element,
327            'Name'           : message[0],
328            'Arguments'      : [].slice.call(message, 1) || '',
329            'Execution Time' : executionTime
330          });
331        }
332        clearTimeout(module.performance.timer);
333        module.performance.timer = setTimeout(module.performance.display, 500);
334      },
335      display: function() {
336        var
337          title = settings.name + ':',
338          totalTime = 0
339        ;
340        time = false;
341        clearTimeout(module.performance.timer);
342        $.each(performance, function(index, data) {
343          totalTime += data['Execution Time'];
344        });
345        title += ' ' + totalTime + 'ms';
346        if( (console.group !== undefined || console.table !== undefined) && performance.length > 0) {
347          console.groupCollapsed(title);
348          if(console.table) {
349            console.table(performance);
350          }
351          else {
352            $.each(performance, function(index, data) {
353              console.log(data['Name'] + ': ' + data['Execution Time']+'ms');
354            });
355          }
356          console.groupEnd();
357        }
358        performance = [];
359      }
360    },
361    invoke: function(query, passedArguments, context) {
362      var
363        object = instance,
364        maxDepth,
365        found,
366        response
367      ;
368      passedArguments = passedArguments || queryArguments;
369      context         = element         || context;
370      if(typeof query == 'string' && object !== undefined) {
371        query    = query.split(/[\. ]/);
372        maxDepth = query.length - 1;
373        $.each(query, function(depth, value) {
374          var camelCaseValue = (depth != maxDepth)
375            ? value + query[depth + 1].charAt(0).toUpperCase() + query[depth + 1].slice(1)
376            : query
377          ;
378          if( $.isPlainObject( object[camelCaseValue] ) && (depth != maxDepth) ) {
379            object = object[camelCaseValue];
380          }
381          else if( object[camelCaseValue] !== undefined ) {
382            found = object[camelCaseValue];
383            return false;
384          }
385          else if( $.isPlainObject( object[value] ) && (depth != maxDepth) ) {
386            object = object[value];
387          }
388          else if( object[value] !== undefined ) {
389            found = object[value];
390            return false;
391          }
392          else {
393            module.error(error.method, query);
394            return false;
395          }
396        });
397      }
398      if ( $.isFunction( found ) ) {
399        response = found.apply(context, passedArguments);
400      }
401      else if(found !== undefined) {
402        response = found;
403      }
404      if($.isArray(returnedValue)) {
405        returnedValue.push(response);
406      }
407      else if(returnedValue !== undefined) {
408        returnedValue = [returnedValue, response];
409      }
410      else if(response !== undefined) {
411        returnedValue = response;
412      }
413      return found;
414    }
415  };
416
417  if(methodInvoked) {
418    if(instance === undefined) {
419      module.initialize();
420    }
421    module.invoke(query);
422  }
423  else {
424    if(instance !== undefined) {
425      module.destroy();
426    }
427    module.initialize();
428  }
429  return (returnedValue !== undefined)
430    ? returnedValue
431    : this
432  ;
433};
434
435$.site.settings = {
436
437  name        : 'Site',
438  namespace   : 'site',
439
440  error : {
441    console : 'Console cannot be restored, most likely it was overwritten outside of module',
442    method : 'The method you called is not defined.'
443  },
444
445  debug       : false,
446  verbose     : false,
447  performance : true,
448
449  modules: [
450    'accordion',
451    'api',
452    'checkbox',
453    'dimmer',
454    'dropdown',
455    'embed',
456    'form',
457    'modal',
458    'nag',
459    'popup',
460    'rating',
461    'shape',
462    'sidebar',
463    'state',
464    'sticky',
465    'tab',
466    'transition',
467    'visit',
468    'visibility'
469  ],
470
471  siteNamespace   : 'site',
472  namespaceStub   : {
473    cache     : {},
474    config    : {},
475    sections  : {},
476    section   : {},
477    utilities : {}
478  }
479
480};
481
482// allows for selection of elements with data attributes
483$.extend($.expr[ ":" ], {
484  data: ($.expr.createPseudo)
485    ? $.expr.createPseudo(function(dataName) {
486        return function(elem) {
487          return !!$.data(elem, dataName);
488        };
489      })
490    : function(elem, i, match) {
491      // support: jQuery < 1.8
492      return !!$.data(elem, match[ 3 ]);
493    }
494});
495
496
497})( jQuery, window, document );
498
499/*!
500 * # Semantic UI 2.
vendor: 16,326 bytes, lines 500-975
5001.7 - Form Validation
501 * http://github.com/semantic-org/semantic-ui/
502 *
503 *
504 * Copyright 2015 Contributors
505 * Released under the MIT license
506 * http://opensource.org/licenses/MIT
507 *
508 */
509
510;(function ( $, window, document, undefined ) {
511
512"use strict";
513
514$.fn.form = function(parameters) {
515  var
516    $allModules      = $(this),
517    moduleSelector   = $allModules.selector || '',
518
519    time             = new Date().getTime(),
520    performance      = [],
521
522    query            = arguments[0],
523    legacyParameters = arguments[1],
524    methodInvoked    = (typeof query == 'string'),
525    queryArguments   = [].slice.call(arguments, 1),
526    returnedValue
527  ;
528  $allModules
529    .each(function() {
530      var
531        $module     = $(this),
532        element     = this,
533
534        formErrors  = [],
535        keyHeldDown = false,
536
537        // set at run-time
538        $field,
539        $group,
540        $message,
541        $prompt,
542        $submit,
543        $clear,
544        $reset,
545
546        settings,
547        validation,
548
549        metadata,
550        selector,
551        className,
552        error,
553
554        namespace,
555        moduleNamespace,
556        eventNamespace,
557
558        instance,
559        module
560      ;
561
562      module      = {
563
564        initialize: function() {
565
566          // settings grabbed at run time
567          module.get.settings();
568          if(methodInvoked) {
569            if(instance === undefined) {
570              module.instantiate();
571            }
572            module.invoke(query);
573          }
574          else {
575            module.verbose('Initializing form validation', $module, settings);
576            module.bindEvents();
577            module.set.defaults();
578            module.instantiate();
579          }
580        },
581
582        instantiate: function() {
583          module.verbose('Storing instance of module', module);
584          instance = module;
585          $module
586            .data(moduleNamespace, module)
587          ;
588        },
589
590        destroy: function() {
591          module.verbose('Destroying previous module', instance);
592          module.removeEvents();
593          $module
594            .removeData(moduleNamespace)
595          ;
596        },
597
598        refresh: function() {
599          module.verbose('Refreshing selector cache');
600          $field      = $module.find(selector.field);
601          $group      = $module.find(selector.group);
602          $message    = $module.find(selector.message);
603          $prompt     = $module.find(selector.prompt);
604
605          $submit     = $module.find(selector.submit);
606          $clear      = $module.find(selector.clear);
607          $reset      = $module.find(selector.reset);
608        },
609
610        submit: function() {
611          module.verbose('Submitting form', $module);
612          $module
613            .submit()
614          ;
615        },
616
617        attachEvents: function(selector, action) {
618          action = action || 'submit';
619          $(selector)
620            .on('click' + eventNamespace, function(event) {
621              module[action]();
622              event.preventDefault();
623            })
624          ;
625        },
626
627        bindEvents: function() {
628          module.verbose('Attaching form events');
629          $module
630            .on('submit' + eventNamespace, module.validate.form)
631            .on('blur'   + eventNamespace, selector.field, module.event.field.blur)
632            .on('click'  + eventNamespace, selector.submit, module.submit)
633            .on('click'  + eventNamespace, selector.reset, module.reset)
634            .on('click'  + eventNamespace, selector.clear, module.clear)
635          ;
636          if(settings.keyboardShortcuts) {
637            $module
638              .on('keydown' + eventNamespace, selector.field, module.event.field.keydown)
639            ;
640          }
641          $field
642            .each(function() {
643              var
644                $input     = $(this),
645                type       = $input.prop('type'),
646                inputEvent = module.get.changeEvent(type, $input)
647              ;
648              $(this)
649                .on(inputEvent + eventNamespace, module.event.field.change)
650              ;
651            })
652          ;
653        },
654
655        clear: function() {
656          $field
657            .each(function () {
658              var
659                $field       = $(this),
660                $element     = $field.parent(),
661                $fieldGroup  = $field.closest($group),
662                $prompt      = $fieldGroup.find(selector.prompt),
663                defaultValue = $field.data(metadata.defaultValue) || '',
664                isCheckbox   = $element.is(selector.uiCheckbox),
665                isDropdown   = $element.is(selector.uiDropdown),
666                isErrored    = $fieldGroup.hasClass(className.error)
667              ;
668              if(isErrored) {
669                module.verbose('Resetting error on field', $fieldGroup);
670                $fieldGroup.removeClass(className.error);
671                $prompt.remove();
672              }
673              if(isDropdown) {
674                module.verbose('Resetting dropdown value', $element, defaultValue);
675                $element.dropdown('clear');
676              }
677              else if(isCheckbox) {
678                $field.prop('checked', false);
679              }
680              else {
681                module.verbose('Resetting field value', $field, defaultValue);
682                $field.val('');
683              }
684            })
685          ;
686        },
687
688        reset: function() {
689          $field
690            .each(function () {
691              var
692                $field       = $(this),
693                $element     = $field.parent(),
694                $fieldGroup  = $field.closest($group),
695                $prompt      = $fieldGroup.find(selector.prompt),
696                defaultValue = $field.data(metadata.defaultValue),
697                isCheckbox   = $element.is(selector.uiCheckbox),
698                isDropdown   = $element.is(selector.uiDropdown),
699                isErrored    = $fieldGroup.hasClass(className.error)
700              ;
701              if(defaultValue === undefined) {
702                return;
703              }
704              if(isErrored) {
705                module.verbose('Resetting error on field', $fieldGroup);
706                $fieldGroup.removeClass(className.error);
707                $prompt.remove();
708              }
709              if(isDropdown) {
710                module.verbose('Resetting dropdown value', $element, defaultValue);
711                $element.dropdown('restore defaults');
712              }
713              else if(isCheckbox) {
714                module.verbose('Resetting checkbox value', $element, defaultValue);
715                $field.prop('checked', defaultValue);
716              }
717              else {
718                module.verbose('Resetting field value', $field, defaultValue);
719                $field.val(defaultValue);
720              }
721            })
722          ;
723        },
724
725        is: {
726          bracketedRule: function(rule) {
727            return (rule.type && rule.type.match(settings.regExp.bracket));
728          },
729          valid: function() {
730            var
731              allValid = true
732            ;
733            module.verbose('Checking if form is valid');
734            $.each(validation, function(fieldName, field) {
735              if( !( module.validate.field(field, fieldName) ) ) {
736                allValid = false;
737              }
738            });
739            return allValid;
740          }
741        },
742
743        removeEvents: function() {
744          $module
745            .off(eventNamespace)
746          ;
747          $field
748            .off(eventNamespace)
749          ;
750          $submit
751            .off(eventNamespace)
752          ;
753          $field
754            .off(eventNamespace)
755          ;
756        },
757
758        event: {
759          field: {
760            keydown: function(event) {
761              var
762                $field  = $(this),
763                key     = event.which,
764                keyCode = {
765                  enter  : 13,
766                  escape : 27
767                }
768              ;
769              if( key == keyCode.escape) {
770                module.verbose('Escape key pressed blurring field');
771                $field
772                  .blur()
773                ;
774              }
775              if(!event.ctrlKey && key == keyCode.enter && $field.is(selector.input) && $field.not(selector.checkbox).length > 0 ) {
776                if(!keyHeldDown) {
777                  $field
778                    .one('keyup' + eventNamespace, module.event.field.keyup)
779                  ;
780                  module.submit();
781                  module.debug('Enter pressed on input submitting form');
782                }
783                keyHeldDown = true;
784              }
785            },
786            keyup: function() {
787              keyHeldDown = false;
788            },
789            blur: function(event) {
790              var
791                $field          = $(this),
792                $fieldGroup     = $field.closest($group),
793                validationRules = module.get.validation($field)
794              ;
795              if( $fieldGroup.hasClass(className.error) ) {
796                module.debug('Revalidating field', $field, validationRules);
797                module.validate.form.call(module, event, true);
798              }
799              else if(settings.on == 'blur' || settings.on == 'change') {
800                if(validationRules) {
801                  module.validate.field( validationRules );
802                }
803              }
804            },
805            change: function(event) {
806              var
807                $field      = $(this),
808                $fieldGroup = $field.closest($group)
809              ;
810              if(settings.on == 'change' || ( $fieldGroup.hasClass(className.error) && settings.revalidate) ) {
811                clearTimeout(module.timer);
812                module.timer = setTimeout(function() {
813                  module.debug('Revalidating field', $field,  module.get.validation($field));
814                  module.validate.form.call(module, event, true);
815                }, settings.delay);
816              }
817            }
818          }
819
820        },
821
822        get: {
823          ancillaryValue: function(rule) {
824            if(!rule.type || !module.is.bracketedRule(rule)) {
825              return false;
826            }
827            return rule.type.match(settings.regExp.bracket)[1] + '';
828          },
829          ruleName: function(rule) {
830            if( module.is.bracketedRule(rule) ) {
831              return rule.type.replace(rule.type.match(settings.regExp.bracket)[0], '');
832            }
833            return rule.type;
834          },
835          changeEvent: function(type, $input) {
836            if(type == 'checkbox' || type == 'radio' || type == 'hidden' || $input.is('select')) {
837              return 'change';
838            }
839            else {
840              return module.get.inputEvent();
841            }
842          },
843          inputEvent: function() {
844            return (document.createElement('input').oninput !== undefined)
845              ? 'input'
846              : (document.createElement('input').onpropertychange !== undefined)
847                ? 'propertychange'
848                : 'keyup'
849            ;
850          },
851          prompt: function(rule, field) {
852            var
853              ruleName      = module.get.ruleName(rule),
854              ancillary     = module.get.ancillaryValue(rule),
855              prompt        = rule.prompt || settings.prompt[ruleName] || settings.text.unspecifiedRule,
856              requiresValue = (prompt.search('{value}') !== -1),
857              requiresName  = (prompt.search('{name}') !== -1),
858              $label,
859              $field,
860              name
861            ;
862            if(requiresName || requiresValue) {
863              $field = module.get.field(field.identifier);
864            }
865            if(requiresValue) {
866              prompt = prompt.replace('{value}', $field.val());
867            }
868            if(requiresName) {
869              $label = $field.closest(selector.group).find('label').eq(0);
870              name = ($label.size() == 1)
871                ? $label.text()
872                : $field.prop('placeholder') || settings.text.unspecifiedField
873              ;
874              prompt = prompt.replace('{name}', name);
875            }
876            prompt = prompt.replace('{identifier}', field.identifier);
877            prompt = prompt.replace('{ruleValue}', ancillary);
878            if(!rule.prompt) {
879              module.verbose('Using default validation prompt for type', prompt, ruleName);
880            }
881            return prompt;
882          },
883          settings: function() {
884            if($.isPlainObject(parameters)) {
885              var
886                keys     = Object.keys(parameters),
887                isLegacySettings = (keys.length > 0)
888                  ? (parameters[keys[0]].identifier !== undefined && parameters[keys[0]].rules !== undefined)
889                  : false,
890                ruleKeys
891              ;
892              if(isLegacySettings) {
893                // 1.x (ducktyped)
894                settings   = $.extend(true, {}, $.fn.form.settings, legacyParameters);
895                validation = $.extend({}, $.fn.form.settings.defaults, parameters);
896                module.error(settings.error.oldSyntax, element);
897                module.verbose('Extending settings from legacy parameters', validation, settings);
898              }
899              else {
900                // 2.x
901                if(parameters.fields) {
902                  ruleKeys = Object.keys(parameters.fields);
903                  if( typeof parameters.fields[ruleKeys[0]] == 'string' || $.isArray(parameters.fields[ruleKeys[0]]) ) {
904                    $.each(parameters.fields, function(name, rules) {
905                      if(typeof rules == 'string') {
906                        rules = [rules];
907                      }
908                      parameters.fields[name] = {
909                        rules: []
910                      };
911                      $.each(rules, function(index, rule) {
912                        parameters.fields[name].rules.push({ type: rule });
913                      });
914                    });
915                  }
916                }
917
918                settings   = $.extend(true, {}, $.fn.form.settings, parameters);
919                validation = $.extend({}, $.fn.form.settings.defaults, settings.fields);
920                module.verbose('Extending settings', validation, settings);
921              }
922            }
923            else {
924              settings   = $.fn.form.settings;
925              validation = $.fn.form.settings.defaults;
926              module.verbose('Using default form validation', validation, settings);
927            }
928
929            // shorthand
930            namespace       = settings.namespace;
931            metadata        = settings.metadata;
932            selector        = settings.selector;
933            className       = settings.className;
934            error           = settings.error;
935            moduleNamespace = 'module-' + namespace;
936            eventNamespace  = '.' + namespace;
937
938            // grab instance
939            instance = $module.data(moduleNamespace);
940
941            // refresh selector cache
942            module.refresh();
943          },
944          field: function(identifier) {
945            module.verbose('Finding field with identifier', identifier);
946            if( $field.filter('#' + identifier).length > 0 ) {
947              return $field.filter('#' + identifier);
948            }
949            else if( $field.filter('[name="' + identifier +'"]').length > 0 ) {
950              return $field.filter('[name="' + identifier +'"]');
951            }
952            else if( $field.filter('[name="' + identifier +'[]"]').length > 0 ) {
953              return $field.filter('[name="' + identifier +'[]"]');
954            }
955            else if( $field.filter('[data-' + metadata.validate + '="'+ identifier +'"]').length > 0 ) {
956              return $field.filter('[data-' + metadata.validate + '="'+ identifier +'"]');
957            }
958            return $('<input/>');
959          },
960          fields: function(fields) {
961            var
962              $fields = $()
963            ;
964            $.each(fields, function(index, name) {
965              $fields = $fields.add( module.get.field(name) );
966            });
967            return $fields;
968          },
969          validation: function($field) {
970            var
971              fieldValidation,
972              identifier
973            ;
974            if(!validation) {
975              return false;
vendor: 9,712 bytes, lines 976-1258
976            }
977            $.each(validation, function(fieldName, field) {
978              identifier = field.identifier || fieldName;
979              if( module.get.field(identifier)[0] == $field[0] ) {
980                field.identifier = identifier;
981                fieldValidation = field;
982              }
983            });
984            return fieldValidation || false;
985          },
986          value: function (field) {
987            var
988              fields = [],
989              results
990            ;
991            fields.push(field);
992            results = module.get.values.call(element, fields);
993            return results[field];
994          },
995          values: function (fields) {
996            var
997              $fields = $.isArray(fields)
998                ? module.get.fields(fields)
999                : $field,
1000              values = {}
1001            ;
1002            $fields.each(function(index, field) {
1003              var
1004                $field     = $(field),
1005                type       = $field.prop('type'),
1006                name       = $field.prop('name'),
1007                value      = $field.val(),
1008                isCheckbox = $field.is(selector.checkbox),
1009                isRadio    = $field.is(selector.radio),
1010                isMultiple = (name.indexOf('[]') !== -1),
1011                isChecked  = (isCheckbox)
1012                  ? $field.is(':checked')
1013                  : false
1014              ;
1015              if(name) {
1016                if(isMultiple) {
1017                  name = name.replace('[]', '');
1018                  if(!values[name]) {
1019                    values[name] = [];
1020                  }
1021                  if(isCheckbox) {
1022                    if(isChecked) {
1023                      values[name].push(value || true);
1024                    }
1025                    else {
1026                      values[name].push(false);
1027                    }
1028                  }
1029                  else {
1030                    values[name].push(value);
1031                  }
1032                }
1033                else {
1034                  if(isRadio) {
1035                    if(isChecked) {
1036                      values[name] = value;
1037                    }
1038                  }
1039                  else if(isCheckbox) {
1040                    if(isChecked) {
1041                      values[name] = value || true;
1042                    }
1043                    else {
1044                      values[name] = false;
1045                    }
1046                  }
1047                  else {
1048                    values[name] = value;
1049                  }
1050                }
1051              }
1052            });
1053            return values;
1054          }
1055        },
1056
1057        has: {
1058
1059          field: function(identifier) {
1060            module.verbose('Checking for existence of a field with identifier', identifier);
1061            if(typeof identifier !== 'string') {
1062              module.error(error.identifier, identifier);
1063            }
1064            if( $field.filter('#' + identifier).length > 0 ) {
1065              return true;
1066            }
1067            else if( $field.filter('[name="' + identifier +'"]').length > 0 ) {
1068              return true;
1069            }
1070            else if( $field.filter('[data-' + metadata.validate + '="'+ identifier +'"]').length > 0 ) {
1071              return true;
1072            }
1073            return false;
1074          }
1075
1076        },
1077
1078        add: {
1079          prompt: function(identifier, errors) {
1080            var
1081              $field       = module.get.field(identifier),
1082              $fieldGroup  = $field.closest($group),
1083              $prompt      = $fieldGroup.children(selector.prompt),
1084              promptExists = ($prompt.length !== 0)
1085            ;
1086            errors = (typeof errors == 'string')
1087              ? [errors]
1088              : errors
1089            ;
1090            module.verbose('Adding field error state', identifier);
1091            $fieldGroup
1092              .addClass(className.error)
1093            ;
1094            if(settings.inline) {
1095              if(!promptExists) {
1096                $prompt = settings.templates.prompt(errors);
1097                $prompt
1098                  .appendTo($fieldGroup)
1099                ;
1100              }
1101              $prompt
1102                .html(errors[0])
1103              ;
1104              if(!promptExists) {
1105                if(settings.transition && $.fn.transition !== undefined && $module.transition('is supported')) {
1106                  module.verbose('Displaying error with css transition', settings.transition);
1107                  $prompt.transition(settings.transition + ' in', settings.duration);
1108                }
1109                else {
1110                  module.verbose('Displaying error with fallback javascript animation');
1111                  $prompt
1112                    .fadeIn(settings.duration)
1113                  ;
1114                }
1115              }
1116              else {
1117                module.verbose('Inline errors are disabled, no inline error added', identifier);
1118              }
1119            }
1120          },
1121          errors: function(errors) {
1122            module.debug('Adding form error messages', errors);
1123            module.set.error();
1124            $message
1125              .html( settings.templates.error(errors) )
1126            ;
1127          }
1128        },
1129
1130        remove: {
1131          prompt: function(identifier) {
1132            var
1133              $field      = module.get.field(identifier),
1134              $fieldGroup = $field.closest($group),
1135              $prompt     = $fieldGroup.children(selector.prompt)
1136            ;
1137            $fieldGroup
1138              .removeClass(className.error)
1139            ;
1140            if(settings.inline && $prompt.is(':visible')) {
1141              module.verbose('Removing prompt for field', identifier);
1142              if(settings.transition && $.fn.transition !== undefined && $module.transition('is supported')) {
1143                $prompt.transition(settings.transition + ' out', settings.duration, function() {
1144                  $prompt.remove();
1145                });
1146              }
1147              else {
1148                $prompt
1149                  .fadeOut(settings.duration, function(){
1150                    $prompt.remove();
1151                  })
1152                ;
1153              }
1154            }
1155          }
1156        },
1157
1158        set: {
1159          success: function() {
1160            $module
1161              .removeClass(className.error)
1162              .addClass(className.success)
1163            ;
1164          },
1165          defaults: function () {
1166            $field
1167              .each(function () {
1168                var
1169                  $field     = $(this),
1170                  isCheckbox = ($field.filter(selector.checkbox).length > 0),
1171                  value      = (isCheckbox)
1172                    ? $field.is(':checked')
1173                    : $field.val()
1174                ;
1175                $field.data(metadata.defaultValue, value);
1176              })
1177            ;
1178          },
1179          error: function() {
1180            $module
1181              .removeClass(className.success)
1182              .addClass(className.error)
1183            ;
1184          },
1185          value: function (field, value) {
1186            var
1187              fields = {}
1188            ;
1189            fields[field] = value;
1190            return module.set.values.call(element, fields);
1191          },
1192          values: function (fields) {
1193            if($.isEmptyObject(fields)) {
1194              return;
1195            }
1196            $.each(fields, function(key, value) {
1197              var
1198                $field      = module.get.field(key),
1199                $element    = $field.parent(),
1200                isMultiple  = $.isArray(value),
1201                isCheckbox  = $element.is(selector.uiCheckbox),
1202                isDropdown  = $element.is(selector.uiDropdown),
1203                isRadio     = ($field.is(selector.radio) && isCheckbox),
1204                fieldExists = ($field.length > 0),
1205                $multipleField
1206              ;
1207              if(fieldExists) {
1208                if(isMultiple && isCheckbox) {
1209                  module.verbose('Selecting multiple', value, $field);
1210                  $element.checkbox('uncheck');
1211                  $.each(value, function(index, value) {
1212                    $multipleField = $field.filter('[value="' + value + '"]');
1213                    $element       = $multipleField.parent();
1214                    if($multipleField.length > 0) {
1215                      $element.checkbox('check');
1216                    }
1217                  });
1218                }
1219                else if(isRadio) {
1220                  module.verbose('Selecting radio value', value, $field);
1221                  $field.filter('[value="' + value + '"]')
1222                    .parent(selector.uiCheckbox)
1223                      .checkbox('check')
1224                  ;
1225                }
1226                else if(isCheckbox) {
1227                  module.verbose('Setting checkbox value', value, $element);
1228                  if(value === true) {
1229                    $element.checkbox('check');
1230                  }
1231                  else {
1232                    $element.checkbox('uncheck');
1233                  }
1234                }
1235                else if(isDropdown) {
1236                  module.verbose('Setting dropdown value', value, $element);
1237                  $element.dropdown('set selected', value);
1238                }
1239                else {
1240                  module.verbose('Setting field value', value, $field);
1241                  $field.val(value);
1242                }
1243              }
1244            });
1245          }
1246        },
1247
1248        validate: {
1249
1250          form: function(event, ignoreCallbacks) {
1251            var
1252              values = module.get.values(),
1253              apiRequest
1254            ;
1255
1256            // input keydown event will fire submit repeatedly by browser default
1257            if(keyHeldDown) {
1258              return false;
vendor: 12,702 bytes, lines 1259-1611
1259            }
1260
1261            // reset errors
1262            formErrors = [];
1263            if( module.is.valid() ) {
1264              module.debug('Form has no validation errors, submitting');
1265              module.set.success();
1266              if(ignoreCallbacks !== true) {
1267                return settings.onSuccess.call(element, event, values);
1268              }
1269            }
1270            else {
1271              module.debug('Form has errors');
1272              module.set.error();
1273              if(!settings.inline) {
1274                module.add.errors(formErrors);
1275              }
1276              // prevent ajax submit
1277              if($module.data('moduleApi') !== undefined) {
1278                event.stopImmediatePropagation();
1279              }
1280              if(ignoreCallbacks !== true) {
1281                return settings.onFailure.call(element, formErrors, values);
1282              }
1283            }
1284          },
1285
1286          // takes a validation object and returns whether field passes validation
1287          field: function(field, fieldName) {
1288            var
1289              identifier  = field.identifier || fieldName,
1290              $field      = module.get.field(identifier),
1291              fieldValid  = true,
1292              fieldErrors = []
1293            ;
1294            if(!field.identifier) {
1295              module.debug('Using field name as identifier', identifier);
1296              field.identifier = identifier;
1297            }
1298            if($field.prop('disabled')) {
1299              module.debug('Field is disabled. Skipping', identifier);
1300              fieldValid = true;
1301            }
1302            else if(field.optional && $.trim($field.val()) === ''){
1303              module.debug('Field is optional and empty. Skipping', identifier);
1304              fieldValid = true;
1305            }
1306            else if(field.rules !== undefined) {
1307              $.each(field.rules, function(index, rule) {
1308                if( module.has.field(identifier) && !( module.validate.rule(field, rule) ) ) {
1309                  module.debug('Field is invalid', identifier, rule.type);
1310                  fieldErrors.push(module.get.prompt(rule, field));
1311                  fieldValid = false;
1312                }
1313              });
1314            }
1315            if(fieldValid) {
1316              module.remove.prompt(identifier, fieldErrors);
1317              settings.onValid.call($field);
1318            }
1319            else {
1320              formErrors = formErrors.concat(fieldErrors);
1321              module.add.prompt(identifier, fieldErrors);
1322              settings.onInvalid.call($field, fieldErrors);
1323              return false;
1324            }
1325            return true;
1326          },
1327
1328          // takes validation rule and returns whether field passes rule
1329          rule: function(field, rule) {
1330            var
1331              $field       = module.get.field(field.identifier),
1332              type         = rule.type,
1333              value        = $field.val(),
1334              isValid      = true,
1335              ancillary    = module.get.ancillaryValue(rule),
1336              ruleName     = module.get.ruleName(rule),
1337              ruleFunction = settings.rules[ruleName]
1338            ;
1339            if( !$.isFunction(ruleFunction) ) {
1340              module.error(error.noRule, ruleName);
1341              return;
1342            }
1343            // cast to string avoiding encoding special values
1344            value = (value === undefined || value === '' || value === null)
1345              ? ''
1346              : $.trim(value + '')
1347            ;
1348            return ruleFunction.call($field, value, ancillary);
1349          }
1350        },
1351
1352        setting: function(name, value) {
1353          if( $.isPlainObject(name) ) {
1354            $.extend(true, settings, name);
1355          }
1356          else if(value !== undefined) {
1357            settings[name] = value;
1358          }
1359          else {
1360            return settings[name];
1361          }
1362        },
1363        internal: function(name, value) {
1364          if( $.isPlainObject(name) ) {
1365            $.extend(true, module, name);
1366          }
1367          else if(value !== undefined) {
1368            module[name] = value;
1369          }
1370          else {
1371            return module[name];
1372          }
1373        },
1374        debug: function() {
1375          if(settings.debug) {
1376            if(settings.performance) {
1377              module.performance.log(arguments);
1378            }
1379            else {
1380              module.debug = Function.prototype.bind.call(console.info, console, settings.name + ':');
1381              module.debug.apply(console, arguments);
1382            }
1383          }
1384        },
1385        verbose: function() {
1386          if(settings.verbose && settings.debug) {
1387            if(settings.performance) {
1388              module.performance.log(arguments);
1389            }
1390            else {
1391              module.verbose = Function.prototype.bind.call(console.info, console, settings.name + ':');
1392              module.verbose.apply(console, arguments);
1393            }
1394          }
1395        },
1396        error: function() {
1397          module.error = Function.prototype.bind.call(console.error, console, settings.name + ':');
1398          module.error.apply(console, arguments);
1399        },
1400        performance: {
1401          log: function(message) {
1402            var
1403              currentTime,
1404              executionTime,
1405              previousTime
1406            ;
1407            if(settings.performance) {
1408              currentTime   = new Date().getTime();
1409              previousTime  = time || currentTime;
1410              executionTime = currentTime - previousTime;
1411              time          = currentTime;
1412              performance.push({
1413                'Name'           : message[0],
1414                'Arguments'      : [].slice.call(message, 1) || '',
1415                'Element'        : element,
1416                'Execution Time' : executionTime
1417              });
1418            }
1419            clearTimeout(module.performance.timer);
1420            module.performance.timer = setTimeout(module.performance.display, 500);
1421          },
1422          display: function() {
1423            var
1424              title = settings.name + ':',
1425              totalTime = 0
1426            ;
1427            time = false;
1428            clearTimeout(module.performance.timer);
1429            $.each(performance, function(index, data) {
1430              totalTime += data['Execution Time'];
1431            });
1432            title += ' ' + totalTime + 'ms';
1433            if(moduleSelector) {
1434              title += ' \'' + moduleSelector + '\'';
1435            }
1436            if($allModules.length > 1) {
1437              title += ' ' + '(' + $allModules.length + ')';
1438            }
1439            if( (console.group !== undefined || console.table !== undefined) && performance.length > 0) {
1440              console.groupCollapsed(title);
1441              if(console.table) {
1442                console.table(performance);
1443              }
1444              else {
1445                $.each(performance, function(index, data) {
1446                  console.log(data['Name'] + ': ' + data['Execution Time']+'ms');
1447                });
1448              }
1449              console.groupEnd();
1450            }
1451            performance = [];
1452          }
1453        },
1454        invoke: function(query, passedArguments, context) {
1455          var
1456            object = instance,
1457            maxDepth,
1458            found,
1459            response
1460          ;
1461          passedArguments = passedArguments || queryArguments;
1462          context         = element         || context;
1463          if(typeof query == 'string' && object !== undefined) {
1464            query    = query.split(/[\. ]/);
1465            maxDepth = query.length - 1;
1466            $.each(query, function(depth, value) {
1467              var camelCaseValue = (depth != maxDepth)
1468                ? value + query[depth + 1].charAt(0).toUpperCase() + query[depth + 1].slice(1)
1469                : query
1470              ;
1471              if( $.isPlainObject( object[camelCaseValue] ) && (depth != maxDepth) ) {
1472                object = object[camelCaseValue];
1473              }
1474              else if( object[camelCaseValue] !== undefined ) {
1475                found = object[camelCaseValue];
1476                return false;
1477              }
1478              else if( $.isPlainObject( object[value] ) && (depth != maxDepth) ) {
1479                object = object[value];
1480              }
1481              else if( object[value] !== undefined ) {
1482                found = object[value];
1483                return false;
1484              }
1485              else {
1486                return false;
1487              }
1488            });
1489          }
1490          if( $.isFunction( found ) ) {
1491            response = found.apply(context, passedArguments);
1492          }
1493          else if(found !== undefined) {
1494            response = found;
1495          }
1496          if($.isArray(returnedValue)) {
1497            returnedValue.push(response);
1498          }
1499          else if(returnedValue !== undefined) {
1500            returnedValue = [returnedValue, response];
1501          }
1502          else if(response !== undefined) {
1503            returnedValue = response;
1504          }
1505          return found;
1506        }
1507      };
1508      module.initialize();
1509    })
1510  ;
1511
1512  return (returnedValue !== undefined)
1513    ? returnedValue
1514    : this
1515  ;
1516};
1517
1518$.fn.form.settings = {
1519
1520  name              : 'Form',
1521  namespace         : 'form',
1522
1523  debug             : false,
1524  verbose           : false,
1525  performance       : true,
1526
1527  fields            : false,
1528
1529  keyboardShortcuts : true,
1530  on                : 'submit',
1531  inline            : false,
1532
1533  delay             : 200,
1534  revalidate        : true,
1535
1536  transition        : 'scale',
1537  duration          : 200,
1538
1539  onValid           : function() {},
1540  onInvalid         : function() {},
1541  onSuccess         : function() { return true; },
1542  onFailure         : function() { return false; },
1543
1544  metadata : {
1545    defaultValue : 'default',
1546    validate     : 'validate'
1547  },
1548
1549  regExp: {
1550    bracket : /\[(.*)\]/i,
1551    decimal : /^\d*(\.)\d+/,
1552    email   : "[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?",
1553    escape  : /[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g,
1554    flags   : /^\/(.*)\/(.*)?/,
1555    integer : /^\-?\d+$/,
1556    number  : /^\-?\d*(\.\d+)?$/,
1557    url     : /(https?:\/\/(?:www\.|(?!www))[^\s\.]+\.[^\s]{2,}|www\.[^\s]+\.[^\s]{2,})/i
1558  },
1559
1560  text: {
1561    unspecifiedRule  : 'Please enter a valid value',
1562    unspecifiedField : 'This field'
1563  },
1564
1565  prompt: {
1566    empty                : '{name} must have a value',
1567    checked              : '{name} must be checked',
1568    email                : '{name} must be a valid e-mail',
1569    url                  : '{name} must be a valid url',
1570    regExp               : '{name} is not formatted correctly',
1571    integer              : '{name} must be an integer',
1572    decimal              : '{name} must be a decimal number',
1573    number               : '{name} must be set to a number',
1574    is                   : '{name} must be "{ruleValue}"',
1575    isExactly            : '{name} must be exactly "{ruleValue}"',
1576    not                  : '{name} cannot be set to "{ruleValue}"',
1577    notExactly           : '{name} cannot be set to exactly "{ruleValue}"',
1578    contain              : '{name} cannot contain "{ruleValue}"',
1579    containExactly       : '{name} cannot contain exactly "{ruleValue}"',
1580    doesntContain        : '{name} must contain  "{ruleValue}"',
1581    doesntContainExactly : '{name} must contain exactly "{ruleValue}"',
1582    minLength            : '{name} must be at least {ruleValue} characters',
1583    length               : '{name} must be at least {ruleValue} characters',
1584    exactLength          : '{name} must be exactly {ruleValue} characters',
1585    maxLength            : '{name} cannot be longer than {ruleValue} characters',
1586    match                : '{name} must match {ruleValue} field',
1587    different            : '{name} must have a different value than {ruleValue} field',
1588    creditCard           : '{name} must be a valid credit card number',
1589    minCount             : '{name} must have at least {ruleValue} choices',
1590    exactCount           : '{name} must have exactly {ruleValue} choices',
1591    maxCount             : '{name} must have {ruleValue} or less choices'
1592  },
1593
1594  selector : {
1595    checkbox   : 'input[type="checkbox"], input[type="radio"]',
1596    clear      : '.clear',
1597    field      : 'input, textarea, select',
1598    group      : '.field',
1599    input      : 'input',
1600    message    : '.error.message',
1601    prompt     : '.prompt.label',
1602    radio      : 'input[type="radio"]',
1603    reset      : '.reset:not([type="reset"])',
1604    submit     : '.submit:not([type="submit"])',
1605    uiCheckbox : '.ui.checkbox',
1606    uiDropdown : '.ui.dropdown'
1607  },
1608
1609  className : {
1610    error   : 'error',
1611    label   : 'ui prompt label',
vendor: 9,094 bytes, lines 1612-1941
1612    pressed : 'down',
1613    success : 'success'
1614  },
1615
1616  error: {
1617    identifier : 'You must specify a string identifier for each field',
1618    method     : 'The method you called is not defined.',
1619    noRule     : 'There is no rule matching the one you specified',
1620    oldSyntax  : 'Starting in 2.0 forms now only take a single settings object. Validation settings converted to new syntax automatically.'
1621  },
1622
1623  templates: {
1624
1625    // template that produces error message
1626    error: function(errors) {
1627      var
1628        html = '<ul class="list">'
1629      ;
1630      $.each(errors, function(index, value) {
1631        html += '<li>' + value + '</li>';
1632      });
1633      html += '</ul>';
1634      return $(html);
1635    },
1636
1637    // template that produces label
1638    prompt: function(errors) {
1639      return $('<div/>')
1640        .addClass('ui basic red pointing prompt label')
1641        .html(errors[0])
1642      ;
1643    }
1644  },
1645
1646  rules: {
1647
1648    // is not empty or blank string
1649    empty: function(value) {
1650      return !(value === undefined || '' === value || $.isArray(value) && value.length === 0);
1651    },
1652
1653    // checkbox checked
1654    checked: function() {
1655      return ($(this).filter(':checked').length > 0);
1656    },
1657
1658    // is most likely an email
1659    email: function(value){
1660      var
1661        emailRegExp = new RegExp($.fn.form.settings.regExp.email, 'i')
1662      ;
1663      return emailRegExp.test(value);
1664    },
1665
1666    // value is most likely url
1667    url: function(value) {
1668      return $.fn.form.settings.regExp.url.test(value);
1669    },
1670
1671    // matches specified regExp
1672    regExp: function(value, regExp) {
1673      var
1674        regExpParts = regExp.match($.fn.form.settings.regExp.flags),
1675        flags
1676      ;
1677      // regular expression specified as /baz/gi (flags)
1678      if(regExpParts) {
1679        regExp = (regExpParts.length >= 2)
1680          ? regExpParts[1]
1681          : regExp
1682        ;
1683        flags = (regExpParts.length >= 3)
1684          ? regExpParts[2]
1685          : ''
1686        ;
1687      }
1688      return value.match( new RegExp(regExp, flags) );
1689    },
1690
1691    // is valid integer or matches range
1692    integer: function(value, range) {
1693      var
1694        intRegExp = $.fn.form.settings.regExp.integer,
1695        min,
1696        max,
1697        parts
1698      ;
1699      if( !range || ['', '..'].indexOf(range) !== -1) {
1700        // do nothing
1701      }
1702      else if(range.indexOf('..') == -1) {
1703        if(intRegExp.test(range)) {
1704          min = max = range - 0;
1705        }
1706      }
1707      else {
1708        parts = range.split('..', 2);
1709        if(intRegExp.test(parts[0])) {
1710          min = parts[0] - 0;
1711        }
1712        if(intRegExp.test(parts[1])) {
1713          max = parts[1] - 0;
1714        }
1715      }
1716      return (
1717        intRegExp.test(value) &&
1718        (min === undefined || value >= min) &&
1719        (max === undefined || value <= max)
1720      );
1721    },
1722
1723    // is valid number (with decimal)
1724    decimal: function(value) {
1725      return $.fn.form.settings.regExp.decimal.test(value);
1726    },
1727
1728    // is valid number
1729    number: function(value) {
1730      return $.fn.form.settings.regExp.number.test(value);
1731    },
1732
1733    // is value (case insensitive)
1734    is: function(value, text) {
1735      text = (typeof text == 'string')
1736        ? text.toLowerCase()
1737        : text
1738      ;
1739      value = (typeof value == 'string')
1740        ? value.toLowerCase()
1741        : value
1742      ;
1743      return (value == text);
1744    },
1745
1746    // is value
1747    isExactly: function(value, text) {
1748      return (value == text);
1749    },
1750
1751    // value is not another value (case insensitive)
1752    not: function(value, notValue) {
1753      value = (typeof value == 'string')
1754        ? value.toLowerCase()
1755        : value
1756      ;
1757      notValue = (typeof notValue == 'string')
1758        ? notValue.toLowerCase()
1759        : notValue
1760      ;
1761      return (value != notValue);
1762    },
1763
1764    // value is not another value (case sensitive)
1765    notExactly: function(value, notValue) {
1766      return (value != notValue);
1767    },
1768
1769    // value contains text (insensitive)
1770    contains: function(value, text) {
1771      // escape regex characters
1772      text = text.replace($.fn.form.settings.regExp.escape, "\\$&");
1773      return (value.search( new RegExp(text, 'i') ) !== -1);
1774    },
1775
1776    // value contains text (case sensitive)
1777    containsExactly: function(value, text) {
1778      // escape regex characters
1779      text = text.replace($.fn.form.settings.regExp.escape, "\\$&");
1780      return (value.search( new RegExp(text) ) !== -1);
1781    },
1782
1783    // value contains text (insensitive)
1784    doesntContain: function(value, text) {
1785      // escape regex characters
1786      text = text.replace($.fn.form.settings.regExp.escape, "\\$&");
1787      return (value.search( new RegExp(text, 'i') ) === -1);
1788    },
1789
1790    // value contains text (case sensitive)
1791    doesntContainExactly: function(value, text) {
1792      // escape regex characters
1793      text = text.replace($.fn.form.settings.regExp.escape, "\\$&");
1794      return (value.search( new RegExp(text) ) === -1);
1795    },
1796
1797    // is at least string length
1798    minLength: function(value, requiredLength) {
1799      return (value !== undefined)
1800        ? (value.length >= requiredLength)
1801        : false
1802      ;
1803    },
1804
1805    // see rls notes for 2.0.6 (this is a duplicate of minLength)
1806    length: function(value, requiredLength) {
1807      return (value !== undefined)
1808        ? (value.length >= requiredLength)
1809        : false
1810      ;
1811    },
1812
1813    // is exactly length
1814    exactLength: function(value, requiredLength) {
1815      return (value !== undefined)
1816        ? (value.length == requiredLength)
1817        : false
1818      ;
1819    },
1820
1821    // is less than length
1822    maxLength: function(value, maxLength) {
1823      return (value !== undefined)
1824        ? (value.length <= maxLength)
1825        : false
1826      ;
1827    },
1828
1829    // matches another field
1830    match: function(value, identifier) {
1831      var
1832        $form = $(this),
1833        matchingValue
1834      ;
1835      if( $('[data-validate="'+ identifier +'"]').length > 0 ) {
1836        matchingValue = $('[data-validate="'+ identifier +'"]').val();
1837      }
1838      else if($('#' + identifier).length > 0) {
1839        matchingValue = $('#' + identifier).val();
1840      }
1841      else if($('[name="' + identifier +'"]').length > 0) {
1842        matchingValue = $('[name="' + identifier + '"]').val();
1843      }
1844      else if( $('[name="' + identifier +'[]"]').length > 0 ) {
1845        matchingValue = $('[name="' + identifier +'[]"]');
1846      }
1847      return (matchingValue !== undefined)
1848        ? ( value.toString() == matchingValue.toString() )
1849        : false
1850      ;
1851    },
1852
1853    // different than another field
1854    different: function(value, identifier) {
1855      // use either id or name of field
1856      var
1857        $form = $(this),
1858        matchingValue
1859      ;
1860      if( $('[data-validate="'+ identifier +'"]').length > 0 ) {
1861        matchingValue = $('[data-validate="'+ identifier +'"]').val();
1862      }
1863      else if($('#' + identifier).length > 0) {
1864        matchingValue = $('#' + identifier).val();
1865      }
1866      else if($('[name="' + identifier +'"]').length > 0) {
1867        matchingValue = $('[name="' + identifier + '"]').val();
1868      }
1869      else if( $('[name="' + identifier +'[]"]').length > 0 ) {
1870        matchingValue = $('[name="' + identifier +'[]"]');
1871      }
1872      return (matchingValue !== undefined)
1873        ? ( value.toString() !== matchingValue.toString() )
1874        : false
1875      ;
1876    },
1877
1878    creditCard: function(cardNumber, cardTypes) {
1879      var
1880        cards = {
1881          visa: {
1882            pattern : /^4/,
1883            length  : [16]
1884          },
1885          amex: {
1886            pattern : /^3[47]/,
1887            length  : [15]
1888          },
1889          mastercard: {
1890            pattern : /^5[1-5]/,
1891            length  : [16]
1892          },
1893          discover: {
1894            pattern : /^(6011|622(12[6-9]|1[3-9][0-9]|[2-8][0-9]{2}|9[0-1][0-9]|92[0-5]|64[4-9])|65)/,
1895            length  : [16]
1896          },
1897          unionPay: {
1898            pattern : /^(62|88)/,
1899            length  : [16, 17, 18, 19]
1900          },
1901          jcb: {
1902            pattern : /^35(2[89]|[3-8][0-9])/,
1903            length  : [16]
1904          },
1905          maestro: {
1906            pattern : /^(5018|5020|5038|6304|6759|676[1-3])/,
1907            length  : [12, 13, 14, 15, 16, 17, 18, 19]
1908          },
1909          dinersClub: {
1910            pattern : /^(30[0-5]|^36)/,
1911            length  : [14]
1912          },
1913          laser: {
1914            pattern : /^(6304|670[69]|6771)/,
1915            length  : [16, 17, 18, 19]
1916          },
1917          visaElectron: {
1918            pattern : /^(4026|417500|4508|4844|491(3|7))/,
1919            length  : [16]
1920          }
1921        },
1922        valid         = {},
1923        validCard     = false,
1924        requiredTypes = (typeof cardTypes == 'string')
1925          ? cardTypes.split(',')
1926          : false,
1927        unionPay,
1928        validation
1929      ;
1930
1931      if(typeof cardNumber !== 'string' || cardNumber.length === 0) {
1932        return;
1933      }
1934
1935      // verify card types
1936      if(requiredTypes) {
1937        $.each(requiredTypes, function(index, type){
1938          // verify each card type
1939          validation = cards[type];
1940          if(validation) {
1941            valid = {
vendor: 25,894 bytes, lines 1942-2771
1942              length  : ($.inArray(cardNumber.length, validation.length) !== -1),
1943              pattern : (cardNumber.search(validation.pattern) !== -1)
1944            };
1945            if(valid.length && valid.pattern) {
1946              validCard = true;
1947            }
1948          }
1949        });
1950
1951        if(!validCard) {
1952          return false;
1953        }
1954      }
1955
1956      // skip luhn for UnionPay
1957      unionPay = {
1958        number  : ($.inArray(cardNumber.length, cards.unionPay.length) !== -1),
1959        pattern : (cardNumber.search(cards.unionPay.pattern) !== -1)
1960      };
1961      if(unionPay.number && unionPay.pattern) {
1962        return true;
1963      }
1964
1965      // verify luhn, adapted from  <https://gist.github.com/2134376>
1966      var
1967        length        = cardNumber.length,
1968        multiple      = 0,
1969        producedValue = [
1970          [0, 1, 2, 3, 4, 5, 6, 7, 8, 9],
1971          [0, 2, 4, 6, 8, 1, 3, 5, 7, 9]
1972        ],
1973        sum           = 0
1974      ;
1975      while (length--) {
1976        sum += producedValue[multiple][parseInt(cardNumber.charAt(length), 10)];
1977        multiple ^= 1;
1978      }
1979      return (sum % 10 === 0 && sum > 0);
1980    },
1981
1982    minCount: function(value, minCount) {
1983      if(minCount == 0) {
1984        return true;
1985      }
1986      if(minCount == 1) {
1987        return (value !== '');
1988      }
1989      return (value.split(',').length >= minCount);
1990    },
1991
1992    exactCount: function(value, exactCount) {
1993      if(exactCount == 0) {
1994        return (value === '');
1995      }
1996      if(exactCount == 1) {
1997        return (value !== '' && value.search(',') === -1);
1998      }
1999      return (value.split(',').length == exactCount);
2000    },
2001
2002    maxCount: function(value, maxCount) {
2003      if(maxCount == 0) {
2004        return false;
2005      }
2006      if(maxCount == 1) {
2007        return (value.search(',') === -1);
2008      }
2009      return (value.split(',').length <= maxCount);
2010    }
2011  }
2012
2013};
2014
2015})( jQuery, window, document );
2016
2017/*!
2018 * # Semantic UI 2.1.7 - Accordion
2019 * http://github.com/semantic-org/semantic-ui/
2020 *
2021 *
2022 * Copyright 2015 Contributors
2023 * Released under the MIT license
2024 * http://opensource.org/licenses/MIT
2025 *
2026 */
2027
2028;(function ($, window, document, undefined) {
2029
2030"use strict";
2031
2032$.fn.accordion = function(parameters) {
2033  var
2034    $allModules     = $(this),
2035
2036    time            = new Date().getTime(),
2037    performance     = [],
2038
2039    query           = arguments[0],
2040    methodInvoked   = (typeof query == 'string'),
2041    queryArguments  = [].slice.call(arguments, 1),
2042
2043    requestAnimationFrame = window.requestAnimationFrame
2044      || window.mozRequestAnimationFrame
2045      || window.webkitRequestAnimationFrame
2046      || window.msRequestAnimationFrame
2047      || function(callback) { setTimeout(callback, 0); },
2048
2049    returnedValue
2050  ;
2051  $allModules
2052    .each(function() {
2053      var
2054        settings        = ( $.isPlainObject(parameters) )
2055          ? $.extend(true, {}, $.fn.accordion.settings, parameters)
2056          : $.extend({}, $.fn.accordion.settings),
2057
2058        className       = settings.className,
2059        namespace       = settings.namespace,
2060        selector        = settings.selector,
2061        error           = settings.error,
2062
2063        eventNamespace  = '.' + namespace,
2064        moduleNamespace = 'module-' + namespace,
2065        moduleSelector  = $allModules.selector || '',
2066
2067        $module  = $(this),
2068        $title   = $module.find(selector.title),
2069        $content = $module.find(selector.content),
2070
2071        element  = this,
2072        instance = $module.data(moduleNamespace),
2073        observer,
2074        module
2075      ;
2076
2077      module = {
2078
2079        initialize: function() {
2080          module.debug('Initializing', $module);
2081          module.bind.events();
2082          if(settings.observeChanges) {
2083            module.observeChanges();
2084          }
2085          module.instantiate();
2086        },
2087
2088        instantiate: function() {
2089          instance = module;
2090          $module
2091            .data(moduleNamespace, module)
2092          ;
2093        },
2094
2095        destroy: function() {
2096          module.debug('Destroying previous instance', $module);
2097          $module
2098            .off(eventNamespace)
2099            .removeData(moduleNamespace)
2100          ;
2101        },
2102
2103        refresh: function() {
2104          $title   = $module.find(selector.title);
2105          $content = $module.find(selector.content);
2106        },
2107
2108        observeChanges: function() {
2109          if('MutationObserver' in window) {
2110            observer = new MutationObserver(function(mutations) {
2111              module.debug('DOM tree modified, updating selector cache');
2112              module.refresh();
2113            });
2114            observer.observe(element, {
2115              childList : true,
2116              subtree   : true
2117            });
2118            module.debug('Setting up mutation observer', observer);
2119          }
2120        },
2121
2122        bind: {
2123          events: function() {
2124            module.debug('Binding delegated events');
2125            $module
2126              .on(settings.on + eventNamespace, selector.trigger, module.event.click)
2127            ;
2128          }
2129        },
2130
2131        event: {
2132          click: function() {
2133            module.toggle.call(this);
2134          }
2135        },
2136
2137        toggle: function(query) {
2138          var
2139            $activeTitle = (query !== undefined)
2140              ? (typeof query === 'number')
2141                ? $title.eq(query)
2142                : $(query).closest(selector.title)
2143              : $(this).closest(selector.title),
2144            $activeContent = $activeTitle.next($content),
2145            isAnimating = $activeContent.hasClass(className.animating),
2146            isActive    = $activeContent.hasClass(className.active),
2147            isOpen      = (isActive && !isAnimating),
2148            isOpening   = (!isActive && isAnimating)
2149          ;
2150          module.debug('Toggling visibility of content', $activeTitle);
2151          if(isOpen || isOpening) {
2152            if(settings.collapsible) {
2153              module.close.call($activeTitle);
2154            }
2155            else {
2156              module.debug('Cannot close accordion content collapsing is disabled');
2157            }
2158          }
2159          else {
2160            module.open.call($activeTitle);
2161          }
2162        },
2163
2164        open: function(query) {
2165          var
2166            $activeTitle = (query !== undefined)
2167              ? (typeof query === 'number')
2168                ? $title.eq(query)
2169                : $(query).closest(selector.title)
2170              : $(this).closest(selector.title),
2171            $activeContent = $activeTitle.next($content),
2172            isAnimating = $activeContent.hasClass(className.animating),
2173            isActive    = $activeContent.hasClass(className.active),
2174            isOpen      = (isActive || isAnimating)
2175          ;
2176          if(isOpen) {
2177            module.debug('Accordion already open, skipping', $activeContent);
2178            return;
2179          }
2180          module.debug('Opening accordion content', $activeTitle);
2181          settings.onOpening.call($activeContent);
2182          if(settings.exclusive) {
2183            module.closeOthers.call($activeTitle);
2184          }
2185          $activeTitle
2186            .addClass(className.active)
2187          ;
2188          $activeContent
2189            .stop(true, true)
2190            .addClass(className.animating)
2191          ;
2192          if(settings.animateChildren) {
2193            if($.fn.transition !== undefined && $module.transition('is supported')) {
2194              $activeContent
2195                .children()
2196                  .transition({
2197                    animation   : 'fade in',
2198                    queue       : false,
2199                    useFailSafe : true,
2200                    debug       : settings.debug,
2201                    verbose     : settings.verbose,
2202                    duration    : settings.duration
2203                  })
2204              ;
2205            }
2206            else {
2207              $activeContent
2208                .children()
2209                  .stop(true, true)
2210                  .animate({
2211                    opacity: 1
2212                  }, settings.duration, module.resetOpacity)
2213              ;
2214            }
2215          }
2216          $activeContent
2217            .slideDown(settings.duration, settings.easing, function() {
2218              $activeContent
2219                .removeClass(className.animating)
2220                .addClass(className.active)
2221              ;
2222              module.reset.display.call(this);
2223              settings.onOpen.call(this);
2224              settings.onChange.call(this);
2225            })
2226          ;
2227        },
2228
2229        close: function(query) {
2230          var
2231            $activeTitle = (query !== undefined)
2232              ? (typeof query === 'number')
2233                ? $title.eq(query)
2234                : $(query).closest(selector.title)
2235              : $(this).closest(selector.title),
2236            $activeContent = $activeTitle.next($content),
2237            isAnimating    = $activeContent.hasClass(className.animating),
2238            isActive       = $activeContent.hasClass(className.active),
2239            isOpening      = (!isActive && isAnimating),
2240            isClosing      = (isActive && isAnimating)
2241          ;
2242          if((isActive || isOpening) && !isClosing) {
2243            module.debug('Closing accordion content', $activeContent);
2244            settings.onClosing.call($activeContent);
2245            $activeTitle
2246              .removeClass(className.active)
2247            ;
2248            $activeContent
2249              .stop(true, true)
2250              .addClass(className.animating)
2251            ;
2252            if(settings.animateChildren) {
2253              if($.fn.transition !== undefined && $module.transition('is supported')) {
2254                $activeContent
2255                  .children()
2256                    .transition({
2257                      animation   : 'fade out',
2258                      queue       : false,
2259                      useFailSafe : true,
2260                      debug       : settings.debug,
2261                      verbose     : settings.verbose,
2262                      duration    : settings.duration
2263                    })
2264                ;
2265              }
2266              else {
2267                $activeContent
2268                  .children()
2269                    .stop(true, true)
2270                    .animate({
2271                      opacity: 0
2272                    }, settings.duration, module.resetOpacity)
2273                ;
2274              }
2275            }
2276            $activeContent
2277              .slideUp(settings.duration, settings.easing, function() {
2278                $activeContent
2279                  .removeClass(className.animating)
2280                  .removeClass(className.active)
2281                ;
2282                module.reset.display.call(this);
2283                settings.onClose.call(this);
2284                settings.onChange.call(this);
2285              })
2286            ;
2287          }
2288        },
2289
2290        closeOthers: function(index) {
2291          var
2292            $activeTitle = (index !== undefined)
2293              ? $title.eq(index)
2294              : $(this).closest(selector.title),
2295            $parentTitles    = $activeTitle.parents(selector.content).prev(selector.title),
2296            $activeAccordion = $activeTitle.closest(selector.accordion),
2297            activeSelector   = selector.title + '.' + className.active + ':visible',
2298            activeContent    = selector.content + '.' + className.active + ':visible',
2299            $openTitles,
2300            $nestedTitles,
2301            $openContents
2302          ;
2303          if(settings.closeNested) {
2304            $openTitles   = $activeAccordion.find(activeSelector).not($parentTitles);
2305            $openContents = $openTitles.next($content);
2306          }
2307          else {
2308            $openTitles   = $activeAccordion.find(activeSelector).not($parentTitles);
2309            $nestedTitles = $activeAccordion.find(activeContent).find(activeSelector).not($parentTitles);
2310            $openTitles   = $openTitles.not($nestedTitles);
2311            $openContents = $openTitles.next($content);
2312          }
2313          if( ($openTitles.length > 0) ) {
2314            module.debug('Exclusive enabled, closing other content', $openTitles);
2315            $openTitles
2316              .removeClass(className.active)
2317            ;
2318            $openContents
2319              .removeClass(className.animating)
2320              .stop(true, true)
2321            ;
2322            if(settings.animateChildren) {
2323              if($.fn.transition !== undefined && $module.transition('is supported')) {
2324                $openContents
2325                  .children()
2326                    .transition({
2327                      animation   : 'fade out',
2328                      useFailSafe : true,
2329                      debug       : settings.debug,
2330                      verbose     : settings.verbose,
2331                      duration    : settings.duration
2332                    })
2333                ;
2334              }
2335              else {
2336                $openContents
2337                  .children()
2338                    .stop(true, true)
2339                    .animate({
2340                      opacity: 0
2341                    }, settings.duration, module.resetOpacity)
2342                ;
2343              }
2344            }
2345            $openContents
2346              .slideUp(settings.duration , settings.easing, function() {
2347                $(this).removeClass(className.active);
2348                module.reset.display.call(this);
2349              })
2350            ;
2351          }
2352        },
2353
2354        reset: {
2355
2356          display: function() {
2357            module.verbose('Removing inline display from element', this);
2358            $(this).css('display', '');
2359            if( $(this).attr('style') === '') {
2360              $(this)
2361                .attr('style', '')
2362                .removeAttr('style')
2363              ;
2364            }
2365          },
2366
2367          opacity: function() {
2368            module.verbose('Removing inline opacity from element', this);
2369            $(this).css('opacity', '');
2370            if( $(this).attr('style') === '') {
2371              $(this)
2372                .attr('style', '')
2373                .removeAttr('style')
2374              ;
2375            }
2376          },
2377
2378        },
2379
2380        setting: function(name, value) {
2381          module.debug('Changing setting', name, value);
2382          if( $.isPlainObject(name) ) {
2383            $.extend(true, settings, name);
2384          }
2385          else if(value !== undefined) {
2386            settings[name] = value;
2387          }
2388          else {
2389            return settings[name];
2390          }
2391        },
2392        internal: function(name, value) {
2393          module.debug('Changing internal', name, value);
2394          if(value !== undefined) {
2395            if( $.isPlainObject(name) ) {
2396              $.extend(true, module, name);
2397            }
2398            else {
2399              module[name] = value;
2400            }
2401          }
2402          else {
2403            return module[name];
2404          }
2405        },
2406        debug: function() {
2407          if(settings.debug) {
2408            if(settings.performance) {
2409              module.performance.log(arguments);
2410            }
2411            else {
2412              module.debug = Function.prototype.bind.call(console.info, console, settings.name + ':');
2413              module.debug.apply(console, arguments);
2414            }
2415          }
2416        },
2417        verbose: function() {
2418          if(settings.verbose && settings.debug) {
2419            if(settings.performance) {
2420              module.performance.log(arguments);
2421            }
2422            else {
2423              module.verbose = Function.prototype.bind.call(console.info, console, settings.name + ':');
2424              module.verbose.apply(console, arguments);
2425            }
2426          }
2427        },
2428        error: function() {
2429          module.error = Function.prototype.bind.call(console.error, console, settings.name + ':');
2430          module.error.apply(console, arguments);
2431        },
2432        performance: {
2433          log: function(message) {
2434            var
2435              currentTime,
2436              executionTime,
2437              previousTime
2438            ;
2439            if(settings.performance) {
2440              currentTime   = new Date().getTime();
2441              previousTime  = time || currentTime;
2442              executionTime = currentTime - previousTime;
2443              time          = currentTime;
2444              performance.push({
2445                'Name'           : message[0],
2446                'Arguments'      : [].slice.call(message, 1) || '',
2447                'Element'        : element,
2448                'Execution Time' : executionTime
2449              });
2450            }
2451            clearTimeout(module.performance.timer);
2452            module.performance.timer = setTimeout(module.performance.display, 500);
2453          },
2454          display: function() {
2455            var
2456              title = settings.name + ':',
2457              totalTime = 0
2458            ;
2459            time = false;
2460            clearTimeout(module.performance.timer);
2461            $.each(performance, function(index, data) {
2462              totalTime += data['Execution Time'];
2463            });
2464            title += ' ' + totalTime + 'ms';
2465            if(moduleSelector) {
2466              title += ' \'' + moduleSelector + '\'';
2467            }
2468            if( (console.group !== undefined || console.table !== undefined) && performance.length > 0) {
2469              console.groupCollapsed(title);
2470              if(console.table) {
2471                console.table(performance);
2472              }
2473              else {
2474                $.each(performance, function(index, data) {
2475                  console.log(data['Name'] + ': ' + data['Execution Time']+'ms');
2476                });
2477              }
2478              console.groupEnd();
2479            }
2480            performance = [];
2481          }
2482        },
2483        invoke: function(query, passedArguments, context) {
2484          var
2485            object = instance,
2486            maxDepth,
2487            found,
2488            response
2489          ;
2490          passedArguments = passedArguments || queryArguments;
2491          context         = element         || context;
2492          if(typeof query == 'string' && object !== undefined) {
2493            query    = query.split(/[\. ]/);
2494            maxDepth = query.length - 1;
2495            $.each(query, function(depth, value) {
2496              var camelCaseValue = (depth != maxDepth)
2497                ? value + query[depth + 1].charAt(0).toUpperCase() + query[depth + 1].slice(1)
2498                : query
2499              ;
2500              if( $.isPlainObject( object[camelCaseValue] ) && (depth != maxDepth) ) {
2501                object = object[camelCaseValue];
2502              }
2503              else if( object[camelCaseValue] !== undefined ) {
2504                found = object[camelCaseValue];
2505                return false;
2506              }
2507              else if( $.isPlainObject( object[value] ) && (depth != maxDepth) ) {
2508                object = object[value];
2509              }
2510              else if( object[value] !== undefined ) {
2511                found = object[value];
2512                return false;
2513              }
2514              else {
2515                module.error(error.method, query);
2516                return false;
2517              }
2518            });
2519          }
2520          if ( $.isFunction( found ) ) {
2521            response = found.apply(context, passedArguments);
2522          }
2523          else if(found !== undefined) {
2524            response = found;
2525          }
2526          if($.isArray(returnedValue)) {
2527            returnedValue.push(response);
2528          }
2529          else if(returnedValue !== undefined) {
2530            returnedValue = [returnedValue, response];
2531          }
2532          else if(response !== undefined) {
2533            returnedValue = response;
2534          }
2535          return found;
2536        }
2537      };
2538      if(methodInvoked) {
2539        if(instance === undefined) {
2540          module.initialize();
2541        }
2542        module.invoke(query);
2543      }
2544      else {
2545        if(instance !== undefined) {
2546          instance.invoke('destroy');
2547        }
2548        module.initialize();
2549      }
2550    })
2551  ;
2552  return (returnedValue !== undefined)
2553    ? returnedValue
2554    : this
2555  ;
2556};
2557
2558$.fn.accordion.settings = {
2559
2560  name            : 'Accordion',
2561  namespace       : 'accordion',
2562
2563  debug           : false,
2564  verbose         : false,
2565  performance     : true,
2566
2567  on              : 'click', // event on title that opens accordion
2568
2569  observeChanges  : true,  // whether accordion should automatically refresh on DOM insertion
2570
2571  exclusive       : true,  // whether a single accordion content panel should be open at once
2572  collapsible     : true,  // whether accordion content can be closed
2573  closeNested     : false, // whether nested content should be closed when a panel is closed
2574  animateChildren : true,  // whether children opacity should be animated
2575
2576  duration        : 350, // duration of animation
2577  easing          : 'easeOutQuad', // easing equation for animation
2578
2579
2580  onOpening       : function(){}, // callback before open animation
2581  onOpen          : function(){}, // callback after open animation
2582  onClosing       : function(){}, // callback before closing animation
2583  onClose         : function(){}, // callback after closing animation
2584  onChange        : function(){}, // callback after closing or opening animation
2585
2586  error: {
2587    method : 'The method you called is not defined'
2588  },
2589
2590  className   : {
2591    active    : 'active',
2592    animating : 'animating'
2593  },
2594
2595  selector    : {
2596    accordion : '.accordion',
2597    title     : '.title',
2598    trigger   : '.title',
2599    content   : '.content'
2600  }
2601
2602};
2603
2604// Adds easing
2605$.extend( $.easing, {
2606  easeOutQuad: function (x, t, b, c, d) {
2607    return -c *(t/=d)*(t-2) + b;
2608  }
2609});
2610
2611})( jQuery, window, document );
2612
2613
2614/*!
2615 * # Semantic UI 2.1.7 - Checkbox
2616 * http://github.com/semantic-org/semantic-ui/
2617 *
2618 *
2619 * Copyright 2015 Contributors
2620 * Released under the MIT license
2621 * http://opensource.org/licenses/MIT
2622 *
2623 */
2624
2625;(function ( $, window, document, undefined ) {
2626
2627"use strict";
2628
2629$.fn.checkbox = function(parameters) {
2630  var
2631    $allModules    = $(this),
2632    moduleSelector = $allModules.selector || '',
2633
2634    time           = new Date().getTime(),
2635    performance    = [],
2636
2637    query          = arguments[0],
2638    methodInvoked  = (typeof query == 'string'),
2639    queryArguments = [].slice.call(arguments, 1),
2640    returnedValue
2641  ;
2642
2643  $allModules
2644    .each(function() {
2645      var
2646        settings        = $.extend(true, {}, $.fn.checkbox.settings, parameters),
2647
2648        className       = settings.className,
2649        namespace       = settings.namespace,
2650        selector        = settings.selector,
2651        error           = settings.error,
2652
2653        eventNamespace  = '.' + namespace,
2654        moduleNamespace = 'module-' + namespace,
2655
2656        $module         = $(this),
2657        $label          = $(this).children(selector.label),
2658        $input          = $(this).children(selector.input),
2659        input           = $input[0],
2660
2661        initialLoad     = false,
2662        shortcutPressed = false,
2663        instance        = $module.data(moduleNamespace),
2664
2665        observer,
2666        element         = this,
2667        module
2668      ;
2669
2670      module      = {
2671
2672        initialize: function() {
2673          module.verbose('Initializing checkbox', settings);
2674
2675          module.create.label();
2676          module.bind.events();
2677
2678          module.set.tabbable();
2679          module.hide.input();
2680
2681          module.observeChanges();
2682          module.instantiate();
2683          module.setup();
2684        },
2685
2686        instantiate: function() {
2687          module.verbose('Storing instance of module', module);
2688          instance = module;
2689          $module
2690            .data(moduleNamespace, module)
2691          ;
2692        },
2693
2694        destroy: function() {
2695          module.verbose('Destroying module');
2696          module.unbind.events();
2697          module.show.input();
2698          $module.removeData(moduleNamespace);
2699        },
2700
2701        fix: {
2702          reference: function() {
2703            if( $module.is(selector.input) ) {
2704              module.debug('Behavior called on <input> adjusting invoked element');
2705              $module = $module.closest(selector.checkbox);
2706              module.refresh();
2707            }
2708          }
2709        },
2710
2711        setup: function() {
2712          module.set.initialLoad();
2713          if( module.is.indeterminate() ) {
2714            module.debug('Initial value is indeterminate');
2715            module.indeterminate();
2716          }
2717          else if( module.is.checked() ) {
2718            module.debug('Initial value is checked');
2719            module.check();
2720          }
2721          else {
2722            module.debug('Initial value is unchecked');
2723            module.uncheck();
2724          }
2725          module.remove.initialLoad();
2726        },
2727
2728        refresh: function() {
2729          $label = $module.children(selector.label);
2730          $input = $module.children(selector.input);
2731          input  = $input[0];
2732        },
2733
2734        hide: {
2735          input: function() {
2736            module.verbose('Modfying <input> z-index to be unselectable');
2737            $input.addClass(className.hidden);
2738          }
2739        },
2740        show: {
2741          input: function() {
2742            module.verbose('Modfying <input> z-index to be selectable');
2743            $input.removeClass(className.hidden);
2744          }
2745        },
2746
2747        observeChanges: function() {
2748          if('MutationObserver' in window) {
2749            observer = new MutationObserver(function(mutations) {
2750              module.debug('DOM tree modified, updating selector cache');
2751              module.refresh();
2752            });
2753            observer.observe(element, {
2754              childList : true,
2755              subtree   : true
2756            });
2757            module.debug('Setting up mutation observer', observer);
2758          }
2759        },
2760
2761        attachEvents: function(selector, event) {
2762          var
2763            $element = $(selector)
2764          ;
2765          event = $.isFunction(module[event])
2766            ? module[event]
2767            : module.toggle
2768          ;
2769          if($element.length > 0) {
2770            module.debug('Attaching checkbox events to element', selector, event);
2771            $element
vendor: 3,728 bytes, lines 2772-2893
2772              .on('click' + eventNamespace, event)
2773            ;
2774          }
2775          else {
2776            module.error(error.notFound);
2777          }
2778        },
2779
2780        event: {
2781          click: function(event) {
2782            var
2783              $target = $(event.target)
2784            ;
2785            if( $target.is(selector.input) ) {
2786              module.verbose('Using default check action on initialized checkbox');
2787              return;
2788            }
2789            if( $target.is(selector.link) ) {
2790              module.debug('Clicking link inside checkbox, skipping toggle');
2791              return;
2792            }
2793            module.toggle();
2794            $input.focus();
2795            event.preventDefault();
2796          },
2797          keydown: function(event) {
2798            var
2799              key     = event.which,
2800              keyCode = {
2801                enter  : 13,
2802                space  : 32,
2803                escape : 27
2804              }
2805            ;
2806            if(key == keyCode.escape) {
2807              module.verbose('Escape key pressed blurring field');
2808              $input.blur();
2809              shortcutPressed = true;
2810            }
2811            else if(!event.ctrlKey && ( key == keyCode.space || key == keyCode.enter) ) {
2812              module.verbose('Enter/space key pressed, toggling checkbox');
2813              module.toggle();
2814              shortcutPressed = true;
2815            }
2816            else {
2817              shortcutPressed = false;
2818            }
2819          },
2820          keyup: function(event) {
2821            if(shortcutPressed) {
2822              event.preventDefault();
2823            }
2824          }
2825        },
2826
2827        check: function() {
2828          if( !module.should.allowCheck() ) {
2829            return;
2830          }
2831          module.debug('Checking checkbox', $input);
2832          module.set.checked();
2833          if( !module.should.ignoreCallbacks() ) {
2834            settings.onChecked.call(input);
2835            settings.onChange.call(input);
2836          }
2837        },
2838
2839        uncheck: function() {
2840          if( !module.should.allowUncheck() ) {
2841            return;
2842          }
2843          module.debug('Unchecking checkbox');
2844          module.set.unchecked();
2845          if( !module.should.ignoreCallbacks() ) {
2846            settings.onUnchecked.call(input);
2847            settings.onChange.call(input);
2848          }
2849        },
2850
2851        indeterminate: function() {
2852          if( module.should.allowIndeterminate() ) {
2853            module.debug('Checkbox is already indeterminate');
2854            return;
2855          }
2856          module.debug('Making checkbox indeterminate');
2857          module.set.indeterminate();
2858          if( !module.should.ignoreCallbacks() ) {
2859            settings.onIndeterminate.call(input);
2860            settings.onChange.call(input);
2861          }
2862        },
2863
2864        determinate: function() {
2865          if( module.should.allowDeterminate() ) {
2866            module.debug('Checkbox is already determinate');
2867            return;
2868          }
2869          module.debug('Making checkbox determinate');
2870          module.set.determinate();
2871          if( !module.should.ignoreCallbacks() ) {
2872            settings.onDeterminate.call(input);
2873            settings.onChange.call(input);
2874          }
2875        },
2876
2877        enable: function() {
2878          if( module.is.enabled() ) {
2879            module.debug('Checkbox is already enabled');
2880            return;
2881          }
2882          module.debug('Enabling checkbox');
2883          module.set.enabled();
2884          settings.onEnabled.call(input);
2885        },
2886
2887        disable: function() {
2888          if( module.is.disabled() ) {
2889            module.debug('Checkbox is already disabled');
2890            return;
2891          }
2892          module.debug('Disabling checkbox');
2893          module.set.disabled();
vendor: 10,441 bytes, lines 2893-3200
2893
2894          settings.onDisabled.call(input);
2895        },
2896
2897        get: {
2898          radios: function() {
2899            var
2900              name = module.get.name()
2901            ;
2902            return $('input[name="' + name + '"]').closest(selector.checkbox);
2903          },
2904          otherRadios: function() {
2905            return module.get.radios().not($module);
2906          },
2907          name: function() {
2908            return $input.attr('name');
2909          }
2910        },
2911
2912        is: {
2913          initialLoad: function() {
2914            return initialLoad;
2915          },
2916          radio: function() {
2917            return ($input.hasClass(className.radio) || $input.attr('type') == 'radio');
2918          },
2919          indeterminate: function() {
2920            return $input.prop('indeterminate') !== undefined && $input.prop('indeterminate');
2921          },
2922          checked: function() {
2923            return $input.prop('checked') !== undefined && $input.prop('checked');
2924          },
2925          disabled: function() {
2926            return $input.prop('disabled') !== undefined && $input.prop('disabled');
2927          },
2928          enabled: function() {
2929            return !module.is.disabled();
2930          },
2931          determinate: function() {
2932            return !module.is.indeterminate();
2933          },
2934          unchecked: function() {
2935            return !module.is.checked();
2936          }
2937        },
2938
2939        should: {
2940          allowCheck: function() {
2941            if(module.is.determinate() && module.is.checked() && !module.should.forceCallbacks() ) {
2942              module.debug('Should not allow check, checkbox is already checked');
2943              return false;
2944            }
2945            if(settings.beforeChecked.apply(input) === false) {
2946              module.debug('Should not allow check, beforeChecked cancelled');
2947              return false;
2948            }
2949            return true;
2950          },
2951          allowUncheck: function() {
2952            if(module.is.determinate() && module.is.unchecked() && !module.should.forceCallbacks() ) {
2953              module.debug('Should not allow uncheck, checkbox is already unchecked');
2954              return false;
2955            }
2956            if(settings.beforeUnchecked.apply(input) === false) {
2957              module.debug('Should not allow uncheck, beforeUnchecked cancelled');
2958              return false;
2959            }
2960            return true;
2961          },
2962          allowIndeterminate: function() {
2963            if(module.is.indeterminate() && !module.should.forceCallbacks() ) {
2964              module.debug('Should not allow indeterminate, checkbox is already indeterminate');
2965              return false;
2966            }
2967            if(settings.beforeIndeterminate.apply(input) === false) {
2968              module.debug('Should not allow indeterminate, beforeIndeterminate cancelled');
2969              return false;
2970            }
2971            return true;
2972          },
2973          allowDeterminate: function() {
2974            if(module.is.determinate() && !module.should.forceCallbacks() ) {
2975              module.debug('Should not allow determinate, checkbox is already determinate');
2976              return false;
2977            }
2978            if(settings.beforeDeterminate.apply(input) === false) {
2979              module.debug('Should not allow determinate, beforeDeterminate cancelled');
2980              return false;
2981            }
2982            return true;
2983          },
2984          forceCallbacks: function() {
2985            return (module.is.initialLoad() && settings.fireOnInit);
2986          },
2987          ignoreCallbacks: function() {
2988            return (initialLoad && !settings.fireOnInit);
2989          }
2990        },
2991
2992        can: {
2993          change: function() {
2994            return !( $module.hasClass(className.disabled) || $module.hasClass(className.readOnly) || $input.prop('disabled') || $input.prop('readonly') );
2995          },
2996          uncheck: function() {
2997            return (typeof settings.uncheckable === 'boolean')
2998              ? settings.uncheckable
2999              : !module.is.radio()
3000            ;
3001          }
3002        },
3003
3004        set: {
3005          initialLoad: function() {
3006            initialLoad = true;
3007          },
3008          checked: function() {
3009            module.verbose('Setting class to checked');
3010            $module
3011              .removeClass(className.indeterminate)
3012              .addClass(className.checked)
3013            ;
3014            if( module.is.radio() ) {
3015              module.uncheckOthers();
3016            }
3017            if(!module.is.indeterminate() && module.is.checked()) {
3018              module.debug('Input is already checked, skipping input property change');
3019              return;
3020            }
3021            module.verbose('Setting state to checked', input);
3022            $input
3023              .prop('indeterminate', false)
3024              .prop('checked', true)
3025            ;
3026            module.trigger.change();
3027          },
3028          unchecked: function() {
3029            module.verbose('Removing checked class');
3030            $module
3031              .removeClass(className.indeterminate)
3032              .removeClass(className.checked)
3033            ;
3034            if(!module.is.indeterminate() &&  module.is.unchecked() ) {
3035              module.debug('Input is already unchecked');
3036              return;
3037            }
3038            module.debug('Setting state to unchecked');
3039            $input
3040              .prop('indeterminate', false)
3041              .prop('checked', false)
3042            ;
3043            module.trigger.change();
3044          },
3045          indeterminate: function() {
3046            module.verbose('Setting class to indeterminate');
3047            $module
3048              .addClass(className.indeterminate)
3049            ;
3050            if( module.is.indeterminate() ) {
3051              module.debug('Input is already indeterminate, skipping input property change');
3052              return;
3053            }
3054            module.debug('Setting state to indeterminate');
3055            $input
3056              .prop('indeterminate', true)
3057            ;
3058            module.trigger.change();
3059          },
3060          determinate: function() {
3061            module.verbose('Removing indeterminate class');
3062            $module
3063              .removeClass(className.indeterminate)
3064            ;
3065            if( module.is.determinate() ) {
3066              module.debug('Input is already determinate, skipping input property change');
3067              return;
3068            }
3069            module.debug('Setting state to determinate');
3070            $input
3071              .prop('indeterminate', false)
3072            ;
3073          },
3074          disabled: function() {
3075            module.verbose('Setting class to disabled');
3076            $module
3077              .addClass(className.disabled)
3078            ;
3079            if( module.is.disabled() ) {
3080              module.debug('Input is already disabled, skipping input property change');
3081              return;
3082            }
3083            module.debug('Setting state to disabled');
3084            $input
3085              .prop('disabled', 'disabled')
3086            ;
3087            module.trigger.change();
3088          },
3089          enabled: function() {
3090            module.verbose('Removing disabled class');
3091            $module.removeClass(className.disabled);
3092            if( module.is.enabled() ) {
3093              module.debug('Input is already enabled, skipping input property change');
3094              return;
3095            }
3096            module.debug('Setting state to enabled');
3097            $input
3098              .prop('disabled', false)
3099            ;
3100            module.trigger.change();
3101          },
3102          tabbable: function() {
3103            module.verbose('Adding tabindex to checkbox');
3104            if( $input.attr('tabindex') === undefined) {
3105              $input.attr('tabindex', 0);
3106            }
3107          }
3108        },
3109
3110        remove: {
3111          initialLoad: function() {
3112            initialLoad = false;
3113          }
3114        },
3115
3116        trigger: {
3117          change: function() {
3118            var
3119              events       = document.createEvent('HTMLEvents'),
3120              inputElement = $input[0]
3121            ;
3122            if(inputElement) {
3123              module.verbose('Triggering native change event');
3124              events.initEvent('change', true, false);
3125              inputElement.dispatchEvent(events);
3126            }
3127          }
3128        },
3129
3130
3131        create: {
3132          label: function() {
3133            if($input.prevAll(selector.label).length > 0) {
3134              $input.prev(selector.label).detach().insertAfter($input);
3135              module.debug('Moving existing label', $label);
3136            }
3137            else if( !module.has.label() ) {
3138              $label = $('<label>').insertAfter($input);
3139              module.debug('Creating label', $label);
3140            }
3141          }
3142        },
3143
3144        has: {
3145          label: function() {
3146            return ($label.length > 0);
3147          }
3148        },
3149
3150        bind: {
3151          events: function() {
3152            module.verbose('Attaching checkbox events');
3153            $module
3154              .on('click'   + eventNamespace, module.event.click)
3155              .on('keydown' + eventNamespace, selector.input, module.event.keydown)
3156              .on('keyup'   + eventNamespace, selector.input, module.event.keyup)
3157            ;
3158          }
3159        },
3160
3161        unbind: {
3162          events: function() {
3163            module.debug('Removing events');
3164            $module
3165              .off(eventNamespace)
3166            ;
3167          }
3168        },
3169
3170        uncheckOthers: function() {
3171          var
3172            $radios = module.get.otherRadios()
3173          ;
3174          module.debug('Unchecking other radios', $radios);
3175          $radios.removeClass(className.checked);
3176        },
3177
3178        toggle: function() {
3179          if( !module.can.change() ) {
3180            if(!module.is.radio()) {
3181              module.debug('Checkbox is read-only or disabled, ignoring toggle');
3182            }
3183            return;
3184          }
3185          if( module.is.indeterminate() || module.is.unchecked() ) {
3186            module.debug('Currently unchecked');
3187            module.check();
3188          }
3189          else if( module.is.checked() && module.can.uncheck() ) {
3190            module.debug('Currently checked');
3191            module.uncheck();
3192          }
3193        },
3194        setting: function(name, value) {
3195          module.debug('Changing setting', name, value);
3196          if( $.isPlainObject(name) ) {
3197            $.extend(true, settings, name);
3198          }
3199          else if(value !== undefined) {
3200            
vendor: 1,817 bytes, lines 3200-3255
3200settings[name] = value;
3201          }
3202          else {
3203            return settings[name];
3204          }
3205        },
3206        internal: function(name, value) {
3207          if( $.isPlainObject(name) ) {
3208            $.extend(true, module, name);
3209          }
3210          else if(value !== undefined) {
3211            module[name] = value;
3212          }
3213          else {
3214            return module[name];
3215          }
3216        },
3217        debug: function() {
3218          if(settings.debug) {
3219            if(settings.performance) {
3220              module.performance.log(arguments);
3221            }
3222            else {
3223              module.debug = Function.prototype.bind.call(console.info, console, settings.name + ':');
3224              module.debug.apply(console, arguments);
3225            }
3226          }
3227        },
3228        verbose: function() {
3229          if(settings.verbose && settings.debug) {
3230            if(settings.performance) {
3231              module.performance.log(arguments);
3232            }
3233            else {
3234              module.verbose = Function.prototype.bind.call(console.info, console, settings.name + ':');
3235              module.verbose.apply(console, arguments);
3236            }
3237          }
3238        },
3239        error: function() {
3240          module.error = Function.prototype.bind.call(console.error, console, settings.name + ':');
3241          module.error.apply(console, arguments);
3242        },
3243        performance: {
3244          log: function(message) {
3245            var
3246              currentTime,
3247              executionTime,
3248              previousTime
3249            ;
3250            if(settings.performance) {
3251              currentTime   = new Date().getTime();
3252              previousTime  = time || currentTime;
3253              executionTime = currentTime - previousTime;
3254              time          = currentTime;
3255              performance.push({
vendor: 4,936 bytes, lines 3256-3422
3256                'Name'           : message[0],
3257                'Arguments'      : [].slice.call(message, 1) || '',
3258                'Element'        : element,
3259                'Execution Time' : executionTime
3260              });
3261            }
3262            clearTimeout(module.performance.timer);
3263            module.performance.timer = setTimeout(module.performance.display, 500);
3264          },
3265          display: function() {
3266            var
3267              title = settings.name + ':',
3268              totalTime = 0
3269            ;
3270            time = false;
3271            clearTimeout(module.performance.timer);
3272            $.each(performance, function(index, data) {
3273              totalTime += data['Execution Time'];
3274            });
3275            title += ' ' + totalTime + 'ms';
3276            if(moduleSelector) {
3277              title += ' \'' + moduleSelector + '\'';
3278            }
3279            if( (console.group !== undefined || console.table !== undefined) && performance.length > 0) {
3280              console.groupCollapsed(title);
3281              if(console.table) {
3282                console.table(performance);
3283              }
3284              else {
3285                $.each(performance, function(index, data) {
3286                  console.log(data['Name'] + ': ' + data['Execution Time']+'ms');
3287                });
3288              }
3289              console.groupEnd();
3290            }
3291            performance = [];
3292          }
3293        },
3294        invoke: function(query, passedArguments, context) {
3295          var
3296            object = instance,
3297            maxDepth,
3298            found,
3299            response
3300          ;
3301          passedArguments = passedArguments || queryArguments;
3302          context         = element         || context;
3303          if(typeof query == 'string' && object !== undefined) {
3304            query    = query.split(/[\. ]/);
3305            maxDepth = query.length - 1;
3306            $.each(query, function(depth, value) {
3307              var camelCaseValue = (depth != maxDepth)
3308                ? value + query[depth + 1].charAt(0).toUpperCase() + query[depth + 1].slice(1)
3309                : query
3310              ;
3311              if( $.isPlainObject( object[camelCaseValue] ) && (depth != maxDepth) ) {
3312                object = object[camelCaseValue];
3313              }
3314              else if( object[camelCaseValue] !== undefined ) {
3315                found = object[camelCaseValue];
3316                return false;
3317              }
3318              else if( $.isPlainObject( object[value] ) && (depth != maxDepth) ) {
3319                object = object[value];
3320              }
3321              else if( object[value] !== undefined ) {
3322                found = object[value];
3323                return false;
3324              }
3325              else {
3326                module.error(error.method, query);
3327                return false;
3328              }
3329            });
3330          }
3331          if ( $.isFunction( found ) ) {
3332            response = found.apply(context, passedArguments);
3333          }
3334          else if(found !== undefined) {
3335            response = found;
3336          }
3337          if($.isArray(returnedValue)) {
3338            returnedValue.push(response);
3339          }
3340          else if(returnedValue !== undefined) {
3341            returnedValue = [returnedValue, response];
3342          }
3343          else if(response !== undefined) {
3344            returnedValue = response;
3345          }
3346          return found;
3347        }
3348      };
3349
3350      if(methodInvoked) {
3351        if(instance === undefined) {
3352          module.initialize();
3353        }
3354        module.invoke(query);
3355      }
3356      else {
3357        if(instance !== undefined) {
3358          instance.invoke('destroy');
3359        }
3360        module.initialize();
3361      }
3362    })
3363  ;
3364
3365  return (returnedValue !== undefined)
3366    ? returnedValue
3367    : this
3368  ;
3369};
3370
3371$.fn.checkbox.settings = {
3372
3373  name                : 'Checkbox',
3374  namespace           : 'checkbox',
3375
3376  debug               : false,
3377  verbose             : true,
3378  performance         : true,
3379
3380  // delegated event context
3381  uncheckable         : 'auto',
3382  fireOnInit          : false,
3383
3384  onChange            : function(){},
3385
3386  beforeChecked       : function(){},
3387  beforeUnchecked     : function(){},
3388  beforeDeterminate   : function(){},
3389  beforeIndeterminate : function(){},
3390
3391  onChecked           : function(){},
3392  onUnchecked         : function(){},
3393
3394  onDeterminate       : function() {},
3395  onIndeterminate     : function() {},
3396
3397  onEnable            : function(){},
3398  onDisable           : function(){},
3399
3400  className       : {
3401    checked       : 'checked',
3402    indeterminate : 'indeterminate',
3403    disabled      : 'disabled',
3404    hidden        : 'hidden',
3405    radio         : 'radio',
3406    readOnly      : 'read-only'
3407  },
3408
3409  error     : {
3410    method       : 'The method you called is not defined'
3411  },
3412
3413  selector : {
3414    checkbox : '.ui.checkbox',
3415    label    : 'label, .box',
3416    input    : 'input[type="checkbox"], input[type="radio"]',
3417    link     : 'a[href]'
3418  }
3419
3420};
3421
3422}
vendor: 15,138 bytes, lines 3422-3926
3422)( jQuery, window, document );
3423
3424/*!
3425 * # Semantic UI 2.1.7 - Dimmer
3426 * http://github.com/semantic-org/semantic-ui/
3427 *
3428 *
3429 * Copyright 2015 Contributors
3430 * Released under the MIT license
3431 * http://opensource.org/licenses/MIT
3432 *
3433 */
3434
3435;(function ( $, window, document, undefined ) {
3436
3437"use strict";
3438
3439$.fn.dimmer = function(parameters) {
3440  var
3441    $allModules     = $(this),
3442
3443    time            = new Date().getTime(),
3444    performance     = [],
3445
3446    query           = arguments[0],
3447    methodInvoked   = (typeof query == 'string'),
3448    queryArguments  = [].slice.call(arguments, 1),
3449
3450    returnedValue
3451  ;
3452
3453  $allModules
3454    .each(function() {
3455      var
3456        settings        = ( $.isPlainObject(parameters) )
3457          ? $.extend(true, {}, $.fn.dimmer.settings, parameters)
3458          : $.extend({}, $.fn.dimmer.settings),
3459
3460        selector        = settings.selector,
3461        namespace       = settings.namespace,
3462        className       = settings.className,
3463        error           = settings.error,
3464
3465        eventNamespace  = '.' + namespace,
3466        moduleNamespace = 'module-' + namespace,
3467        moduleSelector  = $allModules.selector || '',
3468
3469        clickEvent      = ('ontouchstart' in document.documentElement)
3470          ? 'touchstart'
3471          : 'click',
3472
3473        $module = $(this),
3474        $dimmer,
3475        $dimmable,
3476
3477        element   = this,
3478        instance  = $module.data(moduleNamespace),
3479        module
3480      ;
3481
3482      module = {
3483
3484        preinitialize: function() {
3485          if( module.is.dimmer() ) {
3486
3487            $dimmable = $module.parent();
3488            $dimmer   = $module;
3489          }
3490          else {
3491            $dimmable = $module;
3492            if( module.has.dimmer() ) {
3493              if(settings.dimmerName) {
3494                $dimmer = $dimmable.find(selector.dimmer).filter('.' + settings.dimmerName);
3495              }
3496              else {
3497                $dimmer = $dimmable.find(selector.dimmer);
3498              }
3499            }
3500            else {
3501              $dimmer = module.create();
3502            }
3503          }
3504        },
3505
3506        initialize: function() {
3507          module.debug('Initializing dimmer', settings);
3508
3509          module.bind.events();
3510          module.set.dimmable();
3511          module.instantiate();
3512        },
3513
3514        instantiate: function() {
3515          module.verbose('Storing instance of module', module);
3516          instance = module;
3517          $module
3518            .data(moduleNamespace, instance)
3519          ;
3520        },
3521
3522        destroy: function() {
3523          module.verbose('Destroying previous module', $dimmer);
3524          module.unbind.events();
3525          module.remove.variation();
3526          $dimmable
3527            .off(eventNamespace)
3528          ;
3529        },
3530
3531        bind: {
3532          events: function() {
3533            if(settings.on == 'hover') {
3534              $dimmable
3535                .on('mouseenter' + eventNamespace, module.show)
3536                .on('mouseleave' + eventNamespace, module.hide)
3537              ;
3538            }
3539            else if(settings.on == 'click') {
3540              $dimmable
3541                .on(clickEvent + eventNamespace, module.toggle)
3542              ;
3543            }
3544            if( module.is.page() ) {
3545              module.debug('Setting as a page dimmer', $dimmable);
3546              module.set.pageDimmer();
3547            }
3548
3549            if( module.is.closable() ) {
3550              module.verbose('Adding dimmer close event', $dimmer);
3551              $dimmable
3552                .on(clickEvent + eventNamespace, selector.dimmer, module.event.click)
3553              ;
3554            }
3555          }
3556        },
3557
3558        unbind: {
3559          events: function() {
3560            $module
3561              .removeData(moduleNamespace)
3562            ;
3563          }
3564        },
3565
3566        event: {
3567          click: function(event) {
3568            module.verbose('Determining if event occured on dimmer', event);
3569            if( $dimmer.find(event.target).length === 0 || $(event.target).is(selector.content) ) {
3570              module.hide();
3571              event.stopImmediatePropagation();
3572            }
3573          }
3574        },
3575
3576        addContent: function(element) {
3577          var
3578            $content = $(element)
3579          ;
3580          module.debug('Add content to dimmer', $content);
3581          if($content.parent()[0] !== $dimmer[0]) {
3582            $content.detach().appendTo($dimmer);
3583          }
3584        },
3585
3586        create: function() {
3587          var
3588            $element = $( settings.template.dimmer() )
3589          ;
3590          if(settings.variation) {
3591            module.debug('Creating dimmer with variation', settings.variation);
3592            $element.addClass(settings.variation);
3593          }
3594          if(settings.dimmerName) {
3595            module.debug('Creating named dimmer', settings.dimmerName);
3596            $element.addClass(settings.dimmerName);
3597          }
3598          $element
3599            .appendTo($dimmable)
3600          ;
3601          return $element;
3602        },
3603
3604        show: function(callback) {
3605          callback = $.isFunction(callback)
3606            ? callback
3607            : function(){}
3608          ;
3609          module.debug('Showing dimmer', $dimmer, settings);
3610          if( (!module.is.dimmed() || module.is.animating()) && module.is.enabled() ) {
3611            module.animate.show(callback);
3612            settings.onShow.call(element);
3613            settings.onChange.call(element);
3614          }
3615          else {
3616            module.debug('Dimmer is already shown or disabled');
3617          }
3618        },
3619
3620        hide: function(callback) {
3621          callback = $.isFunction(callback)
3622            ? callback
3623            : function(){}
3624          ;
3625          if( module.is.dimmed() || module.is.animating() ) {
3626            module.debug('Hiding dimmer', $dimmer);
3627            module.animate.hide(callback);
3628            settings.onHide.call(element);
3629            settings.onChange.call(element);
3630          }
3631          else {
3632            module.debug('Dimmer is not visible');
3633          }
3634        },
3635
3636        toggle: function() {
3637          module.verbose('Toggling dimmer visibility', $dimmer);
3638          if( !module.is.dimmed() ) {
3639            module.show();
3640          }
3641          else {
3642            module.hide();
3643          }
3644        },
3645
3646        animate: {
3647          show: function(callback) {
3648            callback = $.isFunction(callback)
3649              ? callback
3650              : function(){}
3651            ;
3652            if(settings.useCSS && $.fn.transition !== undefined && $dimmer.transition('is supported')) {
3653              if(settings.opacity !== 'auto') {
3654                module.set.opacity();
3655              }
3656              $dimmer
3657                .transition({
3658                  animation   : settings.transition + ' in',
3659                  queue       : false,
3660                  duration    : module.get.duration(),
3661                  useFailSafe : true,
3662                  onStart     : function() {
3663                    module.set.dimmed();
3664                  },
3665                  onComplete  : function() {
3666                    module.set.active();
3667                    callback();
3668                  }
3669                })
3670              ;
3671            }
3672            else {
3673              module.verbose('Showing dimmer animation with javascript');
3674              module.set.dimmed();
3675              if(settings.opacity == 'auto') {
3676                settings.opacity = 0.8;
3677              }
3678              $dimmer
3679                .stop()
3680                .css({
3681                  opacity : 0,
3682                  width   : '100%',
3683                  height  : '100%'
3684                })
3685                .fadeTo(module.get.duration(), settings.opacity, function() {
3686                  $dimmer.removeAttr('style');
3687                  module.set.active();
3688                  callback();
3689                })
3690              ;
3691            }
3692          },
3693          hide: function(callback) {
3694            callback = $.isFunction(callback)
3695              ? callback
3696              : function(){}
3697            ;
3698            if(settings.useCSS && $.fn.transition !== undefined && $dimmer.transition('is supported')) {
3699              module.verbose('Hiding dimmer with css');
3700              $dimmer
3701                .transition({
3702                  animation   : settings.transition + ' out',
3703                  queue       : false,
3704                  duration    : module.get.duration(),
3705                  useFailSafe : true,
3706                  onStart     : function() {
3707                    module.remove.dimmed();
3708                  },
3709                  onComplete  : function() {
3710                    module.remove.active();
3711                    callback();
3712                  }
3713                })
3714              ;
3715            }
3716            else {
3717              module.verbose('Hiding dimmer with javascript');
3718              module.remove.dimmed();
3719              $dimmer
3720                .stop()
3721                .fadeOut(module.get.duration(), function() {
3722                  module.remove.active();
3723                  $dimmer.removeAttr('style');
3724                  callback();
3725                })
3726              ;
3727            }
3728          }
3729        },
3730
3731        get: {
3732          dimmer: function() {
3733            return $dimmer;
3734          },
3735          duration: function() {
3736            if(typeof settings.duration == 'object') {
3737              if( module.is.active() ) {
3738                return settings.duration.hide;
3739              }
3740              else {
3741                return settings.duration.show;
3742              }
3743            }
3744            return settings.duration;
3745          }
3746        },
3747
3748        has: {
3749          dimmer: function() {
3750            if(settings.dimmerName) {
3751              return ($module.find(selector.dimmer).filter('.' + settings.dimmerName).length > 0);
3752            }
3753            else {
3754              return ( $module.find(selector.dimmer).length > 0 );
3755            }
3756          }
3757        },
3758
3759        is: {
3760          active: function() {
3761            return $dimmer.hasClass(className.active);
3762          },
3763          animating: function() {
3764            return ( $dimmer.is(':animated') || $dimmer.hasClass(className.animating) );
3765          },
3766          closable: function() {
3767            if(settings.closable == 'auto') {
3768              if(settings.on == 'hover') {
3769                return false;
3770              }
3771              return true;
3772            }
3773            return settings.closable;
3774          },
3775          dimmer: function() {
3776            return $module.hasClass(className.dimmer);
3777          },
3778          dimmable: function() {
3779            return $module.hasClass(className.dimmable);
3780          },
3781          dimmed: function() {
3782            return $dimmable.hasClass(className.dimmed);
3783          },
3784          disabled: function() {
3785            return $dimmable.hasClass(className.disabled);
3786          },
3787          enabled: function() {
3788            return !module.is.disabled();
3789          },
3790          page: function () {
3791            return $dimmable.is('body');
3792          },
3793          pageDimmer: function() {
3794            return $dimmer.hasClass(className.pageDimmer);
3795          }
3796        },
3797
3798        can: {
3799          show: function() {
3800            return !$dimmer.hasClass(className.disabled);
3801          }
3802        },
3803
3804        set: {
3805          opacity: function(opacity) {
3806            var
3807              color      = $dimmer.css('background-color'),
3808              colorArray = color.split(','),
3809              isRGBA     = (colorArray && colorArray.length == 4)
3810            ;
3811            opacity    = settings.opacity === 0 ? 0 : settings.opacity || opacity;
3812            if(isRGBA) {
3813              colorArray[3] = opacity + ')';
3814              color         = colorArray.join(',');
3815            }
3816            else {
3817              color = 'rgba(0, 0, 0, ' + opacity + ')';
3818            }
3819            module.debug('Setting opacity to', opacity);
3820            $dimmer.css('background-color', color);
3821          },
3822          active: function() {
3823            $dimmer.addClass(className.active);
3824          },
3825          dimmable: function() {
3826            $dimmable.addClass(className.dimmable);
3827          },
3828          dimmed: function() {
3829            $dimmable.addClass(className.dimmed);
3830          },
3831          pageDimmer: function() {
3832            $dimmer.addClass(className.pageDimmer);
3833          },
3834          disabled: function() {
3835            $dimmer.addClass(className.disabled);
3836          },
3837          variation: function(variation) {
3838            variation = variation || settings.variation;
3839            if(variation) {
3840              $dimmer.addClass(variation);
3841            }
3842          }
3843        },
3844
3845        remove: {
3846          active: function() {
3847            $dimmer
3848              .removeClass(className.active)
3849            ;
3850          },
3851          dimmed: function() {
3852            $dimmable.removeClass(className.dimmed);
3853          },
3854          disabled: function() {
3855            $dimmer.removeClass(className.disabled);
3856          },
3857          variation: function(variation) {
3858            variation = variation || settings.variation;
3859            if(variation) {
3860              $dimmer.removeClass(variation);
3861            }
3862          }
3863        },
3864
3865        setting: function(name, value) {
3866          module.debug('Changing setting', name, value);
3867          if( $.isPlainObject(name) ) {
3868            $.extend(true, settings, name);
3869          }
3870          else if(value !== undefined) {
3871            settings[name] = value;
3872          }
3873          else {
3874            return settings[name];
3875          }
3876        },
3877        internal: function(name, value) {
3878          if( $.isPlainObject(name) ) {
3879            $.extend(true, module, name);
3880          }
3881          else if(value !== undefined) {
3882            module[name] = value;
3883          }
3884          else {
3885            return module[name];
3886          }
3887        },
3888        debug: function() {
3889          if(settings.debug) {
3890            if(settings.performance) {
3891              module.performance.log(arguments);
3892            }
3893            else {
3894              module.debug = Function.prototype.bind.call(console.info, console, settings.name + ':');
3895              module.debug.apply(console, arguments);
3896            }
3897          }
3898        },
3899        verbose: function() {
3900          if(settings.verbose && settings.debug) {
3901            if(settings.performance) {
3902              module.performance.log(arguments);
3903            }
3904            else {
3905              module.verbose = Function.prototype.bind.call(console.info, console, settings.name + ':');
3906              module.verbose.apply(console, arguments);
3907            }
3908          }
3909        },
3910        error: function() {
3911          module.error = Function.prototype.bind.call(console.error, console, settings.name + ':');
3912          module.error.apply(console, arguments);
3913        },
3914        performance: {
3915          log: function(message) {
3916            var
3917              currentTime,
3918              executionTime,
3919              previousTime
3920            ;
3921            if(settings.performance) {
3922              currentTime   = new Date().getTime();
3923              previousTime  = time || currentTime;
3924              executionTime = currentTime - previousTime;
3925              time          = currentTime;
3926              performance.push({
vendor: 5,206 bytes, lines 3927-4116
3927                'Name'           : message[0],
3928                'Arguments'      : [].slice.call(message, 1) || '',
3929                'Element'        : element,
3930                'Execution Time' : executionTime
3931              });
3932            }
3933            clearTimeout(module.performance.timer);
3934            module.performance.timer = setTimeout(module.performance.display, 500);
3935          },
3936          display: function() {
3937            var
3938              title = settings.name + ':',
3939              totalTime = 0
3940            ;
3941            time = false;
3942            clearTimeout(module.performance.timer);
3943            $.each(performance, function(index, data) {
3944              totalTime += data['Execution Time'];
3945            });
3946            title += ' ' + totalTime + 'ms';
3947            if(moduleSelector) {
3948              title += ' \'' + moduleSelector + '\'';
3949            }
3950            if($allModules.length > 1) {
3951              title += ' ' + '(' + $allModules.length + ')';
3952            }
3953            if( (console.group !== undefined || console.table !== undefined) && performance.length > 0) {
3954              console.groupCollapsed(title);
3955              if(console.table) {
3956                console.table(performance);
3957              }
3958              else {
3959                $.each(performance, function(index, data) {
3960                  console.log(data['Name'] + ': ' + data['Execution Time']+'ms');
3961                });
3962              }
3963              console.groupEnd();
3964            }
3965            performance = [];
3966          }
3967        },
3968        invoke: function(query, passedArguments, context) {
3969          var
3970            object = instance,
3971            maxDepth,
3972            found,
3973            response
3974          ;
3975          passedArguments = passedArguments || queryArguments;
3976          context         = element         || context;
3977          if(typeof query == 'string' && object !== undefined) {
3978            query    = query.split(/[\. ]/);
3979            maxDepth = query.length - 1;
3980            $.each(query, function(depth, value) {
3981              var camelCaseValue = (depth != maxDepth)
3982                ? value + query[depth + 1].charAt(0).toUpperCase() + query[depth + 1].slice(1)
3983                : query
3984              ;
3985              if( $.isPlainObject( object[camelCaseValue] ) && (depth != maxDepth) ) {
3986                object = object[camelCaseValue];
3987              }
3988              else if( object[camelCaseValue] !== undefined ) {
3989                found = object[camelCaseValue];
3990                return false;
3991              }
3992              else if( $.isPlainObject( object[value] ) && (depth != maxDepth) ) {
3993                object = object[value];
3994              }
3995              else if( object[value] !== undefined ) {
3996                found = object[value];
3997                return false;
3998              }
3999              else {
4000                module.error(error.method, query);
4001                return false;
4002              }
4003            });
4004          }
4005          if ( $.isFunction( found ) ) {
4006            response = found.apply(context, passedArguments);
4007          }
4008          else if(found !== undefined) {
4009            response = found;
4010          }
4011          if($.isArray(returnedValue)) {
4012            returnedValue.push(response);
4013          }
4014          else if(returnedValue !== undefined) {
4015            returnedValue = [returnedValue, response];
4016          }
4017          else if(response !== undefined) {
4018            returnedValue = response;
4019          }
4020          return found;
4021        }
4022      };
4023
4024      module.preinitialize();
4025
4026      if(methodInvoked) {
4027        if(instance === undefined) {
4028          module.initialize();
4029        }
4030        module.invoke(query);
4031      }
4032      else {
4033        if(instance !== undefined) {
4034          instance.invoke('destroy');
4035        }
4036        module.initialize();
4037      }
4038    })
4039  ;
4040
4041  return (returnedValue !== undefined)
4042    ? returnedValue
4043    : this
4044  ;
4045};
4046
4047$.fn.dimmer.settings = {
4048
4049  name        : 'Dimmer',
4050  namespace   : 'dimmer',
4051
4052  debug       : false,
4053  verbose     : false,
4054  performance : true,
4055
4056  // name to distinguish between multiple dimmers in context
4057  dimmerName  : false,
4058
4059  // whether to add a variation type
4060  variation   : false,
4061
4062  // whether to bind close events
4063  closable    : 'auto',
4064
4065  // whether to use css animations
4066  useCSS      : true,
4067
4068  // css animation to use
4069  transition  : 'fade',
4070
4071  // event to bind to
4072  on          : false,
4073
4074  // overriding opacity value
4075  opacity     : 'auto',
4076
4077  // transition durations
4078  duration    : {
4079    show : 500,
4080    hide : 500
4081  },
4082
4083  onChange    : function(){},
4084  onShow      : function(){},
4085  onHide      : function(){},
4086
4087  error   : {
4088    method   : 'The method you called is not defined.'
4089  },
4090
4091  className : {
4092    active     : 'active',
4093    animating  : 'animating',
4094    dimmable   : 'dimmable',
4095    dimmed     : 'dimmed',
4096    dimmer     : 'dimmer',
4097    disabled   : 'disabled',
4098    hide       : 'hide',
4099    pageDimmer : 'page',
4100    show       : 'show'
4101  },
4102
4103  selector: {
4104    dimmer   : '> .ui.dimmer',
4105    content  : '.ui.dimmer > .content, .ui.dimmer > .content > .center'
4106  },
4107
4108  template: {
4109    dimmer: function() {
4110     return $('<div />').attr('class', 'ui dimmer');
4111    }
4112  }
4113
4114};
4115
4116}
vendor: 55,767 bytes, lines 4116-5689
4116)( jQuery, window, document );
4117/*!
4118 * # Semantic UI 2.1.7 - Dropdown
4119 * http://github.com/semantic-org/semantic-ui/
4120 *
4121 *
4122 * Copyright 2015 Contributors
4123 * Released under the MIT license
4124 * http://opensource.org/licenses/MIT
4125 *
4126 */
4127
4128;(function ( $, window, document, undefined ) {
4129
4130"use strict";
4131
4132$.fn.dropdown = function(parameters) {
4133  var
4134    $allModules    = $(this),
4135    $document      = $(document),
4136
4137    moduleSelector = $allModules.selector || '',
4138
4139    hasTouch       = ('ontouchstart' in document.documentElement),
4140    time           = new Date().getTime(),
4141    performance    = [],
4142
4143    query          = arguments[0],
4144    methodInvoked  = (typeof query == 'string'),
4145    queryArguments = [].slice.call(arguments, 1),
4146    returnedValue
4147  ;
4148
4149  $allModules
4150    .each(function(elementIndex) {
4151      var
4152        settings          = ( $.isPlainObject(parameters) )
4153          ? $.extend(true, {}, $.fn.dropdown.settings, parameters)
4154          : $.extend({}, $.fn.dropdown.settings),
4155
4156        className       = settings.className,
4157        message         = settings.message,
4158        fields          = settings.fields,
4159        keys            = settings.keys,
4160        metadata        = settings.metadata,
4161        namespace       = settings.namespace,
4162        regExp          = settings.regExp,
4163        selector        = settings.selector,
4164        error           = settings.error,
4165        templates       = settings.templates,
4166
4167        eventNamespace  = '.' + namespace,
4168        moduleNamespace = 'module-' + namespace,
4169
4170        $module         = $(this),
4171        $context        = $(settings.context),
4172        $text           = $module.find(selector.text),
4173        $search         = $module.find(selector.search),
4174        $input          = $module.find(selector.input),
4175        $icon           = $module.find(selector.icon),
4176
4177        $combo = ($module.prev().find(selector.text).length > 0)
4178          ? $module.prev().find(selector.text)
4179          : $module.prev(),
4180
4181        $menu           = $module.children(selector.menu),
4182        $item           = $menu.find(selector.item),
4183
4184        activated       = false,
4185        itemActivated   = false,
4186        internalChange  = false,
4187        element         = this,
4188        instance        = $module.data(moduleNamespace),
4189
4190        initialLoad,
4191        pageLostFocus,
4192        elementNamespace,
4193        id,
4194        selectObserver,
4195        menuObserver,
4196        module
4197      ;
4198
4199      module = {
4200
4201        initialize: function() {
4202          module.debug('Initializing dropdown', settings);
4203
4204          if( module.is.alreadySetup() ) {
4205            module.setup.reference();
4206          }
4207          else {
4208            module.setup.layout();
4209            module.refreshData();
4210
4211            module.save.defaults();
4212            module.restore.selected();
4213
4214            module.create.id();
4215            module.bind.events();
4216
4217            module.observeChanges();
4218            module.instantiate();
4219          }
4220
4221        },
4222
4223        instantiate: function() {
4224          module.verbose('Storing instance of dropdown', module);
4225          instance = module;
4226          $module
4227            .data(moduleNamespace, module)
4228          ;
4229        },
4230
4231        destroy: function() {
4232          module.verbose('Destroying previous dropdown', $module);
4233          module.remove.tabbable();
4234          $module
4235            .off(eventNamespace)
4236            .removeData(moduleNamespace)
4237          ;
4238          $menu
4239            .off(eventNamespace)
4240          ;
4241          $document
4242            .off(elementNamespace)
4243          ;
4244          if(selectObserver) {
4245            selectObserver.disconnect();
4246          }
4247          if(menuObserver) {
4248            menuObserver.disconnect();
4249          }
4250        },
4251
4252        observeChanges: function() {
4253          if('MutationObserver' in window) {
4254            selectObserver = new MutationObserver(function(mutations) {
4255              module.debug('<select> modified, recreating menu');
4256              module.setup.select();
4257            });
4258            menuObserver = new MutationObserver(function(mutations) {
4259              module.debug('Menu modified, updating selector cache');
4260              module.refresh();
4261            });
4262            if(module.has.input()) {
4263              selectObserver.observe($input[0], {
4264                childList : true,
4265                subtree   : true
4266              });
4267            }
4268            if(module.has.menu()) {
4269              menuObserver.observe($menu[0], {
4270                childList : true,
4271                subtree   : true
4272              });
4273            }
4274            module.debug('Setting up mutation observer', selectObserver, menuObserver);
4275          }
4276        },
4277
4278        create: {
4279          id: function() {
4280            id = (Math.random().toString(16) + '000000000').substr(2, 8);
4281            elementNamespace = '.' + id;
4282            module.verbose('Creating unique id for element', id);
4283          },
4284          userChoice: function(values) {
4285            var
4286              $userChoices,
4287              $userChoice,
4288              isUserValue,
4289              html
4290            ;
4291            values = values || module.get.userValues();
4292            if(!values) {
4293              return false;
4294            }
4295            values = $.isArray(values)
4296              ? values
4297              : [values]
4298            ;
4299            $.each(values, function(index, value) {
4300              if(module.get.item(value) === false) {
4301                html         = settings.templates.addition( module.add.variables(message.addResult, value) );
4302                $userChoice  = $('<div />')
4303                  .html(html)
4304                  .attr('data-' + metadata.value, value)
4305                  .attr('data-' + metadata.text, value)
4306                  .addClass(className.addition)
4307                  .addClass(className.item)
4308                ;
4309                $userChoices = ($userChoices === undefined)
4310                  ? $userChoice
4311                  : $userChoices.add($userChoice)
4312                ;
4313                module.verbose('Creating user choices for value', value, $userChoice);
4314              }
4315            });
4316            return $userChoices;
4317          },
4318          userLabels: function(value) {
4319            var
4320              userValues = module.get.userValues()
4321            ;
4322            if(userValues) {
4323              module.debug('Adding user labels', userValues);
4324              $.each(userValues, function(index, value) {
4325                module.verbose('Adding custom user value');
4326                module.add.label(value, value);
4327              });
4328            }
4329          },
4330          menu: function() {
4331            $menu = $('<div />')
4332              .addClass(className.menu)
4333              .appendTo($module)
4334            ;
4335          }
4336        },
4337
4338        search: function(query) {
4339          query = (query !== undefined)
4340            ? query
4341            : module.get.query()
4342          ;
4343          module.verbose('Searching for query', query);
4344          module.filter(query);
4345        },
4346
4347        select: {
4348          firstUnfiltered: function() {
4349            module.verbose('Selecting first non-filtered element');
4350            module.remove.selectedItem();
4351            $item
4352              .not(selector.unselectable)
4353                .eq(0)
4354                .addClass(className.selected)
4355            ;
4356          },
4357          nextAvailable: function($selected) {
4358            $selected = $selected.eq(0);
4359            var
4360              $nextAvailable = $selected.nextAll(selector.item).not(selector.unselectable).eq(0),
4361              $prevAvailable = $selected.prevAll(selector.item).not(selector.unselectable).eq(0),
4362              hasNext        = ($nextAvailable.length > 0)
4363            ;
4364            if(hasNext) {
4365              module.verbose('Moving selection to', $nextAvailable);
4366              $nextAvailable.addClass(className.selected);
4367            }
4368            else {
4369              module.verbose('Moving selection to', $prevAvailable);
4370              $prevAvailable.addClass(className.selected);
4371            }
4372          }
4373        },
4374
4375        setup: {
4376          api: function() {
4377            var
4378              apiSettings = {
4379                debug : settings.debug,
4380                on    : false
4381              }
4382            ;
4383            module.verbose('First request, initializing API');
4384            $module
4385              .api(apiSettings)
4386            ;
4387          },
4388          layout: function() {
4389            if( $module.is('select') ) {
4390              module.setup.select();
4391              module.setup.returnedObject();
4392            }
4393            if( !module.has.menu() ) {
4394              module.create.menu();
4395            }
4396            if( module.is.search() && !module.has.search() ) {
4397              module.verbose('Adding search input');
4398              $search = $('<input />')
4399                .addClass(className.search)
4400                .prop('autocomplete', 'off')
4401                .insertBefore($text)
4402              ;
4403            }
4404            if(settings.allowTab) {
4405              module.set.tabbable();
4406            }
4407          },
4408          select: function() {
4409            var
4410              selectValues  = module.get.selectValues()
4411            ;
4412            module.debug('Dropdown initialized on a select', selectValues);
4413            if( $module.is('select') ) {
4414              $input = $module;
4415            }
4416            // see if select is placed correctly already
4417            if($input.parent(selector.dropdown).length > 0) {
4418              module.debug('UI dropdown already exists. Creating dropdown menu only');
4419              $module = $input.closest(selector.dropdown);
4420              if( !module.has.menu() ) {
4421                module.create.menu();
4422              }
4423              $menu = $module.children(selector.menu);
4424              module.setup.menu(selectValues);
4425            }
4426            else {
4427              module.debug('Creating entire dropdown from select');
4428              $module = $('<div />')
4429                .attr('class', $input.attr('class') )
4430                .addClass(className.selection)
4431                .addClass(className.dropdown)
4432                .html( templates.dropdown(selectValues) )
4433                .insertBefore($input)
4434              ;
4435              if($input.hasClass(className.multiple) && $input.prop('multiple') === false) {
4436                module.error(error.missingMultiple);
4437                $input.prop('multiple', true);
4438              }
4439              if($input.is('[multiple]')) {
4440                module.set.multiple();
4441              }
4442              if ($input.prop('disabled')) {
4443                module.debug('Disabling dropdown')
4444                $module.addClass(className.disabled)
4445              }
4446              $input
4447                .removeAttr('class')
4448                .detach()
4449                .prependTo($module)
4450              ;
4451            }
4452            module.refresh();
4453          },
4454          menu: function(values) {
4455            $menu.html( templates.menu(values, fields));
4456            $item = $menu.find(selector.item);
4457          },
4458          reference: function() {
4459            module.debug('Dropdown behavior was called on select, replacing with closest dropdown');
4460            // replace module reference
4461            $module = $module.parent(selector.dropdown);
4462            module.refresh();
4463            module.setup.returnedObject();
4464            // invoke method in context of current instance
4465            if(methodInvoked) {
4466              instance = module;
4467              module.invoke(query);
4468            }
4469          },
4470          returnedObject: function() {
4471            var
4472              $firstModules = $allModules.slice(0, elementIndex),
4473              $lastModules = $allModules.slice(elementIndex + 1)
4474            ;
4475            // adjust all modules to use correct reference
4476            $allModules = $firstModules.add($module).add($lastModules);
4477          }
4478        },
4479
4480        refresh: function() {
4481          module.refreshSelectors();
4482          module.refreshData();
4483        },
4484
4485        refreshSelectors: function() {
4486          module.verbose('Refreshing selector cache');
4487          $text   = $module.find(selector.text);
4488          $search = $module.find(selector.search);
4489          $input  = $module.find(selector.input);
4490          $icon   = $module.find(selector.icon);
4491          $combo  = ($module.prev().find(selector.text).length > 0)
4492            ? $module.prev().find(selector.text)
4493            : $module.prev()
4494          ;
4495          $menu    = $module.children(selector.menu);
4496          $item    = $menu.find(selector.item);
4497        },
4498
4499        refreshData: function() {
4500          module.verbose('Refreshing cached metadata');
4501          $item
4502            .removeData(metadata.text)
4503            .removeData(metadata.value)
4504          ;
4505          $module
4506            .removeData(metadata.defaultText)
4507            .removeData(metadata.defaultValue)
4508            .removeData(metadata.placeholderText)
4509          ;
4510        },
4511
4512        toggle: function() {
4513          module.verbose('Toggling menu visibility');
4514          if( !module.is.active() ) {
4515            module.show();
4516          }
4517          else {
4518            module.hide();
4519          }
4520        },
4521
4522        show: function(callback) {
4523          callback = $.isFunction(callback)
4524            ? callback
4525            : function(){}
4526          ;
4527          if( module.can.show() && !module.is.active() ) {
4528            module.debug('Showing dropdown');
4529            if(module.is.multiple() && !module.has.search() && module.is.allFiltered()) {
4530              return true;
4531            }
4532            if(module.has.message() && !(module.has.maxSelections() || module.has.allResultsFiltered()) ) {
4533              module.remove.message();
4534            }
4535            if(settings.onShow.call(element) !== false) {
4536              module.animate.show(function() {
4537                if( module.can.click() ) {
4538                  module.bind.intent();
4539                }
4540                module.set.visible();
4541                callback.call(element);
4542              });
4543            }
4544          }
4545        },
4546
4547        hide: function(callback) {
4548          callback = $.isFunction(callback)
4549            ? callback
4550            : function(){}
4551          ;
4552          if( module.is.active() ) {
4553            module.debug('Hiding dropdown');
4554            if(settings.onHide.call(element) !== false) {
4555              module.animate.hide(function() {
4556                module.remove.visible();
4557                callback.call(element);
4558              });
4559            }
4560          }
4561        },
4562
4563        hideOthers: function() {
4564          module.verbose('Finding other dropdowns to hide');
4565          $allModules
4566            .not($module)
4567              .has(selector.menu + '.' + className.visible)
4568                .dropdown('hide')
4569          ;
4570        },
4571
4572        hideMenu: function() {
4573          module.verbose('Hiding menu  instantaneously');
4574          module.remove.active();
4575          module.remove.visible();
4576          $menu.transition('hide');
4577        },
4578
4579        hideSubMenus: function() {
4580          var
4581            $subMenus = $menu.children(selector.item).find(selector.menu)
4582          ;
4583          module.verbose('Hiding sub menus', $subMenus);
4584          $subMenus.transition('hide');
4585        },
4586
4587        bind: {
4588          events: function() {
4589            if(hasTouch) {
4590              module.bind.touchEvents();
4591            }
4592            module.bind.keyboardEvents();
4593            module.bind.inputEvents();
4594            module.bind.mouseEvents();
4595          },
4596          touchEvents: function() {
4597            module.debug('Touch device detected binding additional touch events');
4598            if( module.is.searchSelection() ) {
4599              // do nothing special yet
4600            }
4601            else if( module.is.single() ) {
4602              $module
4603                .on('touchstart' + eventNamespace, module.event.test.toggle)
4604              ;
4605            }
4606            $menu
4607              .on('touchstart' + eventNamespace, selector.item, module.event.item.mouseenter)
4608            ;
4609          },
4610          keyboardEvents: function() {
4611            module.verbose('Binding keyboard events');
4612            $module
4613              .on('keydown' + eventNamespace, module.event.keydown)
4614            ;
4615            if( module.has.search() ) {
4616              $module
4617                .on(module.get.inputEvent() + eventNamespace, selector.search, module.event.input)
4618              ;
4619            }
4620            if( module.is.multiple() ) {
4621              $document
4622                .on('keydown' + elementNamespace, module.event.document.keydown)
4623              ;
4624            }
4625          },
4626          inputEvents: function() {
4627            module.verbose('Binding input change events');
4628            $module
4629              .on('change' + eventNamespace, selector.input, module.event.change)
4630            ;
4631          },
4632          mouseEvents: function() {
4633            module.verbose('Binding mouse events');
4634            if(module.is.multiple()) {
4635              $module
4636                .on('click'   + eventNamespace, selector.label,  module.event.label.click)
4637                .on('click'   + eventNamespace, selector.remove, module.event.remove.click)
4638              ;
4639            }
4640            if( module.is.searchSelection() ) {
4641              $module
4642                .on('mousedown' + eventNamespace, selector.menu,   module.event.menu.mousedown)
4643                .on('mouseup'   + eventNamespace, selector.menu,   module.event.menu.mouseup)
4644                .on('click'     + eventNamespace, selector.icon,   module.event.icon.click)
4645                .on('click'     + eventNamespace, selector.search, module.show)
4646                .on('focus'     + eventNamespace, selector.search, module.event.search.focus)
4647                .on('blur'      + eventNamespace, selector.search, module.event.search.blur)
4648                .on('click'     + eventNamespace, selector.text,   module.event.text.focus)
4649              ;
4650              if(module.is.multiple()) {
4651                $module
4652                  .on('click' + eventNamespace, module.event.click)
4653                ;
4654              }
4655            }
4656            else {
4657              if(settings.on == 'click') {
4658                $module
4659                  .on('click' + eventNamespace, selector.icon, module.event.icon.click)
4660                  .on('click' + eventNamespace, module.event.test.toggle)
4661                ;
4662              }
4663              else if(settings.on == 'hover') {
4664                $module
4665                  .on('mouseenter' + eventNamespace, module.delay.show)
4666                  .on('mouseleave' + eventNamespace, module.delay.hide)
4667                ;
4668              }
4669              else {
4670                $module
4671                  .on(settings.on + eventNamespace, module.toggle)
4672                ;
4673              }
4674              $module
4675                .on('mousedown' + eventNamespace, module.event.mousedown)
4676                .on('mouseup'   + eventNamespace, module.event.mouseup)
4677                .on('focus'     + eventNamespace, module.event.focus)
4678                .on('blur'      + eventNamespace, module.event.blur)
4679              ;
4680            }
4681            $menu
4682              .on('mouseenter' + eventNamespace, selector.item, module.event.item.mouseenter)
4683              .on('mouseleave' + eventNamespace, selector.item, module.event.item.mouseleave)
4684              .on('click'      + eventNamespace, selector.item, module.event.item.click)
4685            ;
4686          },
4687          intent: function() {
4688            module.verbose('Binding hide intent event to document');
4689            if(hasTouch) {
4690              $document
4691                .on('touchstart' + elementNamespace, module.event.test.touch)
4692                .on('touchmove'  + elementNamespace, module.event.test.touch)
4693              ;
4694            }
4695            $document
4696              .on('click' + elementNamespace, module.event.test.hide)
4697            ;
4698          }
4699        },
4700
4701        unbind: {
4702          intent: function() {
4703            module.verbose('Removing hide intent event from document');
4704            if(hasTouch) {
4705              $document
4706                .off('touchstart' + elementNamespace)
4707                .off('touchmove' + elementNamespace)
4708              ;
4709            }
4710            $document
4711              .off('click' + elementNamespace)
4712            ;
4713          }
4714        },
4715
4716        filter: function(query) {
4717          var
4718            searchTerm = (query !== undefined)
4719              ? query
4720              : module.get.query(),
4721            afterFiltered = function() {
4722              if(module.is.multiple()) {
4723                module.filterActive();
4724              }
4725              module.select.firstUnfiltered();
4726              if( module.has.allResultsFiltered() ) {
4727                if( settings.onNoResults.call(element, searchTerm) ) {
4728                  if(!settings.allowAdditions) {
4729                    module.verbose('All items filtered, showing message', searchTerm);
4730                    module.add.message(message.noResults);
4731                  }
4732                }
4733                else {
4734                  module.verbose('All items filtered, hiding dropdown', searchTerm);
4735                  module.hideMenu();
4736                }
4737              }
4738              else {
4739                module.remove.message();
4740              }
4741              if(settings.allowAdditions) {
4742                module.add.userSuggestion(query);
4743              }
4744              if(module.is.searchSelection() && module.can.show() && module.is.focusedOnSearch() ) {
4745                module.show();
4746              }
4747            }
4748          ;
4749          if(settings.useLabels && module.has.maxSelections()) {
4750            return;
4751          }
4752          if(settings.apiSettings) {
4753            if( module.can.useAPI() ) {
4754              module.queryRemote(searchTerm, function() {
4755                afterFiltered();
4756              });
4757            }
4758            else {
4759              module.error(error.noAPI);
4760            }
4761          }
4762          else {
4763            module.filterItems(searchTerm);
4764            afterFiltered();
4765          }
4766        },
4767
4768        queryRemote: function(query, callback) {
4769          var
4770            apiSettings = {
4771              errorDuration        : false,
4772              throttle             : settings.throttle,
4773              urlData              : {
4774                query: query
4775              },
4776              onError: function() {
4777                module.add.message(message.serverError);
4778                callback();
4779              },
4780              onFailure: function() {
4781                module.add.message(message.serverError);
4782                callback();
4783              },
4784              onSuccess : function(response) {
4785                module.remove.message();
4786                module.setup.menu({
4787                  values: response[fields.remoteValues]
4788                });
4789                callback();
4790              }
4791            }
4792          ;
4793          if( !$module.api('get request') ) {
4794            module.setup.api();
4795          }
4796          apiSettings = $.extend(true, {}, apiSettings, settings.apiSettings);
4797          $module
4798            .api('setting', apiSettings)
4799            .api('query')
4800          ;
4801        },
4802
4803        filterItems: function(query) {
4804          var
4805            searchTerm = (query !== undefined)
4806              ? query
4807              : module.get.query(),
4808            results          =  null,
4809            escapedTerm      = module.escape.regExp(searchTerm),
4810            beginsWithRegExp = new RegExp('^' + escapedTerm, 'igm')
4811          ;
4812          // avoid loop if we're matching nothing
4813          if( module.has.query() ) {
4814            results = [];
4815
4816            module.verbose('Searching for matching values', searchTerm);
4817            $item
4818              .each(function(){
4819                var
4820                  $choice = $(this),
4821                  text,
4822                  value
4823                ;
4824                if(settings.match == 'both' || settings.match == 'text') {
4825                  text = String(module.get.choiceText($choice, false));
4826                  if(text.search(beginsWithRegExp) !== -1) {
4827                    results.push(this);
4828                    return true;
4829                  }
4830                  else if(settings.fullTextSearch && module.fuzzySearch(searchTerm, text)) {
4831                    results.push(this);
4832                    return true;
4833                  }
4834                }
4835                if(settings.match == 'both' || settings.match == 'value') {
4836                  value = String(module.get.choiceValue($choice, text));
4837
4838                  if(value.search(beginsWithRegExp) !== -1) {
4839                    results.push(this);
4840                    return true;
4841                  }
4842                  else if(settings.fullTextSearch && module.fuzzySearch(searchTerm, value)) {
4843                    results.push(this);
4844                    return true;
4845                  }
4846                }
4847              })
4848            ;
4849          }
4850          module.debug('Showing only matched items', searchTerm);
4851          module.remove.filteredItem();
4852          if(results) {
4853            $item
4854              .not(results)
4855              .addClass(className.filtered)
4856            ;
4857          }
4858        },
4859
4860        fuzzySearch: function(query, term) {
4861          var
4862            termLength  = term.length,
4863            queryLength = query.length
4864          ;
4865          query = query.toLowerCase();
4866          term  = term.toLowerCase();
4867          if(queryLength > termLength) {
4868            return false;
4869          }
4870          if(queryLength === termLength) {
4871            return (query === term);
4872          }
4873          search: for (var characterIndex = 0, nextCharacterIndex = 0; characterIndex < queryLength; characterIndex++) {
4874            var
4875              queryCharacter = query.charCodeAt(characterIndex)
4876            ;
4877            while(nextCharacterIndex < termLength) {
4878              if(term.charCodeAt(nextCharacterIndex++) === queryCharacter) {
4879                continue search;
4880              }
4881            }
4882            return false;
4883          }
4884          return true;
4885        },
4886
4887        filterActive: function() {
4888          if(settings.useLabels) {
4889            $item.filter('.' + className.active)
4890              .addClass(className.filtered)
4891            ;
4892          }
4893        },
4894
4895        focusSearch: function() {
4896          if( module.is.search() && !module.is.focusedOnSearch() ) {
4897            $search[0].focus();
4898          }
4899        },
4900
4901        forceSelection: function() {
4902          var
4903            $currentlySelected = $item.not(className.filtered).filter('.' + className.selected).eq(0),
4904            $activeItem        = $item.not(className.filtered).filter('.' + className.active).eq(0),
4905            $selectedItem      = ($currentlySelected.length > 0)
4906              ? $currentlySelected
4907              : $activeItem,
4908            hasSelected = ($selectedItem.size() > 0)
4909          ;
4910          if( module.has.query() ) {
4911            if(hasSelected) {
4912              module.debug('Forcing partial selection to selected item', $selectedItem);
4913              module.event.item.click.call($selectedItem);
4914              return;
4915            }
4916            else {
4917              module.remove.searchTerm();
4918            }
4919          }
4920          module.hide();
4921        },
4922
4923        event: {
4924          change: function() {
4925            if(!internalChange) {
4926              module.debug('Input changed, updating selection');
4927              module.set.selected();
4928            }
4929          },
4930          focus: function() {
4931            if(settings.showOnFocus && !activated && module.is.hidden() && !pageLostFocus) {
4932              module.show();
4933            }
4934          },
4935          click: function(event) {
4936            var
4937              $target = $(event.target)
4938            ;
4939            // focus search
4940            if($target.is($module) && !module.is.focusedOnSearch()) {
4941              module.focusSearch();
4942            }
4943          },
4944          blur: function(event) {
4945            pageLostFocus = (document.activeElement === this);
4946            if(!activated && !pageLostFocus) {
4947              module.remove.activeLabel();
4948              module.hide();
4949            }
4950          },
4951          // prevents focus callback from occurring on mousedown
4952          mousedown: function() {
4953            activated = true;
4954          },
4955          mouseup: function() {
4956            activated = false;
4957          },
4958          search: {
4959            focus: function() {
4960              activated = true;
4961              if(module.is.multiple()) {
4962                module.remove.activeLabel();
4963              }
4964              if(settings.showOnFocus) {
4965                module.search();
4966                module.show();
4967              }
4968            },
4969            blur: function(event) {
4970              pageLostFocus = (document.activeElement === this);
4971              if(!itemActivated && !pageLostFocus) {
4972                if(module.is.multiple()) {
4973                  module.remove.activeLabel();
4974                  module.hide();
4975                }
4976                else if(settings.forceSelection) {
4977                  module.forceSelection();
4978                }
4979                else {
4980                  module.hide();
4981                }
4982              }
4983              else if(pageLostFocus) {
4984                if(settings.forceSelection) {
4985                  module.forceSelection();
4986                }
4987              }
4988            }
4989          },
4990          icon: {
4991            click: function(event) {
4992              module.toggle();
4993              event.stopPropagation();
4994            }
4995          },
4996          text: {
4997            focus: function(event) {
4998              activated = true;
4999              module.focusSearch();
5000            }
5001          },
5002          input: function(event) {
5003            if(module.is.multiple() || module.is.searchSelection()) {
5004              module.set.filtered();
5005            }
5006            clearTimeout(module.timer);
5007            module.timer = setTimeout(module.search, settings.delay.search);
5008          },
5009          label: {
5010            click: function(event) {
5011              var
5012                $label        = $(this),
5013                $labels       = $module.find(selector.label),
5014                $activeLabels = $labels.filter('.' + className.active),
5015                $nextActive   = $label.nextAll('.' + className.active),
5016                $prevActive   = $label.prevAll('.' + className.active),
5017                $range = ($nextActive.length > 0)
5018                  ? $label.nextUntil($nextActive).add($activeLabels).add($label)
5019                  : $label.prevUntil($prevActive).add($activeLabels).add($label)
5020              ;
5021              if(event.shiftKey) {
5022                $activeLabels.removeClass(className.active);
5023                $range.addClass(className.active);
5024              }
5025              else if(event.ctrlKey) {
5026                $label.toggleClass(className.active);
5027              }
5028              else {
5029                $activeLabels.removeClass(className.active);
5030                $label.addClass(className.active);
5031              }
5032              settings.onLabelSelect.apply(this, $labels.filter('.' + className.active));
5033            }
5034          },
5035          remove: {
5036            click: function() {
5037              var
5038                $label = $(this).parent()
5039              ;
5040              if( $label.hasClass(className.active) ) {
5041                // remove all selected labels
5042                module.remove.activeLabels();
5043              }
5044              else {
5045                // remove this label only
5046                module.remove.activeLabels( $label );
5047              }
5048            }
5049          },
5050          test: {
5051            toggle: function(event) {
5052              var
5053                toggleBehavior = (module.is.multiple())
5054                  ? module.show
5055                  : module.toggle
5056              ;
5057              if( module.determine.eventOnElement(event, toggleBehavior) ) {
5058                event.preventDefault();
5059              }
5060            },
5061            touch: function(event) {
5062              module.determine.eventOnElement(event, function() {
5063                if(event.type == 'touchstart') {
5064                  module.timer = setTimeout(function() {
5065                    module.hide();
5066                  }, settings.delay.touch);
5067                }
5068                else if(event.type == 'touchmove') {
5069                  clearTimeout(module.timer);
5070                }
5071              });
5072              event.stopPropagation();
5073            },
5074            hide: function(event) {
5075              module.determine.eventInModule(event, module.hide);
5076            }
5077          },
5078          menu: {
5079            mousedown: function() {
5080              itemActivated = true;
5081            },
5082            mouseup: function() {
5083              itemActivated = false;
5084            }
5085          },
5086          item: {
5087            mouseenter: function(event) {
5088              var
5089                $subMenu    = $(this).children(selector.menu),
5090                $otherMenus = $(this).siblings(selector.item).children(selector.menu)
5091              ;
5092              if( $subMenu.length > 0 ) {
5093                clearTimeout(module.itemTimer);
5094                module.itemTimer = setTimeout(function() {
5095                  module.verbose('Showing sub-menu', $subMenu);
5096                  $.each($otherMenus, function() {
5097                    module.animate.hide(false, $(this));
5098                  });
5099                  module.animate.show(false,  $subMenu);
5100                }, settings.delay.show);
5101                event.preventDefault();
5102              }
5103            },
5104            mouseleave: function(event) {
5105              var
5106                $subMenu = $(this).children(selector.menu)
5107              ;
5108              if($subMenu.length > 0) {
5109                clearTimeout(module.itemTimer);
5110                module.itemTimer = setTimeout(function() {
5111                  module.verbose('Hiding sub-menu', $subMenu);
5112                  module.animate.hide(false,  $subMenu);
5113                }, settings.delay.hide);
5114              }
5115            },
5116            touchend: function() {
5117            },
5118            click: function (event) {
5119              var
5120                $choice        = $(this),
5121                $target        = (event)
5122                  ? $(event.target)
5123                  : $(''),
5124                $subMenu       = $choice.find(selector.menu),
5125                text           = module.get.choiceText($choice),
5126                value          = module.get.choiceValue($choice, text),
5127                hasSubMenu     = ($subMenu.length > 0),
5128                isBubbledEvent = ($subMenu.find($target).length > 0)
5129              ;
5130              if(!isBubbledEvent && (!hasSubMenu || settings.allowCategorySelection)) {
5131                if(!settings.useLabels) {
5132                  module.remove.filteredItem();
5133                  module.remove.searchTerm();
5134                  module.set.scrollPosition($choice);
5135                }
5136                module.determine.selectAction.call(this, text, value);
5137              }
5138            }
5139          },
5140
5141          document: {
5142            // label selection should occur even when element has no focus
5143            keydown: function(event) {
5144              var
5145                pressedKey    = event.which,
5146                isShortcutKey = module.is.inObject(pressedKey, keys)
5147              ;
5148              if(isShortcutKey) {
5149                var
5150                  $label            = $module.find(selector.label),
5151                  $activeLabel      = $label.filter('.' + className.active),
5152                  activeValue       = $activeLabel.data(metadata.value),
5153                  labelIndex        = $label.index($activeLabel),
5154                  labelCount        = $label.length,
5155                  hasActiveLabel    = ($activeLabel.length > 0),
5156                  hasMultipleActive = ($activeLabel.length > 1),
5157                  isFirstLabel      = (labelIndex === 0),
5158                  isLastLabel       = (labelIndex + 1 == labelCount),
5159                  isSearch          = module.is.searchSelection(),
5160                  isFocusedOnSearch = module.is.focusedOnSearch(),
5161                  isFocused         = module.is.focused(),
5162                  caretAtStart      = (isFocusedOnSearch && module.get.caretPosition() === 0),
5163                  $nextLabel
5164                ;
5165                if(isSearch && !hasActiveLabel && !isFocusedOnSearch) {
5166                  return;
5167                }
5168
5169                if(pressedKey == keys.leftArrow) {
5170                  // activate previous label
5171                  if((isFocused || caretAtStart) && !hasActiveLabel) {
5172                    module.verbose('Selecting previous label');
5173                    $label.last().addClass(className.active);
5174                  }
5175                  else if(hasActiveLabel) {
5176                    if(!event.shiftKey) {
5177                      module.verbose('Selecting previous label');
5178                      $label.removeClass(className.active);
5179                    }
5180                    else {
5181                      module.verbose('Adding previous label to selection');
5182                    }
5183                    if(isFirstLabel && !hasMultipleActive) {
5184                      $activeLabel.addClass(className.active);
5185                    }
5186                    else {
5187                      $activeLabel.prev(selector.siblingLabel)
5188                        .addClass(className.active)
5189                        .end()
5190                      ;
5191                    }
5192                    event.preventDefault();
5193                  }
5194                }
5195                else if(pressedKey == keys.rightArrow) {
5196                  // activate first label
5197                  if(isFocused && !hasActiveLabel) {
5198                    $label.first().addClass(className.active);
5199                  }
5200                  // activate next label
5201                  if(hasActiveLabel) {
5202                    if(!event.shiftKey) {
5203                      module.verbose('Selecting next label');
5204                      $label.removeClass(className.active);
5205                    }
5206                    else {
5207                      module.verbose('Adding next label to selection');
5208                    }
5209                    if(isLastLabel) {
5210                      if(isSearch) {
5211                        if(!isFocusedOnSearch) {
5212                          module.focusSearch();
5213                        }
5214                        else {
5215                          $label.removeClass(className.active);
5216                        }
5217                      }
5218                      else if(hasMultipleActive) {
5219                        $activeLabel.next(selector.siblingLabel).addClass(className.active);
5220                      }
5221                      else {
5222                        $activeLabel.addClass(className.active);
5223                      }
5224                    }
5225                    else {
5226                      $activeLabel.next(selector.siblingLabel).addClass(className.active);
5227                    }
5228                    event.preventDefault();
5229                  }
5230                }
5231                else if(pressedKey == keys.deleteKey || pressedKey == keys.backspace) {
5232                  if(hasActiveLabel) {
5233                    module.verbose('Removing active labels');
5234                    if(isLastLabel) {
5235                      if(isSearch && !isFocusedOnSearch) {
5236                        module.focusSearch();
5237                      }
5238                    }
5239                    $activeLabel.last().next(selector.siblingLabel).addClass(className.active);
5240                    module.remove.activeLabels($activeLabel);
5241                    event.preventDefault();
5242                  }
5243                  else if(caretAtStart && !hasActiveLabel && pressedKey == keys.backspace) {
5244                    module.verbose('Removing last label on input backspace');
5245                    $activeLabel = $label.last().addClass(className.active);
5246                    module.remove.activeLabels($activeLabel);
5247                  }
5248                }
5249                else {
5250                  $activeLabel.removeClass(className.active);
5251                }
5252              }
5253            }
5254          },
5255
5256          keydown: function(event) {
5257            var
5258              pressedKey    = event.which,
5259              isShortcutKey = module.is.inObject(pressedKey, keys)
5260            ;
5261            if(isShortcutKey) {
5262              var
5263                $currentlySelected = $item.not(selector.unselectable).filter('.' + className.selected).eq(0),
5264                $activeItem        = $menu.children('.' + className.active).eq(0),
5265                $selectedItem      = ($currentlySelected.length > 0)
5266                  ? $currentlySelected
5267                  : $activeItem,
5268                $visibleItems = ($selectedItem.length > 0)
5269                  ? $selectedItem.siblings(':not(.' + className.filtered +')').andSelf()
5270                  : $menu.children(':not(.' + className.filtered +')'),
5271                $subMenu             = $selectedItem.children(selector.menu),
5272                $parentMenu          = $selectedItem.closest(selector.menu),
5273                inVisibleMenu        = ($parentMenu.hasClass(className.visible) || $parentMenu.hasClass(className.animating) || $parentMenu.parent(selector.menu).length > 0),
5274                hasSubMenu           = ($subMenu.length> 0),
5275                hasSelectedItem      = ($selectedItem.length > 0),
5276                selectedIsSelectable = ($selectedItem.not(selector.unselectable).length > 0),
5277                delimiterPressed     = (pressedKey == keys.delimiter && settings.allowAdditions && module.is.multiple()),
5278                $nextItem,
5279                isSubMenuItem,
5280                newIndex
5281              ;
5282              // visible menu keyboard shortcuts
5283              if( module.is.visible() ) {
5284
5285                // enter (select or open sub-menu)
5286                if(pressedKey == keys.enter || delimiterPressed) {
5287                  if(pressedKey == keys.enter && hasSelectedItem && hasSubMenu && !settings.allowCategorySelection) {
5288                    module.verbose('Pressed enter on unselectable category, opening sub menu');
5289                    pressedKey = keys.rightArrow;
5290                  }
5291                  else if(selectedIsSelectable) {
5292                    module.verbose('Selecting item from keyboard shortcut', $selectedItem);
5293                    module.event.item.click.call($selectedItem, event);
5294                    if(module.is.searchSelection()) {
5295                      module.remove.searchTerm();
5296                    }
5297                  }
5298                  event.preventDefault();
5299                }
5300
5301                // left arrow (hide sub-menu)
5302                if(pressedKey == keys.leftArrow) {
5303
5304                  isSubMenuItem = ($parentMenu[0] !== $menu[0]);
5305
5306                  if(isSubMenuItem) {
5307                    module.verbose('Left key pressed, closing sub-menu');
5308                    module.animate.hide(false,  $parentMenu);
5309                    $selectedItem
5310                      .removeClass(className.selected)
5311                    ;
5312                    $parentMenu
5313                      .closest(selector.item)
5314                        .addClass(className.selected)
5315                    ;
5316                    event.preventDefault();
5317                  }
5318                }
5319
5320                // right arrow (show sub-menu)
5321                if(pressedKey == keys.rightArrow) {
5322                  if(hasSubMenu) {
5323                    module.verbose('Right key pressed, opening sub-menu');
5324                    module.animate.show(false,  $subMenu);
5325                    $selectedItem
5326                      .removeClass(className.selected)
5327                    ;
5328                    $subMenu
5329                      .find(selector.item).eq(0)
5330                        .addClass(className.selected)
5331                    ;
5332                    event.preventDefault();
5333                  }
5334                }
5335
5336                // up arrow (traverse menu up)
5337                if(pressedKey == keys.upArrow) {
5338                  $nextItem = (hasSelectedItem && inVisibleMenu)
5339                    ? $selectedItem.prevAll(selector.item + ':not(' + selector.unselectable + ')').eq(0)
5340                    : $item.eq(0)
5341                  ;
5342                  if($visibleItems.index( $nextItem ) < 0) {
5343                    module.verbose('Up key pressed but reached top of current menu');
5344                    event.preventDefault();
5345                    return;
5346                  }
5347                  else {
5348                    module.verbose('Up key pressed, changing active item');
5349                    $selectedItem
5350                      .removeClass(className.selected)
5351                    ;
5352                    $nextItem
5353                      .addClass(className.selected)
5354                    ;
5355                    module.set.scrollPosition($nextItem);
5356                  }
5357                  event.preventDefault();
5358                }
5359
5360                // down arrow (traverse menu down)
5361                if(pressedKey == keys.downArrow) {
5362                  $nextItem = (hasSelectedItem && inVisibleMenu)
5363                    ? $nextItem = $selectedItem.nextAll(selector.item + ':not(' + selector.unselectable + ')').eq(0)
5364                    : $item.eq(0)
5365                  ;
5366                  if($nextItem.length === 0) {
5367                    module.verbose('Down key pressed but reached bottom of current menu');
5368                    event.preventDefault();
5369                    return;
5370                  }
5371                  else {
5372                    module.verbose('Down key pressed, changing active item');
5373                    $item
5374                      .removeClass(className.selected)
5375                    ;
5376                    $nextItem
5377                      .addClass(className.selected)
5378                    ;
5379                    module.set.scrollPosition($nextItem);
5380                  }
5381                  event.preventDefault();
5382                }
5383
5384                // page down (show next page)
5385                if(pressedKey == keys.pageUp) {
5386                  module.scrollPage('up');
5387                  event.preventDefault();
5388                }
5389                if(pressedKey == keys.pageDown) {
5390                  module.scrollPage('down');
5391                  event.preventDefault();
5392                }
5393
5394                // escape (close menu)
5395                if(pressedKey == keys.escape) {
5396                  module.verbose('Escape key pressed, closing dropdown');
5397                  module.hide();
5398                }
5399
5400              }
5401              else {
5402                // delimiter key
5403                if(delimiterPressed) {
5404                  event.preventDefault();
5405                }
5406                // down arrow (open menu)
5407                if(pressedKey == keys.downArrow) {
5408                  module.verbose('Down key pressed, showing dropdown');
5409                  module.show();
5410                  event.preventDefault();
5411                }
5412              }
5413            }
5414            else {
5415              if( module.is.selection() && !module.is.search() ) {
5416                module.set.selectedLetter( String.fromCharCode(pressedKey) );
5417              }
5418            }
5419          }
5420        },
5421
5422        trigger: {
5423          change: function() {
5424            var
5425              events       = document.createEvent('HTMLEvents'),
5426              inputElement = $input[0]
5427            ;
5428            if(inputElement) {
5429              module.verbose('Triggering native change event');
5430              events.initEvent('change', true, false);
5431              inputElement.dispatchEvent(events);
5432            }
5433          }
5434        },
5435
5436        determine: {
5437          selectAction: function(text, value) {
5438            module.verbose('Determining action', settings.action);
5439            if( $.isFunction( module.action[settings.action] ) ) {
5440              module.verbose('Triggering preset action', settings.action, text, value);
5441              module.action[ settings.action ].call(this, text, value);
5442            }
5443            else if( $.isFunction(settings.action) ) {
5444              module.verbose('Triggering user action', settings.action, text, value);
5445              settings.action.call(this, text, value);
5446            }
5447            else {
5448              module.error(error.action, settings.action);
5449            }
5450          },
5451          eventInModule: function(event, callback) {
5452            var
5453              $target    = $(event.target),
5454              inDocument = ($target.closest(document.documentElement).length > 0),
5455              inModule   = ($target.closest($module).length > 0)
5456            ;
5457            callback = $.isFunction(callback)
5458              ? callback
5459              : function(){}
5460            ;
5461            if(inDocument && !inModule) {
5462              module.verbose('Triggering event', callback);
5463              callback();
5464              return true;
5465            }
5466            else {
5467              module.verbose('Event occurred in dropdown, canceling callback');
5468              return false;
5469            }
5470          },
5471          eventOnElement: function(event, callback) {
5472            var
5473              $target    = $(event.target),
5474              $label     = $target.closest(selector.siblingLabel),
5475              notOnLabel = ($module.find($label).length === 0),
5476              notInMenu  = ($target.closest($menu).length === 0)
5477            ;
5478            callback = $.isFunction(callback)
5479              ? callback
5480              : function(){}
5481            ;
5482            if(notOnLabel && notInMenu) {
5483              module.verbose('Triggering event', callback);
5484              callback();
5485              return true;
5486            }
5487            else {
5488              module.verbose('Event occurred in dropdown menu, canceling callback');
5489              return false;
5490            }
5491          }
5492        },
5493
5494        action: {
5495
5496          nothing: function() {},
5497
5498          activate: function(text, value) {
5499            value = (value !== undefined)
5500              ? value
5501              : text
5502            ;
5503            if( module.can.activate( $(this) ) ) {
5504              module.set.selected(value, $(this));
5505              if(module.is.multiple() && !module.is.allFiltered()) {
5506                return;
5507              }
5508              else {
5509                module.hideAndClear();
5510              }
5511            }
5512          },
5513
5514          select: function(text, value) {
5515            // mimics action.activate but does not select text
5516            module.action.activate.call(this);
5517          },
5518
5519          combo: function(text, value) {
5520            value = (value !== undefined)
5521              ? value
5522              : text
5523            ;
5524            module.set.selected(value, $(this));
5525            module.hideAndClear();
5526          },
5527
5528          hide: function(text, value) {
5529            module.set.value(value);
5530            module.hideAndClear();
5531          }
5532
5533        },
5534
5535        get: {
5536          id: function() {
5537            return id;
5538          },
5539          defaultText: function() {
5540            return $module.data(metadata.defaultText);
5541          },
5542          defaultValue: function() {
5543            return $module.data(metadata.defaultValue);
5544          },
5545          placeholderText: function() {
5546            return $module.data(metadata.placeholderText) || '';
5547          },
5548          text: function() {
5549            return $text.text();
5550          },
5551          query: function() {
5552            return $.trim($search.val());
5553          },
5554          searchWidth: function(characterCount) {
5555            return (characterCount * settings.glyphWidth) + 'em';
5556          },
5557          selectionCount: function() {
5558            var
5559              values = module.get.values(),
5560              count
5561            ;
5562            count = ( module.is.multiple() )
5563              ? $.isArray(values)
5564                ? values.length
5565                : 0
5566              : (module.get.value() !== '')
5567                ? 1
5568                : 0
5569            ;
5570            return count;
5571          },
5572          transition: function($subMenu) {
5573            return (settings.transition == 'auto')
5574              ? module.is.upward($subMenu)
5575                ? 'slide up'
5576                : 'slide down'
5577              : settings.transition
5578            ;
5579          },
5580          userValues: function() {
5581            var
5582              values = module.get.values()
5583            ;
5584            if(!values) {
5585              return false;
5586            }
5587            values = $.isArray(values)
5588              ? values
5589              : [values]
5590            ;
5591            return $.grep(values, function(value) {
5592              return (module.get.item(value) === false);
5593            });
5594          },
5595          uniqueArray: function(array) {
5596            return $.grep(array, function (value, index) {
5597                return $.inArray(value, array) === index;
5598            });
5599          },
5600          caretPosition: function() {
5601            var
5602              input = $search.get(0),
5603              range,
5604              rangeLength
5605            ;
5606            if('selectionStart' in input) {
5607              return input.selectionStart;
5608            }
5609            else if (document.selection) {
5610              input.focus();
5611              range       = document.selection.createRange();
5612              rangeLength = range.text.length;
5613              range.moveStart('character', -input.value.length);
5614              return range.text.length - rangeLength;
5615            }
5616          },
5617          value: function() {
5618            var
5619              value = ($input.length > 0)
5620                ? $input.val()
5621                : $module.data(metadata.value)
5622            ;
5623            // prevents placeholder element from being selected when multiple
5624            if($.isArray(value) && value.length === 1 && value[0] === '') {
5625              return '';
5626            }
5627            return value;
5628          },
5629          values: function() {
5630            var
5631              value = module.get.value()
5632            ;
5633            if(value === '') {
5634              return '';
5635            }
5636            return ( !module.has.selectInput() && module.is.multiple() )
5637              ? (typeof value == 'string') // delimited string
5638                ? value.split(settings.delimiter)
5639                : ''
5640              : value
5641            ;
5642          },
5643          remoteValues: function() {
5644            var
5645              values = module.get.values(),
5646              remoteValues = false
5647            ;
5648            if(values) {
5649              if(typeof values == 'string') {
5650                values = [values];
5651              }
5652              remoteValues = {};
5653              $.each(values, function(index, value) {
5654                var
5655                  name = module.read.remoteData(value)
5656                ;
5657                module.verbose('Restoring value from session data', name, value);
5658                remoteValues[value] = (name)
5659                  ? name
5660                  : value
5661                ;
5662              });
5663            }
5664            return remoteValues;
5665          },
5666          choiceText: function($choice, preserveHTML) {
5667            preserveHTML = (preserveHTML !== undefined)
5668              ? preserveHTML
5669              : settings.preserveHTML
5670            ;
5671            if($choice) {
5672              if($choice.find(selector.menu).length > 0) {
5673                module.verbose('Retreiving text of element with sub-menu');
5674                $choice = $choice.clone();
5675                $choice.find(selector.menu).remove();
5676                $choice.find(selector.menuIcon).remove();
5677              }
5678              return ($choice.data(metadata.text) !== undefined)
5679                ? $choice.data(metadata.text)
5680                : (preserveHTML)
5681                  ? $.trim($choice.html())
5682                  : $.trim($choice.text())
5683              ;
5684            }
5685          },
5686          choiceValue: function($choice, choiceText) {
5687            choiceText = choiceText || module.get.choiceText($choice);
5688            if(!$choice) {
5689              return false;
vendor: 6,411 bytes, lines 5690-5868
5690            }
5691            return ($choice.data(metadata.value) !== undefined)
5692              ? String( $choice.data(metadata.value) )
5693              : (typeof choiceText === 'string')
5694                ? $.trim(choiceText.toLowerCase())
5695                : String(choiceText)
5696            ;
5697          },
5698          inputEvent: function() {
5699            var
5700              input = $search[0]
5701            ;
5702            if(input) {
5703              return (input.oninput !== undefined)
5704                ? 'input'
5705                : (input.onpropertychange !== undefined)
5706                  ? 'propertychange'
5707                  : 'keyup'
5708              ;
5709            }
5710            return false;
5711          },
5712          selectValues: function() {
5713            var
5714              select = {}
5715            ;
5716            select.values = [];
5717            $module
5718              .find('option')
5719                .each(function() {
5720                  var
5721                    $option  = $(this),
5722                    name     = $option.html(),
5723                    disabled = $option.attr('disabled'),
5724                    value    = ( $option.attr('value') !== undefined )
5725                      ? $option.attr('value')
5726                      : name
5727                  ;
5728                  if(settings.placeholder === 'auto' && value === '') {
5729                    select.placeholder = name;
5730                  }
5731                  else {
5732                    select.values.push({
5733                      name     : name,
5734                      value    : value,
5735                      disabled : disabled
5736                    });
5737                  }
5738                })
5739            ;
5740            if(settings.placeholder && settings.placeholder !== 'auto') {
5741              module.debug('Setting placeholder value to', settings.placeholder);
5742              select.placeholder = settings.placeholder;
5743            }
5744            if(settings.sortSelect) {
5745              select.values.sort(function(a, b) {
5746                return (a.name > b.name)
5747                  ? 1
5748                  : -1
5749                ;
5750              });
5751              module.debug('Retrieved and sorted values from select', select);
5752            }
5753            else {
5754              module.debug('Retreived values from select', select);
5755            }
5756            return select;
5757          },
5758          activeItem: function() {
5759            return $item.filter('.'  + className.active);
5760          },
5761          selectedItem: function() {
5762            var
5763              $selectedItem = $item.not(selector.unselectable).filter('.'  + className.selected)
5764            ;
5765            return ($selectedItem.length > 0)
5766              ? $selectedItem
5767              : $item.eq(0)
5768            ;
5769          },
5770          itemWithAdditions: function(value) {
5771            var
5772              $items       = module.get.item(value),
5773              $userItems   = module.create.userChoice(value),
5774              hasUserItems = ($userItems && $userItems.length > 0)
5775            ;
5776            if(hasUserItems) {
5777              $items = ($items.length > 0)
5778                ? $items.add($userItems)
5779                : $userItems
5780              ;
5781            }
5782            return $items;
5783          },
5784          item: function(value, strict) {
5785            var
5786              $selectedItem = false,
5787              shouldSearch,
5788              isMultiple
5789            ;
5790            value = (value !== undefined)
5791              ? value
5792              : ( module.get.values() !== undefined)
5793                ? module.get.values()
5794                : module.get.text()
5795            ;
5796            shouldSearch = (isMultiple)
5797              ? (value.length > 0)
5798              : (value !== undefined && value !== null)
5799            ;
5800            isMultiple = (module.is.multiple() && $.isArray(value));
5801            strict     = (value === '' || value === 0)
5802              ? true
5803              : strict || false
5804            ;
5805            if(shouldSearch) {
5806              $item
5807                .each(function() {
5808                  var
5809                    $choice       = $(this),
5810                    optionText    = module.get.choiceText($choice),
5811                    optionValue   = module.get.choiceValue($choice, optionText)
5812                  ;
5813                  // safe early exit
5814                  if(optionValue === null || optionValue === undefined) {
5815                    return;
5816                  }
5817                  if(isMultiple) {
5818                    if($.inArray( String(optionValue), value) !== -1 || $.inArray(optionText, value) !== -1) {
5819                      $selectedItem = ($selectedItem)
5820                        ? $selectedItem.add($choice)
5821                        : $choice
5822                      ;
5823                    }
5824                  }
5825                  else if(strict) {
5826                    module.verbose('Ambiguous dropdown value using strict type check', $choice, value);
5827                    if( optionValue === value || optionText === value) {
5828                      $selectedItem = $choice;
5829                      return true;
5830                    }
5831                  }
5832                  else {
5833                    if( String(optionValue) == String(value) || optionText == value) {
5834                      module.verbose('Found select item by value', optionValue, value);
5835                      $selectedItem = $choice;
5836                      return true;
5837                    }
5838                  }
5839                })
5840              ;
5841            }
5842            return $selectedItem;
5843          }
5844        },
5845
5846        check: {
5847          maxSelections: function(selectionCount) {
5848            if(settings.maxSelections) {
5849              selectionCount = (selectionCount !== undefined)
5850                ? selectionCount
5851                : module.get.selectionCount()
5852              ;
5853              if(selectionCount >= settings.maxSelections) {
5854                module.debug('Maximum selection count reached');
5855                if(settings.useLabels) {
5856                  $item.addClass(className.filtered);
5857                  module.add.message(message.maxSelections);
5858                }
5859                return true;
5860              }
5861              else {
5862                module.verbose('No longer at maximum selection count');
5863                module.remove.message();
5864                module.remove.filteredItem();
5865                if(module.is.searchSelection()) {
5866                  module.filterItems();
5867                }
5868                return false;
vendor: 26,575 bytes, lines 5869-6611
5869              }
5870            }
5871            return true;
5872          }
5873        },
5874
5875        restore: {
5876          defaults: function() {
5877            module.clear();
5878            module.restore.defaultText();
5879            module.restore.defaultValue();
5880          },
5881          defaultText: function() {
5882            var
5883              defaultText     = module.get.defaultText(),
5884              placeholderText = module.get.placeholderText
5885            ;
5886            if(defaultText === placeholderText) {
5887              module.debug('Restoring default placeholder text', defaultText);
5888              module.set.placeholderText(defaultText);
5889            }
5890            else {
5891              module.debug('Restoring default text', defaultText);
5892              module.set.text(defaultText);
5893            }
5894          },
5895          defaultValue: function() {
5896            var
5897              defaultValue = module.get.defaultValue()
5898            ;
5899            if(defaultValue !== undefined) {
5900              module.debug('Restoring default value', defaultValue);
5901              if(defaultValue !== '') {
5902                module.set.value(defaultValue);
5903                module.set.selected();
5904              }
5905              else {
5906                module.remove.activeItem();
5907                module.remove.selectedItem();
5908              }
5909            }
5910          },
5911          labels: function() {
5912            if(settings.allowAdditions) {
5913              if(!settings.useLabels) {
5914                module.error(error.labels);
5915                settings.useLabels = true;
5916              }
5917              module.debug('Restoring selected values');
5918              module.create.userLabels();
5919            }
5920            module.check.maxSelections();
5921          },
5922          selected: function() {
5923            module.restore.values();
5924            if(module.is.multiple()) {
5925              module.debug('Restoring previously selected values and labels');
5926              module.restore.labels();
5927            }
5928            else {
5929              module.debug('Restoring previously selected values');
5930            }
5931          },
5932          values: function() {
5933            // prevents callbacks from occuring on initial load
5934            module.set.initialLoad();
5935            if(settings.apiSettings) {
5936              if(settings.saveRemoteData) {
5937                module.restore.remoteValues();
5938              }
5939              else {
5940                module.clearValue();
5941              }
5942            }
5943            else {
5944              module.set.selected();
5945            }
5946            module.remove.initialLoad();
5947          },
5948          remoteValues: function() {
5949            var
5950              values = module.get.remoteValues()
5951            ;
5952            module.debug('Recreating selected from session data', values);
5953            if(values) {
5954              if( module.is.single() ) {
5955                $.each(values, function(value, name) {
5956                  module.set.text(name);
5957                });
5958              }
5959              else {
5960                $.each(values, function(value, name) {
5961                  module.add.label(value, name);
5962                });
5963              }
5964            }
5965          }
5966        },
5967
5968        read: {
5969          remoteData: function(value) {
5970            var
5971              name
5972            ;
5973            if(window.Storage === undefined) {
5974              module.error(error.noStorage);
5975              return;
5976            }
5977            name = sessionStorage.getItem(value);
5978            return (name !== undefined)
5979              ? name
5980              : false
5981            ;
5982          }
5983        },
5984
5985        save: {
5986          defaults: function() {
5987            module.save.defaultText();
5988            module.save.placeholderText();
5989            module.save.defaultValue();
5990          },
5991          defaultValue: function() {
5992            var
5993              value = module.get.value()
5994            ;
5995            module.verbose('Saving default value as', value);
5996            $module.data(metadata.defaultValue, value);
5997          },
5998          defaultText: function() {
5999            var
6000              text = module.get.text()
6001            ;
6002            module.verbose('Saving default text as', text);
6003            $module.data(metadata.defaultText, text);
6004          },
6005          placeholderText: function() {
6006            var
6007              text
6008            ;
6009            if(settings.placeholder !== false && $text.hasClass(className.placeholder)) {
6010              text = module.get.text();
6011              module.verbose('Saving placeholder text as', text);
6012              $module.data(metadata.placeholderText, text);
6013            }
6014          },
6015          remoteData: function(name, value) {
6016            if(window.Storage === undefined) {
6017              module.error(error.noStorage);
6018              return;
6019            }
6020            module.verbose('Saving remote data to session storage', value, name);
6021            sessionStorage.setItem(value, name);
6022          }
6023        },
6024
6025        clear: function() {
6026          if(module.is.multiple()) {
6027            module.remove.labels();
6028          }
6029          else {
6030            module.remove.activeItem();
6031            module.remove.selectedItem();
6032          }
6033          module.set.placeholderText();
6034          module.clearValue();
6035        },
6036
6037        clearValue: function() {
6038          module.set.value('');
6039        },
6040
6041        scrollPage: function(direction, $selectedItem) {
6042          var
6043            $currentItem  = $selectedItem || module.get.selectedItem(),
6044            $menu         = $currentItem.closest(selector.menu),
6045            menuHeight    = $menu.outerHeight(),
6046            currentScroll = $menu.scrollTop(),
6047            itemHeight    = $item.eq(0).outerHeight(),
6048            itemsPerPage  = Math.floor(menuHeight / itemHeight),
6049            maxScroll     = $menu.prop('scrollHeight'),
6050            newScroll     = (direction == 'up')
6051              ? currentScroll - (itemHeight * itemsPerPage)
6052              : currentScroll + (itemHeight * itemsPerPage),
6053            $selectableItem = $item.not(selector.unselectable),
6054            isWithinRange,
6055            $nextSelectedItem,
6056            elementIndex
6057          ;
6058          elementIndex      = (direction == 'up')
6059            ? $selectableItem.index($currentItem) - itemsPerPage
6060            : $selectableItem.index($currentItem) + itemsPerPage
6061          ;
6062          isWithinRange = (direction == 'up')
6063            ? (elementIndex >= 0)
6064            : (elementIndex < $selectableItem.length)
6065          ;
6066          $nextSelectedItem = (isWithinRange)
6067            ? $selectableItem.eq(elementIndex)
6068            : (direction == 'up')
6069              ? $selectableItem.first()
6070              : $selectableItem.last()
6071          ;
6072          if($nextSelectedItem.length > 0) {
6073            module.debug('Scrolling page', direction, $nextSelectedItem);
6074            $currentItem
6075              .removeClass(className.selected)
6076            ;
6077            $nextSelectedItem
6078              .addClass(className.selected)
6079            ;
6080            $menu
6081              .scrollTop(newScroll)
6082            ;
6083          }
6084        },
6085
6086        set: {
6087          filtered: function() {
6088            var
6089              isMultiple       = module.is.multiple(),
6090              isSearch         = module.is.searchSelection(),
6091              isSearchMultiple = (isMultiple && isSearch),
6092              searchValue      = (isSearch)
6093                ? module.get.query()
6094                : '',
6095              hasSearchValue   = (typeof searchValue === 'string' && searchValue.length > 0),
6096              searchWidth      = module.get.searchWidth(searchValue.length),
6097              valueIsSet       = searchValue !== ''
6098            ;
6099            if(isMultiple && hasSearchValue) {
6100              module.verbose('Adjusting input width', searchWidth, settings.glyphWidth);
6101              $search.css('width', searchWidth);
6102            }
6103            if(hasSearchValue || (isSearchMultiple && valueIsSet)) {
6104              module.verbose('Hiding placeholder text');
6105              $text.addClass(className.filtered);
6106            }
6107            else if(!isMultiple || (isSearchMultiple && !valueIsSet)) {
6108              module.verbose('Showing placeholder text');
6109              $text.removeClass(className.filtered);
6110            }
6111          },
6112          loading: function() {
6113            $module.addClass(className.loading);
6114          },
6115          placeholderText: function(text) {
6116            text = text || module.get.placeholderText();
6117            module.debug('Setting placeholder text', text);
6118            module.set.text(text);
6119            $text.addClass(className.placeholder);
6120          },
6121          tabbable: function() {
6122            if( module.has.search() ) {
6123              module.debug('Added tabindex to searchable dropdown');
6124              $search
6125                .val('')
6126                .attr('tabindex', 0)
6127              ;
6128              $menu
6129                .attr('tabindex', -1)
6130              ;
6131            }
6132            else {
6133              module.debug('Added tabindex to dropdown');
6134              if( $module.attr('tabindex') === undefined) {
6135                $module
6136                  .attr('tabindex', 0)
6137                ;
6138                $menu
6139                  .attr('tabindex', -1)
6140                ;
6141              }
6142            }
6143          },
6144          initialLoad: function() {
6145            module.verbose('Setting initial load');
6146            initialLoad = true;
6147          },
6148          activeItem: function($item) {
6149            if( settings.allowAdditions && $item.filter(selector.addition).length > 0 ) {
6150              $item.addClass(className.filtered);
6151            }
6152            else {
6153              $item.addClass(className.active);
6154            }
6155          },
6156          scrollPosition: function($item, forceScroll) {
6157            var
6158              edgeTolerance = 5,
6159              $menu,
6160              hasActive,
6161              offset,
6162              itemHeight,
6163              itemOffset,
6164              menuOffset,
6165              menuScroll,
6166              menuHeight,
6167              abovePage,
6168              belowPage
6169            ;
6170
6171            $item       = $item || module.get.selectedItem();
6172            $menu       = $item.closest(selector.menu);
6173            hasActive   = ($item && $item.length > 0);
6174            forceScroll = (forceScroll !== undefined)
6175              ? forceScroll
6176              : false
6177            ;
6178            if($item && $menu.length > 0 && hasActive) {
6179              itemOffset = $item.position().top;
6180
6181              $menu.addClass(className.loading);
6182              menuScroll = $menu.scrollTop();
6183              menuOffset = $menu.offset().top;
6184              itemOffset = $item.offset().top;
6185              offset     = menuScroll - menuOffset + itemOffset;
6186              if(!forceScroll) {
6187                menuHeight = $menu.height();
6188                belowPage  = menuScroll + menuHeight < (offset + edgeTolerance);
6189                abovePage  = ((offset - edgeTolerance) < menuScroll);
6190              }
6191              module.debug('Scrolling to active item', offset);
6192              if(forceScroll || abovePage || belowPage) {
6193                $menu.scrollTop(offset);
6194              }
6195              $menu.removeClass(className.loading);
6196            }
6197          },
6198          text: function(text) {
6199            if(settings.action !== 'select') {
6200              if(settings.action == 'combo') {
6201                module.debug('Changing combo button text', text, $combo);
6202                if(settings.preserveHTML) {
6203                  $combo.html(text);
6204                }
6205                else {
6206                  $combo.text(text);
6207                }
6208              }
6209              else {
6210                if(text !== module.get.placeholderText()) {
6211                  $text.removeClass(className.placeholder);
6212                }
6213                module.debug('Changing text', text, $text);
6214                $text
6215                  .removeClass(className.filtered)
6216                ;
6217                if(settings.preserveHTML) {
6218                  $text.html(text);
6219                }
6220                else {
6221                  $text.text(text);
6222                }
6223              }
6224            }
6225          },
6226          selectedLetter: function(letter) {
6227            var
6228              $selectedItem         = $item.filter('.' + className.selected),
6229              alreadySelectedLetter = $selectedItem.length > 0 && module.has.firstLetter($selectedItem, letter),
6230              $nextValue            = false,
6231              $nextItem
6232            ;
6233            // check next of same letter
6234            if(alreadySelectedLetter) {
6235              $nextItem = $selectedItem.nextAll($item).eq(0);
6236              if( module.has.firstLetter($nextItem, letter) ) {
6237                $nextValue  = $nextItem;
6238              }
6239            }
6240            // check all values
6241            if(!$nextValue) {
6242              $item
6243                .each(function(){
6244                  if(module.has.firstLetter($(this), letter)) {
6245                    $nextValue = $(this);
6246                    return false;
6247                  }
6248                })
6249              ;
6250            }
6251            // set next value
6252            if($nextValue) {
6253              module.verbose('Scrolling to next value with letter', letter);
6254              module.set.scrollPosition($nextValue);
6255              $selectedItem.removeClass(className.selected);
6256              $nextValue.addClass(className.selected);
6257            }
6258          },
6259          direction: function($menu) {
6260            if(settings.direction == 'auto') {
6261              if(module.is.onScreen($menu)) {
6262                module.remove.upward($menu);
6263              }
6264              else {
6265                module.set.upward($menu);
6266              }
6267            }
6268            else if(settings.direction == 'upward') {
6269              module.set.upward($menu);
6270            }
6271          },
6272          upward: function($menu) {
6273            var $element = $menu || $module;
6274            $element.addClass(className.upward);
6275          },
6276          value: function(value, text, $selected) {
6277            var
6278              hasInput     = ($input.length > 0),
6279              isAddition   = !module.has.value(value),
6280              currentValue = module.get.values(),
6281              stringValue  = (value !== undefined)
6282                ? String(value)
6283                : value,
6284              newValue
6285            ;
6286            if(hasInput) {
6287              if(stringValue == currentValue) {
6288                module.verbose('Skipping value update already same value', value, currentValue);
6289                if(!module.is.initialLoad()) {
6290                  return;
6291                }
6292              }
6293
6294              if( module.is.single() && module.has.selectInput() && module.can.extendSelect() ) {
6295                module.debug('Adding user option', value);
6296                module.add.optionValue(value);
6297              }
6298              module.debug('Updating input value', value, currentValue);
6299              internalChange = true;
6300              $input
6301                .val(value)
6302              ;
6303              if(settings.fireOnInit === false && module.is.initialLoad()) {
6304                module.debug('Input native change event ignored on initial load');
6305              }
6306              else {
6307                module.trigger.change();
6308              }
6309              internalChange = false;
6310            }
6311            else {
6312              module.verbose('Storing value in metadata', value, $input);
6313              if(value !== currentValue) {
6314                $module.data(metadata.value, stringValue);
6315              }
6316            }
6317            if(settings.fireOnInit === false && module.is.initialLoad()) {
6318              module.verbose('No callback on initial load', settings.onChange);
6319            }
6320            else {
6321              settings.onChange.call(element, value, text, $selected);
6322            }
6323          },
6324          active: function() {
6325            $module
6326              .addClass(className.active)
6327            ;
6328          },
6329          multiple: function() {
6330            $module.addClass(className.multiple);
6331          },
6332          visible: function() {
6333            $module.addClass(className.visible);
6334          },
6335          exactly: function(value, $selectedItem) {
6336            module.debug('Setting selected to exact values');
6337            module.clear();
6338            module.set.selected(value, $selectedItem);
6339          },
6340          selected: function(value, $selectedItem) {
6341            var
6342              isMultiple = module.is.multiple(),
6343              $userSelectedItem
6344            ;
6345            $selectedItem = (settings.allowAdditions)
6346              ? $selectedItem || module.get.itemWithAdditions(value)
6347              : $selectedItem || module.get.item(value)
6348            ;
6349            if(!$selectedItem) {
6350              return;
6351            }
6352            module.debug('Setting selected menu item to', $selectedItem);
6353            if(module.is.single()) {
6354              module.remove.activeItem();
6355              module.remove.selectedItem();
6356            }
6357            else if(settings.useLabels) {
6358              module.remove.selectedItem();
6359            }
6360            // select each item
6361            $selectedItem
6362              .each(function() {
6363                var
6364                  $selected      = $(this),
6365                  selectedText   = module.get.choiceText($selected),
6366                  selectedValue  = module.get.choiceValue($selected, selectedText),
6367
6368                  isFiltered     = $selected.hasClass(className.filtered),
6369                  isActive       = $selected.hasClass(className.active),
6370                  isUserValue    = $selected.hasClass(className.addition),
6371                  shouldAnimate  = (isMultiple && $selectedItem.length == 1)
6372                ;
6373                if(isMultiple) {
6374                  if(!isActive || isUserValue) {
6375                    if(settings.apiSettings && settings.saveRemoteData) {
6376                      module.save.remoteData(selectedText, selectedValue);
6377                    }
6378                    if(settings.useLabels) {
6379                      module.add.value(selectedValue, selectedText, $selected);
6380                      module.add.label(selectedValue, selectedText, shouldAnimate);
6381                      module.set.activeItem($selected);
6382                      module.filterActive();
6383                      module.select.nextAvailable($selectedItem);
6384                    }
6385                    else {
6386                      module.add.value(selectedValue, selectedText, $selected);
6387                      module.set.text(module.add.variables(message.count));
6388                      module.set.activeItem($selected);
6389                    }
6390                  }
6391                  else if(!isFiltered) {
6392                    module.debug('Selected active value, removing label');
6393                    module.remove.selected(selectedValue);
6394                  }
6395                }
6396                else {
6397                  if(settings.apiSettings && settings.saveRemoteData) {
6398                    module.save.remoteData(selectedText, selectedValue);
6399                  }
6400                  module.set.text(selectedText);
6401                  module.set.value(selectedValue, selectedText, $selected);
6402                  $selected
6403                    .addClass(className.active)
6404                    .addClass(className.selected)
6405                  ;
6406                }
6407              })
6408            ;
6409          }
6410        },
6411
6412        add: {
6413          label: function(value, text, shouldAnimate) {
6414            var
6415              $next  = module.is.searchSelection()
6416                ? $search
6417                : $text,
6418              $label
6419            ;
6420            $label =  $('<a />')
6421              .addClass(className.label)
6422              .attr('data-value', value)
6423              .html(templates.label(value, text))
6424            ;
6425            $label = settings.onLabelCreate.call($label, value, text);
6426
6427            if(module.has.label(value)) {
6428              module.debug('Label already exists, skipping', value);
6429              return;
6430            }
6431            if(settings.label.variation) {
6432              $label.addClass(settings.label.variation);
6433            }
6434            if(shouldAnimate === true) {
6435              module.debug('Animating in label', $label);
6436              $label
6437                .addClass(className.hidden)
6438                .insertBefore($next)
6439                .transition(settings.label.transition, settings.label.duration)
6440              ;
6441            }
6442            else {
6443              module.debug('Adding selection label', $label);
6444              $label
6445                .insertBefore($next)
6446              ;
6447            }
6448          },
6449          message: function(message) {
6450            var
6451              $message = $menu.children(selector.message),
6452              html     = settings.templates.message(module.add.variables(message))
6453            ;
6454            if($message.length > 0) {
6455              $message
6456                .html(html)
6457              ;
6458            }
6459            else {
6460              $message = $('<div/>')
6461                .html(html)
6462                .addClass(className.message)
6463                .appendTo($menu)
6464              ;
6465            }
6466          },
6467          optionValue: function(value) {
6468            var
6469              $option   = $input.find('option[value="' + value + '"]'),
6470              hasOption = ($option.length > 0)
6471            ;
6472            if(hasOption) {
6473              return;
6474            }
6475            // temporarily disconnect observer
6476            if(selectObserver) {
6477              selectObserver.disconnect();
6478              module.verbose('Temporarily disconnecting mutation observer', value);
6479            }
6480            if( module.is.single() ) {
6481              module.verbose('Removing previous user addition');
6482              $input.find('option.' + className.addition).remove();
6483            }
6484            $('<option/>')
6485              .prop('value', value)
6486              .addClass(className.addition)
6487              .html(value)
6488              .appendTo($input)
6489            ;
6490            module.verbose('Adding user addition as an <option>', value);
6491            if(selectObserver) {
6492              selectObserver.observe($input[0], {
6493                childList : true,
6494                subtree   : true
6495              });
6496            }
6497          },
6498          userSuggestion: function(value) {
6499            var
6500              $addition         = $menu.children(selector.addition),
6501              $existingItem     = module.get.item(value),
6502              alreadyHasValue   = $existingItem && $existingItem.not(selector.addition).length,
6503              hasUserSuggestion = $addition.length > 0,
6504              html
6505            ;
6506            if(settings.useLabels && module.has.maxSelections()) {
6507              return;
6508            }
6509            if(value === '' || alreadyHasValue) {
6510              $addition.remove();
6511              return;
6512            }
6513            $item
6514              .removeClass(className.selected)
6515            ;
6516            if(hasUserSuggestion) {
6517              html = settings.templates.addition( module.add.variables(message.addResult, value) );
6518              $addition
6519                .html(html)
6520                .attr('data-' + metadata.value, value)
6521                .attr('data-' + metadata.text, value)
6522                .removeClass(className.filtered)
6523                .addClass(className.selected)
6524              ;
6525              module.verbose('Replacing user suggestion with new value', $addition);
6526            }
6527            else {
6528              $addition = module.create.userChoice(value);
6529              $addition
6530                .prependTo($menu)
6531                .addClass(className.selected)
6532              ;
6533              module.verbose('Adding item choice to menu corresponding with user choice addition', $addition);
6534            }
6535          },
6536          variables: function(message, term) {
6537            var
6538              hasCount    = (message.search('{count}') !== -1),
6539              hasMaxCount = (message.search('{maxCount}') !== -1),
6540              hasTerm     = (message.search('{term}') !== -1),
6541              values,
6542              count,
6543              query
6544            ;
6545            module.verbose('Adding templated variables to message', message);
6546            if(hasCount) {
6547              count  = module.get.selectionCount();
6548              message = message.replace('{count}', count);
6549            }
6550            if(hasMaxCount) {
6551              count  = module.get.selectionCount();
6552              message = message.replace('{maxCount}', settings.maxSelections);
6553            }
6554            if(hasTerm) {
6555              query   = term || module.get.query();
6556              message = message.replace('{term}', query);
6557            }
6558            return message;
6559          },
6560          value: function(addedValue, addedText, $selectedItem) {
6561            var
6562              currentValue = module.get.values(),
6563              newValue
6564            ;
6565            if(addedValue === '') {
6566              module.debug('Cannot select blank values from multiselect');
6567              return;
6568            }
6569            // extend current array
6570            if($.isArray(currentValue)) {
6571              newValue = currentValue.concat([addedValue]);
6572              newValue = module.get.uniqueArray(newValue);
6573            }
6574            else {
6575              newValue = [addedValue];
6576            }
6577            // add values
6578            if( module.has.selectInput() ) {
6579              if(module.can.extendSelect()) {
6580                module.debug('Adding value to select', addedValue, newValue, $input);
6581                module.add.optionValue(addedValue);
6582              }
6583            }
6584            else {
6585              newValue = newValue.join(settings.delimiter);
6586              module.debug('Setting hidden input to delimited value', newValue, $input);
6587            }
6588
6589            if(settings.fireOnInit === false && module.is.initialLoad()) {
6590              module.verbose('Skipping onadd callback on initial load', settings.onAdd);
6591            }
6592            else {
6593              settings.onAdd.call(element, addedValue, addedText, $selectedItem);
6594            }
6595            module.set.value(newValue, addedValue, addedText, $selectedItem);
6596            module.check.maxSelections();
6597          }
6598        },
6599
6600        remove: {
6601          active: function() {
6602            $module.removeClass(className.active);
6603          },
6604          activeLabel: function() {
6605            $module.find(selector.label).removeClass(className.active);
6606          },
6607          loading: function() {
6608            $module.removeClass(className.loading);
6609          },
6610          initialLoad: function() {
6611            initialLoad = false;
vendor: 6,056 bytes, lines 6612-6766
6612          },
6613          upward: function($menu) {
6614            var $element = $menu || $module;
6615            $element.removeClass(className.upward);
6616          },
6617          visible: function() {
6618            $module.removeClass(className.visible);
6619          },
6620          activeItem: function() {
6621            $item.removeClass(className.active);
6622          },
6623          filteredItem: function() {
6624            if(settings.useLabels && module.has.maxSelections() ) {
6625              return;
6626            }
6627            if(settings.useLabels && module.is.multiple()) {
6628              $item.not('.' + className.active).removeClass(className.filtered);
6629            }
6630            else {
6631              $item.removeClass(className.filtered);
6632            }
6633          },
6634          optionValue: function(value) {
6635            var
6636              $option   = $input.find('option[value="' + value + '"]'),
6637              hasOption = ($option.length > 0)
6638            ;
6639            if(!hasOption || !$option.hasClass(className.addition)) {
6640              return;
6641            }
6642            // temporarily disconnect observer
6643            if(selectObserver) {
6644              selectObserver.disconnect();
6645              module.verbose('Temporarily disconnecting mutation observer', value);
6646            }
6647            $option.remove();
6648            module.verbose('Removing user addition as an <option>', value);
6649            if(selectObserver) {
6650              selectObserver.observe($input[0], {
6651                childList : true,
6652                subtree   : true
6653              });
6654            }
6655          },
6656          message: function() {
6657            $menu.children(selector.message).remove();
6658          },
6659          searchTerm: function() {
6660            module.verbose('Cleared search term');
6661            $search.val('');
6662            module.set.filtered();
6663          },
6664          selected: function(value, $selectedItem) {
6665            $selectedItem = (settings.allowAdditions)
6666              ? $selectedItem || module.get.itemWithAdditions(value)
6667              : $selectedItem || module.get.item(value)
6668            ;
6669
6670            if(!$selectedItem) {
6671              return false;
6672            }
6673
6674            $selectedItem
6675              .each(function() {
6676                var
6677                  $selected     = $(this),
6678                  selectedText  = module.get.choiceText($selected),
6679                  selectedValue = module.get.choiceValue($selected, selectedText)
6680                ;
6681                if(module.is.multiple()) {
6682                  if(settings.useLabels) {
6683                    module.remove.value(selectedValue, selectedText, $selected);
6684                    module.remove.label(selectedValue);
6685                  }
6686                  else {
6687                    module.remove.value(selectedValue, selectedText, $selected);
6688                    if(module.get.selectionCount() === 0) {
6689                      module.set.placeholderText();
6690                    }
6691                    else {
6692                      module.set.text(module.add.variables(message.count));
6693                    }
6694                  }
6695                }
6696                else {
6697                  module.remove.value(selectedValue, selectedText, $selected);
6698                }
6699                $selected
6700                  .removeClass(className.filtered)
6701                  .removeClass(className.active)
6702                ;
6703                if(settings.useLabels) {
6704                  $selected.removeClass(className.selected);
6705                }
6706              })
6707            ;
6708          },
6709          selectedItem: function() {
6710            $item.removeClass(className.selected);
6711          },
6712          value: function(removedValue, removedText, $removedItem) {
6713            var
6714              values = module.get.values(),
6715              newValue
6716            ;
6717            if( module.has.selectInput() ) {
6718              module.verbose('Input is <select> removing selected option', removedValue);
6719              newValue = module.remove.arrayValue(removedValue, values);
6720              module.remove.optionValue(removedValue);
6721            }
6722            else {
6723              module.verbose('Removing from delimited values', removedValue);
6724              newValue = module.remove.arrayValue(removedValue, values);
6725              newValue = newValue.join(settings.delimiter);
6726            }
6727            if(settings.fireOnInit === false && module.is.initialLoad()) {
6728              module.verbose('No callback on initial load', settings.onRemove);
6729            }
6730            else {
6731              settings.onRemove.call(element, removedValue, removedText, $removedItem);
6732            }
6733            module.set.value(newValue, removedText, $removedItem);
6734            module.check.maxSelections();
6735          },
6736          arrayValue: function(removedValue, values) {
6737            if( !$.isArray(values) ) {
6738              values = [values];
6739            }
6740            values = $.grep(values, function(value){
6741              return (removedValue != value);
6742            });
6743            module.verbose('Removed value from delimited string', removedValue, values);
6744            return values;
6745          },
6746          label: function(value, shouldAnimate) {
6747            var
6748              $labels       = $module.find(selector.label),
6749              $removedLabel = $labels.filter('[data-value="' + value +'"]')
6750            ;
6751            module.verbose('Removing label', $removedLabel);
6752            $removedLabel.remove();
6753          },
6754          activeLabels: function($activeLabels) {
6755            $activeLabels = $activeLabels || $module.find(selector.label).filter('.' + className.active);
6756            module.verbose('Removing active label selections', $activeLabels);
6757            module.remove.labels($activeLabels);
6758          },
6759          labels: function($labels) {
6760            $labels = $labels || $module.find(selector.label);
6761            module.verbose('Removing labels', $labels);
6762            $labels
6763              .each(function(){
6764                var
6765                  $label      = $(this),
6766                  value       = $label.data(metadata.value),
vendor: 73,223 bytes, lines 6767-9126
6767                  stringValue = (value !== undefined)
6768                    ? String(value)
6769                    : value,
6770                  isUserValue = module.is.userValue(stringValue)
6771                ;
6772                if(settings.onLabelRemove.call($label, value) === false) {
6773                  module.debug('Label remove callback cancelled removal');
6774                  return;
6775                }
6776                if(isUserValue) {
6777                  module.remove.value(stringValue);
6778                  module.remove.label(stringValue);
6779                }
6780                else {
6781                  // selected will also remove label
6782                  module.remove.selected(stringValue);
6783                }
6784              })
6785            ;
6786          },
6787          tabbable: function() {
6788            if( module.has.search() ) {
6789              module.debug('Searchable dropdown initialized');
6790              $search
6791                .removeAttr('tabindex')
6792              ;
6793              $menu
6794                .removeAttr('tabindex')
6795              ;
6796            }
6797            else {
6798              module.debug('Simple selection dropdown initialized');
6799              $module
6800                .removeAttr('tabindex')
6801              ;
6802              $menu
6803                .removeAttr('tabindex')
6804              ;
6805            }
6806          }
6807        },
6808
6809        has: {
6810          search: function() {
6811            return ($search.length > 0);
6812          },
6813          selectInput: function() {
6814            return ( $input.is('select') );
6815          },
6816          firstLetter: function($item, letter) {
6817            var
6818              text,
6819              firstLetter
6820            ;
6821            if(!$item || $item.length === 0 || typeof letter !== 'string') {
6822              return false;
6823            }
6824            text        = module.get.choiceText($item, false);
6825            letter      = letter.toLowerCase();
6826            firstLetter = String(text).charAt(0).toLowerCase();
6827            return (letter == firstLetter);
6828          },
6829          input: function() {
6830            return ($input.length > 0);
6831          },
6832          items: function() {
6833            return ($item.length > 0);
6834          },
6835          menu: function() {
6836            return ($menu.length > 0);
6837          },
6838          message: function() {
6839            return ($menu.children(selector.message).length !== 0);
6840          },
6841          label: function(value) {
6842            var
6843              $labels = $module.find(selector.label)
6844            ;
6845            return ($labels.filter('[data-value="' + value +'"]').length > 0);
6846          },
6847          maxSelections: function() {
6848            return (settings.maxSelections && module.get.selectionCount() >= settings.maxSelections);
6849          },
6850          allResultsFiltered: function() {
6851            return ($item.filter(selector.unselectable).length === $item.length);
6852          },
6853          query: function() {
6854            return (module.get.query() !== '');
6855          },
6856          value: function(value) {
6857            var
6858              values   = module.get.values(),
6859              hasValue = $.isArray(values)
6860               ? values && ($.inArray(value, values) !== -1)
6861               : (values == value)
6862            ;
6863            return (hasValue)
6864              ? true
6865              : false
6866            ;
6867          }
6868        },
6869
6870        is: {
6871          active: function() {
6872            return $module.hasClass(className.active);
6873          },
6874          alreadySetup: function() {
6875            return ($module.is('select') && $module.parent(selector.dropdown).length > 0  && $module.prev().length === 0);
6876          },
6877          animating: function($subMenu) {
6878            return ($subMenu)
6879              ? $subMenu.transition && $subMenu.transition('is animating')
6880              : $menu.transition    && $menu.transition('is animating')
6881            ;
6882          },
6883          disabled: function() {
6884            return $module.hasClass(className.disabled);
6885          },
6886          focused: function() {
6887            return (document.activeElement === $module[0]);
6888          },
6889          focusedOnSearch: function() {
6890            return (document.activeElement === $search[0]);
6891          },
6892          allFiltered: function() {
6893            return( (module.is.multiple() || module.has.search()) && !module.has.message() && module.has.allResultsFiltered() );
6894          },
6895          hidden: function($subMenu) {
6896            return !module.is.visible($subMenu);
6897          },
6898          initialLoad: function() {
6899            return initialLoad;
6900          },
6901          onScreen: function($subMenu) {
6902            var
6903              $currentMenu   = $subMenu || $menu,
6904              canOpenDownward = true,
6905              onScreen = {},
6906              calculations
6907            ;
6908            $currentMenu.addClass(className.loading);
6909            calculations = {
6910              context: {
6911                scrollTop : $context.scrollTop(),
6912                height    : $context.outerHeight()
6913              },
6914              menu : {
6915                offset: $currentMenu.offset(),
6916                height: $currentMenu.outerHeight()
6917              }
6918            };
6919            onScreen = {
6920              above : (calculations.context.scrollTop) <= calculations.menu.offset.top - calculations.menu.height,
6921              below : (calculations.context.scrollTop + calculations.context.height) >= calculations.menu.offset.top + calculations.menu.height
6922            };
6923            if(onScreen.below) {
6924              module.verbose('Dropdown can fit in context downward', onScreen);
6925              canOpenDownward = true;
6926            }
6927            else if(!onScreen.below && !onScreen.above) {
6928              module.verbose('Dropdown cannot fit in either direction, favoring downward', onScreen);
6929              canOpenDownward = true;
6930            }
6931            else {
6932              module.verbose('Dropdown cannot fit below, opening upward', onScreen);
6933              canOpenDownward = false;
6934            }
6935            $currentMenu.removeClass(className.loading);
6936            return canOpenDownward;
6937          },
6938          inObject: function(needle, object) {
6939            var
6940              found = false
6941            ;
6942            $.each(object, function(index, property) {
6943              if(property == needle) {
6944                found = true;
6945                return true;
6946              }
6947            });
6948            return found;
6949          },
6950          multiple: function() {
6951            return $module.hasClass(className.multiple);
6952          },
6953          single: function() {
6954            return !module.is.multiple();
6955          },
6956          selectMutation: function(mutations) {
6957            var
6958              selectChanged = false
6959            ;
6960            $.each(mutations, function(index, mutation) {
6961              if(mutation.target && $(mutation.target).is('select')) {
6962                selectChanged = true;
6963                return true;
6964              }
6965            });
6966            return selectChanged;
6967          },
6968          search: function() {
6969            return $module.hasClass(className.search);
6970          },
6971          searchSelection: function() {
6972            return ( module.has.search() && $search.parent(selector.dropdown).length === 1 );
6973          },
6974          selection: function() {
6975            return $module.hasClass(className.selection);
6976          },
6977          userValue: function(value) {
6978            return ($.inArray(value, module.get.userValues()) !== -1);
6979          },
6980          upward: function($menu) {
6981            var $element = $menu || $module;
6982            return $element.hasClass(className.upward);
6983          },
6984          visible: function($subMenu) {
6985            return ($subMenu)
6986              ? $subMenu.hasClass(className.visible)
6987              : $menu.hasClass(className.visible)
6988            ;
6989          }
6990        },
6991
6992        can: {
6993          activate: function($item) {
6994            if(settings.useLabels) {
6995              return true;
6996            }
6997            if(!module.has.maxSelections()) {
6998              return true;
6999            }
7000            if(module.has.maxSelections() && $item.hasClass(className.active)) {
7001              return true;
7002            }
7003            return false;
7004          },
7005          click: function() {
7006            return (hasTouch || settings.on == 'click');
7007          },
7008          extendSelect: function() {
7009            return settings.allowAdditions || settings.apiSettings;
7010          },
7011          show: function() {
7012            return !module.is.disabled() && (module.has.items() || module.has.message());
7013          },
7014          useAPI: function() {
7015            return $.fn.api !== undefined;
7016          }
7017        },
7018
7019        animate: {
7020          show: function(callback, $subMenu) {
7021            var
7022              $currentMenu = $subMenu || $menu,
7023              start = ($subMenu)
7024                ? function() {}
7025                : function() {
7026                  module.hideSubMenus();
7027                  module.hideOthers();
7028                  module.set.active();
7029                },
7030              transition
7031            ;
7032            callback = $.isFunction(callback)
7033              ? callback
7034              : function(){}
7035            ;
7036            module.verbose('Doing menu show animation', $currentMenu);
7037            module.set.direction($subMenu);
7038            transition = module.get.transition($subMenu);
7039            if( module.is.selection() ) {
7040              module.set.scrollPosition(module.get.selectedItem(), true);
7041            }
7042            if( module.is.hidden($currentMenu) || module.is.animating($currentMenu) ) {
7043              if(transition == 'none') {
7044                start();
7045                $currentMenu.transition('show');
7046                callback.call(element);
7047              }
7048              else if($.fn.transition !== undefined && $module.transition('is supported')) {
7049                $currentMenu
7050                  .transition({
7051                    animation  : transition + ' in',
7052                    debug      : settings.debug,
7053                    verbose    : settings.verbose,
7054                    duration   : settings.duration,
7055                    queue      : true,
7056                    onStart    : start,
7057                    onComplete : function() {
7058                      callback.call(element);
7059                    }
7060                  })
7061                ;
7062              }
7063              else {
7064                module.error(error.noTransition, transition);
7065              }
7066            }
7067          },
7068          hide: function(callback, $subMenu) {
7069            var
7070              $currentMenu = $subMenu || $menu,
7071              duration = ($subMenu)
7072                ? (settings.duration * 0.9)
7073                : settings.duration,
7074              start = ($subMenu)
7075                ? function() {}
7076                : function() {
7077                  if( module.can.click() ) {
7078                    module.unbind.intent();
7079                  }
7080                  module.remove.active();
7081                },
7082              transition = module.get.transition($subMenu)
7083            ;
7084            callback = $.isFunction(callback)
7085              ? callback
7086              : function(){}
7087            ;
7088            if( module.is.visible($currentMenu) || module.is.animating($currentMenu) ) {
7089              module.verbose('Doing menu hide animation', $currentMenu);
7090
7091              if(transition == 'none') {
7092                start();
7093                $currentMenu.transition('hide');
7094                callback.call(element);
7095              }
7096              else if($.fn.transition !== undefined && $module.transition('is supported')) {
7097                $currentMenu
7098                  .transition({
7099                    animation  : transition + ' out',
7100                    duration   : settings.duration,
7101                    debug      : settings.debug,
7102                    verbose    : settings.verbose,
7103                    queue      : true,
7104                    onStart    : start,
7105                    onComplete : function() {
7106                      if(settings.direction == 'auto') {
7107                        module.remove.upward($subMenu);
7108                      }
7109                      callback.call(element);
7110                    }
7111                  })
7112                ;
7113              }
7114              else {
7115                module.error(error.transition);
7116              }
7117            }
7118          }
7119        },
7120
7121        hideAndClear: function() {
7122          module.remove.searchTerm();
7123          if( module.has.maxSelections() ) {
7124            return;
7125          }
7126          if(module.has.search()) {
7127            module.hide(function() {
7128              module.remove.filteredItem();
7129            });
7130          }
7131          else {
7132            module.hide();
7133          }
7134        },
7135
7136        delay: {
7137          show: function() {
7138            module.verbose('Delaying show event to ensure user intent');
7139            clearTimeout(module.timer);
7140            module.timer = setTimeout(module.show, settings.delay.show);
7141          },
7142          hide: function() {
7143            module.verbose('Delaying hide event to ensure user intent');
7144            clearTimeout(module.timer);
7145            module.timer = setTimeout(module.hide, settings.delay.hide);
7146          }
7147        },
7148
7149        escape: {
7150          regExp: function(text) {
7151            text =  String(text);
7152            return text.replace(regExp.escape, '\\$&');
7153          }
7154        },
7155
7156        setting: function(name, value) {
7157          module.debug('Changing setting', name, value);
7158          if( $.isPlainObject(name) ) {
7159            $.extend(true, settings, name);
7160          }
7161          else if(value !== undefined) {
7162            settings[name] = value;
7163          }
7164          else {
7165            return settings[name];
7166          }
7167        },
7168        internal: function(name, value) {
7169          if( $.isPlainObject(name) ) {
7170            $.extend(true, module, name);
7171          }
7172          else if(value !== undefined) {
7173            module[name] = value;
7174          }
7175          else {
7176            return module[name];
7177          }
7178        },
7179        debug: function() {
7180          if(settings.debug) {
7181            if(settings.performance) {
7182              module.performance.log(arguments);
7183            }
7184            else {
7185              module.debug = Function.prototype.bind.call(console.info, console, settings.name + ':');
7186              module.debug.apply(console, arguments);
7187            }
7188          }
7189        },
7190        verbose: function() {
7191          if(settings.verbose && settings.debug) {
7192            if(settings.performance) {
7193              module.performance.log(arguments);
7194            }
7195            else {
7196              module.verbose = Function.prototype.bind.call(console.info, console, settings.name + ':');
7197              module.verbose.apply(console, arguments);
7198            }
7199          }
7200        },
7201        error: function() {
7202          module.error = Function.prototype.bind.call(console.error, console, settings.name + ':');
7203          module.error.apply(console, arguments);
7204        },
7205        performance: {
7206          log: function(message) {
7207            var
7208              currentTime,
7209              executionTime,
7210              previousTime
7211            ;
7212            if(settings.performance) {
7213              currentTime   = new Date().getTime();
7214              previousTime  = time || currentTime;
7215              executionTime = currentTime - previousTime;
7216              time          = currentTime;
7217              performance.push({
7218                'Name'           : message[0],
7219                'Arguments'      : [].slice.call(message, 1) || '',
7220                'Element'        : element,
7221                'Execution Time' : executionTime
7222              });
7223            }
7224            clearTimeout(module.performance.timer);
7225            module.performance.timer = setTimeout(module.performance.display, 500);
7226          },
7227          display: function() {
7228            var
7229              title = settings.name + ':',
7230              totalTime = 0
7231            ;
7232            time = false;
7233            clearTimeout(module.performance.timer);
7234            $.each(performance, function(index, data) {
7235              totalTime += data['Execution Time'];
7236            });
7237            title += ' ' + totalTime + 'ms';
7238            if(moduleSelector) {
7239              title += ' \'' + moduleSelector + '\'';
7240            }
7241            if( (console.group !== undefined || console.table !== undefined) && performance.length > 0) {
7242              console.groupCollapsed(title);
7243              if(console.table) {
7244                console.table(performance);
7245              }
7246              else {
7247                $.each(performance, function(index, data) {
7248                  console.log(data['Name'] + ': ' + data['Execution Time']+'ms');
7249                });
7250              }
7251              console.groupEnd();
7252            }
7253            performance = [];
7254          }
7255        },
7256        invoke: function(query, passedArguments, context) {
7257          var
7258            object = instance,
7259            maxDepth,
7260            found,
7261            response
7262          ;
7263          passedArguments = passedArguments || queryArguments;
7264          context         = element         || context;
7265          if(typeof query == 'string' && object !== undefined) {
7266            query    = query.split(/[\. ]/);
7267            maxDepth = query.length - 1;
7268            $.each(query, function(depth, value) {
7269              var camelCaseValue = (depth != maxDepth)
7270                ? value + query[depth + 1].charAt(0).toUpperCase() + query[depth + 1].slice(1)
7271                : query
7272              ;
7273              if( $.isPlainObject( object[camelCaseValue] ) && (depth != maxDepth) ) {
7274                object = object[camelCaseValue];
7275              }
7276              else if( object[camelCaseValue] !== undefined ) {
7277                found = object[camelCaseValue];
7278                return false;
7279              }
7280              else if( $.isPlainObject( object[value] ) && (depth != maxDepth) ) {
7281                object = object[value];
7282              }
7283              else if( object[value] !== undefined ) {
7284                found = object[value];
7285                return false;
7286              }
7287              else {
7288                module.error(error.method, query);
7289                return false;
7290              }
7291            });
7292          }
7293          if ( $.isFunction( found ) ) {
7294            response = found.apply(context, passedArguments);
7295          }
7296          else if(found !== undefined) {
7297            response = found;
7298          }
7299          if($.isArray(returnedValue)) {
7300            returnedValue.push(response);
7301          }
7302          else if(returnedValue !== undefined) {
7303            returnedValue = [returnedValue, response];
7304          }
7305          else if(response !== undefined) {
7306            returnedValue = response;
7307          }
7308          return found;
7309        }
7310      };
7311
7312      if(methodInvoked) {
7313        if(instance === undefined) {
7314          module.initialize();
7315        }
7316        module.invoke(query);
7317      }
7318      else {
7319        if(instance !== undefined) {
7320          instance.invoke('destroy');
7321        }
7322        module.initialize();
7323      }
7324    })
7325  ;
7326  return (returnedValue !== undefined)
7327    ? returnedValue
7328    : $allModules
7329  ;
7330};
7331
7332$.fn.dropdown.settings = {
7333
7334  debug                  : false,
7335  verbose                : false,
7336  performance            : true,
7337
7338  on                     : 'click',    // what event should show menu action on item selection
7339  action                 : 'activate', // action on item selection (nothing, activate, select, combo, hide, function(){})
7340
7341
7342  apiSettings            : false,
7343  saveRemoteData         : true,      // Whether remote name/value pairs should be stored in sessionStorage to allow remote data to be restored on page refresh
7344  throttle               : 200,       // How long to wait after last user input to search remotely
7345
7346  context                : window,      // Context to use when determining if on screen
7347  direction              : 'auto',     // Whether dropdown should always open in one direction
7348  keepOnScreen           : true,       // Whether dropdown should check whether it is on screen before showing
7349
7350  match                  : 'both',     // what to match against with search selection (both, text, or label)
7351  fullTextSearch         : false,      // search anywhere in value
7352
7353  placeholder            : 'auto',     // whether to convert blank <select> values to placeholder text
7354  preserveHTML           : true,       // preserve html when selecting value
7355  sortSelect             : false,      // sort selection on init
7356
7357  forceSelection         : true,       // force a choice on blur with search selection
7358  allowAdditions         : false,      // whether multiple select should allow user added values
7359
7360  maxSelections          : false,      // When set to a number limits the number of selections to this count
7361  useLabels              : true,       // whether multiple select should filter currently active selections from choices
7362  delimiter              : ',',        // when multiselect uses normal <input> the values will be delimited with this character
7363
7364  showOnFocus            : true,       // show menu on focus
7365  allowTab               : true,       // add tabindex to element
7366  allowCategorySelection : false,      // allow elements with sub-menus to be selected
7367
7368  fireOnInit             : false,      // Whether callbacks should fire when initializing dropdown values
7369
7370  transition             : 'auto',     // auto transition will slide down or up based on direction
7371  duration               : 200,        // duration of transition
7372
7373  glyphWidth             : 1.0714,     // widest glyph width in em (W is 1.0714 em) used to calculate multiselect input width
7374
7375  // label settings on multi-select
7376  label: {
7377    transition : 'scale',
7378    duration   : 200,
7379    variation  : false
7380  },
7381
7382  // delay before event
7383  delay : {
7384    hide   : 300,
7385    show   : 200,
7386    search : 20,
7387    touch  : 50
7388  },
7389
7390  /* Callbacks */
7391  onChange      : function(value, text, $selected){},
7392  onAdd         : function(value, text, $selected){},
7393  onRemove      : function(value, text, $selected){},
7394
7395  onLabelSelect : function($selectedLabels){},
7396  onLabelCreate : function(value, text) { return $(this); },
7397  onLabelRemove : function(value) { return true; },
7398  onNoResults   : function(searchTerm) { return true; },
7399  onShow        : function(){},
7400  onHide        : function(){},
7401
7402  /* Component */
7403  name           : 'Dropdown',
7404  namespace      : 'dropdown',
7405
7406  message: {
7407    addResult     : 'Add <b>{term}</b>',
7408    count         : '{count} selected',
7409    maxSelections : 'Max {maxCount} selections',
7410    noResults     : 'No results found.',
7411    serverError   : 'There was an error contacting the server'
7412  },
7413
7414  error : {
7415    action          : 'You called a dropdown action that was not defined',
7416    alreadySetup    : 'Once a select has been initialized behaviors must be called on the created ui dropdown',
7417    labels          : 'Allowing user additions currently requires the use of labels.',
7418    missingMultiple : '<select> requires multiple property to be set to correctly preserve multiple values',
7419    method          : 'The method you called is not defined.',
7420    noAPI           : 'The API module is required to load resources remotely',
7421    noStorage       : 'Saving remote data requires session storage',
7422    noTransition    : 'This module requires ui transitions <https://github.com/Semantic-Org/UI-Transition>'
7423  },
7424
7425  regExp : {
7426    escape   : /[-[\]{}()*+?.,\\^$|#\s]/g,
7427  },
7428
7429  metadata : {
7430    defaultText     : 'defaultText',
7431    defaultValue    : 'defaultValue',
7432    placeholderText : 'placeholder',
7433    text            : 'text',
7434    value           : 'value'
7435  },
7436
7437  // property names for remote query
7438  fields: {
7439    remoteValues : 'results', // grouping for api results
7440    values       : 'values', // grouping for all dropdown values
7441    name         : 'name',   // displayed dropdown text
7442    value        : 'value'   // actual dropdown value
7443  },
7444
7445  keys : {
7446    backspace  : 8,
7447    delimiter  : 188, // comma
7448    deleteKey  : 46,
7449    enter      : 13,
7450    escape     : 27,
7451    pageUp     : 33,
7452    pageDown   : 34,
7453    leftArrow  : 37,
7454    upArrow    : 38,
7455    rightArrow : 39,
7456    downArrow  : 40
7457  },
7458
7459  selector : {
7460    addition     : '.addition',
7461    dropdown     : '.ui.dropdown',
7462    icon         : '> .dropdown.icon',
7463    input        : '> input[type="hidden"], > select',
7464    item         : '.item',
7465    label        : '> .label',
7466    remove       : '> .label > .delete.icon',
7467    siblingLabel : '.label',
7468    menu         : '.menu',
7469    message      : '.message',
7470    menuIcon     : '.dropdown.icon',
7471    search       : 'input.search, .menu > .search > input',
7472    text         : '> .text:not(.icon)',
7473    unselectable : '.disabled, .filtered'
7474  },
7475
7476  className : {
7477    active      : 'active',
7478    addition    : 'addition',
7479    animating   : 'animating',
7480    disabled    : 'disabled',
7481    dropdown    : 'ui dropdown',
7482    filtered    : 'filtered',
7483    hidden      : 'hidden transition',
7484    item        : 'item',
7485    label       : 'ui label',
7486    loading     : 'loading',
7487    menu        : 'menu',
7488    message     : 'message',
7489    multiple    : 'multiple',
7490    placeholder : 'default',
7491    search      : 'search',
7492    selected    : 'selected',
7493    selection   : 'selection',
7494    upward      : 'upward',
7495    visible     : 'visible'
7496  }
7497
7498};
7499
7500/* Templates */
7501$.fn.dropdown.settings.templates = {
7502
7503  // generates dropdown from select values
7504  dropdown: function(select) {
7505    var
7506      placeholder = select.placeholder || false,
7507      values      = select.values || {},
7508      html        = ''
7509    ;
7510    html +=  '<i class="dropdown icon"></i>';
7511    if(select.placeholder) {
7512      html += '<div class="default text">' + placeholder + '</div>';
7513    }
7514    else {
7515      html += '<div class="text"></div>';
7516    }
7517    html += '<div class="menu">';
7518    $.each(select.values, function(index, option) {
7519      html += (option.disabled)
7520        ? '<div class="disabled item" data-value="' + option.value + '">' + option.name + '</div>'
7521        : '<div class="item" data-value="' + option.value + '">' + option.name + '</div>'
7522      ;
7523    });
7524    html += '</div>';
7525    return html;
7526  },
7527
7528  // generates just menu from select
7529  menu: function(response, fields) {
7530    var
7531      values = response[fields.values] || {},
7532      html   = ''
7533    ;
7534    $.each(values, function(index, option) {
7535      html += '<div class="item" data-value="' + option[fields.value] + '">' + option[fields.name] + '</div>';
7536    });
7537    return html;
7538  },
7539
7540  // generates label for multiselect
7541  label: function(value, text) {
7542    return text + '<i class="delete icon"></i>';
7543  },
7544
7545
7546  // generates messages like "No results"
7547  message: function(message) {
7548    return message;
7549  },
7550
7551  // generates user addition to selection menu
7552  addition: function(choice) {
7553    return choice;
7554  }
7555
7556};
7557
7558})( jQuery, window, document );
7559
7560/*!
7561 * # Semantic UI 2.1.7 - Video
7562 * http://github.com/semantic-org/semantic-ui/
7563 *
7564 *
7565 * Copyright 2015 Contributors
7566 * Released under the MIT license
7567 * http://opensource.org/licenses/MIT
7568 *
7569 */
7570
7571;(function ($, window, document, undefined) {
7572
7573"use strict";
7574
7575$.fn.embed = function(parameters) {
7576
7577  var
7578    $allModules     = $(this),
7579
7580    moduleSelector  = $allModules.selector || '',
7581
7582    time            = new Date().getTime(),
7583    performance     = [],
7584
7585    query           = arguments[0],
7586    methodInvoked   = (typeof query == 'string'),
7587    queryArguments  = [].slice.call(arguments, 1),
7588
7589    returnedValue
7590  ;
7591
7592  $allModules
7593    .each(function() {
7594      var
7595        settings        = ( $.isPlainObject(parameters) )
7596          ? $.extend(true, {}, $.fn.embed.settings, parameters)
7597          : $.extend({}, $.fn.embed.settings),
7598
7599        selector        = settings.selector,
7600        className       = settings.className,
7601        sources         = settings.sources,
7602        error           = settings.error,
7603        metadata        = settings.metadata,
7604        namespace       = settings.namespace,
7605        templates       = settings.templates,
7606
7607        eventNamespace  = '.' + namespace,
7608        moduleNamespace = 'module-' + namespace,
7609
7610        $window         = $(window),
7611        $module         = $(this),
7612        $placeholder    = $module.find(selector.placeholder),
7613        $icon           = $module.find(selector.icon),
7614        $embed          = $module.find(selector.embed),
7615
7616        element         = this,
7617        instance        = $module.data(moduleNamespace),
7618        module
7619      ;
7620
7621      module = {
7622
7623        initialize: function() {
7624          module.debug('Initializing embed');
7625          module.determine.autoplay();
7626          module.create();
7627          module.bind.events();
7628          module.instantiate();
7629        },
7630
7631        instantiate: function() {
7632          module.verbose('Storing instance of module', module);
7633          instance = module;
7634          $module
7635            .data(moduleNamespace, module)
7636          ;
7637        },
7638
7639        destroy: function() {
7640          module.verbose('Destroying previous instance of embed');
7641          module.reset();
7642          $module
7643            .removeData(moduleNamespace)
7644            .off(eventNamespace)
7645          ;
7646        },
7647
7648        refresh: function() {
7649          module.verbose('Refreshing selector cache');
7650          $placeholder = $module.find(selector.placeholder);
7651          $icon        = $module.find(selector.icon);
7652          $embed       = $module.find(selector.embed);
7653        },
7654
7655        bind: {
7656          events: function() {
7657            if( module.has.placeholder() ) {
7658              module.debug('Adding placeholder events');
7659              $module
7660                .on('click' + eventNamespace, selector.placeholder, module.createAndShow)
7661                .on('click' + eventNamespace, selector.icon, module.createAndShow)
7662              ;
7663            }
7664          }
7665        },
7666
7667        create: function() {
7668          var
7669            placeholder = module.get.placeholder()
7670          ;
7671          if(placeholder) {
7672            module.createPlaceholder();
7673          }
7674          else {
7675            module.createAndShow();
7676          }
7677        },
7678
7679        createPlaceholder: function(placeholder) {
7680          var
7681            icon  = module.get.icon(),
7682            url   = module.get.url(),
7683            embed = module.generate.embed(url)
7684          ;
7685          placeholder = placeholder || module.get.placeholder();
7686          $module.html( templates.placeholder(placeholder, icon) );
7687          module.debug('Creating placeholder for embed', placeholder, icon);
7688        },
7689
7690        createEmbed: function(url) {
7691          module.refresh();
7692          url = url || module.get.url();
7693          $embed = $('<div/>')
7694            .addClass(className.embed)
7695            .html( module.generate.embed(url) )
7696            .appendTo($module)
7697          ;
7698          settings.onCreate.call(element, url);
7699          module.debug('Creating embed object', $embed);
7700        },
7701
7702        createAndShow: function() {
7703          module.createEmbed();
7704          module.show();
7705        },
7706
7707        // sets new embed
7708        change: function(source, id, url) {
7709          module.debug('Changing video to ', source, id, url);
7710          $module
7711            .data(metadata.source, source)
7712            .data(metadata.id, id)
7713            .data(metadata.url, url)
7714          ;
7715          module.create();
7716        },
7717
7718        // clears embed
7719        reset: function() {
7720          module.debug('Clearing embed and showing placeholder');
7721          module.remove.active();
7722          module.remove.embed();
7723          module.showPlaceholder();
7724          settings.onReset.call(element);
7725        },
7726
7727        // shows current embed
7728        show: function() {
7729          module.debug('Showing embed');
7730          module.set.active();
7731          settings.onDisplay.call(element);
7732        },
7733
7734        hide: function() {
7735          module.debug('Hiding embed');
7736          module.showPlaceholder();
7737        },
7738
7739        showPlaceholder: function() {
7740          module.debug('Showing placeholder image');
7741          module.remove.active();
7742          settings.onPlaceholderDisplay.call(element);
7743        },
7744
7745        get: {
7746          id: function() {
7747            return settings.id || $module.data(metadata.id);
7748          },
7749          placeholder: function() {
7750            return settings.placeholder || $module.data(metadata.placeholder);
7751          },
7752          icon: function() {
7753            return (settings.icon)
7754              ? settings.icon
7755              : ($module.data(metadata.icon) !== undefined)
7756                ? $module.data(metadata.icon)
7757                : module.determine.icon()
7758            ;
7759          },
7760          source: function(url) {
7761            return (settings.source)
7762              ? settings.source
7763              : ($module.data(metadata.source) !== undefined)
7764                ? $module.data(metadata.source)
7765                : module.determine.source()
7766            ;
7767          },
7768          type: function() {
7769            var source = module.get.source();
7770            return (sources[source] !== undefined)
7771              ? sources[source].type
7772              : false
7773            ;
7774          },
7775          url: function() {
7776            return (settings.url)
7777              ? settings.url
7778              : ($module.data(metadata.url) !== undefined)
7779                ? $module.data(metadata.url)
7780                : module.determine.url()
7781            ;
7782          }
7783        },
7784
7785        determine: {
7786          autoplay: function() {
7787            if(module.should.autoplay()) {
7788              settings.autoplay = true;
7789            }
7790          },
7791          source: function(url) {
7792            var
7793              matchedSource = false
7794            ;
7795            url = url || module.get.url();
7796            if(url) {
7797              $.each(sources, function(name, source) {
7798                if(url.search(source.domain) !== -1) {
7799                  matchedSource = name;
7800                  return false;
7801                }
7802              });
7803            }
7804            return matchedSource;
7805          },
7806          icon: function() {
7807            var
7808              source = module.get.source()
7809            ;
7810            return (sources[source] !== undefined)
7811              ? sources[source].icon
7812              : false
7813            ;
7814          },
7815          url: function() {
7816            var
7817              id     = settings.id     || $module.data(metadata.id),
7818              source = settings.source || $module.data(metadata.source),
7819              url
7820            ;
7821            url = (sources[source] !== undefined)
7822              ? sources[source].url.replace('{id}', id)
7823              : false
7824            ;
7825            if(url) {
7826              $module.data(metadata.url, url);
7827            }
7828            return url;
7829          }
7830        },
7831
7832
7833        set: {
7834          active: function() {
7835            $module.addClass(className.active);
7836          }
7837        },
7838
7839        remove: {
7840          active: function() {
7841            $module.removeClass(className.active);
7842          },
7843          embed: function() {
7844            $embed.empty();
7845          }
7846        },
7847
7848        encode: {
7849          parameters: function(parameters) {
7850            var
7851              urlString = [],
7852              index
7853            ;
7854            for (index in parameters) {
7855              urlString.push( encodeURIComponent(index) + '=' + encodeURIComponent( parameters[index] ) );
7856            }
7857            return urlString.join('&amp;');
7858          }
7859        },
7860
7861        generate: {
7862          embed: function(url) {
7863            module.debug('Generating embed html');
7864            var
7865              source = module.get.source(),
7866              html,
7867              parameters
7868            ;
7869            url = module.get.url(url);
7870            if(url) {
7871              parameters = module.generate.parameters(source);
7872              html       = templates.iframe(url, parameters);
7873            }
7874            else {
7875              module.error(error.noURL, $module);
7876            }
7877            return html;
7878          },
7879          parameters: function(source, extraParameters) {
7880            var
7881              parameters = (sources[source] && sources[source].parameters !== undefined)
7882                ? sources[source].parameters(settings)
7883                : {}
7884            ;
7885            extraParameters = extraParameters || settings.parameters;
7886            if(extraParameters) {
7887              parameters = $.extend({}, parameters, extraParameters);
7888            }
7889            parameters = settings.onEmbed(parameters);
7890            return module.encode.parameters(parameters);
7891          }
7892        },
7893
7894        has: {
7895          placeholder: function() {
7896            return settings.placeholder || $module.data(metadata.placeholder);
7897          }
7898        },
7899
7900        should: {
7901          autoplay: function() {
7902            return (settings.autoplay === 'auto')
7903              ? (settings.placeholder || $module.data(metadata.placeholder) !== undefined)
7904              : settings.autoplay
7905            ;
7906          }
7907        },
7908
7909        is: {
7910          video: function() {
7911            return module.get.type() == 'video';
7912          }
7913        },
7914
7915        setting: function(name, value) {
7916          module.debug('Changing setting', name, value);
7917          if( $.isPlainObject(name) ) {
7918            $.extend(true, settings, name);
7919          }
7920          else if(value !== undefined) {
7921            settings[name] = value;
7922          }
7923          else {
7924            return settings[name];
7925          }
7926        },
7927        internal: function(name, value) {
7928          if( $.isPlainObject(name) ) {
7929            $.extend(true, module, name);
7930          }
7931          else if(value !== undefined) {
7932            module[name] = value;
7933          }
7934          else {
7935            return module[name];
7936          }
7937        },
7938        debug: function() {
7939          if(settings.debug) {
7940            if(settings.performance) {
7941              module.performance.log(arguments);
7942            }
7943            else {
7944              module.debug = Function.prototype.bind.call(console.info, console, settings.name + ':');
7945              module.debug.apply(console, arguments);
7946            }
7947          }
7948        },
7949        verbose: function() {
7950          if(settings.verbose && settings.debug) {
7951            if(settings.performance) {
7952              module.performance.log(arguments);
7953            }
7954            else {
7955              module.verbose = Function.prototype.bind.call(console.info, console, settings.name + ':');
7956              module.verbose.apply(console, arguments);
7957            }
7958          }
7959        },
7960        error: function() {
7961          module.error = Function.prototype.bind.call(console.error, console, settings.name + ':');
7962          module.error.apply(console, arguments);
7963        },
7964        performance: {
7965          log: function(message) {
7966            var
7967              currentTime,
7968              executionTime,
7969              previousTime
7970            ;
7971            if(settings.performance) {
7972              currentTime   = new Date().getTime();
7973              previousTime  = time || currentTime;
7974              executionTime = currentTime - previousTime;
7975              time          = currentTime;
7976              performance.push({
7977                'Name'           : message[0],
7978                'Arguments'      : [].slice.call(message, 1) || '',
7979                'Element'        : element,
7980                'Execution Time' : executionTime
7981              });
7982            }
7983            clearTimeout(module.performance.timer);
7984            module.performance.timer = setTimeout(module.performance.display, 500);
7985          },
7986          display: function() {
7987            var
7988              title = settings.name + ':',
7989              totalTime = 0
7990            ;
7991            time = false;
7992            clearTimeout(module.performance.timer);
7993            $.each(performance, function(index, data) {
7994              totalTime += data['Execution Time'];
7995            });
7996            title += ' ' + totalTime + 'ms';
7997            if(moduleSelector) {
7998              title += ' \'' + moduleSelector + '\'';
7999            }
8000            if($allModules.length > 1) {
8001              title += ' ' + '(' + $allModules.length + ')';
8002            }
8003            if( (console.group !== undefined || console.table !== undefined) && performance.length > 0) {
8004              console.groupCollapsed(title);
8005              if(console.table) {
8006                console.table(performance);
8007              }
8008              else {
8009                $.each(performance, function(index, data) {
8010                  console.log(data['Name'] + ': ' + data['Execution Time']+'ms');
8011                });
8012              }
8013              console.groupEnd();
8014            }
8015            performance = [];
8016          }
8017        },
8018        invoke: function(query, passedArguments, context) {
8019          var
8020            object = instance,
8021            maxDepth,
8022            found,
8023            response
8024          ;
8025          passedArguments = passedArguments || queryArguments;
8026          context         = element         || context;
8027          if(typeof query == 'string' && object !== undefined) {
8028            query    = query.split(/[\. ]/);
8029            maxDepth = query.length - 1;
8030            $.each(query, function(depth, value) {
8031              var camelCaseValue = (depth != maxDepth)
8032                ? value + query[depth + 1].charAt(0).toUpperCase() + query[depth + 1].slice(1)
8033                : query
8034              ;
8035              if( $.isPlainObject( object[camelCaseValue] ) && (depth != maxDepth) ) {
8036                object = object[camelCaseValue];
8037              }
8038              else if( object[camelCaseValue] !== undefined ) {
8039                found = object[camelCaseValue];
8040                return false;
8041              }
8042              else if( $.isPlainObject( object[value] ) && (depth != maxDepth) ) {
8043                object = object[value];
8044              }
8045              else if( object[value] !== undefined ) {
8046                found = object[value];
8047                return false;
8048              }
8049              else {
8050                module.error(error.method, query);
8051                return false;
8052              }
8053            });
8054          }
8055          if ( $.isFunction( found ) ) {
8056            response = found.apply(context, passedArguments);
8057          }
8058          else if(found !== undefined) {
8059            response = found;
8060          }
8061          if($.isArray(returnedValue)) {
8062            returnedValue.push(response);
8063          }
8064          else if(returnedValue !== undefined) {
8065            returnedValue = [returnedValue, response];
8066          }
8067          else if(response !== undefined) {
8068            returnedValue = response;
8069          }
8070          return found;
8071        }
8072      };
8073
8074      if(methodInvoked) {
8075        if(instance === undefined) {
8076          module.initialize();
8077        }
8078        module.invoke(query);
8079      }
8080      else {
8081        if(instance !== undefined) {
8082          instance.invoke('destroy');
8083        }
8084        module.initialize();
8085      }
8086    })
8087  ;
8088  return (returnedValue !== undefined)
8089    ? returnedValue
8090    : this
8091  ;
8092};
8093
8094$.fn.embed.settings = {
8095
8096  name        : 'Embed',
8097  namespace   : 'embed',
8098
8099  debug       : false,
8100  verbose     : false,
8101  performance : true,
8102
8103  icon     : false,
8104  source   : false,
8105  url      : false,
8106  id       : false,
8107
8108  // standard video settings
8109  autoplay  : 'auto',
8110  color     : '#444444',
8111  hd        : true,
8112  brandedUI : false,
8113
8114  // additional parameters to include with the embed
8115  parameters: false,
8116
8117  onDisplay            : function() {},
8118  onPlaceholderDisplay : function() {},
8119  onReset              : function() {},
8120  onCreate             : function(url) {},
8121  onEmbed              : function(parameters) {
8122    return parameters;
8123  },
8124
8125  metadata    : {
8126    id          : 'id',
8127    icon        : 'icon',
8128    placeholder : 'placeholder',
8129    source      : 'source',
8130    url         : 'url'
8131  },
8132
8133  error : {
8134    noURL  : 'No URL specified',
8135    method : 'The method you called is not defined'
8136  },
8137
8138  className : {
8139    active : 'active',
8140    embed  : 'embed'
8141  },
8142
8143  selector : {
8144    embed       : '.embed',
8145    placeholder : '.placeholder',
8146    icon        : '.icon'
8147  },
8148
8149  sources: {
8150    youtube: {
8151      name   : 'youtube',
8152      type   : 'video',
8153      icon   : 'video play',
8154      domain : 'youtube.com',
8155      url    : '//www.youtube.com/embed/{id}',
8156      parameters: function(settings) {
8157        return {
8158          autohide       : !settings.brandedUI,
8159          autoplay       : settings.autoplay,
8160          color          : settings.colors || undefined,
8161          hq             : settings.hd,
8162          jsapi          : settings.api,
8163          modestbranding : !settings.brandedUI
8164        };
8165      }
8166    },
8167    vimeo: {
8168      name   : 'vimeo',
8169      type   : 'video',
8170      icon   : 'video play',
8171      domain : 'vimeo.com',
8172      url    : '//player.vimeo.com/video/{id}',
8173      parameters: function(settings) {
8174        return {
8175          api      : settings.api,
8176          autoplay : settings.autoplay,
8177          byline   : settings.brandedUI,
8178          color    : settings.colors || undefined,
8179          portrait : settings.brandedUI,
8180          title    : settings.brandedUI
8181        };
8182      }
8183    }
8184  },
8185
8186  templates: {
8187    iframe : function(url, parameters) {
8188      return ''
8189        + '<iframe src="' + url + '?' + parameters + '"'
8190        + ' width="100%" height="100%"'
8191        + ' frameborder="0" scrolling="no" webkitAllowFullScreen mozallowfullscreen allowFullScreen></iframe>'
8192      ;
8193    },
8194    placeholder : function(image, icon) {
8195      var
8196        html = ''
8197      ;
8198      if(icon) {
8199        html += '<i class="' + icon + ' icon"></i>';
8200      }
8201      if(image) {
8202        html += '<img class="placeholder" src="' + image + '">';
8203      }
8204      return html;
8205    }
8206  },
8207
8208  // NOT YET IMPLEMENTED
8209  api     : true,
8210  onPause : function() {},
8211  onPlay  : function() {},
8212  onStop  : function() {}
8213
8214};
8215
8216
8217
8218})( jQuery, window, document );
8219
8220/*!
8221 * # Semantic UI 2.1.7 - Modal
8222 * http://github.com/semantic-org/semantic-ui/
8223 *
8224 *
8225 * Copyright 2015 Contributors
8226 * Released under the MIT license
8227 * http://opensource.org/licenses/MIT
8228 *
8229 */
8230
8231;(function ( $, window, document, undefined ) {
8232
8233"use strict";
8234
8235$.fn.modal = function(parameters) {
8236  var
8237    $allModules    = $(this),
8238    $window        = $(window),
8239    $document      = $(document),
8240    $body          = $('body'),
8241
8242    moduleSelector = $allModules.selector || '',
8243
8244    time           = new Date().getTime(),
8245    performance    = [],
8246
8247    query          = arguments[0],
8248    methodInvoked  = (typeof query == 'string'),
8249    queryArguments = [].slice.call(arguments, 1),
8250
8251    requestAnimationFrame = window.requestAnimationFrame
8252      || window.mozRequestAnimationFrame
8253      || window.webkitRequestAnimationFrame
8254      || window.msRequestAnimationFrame
8255      || function(callback) { setTimeout(callback, 0); },
8256
8257    returnedValue
8258  ;
8259
8260  $allModules
8261    .each(function() {
8262      var
8263        settings    = ( $.isPlainObject(parameters) )
8264          ? $.extend(true, {}, $.fn.modal.settings, parameters)
8265          : $.extend({}, $.fn.modal.settings),
8266
8267        selector        = settings.selector,
8268        className       = settings.className,
8269        namespace       = settings.namespace,
8270        error           = settings.error,
8271
8272        eventNamespace  = '.' + namespace,
8273        moduleNamespace = 'module-' + namespace,
8274
8275        $module         = $(this),
8276        $context        = $(settings.context),
8277        $close          = $module.find(selector.close),
8278
8279        $allModals,
8280        $otherModals,
8281        $focusedElement,
8282        $dimmable,
8283        $dimmer,
8284
8285        element         = this,
8286        instance        = $module.data(moduleNamespace),
8287
8288        elementNamespace,
8289        id,
8290        observer,
8291        module
8292      ;
8293      module  = {
8294
8295        initialize: function() {
8296          module.verbose('Initializing dimmer', $context);
8297
8298          module.create.id();
8299          module.create.dimmer();
8300          module.refreshModals();
8301
8302          module.bind.events();
8303          if(settings.observeChanges) {
8304            module.observeChanges();
8305          }
8306          module.instantiate();
8307        },
8308
8309        instantiate: function() {
8310          module.verbose('Storing instance of modal');
8311          instance = module;
8312          $module
8313            .data(moduleNamespace, instance)
8314          ;
8315        },
8316
8317        create: {
8318          dimmer: function() {
8319            var
8320              defaultSettings = {
8321                debug      : settings.debug,
8322                dimmerName : 'modals',
8323                duration   : {
8324                  show     : settings.duration,
8325                  hide     : settings.duration
8326                }
8327              },
8328              dimmerSettings = $.extend(true, defaultSettings, settings.dimmerSettings)
8329            ;
8330            if(settings.inverted) {
8331              dimmerSettings.variation = (dimmerSettings.variation !== undefined)
8332                ? dimmerSettings.variation + ' inverted'
8333                : 'inverted'
8334              ;
8335            }
8336            if($.fn.dimmer === undefined) {
8337              module.error(error.dimmer);
8338              return;
8339            }
8340            module.debug('Creating dimmer with settings', dimmerSettings);
8341            $dimmable = $context.dimmer(dimmerSettings);
8342            if(settings.detachable) {
8343              module.verbose('Modal is detachable, moving content into dimmer');
8344              $dimmable.dimmer('add content', $module);
8345            }
8346            else {
8347              module.set.undetached();
8348            }
8349            if(settings.blurring) {
8350              $dimmable.addClass(className.blurring);
8351            }
8352            $dimmer = $dimmable.dimmer('get dimmer');
8353          },
8354          id: function() {
8355            id = (Math.random().toString(16) + '000000000').substr(2,8);
8356            elementNamespace = '.' + id;
8357            module.verbose('Creating unique id for element', id);
8358          }
8359        },
8360
8361        destroy: function() {
8362          module.verbose('Destroying previous modal');
8363          $module
8364            .removeData(moduleNamespace)
8365            .off(eventNamespace)
8366          ;
8367          $window.off(elementNamespace);
8368          $close.off(eventNamespace);
8369          $context.dimmer('destroy');
8370        },
8371
8372        observeChanges: function() {
8373          if('MutationObserver' in window) {
8374            observer = new MutationObserver(function(mutations) {
8375              module.debug('DOM tree modified, refreshing');
8376              module.refresh();
8377            });
8378            observer.observe(element, {
8379              childList : true,
8380              subtree   : true
8381            });
8382            module.debug('Setting up mutation observer', observer);
8383          }
8384        },
8385
8386        refresh: function() {
8387          module.remove.scrolling();
8388          module.cacheSizes();
8389          module.set.screenHeight();
8390          module.set.type();
8391          module.set.position();
8392        },
8393
8394        refreshModals: function() {
8395          $otherModals = $module.siblings(selector.modal);
8396          $allModals   = $otherModals.add($module);
8397        },
8398
8399        attachEvents: function(selector, event) {
8400          var
8401            $toggle = $(selector)
8402          ;
8403          event = $.isFunction(module[event])
8404            ? module[event]
8405            : module.toggle
8406          ;
8407          if($toggle.length > 0) {
8408            module.debug('Attaching modal events to element', selector, event);
8409            $toggle
8410              .off(eventNamespace)
8411              .on('click' + eventNamespace, event)
8412            ;
8413          }
8414          else {
8415            module.error(error.notFound, selector);
8416          }
8417        },
8418
8419        bind: {
8420          events: function() {
8421            module.verbose('Attaching events');
8422            $module
8423              .on('click' + eventNamespace, selector.close, module.event.close)
8424              .on('click' + eventNamespace, selector.approve, module.event.approve)
8425              .on('click' + eventNamespace, selector.deny, module.event.deny)
8426            ;
8427            $window
8428              .on('resize' + elementNamespace, module.event.resize)
8429            ;
8430          }
8431        },
8432
8433        get: {
8434          id: function() {
8435            return (Math.random().toString(16) + '000000000').substr(2,8);
8436          }
8437        },
8438
8439        event: {
8440          approve: function() {
8441            if(settings.onApprove.call(element, $(this)) === false) {
8442              module.verbose('Approve callback returned false cancelling hide');
8443              return;
8444            }
8445            module.hide();
8446          },
8447          deny: function() {
8448            if(settings.onDeny.call(element, $(this)) === false) {
8449              module.verbose('Deny callback returned false cancelling hide');
8450              return;
8451            }
8452            module.hide();
8453          },
8454          close: function() {
8455            module.hide();
8456          },
8457          click: function(event) {
8458            var
8459              $target   = $(event.target),
8460              isInModal = ($target.closest(selector.modal).length > 0),
8461              isInDOM   = $.contains(document.documentElement, event.target)
8462            ;
8463            if(!isInModal && isInDOM) {
8464              module.debug('Dimmer clicked, hiding all modals');
8465              if( module.is.active() ) {
8466                module.remove.clickaway();
8467                if(settings.allowMultiple) {
8468                  module.hide();
8469                }
8470                else {
8471                  module.hideAll();
8472                }
8473              }
8474            }
8475          },
8476          debounce: function(method, delay) {
8477            clearTimeout(module.timer);
8478            module.timer = setTimeout(method, delay);
8479          },
8480          keyboard: function(event) {
8481            var
8482              keyCode   = event.which,
8483              escapeKey = 27
8484            ;
8485            if(keyCode == escapeKey) {
8486              if(settings.closable) {
8487                module.debug('Escape key pressed hiding modal');
8488                module.hide();
8489              }
8490              else {
8491                module.debug('Escape key pressed, but closable is set to false');
8492              }
8493              event.preventDefault();
8494            }
8495          },
8496          resize: function() {
8497            if( $dimmable.dimmer('is active') ) {
8498              requestAnimationFrame(module.refresh);
8499            }
8500          }
8501        },
8502
8503        toggle: function() {
8504          if( module.is.active() || module.is.animating() ) {
8505            module.hide();
8506          }
8507          else {
8508            module.show();
8509          }
8510        },
8511
8512        show: function(callback) {
8513          callback = $.isFunction(callback)
8514            ? callback
8515            : function(){}
8516          ;
8517          module.refreshModals();
8518          module.showModal(callback);
8519        },
8520
8521        hide: function(callback) {
8522          callback = $.isFunction(callback)
8523            ? callback
8524            : function(){}
8525          ;
8526          module.refreshModals();
8527          module.hideModal(callback);
8528        },
8529
8530        showModal: function(callback) {
8531          callback = $.isFunction(callback)
8532            ? callback
8533            : function(){}
8534          ;
8535          if( module.is.animating() || !module.is.active() ) {
8536
8537            module.showDimmer();
8538            module.cacheSizes();
8539            module.set.position();
8540            module.set.screenHeight();
8541            module.set.type();
8542            module.set.clickaway();
8543
8544            if( !settings.allowMultiple && module.others.active() ) {
8545              module.hideOthers(module.showModal);
8546            }
8547            else {
8548              settings.onShow.call(element);
8549              if(settings.transition && $.fn.transition !== undefined && $module.transition('is supported')) {
8550                module.debug('Showing modal with css animations');
8551                $module
8552                  .transition({
8553                    debug       : settings.debug,
8554                    animation   : settings.transition + ' in',
8555                    queue       : settings.queue,
8556                    duration    : settings.duration,
8557                    useFailSafe : true,
8558                    onComplete : function() {
8559                      settings.onVisible.apply(element);
8560                      module.add.keyboardShortcuts();
8561                      module.save.focus();
8562                      module.set.active();
8563                      if(settings.autofocus) {
8564                        module.set.autofocus();
8565                      }
8566                      callback();
8567                    }
8568                  })
8569                ;
8570              }
8571              else {
8572                module.error(error.noTransition);
8573              }
8574            }
8575          }
8576          else {
8577            module.debug('Modal is already visible');
8578          }
8579        },
8580
8581        hideModal: function(callback, keepDimmed) {
8582          callback = $.isFunction(callback)
8583            ? callback
8584            : function(){}
8585          ;
8586          module.debug('Hiding modal');
8587          if(settings.onHide.call(element, $(this)) === false) {
8588            module.verbose('Hide callback returned false cancelling hide');
8589            return;
8590          }
8591
8592          if( module.is.animating() || module.is.active() ) {
8593            if(settings.transition && $.fn.transition !== undefined && $module.transition('is supported')) {
8594              module.remove.active();
8595              $module
8596                .transition({
8597                  debug       : settings.debug,
8598                  animation   : settings.transition + ' out',
8599                  queue       : settings.queue,
8600                  duration    : settings.duration,
8601                  useFailSafe : true,
8602                  onStart     : function() {
8603                    if(!module.others.active() && !keepDimmed) {
8604                      module.hideDimmer();
8605                    }
8606                    module.remove.keyboardShortcuts();
8607                  },
8608                  onComplete : function() {
8609                    settings.onHidden.call(element);
8610                    module.restore.focus();
8611                    callback();
8612                  }
8613                })
8614              ;
8615            }
8616            else {
8617              module.error(error.noTransition);
8618            }
8619          }
8620        },
8621
8622        showDimmer: function() {
8623          if($dimmable.dimmer('is animating') || !$dimmable.dimmer('is active') ) {
8624            module.debug('Showing dimmer');
8625            $dimmable.dimmer('show');
8626          }
8627          else {
8628            module.debug('Dimmer already visible');
8629          }
8630        },
8631
8632        hideDimmer: function() {
8633          if( $dimmable.dimmer('is animating') || ($dimmable.dimmer('is active')) ) {
8634            $dimmable.dimmer('hide', function() {
8635              module.remove.clickaway();
8636              module.remove.screenHeight();
8637            });
8638          }
8639          else {
8640            module.debug('Dimmer is not visible cannot hide');
8641            return;
8642          }
8643        },
8644
8645        hideAll: function(callback) {
8646          var
8647            $visibleModals = $allModals.filter('.' + className.active + ', .' + className.animating)
8648          ;
8649          callback = $.isFunction(callback)
8650            ? callback
8651            : function(){}
8652          ;
8653          if( $visibleModals.length > 0 ) {
8654            module.debug('Hiding all visible modals');
8655            module.hideDimmer();
8656            $visibleModals
8657              .modal('hide modal', callback)
8658            ;
8659          }
8660        },
8661
8662        hideOthers: function(callback) {
8663          var
8664            $visibleModals = $otherModals.filter('.' + className.active + ', .' + className.animating)
8665          ;
8666          callback = $.isFunction(callback)
8667            ? callback
8668            : function(){}
8669          ;
8670          if( $visibleModals.length > 0 ) {
8671            module.debug('Hiding other modals', $otherModals);
8672            $visibleModals
8673              .modal('hide modal', callback, true)
8674            ;
8675          }
8676        },
8677
8678        others: {
8679          active: function() {
8680            return ($otherModals.filter('.' + className.active).length > 0);
8681          },
8682          animating: function() {
8683            return ($otherModals.filter('.' + className.animating).length > 0);
8684          }
8685        },
8686
8687
8688        add: {
8689          keyboardShortcuts: function() {
8690            module.verbose('Adding keyboard shortcuts');
8691            $document
8692              .on('keyup' + eventNamespace, module.event.keyboard)
8693            ;
8694          }
8695        },
8696
8697        save: {
8698          focus: function() {
8699            $focusedElement = $(document.activeElement).blur();
8700          }
8701        },
8702
8703        restore: {
8704          focus: function() {
8705            if($focusedElement && $focusedElement.length > 0) {
8706              $focusedElement.focus();
8707            }
8708          }
8709        },
8710
8711        remove: {
8712          active: function() {
8713            $module.removeClass(className.active);
8714          },
8715          clickaway: function() {
8716            if(settings.closable) {
8717              $dimmer
8718                .off('click' + elementNamespace)
8719              ;
8720            }
8721          },
8722          bodyStyle: function() {
8723            if($body.attr('style') === '') {
8724              module.verbose('Removing style attribute');
8725              $body.removeAttr('style');
8726            }
8727          },
8728          screenHeight: function() {
8729            module.debug('Removing page height');
8730            $body
8731              .css('height', '')
8732            ;
8733          },
8734          keyboardShortcuts: function() {
8735            module.verbose('Removing keyboard shortcuts');
8736            $document
8737              .off('keyup' + eventNamespace)
8738            ;
8739          },
8740          scrolling: function() {
8741            $dimmable.removeClass(className.scrolling);
8742            $module.removeClass(className.scrolling);
8743          }
8744        },
8745
8746        cacheSizes: function() {
8747          var
8748            modalHeight = $module.outerHeight()
8749          ;
8750          if(module.cache === undefined || modalHeight !== 0) {
8751            module.cache = {
8752              pageHeight    : $(document).outerHeight(),
8753              height        : modalHeight + settings.offset,
8754              contextHeight : (settings.context == 'body')
8755                ? $(window).height()
8756                : $dimmable.height()
8757            };
8758          }
8759          module.debug('Caching modal and container sizes', module.cache);
8760        },
8761
8762        can: {
8763          fit: function() {
8764            return ( ( module.cache.height + (settings.padding * 2) ) < module.cache.contextHeight);
8765          }
8766        },
8767
8768        is: {
8769          active: function() {
8770            return $module.hasClass(className.active);
8771          },
8772          animating: function() {
8773            return $module.transition('is supported')
8774              ? $module.transition('is animating')
8775              : $module.is(':visible')
8776            ;
8777          },
8778          scrolling: function() {
8779            return $dimmable.hasClass(className.scrolling);
8780          },
8781          modernBrowser: function() {
8782            // appName for IE11 reports 'Netscape' can no longer use
8783            return !(window.ActiveXObject || "ActiveXObject" in window);
8784          }
8785        },
8786
8787        set: {
8788          autofocus: function() {
8789            var
8790              $inputs    = $module.find(':input').filter(':visible'),
8791              $autofocus = $inputs.filter('[autofocus]'),
8792              $input     = ($autofocus.length > 0)
8793                ? $autofocus.first()
8794                : $inputs.first()
8795            ;
8796            if($input.length > 0) {
8797              $input.focus();
8798            }
8799          },
8800          clickaway: function() {
8801            if(settings.closable) {
8802              $dimmer
8803                .on('click' + elementNamespace, module.event.click)
8804              ;
8805            }
8806          },
8807          screenHeight: function() {
8808            if( module.can.fit() ) {
8809              $body.css('height', '');
8810            }
8811            else {
8812              module.debug('Modal is taller than page content, resizing page height');
8813              $body
8814                .css('height', module.cache.height + (settings.padding * 2) )
8815              ;
8816            }
8817          },
8818          active: function() {
8819            $module.addClass(className.active);
8820          },
8821          scrolling: function() {
8822            $dimmable.addClass(className.scrolling);
8823            $module.addClass(className.scrolling);
8824          },
8825          type: function() {
8826            if(module.can.fit()) {
8827              module.verbose('Modal fits on screen');
8828              if(!module.others.active() && !module.others.animating()) {
8829                module.remove.scrolling();
8830              }
8831            }
8832            else {
8833              module.verbose('Modal cannot fit on screen setting to scrolling');
8834              module.set.scrolling();
8835            }
8836          },
8837          position: function() {
8838            module.verbose('Centering modal on page', module.cache);
8839            if(module.can.fit()) {
8840              $module
8841                .css({
8842                  top: '',
8843                  marginTop: -(module.cache.height / 2)
8844                })
8845              ;
8846            }
8847            else {
8848              $module
8849                .css({
8850                  marginTop : '',
8851                  top       : $document.scrollTop()
8852                })
8853              ;
8854            }
8855          },
8856          undetached: function() {
8857            $dimmable.addClass(className.undetached);
8858          }
8859        },
8860
8861        setting: function(name, value) {
8862          module.debug('Changing setting', name, value);
8863          if( $.isPlainObject(name) ) {
8864            $.extend(true, settings, name);
8865          }
8866          else if(value !== undefined) {
8867            settings[name] = value;
8868          }
8869          else {
8870            return settings[name];
8871          }
8872        },
8873        internal: function(name, value) {
8874          if( $.isPlainObject(name) ) {
8875            $.extend(true, module, name);
8876          }
8877          else if(value !== undefined) {
8878            module[name] = value;
8879          }
8880          else {
8881            return module[name];
8882          }
8883        },
8884        debug: function() {
8885          if(settings.debug) {
8886            if(settings.performance) {
8887              module.performance.log(arguments);
8888            }
8889            else {
8890              module.debug = Function.prototype.bind.call(console.info, console, settings.name + ':');
8891              module.debug.apply(console, arguments);
8892            }
8893          }
8894        },
8895        verbose: function() {
8896          if(settings.verbose && settings.debug) {
8897            if(settings.performance) {
8898              module.performance.log(arguments);
8899            }
8900            else {
8901              module.verbose = Function.prototype.bind.call(console.info, console, settings.name + ':');
8902              module.verbose.apply(console, arguments);
8903            }
8904          }
8905        },
8906        error: function() {
8907          module.error = Function.prototype.bind.call(console.error, console, settings.name + ':');
8908          module.error.apply(console, arguments);
8909        },
8910        performance: {
8911          log: function(message) {
8912            var
8913              currentTime,
8914              executionTime,
8915              previousTime
8916            ;
8917            if(settings.performance) {
8918              currentTime   = new Date().getTime();
8919              previousTime  = time || currentTime;
8920              executionTime = currentTime - previousTime;
8921              time          = currentTime;
8922              performance.push({
8923                'Name'           : message[0],
8924                'Arguments'      : [].slice.call(message, 1) || '',
8925                'Element'        : element,
8926                'Execution Time' : executionTime
8927              });
8928            }
8929            clearTimeout(module.performance.timer);
8930            module.performance.timer = setTimeout(module.performance.display, 500);
8931          },
8932          display: function() {
8933            var
8934              title = settings.name + ':',
8935              totalTime = 0
8936            ;
8937            time = false;
8938            clearTimeout(module.performance.timer);
8939            $.each(performance, function(index, data) {
8940              totalTime += data['Execution Time'];
8941            });
8942            title += ' ' + totalTime + 'ms';
8943            if(moduleSelector) {
8944              title += ' \'' + moduleSelector + '\'';
8945            }
8946            if( (console.group !== undefined || console.table !== undefined) && performance.length > 0) {
8947              console.groupCollapsed(title);
8948              if(console.table) {
8949                console.table(performance);
8950              }
8951              else {
8952                $.each(performance, function(index, data) {
8953                  console.log(data['Name'] + ': ' + data['Execution Time']+'ms');
8954                });
8955              }
8956              console.groupEnd();
8957            }
8958            performance = [];
8959          }
8960        },
8961        invoke: function(query, passedArguments, context) {
8962          var
8963            object = instance,
8964            maxDepth,
8965            found,
8966            response
8967          ;
8968          passedArguments = passedArguments || queryArguments;
8969          context         = element         || context;
8970          if(typeof query == 'string' && object !== undefined) {
8971            query    = query.split(/[\. ]/);
8972            maxDepth = query.length - 1;
8973            $.each(query, function(depth, value) {
8974              var camelCaseValue = (depth != maxDepth)
8975                ? value + query[depth + 1].charAt(0).toUpperCase() + query[depth + 1].slice(1)
8976                : query
8977              ;
8978              if( $.isPlainObject( object[camelCaseValue] ) && (depth != maxDepth) ) {
8979                object = object[camelCaseValue];
8980              }
8981              else if( object[camelCaseValue] !== undefined ) {
8982                found = object[camelCaseValue];
8983                return false;
8984              }
8985              else if( $.isPlainObject( object[value] ) && (depth != maxDepth) ) {
8986                object = object[value];
8987              }
8988              else if( object[value] !== undefined ) {
8989                found = object[value];
8990                return false;
8991              }
8992              else {
8993                return false;
8994              }
8995            });
8996          }
8997          if ( $.isFunction( found ) ) {
8998            response = found.apply(context, passedArguments);
8999          }
9000          else if(found !== undefined) {
9001            response = found;
9002          }
9003          if($.isArray(returnedValue)) {
9004            returnedValue.push(response);
9005          }
9006          else if(returnedValue !== undefined) {
9007            returnedValue = [returnedValue, response];
9008          }
9009          else if(response !== undefined) {
9010            returnedValue = response;
9011          }
9012          return found;
9013        }
9014      };
9015
9016      if(methodInvoked) {
9017        if(instance === undefined) {
9018          module.initialize();
9019        }
9020        module.invoke(query);
9021      }
9022      else {
9023        if(instance !== undefined) {
9024          instance.invoke('destroy');
9025        }
9026        module.initialize();
9027      }
9028    })
9029  ;
9030
9031  return (returnedValue !== undefined)
9032    ? returnedValue
9033    : this
9034  ;
9035};
9036
9037$.fn.modal.settings = {
9038
9039  name           : 'Modal',
9040  namespace      : 'modal',
9041
9042  debug          : false,
9043  verbose        : false,
9044  performance    : true,
9045
9046  observeChanges : false,
9047
9048  allowMultiple  : false,
9049  detachable     : true,
9050  closable       : true,
9051  autofocus      : true,
9052
9053  inverted       : false,
9054  blurring       : false,
9055
9056  dimmerSettings : {
9057    closable : false,
9058    useCSS   : true
9059  },
9060
9061
9062  context    : 'body',
9063
9064  queue      : false,
9065  duration   : 500,
9066  offset     : 0,
9067  transition : 'scale',
9068
9069  // padding with edge of page
9070  padding    : 50,
9071
9072  // called before show animation
9073  onShow     : function(){},
9074
9075  // called after show animation
9076  onVisible  : function(){},
9077
9078  // called before hide animation
9079  onHide     : function(){ return true; },
9080
9081  // called after hide animation
9082  onHidden   : function(){},
9083
9084  // called after approve selector match
9085  onApprove  : function(){ return true; },
9086
9087  // called after deny selector match
9088  onDeny     : function(){ return true; },
9089
9090  selector    : {
9091    close    : '> .close',
9092    approve  : '.actions .positive, .actions .approve, .actions .ok',
9093    deny     : '.actions .negative, .actions .deny, .actions .cancel',
9094    modal    : '.ui.modal'
9095  },
9096  error : {
9097    dimmer    : 'UI Dimmer, a required component is not included in this page',
9098    method    : 'The method you called is not defined.',
9099    notFound  : 'The element you specified could not be found'
9100  },
9101  className : {
9102    active     : 'active',
9103    animating  : 'animating',
9104    blurring   : 'blurring',
9105    scrolling  : 'scrolling',
9106    undetached : 'undetached'
9107  }
9108};
9109
9110
9111})( jQuery, window, document );
9112
9113/*!
9114 * # Semantic UI 2.1.7 - Nag
9115 * http://github.com/semantic-org/semantic-ui/
9116 *
9117 *
9118 * Copyright 2015 Contributors
9119 * Released under the MIT license
9120 * http://opensource.org/licenses/MIT
9121 *
9122 */
9123
9124;(function ($, window, document, undefined) {
9125
9126"use strict"
vendor: 7,533 bytes, lines 9126-9370
9126;
9127
9128$.fn.nag = function(parameters) {
9129  var
9130    $allModules    = $(this),
9131    moduleSelector = $allModules.selector || '',
9132
9133    time           = new Date().getTime(),
9134    performance    = [],
9135
9136    query          = arguments[0],
9137    methodInvoked  = (typeof query == 'string'),
9138    queryArguments = [].slice.call(arguments, 1),
9139    returnedValue
9140  ;
9141  $allModules
9142    .each(function() {
9143      var
9144        settings          = ( $.isPlainObject(parameters) )
9145          ? $.extend(true, {}, $.fn.nag.settings, parameters)
9146          : $.extend({}, $.fn.nag.settings),
9147
9148        className       = settings.className,
9149        selector        = settings.selector,
9150        error           = settings.error,
9151        namespace       = settings.namespace,
9152
9153        eventNamespace  = '.' + namespace,
9154        moduleNamespace = namespace + '-module',
9155
9156        $module         = $(this),
9157
9158        $close          = $module.find(selector.close),
9159        $context        = (settings.context)
9160          ? $(settings.context)
9161          : $('body'),
9162
9163        element         = this,
9164        instance        = $module.data(moduleNamespace),
9165
9166        moduleOffset,
9167        moduleHeight,
9168
9169        contextWidth,
9170        contextHeight,
9171        contextOffset,
9172
9173        yOffset,
9174        yPosition,
9175
9176        timer,
9177        module,
9178
9179        requestAnimationFrame = window.requestAnimationFrame
9180          || window.mozRequestAnimationFrame
9181          || window.webkitRequestAnimationFrame
9182          || window.msRequestAnimationFrame
9183          || function(callback) { setTimeout(callback, 0); }
9184      ;
9185      module = {
9186
9187        initialize: function() {
9188          module.verbose('Initializing element');
9189
9190          $module
9191            .on('click' + eventNamespace, selector.close, module.dismiss)
9192            .data(moduleNamespace, module)
9193          ;
9194
9195          if(settings.detachable && $module.parent()[0] !== $context[0]) {
9196            $module
9197              .detach()
9198              .prependTo($context)
9199            ;
9200          }
9201
9202          if(settings.displayTime > 0) {
9203            setTimeout(module.hide, settings.displayTime);
9204          }
9205          module.show();
9206        },
9207
9208        destroy: function() {
9209          module.verbose('Destroying instance');
9210          $module
9211            .removeData(moduleNamespace)
9212            .off(eventNamespace)
9213          ;
9214        },
9215
9216        show: function() {
9217          if( module.should.show() && !$module.is(':visible') ) {
9218            module.debug('Showing nag', settings.animation.show);
9219            if(settings.animation.show == 'fade') {
9220              $module
9221                .fadeIn(settings.duration, settings.easing)
9222              ;
9223            }
9224            else {
9225              $module
9226                .slideDown(settings.duration, settings.easing)
9227              ;
9228            }
9229          }
9230        },
9231
9232        hide: function() {
9233          module.debug('Showing nag', settings.animation.hide);
9234          if(settings.animation.show == 'fade') {
9235            $module
9236              .fadeIn(settings.duration, settings.easing)
9237            ;
9238          }
9239          else {
9240            $module
9241              .slideUp(settings.duration, settings.easing)
9242            ;
9243          }
9244        },
9245
9246        onHide: function() {
9247          module.debug('Removing nag', settings.animation.hide);
9248          $module.remove();
9249          if (settings.onHide) {
9250            settings.onHide();
9251          }
9252        },
9253
9254        dismiss: function(event) {
9255          if(settings.storageMethod) {
9256            module.storage.set(settings.key, settings.value);
9257          }
9258          module.hide();
9259          event.stopImmediatePropagation();
9260          event.preventDefault();
9261        },
9262
9263        should: {
9264          show: function() {
9265            if(settings.persist) {
9266              module.debug('Persistent nag is set, can show nag');
9267              return true;
9268            }
9269            if( module.storage.get(settings.key) != settings.value.toString() ) {
9270              module.debug('Stored value is not set, can show nag', module.storage.get(settings.key));
9271              return true;
9272            }
9273            module.debug('Stored value is set, cannot show nag', module.storage.get(settings.key));
9274            return false;
9275          }
9276        },
9277
9278        get: {
9279          storageOptions: function() {
9280            var
9281              options = {}
9282            ;
9283            if(settings.expires) {
9284              options.expires = settings.expires;
9285            }
9286            if(settings.domain) {
9287              options.domain = settings.domain;
9288            }
9289            if(settings.path) {
9290              options.path = settings.path;
9291            }
9292            return options;
9293          }
9294        },
9295
9296        clear: function() {
9297          module.storage.remove(settings.key);
9298        },
9299
9300        storage: {
9301          set: function(key, value) {
9302            var
9303              options = module.get.storageOptions()
9304            ;
9305            if(settings.storageMethod == 'localstorage' && window.localStorage !== undefined) {
9306              window.localStorage.setItem(key, value);
9307              module.debug('Value stored using local storage', key, value);
9308            }
9309            else if(settings.storageMethod == 'sessionstorage' && window.sessionStorage !== undefined) {
9310              window.sessionStorage.setItem(key, value);
9311              module.debug('Value stored using session storage', key, value);
9312            }
9313            else if($.cookie !== undefined) {
9314              $.cookie(key, value, options);
9315              module.debug('Value stored using cookie', key, value, options);
9316            }
9317            else {
9318              module.error(error.noCookieStorage);
9319              return;
9320            }
9321          },
9322          get: function(key, value) {
9323            var
9324              storedValue
9325            ;
9326            if(settings.storageMethod == 'localstorage' && window.localStorage !== undefined) {
9327              storedValue = window.localStorage.getItem(key);
9328            }
9329            else if(settings.storageMethod == 'sessionstorage' && window.sessionStorage !== undefined) {
9330              storedValue = window.sessionStorage.getItem(key);
9331            }
9332            // get by cookie
9333            else if($.cookie !== undefined) {
9334              storedValue = $.cookie(key);
9335            }
9336            else {
9337              module.error(error.noCookieStorage);
9338            }
9339            if(storedValue == 'undefined' || storedValue == 'null' || storedValue === undefined || storedValue === null) {
9340              storedValue = undefined;
9341            }
9342            return storedValue;
9343          },
9344          remove: function(key) {
9345            var
9346              options = module.get.storageOptions()
9347            ;
9348            if(settings.storageMethod == 'localstorage' && window.localStorage !== undefined) {
9349              window.localStorage.removeItem(key);
9350            }
9351            else if(settings.storageMethod == 'sessionstorage' && window.sessionStorage !== undefined) {
9352              window.sessionStorage.removeItem(key);
9353            }
9354            // store by cookie
9355            else if($.cookie !== undefined) {
9356              $.removeCookie(key, options);
9357            }
9358            else {
9359              module.error(error.noStorage);
9360            }
9361          }
9362        },
9363
9364        setting: function(name, value) {
9365          module.debug('Changing setting', name, value);
9366          if( $.isPlainObject(name) ) {
9367            $.extend(true, settings, name);
9368          }
9369          else if(value !== undefined) {
9370            
vendor: 3,731 bytes, lines 9370-9476
9370settings[name] = value;
9371          }
9372          else {
9373            return settings[name];
9374          }
9375        },
9376        internal: function(name, value) {
9377          if( $.isPlainObject(name) ) {
9378            $.extend(true, module, name);
9379          }
9380          else if(value !== undefined) {
9381            module[name] = value;
9382          }
9383          else {
9384            return module[name];
9385          }
9386        },
9387        debug: function() {
9388          if(settings.debug) {
9389            if(settings.performance) {
9390              module.performance.log(arguments);
9391            }
9392            else {
9393              module.debug = Function.prototype.bind.call(console.info, console, settings.name + ':');
9394              module.debug.apply(console, arguments);
9395            }
9396          }
9397        },
9398        verbose: function() {
9399          if(settings.verbose && settings.debug) {
9400            if(settings.performance) {
9401              module.performance.log(arguments);
9402            }
9403            else {
9404              module.verbose = Function.prototype.bind.call(console.info, console, settings.name + ':');
9405              module.verbose.apply(console, arguments);
9406            }
9407          }
9408        },
9409        error: function() {
9410          module.error = Function.prototype.bind.call(console.error, console, settings.name + ':');
9411          module.error.apply(console, arguments);
9412        },
9413        performance: {
9414          log: function(message) {
9415            var
9416              currentTime,
9417              executionTime,
9418              previousTime
9419            ;
9420            if(settings.performance) {
9421              currentTime   = new Date().getTime();
9422              previousTime  = time || currentTime;
9423              executionTime = currentTime - previousTime;
9424              time          = currentTime;
9425              performance.push({
9426                'Name'           : message[0],
9427                'Arguments'      : [].slice.call(message, 1) || '',
9428                'Element'        : element,
9429                'Execution Time' : executionTime
9430              });
9431            }
9432            clearTimeout(module.performance.timer);
9433            module.performance.timer = setTimeout(module.performance.display, 500);
9434          },
9435          display: function() {
9436            var
9437              title = settings.name + ':',
9438              totalTime = 0
9439            ;
9440            time = false;
9441            clearTimeout(module.performance.timer);
9442            $.each(performance, function(index, data) {
9443              totalTime += data['Execution Time'];
9444            });
9445            title += ' ' + totalTime + 'ms';
9446            if(moduleSelector) {
9447              title += ' \'' + moduleSelector + '\'';
9448            }
9449            if( (console.group !== undefined || console.table !== undefined) && performance.length > 0) {
9450              console.groupCollapsed(title);
9451              if(console.table) {
9452                console.table(performance);
9453              }
9454              else {
9455                $.each(performance, function(index, data) {
9456                  console.log(data['Name'] + ': ' + data['Execution Time']+'ms');
9457                });
9458              }
9459              console.groupEnd();
9460            }
9461            performance = [];
9462          }
9463        },
9464        invoke: function(query, passedArguments, context) {
9465          var
9466            object = instance,
9467            maxDepth,
9468            found,
9469            response
9470          ;
9471          passedArguments = passedArguments || queryArguments;
9472          context         = element         || context;
9473          if(typeof query == 'string' && object !== undefined) {
9474            query    = query.split(/[\. ]/);
9475            maxDepth = query.length - 1;
9476            $.each(query, function(depth, value) {
vendor: 11,842 bytes, lines 9477-9888
9477              var camelCaseValue = (depth != maxDepth)
9478                ? value + query[depth + 1].charAt(0).toUpperCase() + query[depth + 1].slice(1)
9479                : query
9480              ;
9481              if( $.isPlainObject( object[camelCaseValue] ) && (depth != maxDepth) ) {
9482                object = object[camelCaseValue];
9483              }
9484              else if( object[camelCaseValue] !== undefined ) {
9485                found = object[camelCaseValue];
9486                return false;
9487              }
9488              else if( $.isPlainObject( object[value] ) && (depth != maxDepth) ) {
9489                object = object[value];
9490              }
9491              else if( object[value] !== undefined ) {
9492                found = object[value];
9493                return false;
9494              }
9495              else {
9496                module.error(error.method, query);
9497                return false;
9498              }
9499            });
9500          }
9501          if ( $.isFunction( found ) ) {
9502            response = found.apply(context, passedArguments);
9503          }
9504          else if(found !== undefined) {
9505            response = found;
9506          }
9507          if($.isArray(returnedValue)) {
9508            returnedValue.push(response);
9509          }
9510          else if(returnedValue !== undefined) {
9511            returnedValue = [returnedValue, response];
9512          }
9513          else if(response !== undefined) {
9514            returnedValue = response;
9515          }
9516          return found;
9517        }
9518      };
9519
9520      if(methodInvoked) {
9521        if(instance === undefined) {
9522          module.initialize();
9523        }
9524        module.invoke(query);
9525      }
9526      else {
9527        if(instance !== undefined) {
9528          instance.invoke('destroy');
9529        }
9530        module.initialize();
9531      }
9532    })
9533  ;
9534
9535  return (returnedValue !== undefined)
9536    ? returnedValue
9537    : this
9538  ;
9539};
9540
9541$.fn.nag.settings = {
9542
9543  name        : 'Nag',
9544
9545  debug       : false,
9546  verbose     : false,
9547  performance : true,
9548
9549  namespace   : 'Nag',
9550
9551  // allows cookie to be overriden
9552  persist     : false,
9553
9554  // set to zero to require manually dismissal, otherwise hides on its own
9555  displayTime : 0,
9556
9557  animation   : {
9558    show : 'slide',
9559    hide : 'slide'
9560  },
9561
9562  context       : false,
9563  detachable    : false,
9564
9565  expires       : 30,
9566  domain        : false,
9567  path          : '/',
9568
9569  // type of storage to use
9570  storageMethod : 'cookie',
9571
9572  // value to store in dismissed localstorage/cookie
9573  key           : 'nag',
9574  value         : 'dismiss',
9575
9576  error: {
9577    noCookieStorage : '$.cookie is not included. A storage solution is required.',
9578    noStorage       : 'Neither $.cookie or store is defined. A storage solution is required for storing state',
9579    method          : 'The method you called is not defined.'
9580  },
9581
9582  className     : {
9583    bottom : 'bottom',
9584    fixed  : 'fixed'
9585  },
9586
9587  selector      : {
9588    close : '.close.icon'
9589  },
9590
9591  speed         : 500,
9592  easing        : 'easeOutQuad',
9593
9594  onHide: function() {}
9595
9596};
9597
9598})( jQuery, window, document );
9599
9600/*!
9601 * # Semantic UI 2.1.7 - Popup
9602 * http://github.com/semantic-org/semantic-ui/
9603 *
9604 *
9605 * Copyright 2015 Contributors
9606 * Released under the MIT license
9607 * http://opensource.org/licenses/MIT
9608 *
9609 */
9610
9611;(function ($, window, document, undefined) {
9612
9613"use strict";
9614
9615$.fn.popup = function(parameters) {
9616  var
9617    $allModules    = $(this),
9618    $document      = $(document),
9619    $window        = $(window),
9620    $body          = $('body'),
9621
9622    moduleSelector = $allModules.selector || '',
9623
9624    hasTouch       = (true),
9625    time           = new Date().getTime(),
9626    performance    = [],
9627
9628    query          = arguments[0],
9629    methodInvoked  = (typeof query == 'string'),
9630    queryArguments = [].slice.call(arguments, 1),
9631
9632    returnedValue
9633  ;
9634  $allModules
9635    .each(function() {
9636      var
9637        settings        = ( $.isPlainObject(parameters) )
9638          ? $.extend(true, {}, $.fn.popup.settings, parameters)
9639          : $.extend({}, $.fn.popup.settings),
9640
9641        selector           = settings.selector,
9642        className          = settings.className,
9643        error              = settings.error,
9644        metadata           = settings.metadata,
9645        namespace          = settings.namespace,
9646
9647        eventNamespace     = '.' + settings.namespace,
9648        moduleNamespace    = 'module-' + namespace,
9649
9650        $module            = $(this),
9651        $context           = $(settings.context),
9652        $target            = (settings.target)
9653          ? $(settings.target)
9654          : $module,
9655
9656        $popup,
9657        $offsetParent,
9658
9659        searchDepth        = 0,
9660        triedPositions     = false,
9661        openedWithTouch    = false,
9662
9663        element            = this,
9664        instance           = $module.data(moduleNamespace),
9665
9666        elementNamespace,
9667        id,
9668        module
9669      ;
9670
9671      module = {
9672
9673        // binds events
9674        initialize: function() {
9675          module.debug('Initializing', $module);
9676          module.createID();
9677          module.bind.events();
9678          if( !module.exists() && settings.preserve) {
9679            module.create();
9680          }
9681          module.instantiate();
9682        },
9683
9684        instantiate: function() {
9685          module.verbose('Storing instance', module);
9686          instance = module;
9687          $module
9688            .data(moduleNamespace, instance)
9689          ;
9690        },
9691
9692        refresh: function() {
9693          if(settings.popup) {
9694            $popup = $(settings.popup).eq(0);
9695          }
9696          else {
9697            if(settings.inline) {
9698              $popup = $target.nextAll(selector.popup).eq(0);
9699              settings.popup = $popup;
9700            }
9701          }
9702          if(settings.popup) {
9703            $popup.addClass(className.loading);
9704            $offsetParent = module.get.offsetParent();
9705            $popup.removeClass(className.loading);
9706            if(settings.movePopup && module.has.popup() && module.get.offsetParent($popup)[0] !== $offsetParent[0]) {
9707              module.debug('Moving popup to the same offset parent as activating element');
9708              $popup
9709                .detach()
9710                .appendTo($offsetParent)
9711              ;
9712            }
9713          }
9714          else {
9715            $offsetParent = (settings.inline)
9716              ? module.get.offsetParent($target)
9717              : module.has.popup()
9718                ? module.get.offsetParent($popup)
9719                : $body
9720            ;
9721          }
9722          if( $offsetParent.is('html') && $offsetParent[0] !== $body[0] ) {
9723            module.debug('Setting page as offset parent');
9724            $offsetParent = $body;
9725          }
9726          if( module.get.variation() ) {
9727            module.set.variation();
9728          }
9729        },
9730
9731        reposition: function() {
9732          module.refresh();
9733          module.set.position();
9734        },
9735
9736        destroy: function() {
9737          module.debug('Destroying previous module');
9738          // remove element only if was created dynamically
9739          if($popup && !settings.preserve) {
9740            module.removePopup();
9741          }
9742          // clear all timeouts
9743          clearTimeout(module.hideTimer);
9744          clearTimeout(module.showTimer);
9745          // remove events
9746          $window.off(elementNamespace);
9747          $module
9748            .off(eventNamespace)
9749            .removeData(moduleNamespace)
9750          ;
9751        },
9752
9753        event: {
9754          start:  function(event) {
9755            var
9756              delay = ($.isPlainObject(settings.delay))
9757                ? settings.delay.show
9758                : settings.delay
9759            ;
9760            clearTimeout(module.hideTimer);
9761            if(!openedWithTouch) {
9762              module.showTimer = setTimeout(module.show, delay);
9763            }
9764          },
9765          end:  function() {
9766            var
9767              delay = ($.isPlainObject(settings.delay))
9768                ? settings.delay.hide
9769                : settings.delay
9770            ;
9771            clearTimeout(module.showTimer);
9772            module.hideTimer = setTimeout(module.hide, delay);
9773          },
9774          touchstart: function(event) {
9775            openedWithTouch = true;
9776            module.show();
9777          },
9778          resize: function() {
9779            if( module.is.visible() ) {
9780              module.set.position();
9781            }
9782          },
9783          hideGracefully: function(event) {
9784            // don't close on clicks inside popup
9785            if(event && $(event.target).closest(selector.popup).length === 0) {
9786              module.debug('Click occurred outside popup hiding popup');
9787              module.hide();
9788            }
9789            else {
9790              module.debug('Click was inside popup, keeping popup open');
9791            }
9792          }
9793        },
9794
9795        // generates popup html from metadata
9796        create: function() {
9797          var
9798            html      = module.get.html(),
9799            title     = module.get.title(),
9800            content   = module.get.content()
9801          ;
9802
9803          if(html || content || title) {
9804            module.debug('Creating pop-up html');
9805            if(!html) {
9806              html = settings.templates.popup({
9807                title   : title,
9808                content : content
9809              });
9810            }
9811            $popup = $('<div/>')
9812              .addClass(className.popup)
9813              .data(metadata.activator, $module)
9814              .html(html)
9815            ;
9816            if(settings.inline) {
9817              module.verbose('Inserting popup element inline', $popup);
9818              $popup
9819                .insertAfter($module)
9820              ;
9821            }
9822            else {
9823              module.verbose('Appending popup element to body', $popup);
9824              $popup
9825                .appendTo( $context )
9826              ;
9827            }
9828            module.refresh();
9829            module.set.variation();
9830
9831            if(settings.hoverable) {
9832              module.bind.popup();
9833            }
9834            settings.onCreate.call($popup, element);
9835          }
9836          else if($target.next(selector.popup).length !== 0) {
9837            module.verbose('Pre-existing popup found');
9838            settings.inline = true;
9839            settings.popups  = $target.next(selector.popup).data(metadata.activator, $module);
9840            module.refresh();
9841            if(settings.hoverable) {
9842              module.bind.popup();
9843            }
9844          }
9845          else if(settings.popup) {
9846            $(settings.popup).data(metadata.activator, $module);
9847            module.verbose('Used popup specified in settings');
9848            module.refresh();
9849            if(settings.hoverable) {
9850              module.bind.popup();
9851            }
9852          }
9853          else {
9854            module.debug('No content specified skipping display', element);
9855          }
9856        },
9857
9858        createID: function() {
9859          id = (Math.random().toString(16) + '000000000').substr(2,8);
9860          elementNamespace = '.' + id;
9861          module.verbose('Creating unique id for element', id);
9862        },
9863
9864        // determines popup state
9865        toggle: function() {
9866          module.debug('Toggling pop-up');
9867          if( module.is.hidden() ) {
9868            module.debug('Popup is hidden, showing pop-up');
9869            module.unbind.close();
9870            module.show();
9871          }
9872          else {
9873            module.debug('Popup is visible, hiding pop-up');
9874            module.hide();
9875          }
9876        },
9877
9878        show: function(callback) {
9879          callback = callback || function(){};
9880          module.debug('Showing pop-up', settings.transition);
9881          if(module.is.hidden() && !( module.is.active() && module.is.dropdown()) ) {
9882            if( !module.exists() ) {
9883              module.create();
9884            }
9885            if(settings.onShow.call($popup, element) === false) {
9886              module.debug('onShow callback returned false, cancelling popup animation');
9887              return;
9888            }
vendor: 1,560 bytes, lines 9889-9943
9889            else if(!settings.preserve && !settings.popup) {
9890              module.refresh();
9891            }
9892            if( $popup && module.set.position() ) {
9893              module.save.conditions();
9894              if(settings.exclusive) {
9895                module.hideAll();
9896              }
9897              module.animate.show(callback);
9898            }
9899          }
9900        },
9901
9902
9903        hide: function(callback) {
9904          callback = callback || function(){};
9905          if( module.is.visible() || module.is.animating() ) {
9906            if(settings.onHide.call($popup, element) === false) {
9907              module.debug('onHide callback returned false, cancelling popup animation');
9908              return;
9909            }
9910            module.remove.visible();
9911            module.unbind.close();
9912            module.restore.conditions();
9913            module.animate.hide(callback);
9914          }
9915        },
9916
9917        hideAll: function() {
9918          $(selector.popup)
9919            .filter('.' + className.visible)
9920            .each(function() {
9921              $(this)
9922                .data(metadata.activator)
9923                .popup('hide')
9924              ;
9925            })
9926          ;
9927        },
9928        exists: function() {
9929          if(!$popup) {
9930            return false;
9931          }
9932          if(settings.inline || settings.popup) {
9933            return ( module.has.popup() );
9934          }
9935          else {
9936            return ( $popup.closest($context).length >= 1 )
9937              ? true
9938              : false
9939            ;
9940          }
9941        },
9942
9943        removePopup: function() {
vendor: 12,938 bytes, lines 9944-10299
9944          if( module.has.popup() && !settings.popup) {
9945            module.debug('Removing popup', $popup);
9946            $popup.remove();
9947            $popup = undefined;
9948            settings.onRemove.call($popup, element);
9949          }
9950        },
9951
9952        save: {
9953          conditions: function() {
9954            module.cache = {
9955              title: $module.attr('title')
9956            };
9957            if (module.cache.title) {
9958              $module.removeAttr('title');
9959            }
9960            module.verbose('Saving original attributes', module.cache.title);
9961          }
9962        },
9963        restore: {
9964          conditions: function() {
9965            if(module.cache && module.cache.title) {
9966              $module.attr('title', module.cache.title);
9967              module.verbose('Restoring original attributes', module.cache.title);
9968            }
9969            return true;
9970          }
9971        },
9972        animate: {
9973          show: function(callback) {
9974            callback = $.isFunction(callback) ? callback : function(){};
9975            if(settings.transition && $.fn.transition !== undefined && $module.transition('is supported')) {
9976              module.set.visible();
9977              $popup
9978                .transition({
9979                  animation  : settings.transition + ' in',
9980                  queue      : false,
9981                  debug      : settings.debug,
9982                  verbose    : settings.verbose,
9983                  duration   : settings.duration,
9984                  onComplete : function() {
9985                    module.bind.close();
9986                    callback.call($popup, element);
9987                    settings.onVisible.call($popup, element);
9988                  }
9989                })
9990              ;
9991            }
9992            else {
9993              module.error(error.noTransition);
9994            }
9995          },
9996          hide: function(callback) {
9997            callback = $.isFunction(callback) ? callback : function(){};
9998            module.debug('Hiding pop-up');
9999            if(settings.onHide.call($popup, element) === false) {
10000              module.debug('onHide callback returned false, cancelling popup animation');
10001              return;
10002            }
10003            if(settings.transition && $.fn.transition !== undefined && $module.transition('is supported')) {
10004              $popup
10005                .transition({
10006                  animation  : settings.transition + ' out',
10007                  queue      : false,
10008                  duration   : settings.duration,
10009                  debug      : settings.debug,
10010                  verbose    : settings.verbose,
10011                  onComplete : function() {
10012                    module.reset();
10013                    callback.call($popup, element);
10014                    settings.onHidden.call($popup, element);
10015                  }
10016                })
10017              ;
10018            }
10019            else {
10020              module.error(error.noTransition);
10021            }
10022          }
10023        },
10024
10025        change: {
10026          content: function(html) {
10027            $popup.html(html);
10028          }
10029        },
10030
10031        get: {
10032          html: function() {
10033            $module.removeData(metadata.html);
10034            return $module.data(metadata.html) || settings.html;
10035          },
10036          title: function() {
10037            $module.removeData(metadata.title);
10038            return $module.data(metadata.title) || settings.title;
10039          },
10040          content: function() {
10041            $module.removeData(metadata.content);
10042            return $module.data(metadata.content) || $module.attr('title') || settings.content;
10043          },
10044          variation: function() {
10045            $module.removeData(metadata.variation);
10046            return $module.data(metadata.variation) || settings.variation;
10047          },
10048          popup: function() {
10049            return $popup;
10050          },
10051          popupOffset: function() {
10052            return $popup.offset();
10053          },
10054          calculations: function() {
10055            var
10056              targetElement  = $target[0],
10057              targetPosition = (settings.inline || (settings.popup && settings.movePopup))
10058                ? $target.position()
10059                : $target.offset(),
10060              calculations = {},
10061              screen
10062            ;
10063            calculations = {
10064              // element which is launching popup
10065              target : {
10066                element : $target[0],
10067                width   : $target.outerWidth(),
10068                height  : $target.outerHeight(),
10069                top     : targetPosition.top,
10070                left    : targetPosition.left,
10071                margin  : {}
10072              },
10073              // popup itself
10074              popup : {
10075                width  : $popup.outerWidth(),
10076                height : $popup.outerHeight()
10077              },
10078              // offset container (or 3d context)
10079              parent : {
10080                width  : $offsetParent.outerWidth(),
10081                height : $offsetParent.outerHeight()
10082              },
10083              // screen boundaries
10084              screen : {
10085                scroll: {
10086                  top  : $window.scrollTop(),
10087                  left : $window.scrollLeft()
10088                },
10089                width  : $window.width(),
10090                height : $window.height()
10091              }
10092            };
10093
10094            // add in container calcs if fluid
10095            if( settings.setFluidWidth && module.is.fluid() ) {
10096              calculations.container = {
10097                width: $popup.parent().outerWidth()
10098              };
10099              calculations.popup.width = calculations.container.width;
10100            }
10101
10102            // add in margins if inline
10103            calculations.target.margin.top = (settings.inline)
10104              ? parseInt( window.getComputedStyle(targetElement).getPropertyValue('margin-top'), 10)
10105              : 0
10106            ;
10107            calculations.target.margin.left = (settings.inline)
10108              ? module.is.rtl()
10109                ? parseInt( window.getComputedStyle(targetElement).getPropertyValue('margin-right'), 10)
10110                : parseInt( window.getComputedStyle(targetElement).getPropertyValue('margin-left') , 10)
10111              : 0
10112            ;
10113            // calculate screen boundaries
10114            screen = calculations.screen;
10115            calculations.boundary = {
10116              top    : screen.scroll.top,
10117              bottom : screen.scroll.top + screen.height,
10118              left   : screen.scroll.left,
10119              right  : screen.scroll.left + screen.width
10120            };
10121            return calculations;
10122          },
10123          id: function() {
10124            return id;
10125          },
10126          startEvent: function() {
10127            if(settings.on == 'hover') {
10128              return 'mouseenter';
10129            }
10130            else if(settings.on == 'focus') {
10131              return 'focus';
10132            }
10133            return false;
10134          },
10135          scrollEvent: function() {
10136            return 'scroll';
10137          },
10138          endEvent: function() {
10139            if(settings.on == 'hover') {
10140              return 'mouseleave';
10141            }
10142            else if(settings.on == 'focus') {
10143              return 'blur';
10144            }
10145            return false;
10146          },
10147          distanceFromBoundary: function(offset, calculations) {
10148            var
10149              distanceFromBoundary = {},
10150              popup,
10151              boundary
10152            ;
10153            offset       = offset       || module.get.offset();
10154            calculations = calculations || module.get.calculations();
10155
10156            // shorthand
10157            popup        = calculations.popup;
10158            boundary     = calculations.boundary;
10159
10160            if(offset) {
10161              distanceFromBoundary = {
10162                top    : (offset.top - boundary.top),
10163                left   : (offset.left - boundary.left),
10164                right  : (boundary.right - (offset.left + popup.width) ),
10165                bottom : (boundary.bottom - (offset.top + popup.height) )
10166              };
10167              module.verbose('Distance from boundaries determined', offset, distanceFromBoundary);
10168            }
10169            return distanceFromBoundary;
10170          },
10171          offsetParent: function($target) {
10172            var
10173              element = ($target !== undefined)
10174                ? $target[0]
10175                : $module[0],
10176              parentNode = element.parentNode,
10177              $node    = $(parentNode)
10178            ;
10179            if(parentNode) {
10180              var
10181                is2D     = ($node.css('transform') === 'none'),
10182                isStatic = ($node.css('position') === 'static'),
10183                isHTML   = $node.is('html')
10184              ;
10185              while(parentNode && !isHTML && isStatic && is2D) {
10186                parentNode = parentNode.parentNode;
10187                $node    = $(parentNode);
10188                is2D     = ($node.css('transform') === 'none');
10189                isStatic = ($node.css('position') === 'static');
10190                isHTML   = $node.is('html');
10191              }
10192            }
10193            return ($node && $node.length > 0)
10194              ? $node
10195              : $()
10196            ;
10197          },
10198          positions: function() {
10199            return {
10200              'top left'      : false,
10201              'top center'    : false,
10202              'top right'     : false,
10203              'bottom left'   : false,
10204              'bottom center' : false,
10205              'bottom right'  : false,
10206              'left center'   : false,
10207              'right center'  : false
10208            };
10209          },
10210          nextPosition: function(position) {
10211            var
10212              positions          = position.split(' '),
10213              verticalPosition   = positions[0],
10214              horizontalPosition = positions[1],
10215              opposite = {
10216                top    : 'bottom',
10217                bottom : 'top',
10218                left   : 'right',
10219                right  : 'left'
10220              },
10221              adjacent = {
10222                left   : 'center',
10223                center : 'right',
10224                right  : 'left'
10225              },
10226              backup = {
10227                'top left'      : 'top center',
10228                'top center'    : 'top right',
10229                'top right'     : 'right center',
10230                'right center'  : 'bottom right',
10231                'bottom right'  : 'bottom center',
10232                'bottom center' : 'bottom left',
10233                'bottom left'   : 'left center',
10234                'left center'   : 'top left'
10235              },
10236              adjacentsAvailable = (verticalPosition == 'top' || verticalPosition == 'bottom'),
10237              oppositeTried = false,
10238              adjacentTried = false,
10239              nextPosition  = false
10240            ;
10241            if(!triedPositions) {
10242              module.verbose('All available positions available');
10243              triedPositions = module.get.positions();
10244            }
10245
10246            module.debug('Recording last position tried', position);
10247            triedPositions[position] = true;
10248
10249            if(settings.prefer === 'opposite') {
10250              nextPosition  = [opposite[verticalPosition], horizontalPosition];
10251              nextPosition  = nextPosition.join(' ');
10252              oppositeTried = (triedPositions[nextPosition] === true);
10253              module.debug('Trying opposite strategy', nextPosition);
10254            }
10255            if((settings.prefer === 'adjacent') && adjacentsAvailable ) {
10256              nextPosition  = [verticalPosition, adjacent[horizontalPosition]];
10257              nextPosition  = nextPosition.join(' ');
10258              adjacentTried = (triedPositions[nextPosition] === true);
10259              module.debug('Trying adjacent strategy', nextPosition);
10260            }
10261            if(adjacentTried || oppositeTried) {
10262              module.debug('Using backup position', nextPosition);
10263              nextPosition = backup[position];
10264            }
10265            return nextPosition;
10266          }
10267        },
10268
10269        set: {
10270          position: function(position, calculations) {
10271
10272            // exit conditions
10273            if($target.length === 0 || $popup.length === 0) {
10274              module.error(error.notFound);
10275              return;
10276            }
10277            var
10278              offset,
10279              distanceAway,
10280              target,
10281              popup,
10282              parent,
10283              positioning,
10284              popupOffset,
10285              distanceFromBoundary
10286            ;
10287
10288            calculations = calculations || module.get.calculations();
10289            position     = position     || $module.data(metadata.position) || settings.position;
10290
10291            offset       = $module.data(metadata.offset) || settings.offset;
10292            distanceAway = settings.distanceAway;
10293
10294            // shorthand
10295            target = calculations.target;
10296            popup  = calculations.popup;
10297            parent = calculations.parent;
10298
10299            if(target.width === 0 && target.height === 0 && !(target.element instanceof SVGGraphicsE
vendor: 8,925 bytes, lines 10299-10531
10299lement)) {
10300              module.debug('Popup target is hidden, no action taken');
10301              return false;
10302            }
10303
10304            if(settings.inline) {
10305              module.debug('Adding margin to calculation', target.margin);
10306              if(position == 'left center' || position == 'right center') {
10307                offset       +=  target.margin.top;
10308                distanceAway += -target.margin.left;
10309              }
10310              else if (position == 'top left' || position == 'top center' || position == 'top right') {
10311                offset       += target.margin.left;
10312                distanceAway -= target.margin.top;
10313              }
10314              else {
10315                offset       += target.margin.left;
10316                distanceAway += target.margin.top;
10317              }
10318            }
10319
10320            module.debug('Determining popup position from calculations', position, calculations);
10321
10322            if (module.is.rtl()) {
10323              position = position.replace(/left|right/g, function (match) {
10324                return (match == 'left')
10325                  ? 'right'
10326                  : 'left'
10327                ;
10328              });
10329              module.debug('RTL: Popup position updated', position);
10330            }
10331
10332            // if last attempt use specified last resort position
10333            if(searchDepth == settings.maxSearchDepth && typeof settings.lastResort === 'string') {
10334              position = settings.lastResort;
10335            }
10336
10337            switch (position) {
10338              case 'top left':
10339                positioning = {
10340                  top    : 'auto',
10341                  bottom : parent.height - target.top + distanceAway,
10342                  left   : target.left + offset,
10343                  right  : 'auto'
10344                };
10345              break;
10346              case 'top center':
10347                positioning = {
10348                  bottom : parent.height - target.top + distanceAway,
10349                  left   : target.left + (target.width / 2) - (popup.width / 2) + offset,
10350                  top    : 'auto',
10351                  right  : 'auto'
10352                };
10353              break;
10354              case 'top right':
10355                positioning = {
10356                  bottom :  parent.height - target.top + distanceAway,
10357                  right  :  parent.width - target.left - target.width - offset,
10358                  top    : 'auto',
10359                  left   : 'auto'
10360                };
10361              break;
10362              case 'left center':
10363                positioning = {
10364                  top    : target.top + (target.height / 2) - (popup.height / 2) + offset,
10365                  right  : parent.width - target.left + distanceAway,
10366                  left   : 'auto',
10367                  bottom : 'auto'
10368                };
10369              break;
10370              case 'right center':
10371                positioning = {
10372                  top    : target.top + (target.height / 2) - (popup.height / 2) + offset,
10373                  left   : target.left + target.width + distanceAway,
10374                  bottom : 'auto',
10375                  right  : 'auto'
10376                };
10377              break;
10378              case 'bottom left':
10379                positioning = {
10380                  top    : target.top + target.height + distanceAway,
10381                  left   : target.left + offset,
10382                  bottom : 'auto',
10383                  right  : 'auto'
10384                };
10385              break;
10386              case 'bottom center':
10387                positioning = {
10388                  top    : target.top + target.height + distanceAway,
10389                  left   : target.left + (target.width / 2) - (popup.width / 2) + offset,
10390                  bottom : 'auto',
10391                  right  : 'auto'
10392                };
10393              break;
10394              case 'bottom right':
10395                positioning = {
10396                  top    : target.top + target.height + distanceAway,
10397                  right  : parent.width - target.left  - target.width - offset,
10398                  left   : 'auto',
10399                  bottom : 'auto'
10400                };
10401              break;
10402            }
10403            if(positioning === undefined) {
10404              module.error(error.invalidPosition, position);
10405            }
10406
10407            module.debug('Calculated popup positioning values', positioning);
10408
10409            // tentatively place on stage
10410            $popup
10411              .css(positioning)
10412              .removeClass(className.position)
10413              .addClass(position)
10414              .addClass(className.loading)
10415            ;
10416
10417            popupOffset = module.get.popupOffset();
10418
10419            // see if any boundaries are surpassed with this tentative position
10420            distanceFromBoundary = module.get.distanceFromBoundary(popupOffset, calculations);
10421
10422            if( module.is.offstage(distanceFromBoundary, position) ) {
10423              module.debug('Position is outside viewport', position);
10424              if(searchDepth < settings.maxSearchDepth) {
10425                searchDepth++;
10426                position = module.get.nextPosition(position);
10427                module.debug('Trying new position', position);
10428                return ($popup)
10429                  ? module.set.position(position, calculations)
10430                  : false
10431                ;
10432              }
10433              else {
10434                if(settings.lastResort) {
10435                  module.debug('No position found, showing with last position');
10436                }
10437                else {
10438                  module.debug('Popup could not find a position to display', $popup);
10439                  module.error(error.cannotPlace, element);
10440                  module.remove.attempts();
10441                  module.remove.loading();
10442                  module.reset();
10443                  settings.onUnplaceable.call($popup, element);
10444                  return false;
10445                }
10446              }
10447            }
10448            module.debug('Position is on stage', position);
10449            module.remove.attempts();
10450            module.remove.loading();
10451            if( settings.setFluidWidth && module.is.fluid() ) {
10452              module.set.fluidWidth(calculations);
10453            }
10454            return true;
10455          },
10456
10457          fluidWidth: function(calculations) {
10458            calculations = calculations || module.get.calculations();
10459            module.debug('Automatically setting element width to parent width', calculations.parent.width);
10460            $popup.css('width', calculations.container.width);
10461          },
10462
10463          variation: function(variation) {
10464            variation = variation || module.get.variation();
10465            if(variation && module.has.popup() ) {
10466              module.verbose('Adding variation to popup', variation);
10467              $popup.addClass(variation);
10468            }
10469          },
10470
10471          visible: function() {
10472            $module.addClass(className.visible);
10473          }
10474        },
10475
10476        remove: {
10477          loading: function() {
10478            $popup.removeClass(className.loading);
10479          },
10480          variation: function(variation) {
10481            variation = variation || module.get.variation();
10482            if(variation) {
10483              module.verbose('Removing variation', variation);
10484              $popup.removeClass(variation);
10485            }
10486          },
10487          visible: function() {
10488            $module.removeClass(className.visible);
10489          },
10490          attempts: function() {
10491            module.verbose('Resetting all searched positions');
10492            searchDepth    = 0;
10493            triedPositions = false;
10494          }
10495        },
10496
10497        bind: {
10498          events: function() {
10499            module.debug('Binding popup events to module');
10500            if(settings.on == 'click') {
10501              $module
10502                .on('click' + eventNamespace, module.toggle)
10503              ;
10504            }
10505            if(settings.on == 'hover' && hasTouch) {
10506              $module
10507                .on('touchstart' + eventNamespace, module.event.touchstart)
10508              ;
10509            }
10510            if( module.get.startEvent() ) {
10511              $module
10512                .on(module.get.startEvent() + eventNamespace, module.event.start)
10513                .on(module.get.endEvent() + eventNamespace, module.event.end)
10514              ;
10515            }
10516            if(settings.target) {
10517              module.debug('Target set to element', $target);
10518            }
10519            $window.on('resize' + elementNamespace, module.event.resize);
10520          },
10521          popup: function() {
10522            module.verbose('Allowing hover events on popup to prevent closing');
10523            if( $popup && module.has.popup() ) {
10524              $popup
10525                .on('mouseenter' + eventNamespace, module.event.start)
10526                .on('mouseleave' + eventNamespace, module.event.end)
10527              ;
10528            }
10529          },
10530          close: function() {
10531            if(settings.hideOnScroll === true || (settings.hideOnScroll == 'auto' && settings.on != 'click')) 
vendor: 71,266 bytes, lines 10531-12823
10531  {
10532              $document
10533                .one(module.get.scrollEvent() + elementNamespace, module.event.hideGracefully)
10534              ;
10535              $context
10536                .one(module.get.scrollEvent() + elementNamespace, module.event.hideGracefully)
10537              ;
10538            }
10539            if(settings.on == 'hover' && openedWithTouch) {
10540              module.verbose('Binding popup close event to document');
10541              $document
10542                .on('touchstart' + elementNamespace, function(event) {
10543                  module.verbose('Touched away from popup');
10544                  module.event.hideGracefully.call(element, event);
10545                })
10546              ;
10547            }
10548            if(settings.on == 'click' && settings.closable) {
10549              module.verbose('Binding popup close event to document');
10550              $document
10551                .on('click' + elementNamespace, function(event) {
10552                  module.verbose('Clicked away from popup');
10553                  module.event.hideGracefully.call(element, event);
10554                })
10555              ;
10556            }
10557          }
10558        },
10559
10560        unbind: {
10561          close: function() {
10562            if(settings.hideOnScroll === true || (settings.hideOnScroll == 'auto' && settings.on != 'click')) {
10563              $document
10564                .off('scroll' + elementNamespace, module.hide)
10565              ;
10566              $context
10567                .off('scroll' + elementNamespace, module.hide)
10568              ;
10569            }
10570            if(settings.on == 'hover' && openedWithTouch) {
10571              $document
10572                .off('touchstart' + elementNamespace)
10573              ;
10574              openedWithTouch = false;
10575            }
10576            if(settings.on == 'click' && settings.closable) {
10577              module.verbose('Removing close event from document');
10578              $document
10579                .off('click' + elementNamespace)
10580              ;
10581            }
10582          }
10583        },
10584
10585        has: {
10586          popup: function() {
10587            return ($popup && $popup.length > 0);
10588          }
10589        },
10590
10591        is: {
10592          offstage: function(distanceFromBoundary, position) {
10593            var
10594              offstage = []
10595            ;
10596            // return boundaries that have been surpassed
10597            $.each(distanceFromBoundary, function(direction, distance) {
10598              if(distance < -settings.jitter) {
10599                module.debug('Position exceeds allowable distance from edge', direction, distance, position);
10600                offstage.push(direction);
10601              }
10602            });
10603            if(offstage.length > 0) {
10604              return true;
10605            }
10606            else {
10607              return false;
10608            }
10609          },
10610          active: function() {
10611            return $module.hasClass(className.active);
10612          },
10613          animating: function() {
10614            return ($popup !== undefined && $popup.hasClass(className.animating) );
10615          },
10616          fluid: function() {
10617            return ($popup !== undefined && $popup.hasClass(className.fluid));
10618          },
10619          visible: function() {
10620            return ($popup !== undefined && $popup.hasClass(className.visible));
10621          },
10622          dropdown: function() {
10623            return $module.hasClass(className.dropdown);
10624          },
10625          hidden: function() {
10626            return !module.is.visible();
10627          },
10628          rtl: function () {
10629            return $module.css('direction') == 'rtl';
10630          }
10631        },
10632
10633        reset: function() {
10634          module.remove.visible();
10635          if(settings.preserve) {
10636            if($.fn.transition !== undefined) {
10637              $popup
10638                .transition('remove transition')
10639              ;
10640            }
10641          }
10642          else {
10643            module.removePopup();
10644          }
10645        },
10646
10647        setting: function(name, value) {
10648          if( $.isPlainObject(name) ) {
10649            $.extend(true, settings, name);
10650          }
10651          else if(value !== undefined) {
10652            settings[name] = value;
10653          }
10654          else {
10655            return settings[name];
10656          }
10657        },
10658        internal: function(name, value) {
10659          if( $.isPlainObject(name) ) {
10660            $.extend(true, module, name);
10661          }
10662          else if(value !== undefined) {
10663            module[name] = value;
10664          }
10665          else {
10666            return module[name];
10667          }
10668        },
10669        debug: function() {
10670          if(settings.debug) {
10671            if(settings.performance) {
10672              module.performance.log(arguments);
10673            }
10674            else {
10675              module.debug = Function.prototype.bind.call(console.info, console, settings.name + ':');
10676              module.debug.apply(console, arguments);
10677            }
10678          }
10679        },
10680        verbose: function() {
10681          if(settings.verbose && settings.debug) {
10682            if(settings.performance) {
10683              module.performance.log(arguments);
10684            }
10685            else {
10686              module.verbose = Function.prototype.bind.call(console.info, console, settings.name + ':');
10687              module.verbose.apply(console, arguments);
10688            }
10689          }
10690        },
10691        error: function() {
10692          module.error = Function.prototype.bind.call(console.error, console, settings.name + ':');
10693          module.error.apply(console, arguments);
10694        },
10695        performance: {
10696          log: function(message) {
10697            var
10698              currentTime,
10699              executionTime,
10700              previousTime
10701            ;
10702            if(settings.performance) {
10703              currentTime   = new Date().getTime();
10704              previousTime  = time || currentTime;
10705              executionTime = currentTime - previousTime;
10706              time          = currentTime;
10707              performance.push({
10708                'Name'           : message[0],
10709                'Arguments'      : [].slice.call(message, 1) || '',
10710                'Element'        : element,
10711                'Execution Time' : executionTime
10712              });
10713            }
10714            clearTimeout(module.performance.timer);
10715            module.performance.timer = setTimeout(module.performance.display, 500);
10716          },
10717          display: function() {
10718            var
10719              title = settings.name + ':',
10720              totalTime = 0
10721            ;
10722            time = false;
10723            clearTimeout(module.performance.timer);
10724            $.each(performance, function(index, data) {
10725              totalTime += data['Execution Time'];
10726            });
10727            title += ' ' + totalTime + 'ms';
10728            if(moduleSelector) {
10729              title += ' \'' + moduleSelector + '\'';
10730            }
10731            if( (console.group !== undefined || console.table !== undefined) && performance.length > 0) {
10732              console.groupCollapsed(title);
10733              if(console.table) {
10734                console.table(performance);
10735              }
10736              else {
10737                $.each(performance, function(index, data) {
10738                  console.log(data['Name'] + ': ' + data['Execution Time']+'ms');
10739                });
10740              }
10741              console.groupEnd();
10742            }
10743            performance = [];
10744          }
10745        },
10746        invoke: function(query, passedArguments, context) {
10747          var
10748            object = instance,
10749            maxDepth,
10750            found,
10751            response
10752          ;
10753          passedArguments = passedArguments || queryArguments;
10754          context         = element         || context;
10755          if(typeof query == 'string' && object !== undefined) {
10756            query    = query.split(/[\. ]/);
10757            maxDepth = query.length - 1;
10758            $.each(query, function(depth, value) {
10759              var camelCaseValue = (depth != maxDepth)
10760                ? value + query[depth + 1].charAt(0).toUpperCase() + query[depth + 1].slice(1)
10761                : query
10762              ;
10763              if( $.isPlainObject( object[camelCaseValue] ) && (depth != maxDepth) ) {
10764                object = object[camelCaseValue];
10765              }
10766              else if( object[camelCaseValue] !== undefined ) {
10767                found = object[camelCaseValue];
10768                return false;
10769              }
10770              else if( $.isPlainObject( object[value] ) && (depth != maxDepth) ) {
10771                object = object[value];
10772              }
10773              else if( object[value] !== undefined ) {
10774                found = object[value];
10775                return false;
10776              }
10777              else {
10778                return false;
10779              }
10780            });
10781          }
10782          if ( $.isFunction( found ) ) {
10783            response = found.apply(context, passedArguments);
10784          }
10785          else if(found !== undefined) {
10786            response = found;
10787          }
10788          if($.isArray(returnedValue)) {
10789            returnedValue.push(response);
10790          }
10791          else if(returnedValue !== undefined) {
10792            returnedValue = [returnedValue, response];
10793          }
10794          else if(response !== undefined) {
10795            returnedValue = response;
10796          }
10797          return found;
10798        }
10799      };
10800
10801      if(methodInvoked) {
10802        if(instance === undefined) {
10803          module.initialize();
10804        }
10805        module.invoke(query);
10806      }
10807      else {
10808        if(instance !== undefined) {
10809          instance.invoke('destroy');
10810        }
10811        module.initialize();
10812      }
10813    })
10814  ;
10815
10816  return (returnedValue !== undefined)
10817    ? returnedValue
10818    : this
10819  ;
10820};
10821
10822$.fn.popup.settings = {
10823
10824  name         : 'Popup',
10825
10826  // module settings
10827  debug        : false,
10828  verbose      : false,
10829  performance  : true,
10830  namespace    : 'popup',
10831
10832  // callback only when element added to dom
10833  onCreate     : function(){},
10834
10835  // callback before element removed from dom
10836  onRemove     : function(){},
10837
10838  // callback before show animation
10839  onShow       : function(){},
10840
10841  // callback after show animation
10842  onVisible    : function(){},
10843
10844  // callback before hide animation
10845  onHide       : function(){},
10846
10847  // callback when popup cannot be positioned in visible screen
10848  onUnplaceable: function(){},
10849
10850  // callback after hide animation
10851  onHidden     : function(){},
10852
10853  // when to show popup
10854  on           : 'hover',
10855
10856  // whether to add touchstart events when using hover
10857  addTouchEvents : true,
10858
10859  // default position relative to element
10860  position     : 'top left',
10861
10862  // name of variation to use
10863  variation    : '',
10864
10865  // whether popup should be moved to context
10866  movePopup      : true,
10867
10868  // element which popup should be relative to
10869  target         : false,
10870
10871  // jq selector or element that should be used as popup
10872  popup          : false,
10873
10874  // popup should remain inline next to activator
10875  inline         : false,
10876
10877  // popup should be removed from page on hide
10878  preserve       : false,
10879
10880  // popup should not close when being hovered on
10881  hoverable      : false,
10882
10883  // explicitly set content
10884  content      : false,
10885
10886  // explicitly set html
10887  html         : false,
10888
10889  // explicitly set title
10890  title        : false,
10891
10892  // whether automatically close on clickaway when on click
10893  closable     : true,
10894
10895  // automatically hide on scroll
10896  hideOnScroll : 'auto',
10897
10898  // hide other popups on show
10899  exclusive    : false,
10900
10901  // context to attach popups
10902  context      : 'body',
10903
10904  // position to prefer when calculating new position
10905  prefer       : 'opposite',
10906
10907  // specify position to appear even if it doesn't fit
10908  lastResort   : false,
10909
10910  // delay used to prevent accidental refiring of animations due to user error
10911  delay        : {
10912    show : 50,
10913    hide : 70
10914  },
10915
10916  // whether fluid variation should assign width explicitly
10917  setFluidWidth  : true,
10918
10919  // transition settings
10920  duration       : 200,
10921  transition     : 'scale',
10922
10923  // distance away from activating element in px
10924  distanceAway   : 0,
10925
10926  // number of pixels an element is allowed to be "offstage" for a position to be chosen (allows for rounding)
10927  jitter         : 2,
10928
10929  // offset on aligning axis from calculated position
10930  offset         : 0,
10931
10932  // maximum times to look for a position before failing (9 positions total)
10933  maxSearchDepth : 15,
10934
10935  error: {
10936    invalidPosition : 'The position you specified is not a valid position',
10937    cannotPlace     : 'Popup does not fit within the boundaries of the viewport',
10938    method          : 'The method you called is not defined.',
10939    noTransition    : 'This module requires ui transitions <https://github.com/Semantic-Org/UI-Transition>',
10940    notFound        : 'The target or popup you specified does not exist on the page'
10941  },
10942
10943  metadata: {
10944    activator : 'activator',
10945    content   : 'content',
10946    html      : 'html',
10947    offset    : 'offset',
10948    position  : 'position',
10949    title     : 'title',
10950    variation : 'variation'
10951  },
10952
10953  className   : {
10954    active    : 'active',
10955    animating : 'animating',
10956    dropdown  : 'dropdown',
10957    fluid     : 'fluid',
10958    loading   : 'loading',
10959    popup     : 'ui popup',
10960    position  : 'top left center bottom right',
10961    visible   : 'visible'
10962  },
10963
10964  selector    : {
10965    popup    : '.ui.popup'
10966  },
10967
10968  templates: {
10969    escape: function(string) {
10970      var
10971        badChars     = /[&<>"'`]/g,
10972        shouldEscape = /[&<>"'`]/,
10973        escape       = {
10974          "&": "&amp;",
10975          "<": "&lt;",
10976          ">": "&gt;",
10977          '"': "&quot;",
10978          "'": "&#x27;",
10979          "`": "&#x60;"
10980        },
10981        escapedChar  = function(chr) {
10982          return escape[chr];
10983        }
10984      ;
10985      if(shouldEscape.test(string)) {
10986        return string.replace(badChars, escapedChar);
10987      }
10988      return string;
10989    },
10990    popup: function(text) {
10991      var
10992        html   = '',
10993        escape = $.fn.popup.settings.templates.escape
10994      ;
10995      if(typeof text !== undefined) {
10996        if(typeof text.title !== undefined && text.title) {
10997          text.title = escape(text.title);
10998          html += '<div class="header">' + text.title + '</div>';
10999        }
11000        if(typeof text.content !== undefined && text.content) {
11001          text.content = escape(text.content);
11002          html += '<div class="content">' + text.content + '</div>';
11003        }
11004      }
11005      return html;
11006    }
11007  }
11008
11009};
11010
11011
11012})( jQuery, window, document );
11013
11014/*!
11015 * # Semantic UI 2.1.7 - Progress
11016 * http://github.com/semantic-org/semantic-ui/
11017 *
11018 *
11019 * Copyright 2015 Contributors
11020 * Released under the MIT license
11021 * http://opensource.org/licenses/MIT
11022 *
11023 */
11024
11025;(function ( $, window, document, undefined ) {
11026
11027"use strict";
11028
11029$.fn.progress = function(parameters) {
11030  var
11031    $allModules    = $(this),
11032
11033    moduleSelector = $allModules.selector || '',
11034
11035    time           = new Date().getTime(),
11036    performance    = [],
11037
11038    query          = arguments[0],
11039    methodInvoked  = (typeof query == 'string'),
11040    queryArguments = [].slice.call(arguments, 1),
11041
11042    returnedValue
11043  ;
11044
11045  $allModules
11046    .each(function() {
11047      var
11048        settings          = ( $.isPlainObject(parameters) )
11049          ? $.extend(true, {}, $.fn.progress.settings, parameters)
11050          : $.extend({}, $.fn.progress.settings),
11051
11052        className       = settings.className,
11053        metadata        = settings.metadata,
11054        namespace       = settings.namespace,
11055        selector        = settings.selector,
11056        error           = settings.error,
11057
11058        eventNamespace  = '.' + namespace,
11059        moduleNamespace = 'module-' + namespace,
11060
11061        $module         = $(this),
11062        $bar            = $(this).find(selector.bar),
11063        $progress       = $(this).find(selector.progress),
11064        $label          = $(this).find(selector.label),
11065
11066        element         = this,
11067        instance        = $module.data(moduleNamespace),
11068
11069        animating = false,
11070        transitionEnd,
11071        module
11072      ;
11073
11074      module = {
11075
11076        initialize: function() {
11077          module.debug('Initializing progress bar', settings);
11078
11079          module.set.duration();
11080          module.set.transitionEvent();
11081
11082          module.read.metadata();
11083          module.read.settings();
11084
11085          module.instantiate();
11086        },
11087
11088        instantiate: function() {
11089          module.verbose('Storing instance of progress', module);
11090          instance = module;
11091          $module
11092            .data(moduleNamespace, module)
11093          ;
11094        },
11095        destroy: function() {
11096          module.verbose('Destroying previous progress for', $module);
11097          clearInterval(instance.interval);
11098          module.remove.state();
11099          $module.removeData(moduleNamespace);
11100          instance = undefined;
11101        },
11102
11103        reset: function() {
11104          module.set.percent(0);
11105          module.set.value(0);
11106        },
11107
11108        complete: function() {
11109          if(module.percent === undefined || module.percent < 100) {
11110            module.set.percent(100);
11111          }
11112        },
11113
11114        read: {
11115          metadata: function() {
11116            var
11117              data = {
11118                percent : $module.data(metadata.percent),
11119                total   : $module.data(metadata.total),
11120                value   : $module.data(metadata.value)
11121              }
11122            ;
11123            if(data.percent) {
11124              module.debug('Current percent value set from metadata', data.percent);
11125              module.set.percent(data.percent);
11126            }
11127            if(data.total) {
11128              module.debug('Total value set from metadata', data.total);
11129              module.set.total(data.total);
11130            }
11131            if(data.value) {
11132              module.debug('Current value set from metadata', data.value);
11133              module.set.value(data.value);
11134              module.set.progress(data.value);
11135            }
11136          },
11137          settings: function() {
11138            if(settings.total !== false) {
11139              module.debug('Current total set in settings', settings.total);
11140              module.set.total(settings.total);
11141            }
11142            if(settings.value !== false) {
11143              module.debug('Current value set in settings', settings.value);
11144              module.set.value(settings.value);
11145              module.set.progress(module.value);
11146            }
11147            if(settings.percent !== false) {
11148              module.debug('Current percent set in settings', settings.percent);
11149              module.set.percent(settings.percent);
11150            }
11151          }
11152        },
11153
11154        increment: function(incrementValue) {
11155          var
11156            maxValue,
11157            startValue,
11158            newValue
11159          ;
11160          if( module.has.total() ) {
11161            startValue     = module.get.value();
11162            incrementValue = incrementValue || 1;
11163
11164            newValue       = startValue + incrementValue;
11165            maxValue       = module.get.total();
11166
11167            module.debug('Incrementing value', startValue, newValue, maxValue);
11168            if(newValue > maxValue ) {
11169              module.debug('Value cannot increment above total', maxValue);
11170              newValue = maxValue;
11171            }
11172          }
11173          else {
11174            startValue     = module.get.percent();
11175            incrementValue = incrementValue || module.get.randomValue();
11176
11177            newValue       = startValue + incrementValue;
11178            maxValue       = 100;
11179
11180            module.debug('Incrementing percentage by', startValue, newValue);
11181            if(newValue > maxValue ) {
11182              module.debug('Value cannot increment above 100 percent');
11183              newValue = maxValue;
11184            }
11185          }
11186          module.set.progress(newValue);
11187        },
11188        decrement: function(decrementValue) {
11189          var
11190            total     = module.get.total(),
11191            startValue,
11192            newValue
11193          ;
11194          if(total) {
11195            startValue     =  module.get.value();
11196            decrementValue =  decrementValue || 1;
11197            newValue       =  startValue - decrementValue;
11198            module.debug('Decrementing value by', decrementValue, startValue);
11199          }
11200          else {
11201            startValue     =  module.get.percent();
11202            decrementValue =  decrementValue || module.get.randomValue();
11203            newValue       =  startValue - decrementValue;
11204            module.debug('Decrementing percentage by', decrementValue, startValue);
11205          }
11206
11207          if(newValue < 0) {
11208            module.debug('Value cannot decrement below 0');
11209            newValue = 0;
11210          }
11211          module.set.progress(newValue);
11212        },
11213
11214        has: {
11215          total: function() {
11216            return (module.get.total() !== false);
11217          }
11218        },
11219
11220        get: {
11221          text: function(templateText) {
11222            var
11223              value   = module.value                || 0,
11224              total   = module.total                || 0,
11225              percent = (animating)
11226                ? module.get.displayPercent()
11227                : module.percent || 0,
11228              left = (module.total > 0)
11229                ? (total - value)
11230                : (100 - percent)
11231            ;
11232            templateText = templateText || '';
11233            templateText = templateText
11234              .replace('{value}', value)
11235              .replace('{total}', total)
11236              .replace('{left}', left)
11237              .replace('{percent}', percent)
11238            ;
11239            module.debug('Adding variables to progress bar text', templateText);
11240            return templateText;
11241          },
11242
11243
11244          randomValue: function() {
11245            module.debug('Generating random increment percentage');
11246            return Math.floor((Math.random() * settings.random.max) + settings.random.min);
11247          },
11248
11249          numericValue: function(value) {
11250            return (typeof value === 'string')
11251              ? (value.replace(/[^\d.]/g, '') !== '')
11252                ? +(value.replace(/[^\d.]/g, ''))
11253                : false
11254              : value
11255            ;
11256          },
11257
11258          transitionEnd: function() {
11259            var
11260              element     = document.createElement('element'),
11261              transitions = {
11262                'transition'       :'transitionend',
11263                'OTransition'      :'oTransitionEnd',
11264                'MozTransition'    :'transitionend',
11265                'WebkitTransition' :'webkitTransitionEnd'
11266              },
11267              transition
11268            ;
11269            for(transition in transitions){
11270              if( element.style[transition] !== undefined ){
11271                return transitions[transition];
11272              }
11273            }
11274          },
11275
11276          // gets current displayed percentage (if animating values this is the intermediary value)
11277          displayPercent: function() {
11278            var
11279              barWidth       = $bar.width(),
11280              totalWidth     = $module.width(),
11281              minDisplay     = parseInt($bar.css('min-width'), 10),
11282              displayPercent = (barWidth > minDisplay)
11283                ? (barWidth / totalWidth * 100)
11284                : module.percent
11285            ;
11286            return (settings.precision > 0)
11287              ? Math.round(displayPercent * (10 * settings.precision)) / (10 * settings.precision)
11288              : Math.round(displayPercent)
11289            ;
11290          },
11291
11292          percent: function() {
11293            return module.percent || 0;
11294          },
11295          value: function() {
11296            return module.value || 0;
11297          },
11298          total: function() {
11299            return module.total || false;
11300          }
11301        },
11302
11303        is: {
11304          success: function() {
11305            return $module.hasClass(className.success);
11306          },
11307          warning: function() {
11308            return $module.hasClass(className.warning);
11309          },
11310          error: function() {
11311            return $module.hasClass(className.error);
11312          },
11313          active: function() {
11314            return $module.hasClass(className.active);
11315          },
11316          visible: function() {
11317            return $module.is(':visible');
11318          }
11319        },
11320
11321        remove: {
11322          state: function() {
11323            module.verbose('Removing stored state');
11324            delete module.total;
11325            delete module.percent;
11326            delete module.value;
11327          },
11328          active: function() {
11329            module.verbose('Removing active state');
11330            $module.removeClass(className.active);
11331          },
11332          success: function() {
11333            module.verbose('Removing success state');
11334            $module.removeClass(className.success);
11335          },
11336          warning: function() {
11337            module.verbose('Removing warning state');
11338            $module.removeClass(className.warning);
11339          },
11340          error: function() {
11341            module.verbose('Removing error state');
11342            $module.removeClass(className.error);
11343          }
11344        },
11345
11346        set: {
11347          barWidth: function(value) {
11348            if(value > 100) {
11349              module.error(error.tooHigh, value);
11350            }
11351            else if (value < 0) {
11352              module.error(error.tooLow, value);
11353            }
11354            else {
11355              $bar
11356                .css('width', value + '%')
11357              ;
11358              $module
11359                .attr('data-percent', parseInt(value, 10))
11360              ;
11361            }
11362          },
11363          duration: function(duration) {
11364            duration = duration || settings.duration;
11365            duration = (typeof duration == 'number')
11366              ? duration + 'ms'
11367              : duration
11368            ;
11369            module.verbose('Setting progress bar transition duration', duration);
11370            $bar
11371              .css({
11372                'transition-duration':  duration
11373              })
11374            ;
11375          },
11376          percent: function(percent) {
11377            percent = (typeof percent == 'string')
11378              ? +(percent.replace('%', ''))
11379              : percent
11380            ;
11381            // round display percentage
11382            percent = (settings.precision > 0)
11383              ? Math.round(percent * (10 * settings.precision)) / (10 * settings.precision)
11384              : Math.round(percent)
11385            ;
11386            module.percent = percent;
11387            if( !module.has.total() ) {
11388              module.value = (settings.precision > 0)
11389                ? Math.round( (percent / 100) * module.total * (10 * settings.precision)) / (10 * settings.precision)
11390                : Math.round( (percent / 100) * module.total * 10) / 10
11391              ;
11392              if(settings.limitValues) {
11393                module.value = (module.value > 100)
11394                  ? 100
11395                  : (module.value < 0)
11396                    ? 0
11397                    : module.value
11398                ;
11399              }
11400            }
11401            module.set.barWidth(percent);
11402            module.set.labelInterval();
11403            module.set.labels();
11404            settings.onChange.call(element, percent, module.value, module.total);
11405          },
11406          labelInterval: function() {
11407            var
11408              animationCallback = function() {
11409                module.verbose('Bar finished animating, removing continuous label updates');
11410                clearInterval(module.interval);
11411                animating = false;
11412                module.set.labels();
11413              }
11414            ;
11415            clearInterval(module.interval);
11416            $bar.one(transitionEnd + eventNamespace, animationCallback);
11417            module.timer = setTimeout(animationCallback, settings.duration + 100);
11418            animating = true;
11419            module.interval = setInterval(module.set.labels, settings.framerate);
11420          },
11421          labels: function() {
11422            module.verbose('Setting both bar progress and outer label text');
11423            module.set.barLabel();
11424            module.set.state();
11425          },
11426          label: function(text) {
11427            text = text || '';
11428            if(text) {
11429              text = module.get.text(text);
11430              module.debug('Setting label to text', text);
11431              $label.text(text);
11432            }
11433          },
11434          state: function(percent) {
11435            percent = (percent !== undefined)
11436              ? percent
11437              : module.percent
11438            ;
11439            if(percent === 100) {
11440              if(settings.autoSuccess && !(module.is.warning() || module.is.error())) {
11441                module.set.success();
11442                module.debug('Automatically triggering success at 100%');
11443              }
11444              else {
11445                module.verbose('Reached 100% removing active state');
11446                module.remove.active();
11447              }
11448            }
11449            else if(percent > 0) {
11450              module.verbose('Adjusting active progress bar label', percent);
11451              module.set.active();
11452            }
11453            else {
11454              module.remove.active();
11455              module.set.label(settings.text.active);
11456            }
11457          },
11458          barLabel: function(text) {
11459            if(text !== undefined) {
11460              $progress.text( module.get.text(text) );
11461            }
11462            else if(settings.label == 'ratio' && module.total) {
11463              module.debug('Adding ratio to bar label');
11464              $progress.text( module.get.text(settings.text.ratio) );
11465            }
11466            else if(settings.label == 'percent') {
11467              module.debug('Adding percentage to bar label');
11468              $progress.text( module.get.text(settings.text.percent) );
11469            }
11470          },
11471          active: function(text) {
11472            text = text || settings.text.active;
11473            module.debug('Setting active state');
11474            if(settings.showActivity && !module.is.active() ) {
11475              $module.addClass(className.active);
11476            }
11477            module.remove.warning();
11478            module.remove.error();
11479            module.remove.success();
11480            if(text) {
11481              module.set.label(text);
11482            }
11483            settings.onActive.call(element, module.value, module.total);
11484          },
11485          success : function(text) {
11486            text = text || settings.text.success;
11487            module.debug('Setting success state');
11488            $module.addClass(className.success);
11489            module.remove.active();
11490            module.remove.warning();
11491            module.remove.error();
11492            module.complete();
11493            if(text) {
11494              module.set.label(text);
11495            }
11496            settings.onSuccess.call(element, module.total);
11497          },
11498          warning : function(text) {
11499            text = text || settings.text.warning;
11500            module.debug('Setting warning state');
11501            $module.addClass(className.warning);
11502            module.remove.active();
11503            module.remove.success();
11504            module.remove.error();
11505            module.complete();
11506            if(text) {
11507              module.set.label(text);
11508            }
11509            settings.onWarning.call(element, module.value, module.total);
11510          },
11511          error : function(text) {
11512            text = text || settings.text.error;
11513            module.debug('Setting error state');
11514            $module.addClass(className.error);
11515            module.remove.active();
11516            module.remove.success();
11517            module.remove.warning();
11518            module.complete();
11519            if(text) {
11520              module.set.label(text);
11521            }
11522            settings.onError.call(element, module.value, module.total);
11523          },
11524          transitionEvent: function() {
11525            transitionEnd = module.get.transitionEnd();
11526          },
11527          total: function(totalValue) {
11528            module.total = totalValue;
11529          },
11530          value: function(value) {
11531            module.value = value;
11532          },
11533          progress: function(value) {
11534            var
11535              numericValue = module.get.numericValue(value),
11536              percentComplete
11537            ;
11538            if(numericValue === false) {
11539              module.error(error.nonNumeric, value);
11540            }
11541            if( module.has.total() ) {
11542              module.set.value(numericValue);
11543              percentComplete = (numericValue / module.total) * 100;
11544              module.debug('Calculating percent complete from total', percentComplete);
11545              module.set.percent( percentComplete );
11546            }
11547            else {
11548              percentComplete = numericValue;
11549              module.debug('Setting value to exact percentage value', percentComplete);
11550              module.set.percent( percentComplete );
11551            }
11552          }
11553        },
11554
11555        setting: function(name, value) {
11556          module.debug('Changing setting', name, value);
11557          if( $.isPlainObject(name) ) {
11558            $.extend(true, settings, name);
11559          }
11560          else if(value !== undefined) {
11561            settings[name] = value;
11562          }
11563          else {
11564            return settings[name];
11565          }
11566        },
11567        internal: function(name, value) {
11568          if( $.isPlainObject(name) ) {
11569            $.extend(true, module, name);
11570          }
11571          else if(value !== undefined) {
11572            module[name] = value;
11573          }
11574          else {
11575            return module[name];
11576          }
11577        },
11578        debug: function() {
11579          if(settings.debug) {
11580            if(settings.performance) {
11581              module.performance.log(arguments);
11582            }
11583            else {
11584              module.debug = Function.prototype.bind.call(console.info, console, settings.name + ':');
11585              module.debug.apply(console, arguments);
11586            }
11587          }
11588        },
11589        verbose: function() {
11590          if(settings.verbose && settings.debug) {
11591            if(settings.performance) {
11592              module.performance.log(arguments);
11593            }
11594            else {
11595              module.verbose = Function.prototype.bind.call(console.info, console, settings.name + ':');
11596              module.verbose.apply(console, arguments);
11597            }
11598          }
11599        },
11600        error: function() {
11601          module.error = Function.prototype.bind.call(console.error, console, settings.name + ':');
11602          module.error.apply(console, arguments);
11603        },
11604        performance: {
11605          log: function(message) {
11606            var
11607              currentTime,
11608              executionTime,
11609              previousTime
11610            ;
11611            if(settings.performance) {
11612              currentTime   = new Date().getTime();
11613              previousTime  = time || currentTime;
11614              executionTime = currentTime - previousTime;
11615              time          = currentTime;
11616              performance.push({
11617                'Name'           : message[0],
11618                'Arguments'      : [].slice.call(message, 1) || '',
11619                'Element'        : element,
11620                'Execution Time' : executionTime
11621              });
11622            }
11623            clearTimeout(module.performance.timer);
11624            module.performance.timer = setTimeout(module.performance.display, 500);
11625          },
11626          display: function() {
11627            var
11628              title = settings.name + ':',
11629              totalTime = 0
11630            ;
11631            time = false;
11632            clearTimeout(module.performance.timer);
11633            $.each(performance, function(index, data) {
11634              totalTime += data['Execution Time'];
11635            });
11636            title += ' ' + totalTime + 'ms';
11637            if(moduleSelector) {
11638              title += ' \'' + moduleSelector + '\'';
11639            }
11640            if( (console.group !== undefined || console.table !== undefined) && performance.length > 0) {
11641              console.groupCollapsed(title);
11642              if(console.table) {
11643                console.table(performance);
11644              }
11645              else {
11646                $.each(performance, function(index, data) {
11647                  console.log(data['Name'] + ': ' + data['Execution Time']+'ms');
11648                });
11649              }
11650              console.groupEnd();
11651            }
11652            performance = [];
11653          }
11654        },
11655        invoke: function(query, passedArguments, context) {
11656          var
11657            object = instance,
11658            maxDepth,
11659            found,
11660            response
11661          ;
11662          passedArguments = passedArguments || queryArguments;
11663          context         = element         || context;
11664          if(typeof query == 'string' && object !== undefined) {
11665            query    = query.split(/[\. ]/);
11666            maxDepth = query.length - 1;
11667            $.each(query, function(depth, value) {
11668              var camelCaseValue = (depth != maxDepth)
11669                ? value + query[depth + 1].charAt(0).toUpperCase() + query[depth + 1].slice(1)
11670                : query
11671              ;
11672              if( $.isPlainObject( object[camelCaseValue] ) && (depth != maxDepth) ) {
11673                object = object[camelCaseValue];
11674              }
11675              else if( object[camelCaseValue] !== undefined ) {
11676                found = object[camelCaseValue];
11677                return false;
11678              }
11679              else if( $.isPlainObject( object[value] ) && (depth != maxDepth) ) {
11680                object = object[value];
11681              }
11682              else if( object[value] !== undefined ) {
11683                found = object[value];
11684                return false;
11685              }
11686              else {
11687                module.error(error.method, query);
11688                return false;
11689              }
11690            });
11691          }
11692          if ( $.isFunction( found ) ) {
11693            response = found.apply(context, passedArguments);
11694          }
11695          else if(found !== undefined) {
11696            response = found;
11697          }
11698          if($.isArray(returnedValue)) {
11699            returnedValue.push(response);
11700          }
11701          else if(returnedValue !== undefined) {
11702            returnedValue = [returnedValue, response];
11703          }
11704          else if(response !== undefined) {
11705            returnedValue = response;
11706          }
11707          return found;
11708        }
11709      };
11710
11711      if(methodInvoked) {
11712        if(instance === undefined) {
11713          module.initialize();
11714        }
11715        module.invoke(query);
11716      }
11717      else {
11718        if(instance !== undefined) {
11719          instance.invoke('destroy');
11720        }
11721        module.initialize();
11722      }
11723    })
11724  ;
11725
11726  return (returnedValue !== undefined)
11727    ? returnedValue
11728    : this
11729  ;
11730};
11731
11732$.fn.progress.settings = {
11733
11734  name         : 'Progress',
11735  namespace    : 'progress',
11736
11737  debug        : false,
11738  verbose      : false,
11739  performance  : true,
11740
11741  random       : {
11742    min : 2,
11743    max : 5
11744  },
11745
11746  duration     : 300,
11747
11748  autoSuccess  : true,
11749  showActivity : true,
11750  limitValues  : true,
11751
11752  label        : 'percent',
11753  precision    : 0,
11754  framerate    : (1000 / 30), /// 30 fps
11755
11756  percent      : false,
11757  total        : false,
11758  value        : false,
11759
11760  onChange     : function(percent, value, total){},
11761  onSuccess    : function(total){},
11762  onActive     : function(value, total){},
11763  onError      : function(value, total){},
11764  onWarning    : function(value, total){},
11765
11766  error    : {
11767    method     : 'The method you called is not defined.',
11768    nonNumeric : 'Progress value is non numeric',
11769    tooHigh    : 'Value specified is above 100%',
11770    tooLow     : 'Value specified is below 0%'
11771  },
11772
11773  regExp: {
11774    variable: /\{\$*[A-z0-9]+\}/g
11775  },
11776
11777  metadata: {
11778    percent : 'percent',
11779    total   : 'total',
11780    value   : 'value'
11781  },
11782
11783  selector : {
11784    bar      : '> .bar',
11785    label    : '> .label',
11786    progress : '.bar > .progress'
11787  },
11788
11789  text : {
11790    active  : false,
11791    error   : false,
11792    success : false,
11793    warning : false,
11794    percent : '{percent}%',
11795    ratio   : '{value} of {total}'
11796  },
11797
11798  className : {
11799    active  : 'active',
11800    error   : 'error',
11801    success : 'success',
11802    warning : 'warning'
11803  }
11804
11805};
11806
11807
11808})( jQuery, window, document );
11809/*!
11810 * # Semantic UI 2.1.7 - Rating
11811 * http://github.com/semantic-org/semantic-ui/
11812 *
11813 *
11814 * Copyright 2015 Contributors
11815 * Released under the MIT license
11816 * http://opensource.org/licenses/MIT
11817 *
11818 */
11819
11820;(function ($, window, document, undefined) {
11821
11822"use strict";
11823
11824$.fn.rating = function(parameters) {
11825  var
11826    $allModules     = $(this),
11827    moduleSelector  = $allModules.selector || '',
11828
11829    time            = new Date().getTime(),
11830    performance     = [],
11831
11832    query           = arguments[0],
11833    methodInvoked   = (typeof query == 'string'),
11834    queryArguments  = [].slice.call(arguments, 1),
11835    returnedValue
11836  ;
11837  $allModules
11838    .each(function() {
11839      var
11840        settings        = ( $.isPlainObject(parameters) )
11841          ? $.extend(true, {}, $.fn.rating.settings, parameters)
11842          : $.extend({}, $.fn.rating.settings),
11843
11844        namespace       = settings.namespace,
11845        className       = settings.className,
11846        metadata        = settings.metadata,
11847        selector        = settings.selector,
11848        error           = settings.error,
11849
11850        eventNamespace  = '.' + namespace,
11851        moduleNamespace = 'module-' + namespace,
11852
11853        element         = this,
11854        instance        = $(this).data(moduleNamespace),
11855
11856        $module         = $(this),
11857        $icon           = $module.find(selector.icon),
11858
11859        module
11860      ;
11861
11862      module = {
11863
11864        initialize: function() {
11865          module.verbose('Initializing rating module', settings);
11866
11867          if($icon.length === 0) {
11868            module.setup.layout();
11869          }
11870
11871          if(settings.interactive) {
11872            module.enable();
11873          }
11874          else {
11875            module.disable();
11876          }
11877          module.set.rating( module.get.initialRating() );
11878          module.instantiate();
11879        },
11880
11881        instantiate: function() {
11882          module.verbose('Instantiating module', settings);
11883          instance = module;
11884          $module
11885            .data(moduleNamespace, module)
11886          ;
11887        },
11888
11889        destroy: function() {
11890          module.verbose('Destroying previous instance', instance);
11891          module.remove.events();
11892          $module
11893            .removeData(moduleNamespace)
11894          ;
11895        },
11896
11897        refresh: function() {
11898          $icon   = $module.find(selector.icon);
11899        },
11900
11901        setup: {
11902          layout: function() {
11903            var
11904              maxRating = module.get.maxRating(),
11905              html      = $.fn.rating.settings.templates.icon(maxRating)
11906            ;
11907            module.debug('Generating icon html dynamically');
11908            $module
11909              .html(html)
11910            ;
11911            module.refresh();
11912          }
11913        },
11914
11915        event: {
11916          mouseenter: function() {
11917            var
11918              $activeIcon = $(this)
11919            ;
11920            $activeIcon
11921              .nextAll()
11922                .removeClass(className.selected)
11923            ;
11924            $module
11925              .addClass(className.selected)
11926            ;
11927            $activeIcon
11928              .addClass(className.selected)
11929                .prevAll()
11930                .addClass(className.selected)
11931            ;
11932          },
11933          mouseleave: function() {
11934            $module
11935              .removeClass(className.selected)
11936            ;
11937            $icon
11938              .removeClass(className.selected)
11939            ;
11940          },
11941          click: function() {
11942            var
11943              $activeIcon   = $(this),
11944              currentRating = module.get.rating(),
11945              rating        = $icon.index($activeIcon) + 1,
11946              canClear      = (settings.clearable == 'auto')
11947               ? ($icon.length === 1)
11948               : settings.clearable
11949            ;
11950            if(canClear && currentRating == rating) {
11951              module.clearRating();
11952            }
11953            else {
11954              module.set.rating( rating );
11955            }
11956          }
11957        },
11958
11959        clearRating: function() {
11960          module.debug('Clearing current rating');
11961          module.set.rating(0);
11962        },
11963
11964        bind: {
11965          events: function() {
11966            module.verbose('Binding events');
11967            $module
11968              .on('mouseenter' + eventNamespace, selector.icon, module.event.mouseenter)
11969              .on('mouseleave' + eventNamespace, selector.icon, module.event.mouseleave)
11970              .on('click'      + eventNamespace, selector.icon, module.event.click)
11971            ;
11972          }
11973        },
11974
11975        remove: {
11976          events: function() {
11977            module.verbose('Removing events');
11978            $module
11979              .off(eventNamespace)
11980            ;
11981          }
11982        },
11983
11984        enable: function() {
11985          module.debug('Setting rating to interactive mode');
11986          module.bind.events();
11987          $module
11988            .removeClass(className.disabled)
11989          ;
11990        },
11991
11992        disable: function() {
11993          module.debug('Setting rating to read-only mode');
11994          module.remove.events();
11995          $module
11996            .addClass(className.disabled)
11997          ;
11998        },
11999
12000        get: {
12001          initialRating: function() {
12002            if($module.data(metadata.rating) !== undefined) {
12003              $module.removeData(metadata.rating);
12004              return $module.data(metadata.rating);
12005            }
12006            return settings.initialRating;
12007          },
12008          maxRating: function() {
12009            if($module.data(metadata.maxRating) !== undefined) {
12010              $module.removeData(metadata.maxRating);
12011              return $module.data(metadata.maxRating);
12012            }
12013            return settings.maxRating;
12014          },
12015          rating: function() {
12016            var
12017              currentRating = $icon.filter('.' + className.active).length
12018            ;
12019            module.verbose('Current rating retrieved', currentRating);
12020            return currentRating;
12021          }
12022        },
12023
12024        set: {
12025          rating: function(rating) {
12026            var
12027              ratingIndex = (rating - 1 >= 0)
12028                ? (rating - 1)
12029                : 0,
12030              $activeIcon = $icon.eq(ratingIndex)
12031            ;
12032            $module
12033              .removeClass(className.selected)
12034            ;
12035            $icon
12036              .removeClass(className.selected)
12037              .removeClass(className.active)
12038            ;
12039            if(rating > 0) {
12040              module.verbose('Setting current rating to', rating);
12041              $activeIcon
12042                .prevAll()
12043                .andSelf()
12044                  .addClass(className.active)
12045              ;
12046            }
12047            settings.onRate.call(element, rating);
12048          }
12049        },
12050
12051        setting: function(name, value) {
12052          module.debug('Changing setting', name, value);
12053          if( $.isPlainObject(name) ) {
12054            $.extend(true, settings, name);
12055          }
12056          else if(value !== undefined) {
12057            settings[name] = value;
12058          }
12059          else {
12060            return settings[name];
12061          }
12062        },
12063        internal: function(name, value) {
12064          if( $.isPlainObject(name) ) {
12065            $.extend(true, module, name);
12066          }
12067          else if(value !== undefined) {
12068            module[name] = value;
12069          }
12070          else {
12071            return module[name];
12072          }
12073        },
12074        debug: function() {
12075          if(settings.debug) {
12076            if(settings.performance) {
12077              module.performance.log(arguments);
12078            }
12079            else {
12080              module.debug = Function.prototype.bind.call(console.info, console, settings.name + ':');
12081              module.debug.apply(console, arguments);
12082            }
12083          }
12084        },
12085        verbose: function() {
12086          if(settings.verbose && settings.debug) {
12087            if(settings.performance) {
12088              module.performance.log(arguments);
12089            }
12090            else {
12091              module.verbose = Function.prototype.bind.call(console.info, console, settings.name + ':');
12092              module.verbose.apply(console, arguments);
12093            }
12094          }
12095        },
12096        error: function() {
12097          module.error = Function.prototype.bind.call(console.error, console, settings.name + ':');
12098          module.error.apply(console, arguments);
12099        },
12100        performance: {
12101          log: function(message) {
12102            var
12103              currentTime,
12104              executionTime,
12105              previousTime
12106            ;
12107            if(settings.performance) {
12108              currentTime   = new Date().getTime();
12109              previousTime  = time || currentTime;
12110              executionTime = currentTime - previousTime;
12111              time          = currentTime;
12112              performance.push({
12113                'Name'           : message[0],
12114                'Arguments'      : [].slice.call(message, 1) || '',
12115                'Element'        : element,
12116                'Execution Time' : executionTime
12117              });
12118            }
12119            clearTimeout(module.performance.timer);
12120            module.performance.timer = setTimeout(module.performance.display, 500);
12121          },
12122          display: function() {
12123            var
12124              title = settings.name + ':',
12125              totalTime = 0
12126            ;
12127            time = false;
12128            clearTimeout(module.performance.timer);
12129            $.each(performance, function(index, data) {
12130              totalTime += data['Execution Time'];
12131            });
12132            title += ' ' + totalTime + 'ms';
12133            if(moduleSelector) {
12134              title += ' \'' + moduleSelector + '\'';
12135            }
12136            if($allModules.length > 1) {
12137              title += ' ' + '(' + $allModules.length + ')';
12138            }
12139            if( (console.group !== undefined || console.table !== undefined) && performance.length > 0) {
12140              console.groupCollapsed(title);
12141              if(console.table) {
12142                console.table(performance);
12143              }
12144              else {
12145                $.each(performance, function(index, data) {
12146                  console.log(data['Name'] + ': ' + data['Execution Time']+'ms');
12147                });
12148              }
12149              console.groupEnd();
12150            }
12151            performance = [];
12152          }
12153        },
12154        invoke: function(query, passedArguments, context) {
12155          var
12156            object = instance,
12157            maxDepth,
12158            found,
12159            response
12160          ;
12161          passedArguments = passedArguments || queryArguments;
12162          context         = element         || context;
12163          if(typeof query == 'string' && object !== undefined) {
12164            query    = query.split(/[\. ]/);
12165            maxDepth = query.length - 1;
12166            $.each(query, function(depth, value) {
12167              var camelCaseValue = (depth != maxDepth)
12168                ? value + query[depth + 1].charAt(0).toUpperCase() + query[depth + 1].slice(1)
12169                : query
12170              ;
12171              if( $.isPlainObject( object[camelCaseValue] ) && (depth != maxDepth) ) {
12172                object = object[camelCaseValue];
12173              }
12174              else if( object[camelCaseValue] !== undefined ) {
12175                found = object[camelCaseValue];
12176                return false;
12177              }
12178              else if( $.isPlainObject( object[value] ) && (depth != maxDepth) ) {
12179                object = object[value];
12180              }
12181              else if( object[value] !== undefined ) {
12182                found = object[value];
12183                return false;
12184              }
12185              else {
12186                return false;
12187              }
12188            });
12189          }
12190          if ( $.isFunction( found ) ) {
12191            response = found.apply(context, passedArguments);
12192          }
12193          else if(found !== undefined) {
12194            response = found;
12195          }
12196          if($.isArray(returnedValue)) {
12197            returnedValue.push(response);
12198          }
12199          else if(returnedValue !== undefined) {
12200            returnedValue = [returnedValue, response];
12201          }
12202          else if(response !== undefined) {
12203            returnedValue = response;
12204          }
12205          return found;
12206        }
12207      };
12208      if(methodInvoked) {
12209        if(instance === undefined) {
12210          module.initialize();
12211        }
12212        module.invoke(query);
12213      }
12214      else {
12215        if(instance !== undefined) {
12216          instance.invoke('destroy');
12217        }
12218        module.initialize();
12219      }
12220    })
12221  ;
12222
12223  return (returnedValue !== undefined)
12224    ? returnedValue
12225    : this
12226  ;
12227};
12228
12229$.fn.rating.settings = {
12230
12231  name          : 'Rating',
12232  namespace     : 'rating',
12233
12234  debug         : false,
12235  verbose       : false,
12236  performance   : true,
12237
12238  initialRating : 0,
12239  interactive   : true,
12240  maxRating     : 4,
12241  clearable     : 'auto',
12242
12243  onRate        : function(rating){},
12244
12245  error         : {
12246    method    : 'The method you called is not defined',
12247    noMaximum : 'No maximum rating specified. Cannot generate HTML automatically'
12248  },
12249
12250
12251  metadata: {
12252    rating    : 'rating',
12253    maxRating : 'maxRating'
12254  },
12255
12256  className : {
12257    active   : 'active',
12258    disabled : 'disabled',
12259    selected : 'selected',
12260    loading  : 'loading'
12261  },
12262
12263  selector  : {
12264    icon : '.icon'
12265  },
12266
12267  templates: {
12268    icon: function(maxRating) {
12269      var
12270        icon = 1,
12271        html = ''
12272      ;
12273      while(icon <= maxRating) {
12274        html += '<i class="icon"></i>';
12275        icon++;
12276      }
12277      return html;
12278    }
12279  }
12280
12281};
12282
12283})( jQuery, window, document );
12284
12285/*!
12286 * # Semantic UI 2.1.7 - Search
12287 * http://github.com/semantic-org/semantic-ui/
12288 *
12289 *
12290 * Copyright 2015 Contributors
12291 * Released under the MIT license
12292 * http://opensource.org/licenses/MIT
12293 *
12294 */
12295
12296;(function ($, window, document, undefined) {
12297
12298"use strict";
12299
12300$.fn.search = function(parameters) {
12301  var
12302    $allModules     = $(this),
12303    moduleSelector  = $allModules.selector || '',
12304
12305    time            = new Date().getTime(),
12306    performance     = [],
12307
12308    query           = arguments[0],
12309    methodInvoked   = (typeof query == 'string'),
12310    queryArguments  = [].slice.call(arguments, 1),
12311    returnedValue
12312  ;
12313  $(this)
12314    .each(function() {
12315      var
12316        settings          = ( $.isPlainObject(parameters) )
12317          ? $.extend(true, {}, $.fn.search.settings, parameters)
12318          : $.extend({}, $.fn.search.settings),
12319
12320        className       = settings.className,
12321        metadata        = settings.metadata,
12322        regExp          = settings.regExp,
12323        fields          = settings.fields,
12324        selector        = settings.selector,
12325        error           = settings.error,
12326        namespace       = settings.namespace,
12327
12328        eventNamespace  = '.' + namespace,
12329        moduleNamespace = namespace + '-module',
12330
12331        $module         = $(this),
12332        $prompt         = $module.find(selector.prompt),
12333        $searchButton   = $module.find(selector.searchButton),
12334        $results        = $module.find(selector.results),
12335        $result         = $module.find(selector.result),
12336        $category       = $module.find(selector.category),
12337
12338        element         = this,
12339        instance        = $module.data(moduleNamespace),
12340
12341        module
12342      ;
12343
12344      module = {
12345
12346        initialize: function() {
12347          module.verbose('Initializing module');
12348          module.determine.searchFields();
12349          module.bind.events();
12350          module.set.type();
12351          module.create.results();
12352          module.instantiate();
12353        },
12354        instantiate: function() {
12355          module.verbose('Storing instance of module', module);
12356          instance = module;
12357          $module
12358            .data(moduleNamespace, module)
12359          ;
12360        },
12361        destroy: function() {
12362          module.verbose('Destroying instance');
12363          $module
12364            .off(eventNamespace)
12365            .removeData(moduleNamespace)
12366          ;
12367        },
12368
12369        bind: {
12370          events: function() {
12371            module.verbose('Binding events to search');
12372            if(settings.automatic) {
12373              $module
12374                .on(module.get.inputEvent() + eventNamespace, selector.prompt, module.event.input)
12375              ;
12376              $prompt
12377                .attr('autocomplete', 'off')
12378              ;
12379            }
12380            $module
12381              // prompt
12382              .on('focus'     + eventNamespace, selector.prompt, module.event.focus)
12383              .on('blur'      + eventNamespace, selector.prompt, module.event.blur)
12384              .on('keydown'   + eventNamespace, selector.prompt, module.handleKeyboard)
12385              // search button
12386              .on('click'     + eventNamespace, selector.searchButton, module.query)
12387              // results
12388              .on('mousedown' + eventNamespace, selector.results, module.event.result.mousedown)
12389              .on('mouseup'   + eventNamespace, selector.results, module.event.result.mouseup)
12390              .on('click'     + eventNamespace, selector.result,  module.event.result.click)
12391            ;
12392          }
12393        },
12394
12395        determine: {
12396          searchFields: function() {
12397            // this makes sure $.extend does not add specified search fields to default fields
12398            // this is the only setting which should not extend defaults
12399            if(parameters && parameters.searchFields !== undefined) {
12400              settings.searchFields = parameters.searchFields;
12401            }
12402          }
12403        },
12404
12405        event: {
12406          input: function() {
12407            clearTimeout(module.timer);
12408            module.timer = setTimeout(module.query, settings.searchDelay);
12409          },
12410          focus: function() {
12411            module.set.focus();
12412            if( module.has.minimumCharacters() ) {
12413              module.query();
12414              if( module.can.show() ) {
12415                module.showResults();
12416              }
12417            }
12418          },
12419          blur: function(event) {
12420            var
12421              pageLostFocus = (document.activeElement === this),
12422              callback      = function() {
12423                module.cancel.query();
12424                module.remove.focus();
12425                module.timer = setTimeout(module.hideResults, settings.hideDelay);
12426              }
12427            ;
12428            if(pageLostFocus) {
12429              return;
12430            }
12431            if(module.resultsClicked) {
12432              module.debug('Determining if user action caused search to close');
12433              $module
12434                .one('click', selector.results, function(event) {
12435                  if( !module.is.animating() && !module.is.hidden() ) {
12436                    callback();
12437                  }
12438                })
12439              ;
12440            }
12441            else {
12442              module.debug('Input blurred without user action, closing results');
12443              callback();
12444            }
12445          },
12446          result: {
12447            mousedown: function() {
12448              module.resultsClicked = true;
12449            },
12450            mouseup: function() {
12451              module.resultsClicked = false;
12452            },
12453            click: function(event) {
12454              module.debug('Search result selected');
12455              var
12456                $result = $(this),
12457                $title  = $result.find(selector.title).eq(0),
12458                $link   = $result.find('a[href]').eq(0),
12459                href    = $link.attr('href')   || false,
12460                target  = $link.attr('target') || false,
12461                title   = $title.html(),
12462                // title is used for result lookup
12463                value   = ($title.length > 0)
12464                  ? $title.text()
12465                  : false,
12466                results = module.get.results(),
12467                result  = $result.data(metadata.result) || module.get.result(value, results),
12468                returnedValue
12469              ;
12470              if( $.isFunction(settings.onSelect) ) {
12471                if(settings.onSelect.call(element, result, results) === false) {
12472                  module.debug('Custom onSelect callback cancelled default select action');
12473                  return;
12474                }
12475              }
12476              module.hideResults();
12477              if(value) {
12478                module.set.value(value);
12479              }
12480              if(href) {
12481                module.verbose('Opening search link found in result', $link);
12482                if(target == '_blank' || event.ctrlKey) {
12483                  window.open(href);
12484                }
12485                else {
12486                  window.location.href = (href);
12487                }
12488              }
12489            }
12490          }
12491        },
12492        handleKeyboard: function(event) {
12493          var
12494            // force selector refresh
12495            $result      = $module.find(selector.result),
12496            $category    = $module.find(selector.category),
12497            currentIndex = $result.index( $result.filter('.' + className.active) ),
12498            resultSize   = $result.length,
12499
12500            keyCode      = event.which,
12501            keys         = {
12502              backspace : 8,
12503              enter     : 13,
12504              escape    : 27,
12505              upArrow   : 38,
12506              downArrow : 40
12507            },
12508            newIndex
12509          ;
12510          // search shortcuts
12511          if(keyCode == keys.escape) {
12512            module.verbose('Escape key pressed, blurring search field');
12513            module.trigger.blur();
12514          }
12515          if( module.is.visible() ) {
12516            if(keyCode == keys.enter) {
12517              module.verbose('Enter key pressed, selecting active result');
12518              if( $result.filter('.' + className.active).length > 0 ) {
12519                module.event.result.click.call($result.filter('.' + className.active), event);
12520                event.preventDefault();
12521                return false;
12522              }
12523            }
12524            else if(keyCode == keys.upArrow) {
12525              module.verbose('Up key pressed, changing active result');
12526              newIndex = (currentIndex - 1 < 0)
12527                ? currentIndex
12528                : currentIndex - 1
12529              ;
12530              $category
12531                .removeClass(className.active)
12532              ;
12533              $result
12534                .removeClass(className.active)
12535                .eq(newIndex)
12536                  .addClass(className.active)
12537                  .closest($category)
12538                    .addClass(className.active)
12539              ;
12540              event.preventDefault();
12541            }
12542            else if(keyCode == keys.downArrow) {
12543              module.verbose('Down key pressed, changing active result');
12544              newIndex = (currentIndex + 1 >= resultSize)
12545                ? currentIndex
12546                : currentIndex + 1
12547              ;
12548              $category
12549                .removeClass(className.active)
12550              ;
12551              $result
12552                .removeClass(className.active)
12553                .eq(newIndex)
12554                  .addClass(className.active)
12555                  .closest($category)
12556                    .addClass(className.active)
12557              ;
12558              event.preventDefault();
12559            }
12560          }
12561          else {
12562            // query shortcuts
12563            if(keyCode == keys.enter) {
12564              module.verbose('Enter key pressed, executing query');
12565              module.query();
12566              module.set.buttonPressed();
12567              $prompt.one('keyup', module.remove.buttonFocus);
12568            }
12569          }
12570        },
12571
12572        setup: {
12573          api: function() {
12574            var
12575              apiSettings = {
12576                debug     : settings.debug,
12577                on        : false,
12578                cache     : 'local',
12579                action    : 'search',
12580                onError   : module.error
12581              },
12582              searchHTML
12583            ;
12584            module.verbose('First request, initializing API');
12585            $module.api(apiSettings);
12586          }
12587        },
12588
12589        can: {
12590          useAPI: function() {
12591            return $.fn.api !== undefined;
12592          },
12593          show: function() {
12594            return module.is.focused() && !module.is.visible() && !module.is.empty();
12595          },
12596          transition: function() {
12597            return settings.transition && $.fn.transition !== undefined && $module.transition('is supported');
12598          }
12599        },
12600
12601        is: {
12602          animating: function() {
12603            return $results.hasClass(className.animating);
12604          },
12605          hidden: function() {
12606            return $results.hasClass(className.hidden);
12607          },
12608          empty: function() {
12609            return ($results.html() === '');
12610          },
12611          visible: function() {
12612            return ($results.filter(':visible').length > 0);
12613          },
12614          focused: function() {
12615            return ($prompt.filter(':focus').length > 0);
12616          }
12617        },
12618
12619        trigger: {
12620          blur: function() {
12621            var
12622              events        = document.createEvent('HTMLEvents'),
12623              promptElement = $prompt[0]
12624            ;
12625            if(promptElement) {
12626              module.verbose('Triggering native blur event');
12627              events.initEvent('blur', false, false);
12628              promptElement.dispatchEvent(events);
12629            }
12630          }
12631        },
12632
12633        get: {
12634          inputEvent: function() {
12635            var
12636              prompt = $prompt[0],
12637              inputEvent   = (prompt !== undefined && prompt.oninput !== undefined)
12638                ? 'input'
12639                : (prompt !== undefined && prompt.onpropertychange !== undefined)
12640                  ? 'propertychange'
12641                  : 'keyup'
12642            ;
12643            return inputEvent;
12644          },
12645          value: function() {
12646            return $prompt.val();
12647          },
12648          results: function() {
12649            var
12650              results = $module.data(metadata.results)
12651            ;
12652            return results;
12653          },
12654          result: function(value, results) {
12655            var
12656              lookupFields = ['title', 'id'],
12657              result       = false
12658            ;
12659            value = (value !== undefined)
12660              ? value
12661              : module.get.value()
12662            ;
12663            results = (results !== undefined)
12664              ? results
12665              : module.get.results()
12666            ;
12667            if(settings.type === 'category') {
12668              module.debug('Finding result that matches', value);
12669              $.each(results, function(index, category) {
12670                if($.isArray(category.results)) {
12671                  result = module.search.object(value, category.results, lookupFields)[0];
12672                  // don't continue searching if a result is found
12673                  if(result) {
12674                    return false;
12675                  }
12676                }
12677              });
12678            }
12679            else {
12680              module.debug('Finding result in results object', value);
12681              result = module.search.object(value, results, lookupFields)[0];
12682            }
12683            return result || false;
12684          },
12685        },
12686
12687        set: {
12688          focus: function() {
12689            $module.addClass(className.focus);
12690          },
12691          loading: function() {
12692            $module.addClass(className.loading);
12693          },
12694          value: function(value) {
12695            module.verbose('Setting search input value', value);
12696            $prompt
12697              .val(value)
12698            ;
12699          },
12700          type: function(type) {
12701            type = type || settings.type;
12702            if(settings.type == 'category') {
12703              $module.addClass(settings.type);
12704            }
12705          },
12706          buttonPressed: function() {
12707            $searchButton.addClass(className.pressed);
12708          }
12709        },
12710
12711        remove: {
12712          loading: function() {
12713            $module.removeClass(className.loading);
12714          },
12715          focus: function() {
12716            $module.removeClass(className.focus);
12717          },
12718          buttonPressed: function() {
12719            $searchButton.removeClass(className.pressed);
12720          }
12721        },
12722
12723        query: function() {
12724          var
12725            searchTerm = module.get.value(),
12726            cache = module.read.cache(searchTerm)
12727          ;
12728          if( module.has.minimumCharacters() )  {
12729            if(cache) {
12730              module.debug('Reading result from cache', searchTerm);
12731              module.save.results(cache.results);
12732              module.addResults(cache.html);
12733              module.inject.id(cache.results);
12734            }
12735            else {
12736              module.debug('Querying for', searchTerm);
12737              if($.isPlainObject(settings.source) || $.isArray(settings.source)) {
12738                module.search.local(searchTerm);
12739              }
12740              else if( module.can.useAPI() ) {
12741                module.search.remote(searchTerm);
12742              }
12743              else {
12744                module.error(error.source);
12745              }
12746            }
12747            settings.onSearchQuery.call(element, searchTerm);
12748          }
12749          else {
12750            module.hideResults();
12751          }
12752        },
12753
12754        search: {
12755          local: function(searchTerm) {
12756            var
12757              results = module.search.object(searchTerm, settings.content),
12758              searchHTML
12759            ;
12760            module.set.loading();
12761            module.save.results(results);
12762            module.debug('Returned local search results', results);
12763
12764            searchHTML = module.generateResults({
12765              results: results
12766            });
12767            module.remove.loading();
12768            module.addResults(searchHTML);
12769            module.inject.id(results);
12770            module.write.cache(searchTerm, {
12771              html    : searchHTML,
12772              results : results
12773            });
12774          },
12775          remote: function(searchTerm) {
12776            var
12777              apiSettings = {
12778                onSuccess : function(response) {
12779                  module.parse.response.call(element, response, searchTerm);
12780                },
12781                onFailure: function() {
12782                  module.displayMessage(error.serverError);
12783                },
12784                urlData: {
12785                  query: searchTerm
12786                }
12787              }
12788            ;
12789            if( !$module.api('get request') ) {
12790              module.setup.api();
12791            }
12792            $.extend(true, apiSettings, settings.apiSettings);
12793            module.debug('Executing search', apiSettings);
12794            module.cancel.query();
12795            $module
12796              .api('setting', apiSettings)
12797              .api('query')
12798            ;
12799          },
12800          object: function(searchTerm, source, searchFields) {
12801            var
12802              results      = [],
12803              fuzzyResults = [],
12804              searchExp    = searchTerm.toString().replace(regExp.escape, '\\$&'),
12805              matchRegExp  = new RegExp(regExp.beginsWith + searchExp, 'i'),
12806
12807              // avoid duplicates when pushing results
12808              addResult = function(array, result) {
12809                var
12810                  notResult      = ($.inArray(result, results) == -1),
12811                  notFuzzyResult = ($.inArray(result, fuzzyResults) == -1)
12812                ;
12813                if(notResult && notFuzzyResult) {
12814                  array.push(result);
12815                }
12816              }
12817            ;
12818            source = source || settings.source;
12819            searchFields = (searchFields !== undefined)
12820              ? searchFields
12821              : settings.searchFields
12822            ;
12823
vendor: 4,325 bytes, lines 12824-12954
12824            // search fields should be array to loop correctly
12825            if(!$.isArray(searchFields)) {
12826              searchFields = [searchFields];
12827            }
12828
12829            // exit conditions if no source
12830            if(source === undefined || source === false) {
12831              module.error(error.source);
12832              return [];
12833            }
12834
12835            // iterate through search fields looking for matches
12836            $.each(searchFields, function(index, field) {
12837              $.each(source, function(label, content) {
12838                var
12839                  fieldExists = (typeof content[field] == 'string')
12840                ;
12841                if(fieldExists) {
12842                  if( content[field].search(matchRegExp) !== -1) {
12843                    // content starts with value (first in results)
12844                    addResult(results, content);
12845                  }
12846                  else if(settings.searchFullText && module.fuzzySearch(searchTerm, content[field]) ) {
12847                    // content fuzzy matches (last in results)
12848                    addResult(fuzzyResults, content);
12849                  }
12850                }
12851              });
12852            });
12853            return $.merge(results, fuzzyResults);
12854          }
12855        },
12856
12857        fuzzySearch: function(query, term) {
12858          var
12859            termLength  = term.length,
12860            queryLength = query.length
12861          ;
12862          if(typeof query !== 'string') {
12863            return false;
12864          }
12865          query = query.toLowerCase();
12866          term  = term.toLowerCase();
12867          if(queryLength > termLength) {
12868            return false;
12869          }
12870          if(queryLength === termLength) {
12871            return (query === term);
12872          }
12873          search: for (var characterIndex = 0, nextCharacterIndex = 0; characterIndex < queryLength; characterIndex++) {
12874            var
12875              queryCharacter = query.charCodeAt(characterIndex)
12876            ;
12877            while(nextCharacterIndex < termLength) {
12878              if(term.charCodeAt(nextCharacterIndex++) === queryCharacter) {
12879                continue search;
12880              }
12881            }
12882            return false;
12883          }
12884          return true;
12885        },
12886
12887        parse: {
12888          response: function(response, searchTerm) {
12889            var
12890              searchHTML = module.generateResults(response)
12891            ;
12892            module.verbose('Parsing server response', response);
12893            if(response !== undefined) {
12894              if(searchTerm !== undefined && response[fields.results] !== undefined) {
12895                module.addResults(searchHTML);
12896                module.inject.id(response[fields.results]);
12897                module.write.cache(searchTerm, {
12898                  html    : searchHTML,
12899                  results : response[fields.results]
12900                });
12901                module.save.results(response[fields.results]);
12902              }
12903            }
12904          }
12905        },
12906
12907        cancel: {
12908          query: function() {
12909            if( module.can.useAPI() ) {
12910              $module.api('abort');
12911            }
12912          }
12913        },
12914
12915        has: {
12916          minimumCharacters: function() {
12917            var
12918              searchTerm    = module.get.value(),
12919              numCharacters = searchTerm.length
12920            ;
12921            return (numCharacters >= settings.minCharacters);
12922          }
12923        },
12924
12925        clear: {
12926          cache: function(value) {
12927            var
12928              cache = $module.data(metadata.cache)
12929            ;
12930            if(!value) {
12931              module.debug('Clearing cache', value);
12932              $module.removeData(metadata.cache);
12933            }
12934            else if(value && cache && cache[value]) {
12935              module.debug('Removing value from cache', value);
12936              delete cache[value];
12937              $module.data(metadata.cache, cache);
12938            }
12939          }
12940        },
12941
12942        read: {
12943          cache: function(name) {
12944            var
12945              cache = $module.data(metadata.cache)
12946            ;
12947            if(settings.cache) {
12948              module.verbose('Checking cache for generated html for query', name);
12949              return (typeof cache == 'object') && (cache[name] !== undefined)
12950                ? cache[name]
12951                : false
12952              ;
12953            }
12954            return false;
vendor: 31,349 bytes, lines 12955-13952
12955          }
12956        },
12957
12958        create: {
12959          id: function(resultIndex, categoryIndex) {
12960            var
12961              resultID      = (resultIndex + 1), // not zero indexed
12962              categoryID    = (categoryIndex + 1),
12963              firstCharCode,
12964              letterID,
12965              id
12966            ;
12967            if(categoryIndex !== undefined) {
12968              // start char code for "A"
12969              letterID = String.fromCharCode(97 + categoryIndex);
12970              id          = letterID + resultID;
12971              module.verbose('Creating category result id', id);
12972            }
12973            else {
12974              id = resultID;
12975              module.verbose('Creating result id', id);
12976            }
12977            return id;
12978          },
12979          results: function() {
12980            if($results.length === 0) {
12981              $results = $('<div />')
12982                .addClass(className.results)
12983                .appendTo($module)
12984              ;
12985            }
12986          }
12987        },
12988
12989        inject: {
12990          result: function(result, resultIndex, categoryIndex) {
12991            module.verbose('Injecting result into results');
12992            var
12993              $selectedResult = (categoryIndex !== undefined)
12994                ? $results
12995                    .children().eq(categoryIndex)
12996                      .children(selector.result).eq(resultIndex)
12997                : $results
12998                    .children(selector.result).eq(resultIndex)
12999            ;
13000            module.verbose('Injecting results metadata', $selectedResult);
13001            $selectedResult
13002              .data(metadata.result, result)
13003            ;
13004          },
13005          id: function(results) {
13006            module.debug('Injecting unique ids into results');
13007            var
13008              // since results may be object, we must use counters
13009              categoryIndex = 0,
13010              resultIndex   = 0
13011            ;
13012            if(settings.type === 'category') {
13013              // iterate through each category result
13014              $.each(results, function(index, category) {
13015                resultIndex = 0;
13016                $.each(category.results, function(index, value) {
13017                  var
13018                    result = category.results[index]
13019                  ;
13020                  if(result.id === undefined) {
13021                    result.id = module.create.id(resultIndex, categoryIndex);
13022                  }
13023                  module.inject.result(result, resultIndex, categoryIndex);
13024                  resultIndex++;
13025                });
13026                categoryIndex++;
13027              });
13028            }
13029            else {
13030              // top level
13031              $.each(results, function(index, value) {
13032                var
13033                  result = results[index]
13034                ;
13035                if(result.id === undefined) {
13036                  result.id = module.create.id(resultIndex);
13037                }
13038                module.inject.result(result, resultIndex);
13039                resultIndex++;
13040              });
13041            }
13042            return results;
13043          }
13044        },
13045
13046        save: {
13047          results: function(results) {
13048            module.verbose('Saving current search results to metadata', results);
13049            $module.data(metadata.results, results);
13050          }
13051        },
13052
13053        write: {
13054          cache: function(name, value) {
13055            var
13056              cache = ($module.data(metadata.cache) !== undefined)
13057                ? $module.data(metadata.cache)
13058                : {}
13059            ;
13060            if(settings.cache) {
13061              module.verbose('Writing generated html to cache', name, value);
13062              cache[name] = value;
13063              $module
13064                .data(metadata.cache, cache)
13065              ;
13066            }
13067          }
13068        },
13069
13070        addResults: function(html) {
13071          if( $.isFunction(settings.onResultsAdd) ) {
13072            if( settings.onResultsAdd.call($results, html) === false ) {
13073              module.debug('onResultsAdd callback cancelled default action');
13074              return false;
13075            }
13076          }
13077          $results
13078            .html(html)
13079          ;
13080          if( module.can.show() ) {
13081            module.showResults();
13082          }
13083        },
13084
13085        showResults: function() {
13086          if(!module.is.visible()) {
13087            if( module.can.transition() ) {
13088              module.debug('Showing results with css animations');
13089              $results
13090                .transition({
13091                  animation  : settings.transition + ' in',
13092                  debug      : settings.debug,
13093                  verbose    : settings.verbose,
13094                  duration   : settings.duration,
13095                  queue      : true
13096                })
13097              ;
13098            }
13099            else {
13100              module.debug('Showing results with javascript');
13101              $results
13102                .stop()
13103                .fadeIn(settings.duration, settings.easing)
13104              ;
13105            }
13106            settings.onResultsOpen.call($results);
13107          }
13108        },
13109        hideResults: function() {
13110          if( module.is.visible() ) {
13111            if( module.can.transition() ) {
13112              module.debug('Hiding results with css animations');
13113              $results
13114                .transition({
13115                  animation  : settings.transition + ' out',
13116                  debug      : settings.debug,
13117                  verbose    : settings.verbose,
13118                  duration   : settings.duration,
13119                  queue      : true
13120                })
13121              ;
13122            }
13123            else {
13124              module.debug('Hiding results with javascript');
13125              $results
13126                .stop()
13127                .fadeOut(settings.duration, settings.easing)
13128              ;
13129            }
13130            settings.onResultsClose.call($results);
13131          }
13132        },
13133
13134        generateResults: function(response) {
13135          module.debug('Generating html from response', response);
13136          var
13137            template       = settings.templates[settings.type],
13138            isProperObject = ($.isPlainObject(response[fields.results]) && !$.isEmptyObject(response[fields.results])),
13139            isProperArray  = ($.isArray(response[fields.results]) && response[fields.results].length > 0),
13140            html           = ''
13141          ;
13142          if(isProperObject || isProperArray ) {
13143            if(settings.maxResults > 0) {
13144              if(isProperObject) {
13145                if(settings.type == 'standard') {
13146                  module.error(error.maxResults);
13147                }
13148              }
13149              else {
13150                response[fields.results] = response[fields.results].slice(0, settings.maxResults);
13151              }
13152            }
13153            if($.isFunction(template)) {
13154              html = template(response, fields);
13155            }
13156            else {
13157              module.error(error.noTemplate, false);
13158            }
13159          }
13160          else {
13161            html = module.displayMessage(error.noResults, 'empty');
13162          }
13163          settings.onResults.call(element, response);
13164          return html;
13165        },
13166
13167        displayMessage: function(text, type) {
13168          type = type || 'standard';
13169          module.debug('Displaying message', text, type);
13170          module.addResults( settings.templates.message(text, type) );
13171          return settings.templates.message(text, type);
13172        },
13173
13174        setting: function(name, value) {
13175          if( $.isPlainObject(name) ) {
13176            $.extend(true, settings, name);
13177          }
13178          else if(value !== undefined) {
13179            settings[name] = value;
13180          }
13181          else {
13182            return settings[name];
13183          }
13184        },
13185        internal: function(name, value) {
13186          if( $.isPlainObject(name) ) {
13187            $.extend(true, module, name);
13188          }
13189          else if(value !== undefined) {
13190            module[name] = value;
13191          }
13192          else {
13193            return module[name];
13194          }
13195        },
13196        debug: function() {
13197          if(settings.debug) {
13198            if(settings.performance) {
13199              module.performance.log(arguments);
13200            }
13201            else {
13202              module.debug = Function.prototype.bind.call(console.info, console, settings.name + ':');
13203              module.debug.apply(console, arguments);
13204            }
13205          }
13206        },
13207        verbose: function() {
13208          if(settings.verbose && settings.debug) {
13209            if(settings.performance) {
13210              module.performance.log(arguments);
13211            }
13212            else {
13213              module.verbose = Function.prototype.bind.call(console.info, console, settings.name + ':');
13214              module.verbose.apply(console, arguments);
13215            }
13216          }
13217        },
13218        error: function() {
13219          module.error = Function.prototype.bind.call(console.error, console, settings.name + ':');
13220          module.error.apply(console, arguments);
13221        },
13222        performance: {
13223          log: function(message) {
13224            var
13225              currentTime,
13226              executionTime,
13227              previousTime
13228            ;
13229            if(settings.performance) {
13230              currentTime   = new Date().getTime();
13231              previousTime  = time || currentTime;
13232              executionTime = currentTime - previousTime;
13233              time          = currentTime;
13234              performance.push({
13235                'Name'           : message[0],
13236                'Arguments'      : [].slice.call(message, 1) || '',
13237                'Element'        : element,
13238                'Execution Time' : executionTime
13239              });
13240            }
13241            clearTimeout(module.performance.timer);
13242            module.performance.timer = setTimeout(module.performance.display, 500);
13243          },
13244          display: function() {
13245            var
13246              title = settings.name + ':',
13247              totalTime = 0
13248            ;
13249            time = false;
13250            clearTimeout(module.performance.timer);
13251            $.each(performance, function(index, data) {
13252              totalTime += data['Execution Time'];
13253            });
13254            title += ' ' + totalTime + 'ms';
13255            if(moduleSelector) {
13256              title += ' \'' + moduleSelector + '\'';
13257            }
13258            if($allModules.length > 1) {
13259              title += ' ' + '(' + $allModules.length + ')';
13260            }
13261            if( (console.group !== undefined || console.table !== undefined) && performance.length > 0) {
13262              console.groupCollapsed(title);
13263              if(console.table) {
13264                console.table(performance);
13265              }
13266              else {
13267                $.each(performance, function(index, data) {
13268                  console.log(data['Name'] + ': ' + data['Execution Time']+'ms');
13269                });
13270              }
13271              console.groupEnd();
13272            }
13273            performance = [];
13274          }
13275        },
13276        invoke: function(query, passedArguments, context) {
13277          var
13278            object = instance,
13279            maxDepth,
13280            found,
13281            response
13282          ;
13283          passedArguments = passedArguments || queryArguments;
13284          context         = element         || context;
13285          if(typeof query == 'string' && object !== undefined) {
13286            query    = query.split(/[\. ]/);
13287            maxDepth = query.length - 1;
13288            $.each(query, function(depth, value) {
13289              var camelCaseValue = (depth != maxDepth)
13290                ? value + query[depth + 1].charAt(0).toUpperCase() + query[depth + 1].slice(1)
13291                : query
13292              ;
13293              if( $.isPlainObject( object[camelCaseValue] ) && (depth != maxDepth) ) {
13294                object = object[camelCaseValue];
13295              }
13296              else if( object[camelCaseValue] !== undefined ) {
13297                found = object[camelCaseValue];
13298                return false;
13299              }
13300              else if( $.isPlainObject( object[value] ) && (depth != maxDepth) ) {
13301                object = object[value];
13302              }
13303              else if( object[value] !== undefined ) {
13304                found = object[value];
13305                return false;
13306              }
13307              else {
13308                return false;
13309              }
13310            });
13311          }
13312          if( $.isFunction( found ) ) {
13313            response = found.apply(context, passedArguments);
13314          }
13315          else if(found !== undefined) {
13316            response = found;
13317          }
13318          if($.isArray(returnedValue)) {
13319            returnedValue.push(response);
13320          }
13321          else if(returnedValue !== undefined) {
13322            returnedValue = [returnedValue, response];
13323          }
13324          else if(response !== undefined) {
13325            returnedValue = response;
13326          }
13327          return found;
13328        }
13329      };
13330      if(methodInvoked) {
13331        if(instance === undefined) {
13332          module.initialize();
13333        }
13334        module.invoke(query);
13335      }
13336      else {
13337        if(instance !== undefined) {
13338          instance.invoke('destroy');
13339        }
13340        module.initialize();
13341      }
13342
13343    })
13344  ;
13345
13346  return (returnedValue !== undefined)
13347    ? returnedValue
13348    : this
13349  ;
13350};
13351
13352$.fn.search.settings = {
13353
13354  name           : 'Search',
13355  namespace      : 'search',
13356
13357  debug          : false,
13358  verbose        : false,
13359  performance    : true,
13360
13361  type           : 'standard',
13362  // template to use (specified in settings.templates)
13363
13364  minCharacters  : 1,
13365  // minimum characters required to search
13366
13367  apiSettings    : false,
13368  // API config
13369
13370  source         : false,
13371  // object to search
13372
13373  searchFields   : [
13374    'title',
13375    'description'
13376  ],
13377  // fields to search
13378
13379  displayField   : '',
13380  // field to display in standard results template
13381
13382  searchFullText : true,
13383  // whether to include fuzzy results in local search
13384
13385  automatic      : true,
13386  // whether to add events to prompt automatically
13387
13388  hideDelay      : 0,
13389  // delay before hiding menu after blur
13390
13391  searchDelay    : 200,
13392  // delay before searching
13393
13394  maxResults     : 7,
13395  // maximum results returned from local
13396
13397  cache          : true,
13398  // whether to store lookups in local cache
13399
13400  // transition settings
13401  transition     : 'scale',
13402  duration       : 200,
13403  easing         : 'easeOutExpo',
13404
13405  // callbacks
13406  onSelect       : false,
13407  onResultsAdd   : false,
13408
13409  onSearchQuery  : function(query){},
13410  onResults      : function(response){},
13411
13412  onResultsOpen  : function(){},
13413  onResultsClose : function(){},
13414
13415  className: {
13416    animating : 'animating',
13417    active    : 'active',
13418    empty     : 'empty',
13419    focus     : 'focus',
13420    hidden    : 'hidden',
13421    loading   : 'loading',
13422    results   : 'results',
13423    pressed   : 'down'
13424  },
13425
13426  error : {
13427    source      : 'Cannot search. No source used, and Semantic API module was not included',
13428    noResults   : 'Your search returned no results',
13429    logging     : 'Error in debug logging, exiting.',
13430    noEndpoint  : 'No search endpoint was specified',
13431    noTemplate  : 'A valid template name was not specified.',
13432    serverError : 'There was an issue querying the server.',
13433    maxResults  : 'Results must be an array to use maxResults setting',
13434    method      : 'The method you called is not defined.'
13435  },
13436
13437  metadata: {
13438    cache   : 'cache',
13439    results : 'results',
13440    result  : 'result'
13441  },
13442
13443  regExp: {
13444    escape     : /[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g,
13445    beginsWith : '(?:\s|^)'
13446  },
13447
13448  // maps api response attributes to internal representation
13449  fields: {
13450    categories      : 'results',     // array of categories (category view)
13451    categoryName    : 'name',        // name of category (category view)
13452    categoryResults : 'results',     // array of results (category view)
13453    description     : 'description', // result description
13454    image           : 'image',       // result image
13455    price           : 'price',       // result price
13456    results         : 'results',     // array of results (standard)
13457    title           : 'title',       // result title
13458    url             : 'url',         // result url
13459    action          : 'action',      // "view more" object name
13460    actionText      : 'text',        // "view more" text
13461    actionURL       : 'url'          // "view more" url
13462  },
13463
13464  selector : {
13465    prompt       : '.prompt',
13466    searchButton : '.search.button',
13467    results      : '.results',
13468    category     : '.category',
13469    result       : '.result',
13470    title        : '.title, .name'
13471  },
13472
13473  templates: {
13474    escape: function(string) {
13475      var
13476        badChars     = /[&<>"'`]/g,
13477        shouldEscape = /[&<>"'`]/,
13478        escape       = {
13479          "&": "&amp;",
13480          "<": "&lt;",
13481          ">": "&gt;",
13482          '"': "&quot;",
13483          "'": "&#x27;",
13484          "`": "&#x60;"
13485        },
13486        escapedChar  = function(chr) {
13487          return escape[chr];
13488        }
13489      ;
13490      if(shouldEscape.test(string)) {
13491        return string.replace(badChars, escapedChar);
13492      }
13493      return string;
13494    },
13495    message: function(message, type) {
13496      var
13497        html = ''
13498      ;
13499      if(message !== undefined && type !== undefined) {
13500        html +=  ''
13501          + '<div class="message ' + type + '">'
13502        ;
13503        // message type
13504        if(type == 'empty') {
13505          html += ''
13506            + '<div class="header">No Results</div class="header">'
13507            + '<div class="description">' + message + '</div class="description">'
13508          ;
13509        }
13510        else {
13511          html += ' <div class="description">' + message + '</div>';
13512        }
13513        html += '</div>';
13514      }
13515      return html;
13516    },
13517    category: function(response, fields) {
13518      var
13519        html = '',
13520        escape = $.fn.search.settings.templates.escape
13521      ;
13522      if(response[fields.categoryResults] !== undefined) {
13523
13524        // each category
13525        $.each(response[fields.categoryResults], function(index, category) {
13526          if(category[fields.results] !== undefined && category.results.length > 0) {
13527
13528            html  += '<div class="category">';
13529
13530            if(category[fields.categoryName] !== undefined) {
13531              html += '<div class="name">' + category[fields.categoryName] + '</div>';
13532            }
13533
13534            // each item inside category
13535            $.each(category.results, function(index, result) {
13536              if(result[fields.url]) {
13537                html  += '<a class="result" href="' + result[fields.url] + '">';
13538              }
13539              else {
13540                html  += '<a class="result">';
13541              }
13542              if(result[fields.image] !== undefined) {
13543                html += ''
13544                  + '<div class="image">'
13545                  + ' <img src="' + result[fields.image] + '">'
13546                  + '</div>'
13547                ;
13548              }
13549              html += '<div class="content">';
13550              if(result[fields.price] !== undefined) {
13551                html += '<div class="price">' + result[fields.price] + '</div>';
13552              }
13553              if(result[fields.title] !== undefined) {
13554                html += '<div class="title">' + result[fields.title] + '</div>';
13555              }
13556              if(result[fields.description] !== undefined) {
13557                html += '<div class="description">' + result[fields.description] + '</div>';
13558              }
13559              html  += ''
13560                + '</div>'
13561              ;
13562              html += '</a>';
13563            });
13564            html  += ''
13565              + '</div>'
13566            ;
13567          }
13568        });
13569        if(response[fields.action]) {
13570          html += ''
13571          + '<a href="' + response[fields.action][fields.actionURL] + '" class="action">'
13572          +   response[fields.action][fields.actionText]
13573          + '</a>';
13574        }
13575        return html;
13576      }
13577      return false;
13578    },
13579    standard: function(response, fields) {
13580      var
13581        html = ''
13582      ;
13583      if(response[fields.results] !== undefined) {
13584
13585        // each result
13586        $.each(response[fields.results], function(index, result) {
13587          if(result[fields.url]) {
13588            html  += '<a class="result" href="' + result[fields.url] + '">';
13589          }
13590          else {
13591            html  += '<a class="result">';
13592          }
13593          if(result[fields.image] !== undefined) {
13594            html += ''
13595              + '<div class="image">'
13596              + ' <img src="' + result[fields.image] + '">'
13597              + '</div>'
13598            ;
13599          }
13600          html += '<div class="content">';
13601          if(result[fields.price] !== undefined) {
13602            html += '<div class="price">' + result[fields.price] + '</div>';
13603          }
13604          if(result[fields.title] !== undefined) {
13605            html += '<div class="title">' + result[fields.title] + '</div>';
13606          }
13607          if(result[fields.description] !== undefined) {
13608            html += '<div class="description">' + result[fields.description] + '</div>';
13609          }
13610          html  += ''
13611            + '</div>'
13612          ;
13613          html += '</a>';
13614        });
13615
13616        if(response[fields.action]) {
13617          html += ''
13618          + '<a href="' + response[fields.action][fields.actionURL] + '" class="action">'
13619          +   response[fields.action][fields.actionText]
13620          + '</a>';
13621        }
13622        return html;
13623      }
13624      return false;
13625    }
13626  }
13627};
13628
13629})( jQuery, window, document );
13630
13631/*!
13632 * # Semantic UI 2.1.7 - Shape
13633 * http://github.com/semantic-org/semantic-ui/
13634 *
13635 *
13636 * Copyright 2015 Contributors
13637 * Released under the MIT license
13638 * http://opensource.org/licenses/MIT
13639 *
13640 */
13641
13642;(function ( $, window, document, undefined ) {
13643
13644"use strict";
13645
13646$.fn.shape = function(parameters) {
13647  var
13648    $allModules     = $(this),
13649    $body           = $('body'),
13650
13651    time            = new Date().getTime(),
13652    performance     = [],
13653
13654    query           = arguments[0],
13655    methodInvoked   = (typeof query == 'string'),
13656    queryArguments  = [].slice.call(arguments, 1),
13657
13658    requestAnimationFrame = window.requestAnimationFrame
13659      || window.mozRequestAnimationFrame
13660      || window.webkitRequestAnimationFrame
13661      || window.msRequestAnimationFrame
13662      || function(callback) { setTimeout(callback, 0); },
13663
13664    returnedValue
13665  ;
13666
13667  $allModules
13668    .each(function() {
13669      var
13670        moduleSelector = $allModules.selector || '',
13671        settings       = ( $.isPlainObject(parameters) )
13672          ? $.extend(true, {}, $.fn.shape.settings, parameters)
13673          : $.extend({}, $.fn.shape.settings),
13674
13675        // internal aliases
13676        namespace     = settings.namespace,
13677        selector      = settings.selector,
13678        error         = settings.error,
13679        className     = settings.className,
13680
13681        // define namespaces for modules
13682        eventNamespace  = '.' + namespace,
13683        moduleNamespace = 'module-' + namespace,
13684
13685        // selector cache
13686        $module       = $(this),
13687        $sides        = $module.find(selector.sides),
13688        $side         = $module.find(selector.side),
13689
13690        // private variables
13691        nextIndex = false,
13692        $activeSide,
13693        $nextSide,
13694
13695        // standard module
13696        element       = this,
13697        instance      = $module.data(moduleNamespace),
13698        module
13699      ;
13700
13701      module = {
13702
13703        initialize: function() {
13704          module.verbose('Initializing module for', element);
13705          module.set.defaultSide();
13706          module.instantiate();
13707        },
13708
13709        instantiate: function() {
13710          module.verbose('Storing instance of module', module);
13711          instance = module;
13712          $module
13713            .data(moduleNamespace, instance)
13714          ;
13715        },
13716
13717        destroy: function() {
13718          module.verbose('Destroying previous module for', element);
13719          $module
13720            .removeData(moduleNamespace)
13721            .off(eventNamespace)
13722          ;
13723        },
13724
13725        refresh: function() {
13726          module.verbose('Refreshing selector cache for', element);
13727          $module = $(element);
13728          $sides  = $(this).find(selector.shape);
13729          $side   = $(this).find(selector.side);
13730        },
13731
13732        repaint: function() {
13733          module.verbose('Forcing repaint event');
13734          var
13735            shape          = $sides[0] || document.createElement('div'),
13736            fakeAssignment = shape.offsetWidth
13737          ;
13738        },
13739
13740        animate: function(propertyObject, callback) {
13741          module.verbose('Animating box with properties', propertyObject);
13742          callback = callback || function(event) {
13743            module.verbose('Executing animation callback');
13744            if(event !== undefined) {
13745              event.stopPropagation();
13746            }
13747            module.reset();
13748            module.set.active();
13749          };
13750          settings.beforeChange.call($nextSide[0]);
13751          if(module.get.transitionEvent()) {
13752            module.verbose('Starting CSS animation');
13753            $module
13754              .addClass(className.animating)
13755            ;
13756            $sides
13757              .css(propertyObject)
13758              .one(module.get.transitionEvent(), callback)
13759            ;
13760            module.set.duration(settings.duration);
13761            requestAnimationFrame(function() {
13762              $module
13763                .addClass(className.animating)
13764              ;
13765              $activeSide
13766                .addClass(className.hidden)
13767              ;
13768            });
13769          }
13770          else {
13771            callback();
13772          }
13773        },
13774
13775        queue: function(method) {
13776          module.debug('Queueing animation of', method);
13777          $sides
13778            .one(module.get.transitionEvent(), function() {
13779              module.debug('Executing queued animation');
13780              setTimeout(function(){
13781                $module.shape(method);
13782              }, 0);
13783            })
13784          ;
13785        },
13786
13787        reset: function() {
13788          module.verbose('Animating states reset');
13789          $module
13790            .removeClass(className.animating)
13791            .attr('style', '')
13792            .removeAttr('style')
13793          ;
13794          // removeAttr style does not consistently work in safari
13795          $sides
13796            .attr('style', '')
13797            .removeAttr('style')
13798          ;
13799          $side
13800            .attr('style', '')
13801            .removeAttr('style')
13802            .removeClass(className.hidden)
13803          ;
13804          $nextSide
13805            .removeClass(className.animating)
13806            .attr('style', '')
13807            .removeAttr('style')
13808          ;
13809        },
13810
13811        is: {
13812          complete: function() {
13813            return ($side.filter('.' + className.active)[0] == $nextSide[0]);
13814          },
13815          animating: function() {
13816            return $module.hasClass(className.animating);
13817          }
13818        },
13819
13820        set: {
13821
13822          defaultSide: function() {
13823            $activeSide = $module.find('.' + settings.className.active);
13824            $nextSide   = ( $activeSide.next(selector.side).length > 0 )
13825              ? $activeSide.next(selector.side)
13826              : $module.find(selector.side).first()
13827            ;
13828            nextIndex = false;
13829            module.verbose('Active side set to', $activeSide);
13830            module.verbose('Next side set to', $nextSide);
13831          },
13832
13833          duration: function(duration) {
13834            duration = duration || settings.duration;
13835            duration = (typeof duration == 'number')
13836              ? duration + 'ms'
13837              : duration
13838            ;
13839            module.verbose('Setting animation duration', duration);
13840            if(settings.duration || settings.duration === 0) {
13841              $sides.add($side)
13842                .css({
13843                  '-webkit-transition-duration': duration,
13844                  '-moz-transition-duration': duration,
13845                  '-ms-transition-duration': duration,
13846                  '-o-transition-duration': duration,
13847                  'transition-duration': duration
13848                })
13849              ;
13850            }
13851          },
13852
13853          currentStageSize: function() {
13854            var
13855              $activeSide = $module.find('.' + settings.className.active),
13856              width       = $activeSide.outerWidth(true),
13857              height      = $activeSide.outerHeight(true)
13858            ;
13859            $module
13860              .css({
13861                width: width,
13862                height: height
13863              })
13864            ;
13865          },
13866
13867          stageSize: function() {
13868            var
13869              $clone      = $module.clone().addClass(className.loading),
13870              $activeSide = $clone.find('.' + settings.className.active),
13871              $nextSide   = (nextIndex)
13872                ? $clone.find(selector.side).eq(nextIndex)
13873                : ( $activeSide.next(selector.side).length > 0 )
13874                  ? $activeSide.next(selector.side)
13875                  : $clone.find(selector.side).first(),
13876              newSize = {}
13877            ;
13878            module.set.currentStageSize();
13879            $activeSide.removeClass(className.active);
13880            $nextSide.addClass(className.active);
13881            $clone.insertAfter($module);
13882            newSize = {
13883              width  : $nextSide.outerWidth(true),
13884              height : $nextSide.outerHeight(true)
13885            };
13886            $clone.remove();
13887            $module
13888              .css(newSize)
13889            ;
13890            module.verbose('Resizing stage to fit new content', newSize);
13891          },
13892
13893          nextSide: function(selector) {
13894            nextIndex = selector;
13895            $nextSide = $side.filter(selector);
13896            nextIndex = $side.index($nextSide);
13897            if($nextSide.length === 0) {
13898              module.set.defaultSide();
13899              module.error(error.side);
13900            }
13901            module.verbose('Next side manually set to', $nextSide);
13902          },
13903
13904          active: function() {
13905            module.verbose('Setting new side to active', $nextSide);
13906            $side
13907              .removeClass(className.active)
13908            ;
13909            $nextSide
13910              .addClass(className.active)
13911            ;
13912            settings.onChange.call($nextSide[0]);
13913            module.set.defaultSide();
13914          }
13915        },
13916
13917        flip: {
13918
13919          up: function() {
13920            if(module.is.complete() && !module.is.animating() && !settings.allowRepeats) {
13921              module.debug('Side already visible', $nextSide);
13922              return;
13923            }
13924            if( !module.is.animating()) {
13925              module.debug('Flipping up', $nextSide);
13926              module.set.stageSize();
13927              module.stage.above();
13928              module.animate( module.get.transform.up() );
13929            }
13930            else {
13931              module.queue('flip up');
13932            }
13933          },
13934
13935          down: function() {
13936            if(module.is.complete() && !module.is.animating() && !settings.allowRepeats) {
13937              module.debug('Side already visible', $nextSide);
13938              return;
13939            }
13940            if( !module.is.animating()) {
13941              module.debug('Flipping down', $nextSide);
13942              module.set.stageSize();
13943              module.stage.below();
13944              module.animate( module.get.transform.down() );
13945            }
13946            else {
13947              module.queue('flip down');
13948            }
13949          },
13950
13951          left: function() {
13952            if(module.is.complete() && !module.is.animating() && !sett
vendor: 7,719 bytes, lines 13952-14186
13952ings.allowRepeats) {
13953              module.debug('Side already visible', $nextSide);
13954              return;
13955            }
13956            if( !module.is.animating()) {
13957              module.debug('Flipping left', $nextSide);
13958              module.set.stageSize();
13959              module.stage.left();
13960              module.animate(module.get.transform.left() );
13961            }
13962            else {
13963              module.queue('flip left');
13964            }
13965          },
13966
13967          right: function() {
13968            if(module.is.complete() && !module.is.animating() && !settings.allowRepeats) {
13969              module.debug('Side already visible', $nextSide);
13970              return;
13971            }
13972            if( !module.is.animating()) {
13973              module.debug('Flipping right', $nextSide);
13974              module.set.stageSize();
13975              module.stage.right();
13976              module.animate(module.get.transform.right() );
13977            }
13978            else {
13979              module.queue('flip right');
13980            }
13981          },
13982
13983          over: function() {
13984            if(module.is.complete() && !module.is.animating() && !settings.allowRepeats) {
13985              module.debug('Side already visible', $nextSide);
13986              return;
13987            }
13988            if( !module.is.animating()) {
13989              module.debug('Flipping over', $nextSide);
13990              module.set.stageSize();
13991              module.stage.behind();
13992              module.animate(module.get.transform.over() );
13993            }
13994            else {
13995              module.queue('flip over');
13996            }
13997          },
13998
13999          back: function() {
14000            if(module.is.complete() && !module.is.animating() && !settings.allowRepeats) {
14001              module.debug('Side already visible', $nextSide);
14002              return;
14003            }
14004            if( !module.is.animating()) {
14005              module.debug('Flipping back', $nextSide);
14006              module.set.stageSize();
14007              module.stage.behind();
14008              module.animate(module.get.transform.back() );
14009            }
14010            else {
14011              module.queue('flip back');
14012            }
14013          }
14014
14015        },
14016
14017        get: {
14018
14019          transform: {
14020            up: function() {
14021              var
14022                translate = {
14023                  y: -(($activeSide.outerHeight(true) - $nextSide.outerHeight(true)) / 2),
14024                  z: -($activeSide.outerHeight(true) / 2)
14025                }
14026              ;
14027              return {
14028                transform: 'translateY(' + translate.y + 'px) translateZ('+ translate.z + 'px) rotateX(-90deg)'
14029              };
14030            },
14031
14032            down: function() {
14033              var
14034                translate = {
14035                  y: -(($activeSide.outerHeight(true) - $nextSide.outerHeight(true)) / 2),
14036                  z: -($activeSide.outerHeight(true) / 2)
14037                }
14038              ;
14039              return {
14040                transform: 'translateY(' + translate.y + 'px) translateZ('+ translate.z + 'px) rotateX(90deg)'
14041              };
14042            },
14043
14044            left: function() {
14045              var
14046                translate = {
14047                  x : -(($activeSide.outerWidth(true) - $nextSide.outerWidth(true)) / 2),
14048                  z : -($activeSide.outerWidth(true) / 2)
14049                }
14050              ;
14051              return {
14052                transform: 'translateX(' + translate.x + 'px) translateZ(' + translate.z + 'px) rotateY(90deg)'
14053              };
14054            },
14055
14056            right: function() {
14057              var
14058                translate = {
14059                  x : -(($activeSide.outerWidth(true) - $nextSide.outerWidth(true)) / 2),
14060                  z : -($activeSide.outerWidth(true) / 2)
14061                }
14062              ;
14063              return {
14064                transform: 'translateX(' + translate.x + 'px) translateZ(' + translate.z + 'px) rotateY(-90deg)'
14065              };
14066            },
14067
14068            over: function() {
14069              var
14070                translate = {
14071                  x : -(($activeSide.outerWidth(true) - $nextSide.outerWidth(true)) / 2)
14072                }
14073              ;
14074              return {
14075                transform: 'translateX(' + translate.x + 'px) rotateY(180deg)'
14076              };
14077            },
14078
14079            back: function() {
14080              var
14081                translate = {
14082                  x : -(($activeSide.outerWidth(true) - $nextSide.outerWidth(true)) / 2)
14083                }
14084              ;
14085              return {
14086                transform: 'translateX(' + translate.x + 'px) rotateY(-180deg)'
14087              };
14088            }
14089          },
14090
14091          transitionEvent: function() {
14092            var
14093              element     = document.createElement('element'),
14094              transitions = {
14095                'transition'       :'transitionend',
14096                'OTransition'      :'oTransitionEnd',
14097                'MozTransition'    :'transitionend',
14098                'WebkitTransition' :'webkitTransitionEnd'
14099              },
14100              transition
14101            ;
14102            for(transition in transitions){
14103              if( element.style[transition] !== undefined ){
14104                return transitions[transition];
14105              }
14106            }
14107          },
14108
14109          nextSide: function() {
14110            return ( $activeSide.next(selector.side).length > 0 )
14111              ? $activeSide.next(selector.side)
14112              : $module.find(selector.side).first()
14113            ;
14114          }
14115
14116        },
14117
14118        stage: {
14119
14120          above: function() {
14121            var
14122              box = {
14123                origin : (($activeSide.outerHeight(true) - $nextSide.outerHeight(true)) / 2),
14124                depth  : {
14125                  active : ($nextSide.outerHeight(true) / 2),
14126                  next   : ($activeSide.outerHeight(true) / 2)
14127                }
14128              }
14129            ;
14130            module.verbose('Setting the initial animation position as above', $nextSide, box);
14131            $sides
14132              .css({
14133                'transform' : 'translateZ(-' + box.depth.active + 'px)'
14134              })
14135            ;
14136            $activeSide
14137              .css({
14138                'transform' : 'rotateY(0deg) translateZ(' + box.depth.active + 'px)'
14139              })
14140            ;
14141            $nextSide
14142              .addClass(className.animating)
14143              .css({
14144                'top'       : box.origin + 'px',
14145                'transform' : 'rotateX(90deg) translateZ(' + box.depth.next + 'px)'
14146              })
14147            ;
14148          },
14149
14150          below: function() {
14151            var
14152              box = {
14153                origin : (($activeSide.outerHeight(true) - $nextSide.outerHeight(true)) / 2),
14154                depth  : {
14155                  active : ($nextSide.outerHeight(true) / 2),
14156                  next   : ($activeSide.outerHeight(true) / 2)
14157                }
14158              }
14159            ;
14160            module.verbose('Setting the initial animation position as below', $nextSide, box);
14161            $sides
14162              .css({
14163                'transform' : 'translateZ(-' + box.depth.active + 'px)'
14164              })
14165            ;
14166            $activeSide
14167              .css({
14168                'transform' : 'rotateY(0deg) translateZ(' + box.depth.active + 'px)'
14169              })
14170            ;
14171            $nextSide
14172              .addClass(className.animating)
14173              .css({
14174                'top'       : box.origin + 'px',
14175                'transform' : 'rotateX(-90deg) translateZ(' + box.depth.next + 'px)'
14176              })
14177            ;
14178          },
14179
14180          left: function() {
14181            var
14182              height = {
14183                active : $activeSide.outerWidth(true),
14184                next   : $nextSide.outerWidth(true)
14185              },
14186              box = {
vendor: 12,012 bytes, lines 14187-14594
14187                origin : ( ( height.active - height.next ) / 2),
14188                depth  : {
14189                  active : (height.next / 2),
14190                  next   : (height.active / 2)
14191                }
14192              }
14193            ;
14194            module.verbose('Setting the initial animation position as left', $nextSide, box);
14195            $sides
14196              .css({
14197                'transform' : 'translateZ(-' + box.depth.active + 'px)'
14198              })
14199            ;
14200            $activeSide
14201              .css({
14202                'transform' : 'rotateY(0deg) translateZ(' + box.depth.active + 'px)'
14203              })
14204            ;
14205            $nextSide
14206              .addClass(className.animating)
14207              .css({
14208                'left'      : box.origin + 'px',
14209                'transform' : 'rotateY(-90deg) translateZ(' + box.depth.next + 'px)'
14210              })
14211            ;
14212          },
14213
14214          right: function() {
14215            var
14216              height = {
14217                active : $activeSide.outerWidth(true),
14218                next   : $nextSide.outerWidth(true)
14219              },
14220              box = {
14221                origin : ( ( height.active - height.next ) / 2),
14222                depth  : {
14223                  active : (height.next / 2),
14224                  next   : (height.active / 2)
14225                }
14226              }
14227            ;
14228            module.verbose('Setting the initial animation position as left', $nextSide, box);
14229            $sides
14230              .css({
14231                'transform' : 'translateZ(-' + box.depth.active + 'px)'
14232              })
14233            ;
14234            $activeSide
14235              .css({
14236                'transform' : 'rotateY(0deg) translateZ(' + box.depth.active + 'px)'
14237              })
14238            ;
14239            $nextSide
14240              .addClass(className.animating)
14241              .css({
14242                'left'      : box.origin + 'px',
14243                'transform' : 'rotateY(90deg) translateZ(' + box.depth.next + 'px)'
14244              })
14245            ;
14246          },
14247
14248          behind: function() {
14249            var
14250              height = {
14251                active : $activeSide.outerWidth(true),
14252                next   : $nextSide.outerWidth(true)
14253              },
14254              box = {
14255                origin : ( ( height.active - height.next ) / 2),
14256                depth  : {
14257                  active : (height.next / 2),
14258                  next   : (height.active / 2)
14259                }
14260              }
14261            ;
14262            module.verbose('Setting the initial animation position as behind', $nextSide, box);
14263            $activeSide
14264              .css({
14265                'transform' : 'rotateY(0deg)'
14266              })
14267            ;
14268            $nextSide
14269              .addClass(className.animating)
14270              .css({
14271                'left'      : box.origin + 'px',
14272                'transform' : 'rotateY(-180deg)'
14273              })
14274            ;
14275          }
14276        },
14277        setting: function(name, value) {
14278          module.debug('Changing setting', name, value);
14279          if( $.isPlainObject(name) ) {
14280            $.extend(true, settings, name);
14281          }
14282          else if(value !== undefined) {
14283            settings[name] = value;
14284          }
14285          else {
14286            return settings[name];
14287          }
14288        },
14289        internal: function(name, value) {
14290          if( $.isPlainObject(name) ) {
14291            $.extend(true, module, name);
14292          }
14293          else if(value !== undefined) {
14294            module[name] = value;
14295          }
14296          else {
14297            return module[name];
14298          }
14299        },
14300        debug: function() {
14301          if(settings.debug) {
14302            if(settings.performance) {
14303              module.performance.log(arguments);
14304            }
14305            else {
14306              module.debug = Function.prototype.bind.call(console.info, console, settings.name + ':');
14307              module.debug.apply(console, arguments);
14308            }
14309          }
14310        },
14311        verbose: function() {
14312          if(settings.verbose && settings.debug) {
14313            if(settings.performance) {
14314              module.performance.log(arguments);
14315            }
14316            else {
14317              module.verbose = Function.prototype.bind.call(console.info, console, settings.name + ':');
14318              module.verbose.apply(console, arguments);
14319            }
14320          }
14321        },
14322        error: function() {
14323          module.error = Function.prototype.bind.call(console.error, console, settings.name + ':');
14324          module.error.apply(console, arguments);
14325        },
14326        performance: {
14327          log: function(message) {
14328            var
14329              currentTime,
14330              executionTime,
14331              previousTime
14332            ;
14333            if(settings.performance) {
14334              currentTime   = new Date().getTime();
14335              previousTime  = time || currentTime;
14336              executionTime = currentTime - previousTime;
14337              time          = currentTime;
14338              performance.push({
14339                'Name'           : message[0],
14340                'Arguments'      : [].slice.call(message, 1) || '',
14341                'Element'        : element,
14342                'Execution Time' : executionTime
14343              });
14344            }
14345            clearTimeout(module.performance.timer);
14346            module.performance.timer = setTimeout(module.performance.display, 500);
14347          },
14348          display: function() {
14349            var
14350              title = settings.name + ':',
14351              totalTime = 0
14352            ;
14353            time = false;
14354            clearTimeout(module.performance.timer);
14355            $.each(performance, function(index, data) {
14356              totalTime += data['Execution Time'];
14357            });
14358            title += ' ' + totalTime + 'ms';
14359            if(moduleSelector) {
14360              title += ' \'' + moduleSelector + '\'';
14361            }
14362            if($allModules.length > 1) {
14363              title += ' ' + '(' + $allModules.length + ')';
14364            }
14365            if( (console.group !== undefined || console.table !== undefined) && performance.length > 0) {
14366              console.groupCollapsed(title);
14367              if(console.table) {
14368                console.table(performance);
14369              }
14370              else {
14371                $.each(performance, function(index, data) {
14372                  console.log(data['Name'] + ': ' + data['Execution Time']+'ms');
14373                });
14374              }
14375              console.groupEnd();
14376            }
14377            performance = [];
14378          }
14379        },
14380        invoke: function(query, passedArguments, context) {
14381          var
14382            object = instance,
14383            maxDepth,
14384            found,
14385            response
14386          ;
14387          passedArguments = passedArguments || queryArguments;
14388          context         = element         || context;
14389          if(typeof query == 'string' && object !== undefined) {
14390            query    = query.split(/[\. ]/);
14391            maxDepth = query.length - 1;
14392            $.each(query, function(depth, value) {
14393              var camelCaseValue = (depth != maxDepth)
14394                ? value + query[depth + 1].charAt(0).toUpperCase() + query[depth + 1].slice(1)
14395                : query
14396              ;
14397              if( $.isPlainObject( object[camelCaseValue] ) && (depth != maxDepth) ) {
14398                object = object[camelCaseValue];
14399              }
14400              else if( object[camelCaseValue] !== undefined ) {
14401                found = object[camelCaseValue];
14402                return false;
14403              }
14404              else if( $.isPlainObject( object[value] ) && (depth != maxDepth) ) {
14405                object = object[value];
14406              }
14407              else if( object[value] !== undefined ) {
14408                found = object[value];
14409                return false;
14410              }
14411              else {
14412                return false;
14413              }
14414            });
14415          }
14416          if ( $.isFunction( found ) ) {
14417            response = found.apply(context, passedArguments);
14418          }
14419          else if(found !== undefined) {
14420            response = found;
14421          }
14422          if($.isArray(returnedValue)) {
14423            returnedValue.push(response);
14424          }
14425          else if(returnedValue !== undefined) {
14426            returnedValue = [returnedValue, response];
14427          }
14428          else if(response !== undefined) {
14429            returnedValue = response;
14430          }
14431          return found;
14432        }
14433      };
14434
14435      if(methodInvoked) {
14436        if(instance === undefined) {
14437          module.initialize();
14438        }
14439        module.invoke(query);
14440      }
14441      else {
14442        if(instance !== undefined) {
14443          instance.invoke('destroy');
14444        }
14445        module.initialize();
14446      }
14447    })
14448  ;
14449
14450  return (returnedValue !== undefined)
14451    ? returnedValue
14452    : this
14453  ;
14454};
14455
14456$.fn.shape.settings = {
14457
14458  // module info
14459  name : 'Shape',
14460
14461  // debug content outputted to console
14462  debug      : false,
14463
14464  // verbose debug output
14465  verbose    : false,
14466
14467  // performance data output
14468  performance: true,
14469
14470  // event namespace
14471  namespace  : 'shape',
14472
14473  // callback occurs on side change
14474  beforeChange : function() {},
14475  onChange     : function() {},
14476
14477  // allow animation to same side
14478  allowRepeats: false,
14479
14480  // animation duration
14481  duration   : false,
14482
14483  // possible errors
14484  error: {
14485    side   : 'You tried to switch to a side that does not exist.',
14486    method : 'The method you called is not defined'
14487  },
14488
14489  // classnames used
14490  className   : {
14491    animating : 'animating',
14492    hidden    : 'hidden',
14493    loading   : 'loading',
14494    active    : 'active'
14495  },
14496
14497  // selectors used
14498  selector    : {
14499    sides : '.sides',
14500    side  : '.side'
14501  }
14502
14503};
14504
14505
14506})( jQuery, window, document );
14507/*!
14508 * # Semantic UI 2.1.7 - Sidebar
14509 * http://github.com/semantic-org/semantic-ui/
14510 *
14511 *
14512 * Copyright 2015 Contributors
14513 * Released under the MIT license
14514 * http://opensource.org/licenses/MIT
14515 *
14516 */
14517
14518;(function ( $, window, document, undefined ) {
14519
14520"use strict";
14521
14522$.fn.sidebar = function(parameters) {
14523  var
14524    $allModules     = $(this),
14525    $window         = $(window),
14526    $document       = $(document),
14527    $html           = $('html'),
14528    $head           = $('head'),
14529
14530    moduleSelector  = $allModules.selector || '',
14531
14532    time            = new Date().getTime(),
14533    performance     = [],
14534
14535    query           = arguments[0],
14536    methodInvoked   = (typeof query == 'string'),
14537    queryArguments  = [].slice.call(arguments, 1),
14538
14539    requestAnimationFrame = window.requestAnimationFrame
14540      || window.mozRequestAnimationFrame
14541      || window.webkitRequestAnimationFrame
14542      || window.msRequestAnimationFrame
14543      || function(callback) { setTimeout(callback, 0); },
14544
14545    returnedValue
14546  ;
14547
14548  $allModules
14549    .each(function() {
14550      var
14551        settings        = ( $.isPlainObject(parameters) )
14552          ? $.extend(true, {}, $.fn.sidebar.settings, parameters)
14553          : $.extend({}, $.fn.sidebar.settings),
14554
14555        selector        = settings.selector,
14556        className       = settings.className,
14557        namespace       = settings.namespace,
14558        regExp          = settings.regExp,
14559        error           = settings.error,
14560
14561        eventNamespace  = '.' + namespace,
14562        moduleNamespace = 'module-' + namespace,
14563
14564        $module         = $(this),
14565        $context        = $(settings.context),
14566
14567        $sidebars       = $module.children(selector.sidebar),
14568        $fixed          = $context.children(selector.fixed),
14569        $pusher         = $context.children(selector.pusher),
14570        $style,
14571
14572        element         = this,
14573        instance        = $module.data(moduleNamespace),
14574
14575        elementNamespace,
14576        id,
14577        currentScroll,
14578        transitionEvent,
14579
14580        module
14581      ;
14582
14583      module      = {
14584
14585        initialize: function() {
14586          module.debug('Initializing sidebar', parameters);
14587
14588          module.create.id();
14589
14590          transitionEvent = module.get.transitionEvent();
14591
14592          if(module.is.ios()) {
14593            module.set.ios();
14594          }
vendor: 16,585 bytes, lines 14594-15072
14594
14595
14596          // avoids locking rendering if initialized in onReady
14597          if(settings.delaySetup) {
14598            requestAnimationFrame(module.setup.layout);
14599          }
14600          else {
14601            module.setup.layout();
14602          }
14603
14604          requestAnimationFrame(function() {
14605            module.setup.cache();
14606          });
14607
14608          module.instantiate();
14609        },
14610
14611        instantiate: function() {
14612          module.verbose('Storing instance of module', module);
14613          instance = module;
14614          $module
14615            .data(moduleNamespace, module)
14616          ;
14617        },
14618
14619        create: {
14620          id: function() {
14621            id = (Math.random().toString(16) + '000000000').substr(2,8);
14622            elementNamespace = '.' + id;
14623            module.verbose('Creating unique id for element', id);
14624          }
14625        },
14626
14627        destroy: function() {
14628          module.verbose('Destroying previous module for', $module);
14629          $module
14630            .off(eventNamespace)
14631            .removeData(moduleNamespace)
14632          ;
14633          if(module.is.ios()) {
14634            module.remove.ios();
14635          }
14636          // bound by uuid
14637          $context.off(elementNamespace);
14638          $window.off(elementNamespace);
14639          $document.off(elementNamespace);
14640        },
14641
14642        event: {
14643          clickaway: function(event) {
14644            var
14645              clickedInPusher = ($pusher.find(event.target).length > 0 || $pusher.is(event.target)),
14646              clickedContext  = ($context.is(event.target))
14647            ;
14648            if(clickedInPusher) {
14649              module.verbose('User clicked on dimmed page');
14650              module.hide();
14651            }
14652            if(clickedContext) {
14653              module.verbose('User clicked on dimmable context (scaled out page)');
14654              module.hide();
14655            }
14656          },
14657          touch: function(event) {
14658            //event.stopPropagation();
14659          },
14660          containScroll: function(event) {
14661            if(element.scrollTop <= 0)  {
14662              element.scrollTop = 1;
14663            }
14664            if((element.scrollTop + element.offsetHeight) >= element.scrollHeight) {
14665              element.scrollTop = element.scrollHeight - element.offsetHeight - 1;
14666            }
14667          },
14668          scroll: function(event) {
14669            if( $(event.target).closest(selector.sidebar).length === 0 ) {
14670              event.preventDefault();
14671            }
14672          }
14673        },
14674
14675        bind: {
14676          clickaway: function() {
14677            module.verbose('Adding clickaway events to context', $context);
14678            if(settings.closable) {
14679              $context
14680                .on('click'    + elementNamespace, module.event.clickaway)
14681                .on('touchend' + elementNamespace, module.event.clickaway)
14682              ;
14683            }
14684          },
14685          scrollLock: function() {
14686            if(settings.scrollLock) {
14687              module.debug('Disabling page scroll');
14688              $window
14689                .on('DOMMouseScroll' + elementNamespace, module.event.scroll)
14690              ;
14691            }
14692            module.verbose('Adding events to contain sidebar scroll');
14693            $document
14694              .on('touchmove' + elementNamespace, module.event.touch)
14695            ;
14696            $module
14697              .on('scroll' + eventNamespace, module.event.containScroll)
14698            ;
14699          }
14700        },
14701        unbind: {
14702          clickaway: function() {
14703            module.verbose('Removing clickaway events from context', $context);
14704            $context.off(elementNamespace);
14705          },
14706          scrollLock: function() {
14707            module.verbose('Removing scroll lock from page');
14708            $document.off(elementNamespace);
14709            $window.off(elementNamespace);
14710            $module.off('scroll' + eventNamespace);
14711          }
14712        },
14713
14714        add: {
14715          inlineCSS: function() {
14716            var
14717              width     = module.cache.width  || $module.outerWidth(),
14718              height    = module.cache.height || $module.outerHeight(),
14719              isRTL     = module.is.rtl(),
14720              direction = module.get.direction(),
14721              distance  = {
14722                left   : width,
14723                right  : -width,
14724                top    : height,
14725                bottom : -height
14726              },
14727              style
14728            ;
14729
14730            if(isRTL){
14731              module.verbose('RTL detected, flipping widths');
14732              distance.left = -width;
14733              distance.right = width;
14734            }
14735
14736            style  = '<style>';
14737
14738            if(direction === 'left' || direction === 'right') {
14739              module.debug('Adding CSS rules for animation distance', width);
14740              style  += ''
14741                + ' .ui.visible.' + direction + '.sidebar ~ .fixed,'
14742                + ' .ui.visible.' + direction + '.sidebar ~ .pusher {'
14743                + '   -webkit-transform: translate3d('+ distance[direction] + 'px, 0, 0);'
14744                + '           transform: translate3d('+ distance[direction] + 'px, 0, 0);'
14745                + ' }'
14746              ;
14747            }
14748            else if(direction === 'top' || direction == 'bottom') {
14749              style  += ''
14750                + ' .ui.visible.' + direction + '.sidebar ~ .fixed,'
14751                + ' .ui.visible.' + direction + '.sidebar ~ .pusher {'
14752                + '   -webkit-transform: translate3d(0, ' + distance[direction] + 'px, 0);'
14753                + '           transform: translate3d(0, ' + distance[direction] + 'px, 0);'
14754                + ' }'
14755              ;
14756            }
14757
14758            /* IE is only browser not to create context with transforms */
14759            /* https://www.w3.org/Bugs/Public/show_bug.cgi?id=16328 */
14760            if( module.is.ie() ) {
14761              if(direction === 'left' || direction === 'right') {
14762                module.debug('Adding CSS rules for animation distance', width);
14763                style  += ''
14764                  + ' body.pushable > .ui.visible.' + direction + '.sidebar ~ .pusher:after {'
14765                  + '   -webkit-transform: translate3d('+ distance[direction] + 'px, 0, 0);'
14766                  + '           transform: translate3d('+ distance[direction] + 'px, 0, 0);'
14767                  + ' }'
14768                ;
14769              }
14770              else if(direction === 'top' || direction == 'bottom') {
14771                style  += ''
14772                  + ' body.pushable > .ui.visible.' + direction + '.sidebar ~ .pusher:after {'
14773                  + '   -webkit-transform: translate3d(0, ' + distance[direction] + 'px, 0);'
14774                  + '           transform: translate3d(0, ' + distance[direction] + 'px, 0);'
14775                  + ' }'
14776                ;
14777              }
14778              /* opposite sides visible forces content overlay */
14779              style += ''
14780                + ' body.pushable > .ui.visible.left.sidebar ~ .ui.visible.right.sidebar ~ .pusher:after,'
14781                + ' body.pushable > .ui.visible.right.sidebar ~ .ui.visible.left.sidebar ~ .pusher:after {'
14782                + '   -webkit-transform: translate3d(0px, 0, 0);'
14783                + '           transform: translate3d(0px, 0, 0);'
14784                + ' }'
14785              ;
14786            }
14787            style += '</style>';
14788            $style = $(style)
14789              .appendTo($head)
14790            ;
14791            module.debug('Adding sizing css to head', $style);
14792          }
14793        },
14794
14795        refresh: function() {
14796          module.verbose('Refreshing selector cache');
14797          $context  = $(settings.context);
14798          $sidebars = $context.children(selector.sidebar);
14799          $pusher   = $context.children(selector.pusher);
14800          $fixed    = $context.children(selector.fixed);
14801          module.clear.cache();
14802        },
14803
14804        refreshSidebars: function() {
14805          module.verbose('Refreshing other sidebars');
14806          $sidebars = $context.children(selector.sidebar);
14807        },
14808
14809        repaint: function() {
14810          module.verbose('Forcing repaint event');
14811          element.style.display = 'none';
14812          var ignored = element.offsetHeight;
14813          element.scrollTop = element.scrollTop;
14814          element.style.display = '';
14815        },
14816
14817        setup: {
14818          cache: function() {
14819            module.cache = {
14820              width  : $module.outerWidth(),
14821              height : $module.outerHeight(),
14822              rtl    : ($module.css('direction') == 'rtl')
14823            };
14824          },
14825          layout: function() {
14826            if( $context.children(selector.pusher).length === 0 ) {
14827              module.debug('Adding wrapper element for sidebar');
14828              module.error(error.pusher);
14829              $pusher = $('<div class="pusher" />');
14830              $context
14831                .children()
14832                  .not(selector.omitted)
14833                  .not($sidebars)
14834                  .wrapAll($pusher)
14835              ;
14836              module.refresh();
14837            }
14838            if($module.nextAll(selector.pusher).length === 0 || $module.nextAll(selector.pusher)[0] !== $pusher[0]) {
14839              module.debug('Moved sidebar to correct parent element');
14840              module.error(error.movedSidebar, element);
14841              $module.detach().prependTo($context);
14842              module.refresh();
14843            }
14844            module.clear.cache();
14845            module.set.pushable();
14846            module.set.direction();
14847          }
14848        },
14849
14850        attachEvents: function(selector, event) {
14851          var
14852            $toggle = $(selector)
14853          ;
14854          event = $.isFunction(module[event])
14855            ? module[event]
14856            : module.toggle
14857          ;
14858          if($toggle.length > 0) {
14859            module.debug('Attaching sidebar events to element', selector, event);
14860            $toggle
14861              .on('click' + eventNamespace, event)
14862            ;
14863          }
14864          else {
14865            module.error(error.notFound, selector);
14866          }
14867        },
14868
14869        show: function(callback) {
14870          callback = $.isFunction(callback)
14871            ? callback
14872            : function(){}
14873          ;
14874          if(module.is.hidden()) {
14875            module.refreshSidebars();
14876            if(settings.overlay)  {
14877              module.error(error.overlay);
14878              settings.transition = 'overlay';
14879            }
14880            module.refresh();
14881            if(module.othersActive()) {
14882              module.debug('Other sidebars currently visible');
14883              if(settings.exclusive) {
14884                // if not overlay queue animation after hide
14885                if(settings.transition != 'overlay') {
14886                  module.hideOthers(module.show);
14887                  return;
14888                }
14889                else {
14890                  module.hideOthers();
14891                }
14892              }
14893              else {
14894                settings.transition = 'overlay';
14895              }
14896            }
14897            module.pushPage(function() {
14898              callback.call(element);
14899              settings.onShow.call(element);
14900            });
14901            settings.onChange.call(element);
14902            settings.onVisible.call(element);
14903          }
14904          else {
14905            module.debug('Sidebar is already visible');
14906          }
14907        },
14908
14909        hide: function(callback) {
14910          callback = $.isFunction(callback)
14911            ? callback
14912            : function(){}
14913          ;
14914          if(module.is.visible() || module.is.animating()) {
14915            module.debug('Hiding sidebar', callback);
14916            module.refreshSidebars();
14917            module.pullPage(function() {
14918              callback.call(element);
14919              settings.onHidden.call(element);
14920            });
14921            settings.onChange.call(element);
14922            settings.onHide.call(element);
14923          }
14924        },
14925
14926        othersAnimating: function() {
14927          return ($sidebars.not($module).filter('.' + className.animating).length > 0);
14928        },
14929        othersVisible: function() {
14930          return ($sidebars.not($module).filter('.' + className.visible).length > 0);
14931        },
14932        othersActive: function() {
14933          return(module.othersVisible() || module.othersAnimating());
14934        },
14935
14936        hideOthers: function(callback) {
14937          var
14938            $otherSidebars = $sidebars.not($module).filter('.' + className.visible),
14939            sidebarCount   = $otherSidebars.length,
14940            callbackCount  = 0
14941          ;
14942          callback = callback || function(){};
14943          $otherSidebars
14944            .sidebar('hide', function() {
14945              callbackCount++;
14946              if(callbackCount == sidebarCount) {
14947                callback();
14948              }
14949            })
14950          ;
14951        },
14952
14953        toggle: function() {
14954          module.verbose('Determining toggled direction');
14955          if(module.is.hidden()) {
14956            module.show();
14957          }
14958          else {
14959            module.hide();
14960          }
14961        },
14962
14963        pushPage: function(callback) {
14964          var
14965            transition = module.get.transition(),
14966            $transition = (transition === 'overlay' || module.othersActive())
14967              ? $module
14968              : $pusher,
14969            animate,
14970            dim,
14971            transitionEnd
14972          ;
14973          callback = $.isFunction(callback)
14974            ? callback
14975            : function(){}
14976          ;
14977          if(settings.transition == 'scale down') {
14978            module.scrollToTop();
14979          }
14980          module.set.transition(transition);
14981          module.repaint();
14982          animate = function() {
14983            module.bind.clickaway();
14984            module.add.inlineCSS();
14985            module.set.animating();
14986            module.set.visible();
14987          };
14988          dim = function() {
14989            module.set.dimmed();
14990          };
14991          transitionEnd = function(event) {
14992            if( event.target == $transition[0] ) {
14993              $transition.off(transitionEvent + elementNamespace, transitionEnd);
14994              module.remove.animating();
14995              module.bind.scrollLock();
14996              callback.call(element);
14997            }
14998          };
14999          $transition.off(transitionEvent + elementNamespace);
15000          $transition.on(transitionEvent + elementNamespace, transitionEnd);
15001          requestAnimationFrame(animate);
15002          if(settings.dimPage && !module.othersVisible()) {
15003            requestAnimationFrame(dim);
15004          }
15005        },
15006
15007        pullPage: function(callback) {
15008          var
15009            transition = module.get.transition(),
15010            $transition = (transition == 'overlay' || module.othersActive())
15011              ? $module
15012              : $pusher,
15013            animate,
15014            transitionEnd
15015          ;
15016          callback = $.isFunction(callback)
15017            ? callback
15018            : function(){}
15019          ;
15020          module.verbose('Removing context push state', module.get.direction());
15021
15022          module.unbind.clickaway();
15023          module.unbind.scrollLock();
15024
15025          animate = function() {
15026            module.set.transition(transition);
15027            module.set.animating();
15028            module.remove.visible();
15029            if(settings.dimPage && !module.othersVisible()) {
15030              $pusher.removeClass(className.dimmed);
15031            }
15032          };
15033          transitionEnd = function(event) {
15034            if( event.target == $transition[0] ) {
15035              $transition.off(transitionEvent + elementNamespace, transitionEnd);
15036              module.remove.animating();
15037              module.remove.transition();
15038              module.remove.inlineCSS();
15039              if(transition == 'scale down' || (settings.returnScroll && module.is.mobile()) ) {
15040                module.scrollBack();
15041              }
15042              callback.call(element);
15043            }
15044          };
15045          $transition.off(transitionEvent + elementNamespace);
15046          $transition.on(transitionEvent + elementNamespace, transitionEnd);
15047          requestAnimationFrame(animate);
15048        },
15049
15050        scrollToTop: function() {
15051          module.verbose('Scrolling to top of page to avoid animation issues');
15052          currentScroll = $(window).scrollTop();
15053          $module.scrollTop(0);
15054          window.scrollTo(0, 0);
15055        },
15056
15057        scrollBack: function() {
15058          module.verbose('Scrolling back to original page position');
15059          window.scrollTo(0, currentScroll);
15060        },
15061
15062        clear: {
15063          cache: function() {
15064            module.verbose('Clearing cached dimensions');
15065            module.cache = {};
15066          }
15067        },
15068
15069        set: {
15070
15071          // ios only (scroll on html not document). This prevent auto-resize canvas/scroll in ios
15072          
vendor: 3,083 bytes, lines 15072-15174
15072ios: function() {
15073            $html.addClass(className.ios);
15074          },
15075
15076          // container
15077          pushed: function() {
15078            $context.addClass(className.pushed);
15079          },
15080          pushable: function() {
15081            $context.addClass(className.pushable);
15082          },
15083
15084          // pusher
15085          dimmed: function() {
15086            $pusher.addClass(className.dimmed);
15087          },
15088
15089          // sidebar
15090          active: function() {
15091            $module.addClass(className.active);
15092          },
15093          animating: function() {
15094            $module.addClass(className.animating);
15095          },
15096          transition: function(transition) {
15097            transition = transition || module.get.transition();
15098            $module.addClass(transition);
15099          },
15100          direction: function(direction) {
15101            direction = direction || module.get.direction();
15102            $module.addClass(className[direction]);
15103          },
15104          visible: function() {
15105            $module.addClass(className.visible);
15106          },
15107          overlay: function() {
15108            $module.addClass(className.overlay);
15109          }
15110        },
15111        remove: {
15112
15113          inlineCSS: function() {
15114            module.debug('Removing inline css styles', $style);
15115            if($style && $style.length > 0) {
15116              $style.remove();
15117            }
15118          },
15119
15120          // ios scroll on html not document
15121          ios: function() {
15122            $html.removeClass(className.ios);
15123          },
15124
15125          // context
15126          pushed: function() {
15127            $context.removeClass(className.pushed);
15128          },
15129          pushable: function() {
15130            $context.removeClass(className.pushable);
15131          },
15132
15133          // sidebar
15134          active: function() {
15135            $module.removeClass(className.active);
15136          },
15137          animating: function() {
15138            $module.removeClass(className.animating);
15139          },
15140          transition: function(transition) {
15141            transition = transition || module.get.transition();
15142            $module.removeClass(transition);
15143          },
15144          direction: function(direction) {
15145            direction = direction || module.get.direction();
15146            $module.removeClass(className[direction]);
15147          },
15148          visible: function() {
15149            $module.removeClass(className.visible);
15150          },
15151          overlay: function() {
15152            $module.removeClass(className.overlay);
15153          }
15154        },
15155
15156        get: {
15157          direction: function() {
15158            if($module.hasClass(className.top)) {
15159              return className.top;
15160            }
15161            else if($module.hasClass(className.right)) {
15162              return className.right;
15163            }
15164            else if($module.hasClass(className.bottom)) {
15165              return className.bottom;
15166            }
15167            return className.left;
15168          },
15169          transition: function() {
15170            var
15171              direction = module.get.direction(),
15172              transition
15173            ;
15174            transition = ( module.is.mobile() )
vendor: 15,106 bytes, lines 15175-15670
15175              ? (settings.mobileTransition == 'auto')
15176                ? settings.defaultTransition.mobile[direction]
15177                : settings.mobileTransition
15178              : (settings.transition == 'auto')
15179                ? settings.defaultTransition.computer[direction]
15180                : settings.transition
15181            ;
15182            module.verbose('Determined transition', transition);
15183            return transition;
15184          },
15185          transitionEvent: function() {
15186            var
15187              element     = document.createElement('element'),
15188              transitions = {
15189                'transition'       :'transitionend',
15190                'OTransition'      :'oTransitionEnd',
15191                'MozTransition'    :'transitionend',
15192                'WebkitTransition' :'webkitTransitionEnd'
15193              },
15194              transition
15195            ;
15196            for(transition in transitions){
15197              if( element.style[transition] !== undefined ){
15198                return transitions[transition];
15199              }
15200            }
15201          }
15202        },
15203
15204        is: {
15205
15206          ie: function() {
15207            var
15208              isIE11 = (!(window.ActiveXObject) && 'ActiveXObject' in window),
15209              isIE   = ('ActiveXObject' in window)
15210            ;
15211            return (isIE11 || isIE);
15212          },
15213
15214          ios: function() {
15215            var
15216              userAgent      = navigator.userAgent,
15217              isIOS          = userAgent.match(regExp.ios),
15218              isMobileChrome = userAgent.match(regExp.mobileChrome)
15219            ;
15220            if(isIOS && !isMobileChrome) {
15221              module.verbose('Browser was found to be iOS', userAgent);
15222              return true;
15223            }
15224            else {
15225              return false;
15226            }
15227          },
15228          mobile: function() {
15229            var
15230              userAgent    = navigator.userAgent,
15231              isMobile     = userAgent.match(regExp.mobile)
15232            ;
15233            if(isMobile) {
15234              module.verbose('Browser was found to be mobile', userAgent);
15235              return true;
15236            }
15237            else {
15238              module.verbose('Browser is not mobile, using regular transition', userAgent);
15239              return false;
15240            }
15241          },
15242          hidden: function() {
15243            return !module.is.visible();
15244          },
15245          visible: function() {
15246            return $module.hasClass(className.visible);
15247          },
15248          // alias
15249          open: function() {
15250            return module.is.visible();
15251          },
15252          closed: function() {
15253            return module.is.hidden();
15254          },
15255          vertical: function() {
15256            return $module.hasClass(className.top);
15257          },
15258          animating: function() {
15259            return $context.hasClass(className.animating);
15260          },
15261          rtl: function () {
15262            if(module.cache.rtl === undefined) {
15263              module.cache.rtl = ($module.css('direction') == 'rtl');
15264            }
15265            return module.cache.rtl;
15266          }
15267        },
15268
15269        setting: function(name, value) {
15270          module.debug('Changing setting', name, value);
15271          if( $.isPlainObject(name) ) {
15272            $.extend(true, settings, name);
15273          }
15274          else if(value !== undefined) {
15275            settings[name] = value;
15276          }
15277          else {
15278            return settings[name];
15279          }
15280        },
15281        internal: function(name, value) {
15282          if( $.isPlainObject(name) ) {
15283            $.extend(true, module, name);
15284          }
15285          else if(value !== undefined) {
15286            module[name] = value;
15287          }
15288          else {
15289            return module[name];
15290          }
15291        },
15292        debug: function() {
15293          if(settings.debug) {
15294            if(settings.performance) {
15295              module.performance.log(arguments);
15296            }
15297            else {
15298              module.debug = Function.prototype.bind.call(console.info, console, settings.name + ':');
15299              module.debug.apply(console, arguments);
15300            }
15301          }
15302        },
15303        verbose: function() {
15304          if(settings.verbose && settings.debug) {
15305            if(settings.performance) {
15306              module.performance.log(arguments);
15307            }
15308            else {
15309              module.verbose = Function.prototype.bind.call(console.info, console, settings.name + ':');
15310              module.verbose.apply(console, arguments);
15311            }
15312          }
15313        },
15314        error: function() {
15315          module.error = Function.prototype.bind.call(console.error, console, settings.name + ':');
15316          module.error.apply(console, arguments);
15317        },
15318        performance: {
15319          log: function(message) {
15320            var
15321              currentTime,
15322              executionTime,
15323              previousTime
15324            ;
15325            if(settings.performance) {
15326              currentTime   = new Date().getTime();
15327              previousTime  = time || currentTime;
15328              executionTime = currentTime - previousTime;
15329              time          = currentTime;
15330              performance.push({
15331                'Name'           : message[0],
15332                'Arguments'      : [].slice.call(message, 1) || '',
15333                'Element'        : element,
15334                'Execution Time' : executionTime
15335              });
15336            }
15337            clearTimeout(module.performance.timer);
15338            module.performance.timer = setTimeout(module.performance.display, 500);
15339          },
15340          display: function() {
15341            var
15342              title = settings.name + ':',
15343              totalTime = 0
15344            ;
15345            time = false;
15346            clearTimeout(module.performance.timer);
15347            $.each(performance, function(index, data) {
15348              totalTime += data['Execution Time'];
15349            });
15350            title += ' ' + totalTime + 'ms';
15351            if(moduleSelector) {
15352              title += ' \'' + moduleSelector + '\'';
15353            }
15354            if( (console.group !== undefined || console.table !== undefined) && performance.length > 0) {
15355              console.groupCollapsed(title);
15356              if(console.table) {
15357                console.table(performance);
15358              }
15359              else {
15360                $.each(performance, function(index, data) {
15361                  console.log(data['Name'] + ': ' + data['Execution Time']+'ms');
15362                });
15363              }
15364              console.groupEnd();
15365            }
15366            performance = [];
15367          }
15368        },
15369        invoke: function(query, passedArguments, context) {
15370          var
15371            object = instance,
15372            maxDepth,
15373            found,
15374            response
15375          ;
15376          passedArguments = passedArguments || queryArguments;
15377          context         = element         || context;
15378          if(typeof query == 'string' && object !== undefined) {
15379            query    = query.split(/[\. ]/);
15380            maxDepth = query.length - 1;
15381            $.each(query, function(depth, value) {
15382              var camelCaseValue = (depth != maxDepth)
15383                ? value + query[depth + 1].charAt(0).toUpperCase() + query[depth + 1].slice(1)
15384                : query
15385              ;
15386              if( $.isPlainObject( object[camelCaseValue] ) && (depth != maxDepth) ) {
15387                object = object[camelCaseValue];
15388              }
15389              else if( object[camelCaseValue] !== undefined ) {
15390                found = object[camelCaseValue];
15391                return false;
15392              }
15393              else if( $.isPlainObject( object[value] ) && (depth != maxDepth) ) {
15394                object = object[value];
15395              }
15396              else if( object[value] !== undefined ) {
15397                found = object[value];
15398                return false;
15399              }
15400              else {
15401                module.error(error.method, query);
15402                return false;
15403              }
15404            });
15405          }
15406          if ( $.isFunction( found ) ) {
15407            response = found.apply(context, passedArguments);
15408          }
15409          else if(found !== undefined) {
15410            response = found;
15411          }
15412          if($.isArray(returnedValue)) {
15413            returnedValue.push(response);
15414          }
15415          else if(returnedValue !== undefined) {
15416            returnedValue = [returnedValue, response];
15417          }
15418          else if(response !== undefined) {
15419            returnedValue = response;
15420          }
15421          return found;
15422        }
15423      }
15424    ;
15425
15426    if(methodInvoked) {
15427      if(instance === undefined) {
15428        module.initialize();
15429      }
15430      module.invoke(query);
15431    }
15432    else {
15433      if(instance !== undefined) {
15434        module.invoke('destroy');
15435      }
15436      module.initialize();
15437    }
15438  });
15439
15440  return (returnedValue !== undefined)
15441    ? returnedValue
15442    : this
15443  ;
15444};
15445
15446$.fn.sidebar.settings = {
15447
15448  name              : 'Sidebar',
15449  namespace         : 'sidebar',
15450
15451  debug             : false,
15452  verbose           : false,
15453  performance       : true,
15454
15455  transition        : 'auto',
15456  mobileTransition  : 'auto',
15457
15458  defaultTransition : {
15459    computer: {
15460      left   : 'uncover',
15461      right  : 'uncover',
15462      top    : 'overlay',
15463      bottom : 'overlay'
15464    },
15465    mobile: {
15466      left   : 'uncover',
15467      right  : 'uncover',
15468      top    : 'overlay',
15469      bottom : 'overlay'
15470    }
15471  },
15472
15473  context           : 'body',
15474  exclusive         : false,
15475  closable          : true,
15476  dimPage           : true,
15477  scrollLock        : false,
15478  returnScroll      : false,
15479  delaySetup        : false,
15480
15481  duration          : 500,
15482
15483  onChange          : function(){},
15484  onShow            : function(){},
15485  onHide            : function(){},
15486
15487  onHidden          : function(){},
15488  onVisible         : function(){},
15489
15490  className         : {
15491    active    : 'active',
15492    animating : 'animating',
15493    dimmed    : 'dimmed',
15494    ios       : 'ios',
15495    pushable  : 'pushable',
15496    pushed    : 'pushed',
15497    right     : 'right',
15498    top       : 'top',
15499    left      : 'left',
15500    bottom    : 'bottom',
15501    visible   : 'visible'
15502  },
15503
15504  selector: {
15505    fixed   : '.fixed',
15506    omitted : 'script, link, style, .ui.modal, .ui.dimmer, .ui.nag, .ui.fixed',
15507    pusher  : '.pusher',
15508    sidebar : '.ui.sidebar'
15509  },
15510
15511  regExp: {
15512    ios          : /(iPad|iPhone|iPod)/g,
15513    mobileChrome : /(CriOS)/g,
15514    mobile       : /Mobile|iP(hone|od|ad)|Android|BlackBerry|IEMobile|Kindle|NetFront|Silk-Accelerated|(hpw|web)OS|Fennec|Minimo|Opera M(obi|ini)|Blazer|Dolfin|Dolphin|Skyfire|Zune/g
15515  },
15516
15517  error   : {
15518    method       : 'The method you called is not defined.',
15519    pusher       : 'Had to add pusher element. For optimal performance make sure body content is inside a pusher element',
15520    movedSidebar : 'Had to move sidebar. For optimal performance make sure sidebar and pusher are direct children of your body tag',
15521    overlay      : 'The overlay setting is no longer supported, use animation: overlay',
15522    notFound     : 'There were no elements that matched the specified selector'
15523  }
15524
15525};
15526
15527
15528})( jQuery, window, document );
15529
15530/*!
15531 * # Semantic UI 2.1.7 - Sticky
15532 * http://github.com/semantic-org/semantic-ui/
15533 *
15534 *
15535 * Copyright 2015 Contributors
15536 * Released under the MIT license
15537 * http://opensource.org/licenses/MIT
15538 *
15539 */
15540
15541;(function ( $, window, document, undefined ) {
15542
15543"use strict";
15544
15545$.fn.sticky = function(parameters) {
15546  var
15547    $allModules    = $(this),
15548    moduleSelector = $allModules.selector || '',
15549
15550    time           = new Date().getTime(),
15551    performance    = [],
15552
15553    query          = arguments[0],
15554    methodInvoked  = (typeof query == 'string'),
15555    queryArguments = [].slice.call(arguments, 1),
15556    returnedValue
15557  ;
15558
15559  $allModules
15560    .each(function() {
15561      var
15562        settings              = ( $.isPlainObject(parameters) )
15563          ? $.extend(true, {}, $.fn.sticky.settings, parameters)
15564          : $.extend({}, $.fn.sticky.settings),
15565
15566        className             = settings.className,
15567        namespace             = settings.namespace,
15568        error                 = settings.error,
15569
15570        eventNamespace        = '.' + namespace,
15571        moduleNamespace       = 'module-' + namespace,
15572
15573        $module               = $(this),
15574        $window               = $(window),
15575        $scroll               = $(settings.scrollContext),
15576        $container,
15577        $context,
15578
15579        selector              = $module.selector || '',
15580        instance              = $module.data(moduleNamespace),
15581
15582        requestAnimationFrame = window.requestAnimationFrame
15583          || window.mozRequestAnimationFrame
15584          || window.webkitRequestAnimationFrame
15585          || window.msRequestAnimationFrame
15586          || function(callback) { setTimeout(callback, 0); },
15587
15588        element         = this,
15589        observer,
15590        module
15591      ;
15592
15593      module      = {
15594
15595        initialize: function() {
15596
15597          module.determineContainer();
15598          module.determineContext();
15599          module.verbose('Initializing sticky', settings, $container);
15600
15601          module.save.positions();
15602          module.checkErrors();
15603          module.bind.events();
15604
15605          if(settings.observeChanges) {
15606            module.observeChanges();
15607          }
15608          module.instantiate();
15609        },
15610
15611        instantiate: function() {
15612          module.verbose('Storing instance of module', module);
15613          instance = module;
15614          $module
15615            .data(moduleNamespace, module)
15616          ;
15617        },
15618
15619        destroy: function() {
15620          module.verbose('Destroying previous instance');
15621          module.reset();
15622          if(observer) {
15623            observer.disconnect();
15624          }
15625          $window
15626            .off('load' + eventNamespace, module.event.load)
15627            .off('resize' + eventNamespace, module.event.resize)
15628          ;
15629          $scroll
15630            .off('scrollchange' + eventNamespace, module.event.scrollchange)
15631          ;
15632          $module.removeData(moduleNamespace);
15633        },
15634
15635        observeChanges: function() {
15636          var
15637            context = $context[0]
15638          ;
15639          if('MutationObserver' in window) {
15640            observer = new MutationObserver(function(mutations) {
15641              clearTimeout(module.timer);
15642              module.timer = setTimeout(function() {
15643                module.verbose('DOM tree modified, updating sticky menu', mutations);
15644                module.refresh();
15645              }, 100);
15646            });
15647            observer.observe(element, {
15648              childList : true,
15649              subtree   : true
15650            });
15651            observer.observe(context, {
15652              childList : true,
15653              subtree   : true
15654            });
15655            module.debug('Setting up mutation observer', observer);
15656          }
15657        },
15658
15659        determineContainer: function() {
15660          $container = $module.offsetParent();
15661        },
15662
15663        determineContext: function() {
15664          if(settings.context) {
15665            $context = $(settings.context);
15666          }
15667          else {
15668            $context = $container;
15669          }
15670          if($context.length === 0) {
vendor: 9,868 bytes, lines 15671-15968
15671            module.error(error.invalidContext, settings.context, $module);
15672            return;
15673          }
15674        },
15675
15676        checkErrors: function() {
15677          if( module.is.hidden() ) {
15678            module.error(error.visible, $module);
15679          }
15680          if(module.cache.element.height > module.cache.context.height) {
15681            module.reset();
15682            module.error(error.elementSize, $module);
15683            return;
15684          }
15685        },
15686
15687        bind: {
15688          events: function() {
15689            $window
15690              .on('load' + eventNamespace, module.event.load)
15691              .on('resize' + eventNamespace, module.event.resize)
15692            ;
15693            // pub/sub pattern
15694            $scroll
15695              .off('scroll' + eventNamespace)
15696              .on('scroll' + eventNamespace, module.event.scroll)
15697              .on('scrollchange' + eventNamespace, module.event.scrollchange)
15698            ;
15699          }
15700        },
15701
15702        event: {
15703          load: function() {
15704            module.verbose('Page contents finished loading');
15705            requestAnimationFrame(module.refresh);
15706          },
15707          resize: function() {
15708            module.verbose('Window resized');
15709            requestAnimationFrame(module.refresh);
15710          },
15711          scroll: function() {
15712            requestAnimationFrame(function() {
15713              $scroll.triggerHandler('scrollchange' + eventNamespace, $scroll.scrollTop() );
15714            });
15715          },
15716          scrollchange: function(event, scrollPosition) {
15717            module.stick(scrollPosition);
15718            settings.onScroll.call(element);
15719          }
15720        },
15721
15722        refresh: function(hardRefresh) {
15723          module.reset();
15724          if(!settings.context) {
15725            module.determineContext();
15726          }
15727          if(hardRefresh) {
15728            module.determineContainer();
15729          }
15730          module.save.positions();
15731          module.stick();
15732          settings.onReposition.call(element);
15733        },
15734
15735        supports: {
15736          sticky: function() {
15737            var
15738              $element = $('<div/>'),
15739              element = $element[0]
15740            ;
15741            $element.addClass(className.supported);
15742            return($element.css('position').match('sticky'));
15743          }
15744        },
15745
15746        save: {
15747          lastScroll: function(scroll) {
15748            module.lastScroll = scroll;
15749          },
15750          elementScroll: function(scroll) {
15751            module.elementScroll = scroll;
15752          },
15753          positions: function() {
15754            var
15755              scrollContext = {
15756                height : $scroll.height()
15757              },
15758              element = {
15759                margin: {
15760                  top    : parseInt($module.css('margin-top'), 10),
15761                  bottom : parseInt($module.css('margin-bottom'), 10),
15762                },
15763                offset : $module.offset(),
15764                width  : $module.outerWidth(),
15765                height : $module.outerHeight()
15766              },
15767              context = {
15768                offset : $context.offset(),
15769                height : $context.outerHeight()
15770              },
15771              container = {
15772                height: $container.outerHeight()
15773              }
15774            ;
15775            if( !module.is.standardScroll() ) {
15776              module.debug('Non-standard scroll. Removing scroll offset from element offset');
15777
15778              scrollContext.top  = $scroll.scrollTop();
15779              scrollContext.left = $scroll.scrollLeft();
15780
15781              element.offset.top  += scrollContext.top;
15782              context.offset.top  += scrollContext.top;
15783              element.offset.left += scrollContext.left;
15784              context.offset.left += scrollContext.left;
15785            }
15786            module.cache = {
15787              fits : ( element.height < scrollContext.height ),
15788              scrollContext : {
15789                height : scrollContext.height
15790              },
15791              element: {
15792                margin : element.margin,
15793                top    : element.offset.top - element.margin.top,
15794                left   : element.offset.left,
15795                width  : element.width,
15796                height : element.height,
15797                bottom : element.offset.top + element.height
15798              },
15799              context: {
15800                top           : context.offset.top,
15801                height        : context.height,
15802                bottom        : context.offset.top + context.height
15803              }
15804            };
15805            module.set.containerSize();
15806            module.set.size();
15807            module.stick();
15808            module.debug('Caching element positions', module.cache);
15809          }
15810        },
15811
15812        get: {
15813          direction: function(scroll) {
15814            var
15815              direction = 'down'
15816            ;
15817            scroll = scroll || $scroll.scrollTop();
15818            if(module.lastScroll !== undefined) {
15819              if(module.lastScroll < scroll) {
15820                direction = 'down';
15821              }
15822              else if(module.lastScroll > scroll) {
15823                direction = 'up';
15824              }
15825            }
15826            return direction;
15827          },
15828          scrollChange: function(scroll) {
15829            scroll = scroll || $scroll.scrollTop();
15830            return (module.lastScroll)
15831              ? (scroll - module.lastScroll)
15832              : 0
15833            ;
15834          },
15835          currentElementScroll: function() {
15836            if(module.elementScroll) {
15837              return module.elementScroll;
15838            }
15839            return ( module.is.top() )
15840              ? Math.abs(parseInt($module.css('top'), 10))    || 0
15841              : Math.abs(parseInt($module.css('bottom'), 10)) || 0
15842            ;
15843          },
15844
15845          elementScroll: function(scroll) {
15846            scroll = scroll || $scroll.scrollTop();
15847            var
15848              element        = module.cache.element,
15849              scrollContext  = module.cache.scrollContext,
15850              delta          = module.get.scrollChange(scroll),
15851              maxScroll      = (element.height - scrollContext.height + settings.offset),
15852              elementScroll  = module.get.currentElementScroll(),
15853              possibleScroll = (elementScroll + delta)
15854            ;
15855            if(module.cache.fits || possibleScroll < 0) {
15856              elementScroll = 0;
15857            }
15858            else if(possibleScroll > maxScroll ) {
15859              elementScroll = maxScroll;
15860            }
15861            else {
15862              elementScroll = possibleScroll;
15863            }
15864            return elementScroll;
15865          }
15866        },
15867
15868        remove: {
15869          lastScroll: function() {
15870            delete module.lastScroll;
15871          },
15872          elementScroll: function(scroll) {
15873            delete module.elementScroll;
15874          },
15875          offset: function() {
15876            $module.css('margin-top', '');
15877          }
15878        },
15879
15880        set: {
15881          offset: function() {
15882            module.verbose('Setting offset on element', settings.offset);
15883            $module
15884              .css('margin-top', settings.offset)
15885            ;
15886          },
15887          containerSize: function() {
15888            var
15889              tagName = $container.get(0).tagName
15890            ;
15891            if(tagName === 'HTML' || tagName == 'body') {
15892              // this can trigger for too many reasons
15893              //module.error(error.container, tagName, $module);
15894              module.determineContainer();
15895            }
15896            else {
15897              if( Math.abs($container.outerHeight() - module.cache.context.height) > settings.jitter) {
15898                module.debug('Context has padding, specifying exact height for container', module.cache.context.height);
15899                $container.css({
15900                  height: module.cache.context.height
15901                });
15902              }
15903            }
15904          },
15905          minimumSize: function() {
15906            var
15907              element   = module.cache.element
15908            ;
15909            $container
15910              .css('min-height', element.height)
15911            ;
15912          },
15913          scroll: function(scroll) {
15914            module.debug('Setting scroll on element', scroll);
15915            if(module.elementScroll == scroll) {
15916              return;
15917            }
15918            if( module.is.top() ) {
15919              $module
15920                .css('bottom', '')
15921                .css('top', -scroll)
15922              ;
15923            }
15924            if( module.is.bottom() ) {
15925              $module
15926                .css('top', '')
15927                .css('bottom', scroll)
15928              ;
15929            }
15930          },
15931          size: function() {
15932            if(module.cache.element.height !== 0 && module.cache.element.width !== 0) {
15933              element.style.setProperty('width',  module.cache.element.width  + 'px', 'important');
15934              element.style.setProperty('height', module.cache.element.height + 'px', 'important');
15935            }
15936          }
15937        },
15938
15939        is: {
15940          standardScroll: function() {
15941            return ($scroll[0] == window);
15942          },
15943          top: function() {
15944            return $module.hasClass(className.top);
15945          },
15946          bottom: function() {
15947            return $module.hasClass(className.bottom);
15948          },
15949          initialPosition: function() {
15950            return (!module.is.fixed() && !module.is.bound());
15951          },
15952          hidden: function() {
15953            return (!$module.is(':visible'));
15954          },
15955          bound: function() {
15956            return $module.hasClass(className.bound);
15957          },
15958          fixed: function() {
15959            return $module.hasClass(className.fixed);
15960          }
15961        },
15962
15963        stick: function(scroll) {
15964          var
15965            cachedPosition = scroll || $scroll.scrollTop(),
15966            cache          = module.cache,
15967            fits           = cache.fits,
15968            element        = cache.element,
vendor: 14,934 bytes, lines 15969-16426
15969            scrollContext  = cache.scrollContext,
15970            context        = cache.context,
15971            offset         = (module.is.bottom() && settings.pushing)
15972              ? settings.bottomOffset
15973              : settings.offset,
15974            scroll         = {
15975              top    : cachedPosition + offset,
15976              bottom : cachedPosition + offset + scrollContext.height
15977            },
15978            direction      = module.get.direction(scroll.top),
15979            elementScroll  = (fits)
15980              ? 0
15981              : module.get.elementScroll(scroll.top),
15982
15983            // shorthand
15984            doesntFit      = !fits,
15985            elementVisible = (element.height !== 0)
15986          ;
15987
15988          if(elementVisible) {
15989
15990            if( module.is.initialPosition() ) {
15991              if(scroll.top >= context.bottom) {
15992                module.debug('Initial element position is bottom of container');
15993                module.bindBottom();
15994              }
15995              else if(scroll.top > element.top) {
15996                if( (element.height + scroll.top - elementScroll) >= context.bottom ) {
15997                  module.debug('Initial element position is bottom of container');
15998                  module.bindBottom();
15999                }
16000                else {
16001                  module.debug('Initial element position is fixed');
16002                  module.fixTop();
16003                }
16004              }
16005
16006            }
16007            else if( module.is.fixed() ) {
16008
16009              // currently fixed top
16010              if( module.is.top() ) {
16011                if( scroll.top <= element.top ) {
16012                  module.debug('Fixed element reached top of container');
16013                  module.setInitialPosition();
16014                }
16015                else if( (element.height + scroll.top - elementScroll) >= context.bottom ) {
16016                  module.debug('Fixed element reached bottom of container');
16017                  module.bindBottom();
16018                }
16019                // scroll element if larger than screen
16020                else if(doesntFit) {
16021                  module.set.scroll(elementScroll);
16022                  module.save.lastScroll(scroll.top);
16023                  module.save.elementScroll(elementScroll);
16024                }
16025              }
16026
16027              // currently fixed bottom
16028              else if(module.is.bottom() ) {
16029
16030                // top edge
16031                if( (scroll.bottom - element.height) <= element.top) {
16032                  module.debug('Bottom fixed rail has reached top of container');
16033                  module.setInitialPosition();
16034                }
16035                // bottom edge
16036                else if(scroll.bottom >= context.bottom) {
16037                  module.debug('Bottom fixed rail has reached bottom of container');
16038                  module.bindBottom();
16039                }
16040                // scroll element if larger than screen
16041                else if(doesntFit) {
16042                  module.set.scroll(elementScroll);
16043                  module.save.lastScroll(scroll.top);
16044                  module.save.elementScroll(elementScroll);
16045                }
16046
16047              }
16048            }
16049            else if( module.is.bottom() ) {
16050              if( scroll.top <= element.top ) {
16051                module.debug('Jumped from bottom fixed to top fixed, most likely used home/end button');
16052                module.setInitialPosition();
16053              }
16054              else {
16055                if(settings.pushing) {
16056                  if(module.is.bound() && scroll.bottom <= context.bottom ) {
16057                    module.debug('Fixing bottom attached element to bottom of browser.');
16058                    module.fixBottom();
16059                  }
16060                }
16061                else {
16062                  if(module.is.bound() && (scroll.top <= context.bottom - element.height) ) {
16063                    module.debug('Fixing bottom attached element to top of browser.');
16064                    module.fixTop();
16065                  }
16066                }
16067              }
16068            }
16069          }
16070        },
16071
16072        bindTop: function() {
16073          module.debug('Binding element to top of parent container');
16074          module.remove.offset();
16075          $module
16076            .css({
16077              left         : '',
16078              top          : '',
16079              marginBottom : ''
16080            })
16081            .removeClass(className.fixed)
16082            .removeClass(className.bottom)
16083            .addClass(className.bound)
16084            .addClass(className.top)
16085          ;
16086          settings.onTop.call(element);
16087          settings.onUnstick.call(element);
16088        },
16089        bindBottom: function() {
16090          module.debug('Binding element to bottom of parent container');
16091          module.remove.offset();
16092          $module
16093            .css({
16094              left         : '',
16095              top          : ''
16096            })
16097            .removeClass(className.fixed)
16098            .removeClass(className.top)
16099            .addClass(className.bound)
16100            .addClass(className.bottom)
16101          ;
16102          settings.onBottom.call(element);
16103          settings.onUnstick.call(element);
16104        },
16105
16106        setInitialPosition: function() {
16107          module.debug('Returning to initial position');
16108          module.unfix();
16109          module.unbind();
16110        },
16111
16112
16113        fixTop: function() {
16114          module.debug('Fixing element to top of page');
16115          module.set.minimumSize();
16116          module.set.offset();
16117          $module
16118            .css({
16119              left         : module.cache.element.left,
16120              bottom       : '',
16121              marginBottom : ''
16122            })
16123            .removeClass(className.bound)
16124            .removeClass(className.bottom)
16125            .addClass(className.fixed)
16126            .addClass(className.top)
16127          ;
16128          settings.onStick.call(element);
16129        },
16130
16131        fixBottom: function() {
16132          module.debug('Sticking element to bottom of page');
16133          module.set.minimumSize();
16134          module.set.offset();
16135          $module
16136            .css({
16137              left         : module.cache.element.left,
16138              bottom       : '',
16139              marginBottom : ''
16140            })
16141            .removeClass(className.bound)
16142            .removeClass(className.top)
16143            .addClass(className.fixed)
16144            .addClass(className.bottom)
16145          ;
16146          settings.onStick.call(element);
16147        },
16148
16149        unbind: function() {
16150          if( module.is.bound() ) {
16151            module.debug('Removing container bound position on element');
16152            module.remove.offset();
16153            $module
16154              .removeClass(className.bound)
16155              .removeClass(className.top)
16156              .removeClass(className.bottom)
16157            ;
16158          }
16159        },
16160
16161        unfix: function() {
16162          if( module.is.fixed() ) {
16163            module.debug('Removing fixed position on element');
16164            module.remove.offset();
16165            $module
16166              .removeClass(className.fixed)
16167              .removeClass(className.top)
16168              .removeClass(className.bottom)
16169            ;
16170            settings.onUnstick.call(element);
16171          }
16172        },
16173
16174        reset: function() {
16175          module.debug('Reseting elements position');
16176          module.unbind();
16177          module.unfix();
16178          module.resetCSS();
16179          module.remove.offset();
16180          module.remove.lastScroll();
16181        },
16182
16183        resetCSS: function() {
16184          $module
16185            .css({
16186              width  : '',
16187              height : ''
16188            })
16189          ;
16190          $container
16191            .css({
16192              height: ''
16193            })
16194          ;
16195        },
16196
16197        setting: function(name, value) {
16198          if( $.isPlainObject(name) ) {
16199            $.extend(true, settings, name);
16200          }
16201          else if(value !== undefined) {
16202            settings[name] = value;
16203          }
16204          else {
16205            return settings[name];
16206          }
16207        },
16208        internal: function(name, value) {
16209          if( $.isPlainObject(name) ) {
16210            $.extend(true, module, name);
16211          }
16212          else if(value !== undefined) {
16213            module[name] = value;
16214          }
16215          else {
16216            return module[name];
16217          }
16218        },
16219        debug: function() {
16220          if(settings.debug) {
16221            if(settings.performance) {
16222              module.performance.log(arguments);
16223            }
16224            else {
16225              module.debug = Function.prototype.bind.call(console.info, console, settings.name + ':');
16226              module.debug.apply(console, arguments);
16227            }
16228          }
16229        },
16230        verbose: function() {
16231          if(settings.verbose && settings.debug) {
16232            if(settings.performance) {
16233              module.performance.log(arguments);
16234            }
16235            else {
16236              module.verbose = Function.prototype.bind.call(console.info, console, settings.name + ':');
16237              module.verbose.apply(console, arguments);
16238            }
16239          }
16240        },
16241        error: function() {
16242          module.error = Function.prototype.bind.call(console.error, console, settings.name + ':');
16243          module.error.apply(console, arguments);
16244        },
16245        performance: {
16246          log: function(message) {
16247            var
16248              currentTime,
16249              executionTime,
16250              previousTime
16251            ;
16252            if(settings.performance) {
16253              currentTime   = new Date().getTime();
16254              previousTime  = time || currentTime;
16255              executionTime = currentTime - previousTime;
16256              time          = currentTime;
16257              performance.push({
16258                'Name'           : message[0],
16259                'Arguments'      : [].slice.call(message, 1) || '',
16260                'Element'        : element,
16261                'Execution Time' : executionTime
16262              });
16263            }
16264            clearTimeout(module.performance.timer);
16265            module.performance.timer = setTimeout(module.performance.display, 0);
16266          },
16267          display: function() {
16268            var
16269              title = settings.name + ':',
16270              totalTime = 0
16271            ;
16272            time = false;
16273            clearTimeout(module.performance.timer);
16274            $.each(performance, function(index, data) {
16275              totalTime += data['Execution Time'];
16276            });
16277            title += ' ' + totalTime + 'ms';
16278            if(moduleSelector) {
16279              title += ' \'' + moduleSelector + '\'';
16280            }
16281            if( (console.group !== undefined || console.table !== undefined) && performance.length > 0) {
16282              console.groupCollapsed(title);
16283              if(console.table) {
16284                console.table(performance);
16285              }
16286              else {
16287                $.each(performance, function(index, data) {
16288                  console.log(data['Name'] + ': ' + data['Execution Time']+'ms');
16289                });
16290              }
16291              console.groupEnd();
16292            }
16293            performance = [];
16294          }
16295        },
16296        invoke: function(query, passedArguments, context) {
16297          var
16298            object = instance,
16299            maxDepth,
16300            found,
16301            response
16302          ;
16303          passedArguments = passedArguments || queryArguments;
16304          context         = element         || context;
16305          if(typeof query == 'string' && object !== undefined) {
16306            query    = query.split(/[\. ]/);
16307            maxDepth = query.length - 1;
16308            $.each(query, function(depth, value) {
16309              var camelCaseValue = (depth != maxDepth)
16310                ? value + query[depth + 1].charAt(0).toUpperCase() + query[depth + 1].slice(1)
16311                : query
16312              ;
16313              if( $.isPlainObject( object[camelCaseValue] ) && (depth != maxDepth) ) {
16314                object = object[camelCaseValue];
16315              }
16316              else if( object[camelCaseValue] !== undefined ) {
16317                found = object[camelCaseValue];
16318                return false;
16319              }
16320              else if( $.isPlainObject( object[value] ) && (depth != maxDepth) ) {
16321                object = object[value];
16322              }
16323              else if( object[value] !== undefined ) {
16324                found = object[value];
16325                return false;
16326              }
16327              else {
16328                return false;
16329              }
16330            });
16331          }
16332          if ( $.isFunction( found ) ) {
16333            response = found.apply(context, passedArguments);
16334          }
16335          else if(found !== undefined) {
16336            response = found;
16337          }
16338          if($.isArray(returnedValue)) {
16339            returnedValue.push(response);
16340          }
16341          else if(returnedValue !== undefined) {
16342            returnedValue = [returnedValue, response];
16343          }
16344          else if(response !== undefined) {
16345            returnedValue = response;
16346          }
16347          return found;
16348        }
16349      };
16350
16351      if(methodInvoked) {
16352        if(instance === undefined) {
16353          module.initialize();
16354        }
16355        module.invoke(query);
16356      }
16357      else {
16358        if(instance !== undefined) {
16359          instance.invoke('destroy');
16360        }
16361        module.initialize();
16362      }
16363    })
16364  ;
16365
16366  return (returnedValue !== undefined)
16367    ? returnedValue
16368    : this
16369  ;
16370};
16371
16372$.fn.sticky.settings = {
16373
16374  name           : 'Sticky',
16375  namespace      : 'sticky',
16376
16377  debug          : false,
16378  verbose        : true,
16379  performance    : true,
16380
16381  // whether to stick in the opposite direction on scroll up
16382  pushing        : false,
16383
16384  context        : false,
16385
16386  // Context to watch scroll events
16387  scrollContext  : window,
16388
16389  // Offset to adjust scroll
16390  offset         : 0,
16391
16392  // Offset to adjust scroll when attached to bottom of screen
16393  bottomOffset   : 0,
16394
16395  jitter         : 5, // will only set container height if difference between context and container is larger than this number
16396
16397  // Whether to automatically observe changes with Mutation Observers
16398  observeChanges : false,
16399
16400  // Called when position is recalculated
16401  onReposition   : function(){},
16402
16403  // Called on each scroll
16404  onScroll       : function(){},
16405
16406  // Called when element is stuck to viewport
16407  onStick        : function(){},
16408
16409  // Called when element is unstuck from viewport
16410  onUnstick      : function(){},
16411
16412  // Called when element reaches top of context
16413  onTop          : function(){},
16414
16415  // Called when element reaches bottom of context
16416  onBottom       : function(){},
16417
16418  error         : {
16419    container      : 'Sticky element must be inside a relative container',
16420    visible        : 'Element is hidden, you must call refresh after element becomes visible',
16421    method         : 'The method you called is not defined.',
16422    invalidContext : 'Context specified does not exist',
16423    elementSize    : 'Sticky element is larger than its container, cannot create sticky.'
16424  },
16425
16426  className : {
16427    bound     : 'bound',
16428    fixed     : 'fixed',
16429    supported : 'native',
16430    top       : 'top',
16431    bottom    : 'bottom'
16432  }
16433
16434};
16435
16436})( jQuery, window, document );
16437/*!
16438 * # Semantic UI 2.1.7 - Tab
16439 * http://github.com/semantic-org/semantic-ui/
16440 *
16441 *
16442 * Copyright 2015 Contributors
16443 * Released under the MIT license
16444 * http://opensource.org/licenses/MIT
16445 *
16446 */
16447
16448;(function ($, window, document, undefined) {
16449
16450"use strict"
vendor: 13,995 bytes, lines 16450-16862
16450;
16451
16452$.fn.tab = function(parameters) {
16453
16454  var
16455    // use window context if none specified
16456    $allModules     = $.isFunction(this)
16457        ? $(window)
16458        : $(this),
16459
16460    moduleSelector  = $allModules.selector || '',
16461    time            = new Date().getTime(),
16462    performance     = [],
16463
16464    query           = arguments[0],
16465    methodInvoked   = (typeof query == 'string'),
16466    queryArguments  = [].slice.call(arguments, 1),
16467
16468    initializedHistory = false,
16469    returnedValue
16470  ;
16471
16472  $allModules
16473    .each(function() {
16474      var
16475
16476        settings        = ( $.isPlainObject(parameters) )
16477          ? $.extend(true, {}, $.fn.tab.settings, parameters)
16478          : $.extend({}, $.fn.tab.settings),
16479
16480        className       = settings.className,
16481        metadata        = settings.metadata,
16482        selector        = settings.selector,
16483        error           = settings.error,
16484
16485        eventNamespace  = '.' + settings.namespace,
16486        moduleNamespace = 'module-' + settings.namespace,
16487
16488        $module         = $(this),
16489        $context,
16490        $tabs,
16491
16492        cache           = {},
16493        firstLoad       = true,
16494        recursionDepth  = 0,
16495        element         = this,
16496        instance        = $module.data(moduleNamespace),
16497
16498        activeTabPath,
16499        parameterArray,
16500        module,
16501
16502        historyEvent
16503
16504      ;
16505
16506      module = {
16507
16508        initialize: function() {
16509          module.debug('Initializing tab menu item', $module);
16510          module.fix.callbacks();
16511          module.determineTabs();
16512
16513          module.debug('Determining tabs', settings.context, $tabs);
16514          // set up automatic routing
16515          if(settings.auto) {
16516            module.set.auto();
16517          }
16518          module.bind.events();
16519
16520          if(settings.history && !initializedHistory) {
16521            module.initializeHistory();
16522            initializedHistory = true;
16523          }
16524
16525          module.instantiate();
16526        },
16527
16528        instantiate: function () {
16529          module.verbose('Storing instance of module', module);
16530          instance = module;
16531          $module
16532            .data(moduleNamespace, module)
16533          ;
16534        },
16535
16536        destroy: function() {
16537          module.debug('Destroying tabs', $module);
16538          $module
16539            .removeData(moduleNamespace)
16540            .off(eventNamespace)
16541          ;
16542        },
16543
16544        bind: {
16545          events: function() {
16546            // if using $.tab don't add events
16547            if( !$.isWindow( element ) ) {
16548              module.debug('Attaching tab activation events to element', $module);
16549              $module
16550                .on('click' + eventNamespace, module.event.click)
16551              ;
16552            }
16553          }
16554        },
16555
16556        determineTabs: function() {
16557          var
16558            $reference
16559          ;
16560
16561          // determine tab context
16562          if(settings.context === 'parent') {
16563            if($module.closest(selector.ui).length > 0) {
16564              $reference = $module.closest(selector.ui);
16565              module.verbose('Using closest UI element as parent', $reference);
16566            }
16567            else {
16568              $reference = $module;
16569            }
16570            $context = $reference.parent();
16571            module.verbose('Determined parent element for creating context', $context);
16572          }
16573          else if(settings.context) {
16574            $context = $(settings.context);
16575            module.verbose('Using selector for tab context', settings.context, $context);
16576          }
16577          else {
16578            $context = $('body');
16579          }
16580          // find tabs
16581          if(settings.childrenOnly) {
16582            $tabs = $context.children(selector.tabs);
16583            module.debug('Searching tab context children for tabs', $context, $tabs);
16584          }
16585          else {
16586            $tabs = $context.find(selector.tabs);
16587            module.debug('Searching tab context for tabs', $context, $tabs);
16588          }
16589        },
16590
16591        fix: {
16592          callbacks: function() {
16593            if( $.isPlainObject(parameters) && (parameters.onTabLoad || parameters.onTabInit) ) {
16594              if(parameters.onTabLoad) {
16595                parameters.onLoad = parameters.onTabLoad;
16596                delete parameters.onTabLoad;
16597                module.error(error.legacyLoad, parameters.onLoad);
16598              }
16599              if(parameters.onTabInit) {
16600                parameters.onFirstLoad = parameters.onTabInit;
16601                delete parameters.onTabInit;
16602                module.error(error.legacyInit, parameters.onFirstLoad);
16603              }
16604              settings = $.extend(true, {}, $.fn.tab.settings, parameters);
16605            }
16606          }
16607        },
16608
16609        initializeHistory: function() {
16610          module.debug('Initializing page state');
16611          if( $.address === undefined ) {
16612            module.error(error.state);
16613            return false;
16614          }
16615          else {
16616            if(settings.historyType == 'state') {
16617              module.debug('Using HTML5 to manage state');
16618              if(settings.path !== false) {
16619                $.address
16620                  .history(true)
16621                  .state(settings.path)
16622                ;
16623              }
16624              else {
16625                module.error(error.path);
16626                return false;
16627              }
16628            }
16629            $.address
16630              .bind('change', module.event.history.change)
16631            ;
16632          }
16633        },
16634
16635        event: {
16636          click: function(event) {
16637            var
16638              tabPath = $(this).data(metadata.tab)
16639            ;
16640            if(tabPath !== undefined) {
16641              if(settings.history) {
16642                module.verbose('Updating page state', event);
16643                $.address.value(tabPath);
16644              }
16645              else {
16646                module.verbose('Changing tab', event);
16647                module.changeTab(tabPath);
16648              }
16649              event.preventDefault();
16650            }
16651            else {
16652              module.debug('No tab specified');
16653            }
16654          },
16655          history: {
16656            change: function(event) {
16657              var
16658                tabPath   = event.pathNames.join('/') || module.get.initialPath(),
16659                pageTitle = settings.templates.determineTitle(tabPath) || false
16660              ;
16661              module.performance.display();
16662              module.debug('History change event', tabPath, event);
16663              historyEvent = event;
16664              if(tabPath !== undefined) {
16665                module.changeTab(tabPath);
16666              }
16667              if(pageTitle) {
16668                $.address.title(pageTitle);
16669              }
16670            }
16671          }
16672        },
16673
16674        refresh: function() {
16675          if(activeTabPath) {
16676            module.debug('Refreshing tab', activeTabPath);
16677            module.changeTab(activeTabPath);
16678          }
16679        },
16680
16681        cache: {
16682
16683          read: function(cacheKey) {
16684            return (cacheKey !== undefined)
16685              ? cache[cacheKey]
16686              : false
16687            ;
16688          },
16689          add: function(cacheKey, content) {
16690            cacheKey = cacheKey || activeTabPath;
16691            module.debug('Adding cached content for', cacheKey);
16692            cache[cacheKey] = content;
16693          },
16694          remove: function(cacheKey) {
16695            cacheKey = cacheKey || activeTabPath;
16696            module.debug('Removing cached content for', cacheKey);
16697            delete cache[cacheKey];
16698          }
16699        },
16700
16701        set: {
16702          auto: function() {
16703            var
16704              url = (typeof settings.path == 'string')
16705                ? settings.path.replace(/\/$/, '') + '/{$tab}'
16706                : '/{$tab}'
16707            ;
16708            module.verbose('Setting up automatic tab retrieval from server', url);
16709            if($.isPlainObject(settings.apiSettings)) {
16710              settings.apiSettings.url = url;
16711            }
16712            else {
16713              settings.apiSettings = {
16714                url: url
16715              };
16716            }
16717          },
16718          loading: function(tabPath) {
16719            var
16720              $tab      = module.get.tabElement(tabPath),
16721              isLoading = $tab.hasClass(className.loading)
16722            ;
16723            if(!isLoading) {
16724              module.verbose('Setting loading state for', $tab);
16725              $tab
16726                .addClass(className.loading)
16727                .siblings($tabs)
16728                  .removeClass(className.active + ' ' + className.loading)
16729              ;
16730              if($tab.length > 0) {
16731                settings.onRequest.call($tab[0], tabPath);
16732              }
16733            }
16734          },
16735          state: function(state) {
16736            $.address.value(state);
16737          }
16738        },
16739
16740        changeTab: function(tabPath) {
16741          var
16742            pushStateAvailable = (window.history && window.history.pushState),
16743            shouldIgnoreLoad   = (pushStateAvailable && settings.ignoreFirstLoad && firstLoad),
16744            remoteContent      = (settings.auto || $.isPlainObject(settings.apiSettings) ),
16745            // only add default path if not remote content
16746            pathArray = (remoteContent && !shouldIgnoreLoad)
16747              ? module.utilities.pathToArray(tabPath)
16748              : module.get.defaultPathArray(tabPath)
16749          ;
16750          tabPath = module.utilities.arrayToPath(pathArray);
16751          $.each(pathArray, function(index, tab) {
16752            var
16753              currentPathArray   = pathArray.slice(0, index + 1),
16754              currentPath        = module.utilities.arrayToPath(currentPathArray),
16755
16756              isTab              = module.is.tab(currentPath),
16757              isLastIndex        = (index + 1 == pathArray.length),
16758
16759              $tab               = module.get.tabElement(currentPath),
16760              $anchor,
16761              nextPathArray,
16762              nextPath,
16763              isLastTab
16764            ;
16765            module.verbose('Looking for tab', tab);
16766            if(isTab) {
16767              module.verbose('Tab was found', tab);
16768              // scope up
16769              activeTabPath  = currentPath;
16770              parameterArray = module.utilities.filterArray(pathArray, currentPathArray);
16771
16772              if(isLastIndex) {
16773                isLastTab = true;
16774              }
16775              else {
16776                nextPathArray = pathArray.slice(0, index + 2);
16777                nextPath      = module.utilities.arrayToPath(nextPathArray);
16778                isLastTab     = ( !module.is.tab(nextPath) );
16779                if(isLastTab) {
16780                  module.verbose('Tab parameters found', nextPathArray);
16781                }
16782              }
16783              if(isLastTab && remoteContent) {
16784                if(!shouldIgnoreLoad) {
16785                  module.activate.navigation(currentPath);
16786                  module.fetch.content(currentPath, tabPath);
16787                }
16788                else {
16789                  module.debug('Ignoring remote content on first tab load', currentPath);
16790                  firstLoad = false;
16791                  module.cache.add(tabPath, $tab.html());
16792                  module.activate.all(currentPath);
16793                  settings.onFirstLoad.call($tab[0], currentPath, parameterArray, historyEvent);
16794                  settings.onLoad.call($tab[0], currentPath, parameterArray, historyEvent);
16795                }
16796                return false;
16797              }
16798              else {
16799                module.debug('Opened local tab', currentPath);
16800                module.activate.all(currentPath);
16801                if( !module.cache.read(currentPath) ) {
16802                  module.cache.add(currentPath, true);
16803                  module.debug('First time tab loaded calling tab init');
16804                  settings.onFirstLoad.call($tab[0], currentPath, parameterArray, historyEvent);
16805                }
16806                settings.onLoad.call($tab[0], currentPath, parameterArray, historyEvent);
16807              }
16808
16809            }
16810            else if(tabPath.search('/') == -1 && tabPath !== '') {
16811              // look for in page anchor
16812              $anchor     = $('#' + tabPath + ', a[name="' + tabPath + '"]');
16813              currentPath = $anchor.closest('[data-tab]').data(metadata.tab);
16814              $tab        = module.get.tabElement(currentPath);
16815              // if anchor exists use parent tab
16816              if($anchor && $anchor.length > 0 && currentPath) {
16817                module.debug('Anchor link used, opening parent tab', $tab, $anchor);
16818                if( !$tab.hasClass(className.active) ) {
16819                  setTimeout(function() {
16820                    module.scrollTo($anchor);
16821                  }, 0);
16822                }
16823                module.activate.all(currentPath);
16824                if( !module.cache.read(currentPath) ) {
16825                  module.cache.add(currentPath, true);
16826                  module.debug('First time tab loaded calling tab init');
16827                  settings.onFirstLoad.call($tab[0], currentPath, parameterArray, historyEvent);
16828                }
16829                settings.onLoad.call($tab[0], currentPath, parameterArray, historyEvent);
16830                return false;
16831              }
16832            }
16833            else {
16834              module.error(error.missingTab, $module, $context, currentPath);
16835              return false;
16836            }
16837          });
16838        },
16839
16840        scrollTo: function($element) {
16841          var
16842            scrollOffset = ($element && $element.length > 0)
16843              ? $element.offset().top
16844              : false
16845          ;
16846          if(scrollOffset !== false) {
16847            module.debug('Forcing scroll to an in-page link in a hidden tab', scrollOffset, $element);
16848            $(document).scrollTop(scrollOffset);
16849          }
16850        },
16851
16852        update: {
16853          content: function(tabPath, html, evaluateScripts) {
16854            var
16855              $tab = module.get.tabElement(tabPath),
16856              tab  = $tab[0]
16857            ;
16858            evaluateScripts = (evaluateScripts !== undefined)
16859              ? evaluateScripts
16860              : settings.evaluateScripts
16861            ;
16862            if(
vendor: 15,826 bytes, lines 16862-17311
16862evaluateScripts) {
16863              module.debug('Updating HTML and evaluating inline scripts', tabPath, html);
16864              $tab.html(html);
16865            }
16866            else {
16867              module.debug('Updating HTML', tabPath, html);
16868              tab.innerHTML = html;
16869            }
16870          }
16871        },
16872
16873        fetch: {
16874
16875          content: function(tabPath, fullTabPath) {
16876            var
16877              $tab        = module.get.tabElement(tabPath),
16878              apiSettings = {
16879                dataType         : 'html',
16880                encodeParameters : false,
16881                on               : 'now',
16882                cache            : settings.alwaysRefresh,
16883                headers          : {
16884                  'X-Remote': true
16885                },
16886                onSuccess : function(response) {
16887                  module.cache.add(fullTabPath, response);
16888                  module.update.content(tabPath, response);
16889                  if(tabPath == activeTabPath) {
16890                    module.debug('Content loaded', tabPath);
16891                    module.activate.tab(tabPath);
16892                  }
16893                  else {
16894                    module.debug('Content loaded in background', tabPath);
16895                  }
16896                  settings.onFirstLoad.call($tab[0], tabPath, parameterArray, historyEvent);
16897                  settings.onLoad.call($tab[0], tabPath, parameterArray, historyEvent);
16898                },
16899                urlData: {
16900                  tab: fullTabPath
16901                }
16902              },
16903              request         = $tab.api('get request') || false,
16904              existingRequest = ( request && request.state() === 'pending' ),
16905              requestSettings,
16906              cachedContent
16907            ;
16908
16909            fullTabPath   = fullTabPath || tabPath;
16910            cachedContent = module.cache.read(fullTabPath);
16911
16912
16913            if(settings.cache && cachedContent) {
16914              module.activate.tab(tabPath);
16915              module.debug('Adding cached content', fullTabPath);
16916              if(settings.evaluateScripts == 'once') {
16917                module.update.content(tabPath, cachedContent, false);
16918              }
16919              else {
16920                module.update.content(tabPath, cachedContent);
16921              }
16922              settings.onLoad.call($tab[0], tabPath, parameterArray, historyEvent);
16923            }
16924            else if(existingRequest) {
16925              module.set.loading(tabPath);
16926              module.debug('Content is already loading', fullTabPath);
16927            }
16928            else if($.api !== undefined) {
16929              requestSettings = $.extend(true, {}, settings.apiSettings, apiSettings);
16930              module.debug('Retrieving remote content', fullTabPath, requestSettings);
16931              module.set.loading(tabPath);
16932              $tab.api(requestSettings);
16933            }
16934            else {
16935              module.error(error.api);
16936            }
16937          }
16938        },
16939
16940        activate: {
16941          all: function(tabPath) {
16942            module.activate.tab(tabPath);
16943            module.activate.navigation(tabPath);
16944          },
16945          tab: function(tabPath) {
16946            var
16947              $tab     = module.get.tabElement(tabPath),
16948              isActive = $tab.hasClass(className.active)
16949            ;
16950            module.verbose('Showing tab content for', $tab);
16951            if(!isActive) {
16952              $tab
16953                .addClass(className.active)
16954                .siblings($tabs)
16955                  .removeClass(className.active + ' ' + className.loading)
16956              ;
16957              if($tab.length > 0) {
16958                settings.onVisible.call($tab[0], tabPath);
16959              }
16960            }
16961          },
16962          navigation: function(tabPath) {
16963            var
16964              $navigation = module.get.navElement(tabPath),
16965              isActive    = $navigation.hasClass(className.active)
16966            ;
16967            module.verbose('Activating tab navigation for', $navigation, tabPath);
16968            if(!isActive) {
16969              $navigation
16970                .addClass(className.active)
16971                .siblings($allModules)
16972                  .removeClass(className.active + ' ' + className.loading)
16973              ;
16974            }
16975          }
16976        },
16977
16978        deactivate: {
16979          all: function() {
16980            module.deactivate.navigation();
16981            module.deactivate.tabs();
16982          },
16983          navigation: function() {
16984            $allModules
16985              .removeClass(className.active)
16986            ;
16987          },
16988          tabs: function() {
16989            $tabs
16990              .removeClass(className.active + ' ' + className.loading)
16991            ;
16992          }
16993        },
16994
16995        is: {
16996          tab: function(tabName) {
16997            return (tabName !== undefined)
16998              ? ( module.get.tabElement(tabName).length > 0 )
16999              : false
17000            ;
17001          }
17002        },
17003
17004        get: {
17005          initialPath: function() {
17006            return $allModules.eq(0).data(metadata.tab) || $tabs.eq(0).data(metadata.tab);
17007          },
17008          path: function() {
17009            return $.address.value();
17010          },
17011          // adds default tabs to tab path
17012          defaultPathArray: function(tabPath) {
17013            return module.utilities.pathToArray( module.get.defaultPath(tabPath) );
17014          },
17015          defaultPath: function(tabPath) {
17016            var
17017              $defaultNav = $allModules.filter('[data-' + metadata.tab + '^="' + tabPath + '/"]').eq(0),
17018              defaultTab  = $defaultNav.data(metadata.tab) || false
17019            ;
17020            if( defaultTab ) {
17021              module.debug('Found default tab', defaultTab);
17022              if(recursionDepth < settings.maxDepth) {
17023                recursionDepth++;
17024                return module.get.defaultPath(defaultTab);
17025              }
17026              module.error(error.recursion);
17027            }
17028            else {
17029              module.debug('No default tabs found for', tabPath, $tabs);
17030            }
17031            recursionDepth = 0;
17032            return tabPath;
17033          },
17034          navElement: function(tabPath) {
17035            tabPath = tabPath || activeTabPath;
17036            return $allModules.filter('[data-' + metadata.tab + '="' + tabPath + '"]');
17037          },
17038          tabElement: function(tabPath) {
17039            var
17040              $fullPathTab,
17041              $simplePathTab,
17042              tabPathArray,
17043              lastTab
17044            ;
17045            tabPath        = tabPath || activeTabPath;
17046            tabPathArray   = module.utilities.pathToArray(tabPath);
17047            lastTab        = module.utilities.last(tabPathArray);
17048            $fullPathTab   = $tabs.filter('[data-' + metadata.tab + '="' + tabPath + '"]');
17049            $simplePathTab = $tabs.filter('[data-' + metadata.tab + '="' + lastTab + '"]');
17050            return ($fullPathTab.length > 0)
17051              ? $fullPathTab
17052              : $simplePathTab
17053            ;
17054          },
17055          tab: function() {
17056            return activeTabPath;
17057          }
17058        },
17059
17060        utilities: {
17061          filterArray: function(keepArray, removeArray) {
17062            return $.grep(keepArray, function(keepValue) {
17063              return ( $.inArray(keepValue, removeArray) == -1);
17064            });
17065          },
17066          last: function(array) {
17067            return $.isArray(array)
17068              ? array[ array.length - 1]
17069              : false
17070            ;
17071          },
17072          pathToArray: function(pathName) {
17073            if(pathName === undefined) {
17074              pathName = activeTabPath;
17075            }
17076            return typeof pathName == 'string'
17077              ? pathName.split('/')
17078              : [pathName]
17079            ;
17080          },
17081          arrayToPath: function(pathArray) {
17082            return $.isArray(pathArray)
17083              ? pathArray.join('/')
17084              : false
17085            ;
17086          }
17087        },
17088
17089        setting: function(name, value) {
17090          module.debug('Changing setting', name, value);
17091          if( $.isPlainObject(name) ) {
17092            $.extend(true, settings, name);
17093          }
17094          else if(value !== undefined) {
17095            settings[name] = value;
17096          }
17097          else {
17098            return settings[name];
17099          }
17100        },
17101        internal: function(name, value) {
17102          if( $.isPlainObject(name) ) {
17103            $.extend(true, module, name);
17104          }
17105          else if(value !== undefined) {
17106            module[name] = value;
17107          }
17108          else {
17109            return module[name];
17110          }
17111        },
17112        debug: function() {
17113          if(settings.debug) {
17114            if(settings.performance) {
17115              module.performance.log(arguments);
17116            }
17117            else {
17118              module.debug = Function.prototype.bind.call(console.info, console, settings.name + ':');
17119              module.debug.apply(console, arguments);
17120            }
17121          }
17122        },
17123        verbose: function() {
17124          if(settings.verbose && settings.debug) {
17125            if(settings.performance) {
17126              module.performance.log(arguments);
17127            }
17128            else {
17129              module.verbose = Function.prototype.bind.call(console.info, console, settings.name + ':');
17130              module.verbose.apply(console, arguments);
17131            }
17132          }
17133        },
17134        error: function() {
17135          module.error = Function.prototype.bind.call(console.error, console, settings.name + ':');
17136          module.error.apply(console, arguments);
17137        },
17138        performance: {
17139          log: function(message) {
17140            var
17141              currentTime,
17142              executionTime,
17143              previousTime
17144            ;
17145            if(settings.performance) {
17146              currentTime   = new Date().getTime();
17147              previousTime  = time || currentTime;
17148              executionTime = currentTime - previousTime;
17149              time          = currentTime;
17150              performance.push({
17151                'Name'           : message[0],
17152                'Arguments'      : [].slice.call(message, 1) || '',
17153                'Element'        : element,
17154                'Execution Time' : executionTime
17155              });
17156            }
17157            clearTimeout(module.performance.timer);
17158            module.performance.timer = setTimeout(module.performance.display, 500);
17159          },
17160          display: function() {
17161            var
17162              title = settings.name + ':',
17163              totalTime = 0
17164            ;
17165            time = false;
17166            clearTimeout(module.performance.timer);
17167            $.each(performance, function(index, data) {
17168              totalTime += data['Execution Time'];
17169            });
17170            title += ' ' + totalTime + 'ms';
17171            if(moduleSelector) {
17172              title += ' \'' + moduleSelector + '\'';
17173            }
17174            if( (console.group !== undefined || console.table !== undefined) && performance.length > 0) {
17175              console.groupCollapsed(title);
17176              if(console.table) {
17177                console.table(performance);
17178              }
17179              else {
17180                $.each(performance, function(index, data) {
17181                  console.log(data['Name'] + ': ' + data['Execution Time']+'ms');
17182                });
17183              }
17184              console.groupEnd();
17185            }
17186            performance = [];
17187          }
17188        },
17189        invoke: function(query, passedArguments, context) {
17190          var
17191            object = instance,
17192            maxDepth,
17193            found,
17194            response
17195          ;
17196          passedArguments = passedArguments || queryArguments;
17197          context         = element         || context;
17198          if(typeof query == 'string' && object !== undefined) {
17199            query    = query.split(/[\. ]/);
17200            maxDepth = query.length - 1;
17201            $.each(query, function(depth, value) {
17202              var camelCaseValue = (depth != maxDepth)
17203                ? value + query[depth + 1].charAt(0).toUpperCase() + query[depth + 1].slice(1)
17204                : query
17205              ;
17206              if( $.isPlainObject( object[camelCaseValue] ) && (depth != maxDepth) ) {
17207                object = object[camelCaseValue];
17208              }
17209              else if( object[camelCaseValue] !== undefined ) {
17210                found = object[camelCaseValue];
17211                return false;
17212              }
17213              else if( $.isPlainObject( object[value] ) && (depth != maxDepth) ) {
17214                object = object[value];
17215              }
17216              else if( object[value] !== undefined ) {
17217                found = object[value];
17218                return false;
17219              }
17220              else {
17221                module.error(error.method, query);
17222                return false;
17223              }
17224            });
17225          }
17226          if ( $.isFunction( found ) ) {
17227            response = found.apply(context, passedArguments);
17228          }
17229          else if(found !== undefined) {
17230            response = found;
17231          }
17232          if($.isArray(returnedValue)) {
17233            returnedValue.push(response);
17234          }
17235          else if(returnedValue !== undefined) {
17236            returnedValue = [returnedValue, response];
17237          }
17238          else if(response !== undefined) {
17239            returnedValue = response;
17240          }
17241          return found;
17242        }
17243      };
17244      if(methodInvoked) {
17245        if(instance === undefined) {
17246          module.initialize();
17247        }
17248        module.invoke(query);
17249      }
17250      else {
17251        if(instance !== undefined) {
17252          instance.invoke('destroy');
17253        }
17254        module.initialize();
17255      }
17256    })
17257  ;
17258  return (returnedValue !== undefined)
17259    ? returnedValue
17260    : this
17261  ;
17262
17263};
17264
17265// shortcut for tabbed content with no defined navigation
17266$.tab = function() {
17267  $(window).tab.apply(this, arguments);
17268};
17269
17270$.fn.tab.settings = {
17271
17272  name            : 'Tab',
17273  namespace       : 'tab',
17274
17275  debug           : false,
17276  verbose         : false,
17277  performance     : true,
17278
17279  auto            : false,  // uses pjax style endpoints fetching content from same url with remote-content headers
17280  history         : false,  // use browser history
17281  historyType     : 'hash', // #/ or html5 state
17282  path            : false,  // base path of url
17283
17284  context         : false,  // specify a context that tabs must appear inside
17285  childrenOnly    : false,  // use only tabs that are children of context
17286  maxDepth        : 25,     // max depth a tab can be nested
17287
17288  alwaysRefresh   : false,  // load tab content new every tab click
17289  cache           : true,   // cache the content requests to pull locally
17290  ignoreFirstLoad : false,  // don't load remote content on first load
17291
17292  apiSettings     : false,  // settings for api call
17293  evaluateScripts : 'once', // whether inline scripts should be parsed (true/false/once). Once will not re-evaluate on cached content
17294
17295  onFirstLoad : function(tabPath, parameterArray, historyEvent) {}, // called first time loaded
17296  onLoad      : function(tabPath, parameterArray, historyEvent) {}, // called on every load
17297  onVisible   : function(tabPath, parameterArray, historyEvent) {}, // called every time tab visible
17298  onRequest   : function(tabPath, parameterArray, historyEvent) {}, // called ever time a tab beings loading remote content
17299
17300  templates    : {
17301    determineTitle: function(tabArray) {} // returns page title for path
17302  },
17303
17304  error: {
17305    api        : 'You attempted to load content without API module',
17306    method     : 'The method you called is not defined',
17307    missingTab : 'Activated tab cannot be found. Tabs are case-sensitive.',
17308    noContent  : 'The tab you specified is missing a content url.',
17309    path       : 'History enabled, but no path was specified',
17310    recursion  : 'Max recursive depth reached',
17311    legacyInit : 'onTabInit has been renamed to onFirstLoad in 2.0, please adjust your co
17311de.',
17312    legacyLoad : 'onTabLoad has been renamed to onLoad in 2.0. Please adjust your code',
17313    state      : 'History requires Asual\'s Address library <https://github.com/asual/jquery-address>'
17314  },
17315
17316  metadata : {
17317    tab    : 'tab',
17318    loaded : 'loaded',
17319    promise: 'promise'
17320  },
17321
17322  className   : {
17323    loading : 'loading',
17324    active  : 'active'
17325  },
17326
17327  selector    : {
17328    tabs : '.ui.tab',
17329    ui   : '.ui'
17330  }
17331
17332};
17333
17334})( jQuery, window, document );
17335
17336/*!
17337 * # Semantic UI 2.1.7 - Transition
17338 * http://github.com/semantic-org/semantic-ui/
17339 *
17340 *
17341 * Copyright 2015 Contributors
17342 * Released under the MIT license
17343 * http://opensource.org/licenses/MIT
17344 *
17345 */
17346
17347;(function ( $, window, document, undefined ) {
17348
17349"use strict"
vendor: 16,786 bytes, lines 17349-17877
17349;
17350
17351$.fn.transition = function() {
17352  var
17353    $allModules     = $(this),
17354    moduleSelector  = $allModules.selector || '',
17355
17356    time            = new Date().getTime(),
17357    performance     = [],
17358
17359    moduleArguments = arguments,
17360    query           = moduleArguments[0],
17361    queryArguments  = [].slice.call(arguments, 1),
17362    methodInvoked   = (typeof query === 'string'),
17363
17364    requestAnimationFrame = window.requestAnimationFrame
17365      || window.mozRequestAnimationFrame
17366      || window.webkitRequestAnimationFrame
17367      || window.msRequestAnimationFrame
17368      || function(callback) { setTimeout(callback, 0); },
17369
17370    returnedValue
17371  ;
17372  $allModules
17373    .each(function(index) {
17374      var
17375        $module  = $(this),
17376        element  = this,
17377
17378        // set at run time
17379        settings,
17380        instance,
17381
17382        error,
17383        className,
17384        metadata,
17385        animationEnd,
17386        animationName,
17387
17388        namespace,
17389        moduleNamespace,
17390        eventNamespace,
17391        module
17392      ;
17393
17394      module = {
17395
17396        initialize: function() {
17397
17398          // get full settings
17399          settings        = module.get.settings.apply(element, moduleArguments);
17400
17401          // shorthand
17402          className       = settings.className;
17403          error           = settings.error;
17404          metadata        = settings.metadata;
17405
17406          // define namespace
17407          eventNamespace  = '.' + settings.namespace;
17408          moduleNamespace = 'module-' + settings.namespace;
17409          instance        = $module.data(moduleNamespace) || module;
17410
17411          // get vendor specific events
17412          animationEnd    = module.get.animationEndEvent();
17413
17414          if(methodInvoked) {
17415            methodInvoked = module.invoke(query);
17416          }
17417
17418          // method not invoked, lets run an animation
17419          if(methodInvoked === false) {
17420            module.verbose('Converted arguments into settings object', settings);
17421            if(settings.interval) {
17422              module.delay(settings.animate);
17423            }
17424            else  {
17425              module.animate();
17426            }
17427            module.instantiate();
17428          }
17429        },
17430
17431        instantiate: function() {
17432          module.verbose('Storing instance of module', module);
17433          instance = module;
17434          $module
17435            .data(moduleNamespace, instance)
17436          ;
17437        },
17438
17439        destroy: function() {
17440          module.verbose('Destroying previous module for', element);
17441          $module
17442            .removeData(moduleNamespace)
17443          ;
17444        },
17445
17446        refresh: function() {
17447          module.verbose('Refreshing display type on next animation');
17448          delete module.displayType;
17449        },
17450
17451        forceRepaint: function() {
17452          module.verbose('Forcing element repaint');
17453          var
17454            $parentElement = $module.parent(),
17455            $nextElement = $module.next()
17456          ;
17457          if($nextElement.length === 0) {
17458            $module.detach().appendTo($parentElement);
17459          }
17460          else {
17461            $module.detach().insertBefore($nextElement);
17462          }
17463        },
17464
17465        repaint: function() {
17466          module.verbose('Repainting element');
17467          var
17468            fakeAssignment = element.offsetWidth
17469          ;
17470        },
17471
17472        delay: function(interval) {
17473          var
17474            direction = module.get.animationDirection(),
17475            shouldReverse,
17476            delay
17477          ;
17478          if(!direction) {
17479            direction = module.can.transition()
17480              ? module.get.direction()
17481              : 'static'
17482            ;
17483          }
17484          interval = (interval !== undefined)
17485            ? interval
17486            : settings.interval
17487          ;
17488          shouldReverse = (settings.reverse == 'auto' && direction == className.outward);
17489          delay = (shouldReverse || settings.reverse == true)
17490            ? ($allModules.length - index) * settings.interval
17491            : index * settings.interval
17492          ;
17493          module.debug('Delaying animation by', delay);
17494          setTimeout(module.animate, delay);
17495        },
17496
17497        animate: function(overrideSettings) {
17498          settings = overrideSettings || settings;
17499          if(!module.is.supported()) {
17500            module.error(error.support);
17501            return false;
17502          }
17503          module.debug('Preparing animation', settings.animation);
17504          if(module.is.animating()) {
17505            if(settings.queue) {
17506              if(!settings.allowRepeats && module.has.direction() && module.is.occurring() && module.queuing !== true) {
17507                module.debug('Animation is currently occurring, preventing queueing same animation', settings.animation);
17508              }
17509              else {
17510                module.queue(settings.animation);
17511              }
17512              return false;
17513            }
17514            else if(!settings.allowRepeats && module.is.occurring()) {
17515              module.debug('Animation is already occurring, will not execute repeated animation', settings.animation);
17516              return false;
17517            }
17518            else {
17519              module.debug('New animation started, completing previous early', settings.animation);
17520              instance.complete();
17521            }
17522          }
17523          if( module.can.animate() ) {
17524            module.set.animating(settings.animation);
17525          }
17526          else {
17527            module.error(error.noAnimation, settings.animation, element);
17528          }
17529        },
17530
17531        reset: function() {
17532          module.debug('Resetting animation to beginning conditions');
17533          module.remove.animationCallbacks();
17534          module.restore.conditions();
17535          module.remove.animating();
17536        },
17537
17538        queue: function(animation) {
17539          module.debug('Queueing animation of', animation);
17540          module.queuing = true;
17541          $module
17542            .one(animationEnd + '.queue' + eventNamespace, function() {
17543              module.queuing = false;
17544              module.repaint();
17545              module.animate.apply(this, settings);
17546            })
17547          ;
17548        },
17549
17550        complete: function (event) {
17551          module.debug('Animation complete', settings.animation);
17552          module.remove.completeCallback();
17553          module.remove.failSafe();
17554          if(!module.is.looping()) {
17555            if( module.is.outward() ) {
17556              module.verbose('Animation is outward, hiding element');
17557              module.restore.conditions();
17558              module.hide();
17559            }
17560            else if( module.is.inward() ) {
17561              module.verbose('Animation is outward, showing element');
17562              module.restore.conditions();
17563              module.show();
17564            }
17565            else {
17566              module.verbose('Static animation completed');
17567              module.restore.conditions();
17568              settings.onComplete.call(element);
17569            }
17570          }
17571        },
17572
17573        force: {
17574          visible: function() {
17575            var
17576              style          = $module.attr('style'),
17577              userStyle      = module.get.userStyle(),
17578              displayType    = module.get.displayType(),
17579              overrideStyle  = userStyle + 'display: ' + displayType + ' !important;',
17580              currentDisplay = $module.css('display'),
17581              emptyStyle     = (style === undefined || style === '')
17582            ;
17583            if(currentDisplay !== displayType) {
17584              module.verbose('Overriding default display to show element', displayType);
17585              $module
17586                .attr('style', overrideStyle)
17587              ;
17588            }
17589            else if(emptyStyle) {
17590              $module.removeAttr('style');
17591            }
17592          },
17593          hidden: function() {
17594            var
17595              style          = $module.attr('style'),
17596              currentDisplay = $module.css('display'),
17597              emptyStyle     = (style === undefined || style === '')
17598            ;
17599            if(currentDisplay !== 'none' && !module.is.hidden()) {
17600              module.verbose('Overriding default display to hide element');
17601              $module
17602                .css('display', 'none')
17603              ;
17604            }
17605            else if(emptyStyle) {
17606              $module
17607                .removeAttr('style')
17608              ;
17609            }
17610          }
17611        },
17612
17613        has: {
17614          direction: function(animation) {
17615            var
17616              hasDirection = false
17617            ;
17618            animation = animation || settings.animation;
17619            if(typeof animation === 'string') {
17620              animation = animation.split(' ');
17621              $.each(animation, function(index, word){
17622                if(word === className.inward || word === className.outward) {
17623                  hasDirection = true;
17624                }
17625              });
17626            }
17627            return hasDirection;
17628          },
17629          inlineDisplay: function() {
17630            var
17631              style = $module.attr('style') || ''
17632            ;
17633            return $.isArray(style.match(/display.*?;/, ''));
17634          }
17635        },
17636
17637        set: {
17638          animating: function(animation) {
17639            var
17640              animationClass,
17641              direction
17642            ;
17643            // remove previous callbacks
17644            module.remove.completeCallback();
17645
17646            // determine exact animation
17647            animation      = animation || settings.animation;
17648            animationClass = module.get.animationClass(animation);
17649
17650            // save animation class in cache to restore class names
17651            module.save.animation(animationClass);
17652
17653            // override display if necessary so animation appears visibly
17654            module.force.visible();
17655
17656            module.remove.hidden();
17657            module.remove.direction();
17658
17659            module.start.animation(animationClass);
17660
17661          },
17662          duration: function(animationName, duration) {
17663            duration = duration || settings.duration;
17664            duration = (typeof duration == 'number')
17665              ? duration + 'ms'
17666              : duration
17667            ;
17668            if(duration || duration === 0) {
17669              module.verbose('Setting animation duration', duration);
17670              $module
17671                .css({
17672                  'animation-duration':  duration
17673                })
17674              ;
17675            }
17676          },
17677          direction: function(direction) {
17678            direction = direction || module.get.direction();
17679            if(direction == className.inward) {
17680              module.set.inward();
17681            }
17682            else {
17683              module.set.outward();
17684            }
17685          },
17686          looping: function() {
17687            module.debug('Transition set to loop');
17688            $module
17689              .addClass(className.looping)
17690            ;
17691          },
17692          hidden: function() {
17693            $module
17694              .addClass(className.transition)
17695              .addClass(className.hidden)
17696            ;
17697          },
17698          inward: function() {
17699            module.debug('Setting direction to inward');
17700            $module
17701              .removeClass(className.outward)
17702              .addClass(className.inward)
17703            ;
17704          },
17705          outward: function() {
17706            module.debug('Setting direction to outward');
17707            $module
17708              .removeClass(className.inward)
17709              .addClass(className.outward)
17710            ;
17711          },
17712          visible: function() {
17713            $module
17714              .addClass(className.transition)
17715              .addClass(className.visible)
17716            ;
17717          }
17718        },
17719
17720        start: {
17721          animation: function(animationClass) {
17722            animationClass = animationClass || module.get.animationClass();
17723            module.debug('Starting tween', animationClass);
17724            $module
17725              .addClass(animationClass)
17726              .one(animationEnd + '.complete' + eventNamespace, module.complete)
17727            ;
17728            if(settings.useFailSafe) {
17729              module.add.failSafe();
17730            }
17731            module.set.duration(settings.duration);
17732            settings.onStart.call(element);
17733          }
17734        },
17735
17736        save: {
17737          animation: function(animation) {
17738            if(!module.cache) {
17739              module.cache = {};
17740            }
17741            module.cache.animation = animation;
17742          },
17743          displayType: function(displayType) {
17744            if(displayType !== 'none') {
17745              $module.data(metadata.displayType, displayType);
17746            }
17747          },
17748          transitionExists: function(animation, exists) {
17749            $.fn.transition.exists[animation] = exists;
17750            module.verbose('Saving existence of transition', animation, exists);
17751          }
17752        },
17753
17754        restore: {
17755          conditions: function() {
17756            var
17757              animation = module.get.currentAnimation()
17758            ;
17759            if(animation) {
17760              $module
17761                .removeClass(animation)
17762              ;
17763              module.verbose('Removing animation class', module.cache);
17764            }
17765            module.remove.duration();
17766          }
17767        },
17768
17769        add: {
17770          failSafe: function() {
17771            var
17772              duration = module.get.duration()
17773            ;
17774            module.timer = setTimeout(function() {
17775              $module.triggerHandler(animationEnd);
17776            }, duration + settings.failSafeDelay);
17777            module.verbose('Adding fail safe timer', module.timer);
17778          }
17779        },
17780
17781        remove: {
17782          animating: function() {
17783            $module.removeClass(className.animating);
17784          },
17785          animationCallbacks: function() {
17786            module.remove.queueCallback();
17787            module.remove.completeCallback();
17788          },
17789          queueCallback: function() {
17790            $module.off('.queue' + eventNamespace);
17791          },
17792          completeCallback: function() {
17793            $module.off('.complete' + eventNamespace);
17794          },
17795          display: function() {
17796            $module.css('display', '');
17797          },
17798          direction: function() {
17799            $module
17800              .removeClass(className.inward)
17801              .removeClass(className.outward)
17802            ;
17803          },
17804          duration: function() {
17805            $module
17806              .css('animation-duration', '')
17807            ;
17808          },
17809          failSafe: function() {
17810            module.verbose('Removing fail safe timer', module.timer);
17811            if(module.timer) {
17812              clearTimeout(module.timer);
17813            }
17814          },
17815          hidden: function() {
17816            $module.removeClass(className.hidden);
17817          },
17818          visible: function() {
17819            $module.removeClass(className.visible);
17820          },
17821          looping: function() {
17822            module.debug('Transitions are no longer looping');
17823            if( module.is.looping() ) {
17824              module.reset();
17825              $module
17826                .removeClass(className.looping)
17827              ;
17828            }
17829          },
17830          transition: function() {
17831            $module
17832              .removeClass(className.visible)
17833              .removeClass(className.hidden)
17834            ;
17835          }
17836        },
17837        get: {
17838          settings: function(animation, duration, onComplete) {
17839            // single settings object
17840            if(typeof animation == 'object') {
17841              return $.extend(true, {}, $.fn.transition.settings, animation);
17842            }
17843            // all arguments provided
17844            else if(typeof onComplete == 'function') {
17845              return $.extend({}, $.fn.transition.settings, {
17846                animation  : animation,
17847                onComplete : onComplete,
17848                duration   : duration
17849              });
17850            }
17851            // only duration provided
17852            else if(typeof duration == 'string' || typeof duration == 'number') {
17853              return $.extend({}, $.fn.transition.settings, {
17854                animation : animation,
17855                duration  : duration
17856              });
17857            }
17858            // duration is actually settings object
17859            else if(typeof duration == 'object') {
17860              return $.extend({}, $.fn.transition.settings, duration, {
17861                animation : animation
17862              });
17863            }
17864            // duration is actually callback
17865            else if(typeof duration == 'function') {
17866              return $.extend({}, $.fn.transition.settings, {
17867                animation  : animation,
17868                onComplete : duration
17869              });
17870            }
17871            // only animation provided
17872            else {
17873              return $.extend({}, $.fn.transition.settings, {
17874                animation : animation
17875              });
17876            }
17877          
vendor: 1,569 bytes, lines 17877-17921
17877  return $.fn.transition.settings;
17878          },
17879          animationClass: function(animation) {
17880            var
17881              animationClass = animation || settings.animation,
17882              directionClass = (module.can.transition() && !module.has.direction())
17883                ? module.get.direction() + ' '
17884                : ''
17885            ;
17886            return className.animating + ' '
17887              + className.transition + ' '
17888              + directionClass
17889              + animationClass
17890            ;
17891          },
17892          currentAnimation: function() {
17893            return (module.cache && module.cache.animation !== undefined)
17894              ? module.cache.animation
17895              : false
17896            ;
17897          },
17898          currentDirection: function() {
17899            return module.is.inward()
17900              ? className.inward
17901              : className.outward
17902            ;
17903          },
17904          direction: function() {
17905            return module.is.hidden() || !module.is.visible()
17906              ? className.inward
17907              : className.outward
17908            ;
17909          },
17910          animationDirection: function(animation) {
17911            var
17912              direction
17913            ;
17914            animation = animation || settings.animation;
17915            if(typeof animation === 'string') {
17916              animation = animation.split(' ');
17917              // search animation name for out/in class
17918              $.each(animation, function(index, word){
17919                if(word === className.inward) {
17920                  direction = className.inward;
17921                }
vendor: 19,426 bytes, lines 17922-18554
17922                else if(word === className.outward) {
17923                  direction = className.outward;
17924                }
17925              });
17926            }
17927            // return found direction
17928            if(direction) {
17929              return direction;
17930            }
17931            return false;
17932          },
17933          duration: function(duration) {
17934            duration = duration || settings.duration;
17935            if(duration === false) {
17936              duration = $module.css('animation-duration') || 0;
17937            }
17938            return (typeof duration === 'string')
17939              ? (duration.indexOf('ms') > -1)
17940                ? parseFloat(duration)
17941                : parseFloat(duration) * 1000
17942              : duration
17943            ;
17944          },
17945          displayType: function() {
17946            if(settings.displayType) {
17947              return settings.displayType;
17948            }
17949            if($module.data(metadata.displayType) === undefined) {
17950              // create fake element to determine display state
17951              module.can.transition(true);
17952            }
17953            return $module.data(metadata.displayType);
17954          },
17955          userStyle: function(style) {
17956            style = style || $module.attr('style') || '';
17957            return style.replace(/display.*?;/, '');
17958          },
17959          transitionExists: function(animation) {
17960            return $.fn.transition.exists[animation];
17961          },
17962          animationStartEvent: function() {
17963            var
17964              element     = document.createElement('div'),
17965              animations  = {
17966                'animation'       :'animationstart',
17967                'OAnimation'      :'oAnimationStart',
17968                'MozAnimation'    :'mozAnimationStart',
17969                'WebkitAnimation' :'webkitAnimationStart'
17970              },
17971              animation
17972            ;
17973            for(animation in animations){
17974              if( element.style[animation] !== undefined ){
17975                return animations[animation];
17976              }
17977            }
17978            return false;
17979          },
17980          animationEndEvent: function() {
17981            var
17982              element     = document.createElement('div'),
17983              animations  = {
17984                'animation'       :'animationend',
17985                'OAnimation'      :'oAnimationEnd',
17986                'MozAnimation'    :'mozAnimationEnd',
17987                'WebkitAnimation' :'webkitAnimationEnd'
17988              },
17989              animation
17990            ;
17991            for(animation in animations){
17992              if( element.style[animation] !== undefined ){
17993                return animations[animation];
17994              }
17995            }
17996            return false;
17997          }
17998
17999        },
18000
18001        can: {
18002          transition: function(forced) {
18003            var
18004              animation         = settings.animation,
18005              transitionExists  = module.get.transitionExists(animation),
18006              elementClass,
18007              tagName,
18008              $clone,
18009              currentAnimation,
18010              inAnimation,
18011              directionExists,
18012              displayType
18013            ;
18014            if( transitionExists === undefined || forced) {
18015              module.verbose('Determining whether animation exists');
18016              elementClass = $module.attr('class');
18017              tagName      = $module.prop('tagName');
18018
18019              $clone = $('<' + tagName + ' />').addClass( elementClass ).insertAfter($module);
18020              currentAnimation = $clone
18021                .addClass(animation)
18022                .removeClass(className.inward)
18023                .removeClass(className.outward)
18024                .addClass(className.animating)
18025                .addClass(className.transition)
18026                .css('animationName')
18027              ;
18028              inAnimation = $clone
18029                .addClass(className.inward)
18030                .css('animationName')
18031              ;
18032              displayType = $clone
18033                .attr('class', elementClass)
18034                .removeAttr('style')
18035                .removeClass(className.hidden)
18036                .removeClass(className.visible)
18037                .show()
18038                .css('display')
18039              ;
18040              module.verbose('Determining final display state', displayType);
18041              module.save.displayType(displayType);
18042
18043              $clone.remove();
18044              if(currentAnimation != inAnimation) {
18045                module.debug('Direction exists for animation', animation);
18046                directionExists = true;
18047              }
18048              else if(currentAnimation == 'none' || !currentAnimation) {
18049                module.debug('No animation defined in css', animation);
18050                return;
18051              }
18052              else {
18053                module.debug('Static animation found', animation, displayType);
18054                directionExists = false;
18055              }
18056              module.save.transitionExists(animation, directionExists);
18057            }
18058            return (transitionExists !== undefined)
18059              ? transitionExists
18060              : directionExists
18061            ;
18062          },
18063          animate: function() {
18064            // can transition does not return a value if animation does not exist
18065            return (module.can.transition() !== undefined);
18066          }
18067        },
18068
18069        is: {
18070          animating: function() {
18071            return $module.hasClass(className.animating);
18072          },
18073          inward: function() {
18074            return $module.hasClass(className.inward);
18075          },
18076          outward: function() {
18077            return $module.hasClass(className.outward);
18078          },
18079          looping: function() {
18080            return $module.hasClass(className.looping);
18081          },
18082          occurring: function(animation) {
18083            animation = animation || settings.animation;
18084            animation = '.' + animation.replace(' ', '.');
18085            return ( $module.filter(animation).length > 0 );
18086          },
18087          visible: function() {
18088            return $module.is(':visible');
18089          },
18090          hidden: function() {
18091            return $module.css('visibility') === 'hidden';
18092          },
18093          supported: function() {
18094            return(animationEnd !== false);
18095          }
18096        },
18097
18098        hide: function() {
18099          module.verbose('Hiding element');
18100          if( module.is.animating() ) {
18101            module.reset();
18102          }
18103          element.blur(); // IE will trigger focus change if element is not blurred before hiding
18104          module.remove.display();
18105          module.remove.visible();
18106          module.set.hidden();
18107          module.force.hidden();
18108          settings.onHide.call(element);
18109          settings.onComplete.call(element);
18110          // module.repaint();
18111        },
18112
18113        show: function(display) {
18114          module.verbose('Showing element', display);
18115          module.remove.hidden();
18116          module.set.visible();
18117          module.force.visible();
18118          settings.onShow.call(element);
18119          settings.onComplete.call(element);
18120          // module.repaint();
18121        },
18122
18123        toggle: function() {
18124          if( module.is.visible() ) {
18125            module.hide();
18126          }
18127          else {
18128            module.show();
18129          }
18130        },
18131
18132        stop: function() {
18133          module.debug('Stopping current animation');
18134          $module.triggerHandler(animationEnd);
18135        },
18136
18137        stopAll: function() {
18138          module.debug('Stopping all animation');
18139          module.remove.queueCallback();
18140          $module.triggerHandler(animationEnd);
18141        },
18142
18143        clear: {
18144          queue: function() {
18145            module.debug('Clearing animation queue');
18146            module.remove.queueCallback();
18147          }
18148        },
18149
18150        enable: function() {
18151          module.verbose('Starting animation');
18152          $module.removeClass(className.disabled);
18153        },
18154
18155        disable: function() {
18156          module.debug('Stopping animation');
18157          $module.addClass(className.disabled);
18158        },
18159
18160        setting: function(name, value) {
18161          module.debug('Changing setting', name, value);
18162          if( $.isPlainObject(name) ) {
18163            $.extend(true, settings, name);
18164          }
18165          else if(value !== undefined) {
18166            settings[name] = value;
18167          }
18168          else {
18169            return settings[name];
18170          }
18171        },
18172        internal: function(name, value) {
18173          if( $.isPlainObject(name) ) {
18174            $.extend(true, module, name);
18175          }
18176          else if(value !== undefined) {
18177            module[name] = value;
18178          }
18179          else {
18180            return module[name];
18181          }
18182        },
18183        debug: function() {
18184          if(settings.debug) {
18185            if(settings.performance) {
18186              module.performance.log(arguments);
18187            }
18188            else {
18189              module.debug = Function.prototype.bind.call(console.info, console, settings.name + ':');
18190              module.debug.apply(console, arguments);
18191            }
18192          }
18193        },
18194        verbose: function() {
18195          if(settings.verbose && settings.debug) {
18196            if(settings.performance) {
18197              module.performance.log(arguments);
18198            }
18199            else {
18200              module.verbose = Function.prototype.bind.call(console.info, console, settings.name + ':');
18201              module.verbose.apply(console, arguments);
18202            }
18203          }
18204        },
18205        error: function() {
18206          module.error = Function.prototype.bind.call(console.error, console, settings.name + ':');
18207          module.error.apply(console, arguments);
18208        },
18209        performance: {
18210          log: function(message) {
18211            var
18212              currentTime,
18213              executionTime,
18214              previousTime
18215            ;
18216            if(settings.performance) {
18217              currentTime   = new Date().getTime();
18218              previousTime  = time || currentTime;
18219              executionTime = currentTime - previousTime;
18220              time          = currentTime;
18221              performance.push({
18222                'Name'           : message[0],
18223                'Arguments'      : [].slice.call(message, 1) || '',
18224                'Element'        : element,
18225                'Execution Time' : executionTime
18226              });
18227            }
18228            clearTimeout(module.performance.timer);
18229            module.performance.timer = setTimeout(module.performance.display, 500);
18230          },
18231          display: function() {
18232            var
18233              title = settings.name + ':',
18234              totalTime = 0
18235            ;
18236            time = false;
18237            clearTimeout(module.performance.timer);
18238            $.each(performance, function(index, data) {
18239              totalTime += data['Execution Time'];
18240            });
18241            title += ' ' + totalTime + 'ms';
18242            if(moduleSelector) {
18243              title += ' \'' + moduleSelector + '\'';
18244            }
18245            if($allModules.length > 1) {
18246              title += ' ' + '(' + $allModules.length + ')';
18247            }
18248            if( (console.group !== undefined || console.table !== undefined) && performance.length > 0) {
18249              console.groupCollapsed(title);
18250              if(console.table) {
18251                console.table(performance);
18252              }
18253              else {
18254                $.each(performance, function(index, data) {
18255                  console.log(data['Name'] + ': ' + data['Execution Time']+'ms');
18256                });
18257              }
18258              console.groupEnd();
18259            }
18260            performance = [];
18261          }
18262        },
18263        // modified for transition to return invoke success
18264        invoke: function(query, passedArguments, context) {
18265          var
18266            object = instance,
18267            maxDepth,
18268            found,
18269            response
18270          ;
18271          passedArguments = passedArguments || queryArguments;
18272          context         = element         || context;
18273          if(typeof query == 'string' && object !== undefined) {
18274            query    = query.split(/[\. ]/);
18275            maxDepth = query.length - 1;
18276            $.each(query, function(depth, value) {
18277              var camelCaseValue = (depth != maxDepth)
18278                ? value + query[depth + 1].charAt(0).toUpperCase() + query[depth + 1].slice(1)
18279                : query
18280              ;
18281              if( $.isPlainObject( object[camelCaseValue] ) && (depth != maxDepth) ) {
18282                object = object[camelCaseValue];
18283              }
18284              else if( object[camelCaseValue] !== undefined ) {
18285                found = object[camelCaseValue];
18286                return false;
18287              }
18288              else if( $.isPlainObject( object[value] ) && (depth != maxDepth) ) {
18289                object = object[value];
18290              }
18291              else if( object[value] !== undefined ) {
18292                found = object[value];
18293                return false;
18294              }
18295              else {
18296                return false;
18297              }
18298            });
18299          }
18300          if ( $.isFunction( found ) ) {
18301            response = found.apply(context, passedArguments);
18302          }
18303          else if(found !== undefined) {
18304            response = found;
18305          }
18306
18307          if($.isArray(returnedValue)) {
18308            returnedValue.push(response);
18309          }
18310          else if(returnedValue !== undefined) {
18311            returnedValue = [returnedValue, response];
18312          }
18313          else if(response !== undefined) {
18314            returnedValue = response;
18315          }
18316          return (found !== undefined)
18317            ? found
18318            : false
18319          ;
18320        }
18321      };
18322      module.initialize();
18323    })
18324  ;
18325  return (returnedValue !== undefined)
18326    ? returnedValue
18327    : this
18328  ;
18329};
18330
18331// Records if CSS transition is available
18332$.fn.transition.exists = {};
18333
18334$.fn.transition.settings = {
18335
18336  // module info
18337  name          : 'Transition',
18338
18339  // debug content outputted to console
18340  debug         : false,
18341
18342  // verbose debug output
18343  verbose       : false,
18344
18345  // performance data output
18346  performance   : true,
18347
18348  // event namespace
18349  namespace     : 'transition',
18350
18351  // delay between animations in group
18352  interval      : 0,
18353
18354  // whether group animations should be reversed
18355  reverse       : 'auto',
18356
18357  // animation callback event
18358  onStart       : function() {},
18359  onComplete    : function() {},
18360  onShow        : function() {},
18361  onHide        : function() {},
18362
18363  // whether timeout should be used to ensure callback fires in cases animationend does not
18364  useFailSafe   : true,
18365
18366  // delay in ms for fail safe
18367  failSafeDelay : 100,
18368
18369  // whether EXACT animation can occur twice in a row
18370  allowRepeats  : false,
18371
18372  // Override final display type on visible
18373  displayType   : false,
18374
18375  // animation duration
18376  animation     : 'fade',
18377  duration      : false,
18378
18379  // new animations will occur after previous ones
18380  queue         : true,
18381
18382  metadata : {
18383    displayType: 'display'
18384  },
18385
18386  className   : {
18387    animating  : 'animating',
18388    disabled   : 'disabled',
18389    hidden     : 'hidden',
18390    inward     : 'in',
18391    loading    : 'loading',
18392    looping    : 'looping',
18393    outward    : 'out',
18394    transition : 'transition',
18395    visible    : 'visible'
18396  },
18397
18398  // possible errors
18399  error: {
18400    noAnimation : 'Element is no longer attached to DOM. Unable to animate.',
18401    repeated    : 'That animation is already occurring, cancelling repeated animation',
18402    method      : 'The method you called is not defined',
18403    support     : 'This browser does not support CSS animations'
18404  }
18405
18406};
18407
18408
18409})( jQuery, window, document );
18410
18411/*!
18412 * # Semantic UI 2.1.7 - API
18413 * http://github.com/semantic-org/semantic-ui/
18414 *
18415 *
18416 * Copyright 2015 Contributors
18417 * Released under the MIT license
18418 * http://opensource.org/licenses/MIT
18419 *
18420 */
18421
18422;(function ( $, window, document, undefined ) {
18423
18424"use strict";
18425
18426$.api = $.fn.api = function(parameters) {
18427
18428  var
18429    // use window context if none specified
18430    $allModules     = $.isFunction(this)
18431        ? $(window)
18432        : $(this),
18433    moduleSelector = $allModules.selector || '',
18434    time           = new Date().getTime(),
18435    performance    = [],
18436
18437    query          = arguments[0],
18438    methodInvoked  = (typeof query == 'string'),
18439    queryArguments = [].slice.call(arguments, 1),
18440
18441    returnedValue
18442  ;
18443
18444  $allModules
18445    .each(function() {
18446      var
18447        settings          = ( $.isPlainObject(parameters) )
18448          ? $.extend(true, {}, $.fn.api.settings, parameters)
18449          : $.extend({}, $.fn.api.settings),
18450
18451        // internal aliases
18452        namespace       = settings.namespace,
18453        metadata        = settings.metadata,
18454        selector        = settings.selector,
18455        error           = settings.error,
18456        className       = settings.className,
18457
18458        // define namespaces for modules
18459        eventNamespace  = '.' + namespace,
18460        moduleNamespace = 'module-' + namespace,
18461
18462        // element that creates request
18463        $module         = $(this),
18464        $form           = $module.closest(selector.form),
18465
18466        // context used for state
18467        $context        = (settings.stateContext)
18468          ? $(settings.stateContext)
18469          : $module,
18470
18471        // request details
18472        ajaxSettings,
18473        requestSettings,
18474        url,
18475        data,
18476        requestStartTime,
18477
18478        // standard module
18479        element         = this,
18480        context         = $context[0],
18481        instance        = $module.data(moduleNamespace),
18482        module
18483      ;
18484
18485      module = {
18486
18487        initialize: function() {
18488          if(!methodInvoked) {
18489            module.bind.events();
18490          }
18491          module.instantiate();
18492        },
18493
18494        instantiate: function() {
18495          module.verbose('Storing instance of module', module);
18496          instance = module;
18497          $module
18498            .data(moduleNamespace, instance)
18499          ;
18500        },
18501
18502        destroy: function() {
18503          module.verbose('Destroying previous module for', element);
18504          $module
18505            .removeData(moduleNamespace)
18506            .off(eventNamespace)
18507          ;
18508        },
18509
18510        bind: {
18511          events: function() {
18512            var
18513              triggerEvent = module.get.event()
18514            ;
18515            if( triggerEvent ) {
18516              module.verbose('Attaching API events to element', triggerEvent);
18517              $module
18518                .on(triggerEvent + eventNamespace, module.event.trigger)
18519              ;
18520            }
18521            else if(settings.on == 'now') {
18522              module.debug('Querying API endpoint immediately');
18523              module.query();
18524            }
18525          }
18526        },
18527
18528        decode: {
18529          json: function(response) {
18530            if(response !== undefined && typeof response == 'string') {
18531              try {
18532               response = JSON.parse(response);
18533              }
18534              catch(e) {
18535                // isnt json string
18536              }
18537            }
18538            return response;
18539          }
18540        },
18541
18542        read: {
18543          cachedResponse: function(url) {
18544            var
18545              response
18546            ;
18547            if(window.Storage === undefined) {
18548              module.error(error.noStorage);
18549              return;
18550            }
18551            response = sessionStorage.getItem(url);
18552            module.debug('Using cached response', url, response);
18553            response = module.decode.json(response);
18554            return false;
vendor: 15,320 bytes, lines 18555-18957
18555          }
18556        },
18557        write: {
18558          cachedResponse: function(url, response) {
18559            if(response && response === '') {
18560              module.debug('Response empty, not caching', response);
18561              return;
18562            }
18563            if(window.Storage === undefined) {
18564              module.error(error.noStorage);
18565              return;
18566            }
18567            if( $.isPlainObject(response) ) {
18568              response = JSON.stringify(response);
18569            }
18570            sessionStorage.setItem(url, response);
18571            module.verbose('Storing cached response for url', url, response);
18572          }
18573        },
18574
18575        query: function() {
18576
18577          if(module.is.disabled()) {
18578            module.debug('Element is disabled API request aborted');
18579            return;
18580          }
18581
18582          if(module.is.loading()) {
18583            if(settings.interruptRequests) {
18584              module.debug('Interrupting previous request');
18585              module.abort();
18586            }
18587            else {
18588              module.debug('Cancelling request, previous request is still pending');
18589              return;
18590            }
18591          }
18592
18593          // pass element metadata to url (value, text)
18594          if(settings.defaultData) {
18595            $.extend(true, settings.urlData, module.get.defaultData());
18596          }
18597
18598          // Add form content
18599          if(settings.serializeForm) {
18600            settings.data = module.add.formData(settings.data);
18601          }
18602
18603          // call beforesend and get any settings changes
18604          requestSettings = module.get.settings();
18605
18606          // check if before send cancelled request
18607          if(requestSettings === false) {
18608            module.cancelled = true;
18609            module.error(error.beforeSend);
18610            return;
18611          }
18612          else {
18613            module.cancelled = false;
18614          }
18615
18616          // get url
18617          url = module.get.templatedURL();
18618
18619          if(!url && !module.is.mocked()) {
18620            module.error(error.missingURL);
18621            return;
18622          }
18623
18624          // replace variables
18625          url = module.add.urlData( url );
18626          // missing url parameters
18627          if( !url && !module.is.mocked()) {
18628            return;
18629          }
18630
18631          requestSettings.url = settings.base + url;
18632
18633          // look for jQuery ajax parameters in settings
18634          ajaxSettings = $.extend(true, {}, settings, {
18635            type       : settings.method || settings.type,
18636            data       : data,
18637            url        : settings.base + url,
18638            beforeSend : settings.beforeXHR,
18639            success    : function() {},
18640            failure    : function() {},
18641            complete   : function() {}
18642          });
18643
18644          module.debug('Querying URL', ajaxSettings.url);
18645          module.verbose('Using AJAX settings', ajaxSettings);
18646
18647          if(settings.cache === 'local' && module.read.cachedResponse(url)) {
18648            module.debug('Response returned from local cache');
18649            module.request = module.create.request();
18650            module.request.resolveWith(context, [ module.read.cachedResponse(url) ]);
18651            return;
18652          }
18653
18654          if( !settings.throttle ) {
18655            module.debug('Sending request', data, ajaxSettings.method);
18656            module.send.request();
18657          }
18658          else {
18659            if(!settings.throttleFirstRequest && !module.timer) {
18660              module.debug('Sending request', data, ajaxSettings.method);
18661              module.send.request();
18662              module.timer = setTimeout(function(){}, settings.throttle);
18663            }
18664            else {
18665              module.debug('Throttling request', settings.throttle);
18666              clearTimeout(module.timer);
18667              module.timer = setTimeout(function() {
18668                if(module.timer) {
18669                  delete module.timer;
18670                }
18671                module.debug('Sending throttled request', data, ajaxSettings.method);
18672                module.send.request();
18673              }, settings.throttle);
18674            }
18675          }
18676
18677        },
18678
18679        should: {
18680          removeError: function() {
18681            return ( settings.hideError === true || (settings.hideError === 'auto' && !module.is.form()) );
18682          }
18683        },
18684
18685        is: {
18686          disabled: function() {
18687            return ($module.filter(selector.disabled).length > 0);
18688          },
18689          form: function() {
18690            return $module.is('form') || $context.is('form');
18691          },
18692          mocked: function() {
18693            return (settings.mockResponse || settings.mockResponseAsync || settings.response || settings.responseAsync);
18694          },
18695          input: function() {
18696            return $module.is('input');
18697          },
18698          loading: function() {
18699            return (module.request && module.request.state() == 'pending');
18700          },
18701          abortedRequest: function(xhr) {
18702            if(xhr && xhr.readyState !== undefined && xhr.readyState === 0) {
18703              module.verbose('XHR request determined to be aborted');
18704              return true;
18705            }
18706            else {
18707              module.verbose('XHR request was not aborted');
18708              return false;
18709            }
18710          },
18711          validResponse: function(response) {
18712            if( (settings.dataType !== 'json' && settings.dataType !== 'jsonp') || !$.isFunction(settings.successTest) ) {
18713              module.verbose('Response is not JSON, skipping validation', settings.successTest, response);
18714              return true;
18715            }
18716            module.debug('Checking JSON returned success', settings.successTest, response);
18717            if( settings.successTest(response) ) {
18718              module.debug('Response passed success test', response);
18719              return true;
18720            }
18721            else {
18722              module.debug('Response failed success test', response);
18723              return false;
18724            }
18725          }
18726        },
18727
18728        was: {
18729          cancelled: function() {
18730            return (module.cancelled || false);
18731          },
18732          succesful: function() {
18733            return (module.request && module.request.state() == 'resolved');
18734          },
18735          failure: function() {
18736            return (module.request && module.request.state() == 'rejected');
18737          },
18738          complete: function() {
18739            return (module.request && (module.request.state() == 'resolved' || module.request.state() == 'rejected') );
18740          }
18741        },
18742
18743        add: {
18744          urlData: function(url, urlData) {
18745            var
18746              requiredVariables,
18747              optionalVariables
18748            ;
18749            if(url) {
18750              requiredVariables = url.match(settings.regExp.required);
18751              optionalVariables = url.match(settings.regExp.optional);
18752              urlData           = urlData || settings.urlData;
18753              if(requiredVariables) {
18754                module.debug('Looking for required URL variables', requiredVariables);
18755                $.each(requiredVariables, function(index, templatedString) {
18756                  var
18757                    // allow legacy {$var} style
18758                    variable = (templatedString.indexOf('$') !== -1)
18759                      ? templatedString.substr(2, templatedString.length - 3)
18760                      : templatedString.substr(1, templatedString.length - 2),
18761                    value   = ($.isPlainObject(urlData) && urlData[variable] !== undefined)
18762                      ? urlData[variable]
18763                      : ($module.data(variable) !== undefined)
18764                        ? $module.data(variable)
18765                        : ($context.data(variable) !== undefined)
18766                          ? $context.data(variable)
18767                          : urlData[variable]
18768                  ;
18769                  // remove value
18770                  if(value === undefined) {
18771                    module.error(error.requiredParameter, variable, url);
18772                    url = false;
18773                    return false;
18774                  }
18775                  else {
18776                    module.verbose('Found required variable', variable, value);
18777                    value = (settings.encodeParameters)
18778                      ? module.get.urlEncodedValue(value)
18779                      : value
18780                    ;
18781                    url = url.replace(templatedString, value);
18782                  }
18783                });
18784              }
18785              if(optionalVariables) {
18786                module.debug('Looking for optional URL variables', requiredVariables);
18787                $.each(optionalVariables, function(index, templatedString) {
18788                  var
18789                    // allow legacy {/$var} style
18790                    variable = (templatedString.indexOf('$') !== -1)
18791                      ? templatedString.substr(3, templatedString.length - 4)
18792                      : templatedString.substr(2, templatedString.length - 3),
18793                    value   = ($.isPlainObject(urlData) && urlData[variable] !== undefined)
18794                      ? urlData[variable]
18795                      : ($module.data(variable) !== undefined)
18796                        ? $module.data(variable)
18797                        : ($context.data(variable) !== undefined)
18798                          ? $context.data(variable)
18799                          : urlData[variable]
18800                  ;
18801                  // optional replacement
18802                  if(value !== undefined) {
18803                    module.verbose('Optional variable Found', variable, value);
18804                    url = url.replace(templatedString, value);
18805                  }
18806                  else {
18807                    module.verbose('Optional variable not found', variable);
18808                    // remove preceding slash if set
18809                    if(url.indexOf('/' + templatedString) !== -1) {
18810                      url = url.replace('/' + templatedString, '');
18811                    }
18812                    else {
18813                      url = url.replace(templatedString, '');
18814                    }
18815                  }
18816                });
18817              }
18818            }
18819            return url;
18820          },
18821          formData: function(data) {
18822            var
18823              canSerialize = ($.fn.serializeObject !== undefined),
18824              formData     = (canSerialize)
18825                ? $form.serializeObject()
18826                : $form.serialize(),
18827              hasOtherData
18828            ;
18829            data         = data || settings.data;
18830            hasOtherData = $.isPlainObject(data);
18831
18832            if(hasOtherData) {
18833              if(canSerialize) {
18834                module.debug('Extending existing data with form data', data, formData);
18835                data = $.extend(true, {}, data, formData);
18836              }
18837              else {
18838                module.error(error.missingSerialize);
18839                module.debug('Cant extend data. Replacing data with form data', data, formData);
18840                data = formData;
18841              }
18842            }
18843            else {
18844              module.debug('Adding form data', formData);
18845              data = formData;
18846            }
18847            return data;
18848          }
18849        },
18850
18851        send: {
18852          request: function() {
18853            module.set.loading();
18854            module.request = module.create.request();
18855            if( module.is.mocked() ) {
18856              module.mockedXHR = module.create.mockedXHR();
18857            }
18858            else {
18859              module.xhr = module.create.xhr();
18860            }
18861            settings.onRequest.call(context, module.request, module.xhr);
18862          }
18863        },
18864
18865        event: {
18866          trigger: function(event) {
18867            module.query();
18868            if(event.type == 'submit' || event.type == 'click') {
18869              event.preventDefault();
18870            }
18871          },
18872          xhr: {
18873            always: function() {
18874              // nothing special
18875            },
18876            done: function(response, textStatus, xhr) {
18877              var
18878                context            = this,
18879                elapsedTime        = (new Date().getTime() - requestStartTime),
18880                timeLeft           = (settings.loadingDuration - elapsedTime),
18881                translatedResponse = ( $.isFunction(settings.onResponse) )
18882                  ? settings.onResponse.call(context, $.extend(true, {}, response))
18883                  : false
18884              ;
18885              timeLeft = (timeLeft > 0)
18886                ? timeLeft
18887                : 0
18888              ;
18889              if(translatedResponse) {
18890                module.debug('Modified API response in onResponse callback', settings.onResponse, translatedResponse, response);
18891                response = translatedResponse;
18892              }
18893              if(timeLeft > 0) {
18894                module.debug('Response completed early delaying state change by', timeLeft);
18895              }
18896              setTimeout(function() {
18897                if( module.is.validResponse(response) ) {
18898                  module.request.resolveWith(context, [response, xhr]);
18899                }
18900                else {
18901                  module.request.rejectWith(context, [xhr, 'invalid']);
18902                }
18903              }, timeLeft);
18904            },
18905            fail: function(xhr, status, httpMessage) {
18906              var
18907                context     = this,
18908                elapsedTime = (new Date().getTime() - requestStartTime),
18909                timeLeft    = (settings.loadingDuration - elapsedTime)
18910              ;
18911              timeLeft = (timeLeft > 0)
18912                ? timeLeft
18913                : 0
18914              ;
18915              if(timeLeft > 0) {
18916                module.debug('Response completed early delaying state change by', timeLeft);
18917              }
18918              setTimeout(function() {
18919                if( module.is.abortedRequest(xhr) ) {
18920                  module.request.rejectWith(context, [xhr, 'aborted', httpMessage]);
18921                }
18922                else {
18923                  module.request.rejectWith(context, [xhr, 'error', status, httpMessage]);
18924                }
18925              }, timeLeft);
18926            }
18927          },
18928          request: {
18929            done: function(response, xhr) {
18930              module.debug('Successful API Response', response);
18931              if(settings.cache === 'local' && url) {
18932                module.write.cachedResponse(url, response);
18933                module.debug('Saving server response locally', module.cache);
18934              }
18935              settings.onSuccess.call(context, response, $module, xhr);
18936            },
18937            complete: function(firstParameter, secondParameter) {
18938              var
18939                xhr,
18940                response
18941              ;
18942              // have to guess callback parameters based on request success
18943              if( module.was.succesful() ) {
18944                response = firstParameter;
18945                xhr      = secondParameter;
18946              }
18947              else {
18948                xhr      = firstParameter;
18949                response = module.get.responseFromXHR(xhr);
18950              }
18951              module.remove.loading();
18952              settings.onComplete.call(context, response, $module, xhr);
18953            },
18954            fail: function(xhr, status, httpMessage) {
18955              var
18956                // pull response from xhr if available
18957                response     = module.get.responseFromXHR(xhr),
vendor: 11,380 bytes, lines 18958-19268
18958                errorMessage = module.get.errorFromRequest(response, status, httpMessage)
18959              ;
18960              if(status == 'aborted') {
18961                module.debug('XHR Aborted (Most likely caused by page navigation or CORS Policy)', status, httpMessage);
18962                settings.onAbort.call(context, status, $module, xhr);
18963              }
18964              else if(status == 'invalid') {
18965                module.debug('JSON did not pass success test. A server-side error has most likely occurred', response);
18966              }
18967              else if(status == 'error')  {
18968                if(xhr !== undefined) {
18969                  module.debug('XHR produced a server error', status, httpMessage);
18970                  // make sure we have an error to display to console
18971                  if( xhr.status != 200 && httpMessage !== undefined && httpMessage !== '') {
18972                    module.error(error.statusMessage + httpMessage, ajaxSettings.url);
18973                  }
18974                  settings.onError.call(context, errorMessage, $module, xhr);
18975                }
18976              }
18977
18978              if(settings.errorDuration && status !== 'aborted') {
18979                module.debug('Adding error state');
18980                module.set.error();
18981                if( module.should.removeError() ) {
18982                  setTimeout(module.remove.error, settings.errorDuration);
18983                }
18984              }
18985              module.debug('API Request failed', errorMessage, xhr);
18986              settings.onFailure.call(context, response, $module, xhr);
18987            }
18988          }
18989        },
18990
18991        create: {
18992
18993          request: function() {
18994            // api request promise
18995            return $.Deferred()
18996              .always(module.event.request.complete)
18997              .done(module.event.request.done)
18998              .fail(module.event.request.fail)
18999            ;
19000          },
19001
19002          mockedXHR: function () {
19003            var
19004              // xhr does not simulate these properties of xhr but must return them
19005              textStatus     = false,
19006              status         = false,
19007              httpMessage    = false,
19008              responder      = settings.mockResponse      || settings.response,
19009              asyncResponder = settings.mockResponseAsync || settings.responseAsync,
19010              asyncCallback,
19011              response,
19012              mockedXHR
19013            ;
19014
19015            mockedXHR = $.Deferred()
19016              .always(module.event.xhr.complete)
19017              .done(module.event.xhr.done)
19018              .fail(module.event.xhr.fail)
19019            ;
19020
19021            if(responder) {
19022              if( $.isFunction(responder) ) {
19023                module.debug('Using specified synchronous callback', responder);
19024                response = responder.call(context, requestSettings);
19025              }
19026              else {
19027                module.debug('Using settings specified response', responder);
19028                response = responder;
19029              }
19030              // simulating response
19031              mockedXHR.resolveWith(context, [ response, textStatus, { responseText: response }]);
19032            }
19033            else if( $.isFunction(asyncResponder) ) {
19034              asyncCallback = function(response) {
19035                module.debug('Async callback returned response', response);
19036
19037                if(response) {
19038                  mockedXHR.resolveWith(context, [ response, textStatus, { responseText: response }]);
19039                }
19040                else {
19041                  mockedXHR.rejectWith(context, [{ responseText: response }, status, httpMessage]);
19042                }
19043              };
19044              module.debug('Using specified async response callback', asyncResponder);
19045              asyncResponder.call(context, requestSettings, asyncCallback);
19046            }
19047            return mockedXHR;
19048          },
19049
19050          xhr: function() {
19051            var
19052              xhr
19053            ;
19054            // ajax request promise
19055            xhr = $.ajax(ajaxSettings)
19056              .always(module.event.xhr.always)
19057              .done(module.event.xhr.done)
19058              .fail(module.event.xhr.fail)
19059            ;
19060            module.verbose('Created server request', xhr);
19061            return xhr;
19062          }
19063        },
19064
19065        set: {
19066          error: function() {
19067            module.verbose('Adding error state to element', $context);
19068            $context.addClass(className.error);
19069          },
19070          loading: function() {
19071            module.verbose('Adding loading state to element', $context);
19072            $context.addClass(className.loading);
19073            requestStartTime = new Date().getTime();
19074          }
19075        },
19076
19077        remove: {
19078          error: function() {
19079            module.verbose('Removing error state from element', $context);
19080            $context.removeClass(className.error);
19081          },
19082          loading: function() {
19083            module.verbose('Removing loading state from element', $context);
19084            $context.removeClass(className.loading);
19085          }
19086        },
19087
19088        get: {
19089          responseFromXHR: function(xhr) {
19090            return $.isPlainObject(xhr)
19091              ? (settings.dataType == 'json' || settings.dataType == 'jsonp')
19092                ? module.decode.json(xhr.responseText)
19093                : xhr.responseText
19094              : false
19095            ;
19096          },
19097          errorFromRequest: function(response, status, httpMessage) {
19098            return ($.isPlainObject(response) && response.error !== undefined)
19099              ? response.error // use json error message
19100              : (settings.error[status] !== undefined) // use server error message
19101                ? settings.error[status]
19102                : httpMessage
19103            ;
19104          },
19105          request: function() {
19106            return module.request || false;
19107          },
19108          xhr: function() {
19109            return module.xhr || false;
19110          },
19111          settings: function() {
19112            var
19113              runSettings
19114            ;
19115            runSettings = settings.beforeSend.call(context, settings);
19116            if(runSettings) {
19117              if(runSettings.success !== undefined) {
19118                module.debug('Legacy success callback detected', runSettings);
19119                module.error(error.legacyParameters, runSettings.success);
19120                runSettings.onSuccess = runSettings.success;
19121              }
19122              if(runSettings.failure !== undefined) {
19123                module.debug('Legacy failure callback detected', runSettings);
19124                module.error(error.legacyParameters, runSettings.failure);
19125                runSettings.onFailure = runSettings.failure;
19126              }
19127              if(runSettings.complete !== undefined) {
19128                module.debug('Legacy complete callback detected', runSettings);
19129                module.error(error.legacyParameters, runSettings.complete);
19130                runSettings.onComplete = runSettings.complete;
19131              }
19132            }
19133            if(runSettings === undefined) {
19134              module.error(error.noReturnedValue);
19135            }
19136            return (runSettings !== undefined)
19137              ? $.extend(true, {}, runSettings)
19138              : $.extend(true, {}, settings)
19139            ;
19140          },
19141          urlEncodedValue: function(value) {
19142            var
19143              decodedValue   = window.decodeURIComponent(value),
19144              encodedValue   = window.encodeURIComponent(value),
19145              alreadyEncoded = (decodedValue !== value)
19146            ;
19147            if(alreadyEncoded) {
19148              module.debug('URL value is already encoded, avoiding double encoding', value);
19149              return value;
19150            }
19151            module.verbose('Encoding value using encodeURIComponent', value, encodedValue);
19152            return encodedValue;
19153          },
19154          defaultData: function() {
19155            var
19156              data = {}
19157            ;
19158            if( !$.isWindow(element) ) {
19159              if( module.is.input() ) {
19160                data.value = $module.val();
19161              }
19162              else if( !module.is.form() ) {
19163
19164              }
19165              else {
19166                data.text = $module.text();
19167              }
19168            }
19169            return data;
19170          },
19171          event: function() {
19172            if( $.isWindow(element) || settings.on == 'now' ) {
19173              module.debug('API called without element, no events attached');
19174              return false;
19175            }
19176            else if(settings.on == 'auto') {
19177              if( $module.is('input') ) {
19178                return (element.oninput !== undefined)
19179                  ? 'input'
19180                  : (element.onpropertychange !== undefined)
19181                    ? 'propertychange'
19182                    : 'keyup'
19183                ;
19184              }
19185              else if( $module.is('form') ) {
19186                return 'submit';
19187              }
19188              else {
19189                return 'click';
19190              }
19191            }
19192            else {
19193              return settings.on;
19194            }
19195          },
19196          templatedURL: function(action) {
19197            action = action || $module.data(metadata.action) || settings.action || false;
19198            url    = $module.data(metadata.url) || settings.url || false;
19199            if(url) {
19200              module.debug('Using specified url', url);
19201              return url;
19202            }
19203            if(action) {
19204              module.debug('Looking up url for action', action, settings.api);
19205              if(settings.api[action] === undefined && !module.is.mocked()) {
19206                module.error(error.missingAction, settings.action, settings.api);
19207                return;
19208              }
19209              url = settings.api[action];
19210            }
19211            else if( module.is.form() ) {
19212              url = $module.attr('action') || $context.attr('action') || false;
19213              module.debug('No url or action specified, defaulting to form action', url);
19214            }
19215            return url;
19216          }
19217        },
19218
19219        abort: function() {
19220          var
19221            xhr = module.get.xhr()
19222          ;
19223          if( xhr && xhr.state() !== 'resolved') {
19224            module.debug('Cancelling API request');
19225            xhr.abort();
19226          }
19227        },
19228
19229        // reset state
19230        reset: function() {
19231          module.remove.error();
19232          module.remove.loading();
19233        },
19234
19235        setting: function(name, value) {
19236          module.debug('Changing setting', name, value);
19237          if( $.isPlainObject(name) ) {
19238            $.extend(true, settings, name);
19239          }
19240          else if(value !== undefined) {
19241            settings[name] = value;
19242          }
19243          else {
19244            return settings[name];
19245          }
19246        },
19247        internal: function(name, value) {
19248          if( $.isPlainObject(name) ) {
19249            $.extend(true, module, name);
19250          }
19251          else if(value !== undefined) {
19252            module[name] = value;
19253          }
19254          else {
19255            return module[name];
19256          }
19257        },
19258        debug: function() {
19259          if(settings.debug) {
19260            if(settings.performance) {
19261              module.performance.log(arguments);
19262            }
19263            else {
19264              module.debug = Function.prototype.bind.call(console.info, console, settings.name + ':');
19265              module.debug.apply(console, arguments);
19266            }
19267          }
19268        },
19269        verbose: function() {
19270          if(settings.verbose && settings.debug) {
19271            if(settings.performance) {
19272              module.performance.log(arguments);
19273            }
19274            else {
19275              module.verbose = Function.prototype.bind.call(console.info, console, settings.name + ':');
19276              module.verbose.apply(console, arguments);
19277            }
19278          }
19279        },
19280        error: function() {
19281          module.error = Function.prototype.bind.call(console.error, console, settings.name + ':');
19282          module.error.apply(console, arguments);
vendor: 7,950 bytes, lines 19282-19555
19282
19283        },
19284        performance: {
19285          log: function(message) {
19286            var
19287              currentTime,
19288              executionTime,
19289              previousTime
19290            ;
19291            if(settings.performance) {
19292              currentTime   = new Date().getTime();
19293              previousTime  = time || currentTime;
19294              executionTime = currentTime - previousTime;
19295              time          = currentTime;
19296              performance.push({
19297                'Name'           : message[0],
19298                'Arguments'      : [].slice.call(message, 1) || '',
19299                //'Element'        : element,
19300                'Execution Time' : executionTime
19301              });
19302            }
19303            clearTimeout(module.performance.timer);
19304            module.performance.timer = setTimeout(module.performance.display, 500);
19305          },
19306          display: function() {
19307            var
19308              title = settings.name + ':',
19309              totalTime = 0
19310            ;
19311            time = false;
19312            clearTimeout(module.performance.timer);
19313            $.each(performance, function(index, data) {
19314              totalTime += data['Execution Time'];
19315            });
19316            title += ' ' + totalTime + 'ms';
19317            if(moduleSelector) {
19318              title += ' \'' + moduleSelector + '\'';
19319            }
19320            if( (console.group !== undefined || console.table !== undefined) && performance.length > 0) {
19321              console.groupCollapsed(title);
19322              if(console.table) {
19323                console.table(performance);
19324              }
19325              else {
19326                $.each(performance, function(index, data) {
19327                  console.log(data['Name'] + ': ' + data['Execution Time']+'ms');
19328                });
19329              }
19330              console.groupEnd();
19331            }
19332            performance = [];
19333          }
19334        },
19335        invoke: function(query, passedArguments, context) {
19336          var
19337            object = instance,
19338            maxDepth,
19339            found,
19340            response
19341          ;
19342          passedArguments = passedArguments || queryArguments;
19343          context         = element         || context;
19344          if(typeof query == 'string' && object !== undefined) {
19345            query    = query.split(/[\. ]/);
19346            maxDepth = query.length - 1;
19347            $.each(query, function(depth, value) {
19348              var camelCaseValue = (depth != maxDepth)
19349                ? value + query[depth + 1].charAt(0).toUpperCase() + query[depth + 1].slice(1)
19350                : query
19351              ;
19352              if( $.isPlainObject( object[camelCaseValue] ) && (depth != maxDepth) ) {
19353                object = object[camelCaseValue];
19354              }
19355              else if( object[camelCaseValue] !== undefined ) {
19356                found = object[camelCaseValue];
19357                return false;
19358              }
19359              else if( $.isPlainObject( object[value] ) && (depth != maxDepth) ) {
19360                object = object[value];
19361              }
19362              else if( object[value] !== undefined ) {
19363                found = object[value];
19364                return false;
19365              }
19366              else {
19367                module.error(error.method, query);
19368                return false;
19369              }
19370            });
19371          }
19372          if ( $.isFunction( found ) ) {
19373            response = found.apply(context, passedArguments);
19374          }
19375          else if(found !== undefined) {
19376            response = found;
19377          }
19378          if($.isArray(returnedValue)) {
19379            returnedValue.push(response);
19380          }
19381          else if(returnedValue !== undefined) {
19382            returnedValue = [returnedValue, response];
19383          }
19384          else if(response !== undefined) {
19385            returnedValue = response;
19386          }
19387          return found;
19388        }
19389      };
19390
19391      if(methodInvoked) {
19392        if(instance === undefined) {
19393          module.initialize();
19394        }
19395        module.invoke(query);
19396      }
19397      else {
19398        if(instance !== undefined) {
19399          instance.invoke('destroy');
19400        }
19401        module.initialize();
19402      }
19403    })
19404  ;
19405
19406  return (returnedValue !== undefined)
19407    ? returnedValue
19408    : this
19409  ;
19410};
19411
19412$.api.settings = {
19413
19414  name              : 'API',
19415  namespace         : 'api',
19416
19417  debug             : false,
19418  verbose           : false,
19419  performance       : true,
19420
19421  // object containing all templates endpoints
19422  api               : {},
19423
19424  // whether to cache responses
19425  cache             : true,
19426
19427  // whether new requests should abort previous requests
19428  interruptRequests : true,
19429
19430  // event binding
19431  on                : 'auto',
19432
19433  // context for applying state classes
19434  stateContext      : false,
19435
19436  // duration for loading state
19437  loadingDuration   : 0,
19438
19439  // whether to hide errors after a period of time
19440  hideError         : 'auto',
19441
19442  // duration for error state
19443  errorDuration     : 2000,
19444
19445  // whether parameters should be encoded with encodeURIComponent
19446  encodeParameters  : true,
19447
19448  // API action to use
19449  action            : false,
19450
19451  // templated URL to use
19452  url               : false,
19453
19454  // base URL to apply to all endpoints
19455  base              : '',
19456
19457  // data that will
19458  urlData           : {},
19459
19460  // whether to add default data to url data
19461  defaultData          : true,
19462
19463  // whether to serialize closest form
19464  serializeForm        : false,
19465
19466  // how long to wait before request should occur
19467  throttle             : 0,
19468
19469  // whether to throttle first request or only repeated
19470  throttleFirstRequest : true,
19471
19472  // standard ajax settings
19473  method            : 'get',
19474  data              : {},
19475  dataType          : 'json',
19476
19477  // mock response
19478  mockResponse      : false,
19479  mockResponseAsync : false,
19480
19481  // aliases for mock
19482  response          : false,
19483  responseAsync     : false,
19484
19485  // callbacks before request
19486  beforeSend  : function(settings) { return settings; },
19487  beforeXHR   : function(xhr) {},
19488  onRequest   : function(promise, xhr) {},
19489
19490  // after request
19491  onResponse  : false, // function(response) { },
19492
19493  // response was successful, if JSON passed validation
19494  onSuccess   : function(response, $module) {},
19495
19496  // request finished without aborting
19497  onComplete  : function(response, $module) {},
19498
19499  // failed JSON success test
19500  onFailure   : function(response, $module) {},
19501
19502  // server error
19503  onError     : function(errorMessage, $module) {},
19504
19505  // request aborted
19506  onAbort     : function(errorMessage, $module) {},
19507
19508  successTest : false,
19509
19510  // errors
19511  error : {
19512    beforeSend        : 'The before send function has aborted the request',
19513    error             : 'There was an error with your request',
19514    exitConditions    : 'API Request Aborted. Exit conditions met',
19515    JSONParse         : 'JSON could not be parsed during error handling',
19516    legacyParameters  : 'You are using legacy API success callback names',
19517    method            : 'The method you called is not defined',
19518    missingAction     : 'API action used but no url was defined',
19519    missingSerialize  : 'jquery-serialize-object is required to add form data to an existing data object',
19520    missingURL        : 'No URL specified for api event',
19521    noReturnedValue   : 'The beforeSend callback must return a settings object, beforeSend ignored.',
19522    noStorage         : 'Caching responses locally requires session storage',
19523    parseError        : 'There was an error parsing your request',
19524    requiredParameter : 'Missing a required URL parameter: ',
19525    statusMessage     : 'Server gave an error: ',
19526    timeout           : 'Your request timed out'
19527  },
19528
19529  regExp  : {
19530    required : /\{\$*[A-z0-9]+\}/g,
19531    optional : /\{\/\$*[A-z0-9]+\}/g,
19532  },
19533
19534  className: {
19535    loading : 'loading',
19536    error   : 'error'
19537  },
19538
19539  selector: {
19540    disabled : '.disabled',
19541    form      : 'form'
19542  },
19543
19544  metadata: {
19545    action  : 'action',
19546    url     : 'url'
19547  }
19548};
19549
19550
19551
19552})( jQuery, window, document );
19553
19554/*!
19555 * # Semantic UI 2.
195551.7 - State
19556 * http://github.com/semantic-org/semantic-ui/
19557 *
19558 *
19559 * Copyright 2015 Contributors
19560 * Released under the MIT license
19561 * http://opensource.org/licenses/MIT
19562 *
19563 */
19564
19565;(function ( $, window, document, undefined ) {
19566
19567"use strict";
19568
19569$.fn.state = function(parameters) {
19570  var
19571    $allModules     = $(this),
19572
19573    moduleSelector  = $allModules.selector || '',
19574
19575    hasTouch        = ('ontouchstart' in document.documentElement),
19576    time            = new Date().getTime(),
19577    performance     = [],
19578
19579    query           = arguments[0],
19580    methodInvoked   = (typeof query == 'string'),
19581    queryArguments  = [].slice.call(arguments, 1),
19582
19583    returnedValue
19584  ;
19585  $allModules
19586    .each(function() {
19587      var
19588        settings          = ( $.isPlainObject(parameters) )
19589          ? $.extend(true, {}, $.fn.state.settings, parameters)
19590          : $.extend({}, $.fn.state.settings),
19591
19592        error           = settings.error,
19593        metadata        = settings.metadata,
19594        className       = settings.className,
19595        namespace       = settings.namespace,
19596        states          = settings.states,
19597        text            = settings.text,
19598
19599        eventNamespace  = '.' + namespace,
19600        moduleNamespace = namespace + '-module',
19601
19602        $module         = $(this),
19603
19604        element         = this,
19605        instance        = $module.data(moduleNamespace),
19606
19607        module
19608      ;
19609      module = {
19610
19611        initialize: function() {
19612          module.verbose('Initializing module');
19613
19614          // allow module to guess desired state based on element
19615          if(settings.automatic) {
19616            module.add.defaults();
19617          }
19618
19619          // bind events with delegated events
19620          if(settings.context && moduleSelector !== '') {
19621            $(settings.context)
19622              .on(moduleSelector, 'mouseenter' + eventNamespace, module.change.text)
19623              .on(moduleSelector, 'mouseleave' + eventNamespace, module.reset.text)
19624              .on(moduleSelector, 'click'      + eventNamespace, module.toggle.state)
19625            ;
19626          }
19627          else {
19628            $module
19629              .on('mouseenter' + eventNamespace, module.change.text)
19630              .on('mouseleave' + eventNamespace, module.reset.text)
19631              .on('click'      + eventNamespace, module.toggle.state)
19632            ;
19633          }
19634          module.instantiate();
19635        },
19636
19637        instantiate: function() {
19638          module.verbose('Storing instance of module', module);
19639          instance = module;
19640          $module
19641            .data(moduleNamespace, module)
19642          ;
19643        },
19644
19645        destroy: function() {
19646          module.verbose('Destroying previous module', instance);
19647          $module
19648            .off(eventNamespace)
19649            .removeData(moduleNamespace)
19650          ;
19651        },
19652
19653        refresh: function() {
19654          module.verbose('Refreshing selector cache');
19655          $module = $(element);
19656        },
19657
19658        add: {
19659          defaults: function() {
19660            var
19661              userStates = parameters && $.isPlainObject(parameters.states)
19662                ? parameters.states
19663                : {}
19664            ;
19665            $.each(settings.defaults, function(type, typeStates) {
19666              if( module.is[type] !== undefined && module.is[type]() ) {
19667                module.verbose('Adding default states', type, element);
19668                $.extend(settings.states, typeStates, userStates);
19669              }
19670            });
19671          }
19672        },
19673
19674        is: {
19675
19676          active: function() {
19677            return $module.hasClass(className.active);
19678          },
19679          loading: function() {
19680            return $module.hasClass(className.loading);
19681          },
19682          inactive: function() {
19683            return !( $module.hasClass(className.active) );
19684          },
19685          state: function(state) {
19686            if(className[state] === undefined) {
19687              return false;
vendor: 11,112 bytes, lines 19688-20035
19688            }
19689            return $module.hasClass( className[state] );
19690          },
19691
19692          enabled: function() {
19693            return !( $module.is(settings.filter.active) );
19694          },
19695          disabled: function() {
19696            return ( $module.is(settings.filter.active) );
19697          },
19698          textEnabled: function() {
19699            return !( $module.is(settings.filter.text) );
19700          },
19701
19702          // definitions for automatic type detection
19703          button: function() {
19704            return $module.is('.button:not(a, .submit)');
19705          },
19706          input: function() {
19707            return $module.is('input');
19708          },
19709          progress: function() {
19710            return $module.is('.ui.progress');
19711          }
19712        },
19713
19714        allow: function(state) {
19715          module.debug('Now allowing state', state);
19716          states[state] = true;
19717        },
19718        disallow: function(state) {
19719          module.debug('No longer allowing', state);
19720          states[state] = false;
19721        },
19722
19723        allows: function(state) {
19724          return states[state] || false;
19725        },
19726
19727        enable: function() {
19728          $module.removeClass(className.disabled);
19729        },
19730
19731        disable: function() {
19732          $module.addClass(className.disabled);
19733        },
19734
19735        setState: function(state) {
19736          if(module.allows(state)) {
19737            $module.addClass( className[state] );
19738          }
19739        },
19740
19741        removeState: function(state) {
19742          if(module.allows(state)) {
19743            $module.removeClass( className[state] );
19744          }
19745        },
19746
19747        toggle: {
19748          state: function() {
19749            var
19750              apiRequest,
19751              requestCancelled
19752            ;
19753            if( module.allows('active') && module.is.enabled() ) {
19754              module.refresh();
19755              if($.fn.api !== undefined) {
19756                apiRequest       = $module.api('get request');
19757                requestCancelled = $module.api('was cancelled');
19758                if( requestCancelled ) {
19759                  module.debug('API Request cancelled by beforesend');
19760                  settings.activateTest   = function(){ return false; };
19761                  settings.deactivateTest = function(){ return false; };
19762                }
19763                else if(apiRequest) {
19764                  module.listenTo(apiRequest);
19765                  return;
19766                }
19767              }
19768              module.change.state();
19769            }
19770          }
19771        },
19772
19773        listenTo: function(apiRequest) {
19774          module.debug('API request detected, waiting for state signal', apiRequest);
19775          if(apiRequest) {
19776            if(text.loading) {
19777              module.update.text(text.loading);
19778            }
19779            $.when(apiRequest)
19780              .then(function() {
19781                if(apiRequest.state() == 'resolved') {
19782                  module.debug('API request succeeded');
19783                  settings.activateTest   = function(){ return true; };
19784                  settings.deactivateTest = function(){ return true; };
19785                }
19786                else {
19787                  module.debug('API request failed');
19788                  settings.activateTest   = function(){ return false; };
19789                  settings.deactivateTest = function(){ return false; };
19790                }
19791                module.change.state();
19792              })
19793            ;
19794          }
19795        },
19796
19797        // checks whether active/inactive state can be given
19798        change: {
19799
19800          state: function() {
19801            module.debug('Determining state change direction');
19802            // inactive to active change
19803            if( module.is.inactive() ) {
19804              module.activate();
19805            }
19806            else {
19807              module.deactivate();
19808            }
19809            if(settings.sync) {
19810              module.sync();
19811            }
19812            settings.onChange.call(element);
19813          },
19814
19815          text: function() {
19816            if( module.is.textEnabled() ) {
19817              if(module.is.disabled() ) {
19818                module.verbose('Changing text to disabled text', text.hover);
19819                module.update.text(text.disabled);
19820              }
19821              else if( module.is.active() ) {
19822                if(text.hover) {
19823                  module.verbose('Changing text to hover text', text.hover);
19824                  module.update.text(text.hover);
19825                }
19826                else if(text.deactivate) {
19827                  module.verbose('Changing text to deactivating text', text.deactivate);
19828                  module.update.text(text.deactivate);
19829                }
19830              }
19831              else {
19832                if(text.hover) {
19833                  module.verbose('Changing text to hover text', text.hover);
19834                  module.update.text(text.hover);
19835                }
19836                else if(text.activate){
19837                  module.verbose('Changing text to activating text', text.activate);
19838                  module.update.text(text.activate);
19839                }
19840              }
19841            }
19842          }
19843
19844        },
19845
19846        activate: function() {
19847          if( settings.activateTest.call(element) ) {
19848            module.debug('Setting state to active');
19849            $module
19850              .addClass(className.active)
19851            ;
19852            module.update.text(text.active);
19853            settings.onActivate.call(element);
19854          }
19855        },
19856
19857        deactivate: function() {
19858          if( settings.deactivateTest.call(element) ) {
19859            module.debug('Setting state to inactive');
19860            $module
19861              .removeClass(className.active)
19862            ;
19863            module.update.text(text.inactive);
19864            settings.onDeactivate.call(element);
19865          }
19866        },
19867
19868        sync: function() {
19869          module.verbose('Syncing other buttons to current state');
19870          if( module.is.active() ) {
19871            $allModules
19872              .not($module)
19873                .state('activate');
19874          }
19875          else {
19876            $allModules
19877              .not($module)
19878                .state('deactivate')
19879            ;
19880          }
19881        },
19882
19883        get: {
19884          text: function() {
19885            return (settings.selector.text)
19886              ? $module.find(settings.selector.text).text()
19887              : $module.html()
19888            ;
19889          },
19890          textFor: function(state) {
19891            return text[state] || false;
19892          }
19893        },
19894
19895        flash: {
19896          text: function(text, duration, callback) {
19897            var
19898              previousText = module.get.text()
19899            ;
19900            module.debug('Flashing text message', text, duration);
19901            text     = text     || settings.text.flash;
19902            duration = duration || settings.flashDuration;
19903            callback = callback || function() {};
19904            module.update.text(text);
19905            setTimeout(function(){
19906              module.update.text(previousText);
19907              callback.call(element);
19908            }, duration);
19909          }
19910        },
19911
19912        reset: {
19913          // on mouseout sets text to previous value
19914          text: function() {
19915            var
19916              activeText   = text.active   || $module.data(metadata.storedText),
19917              inactiveText = text.inactive || $module.data(metadata.storedText)
19918            ;
19919            if( module.is.textEnabled() ) {
19920              if( module.is.active() && activeText) {
19921                module.verbose('Resetting active text', activeText);
19922                module.update.text(activeText);
19923              }
19924              else if(inactiveText) {
19925                module.verbose('Resetting inactive text', activeText);
19926                module.update.text(inactiveText);
19927              }
19928            }
19929          }
19930        },
19931
19932        update: {
19933          text: function(text) {
19934            var
19935              currentText = module.get.text()
19936            ;
19937            if(text && text !== currentText) {
19938              module.debug('Updating text', text);
19939              if(settings.selector.text) {
19940                $module
19941                  .data(metadata.storedText, text)
19942                  .find(settings.selector.text)
19943                    .text(text)
19944                ;
19945              }
19946              else {
19947                $module
19948                  .data(metadata.storedText, text)
19949                  .html(text)
19950                ;
19951              }
19952            }
19953            else {
19954              module.debug('Text is already set, ignoring update', text);
19955            }
19956          }
19957        },
19958
19959        setting: function(name, value) {
19960          module.debug('Changing setting', name, value);
19961          if( $.isPlainObject(name) ) {
19962            $.extend(true, settings, name);
19963          }
19964          else if(value !== undefined) {
19965            settings[name] = value;
19966          }
19967          else {
19968            return settings[name];
19969          }
19970        },
19971        internal: function(name, value) {
19972          if( $.isPlainObject(name) ) {
19973            $.extend(true, module, name);
19974          }
19975          else if(value !== undefined) {
19976            module[name] = value;
19977          }
19978          else {
19979            return module[name];
19980          }
19981        },
19982        debug: function() {
19983          if(settings.debug) {
19984            if(settings.performance) {
19985              module.performance.log(arguments);
19986            }
19987            else {
19988              module.debug = Function.prototype.bind.call(console.info, console, settings.name + ':');
19989              module.debug.apply(console, arguments);
19990            }
19991          }
19992        },
19993        verbose: function() {
19994          if(settings.verbose && settings.debug) {
19995            if(settings.performance) {
19996              module.performance.log(arguments);
19997            }
19998            else {
19999              module.verbose = Function.prototype.bind.call(console.info, console, settings.name + ':');
20000              module.verbose.apply(console, arguments);
20001            }
20002          }
20003        },
20004        error: function() {
20005          module.error = Function.prototype.bind.call(console.error, console, settings.name + ':');
20006          module.error.apply(console, arguments);
20007        },
20008        performance: {
20009          log: function(message) {
20010            var
20011              currentTime,
20012              executionTime,
20013              previousTime
20014            ;
20015            if(settings.performance) {
20016              currentTime   = new Date().getTime();
20017              previousTime  = time || currentTime;
20018              executionTime = currentTime - previousTime;
20019              time          = currentTime;
20020              performance.push({
20021                'Name'           : message[0],
20022                'Arguments'      : [].slice.call(message, 1) || '',
20023                'Element'        : element,
20024                'Execution Time' : executionTime
20025              });
20026            }
20027            clearTimeout(module.performance.timer);
20028            module.performance.timer = setTimeout(module.performance.display, 500);
20029          },
20030          display: function() {
20031            var
20032              title = settings.name + ':',
20033              totalTime = 0
20034            ;
20035            time = false;
vendor: 29,883 bytes, lines 20036-21016
20036            clearTimeout(module.performance.timer);
20037            $.each(performance, function(index, data) {
20038              totalTime += data['Execution Time'];
20039            });
20040            title += ' ' + totalTime + 'ms';
20041            if(moduleSelector) {
20042              title += ' \'' + moduleSelector + '\'';
20043            }
20044            if( (console.group !== undefined || console.table !== undefined) && performance.length > 0) {
20045              console.groupCollapsed(title);
20046              if(console.table) {
20047                console.table(performance);
20048              }
20049              else {
20050                $.each(performance, function(index, data) {
20051                  console.log(data['Name'] + ': ' + data['Execution Time']+'ms');
20052                });
20053              }
20054              console.groupEnd();
20055            }
20056            performance = [];
20057          }
20058        },
20059        invoke: function(query, passedArguments, context) {
20060          var
20061            object = instance,
20062            maxDepth,
20063            found,
20064            response
20065          ;
20066          passedArguments = passedArguments || queryArguments;
20067          context         = element         || context;
20068          if(typeof query == 'string' && object !== undefined) {
20069            query    = query.split(/[\. ]/);
20070            maxDepth = query.length - 1;
20071            $.each(query, function(depth, value) {
20072              var camelCaseValue = (depth != maxDepth)
20073                ? value + query[depth + 1].charAt(0).toUpperCase() + query[depth + 1].slice(1)
20074                : query
20075              ;
20076              if( $.isPlainObject( object[camelCaseValue] ) && (depth != maxDepth) ) {
20077                object = object[camelCaseValue];
20078              }
20079              else if( object[camelCaseValue] !== undefined ) {
20080                found = object[camelCaseValue];
20081                return false;
20082              }
20083              else if( $.isPlainObject( object[value] ) && (depth != maxDepth) ) {
20084                object = object[value];
20085              }
20086              else if( object[value] !== undefined ) {
20087                found = object[value];
20088                return false;
20089              }
20090              else {
20091                module.error(error.method, query);
20092                return false;
20093              }
20094            });
20095          }
20096          if ( $.isFunction( found ) ) {
20097            response = found.apply(context, passedArguments);
20098          }
20099          else if(found !== undefined) {
20100            response = found;
20101          }
20102          if($.isArray(returnedValue)) {
20103            returnedValue.push(response);
20104          }
20105          else if(returnedValue !== undefined) {
20106            returnedValue = [returnedValue, response];
20107          }
20108          else if(response !== undefined) {
20109            returnedValue = response;
20110          }
20111          return found;
20112        }
20113      };
20114
20115      if(methodInvoked) {
20116        if(instance === undefined) {
20117          module.initialize();
20118        }
20119        module.invoke(query);
20120      }
20121      else {
20122        if(instance !== undefined) {
20123          instance.invoke('destroy');
20124        }
20125        module.initialize();
20126      }
20127    })
20128  ;
20129
20130  return (returnedValue !== undefined)
20131    ? returnedValue
20132    : this
20133  ;
20134};
20135
20136$.fn.state.settings = {
20137
20138  // module info
20139  name           : 'State',
20140
20141  // debug output
20142  debug          : false,
20143
20144  // verbose debug output
20145  verbose        : false,
20146
20147  // namespace for events
20148  namespace      : 'state',
20149
20150  // debug data includes performance
20151  performance    : true,
20152
20153  // callback occurs on state change
20154  onActivate     : function() {},
20155  onDeactivate   : function() {},
20156  onChange       : function() {},
20157
20158  // state test functions
20159  activateTest   : function() { return true; },
20160  deactivateTest : function() { return true; },
20161
20162  // whether to automatically map default states
20163  automatic      : true,
20164
20165  // activate / deactivate changes all elements instantiated at same time
20166  sync           : false,
20167
20168  // default flash text duration, used for temporarily changing text of an element
20169  flashDuration  : 1000,
20170
20171  // selector filter
20172  filter     : {
20173    text   : '.loading, .disabled',
20174    active : '.disabled'
20175  },
20176
20177  context    : false,
20178
20179  // error
20180  error: {
20181    beforeSend : 'The before send function has cancelled state change',
20182    method     : 'The method you called is not defined.'
20183  },
20184
20185  // metadata
20186  metadata: {
20187    promise    : 'promise',
20188    storedText : 'stored-text'
20189  },
20190
20191  // change class on state
20192  className: {
20193    active   : 'active',
20194    disabled : 'disabled',
20195    error    : 'error',
20196    loading  : 'loading',
20197    success  : 'success',
20198    warning  : 'warning'
20199  },
20200
20201  selector: {
20202    // selector for text node
20203    text: false
20204  },
20205
20206  defaults : {
20207    input: {
20208      disabled : true,
20209      loading  : true,
20210      active   : true
20211    },
20212    button: {
20213      disabled : true,
20214      loading  : true,
20215      active   : true,
20216    },
20217    progress: {
20218      active   : true,
20219      success  : true,
20220      warning  : true,
20221      error    : true
20222    }
20223  },
20224
20225  states     : {
20226    active   : true,
20227    disabled : true,
20228    error    : true,
20229    loading  : true,
20230    success  : true,
20231    warning  : true
20232  },
20233
20234  text     : {
20235    disabled   : false,
20236    flash      : false,
20237    hover      : false,
20238    active     : false,
20239    inactive   : false,
20240    activate   : false,
20241    deactivate : false
20242  }
20243
20244};
20245
20246
20247
20248})( jQuery, window, document );
20249
20250/*!
20251 * # Semantic UI 2.1.7 - Visibility
20252 * http://github.com/semantic-org/semantic-ui/
20253 *
20254 *
20255 * Copyright 2015 Contributors
20256 * Released under the MIT license
20257 * http://opensource.org/licenses/MIT
20258 *
20259 */
20260
20261;(function ( $, window, document, undefined ) {
20262
20263"use strict";
20264
20265$.fn.visibility = function(parameters) {
20266  var
20267    $allModules    = $(this),
20268    moduleSelector = $allModules.selector || '',
20269
20270    time           = new Date().getTime(),
20271    performance    = [],
20272
20273    query          = arguments[0],
20274    methodInvoked  = (typeof query == 'string'),
20275    queryArguments = [].slice.call(arguments, 1),
20276    returnedValue
20277  ;
20278
20279  $allModules
20280    .each(function() {
20281      var
20282        settings        = ( $.isPlainObject(parameters) )
20283          ? $.extend(true, {}, $.fn.visibility.settings, parameters)
20284          : $.extend({}, $.fn.visibility.settings),
20285
20286        className       = settings.className,
20287        namespace       = settings.namespace,
20288        error           = settings.error,
20289        metadata        = settings.metadata,
20290
20291        eventNamespace  = '.' + namespace,
20292        moduleNamespace = 'module-' + namespace,
20293
20294        $window         = $(window),
20295
20296        $module         = $(this),
20297        $context        = $(settings.context),
20298
20299        $placeholder,
20300
20301        selector        = $module.selector || '',
20302        instance        = $module.data(moduleNamespace),
20303
20304        requestAnimationFrame = window.requestAnimationFrame
20305          || window.mozRequestAnimationFrame
20306          || window.webkitRequestAnimationFrame
20307          || window.msRequestAnimationFrame
20308          || function(callback) { setTimeout(callback, 0); },
20309
20310        element         = this,
20311        disabled        = false,
20312
20313        observer,
20314        module
20315      ;
20316
20317      module = {
20318
20319        initialize: function() {
20320          module.debug('Initializing', settings);
20321
20322          module.setup.cache();
20323
20324          if( module.should.trackChanges() ) {
20325
20326            if(settings.type == 'image') {
20327              module.setup.image();
20328            }
20329            if(settings.type == 'fixed') {
20330              module.setup.fixed();
20331            }
20332
20333            if(settings.observeChanges) {
20334              module.observeChanges();
20335            }
20336            module.bind.events();
20337          }
20338
20339          module.save.position();
20340          if( !module.is.visible() ) {
20341            module.error(error.visible, $module);
20342          }
20343
20344          if(settings.initialCheck) {
20345            module.checkVisibility();
20346          }
20347          module.instantiate();
20348        },
20349
20350        instantiate: function() {
20351          module.debug('Storing instance', module);
20352          $module
20353            .data(moduleNamespace, module)
20354          ;
20355          instance = module;
20356        },
20357
20358        destroy: function() {
20359          module.verbose('Destroying previous module');
20360          if(observer) {
20361            observer.disconnect();
20362          }
20363          $window
20364            .off('load'   + eventNamespace, module.event.load)
20365            .off('resize' + eventNamespace, module.event.resize)
20366          ;
20367          $context
20368            .off('scrollchange' + eventNamespace, module.event.scrollchange)
20369          ;
20370          $module
20371            .off(eventNamespace)
20372            .removeData(moduleNamespace)
20373          ;
20374        },
20375
20376        observeChanges: function() {
20377          if('MutationObserver' in window) {
20378            observer = new MutationObserver(function(mutations) {
20379              module.verbose('DOM tree modified, updating visibility calculations');
20380              module.timer = setTimeout(function() {
20381                module.verbose('DOM tree modified, updating sticky menu');
20382                module.refresh();
20383              }, 100);
20384            });
20385            observer.observe(element, {
20386              childList : true,
20387              subtree   : true
20388            });
20389            module.debug('Setting up mutation observer', observer);
20390          }
20391        },
20392
20393        bind: {
20394          events: function() {
20395            module.verbose('Binding visibility events to scroll and resize');
20396            if(settings.refreshOnLoad) {
20397              $window
20398                .on('load'   + eventNamespace, module.event.load)
20399              ;
20400            }
20401            $window
20402              .on('resize' + eventNamespace, module.event.resize)
20403            ;
20404            // pub/sub pattern
20405            $context
20406              .off('scroll'      + eventNamespace)
20407              .on('scroll'       + eventNamespace, module.event.scroll)
20408              .on('scrollchange' + eventNamespace, module.event.scrollchange)
20409            ;
20410          }
20411        },
20412
20413        event: {
20414          resize: function() {
20415            module.debug('Window resized');
20416            if(settings.refreshOnResize) {
20417              requestAnimationFrame(module.refresh);
20418            }
20419          },
20420          load: function() {
20421            module.debug('Page finished loading');
20422            requestAnimationFrame(module.refresh);
20423          },
20424          // publishes scrollchange event on one scroll
20425          scroll: function() {
20426            if(settings.throttle) {
20427              clearTimeout(module.timer);
20428              module.timer = setTimeout(function() {
20429                $context.triggerHandler('scrollchange' + eventNamespace, [ $context.scrollTop() ]);
20430              }, settings.throttle);
20431            }
20432            else {
20433              requestAnimationFrame(function() {
20434                $context.triggerHandler('scrollchange' + eventNamespace, [ $context.scrollTop() ]);
20435              });
20436            }
20437          },
20438          // subscribes to scrollchange
20439          scrollchange: function(event, scrollPosition) {
20440            module.checkVisibility(scrollPosition);
20441          },
20442        },
20443
20444        precache: function(images, callback) {
20445          if (!(images instanceof Array)) {
20446            images = [images];
20447          }
20448          var
20449            imagesLength  = images.length,
20450            loadedCounter = 0,
20451            cache         = [],
20452            cacheImage    = document.createElement('img'),
20453            handleLoad    = function() {
20454              loadedCounter++;
20455              if (loadedCounter >= images.length) {
20456                if ($.isFunction(callback)) {
20457                  callback();
20458                }
20459              }
20460            }
20461          ;
20462          while (imagesLength--) {
20463            cacheImage         = document.createElement('img');
20464            cacheImage.onload  = handleLoad;
20465            cacheImage.onerror = handleLoad;
20466            cacheImage.src     = images[imagesLength];
20467            cache.push(cacheImage);
20468          }
20469        },
20470
20471        enableCallbacks: function() {
20472          module.debug('Allowing callbacks to occur');
20473          disabled = false;
20474        },
20475
20476        disableCallbacks: function() {
20477          module.debug('Disabling all callbacks temporarily');
20478          disabled = true;
20479        },
20480
20481        should: {
20482          trackChanges: function() {
20483            if(methodInvoked) {
20484              module.debug('One time query, no need to bind events');
20485              return false;
20486            }
20487            module.debug('Callbacks being attached');
20488            return true;
20489          }
20490        },
20491
20492        setup: {
20493          cache: function() {
20494            module.cache = {
20495              occurred : {},
20496              screen   : {},
20497              element  : {},
20498            };
20499          },
20500          image: function() {
20501            var
20502              src = $module.data(metadata.src)
20503            ;
20504            if(src) {
20505              module.verbose('Lazy loading image', src);
20506              settings.once           = true;
20507              settings.observeChanges = false;
20508
20509              // show when top visible
20510              settings.onOnScreen = function() {
20511                module.debug('Image on screen', element);
20512                module.precache(src, function() {
20513                  module.set.image(src);
20514                });
20515              };
20516            }
20517          },
20518          fixed: function() {
20519            module.debug('Setting up fixed');
20520            settings.once           = false;
20521            settings.observeChanges = false;
20522            settings.initialCheck   = true;
20523            settings.refreshOnLoad  = true;
20524            if(!parameters.transition) {
20525              settings.transition = false;
20526            }
20527            module.create.placeholder();
20528            module.debug('Added placeholder', $placeholder);
20529            settings.onTopPassed = function() {
20530              module.debug('Element passed, adding fixed position', $module);
20531              module.show.placeholder();
20532              module.set.fixed();
20533              if(settings.transition) {
20534                if($.fn.transition !== undefined) {
20535                  $module.transition(settings.transition, settings.duration);
20536                }
20537              }
20538            };
20539            settings.onTopPassedReverse = function() {
20540              module.debug('Element returned to position, removing fixed', $module);
20541              module.hide.placeholder();
20542              module.remove.fixed();
20543            };
20544          }
20545        },
20546
20547        create: {
20548          placeholder: function() {
20549            module.verbose('Creating fixed position placeholder');
20550            $placeholder = $module
20551              .clone(false)
20552              .css('display', 'none')
20553              .addClass(className.placeholder)
20554              .insertAfter($module)
20555            ;
20556          }
20557        },
20558
20559        show: {
20560          placeholder: function() {
20561            module.verbose('Showing placeholder');
20562            $placeholder
20563              .css('display', 'block')
20564              .css('visibility', 'hidden')
20565            ;
20566          }
20567        },
20568        hide: {
20569          placeholder: function() {
20570            module.verbose('Hiding placeholder');
20571            $placeholder
20572              .css('display', 'none')
20573              .css('visibility', '')
20574            ;
20575          }
20576        },
20577
20578        set: {
20579          fixed: function() {
20580            module.verbose('Setting element to fixed position');
20581            $module
20582              .addClass(className.fixed)
20583              .css({
20584                position : 'fixed',
20585                top      : settings.offset + 'px',
20586                left     : 'auto',
20587                zIndex   : '1'
20588              })
20589            ;
20590          },
20591          image: function(src) {
20592            $module
20593              .attr('src', src)
20594            ;
20595            if(settings.transition) {
20596              if( $.fn.transition !== undefined ) {
20597                $module.transition(settings.transition, settings.duration);
20598              }
20599              else {
20600                $module.fadeIn(settings.duration);
20601              }
20602            }
20603            else {
20604              $module.show();
20605            }
20606          }
20607        },
20608
20609        is: {
20610          onScreen: function() {
20611            var
20612              calculations   = module.get.elementCalculations()
20613            ;
20614            return calculations.onScreen;
20615          },
20616          offScreen: function() {
20617            var
20618              calculations   = module.get.elementCalculations()
20619            ;
20620            return calculations.offScreen;
20621          },
20622          visible: function() {
20623            if(module.cache && module.cache.element) {
20624              return !(module.cache.element.width === 0 && module.cache.element.offset.top === 0);
20625            }
20626            return false;
20627          }
20628        },
20629
20630        refresh: function() {
20631          module.debug('Refreshing constants (width/height)');
20632          if(settings.type == 'fixed') {
20633            module.remove.fixed();
20634            module.remove.occurred();
20635          }
20636          module.reset();
20637          module.save.position();
20638          if(settings.checkOnRefresh) {
20639            module.checkVisibility();
20640          }
20641          settings.onRefresh.call(element);
20642        },
20643
20644        reset: function() {
20645          module.verbose('Reseting all cached values');
20646          if( $.isPlainObject(module.cache) ) {
20647            module.cache.screen = {};
20648            module.cache.element = {};
20649          }
20650        },
20651
20652        checkVisibility: function(scroll) {
20653          module.verbose('Checking visibility of element', module.cache.element);
20654
20655          if( !disabled && module.is.visible() ) {
20656
20657            // save scroll position
20658            module.save.scroll(scroll);
20659
20660            // update calculations derived from scroll
20661            module.save.calculations();
20662
20663            // percentage
20664            module.passed();
20665
20666            // reverse (must be first)
20667            module.passingReverse();
20668            module.topVisibleReverse();
20669            module.bottomVisibleReverse();
20670            module.topPassedReverse();
20671            module.bottomPassedReverse();
20672
20673            // one time
20674            module.onScreen();
20675            module.offScreen();
20676            module.passing();
20677            module.topVisible();
20678            module.bottomVisible();
20679            module.topPassed();
20680            module.bottomPassed();
20681
20682            // on update callback
20683            if(settings.onUpdate) {
20684              settings.onUpdate.call(element, module.get.elementCalculations());
20685            }
20686          }
20687        },
20688
20689        passed: function(amount, newCallback) {
20690          var
20691            calculations   = module.get.elementCalculations(),
20692            amountInPixels
20693          ;
20694          // assign callback
20695          if(amount && newCallback) {
20696            settings.onPassed[amount] = newCallback;
20697          }
20698          else if(amount !== undefined) {
20699            return (module.get.pixelsPassed(amount) > calculations.pixelsPassed);
20700          }
20701          else if(calculations.passing) {
20702            $.each(settings.onPassed, function(amount, callback) {
20703              if(calculations.bottomVisible || calculations.pixelsPassed > module.get.pixelsPassed(amount)) {
20704                module.execute(callback, amount);
20705              }
20706              else if(!settings.once) {
20707                module.remove.occurred(callback);
20708              }
20709            });
20710          }
20711        },
20712
20713        onScreen: function(newCallback) {
20714          var
20715            calculations = module.get.elementCalculations(),
20716            callback     = newCallback || settings.onOnScreen,
20717            callbackName = 'onScreen'
20718          ;
20719          if(newCallback) {
20720            module.debug('Adding callback for onScreen', newCallback);
20721            settings.onOnScreen = newCallback;
20722          }
20723          if(calculations.onScreen) {
20724            module.execute(callback, callbackName);
20725          }
20726          else if(!settings.once) {
20727            module.remove.occurred(callbackName);
20728          }
20729          if(newCallback !== undefined) {
20730            return calculations.onOnScreen;
20731          }
20732        },
20733
20734        offScreen: function(newCallback) {
20735          var
20736            calculations = module.get.elementCalculations(),
20737            callback     = newCallback || settings.onOffScreen,
20738            callbackName = 'offScreen'
20739          ;
20740          if(newCallback) {
20741            module.debug('Adding callback for offScreen', newCallback);
20742            settings.onOffScreen = newCallback;
20743          }
20744          if(calculations.offScreen) {
20745            module.execute(callback, callbackName);
20746          }
20747          else if(!settings.once) {
20748            module.remove.occurred(callbackName);
20749          }
20750          if(newCallback !== undefined) {
20751            return calculations.onOffScreen;
20752          }
20753        },
20754
20755        passing: function(newCallback) {
20756          var
20757            calculations = module.get.elementCalculations(),
20758            callback     = newCallback || settings.onPassing,
20759            callbackName = 'passing'
20760          ;
20761          if(newCallback) {
20762            module.debug('Adding callback for passing', newCallback);
20763            settings.onPassing = newCallback;
20764          }
20765          if(calculations.passing) {
20766            module.execute(callback, callbackName);
20767          }
20768          else if(!settings.once) {
20769            module.remove.occurred(callbackName);
20770          }
20771          if(newCallback !== undefined) {
20772            return calculations.passing;
20773          }
20774        },
20775
20776
20777        topVisible: function(newCallback) {
20778          var
20779            calculations = module.get.elementCalculations(),
20780            callback     = newCallback || settings.onTopVisible,
20781            callbackName = 'topVisible'
20782          ;
20783          if(newCallback) {
20784            module.debug('Adding callback for top visible', newCallback);
20785            settings.onTopVisible = newCallback;
20786          }
20787          if(calculations.topVisible) {
20788            module.execute(callback, callbackName);
20789          }
20790          else if(!settings.once) {
20791            module.remove.occurred(callbackName);
20792          }
20793          if(newCallback === undefined) {
20794            return calculations.topVisible;
20795          }
20796        },
20797
20798        bottomVisible: function(newCallback) {
20799          var
20800            calculations = module.get.elementCalculations(),
20801            callback     = newCallback || settings.onBottomVisible,
20802            callbackName = 'bottomVisible'
20803          ;
20804          if(newCallback) {
20805            module.debug('Adding callback for bottom visible', newCallback);
20806            settings.onBottomVisible = newCallback;
20807          }
20808          if(calculations.bottomVisible) {
20809            module.execute(callback, callbackName);
20810          }
20811          else if(!settings.once) {
20812            module.remove.occurred(callbackName);
20813          }
20814          if(newCallback === undefined) {
20815            return calculations.bottomVisible;
20816          }
20817        },
20818
20819        topPassed: function(newCallback) {
20820          var
20821            calculations = module.get.elementCalculations(),
20822            callback     = newCallback || settings.onTopPassed,
20823            callbackName = 'topPassed'
20824          ;
20825          if(newCallback) {
20826            module.debug('Adding callback for top passed', newCallback);
20827            settings.onTopPassed = newCallback;
20828          }
20829          if(calculations.topPassed) {
20830            module.execute(callback, callbackName);
20831          }
20832          else if(!settings.once) {
20833            module.remove.occurred(callbackName);
20834          }
20835          if(newCallback === undefined) {
20836            return calculations.topPassed;
20837          }
20838        },
20839
20840        bottomPassed: function(newCallback) {
20841          var
20842            calculations = module.get.elementCalculations(),
20843            callback     = newCallback || settings.onBottomPassed,
20844            callbackName = 'bottomPassed'
20845          ;
20846          if(newCallback) {
20847            module.debug('Adding callback for bottom passed', newCallback);
20848            settings.onBottomPassed = newCallback;
20849          }
20850          if(calculations.bottomPassed) {
20851            module.execute(callback, callbackName);
20852          }
20853          else if(!settings.once) {
20854            module.remove.occurred(callbackName);
20855          }
20856          if(newCallback === undefined) {
20857            return calculations.bottomPassed;
20858          }
20859        },
20860
20861        passingReverse: function(newCallback) {
20862          var
20863            calculations = module.get.elementCalculations(),
20864            callback     = newCallback || settings.onPassingReverse,
20865            callbackName = 'passingReverse'
20866          ;
20867          if(newCallback) {
20868            module.debug('Adding callback for passing reverse', newCallback);
20869            settings.onPassingReverse = newCallback;
20870          }
20871          if(!calculations.passing) {
20872            if(module.get.occurred('passing')) {
20873              module.execute(callback, callbackName);
20874            }
20875          }
20876          else if(!settings.once) {
20877            module.remove.occurred(callbackName);
20878          }
20879          if(newCallback !== undefined) {
20880            return !calculations.passing;
20881          }
20882        },
20883
20884
20885        topVisibleReverse: function(newCallback) {
20886          var
20887            calculations = module.get.elementCalculations(),
20888            callback     = newCallback || settings.onTopVisibleReverse,
20889            callbackName = 'topVisibleReverse'
20890          ;
20891          if(newCallback) {
20892            module.debug('Adding callback for top visible reverse', newCallback);
20893            settings.onTopVisibleReverse = newCallback;
20894          }
20895          if(!calculations.topVisible) {
20896            if(module.get.occurred('topVisible')) {
20897              module.execute(callback, callbackName);
20898            }
20899          }
20900          else if(!settings.once) {
20901            module.remove.occurred(callbackName);
20902          }
20903          if(newCallback === undefined) {
20904            return !calculations.topVisible;
20905          }
20906        },
20907
20908        bottomVisibleReverse: function(newCallback) {
20909          var
20910            calculations = module.get.elementCalculations(),
20911            callback     = newCallback || settings.onBottomVisibleReverse,
20912            callbackName = 'bottomVisibleReverse'
20913          ;
20914          if(newCallback) {
20915            module.debug('Adding callback for bottom visible reverse', newCallback);
20916            settings.onBottomVisibleReverse = newCallback;
20917          }
20918          if(!calculations.bottomVisible) {
20919            if(module.get.occurred('bottomVisible')) {
20920              module.execute(callback, callbackName);
20921            }
20922          }
20923          else if(!settings.once) {
20924            module.remove.occurred(callbackName);
20925          }
20926          if(newCallback === undefined) {
20927            return !calculations.bottomVisible;
20928          }
20929        },
20930
20931        topPassedReverse: function(newCallback) {
20932          var
20933            calculations = module.get.elementCalculations(),
20934            callback     = newCallback || settings.onTopPassedReverse,
20935            callbackName = 'topPassedReverse'
20936          ;
20937          if(newCallback) {
20938            module.debug('Adding callback for top passed reverse', newCallback);
20939            settings.onTopPassedReverse = newCallback;
20940          }
20941          if(!calculations.topPassed) {
20942            if(module.get.occurred('topPassed')) {
20943              module.execute(callback, callbackName);
20944            }
20945          }
20946          else if(!settings.once) {
20947            module.remove.occurred(callbackName);
20948          }
20949          if(newCallback === undefined) {
20950            return !calculations.onTopPassed;
20951          }
20952        },
20953
20954        bottomPassedReverse: function(newCallback) {
20955          var
20956            calculations = module.get.elementCalculations(),
20957            callback     = newCallback || settings.onBottomPassedReverse,
20958            callbackName = 'bottomPassedReverse'
20959          ;
20960          if(newCallback) {
20961            module.debug('Adding callback for bottom passed reverse', newCallback);
20962            settings.onBottomPassedReverse = newCallback;
20963          }
20964          if(!calculations.bottomPassed) {
20965            if(module.get.occurred('bottomPassed')) {
20966              module.execute(callback, callbackName);
20967            }
20968          }
20969          else if(!settings.once) {
20970            module.remove.occurred(callbackName);
20971          }
20972          if(newCallback === undefined) {
20973            return !calculations.bottomPassed;
20974          }
20975        },
20976
20977        execute: function(callback, callbackName) {
20978          var
20979            calculations = module.get.elementCalculations(),
20980            screen       = module.get.screenCalculations()
20981          ;
20982          callback = callback || false;
20983          if(callback) {
20984            if(settings.continuous) {
20985              module.debug('Callback being called continuously', callbackName, calculations);
20986              callback.call(element, calculations, screen);
20987            }
20988            else if(!module.get.occurred(callbackName)) {
20989              module.debug('Conditions met', callbackName, calculations);
20990              callback.call(element, calculations, screen);
20991            }
20992          }
20993          module.save.occurred(callbackName);
20994        },
20995
20996        remove: {
20997          fixed: function() {
20998            module.debug('Removing fixed position');
20999            $module
21000              .removeClass(className.fixed)
21001              .css({
21002                position : '',
21003                top      : '',
21004                left     : '',
21005                zIndex   : ''
21006              })
21007            ;
21008          },
21009          occurred: function(callback) {
21010            if(callback) {
21011              var
21012                occurred = module.cache.occurred
21013              ;
21014              if(occurred[callback] !== undefined && occurred[callback] === true) {
21015                module.debug('Callback can now be called again', callback);
21016                module.cache.occurred[callback] = false;
vendor: 6,569 bytes, lines 21017-21193
21017              }
21018            }
21019            else {
21020              module.cache.occurred = {};
21021            }
21022          }
21023        },
21024
21025        save: {
21026          calculations: function() {
21027            module.verbose('Saving all calculations necessary to determine positioning');
21028            module.save.direction();
21029            module.save.screenCalculations();
21030            module.save.elementCalculations();
21031          },
21032          occurred: function(callback) {
21033            if(callback) {
21034              if(module.cache.occurred[callback] === undefined || (module.cache.occurred[callback] !== true)) {
21035                module.verbose('Saving callback occurred', callback);
21036                module.cache.occurred[callback] = true;
21037              }
21038            }
21039          },
21040          scroll: function(scrollPosition) {
21041            scrollPosition      = scrollPosition + settings.offset || $context.scrollTop() + settings.offset;
21042            module.cache.scroll = scrollPosition;
21043          },
21044          direction: function() {
21045            var
21046              scroll     = module.get.scroll(),
21047              lastScroll = module.get.lastScroll(),
21048              direction
21049            ;
21050            if(scroll > lastScroll && lastScroll) {
21051              direction = 'down';
21052            }
21053            else if(scroll < lastScroll && lastScroll) {
21054              direction = 'up';
21055            }
21056            else {
21057              direction = 'static';
21058            }
21059            module.cache.direction = direction;
21060            return module.cache.direction;
21061          },
21062          elementPosition: function() {
21063            var
21064              element = module.cache.element,
21065              screen  = module.get.screenSize()
21066            ;
21067            module.verbose('Saving element position');
21068            // (quicker than $.extend)
21069            element.fits          = (element.height < screen.height);
21070            element.offset        = $module.offset();
21071            element.width         = $module.outerWidth();
21072            element.height        = $module.outerHeight();
21073            // store
21074            module.cache.element = element;
21075            return element;
21076          },
21077          elementCalculations: function() {
21078            var
21079              screen     = module.get.screenCalculations(),
21080              element    = module.get.elementPosition()
21081            ;
21082            // offset
21083            if(settings.includeMargin) {
21084              element.margin        = {};
21085              element.margin.top    = parseInt($module.css('margin-top'), 10);
21086              element.margin.bottom = parseInt($module.css('margin-bottom'), 10);
21087              element.top    = element.offset.top - element.margin.top;
21088              element.bottom = element.offset.top + element.height + element.margin.bottom;
21089            }
21090            else {
21091              element.top    = element.offset.top;
21092              element.bottom = element.offset.top + element.height;
21093            }
21094
21095            // visibility
21096            element.topVisible       = (screen.bottom >= element.top);
21097            element.topPassed        = (screen.top >= element.top);
21098            element.bottomVisible    = (screen.bottom >= element.bottom);
21099            element.bottomPassed     = (screen.top >= element.bottom);
21100            element.pixelsPassed     = 0;
21101            element.percentagePassed = 0;
21102
21103            // meta calculations
21104            element.onScreen  = (element.topVisible && !element.bottomPassed);
21105            element.passing   = (element.topPassed && !element.bottomPassed);
21106            element.offScreen = (!element.onScreen);
21107
21108            // passing calculations
21109            if(element.passing) {
21110              element.pixelsPassed     = (screen.top - element.top);
21111              element.percentagePassed = (screen.top - element.top) / element.height;
21112            }
21113            module.cache.element = element;
21114            module.verbose('Updated element calculations', element);
21115            return element;
21116          },
21117          screenCalculations: function() {
21118            var
21119              scroll = module.get.scroll()
21120            ;
21121            module.save.direction();
21122            module.cache.screen.top    = scroll;
21123            module.cache.screen.bottom = scroll + module.cache.screen.height;
21124            return module.cache.screen;
21125          },
21126          screenSize: function() {
21127            module.verbose('Saving window position');
21128            module.cache.screen = {
21129              height: $context.height()
21130            };
21131          },
21132          position: function() {
21133            module.save.screenSize();
21134            module.save.elementPosition();
21135          }
21136        },
21137
21138        get: {
21139          pixelsPassed: function(amount) {
21140            var
21141              element = module.get.elementCalculations()
21142            ;
21143            if(amount.search('%') > -1) {
21144              return ( element.height * (parseInt(amount, 10) / 100) );
21145            }
21146            return parseInt(amount, 10);
21147          },
21148          occurred: function(callback) {
21149            return (module.cache.occurred !== undefined)
21150              ? module.cache.occurred[callback] || false
21151              : false
21152            ;
21153          },
21154          direction: function() {
21155            if(module.cache.direction === undefined) {
21156              module.save.direction();
21157            }
21158            return module.cache.direction;
21159          },
21160          elementPosition: function() {
21161            if(module.cache.element === undefined) {
21162              module.save.elementPosition();
21163            }
21164            return module.cache.element;
21165          },
21166          elementCalculations: function() {
21167            if(module.cache.element === undefined) {
21168              module.save.elementCalculations();
21169            }
21170            return module.cache.element;
21171          },
21172          screenCalculations: function() {
21173            if(module.cache.screen === undefined) {
21174              module.save.screenCalculations();
21175            }
21176            return module.cache.screen;
21177          },
21178          screenSize: function() {
21179            if(module.cache.screen === undefined) {
21180              module.save.screenSize();
21181            }
21182            return module.cache.screen;
21183          },
21184          scroll: function() {
21185            if(module.cache.scroll === undefined) {
21186              module.save.scroll();
21187            }
21188            return module.cache.scroll;
21189          },
21190          lastScroll: function() {
21191            if(module.cache.screen === undefined) {
21192              module.debug('First scroll event, no last scroll could be found');
21193              return false;
vendor: 8,239 bytes, lines 21194-21465
21194            }
21195            return module.cache.screen.top;
21196          }
21197        },
21198
21199        setting: function(name, value) {
21200          if( $.isPlainObject(name) ) {
21201            $.extend(true, settings, name);
21202          }
21203          else if(value !== undefined) {
21204            settings[name] = value;
21205          }
21206          else {
21207            return settings[name];
21208          }
21209        },
21210        internal: function(name, value) {
21211          if( $.isPlainObject(name) ) {
21212            $.extend(true, module, name);
21213          }
21214          else if(value !== undefined) {
21215            module[name] = value;
21216          }
21217          else {
21218            return module[name];
21219          }
21220        },
21221        debug: function() {
21222          if(settings.debug) {
21223            if(settings.performance) {
21224              module.performance.log(arguments);
21225            }
21226            else {
21227              module.debug = Function.prototype.bind.call(console.info, console, settings.name + ':');
21228              module.debug.apply(console, arguments);
21229            }
21230          }
21231        },
21232        verbose: function() {
21233          if(settings.verbose && settings.debug) {
21234            if(settings.performance) {
21235              module.performance.log(arguments);
21236            }
21237            else {
21238              module.verbose = Function.prototype.bind.call(console.info, console, settings.name + ':');
21239              module.verbose.apply(console, arguments);
21240            }
21241          }
21242        },
21243        error: function() {
21244          module.error = Function.prototype.bind.call(console.error, console, settings.name + ':');
21245          module.error.apply(console, arguments);
21246        },
21247        performance: {
21248          log: function(message) {
21249            var
21250              currentTime,
21251              executionTime,
21252              previousTime
21253            ;
21254            if(settings.performance) {
21255              currentTime   = new Date().getTime();
21256              previousTime  = time || currentTime;
21257              executionTime = currentTime - previousTime;
21258              time          = currentTime;
21259              performance.push({
21260                'Name'           : message[0],
21261                'Arguments'      : [].slice.call(message, 1) || '',
21262                'Element'        : element,
21263                'Execution Time' : executionTime
21264              });
21265            }
21266            clearTimeout(module.performance.timer);
21267            module.performance.timer = setTimeout(module.performance.display, 500);
21268          },
21269          display: function() {
21270            var
21271              title = settings.name + ':',
21272              totalTime = 0
21273            ;
21274            time = false;
21275            clearTimeout(module.performance.timer);
21276            $.each(performance, function(index, data) {
21277              totalTime += data['Execution Time'];
21278            });
21279            title += ' ' + totalTime + 'ms';
21280            if(moduleSelector) {
21281              title += ' \'' + moduleSelector + '\'';
21282            }
21283            if( (console.group !== undefined || console.table !== undefined) && performance.length > 0) {
21284              console.groupCollapsed(title);
21285              if(console.table) {
21286                console.table(performance);
21287              }
21288              else {
21289                $.each(performance, function(index, data) {
21290                  console.log(data['Name'] + ': ' + data['Execution Time']+'ms');
21291                });
21292              }
21293              console.groupEnd();
21294            }
21295            performance = [];
21296          }
21297        },
21298        invoke: function(query, passedArguments, context) {
21299          var
21300            object = instance,
21301            maxDepth,
21302            found,
21303            response
21304          ;
21305          passedArguments = passedArguments || queryArguments;
21306          context         = element         || context;
21307          if(typeof query == 'string' && object !== undefined) {
21308            query    = query.split(/[\. ]/);
21309            maxDepth = query.length - 1;
21310            $.each(query, function(depth, value) {
21311              var camelCaseValue = (depth != maxDepth)
21312                ? value + query[depth + 1].charAt(0).toUpperCase() + query[depth + 1].slice(1)
21313                : query
21314              ;
21315              if( $.isPlainObject( object[camelCaseValue] ) && (depth != maxDepth) ) {
21316                object = object[camelCaseValue];
21317              }
21318              else if( object[camelCaseValue] !== undefined ) {
21319                found = object[camelCaseValue];
21320                return false;
21321              }
21322              else if( $.isPlainObject( object[value] ) && (depth != maxDepth) ) {
21323                object = object[value];
21324              }
21325              else if( object[value] !== undefined ) {
21326                found = object[value];
21327                return false;
21328              }
21329              else {
21330                module.error(error.method, query);
21331                return false;
21332              }
21333            });
21334          }
21335          if ( $.isFunction( found ) ) {
21336            response = found.apply(context, passedArguments);
21337          }
21338          else if(found !== undefined) {
21339            response = found;
21340          }
21341          if($.isArray(returnedValue)) {
21342            returnedValue.push(response);
21343          }
21344          else if(returnedValue !== undefined) {
21345            returnedValue = [returnedValue, response];
21346          }
21347          else if(response !== undefined) {
21348            returnedValue = response;
21349          }
21350          return found;
21351        }
21352      };
21353
21354      if(methodInvoked) {
21355        if(instance === undefined) {
21356          module.initialize();
21357        }
21358        instance.save.scroll();
21359        instance.save.calculations();
21360        module.invoke(query);
21361      }
21362      else {
21363        if(instance !== undefined) {
21364          instance.invoke('destroy');
21365        }
21366        module.initialize();
21367      }
21368    })
21369  ;
21370
21371  return (returnedValue !== undefined)
21372    ? returnedValue
21373    : this
21374  ;
21375};
21376
21377$.fn.visibility.settings = {
21378
21379  name                   : 'Visibility',
21380  namespace              : 'visibility',
21381
21382  debug                  : false,
21383  verbose                : false,
21384  performance            : true,
21385
21386  // whether to use mutation observers to follow changes
21387  observeChanges         : true,
21388
21389  // check position immediately on init
21390  initialCheck           : true,
21391
21392  // whether to refresh calculations after all page images load
21393  refreshOnLoad          : true,
21394
21395  // whether to refresh calculations after page resize event
21396  refreshOnResize        : true,
21397
21398  // should call callbacks on refresh event (resize, etc)
21399  checkOnRefresh         : true,
21400
21401  // callback should only occur one time
21402  once                   : true,
21403
21404  // callback should fire continuously whe evaluates to true
21405  continuous             : false,
21406
21407  // offset to use with scroll top
21408  offset                 : 0,
21409
21410  // whether to include margin in elements position
21411  includeMargin          : false,
21412
21413  // scroll context for visibility checks
21414  context                : window,
21415
21416  // visibility check delay in ms (defaults to animationFrame)
21417  throttle               : false,
21418
21419  // special visibility type (image, fixed)
21420  type                   : false,
21421
21422  // image only animation settings
21423  transition             : 'fade in',
21424  duration               : 1000,
21425
21426  // array of callbacks for percentage
21427  onPassed               : {},
21428
21429  // standard callbacks
21430  onOnScreen             : false,
21431  onOffScreen            : false,
21432  onPassing              : false,
21433  onTopVisible           : false,
21434  onBottomVisible        : false,
21435  onTopPassed            : false,
21436  onBottomPassed         : false,
21437
21438  // reverse callbacks
21439  onPassingReverse       : false,
21440  onTopVisibleReverse    : false,
21441  onBottomVisibleReverse : false,
21442  onTopPassedReverse     : false,
21443  onBottomPassedReverse  : false,
21444
21445  // utility callbacks
21446  onUpdate               : false, // disabled by default for performance
21447  onRefresh              : function(){},
21448
21449  metadata : {
21450    src: 'src'
21451  },
21452
21453  className: {
21454    fixed       : 'fixed',
21455    placeholder : 'placeholder'
21456  },
21457
21458  error : {
21459    method  : 'The method you called is not defined.',
21460    visible : 'Element is hidden, you must call refresh after element becomes visible'
21461  }
21462
21463};
21464
21465})( jQuery, window, document );

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.