github.com/fanux/shipyard@v0.0.0-20161009071005-6515ce223235/controller/static/semantic/dist/semantic.js (about)

     1   /*
     2   * # Semantic UI - x.x
     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 x.x - Site
    13   * http://github.com/semantic-org/semantic-ui/
    14   *
    15   *
    16   * Copyright 2014 Contributors
    17   * Released under the MIT license
    18   * http://opensource.org/licenses/MIT
    19   *
    20   */
    21  ;(function ( $, window, document, undefined ) {
    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, normailizing 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, 100);
   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     : true,
   447    performance : true,
   448  
   449    modules: [
   450      'accordion',
   451      'api',
   452      'checkbox',
   453      'dimmer',
   454      'dropdown',
   455      'form',
   456      'modal',
   457      'nag',
   458      'popup',
   459      'rating',
   460      'shape',
   461      'sidebar',
   462      'state',
   463      'sticky',
   464      'tab',
   465      'transition',
   466      'video',
   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   * # Semantic UI x.x - Form Validation
   500   * http://github.com/semantic-org/semantic-ui/
   501   *
   502   *
   503   * Copyright 2014 Contributors
   504   * Released under the MIT license
   505   * http://opensource.org/licenses/MIT
   506   *
   507   */
   508  
   509  ;(function ( $, window, document, undefined ) {
   510  
   511  "use strict";
   512  
   513  $.fn.form = function(fields, parameters) {
   514    var
   515      $allModules     = $(this),
   516  
   517      settings        = $.extend(true, {}, $.fn.form.settings, parameters),
   518      validation      = $.extend({}, $.fn.form.settings.defaults, fields),
   519  
   520      namespace       = settings.namespace,
   521      metadata        = settings.metadata,
   522      selector        = settings.selector,
   523      className       = settings.className,
   524      error           = settings.error,
   525  
   526      eventNamespace  = '.' + namespace,
   527      moduleNamespace = 'module-' + namespace,
   528  
   529      moduleSelector  = $allModules.selector || '',
   530  
   531      time            = new Date().getTime(),
   532      performance     = [],
   533  
   534      query           = arguments[0],
   535      methodInvoked   = (typeof query == 'string'),
   536      queryArguments  = [].slice.call(arguments, 1),
   537      returnedValue
   538    ;
   539    $allModules
   540      .each(function() {
   541        var
   542          $module     = $(this),
   543          $field      = $(this).find(selector.field),
   544          $group      = $(this).find(selector.group),
   545          $message    = $(this).find(selector.message),
   546          $prompt     = $(this).find(selector.prompt),
   547  
   548          $submit     = $(this).find(selector.submit),
   549          $clear      = $(this).find(selector.clear),
   550          $reset      = $(this).find(selector.reset),
   551  
   552          formErrors  = [],
   553          keyHeldDown = false,
   554  
   555          element     = this,
   556          instance    = $module.data(moduleNamespace),
   557          module
   558        ;
   559  
   560        module      = {
   561  
   562          initialize: function() {
   563            module.verbose('Initializing form validation', $module, validation, settings);
   564            module.bindEvents();
   565            module.set.defaults();
   566            module.instantiate();
   567          },
   568  
   569          instantiate: function() {
   570            module.verbose('Storing instance of module', module);
   571            instance = module;
   572            $module
   573              .data(moduleNamespace, module)
   574            ;
   575          },
   576  
   577          destroy: function() {
   578            module.verbose('Destroying previous module', instance);
   579            module.removeEvents();
   580            $module
   581              .removeData(moduleNamespace)
   582            ;
   583          },
   584  
   585          refresh: function() {
   586            module.verbose('Refreshing selector cache');
   587            $field = $module.find(selector.field);
   588          },
   589  
   590          submit: function() {
   591            module.verbose('Submitting form', $module);
   592            $module
   593              .submit()
   594            ;
   595          },
   596  
   597          attachEvents: function(selector, action) {
   598            action = action || 'submit';
   599            $(selector)
   600              .on('click', function(event) {
   601                module[action]();
   602                event.preventDefault();
   603              })
   604            ;
   605          },
   606  
   607          bindEvents: function() {
   608            if(settings.keyboardShortcuts) {
   609              $field
   610                .on('keydown' + eventNamespace, module.event.field.keydown)
   611              ;
   612            }
   613            $module
   614              .on('submit' + eventNamespace, module.validate.form)
   615            ;
   616            $field
   617              .on('blur' + eventNamespace, module.event.field.blur)
   618            ;
   619  
   620            // attach events to common elements
   621            module.attachEvents($submit, 'submit');
   622            module.attachEvents($reset, 'reset');
   623            module.attachEvents($clear, 'clear');
   624  
   625            $field
   626              .each(function() {
   627                var
   628                  type       = $(this).prop('type'),
   629                  inputEvent = module.get.changeEvent(type)
   630                ;
   631                $(this)
   632                  .on(inputEvent + eventNamespace, module.event.field.change)
   633                ;
   634              })
   635            ;
   636          },
   637  
   638          clear: function() {
   639            $field
   640              .each(function () {
   641                var
   642                  $field       = $(this),
   643                  $element     = $field.parent(),
   644                  $fieldGroup  = $field.closest($group),
   645                  $prompt      = $fieldGroup.find(selector.prompt),
   646                  defaultValue = $field.data(metadata.defaultValue) || '',
   647                  isCheckbox   = $element.is(selector.uiCheckbox),
   648                  isDropdown   = $element.is(selector.uiDropdown),
   649                  isErrored    = $fieldGroup.hasClass(className.error)
   650                ;
   651                if(isErrored) {
   652                  module.verbose('Resetting error on field', $fieldGroup);
   653                  $fieldGroup.removeClass(className.error);
   654                  $prompt.remove();
   655                }
   656                if(isDropdown) {
   657                  module.verbose('Resetting dropdown value', $element, defaultValue);
   658                  $element.dropdown('clear');
   659                }
   660                else if(isCheckbox) {
   661                  $element.checkbox('uncheck');
   662                }
   663                else {
   664                  module.verbose('Resetting field value', $field, defaultValue);
   665                  $field.val('');
   666                }
   667              })
   668            ;
   669          },
   670  
   671          reset: function() {
   672            $field
   673              .each(function () {
   674                var
   675                  $field       = $(this),
   676                  $element     = $field.parent(),
   677                  $fieldGroup  = $field.closest($group),
   678                  $prompt      = $fieldGroup.find(selector.prompt),
   679                  defaultValue = $field.data(metadata.defaultValue) || '',
   680                  isCheckbox   = $element.is(selector.uiCheckbox),
   681                  isDropdown   = $element.is(selector.uiDropdown),
   682                  isErrored    = $fieldGroup.hasClass(className.error)
   683                ;
   684                if(isErrored) {
   685                  module.verbose('Resetting error on field', $fieldGroup);
   686                  $fieldGroup.removeClass(className.error);
   687                  $prompt.remove();
   688                }
   689                if(isDropdown) {
   690                  module.verbose('Resetting dropdown value', $element, defaultValue);
   691                  $element.dropdown('restore defaults');
   692                }
   693                else if(isCheckbox) {
   694                  module.verbose('Resetting checkbox value', $element, defaultValue);
   695                  if(defaultValue === true) {
   696                    $element.checkbox('check');
   697                  }
   698                  else {
   699                    $element.checkbox('uncheck');
   700                  }
   701                }
   702                else {
   703                  module.verbose('Resetting field value', $field, defaultValue);
   704                  $field.val(defaultValue);
   705                }
   706              })
   707            ;
   708          },
   709  
   710          removeEvents: function() {
   711            $module
   712              .off(eventNamespace)
   713            ;
   714            $field
   715              .off(eventNamespace)
   716            ;
   717            $submit
   718              .off(eventNamespace)
   719            ;
   720            $field
   721              .off(eventNamespace)
   722            ;
   723          },
   724  
   725          event: {
   726            field: {
   727              keydown: function(event) {
   728                var
   729                  $field  = $(this),
   730                  key     = event.which,
   731                  keyCode = {
   732                    enter  : 13,
   733                    escape : 27
   734                  }
   735                ;
   736                if( key == keyCode.escape) {
   737                  module.verbose('Escape key pressed blurring field');
   738                  $field
   739                    .blur()
   740                  ;
   741                }
   742                if(!event.ctrlKey && key == keyCode.enter && $field.is(selector.input) && $field.not(selector.checkbox).length > 0 ) {
   743                  $submit
   744                    .addClass(className.pressed)
   745                  ;
   746                  if(!keyHeldDown) {
   747                    $field
   748                      .one('keyup' + eventNamespace, module.event.field.keyup)
   749                    ;
   750                    module.submit();
   751                    module.debug('Enter pressed on input submitting form');
   752                  }
   753                  keyHeldDown = true;
   754                }
   755              },
   756              keyup: function() {
   757                keyHeldDown = false;
   758                $submit.removeClass(className.pressed);
   759              },
   760              blur: function() {
   761                var
   762                  $field      = $(this),
   763                  $fieldGroup = $field.closest($group)
   764                ;
   765                if( $fieldGroup.hasClass(className.error) ) {
   766                  module.debug('Revalidating field', $field,  module.get.validation($field));
   767                  module.validate.field( module.get.validation($field) );
   768                }
   769                else if(settings.on == 'blur' || settings.on == 'change') {
   770                  module.validate.field( module.get.validation($field) );
   771                }
   772              },
   773              change: function() {
   774                var
   775                  $field      = $(this),
   776                  $fieldGroup = $field.closest($group)
   777                ;
   778                if(settings.on == 'change' || ( $fieldGroup.hasClass(className.error) && settings.revalidate) ) {
   779                  clearTimeout(module.timer);
   780                  module.timer = setTimeout(function() {
   781                    module.debug('Revalidating field', $field,  module.get.validation($field));
   782                    module.validate.field( module.get.validation($field) );
   783                  }, settings.delay);
   784                }
   785              }
   786            }
   787  
   788          },
   789  
   790          get: {
   791            changeEvent: function(type) {
   792              if(type == 'checkbox' || type == 'radio' || type == 'hidden') {
   793                return 'change';
   794              }
   795              else {
   796                return module.get.inputEvent();
   797              }
   798            },
   799            inputEvent: function() {
   800              return (document.createElement('input').oninput !== undefined)
   801                ? 'input'
   802                : (document.createElement('input').onpropertychange !== undefined)
   803                  ? 'propertychange'
   804                  : 'keyup'
   805              ;
   806            },
   807            field: function(identifier) {
   808              module.verbose('Finding field with identifier', identifier);
   809              if( $field.filter('#' + identifier).length > 0 ) {
   810                return $field.filter('#' + identifier);
   811              }
   812              else if( $field.filter('[name="' + identifier +'"]').length > 0 ) {
   813                return $field.filter('[name="' + identifier +'"]');
   814              }
   815              else if( $field.filter('[name="' + identifier +'[]"]').length > 0 ) {
   816                return $field.filter('[name="' + identifier +'[]"]');
   817              }
   818              else if( $field.filter('[data-' + metadata.validate + '="'+ identifier +'"]').length > 0 ) {
   819                return $field.filter('[data-' + metadata.validate + '="'+ identifier +'"]');
   820              }
   821              return $('<input/>');
   822            },
   823            fields: function(fields) {
   824              var
   825                $fields = $()
   826              ;
   827              $.each(fields, function(index, name) {
   828                $fields = $fields.add( module.get.field(name) );
   829              });
   830              return $fields;
   831            },
   832            validation: function($field) {
   833              var
   834                rules
   835              ;
   836              $.each(validation, function(fieldName, field) {
   837                if( module.get.field(field.identifier).get(0) == $field.get(0) ) {
   838                  rules = field;
   839                }
   840              });
   841              return rules || false;
   842            },
   843            value: function (field) {
   844              var
   845                fields = [],
   846                results
   847              ;
   848              fields.push(field);
   849              results = module.get.values.call(element, fields);
   850              return results[field];
   851            },
   852            values: function (fields) {
   853              var
   854                $fields = $.isArray(fields)
   855                  ? module.get.fields(fields)
   856                  : $field,
   857                values = {}
   858              ;
   859              $fields.each(function(index, field) {
   860                var
   861                  $field     = $(field),
   862                  type       = $field.prop('type'),
   863                  name       = $field.prop('name'),
   864                  value      = $field.val(),
   865                  isCheckbox = $field.is(selector.checkbox),
   866                  isRadio    = $field.is(selector.radio),
   867                  isMultiple = (name.indexOf('[]') !== -1),
   868                  isChecked  = (isCheckbox)
   869                    ? $field.is(':checked')
   870                    : false
   871                ;
   872                if(name) {
   873                  if(isMultiple) {
   874                    name = name.replace('[]', '');
   875                    if(!values[name]) {
   876                      values[name] = [];
   877                    }
   878                    if(isCheckbox) {
   879                      if(isChecked) {
   880                        values[name].push(value)
   881                      }
   882                      else {
   883                        module.debug('Omitted unchecked checkbox', $field);
   884                        return true;
   885                      }
   886                    }
   887                    else {
   888                      values[name].push(value);
   889                    }
   890                  }
   891                  else {
   892                    if(isRadio) {
   893                      if(isChecked) {
   894                        values[name] = value;
   895                      }
   896                    }
   897                    else if(isCheckbox) {
   898                      if(isChecked) {
   899                        values[name] = true;
   900                      }
   901                      else {
   902                        module.debug('Omitted unchecked checkbox', $field);
   903                        return true;
   904                      }
   905                    }
   906                    else {
   907                      values[name] = value;
   908                    }
   909                  }
   910                }
   911              });
   912              return values;
   913            }
   914          },
   915  
   916          has: {
   917  
   918            field: function(identifier) {
   919              module.verbose('Checking for existence of a field with identifier', identifier);
   920              if( $field.filter('#' + identifier).length > 0 ) {
   921                return true;
   922              }
   923              else if( $field.filter('[name="' + identifier +'"]').length > 0 ) {
   924                return true;
   925              }
   926              else if( $field.filter('[data-' + metadata.validate + '="'+ identifier +'"]').length > 0 ) {
   927                return true;
   928              }
   929              return false;
   930            }
   931  
   932          },
   933  
   934          add: {
   935            prompt: function(identifier, errors) {
   936              var
   937                $field       = module.get.field(identifier),
   938                $fieldGroup  = $field.closest($group),
   939                $prompt      = $fieldGroup.children(selector.prompt),
   940                promptExists = ($prompt.length !== 0)
   941              ;
   942              errors = (typeof errors == 'string')
   943                ? [errors]
   944                : errors
   945              ;
   946              module.verbose('Adding field error state', identifier);
   947              $fieldGroup
   948                .addClass(className.error)
   949              ;
   950              if(settings.inline) {
   951                if(!promptExists) {
   952                  $prompt = settings.templates.prompt(errors);
   953                  $prompt
   954                    .appendTo($fieldGroup)
   955                  ;
   956                }
   957                $prompt
   958                  .html(errors[0])
   959                ;
   960                if(!promptExists) {
   961                  if(settings.transition && $.fn.transition !== undefined && $module.transition('is supported')) {
   962                    module.verbose('Displaying error with css transition', settings.transition);
   963                    $prompt.transition(settings.transition + ' in', settings.duration);
   964                  }
   965                  else {
   966                    module.verbose('Displaying error with fallback javascript animation');
   967                    $prompt
   968                      .fadeIn(settings.duration)
   969                    ;
   970                  }
   971                }
   972                else {
   973                  module.verbose('Inline errors are disabled, no inline error added', identifier);
   974                }
   975              }
   976            },
   977            errors: function(errors) {
   978              module.debug('Adding form error messages', errors);
   979              $message
   980                .html( settings.templates.error(errors) )
   981              ;
   982            }
   983          },
   984  
   985          remove: {
   986            prompt: function(field) {
   987              var
   988                $field      = module.get.field(field.identifier),
   989                $fieldGroup = $field.closest($group),
   990                $prompt     = $fieldGroup.children(selector.prompt)
   991              ;
   992              $fieldGroup
   993                .removeClass(className.error)
   994              ;
   995              if(settings.inline && $prompt.is(':visible')) {
   996                module.verbose('Removing prompt for field', field);
   997                if(settings.transition && $.fn.transition !== undefined && $module.transition('is supported')) {
   998                  $prompt.transition(settings.transition + ' out', settings.duration, function() {
   999                    $prompt.remove();
  1000                  });
  1001                }
  1002                else {
  1003                  $prompt
  1004                    .fadeOut(settings.duration, function(){
  1005                      $prompt.remove();
  1006                    })
  1007                  ;
  1008                }
  1009              }
  1010            }
  1011          },
  1012  
  1013          set: {
  1014            success: function() {
  1015              $module
  1016                .removeClass(className.error)
  1017                .addClass(className.success)
  1018              ;
  1019            },
  1020            defaults: function () {
  1021              $field
  1022                .each(function () {
  1023                  var
  1024                    $field     = $(this),
  1025                    isCheckbox = ($field.filter(selector.checkbox).length > 0),
  1026                    value      = (isCheckbox)
  1027                      ? $field.is(':checked')
  1028                      : $field.val()
  1029                  ;
  1030                  $field.data(metadata.defaultValue, value);
  1031                })
  1032              ;
  1033            },
  1034            error: function() {
  1035              $module
  1036                .removeClass(className.success)
  1037                .addClass(className.error)
  1038              ;
  1039            },
  1040            value: function (field, value) {
  1041              var
  1042                fields = {}
  1043              ;
  1044              fields[field] = value;
  1045              return module.set.values.call(element, fields);
  1046            },
  1047            values: function (fields) {
  1048              if($.isEmptyObject(fields)) {
  1049                return;
  1050              }
  1051              $.each(fields, function(key, value) {
  1052                var
  1053                  $field      = module.get.field(key),
  1054                  $element    = $field.parent(),
  1055                  isMultiple  = $.isArray(value),
  1056                  isCheckbox  = $element.is(selector.uiCheckbox),
  1057                  isDropdown  = $element.is(selector.uiDropdown),
  1058                  isRadio     = ($field.is(selector.radio) && isCheckbox),
  1059                  fieldExists = ($field.length > 0),
  1060                  $multipleField
  1061                ;
  1062                if(fieldExists) {
  1063                  if(isMultiple && isCheckbox) {
  1064                    module.verbose('Selecting multiple', value, $field);
  1065                    $element.checkbox('uncheck');
  1066                    $.each(value, function(index, value) {
  1067                      $multipleField = $field.filter('[value="' + value + '"]');
  1068                      $element       = $multipleField.parent();
  1069                      if($multipleField.length > 0) {
  1070                        $element.checkbox('check');
  1071                      }
  1072                    });
  1073                  }
  1074                  else if(isRadio) {
  1075                    module.verbose('Selecting radio value', value, $field);
  1076                    $field.filter('[value="' + value + '"]')
  1077                      .parent(selector.uiCheckbox)
  1078                        .checkbox('check')
  1079                    ;
  1080                  }
  1081                  else if(isCheckbox) {
  1082                    module.verbose('Setting checkbox value', value, $element);
  1083                    if(value === true) {
  1084                      $element.checkbox('check');
  1085                    }
  1086                    else {
  1087                      $element.checkbox('uncheck');
  1088                    }
  1089                  }
  1090                  else if(isDropdown) {
  1091                    module.verbose('Setting dropdown value', value, $element);
  1092                    $element.dropdown('set selected', value);
  1093                  }
  1094                  else {
  1095                    module.verbose('Setting field value', value, $field);
  1096                    $field.val(value);
  1097                  }
  1098                }
  1099              });
  1100              module.validate.form();
  1101            }
  1102          },
  1103  
  1104          validate: {
  1105  
  1106            form: function(event) {
  1107              var
  1108                allValid = true,
  1109                apiRequest
  1110              ;
  1111  
  1112              // input keydown event will fire submit repeatedly by browser default
  1113              if(keyHeldDown) {
  1114                return false;
  1115              }
  1116  
  1117              // reset errors
  1118              formErrors = [];
  1119              $.each(validation, function(fieldName, field) {
  1120                if( !( module.validate.field(field) ) ) {
  1121                  allValid = false;
  1122                }
  1123              });
  1124              if(allValid) {
  1125                module.debug('Form has no validation errors, submitting');
  1126                module.set.success();
  1127                return settings.onSuccess.call(element, event);
  1128              }
  1129              else {
  1130                module.debug('Form has errors');
  1131                module.set.error();
  1132                if(!settings.inline) {
  1133                  module.add.errors(formErrors);
  1134                }
  1135                // prevent ajax submit
  1136                if($module.data('moduleApi') !== undefined) {
  1137                  event.stopImmediatePropagation();
  1138                }
  1139                return settings.onFailure.call(element, formErrors);
  1140              }
  1141            },
  1142  
  1143            // takes a validation object and returns whether field passes validation
  1144            field: function(field) {
  1145              var
  1146                $field      = module.get.field(field.identifier),
  1147                fieldValid  = true,
  1148                fieldErrors = []
  1149              ;
  1150              if($field.prop('disabled')) {
  1151                module.debug('Field is disabled. Skipping', field.identifier);
  1152                fieldValid = true;
  1153              }
  1154              else if(field.optional && $.trim($field.val()) === ''){
  1155                module.debug('Field is optional and empty. Skipping', field.identifier);
  1156                fieldValid = true;
  1157              }
  1158              else if(field.rules !== undefined) {
  1159                $.each(field.rules, function(index, rule) {
  1160                  if( module.has.field(field.identifier) && !( module.validate.rule(field, rule) ) ) {
  1161                    module.debug('Field is invalid', field.identifier, rule.type);
  1162                    fieldErrors.push(rule.prompt);
  1163                    fieldValid = false;
  1164                  }
  1165                });
  1166              }
  1167              if(fieldValid) {
  1168                module.remove.prompt(field, fieldErrors);
  1169                settings.onValid.call($field);
  1170              }
  1171              else {
  1172                formErrors = formErrors.concat(fieldErrors);
  1173                module.add.prompt(field.identifier, fieldErrors);
  1174                settings.onInvalid.call($field, fieldErrors);
  1175                return false;
  1176              }
  1177              return true;
  1178            },
  1179  
  1180            // takes validation rule and returns whether field passes rule
  1181            rule: function(field, validation) {
  1182              var
  1183                $field        = module.get.field(field.identifier),
  1184                type          = validation.type,
  1185                value         = $.trim($field.val() + ''),
  1186  
  1187                bracketRegExp = /\[(.*)\]/i,
  1188                bracket       = bracketRegExp.exec(type),
  1189                isValid       = true,
  1190                ancillary,
  1191                functionType
  1192              ;
  1193              // if bracket notation is used, pass in extra parameters
  1194              if(bracket !== undefined && bracket !== null) {
  1195                ancillary    = '' + bracket[1];
  1196                functionType = type.replace(bracket[0], '');
  1197                isValid      = settings.rules[functionType].call(element, value, ancillary);
  1198              }
  1199              // normal notation
  1200              else {
  1201                isValid = settings.rules[type].call($field, value);
  1202              }
  1203              return isValid;
  1204            }
  1205          },
  1206  
  1207          setting: function(name, value) {
  1208            if( $.isPlainObject(name) ) {
  1209              $.extend(true, settings, name);
  1210            }
  1211            else if(value !== undefined) {
  1212              settings[name] = value;
  1213            }
  1214            else {
  1215              return settings[name];
  1216            }
  1217          },
  1218          internal: function(name, value) {
  1219            if( $.isPlainObject(name) ) {
  1220              $.extend(true, module, name);
  1221            }
  1222            else if(value !== undefined) {
  1223              module[name] = value;
  1224            }
  1225            else {
  1226              return module[name];
  1227            }
  1228          },
  1229          debug: function() {
  1230            if(settings.debug) {
  1231              if(settings.performance) {
  1232                module.performance.log(arguments);
  1233              }
  1234              else {
  1235                module.debug = Function.prototype.bind.call(console.info, console, settings.name + ':');
  1236                module.debug.apply(console, arguments);
  1237              }
  1238            }
  1239          },
  1240          verbose: function() {
  1241            if(settings.verbose && settings.debug) {
  1242              if(settings.performance) {
  1243                module.performance.log(arguments);
  1244              }
  1245              else {
  1246                module.verbose = Function.prototype.bind.call(console.info, console, settings.name + ':');
  1247                module.verbose.apply(console, arguments);
  1248              }
  1249            }
  1250          },
  1251          error: function() {
  1252            module.error = Function.prototype.bind.call(console.error, console, settings.name + ':');
  1253            module.error.apply(console, arguments);
  1254          },
  1255          performance: {
  1256            log: function(message) {
  1257              var
  1258                currentTime,
  1259                executionTime,
  1260                previousTime
  1261              ;
  1262              if(settings.performance) {
  1263                currentTime   = new Date().getTime();
  1264                previousTime  = time || currentTime;
  1265                executionTime = currentTime - previousTime;
  1266                time          = currentTime;
  1267                performance.push({
  1268                  'Name'           : message[0],
  1269                  'Arguments'      : [].slice.call(message, 1) || '',
  1270                  'Element'        : element,
  1271                  'Execution Time' : executionTime
  1272                });
  1273              }
  1274              clearTimeout(module.performance.timer);
  1275              module.performance.timer = setTimeout(module.performance.display, 100);
  1276            },
  1277            display: function() {
  1278              var
  1279                title = settings.name + ':',
  1280                totalTime = 0
  1281              ;
  1282              time = false;
  1283              clearTimeout(module.performance.timer);
  1284              $.each(performance, function(index, data) {
  1285                totalTime += data['Execution Time'];
  1286              });
  1287              title += ' ' + totalTime + 'ms';
  1288              if(moduleSelector) {
  1289                title += ' \'' + moduleSelector + '\'';
  1290              }
  1291              if($allModules.length > 1) {
  1292                title += ' ' + '(' + $allModules.length + ')';
  1293              }
  1294              if( (console.group !== undefined || console.table !== undefined) && performance.length > 0) {
  1295                console.groupCollapsed(title);
  1296                if(console.table) {
  1297                  console.table(performance);
  1298                }
  1299                else {
  1300                  $.each(performance, function(index, data) {
  1301                    console.log(data['Name'] + ': ' + data['Execution Time']+'ms');
  1302                  });
  1303                }
  1304                console.groupEnd();
  1305              }
  1306              performance = [];
  1307            }
  1308          },
  1309          invoke: function(query, passedArguments, context) {
  1310            var
  1311              object = instance,
  1312              maxDepth,
  1313              found,
  1314              response
  1315            ;
  1316            passedArguments = passedArguments || queryArguments;
  1317            context         = element         || context;
  1318            if(typeof query == 'string' && object !== undefined) {
  1319              query    = query.split(/[\. ]/);
  1320              maxDepth = query.length - 1;
  1321              $.each(query, function(depth, value) {
  1322                var camelCaseValue = (depth != maxDepth)
  1323                  ? value + query[depth + 1].charAt(0).toUpperCase() + query[depth + 1].slice(1)
  1324                  : query
  1325                ;
  1326                if( $.isPlainObject( object[camelCaseValue] ) && (depth != maxDepth) ) {
  1327                  object = object[camelCaseValue];
  1328                }
  1329                else if( object[camelCaseValue] !== undefined ) {
  1330                  found = object[camelCaseValue];
  1331                  return false;
  1332                }
  1333                else if( $.isPlainObject( object[value] ) && (depth != maxDepth) ) {
  1334                  object = object[value];
  1335                }
  1336                else if( object[value] !== undefined ) {
  1337                  found = object[value];
  1338                  return false;
  1339                }
  1340                else {
  1341                  return false;
  1342                }
  1343              });
  1344            }
  1345            if( $.isFunction( found ) ) {
  1346              response = found.apply(context, passedArguments);
  1347            }
  1348            else if(found !== undefined) {
  1349              response = found;
  1350            }
  1351            if($.isArray(returnedValue)) {
  1352              returnedValue.push(response);
  1353            }
  1354            else if(returnedValue !== undefined) {
  1355              returnedValue = [returnedValue, response];
  1356            }
  1357            else if(response !== undefined) {
  1358              returnedValue = response;
  1359            }
  1360            return found;
  1361          }
  1362        };
  1363        if(methodInvoked) {
  1364          if(instance === undefined) {
  1365            module.initialize();
  1366          }
  1367          module.invoke(query);
  1368        }
  1369        else {
  1370          if(instance !== undefined) {
  1371            instance.invoke('destroy');
  1372          }
  1373          module.initialize();
  1374        }
  1375  
  1376      })
  1377    ;
  1378  
  1379    return (returnedValue !== undefined)
  1380      ? returnedValue
  1381      : this
  1382    ;
  1383  };
  1384  
  1385  $.fn.form.settings = {
  1386  
  1387    name              : 'Form',
  1388    namespace         : 'form',
  1389  
  1390    debug             : false,
  1391    verbose           : true,
  1392    performance       : true,
  1393  
  1394  
  1395    keyboardShortcuts : true,
  1396    on                : 'submit',
  1397    inline            : false,
  1398  
  1399    delay             : 200,
  1400    revalidate        : true,
  1401  
  1402    transition        : 'scale',
  1403    duration          : 200,
  1404  
  1405    onValid           : function() {},
  1406    onInvalid         : function() {},
  1407    onSuccess         : function() { return true; },
  1408    onFailure         : function() { return false; },
  1409  
  1410    metadata : {
  1411      defaultValue : 'default',
  1412      validate     : 'validate'
  1413    },
  1414  
  1415    selector : {
  1416      checkbox   : 'input[type="checkbox"], input[type="radio"]',
  1417      clear      : '.clear',
  1418      field      : 'input, textarea, select',
  1419      group      : '.field',
  1420      input      : 'input',
  1421      message    : '.error.message',
  1422      prompt     : '.prompt.label',
  1423      radio      : 'input[type="radio"]',
  1424      reset      : '.reset',
  1425      submit     : '.submit',
  1426      uiCheckbox : '.ui.checkbox',
  1427      uiDropdown : '.ui.dropdown'
  1428    },
  1429  
  1430    className : {
  1431      error   : 'error',
  1432      label   : 'ui prompt label',
  1433      pressed : 'down',
  1434      success : 'success'
  1435    },
  1436  
  1437    error: {
  1438      method   : 'The method you called is not defined.'
  1439    },
  1440  
  1441    templates: {
  1442  
  1443      // template that produces error message
  1444      error: function(errors) {
  1445        var
  1446          html = '<ul class="list">'
  1447        ;
  1448        $.each(errors, function(index, value) {
  1449          html += '<li>' + value + '</li>';
  1450        });
  1451        html += '</ul>';
  1452        return $(html);
  1453      },
  1454  
  1455      // template that produces label
  1456      prompt: function(errors) {
  1457        return $('<div/>')
  1458          .addClass('ui red pointing prompt label')
  1459          .html(errors[0])
  1460        ;
  1461      }
  1462    },
  1463  
  1464    rules: {
  1465  
  1466      // checkbox checked
  1467      checked: function() {
  1468        return ($(this).filter(':checked').length > 0);
  1469      },
  1470  
  1471      // value contains text (insensitive)
  1472      contains: function(value, text) {
  1473        // escape regex characters
  1474        text = text.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&");
  1475        return (value.search( new RegExp(text, 'i') ) !== -1);
  1476      },
  1477  
  1478      // value contains text (case sensitive)
  1479      containsExactly: function(value, text) {
  1480        // escape regex characters
  1481        text = text.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&");
  1482        return (value.search( new RegExp(text) ) !== -1);
  1483      },
  1484  
  1485      // is most likely an email
  1486      email: function(value){
  1487        var
  1488          emailRegExp = new RegExp("[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?", "i")
  1489        ;
  1490        return emailRegExp.test(value);
  1491      },
  1492  
  1493      // is not empty or blank string
  1494      empty: function(value) {
  1495        return !(value === undefined || '' === value);
  1496      },
  1497  
  1498      // is valid integer
  1499      integer: function(value, range) {
  1500        var
  1501          intRegExp = /^\-?\d+$/,
  1502          min,
  1503          max,
  1504          parts
  1505        ;
  1506        if(range === undefined || range === '' || range === '..') {
  1507          // do nothing
  1508        }
  1509        else if(range.indexOf('..') == -1) {
  1510          if(intRegExp.test(range)) {
  1511            min = max = range - 0;
  1512          }
  1513        }
  1514        else {
  1515          parts = range.split('..', 2);
  1516          if(intRegExp.test(parts[0])) {
  1517            min = parts[0] - 0;
  1518          }
  1519          if(intRegExp.test(parts[1])) {
  1520            max = parts[1] - 0;
  1521          }
  1522        }
  1523        return (
  1524          intRegExp.test(value) &&
  1525          (min === undefined || value >= min) &&
  1526          (max === undefined || value <= max)
  1527        );
  1528      },
  1529  
  1530      // is value (case insensitive)
  1531      is: function(value, text) {
  1532        text = (typeof text == 'string')
  1533          ? text.toLowerCase()
  1534          : text
  1535        ;
  1536        value = (typeof value == 'string')
  1537          ? value.toLowerCase()
  1538          : value
  1539        ;
  1540        return (value == text);
  1541      },
  1542  
  1543      // is value
  1544      isExactly: function(value, text) {
  1545        return (value == text);
  1546      },
  1547  
  1548      // is at least string length
  1549      length: function(value, requiredLength) {
  1550        return (value !== undefined)
  1551          ? (value.length >= requiredLength)
  1552          : false
  1553        ;
  1554      },
  1555  
  1556      // matches another field
  1557      match: function(value, fieldIdentifier) {
  1558        // use either id or name of field
  1559        var
  1560          $form = $(this),
  1561          matchingValue
  1562        ;
  1563        if($form.find('#' + fieldIdentifier).length > 0) {
  1564          matchingValue = $form.find('#' + fieldIdentifier).val();
  1565        }
  1566        else if($form.find('[name="' + fieldIdentifier +'"]').length > 0) {
  1567          matchingValue = $form.find('[name="' + fieldIdentifier + '"]').val();
  1568        }
  1569        else if( $form.find('[data-validate="'+ fieldIdentifier +'"]').length > 0 ) {
  1570          matchingValue = $form.find('[data-validate="'+ fieldIdentifier +'"]').val();
  1571        }
  1572        return (matchingValue !== undefined)
  1573          ? ( value.toString() == matchingValue.toString() )
  1574          : false
  1575        ;
  1576      },
  1577  
  1578      // string length is less than max length
  1579      maxLength: function(value, maxLength) {
  1580        return (value !== undefined)
  1581          ? (value.length <= maxLength)
  1582          : false
  1583        ;
  1584      },
  1585  
  1586      // value is not value (case insensitive)
  1587      not: function(value, notValue) {
  1588        value = (typeof value == 'string')
  1589          ? value.toLowerCase()
  1590          : value
  1591        ;
  1592        notValue = (typeof notValue == 'string')
  1593          ? notValue.toLowerCase()
  1594          : notValue
  1595        ;
  1596        return (value != notValue);
  1597      },
  1598  
  1599      // value is not value (case sensitive)
  1600      notExactly: function(value, notValue) {
  1601        return (value != notValue);
  1602      },
  1603  
  1604      // value is most likely url
  1605      url: function(value) {
  1606        var
  1607          urlRegExp = /(ftp|http|https):\/\/(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?/
  1608        ;
  1609        return urlRegExp.test(value);
  1610      }
  1611    }
  1612  
  1613  };
  1614  
  1615  })( jQuery, window , document );
  1616  
  1617  /*!
  1618   * # Semantic UI x.x - Accordion
  1619   * http://github.com/semantic-org/semantic-ui/
  1620   *
  1621   *
  1622   * Copyright 2014 Contributors
  1623   * Released under the MIT license
  1624   * http://opensource.org/licenses/MIT
  1625   *
  1626   */
  1627  
  1628  ;(function ($, window, document, undefined) {
  1629  
  1630  "use strict";
  1631  
  1632  $.fn.accordion = function(parameters) {
  1633    var
  1634      $allModules     = $(this),
  1635  
  1636      time            = new Date().getTime(),
  1637      performance     = [],
  1638  
  1639      query           = arguments[0],
  1640      methodInvoked   = (typeof query == 'string'),
  1641      queryArguments  = [].slice.call(arguments, 1),
  1642  
  1643      requestAnimationFrame = window.requestAnimationFrame
  1644        || window.mozRequestAnimationFrame
  1645        || window.webkitRequestAnimationFrame
  1646        || window.msRequestAnimationFrame
  1647        || function(callback) { setTimeout(callback, 0); },
  1648  
  1649      returnedValue
  1650    ;
  1651    $allModules
  1652      .each(function() {
  1653        var
  1654          settings        = ( $.isPlainObject(parameters) )
  1655            ? $.extend(true, {}, $.fn.accordion.settings, parameters)
  1656            : $.extend({}, $.fn.accordion.settings),
  1657  
  1658          className       = settings.className,
  1659          namespace       = settings.namespace,
  1660          selector        = settings.selector,
  1661          error           = settings.error,
  1662  
  1663          eventNamespace  = '.' + namespace,
  1664          moduleNamespace = 'module-' + namespace,
  1665          moduleSelector  = $allModules.selector || '',
  1666  
  1667          $module  = $(this),
  1668          $title   = $module.find(selector.title),
  1669          $content = $module.find(selector.content),
  1670  
  1671          element  = this,
  1672          instance = $module.data(moduleNamespace),
  1673          observer,
  1674          module
  1675        ;
  1676  
  1677        module = {
  1678  
  1679          initialize: function() {
  1680            module.debug('Initializing', $module);
  1681            module.bind.events();
  1682            module.observeChanges();
  1683            module.instantiate();
  1684          },
  1685  
  1686          instantiate: function() {
  1687            instance = module;
  1688            $module
  1689              .data(moduleNamespace, module)
  1690            ;
  1691          },
  1692  
  1693          destroy: function() {
  1694            module.debug('Destroying previous instance', $module);
  1695            $module
  1696              .off(eventNamespace)
  1697              .removeData(moduleNamespace)
  1698            ;
  1699          },
  1700  
  1701          refresh: function() {
  1702            $title   = $module.find(selector.title);
  1703            $content = $module.find(selector.content);
  1704          },
  1705  
  1706          observeChanges: function() {
  1707            if('MutationObserver' in window) {
  1708              observer = new MutationObserver(function(mutations) {
  1709                module.debug('DOM tree modified, updating selector cache');
  1710                module.refresh();
  1711              });
  1712              observer.observe(element, {
  1713                childList : true,
  1714                subtree   : true
  1715              });
  1716              module.debug('Setting up mutation observer', observer);
  1717            }
  1718          },
  1719  
  1720          bind: {
  1721            events: function() {
  1722              module.debug('Binding delegated events');
  1723              $module
  1724                .on('click' + eventNamespace, selector.trigger, module.event.click)
  1725              ;
  1726            }
  1727          },
  1728  
  1729          event: {
  1730            click: function() {
  1731              module.toggle.call(this);
  1732            }
  1733          },
  1734  
  1735          toggle: function(query) {
  1736            var
  1737              $activeTitle = (query !== undefined)
  1738                ? (typeof query === 'number')
  1739                  ? $title.eq(query)
  1740                  : $(query).closest(selector.title)
  1741                : $(this).closest(selector.title),
  1742              $activeContent = $activeTitle.next($content),
  1743              isAnimating = $activeContent.hasClass(className.animating),
  1744              isActive    = $activeContent.hasClass(className.active),
  1745              isOpen      = (isActive && !isAnimating),
  1746              isOpening   = (!isActive && isAnimating)
  1747            ;
  1748            module.debug('Toggling visibility of content', $activeTitle);
  1749            if(isOpen || isOpening) {
  1750              if(settings.collapsible) {
  1751                module.close.call($activeTitle);
  1752              }
  1753              else {
  1754                module.debug('Cannot close accordion content collapsing is disabled');
  1755              }
  1756            }
  1757            else {
  1758              module.open.call($activeTitle);
  1759            }
  1760          },
  1761  
  1762          open: function(query) {
  1763            var
  1764              $activeTitle = (query !== undefined)
  1765                ? (typeof query === 'number')
  1766                  ? $title.eq(query)
  1767                  : $(query).closest(selector.title)
  1768                : $(this).closest(selector.title),
  1769              $activeContent = $activeTitle.next($content),
  1770              isAnimating = $activeContent.hasClass(className.animating),
  1771              isActive    = $activeContent.hasClass(className.active),
  1772              isUnopen    = (!isActive && !isAnimating)
  1773            ;
  1774            if(isUnopen) {
  1775              module.debug('Opening accordion content', $activeTitle);
  1776              if(settings.exclusive) {
  1777                module.closeOthers.call($activeTitle);
  1778              }
  1779              $activeTitle
  1780                .addClass(className.active)
  1781              ;
  1782              $activeContent.addClass(className.animating);
  1783              if(settings.animateChildren) {
  1784                if($.fn.transition !== undefined && $module.transition('is supported')) {
  1785                  $activeContent
  1786                    .children()
  1787                      .transition({
  1788                        animation   : 'fade in',
  1789                        queue       : false,
  1790                        useFailSafe : true,
  1791                        debug       : settings.debug,
  1792                        verbose     : settings.verbose,
  1793                        duration    : settings.duration
  1794                      })
  1795                  ;
  1796                }
  1797                else {
  1798                  $activeContent
  1799                    .children()
  1800                      .stop(true)
  1801                      .animate({
  1802                        opacity: 1
  1803                      }, settings.duration, module.resetOpacity)
  1804                  ;
  1805                }
  1806              }
  1807              $activeContent
  1808                .stop(true)
  1809                .slideDown(settings.duration, settings.easing, function() {
  1810                  $activeContent
  1811                    .removeClass(className.animating)
  1812                    .addClass(className.active)
  1813                  ;
  1814                  module.reset.display.call(this);
  1815                  settings.onOpen.call(this);
  1816                  settings.onChange.call(this);
  1817                })
  1818              ;
  1819            }
  1820          },
  1821  
  1822          close: function(query) {
  1823            var
  1824              $activeTitle = (query !== undefined)
  1825                ? (typeof query === 'number')
  1826                  ? $title.eq(query)
  1827                  : $(query).closest(selector.title)
  1828                : $(this).closest(selector.title),
  1829              $activeContent = $activeTitle.next($content),
  1830              isAnimating    = $activeContent.hasClass(className.animating),
  1831              isActive       = $activeContent.hasClass(className.active),
  1832              isOpening      = (!isActive && isAnimating),
  1833              isClosing      = (isActive && isAnimating)
  1834            ;
  1835            if((isActive || isOpening) && !isClosing) {
  1836              module.debug('Closing accordion content', $activeContent);
  1837              $activeTitle
  1838                .removeClass(className.active)
  1839              ;
  1840              $activeContent
  1841                .addClass(className.animating)
  1842              ;
  1843              if(settings.animateChildren) {
  1844                if($.fn.transition !== undefined && $module.transition('is supported')) {
  1845                  $activeContent
  1846                    .children()
  1847                      .transition({
  1848                        animation   : 'fade out',
  1849                        queue       : false,
  1850                        useFailSafe : true,
  1851                        debug       : settings.debug,
  1852                        verbose     : settings.verbose,
  1853                        duration    : settings.duration
  1854                      })
  1855                  ;
  1856                }
  1857                else {
  1858                  $activeContent
  1859                    .children()
  1860                      .stop(true)
  1861                      .animate({
  1862                        opacity: 0
  1863                      }, settings.duration, module.resetOpacity)
  1864                  ;
  1865                }
  1866              }
  1867              $activeContent
  1868                .stop(true)
  1869                .slideUp(settings.duration, settings.easing, function() {
  1870                  $activeContent
  1871                    .removeClass(className.animating)
  1872                    .removeClass(className.active)
  1873                  ;
  1874                  module.reset.display.call(this);
  1875                  settings.onClose.call(this);
  1876                  settings.onChange.call(this);
  1877                })
  1878              ;
  1879            }
  1880          },
  1881  
  1882          closeOthers: function(index) {
  1883            var
  1884              $activeTitle = (index !== undefined)
  1885                ? $title.eq(index)
  1886                : $(this).closest(selector.title),
  1887              $parentTitles    = $activeTitle.parents(selector.content).prev(selector.title),
  1888              $activeAccordion = $activeTitle.closest(selector.accordion),
  1889              activeSelector   = selector.title + '.' + className.active + ':visible',
  1890              activeContent    = selector.content + '.' + className.active + ':visible',
  1891              $openTitles,
  1892              $nestedTitles,
  1893              $openContents
  1894            ;
  1895            if(settings.closeNested) {
  1896              $openTitles   = $activeAccordion.find(activeSelector).not($parentTitles);
  1897              $openContents = $openTitles.next($content);
  1898            }
  1899            else {
  1900              $openTitles   = $activeAccordion.find(activeSelector).not($parentTitles);
  1901              $nestedTitles = $activeAccordion.find(activeContent).find(activeSelector).not($parentTitles);
  1902              $openTitles   = $openTitles.not($nestedTitles);
  1903              $openContents = $openTitles.next($content);
  1904            }
  1905            if( ($openTitles.length > 0) ) {
  1906              module.debug('Exclusive enabled, closing other content', $openTitles);
  1907              $openTitles
  1908                .removeClass(className.active)
  1909              ;
  1910              if(settings.animateChildren) {
  1911                if($.fn.transition !== undefined && $module.transition('is supported')) {
  1912                  $openContents
  1913                    .children()
  1914                      .transition({
  1915                        animation   : 'fade out',
  1916                        useFailSafe : true,
  1917                        debug       : settings.debug,
  1918                        verbose     : settings.verbose,
  1919                        duration    : settings.duration
  1920                      })
  1921                  ;
  1922                }
  1923                else {
  1924                  $openContents
  1925                    .children()
  1926                      .stop()
  1927                      .animate({
  1928                        opacity: 0
  1929                      }, settings.duration, module.resetOpacity)
  1930                  ;
  1931                }
  1932              }
  1933              $openContents
  1934                .stop()
  1935                .slideUp(settings.duration , settings.easing, function() {
  1936                  $(this).removeClass(className.active);
  1937                  module.reset.display.call(this);
  1938                })
  1939              ;
  1940            }
  1941          },
  1942  
  1943          reset: {
  1944  
  1945            display: function() {
  1946              module.verbose('Removing inline display from element', this);
  1947              $(this).css('display', '');
  1948              if( $(this).attr('style') === '') {
  1949                $(this)
  1950                  .attr('style', '')
  1951                  .removeAttr('style')
  1952                ;
  1953              }
  1954            },
  1955  
  1956            opacity: function() {
  1957              module.verbose('Removing inline opacity from element', this);
  1958              $(this).css('opacity', '');
  1959              if( $(this).attr('style') === '') {
  1960                $(this)
  1961                  .attr('style', '')
  1962                  .removeAttr('style')
  1963                ;
  1964              }
  1965            },
  1966  
  1967          },
  1968  
  1969          setting: function(name, value) {
  1970            module.debug('Changing setting', name, value);
  1971            if( $.isPlainObject(name) ) {
  1972              $.extend(true, settings, name);
  1973            }
  1974            else if(value !== undefined) {
  1975              settings[name] = value;
  1976            }
  1977            else {
  1978              return settings[name];
  1979            }
  1980          },
  1981          internal: function(name, value) {
  1982            module.debug('Changing internal', name, value);
  1983            if(value !== undefined) {
  1984              if( $.isPlainObject(name) ) {
  1985                $.extend(true, module, name);
  1986              }
  1987              else {
  1988                module[name] = value;
  1989              }
  1990            }
  1991            else {
  1992              return module[name];
  1993            }
  1994          },
  1995          debug: function() {
  1996            if(settings.debug) {
  1997              if(settings.performance) {
  1998                module.performance.log(arguments);
  1999              }
  2000              else {
  2001                module.debug = Function.prototype.bind.call(console.info, console, settings.name + ':');
  2002                module.debug.apply(console, arguments);
  2003              }
  2004            }
  2005          },
  2006          verbose: function() {
  2007            if(settings.verbose && settings.debug) {
  2008              if(settings.performance) {
  2009                module.performance.log(arguments);
  2010              }
  2011              else {
  2012                module.verbose = Function.prototype.bind.call(console.info, console, settings.name + ':');
  2013                module.verbose.apply(console, arguments);
  2014              }
  2015            }
  2016          },
  2017          error: function() {
  2018            module.error = Function.prototype.bind.call(console.error, console, settings.name + ':');
  2019            module.error.apply(console, arguments);
  2020          },
  2021          performance: {
  2022            log: function(message) {
  2023              var
  2024                currentTime,
  2025                executionTime,
  2026                previousTime
  2027              ;
  2028              if(settings.performance) {
  2029                currentTime   = new Date().getTime();
  2030                previousTime  = time || currentTime;
  2031                executionTime = currentTime - previousTime;
  2032                time          = currentTime;
  2033                performance.push({
  2034                  'Name'           : message[0],
  2035                  'Arguments'      : [].slice.call(message, 1) || '',
  2036                  'Element'        : element,
  2037                  'Execution Time' : executionTime
  2038                });
  2039              }
  2040              clearTimeout(module.performance.timer);
  2041              module.performance.timer = setTimeout(module.performance.display, 100);
  2042            },
  2043            display: function() {
  2044              var
  2045                title = settings.name + ':',
  2046                totalTime = 0
  2047              ;
  2048              time = false;
  2049              clearTimeout(module.performance.timer);
  2050              $.each(performance, function(index, data) {
  2051                totalTime += data['Execution Time'];
  2052              });
  2053              title += ' ' + totalTime + 'ms';
  2054              if(moduleSelector) {
  2055                title += ' \'' + moduleSelector + '\'';
  2056              }
  2057              if( (console.group !== undefined || console.table !== undefined) && performance.length > 0) {
  2058                console.groupCollapsed(title);
  2059                if(console.table) {
  2060                  console.table(performance);
  2061                }
  2062                else {
  2063                  $.each(performance, function(index, data) {
  2064                    console.log(data['Name'] + ': ' + data['Execution Time']+'ms');
  2065                  });
  2066                }
  2067                console.groupEnd();
  2068              }
  2069              performance = [];
  2070            }
  2071          },
  2072          invoke: function(query, passedArguments, context) {
  2073            var
  2074              object = instance,
  2075              maxDepth,
  2076              found,
  2077              response
  2078            ;
  2079            passedArguments = passedArguments || queryArguments;
  2080            context         = element         || context;
  2081            if(typeof query == 'string' && object !== undefined) {
  2082              query    = query.split(/[\. ]/);
  2083              maxDepth = query.length - 1;
  2084              $.each(query, function(depth, value) {
  2085                var camelCaseValue = (depth != maxDepth)
  2086                  ? value + query[depth + 1].charAt(0).toUpperCase() + query[depth + 1].slice(1)
  2087                  : query
  2088                ;
  2089                if( $.isPlainObject( object[camelCaseValue] ) && (depth != maxDepth) ) {
  2090                  object = object[camelCaseValue];
  2091                }
  2092                else if( object[camelCaseValue] !== undefined ) {
  2093                  found = object[camelCaseValue];
  2094                  return false;
  2095                }
  2096                else if( $.isPlainObject( object[value] ) && (depth != maxDepth) ) {
  2097                  object = object[value];
  2098                }
  2099                else if( object[value] !== undefined ) {
  2100                  found = object[value];
  2101                  return false;
  2102                }
  2103                else {
  2104                  module.error(error.method, query);
  2105                  return false;
  2106                }
  2107              });
  2108            }
  2109            if ( $.isFunction( found ) ) {
  2110              response = found.apply(context, passedArguments);
  2111            }
  2112            else if(found !== undefined) {
  2113              response = found;
  2114            }
  2115            if($.isArray(returnedValue)) {
  2116              returnedValue.push(response);
  2117            }
  2118            else if(returnedValue !== undefined) {
  2119              returnedValue = [returnedValue, response];
  2120            }
  2121            else if(response !== undefined) {
  2122              returnedValue = response;
  2123            }
  2124            return found;
  2125          }
  2126        };
  2127        if(methodInvoked) {
  2128          if(instance === undefined) {
  2129            module.initialize();
  2130          }
  2131          module.invoke(query);
  2132        }
  2133        else {
  2134          if(instance !== undefined) {
  2135            instance.invoke('destroy');
  2136          }
  2137          module.initialize();
  2138        }
  2139      })
  2140    ;
  2141    return (returnedValue !== undefined)
  2142      ? returnedValue
  2143      : this
  2144    ;
  2145  };
  2146  
  2147  $.fn.accordion.settings = {
  2148  
  2149    name            : 'Accordion',
  2150    namespace       : 'accordion',
  2151  
  2152    debug           : false,
  2153    verbose         : true,
  2154    performance     : true,
  2155  
  2156    exclusive       : true,
  2157    collapsible     : true,
  2158    closeNested     : false,
  2159    animateChildren : true,
  2160  
  2161    duration        : 350,
  2162    easing          : 'easeOutQuad',
  2163  
  2164    onOpen          : function(){},
  2165    onClose         : function(){},
  2166    onChange        : function(){},
  2167  
  2168    error: {
  2169      method : 'The method you called is not defined'
  2170    },
  2171  
  2172    className   : {
  2173      active    : 'active',
  2174      animating : 'animating'
  2175    },
  2176  
  2177    selector    : {
  2178      accordion : '.accordion',
  2179      title     : '.title',
  2180      trigger   : '.title',
  2181      content   : '.content'
  2182    }
  2183  
  2184  };
  2185  
  2186  // Adds easing
  2187  $.extend( $.easing, {
  2188    easeOutQuad: function (x, t, b, c, d) {
  2189      return -c *(t/=d)*(t-2) + b;
  2190    }
  2191  });
  2192  
  2193  })( jQuery, window , document );
  2194  
  2195  
  2196  /*!
  2197   * # Semantic UI x.x - Checkbox
  2198   * http://github.com/semantic-org/semantic-ui/
  2199   *
  2200   *
  2201   * Copyright 2014 Contributors
  2202   * Released under the MIT license
  2203   * http://opensource.org/licenses/MIT
  2204   *
  2205   */
  2206  
  2207  ;(function ( $, window, document, undefined ) {
  2208  
  2209  "use strict";
  2210  
  2211  $.fn.checkbox = function(parameters) {
  2212    var
  2213      $allModules    = $(this),
  2214      moduleSelector = $allModules.selector || '',
  2215  
  2216      time           = new Date().getTime(),
  2217      performance    = [],
  2218  
  2219      query          = arguments[0],
  2220      methodInvoked  = (typeof query == 'string'),
  2221      queryArguments = [].slice.call(arguments, 1),
  2222      returnedValue
  2223    ;
  2224  
  2225    $allModules
  2226      .each(function() {
  2227        var
  2228          settings        = $.extend(true, {}, $.fn.checkbox.settings, parameters),
  2229  
  2230          className       = settings.className,
  2231          namespace       = settings.namespace,
  2232          selector        = settings.selector,
  2233          error           = settings.error,
  2234  
  2235          eventNamespace  = '.' + namespace,
  2236          moduleNamespace = 'module-' + namespace,
  2237  
  2238          $module         = $(this),
  2239          $label          = $(this).find(selector.label).first(),
  2240          $input          = $(this).find(selector.input),
  2241  
  2242          instance        = $module.data(moduleNamespace),
  2243  
  2244          observer,
  2245          element         = this,
  2246          module
  2247        ;
  2248  
  2249        module      = {
  2250  
  2251          initialize: function() {
  2252            module.verbose('Initializing checkbox', settings);
  2253  
  2254            module.create.label();
  2255            module.add.events();
  2256  
  2257            if( module.is.checked() ) {
  2258              module.set.checked();
  2259              if(settings.fireOnInit) {
  2260                settings.onChecked.call($input.get());
  2261              }
  2262            }
  2263            else {
  2264              module.remove.checked();
  2265              if(settings.fireOnInit) {
  2266                settings.onUnchecked.call($input.get());
  2267              }
  2268            }
  2269            module.observeChanges();
  2270  
  2271            module.instantiate();
  2272          },
  2273  
  2274          instantiate: function() {
  2275            module.verbose('Storing instance of module', module);
  2276            instance = module;
  2277            $module
  2278              .data(moduleNamespace, module)
  2279            ;
  2280          },
  2281  
  2282          destroy: function() {
  2283            module.verbose('Destroying module');
  2284            module.remove.events();
  2285            $module
  2286              .removeData(moduleNamespace)
  2287            ;
  2288          },
  2289  
  2290          refresh: function() {
  2291            $module = $(this);
  2292            $label  = $(this).find(selector.label).first();
  2293            $input  = $(this).find(selector.input);
  2294          },
  2295  
  2296          observeChanges: function() {
  2297            if('MutationObserver' in window) {
  2298              observer = new MutationObserver(function(mutations) {
  2299                module.debug('DOM tree modified, updating selector cache');
  2300                module.refresh();
  2301              });
  2302              observer.observe(element, {
  2303                childList : true,
  2304                subtree   : true
  2305              });
  2306              module.debug('Setting up mutation observer', observer);
  2307            }
  2308          },
  2309  
  2310          attachEvents: function(selector, event) {
  2311            var
  2312              $element = $(selector)
  2313            ;
  2314            event = $.isFunction(module[event])
  2315              ? module[event]
  2316              : module.toggle
  2317            ;
  2318            if($element.length > 0) {
  2319              module.debug('Attaching checkbox events to element', selector, event);
  2320              $element
  2321                .on('click' + eventNamespace, event)
  2322              ;
  2323            }
  2324            else {
  2325              module.error(error.notFound);
  2326            }
  2327          },
  2328  
  2329          event: {
  2330            keydown: function(event) {
  2331              var
  2332                key     = event.which,
  2333                keyCode = {
  2334                  enter  : 13,
  2335                  space  : 32,
  2336                  escape : 27
  2337                }
  2338              ;
  2339              if( key == keyCode.escape) {
  2340                module.verbose('Escape key pressed blurring field');
  2341                $module
  2342                  .blur()
  2343                ;
  2344              }
  2345              if(!event.ctrlKey && (key == keyCode.enter || key == keyCode.space)) {
  2346                module.verbose('Enter key pressed, toggling checkbox');
  2347                module.toggle.call(this);
  2348                event.preventDefault();
  2349              }
  2350            }
  2351          },
  2352  
  2353          is: {
  2354            radio: function() {
  2355              return $module.hasClass(className.radio);
  2356            },
  2357            checked: function() {
  2358              return $input.prop('checked') !== undefined && $input.prop('checked');
  2359            },
  2360            unchecked: function() {
  2361              return !module.is.checked();
  2362            }
  2363          },
  2364  
  2365          can: {
  2366            change: function() {
  2367              return !( $module.hasClass(className.disabled) || $module.hasClass(className.readOnly) || $input.prop('disabled') );
  2368            },
  2369            uncheck: function() {
  2370              return (typeof settings.uncheckable === 'boolean')
  2371                ? settings.uncheckable
  2372                : !module.is.radio()
  2373              ;
  2374            }
  2375          },
  2376  
  2377          set: {
  2378            checked: function() {
  2379              $module.addClass(className.checked);
  2380            },
  2381            tab: function() {
  2382              if( $input.attr('tabindex') === undefined) {
  2383                $input
  2384                  .attr('tabindex', 0)
  2385                ;
  2386              }
  2387            }
  2388          },
  2389  
  2390          create: {
  2391            label: function() {
  2392              if($input.prevAll(selector.label).length > 0) {
  2393                $input.prev(selector.label).detach().insertAfter($input);
  2394                module.debug('Moving existing label', $label);
  2395              }
  2396              else if( !module.has.label() ) {
  2397                $label = $('<label>').insertAfter($input);
  2398                module.debug('Creating label', $label);
  2399              }
  2400            }
  2401          },
  2402  
  2403          has: {
  2404            label: function() {
  2405              return ($label.length > 0);
  2406            }
  2407          },
  2408  
  2409          add: {
  2410            events: function() {
  2411              module.verbose('Attaching checkbox events');
  2412              $module
  2413                .on('click'   + eventNamespace, module.toggle)
  2414                .on('keydown' + eventNamespace, selector.input, module.event.keydown)
  2415              ;
  2416            }
  2417          },
  2418  
  2419          remove: {
  2420            checked: function() {
  2421              $module.removeClass(className.checked);
  2422            },
  2423            events: function() {
  2424              module.debug('Removing events');
  2425              $module
  2426                .off(eventNamespace)
  2427                .removeData(moduleNamespace)
  2428              ;
  2429              $input
  2430                .off(eventNamespace, module.event.keydown)
  2431              ;
  2432              $label
  2433                .off(eventNamespace)
  2434              ;
  2435            }
  2436          },
  2437  
  2438          enable: function() {
  2439            module.debug('Enabling checkbox functionality');
  2440            $module.removeClass(className.disabled);
  2441            $input.prop('disabled', false);
  2442            settings.onEnabled.call($input.get());
  2443          },
  2444  
  2445          disable: function() {
  2446            module.debug('Disabling checkbox functionality');
  2447            $module.addClass(className.disabled);
  2448            $input.prop('disabled', 'disabled');
  2449            settings.onDisabled.call($input.get());
  2450          },
  2451  
  2452          check: function() {
  2453            module.debug('Enabling checkbox', $input);
  2454            $input
  2455              .prop('checked', true)
  2456              .trigger('change')
  2457            ;
  2458            module.set.checked();
  2459            $input.trigger('blur');
  2460            settings.onChange.call($input.get());
  2461            settings.onChecked.call($input.get());
  2462          },
  2463  
  2464          uncheck: function() {
  2465            module.debug('Disabling checkbox');
  2466            $input
  2467              .prop('checked', false)
  2468              .trigger('change')
  2469            ;
  2470            module.remove.checked();
  2471            $input.trigger('blur');
  2472            settings.onChange.call($input.get());
  2473            settings.onUnchecked.call($input.get());
  2474          },
  2475  
  2476          toggle: function(event) {
  2477            if( !module.can.change() ) {
  2478              console.log(module.can.change());
  2479              module.debug('Checkbox is read-only or disabled, ignoring toggle');
  2480              return;
  2481            }
  2482            module.verbose('Determining new checkbox state');
  2483            if( module.is.unchecked() ) {
  2484              module.check();
  2485            }
  2486            else if( module.is.checked() && module.can.uncheck() ) {
  2487              module.uncheck();
  2488            }
  2489          },
  2490          setting: function(name, value) {
  2491            module.debug('Changing setting', name, value);
  2492            if( $.isPlainObject(name) ) {
  2493              $.extend(true, settings, name);
  2494            }
  2495            else if(value !== undefined) {
  2496              settings[name] = value;
  2497            }
  2498            else {
  2499              return settings[name];
  2500            }
  2501          },
  2502          internal: function(name, value) {
  2503            if( $.isPlainObject(name) ) {
  2504              $.extend(true, module, name);
  2505            }
  2506            else if(value !== undefined) {
  2507              module[name] = value;
  2508            }
  2509            else {
  2510              return module[name];
  2511            }
  2512          },
  2513          debug: function() {
  2514            if(settings.debug) {
  2515              if(settings.performance) {
  2516                module.performance.log(arguments);
  2517              }
  2518              else {
  2519                module.debug = Function.prototype.bind.call(console.info, console, settings.name + ':');
  2520                module.debug.apply(console, arguments);
  2521              }
  2522            }
  2523          },
  2524          verbose: function() {
  2525            if(settings.verbose && settings.debug) {
  2526              if(settings.performance) {
  2527                module.performance.log(arguments);
  2528              }
  2529              else {
  2530                module.verbose = Function.prototype.bind.call(console.info, console, settings.name + ':');
  2531                module.verbose.apply(console, arguments);
  2532              }
  2533            }
  2534          },
  2535          error: function() {
  2536            module.error = Function.prototype.bind.call(console.error, console, settings.name + ':');
  2537            module.error.apply(console, arguments);
  2538          },
  2539          performance: {
  2540            log: function(message) {
  2541              var
  2542                currentTime,
  2543                executionTime,
  2544                previousTime
  2545              ;
  2546              if(settings.performance) {
  2547                currentTime   = new Date().getTime();
  2548                previousTime  = time || currentTime;
  2549                executionTime = currentTime - previousTime;
  2550                time          = currentTime;
  2551                performance.push({
  2552                  'Name'           : message[0],
  2553                  'Arguments'      : [].slice.call(message, 1) || '',
  2554                  'Element'        : element,
  2555                  'Execution Time' : executionTime
  2556                });
  2557              }
  2558              clearTimeout(module.performance.timer);
  2559              module.performance.timer = setTimeout(module.performance.display, 100);
  2560            },
  2561            display: function() {
  2562              var
  2563                title = settings.name + ':',
  2564                totalTime = 0
  2565              ;
  2566              time = false;
  2567              clearTimeout(module.performance.timer);
  2568              $.each(performance, function(index, data) {
  2569                totalTime += data['Execution Time'];
  2570              });
  2571              title += ' ' + totalTime + 'ms';
  2572              if(moduleSelector) {
  2573                title += ' \'' + moduleSelector + '\'';
  2574              }
  2575              if( (console.group !== undefined || console.table !== undefined) && performance.length > 0) {
  2576                console.groupCollapsed(title);
  2577                if(console.table) {
  2578                  console.table(performance);
  2579                }
  2580                else {
  2581                  $.each(performance, function(index, data) {
  2582                    console.log(data['Name'] + ': ' + data['Execution Time']+'ms');
  2583                  });
  2584                }
  2585                console.groupEnd();
  2586              }
  2587              performance = [];
  2588            }
  2589          },
  2590          invoke: function(query, passedArguments, context) {
  2591            var
  2592              object = instance,
  2593              maxDepth,
  2594              found,
  2595              response
  2596            ;
  2597            passedArguments = passedArguments || queryArguments;
  2598            context         = element         || context;
  2599            if(typeof query == 'string' && object !== undefined) {
  2600              query    = query.split(/[\. ]/);
  2601              maxDepth = query.length - 1;
  2602              $.each(query, function(depth, value) {
  2603                var camelCaseValue = (depth != maxDepth)
  2604                  ? value + query[depth + 1].charAt(0).toUpperCase() + query[depth + 1].slice(1)
  2605                  : query
  2606                ;
  2607                if( $.isPlainObject( object[camelCaseValue] ) && (depth != maxDepth) ) {
  2608                  object = object[camelCaseValue];
  2609                }
  2610                else if( object[camelCaseValue] !== undefined ) {
  2611                  found = object[camelCaseValue];
  2612                  return false;
  2613                }
  2614                else if( $.isPlainObject( object[value] ) && (depth != maxDepth) ) {
  2615                  object = object[value];
  2616                }
  2617                else if( object[value] !== undefined ) {
  2618                  found = object[value];
  2619                  return false;
  2620                }
  2621                else {
  2622                  module.error(error.method, query);
  2623                  return false;
  2624                }
  2625              });
  2626            }
  2627            if ( $.isFunction( found ) ) {
  2628              response = found.apply(context, passedArguments);
  2629            }
  2630            else if(found !== undefined) {
  2631              response = found;
  2632            }
  2633            if($.isArray(returnedValue)) {
  2634              returnedValue.push(response);
  2635            }
  2636            else if(returnedValue !== undefined) {
  2637              returnedValue = [returnedValue, response];
  2638            }
  2639            else if(response !== undefined) {
  2640              returnedValue = response;
  2641            }
  2642            return found;
  2643          }
  2644        };
  2645  
  2646        if(methodInvoked) {
  2647          if(instance === undefined) {
  2648            module.initialize();
  2649          }
  2650          module.invoke(query);
  2651        }
  2652        else {
  2653          if(instance !== undefined) {
  2654            instance.invoke('destroy');
  2655          }
  2656          module.initialize();
  2657        }
  2658      })
  2659    ;
  2660  
  2661    return (returnedValue !== undefined)
  2662      ? returnedValue
  2663      : this
  2664    ;
  2665  };
  2666  
  2667  $.fn.checkbox.settings = {
  2668  
  2669    name        : 'Checkbox',
  2670    namespace   : 'checkbox',
  2671  
  2672    debug       : false,
  2673    verbose     : true,
  2674    performance : true,
  2675  
  2676    // delegated event context
  2677    uncheckable : 'auto',
  2678    fireOnInit  : true,
  2679  
  2680    onChange    : function(){},
  2681    onChecked   : function(){},
  2682    onUnchecked : function(){},
  2683    onEnabled   : function(){},
  2684    onDisabled  : function(){},
  2685  
  2686    className   : {
  2687      checked  : 'checked',
  2688      disabled : 'disabled',
  2689      radio    : 'radio',
  2690      readOnly : 'read-only'
  2691    },
  2692  
  2693    error     : {
  2694      method   : 'The method you called is not defined'
  2695    },
  2696  
  2697    selector : {
  2698      input  : 'input[type="checkbox"], input[type="radio"]',
  2699      label  : 'label'
  2700    }
  2701  
  2702  };
  2703  
  2704  })( jQuery, window , document );
  2705  
  2706  /*!
  2707   * # Semantic UI x.x - Dimmer
  2708   * http://github.com/semantic-org/semantic-ui/
  2709   *
  2710   *
  2711   * Copyright 2014 Contributors
  2712   * Released under the MIT license
  2713   * http://opensource.org/licenses/MIT
  2714   *
  2715   */
  2716  
  2717  ;(function ( $, window, document, undefined ) {
  2718  
  2719  "use strict";
  2720  
  2721  $.fn.dimmer = function(parameters) {
  2722    var
  2723      $allModules     = $(this),
  2724  
  2725      time            = new Date().getTime(),
  2726      performance     = [],
  2727  
  2728      query           = arguments[0],
  2729      methodInvoked   = (typeof query == 'string'),
  2730      queryArguments  = [].slice.call(arguments, 1),
  2731  
  2732      returnedValue
  2733    ;
  2734  
  2735    $allModules
  2736      .each(function() {
  2737        var
  2738          settings        = ( $.isPlainObject(parameters) )
  2739            ? $.extend(true, {}, $.fn.dimmer.settings, parameters)
  2740            : $.extend({}, $.fn.dimmer.settings),
  2741  
  2742          selector        = settings.selector,
  2743          namespace       = settings.namespace,
  2744          className       = settings.className,
  2745          error           = settings.error,
  2746  
  2747          eventNamespace  = '.' + namespace,
  2748          moduleNamespace = 'module-' + namespace,
  2749          moduleSelector  = $allModules.selector || '',
  2750  
  2751          clickEvent      = ('ontouchstart' in document.documentElement)
  2752            ? 'touchstart'
  2753            : 'click',
  2754  
  2755          $module = $(this),
  2756          $dimmer,
  2757          $dimmable,
  2758  
  2759          element   = this,
  2760          instance  = $module.data(moduleNamespace),
  2761          module
  2762        ;
  2763  
  2764        module = {
  2765  
  2766          preinitialize: function() {
  2767            if( module.is.dimmer() ) {
  2768              $dimmable = $module.parent();
  2769              $dimmer   = $module;
  2770            }
  2771            else {
  2772              $dimmable = $module;
  2773              if( module.has.dimmer() ) {
  2774                if(settings.dimmerName) {
  2775                  $dimmer = $dimmable.children(selector.dimmer).filter('.' + settings.dimmerName);
  2776                }
  2777                else {
  2778                  $dimmer = $dimmable.children(selector.dimmer);
  2779                }
  2780              }
  2781              else {
  2782                $dimmer = module.create();
  2783              }
  2784            }
  2785          },
  2786  
  2787          initialize: function() {
  2788            module.debug('Initializing dimmer', settings);
  2789            if(settings.on == 'hover') {
  2790              $dimmable
  2791                .on('mouseenter' + eventNamespace, module.show)
  2792                .on('mouseleave' + eventNamespace, module.hide)
  2793              ;
  2794            }
  2795            else if(settings.on == 'click') {
  2796              $dimmable
  2797                .on(clickEvent + eventNamespace, module.toggle)
  2798              ;
  2799            }
  2800            if( module.is.page() ) {
  2801              module.debug('Setting as a page dimmer', $dimmable);
  2802              module.set.pageDimmer();
  2803            }
  2804  
  2805            if( module.is.closable() ) {
  2806              module.verbose('Adding dimmer close event', $dimmer);
  2807              $dimmer
  2808                .on(clickEvent + eventNamespace, module.event.click)
  2809              ;
  2810            }
  2811            module.set.dimmable();
  2812            module.instantiate();
  2813          },
  2814  
  2815          instantiate: function() {
  2816            module.verbose('Storing instance of module', module);
  2817            instance = module;
  2818            $module
  2819              .data(moduleNamespace, instance)
  2820            ;
  2821          },
  2822  
  2823          destroy: function() {
  2824            module.verbose('Destroying previous module', $dimmer);
  2825            $module
  2826              .removeData(moduleNamespace)
  2827            ;
  2828            $dimmable
  2829              .off(eventNamespace)
  2830            ;
  2831            $dimmer
  2832              .off(eventNamespace)
  2833            ;
  2834          },
  2835  
  2836          event: {
  2837            click: function(event) {
  2838              module.verbose('Determining if event occured on dimmer', event);
  2839              if( $dimmer.find(event.target).length === 0 || $(event.target).is(selector.content) ) {
  2840                module.hide();
  2841                event.stopImmediatePropagation();
  2842              }
  2843            }
  2844          },
  2845  
  2846          addContent: function(element) {
  2847            var
  2848              $content = $(element)
  2849            ;
  2850            module.debug('Add content to dimmer', $content);
  2851            if($content.parent()[0] !== $dimmer[0]) {
  2852              $content.detach().appendTo($dimmer);
  2853            }
  2854          },
  2855  
  2856          create: function() {
  2857            var
  2858              $element = $( settings.template.dimmer() )
  2859            ;
  2860            if(settings.variation) {
  2861              module.debug('Creating dimmer with variation', settings.variation);
  2862              $element.addClass(settings.variation);
  2863            }
  2864            if(settings.dimmerName) {
  2865              module.debug('Creating named dimmer', settings.dimmerName);
  2866              $element.addClass(settings.dimmerName);
  2867            }
  2868            $element
  2869              .appendTo($dimmable)
  2870            ;
  2871            return $element;
  2872          },
  2873  
  2874          show: function(callback) {
  2875            callback = $.isFunction(callback)
  2876              ? callback
  2877              : function(){}
  2878            ;
  2879            module.debug('Showing dimmer', $dimmer, settings);
  2880            if( (!module.is.dimmed() || module.is.animating()) && module.is.enabled() ) {
  2881              module.animate.show(callback);
  2882              settings.onShow.call(element);
  2883              settings.onChange.call(element);
  2884            }
  2885            else {
  2886              module.debug('Dimmer is already shown or disabled');
  2887            }
  2888          },
  2889  
  2890          hide: function(callback) {
  2891            callback = $.isFunction(callback)
  2892              ? callback
  2893              : function(){}
  2894            ;
  2895            if( module.is.dimmed() || module.is.animating() ) {
  2896              module.debug('Hiding dimmer', $dimmer);
  2897              module.animate.hide(callback);
  2898              settings.onHide.call(element);
  2899              settings.onChange.call(element);
  2900            }
  2901            else {
  2902              module.debug('Dimmer is not visible');
  2903            }
  2904          },
  2905  
  2906          toggle: function() {
  2907            module.verbose('Toggling dimmer visibility', $dimmer);
  2908            if( !module.is.dimmed() ) {
  2909              module.show();
  2910            }
  2911            else {
  2912              module.hide();
  2913            }
  2914          },
  2915  
  2916          animate: {
  2917            show: function(callback) {
  2918              callback = $.isFunction(callback)
  2919                ? callback
  2920                : function(){}
  2921              ;
  2922              if(settings.useCSS && $.fn.transition !== undefined && $dimmer.transition('is supported')) {
  2923                if(settings.opacity !== 'auto') {
  2924                  module.set.opacity();
  2925                }
  2926                $dimmer
  2927                  .transition({
  2928                    animation   : settings.transition + ' in',
  2929                    queue       : false,
  2930                    duration    : module.get.duration(),
  2931                    useFailSafe : true,
  2932                    onStart     : function() {
  2933                      module.set.dimmed();
  2934                    },
  2935                    onComplete  : function() {
  2936                      module.set.active();
  2937                      callback();
  2938                    }
  2939                  })
  2940                ;
  2941              }
  2942              else {
  2943                module.verbose('Showing dimmer animation with javascript');
  2944                module.set.dimmed();
  2945                if(settings.opacity == 'auto') {
  2946                  settings.opacity = 0.8;
  2947                }
  2948                $dimmer
  2949                  .stop()
  2950                  .css({
  2951                    opacity : 0,
  2952                    width   : '100%',
  2953                    height  : '100%'
  2954                  })
  2955                  .fadeTo(module.get.duration(), settings.opacity, function() {
  2956                    $dimmer.removeAttr('style');
  2957                    module.set.active();
  2958                    callback();
  2959                  })
  2960                ;
  2961              }
  2962            },
  2963            hide: function(callback) {
  2964              callback = $.isFunction(callback)
  2965                ? callback
  2966                : function(){}
  2967              ;
  2968              if(settings.useCSS && $.fn.transition !== undefined && $dimmer.transition('is supported')) {
  2969                module.verbose('Hiding dimmer with css');
  2970                $dimmer
  2971                  .transition({
  2972                    animation   : settings.transition + ' out',
  2973                    queue       : false,
  2974                    duration    : module.get.duration(),
  2975                    useFailSafe : true,
  2976                    onStart     : function() {
  2977                      module.remove.dimmed();
  2978                    },
  2979                    onComplete  : function() {
  2980                      module.remove.active();
  2981                      callback();
  2982                    }
  2983                  })
  2984                ;
  2985              }
  2986              else {
  2987                module.verbose('Hiding dimmer with javascript');
  2988                module.remove.dimmed();
  2989                $dimmer
  2990                  .stop()
  2991                  .fadeOut(module.get.duration(), function() {
  2992                    module.remove.active();
  2993                    $dimmer.removeAttr('style');
  2994                    callback();
  2995                  })
  2996                ;
  2997              }
  2998            }
  2999          },
  3000  
  3001          get: {
  3002            dimmer: function() {
  3003              return $dimmer;
  3004            },
  3005            duration: function() {
  3006              if(typeof settings.duration == 'object') {
  3007                if( module.is.active() ) {
  3008                  return settings.duration.hide;
  3009                }
  3010                else {
  3011                  return settings.duration.show;
  3012                }
  3013              }
  3014              return settings.duration;
  3015            }
  3016          },
  3017  
  3018          has: {
  3019            dimmer: function() {
  3020              if(settings.dimmerName) {
  3021                return ($module.children(selector.dimmer).filter('.' + settings.dimmerName).length > 0);
  3022              }
  3023              else {
  3024                return ( $module.children(selector.dimmer).length > 0 );
  3025              }
  3026            }
  3027          },
  3028  
  3029          is: {
  3030            active: function() {
  3031              return $dimmer.hasClass(className.active);
  3032            },
  3033            animating: function() {
  3034              return ( $dimmer.is(':animated') || $dimmer.hasClass(className.animating) );
  3035            },
  3036            closable: function() {
  3037              if(settings.closable == 'auto') {
  3038                if(settings.on == 'hover') {
  3039                  return false;
  3040                }
  3041                return true;
  3042              }
  3043              return settings.closable;
  3044            },
  3045            dimmer: function() {
  3046              return $module.is(selector.dimmer);
  3047            },
  3048            dimmable: function() {
  3049              return $module.is(selector.dimmable);
  3050            },
  3051            dimmed: function() {
  3052              return $dimmable.hasClass(className.dimmed);
  3053            },
  3054            disabled: function() {
  3055              return $dimmable.hasClass(className.disabled);
  3056            },
  3057            enabled: function() {
  3058              return !module.is.disabled();
  3059            },
  3060            page: function () {
  3061              return $dimmable.is('body');
  3062            },
  3063            pageDimmer: function() {
  3064              return $dimmer.hasClass(className.pageDimmer);
  3065            }
  3066          },
  3067  
  3068          can: {
  3069            show: function() {
  3070              return !$dimmer.hasClass(className.disabled);
  3071            }
  3072          },
  3073  
  3074          set: {
  3075            opacity: function(opacity) {
  3076              var
  3077                opacity    = settings.opacity || opacity,
  3078                color      = $dimmer.css('background-color'),
  3079                colorArray = color.split(','),
  3080                isRGBA     = (colorArray && colorArray.length == 4)
  3081              ;
  3082              if(isRGBA) {
  3083                colorArray[3] = opacity + ')';
  3084                color         = colorArray.join(',');
  3085              }
  3086              else {
  3087                color = 'rgba(0, 0, 0, ' + opacity + ')';
  3088              }
  3089              module.debug('Setting opacity to', opacity);
  3090              $dimmer.css('background-color', color);
  3091            },
  3092            active: function() {
  3093              $dimmer.addClass(className.active);
  3094            },
  3095            dimmable: function() {
  3096              $dimmable.addClass(className.dimmable);
  3097            },
  3098            dimmed: function() {
  3099              $dimmable.addClass(className.dimmed);
  3100            },
  3101            pageDimmer: function() {
  3102              $dimmer.addClass(className.pageDimmer);
  3103            },
  3104            disabled: function() {
  3105              $dimmer.addClass(className.disabled);
  3106            }
  3107          },
  3108  
  3109          remove: {
  3110            active: function() {
  3111              $dimmer
  3112                .removeClass(className.active)
  3113              ;
  3114            },
  3115            dimmed: function() {
  3116              $dimmable.removeClass(className.dimmed);
  3117            },
  3118            disabled: function() {
  3119              $dimmer.removeClass(className.disabled);
  3120            }
  3121          },
  3122  
  3123          setting: function(name, value) {
  3124            module.debug('Changing setting', name, value);
  3125            if( $.isPlainObject(name) ) {
  3126              $.extend(true, settings, name);
  3127            }
  3128            else if(value !== undefined) {
  3129              settings[name] = value;
  3130            }
  3131            else {
  3132              return settings[name];
  3133            }
  3134          },
  3135          internal: function(name, value) {
  3136            if( $.isPlainObject(name) ) {
  3137              $.extend(true, module, name);
  3138            }
  3139            else if(value !== undefined) {
  3140              module[name] = value;
  3141            }
  3142            else {
  3143              return module[name];
  3144            }
  3145          },
  3146          debug: function() {
  3147            if(settings.debug) {
  3148              if(settings.performance) {
  3149                module.performance.log(arguments);
  3150              }
  3151              else {
  3152                module.debug = Function.prototype.bind.call(console.info, console, settings.name + ':');
  3153                module.debug.apply(console, arguments);
  3154              }
  3155            }
  3156          },
  3157          verbose: function() {
  3158            if(settings.verbose && settings.debug) {
  3159              if(settings.performance) {
  3160                module.performance.log(arguments);
  3161              }
  3162              else {
  3163                module.verbose = Function.prototype.bind.call(console.info, console, settings.name + ':');
  3164                module.verbose.apply(console, arguments);
  3165              }
  3166            }
  3167          },
  3168          error: function() {
  3169            module.error = Function.prototype.bind.call(console.error, console, settings.name + ':');
  3170            module.error.apply(console, arguments);
  3171          },
  3172          performance: {
  3173            log: function(message) {
  3174              var
  3175                currentTime,
  3176                executionTime,
  3177                previousTime
  3178              ;
  3179              if(settings.performance) {
  3180                currentTime   = new Date().getTime();
  3181                previousTime  = time || currentTime;
  3182                executionTime = currentTime - previousTime;
  3183                time          = currentTime;
  3184                performance.push({
  3185                  'Name'           : message[0],
  3186                  'Arguments'      : [].slice.call(message, 1) || '',
  3187                  'Element'        : element,
  3188                  'Execution Time' : executionTime
  3189                });
  3190              }
  3191              clearTimeout(module.performance.timer);
  3192              module.performance.timer = setTimeout(module.performance.display, 100);
  3193            },
  3194            display: function() {
  3195              var
  3196                title = settings.name + ':',
  3197                totalTime = 0
  3198              ;
  3199              time = false;
  3200              clearTimeout(module.performance.timer);
  3201              $.each(performance, function(index, data) {
  3202                totalTime += data['Execution Time'];
  3203              });
  3204              title += ' ' + totalTime + 'ms';
  3205              if(moduleSelector) {
  3206                title += ' \'' + moduleSelector + '\'';
  3207              }
  3208              if($allModules.length > 1) {
  3209                title += ' ' + '(' + $allModules.length + ')';
  3210              }
  3211              if( (console.group !== undefined || console.table !== undefined) && performance.length > 0) {
  3212                console.groupCollapsed(title);
  3213                if(console.table) {
  3214                  console.table(performance);
  3215                }
  3216                else {
  3217                  $.each(performance, function(index, data) {
  3218                    console.log(data['Name'] + ': ' + data['Execution Time']+'ms');
  3219                  });
  3220                }
  3221                console.groupEnd();
  3222              }
  3223              performance = [];
  3224            }
  3225          },
  3226          invoke: function(query, passedArguments, context) {
  3227            var
  3228              object = instance,
  3229              maxDepth,
  3230              found,
  3231              response
  3232            ;
  3233            passedArguments = passedArguments || queryArguments;
  3234            context         = element         || context;
  3235            if(typeof query == 'string' && object !== undefined) {
  3236              query    = query.split(/[\. ]/);
  3237              maxDepth = query.length - 1;
  3238              $.each(query, function(depth, value) {
  3239                var camelCaseValue = (depth != maxDepth)
  3240                  ? value + query[depth + 1].charAt(0).toUpperCase() + query[depth + 1].slice(1)
  3241                  : query
  3242                ;
  3243                if( $.isPlainObject( object[camelCaseValue] ) && (depth != maxDepth) ) {
  3244                  object = object[camelCaseValue];
  3245                }
  3246                else if( object[camelCaseValue] !== undefined ) {
  3247                  found = object[camelCaseValue];
  3248                  return false;
  3249                }
  3250                else if( $.isPlainObject( object[value] ) && (depth != maxDepth) ) {
  3251                  object = object[value];
  3252                }
  3253                else if( object[value] !== undefined ) {
  3254                  found = object[value];
  3255                  return false;
  3256                }
  3257                else {
  3258                  module.error(error.method, query);
  3259                  return false;
  3260                }
  3261              });
  3262            }
  3263            if ( $.isFunction( found ) ) {
  3264              response = found.apply(context, passedArguments);
  3265            }
  3266            else if(found !== undefined) {
  3267              response = found;
  3268            }
  3269            if($.isArray(returnedValue)) {
  3270              returnedValue.push(response);
  3271            }
  3272            else if(returnedValue !== undefined) {
  3273              returnedValue = [returnedValue, response];
  3274            }
  3275            else if(response !== undefined) {
  3276              returnedValue = response;
  3277            }
  3278            return found;
  3279          }
  3280        };
  3281  
  3282        module.preinitialize();
  3283  
  3284        if(methodInvoked) {
  3285          if(instance === undefined) {
  3286            module.initialize();
  3287          }
  3288          module.invoke(query);
  3289        }
  3290        else {
  3291          if(instance !== undefined) {
  3292            instance.invoke('destroy');
  3293          }
  3294          module.initialize();
  3295        }
  3296      })
  3297    ;
  3298  
  3299    return (returnedValue !== undefined)
  3300      ? returnedValue
  3301      : this
  3302    ;
  3303  };
  3304  
  3305  $.fn.dimmer.settings = {
  3306  
  3307    name        : 'Dimmer',
  3308    namespace   : 'dimmer',
  3309  
  3310    debug       : false,
  3311    verbose     : true,
  3312    performance : true,
  3313  
  3314    // name to distinguish between multiple dimmers in context
  3315    dimmerName  : false,
  3316  
  3317    // whether to add a variation type
  3318    variation   : false,
  3319  
  3320    // whether to bind close events
  3321    closable    : 'auto',
  3322  
  3323    // whether to use css animations
  3324    useCSS      : true,
  3325  
  3326    // css animation to use
  3327    transition  : 'fade',
  3328  
  3329    // event to bind to
  3330    on          : false,
  3331  
  3332    // overriding opacity value
  3333    opacity     : 'auto',
  3334  
  3335    // transition durations
  3336    duration    : {
  3337      show : 500,
  3338      hide : 500
  3339    },
  3340  
  3341    onChange    : function(){},
  3342    onShow      : function(){},
  3343    onHide      : function(){},
  3344  
  3345    error   : {
  3346      method   : 'The method you called is not defined.'
  3347    },
  3348  
  3349    selector: {
  3350      dimmable : '.dimmable',
  3351      dimmer   : '.ui.dimmer',
  3352      content  : '.ui.dimmer > .content, .ui.dimmer > .content > .center'
  3353    },
  3354  
  3355    template: {
  3356      dimmer: function() {
  3357       return $('<div />').attr('class', 'ui dimmer');
  3358      }
  3359    },
  3360  
  3361    className : {
  3362      active     : 'active',
  3363      animating  : 'animating',
  3364      dimmable   : 'dimmable',
  3365      dimmed     : 'dimmed',
  3366      disabled   : 'disabled',
  3367      hide       : 'hide',
  3368      pageDimmer : 'page',
  3369      show       : 'show'
  3370    }
  3371  
  3372  };
  3373  
  3374  })( jQuery, window , document );
  3375  /*!
  3376   * # Semantic UI x.x - Dropdown
  3377   * http://github.com/semantic-org/semantic-ui/
  3378   *
  3379   *
  3380   * Copyright 2014 Contributors
  3381   * Released under the MIT license
  3382   * http://opensource.org/licenses/MIT
  3383   *
  3384   */
  3385  
  3386  ;(function ( $, window, document, undefined ) {
  3387  
  3388  "use strict";
  3389  
  3390  $.fn.dropdown = function(parameters) {
  3391    var
  3392      $allModules    = $(this),
  3393      $document      = $(document),
  3394  
  3395      moduleSelector = $allModules.selector || '',
  3396  
  3397      hasTouch       = ('ontouchstart' in document.documentElement),
  3398      time           = new Date().getTime(),
  3399      performance    = [],
  3400  
  3401      query          = arguments[0],
  3402      methodInvoked  = (typeof query == 'string'),
  3403      queryArguments = [].slice.call(arguments, 1),
  3404      returnedValue
  3405    ;
  3406  
  3407    $allModules
  3408      .each(function() {
  3409        var
  3410          settings          = ( $.isPlainObject(parameters) )
  3411            ? $.extend(true, {}, $.fn.dropdown.settings, parameters)
  3412            : $.extend({}, $.fn.dropdown.settings),
  3413  
  3414          className       = settings.className,
  3415          metadata        = settings.metadata,
  3416          namespace       = settings.namespace,
  3417          selector        = settings.selector,
  3418          error           = settings.error,
  3419  
  3420          eventNamespace  = '.' + namespace,
  3421          moduleNamespace = 'module-' + namespace,
  3422  
  3423          $module         = $(this),
  3424          $text           = $module.find(selector.text),
  3425          $search         = $module.find(selector.search),
  3426          $input          = $module.find(selector.input),
  3427  
  3428          $combo = ($module.prev().find(selector.text).length > 0)
  3429            ? $module.prev().find(selector.text)
  3430            : $module.prev(),
  3431  
  3432          $menu           = $module.children(selector.menu),
  3433          $item           = $menu.find(selector.item),
  3434  
  3435          activated       = false,
  3436          itemActivated   = false,
  3437          element         = this,
  3438          instance        = $module.data(moduleNamespace),
  3439  
  3440          elementNamespace,
  3441          id,
  3442          observer,
  3443          module
  3444        ;
  3445  
  3446        module = {
  3447  
  3448          initialize: function() {
  3449            module.debug('Initializing dropdown', settings);
  3450  
  3451            if( module.is.alreadySetup() ) {
  3452              module.setup.reference();
  3453            }
  3454            else {
  3455              module.setup.layout();
  3456  
  3457              module.save.defaults();
  3458              module.set.selected();
  3459  
  3460              module.create.id();
  3461  
  3462              if(hasTouch) {
  3463                module.bind.touchEvents();
  3464              }
  3465              module.bind.mouseEvents();
  3466              module.bind.keyboardEvents();
  3467  
  3468              module.observeChanges();
  3469              module.instantiate();
  3470            }
  3471          },
  3472  
  3473          instantiate: function() {
  3474            module.verbose('Storing instance of dropdown', module);
  3475            instance = module;
  3476            $module
  3477              .data(moduleNamespace, module)
  3478            ;
  3479          },
  3480  
  3481          destroy: function() {
  3482            module.verbose('Destroying previous dropdown for', $module);
  3483            module.remove.tabbable();
  3484            $module
  3485              .off(eventNamespace)
  3486              .removeData(moduleNamespace)
  3487            ;
  3488            $menu
  3489              .off(eventNamespace)
  3490            ;
  3491            $document
  3492              .off(elementNamespace)
  3493            ;
  3494          },
  3495  
  3496          observeChanges: function() {
  3497            if('MutationObserver' in window) {
  3498              observer = new MutationObserver(function(mutations) {
  3499                if( module.is.selectMutation(mutations) ) {
  3500                  module.debug('<select> modified, recreating menu');
  3501                  module.setup.select();
  3502                }
  3503                else {
  3504                  module.debug('DOM tree modified, updating selector cache');
  3505                  module.refresh();
  3506                }
  3507              });
  3508              observer.observe(element, {
  3509                childList : true,
  3510                subtree   : true
  3511              });
  3512              module.debug('Setting up mutation observer', observer);
  3513            }
  3514          },
  3515  
  3516          create: {
  3517            id: function() {
  3518              id = (Math.random().toString(16) + '000000000').substr(2,8);
  3519              elementNamespace = '.' + id;
  3520              module.verbose('Creating unique id for element', id);
  3521            }
  3522          },
  3523  
  3524          search: function() {
  3525            var
  3526              query
  3527            ;
  3528            query = $search.val();
  3529  
  3530            module.verbose('Searching for query', query);
  3531            module.filter(query);
  3532            if(module.is.searchSelection() && module.can.show() ) {
  3533              module.show();
  3534            }
  3535          },
  3536  
  3537          setup: {
  3538            layout: function() {
  3539              if( $module.is('select') ) {
  3540                module.setup.select();
  3541              }
  3542              if( module.is.search() && !module.is.searchable() ) {
  3543                $search = $('<input />')
  3544                  .addClass(className.search)
  3545                  .insertBefore($text)
  3546                ;
  3547              }
  3548              if(settings.allowTab) {
  3549                module.set.tabbable();
  3550              }
  3551            },
  3552            select: function() {
  3553              var
  3554                selectValues  = module.get.selectValues()
  3555              ;
  3556              module.debug('Dropdown initialized on a select', selectValues);
  3557              if( $module.is('select') ) {
  3558                $input = $module;
  3559              }
  3560              // see if select is placed correctly already
  3561              if($input.parent(selector.dropdown).length > 0) {
  3562                module.debug('UI dropdown already exists. Creating dropdown menu only');
  3563                $module = $input.closest(selector.dropdown);
  3564                $menu   = $module.children(selector.menu);
  3565                if($menu.length === 0) {
  3566                  $menu = $('<div />')
  3567                    .addClass(className.menu)
  3568                    .appendTo($module)
  3569                  ;
  3570                }
  3571                $menu.html( settings.templates.menu( selectValues ));
  3572              }
  3573              else {
  3574                module.debug('Creating entire dropdown from select');
  3575                $module = $('<div />')
  3576                  .attr('class', $input.attr('class') )
  3577                  .addClass(className.selection)
  3578                  .addClass(className.dropdown)
  3579                  .html( settings.templates.dropdown(selectValues) )
  3580                  .insertBefore($input)
  3581                ;
  3582                $input
  3583                  .removeAttr('class')
  3584                  .prependTo($module)
  3585                ;
  3586              }
  3587              module.refresh();
  3588            },
  3589            reference: function() {
  3590              var
  3591                index = $allModules.index($module),
  3592                $firstModules,
  3593                $lastModules
  3594              ;
  3595              module.debug('Dropdown behavior was called on select, replacing with closest dropdown');
  3596              // replace module reference
  3597              $module = $module.parent(selector.dropdown);
  3598              module.refresh();
  3599              // adjust all modules
  3600              $firstModules = $allModules.slice(0, index);
  3601              $lastModules = $allModules.slice(index + 1);
  3602              $allModules = $firstModules.add($module).add($lastModules);
  3603            }
  3604          },
  3605  
  3606          refresh: function() {
  3607            module.verbose('Refreshing selector cache');
  3608            $text   = $module.find(selector.text);
  3609            $search = $module.find(selector.search);
  3610            $input  = $module.find(selector.input);
  3611            $combo  = ($module.prev().find(selector.text).length > 0)
  3612              ? $module.prev().find(selector.text)
  3613              : $module.prev()
  3614            ;
  3615            $menu   = $module.children(selector.menu);
  3616            $item   = $menu.find(selector.item);
  3617          },
  3618  
  3619          toggle: function() {
  3620            module.verbose('Toggling menu visibility');
  3621            if( !module.is.active() ) {
  3622              module.show();
  3623            }
  3624            else {
  3625              module.hide();
  3626            }
  3627          },
  3628  
  3629          show: function(callback) {
  3630            callback = $.isFunction(callback)
  3631              ? callback
  3632              : function(){}
  3633            ;
  3634            if( module.is.searchSelection() && module.is.allFiltered() ) {
  3635              return;
  3636            }
  3637            if( module.can.show() && !module.is.active() ) {
  3638              module.debug('Showing dropdown');
  3639              module.animate.show(function() {
  3640                if( module.can.click() ) {
  3641                  module.bind.intent();
  3642                }
  3643                module.set.visible();
  3644                callback.call(element);
  3645              });
  3646              settings.onShow.call(element);
  3647            }
  3648          },
  3649  
  3650          hide: function(callback) {
  3651            callback = $.isFunction(callback)
  3652              ? callback
  3653              : function(){}
  3654            ;
  3655            if( module.is.active() ) {
  3656              module.debug('Hiding dropdown');
  3657              module.animate.hide(function() {
  3658                module.remove.visible();
  3659                callback.call(element);
  3660              });
  3661              settings.onHide.call(element);
  3662            }
  3663          },
  3664  
  3665          hideOthers: function() {
  3666            module.verbose('Finding other dropdowns to hide');
  3667            $allModules
  3668              .not($module)
  3669                .has(selector.menu + ':visible:not(.' + className.animating + ')')
  3670                  .dropdown('hide')
  3671            ;
  3672          },
  3673  
  3674          hideSubMenus: function() {
  3675            var
  3676              $subMenus = $menu.find(selector.menu)
  3677            ;
  3678            $subMenus.transition('hide');
  3679          },
  3680  
  3681          bind: {
  3682            keyboardEvents: function() {
  3683              module.debug('Binding keyboard events');
  3684              $module
  3685                .on('keydown' + eventNamespace, module.event.keydown)
  3686              ;
  3687              if( module.is.searchable() ) {
  3688                $module
  3689                  .on(module.get.inputEvent(), selector.search, module.event.input)
  3690                ;
  3691              }
  3692            },
  3693            touchEvents: function() {
  3694              module.debug('Touch device detected binding additional touch events');
  3695              if( module.is.searchSelection() ) {
  3696                // do nothing special yet
  3697              }
  3698              else {
  3699                $module
  3700                  .on('touchstart' + eventNamespace, module.event.test.toggle)
  3701                ;
  3702              }
  3703              $menu
  3704                .on('touchstart' + eventNamespace, selector.item, module.event.item.mouseenter)
  3705              ;
  3706            },
  3707            mouseEvents: function() {
  3708              module.verbose('Mouse detected binding mouse events');
  3709              if( module.is.searchSelection() ) {
  3710                $module
  3711                  .on('mousedown' + eventNamespace, selector.menu, module.event.menu.activate)
  3712                  .on('mouseup'   + eventNamespace, selector.menu, module.event.menu.deactivate)
  3713                  .on('click'     + eventNamespace, selector.search, module.show)
  3714                  .on('focus'     + eventNamespace, selector.search, module.event.searchFocus)
  3715                  .on('blur'      + eventNamespace, selector.search, module.event.searchBlur)
  3716                  .on('click'     + eventNamespace, selector.text, module.event.searchTextFocus)
  3717                ;
  3718              }
  3719              else {
  3720                if(settings.on == 'click') {
  3721                  $module
  3722                    .on('click' + eventNamespace, module.event.test.toggle)
  3723                  ;
  3724                }
  3725                else if(settings.on == 'hover') {
  3726                  $module
  3727                    .on('mouseenter' + eventNamespace, module.delay.show)
  3728                    .on('mouseleave' + eventNamespace, module.delay.hide)
  3729                  ;
  3730                }
  3731                else {
  3732                  $module
  3733                    .on(settings.on + eventNamespace, module.toggle)
  3734                  ;
  3735                }
  3736                $module
  3737                  .on('mousedown' + eventNamespace, module.event.mousedown)
  3738                  .on('mouseup'   + eventNamespace, module.event.mouseup)
  3739                  .on('focus'     + eventNamespace, module.event.focus)
  3740                  .on('blur'      + eventNamespace, module.event.blur)
  3741                ;
  3742              }
  3743              $menu
  3744                .on('mouseenter' + eventNamespace, selector.item, module.event.item.mouseenter)
  3745                .on('mouseleave' + eventNamespace, selector.item, module.event.item.mouseleave)
  3746                .on('click'      + eventNamespace, selector.item, module.event.item.click)
  3747              ;
  3748            },
  3749            intent: function() {
  3750              module.verbose('Binding hide intent event to document');
  3751              if(hasTouch) {
  3752                $document
  3753                  .on('touchstart' + elementNamespace, module.event.test.touch)
  3754                  .on('touchmove'  + elementNamespace, module.event.test.touch)
  3755                ;
  3756              }
  3757              $document
  3758                .on('click' + elementNamespace, module.event.test.hide)
  3759              ;
  3760            }
  3761          },
  3762  
  3763          unbind: {
  3764            intent: function() {
  3765              module.verbose('Removing hide intent event from document');
  3766              if(hasTouch) {
  3767                $document
  3768                  .off('touchstart' + elementNamespace)
  3769                  .off('touchmove' + elementNamespace)
  3770                ;
  3771              }
  3772              $document
  3773                .off('click' + elementNamespace)
  3774              ;
  3775            }
  3776          },
  3777  
  3778          filter: function(searchTerm) {
  3779            var
  3780              $results       = $(),
  3781              escapedTerm    = module.escape.regExp(searchTerm),
  3782              exactRegExp    = new RegExp('^' + escapedTerm, 'igm'),
  3783              fullTextRegExp = new RegExp(escapedTerm, 'ig'),
  3784              allItemsFiltered
  3785            ;
  3786            module.verbose('Searching for matching values');
  3787            $item
  3788              .each(function(){
  3789                var
  3790                  $choice = $(this),
  3791                  text    = String(module.get.choiceText($choice, false)),
  3792                  value   = String(module.get.choiceValue($choice, text))
  3793                ;
  3794                if( text.match(exactRegExp) || value.match(exactRegExp) ) {
  3795                  $results = $results.add($choice);
  3796                }
  3797                else if(settings.fullTextSearch) {
  3798                  if( text.match(fullTextRegExp) || value.match(fullTextRegExp) ) {
  3799                    $results = $results.add($choice);
  3800                  }
  3801                }
  3802              })
  3803            ;
  3804  
  3805            module.debug('Setting filter', searchTerm);
  3806            module.remove.filteredItem();
  3807            $item
  3808              .not($results)
  3809              .addClass(className.filtered)
  3810            ;
  3811  
  3812            module.verbose('Selecting first non-filtered element');
  3813            module.remove.selectedItem();
  3814            $item
  3815              .not('.' + className.filtered)
  3816                .eq(0)
  3817                .addClass(className.selected)
  3818            ;
  3819            if( module.is.allFiltered() ) {
  3820              module.debug('All items filtered, hiding dropdown', searchTerm);
  3821              if(module.is.searchSelection()) {
  3822                module.hide();
  3823              }
  3824              settings.onNoResults.call(element, searchTerm);
  3825            }
  3826          },
  3827  
  3828          focusSearch: function() {
  3829            if( module.is.search() ) {
  3830              $search
  3831                .focus()
  3832              ;
  3833            }
  3834          },
  3835  
  3836          forceSelection: function() {
  3837            var
  3838              $currentlySelected = $item.not(className.filtered).filter('.' + className.selected).eq(0),
  3839              $activeItem        = $item.filter('.' + className.active).eq(0),
  3840              $selectedItem      = ($currentlySelected.length > 0)
  3841                ? $currentlySelected
  3842                : $activeItem,
  3843              hasSelected = ($selectedItem.size() > 0)
  3844            ;
  3845            if(hasSelected) {
  3846              module.event.item.click.call($selectedItem);
  3847              module.remove.filteredItem();
  3848            }
  3849            else {
  3850              module.hide();
  3851            }
  3852          },
  3853  
  3854          event: {
  3855            // prevents focus callback from occuring on mousedown
  3856            mousedown: function() {
  3857              activated = true;
  3858            },
  3859            mouseup: function() {
  3860              activated = false;
  3861            },
  3862            focus: function() {
  3863              if(!activated && module.is.hidden()) {
  3864                module.show();
  3865              }
  3866            },
  3867            blur: function(event) {
  3868              var
  3869                pageLostFocus = (document.activeElement === this)
  3870              ;
  3871              if(!activated && !pageLostFocus) {
  3872                module.hide();
  3873              }
  3874            },
  3875            searchFocus: function() {
  3876              activated = true;
  3877              module.show();
  3878            },
  3879            searchBlur: function(event) {
  3880              var
  3881                pageLostFocus = (document.activeElement === this)
  3882              ;
  3883              if(!itemActivated && !pageLostFocus) {
  3884                if(settings.forceSelection) {
  3885                  module.forceSelection();
  3886                }
  3887                else {
  3888                  module.hide();
  3889                }
  3890              }
  3891            },
  3892            searchTextFocus: function(event) {
  3893              activated = true;
  3894              $search.focus();
  3895            },
  3896            input: function(event) {
  3897              if(module.is.searchSelection()) {
  3898                module.set.filtered();
  3899              }
  3900              clearTimeout(module.timer);
  3901              module.timer = setTimeout(module.search, settings.delay.search);
  3902            },
  3903            keydown: function(event) {
  3904              var
  3905                $currentlySelected = $item.not(className.filtered).filter('.' + className.selected).eq(0),
  3906                $activeItem        = $menu.children('.' + className.active).eq(0),
  3907                $selectedItem      = ($currentlySelected.length > 0)
  3908                  ? $currentlySelected
  3909                  : $activeItem,
  3910                $visibleItems = ($selectedItem.length > 0)
  3911                  ? $selectedItem.siblings(':not(.' + className.filtered +')').andSelf()
  3912                  : $menu.children(':not(.' + className.filtered +')'),
  3913                $subMenu      = $selectedItem.children(selector.menu),
  3914                $parentMenu   = $selectedItem.closest(selector.menu),
  3915                isSubMenuItem = $parentMenu[0] !== $menu[0],
  3916                inVisibleMenu = $parentMenu.is(':visible'),
  3917                pressedKey    = event.which,
  3918                keys          = {
  3919                  enter      : 13,
  3920                  escape     : 27,
  3921                  leftArrow  : 37,
  3922                  upArrow    : 38,
  3923                  rightArrow : 39,
  3924                  downArrow  : 40
  3925                },
  3926                hasSubMenu       = ($subMenu.length> 0),
  3927                hasSelectedItem  = ($selectedItem.length > 0),
  3928                lastVisibleIndex = ($visibleItems.size() - 1),
  3929                $nextItem,
  3930                newIndex
  3931              ;
  3932              // visible menu keyboard shortcuts
  3933              if(module.is.visible()) {
  3934                // enter (select or sub-menu)
  3935                if(pressedKey == keys.enter && hasSelectedItem) {
  3936                  if(hasSubMenu && !settings.allowCategorySelection) {
  3937                    module.verbose('Pressed enter on unselectable category, opening sub menu');
  3938                    pressedKey = keys.rightArrow;
  3939                  }
  3940                  else {
  3941                    module.verbose('Enter key pressed, choosing selected item');
  3942                    module.event.item.click.call($selectedItem, event);
  3943                  }
  3944                }
  3945                // left arrow (hide sub-menu)
  3946                if(pressedKey == keys.leftArrow) {
  3947                  if(isSubMenuItem) {
  3948                    module.verbose('Left key pressed, closing sub-menu');
  3949                    module.animate.hide(false,  $parentMenu);
  3950                    $selectedItem
  3951                      .removeClass(className.selected)
  3952                    ;
  3953                    $parentMenu
  3954                      .closest(selector.item)
  3955                        .addClass(className.selected)
  3956                    ;
  3957                  }
  3958                  event.preventDefault();
  3959                }
  3960                // right arrow (show sub-menu)
  3961                if(pressedKey == keys.rightArrow) {
  3962                  if(hasSubMenu) {
  3963                    module.verbose('Right key pressed, opening sub-menu');
  3964                    module.animate.show(false,  $subMenu);
  3965                    $selectedItem
  3966                      .removeClass(className.selected)
  3967                    ;
  3968                    $subMenu
  3969                      .find(selector.item).eq(0)
  3970                        .addClass(className.selected)
  3971                    ;
  3972                  }
  3973                  event.preventDefault();
  3974                }
  3975                // up arrow (traverse menu up)
  3976                if(pressedKey == keys.upArrow) {
  3977                  $nextItem = (hasSelectedItem && inVisibleMenu)
  3978                    ? $selectedItem.prevAll(selector.item + ':not(.' + className.filtered + ')').eq(0)
  3979                    : $item.eq(0)
  3980                  ;
  3981                  if($visibleItems.index( $nextItem ) < 0) {
  3982                    module.verbose('Up key pressed but reached top of current menu');
  3983                    return;
  3984                  }
  3985                  else {
  3986                    module.verbose('Up key pressed, changing active item');
  3987                    $selectedItem
  3988                      .removeClass(className.selected)
  3989                    ;
  3990                    $nextItem
  3991                      .addClass(className.selected)
  3992                    ;
  3993                    module.set.scrollPosition($nextItem);
  3994                  }
  3995                  event.preventDefault();
  3996                }
  3997                // down arrow (traverse menu down)
  3998                if(pressedKey == keys.downArrow) {
  3999                  $nextItem = (hasSelectedItem && inVisibleMenu)
  4000                    ? $nextItem = $selectedItem.nextAll(selector.item + ':not(.' + className.filtered + ')').eq(0)
  4001                    : $item.eq(0)
  4002                  ;
  4003                  if($nextItem.length === 0) {
  4004                    module.verbose('Down key pressed but reached bottom of current menu');
  4005                    return;
  4006                  }
  4007                  else {
  4008                    module.verbose('Down key pressed, changing active item');
  4009                    $item
  4010                      .removeClass(className.selected)
  4011                    ;
  4012                    $nextItem
  4013                      .addClass(className.selected)
  4014                    ;
  4015                    module.set.scrollPosition($nextItem);
  4016                  }
  4017                  event.preventDefault();
  4018                }
  4019              }
  4020              else {
  4021                // enter (open menu)
  4022                if(pressedKey == keys.enter) {
  4023                  module.verbose('Enter key pressed, showing dropdown');
  4024                  module.show();
  4025                }
  4026                // escape (close menu)
  4027                if(pressedKey == keys.escape) {
  4028                  module.verbose('Escape key pressed, closing dropdown');
  4029                  module.hide();
  4030                }
  4031                // down arrow (open menu)
  4032                if(pressedKey == keys.downArrow) {
  4033                  module.verbose('Down key pressed, showing dropdown');
  4034                  module.show();
  4035                }
  4036              }
  4037            },
  4038            test: {
  4039              toggle: function(event) {
  4040                if( module.determine.eventInMenu(event, module.toggle) ) {
  4041                  event.preventDefault();
  4042                }
  4043              },
  4044              touch: function(event) {
  4045                module.determine.eventInMenu(event, function() {
  4046                  if(event.type == 'touchstart') {
  4047                    module.timer = setTimeout(module.hide, settings.delay.touch);
  4048                  }
  4049                  else if(event.type == 'touchmove') {
  4050                    clearTimeout(module.timer);
  4051                  }
  4052                });
  4053                event.stopPropagation();
  4054              },
  4055              hide: function(event) {
  4056                module.determine.eventInModule(event, module.hide);
  4057              }
  4058            },
  4059  
  4060            menu: {
  4061              activate: function() {
  4062                itemActivated = true;
  4063              },
  4064              deactivate: function() {
  4065                itemActivated = false;
  4066              }
  4067            },
  4068            item: {
  4069              mouseenter: function(event) {
  4070                var
  4071                  $subMenu    = $(this).children(selector.menu),
  4072                  $otherMenus = $(this).siblings(selector.item).children(selector.menu)
  4073                ;
  4074                if( $subMenu.length > 0 ) {
  4075                  clearTimeout(module.itemTimer);
  4076                  module.itemTimer = setTimeout(function() {
  4077                    module.verbose('Showing sub-menu', $subMenu);
  4078                    $.each($otherMenus, function() {
  4079                      module.animate.hide(false, $(this));
  4080                    });
  4081                    module.animate.show(false,  $subMenu);
  4082                  }, settings.delay.show);
  4083                  event.preventDefault();
  4084                }
  4085              },
  4086              mouseleave: function(event) {
  4087                var
  4088                  $subMenu = $(this).children(selector.menu)
  4089                ;
  4090                if($subMenu.length > 0) {
  4091                  clearTimeout(module.itemTimer);
  4092                  module.itemTimer = setTimeout(function() {
  4093                    module.verbose('Hiding sub-menu', $subMenu);
  4094                    module.animate.hide(false,  $subMenu);
  4095                  }, settings.delay.hide);
  4096                }
  4097              },
  4098              click: function (event) {
  4099                var
  4100                  $choice  = $(this),
  4101                  $target  = (event)
  4102                    ? $(event.target)
  4103                    : $(''),
  4104                  $subMenu = $choice.find(selector.menu),
  4105                  text     = module.get.choiceText($choice),
  4106                  value    = module.get.choiceValue($choice, text),
  4107                  callback = function() {
  4108                    module.remove.searchTerm();
  4109                    module.determine.selectAction(text, value);
  4110                  },
  4111                  hasSubMenu     = ($subMenu.length > 0),
  4112                  isBubbledEvent = ($subMenu.find($target).length > 0)
  4113                ;
  4114                if(!isBubbledEvent && (!hasSubMenu || settings.allowCategorySelection)) {
  4115                  callback();
  4116                }
  4117              }
  4118            },
  4119            resetStyle: function() {
  4120              $(this).removeAttr('style');
  4121            }
  4122          },
  4123  
  4124          determine: {
  4125            selectAction: function(text, value) {
  4126              module.verbose('Determining action', settings.action);
  4127              if( $.isFunction( module.action[settings.action] ) ) {
  4128                module.verbose('Triggering preset action', settings.action, text, value);
  4129                module.action[ settings.action ](text, value);
  4130              }
  4131              else if( $.isFunction(settings.action) ) {
  4132                module.verbose('Triggering user action', settings.action, text, value);
  4133                settings.action(text, value);
  4134              }
  4135              else {
  4136                module.error(error.action, settings.action);
  4137              }
  4138            },
  4139            eventInModule: function(event, callback) {
  4140              callback = $.isFunction(callback)
  4141                ? callback
  4142                : function(){}
  4143              ;
  4144              if( $(event.target).closest($module).length === 0 ) {
  4145                module.verbose('Triggering event', callback);
  4146                callback();
  4147                return true;
  4148              }
  4149              else {
  4150                module.verbose('Event occurred in dropdown, canceling callback');
  4151                return false;
  4152              }
  4153            },
  4154            eventInMenu: function(event, callback) {
  4155              callback = $.isFunction(callback)
  4156                ? callback
  4157                : function(){}
  4158              ;
  4159              if( $(event.target).closest($menu).length === 0 ) {
  4160                module.verbose('Triggering event', callback);
  4161                callback();
  4162                return true;
  4163              }
  4164              else {
  4165                module.verbose('Event occurred in dropdown menu, canceling callback');
  4166                return false;
  4167              }
  4168            }
  4169          },
  4170  
  4171          action: {
  4172  
  4173            nothing: function() {},
  4174  
  4175            activate: function(text, value) {
  4176              value = (value !== undefined)
  4177                ? value
  4178                : text
  4179              ;
  4180              module.set.selected(value);
  4181              module.hide(function() {
  4182                module.remove.filteredItem();
  4183              });
  4184            },
  4185  
  4186            select: function(text, value) {
  4187              value = (value !== undefined)
  4188                ? value
  4189                : text
  4190              ;
  4191              module.set.selected(value);
  4192              module.hide(function() {
  4193                module.remove.filteredItem();
  4194              });
  4195            },
  4196  
  4197            combo: function(text, value) {
  4198              value = (value !== undefined)
  4199                ? value
  4200                : text
  4201              ;
  4202              module.set.selected(value);
  4203              module.hide(function() {
  4204                module.remove.filteredItem();
  4205              });
  4206            },
  4207  
  4208            hide: function() {
  4209              module.hide(function() {
  4210                module.remove.filteredItem();
  4211              });
  4212            }
  4213  
  4214          },
  4215  
  4216          get: {
  4217            id: function() {
  4218              return id;
  4219            },
  4220            text: function() {
  4221              return $text.text();
  4222            },
  4223            value: function() {
  4224              return ($input.length > 0)
  4225                ? $input.val()
  4226                : $module.data(metadata.value)
  4227              ;
  4228            },
  4229            choiceText: function($choice, preserveHTML) {
  4230              preserveHTML = (preserveHTML !== undefined)
  4231                ? preserveHTML
  4232                : settings.preserveHTML
  4233              ;
  4234              if($choice !== undefined) {
  4235                if($choice.find(selector.menu).length > 0) {
  4236                  module.verbose('Retreiving text of element with sub-menu');
  4237                  $choice = $choice.clone();
  4238                  $choice.find(selector.menu).remove();
  4239                  $choice.find(selector.menuIcon).remove();
  4240                }
  4241                return ($choice.data(metadata.text) !== undefined)
  4242                  ? $choice.data(metadata.text)
  4243                  : (preserveHTML)
  4244                    ? $choice.html().trim()
  4245                    : $choice.text().trim()
  4246                ;
  4247              }
  4248            },
  4249            choiceValue: function($choice, choiceText) {
  4250              choiceText = choiceText || module.get.choiceText($choice);
  4251              return ($choice.data(metadata.value) !== undefined)
  4252                ? $choice.data(metadata.value)
  4253                : (typeof choiceText === 'string')
  4254                  ? choiceText.toLowerCase().trim()
  4255                  : choiceText.trim()
  4256              ;
  4257            },
  4258            inputEvent: function() {
  4259              var
  4260                input = $search[0]
  4261              ;
  4262              if(input) {
  4263                return (input.oninput !== undefined)
  4264                  ? 'input'
  4265                  : (input.onpropertychange !== undefined)
  4266                    ? 'propertychange'
  4267                    : 'keyup'
  4268                ;
  4269              }
  4270              return false;
  4271            },
  4272            selectValues: function() {
  4273              var
  4274                select = {}
  4275              ;
  4276              select.values = (settings.sortSelect)
  4277                ? {} // properties will be sorted in object when re-accessed
  4278                : [] // properties will keep original order in array
  4279              ;
  4280              $module
  4281                .find('option')
  4282                  .each(function() {
  4283                    var
  4284                      name  = $(this).html(),
  4285                      value = ( $(this).attr('value') !== undefined )
  4286                        ? $(this).attr('value')
  4287                        : name
  4288                    ;
  4289                    if(value === '') {
  4290                      select.placeholder = name;
  4291                    }
  4292                    else {
  4293                      if(settings.sortSelect) {
  4294                        select.values[value] = {
  4295                          name  : name,
  4296                          value : value
  4297                        };
  4298                      }
  4299                      else {
  4300                        select.values.push({
  4301                          name: name,
  4302                          value: value
  4303                        });
  4304                      }
  4305                    }
  4306                  })
  4307              ;
  4308              if(settings.sortSelect) {
  4309                module.debug('Retrieved and sorted values from select', select);
  4310              }
  4311              else {
  4312                module.debug('Retreived values from select', select);
  4313              }
  4314              return select;
  4315            },
  4316            activeItem: function() {
  4317              return $item.filter('.'  + className.active);
  4318            },
  4319            item: function(value, strict) {
  4320              var
  4321                $selectedItem = false
  4322              ;
  4323              value = (value !== undefined)
  4324                ? value
  4325                : ( module.get.value() !== undefined)
  4326                  ? module.get.value()
  4327                  : module.get.text()
  4328              ;
  4329              strict = (value === '' || value === 0)
  4330                ? true
  4331                : strict || false
  4332              ;
  4333              if(value !== undefined) {
  4334                $item
  4335                  .each(function() {
  4336                    var
  4337                      $choice       = $(this),
  4338                      optionText    = module.get.choiceText($choice),
  4339                      optionValue   = module.get.choiceValue($choice, optionText)
  4340                    ;
  4341                    if(strict) {
  4342                      module.verbose('Ambiguous dropdown value using strict type check', $choice, value);
  4343                      if( optionValue === value ) {
  4344                        $selectedItem = $(this);
  4345                        return true;
  4346                      }
  4347                      else if( !$selectedItem && optionText === value ) {
  4348                        $selectedItem = $(this);
  4349                        return true;
  4350                      }
  4351                    }
  4352                    else {
  4353                      if( optionValue == value ) {
  4354                        module.verbose('Found select item by value', optionValue, value);
  4355                        $selectedItem = $(this);
  4356                        return true;
  4357                      }
  4358                      else if( !$selectedItem && optionText == value ) {
  4359                        module.verbose('Found select item by text', optionText, value);
  4360                        $selectedItem = $(this);
  4361                        return true;
  4362                      }
  4363                    }
  4364                  })
  4365                ;
  4366              }
  4367              else {
  4368                value = module.get.text();
  4369              }
  4370              return $selectedItem || false;
  4371            }
  4372          },
  4373  
  4374          restore: {
  4375            defaults: function() {
  4376              module.restore.defaultText();
  4377              module.restore.defaultValue();
  4378            },
  4379            defaultText: function() {
  4380              var
  4381                defaultText = $module.data(metadata.defaultText)
  4382              ;
  4383              module.debug('Restoring default text', defaultText);
  4384              module.set.text(defaultText);
  4385              $text.addClass(className.placeholder);
  4386            },
  4387            defaultValue: function() {
  4388              var
  4389                defaultValue = $module.data(metadata.defaultValue)
  4390              ;
  4391              if(defaultValue !== undefined) {
  4392                module.debug('Restoring default value', defaultValue);
  4393                if(defaultValue.length) {
  4394                  module.set.selected(defaultValue);
  4395                }
  4396                else {
  4397                  module.remove.activeItem();
  4398                  module.remove.selectedItem();
  4399                }
  4400              }
  4401            }
  4402          },
  4403  
  4404          save: {
  4405            defaults: function() {
  4406              module.save.defaultText();
  4407              module.save.placeholderText();
  4408              module.save.defaultValue();
  4409            },
  4410            defaultValue: function() {
  4411              $module.data(metadata.defaultValue, module.get.value() );
  4412            },
  4413            defaultText: function() {
  4414              $module.data(metadata.defaultText, $text.text() );
  4415            },
  4416            placeholderText: function() {
  4417              if($text.hasClass(className.placeholder)) {
  4418                $module.data(metadata.placeholderText, $text.text());
  4419              }
  4420            }
  4421          },
  4422  
  4423          clear: function() {
  4424            var
  4425              placeholderText = $module.data(metadata.placeholderText)
  4426            ;
  4427            module.set.text(placeholderText);
  4428            module.set.value('');
  4429            module.remove.activeItem();
  4430            module.remove.selectedItem();
  4431            $text.addClass(className.placeholder);
  4432          },
  4433  
  4434          set: {
  4435            filtered: function() {
  4436              var
  4437                searchValue    = $search.val(),
  4438                hasSearchValue = (typeof searchValue === 'string' && searchValue.length > 0)
  4439              ;
  4440              if(hasSearchValue) {
  4441                $text.addClass(className.filtered);
  4442              }
  4443              else {
  4444                $text.removeClass(className.filtered);
  4445              }
  4446            },
  4447            tabbable: function() {
  4448              if( module.is.searchable() ) {
  4449                module.debug('Searchable dropdown initialized');
  4450                $search
  4451                  .val('')
  4452                  .attr('tabindex', 0)
  4453                ;
  4454                $menu
  4455                  .attr('tabindex', '-1')
  4456                ;
  4457              }
  4458              else {
  4459                module.debug('Simple selection dropdown initialized');
  4460                if(!$module.attr('tabindex') ) {
  4461                  $module
  4462                    .attr('tabindex', 0)
  4463                  ;
  4464                  $menu
  4465                    .attr('tabindex', '-1')
  4466                  ;
  4467                }
  4468              }
  4469            },
  4470            scrollPosition: function($item, forceScroll) {
  4471              var
  4472                edgeTolerance = 5,
  4473                hasActive,
  4474                offset,
  4475                itemHeight,
  4476                itemOffset,
  4477                menuOffset,
  4478                menuScroll,
  4479                menuHeight,
  4480                abovePage,
  4481                belowPage
  4482              ;
  4483  
  4484              $item       = $item || module.get.activeItem();
  4485              hasActive   = ($item && $item.length > 0);
  4486              forceScroll = (forceScroll !== undefined)
  4487                ? forceScroll
  4488                : false
  4489              ;
  4490  
  4491              if($item && hasActive) {
  4492  
  4493                if(!$menu.hasClass(className.visible)) {
  4494                  $menu.addClass(className.loading);
  4495                }
  4496  
  4497                menuHeight = $menu.height();
  4498                itemHeight = $item.height();
  4499                menuScroll = $menu.scrollTop();
  4500                menuOffset = $menu.offset().top;
  4501                itemOffset = $item.offset().top;
  4502                offset     = menuScroll - menuOffset + itemOffset;
  4503                belowPage  = menuScroll + menuHeight < (offset + edgeTolerance);
  4504                abovePage  = ((offset - edgeTolerance) < menuScroll);
  4505                module.debug('Scrolling to active item', offset);
  4506                if(abovePage || belowPage || forceScroll) {
  4507                  $menu
  4508                    .scrollTop(offset)
  4509                    .removeClass(className.loading)
  4510                  ;
  4511                }
  4512              }
  4513            },
  4514            text: function(text) {
  4515              if(settings.action == 'combo') {
  4516                module.debug('Changing combo button text', text, $combo);
  4517                if(settings.preserveHTML) {
  4518                  $combo.html(text);
  4519                }
  4520                else {
  4521                  $combo.text(text);
  4522                }
  4523              }
  4524              else if(settings.action !== 'select') {
  4525                module.debug('Changing text', text, $text);
  4526                $text
  4527                  .removeClass(className.filtered)
  4528                  .removeClass(className.placeholder)
  4529                ;
  4530                if(settings.preserveHTML) {
  4531                  $text.html(text);
  4532                }
  4533                else {
  4534                  $text.text(text);
  4535                }
  4536              }
  4537            },
  4538            value: function(value) {
  4539              module.debug('Adding selected value to hidden input', value, $input);
  4540              if($input.length > 0) {
  4541                $input
  4542                  .val(value)
  4543                  .trigger('change')
  4544                ;
  4545              }
  4546              else {
  4547                $module.data(metadata.value, value);
  4548              }
  4549            },
  4550            active: function() {
  4551              $module
  4552                .addClass(className.active)
  4553              ;
  4554            },
  4555            visible: function() {
  4556              $module.addClass(className.visible);
  4557            },
  4558            selected: function(value) {
  4559              var
  4560                $selectedItem = module.get.item(value),
  4561                selectedText,
  4562                selectedValue
  4563              ;
  4564              if($selectedItem && !$selectedItem.hasClass(className.active) ) {
  4565                module.debug('Setting selected menu item to', $selectedItem);
  4566                module.remove.activeItem();
  4567                module.remove.selectedItem();
  4568                $selectedItem
  4569                  .addClass(className.active)
  4570                  .addClass(className.selected)
  4571                ;
  4572                selectedText  = module.get.choiceText($selectedItem);
  4573                selectedValue = module.get.choiceValue($selectedItem, selectedText);
  4574                module.set.text(selectedText);
  4575                module.set.value(selectedValue);
  4576                settings.onChange.call(element, value, selectedText, $selectedItem);
  4577              }
  4578            }
  4579          },
  4580  
  4581          remove: {
  4582            active: function() {
  4583              $module.removeClass(className.active);
  4584            },
  4585            visible: function() {
  4586              $module.removeClass(className.visible);
  4587            },
  4588            activeItem: function() {
  4589              $item.removeClass(className.active);
  4590            },
  4591            filteredItem: function() {
  4592              $item.removeClass(className.filtered);
  4593            },
  4594            searchTerm: function() {
  4595              $search.val('');
  4596            },
  4597            selectedItem: function() {
  4598              $item.removeClass(className.selected);
  4599            },
  4600            tabbable: function() {
  4601              if( module.is.searchable() ) {
  4602                module.debug('Searchable dropdown initialized');
  4603                $search
  4604                  .attr('tabindex', '-1')
  4605                ;
  4606                $menu
  4607                  .attr('tabindex', '-1')
  4608                ;
  4609              }
  4610              else {
  4611                module.debug('Simple selection dropdown initialized');
  4612                $module
  4613                  .attr('tabindex', '-1')
  4614                ;
  4615                $menu
  4616                  .attr('tabindex', '-1')
  4617                ;
  4618              }
  4619            }
  4620          },
  4621  
  4622          is: {
  4623            active: function() {
  4624              return $module.hasClass(className.active);
  4625            },
  4626            alreadySetup: function() {
  4627              return ($module.is('select') && $module.parent(selector.dropdown).length > 0);
  4628            },
  4629            animating: function($subMenu) {
  4630              return ($subMenu)
  4631                ? $subMenu.is(':animated') || $subMenu.transition && $subMenu.transition('is animating')
  4632                : $menu.is(':animated') || $menu.transition && $menu.transition('is animating')
  4633              ;
  4634            },
  4635            allFiltered: function() {
  4636              return ($item.filter('.' + className.filtered).length === $item.length);
  4637            },
  4638            hidden: function($subMenu) {
  4639              return ($subMenu)
  4640                ? $subMenu.is(':hidden')
  4641                : $menu.is(':hidden')
  4642              ;
  4643            },
  4644            selectMutation: function(mutations) {
  4645              var
  4646                selectChanged = false
  4647              ;
  4648              $.each(mutations, function(index, mutation) {
  4649                if(mutation.target && $(mutation.target).is('select')) {
  4650                  selectChanged = true;
  4651                  return true;
  4652                }
  4653              });
  4654              return selectChanged;
  4655            },
  4656            search: function() {
  4657              return $module.hasClass(className.search);
  4658            },
  4659            searchable: function() {
  4660              return ($search.length > 0);
  4661            },
  4662            searchSelection: function() {
  4663              return ( module.is.searchable() && $search.parent().is($module) );
  4664            },
  4665            selection: function() {
  4666              return $module.hasClass(className.selection);
  4667            },
  4668            upward: function() {
  4669              return $module.hasClass(className.upward);
  4670            },
  4671            visible: function($subMenu) {
  4672              return ($subMenu)
  4673                ? $subMenu.is(':visible')
  4674                : $menu.is(':visible')
  4675              ;
  4676            }
  4677          },
  4678  
  4679          can: {
  4680            click: function() {
  4681              return (hasTouch || settings.on == 'click');
  4682            },
  4683            show: function() {
  4684              return !$module.hasClass(className.disabled);
  4685            }
  4686          },
  4687  
  4688          animate: {
  4689            show: function(callback, $subMenu) {
  4690              var
  4691                $currentMenu = $subMenu || $menu,
  4692                start = ($subMenu)
  4693                  ? function() {}
  4694                  : function() {
  4695                    module.hideSubMenus();
  4696                    module.hideOthers();
  4697                    module.set.active();
  4698                  }
  4699              ;
  4700              callback = $.isFunction(callback)
  4701                ? callback
  4702                : function(){}
  4703              ;
  4704              module.set.scrollPosition(module.get.activeItem(), true);
  4705              module.verbose('Doing menu show animation', $currentMenu);
  4706              if( module.is.hidden($currentMenu) || module.is.animating($currentMenu) ) {
  4707  
  4708                if(settings.transition == 'auto') {
  4709                  settings.transition = module.is.upward()
  4710                    ? 'slide up'
  4711                    : 'slide down'
  4712                  ;
  4713                  module.verbose('Automatically determining animation based on animation direction', settings.transition);
  4714                }
  4715                if(settings.transition == 'none') {
  4716                  callback.call(element);
  4717                }
  4718                else if($.fn.transition !== undefined && $module.transition('is supported')) {
  4719                  $currentMenu
  4720                    .transition({
  4721                      animation  : settings.transition + ' in',
  4722                      debug      : settings.debug,
  4723                      verbose    : settings.verbose,
  4724                      duration   : settings.duration,
  4725                      queue      : true,
  4726                      onStart    : start,
  4727                      onComplete : function() {
  4728                        callback.call(element);
  4729                      }
  4730                    })
  4731                  ;
  4732                }
  4733                else if(settings.transition == 'slide down') {
  4734                  start();
  4735                  $currentMenu
  4736                    .hide()
  4737                    .clearQueue()
  4738                    .children()
  4739                      .clearQueue()
  4740                      .css('opacity', 0)
  4741                      .delay(50)
  4742                      .animate({
  4743                        opacity : 1
  4744                      }, settings.duration, 'easeOutQuad', module.event.resetStyle)
  4745                      .end()
  4746                    .slideDown(100, 'easeOutQuad', function() {
  4747                      module.event.resetStyle.call(this);
  4748                      callback.call(element);
  4749                    })
  4750                  ;
  4751                }
  4752                else if(settings.transition == 'fade') {
  4753                  start();
  4754                  $currentMenu
  4755                    .hide()
  4756                    .clearQueue()
  4757                    .fadeIn(settings.duration, function() {
  4758                      module.event.resetStyle.call(this);
  4759                      callback.call(element);
  4760                    })
  4761                  ;
  4762                }
  4763                else {
  4764                  module.error(error.transition, settings.transition);
  4765                }
  4766              }
  4767            },
  4768            hide: function(callback, $subMenu) {
  4769              var
  4770                $currentMenu = $subMenu || $menu,
  4771                duration = ($subMenu)
  4772                  ? (settings.duration * 0.9)
  4773                  : settings.duration,
  4774                start = ($subMenu)
  4775                  ? function() {}
  4776                  : function() {
  4777                    if( module.can.click() ) {
  4778                      module.unbind.intent();
  4779                    }
  4780                    module.focusSearch();
  4781                    module.remove.active();
  4782                  }
  4783              ;
  4784              callback = $.isFunction(callback)
  4785                ? callback
  4786                : function(){}
  4787              ;
  4788              if( module.is.visible($currentMenu) || module.is.animating($currentMenu) ) {
  4789                module.verbose('Doing menu hide animation', $currentMenu);
  4790  
  4791                if(settings.transition == 'auto') {
  4792                  settings.transition = module.is.upward()
  4793                    ? 'slide up'
  4794                    : 'slide down'
  4795                  ;
  4796                }
  4797  
  4798                $input.trigger('blur');
  4799  
  4800                if(settings.transition == 'none') {
  4801                  callback.call(element);
  4802                }
  4803                else if($.fn.transition !== undefined && $module.transition('is supported')) {
  4804                  $currentMenu
  4805                    .transition({
  4806                      animation  : settings.transition + ' out',
  4807                      duration   : settings.duration,
  4808                      debug      : settings.debug,
  4809                      verbose    : settings.verbose,
  4810                      queue      : true,
  4811                      onStart    : start,
  4812                      onComplete : function() {
  4813                        callback.call(element);
  4814                      }
  4815                    })
  4816                  ;
  4817                }
  4818                else if(settings.transition == 'slide down') {
  4819                  start();
  4820                  $currentMenu
  4821                    .show()
  4822                    .clearQueue()
  4823                    .children()
  4824                      .clearQueue()
  4825                      .css('opacity', 1)
  4826                      .animate({
  4827                        opacity : 0
  4828                      }, 100, 'easeOutQuad', module.event.resetStyle)
  4829                      .end()
  4830                    .delay(50)
  4831                    .slideUp(100, 'easeOutQuad', function() {
  4832                      module.event.resetStyle.call(this);
  4833                      callback.call(element);
  4834                    })
  4835                  ;
  4836                }
  4837                else if(settings.transition == 'fade') {
  4838                  start();
  4839                  $currentMenu
  4840                    .show()
  4841                    .clearQueue()
  4842                    .fadeOut(150, function() {
  4843                      module.event.resetStyle.call(this);
  4844                      callback.call(element);
  4845                    })
  4846                  ;
  4847                }
  4848                else {
  4849                  module.error(error.transition);
  4850                }
  4851              }
  4852            }
  4853          },
  4854  
  4855          delay: {
  4856            show: function() {
  4857              module.verbose('Delaying show event to ensure user intent');
  4858              clearTimeout(module.timer);
  4859              module.timer = setTimeout(module.show, settings.delay.show);
  4860            },
  4861            hide: function() {
  4862              module.verbose('Delaying hide event to ensure user intent');
  4863              clearTimeout(module.timer);
  4864              module.timer = setTimeout(module.hide, settings.delay.hide);
  4865            }
  4866          },
  4867  
  4868          escape: {
  4869            regExp: function(text) {
  4870              text =  String(text);
  4871              return text.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&');
  4872            }
  4873          },
  4874  
  4875          setting: function(name, value) {
  4876            module.debug('Changing setting', name, value);
  4877            if( $.isPlainObject(name) ) {
  4878              $.extend(true, settings, name);
  4879            }
  4880            else if(value !== undefined) {
  4881              settings[name] = value;
  4882            }
  4883            else {
  4884              return settings[name];
  4885            }
  4886          },
  4887          internal: function(name, value) {
  4888            if( $.isPlainObject(name) ) {
  4889              $.extend(true, module, name);
  4890            }
  4891            else if(value !== undefined) {
  4892              module[name] = value;
  4893            }
  4894            else {
  4895              return module[name];
  4896            }
  4897          },
  4898          debug: function() {
  4899            if(settings.debug) {
  4900              if(settings.performance) {
  4901                module.performance.log(arguments);
  4902              }
  4903              else {
  4904                module.debug = Function.prototype.bind.call(console.info, console, settings.name + ':');
  4905                module.debug.apply(console, arguments);
  4906              }
  4907            }
  4908          },
  4909          verbose: function() {
  4910            if(settings.verbose && settings.debug) {
  4911              if(settings.performance) {
  4912                module.performance.log(arguments);
  4913              }
  4914              else {
  4915                module.verbose = Function.prototype.bind.call(console.info, console, settings.name + ':');
  4916                module.verbose.apply(console, arguments);
  4917              }
  4918            }
  4919          },
  4920          error: function() {
  4921            module.error = Function.prototype.bind.call(console.error, console, settings.name + ':');
  4922            module.error.apply(console, arguments);
  4923          },
  4924          performance: {
  4925            log: function(message) {
  4926              var
  4927                currentTime,
  4928                executionTime,
  4929                previousTime
  4930              ;
  4931              if(settings.performance) {
  4932                currentTime   = new Date().getTime();
  4933                previousTime  = time || currentTime;
  4934                executionTime = currentTime - previousTime;
  4935                time          = currentTime;
  4936                performance.push({
  4937                  'Name'           : message[0],
  4938                  'Arguments'      : [].slice.call(message, 1) || '',
  4939                  'Element'        : element,
  4940                  'Execution Time' : executionTime
  4941                });
  4942              }
  4943              clearTimeout(module.performance.timer);
  4944              module.performance.timer = setTimeout(module.performance.display, 500);
  4945            },
  4946            display: function() {
  4947              var
  4948                title = settings.name + ':',
  4949                totalTime = 0
  4950              ;
  4951              time = false;
  4952              clearTimeout(module.performance.timer);
  4953              $.each(performance, function(index, data) {
  4954                totalTime += data['Execution Time'];
  4955              });
  4956              title += ' ' + totalTime + 'ms';
  4957              if(moduleSelector) {
  4958                title += ' \'' + moduleSelector + '\'';
  4959              }
  4960              if( (console.group !== undefined || console.table !== undefined) && performance.length > 0) {
  4961                console.groupCollapsed(title);
  4962                if(console.table) {
  4963                  console.table(performance);
  4964                }
  4965                else {
  4966                  $.each(performance, function(index, data) {
  4967                    console.log(data['Name'] + ': ' + data['Execution Time']+'ms');
  4968                  });
  4969                }
  4970                console.groupEnd();
  4971              }
  4972              performance = [];
  4973            }
  4974          },
  4975          invoke: function(query, passedArguments, context) {
  4976            var
  4977              object = instance,
  4978              maxDepth,
  4979              found,
  4980              response
  4981            ;
  4982            passedArguments = passedArguments || queryArguments;
  4983            context         = element         || context;
  4984            if(typeof query == 'string' && object !== undefined) {
  4985              query    = query.split(/[\. ]/);
  4986              maxDepth = query.length - 1;
  4987              $.each(query, function(depth, value) {
  4988                var camelCaseValue = (depth != maxDepth)
  4989                  ? value + query[depth + 1].charAt(0).toUpperCase() + query[depth + 1].slice(1)
  4990                  : query
  4991                ;
  4992                if( $.isPlainObject( object[camelCaseValue] ) && (depth != maxDepth) ) {
  4993                  object = object[camelCaseValue];
  4994                }
  4995                else if( object[camelCaseValue] !== undefined ) {
  4996                  found = object[camelCaseValue];
  4997                  return false;
  4998                }
  4999                else if( $.isPlainObject( object[value] ) && (depth != maxDepth) ) {
  5000                  object = object[value];
  5001                }
  5002                else if( object[value] !== undefined ) {
  5003                  found = object[value];
  5004                  return false;
  5005                }
  5006                else {
  5007                  module.error(error.method, query);
  5008                  return false;
  5009                }
  5010              });
  5011            }
  5012            if ( $.isFunction( found ) ) {
  5013              response = found.apply(context, passedArguments);
  5014            }
  5015            else if(found !== undefined) {
  5016              response = found;
  5017            }
  5018            if($.isArray(returnedValue)) {
  5019              returnedValue.push(response);
  5020            }
  5021            else if(returnedValue !== undefined) {
  5022              returnedValue = [returnedValue, response];
  5023            }
  5024            else if(response !== undefined) {
  5025              returnedValue = response;
  5026            }
  5027            return found;
  5028          }
  5029        };
  5030  
  5031        if(methodInvoked) {
  5032          if(instance === undefined) {
  5033            module.initialize();
  5034          }
  5035          module.invoke(query);
  5036        }
  5037        else {
  5038          if(instance !== undefined) {
  5039            instance.invoke('destroy');
  5040          }
  5041          module.initialize();
  5042        }
  5043      })
  5044    ;
  5045    return (returnedValue !== undefined)
  5046      ? returnedValue
  5047      : $allModules
  5048    ;
  5049  };
  5050  
  5051  $.fn.dropdown.settings = {
  5052  
  5053    debug                  : false,
  5054    verbose                : true,
  5055    performance            : true,
  5056  
  5057    on                     : 'click',
  5058    action                 : 'activate',
  5059  
  5060    allowTab               : true,
  5061    fullTextSearch         : false,
  5062    preserveHTML           : true,
  5063    sortSelect             : false,
  5064  
  5065    allowCategorySelection : false,
  5066  
  5067    delay                  : {
  5068      hide   : 300,
  5069      show   : 200,
  5070      search : 50,
  5071      touch  : 50
  5072    },
  5073  
  5074    forceSelection: true,
  5075  
  5076    transition : 'auto',
  5077    duration   : 250,
  5078  
  5079    /* Callbacks */
  5080    onNoResults : function(searchTerm){},
  5081    onChange    : function(value, text){},
  5082    onShow      : function(){},
  5083    onHide      : function(){},
  5084  
  5085    /* Component */
  5086  
  5087    name           : 'Dropdown',
  5088    namespace      : 'dropdown',
  5089  
  5090    error   : {
  5091      action       : 'You called a dropdown action that was not defined',
  5092      alreadySetup : 'Once a select has been initialized behaviors must be called on the created ui dropdown',
  5093      method       : 'The method you called is not defined.',
  5094      transition   : 'The requested transition was not found'
  5095    },
  5096  
  5097    metadata: {
  5098      defaultText     : 'defaultText',
  5099      defaultValue    : 'defaultValue',
  5100      placeholderText : 'placeholderText',
  5101      text            : 'text',
  5102      value           : 'value'
  5103    },
  5104  
  5105    selector : {
  5106      dropdown : '.ui.dropdown',
  5107      input    : '> input[type="hidden"], > select',
  5108      item     : '.item',
  5109      menu     : '.menu',
  5110      menuIcon : '.dropdown.icon',
  5111      search   : '> input.search, .menu > .search > input, .menu > input.search',
  5112      text     : '> .text:not(.icon)'
  5113    },
  5114  
  5115    className : {
  5116      active      : 'active',
  5117      animating   : 'animating',
  5118      disabled    : 'disabled',
  5119      dropdown    : 'ui dropdown',
  5120      filtered    : 'filtered',
  5121      loading     : 'loading',
  5122      menu        : 'menu',
  5123      placeholder : 'default',
  5124      search      : 'search',
  5125      selected    : 'selected',
  5126      selection   : 'selection',
  5127      upward      : 'upward',
  5128      visible     : 'visible'
  5129    }
  5130  
  5131  };
  5132  
  5133  /* Templates */
  5134  $.fn.dropdown.settings.templates = {
  5135    menu: function(select) {
  5136      var
  5137        placeholder = select.placeholder || false,
  5138        values      = select.values || {},
  5139        html        = ''
  5140      ;
  5141      $.each(select.values, function(index, option) {
  5142        html += '<div class="item" data-value="' + option.value + '">' + option.name + '</div>';
  5143      });
  5144      return html;
  5145    },
  5146    dropdown: function(select) {
  5147      var
  5148        placeholder = select.placeholder || false,
  5149        values      = select.values || {},
  5150        html        = ''
  5151      ;
  5152      html +=  '<i class="dropdown icon"></i>';
  5153      if(select.placeholder) {
  5154        html += '<div class="default text">' + placeholder + '</div>';
  5155      }
  5156      else {
  5157        html += '<div class="text"></div>';
  5158      }
  5159      html += '<div class="menu">';
  5160      $.each(select.values, function(index, option) {
  5161        html += '<div class="item" data-value="' + option.value + '">' + option.name + '</div>';
  5162      });
  5163      html += '</div>';
  5164      return html;
  5165    }
  5166  };
  5167  
  5168  
  5169  /* Dependencies */
  5170  $.extend( $.easing, {
  5171    easeOutQuad: function (x, t, b, c, d) {
  5172      return -c *(t/=d)*(t-2) + b;
  5173    },
  5174  });
  5175  
  5176  
  5177  })( jQuery, window , document );
  5178  
  5179  /*!
  5180   * # Semantic UI x.x - Modal
  5181   * http://github.com/semantic-org/semantic-ui/
  5182   *
  5183   *
  5184   * Copyright 2014 Contributors
  5185   * Released under the MIT license
  5186   * http://opensource.org/licenses/MIT
  5187   *
  5188   */
  5189  
  5190  ;(function ( $, window, document, undefined ) {
  5191  
  5192  "use strict";
  5193  
  5194  $.fn.modal = function(parameters) {
  5195    var
  5196      $allModules    = $(this),
  5197      $window        = $(window),
  5198      $document      = $(document),
  5199      $body          = $('body'),
  5200  
  5201      moduleSelector = $allModules.selector || '',
  5202  
  5203      time           = new Date().getTime(),
  5204      performance    = [],
  5205  
  5206      query          = arguments[0],
  5207      methodInvoked  = (typeof query == 'string'),
  5208      queryArguments = [].slice.call(arguments, 1),
  5209  
  5210      requestAnimationFrame = window.requestAnimationFrame
  5211        || window.mozRequestAnimationFrame
  5212        || window.webkitRequestAnimationFrame
  5213        || window.msRequestAnimationFrame
  5214        || function(callback) { setTimeout(callback, 0); },
  5215  
  5216      returnedValue
  5217    ;
  5218  
  5219    $allModules
  5220      .each(function() {
  5221        var
  5222          settings    = ( $.isPlainObject(parameters) )
  5223            ? $.extend(true, {}, $.fn.modal.settings, parameters)
  5224            : $.extend({}, $.fn.modal.settings),
  5225  
  5226          selector        = settings.selector,
  5227          className       = settings.className,
  5228          namespace       = settings.namespace,
  5229          error           = settings.error,
  5230  
  5231          eventNamespace  = '.' + namespace,
  5232          moduleNamespace = 'module-' + namespace,
  5233  
  5234          $module         = $(this),
  5235          $context        = $(settings.context),
  5236          $close          = $module.find(selector.close),
  5237  
  5238          $allModals,
  5239          $otherModals,
  5240          $focusedElement,
  5241          $dimmable,
  5242          $dimmer,
  5243  
  5244          element         = this,
  5245          instance        = $module.data(moduleNamespace),
  5246  
  5247          elementNamespace,
  5248          id,
  5249          observer,
  5250          module
  5251        ;
  5252        module  = {
  5253  
  5254          initialize: function() {
  5255            module.verbose('Initializing dimmer', $context);
  5256  
  5257            module.create.id();
  5258            module.create.dimmer();
  5259            module.refreshModals();
  5260  
  5261            module.verbose('Attaching close events', $close);
  5262            module.bind.events();
  5263            module.observeChanges();
  5264            module.instantiate();
  5265          },
  5266  
  5267          instantiate: function() {
  5268            module.verbose('Storing instance of modal');
  5269            instance = module;
  5270            $module
  5271              .data(moduleNamespace, instance)
  5272            ;
  5273          },
  5274  
  5275          create: {
  5276            dimmer: function() {
  5277              var
  5278                defaultSettings = {
  5279                  debug      : settings.debug,
  5280                  dimmerName : 'modals',
  5281                  duration   : {
  5282                    show     : settings.duration,
  5283                    hide     : settings.duration
  5284                  }
  5285                },
  5286                dimmerSettings = $.extend(true, defaultSettings, settings.dimmerSettings)
  5287              ;
  5288              if($.fn.dimmer === undefined) {
  5289                module.error(error.dimmer);
  5290                return;
  5291              }
  5292              module.debug('Creating dimmer with settings', dimmerSettings);
  5293              $dimmable = $context.dimmer(dimmerSettings);
  5294              if(settings.detachable) {
  5295                module.verbose('Modal is detachable, moving content into dimmer');
  5296                $dimmable.dimmer('add content', $module);
  5297              }
  5298              $dimmer = $dimmable.dimmer('get dimmer');
  5299            },
  5300            id: function() {
  5301              id = (Math.random().toString(16) + '000000000').substr(2,8);
  5302              elementNamespace = '.' + id;
  5303              module.verbose('Creating unique id for element', id);
  5304            }
  5305          },
  5306  
  5307          destroy: function() {
  5308            module.verbose('Destroying previous modal');
  5309            $module
  5310              .removeData(moduleNamespace)
  5311              .off(eventNamespace)
  5312            ;
  5313            $window.off(elementNamespace);
  5314            $close.off(eventNamespace);
  5315            $context.dimmer('destroy');
  5316          },
  5317  
  5318          observeChanges: function() {
  5319            if('MutationObserver' in window) {
  5320              observer = new MutationObserver(function(mutations) {
  5321                module.debug('DOM tree modified, refreshing');
  5322                module.refresh();
  5323              });
  5324              observer.observe(element, {
  5325                childList : true,
  5326                subtree   : true
  5327              });
  5328              module.debug('Setting up mutation observer', observer);
  5329            }
  5330          },
  5331  
  5332          refresh: function() {
  5333            module.remove.scrolling();
  5334            module.cacheSizes();
  5335            module.set.screenHeight();
  5336            module.set.type();
  5337            module.set.position();
  5338          },
  5339  
  5340          refreshModals: function() {
  5341            $otherModals = $module.siblings(selector.modal);
  5342            $allModals   = $otherModals.add($module);
  5343          },
  5344  
  5345          attachEvents: function(selector, event) {
  5346            var
  5347              $toggle = $(selector)
  5348            ;
  5349            event = $.isFunction(module[event])
  5350              ? module[event]
  5351              : module.toggle
  5352            ;
  5353            if($toggle.length > 0) {
  5354              module.debug('Attaching modal events to element', selector, event);
  5355              $toggle
  5356                .off(eventNamespace)
  5357                .on('click' + eventNamespace, event)
  5358              ;
  5359            }
  5360            else {
  5361              module.error(error.notFound, selector);
  5362            }
  5363          },
  5364  
  5365          bind: {
  5366            events: function() {
  5367              $close.on('click' + eventNamespace, module.event.close);
  5368              $window.on('resize' + elementNamespace, module.event.resize);
  5369            }
  5370          },
  5371  
  5372          get: {
  5373            id: function() {
  5374              return (Math.random().toString(16) + '000000000').substr(2,8);
  5375            }
  5376          },
  5377  
  5378          event: {
  5379            close: function() {
  5380              module.verbose('Closing element pressed');
  5381              if( $(this).is(selector.approve) ) {
  5382                if(settings.onApprove.call(element) !== false) {
  5383                  module.hide();
  5384                }
  5385                else {
  5386                  module.verbose('Approve callback returned false cancelling hide');
  5387                }
  5388              }
  5389              else if( $(this).is(selector.deny) ) {
  5390                if(settings.onDeny.call(element) !== false) {
  5391                  module.hide();
  5392                }
  5393                else {
  5394                  module.verbose('Deny callback returned false cancelling hide');
  5395                }
  5396              }
  5397              else {
  5398                module.hide();
  5399              }
  5400            },
  5401            click: function(event) {
  5402              if( $(event.target).closest($module).length === 0 ) {
  5403                module.debug('Dimmer clicked, hiding all modals');
  5404                if( module.is.active() ) {
  5405                  module.remove.clickaway();
  5406                  if(settings.allowMultiple) {
  5407                    module.hide();
  5408                  }
  5409                  else {
  5410                    module.hideAll();
  5411                  }
  5412                }
  5413              }
  5414            },
  5415            debounce: function(method, delay) {
  5416              clearTimeout(module.timer);
  5417              module.timer = setTimeout(method, delay);
  5418            },
  5419            keyboard: function(event) {
  5420              var
  5421                keyCode   = event.which,
  5422                escapeKey = 27
  5423              ;
  5424              if(keyCode == escapeKey) {
  5425                if(settings.closable) {
  5426                  module.debug('Escape key pressed hiding modal');
  5427                  module.hide();
  5428                }
  5429                else {
  5430                  module.debug('Escape key pressed, but closable is set to false');
  5431                }
  5432                event.preventDefault();
  5433              }
  5434            },
  5435            resize: function() {
  5436              if( $dimmable.dimmer('is active') ) {
  5437                requestAnimationFrame(module.refresh);
  5438              }
  5439            }
  5440          },
  5441  
  5442          toggle: function() {
  5443            if( module.is.active() || module.is.animating() ) {
  5444              module.hide();
  5445            }
  5446            else {
  5447              module.show();
  5448            }
  5449          },
  5450  
  5451          show: function(callback) {
  5452            callback = $.isFunction(callback)
  5453              ? callback
  5454              : function(){}
  5455            ;
  5456            module.refreshModals();
  5457            module.showModal(callback);
  5458          },
  5459  
  5460          hide: function(callback) {
  5461            callback = $.isFunction(callback)
  5462              ? callback
  5463              : function(){}
  5464            ;
  5465            module.refreshModals();
  5466            module.hideModal(callback);
  5467          },
  5468  
  5469          showModal: function(callback) {
  5470            callback = $.isFunction(callback)
  5471              ? callback
  5472              : function(){}
  5473            ;
  5474            if( module.is.animating() || !module.is.active() ) {
  5475  
  5476              module.showDimmer();
  5477              module.cacheSizes();
  5478              module.set.position();
  5479              module.set.screenHeight();
  5480              module.set.type();
  5481              module.set.clickaway();
  5482  
  5483              if( !settings.allowMultiple && $otherModals.filter('.' + className.active).length > 0) {
  5484                module.debug('Other modals visible, queueing show animation');
  5485                module.hideOthers(module.showModal);
  5486              }
  5487              else {
  5488                settings.onShow.call(element);
  5489                if(settings.transition && $.fn.transition !== undefined && $module.transition('is supported')) {
  5490                  module.debug('Showing modal with css animations');
  5491                  $module
  5492                    .transition({
  5493                      debug       : settings.debug,
  5494                      animation   : settings.transition + ' in',
  5495                      queue       : settings.queue,
  5496                      duration    : settings.duration,
  5497                      useFailSafe : true,
  5498                      onComplete : function() {
  5499                        settings.onVisible.apply(element);
  5500                        module.add.keyboardShortcuts();
  5501                        module.save.focus();
  5502                        module.set.active();
  5503                        module.set.autofocus();
  5504                        callback();
  5505                      }
  5506                    })
  5507                  ;
  5508                }
  5509                else {
  5510                  module.debug('Showing modal with javascript');
  5511                  $module
  5512                    .fadeIn(settings.duration, settings.easing, function() {
  5513                      settings.onVisible.apply(element);
  5514                      module.add.keyboardShortcuts();
  5515                      module.save.focus();
  5516                      module.set.active();
  5517                      callback();
  5518                    })
  5519                  ;
  5520                }
  5521              }
  5522            }
  5523            else {
  5524              module.debug('Modal is already visible');
  5525            }
  5526          },
  5527  
  5528          hideModal: function(callback, keepDimmed) {
  5529            callback = $.isFunction(callback)
  5530              ? callback
  5531              : function(){}
  5532            ;
  5533            module.debug('Hiding modal');
  5534            settings.onHide.call(element);
  5535  
  5536            if( module.is.animating() || module.is.active() ) {
  5537              if(settings.transition && $.fn.transition !== undefined && $module.transition('is supported')) {
  5538                module.remove.active();
  5539                $module
  5540                  .transition({
  5541                    debug       : settings.debug,
  5542                    animation   : settings.transition + ' out',
  5543                    queue       : settings.queue,
  5544                    duration    : settings.duration,
  5545                    useFailSafe : true,
  5546                    onStart     : function() {
  5547                      if(!module.othersActive() && !keepDimmed) {
  5548                        module.hideDimmer();
  5549                      }
  5550                      module.remove.keyboardShortcuts();
  5551                    },
  5552                    onComplete : function() {
  5553                      settings.onHidden.call(element);
  5554                      module.restore.focus();
  5555                      callback();
  5556                    }
  5557                  })
  5558                ;
  5559              }
  5560              else {
  5561                module.remove.active();
  5562                if( !module.othersActive() ) {
  5563                  module.hideDimmer();
  5564                }
  5565                module.remove.keyboardShortcuts();
  5566                $module
  5567                  .fadeOut(settings.duration, settings.easing, function() {
  5568                    settings.onHidden.call(element);
  5569                    module.restore.focus();
  5570                    callback();
  5571                  })
  5572                ;
  5573              }
  5574            }
  5575          },
  5576  
  5577          showDimmer: function() {
  5578            if($dimmable.dimmer('is animating') || !$dimmable.dimmer('is active') ) {
  5579              module.debug('Showing dimmer');
  5580              $dimmable.dimmer('show');
  5581            }
  5582            else {
  5583              module.debug('Dimmer already visible');
  5584            }
  5585          },
  5586  
  5587          hideDimmer: function() {
  5588            if( $dimmable.dimmer('is animating') || ($dimmable.dimmer('is active')) ) {
  5589              $dimmable.dimmer('hide', function() {
  5590                if(settings.transition && $.fn.transition !== undefined && $module.transition('is supported')) {
  5591                  module.remove.clickaway();
  5592                  module.remove.screenHeight();
  5593                }
  5594              });
  5595            }
  5596            else {
  5597              module.debug('Dimmer is not visible cannot hide');
  5598              return;
  5599            }
  5600          },
  5601  
  5602          hideAll: function(callback) {
  5603            var
  5604              $visibleModals = $allModals.filter(':visible')
  5605            ;
  5606            callback = $.isFunction(callback)
  5607              ? callback
  5608              : function(){}
  5609            ;
  5610            if( $visibleModals.length > 0 ) {
  5611              module.debug('Hiding all visible modals');
  5612              module.hideDimmer();
  5613              $visibleModals
  5614                .modal('hide modal', callback)
  5615              ;
  5616            }
  5617          },
  5618  
  5619          hideOthers: function(callback) {
  5620            var
  5621              $visibleModals = $otherModals.filter(':visible')
  5622            ;
  5623            callback = $.isFunction(callback)
  5624              ? callback
  5625              : function(){}
  5626            ;
  5627            if( $visibleModals.length > 0 ) {
  5628              module.debug('Hiding other modals', $otherModals);
  5629              $visibleModals
  5630                .modal('hide modal', callback, true)
  5631              ;
  5632            }
  5633          },
  5634  
  5635          othersActive: function() {
  5636            return ($otherModals.filter('.' + className.active).length > 0);
  5637          },
  5638  
  5639          add: {
  5640            keyboardShortcuts: function() {
  5641              module.verbose('Adding keyboard shortcuts');
  5642              $document
  5643                .on('keyup' + eventNamespace, module.event.keyboard)
  5644              ;
  5645            }
  5646          },
  5647  
  5648          save: {
  5649            focus: function() {
  5650              $focusedElement = $(document.activeElement).blur();
  5651            }
  5652          },
  5653  
  5654          restore: {
  5655            focus: function() {
  5656              if($focusedElement && $focusedElement.length > 0) {
  5657                $focusedElement.focus();
  5658              }
  5659            }
  5660          },
  5661  
  5662          remove: {
  5663            active: function() {
  5664              $module.removeClass(className.active);
  5665            },
  5666            clickaway: function() {
  5667              if(settings.closable) {
  5668                $dimmer
  5669                  .off('click' + elementNamespace)
  5670                ;
  5671              }
  5672            },
  5673            screenHeight: function() {
  5674              if(module.cache.height > module.cache.pageHeight) {
  5675                module.debug('Removing page height');
  5676                $body
  5677                  .css('height', '')
  5678                ;
  5679              }
  5680            },
  5681            keyboardShortcuts: function() {
  5682              module.verbose('Removing keyboard shortcuts');
  5683              $document
  5684                .off('keyup' + eventNamespace)
  5685              ;
  5686            },
  5687            scrolling: function() {
  5688              $dimmable.removeClass(className.scrolling);
  5689              $module.removeClass(className.scrolling);
  5690            }
  5691          },
  5692  
  5693          cacheSizes: function() {
  5694            var
  5695              modalHeight = $module.outerHeight()
  5696            ;
  5697            if(module.cache === undefined || modalHeight !== 0) {
  5698              module.cache = {
  5699                pageHeight    : $(document).outerHeight(),
  5700                height        : modalHeight + settings.offset,
  5701                contextHeight : (settings.context == 'body')
  5702                  ? $(window).height()
  5703                  : $dimmable.height()
  5704              };
  5705            }
  5706            module.debug('Caching modal and container sizes', module.cache);
  5707          },
  5708  
  5709          can: {
  5710            fit: function() {
  5711              return ( ( module.cache.height + (settings.padding * 2) ) < module.cache.contextHeight);
  5712            }
  5713          },
  5714  
  5715          is: {
  5716            active: function() {
  5717              return $module.hasClass(className.active);
  5718            },
  5719            animating: function() {
  5720              return $module.transition('is supported')
  5721                ? $module.transition('is animating')
  5722                : $module.is(':visible')
  5723              ;
  5724            },
  5725            scrolling: function() {
  5726              return $dimmable.hasClass(className.scrolling);
  5727            },
  5728            modernBrowser: function() {
  5729              // appName for IE11 reports 'Netscape' can no longer use
  5730              return !(window.ActiveXObject || "ActiveXObject" in window);
  5731            }
  5732          },
  5733  
  5734          set: {
  5735            autofocus: function() {
  5736              if(settings.autofocus) {
  5737                var
  5738                  $inputs    = $module.find(':input:visible'),
  5739                  $autofocus = $inputs.filter('[autofocus]'),
  5740                  $input     = ($autofocus.length > 0)
  5741                    ? $autofocus
  5742                    : $inputs
  5743                ;
  5744                $input.first().focus();
  5745              }
  5746            },
  5747            clickaway: function() {
  5748              if(settings.closable) {
  5749                $dimmer
  5750                  .on('click' + elementNamespace, module.event.click)
  5751                ;
  5752              }
  5753            },
  5754            screenHeight: function() {
  5755              if( module.can.fit() ) {
  5756                $body.css('height', '');
  5757              }
  5758              else {
  5759                module.debug('Modal is taller than page content, resizing page height');
  5760                $body
  5761                  .css('height', module.cache.height + (settings.padding / 2) )
  5762                ;
  5763              }
  5764            },
  5765            active: function() {
  5766              $module.addClass(className.active);
  5767            },
  5768            scrolling: function() {
  5769              $dimmable.addClass(className.scrolling);
  5770              $module.addClass(className.scrolling);
  5771            },
  5772            type: function() {
  5773              if(module.can.fit()) {
  5774                module.verbose('Modal fits on screen');
  5775                if(!module.othersActive) {
  5776                  module.remove.scrolling();
  5777                }
  5778              }
  5779              else {
  5780                module.verbose('Modal cannot fit on screen setting to scrolling');
  5781                module.set.scrolling();
  5782              }
  5783            },
  5784            position: function() {
  5785              module.verbose('Centering modal on page', module.cache);
  5786              if(module.can.fit()) {
  5787                $module
  5788                  .css({
  5789                    top: '',
  5790                    marginTop: -(module.cache.height / 2)
  5791                  })
  5792                ;
  5793              }
  5794              else {
  5795                $module
  5796                  .css({
  5797                    marginTop : '',
  5798                    top       : $document.scrollTop()
  5799                  })
  5800                ;
  5801              }
  5802            }
  5803          },
  5804  
  5805          setting: function(name, value) {
  5806            module.debug('Changing setting', name, value);
  5807            if( $.isPlainObject(name) ) {
  5808              $.extend(true, settings, name);
  5809            }
  5810            else if(value !== undefined) {
  5811              settings[name] = value;
  5812            }
  5813            else {
  5814              return settings[name];
  5815            }
  5816          },
  5817          internal: function(name, value) {
  5818            if( $.isPlainObject(name) ) {
  5819              $.extend(true, module, name);
  5820            }
  5821            else if(value !== undefined) {
  5822              module[name] = value;
  5823            }
  5824            else {
  5825              return module[name];
  5826            }
  5827          },
  5828          debug: function() {
  5829            if(settings.debug) {
  5830              if(settings.performance) {
  5831                module.performance.log(arguments);
  5832              }
  5833              else {
  5834                module.debug = Function.prototype.bind.call(console.info, console, settings.name + ':');
  5835                module.debug.apply(console, arguments);
  5836              }
  5837            }
  5838          },
  5839          verbose: function() {
  5840            if(settings.verbose && settings.debug) {
  5841              if(settings.performance) {
  5842                module.performance.log(arguments);
  5843              }
  5844              else {
  5845                module.verbose = Function.prototype.bind.call(console.info, console, settings.name + ':');
  5846                module.verbose.apply(console, arguments);
  5847              }
  5848            }
  5849          },
  5850          error: function() {
  5851            module.error = Function.prototype.bind.call(console.error, console, settings.name + ':');
  5852            module.error.apply(console, arguments);
  5853          },
  5854          performance: {
  5855            log: function(message) {
  5856              var
  5857                currentTime,
  5858                executionTime,
  5859                previousTime
  5860              ;
  5861              if(settings.performance) {
  5862                currentTime   = new Date().getTime();
  5863                previousTime  = time || currentTime;
  5864                executionTime = currentTime - previousTime;
  5865                time          = currentTime;
  5866                performance.push({
  5867                  'Name'           : message[0],
  5868                  'Arguments'      : [].slice.call(message, 1) || '',
  5869                  'Element'        : element,
  5870                  'Execution Time' : executionTime
  5871                });
  5872              }
  5873              clearTimeout(module.performance.timer);
  5874              module.performance.timer = setTimeout(module.performance.display, 100);
  5875            },
  5876            display: function() {
  5877              var
  5878                title = settings.name + ':',
  5879                totalTime = 0
  5880              ;
  5881              time = false;
  5882              clearTimeout(module.performance.timer);
  5883              $.each(performance, function(index, data) {
  5884                totalTime += data['Execution Time'];
  5885              });
  5886              title += ' ' + totalTime + 'ms';
  5887              if(moduleSelector) {
  5888                title += ' \'' + moduleSelector + '\'';
  5889              }
  5890              if( (console.group !== undefined || console.table !== undefined) && performance.length > 0) {
  5891                console.groupCollapsed(title);
  5892                if(console.table) {
  5893                  console.table(performance);
  5894                }
  5895                else {
  5896                  $.each(performance, function(index, data) {
  5897                    console.log(data['Name'] + ': ' + data['Execution Time']+'ms');
  5898                  });
  5899                }
  5900                console.groupEnd();
  5901              }
  5902              performance = [];
  5903            }
  5904          },
  5905          invoke: function(query, passedArguments, context) {
  5906            var
  5907              object = instance,
  5908              maxDepth,
  5909              found,
  5910              response
  5911            ;
  5912            passedArguments = passedArguments || queryArguments;
  5913            context         = element         || context;
  5914            if(typeof query == 'string' && object !== undefined) {
  5915              query    = query.split(/[\. ]/);
  5916              maxDepth = query.length - 1;
  5917              $.each(query, function(depth, value) {
  5918                var camelCaseValue = (depth != maxDepth)
  5919                  ? value + query[depth + 1].charAt(0).toUpperCase() + query[depth + 1].slice(1)
  5920                  : query
  5921                ;
  5922                if( $.isPlainObject( object[camelCaseValue] ) && (depth != maxDepth) ) {
  5923                  object = object[camelCaseValue];
  5924                }
  5925                else if( object[camelCaseValue] !== undefined ) {
  5926                  found = object[camelCaseValue];
  5927                  return false;
  5928                }
  5929                else if( $.isPlainObject( object[value] ) && (depth != maxDepth) ) {
  5930                  object = object[value];
  5931                }
  5932                else if( object[value] !== undefined ) {
  5933                  found = object[value];
  5934                  return false;
  5935                }
  5936                else {
  5937                  return false;
  5938                }
  5939              });
  5940            }
  5941            if ( $.isFunction( found ) ) {
  5942              response = found.apply(context, passedArguments);
  5943            }
  5944            else if(found !== undefined) {
  5945              response = found;
  5946            }
  5947            if($.isArray(returnedValue)) {
  5948              returnedValue.push(response);
  5949            }
  5950            else if(returnedValue !== undefined) {
  5951              returnedValue = [returnedValue, response];
  5952            }
  5953            else if(response !== undefined) {
  5954              returnedValue = response;
  5955            }
  5956            return found;
  5957          }
  5958        };
  5959  
  5960        if(methodInvoked) {
  5961          if(instance === undefined) {
  5962            module.initialize();
  5963          }
  5964          module.invoke(query);
  5965        }
  5966        else {
  5967          if(instance !== undefined) {
  5968            instance.invoke('destroy');
  5969          }
  5970          module.initialize();
  5971        }
  5972      })
  5973    ;
  5974  
  5975    return (returnedValue !== undefined)
  5976      ? returnedValue
  5977      : this
  5978    ;
  5979  };
  5980  
  5981  $.fn.modal.settings = {
  5982  
  5983    name           : 'Modal',
  5984    namespace      : 'modal',
  5985  
  5986    debug          : false,
  5987    verbose        : true,
  5988    performance    : true,
  5989  
  5990    allowMultiple  : false,
  5991    detachable     : true,
  5992    closable       : true,
  5993    autofocus      : true,
  5994  
  5995    dimmerSettings : {
  5996      closable : false,
  5997      useCSS   : true
  5998    },
  5999  
  6000    context        : 'body',
  6001  
  6002    queue          : false,
  6003    duration       : 500,
  6004    easing         : 'easeOutExpo',
  6005    offset         : 0,
  6006    transition     : 'scale',
  6007  
  6008    padding        : 50,
  6009  
  6010    onShow         : function(){},
  6011    onHide         : function(){},
  6012  
  6013    onVisible      : function(){},
  6014    onHidden       : function(){},
  6015  
  6016    onApprove      : function(){ return true; },
  6017    onDeny         : function(){ return true; },
  6018  
  6019    selector    : {
  6020      close    : '.close, .actions .button',
  6021      approve  : '.actions .positive, .actions .approve, .actions .ok',
  6022      deny     : '.actions .negative, .actions .deny, .actions .cancel',
  6023      modal    : '.ui.modal'
  6024    },
  6025    error : {
  6026      dimmer    : 'UI Dimmer, a required component is not included in this page',
  6027      method    : 'The method you called is not defined.',
  6028      notFound  : 'The element you specified could not be found'
  6029    },
  6030    className : {
  6031      active    : 'active',
  6032      animating : 'animating',
  6033      scrolling : 'scrolling'
  6034    }
  6035  };
  6036  
  6037  
  6038  })( jQuery, window , document );
  6039  
  6040  /*!
  6041   * # Semantic UI x.x - Nag
  6042   * http://github.com/semantic-org/semantic-ui/
  6043   *
  6044   *
  6045   * Copyright 2014 Contributors
  6046   * Released under the MIT license
  6047   * http://opensource.org/licenses/MIT
  6048   *
  6049   */
  6050  
  6051  ;(function ($, window, document, undefined) {
  6052  
  6053  "use strict";
  6054  
  6055  $.fn.nag = function(parameters) {
  6056    var
  6057      $allModules    = $(this),
  6058      moduleSelector = $allModules.selector || '',
  6059  
  6060      time           = new Date().getTime(),
  6061      performance    = [],
  6062  
  6063      query          = arguments[0],
  6064      methodInvoked  = (typeof query == 'string'),
  6065      queryArguments = [].slice.call(arguments, 1),
  6066      returnedValue
  6067    ;
  6068    $allModules
  6069      .each(function() {
  6070        var
  6071          settings          = ( $.isPlainObject(parameters) )
  6072            ? $.extend(true, {}, $.fn.nag.settings, parameters)
  6073            : $.extend({}, $.fn.nag.settings),
  6074  
  6075          className       = settings.className,
  6076          selector        = settings.selector,
  6077          error           = settings.error,
  6078          namespace       = settings.namespace,
  6079  
  6080          eventNamespace  = '.' + namespace,
  6081          moduleNamespace = namespace + '-module',
  6082  
  6083          $module         = $(this),
  6084  
  6085          $close          = $module.find(selector.close),
  6086          $context        = (settings.context)
  6087            ? $(settings.context)
  6088            : $('body'),
  6089  
  6090          element         = this,
  6091          instance        = $module.data(moduleNamespace),
  6092  
  6093          moduleOffset,
  6094          moduleHeight,
  6095  
  6096          contextWidth,
  6097          contextHeight,
  6098          contextOffset,
  6099  
  6100          yOffset,
  6101          yPosition,
  6102  
  6103          timer,
  6104          module,
  6105  
  6106          requestAnimationFrame = window.requestAnimationFrame
  6107            || window.mozRequestAnimationFrame
  6108            || window.webkitRequestAnimationFrame
  6109            || window.msRequestAnimationFrame
  6110            || function(callback) { setTimeout(callback, 0); }
  6111        ;
  6112        module = {
  6113  
  6114          initialize: function() {
  6115            module.verbose('Initializing element');
  6116  
  6117            $module
  6118              .data(moduleNamespace, module)
  6119            ;
  6120            $close
  6121              .on('click' + eventNamespace, module.dismiss)
  6122            ;
  6123  
  6124            if(settings.detachable && $module.parent()[0] !== $context[0]) {
  6125              $module
  6126                .detach()
  6127                .prependTo($context)
  6128              ;
  6129            }
  6130  
  6131            if(settings.displayTime > 0) {
  6132              setTimeout(module.hide, settings.displayTime);
  6133            }
  6134            module.show();
  6135          },
  6136  
  6137          destroy: function() {
  6138            module.verbose('Destroying instance');
  6139            $module
  6140              .removeData(moduleNamespace)
  6141              .off(eventNamespace)
  6142            ;
  6143          },
  6144  
  6145          show: function() {
  6146            if( module.should.show() && !$module.is(':visible') ) {
  6147              module.debug('Showing nag', settings.animation.show);
  6148              if(settings.animation.show == 'fade') {
  6149                $module
  6150                  .fadeIn(settings.duration, settings.easing)
  6151                ;
  6152              }
  6153              else {
  6154                $module
  6155                  .slideDown(settings.duration, settings.easing)
  6156                ;
  6157              }
  6158            }
  6159          },
  6160  
  6161          hide: function() {
  6162            module.debug('Showing nag', settings.animation.hide);
  6163            if(settings.animation.show == 'fade') {
  6164              $module
  6165                .fadeIn(settings.duration, settings.easing)
  6166              ;
  6167            }
  6168            else {
  6169              $module
  6170                .slideUp(settings.duration, settings.easing)
  6171              ;
  6172            }
  6173          },
  6174  
  6175          onHide: function() {
  6176            module.debug('Removing nag', settings.animation.hide);
  6177            $module.remove();
  6178            if (settings.onHide) {
  6179              settings.onHide();
  6180            }
  6181          },
  6182  
  6183          dismiss: function(event) {
  6184            if(settings.storageMethod) {
  6185              module.storage.set(settings.key, settings.value);
  6186            }
  6187            module.hide();
  6188            event.stopImmediatePropagation();
  6189            event.preventDefault();
  6190          },
  6191  
  6192          should: {
  6193            show: function() {
  6194              if(settings.persist) {
  6195                module.debug('Persistent nag is set, can show nag');
  6196                return true;
  6197              }
  6198              if( module.storage.get(settings.key) != settings.value.toString() ) {
  6199                module.debug('Stored value is not set, can show nag', module.storage.get(settings.key));
  6200                return true;
  6201              }
  6202              module.debug('Stored value is set, cannot show nag', module.storage.get(settings.key));
  6203              return false;
  6204            }
  6205          },
  6206  
  6207          get: {
  6208            storageOptions: function() {
  6209              var
  6210                options = {}
  6211              ;
  6212              if(settings.expires) {
  6213                options.expires = settings.expires;
  6214              }
  6215              if(settings.domain) {
  6216                options.domain = settings.domain;
  6217              }
  6218              if(settings.path) {
  6219                options.path = settings.path;
  6220              }
  6221              return options;
  6222            }
  6223          },
  6224  
  6225          clear: function() {
  6226            module.storage.remove(settings.key);
  6227          },
  6228  
  6229          storage: {
  6230            set: function(key, value) {
  6231              var
  6232                options = module.get.storageOptions()
  6233              ;
  6234              if(settings.storageMethod == 'localstorage' && window.localStorage !== undefined) {
  6235                window.localStorage.setItem(key, value);
  6236                module.debug('Value stored using local storage', key, value);
  6237              }
  6238              else if($.cookie !== undefined) {
  6239                $.cookie(key, value, options);
  6240                module.debug('Value stored using cookie', key, value, options);
  6241              }
  6242              else {
  6243                module.error(error.noCookieStorage);
  6244                return;
  6245              }
  6246            },
  6247            get: function(key, value) {
  6248              var
  6249                storedValue
  6250              ;
  6251              if(settings.storageMethod == 'localstorage' && window.localStorage !== undefined) {
  6252                storedValue = window.localStorage.getItem(key);
  6253              }
  6254              // get by cookie
  6255              else if($.cookie !== undefined) {
  6256                storedValue = $.cookie(key);
  6257              }
  6258              else {
  6259                module.error(error.noCookieStorage);
  6260              }
  6261              if(storedValue == 'undefined' || storedValue == 'null' || storedValue === undefined || storedValue === null) {
  6262                storedValue = undefined;
  6263              }
  6264              return storedValue;
  6265            },
  6266            remove: function(key) {
  6267              var
  6268                options = module.get.storageOptions()
  6269              ;
  6270              if(settings.storageMethod == 'local' && window.store !== undefined) {
  6271                window.localStorage.removeItem(key);
  6272              }
  6273              // store by cookie
  6274              else if($.cookie !== undefined) {
  6275                $.removeCookie(key, options);
  6276              }
  6277              else {
  6278                module.error(error.noStorage);
  6279              }
  6280            }
  6281          },
  6282  
  6283          setting: function(name, value) {
  6284            module.debug('Changing setting', name, value);
  6285            if( $.isPlainObject(name) ) {
  6286              $.extend(true, settings, name);
  6287            }
  6288            else if(value !== undefined) {
  6289              settings[name] = value;
  6290            }
  6291            else {
  6292              return settings[name];
  6293            }
  6294          },
  6295          internal: function(name, value) {
  6296            if( $.isPlainObject(name) ) {
  6297              $.extend(true, module, name);
  6298            }
  6299            else if(value !== undefined) {
  6300              module[name] = value;
  6301            }
  6302            else {
  6303              return module[name];
  6304            }
  6305          },
  6306          debug: function() {
  6307            if(settings.debug) {
  6308              if(settings.performance) {
  6309                module.performance.log(arguments);
  6310              }
  6311              else {
  6312                module.debug = Function.prototype.bind.call(console.info, console, settings.name + ':');
  6313                module.debug.apply(console, arguments);
  6314              }
  6315            }
  6316          },
  6317          verbose: function() {
  6318            if(settings.verbose && settings.debug) {
  6319              if(settings.performance) {
  6320                module.performance.log(arguments);
  6321              }
  6322              else {
  6323                module.verbose = Function.prototype.bind.call(console.info, console, settings.name + ':');
  6324                module.verbose.apply(console, arguments);
  6325              }
  6326            }
  6327          },
  6328          error: function() {
  6329            module.error = Function.prototype.bind.call(console.error, console, settings.name + ':');
  6330            module.error.apply(console, arguments);
  6331          },
  6332          performance: {
  6333            log: function(message) {
  6334              var
  6335                currentTime,
  6336                executionTime,
  6337                previousTime
  6338              ;
  6339              if(settings.performance) {
  6340                currentTime   = new Date().getTime();
  6341                previousTime  = time || currentTime;
  6342                executionTime = currentTime - previousTime;
  6343                time          = currentTime;
  6344                performance.push({
  6345                  'Name'           : message[0],
  6346                  'Arguments'      : [].slice.call(message, 1) || '',
  6347                  'Element'        : element,
  6348                  'Execution Time' : executionTime
  6349                });
  6350              }
  6351              clearTimeout(module.performance.timer);
  6352              module.performance.timer = setTimeout(module.performance.display, 100);
  6353            },
  6354            display: function() {
  6355              var
  6356                title = settings.name + ':',
  6357                totalTime = 0
  6358              ;
  6359              time = false;
  6360              clearTimeout(module.performance.timer);
  6361              $.each(performance, function(index, data) {
  6362                totalTime += data['Execution Time'];
  6363              });
  6364              title += ' ' + totalTime + 'ms';
  6365              if(moduleSelector) {
  6366                title += ' \'' + moduleSelector + '\'';
  6367              }
  6368              if( (console.group !== undefined || console.table !== undefined) && performance.length > 0) {
  6369                console.groupCollapsed(title);
  6370                if(console.table) {
  6371                  console.table(performance);
  6372                }
  6373                else {
  6374                  $.each(performance, function(index, data) {
  6375                    console.log(data['Name'] + ': ' + data['Execution Time']+'ms');
  6376                  });
  6377                }
  6378                console.groupEnd();
  6379              }
  6380              performance = [];
  6381            }
  6382          },
  6383          invoke: function(query, passedArguments, context) {
  6384            var
  6385              object = instance,
  6386              maxDepth,
  6387              found,
  6388              response
  6389            ;
  6390            passedArguments = passedArguments || queryArguments;
  6391            context         = element         || context;
  6392            if(typeof query == 'string' && object !== undefined) {
  6393              query    = query.split(/[\. ]/);
  6394              maxDepth = query.length - 1;
  6395              $.each(query, function(depth, value) {
  6396                var camelCaseValue = (depth != maxDepth)
  6397                  ? value + query[depth + 1].charAt(0).toUpperCase() + query[depth + 1].slice(1)
  6398                  : query
  6399                ;
  6400                if( $.isPlainObject( object[camelCaseValue] ) && (depth != maxDepth) ) {
  6401                  object = object[camelCaseValue];
  6402                }
  6403                else if( object[camelCaseValue] !== undefined ) {
  6404                  found = object[camelCaseValue];
  6405                  return false;
  6406                }
  6407                else if( $.isPlainObject( object[value] ) && (depth != maxDepth) ) {
  6408                  object = object[value];
  6409                }
  6410                else if( object[value] !== undefined ) {
  6411                  found = object[value];
  6412                  return false;
  6413                }
  6414                else {
  6415                  module.error(error.method, query);
  6416                  return false;
  6417                }
  6418              });
  6419            }
  6420            if ( $.isFunction( found ) ) {
  6421              response = found.apply(context, passedArguments);
  6422            }
  6423            else if(found !== undefined) {
  6424              response = found;
  6425            }
  6426            if($.isArray(returnedValue)) {
  6427              returnedValue.push(response);
  6428            }
  6429            else if(returnedValue !== undefined) {
  6430              returnedValue = [returnedValue, response];
  6431            }
  6432            else if(response !== undefined) {
  6433              returnedValue = response;
  6434            }
  6435            return found;
  6436          }
  6437        };
  6438  
  6439        if(methodInvoked) {
  6440          if(instance === undefined) {
  6441            module.initialize();
  6442          }
  6443          module.invoke(query);
  6444        }
  6445        else {
  6446          if(instance !== undefined) {
  6447            instance.invoke('destroy');
  6448          }
  6449          module.initialize();
  6450        }
  6451      })
  6452    ;
  6453  
  6454    return (returnedValue !== undefined)
  6455      ? returnedValue
  6456      : this
  6457    ;
  6458  };
  6459  
  6460  $.fn.nag.settings = {
  6461  
  6462    name        : 'Nag',
  6463  
  6464    debug       : false,
  6465    verbose     : true,
  6466    performance : true,
  6467  
  6468    namespace   : 'Nag',
  6469  
  6470    // allows cookie to be overriden
  6471    persist     : false,
  6472  
  6473    // set to zero to require manually dismissal, otherwise hides on its own
  6474    displayTime : 0,
  6475  
  6476    animation   : {
  6477      show : 'slide',
  6478      hide : 'slide'
  6479    },
  6480  
  6481    context       : false,
  6482    detachable    : false,
  6483  
  6484    expires       : 30,
  6485    domain        : false,
  6486    path          : '/',
  6487  
  6488    // type of storage to use
  6489    storageMethod : 'cookie',
  6490  
  6491    // value to store in dismissed localstorage/cookie
  6492    key           : 'nag',
  6493    value         : 'dismiss',
  6494  
  6495    error: {
  6496      noStorage : 'Neither $.cookie or store is defined. A storage solution is required for storing state',
  6497      method    : 'The method you called is not defined.'
  6498    },
  6499  
  6500    className     : {
  6501      bottom : 'bottom',
  6502      fixed  : 'fixed'
  6503    },
  6504  
  6505    selector      : {
  6506      close : '.close.icon'
  6507    },
  6508  
  6509    speed         : 500,
  6510    easing        : 'easeOutQuad',
  6511  
  6512    onHide: function() {}
  6513  
  6514  };
  6515  
  6516  })( jQuery, window , document );
  6517  
  6518  /*!
  6519   * # Semantic UI x.x - Popup
  6520   * http://github.com/semantic-org/semantic-ui/
  6521   *
  6522   *
  6523   * Copyright 2014 Contributors
  6524   * Released under the MIT license
  6525   * http://opensource.org/licenses/MIT
  6526   *
  6527   */
  6528  
  6529  ;(function ($, window, document, undefined) {
  6530  
  6531  "use strict";
  6532  
  6533  $.fn.popup = function(parameters) {
  6534    var
  6535      $allModules    = $(this),
  6536      $document      = $(document),
  6537  
  6538      moduleSelector = $allModules.selector || '',
  6539  
  6540      hasTouch       = ('ontouchstart' in document.documentElement),
  6541      time           = new Date().getTime(),
  6542      performance    = [],
  6543  
  6544      query          = arguments[0],
  6545      methodInvoked  = (typeof query == 'string'),
  6546      queryArguments = [].slice.call(arguments, 1),
  6547  
  6548      returnedValue
  6549    ;
  6550    $allModules
  6551      .each(function() {
  6552        var
  6553          settings        = ( $.isPlainObject(parameters) )
  6554            ? $.extend(true, {}, $.fn.popup.settings, parameters)
  6555            : $.extend({}, $.fn.popup.settings),
  6556  
  6557          selector           = settings.selector,
  6558          className          = settings.className,
  6559          error              = settings.error,
  6560          metadata           = settings.metadata,
  6561          namespace          = settings.namespace,
  6562  
  6563          eventNamespace     = '.' + settings.namespace,
  6564          moduleNamespace    = 'module-' + namespace,
  6565  
  6566          $module            = $(this),
  6567          $context           = $(settings.context),
  6568          $target            = (settings.target)
  6569            ? $(settings.target)
  6570            : $module,
  6571  
  6572          $window            = $(window),
  6573          $body              = $('body'),
  6574          $popup,
  6575          $offsetParent,
  6576  
  6577          searchDepth        = 0,
  6578          triedPositions     = false,
  6579  
  6580          element            = this,
  6581          instance           = $module.data(moduleNamespace),
  6582  
  6583          elementNamespace,
  6584          id,
  6585          module
  6586        ;
  6587  
  6588        module = {
  6589  
  6590          // binds events
  6591          initialize: function() {
  6592            module.debug('Initializing', $module);
  6593            module.createID();
  6594            module.bind.events();
  6595            if( !module.exists() && settings.preserve) {
  6596              module.create();
  6597            }
  6598            module.instantiate();
  6599          },
  6600  
  6601          instantiate: function() {
  6602            module.verbose('Storing instance', module);
  6603            instance = module;
  6604            $module
  6605              .data(moduleNamespace, instance)
  6606            ;
  6607          },
  6608  
  6609          refresh: function() {
  6610            if(settings.popup) {
  6611              $popup = $(settings.popup).eq(0);
  6612            }
  6613            else {
  6614              if(settings.inline) {
  6615                $popup = $target.next(selector.popup).eq(0);
  6616              }
  6617            }
  6618            if(settings.popup) {
  6619              $popup.addClass(className.loading);
  6620              $offsetParent = module.get.offsetParent();
  6621              $popup.removeClass(className.loading);
  6622              if(settings.movePopup && module.has.popup() && module.get.offsetParent($popup)[0] !== $offsetParent[0]) {
  6623                module.debug('Moving popup to the same offset parent as activating element');
  6624                $popup
  6625                  .detach()
  6626                  .appendTo($offsetParent)
  6627                ;
  6628              }
  6629            }
  6630            else {
  6631              $offsetParent = (settings.inline)
  6632                ? module.get.offsetParent($target)
  6633                : module.has.popup()
  6634                  ? module.get.offsetParent($popup)
  6635                  : $body
  6636              ;
  6637            }
  6638            if( $offsetParent.is('html') ) {
  6639              module.debug('Setting page as offset parent');
  6640              $offsetParent = $body;
  6641            }
  6642          },
  6643  
  6644          reposition: function() {
  6645            module.refresh();
  6646            module.set.position();
  6647          },
  6648  
  6649          destroy: function() {
  6650            module.debug('Destroying previous module');
  6651            // remove element only if was created dynamically
  6652            if($popup && !settings.preserve) {
  6653              module.removePopup();
  6654            }
  6655            // clear all timeouts
  6656            clearTimeout(module.hideTimer);
  6657            clearTimeout(module.showTimer);
  6658            // remove events
  6659            $window.off(elementNamespace);
  6660            $module
  6661              .off(eventNamespace)
  6662              .removeData(moduleNamespace)
  6663            ;
  6664          },
  6665  
  6666          event: {
  6667            start:  function(event) {
  6668              var
  6669                delay = ($.isPlainObject(settings.delay))
  6670                  ? settings.delay.show
  6671                  : settings.delay
  6672              ;
  6673              clearTimeout(module.hideTimer);
  6674              module.showTimer = setTimeout(function() {
  6675                if(module.is.hidden() && !( module.is.active() && module.is.dropdown()) ) {
  6676                  module.show();
  6677                }
  6678              }, delay);
  6679            },
  6680            end:  function() {
  6681              var
  6682                delay = ($.isPlainObject(settings.delay))
  6683                  ? settings.delay.hide
  6684                  : settings.delay
  6685              ;
  6686              clearTimeout(module.showTimer);
  6687              module.hideTimer = setTimeout(function() {
  6688                if(module.is.visible() ) {
  6689                  module.hide();
  6690                }
  6691              }, delay);
  6692            },
  6693            resize: function() {
  6694              if( module.is.visible() ) {
  6695                module.set.position();
  6696              }
  6697            }
  6698          },
  6699  
  6700          // generates popup html from metadata
  6701          create: function() {
  6702            var
  6703              html      = $module.data(metadata.html)      || settings.html,
  6704              variation = $module.data(metadata.variation) || settings.variation,
  6705              title     = $module.data(metadata.title)     || settings.title,
  6706              content   = $module.data(metadata.content)   || $module.attr('title') || settings.content
  6707            ;
  6708            if(html || content || title) {
  6709              module.debug('Creating pop-up html');
  6710              if(!html) {
  6711                html = settings.templates.popup({
  6712                  title   : title,
  6713                  content : content
  6714                });
  6715              }
  6716              $popup = $('<div/>')
  6717                .addClass(className.popup)
  6718                .addClass(variation)
  6719                .data(metadata.activator, $module)
  6720                .html(html)
  6721              ;
  6722              if(variation) {
  6723                $popup
  6724                  .addClass(variation)
  6725                ;
  6726              }
  6727              if(settings.inline) {
  6728                module.verbose('Inserting popup element inline', $popup);
  6729                $popup
  6730                  .insertAfter($module)
  6731                ;
  6732              }
  6733              else {
  6734                module.verbose('Appending popup element to body', $popup);
  6735                $popup
  6736                  .appendTo( $context )
  6737                ;
  6738              }
  6739              module.refresh();
  6740              if(settings.hoverable) {
  6741                module.bind.popup();
  6742              }
  6743              settings.onCreate.call($popup, element);
  6744            }
  6745            else if($target.next(selector.popup).length !== 0) {
  6746              module.verbose('Pre-existing popup found');
  6747              settings.inline = true;
  6748              settings.popup  = $target.next(selector.popup).data(metadata.activator, $module);
  6749              module.refresh();
  6750              if(settings.hoverable) {
  6751                module.bind.popup();
  6752              }
  6753            }
  6754            else if(settings.popup) {
  6755              settings.popup.data(metadata.activator, $module);
  6756              module.verbose('Used popup specified in settings');
  6757              module.refresh();
  6758              if(settings.hoverable) {
  6759                module.bind.popup();
  6760              }
  6761            }
  6762            else {
  6763              module.debug('No content specified skipping display', element);
  6764            }
  6765          },
  6766  
  6767          createID: function() {
  6768            id = (Math.random().toString(16) + '000000000').substr(2,8);
  6769            elementNamespace = '.' + id;
  6770            module.verbose('Creating unique id for element', id);
  6771          },
  6772  
  6773          // determines popup state
  6774          toggle: function() {
  6775            module.debug('Toggling pop-up');
  6776            if( module.is.hidden() ) {
  6777              module.debug('Popup is hidden, showing pop-up');
  6778              module.unbind.close();
  6779              module.show();
  6780            }
  6781            else {
  6782              module.debug('Popup is visible, hiding pop-up');
  6783              module.hide();
  6784            }
  6785          },
  6786  
  6787          show: function(callback) {
  6788            callback = $.isFunction(callback) ? callback : function(){};
  6789            module.debug('Showing pop-up', settings.transition);
  6790            if( !module.exists() ) {
  6791              module.create();
  6792            }
  6793            else if(!settings.preserve && !settings.popup) {
  6794              module.refresh();
  6795            }
  6796            if( $popup && module.set.position() ) {
  6797              module.save.conditions();
  6798              if(settings.exclusive) {
  6799                module.hideAll();
  6800              }
  6801              module.animate.show(callback);
  6802            }
  6803          },
  6804  
  6805  
  6806          hide: function(callback) {
  6807            callback = $.isFunction(callback) ? callback : function(){};
  6808            module.remove.visible();
  6809            module.unbind.close();
  6810            if( module.is.visible() ) {
  6811              module.restore.conditions();
  6812              module.animate.hide(callback);
  6813            }
  6814          },
  6815  
  6816          hideAll: function() {
  6817            $(selector.popup)
  6818              .filter('.' + className.visible)
  6819              .each(function() {
  6820                $(this)
  6821                  .data(metadata.activator)
  6822                  .popup('hide')
  6823                ;
  6824              })
  6825            ;
  6826          },
  6827  
  6828          hideGracefully: function(event) {
  6829            // don't close on clicks inside popup
  6830            if(event && $(event.target).closest(selector.popup).length === 0) {
  6831              module.debug('Click occurred outside popup hiding popup');
  6832              module.hide();
  6833            }
  6834            else {
  6835              module.debug('Click was inside popup, keeping popup open');
  6836            }
  6837          },
  6838  
  6839          exists: function() {
  6840            if(!$popup) {
  6841              return false;
  6842            }
  6843            if(settings.inline || settings.popup) {
  6844              return ( module.has.popup() );
  6845            }
  6846            else {
  6847              return ( $popup.closest($context).length >= 1 )
  6848                ? true
  6849                : false
  6850              ;
  6851            }
  6852          },
  6853  
  6854          removePopup: function() {
  6855            module.debug('Removing popup', $popup);
  6856            if( module.has.popup() && !settings.popup) {
  6857              $popup.remove();
  6858              $popup = undefined;
  6859            }
  6860            settings.onRemove.call($popup, element);
  6861          },
  6862  
  6863          save: {
  6864            conditions: function() {
  6865              module.cache = {
  6866                title: $module.attr('title')
  6867              };
  6868              if (module.cache.title) {
  6869                $module.removeAttr('title');
  6870              }
  6871              module.verbose('Saving original attributes', module.cache.title);
  6872            }
  6873          },
  6874          restore: {
  6875            conditions: function() {
  6876              if(module.cache && module.cache.title) {
  6877                $module.attr('title', module.cache.title);
  6878                module.verbose('Restoring original attributes', module.cache.title);
  6879              }
  6880              return true;
  6881            }
  6882          },
  6883          animate: {
  6884            show: function(callback) {
  6885              callback = $.isFunction(callback) ? callback : function(){};
  6886              if(settings.transition && $.fn.transition !== undefined && $module.transition('is supported')) {
  6887                module.set.visible();
  6888                $popup
  6889                  .transition({
  6890                    animation  : settings.transition + ' in',
  6891                    queue      : false,
  6892                    debug      : settings.debug,
  6893                    verbose    : settings.verbose,
  6894                    duration   : settings.duration,
  6895                    onComplete : function() {
  6896                      module.bind.close();
  6897                      callback.call($popup, element);
  6898                      settings.onVisible.call($popup, element);
  6899                    }
  6900                  })
  6901                ;
  6902              }
  6903              else {
  6904                module.set.visible();
  6905                $popup
  6906                  .stop()
  6907                  .fadeIn(settings.duration, settings.easing, function() {
  6908                    module.bind.close();
  6909                    callback.call($popup, element);
  6910                    settings.onVisible.call($popup, element);
  6911                  })
  6912                ;
  6913              }
  6914              settings.onShow.call($popup, element);
  6915            },
  6916            hide: function(callback) {
  6917              callback = $.isFunction(callback) ? callback : function(){};
  6918              module.debug('Hiding pop-up');
  6919              if(settings.transition && $.fn.transition !== undefined && $module.transition('is supported')) {
  6920                $popup
  6921                  .transition({
  6922                    animation  : settings.transition + ' out',
  6923                    queue      : false,
  6924                    duration   : settings.duration,
  6925                    debug      : settings.debug,
  6926                    verbose    : settings.verbose,
  6927                    onComplete : function() {
  6928                      module.reset();
  6929                      callback.call($popup, element);
  6930                      settings.onHidden.call($popup, element);
  6931                    }
  6932                  })
  6933                ;
  6934              }
  6935              else {
  6936                $popup
  6937                  .stop()
  6938                  .fadeOut(settings.duration, settings.easing, function() {
  6939                    module.reset();
  6940                    callback.call($popup, element);
  6941                    settings.onHidden.call($popup, element);
  6942                  })
  6943                ;
  6944              }
  6945              settings.onHide.call($popup, element);
  6946            }
  6947          },
  6948  
  6949          get: {
  6950            id: function() {
  6951              return id;
  6952            },
  6953            startEvent: function() {
  6954              if(settings.on == 'hover') {
  6955                return (hasTouch)
  6956                  ? 'touchstart mouseenter'
  6957                  : 'mouseenter'
  6958                ;
  6959              }
  6960              else if(settings.on == 'focus') {
  6961                return 'focus';
  6962              }
  6963              return false;
  6964            },
  6965            scrollEvent: function() {
  6966              return (hasTouch)
  6967                ? 'touchmove scroll'
  6968                : 'scroll'
  6969              ;
  6970            },
  6971            endEvent: function() {
  6972              if(settings.on == 'hover') {
  6973                return 'mouseleave';
  6974              }
  6975              else if(settings.on == 'focus') {
  6976                return 'blur';
  6977              }
  6978              return false;
  6979            },
  6980            offsetParent: function($target) {
  6981              var
  6982                element = ($target !== undefined)
  6983                  ? $target[0]
  6984                  : $module[0],
  6985                parentNode = element.parentNode,
  6986                $node    = $(parentNode)
  6987              ;
  6988              if(parentNode) {
  6989                var
  6990                  is2D     = ($node.css('transform') === 'none'),
  6991                  isStatic = ($node.css('position') === 'static'),
  6992                  isHTML   = $node.is('html')
  6993                ;
  6994                while(parentNode && !isHTML && isStatic && is2D) {
  6995                  parentNode = parentNode.parentNode;
  6996                  $node    = $(parentNode);
  6997                  is2D     = ($node.css('transform') === 'none');
  6998                  isStatic = ($node.css('position') === 'static');
  6999                  isHTML   = $node.is('html');
  7000                }
  7001              }
  7002              return ($node && $node.length > 0)
  7003                ? $node
  7004                : $()
  7005              ;
  7006            },
  7007            offstagePosition: function(position) {
  7008              var
  7009                boundary  = {
  7010                  top    : $(window).scrollTop(),
  7011                  bottom : $(window).scrollTop() + $(window).height(),
  7012                  left   : 0,
  7013                  right  : $(window).width()
  7014                },
  7015                popup     = {
  7016                  width  : $popup.width(),
  7017                  height : $popup.height(),
  7018                  offset : $popup.offset()
  7019                },
  7020                offstage  = {},
  7021                offstagePositions = []
  7022              ;
  7023              position = position || false;
  7024              if(popup.offset && position) {
  7025                module.verbose('Checking if outside viewable area', popup.offset);
  7026                offstage = {
  7027                  top    : (popup.offset.top < boundary.top),
  7028                  bottom : (popup.offset.top + popup.height > boundary.bottom),
  7029                  right  : (popup.offset.left + popup.width > boundary.right),
  7030                  left   : (popup.offset.left < boundary.left)
  7031                };
  7032              }
  7033              // return only boundaries that have been surpassed
  7034              $.each(offstage, function(direction, isOffstage) {
  7035                if(isOffstage) {
  7036                  offstagePositions.push(direction);
  7037                }
  7038              });
  7039              return (offstagePositions.length > 0)
  7040                ? offstagePositions.join(' ')
  7041                : false
  7042              ;
  7043            },
  7044            positions: function() {
  7045              return {
  7046                'top left'      : false,
  7047                'top center'    : false,
  7048                'top right'     : false,
  7049                'bottom left'   : false,
  7050                'bottom center' : false,
  7051                'bottom right'  : false,
  7052                'left center'   : false,
  7053                'right center'  : false
  7054              };
  7055            },
  7056            nextPosition: function(position) {
  7057              var
  7058                positions          = position.split(' '),
  7059                verticalPosition   = positions[0],
  7060                horizontalPosition = positions[1],
  7061                opposite = {
  7062                  top    : 'bottom',
  7063                  bottom : 'top',
  7064                  left   : 'right',
  7065                  right  : 'left'
  7066                },
  7067                adjacent = {
  7068                  left   : 'center',
  7069                  center : 'right',
  7070                  right  : 'left'
  7071                },
  7072                backup = {
  7073                  'top left'      : 'top center',
  7074                  'top center'    : 'top right',
  7075                  'top right'     : 'right center',
  7076                  'right center'  : 'bottom right',
  7077                  'bottom right'  : 'bottom center',
  7078                  'bottom center' : 'bottom left',
  7079                  'bottom left'   : 'left center',
  7080                  'left center'   : 'top left'
  7081                },
  7082                adjacentsAvailable = (verticalPosition == 'top' || verticalPosition == 'bottom'),
  7083                oppositeTried = false,
  7084                adjacentTried = false,
  7085                nextPosition  = false
  7086              ;
  7087              if(!triedPositions) {
  7088                module.verbose('All available positions available');
  7089                triedPositions = module.get.positions();
  7090              }
  7091  
  7092              module.debug('Recording last position tried', position);
  7093              triedPositions[position] = true;
  7094  
  7095              if(settings.prefer === 'opposite') {
  7096                nextPosition  = [opposite[verticalPosition], horizontalPosition];
  7097                nextPosition  = nextPosition.join(' ');
  7098                oppositeTried = (triedPositions[nextPosition] === true);
  7099                module.debug('Trying opposite strategy', nextPosition);
  7100              }
  7101              if((settings.prefer === 'adjacent') && adjacentsAvailable ) {
  7102                nextPosition  = [verticalPosition, adjacent[horizontalPosition]];
  7103                nextPosition  = nextPosition.join(' ');
  7104                adjacentTried = (triedPositions[nextPosition] === true);
  7105                module.debug('Trying adjacent strategy', nextPosition);
  7106              }
  7107              if(adjacentTried || oppositeTried) {
  7108                module.debug('Using backup position', nextPosition);
  7109                nextPosition = backup[position];
  7110              }
  7111              return nextPosition;
  7112            }
  7113          },
  7114  
  7115          set: {
  7116            position: function(position, arrowOffset) {
  7117              var
  7118                windowWidth   = $(window).width(),
  7119                windowHeight  = $(window).height(),
  7120  
  7121                targetWidth   = $target.outerWidth(),
  7122                targetHeight  = $target.outerHeight(),
  7123  
  7124                popupWidth    = $popup.outerWidth(),
  7125                popupHeight   = $popup.outerHeight(),
  7126  
  7127                parentWidth   = $offsetParent.outerWidth(),
  7128                parentHeight  = $offsetParent.outerHeight(),
  7129  
  7130                distanceAway  = settings.distanceAway,
  7131  
  7132                targetElement = $target[0],
  7133  
  7134                marginTop     = (settings.inline)
  7135                  ? parseInt( window.getComputedStyle(targetElement).getPropertyValue('margin-top'), 10)
  7136                  : 0,
  7137                marginLeft    = (settings.inline)
  7138                  ? parseInt( window.getComputedStyle(targetElement).getPropertyValue(module.is.rtl() ? 'margin-right' : 'margin-left'), 10)
  7139                  : 0,
  7140  
  7141                target        = (settings.inline || settings.popup)
  7142                  ? $target.position()
  7143                  : $target.offset(),
  7144  
  7145                computedPosition,
  7146                positioning,
  7147                offstagePosition
  7148              ;
  7149              position    = position    || $module.data(metadata.position)    || settings.position;
  7150              arrowOffset = arrowOffset || $module.data(metadata.offset)      || settings.offset;
  7151  
  7152              if(searchDepth == settings.maxSearchDepth && settings.lastResort) {
  7153                module.debug('Using last resort position to display', settings.lastResort);
  7154                position = settings.lastResort;
  7155              }
  7156  
  7157              if(settings.inline) {
  7158                module.debug('Adding targets margin to calculation');
  7159                if(position == 'left center' || position == 'right center') {
  7160                  arrowOffset  += marginTop;
  7161                  distanceAway += -marginLeft;
  7162                }
  7163                else if (position == 'top left' || position == 'top center' || position == 'top right') {
  7164                  arrowOffset  += marginLeft;
  7165                  distanceAway -= marginTop;
  7166                }
  7167                else {
  7168                  arrowOffset  += marginLeft;
  7169                  distanceAway += marginTop;
  7170                }
  7171              }
  7172              module.debug('Calculating popup positioning', position);
  7173  
  7174              computedPosition = position;
  7175              if (module.is.rtl()) {
  7176                computedPosition = computedPosition.replace(/left|right/g, function (match) {
  7177                  return (match == 'left')
  7178                    ? 'right'
  7179                    : 'left'
  7180                  ;
  7181                });
  7182                module.debug('RTL: Popup positioning updated', computedPosition);
  7183              }
  7184              switch (computedPosition) {
  7185                case 'top left':
  7186                  positioning = {
  7187                    top    : 'auto',
  7188                    bottom : parentHeight - target.top + distanceAway,
  7189                    left   : target.left + arrowOffset,
  7190                    right  : 'auto'
  7191                  };
  7192                break;
  7193                case 'top center':
  7194                  positioning = {
  7195                    bottom : parentHeight - target.top + distanceAway,
  7196                    left   : target.left + (targetWidth / 2) - (popupWidth / 2) + arrowOffset,
  7197                    top    : 'auto',
  7198                    right  : 'auto'
  7199                  };
  7200                break;
  7201                case 'top right':
  7202                  positioning = {
  7203                    bottom :  parentHeight - target.top + distanceAway,
  7204                    right  :  parentWidth - target.left - targetWidth - arrowOffset,
  7205                    top    : 'auto',
  7206                    left   : 'auto'
  7207                  };
  7208                break;
  7209                case 'left center':
  7210                  positioning = {
  7211                    top    : target.top + (targetHeight / 2) - (popupHeight / 2) + arrowOffset,
  7212                    right  : parentWidth - target.left + distanceAway,
  7213                    left   : 'auto',
  7214                    bottom : 'auto'
  7215                  };
  7216                break;
  7217                case 'right center':
  7218                  positioning = {
  7219                    top    : target.top + (targetHeight / 2) - (popupHeight / 2) + arrowOffset,
  7220                    left   : target.left + targetWidth + distanceAway,
  7221                    bottom : 'auto',
  7222                    right  : 'auto'
  7223                  };
  7224                break;
  7225                case 'bottom left':
  7226                  positioning = {
  7227                    top    : target.top + targetHeight + distanceAway,
  7228                    left   : target.left + arrowOffset,
  7229                    bottom : 'auto',
  7230                    right  : 'auto'
  7231                  };
  7232                break;
  7233                case 'bottom center':
  7234                  positioning = {
  7235                    top    : target.top + targetHeight + distanceAway,
  7236                    left   : target.left + (targetWidth / 2) - (popupWidth / 2) + arrowOffset,
  7237                    bottom : 'auto',
  7238                    right  : 'auto'
  7239                  };
  7240                break;
  7241                case 'bottom right':
  7242                  positioning = {
  7243                    top    : target.top + targetHeight + distanceAway,
  7244                    right  : parentWidth - target.left  - targetWidth - arrowOffset,
  7245                    left   : 'auto',
  7246                    bottom : 'auto'
  7247                  };
  7248                break;
  7249              }
  7250              if(positioning === undefined) {
  7251                module.error(error.invalidPosition, position);
  7252              }
  7253  
  7254              module.debug('Calculated popup positioning values', positioning);
  7255  
  7256              // tentatively place on stage
  7257              $popup
  7258                .css(positioning)
  7259                .removeClass(className.position)
  7260                .addClass(position)
  7261                .addClass(className.loading)
  7262              ;
  7263              // check if is offstage
  7264              offstagePosition = module.get.offstagePosition(position);
  7265  
  7266              // recursively find new positioning
  7267              if(offstagePosition) {
  7268                module.debug('Popup cant fit into viewport', offstagePosition);
  7269                if(searchDepth < settings.maxSearchDepth) {
  7270                  searchDepth++;
  7271                  position = module.get.nextPosition(position);
  7272                  module.debug('Trying new position', position);
  7273                  return ($popup)
  7274                    ? module.set.position(position)
  7275                    : false
  7276                  ;
  7277                }
  7278                else if(!settings.lastResort) {
  7279                  module.debug('Popup could not find a position in view', $popup);
  7280                  module.error(error.cannotPlace, element);
  7281                  module.remove.attempts();
  7282                  module.remove.loading();
  7283                  module.reset();
  7284                  return false;
  7285                }
  7286              }
  7287  
  7288              module.debug('Position is on stage', position);
  7289              module.remove.attempts();
  7290              module.set.fluidWidth();
  7291              module.remove.loading();
  7292              return true;
  7293            },
  7294  
  7295            fluidWidth: function() {
  7296              if( settings.setFluidWidth && $popup.hasClass(className.fluid) ) {
  7297                $popup.css('width', $offsetParent.width());
  7298              }
  7299            },
  7300  
  7301            visible: function() {
  7302              $module.addClass(className.visible);
  7303            }
  7304          },
  7305  
  7306          remove: {
  7307            loading: function() {
  7308              $popup.removeClass(className.loading);
  7309            },
  7310            visible: function() {
  7311              $module.removeClass(className.visible);
  7312            },
  7313            attempts: function() {
  7314              module.verbose('Resetting all searched positions');
  7315              searchDepth    = 0;
  7316              triedPositions = false;
  7317            }
  7318          },
  7319  
  7320          bind: {
  7321            events: function() {
  7322              module.debug('Binding popup events to module');
  7323              if(settings.on == 'click') {
  7324                $module
  7325                  .on('click' + eventNamespace, module.toggle)
  7326                ;
  7327              }
  7328              else if( module.get.startEvent() ) {
  7329                $module
  7330                  .on(module.get.startEvent() + eventNamespace, module.event.start)
  7331                  .on(module.get.endEvent() + eventNamespace, module.event.end)
  7332                ;
  7333              }
  7334              if(settings.target) {
  7335                module.debug('Target set to element', $target);
  7336              }
  7337              $window.on('resize' + elementNamespace, module.event.resize);
  7338            },
  7339            popup: function() {
  7340              module.verbose('Allowing hover events on popup to prevent closing');
  7341              if( $popup && module.has.popup() ) {
  7342                $popup
  7343                  .on('mouseenter' + eventNamespace, module.event.start)
  7344                  .on('mouseleave' + eventNamespace, module.event.end)
  7345                ;
  7346              }
  7347            },
  7348            close:function() {
  7349              if(settings.hideOnScroll === true || settings.hideOnScroll == 'auto' && settings.on != 'click') {
  7350                $document
  7351                  .one(module.get.scrollEvent() + elementNamespace, module.hideGracefully)
  7352                ;
  7353                $context
  7354                  .one(module.get.scrollEvent() + elementNamespace, module.hideGracefully)
  7355                ;
  7356              }
  7357              if(settings.on == 'click' && settings.closable) {
  7358                module.verbose('Binding popup close event to document');
  7359                $document
  7360                  .on('click' + elementNamespace, function(event) {
  7361                    module.verbose('Pop-up clickaway intent detected');
  7362                    module.hideGracefully.call(element, event);
  7363                  })
  7364                ;
  7365              }
  7366            }
  7367          },
  7368  
  7369          unbind: {
  7370            close: function() {
  7371              if(settings.hideOnScroll === true || settings.hideOnScroll == 'auto' && settings.on != 'click') {
  7372                $document
  7373                  .off('scroll' + elementNamespace, module.hide)
  7374                ;
  7375                $context
  7376                  .off('scroll' + elementNamespace, module.hide)
  7377                ;
  7378              }
  7379              if(settings.on == 'click' && settings.closable) {
  7380                module.verbose('Removing close event from document');
  7381                $document
  7382                  .off('click' + elementNamespace)
  7383                ;
  7384              }
  7385            }
  7386          },
  7387  
  7388          has: {
  7389            popup: function() {
  7390              return ($popup && $popup.length > 0);
  7391            }
  7392          },
  7393  
  7394          is: {
  7395            active: function() {
  7396              return $module.hasClass(className.active);
  7397            },
  7398            animating: function() {
  7399              return ( $popup && $popup.is(':animated') || $popup.hasClass(className.animating) );
  7400            },
  7401            visible: function() {
  7402              return $popup && $popup.is(':visible');
  7403            },
  7404            dropdown: function() {
  7405              return $module.hasClass(className.dropdown);
  7406            },
  7407            hidden: function() {
  7408              return !module.is.visible();
  7409            },
  7410            rtl: function () {
  7411              return $module.css('direction') == 'rtl';
  7412            }
  7413          },
  7414  
  7415          reset: function() {
  7416            module.remove.visible();
  7417            if(settings.preserve) {
  7418              if($.fn.transition !== undefined) {
  7419                $popup
  7420                  .transition('remove transition')
  7421                ;
  7422              }
  7423            }
  7424            else {
  7425              module.removePopup();
  7426            }
  7427          },
  7428  
  7429          setting: function(name, value) {
  7430            if( $.isPlainObject(name) ) {
  7431              $.extend(true, settings, name);
  7432            }
  7433            else if(value !== undefined) {
  7434              settings[name] = value;
  7435            }
  7436            else {
  7437              return settings[name];
  7438            }
  7439          },
  7440          internal: function(name, value) {
  7441            if( $.isPlainObject(name) ) {
  7442              $.extend(true, module, name);
  7443            }
  7444            else if(value !== undefined) {
  7445              module[name] = value;
  7446            }
  7447            else {
  7448              return module[name];
  7449            }
  7450          },
  7451          debug: function() {
  7452            if(settings.debug) {
  7453              if(settings.performance) {
  7454                module.performance.log(arguments);
  7455              }
  7456              else {
  7457                module.debug = Function.prototype.bind.call(console.info, console, settings.name + ':');
  7458                module.debug.apply(console, arguments);
  7459              }
  7460            }
  7461          },
  7462          verbose: function() {
  7463            if(settings.verbose && settings.debug) {
  7464              if(settings.performance) {
  7465                module.performance.log(arguments);
  7466              }
  7467              else {
  7468                module.verbose = Function.prototype.bind.call(console.info, console, settings.name + ':');
  7469                module.verbose.apply(console, arguments);
  7470              }
  7471            }
  7472          },
  7473          error: function() {
  7474            module.error = Function.prototype.bind.call(console.error, console, settings.name + ':');
  7475            module.error.apply(console, arguments);
  7476          },
  7477          performance: {
  7478            log: function(message) {
  7479              var
  7480                currentTime,
  7481                executionTime,
  7482                previousTime
  7483              ;
  7484              if(settings.performance) {
  7485                currentTime   = new Date().getTime();
  7486                previousTime  = time || currentTime;
  7487                executionTime = currentTime - previousTime;
  7488                time          = currentTime;
  7489                performance.push({
  7490                  'Name'           : message[0],
  7491                  'Arguments'      : [].slice.call(message, 1) || '',
  7492                  'Element'        : element,
  7493                  'Execution Time' : executionTime
  7494                });
  7495              }
  7496              clearTimeout(module.performance.timer);
  7497              module.performance.timer = setTimeout(module.performance.display, 100);
  7498            },
  7499            display: function() {
  7500              var
  7501                title = settings.name + ':',
  7502                totalTime = 0
  7503              ;
  7504              time = false;
  7505              clearTimeout(module.performance.timer);
  7506              $.each(performance, function(index, data) {
  7507                totalTime += data['Execution Time'];
  7508              });
  7509              title += ' ' + totalTime + 'ms';
  7510              if(moduleSelector) {
  7511                title += ' \'' + moduleSelector + '\'';
  7512              }
  7513              if( (console.group !== undefined || console.table !== undefined) && performance.length > 0) {
  7514                console.groupCollapsed(title);
  7515                if(console.table) {
  7516                  console.table(performance);
  7517                }
  7518                else {
  7519                  $.each(performance, function(index, data) {
  7520                    console.log(data['Name'] + ': ' + data['Execution Time']+'ms');
  7521                  });
  7522                }
  7523                console.groupEnd();
  7524              }
  7525              performance = [];
  7526            }
  7527          },
  7528          invoke: function(query, passedArguments, context) {
  7529            var
  7530              object = instance,
  7531              maxDepth,
  7532              found,
  7533              response
  7534            ;
  7535            passedArguments = passedArguments || queryArguments;
  7536            context         = element         || context;
  7537            if(typeof query == 'string' && object !== undefined) {
  7538              query    = query.split(/[\. ]/);
  7539              maxDepth = query.length - 1;
  7540              $.each(query, function(depth, value) {
  7541                var camelCaseValue = (depth != maxDepth)
  7542                  ? value + query[depth + 1].charAt(0).toUpperCase() + query[depth + 1].slice(1)
  7543                  : query
  7544                ;
  7545                if( $.isPlainObject( object[camelCaseValue] ) && (depth != maxDepth) ) {
  7546                  object = object[camelCaseValue];
  7547                }
  7548                else if( object[camelCaseValue] !== undefined ) {
  7549                  found = object[camelCaseValue];
  7550                  return false;
  7551                }
  7552                else if( $.isPlainObject( object[value] ) && (depth != maxDepth) ) {
  7553                  object = object[value];
  7554                }
  7555                else if( object[value] !== undefined ) {
  7556                  found = object[value];
  7557                  return false;
  7558                }
  7559                else {
  7560                  return false;
  7561                }
  7562              });
  7563            }
  7564            if ( $.isFunction( found ) ) {
  7565              response = found.apply(context, passedArguments);
  7566            }
  7567            else if(found !== undefined) {
  7568              response = found;
  7569            }
  7570            if($.isArray(returnedValue)) {
  7571              returnedValue.push(response);
  7572            }
  7573            else if(returnedValue !== undefined) {
  7574              returnedValue = [returnedValue, response];
  7575            }
  7576            else if(response !== undefined) {
  7577              returnedValue = response;
  7578            }
  7579            return found;
  7580          }
  7581        };
  7582  
  7583        if(methodInvoked) {
  7584          if(instance === undefined) {
  7585            module.initialize();
  7586          }
  7587          module.invoke(query);
  7588        }
  7589        else {
  7590          if(instance !== undefined) {
  7591            instance.invoke('destroy');
  7592          }
  7593          module.initialize();
  7594        }
  7595      })
  7596    ;
  7597  
  7598    return (returnedValue !== undefined)
  7599      ? returnedValue
  7600      : this
  7601    ;
  7602  };
  7603  
  7604  $.fn.popup.settings = {
  7605  
  7606    name         : 'Popup',
  7607  
  7608    debug        : false,
  7609    verbose      : true,
  7610    performance  : true,
  7611    namespace    : 'popup',
  7612  
  7613    onCreate     : function(){},
  7614    onRemove     : function(){},
  7615  
  7616    onShow       : function(){},
  7617    onVisible    : function(){},
  7618    onHide       : function(){},
  7619    onHidden     : function(){},
  7620  
  7621    variation    : '',
  7622    content      : false,
  7623    html         : false,
  7624    title        : false,
  7625  
  7626    on           : 'hover',
  7627    closable     : true,
  7628    hideOnScroll : 'auto',
  7629    exclusive    : true,
  7630  
  7631    context      : 'body',
  7632  
  7633    position     : 'top left',
  7634    prefer       : 'opposite',
  7635    lastResort   : false,
  7636  
  7637    delay        : {
  7638      show : 30,
  7639      hide : 0
  7640    },
  7641  
  7642    setFluidWidth  : true,
  7643    movePopup      : true,
  7644  
  7645    target         : false,
  7646    popup          : false,
  7647    inline         : false,
  7648    preserve       : false,
  7649    hoverable      : false,
  7650  
  7651    duration       : 200,
  7652    easing         : 'easeOutQuint',
  7653    transition     : 'scale',
  7654  
  7655    distanceAway   : 0,
  7656    offset         : 0,
  7657    maxSearchDepth : 20,
  7658  
  7659    error: {
  7660      invalidPosition : 'The position you specified is not a valid position',
  7661      cannotPlace     : 'No visible position could be found for the popup',
  7662      method          : 'The method you called is not defined.'
  7663    },
  7664  
  7665    metadata: {
  7666      activator : 'activator',
  7667      content   : 'content',
  7668      html      : 'html',
  7669      offset    : 'offset',
  7670      position  : 'position',
  7671      title     : 'title',
  7672      variation : 'variation'
  7673    },
  7674  
  7675    className   : {
  7676      active    : 'active',
  7677      animating : 'animating',
  7678      dropdown  : 'dropdown',
  7679      fluid     : 'fluid',
  7680      loading   : 'loading',
  7681      popup     : 'ui popup',
  7682      position  : 'top left center bottom right',
  7683      visible   : 'visible'
  7684    },
  7685  
  7686    selector    : {
  7687      popup    : '.ui.popup'
  7688    },
  7689  
  7690    templates: {
  7691      escape: function(string) {
  7692        var
  7693          badChars     = /[&<>"'`]/g,
  7694          shouldEscape = /[&<>"'`]/,
  7695          escape       = {
  7696            "&": "&amp;",
  7697            "<": "&lt;",
  7698            ">": "&gt;",
  7699            '"': "&quot;",
  7700            "'": "&#x27;",
  7701            "`": "&#x60;"
  7702          },
  7703          escapedChar  = function(chr) {
  7704            return escape[chr];
  7705          }
  7706        ;
  7707        if(shouldEscape.test(string)) {
  7708          return string.replace(badChars, escapedChar);
  7709        }
  7710        return string;
  7711      },
  7712      popup: function(text) {
  7713        var
  7714          html   = '',
  7715          escape = $.fn.popup.settings.templates.escape
  7716        ;
  7717        if(typeof text !== undefined) {
  7718          if(typeof text.title !== undefined && text.title) {
  7719            text.title = escape(text.title);
  7720            html += '<div class="header">' + text.title + '</div>';
  7721          }
  7722          if(typeof text.content !== undefined && text.content) {
  7723            text.content = escape(text.content);
  7724            html += '<div class="content">' + text.content + '</div>';
  7725          }
  7726        }
  7727        return html;
  7728      }
  7729    }
  7730  
  7731  };
  7732  
  7733  // Adds easing
  7734  $.extend( $.easing, {
  7735    easeOutQuad: function (x, t, b, c, d) {
  7736      return -c *(t/=d)*(t-2) + b;
  7737    }
  7738  });
  7739  
  7740  
  7741  })( jQuery, window , document );
  7742  
  7743  /*!
  7744   * # Semantic UI x.x - Progress
  7745   * http://github.com/semantic-org/semantic-ui/
  7746   *
  7747   *
  7748   * Copyright 2014 Contributors
  7749   * Released under the MIT license
  7750   * http://opensource.org/licenses/MIT
  7751   *
  7752   */
  7753  
  7754  ;(function ( $, window, document, undefined ) {
  7755  
  7756  "use strict";
  7757  
  7758  $.fn.progress = function(parameters) {
  7759    var
  7760      $allModules    = $(this),
  7761  
  7762      moduleSelector = $allModules.selector || '',
  7763  
  7764      time           = new Date().getTime(),
  7765      performance    = [],
  7766  
  7767      query          = arguments[0],
  7768      methodInvoked  = (typeof query == 'string'),
  7769      queryArguments = [].slice.call(arguments, 1),
  7770  
  7771      returnedValue
  7772    ;
  7773  
  7774    $allModules
  7775      .each(function() {
  7776        var
  7777          settings          = ( $.isPlainObject(parameters) )
  7778            ? $.extend(true, {}, $.fn.progress.settings, parameters)
  7779            : $.extend({}, $.fn.progress.settings),
  7780  
  7781          className       = settings.className,
  7782          metadata        = settings.metadata,
  7783          namespace       = settings.namespace,
  7784          selector        = settings.selector,
  7785          error           = settings.error,
  7786  
  7787          eventNamespace  = '.' + namespace,
  7788          moduleNamespace = 'module-' + namespace,
  7789  
  7790          $module         = $(this),
  7791          $bar            = $(this).find(selector.bar),
  7792          $progress       = $(this).find(selector.progress),
  7793          $label          = $(this).find(selector.label),
  7794  
  7795          element         = this,
  7796          instance        = $module.data(moduleNamespace),
  7797  
  7798          animating = false,
  7799          transitionEnd,
  7800          module
  7801        ;
  7802  
  7803        module = {
  7804  
  7805          initialize: function() {
  7806            module.debug('Initializing progress bar', settings);
  7807  
  7808            transitionEnd = module.get.transitionEnd();
  7809  
  7810            module.read.metadata();
  7811            module.set.duration();
  7812            module.set.initials();
  7813            module.instantiate();
  7814          },
  7815  
  7816          instantiate: function() {
  7817            module.verbose('Storing instance of progress', module);
  7818            instance = module;
  7819            $module
  7820              .data(moduleNamespace, module)
  7821            ;
  7822          },
  7823          destroy: function() {
  7824            module.verbose('Destroying previous progress for', $module);
  7825            clearInterval(instance.interval);
  7826            module.remove.state();
  7827            $module.removeData(moduleNamespace);
  7828            instance = undefined;
  7829          },
  7830  
  7831          reset: function() {
  7832            module.set.percent(0);
  7833          },
  7834  
  7835          complete: function() {
  7836            if(module.percent === undefined || module.percent < 100) {
  7837              module.set.percent(100);
  7838            }
  7839          },
  7840  
  7841          read: {
  7842            metadata: function() {
  7843              if( $module.data(metadata.percent) ) {
  7844                module.verbose('Current percent value set from metadata');
  7845                module.percent = $module.data(metadata.percent);
  7846              }
  7847              if( $module.data(metadata.total) ) {
  7848                module.verbose('Total value set from metadata');
  7849                module.total = $module.data(metadata.total);
  7850              }
  7851              if( $module.data(metadata.value) ) {
  7852                module.verbose('Current value set from metadata');
  7853                module.value = $module.data(metadata.value);
  7854              }
  7855            },
  7856            currentValue: function() {
  7857              return (module.value !== undefined)
  7858                ? module.value
  7859                : false
  7860              ;
  7861            }
  7862          },
  7863  
  7864          increment: function(incrementValue) {
  7865            var
  7866              total          = module.total || false,
  7867              edgeValue,
  7868              startValue,
  7869              newValue
  7870            ;
  7871            if(total) {
  7872              startValue     = module.value || 0;
  7873              incrementValue = incrementValue || 1;
  7874              newValue       = startValue + incrementValue;
  7875              edgeValue      = module.total;
  7876              module.debug('Incrementing value by', incrementValue, startValue, edgeValue);
  7877              if(newValue > edgeValue ) {
  7878                module.debug('Value cannot increment above total', edgeValue);
  7879                newValue = edgeValue;
  7880              }
  7881              module.set.progress(newValue);
  7882            }
  7883            else {
  7884              startValue     = module.percent || 0;
  7885              incrementValue = incrementValue || module.get.randomValue();
  7886              newValue       = startValue + incrementValue;
  7887              edgeValue      = 100;
  7888              module.debug('Incrementing percentage by', incrementValue, startValue);
  7889              if(newValue > edgeValue ) {
  7890                module.debug('Value cannot increment above 100 percent');
  7891                newValue = edgeValue;
  7892              }
  7893              module.set.progress(newValue);
  7894            }
  7895          },
  7896          decrement: function(decrementValue) {
  7897            var
  7898              total     = module.total || false,
  7899              edgeValue = 0,
  7900              startValue,
  7901              newValue
  7902            ;
  7903            if(total) {
  7904              startValue     =  module.value   || 0;
  7905              decrementValue =  decrementValue || 1;
  7906              newValue       =  startValue - decrementValue;
  7907              module.debug('Decrementing value by', decrementValue, startValue);
  7908            }
  7909            else {
  7910              startValue     =  module.percent || 0;
  7911              decrementValue =  decrementValue || module.get.randomValue();
  7912              newValue       =  startValue - decrementValue;
  7913              module.debug('Decrementing percentage by', decrementValue, startValue);
  7914            }
  7915  
  7916            if(newValue < edgeValue) {
  7917              module.debug('Value cannot decrement below 0');
  7918              newValue = 0;
  7919            }
  7920            module.set.progress(newValue);
  7921          },
  7922  
  7923          get: {
  7924            text: function(templateText) {
  7925              var
  7926                value   = module.value                || 0,
  7927                total   = module.total                || 0,
  7928                percent = (module.is.visible() && animating)
  7929                  ? module.get.displayPercent()
  7930                  : module.percent || 0,
  7931                left = (module.total > 0)
  7932                  ? (total - value)
  7933                  : (100 - percent)
  7934              ;
  7935              templateText = templateText || '';
  7936              templateText = templateText
  7937                .replace('{value}', value)
  7938                .replace('{total}', total)
  7939                .replace('{left}', left)
  7940                .replace('{percent}', percent)
  7941              ;
  7942              module.debug('Adding variables to progress bar text', templateText);
  7943              return templateText;
  7944            },
  7945            randomValue: function() {
  7946              module.debug('Generating random increment percentage');
  7947              return Math.floor((Math.random() * settings.random.max) + settings.random.min);
  7948            },
  7949  
  7950            transitionEnd: function() {
  7951              var
  7952                element     = document.createElement('element'),
  7953                transitions = {
  7954                  'transition'       :'transitionend',
  7955                  'OTransition'      :'oTransitionEnd',
  7956                  'MozTransition'    :'transitionend',
  7957                  'WebkitTransition' :'webkitTransitionEnd'
  7958                },
  7959                transition
  7960              ;
  7961              for(transition in transitions){
  7962                if( element.style[transition] !== undefined ){
  7963                  return transitions[transition];
  7964                }
  7965              }
  7966            },
  7967  
  7968            // gets current displayed percentage (if animating values this is the intermediary value)
  7969            displayPercent: function() {
  7970              var
  7971                barWidth       = $bar.width(),
  7972                totalWidth     = $module.width(),
  7973                minDisplay     = parseInt($bar.css('min-width'), 10),
  7974                displayPercent = (barWidth > minDisplay)
  7975                  ? (barWidth / totalWidth * 100)
  7976                  : module.percent
  7977              ;
  7978              if(settings.precision === 0) {
  7979                return Math.round(displayPercent);
  7980              }
  7981              return Math.round(displayPercent * (10 * settings.precision) / (10 * settings.precision) );
  7982            },
  7983  
  7984            percent: function() {
  7985              return module.percent || 0;
  7986            },
  7987            value: function() {
  7988              return module.value || false;
  7989            },
  7990            total: function() {
  7991              return module.total || false;
  7992            }
  7993          },
  7994  
  7995          is: {
  7996            success: function() {
  7997              return $module.hasClass(className.success);
  7998            },
  7999            warning: function() {
  8000              return $module.hasClass(className.warning);
  8001            },
  8002            error: function() {
  8003              return $module.hasClass(className.error);
  8004            },
  8005            active: function() {
  8006              return $module.hasClass(className.active);
  8007            },
  8008            visible: function() {
  8009              return $module.is(':visible');
  8010            }
  8011          },
  8012  
  8013          remove: {
  8014            state: function() {
  8015              module.verbose('Removing stored state');
  8016              delete module.total;
  8017              delete module.percent;
  8018              delete module.value;
  8019            },
  8020            active: function() {
  8021              module.verbose('Removing active state');
  8022              $module.removeClass(className.active);
  8023            },
  8024            success: function() {
  8025              module.verbose('Removing success state');
  8026              $module.removeClass(className.success);
  8027            },
  8028            warning: function() {
  8029              module.verbose('Removing warning state');
  8030              $module.removeClass(className.warning);
  8031            },
  8032            error: function() {
  8033              module.verbose('Removing error state');
  8034              $module.removeClass(className.error);
  8035            }
  8036          },
  8037  
  8038          set: {
  8039            barWidth: function(value) {
  8040              if(value > 100) {
  8041                module.error(error.tooHigh, value);
  8042              }
  8043              else if (value < 0) {
  8044                module.error(error.tooLow, value);
  8045              }
  8046              else {
  8047                $bar
  8048                  .css('width', value + '%')
  8049                ;
  8050                $module
  8051                  .attr('data-percent', parseInt(value, 10))
  8052                ;
  8053              }
  8054            },
  8055            duration: function(duration) {
  8056              duration = duration || settings.duration;
  8057              duration = (typeof duration == 'number')
  8058                ? duration + 'ms'
  8059                : duration
  8060              ;
  8061              module.verbose('Setting progress bar transition duration', duration);
  8062              $bar
  8063                .css({
  8064                  '-webkit-transition-duration': duration,
  8065                  '-moz-transition-duration': duration,
  8066                  '-ms-transition-duration': duration,
  8067                  '-o-transition-duration': duration,
  8068                  'transition-duration':  duration
  8069                })
  8070              ;
  8071            },
  8072            initials: function() {
  8073              if(settings.total !== false) {
  8074                module.verbose('Current total set in settings', settings.total);
  8075                module.total = settings.total;
  8076              }
  8077              if(settings.value !== false) {
  8078                module.verbose('Current value set in settings', settings.value);
  8079                module.value = settings.value;
  8080              }
  8081              if(settings.percent !== false) {
  8082                module.verbose('Current percent set in settings', settings.percent);
  8083                module.percent = settings.percent;
  8084              }
  8085              if(module.percent !== undefined) {
  8086                module.set.percent(module.percent);
  8087              }
  8088              else if(module.value !== undefined) {
  8089                module.set.progress(module.value);
  8090              }
  8091            },
  8092            percent: function(percent) {
  8093              percent = (typeof percent == 'string')
  8094                ? +(percent.replace('%', ''))
  8095                : percent
  8096              ;
  8097              if(percent > 0 && percent < 1) {
  8098                module.verbose('Module percentage passed as decimal, converting');
  8099                percent = percent * 100;
  8100              }
  8101              // round percentage
  8102              if(settings.precision === 0) {
  8103                percent = Math.round(percent);
  8104              }
  8105              else {
  8106                percent = Math.round(percent * (10 * settings.precision) / (10 * settings.precision) );
  8107              }
  8108              module.percent = percent;
  8109              if(module.total) {
  8110                module.value = Math.round( (percent / 100) * module.total);
  8111              }
  8112              else if(settings.limitValues) {
  8113                module.value = (module.value > 100)
  8114                  ? 100
  8115                  : (module.value < 0)
  8116                    ? 0
  8117                    : module.value
  8118                ;
  8119              }
  8120              module.set.barWidth(percent);
  8121              if( module.is.visible() ) {
  8122                module.set.labelInterval();
  8123              }
  8124              module.set.labels();
  8125              settings.onChange.call(element, percent, module.value, module.total);
  8126            },
  8127            labelInterval: function() {
  8128              var
  8129                animationCallback = function() {
  8130                  module.verbose('Bar finished animating, removing continuous label updates');
  8131                  clearInterval(module.interval);
  8132                  animating = false;
  8133                  module.set.labels();
  8134                }
  8135              ;
  8136              clearInterval(module.interval);
  8137              $bar.one(transitionEnd + eventNamespace, animationCallback);
  8138              module.timer = setTimeout(animationCallback, settings.duration + 100);
  8139              animating = true;
  8140              module.interval = setInterval(module.set.labels, settings.framerate);
  8141            },
  8142            labels: function() {
  8143              module.verbose('Setting both bar progress and outer label text');
  8144              module.set.barLabel();
  8145              module.set.state();
  8146            },
  8147            label: function(text) {
  8148              text = text || '';
  8149              if(text) {
  8150                text = module.get.text(text);
  8151                module.debug('Setting label to text', text);
  8152                $label.text(text);
  8153              }
  8154            },
  8155            state: function(percent) {
  8156              percent = (percent !== undefined)
  8157                ? percent
  8158                : module.percent
  8159              ;
  8160              if(percent === 100) {
  8161                if(settings.autoSuccess && !(module.is.warning() || module.is.error())) {
  8162                  module.set.success();
  8163                  module.debug('Automatically triggering success at 100%');
  8164                }
  8165                else {
  8166                  module.verbose('Reached 100% removing active state');
  8167                  module.remove.active();
  8168                }
  8169              }
  8170              else if(percent > 0) {
  8171                module.verbose('Adjusting active progress bar label', percent);
  8172                module.set.active();
  8173              }
  8174              else {
  8175                module.remove.active();
  8176                module.set.label(settings.text.active);
  8177              }
  8178            },
  8179            barLabel: function(text) {
  8180              if(text !== undefined) {
  8181                $progress.text( module.get.text(text) );
  8182              }
  8183              else if(settings.label == 'ratio' && module.total) {
  8184                module.debug('Adding ratio to bar label');
  8185                $progress.text( module.get.text(settings.text.ratio) );
  8186              }
  8187              else if(settings.label == 'percent') {
  8188                module.debug('Adding percentage to bar label');
  8189                $progress.text( module.get.text(settings.text.percent) );
  8190              }
  8191            },
  8192            active: function(text) {
  8193              text = text || settings.text.active;
  8194              module.debug('Setting active state');
  8195              if(settings.showActivity && !module.is.active() ) {
  8196                $module.addClass(className.active);
  8197              }
  8198              module.remove.warning();
  8199              module.remove.error();
  8200              module.remove.success();
  8201              if(text) {
  8202                module.set.label(text);
  8203              }
  8204              settings.onActive.call(element, module.value, module.total);
  8205            },
  8206            success : function(text) {
  8207              text = text || settings.text.success;
  8208              module.debug('Setting success state');
  8209              $module.addClass(className.success);
  8210              module.remove.active();
  8211              module.remove.warning();
  8212              module.remove.error();
  8213              module.complete();
  8214              if(text) {
  8215                module.set.label(text);
  8216              }
  8217              settings.onSuccess.call(element, module.total);
  8218            },
  8219            warning : function(text) {
  8220              text = text || settings.text.warning;
  8221              module.debug('Setting warning state');
  8222              $module.addClass(className.warning);
  8223              module.remove.active();
  8224              module.remove.success();
  8225              module.remove.error();
  8226              module.complete();
  8227              if(text) {
  8228                module.set.label(text);
  8229              }
  8230              settings.onWarning.call(element, module.value, module.total);
  8231            },
  8232            error : function(text) {
  8233              text = text || settings.text.error;
  8234              module.debug('Setting error state');
  8235              $module.addClass(className.error);
  8236              module.remove.active();
  8237              module.remove.success();
  8238              module.remove.warning();
  8239              module.complete();
  8240              if(text) {
  8241                module.set.label(text);
  8242              }
  8243              settings.onError.call(element, module.value, module.total);
  8244            },
  8245            total: function(totalValue) {
  8246              module.total = totalValue;
  8247            },
  8248            progress: function(value) {
  8249              var
  8250                numericValue = (typeof value === 'string')
  8251                  ? (value.replace(/[^\d.]/g, '') !== '')
  8252                    ? +(value.replace(/[^\d.]/g, ''))
  8253                    : false
  8254                  : value,
  8255                percentComplete
  8256              ;
  8257              if(numericValue === false) {
  8258                module.error(error.nonNumeric, value);
  8259              }
  8260              if(module.total) {
  8261                module.value    = numericValue;
  8262                percentComplete = (numericValue / module.total) * 100;
  8263                module.debug('Calculating percent complete from total', percentComplete);
  8264                module.set.percent( percentComplete );
  8265              }
  8266              else {
  8267                percentComplete = numericValue;
  8268                module.debug('Setting value to exact percentage value', percentComplete);
  8269                module.set.percent( percentComplete );
  8270              }
  8271            }
  8272          },
  8273  
  8274          setting: function(name, value) {
  8275            module.debug('Changing setting', name, value);
  8276            if( $.isPlainObject(name) ) {
  8277              $.extend(true, settings, name);
  8278            }
  8279            else if(value !== undefined) {
  8280              settings[name] = value;
  8281            }
  8282            else {
  8283              return settings[name];
  8284            }
  8285          },
  8286          internal: function(name, value) {
  8287            if( $.isPlainObject(name) ) {
  8288              $.extend(true, module, name);
  8289            }
  8290            else if(value !== undefined) {
  8291              module[name] = value;
  8292            }
  8293            else {
  8294              return module[name];
  8295            }
  8296          },
  8297          debug: function() {
  8298            if(settings.debug) {
  8299              if(settings.performance) {
  8300                module.performance.log(arguments);
  8301              }
  8302              else {
  8303                module.debug = Function.prototype.bind.call(console.info, console, settings.name + ':');
  8304                module.debug.apply(console, arguments);
  8305              }
  8306            }
  8307          },
  8308          verbose: function() {
  8309            if(settings.verbose && settings.debug) {
  8310              if(settings.performance) {
  8311                module.performance.log(arguments);
  8312              }
  8313              else {
  8314                module.verbose = Function.prototype.bind.call(console.info, console, settings.name + ':');
  8315                module.verbose.apply(console, arguments);
  8316              }
  8317            }
  8318          },
  8319          error: function() {
  8320            module.error = Function.prototype.bind.call(console.error, console, settings.name + ':');
  8321            module.error.apply(console, arguments);
  8322          },
  8323          performance: {
  8324            log: function(message) {
  8325              var
  8326                currentTime,
  8327                executionTime,
  8328                previousTime
  8329              ;
  8330              if(settings.performance) {
  8331                currentTime   = new Date().getTime();
  8332                previousTime  = time || currentTime;
  8333                executionTime = currentTime - previousTime;
  8334                time          = currentTime;
  8335                performance.push({
  8336                  'Name'           : message[0],
  8337                  'Arguments'      : [].slice.call(message, 1) || '',
  8338                  'Element'        : element,
  8339                  'Execution Time' : executionTime
  8340                });
  8341              }
  8342              clearTimeout(module.performance.timer);
  8343              module.performance.timer = setTimeout(module.performance.display, 100);
  8344            },
  8345            display: function() {
  8346              var
  8347                title = settings.name + ':',
  8348                totalTime = 0
  8349              ;
  8350              time = false;
  8351              clearTimeout(module.performance.timer);
  8352              $.each(performance, function(index, data) {
  8353                totalTime += data['Execution Time'];
  8354              });
  8355              title += ' ' + totalTime + 'ms';
  8356              if(moduleSelector) {
  8357                title += ' \'' + moduleSelector + '\'';
  8358              }
  8359              if( (console.group !== undefined || console.table !== undefined) && performance.length > 0) {
  8360                console.groupCollapsed(title);
  8361                if(console.table) {
  8362                  console.table(performance);
  8363                }
  8364                else {
  8365                  $.each(performance, function(index, data) {
  8366                    console.log(data['Name'] + ': ' + data['Execution Time']+'ms');
  8367                  });
  8368                }
  8369                console.groupEnd();
  8370              }
  8371              performance = [];
  8372            }
  8373          },
  8374          invoke: function(query, passedArguments, context) {
  8375            var
  8376              object = instance,
  8377              maxDepth,
  8378              found,
  8379              response
  8380            ;
  8381            passedArguments = passedArguments || queryArguments;
  8382            context         = element         || context;
  8383            if(typeof query == 'string' && object !== undefined) {
  8384              query    = query.split(/[\. ]/);
  8385              maxDepth = query.length - 1;
  8386              $.each(query, function(depth, value) {
  8387                var camelCaseValue = (depth != maxDepth)
  8388                  ? value + query[depth + 1].charAt(0).toUpperCase() + query[depth + 1].slice(1)
  8389                  : query
  8390                ;
  8391                if( $.isPlainObject( object[camelCaseValue] ) && (depth != maxDepth) ) {
  8392                  object = object[camelCaseValue];
  8393                }
  8394                else if( object[camelCaseValue] !== undefined ) {
  8395                  found = object[camelCaseValue];
  8396                  return false;
  8397                }
  8398                else if( $.isPlainObject( object[value] ) && (depth != maxDepth) ) {
  8399                  object = object[value];
  8400                }
  8401                else if( object[value] !== undefined ) {
  8402                  found = object[value];
  8403                  return false;
  8404                }
  8405                else {
  8406                  module.error(error.method, query);
  8407                  return false;
  8408                }
  8409              });
  8410            }
  8411            if ( $.isFunction( found ) ) {
  8412              response = found.apply(context, passedArguments);
  8413            }
  8414            else if(found !== undefined) {
  8415              response = found;
  8416            }
  8417            if($.isArray(returnedValue)) {
  8418              returnedValue.push(response);
  8419            }
  8420            else if(returnedValue !== undefined) {
  8421              returnedValue = [returnedValue, response];
  8422            }
  8423            else if(response !== undefined) {
  8424              returnedValue = response;
  8425            }
  8426            return found;
  8427          }
  8428        };
  8429  
  8430        if(methodInvoked) {
  8431          if(instance === undefined) {
  8432            module.initialize();
  8433          }
  8434          module.invoke(query);
  8435        }
  8436        else {
  8437          if(instance !== undefined) {
  8438            instance.invoke('destroy');
  8439          }
  8440          module.initialize();
  8441        }
  8442      })
  8443    ;
  8444  
  8445    return (returnedValue !== undefined)
  8446      ? returnedValue
  8447      : this
  8448    ;
  8449  };
  8450  
  8451  $.fn.progress.settings = {
  8452  
  8453    name         : 'Progress',
  8454    namespace    : 'progress',
  8455  
  8456    debug        : false,
  8457    verbose      : true,
  8458    performance  : true,
  8459  
  8460    random       : {
  8461      min : 2,
  8462      max : 5
  8463    },
  8464  
  8465    duration     : 300,
  8466  
  8467    autoSuccess  : true,
  8468    showActivity : true,
  8469    limitValues  : true,
  8470  
  8471    label        : 'percent',
  8472    precision    : 1,
  8473    framerate    : (1000 / 30), /// 30 fps
  8474  
  8475    percent      : false,
  8476    total        : false,
  8477    value        : false,
  8478  
  8479    onChange     : function(percent, value, total){},
  8480    onSuccess    : function(total){},
  8481    onActive     : function(value, total){},
  8482    onError      : function(value, total){},
  8483    onWarning    : function(value, total){},
  8484  
  8485    error    : {
  8486      method     : 'The method you called is not defined.',
  8487      nonNumeric : 'Progress value is non numeric',
  8488      tooHigh    : 'Value specified is above 100%',
  8489      tooLow     : 'Value specified is below 0%'
  8490    },
  8491  
  8492    regExp: {
  8493      variable: /\{\$*[A-z0-9]+\}/g
  8494    },
  8495  
  8496    metadata: {
  8497      percent : 'percent',
  8498      total   : 'total',
  8499      value   : 'value'
  8500    },
  8501  
  8502    selector : {
  8503      bar      : '> .bar',
  8504      label    : '> .label',
  8505      progress : '.bar > .progress'
  8506    },
  8507  
  8508    text : {
  8509      active  : false,
  8510      error   : false,
  8511      success : false,
  8512      warning : false,
  8513      percent : '{percent}%',
  8514      ratio   : '{value} of {total}'
  8515    },
  8516  
  8517    className : {
  8518      active  : 'active',
  8519      error   : 'error',
  8520      success : 'success',
  8521      warning : 'warning'
  8522    }
  8523  
  8524  };
  8525  
  8526  
  8527  })( jQuery, window , document );
  8528  /*!
  8529   * # Semantic UI x.x - Rating
  8530   * http://github.com/semantic-org/semantic-ui/
  8531   *
  8532   *
  8533   * Copyright 2014 Contributors
  8534   * Released under the MIT license
  8535   * http://opensource.org/licenses/MIT
  8536   *
  8537   */
  8538  
  8539  ;(function ($, window, document, undefined) {
  8540  
  8541  "use strict";
  8542  
  8543  $.fn.rating = function(parameters) {
  8544    var
  8545      $allModules     = $(this),
  8546      moduleSelector  = $allModules.selector || '',
  8547  
  8548      time            = new Date().getTime(),
  8549      performance     = [],
  8550  
  8551      query           = arguments[0],
  8552      methodInvoked   = (typeof query == 'string'),
  8553      queryArguments  = [].slice.call(arguments, 1),
  8554      returnedValue
  8555    ;
  8556    $allModules
  8557      .each(function() {
  8558        var
  8559          settings        = ( $.isPlainObject(parameters) )
  8560            ? $.extend(true, {}, $.fn.rating.settings, parameters)
  8561            : $.extend({}, $.fn.rating.settings),
  8562  
  8563          namespace       = settings.namespace,
  8564          className       = settings.className,
  8565          metadata        = settings.metadata,
  8566          selector        = settings.selector,
  8567          error           = settings.error,
  8568  
  8569          eventNamespace  = '.' + namespace,
  8570          moduleNamespace = 'module-' + namespace,
  8571  
  8572          element         = this,
  8573          instance        = $(this).data(moduleNamespace),
  8574  
  8575          $module         = $(this),
  8576          $icon           = $module.find(selector.icon),
  8577  
  8578          module
  8579        ;
  8580  
  8581        module = {
  8582  
  8583          initialize: function() {
  8584            module.verbose('Initializing rating module', settings);
  8585  
  8586            if($icon.length === 0) {
  8587              module.setup.layout();
  8588            }
  8589  
  8590            if(settings.interactive) {
  8591              module.enable();
  8592            }
  8593            else {
  8594              module.disable();
  8595            }
  8596            if(settings.initialRating) {
  8597              module.debug('Setting initial rating');
  8598              module.setRating(settings.initialRating);
  8599            }
  8600            if( $module.data(metadata.rating) ) {
  8601              module.debug('Rating found in metadata');
  8602              module.setRating( $module.data(metadata.rating) );
  8603            }
  8604            module.instantiate();
  8605          },
  8606  
  8607          instantiate: function() {
  8608            module.verbose('Instantiating module', settings);
  8609            instance = module;
  8610            $module
  8611              .data(moduleNamespace, module)
  8612            ;
  8613          },
  8614  
  8615          destroy: function() {
  8616            module.verbose('Destroying previous instance', instance);
  8617            $module
  8618              .removeData(moduleNamespace)
  8619            ;
  8620            $icon
  8621              .off(eventNamespace)
  8622            ;
  8623          },
  8624  
  8625          refresh: function() {
  8626            $icon   = $module.find(selector.icon);
  8627          },
  8628  
  8629          setup: {
  8630            layout: function() {
  8631              var
  8632                maxRating = $module.data(metadata.maxRating) || settings.maxRating
  8633              ;
  8634              module.debug('Generating icon html dynamically');
  8635              $module
  8636                .html($.fn.rating.settings.templates.icon(maxRating))
  8637              ;
  8638              module.refresh();
  8639            }
  8640          },
  8641  
  8642          event: {
  8643            mouseenter: function() {
  8644              var
  8645                $activeIcon = $(this)
  8646              ;
  8647              $activeIcon
  8648                .nextAll()
  8649                  .removeClass(className.selected)
  8650              ;
  8651              $module
  8652                .addClass(className.selected)
  8653              ;
  8654              $activeIcon
  8655                .addClass(className.selected)
  8656                  .prevAll()
  8657                  .addClass(className.selected)
  8658              ;
  8659            },
  8660            mouseleave: function() {
  8661              $module
  8662                .removeClass(className.selected)
  8663              ;
  8664              $icon
  8665                .removeClass(className.selected)
  8666              ;
  8667            },
  8668            click: function() {
  8669              var
  8670                $activeIcon   = $(this),
  8671                currentRating = module.getRating(),
  8672                rating        = $icon.index($activeIcon) + 1,
  8673                canClear      = (settings.clearable == 'auto')
  8674                 ? ($icon.length === 1)
  8675                 : settings.clearable
  8676              ;
  8677              if(canClear && currentRating == rating) {
  8678                module.clearRating();
  8679              }
  8680              else {
  8681                module.setRating( rating );
  8682              }
  8683            }
  8684          },
  8685  
  8686          clearRating: function() {
  8687            module.debug('Clearing current rating');
  8688            module.setRating(0);
  8689          },
  8690  
  8691          getRating: function() {
  8692            var
  8693              currentRating = $icon.filter('.' + className.active).length
  8694            ;
  8695            module.verbose('Current rating retrieved', currentRating);
  8696            return currentRating;
  8697          },
  8698  
  8699          enable: function() {
  8700            module.debug('Setting rating to interactive mode');
  8701            $icon
  8702              .on('mouseenter' + eventNamespace, module.event.mouseenter)
  8703              .on('mouseleave' + eventNamespace, module.event.mouseleave)
  8704              .on('click' + eventNamespace, module.event.click)
  8705            ;
  8706            $module
  8707              .removeClass(className.disabled)
  8708            ;
  8709          },
  8710  
  8711          disable: function() {
  8712            module.debug('Setting rating to read-only mode');
  8713            $icon
  8714              .off(eventNamespace)
  8715            ;
  8716            $module
  8717              .addClass(className.disabled)
  8718            ;
  8719          },
  8720  
  8721          setRating: function(rating) {
  8722            var
  8723              ratingIndex = (rating - 1 >= 0)
  8724                ? (rating - 1)
  8725                : 0,
  8726              $activeIcon = $icon.eq(ratingIndex)
  8727            ;
  8728            $module
  8729              .removeClass(className.selected)
  8730            ;
  8731            $icon
  8732              .removeClass(className.selected)
  8733              .removeClass(className.active)
  8734            ;
  8735            if(rating > 0) {
  8736              module.verbose('Setting current rating to', rating);
  8737              $activeIcon
  8738                .prevAll()
  8739                .andSelf()
  8740                  .addClass(className.active)
  8741              ;
  8742            }
  8743            settings.onRate.call(element, rating);
  8744          },
  8745  
  8746          setting: function(name, value) {
  8747            module.debug('Changing setting', name, value);
  8748            if( $.isPlainObject(name) ) {
  8749              $.extend(true, settings, name);
  8750            }
  8751            else if(value !== undefined) {
  8752              settings[name] = value;
  8753            }
  8754            else {
  8755              return settings[name];
  8756            }
  8757          },
  8758          internal: function(name, value) {
  8759            if( $.isPlainObject(name) ) {
  8760              $.extend(true, module, name);
  8761            }
  8762            else if(value !== undefined) {
  8763              module[name] = value;
  8764            }
  8765            else {
  8766              return module[name];
  8767            }
  8768          },
  8769          debug: function() {
  8770            if(settings.debug) {
  8771              if(settings.performance) {
  8772                module.performance.log(arguments);
  8773              }
  8774              else {
  8775                module.debug = Function.prototype.bind.call(console.info, console, settings.name + ':');
  8776                module.debug.apply(console, arguments);
  8777              }
  8778            }
  8779          },
  8780          verbose: function() {
  8781            if(settings.verbose && settings.debug) {
  8782              if(settings.performance) {
  8783                module.performance.log(arguments);
  8784              }
  8785              else {
  8786                module.verbose = Function.prototype.bind.call(console.info, console, settings.name + ':');
  8787                module.verbose.apply(console, arguments);
  8788              }
  8789            }
  8790          },
  8791          error: function() {
  8792            module.error = Function.prototype.bind.call(console.error, console, settings.name + ':');
  8793            module.error.apply(console, arguments);
  8794          },
  8795          performance: {
  8796            log: function(message) {
  8797              var
  8798                currentTime,
  8799                executionTime,
  8800                previousTime
  8801              ;
  8802              if(settings.performance) {
  8803                currentTime   = new Date().getTime();
  8804                previousTime  = time || currentTime;
  8805                executionTime = currentTime - previousTime;
  8806                time          = currentTime;
  8807                performance.push({
  8808                  'Name'           : message[0],
  8809                  'Arguments'      : [].slice.call(message, 1) || '',
  8810                  'Element'        : element,
  8811                  'Execution Time' : executionTime
  8812                });
  8813              }
  8814              clearTimeout(module.performance.timer);
  8815              module.performance.timer = setTimeout(module.performance.display, 100);
  8816            },
  8817            display: function() {
  8818              var
  8819                title = settings.name + ':',
  8820                totalTime = 0
  8821              ;
  8822              time = false;
  8823              clearTimeout(module.performance.timer);
  8824              $.each(performance, function(index, data) {
  8825                totalTime += data['Execution Time'];
  8826              });
  8827              title += ' ' + totalTime + 'ms';
  8828              if(moduleSelector) {
  8829                title += ' \'' + moduleSelector + '\'';
  8830              }
  8831              if($allModules.length > 1) {
  8832                title += ' ' + '(' + $allModules.length + ')';
  8833              }
  8834              if( (console.group !== undefined || console.table !== undefined) && performance.length > 0) {
  8835                console.groupCollapsed(title);
  8836                if(console.table) {
  8837                  console.table(performance);
  8838                }
  8839                else {
  8840                  $.each(performance, function(index, data) {
  8841                    console.log(data['Name'] + ': ' + data['Execution Time']+'ms');
  8842                  });
  8843                }
  8844                console.groupEnd();
  8845              }
  8846              performance = [];
  8847            }
  8848          },
  8849          invoke: function(query, passedArguments, context) {
  8850            var
  8851              object = instance,
  8852              maxDepth,
  8853              found,
  8854              response
  8855            ;
  8856            passedArguments = passedArguments || queryArguments;
  8857            context         = element         || context;
  8858            if(typeof query == 'string' && object !== undefined) {
  8859              query    = query.split(/[\. ]/);
  8860              maxDepth = query.length - 1;
  8861              $.each(query, function(depth, value) {
  8862                var camelCaseValue = (depth != maxDepth)
  8863                  ? value + query[depth + 1].charAt(0).toUpperCase() + query[depth + 1].slice(1)
  8864                  : query
  8865                ;
  8866                if( $.isPlainObject( object[camelCaseValue] ) && (depth != maxDepth) ) {
  8867                  object = object[camelCaseValue];
  8868                }
  8869                else if( object[camelCaseValue] !== undefined ) {
  8870                  found = object[camelCaseValue];
  8871                  return false;
  8872                }
  8873                else if( $.isPlainObject( object[value] ) && (depth != maxDepth) ) {
  8874                  object = object[value];
  8875                }
  8876                else if( object[value] !== undefined ) {
  8877                  found = object[value];
  8878                  return false;
  8879                }
  8880                else {
  8881                  return false;
  8882                }
  8883              });
  8884            }
  8885            if ( $.isFunction( found ) ) {
  8886              response = found.apply(context, passedArguments);
  8887            }
  8888            else if(found !== undefined) {
  8889              response = found;
  8890            }
  8891            if($.isArray(returnedValue)) {
  8892              returnedValue.push(response);
  8893            }
  8894            else if(returnedValue !== undefined) {
  8895              returnedValue = [returnedValue, response];
  8896            }
  8897            else if(response !== undefined) {
  8898              returnedValue = response;
  8899            }
  8900            return found;
  8901          }
  8902        };
  8903        if(methodInvoked) {
  8904          if(instance === undefined) {
  8905            module.initialize();
  8906          }
  8907          module.invoke(query);
  8908        }
  8909        else {
  8910          if(instance !== undefined) {
  8911            instance.invoke('destroy');
  8912          }
  8913          module.initialize();
  8914        }
  8915      })
  8916    ;
  8917  
  8918    return (returnedValue !== undefined)
  8919      ? returnedValue
  8920      : this
  8921    ;
  8922  };
  8923  
  8924  $.fn.rating.settings = {
  8925  
  8926    name          : 'Rating',
  8927    namespace     : 'rating',
  8928  
  8929    debug         : false,
  8930    verbose       : true,
  8931    performance   : true,
  8932  
  8933    initialRating : 0,
  8934    interactive   : true,
  8935    maxRating     : 4,
  8936    clearable     : 'auto',
  8937  
  8938    onRate        : function(rating){},
  8939  
  8940    error         : {
  8941      method    : 'The method you called is not defined',
  8942      noMaximum : 'No maximum rating specified. Cannot generate HTML automatically'
  8943    },
  8944  
  8945  
  8946    metadata: {
  8947      rating    : 'rating',
  8948      maxRating : 'maxRating'
  8949    },
  8950  
  8951    className : {
  8952      active   : 'active',
  8953      disabled : 'disabled',
  8954      selected : 'selected',
  8955      loading  : 'loading'
  8956    },
  8957  
  8958    selector  : {
  8959      icon : '.icon'
  8960    },
  8961  
  8962    templates: {
  8963      icon: function(maxRating) {
  8964        var
  8965          icon = 1,
  8966          html = ''
  8967        ;
  8968        while(icon <= maxRating) {
  8969          html += '<i class="icon"></i>';
  8970          icon++;
  8971        }
  8972        return html;
  8973      }
  8974    }
  8975  
  8976  };
  8977  
  8978  })( jQuery, window , document );
  8979  
  8980  /*!
  8981   * # Semantic UI x.x - Search
  8982   * http://github.com/semantic-org/semantic-ui/
  8983   *
  8984   *
  8985   * Copyright 2014 Contributors
  8986   * Released under the MIT license
  8987   * http://opensource.org/licenses/MIT
  8988   *
  8989   */
  8990  
  8991  ;(function ($, window, document, undefined) {
  8992  
  8993  "use strict";
  8994  
  8995  $.fn.search = function(parameters) {
  8996    var
  8997      $allModules     = $(this),
  8998      moduleSelector  = $allModules.selector || '',
  8999  
  9000      time            = new Date().getTime(),
  9001      performance     = [],
  9002  
  9003      query           = arguments[0],
  9004      methodInvoked   = (typeof query == 'string'),
  9005      queryArguments  = [].slice.call(arguments, 1),
  9006      returnedValue
  9007    ;
  9008    $(this)
  9009      .each(function() {
  9010        var
  9011          settings        = $.extend(true, {}, $.fn.search.settings, parameters),
  9012  
  9013          className       = settings.className,
  9014          metadata        = settings.metadata,
  9015          regExp          = settings.regExp,
  9016          selector        = settings.selector,
  9017          error           = settings.error,
  9018          namespace       = settings.namespace,
  9019  
  9020          eventNamespace  = '.' + namespace,
  9021          moduleNamespace = namespace + '-module',
  9022  
  9023          $module         = $(this),
  9024          $prompt         = $module.find(selector.prompt),
  9025          $searchButton   = $module.find(selector.searchButton),
  9026          $results        = $module.find(selector.results),
  9027          $result         = $module.find(selector.result),
  9028          $category       = $module.find(selector.category),
  9029  
  9030          element         = this,
  9031          instance        = $module.data(moduleNamespace),
  9032  
  9033          module
  9034        ;
  9035        module = {
  9036  
  9037          initialize: function() {
  9038            module.verbose('Initializing module');
  9039            var
  9040              prompt = $prompt[0],
  9041              inputEvent   = (prompt !== undefined && prompt.oninput !== undefined)
  9042                ? 'input'
  9043                : (prompt !== undefined && prompt.onpropertychange !== undefined)
  9044                  ? 'propertychange'
  9045                  : 'keyup'
  9046            ;
  9047            if(settings.automatic) {
  9048              $prompt
  9049                .on(inputEvent + eventNamespace, module.throttle)
  9050                .attr('autocomplete', 'off')
  9051              ;
  9052            }
  9053            $prompt
  9054              .on('focus' + eventNamespace, module.event.focus)
  9055              .on('blur' + eventNamespace, module.event.blur)
  9056              .on('keydown' + eventNamespace, module.handleKeyboard)
  9057            ;
  9058            $searchButton
  9059              .on('click' + eventNamespace, module.query)
  9060            ;
  9061            $results
  9062              .on('mousedown' + eventNamespace, module.event.result.mousedown)
  9063              .on('mouseup' + eventNamespace, module.event.result.mouseup)
  9064              .on('click' + eventNamespace, selector.result, module.event.result.click)
  9065            ;
  9066            module.instantiate();
  9067          },
  9068          instantiate: function() {
  9069            module.verbose('Storing instance of module', module);
  9070            instance = module;
  9071            $module
  9072              .data(moduleNamespace, module)
  9073            ;
  9074          },
  9075          destroy: function() {
  9076            module.verbose('Destroying instance');
  9077            $module
  9078              .removeData(moduleNamespace)
  9079            ;
  9080            $prompt
  9081              .off(eventNamespace)
  9082            ;
  9083            $searchButton
  9084              .off(eventNamespace)
  9085            ;
  9086            $results
  9087              .off(eventNamespace)
  9088            ;
  9089          },
  9090          event: {
  9091            focus: function() {
  9092              module.set.focus();
  9093              clearTimeout(module.timer);
  9094              module.throttle();
  9095              if( module.has.minimumCharacters() ) {
  9096                module.showResults();
  9097              }
  9098            },
  9099            blur: function(event) {
  9100              var
  9101                pageLostFocus = (document.activeElement === this)
  9102              ;
  9103              if(!pageLostFocus && !module.resultsClicked) {
  9104                module.cancel.query();
  9105                module.remove.focus();
  9106                module.timer = setTimeout(module.hideResults, settings.hideDelay);
  9107              }
  9108            },
  9109            result: {
  9110              mousedown: function() {
  9111                module.resultsClicked = true;
  9112              },
  9113              mouseup: function() {
  9114                module.resultsClicked = false;
  9115              },
  9116              click: function(event) {
  9117                module.debug('Search result selected');
  9118                var
  9119                  $result = $(this),
  9120                  $title  = $result.find(selector.title).eq(0),
  9121                  $link   = $result.find('a[href]').eq(0),
  9122                  href    = $link.attr('href')   || false,
  9123                  target  = $link.attr('target') || false,
  9124                  title   = $title.html(),
  9125                  name    = ($title.length > 0)
  9126                    ? $title.text()
  9127                    : false,
  9128                  results = module.get.results(),
  9129                  result  = module.get.result(name, results),
  9130                  returnedValue
  9131                ;
  9132                if( $.isFunction(settings.onSelect) ) {
  9133                  if(settings.onSelect.call(element, result, results) === false) {
  9134                    module.debug('Custom onSelect callback cancelled default select action');
  9135                    return;
  9136                  }
  9137                }
  9138                module.hideResults();
  9139                if(name) {
  9140                  module.set.value(name);
  9141                }
  9142                if(href) {
  9143                  module.verbose('Opening search link found in result', $link);
  9144                  if(target == '_blank' || event.ctrlKey) {
  9145                    window.open(href);
  9146                  }
  9147                  else {
  9148                    window.location.href = (href);
  9149                  }
  9150                }
  9151              }
  9152            }
  9153          },
  9154          handleKeyboard: function(event) {
  9155            var
  9156              // force selector refresh
  9157              $result      = $module.find(selector.result),
  9158              $category    = $module.find(selector.category),
  9159              currentIndex = $result.index( $result.filter('.' + className.active) ),
  9160              resultSize   = $result.length,
  9161  
  9162              keyCode      = event.which,
  9163              keys         = {
  9164                backspace : 8,
  9165                enter     : 13,
  9166                escape    : 27,
  9167                upArrow   : 38,
  9168                downArrow : 40
  9169              },
  9170              newIndex
  9171            ;
  9172            // search shortcuts
  9173            if(keyCode == keys.escape) {
  9174              module.verbose('Escape key pressed, blurring search field');
  9175              $prompt
  9176                .trigger('blur')
  9177              ;
  9178            }
  9179            if( module.is.visible() ) {
  9180              if(keyCode == keys.enter) {
  9181                module.verbose('Enter key pressed, selecting active result');
  9182                if( $result.filter('.' + className.active).length > 0 ) {
  9183                  module.event.result.click.call($result.filter('.' + className.active), event);
  9184                  event.preventDefault();
  9185                  return false;
  9186                }
  9187              }
  9188              else if(keyCode == keys.upArrow) {
  9189                module.verbose('Up key pressed, changing active result');
  9190                newIndex = (currentIndex - 1 < 0)
  9191                  ? currentIndex
  9192                  : currentIndex - 1
  9193                ;
  9194                $category
  9195                  .removeClass(className.active)
  9196                ;
  9197                $result
  9198                  .removeClass(className.active)
  9199                  .eq(newIndex)
  9200                    .addClass(className.active)
  9201                    .closest($category)
  9202                      .addClass(className.active)
  9203                ;
  9204                event.preventDefault();
  9205              }
  9206              else if(keyCode == keys.downArrow) {
  9207                module.verbose('Down key pressed, changing active result');
  9208                newIndex = (currentIndex + 1 >= resultSize)
  9209                  ? currentIndex
  9210                  : currentIndex + 1
  9211                ;
  9212                $category
  9213                  .removeClass(className.active)
  9214                ;
  9215                $result
  9216                  .removeClass(className.active)
  9217                  .eq(newIndex)
  9218                    .addClass(className.active)
  9219                    .closest($category)
  9220                      .addClass(className.active)
  9221                ;
  9222                event.preventDefault();
  9223              }
  9224            }
  9225            else {
  9226              // query shortcuts
  9227              if(keyCode == keys.enter) {
  9228                module.verbose('Enter key pressed, executing query');
  9229                module.query();
  9230                module.set.buttonPressed();
  9231                $prompt.one('keyup', module.remove.buttonFocus);
  9232              }
  9233            }
  9234          },
  9235  
  9236          setup: {
  9237            api: function() {
  9238              var
  9239                apiSettings = {
  9240                  on        : false,
  9241                  action    : 'search',
  9242                  onFailure : module.error
  9243                },
  9244                searchHTML
  9245              ;
  9246              module.verbose('First request, initializing API');
  9247              $module.api(apiSettings);
  9248            }
  9249          },
  9250  
  9251          can: {
  9252            useAPI: function() {
  9253              return $.fn.api !== undefined;
  9254            },
  9255            transition: function() {
  9256              return settings.transition && $.fn.transition !== undefined && $module.transition('is supported');
  9257            }
  9258          },
  9259  
  9260          is: {
  9261            empty: function() {
  9262              return ($results.html() === '');
  9263            },
  9264            visible: function() {
  9265              return ($results.filter(':visible').length > 0);
  9266            },
  9267            focused: function() {
  9268              return ($prompt.filter(':focus').length > 0);
  9269            }
  9270          },
  9271  
  9272          get: {
  9273            value: function() {
  9274              return $prompt.val();
  9275            },
  9276            results: function() {
  9277              var
  9278                results = $module.data(metadata.results)
  9279              ;
  9280              return results;
  9281            },
  9282            result: function(value, results) {
  9283              var
  9284                result = false
  9285              ;
  9286              value   = value   || module.get.value();
  9287              results = results || module.get.results();
  9288              if(settings.type === 'category') {
  9289                module.debug('Finding result that matches', value);
  9290                $.each(results, function(index, category) {
  9291                  if($.isArray(category.results)) {
  9292                    result = module.search.object(value, category.results)[0];
  9293                    if(result && result.length > 0) {
  9294                      return true;
  9295                    }
  9296                  }
  9297                });
  9298              }
  9299              else {
  9300                module.debug('Finding result in results object', value);
  9301                result = module.search.object(value, results)[0];
  9302              }
  9303              return result;
  9304            },
  9305          },
  9306  
  9307          set: {
  9308            focus: function() {
  9309              $module.addClass(className.focus);
  9310            },
  9311            loading: function() {
  9312              $module.addClass(className.loading);
  9313            },
  9314            value: function(value) {
  9315              module.verbose('Setting search input value', value);
  9316              $prompt.val(value);
  9317              module.query();
  9318            },
  9319            buttonPressed: function() {
  9320              $searchButton.addClass(className.pressed);
  9321            }
  9322          },
  9323  
  9324          remove: {
  9325            loading: function() {
  9326              $module.removeClass(className.loading);
  9327            },
  9328            focus: function() {
  9329              $module.removeClass(className.focus);
  9330            },
  9331            buttonPressed: function() {
  9332              $searchButton.removeClass(className.pressed);
  9333            }
  9334          },
  9335  
  9336          query: function() {
  9337            var
  9338              searchTerm = module.get.value(),
  9339              cache = module.read.cache(searchTerm)
  9340            ;
  9341            if(cache) {
  9342              module.debug('Reading result for ' + searchTerm + ' from cache');
  9343              module.save.results(cache.results);
  9344              module.addResults(cache.html);
  9345            }
  9346            else {
  9347              module.debug('Querying for ' + searchTerm);
  9348              if($.isPlainObject(settings.source) || $.isArray(settings.source)) {
  9349                module.search.local(searchTerm);
  9350              }
  9351              else if( module.can.useAPI() ) {
  9352                if(settings.apiSettings) {
  9353                  module.debug('Searching with specified API settings', settings.apiSettings);
  9354                  module.search.remote(searchTerm);
  9355                }
  9356                else if($.api.settings.api.search !== undefined) {
  9357                  module.debug('Searching with default search API endpoint');
  9358                  module.search.remote(searchTerm);
  9359                }
  9360                else {
  9361                  module.error(error.noEndpoint);
  9362                }
  9363              }
  9364              else {
  9365                module.error(error.source);
  9366              }
  9367              settings.onSearchQuery.call(element, searchTerm);
  9368            }
  9369          },
  9370  
  9371          search: {
  9372            local: function(searchTerm) {
  9373              var
  9374                searchResults = module.search.object(searchTerm, settings.content),
  9375                searchHTML
  9376              ;
  9377              module.set.loading();
  9378              module.save.results(searchResults);
  9379              module.debug('Returned local search results', searchResults);
  9380  
  9381              searchHTML = module.generateResults({
  9382                results: searchResults
  9383              });
  9384              module.remove.loading();
  9385              module.write.cache(searchTerm, {
  9386                html    : searchHTML,
  9387                results : searchResults
  9388              });
  9389              module.addResults(searchHTML);
  9390            },
  9391            remote: function(searchTerm) {
  9392              var
  9393                apiSettings = {
  9394                  onSuccess : function(response) {
  9395                    module.parse.response.call(element, response, searchTerm);
  9396                  },
  9397                  urlData: {
  9398                    query: searchTerm
  9399                  }
  9400                }
  9401              ;
  9402              if( !$module.api('get request') ) {
  9403                module.setup.api();
  9404              }
  9405              $.extend(true, apiSettings, settings.apiSettings);
  9406              module.debug('Executing search', apiSettings);
  9407              module.cancel.query();
  9408              $module
  9409                .api('setting', apiSettings)
  9410                .api('query')
  9411              ;
  9412            },
  9413            object: function(searchTerm, source) {
  9414              var
  9415                results         = [],
  9416                fullTextResults = [],
  9417                searchFields    = $.isArray(settings.searchFields)
  9418                  ? settings.searchFields
  9419                  : [settings.searchFields],
  9420                searchExp       = searchTerm.replace(regExp.escape, '\\$&'),
  9421                searchRegExp    = new RegExp(regExp.exact + searchExp, 'i')
  9422              ;
  9423  
  9424              source = source || settings.source;
  9425  
  9426              // exit conditions on no source
  9427              if(source === undefined) {
  9428                module.error(error.source);
  9429                return [];
  9430              }
  9431  
  9432              // iterate through search fields in array order
  9433              $.each(searchFields, function(index, field) {
  9434                $.each(source, function(label, content) {
  9435                  var
  9436                    fieldExists = (typeof content[field] == 'string'),
  9437                    notAlreadyResult = ($.inArray(content, results) == -1 && $.inArray(content, fullTextResults) == -1)
  9438                  ;
  9439                  if(fieldExists && notAlreadyResult) {
  9440                    if( content[field].match(searchRegExp) ) {
  9441                      results.push(content);
  9442                    }
  9443                    else if(settings.searchFullText && module.fuzzySearch(searchTerm, content[field]) ) {
  9444                      fullTextResults.push(content);
  9445                    }
  9446                  }
  9447                });
  9448              });
  9449              return $.merge(results, fullTextResults);
  9450            }
  9451          },
  9452  
  9453          fuzzySearch: function(query, term) {
  9454            var
  9455              termLength  = term.length,
  9456              queryLength = query.length
  9457            ;
  9458            query = query.toLowerCase();
  9459            term  = term.toLowerCase();
  9460            if(queryLength > termLength) {
  9461              return false;
  9462            }
  9463            if(queryLength === termLength) {
  9464              return (query === term);
  9465            }
  9466            search: for (var characterIndex = 0, nextCharacterIndex = 0; characterIndex < queryLength; characterIndex++) {
  9467              var
  9468                queryCharacter = query.charCodeAt(characterIndex)
  9469              ;
  9470              while(nextCharacterIndex < termLength) {
  9471                if(term.charCodeAt(nextCharacterIndex++) === queryCharacter) {
  9472                  continue search;
  9473                }
  9474              }
  9475              return false;
  9476            }
  9477            return true;
  9478          },
  9479  
  9480          parse: {
  9481            response: function(response, searchTerm) {
  9482              var
  9483                searchHTML = module.generateResults(response)
  9484              ;
  9485              module.verbose('Parsing server response', response);
  9486              if(response !== undefined) {
  9487                if(searchTerm !== undefined && response.results !== undefined) {
  9488                  module.write.cache(searchTerm, {
  9489                    html    : searchHTML,
  9490                    results : response.results
  9491                  });
  9492                  module.save.results(response.results);
  9493                  module.addResults(searchHTML);
  9494                }
  9495              }
  9496            }
  9497          },
  9498  
  9499          throttle: function() {
  9500            clearTimeout(module.timer);
  9501            if(module.has.minimumCharacters())  {
  9502              module.timer = setTimeout(module.query, settings.searchDelay);
  9503            }
  9504            else {
  9505              module.hideResults();
  9506            }
  9507          },
  9508  
  9509          cancel: {
  9510            query: function() {
  9511              if( module.can.useAPI() ) {
  9512                $module.api('abort');
  9513              }
  9514            }
  9515          },
  9516  
  9517          has: {
  9518            minimumCharacters: function() {
  9519              var
  9520                searchTerm    = module.get.value(),
  9521                numCharacters = searchTerm.length
  9522              ;
  9523              return (numCharacters >= settings.minCharacters);
  9524            }
  9525          },
  9526  
  9527          read: {
  9528            cache: function(name) {
  9529              var
  9530                cache = $module.data(metadata.cache)
  9531              ;
  9532              if(settings.cache) {
  9533                module.verbose('Checking cache for generated html for query', name);
  9534                return (typeof cache == 'object') && (cache[name] !== undefined)
  9535                  ? cache[name]
  9536                  : false
  9537                ;
  9538              }
  9539              return false;
  9540            }
  9541          },
  9542  
  9543          save: {
  9544            results: function(results) {
  9545              module.verbose('Saving current search results to metadata', results);
  9546              $module.data(metadata.results, results);
  9547            }
  9548          },
  9549  
  9550          write: {
  9551            cache: function(name, value) {
  9552              var
  9553                cache = ($module.data(metadata.cache) !== undefined)
  9554                  ? $module.data(metadata.cache)
  9555                  : {}
  9556              ;
  9557              if(settings.cache) {
  9558                module.verbose('Writing generated html to cache', name, value);
  9559                cache[name] = value;
  9560                $module
  9561                  .data(metadata.cache, cache)
  9562                ;
  9563              }
  9564            }
  9565          },
  9566  
  9567          addResults: function(html) {
  9568            if( $.isFunction(settings.onResultsAdd) ) {
  9569              if( settings.onResultsAdd.call($results, html) === false ) {
  9570                module.debug('onResultsAdd callback cancelled default action');
  9571                return false;
  9572              }
  9573            }
  9574            $results
  9575              .html(html)
  9576            ;
  9577            module.showResults();
  9578          },
  9579  
  9580          showResults: function() {
  9581            if( !module.is.visible() && module.is.focused() && !module.is.empty() ) {
  9582              if( module.can.transition() ) {
  9583                module.debug('Showing results with css animations');
  9584                $results
  9585                  .transition({
  9586                    animation  : settings.transition + ' in',
  9587                    duration   : settings.duration,
  9588                    queue      : true
  9589                  })
  9590                ;
  9591              }
  9592              else {
  9593                module.debug('Showing results with javascript');
  9594                $results
  9595                  .stop()
  9596                  .fadeIn(settings.duration, settings.easing)
  9597                ;
  9598              }
  9599              settings.onResultsOpen.call($results);
  9600            }
  9601          },
  9602          hideResults: function() {
  9603            if( module.is.visible() ) {
  9604              if( module.can.transition() ) {
  9605                module.debug('Hiding results with css animations');
  9606                $results
  9607                  .transition({
  9608                    animation  : settings.transition + ' out',
  9609                    duration   : settings.duration,
  9610                    queue      : true
  9611                  })
  9612                ;
  9613              }
  9614              else {
  9615                module.debug('Hiding results with javascript');
  9616                $results
  9617                  .stop()
  9618                  .fadeOut(settings.duration, settings.easing)
  9619                ;
  9620              }
  9621              settings.onResultsClose.call($results);
  9622            }
  9623          },
  9624  
  9625          generateResults: function(response) {
  9626            module.debug('Generating html from response', response);
  9627            var
  9628              template       = settings.templates[settings.type],
  9629              isProperObject = ($.isPlainObject(response.results) && !$.isEmptyObject(response.results)),
  9630              isProperArray  = ($.isArray(response.results) && response.results.length > 0),
  9631              html           = ''
  9632            ;
  9633            if(isProperObject || isProperArray ) {
  9634              if(settings.maxResults > 0) {
  9635                if(isProperObject) {
  9636                  if(settings.type == 'standard') {
  9637                    module.error(error.maxResults);
  9638                  }
  9639                }
  9640                else {
  9641                  response.results = response.results.slice(0, settings.maxResults);
  9642                }
  9643              }
  9644              if($.isFunction(template)) {
  9645                html = template(response);
  9646              }
  9647              else {
  9648                module.error(error.noTemplate, false);
  9649              }
  9650            }
  9651            else {
  9652              html = module.displayMessage(error.noResults, 'empty');
  9653            }
  9654            settings.onResults.call(element, response);
  9655            return html;
  9656          },
  9657  
  9658          displayMessage: function(text, type) {
  9659            type = type || 'standard';
  9660            module.debug('Displaying message', text, type);
  9661            module.addResults( settings.templates.message(text, type) );
  9662            return settings.templates.message(text, type);
  9663          },
  9664  
  9665          setting: function(name, value) {
  9666            if( $.isPlainObject(name) ) {
  9667              $.extend(true, settings, name);
  9668            }
  9669            else if(value !== undefined) {
  9670              settings[name] = value;
  9671            }
  9672            else {
  9673              return settings[name];
  9674            }
  9675          },
  9676          internal: function(name, value) {
  9677            if( $.isPlainObject(name) ) {
  9678              $.extend(true, module, name);
  9679            }
  9680            else if(value !== undefined) {
  9681              module[name] = value;
  9682            }
  9683            else {
  9684              return module[name];
  9685            }
  9686          },
  9687          debug: function() {
  9688            if(settings.debug) {
  9689              if(settings.performance) {
  9690                module.performance.log(arguments);
  9691              }
  9692              else {
  9693                module.debug = Function.prototype.bind.call(console.info, console, settings.name + ':');
  9694                module.debug.apply(console, arguments);
  9695              }
  9696            }
  9697          },
  9698          verbose: function() {
  9699            if(settings.verbose && settings.debug) {
  9700              if(settings.performance) {
  9701                module.performance.log(arguments);
  9702              }
  9703              else {
  9704                module.verbose = Function.prototype.bind.call(console.info, console, settings.name + ':');
  9705                module.verbose.apply(console, arguments);
  9706              }
  9707            }
  9708          },
  9709          error: function() {
  9710            module.error = Function.prototype.bind.call(console.error, console, settings.name + ':');
  9711            module.error.apply(console, arguments);
  9712          },
  9713          performance: {
  9714            log: function(message) {
  9715              var
  9716                currentTime,
  9717                executionTime,
  9718                previousTime
  9719              ;
  9720              if(settings.performance) {
  9721                currentTime   = new Date().getTime();
  9722                previousTime  = time || currentTime;
  9723                executionTime = currentTime - previousTime;
  9724                time          = currentTime;
  9725                performance.push({
  9726                  'Name'           : message[0],
  9727                  'Arguments'      : [].slice.call(message, 1) || '',
  9728                  'Element'        : element,
  9729                  'Execution Time' : executionTime
  9730                });
  9731              }
  9732              clearTimeout(module.performance.timer);
  9733              module.performance.timer = setTimeout(module.performance.display, 100);
  9734            },
  9735            display: function() {
  9736              var
  9737                title = settings.name + ':',
  9738                totalTime = 0
  9739              ;
  9740              time = false;
  9741              clearTimeout(module.performance.timer);
  9742              $.each(performance, function(index, data) {
  9743                totalTime += data['Execution Time'];
  9744              });
  9745              title += ' ' + totalTime + 'ms';
  9746              if(moduleSelector) {
  9747                title += ' \'' + moduleSelector + '\'';
  9748              }
  9749              if($allModules.length > 1) {
  9750                title += ' ' + '(' + $allModules.length + ')';
  9751              }
  9752              if( (console.group !== undefined || console.table !== undefined) && performance.length > 0) {
  9753                console.groupCollapsed(title);
  9754                if(console.table) {
  9755                  console.table(performance);
  9756                }
  9757                else {
  9758                  $.each(performance, function(index, data) {
  9759                    console.log(data['Name'] + ': ' + data['Execution Time']+'ms');
  9760                  });
  9761                }
  9762                console.groupEnd();
  9763              }
  9764              performance = [];
  9765            }
  9766          },
  9767          invoke: function(query, passedArguments, context) {
  9768            var
  9769              object = instance,
  9770              maxDepth,
  9771              found,
  9772              response
  9773            ;
  9774            passedArguments = passedArguments || queryArguments;
  9775            context         = element         || context;
  9776            if(typeof query == 'string' && object !== undefined) {
  9777              query    = query.split(/[\. ]/);
  9778              maxDepth = query.length - 1;
  9779              $.each(query, function(depth, value) {
  9780                var camelCaseValue = (depth != maxDepth)
  9781                  ? value + query[depth + 1].charAt(0).toUpperCase() + query[depth + 1].slice(1)
  9782                  : query
  9783                ;
  9784                if( $.isPlainObject( object[camelCaseValue] ) && (depth != maxDepth) ) {
  9785                  object = object[camelCaseValue];
  9786                }
  9787                else if( object[camelCaseValue] !== undefined ) {
  9788                  found = object[camelCaseValue];
  9789                  return false;
  9790                }
  9791                else if( $.isPlainObject( object[value] ) && (depth != maxDepth) ) {
  9792                  object = object[value];
  9793                }
  9794                else if( object[value] !== undefined ) {
  9795                  found = object[value];
  9796                  return false;
  9797                }
  9798                else {
  9799                  return false;
  9800                }
  9801              });
  9802            }
  9803            if( $.isFunction( found ) ) {
  9804              response = found.apply(context, passedArguments);
  9805            }
  9806            else if(found !== undefined) {
  9807              response = found;
  9808            }
  9809            if($.isArray(returnedValue)) {
  9810              returnedValue.push(response);
  9811            }
  9812            else if(returnedValue !== undefined) {
  9813              returnedValue = [returnedValue, response];
  9814            }
  9815            else if(response !== undefined) {
  9816              returnedValue = response;
  9817            }
  9818            return found;
  9819          }
  9820        };
  9821        if(methodInvoked) {
  9822          if(instance === undefined) {
  9823            module.initialize();
  9824          }
  9825          module.invoke(query);
  9826        }
  9827        else {
  9828          if(instance !== undefined) {
  9829            instance.invoke('destroy');
  9830          }
  9831          module.initialize();
  9832        }
  9833  
  9834      })
  9835    ;
  9836  
  9837    return (returnedValue !== undefined)
  9838      ? returnedValue
  9839      : this
  9840    ;
  9841  };
  9842  
  9843  $.fn.search.settings = {
  9844  
  9845    name           : 'Search Module',
  9846    namespace      : 'search',
  9847  
  9848    debug          : false,
  9849    verbose        : true,
  9850    performance    : true,
  9851  
  9852    type           : 'standard',
  9853    minCharacters  : 1,
  9854  
  9855    // api config
  9856    apiSettings    : false,
  9857  
  9858    source         : false,
  9859    searchFields   : [
  9860      'title',
  9861      'description'
  9862    ],
  9863    searchFullText : true,
  9864  
  9865    automatic      : 'true',
  9866    hideDelay      : 0,
  9867    searchDelay    : 100,
  9868    maxResults     : 7,
  9869    cache          : true,
  9870  
  9871    transition     : 'scale',
  9872    duration       : 300,
  9873    easing         : 'easeOutExpo',
  9874  
  9875    onSelect       : false,
  9876    onResultsAdd   : false,
  9877  
  9878    onSearchQuery  : function(){},
  9879    onResults      : function(response){},
  9880  
  9881    onResultsOpen  : function(){},
  9882    onResultsClose : function(){},
  9883  
  9884    className: {
  9885      active  : 'active',
  9886      empty   : 'empty',
  9887      focus   : 'focus',
  9888      loading : 'loading',
  9889      pressed : 'down'
  9890    },
  9891  
  9892    error : {
  9893      source      : 'Cannot search. No source used, and Semantic API module was not included',
  9894      noResults   : 'Your search returned no results',
  9895      logging     : 'Error in debug logging, exiting.',
  9896      noEndpoint  : 'No search endpoint was specified',
  9897      noTemplate  : 'A valid template name was not specified.',
  9898      serverError : 'There was an issue with querying the server.',
  9899      maxResults  : 'Results must be an array to use maxResults setting',
  9900      method      : 'The method you called is not defined.'
  9901    },
  9902  
  9903    metadata: {
  9904      cache   : 'cache',
  9905      results : 'results'
  9906    },
  9907  
  9908    regExp: {
  9909      escape : /[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g,
  9910      exact  : '(?:\s|^)'
  9911    },
  9912  
  9913    selector : {
  9914      prompt       : '.prompt',
  9915      searchButton : '.search.button',
  9916      results      : '.results',
  9917      category     : '.category',
  9918      result       : '.result',
  9919      title        : '.title, .name'
  9920    },
  9921  
  9922    templates: {
  9923      escape: function(string) {
  9924        var
  9925          badChars     = /[&<>"'`]/g,
  9926          shouldEscape = /[&<>"'`]/,
  9927          escape       = {
  9928            "&": "&amp;",
  9929            "<": "&lt;",
  9930            ">": "&gt;",
  9931            '"': "&quot;",
  9932            "'": "&#x27;",
  9933            "`": "&#x60;"
  9934          },
  9935          escapedChar  = function(chr) {
  9936            return escape[chr];
  9937          }
  9938        ;
  9939        if(shouldEscape.test(string)) {
  9940          return string.replace(badChars, escapedChar);
  9941        }
  9942        return string;
  9943      },
  9944      message: function(message, type) {
  9945        var
  9946          html = ''
  9947        ;
  9948        if(message !== undefined && type !== undefined) {
  9949          html +=  ''
  9950            + '<div class="message ' + type + '">'
  9951          ;
  9952          // message type
  9953          if(type == 'empty') {
  9954            html += ''
  9955              + '<div class="header">No Results</div class="header">'
  9956              + '<div class="description">' + message + '</div class="description">'
  9957            ;
  9958          }
  9959          else {
  9960            html += ' <div class="description">' + message + '</div>';
  9961          }
  9962          html += '</div>';
  9963        }
  9964        return html;
  9965      },
  9966      category: function(response) {
  9967        var
  9968          html = '',
  9969          escape = $.fn.search.settings.templates.escape
  9970        ;
  9971        if(response.results !== undefined) {
  9972          // each category
  9973          $.each(response.results, function(index, category) {
  9974            if(category.results !== undefined && category.results.length > 0) {
  9975              html  += ''
  9976                + '<div class="category">'
  9977                + '<div class="name">' + category.name + '</div>'
  9978              ;
  9979              // each item inside category
  9980              $.each(category.results, function(index, result) {
  9981                html  += '<div class="result">';
  9982                if(result.url) {
  9983                  html  += '<a href="' + result.url + '"></a>';
  9984                }
  9985                if(result.image !== undefined) {
  9986                  result.image = escape(result.image);
  9987                  html += ''
  9988                    + '<div class="image">'
  9989                    + ' <img src="' + result.image + '" alt="">'
  9990                    + '</div>'
  9991                  ;
  9992                }
  9993                html += '<div class="content">';
  9994                if(result.price !== undefined) {
  9995                  result.price = escape(result.price);
  9996                  html += '<div class="price">' + result.price + '</div>';
  9997                }
  9998                if(result.title !== undefined) {
  9999                  result.title = escape(result.title);
 10000                  html += '<div class="title">' + result.title + '</div>';
 10001                }
 10002                if(result.description !== undefined) {
 10003                  html += '<div class="description">' + result.description + '</div>';
 10004                }
 10005                html  += ''
 10006                  + '</div>'
 10007                  + '</div>'
 10008                ;
 10009              });
 10010              html  += ''
 10011                + '</div>'
 10012              ;
 10013            }
 10014          });
 10015          if(response.action) {
 10016            html += ''
 10017            + '<a href="' + response.action.url + '" class="action">'
 10018            +   response.action.text
 10019            + '</a>';
 10020          }
 10021          return html;
 10022        }
 10023        return false;
 10024      },
 10025      standard: function(response) {
 10026        var
 10027          html = ''
 10028        ;
 10029        if(response.results !== undefined) {
 10030  
 10031          // each result
 10032          $.each(response.results, function(index, result) {
 10033            if(result.url) {
 10034              html  += '<a class="result" href="' + result.url + '">';
 10035            }
 10036            else {
 10037              html  += '<a class="result">';
 10038            }
 10039            if(result.image !== undefined) {
 10040              html += ''
 10041                + '<div class="image">'
 10042                + ' <img src="' + result.image + '">'
 10043                + '</div>'
 10044              ;
 10045            }
 10046            html += '<div class="content">';
 10047            if(result.price !== undefined) {
 10048              html += '<div class="price">' + result.price + '</div>';
 10049            }
 10050            if(result.title !== undefined) {
 10051              html += '<div class="title">' + result.title + '</div>';
 10052            }
 10053            if(result.description !== undefined) {
 10054              html += '<div class="description">' + result.description + '</div>';
 10055            }
 10056            html  += ''
 10057              + '</div>'
 10058            ;
 10059            html += '</a>';
 10060          });
 10061  
 10062          if(response.action) {
 10063            html += ''
 10064            + '<a href="' + response.action.url + '" class="action">'
 10065            +   response.action.text
 10066            + '</a>';
 10067          }
 10068          return html;
 10069        }
 10070        return false;
 10071      }
 10072    }
 10073  };
 10074  
 10075  })( jQuery, window , document );
 10076  
 10077  /*!
 10078   * # Semantic UI x.x - Shape
 10079   * http://github.com/semantic-org/semantic-ui/
 10080   *
 10081   *
 10082   * Copyright 2014 Contributors
 10083   * Released under the MIT license
 10084   * http://opensource.org/licenses/MIT
 10085   *
 10086   */
 10087  
 10088  ;(function ( $, window, document, undefined ) {
 10089  
 10090  "use strict";
 10091  
 10092  $.fn.shape = function(parameters) {
 10093    var
 10094      $allModules     = $(this),
 10095      $body           = $('body'),
 10096  
 10097      time            = new Date().getTime(),
 10098      performance     = [],
 10099  
 10100      query           = arguments[0],
 10101      methodInvoked   = (typeof query == 'string'),
 10102      queryArguments  = [].slice.call(arguments, 1),
 10103  
 10104      requestAnimationFrame = window.requestAnimationFrame
 10105        || window.mozRequestAnimationFrame
 10106        || window.webkitRequestAnimationFrame
 10107        || window.msRequestAnimationFrame
 10108        || function(callback) { setTimeout(callback, 0); },
 10109  
 10110      returnedValue
 10111    ;
 10112  
 10113    $allModules
 10114      .each(function() {
 10115        var
 10116          moduleSelector  = $allModules.selector || '',
 10117          settings        = $.extend(true, {}, $.fn.shape.settings, parameters),
 10118  
 10119          // internal aliases
 10120          namespace     = settings.namespace,
 10121          selector      = settings.selector,
 10122          error         = settings.error,
 10123          className     = settings.className,
 10124  
 10125          // define namespaces for modules
 10126          eventNamespace  = '.' + namespace,
 10127          moduleNamespace = 'module-' + namespace,
 10128  
 10129          // selector cache
 10130          $module       = $(this),
 10131          $sides        = $module.find(selector.sides),
 10132          $side         = $module.find(selector.side),
 10133  
 10134          // private variables
 10135          nextIndex = false,
 10136          $activeSide,
 10137          $nextSide,
 10138  
 10139          // standard module
 10140          element       = this,
 10141          instance      = $module.data(moduleNamespace),
 10142          module
 10143        ;
 10144  
 10145        module = {
 10146  
 10147          initialize: function() {
 10148            module.verbose('Initializing module for', element);
 10149            module.set.defaultSide();
 10150            module.instantiate();
 10151          },
 10152  
 10153          instantiate: function() {
 10154            module.verbose('Storing instance of module', module);
 10155            instance = module;
 10156            $module
 10157              .data(moduleNamespace, instance)
 10158            ;
 10159          },
 10160  
 10161          destroy: function() {
 10162            module.verbose('Destroying previous module for', element);
 10163            $module
 10164              .removeData(moduleNamespace)
 10165              .off(eventNamespace)
 10166            ;
 10167          },
 10168  
 10169          refresh: function() {
 10170            module.verbose('Refreshing selector cache for', element);
 10171            $module = $(element);
 10172            $sides  = $(this).find(selector.shape);
 10173            $side   = $(this).find(selector.side);
 10174          },
 10175  
 10176          repaint: function() {
 10177            module.verbose('Forcing repaint event');
 10178            var
 10179              shape          = $sides.get(0) || document.createElement('div'),
 10180              fakeAssignment = shape.offsetWidth
 10181            ;
 10182          },
 10183  
 10184          animate: function(propertyObject, callback) {
 10185            module.verbose('Animating box with properties', propertyObject);
 10186            callback = callback || function(event) {
 10187              module.verbose('Executing animation callback');
 10188              if(event !== undefined) {
 10189                event.stopPropagation();
 10190              }
 10191              module.reset();
 10192              module.set.active();
 10193            };
 10194            settings.beforeChange.call($nextSide.get());
 10195            if(module.get.transitionEvent()) {
 10196              module.verbose('Starting CSS animation');
 10197              $module
 10198                .addClass(className.animating)
 10199              ;
 10200              $sides
 10201                .css(propertyObject)
 10202                .one(module.get.transitionEvent(), callback)
 10203              ;
 10204              module.set.duration(settings.duration);
 10205              requestAnimationFrame(function() {
 10206                $module
 10207                  .addClass(className.animating)
 10208                ;
 10209                $activeSide
 10210                  .addClass(className.hidden)
 10211                ;
 10212              });
 10213            }
 10214            else {
 10215              callback();
 10216            }
 10217          },
 10218  
 10219          queue: function(method) {
 10220            module.debug('Queueing animation of', method);
 10221            $sides
 10222              .one(module.get.transitionEvent(), function() {
 10223                module.debug('Executing queued animation');
 10224                setTimeout(function(){
 10225                  $module.shape(method);
 10226                }, 0);
 10227              })
 10228            ;
 10229          },
 10230  
 10231          reset: function() {
 10232            module.verbose('Animating states reset');
 10233            $module
 10234              .removeClass(className.animating)
 10235              .attr('style', '')
 10236              .removeAttr('style')
 10237            ;
 10238            // removeAttr style does not consistently work in safari
 10239            $sides
 10240              .attr('style', '')
 10241              .removeAttr('style')
 10242            ;
 10243            $side
 10244              .attr('style', '')
 10245              .removeAttr('style')
 10246              .removeClass(className.hidden)
 10247            ;
 10248            $nextSide
 10249              .removeClass(className.animating)
 10250              .attr('style', '')
 10251              .removeAttr('style')
 10252            ;
 10253          },
 10254  
 10255          is: {
 10256            complete: function() {
 10257              return ($side.filter('.' + className.active)[0] == $nextSide[0]);
 10258            },
 10259            animating: function() {
 10260              return $module.hasClass(className.animating);
 10261            }
 10262          },
 10263  
 10264          set: {
 10265  
 10266            defaultSide: function() {
 10267              $activeSide = $module.find('.' + settings.className.active);
 10268              $nextSide   = ( $activeSide.next(selector.side).length > 0 )
 10269                ? $activeSide.next(selector.side)
 10270                : $module.find(selector.side).first()
 10271              ;
 10272              nextIndex = false;
 10273              module.verbose('Active side set to', $activeSide);
 10274              module.verbose('Next side set to', $nextSide);
 10275            },
 10276  
 10277            duration: function(duration) {
 10278              duration = duration || settings.duration;
 10279              duration = (typeof duration == 'number')
 10280                ? duration + 'ms'
 10281                : duration
 10282              ;
 10283              module.verbose('Setting animation duration', duration);
 10284              $sides.add($side)
 10285                .css({
 10286                  '-webkit-transition-duration': duration,
 10287                  '-moz-transition-duration': duration,
 10288                  '-ms-transition-duration': duration,
 10289                  '-o-transition-duration': duration,
 10290                  'transition-duration': duration
 10291                })
 10292              ;
 10293            },
 10294  
 10295            stageSize: function() {
 10296              var
 10297                $clone      = $module.clone().addClass(className.loading),
 10298                $activeSide = $clone.find('.' + settings.className.active),
 10299                $nextSide   = (nextIndex)
 10300                  ? $clone.find(selector.side).eq(nextIndex)
 10301                  : ( $activeSide.next(selector.side).length > 0 )
 10302                    ? $activeSide.next(selector.side)
 10303                    : $clone.find(selector.side).first(),
 10304                newSize = {}
 10305              ;
 10306              $activeSide.removeClass(className.active);
 10307              $nextSide.addClass(className.active);
 10308              $clone.insertAfter($module);
 10309              newSize = {
 10310                width  : $nextSide.outerWidth(),
 10311                height : $nextSide.outerHeight()
 10312              };
 10313              $clone.remove();
 10314              $module
 10315                .css(newSize)
 10316              ;
 10317              module.verbose('Resizing stage to fit new content', newSize);
 10318            },
 10319  
 10320            nextSide: function(selector) {
 10321              nextIndex = selector;
 10322              $nextSide = $side.filter(selector);
 10323              nextIndex = $side.index($nextSide);
 10324              if($nextSide.length === 0) {
 10325                module.set.defaultSide();
 10326                module.error(error.side);
 10327              }
 10328              module.verbose('Next side manually set to', $nextSide);
 10329            },
 10330  
 10331            active: function() {
 10332              module.verbose('Setting new side to active', $nextSide);
 10333              $side
 10334                .removeClass(className.active)
 10335              ;
 10336              $nextSide
 10337                .addClass(className.active)
 10338              ;
 10339              settings.onChange.call($nextSide.get());
 10340              module.set.defaultSide();
 10341            }
 10342          },
 10343  
 10344          flip: {
 10345  
 10346            up: function() {
 10347              if(module.is.complete() && !module.is.animating() && !settings.allowRepeats) {
 10348                module.debug('Side already visible', $nextSide);
 10349                return;
 10350              }
 10351              if( !module.is.animating()) {
 10352                module.debug('Flipping up', $nextSide);
 10353                module.set.stageSize();
 10354                module.stage.above();
 10355                module.animate( module.get.transform.up() );
 10356              }
 10357              else {
 10358                module.queue('flip up');
 10359              }
 10360            },
 10361  
 10362            down: function() {
 10363              if(module.is.complete() && !module.is.animating() && !settings.allowRepeats) {
 10364                module.debug('Side already visible', $nextSide);
 10365                return;
 10366              }
 10367              if( !module.is.animating()) {
 10368                module.debug('Flipping down', $nextSide);
 10369                module.set.stageSize();
 10370                module.stage.below();
 10371                module.animate( module.get.transform.down() );
 10372              }
 10373              else {
 10374                module.queue('flip down');
 10375              }
 10376            },
 10377  
 10378            left: function() {
 10379              if(module.is.complete() && !module.is.animating() && !settings.allowRepeats) {
 10380                module.debug('Side already visible', $nextSide);
 10381                return;
 10382              }
 10383              if( !module.is.animating()) {
 10384                module.debug('Flipping left', $nextSide);
 10385                module.set.stageSize();
 10386                module.stage.left();
 10387                module.animate(module.get.transform.left() );
 10388              }
 10389              else {
 10390                module.queue('flip left');
 10391              }
 10392            },
 10393  
 10394            right: function() {
 10395              if(module.is.complete() && !module.is.animating() && !settings.allowRepeats) {
 10396                module.debug('Side already visible', $nextSide);
 10397                return;
 10398              }
 10399              if( !module.is.animating()) {
 10400                module.debug('Flipping right', $nextSide);
 10401                module.set.stageSize();
 10402                module.stage.right();
 10403                module.animate(module.get.transform.right() );
 10404              }
 10405              else {
 10406                module.queue('flip right');
 10407              }
 10408            },
 10409  
 10410            over: function() {
 10411              if(module.is.complete() && !module.is.animating() && !settings.allowRepeats) {
 10412                module.debug('Side already visible', $nextSide);
 10413                return;
 10414              }
 10415              if( !module.is.animating()) {
 10416                module.debug('Flipping over', $nextSide);
 10417                module.set.stageSize();
 10418                module.stage.behind();
 10419                module.animate(module.get.transform.over() );
 10420              }
 10421              else {
 10422                module.queue('flip over');
 10423              }
 10424            },
 10425  
 10426            back: function() {
 10427              if(module.is.complete() && !module.is.animating() && !settings.allowRepeats) {
 10428                module.debug('Side already visible', $nextSide);
 10429                return;
 10430              }
 10431              if( !module.is.animating()) {
 10432                module.debug('Flipping back', $nextSide);
 10433                module.set.stageSize();
 10434                module.stage.behind();
 10435                module.animate(module.get.transform.back() );
 10436              }
 10437              else {
 10438                module.queue('flip back');
 10439              }
 10440            }
 10441  
 10442          },
 10443  
 10444          get: {
 10445  
 10446            transform: {
 10447              up: function() {
 10448                var
 10449                  translate = {
 10450                    y: -(($activeSide.outerHeight() - $nextSide.outerHeight()) / 2),
 10451                    z: -($activeSide.outerHeight() / 2)
 10452                  }
 10453                ;
 10454                return {
 10455                  transform: 'translateY(' + translate.y + 'px) translateZ('+ translate.z + 'px) rotateX(-90deg)'
 10456                };
 10457              },
 10458  
 10459              down: function() {
 10460                var
 10461                  translate = {
 10462                    y: -(($activeSide.outerHeight() - $nextSide.outerHeight()) / 2),
 10463                    z: -($activeSide.outerHeight() / 2)
 10464                  }
 10465                ;
 10466                return {
 10467                  transform: 'translateY(' + translate.y + 'px) translateZ('+ translate.z + 'px) rotateX(90deg)'
 10468                };
 10469              },
 10470  
 10471              left: function() {
 10472                var
 10473                  translate = {
 10474                    x : -(($activeSide.outerWidth() - $nextSide.outerWidth()) / 2),
 10475                    z : -($activeSide.outerWidth() / 2)
 10476                  }
 10477                ;
 10478                return {
 10479                  transform: 'translateX(' + translate.x + 'px) translateZ(' + translate.z + 'px) rotateY(90deg)'
 10480                };
 10481              },
 10482  
 10483              right: function() {
 10484                var
 10485                  translate = {
 10486                    x : -(($activeSide.outerWidth() - $nextSide.outerWidth()) / 2),
 10487                    z : -($activeSide.outerWidth() / 2)
 10488                  }
 10489                ;
 10490                return {
 10491                  transform: 'translateX(' + translate.x + 'px) translateZ(' + translate.z + 'px) rotateY(-90deg)'
 10492                };
 10493              },
 10494  
 10495              over: function() {
 10496                var
 10497                  translate = {
 10498                    x : -(($activeSide.outerWidth() - $nextSide.outerWidth()) / 2)
 10499                  }
 10500                ;
 10501                return {
 10502                  transform: 'translateX(' + translate.x + 'px) rotateY(180deg)'
 10503                };
 10504              },
 10505  
 10506              back: function() {
 10507                var
 10508                  translate = {
 10509                    x : -(($activeSide.outerWidth() - $nextSide.outerWidth()) / 2)
 10510                  }
 10511                ;
 10512                return {
 10513                  transform: 'translateX(' + translate.x + 'px) rotateY(-180deg)'
 10514                };
 10515              }
 10516            },
 10517  
 10518            transitionEvent: function() {
 10519              var
 10520                element     = document.createElement('element'),
 10521                transitions = {
 10522                  'transition'       :'transitionend',
 10523                  'OTransition'      :'oTransitionEnd',
 10524                  'MozTransition'    :'transitionend',
 10525                  'WebkitTransition' :'webkitTransitionEnd'
 10526                },
 10527                transition
 10528              ;
 10529              for(transition in transitions){
 10530                if( element.style[transition] !== undefined ){
 10531                  return transitions[transition];
 10532                }
 10533              }
 10534            },
 10535  
 10536            nextSide: function() {
 10537              return ( $activeSide.next(selector.side).length > 0 )
 10538                ? $activeSide.next(selector.side)
 10539                : $module.find(selector.side).first()
 10540              ;
 10541            }
 10542  
 10543          },
 10544  
 10545          stage: {
 10546  
 10547            above: function() {
 10548              var
 10549                box = {
 10550                  origin : (($activeSide.outerHeight() - $nextSide.outerHeight()) / 2),
 10551                  depth  : {
 10552                    active : ($nextSide.outerHeight() / 2),
 10553                    next   : ($activeSide.outerHeight() / 2)
 10554                  }
 10555                }
 10556              ;
 10557              module.verbose('Setting the initial animation position as above', $nextSide, box);
 10558              $activeSide
 10559                .css({
 10560                  'transform' : 'rotateY(0deg) translateZ(' + box.depth.active + 'px)'
 10561                })
 10562              ;
 10563              $nextSide
 10564                .addClass(className.animating)
 10565                .css({
 10566                  'display'   : 'block',
 10567                  'top'       : box.origin + 'px',
 10568                  'transform' : 'rotateX(90deg) translateZ(' + box.depth.next + 'px)'
 10569                })
 10570              ;
 10571            },
 10572  
 10573            below: function() {
 10574              var
 10575                box = {
 10576                  origin : (($activeSide.outerHeight() - $nextSide.outerHeight()) / 2),
 10577                  depth  : {
 10578                    active : ($nextSide.outerHeight() / 2),
 10579                    next   : ($activeSide.outerHeight() / 2)
 10580                  }
 10581                }
 10582              ;
 10583              module.verbose('Setting the initial animation position as below', $nextSide, box);
 10584              $activeSide
 10585                .css({
 10586                  'transform' : 'rotateY(0deg) translateZ(' + box.depth.active + 'px)'
 10587                })
 10588              ;
 10589              $nextSide
 10590                .addClass(className.animating)
 10591                .css({
 10592                  'display'   : 'block',
 10593                  'top'       : box.origin + 'px',
 10594                  'transform' : 'rotateX(-90deg) translateZ(' + box.depth.next + 'px)'
 10595                })
 10596              ;
 10597            },
 10598  
 10599            left: function() {
 10600              var
 10601                box = {
 10602                  origin : ( ( $activeSide.outerWidth() - $nextSide.outerWidth() ) / 2),
 10603                  depth  : {
 10604                    active : ($nextSide.outerWidth() / 2),
 10605                    next   : ($activeSide.outerWidth() / 2)
 10606                  }
 10607                }
 10608              ;
 10609              module.verbose('Setting the initial animation position as left', $nextSide, box);
 10610              $activeSide
 10611                .css({
 10612                  'transform' : 'rotateY(0deg) translateZ(' + box.depth.active + 'px)'
 10613                })
 10614              ;
 10615              $nextSide
 10616                .addClass(className.animating)
 10617                .css({
 10618                  'display'   : 'block',
 10619                  'left'      : box.origin + 'px',
 10620                  'transform' : 'rotateY(-90deg) translateZ(' + box.depth.next + 'px)'
 10621                })
 10622              ;
 10623            },
 10624  
 10625            right: function() {
 10626              var
 10627                box = {
 10628                  origin : ( ( $activeSide.outerWidth() - $nextSide.outerWidth() ) / 2),
 10629                  depth  : {
 10630                    active : ($nextSide.outerWidth() / 2),
 10631                    next   : ($activeSide.outerWidth() / 2)
 10632                  }
 10633                }
 10634              ;
 10635              module.verbose('Setting the initial animation position as left', $nextSide, box);
 10636              $activeSide
 10637                .css({
 10638                  'transform' : 'rotateY(0deg) translateZ(' + box.depth.active + 'px)'
 10639                })
 10640              ;
 10641              $nextSide
 10642                .addClass(className.animating)
 10643                .css({
 10644                  'display'   : 'block',
 10645                  'left'      : box.origin + 'px',
 10646                  'transform' : 'rotateY(90deg) translateZ(' + box.depth.next + 'px)'
 10647                })
 10648              ;
 10649            },
 10650  
 10651            behind: function() {
 10652              var
 10653                box = {
 10654                  origin : ( ( $activeSide.outerWidth() - $nextSide.outerWidth() ) / 2),
 10655                  depth  : {
 10656                    active : ($nextSide.outerWidth() / 2),
 10657                    next   : ($activeSide.outerWidth() / 2)
 10658                  }
 10659                }
 10660              ;
 10661              module.verbose('Setting the initial animation position as behind', $nextSide, box);
 10662              $activeSide
 10663                .css({
 10664                  'transform' : 'rotateY(0deg)'
 10665                })
 10666              ;
 10667              $nextSide
 10668                .addClass(className.animating)
 10669                .css({
 10670                  'display'   : 'block',
 10671                  'left'      : box.origin + 'px',
 10672                  'transform' : 'rotateY(-180deg)'
 10673                })
 10674              ;
 10675            }
 10676          },
 10677          setting: function(name, value) {
 10678            module.debug('Changing setting', name, value);
 10679            if( $.isPlainObject(name) ) {
 10680              $.extend(true, settings, name);
 10681            }
 10682            else if(value !== undefined) {
 10683              settings[name] = value;
 10684            }
 10685            else {
 10686              return settings[name];
 10687            }
 10688          },
 10689          internal: function(name, value) {
 10690            if( $.isPlainObject(name) ) {
 10691              $.extend(true, module, name);
 10692            }
 10693            else if(value !== undefined) {
 10694              module[name] = value;
 10695            }
 10696            else {
 10697              return module[name];
 10698            }
 10699          },
 10700          debug: function() {
 10701            if(settings.debug) {
 10702              if(settings.performance) {
 10703                module.performance.log(arguments);
 10704              }
 10705              else {
 10706                module.debug = Function.prototype.bind.call(console.info, console, settings.name + ':');
 10707                module.debug.apply(console, arguments);
 10708              }
 10709            }
 10710          },
 10711          verbose: function() {
 10712            if(settings.verbose && settings.debug) {
 10713              if(settings.performance) {
 10714                module.performance.log(arguments);
 10715              }
 10716              else {
 10717                module.verbose = Function.prototype.bind.call(console.info, console, settings.name + ':');
 10718                module.verbose.apply(console, arguments);
 10719              }
 10720            }
 10721          },
 10722          error: function() {
 10723            module.error = Function.prototype.bind.call(console.error, console, settings.name + ':');
 10724            module.error.apply(console, arguments);
 10725          },
 10726          performance: {
 10727            log: function(message) {
 10728              var
 10729                currentTime,
 10730                executionTime,
 10731                previousTime
 10732              ;
 10733              if(settings.performance) {
 10734                currentTime   = new Date().getTime();
 10735                previousTime  = time || currentTime;
 10736                executionTime = currentTime - previousTime;
 10737                time          = currentTime;
 10738                performance.push({
 10739                  'Name'           : message[0],
 10740                  'Arguments'      : [].slice.call(message, 1) || '',
 10741                  'Element'        : element,
 10742                  'Execution Time' : executionTime
 10743                });
 10744              }
 10745              clearTimeout(module.performance.timer);
 10746              module.performance.timer = setTimeout(module.performance.display, 100);
 10747            },
 10748            display: function() {
 10749              var
 10750                title = settings.name + ':',
 10751                totalTime = 0
 10752              ;
 10753              time = false;
 10754              clearTimeout(module.performance.timer);
 10755              $.each(performance, function(index, data) {
 10756                totalTime += data['Execution Time'];
 10757              });
 10758              title += ' ' + totalTime + 'ms';
 10759              if(moduleSelector) {
 10760                title += ' \'' + moduleSelector + '\'';
 10761              }
 10762              if($allModules.length > 1) {
 10763                title += ' ' + '(' + $allModules.length + ')';
 10764              }
 10765              if( (console.group !== undefined || console.table !== undefined) && performance.length > 0) {
 10766                console.groupCollapsed(title);
 10767                if(console.table) {
 10768                  console.table(performance);
 10769                }
 10770                else {
 10771                  $.each(performance, function(index, data) {
 10772                    console.log(data['Name'] + ': ' + data['Execution Time']+'ms');
 10773                  });
 10774                }
 10775                console.groupEnd();
 10776              }
 10777              performance = [];
 10778            }
 10779          },
 10780          invoke: function(query, passedArguments, context) {
 10781            var
 10782              object = instance,
 10783              maxDepth,
 10784              found,
 10785              response
 10786            ;
 10787            passedArguments = passedArguments || queryArguments;
 10788            context         = element         || context;
 10789            if(typeof query == 'string' && object !== undefined) {
 10790              query    = query.split(/[\. ]/);
 10791              maxDepth = query.length - 1;
 10792              $.each(query, function(depth, value) {
 10793                var camelCaseValue = (depth != maxDepth)
 10794                  ? value + query[depth + 1].charAt(0).toUpperCase() + query[depth + 1].slice(1)
 10795                  : query
 10796                ;
 10797                if( $.isPlainObject( object[camelCaseValue] ) && (depth != maxDepth) ) {
 10798                  object = object[camelCaseValue];
 10799                }
 10800                else if( object[camelCaseValue] !== undefined ) {
 10801                  found = object[camelCaseValue];
 10802                  return false;
 10803                }
 10804                else if( $.isPlainObject( object[value] ) && (depth != maxDepth) ) {
 10805                  object = object[value];
 10806                }
 10807                else if( object[value] !== undefined ) {
 10808                  found = object[value];
 10809                  return false;
 10810                }
 10811                else {
 10812                  return false;
 10813                }
 10814              });
 10815            }
 10816            if ( $.isFunction( found ) ) {
 10817              response = found.apply(context, passedArguments);
 10818            }
 10819            else if(found !== undefined) {
 10820              response = found;
 10821            }
 10822            if($.isArray(returnedValue)) {
 10823              returnedValue.push(response);
 10824            }
 10825            else if(returnedValue !== undefined) {
 10826              returnedValue = [returnedValue, response];
 10827            }
 10828            else if(response !== undefined) {
 10829              returnedValue = response;
 10830            }
 10831            return found;
 10832          }
 10833        };
 10834  
 10835        if(methodInvoked) {
 10836          if(instance === undefined) {
 10837            module.initialize();
 10838          }
 10839          module.invoke(query);
 10840        }
 10841        else {
 10842          if(instance !== undefined) {
 10843            instance.invoke('destroy');
 10844          }
 10845          module.initialize();
 10846        }
 10847      })
 10848    ;
 10849  
 10850    return (returnedValue !== undefined)
 10851      ? returnedValue
 10852      : this
 10853    ;
 10854  };
 10855  
 10856  $.fn.shape.settings = {
 10857  
 10858    // module info
 10859    name : 'Shape',
 10860  
 10861    // debug content outputted to console
 10862    debug      : false,
 10863  
 10864    // verbose debug output
 10865    verbose    : true,
 10866  
 10867    // performance data output
 10868    performance: true,
 10869  
 10870    // event namespace
 10871    namespace  : 'shape',
 10872  
 10873    // callback occurs on side change
 10874    beforeChange : function() {},
 10875    onChange     : function() {},
 10876  
 10877    // allow animation to same side
 10878    allowRepeats: false,
 10879  
 10880    // animation duration
 10881    duration   : 700,
 10882  
 10883    // possible errors
 10884    error: {
 10885      side   : 'You tried to switch to a side that does not exist.',
 10886      method : 'The method you called is not defined'
 10887    },
 10888  
 10889    // classnames used
 10890    className   : {
 10891      animating : 'animating',
 10892      hidden    : 'hidden',
 10893      loading   : 'loading',
 10894      active    : 'active'
 10895    },
 10896  
 10897    // selectors used
 10898    selector    : {
 10899      sides : '.sides',
 10900      side  : '.side'
 10901    }
 10902  
 10903  };
 10904  
 10905  
 10906  })( jQuery, window , document );
 10907  /*!
 10908   * # Semantic UI x.x - Sidebar
 10909   * http://github.com/semantic-org/semantic-ui/
 10910   *
 10911   *
 10912   * Copyright 2014 Contributors
 10913   * Released under the MIT license
 10914   * http://opensource.org/licenses/MIT
 10915   *
 10916   */
 10917  
 10918  ;(function ( $, window, document, undefined ) {
 10919  
 10920  "use strict";
 10921  
 10922  $.fn.sidebar = function(parameters) {
 10923    var
 10924      $allModules     = $(this),
 10925      $window         = $(window),
 10926      $document       = $(document),
 10927      $html           = $('html'),
 10928      $head           = $('head'),
 10929  
 10930      moduleSelector  = $allModules.selector || '',
 10931  
 10932      time            = new Date().getTime(),
 10933      performance     = [],
 10934  
 10935      query           = arguments[0],
 10936      methodInvoked   = (typeof query == 'string'),
 10937      queryArguments  = [].slice.call(arguments, 1),
 10938  
 10939      requestAnimationFrame = window.requestAnimationFrame
 10940        || window.mozRequestAnimationFrame
 10941        || window.webkitRequestAnimationFrame
 10942        || window.msRequestAnimationFrame
 10943        || function(callback) { setTimeout(callback, 0); },
 10944  
 10945      returnedValue
 10946    ;
 10947  
 10948    $allModules
 10949      .each(function() {
 10950        var
 10951          settings        = ( $.isPlainObject(parameters) )
 10952            ? $.extend(true, {}, $.fn.sidebar.settings, parameters)
 10953            : $.extend({}, $.fn.sidebar.settings),
 10954  
 10955          selector        = settings.selector,
 10956          className       = settings.className,
 10957          namespace       = settings.namespace,
 10958          regExp          = settings.regExp,
 10959          error           = settings.error,
 10960  
 10961          eventNamespace  = '.' + namespace,
 10962          moduleNamespace = 'module-' + namespace,
 10963  
 10964          $module         = $(this),
 10965          $context        = $(settings.context),
 10966  
 10967          $sidebars       = $module.children(selector.sidebar),
 10968          $fixed          = $context.children(selector.fixed),
 10969          $pusher         = $context.children(selector.pusher),
 10970          $style,
 10971  
 10972          element         = this,
 10973          instance        = $module.data(moduleNamespace),
 10974  
 10975          elementNamespace,
 10976          id,
 10977          currentScroll,
 10978          transitionEvent,
 10979  
 10980          module
 10981        ;
 10982  
 10983        module      = {
 10984  
 10985          initialize: function() {
 10986            module.debug('Initializing sidebar', parameters);
 10987  
 10988            module.create.id();
 10989  
 10990            transitionEvent = module.get.transitionEvent();
 10991  
 10992            // cache on initialize
 10993            if( ( settings.useLegacy == 'auto' && module.is.legacy() ) || settings.useLegacy === true) {
 10994              settings.transition = 'overlay';
 10995              settings.useLegacy = true;
 10996            }
 10997  
 10998            if(module.is.ios()) {
 10999              module.set.ios();
 11000            }
 11001  
 11002            // avoids locking rendering if initialized in onReady
 11003            if(settings.delaySetup) {
 11004              requestAnimationFrame(module.setup.layout);
 11005            }
 11006            else {
 11007              module.setup.layout();
 11008            }
 11009  
 11010            module.instantiate();
 11011          },
 11012  
 11013          instantiate: function() {
 11014            module.verbose('Storing instance of module', module);
 11015            instance = module;
 11016            $module
 11017              .data(moduleNamespace, module)
 11018            ;
 11019          },
 11020  
 11021          create: {
 11022            id: function() {
 11023              id = (Math.random().toString(16) + '000000000').substr(2,8);
 11024              elementNamespace = '.' + id;
 11025              module.verbose('Creating unique id for element', id);
 11026            }
 11027          },
 11028  
 11029          destroy: function() {
 11030            module.verbose('Destroying previous module for', $module);
 11031            module.remove.direction();
 11032            $module
 11033              .off(eventNamespace)
 11034              .removeData(moduleNamespace)
 11035            ;
 11036            // bound by uuid
 11037            $context.off(elementNamespace);
 11038            $window.off(elementNamespace);
 11039            $document.off(elementNamespace);
 11040          },
 11041  
 11042          event: {
 11043            clickaway: function(event) {
 11044              var
 11045                clickedInPusher = ($pusher.find(event.target).length > 0 || $pusher.is(event.target)),
 11046                clickedContext  = ($context.is(event.target))
 11047              ;
 11048              if(clickedInPusher) {
 11049                module.verbose('User clicked on dimmed page');
 11050                module.hide();
 11051              }
 11052              if(clickedContext) {
 11053                module.verbose('User clicked on dimmable context (scaled out page)');
 11054                module.hide();
 11055              }
 11056            },
 11057            touch: function(event) {
 11058              //event.stopPropagation();
 11059            },
 11060            containScroll: function(event) {
 11061              if(element.scrollTop <= 0)  {
 11062                element.scrollTop = 1;
 11063              }
 11064              if((element.scrollTop + element.offsetHeight) >= element.scrollHeight) {
 11065                element.scrollTop = element.scrollHeight - element.offsetHeight - 1;
 11066              }
 11067            },
 11068            scroll: function(event) {
 11069              if( $(event.target).closest(selector.sidebar).length === 0 ) {
 11070                event.preventDefault();
 11071              }
 11072            }
 11073          },
 11074  
 11075          bind: {
 11076            clickaway: function() {
 11077              module.verbose('Adding clickaway events to context', $context);
 11078              if(settings.closable) {
 11079                $context
 11080                  .on('click' + elementNamespace, module.event.clickaway)
 11081                  .on('touchend' + elementNamespace, module.event.clickaway)
 11082                ;
 11083              }
 11084            },
 11085            scrollLock: function() {
 11086              if(settings.scrollLock) {
 11087                module.debug('Disabling page scroll');
 11088                $window
 11089                  .on('DOMMouseScroll' + elementNamespace, module.event.scroll)
 11090                ;
 11091              }
 11092              module.verbose('Adding events to contain sidebar scroll');
 11093              $document
 11094                .on('touchmove' + elementNamespace, module.event.touch)
 11095              ;
 11096              $module
 11097                .on('scroll' + eventNamespace, module.event.containScroll)
 11098              ;
 11099            }
 11100          },
 11101          unbind: {
 11102            clickaway: function() {
 11103              module.verbose('Removing clickaway events from context', $context);
 11104              $context.off(elementNamespace);
 11105            },
 11106            scrollLock: function() {
 11107              module.verbose('Removing scroll lock from page');
 11108              $document.off(elementNamespace);
 11109              $window.off(elementNamespace);
 11110              $module.off('scroll' + eventNamespace);
 11111            }
 11112          },
 11113  
 11114          add: {
 11115            bodyCSS: function() {
 11116              var
 11117                width     = $module.outerWidth(),
 11118                height    = $module.outerHeight(),
 11119                direction = module.get.direction(),
 11120                distance  = {
 11121                  left   : width,
 11122                  right  : -width,
 11123                  top    : height,
 11124                  bottom : -height
 11125                },
 11126                style
 11127              ;
 11128              if( module.is.rtl() ){
 11129                module.verbose('RTL detected, flipping widths');
 11130                distance.left = -width;
 11131                distance.right = width;
 11132              }
 11133  
 11134              style  = '<style title="' + namespace + '">';
 11135  
 11136              if(direction === 'left' || direction === 'right') {
 11137                module.debug('Adding CSS rules for animation distance', width);
 11138                style  += ''
 11139                  + ' .ui.visible.' + direction + '.sidebar ~ .fixed,'
 11140                  + ' .ui.visible.' + direction + '.sidebar ~ .pusher {'
 11141                  + '   -webkit-transform: translate3d('+ distance[direction] + 'px, 0, 0);'
 11142                  + '           transform: translate3d('+ distance[direction] + 'px, 0, 0);'
 11143                  + ' }'
 11144                ;
 11145              }
 11146              else if(direction === 'top' || direction == 'bottom') {
 11147                style  += ''
 11148                  + ' .ui.visible.' + direction + '.sidebar ~ .fixed,'
 11149                  + ' .ui.visible.' + direction + '.sidebar ~ .pusher {'
 11150                  + '   -webkit-transform: translate3d(0, ' + distance[direction] + 'px, 0);'
 11151                  + '           transform: translate3d(0, ' + distance[direction] + 'px, 0);'
 11152                  + ' }'
 11153                ;
 11154              }
 11155  
 11156              /* IE is only browser not to create context with transforms */
 11157              /* https://www.w3.org/Bugs/Public/show_bug.cgi?id=16328 */
 11158              if( module.is.ie() ) {
 11159                if(direction === 'left' || direction === 'right') {
 11160                  module.debug('Adding CSS rules for animation distance', width);
 11161                  style  += ''
 11162                    + ' body.pushable > .ui.visible.' + direction + '.sidebar ~ .pusher:after {'
 11163                    + '   -webkit-transform: translate3d('+ distance[direction] + 'px, 0, 0);'
 11164                    + '           transform: translate3d('+ distance[direction] + 'px, 0, 0);'
 11165                    + ' }'
 11166                  ;
 11167                }
 11168                else if(direction === 'top' || direction == 'bottom') {
 11169                  style  += ''
 11170                    + ' body.pushable > .ui.visible.' + direction + '.sidebar ~ .pusher:after {'
 11171                    + '   -webkit-transform: translate3d(0, ' + distance[direction] + 'px, 0);'
 11172                    + '           transform: translate3d(0, ' + distance[direction] + 'px, 0);'
 11173                    + ' }'
 11174                  ;
 11175                }
 11176                /* opposite sides visible forces content overlay */
 11177                style += ''
 11178                  + ' body.pushable > .ui.visible.left.sidebar ~ .ui.visible.right.sidebar ~ .pusher:after,'
 11179                  + ' body.pushable > .ui.visible.right.sidebar ~ .ui.visible.left.sidebar ~ .pusher:after {'
 11180                  + '   -webkit-transform: translate3d(0px, 0, 0);'
 11181                  + '           transform: translate3d(0px, 0, 0);'
 11182                  + ' }'
 11183                ;
 11184              }
 11185              style += '</style>';
 11186              $head.append(style);
 11187              $style = $('style[title=' + namespace + ']');
 11188              module.debug('Adding sizing css to head', $style);
 11189            }
 11190          },
 11191  
 11192          refresh: function() {
 11193            module.verbose('Refreshing selector cache');
 11194            $context  = $(settings.context);
 11195            $sidebars = $context.children(selector.sidebar);
 11196            $pusher   = $context.children(selector.pusher);
 11197            $fixed    = $context.children(selector.fixed);
 11198          },
 11199  
 11200          refreshSidebars: function() {
 11201            module.verbose('Refreshing other sidebars');
 11202            $sidebars = $context.children(selector.sidebar);
 11203          },
 11204  
 11205          repaint: function() {
 11206            module.verbose('Forcing repaint event');
 11207            element.style.display='none';
 11208            element.offsetHeight;
 11209            element.scrollTop = element.scrollTop;
 11210            element.style.display='';
 11211          },
 11212  
 11213          setup: {
 11214            layout: function() {
 11215              if( $context.children(selector.pusher).length === 0 ) {
 11216                module.debug('Adding wrapper element for sidebar');
 11217                module.error(error.pusher);
 11218                $pusher = $('<div class="pusher" />');
 11219                $context
 11220                  .children()
 11221                    .not(selector.omitted)
 11222                    .not($sidebars)
 11223                    .wrapAll($pusher)
 11224                ;
 11225                module.refresh();
 11226              }
 11227              if($module.nextAll(selector.pusher).length === 0 || $module.nextAll(selector.pusher)[0] !== $pusher[0]) {
 11228                module.debug('Moved sidebar to correct parent element');
 11229                module.error(error.movedSidebar, element);
 11230                $module.detach().prependTo($context);
 11231                module.refresh();
 11232              }
 11233              module.set.pushable();
 11234              module.set.direction();
 11235            }
 11236          },
 11237  
 11238          attachEvents: function(selector, event) {
 11239            var
 11240              $toggle = $(selector)
 11241            ;
 11242            event = $.isFunction(module[event])
 11243              ? module[event]
 11244              : module.toggle
 11245            ;
 11246            if($toggle.length > 0) {
 11247              module.debug('Attaching sidebar events to element', selector, event);
 11248              $toggle
 11249                .on('click' + eventNamespace, event)
 11250              ;
 11251            }
 11252            else {
 11253              module.error(error.notFound, selector);
 11254            }
 11255          },
 11256  
 11257          show: function(callback) {
 11258            var
 11259              animateMethod = (settings.useLegacy === true)
 11260                ? module.legacyPushPage
 11261                : module.pushPage
 11262            ;
 11263            callback = $.isFunction(callback)
 11264              ? callback
 11265              : function(){}
 11266            ;
 11267            if(module.is.hidden()) {
 11268              module.refreshSidebars();
 11269              if(settings.overlay)  {
 11270                module.error(error.overlay);
 11271                settings.transition = 'overlay';
 11272              }
 11273              module.refresh();
 11274              if(module.othersActive()) {
 11275                module.debug('Other sidebars currently visible');
 11276                if(settings.exclusive) {
 11277                  // if not overlay queue animation after hide
 11278                  if(settings.transition != 'overlay') {
 11279                    module.hideOthers(module.show);
 11280                    return;
 11281                  }
 11282                  else {
 11283                    module.hideOthers();
 11284                  }
 11285                }
 11286                else {
 11287                  settings.transition = 'overlay';
 11288                }
 11289              }
 11290              animateMethod(function() {
 11291                callback.call(element);
 11292                settings.onShow.call(element);
 11293              });
 11294              settings.onChange.call(element);
 11295              settings.onVisible.call(element);
 11296            }
 11297            else {
 11298              module.debug('Sidebar is already visible');
 11299            }
 11300          },
 11301  
 11302          hide: function(callback) {
 11303            var
 11304              animateMethod = (settings.useLegacy === true)
 11305                ? module.legacyPullPage
 11306                : module.pullPage
 11307            ;
 11308            callback = $.isFunction(callback)
 11309              ? callback
 11310              : function(){}
 11311            ;
 11312            if(module.is.visible() || module.is.animating()) {
 11313              module.debug('Hiding sidebar', callback);
 11314              module.refreshSidebars();
 11315              animateMethod(function() {
 11316                callback.call(element);
 11317                settings.onHidden.call(element);
 11318              });
 11319              settings.onChange.call(element);
 11320              settings.onHide.call(element);
 11321            }
 11322          },
 11323  
 11324          othersAnimating: function() {
 11325            return ($sidebars.not($module).filter('.' + className.animating).length > 0);
 11326          },
 11327          othersVisible: function() {
 11328            return ($sidebars.not($module).filter('.' + className.visible).length > 0);
 11329          },
 11330          othersActive: function() {
 11331            return(module.othersVisible() || module.othersAnimating());
 11332          },
 11333  
 11334          hideOthers: function(callback) {
 11335            var
 11336              $otherSidebars = $sidebars.not($module).filter('.' + className.visible),
 11337              sidebarCount   = $otherSidebars.length,
 11338              callbackCount  = 0
 11339            ;
 11340            callback = callback || function(){};
 11341            $otherSidebars
 11342              .sidebar('hide', function() {
 11343                callbackCount++;
 11344                if(callbackCount == sidebarCount) {
 11345                  callback();
 11346                }
 11347              })
 11348            ;
 11349          },
 11350  
 11351          toggle: function() {
 11352            module.verbose('Determining toggled direction');
 11353            if(module.is.hidden()) {
 11354              module.show();
 11355            }
 11356            else {
 11357              module.hide();
 11358            }
 11359          },
 11360  
 11361          pushPage: function(callback) {
 11362            var
 11363              transition = module.get.transition(),
 11364              $transition = (transition == 'safe')
 11365                ? $context
 11366                : (transition === 'overlay' || module.othersActive())
 11367                  ? $module
 11368                  : $pusher,
 11369              animate,
 11370              transitionEnd
 11371            ;
 11372            callback = $.isFunction(callback)
 11373              ? callback
 11374              : function(){}
 11375            ;
 11376            if(settings.transition == 'scale down') {
 11377              module.scrollToTop();
 11378            }
 11379            module.set.transition(transition);
 11380            module.repaint();
 11381            animate = function() {
 11382              module.bind.clickaway();
 11383              module.add.bodyCSS();
 11384              module.set.animating();
 11385              module.set.visible();
 11386              if(!module.othersVisible()) {
 11387                if(settings.dimPage) {
 11388                  $pusher.addClass(className.dimmed);
 11389                }
 11390              }
 11391            };
 11392            transitionEnd = function(event) {
 11393              if( event.target == $transition[0] ) {
 11394                $transition.off(transitionEvent + elementNamespace, transitionEnd);
 11395                module.remove.animating();
 11396                module.bind.scrollLock();
 11397                callback.call(element);
 11398              }
 11399            };
 11400            $transition.off(transitionEvent + elementNamespace);
 11401            $transition.on(transitionEvent + elementNamespace, transitionEnd);
 11402            requestAnimationFrame(animate);
 11403          },
 11404  
 11405          pullPage: function(callback) {
 11406            var
 11407              transition = module.get.transition(),
 11408              $transition = (transition == 'safe')
 11409                ? $context
 11410                : (transition == 'overlay' || module.othersActive())
 11411                  ? $module
 11412                  : $pusher,
 11413              animate,
 11414              transitionEnd
 11415            ;
 11416            callback = $.isFunction(callback)
 11417              ? callback
 11418              : function(){}
 11419            ;
 11420            module.verbose('Removing context push state', module.get.direction());
 11421  
 11422            module.set.transition(transition);
 11423            module.unbind.clickaway();
 11424            module.unbind.scrollLock();
 11425  
 11426            animate = function() {
 11427              module.set.animating();
 11428              module.remove.visible();
 11429              if(settings.dimPage && !module.othersVisible()) {
 11430                $pusher.removeClass(className.dimmed);
 11431              }
 11432            };
 11433            transitionEnd = function(event) {
 11434              if( event.target == $transition[0] ) {
 11435                $transition.off(transitionEvent + elementNamespace, transitionEnd);
 11436                module.remove.animating();
 11437                module.remove.transition();
 11438                module.remove.bodyCSS();
 11439                if(transition == 'scale down' || (settings.returnScroll && module.is.mobile()) ) {
 11440                  module.scrollBack();
 11441                }
 11442                callback.call(element);
 11443              }
 11444            };
 11445            $transition.off(transitionEvent + elementNamespace);
 11446            $transition.on(transitionEvent + elementNamespace, transitionEnd);
 11447            requestAnimationFrame(animate);
 11448          },
 11449  
 11450          legacyPushPage: function(callback) {
 11451            var
 11452              distance   = $module.width(),
 11453              direction  = module.get.direction(),
 11454              properties = {}
 11455            ;
 11456            distance  = distance || $module.width();
 11457            callback  = $.isFunction(callback)
 11458              ? callback
 11459              : function(){}
 11460            ;
 11461            properties[direction] = distance;
 11462            module.debug('Using javascript to push context', properties);
 11463            module.set.visible();
 11464            module.set.transition();
 11465            module.set.animating();
 11466            if(settings.dimPage) {
 11467              $pusher.addClass(className.dimmed);
 11468            }
 11469            $context
 11470              .css('position', 'relative')
 11471              .animate(properties, settings.duration, settings.easing, function() {
 11472                module.remove.animating();
 11473                module.bind.clickaway();
 11474                callback.call(element);
 11475              })
 11476            ;
 11477          },
 11478          legacyPullPage: function(callback) {
 11479            var
 11480              distance   = 0,
 11481              direction  = module.get.direction(),
 11482              properties = {}
 11483            ;
 11484            distance  = distance || $module.width();
 11485            callback  = $.isFunction(callback)
 11486              ? callback
 11487              : function(){}
 11488            ;
 11489            properties[direction] = '0px';
 11490            module.debug('Using javascript to pull context', properties);
 11491            module.unbind.clickaway();
 11492            module.set.animating();
 11493            module.remove.visible();
 11494            if(settings.dimPage && !module.othersActive()) {
 11495              $pusher.removeClass(className.dimmed);
 11496            }
 11497            $context
 11498              .css('position', 'relative')
 11499              .animate(properties, settings.duration, settings.easing, function() {
 11500                module.remove.animating();
 11501                callback.call(element);
 11502              })
 11503            ;
 11504          },
 11505  
 11506          scrollToTop: function() {
 11507            module.verbose('Scrolling to top of page to avoid animation issues');
 11508            currentScroll = $(window).scrollTop();
 11509            $module.scrollTop(0);
 11510            window.scrollTo(0, 0);
 11511          },
 11512  
 11513          scrollBack: function() {
 11514            module.verbose('Scrolling back to original page position');
 11515            window.scrollTo(0, currentScroll);
 11516          },
 11517  
 11518          set: {
 11519            // html
 11520            ios: function() {
 11521              $html.addClass(className.ios);
 11522            },
 11523  
 11524            // container
 11525            pushed: function() {
 11526              $context.addClass(className.pushed);
 11527            },
 11528            pushable: function() {
 11529              $context.addClass(className.pushable);
 11530            },
 11531  
 11532            // sidebar
 11533            active: function() {
 11534              $module.addClass(className.active);
 11535            },
 11536            animating: function() {
 11537              $module.addClass(className.animating);
 11538            },
 11539            transition: function(transition) {
 11540              transition = transition || module.get.transition();
 11541              $module.addClass(transition);
 11542            },
 11543            direction: function(direction) {
 11544              direction = direction || module.get.direction();
 11545              $module.addClass(className[direction]);
 11546            },
 11547            visible: function() {
 11548              $module.addClass(className.visible);
 11549            },
 11550            overlay: function() {
 11551              $module.addClass(className.overlay);
 11552            }
 11553          },
 11554          remove: {
 11555  
 11556            bodyCSS: function() {
 11557              module.debug('Removing body css styles', $style);
 11558              if($style && $style.length > 0) {
 11559                $style.remove();
 11560              }
 11561            },
 11562  
 11563            // context
 11564            pushed: function() {
 11565              $context.removeClass(className.pushed);
 11566            },
 11567            pushable: function() {
 11568              $context.removeClass(className.pushable);
 11569            },
 11570  
 11571            // sidebar
 11572            active: function() {
 11573              $module.removeClass(className.active);
 11574            },
 11575            animating: function() {
 11576              $module.removeClass(className.animating);
 11577            },
 11578            transition: function(transition) {
 11579              transition = transition || module.get.transition();
 11580              $module.removeClass(transition);
 11581            },
 11582            direction: function(direction) {
 11583              direction = direction || module.get.direction();
 11584              $module.removeClass(className[direction]);
 11585            },
 11586            visible: function() {
 11587              $module.removeClass(className.visible);
 11588            },
 11589            overlay: function() {
 11590              $module.removeClass(className.overlay);
 11591            }
 11592          },
 11593  
 11594          get: {
 11595            direction: function() {
 11596              if($module.hasClass(className.top)) {
 11597                return className.top;
 11598              }
 11599              else if($module.hasClass(className.right)) {
 11600                return className.right;
 11601              }
 11602              else if($module.hasClass(className.bottom)) {
 11603                return className.bottom;
 11604              }
 11605              return className.left;
 11606            },
 11607            transition: function() {
 11608              var
 11609                direction = module.get.direction(),
 11610                transition
 11611              ;
 11612              transition = ( module.is.mobile() )
 11613                ? (settings.mobileTransition == 'auto')
 11614                  ? settings.defaultTransition.mobile[direction]
 11615                  : settings.mobileTransition
 11616                : (settings.transition == 'auto')
 11617                  ? settings.defaultTransition.computer[direction]
 11618                  : settings.transition
 11619              ;
 11620              module.verbose('Determined transition', transition);
 11621              return transition;
 11622            },
 11623            transitionEvent: function() {
 11624              var
 11625                element     = document.createElement('element'),
 11626                transitions = {
 11627                  'transition'       :'transitionend',
 11628                  'OTransition'      :'oTransitionEnd',
 11629                  'MozTransition'    :'transitionend',
 11630                  'WebkitTransition' :'webkitTransitionEnd'
 11631                },
 11632                transition
 11633              ;
 11634              for(transition in transitions){
 11635                if( element.style[transition] !== undefined ){
 11636                  return transitions[transition];
 11637                }
 11638              }
 11639            }
 11640          },
 11641  
 11642          is: {
 11643  
 11644            ie: function() {
 11645              var
 11646                isIE11 = (!(window.ActiveXObject) && 'ActiveXObject' in window),
 11647                isIE   = ('ActiveXObject' in window)
 11648              ;
 11649              return (isIE11 || isIE);
 11650            },
 11651  
 11652            legacy: function() {
 11653              var
 11654                element    = document.createElement('div'),
 11655                transforms = {
 11656                  'webkitTransform' :'-webkit-transform',
 11657                  'OTransform'      :'-o-transform',
 11658                  'msTransform'     :'-ms-transform',
 11659                  'MozTransform'    :'-moz-transform',
 11660                  'transform'       :'transform'
 11661                },
 11662                has3D
 11663              ;
 11664  
 11665              // Add it to the body to get the computed style.
 11666              document.body.insertBefore(element, null);
 11667              for (var transform in transforms) {
 11668                if (element.style[transform] !== undefined) {
 11669                  element.style[transform] = "translate3d(1px,1px,1px)";
 11670                  has3D = window.getComputedStyle(element).getPropertyValue(transforms[transform]);
 11671                }
 11672              }
 11673              document.body.removeChild(element);
 11674              return !(has3D !== undefined && has3D.length > 0 && has3D !== 'none');
 11675            },
 11676            ios: function() {
 11677              var
 11678                userAgent = navigator.userAgent,
 11679                isIOS     = userAgent.match(regExp.ios)
 11680              ;
 11681              if(isIOS) {
 11682                module.verbose('Browser was found to be iOS', userAgent);
 11683                return true;
 11684              }
 11685              else {
 11686                return false;
 11687              }
 11688            },
 11689            mobile: function() {
 11690              var
 11691                userAgent    = navigator.userAgent,
 11692                isMobile     = userAgent.match(regExp.mobile)
 11693              ;
 11694              if(isMobile) {
 11695                module.verbose('Browser was found to be mobile', userAgent);
 11696                return true;
 11697              }
 11698              else {
 11699                module.verbose('Browser is not mobile, using regular transition', userAgent);
 11700                return false;
 11701              }
 11702            },
 11703            hidden: function() {
 11704              return !module.is.visible();
 11705            },
 11706            visible: function() {
 11707              return $module.hasClass(className.visible);
 11708            },
 11709            // alias
 11710            open: function() {
 11711              return module.is.visible();
 11712            },
 11713            closed: function() {
 11714              return module.is.hidden();
 11715            },
 11716            vertical: function() {
 11717              return $module.hasClass(className.top);
 11718            },
 11719            animating: function() {
 11720              return $context.hasClass(className.animating);
 11721            },
 11722            rtl: function () {
 11723              return $module.css('direction') == 'rtl';
 11724            }
 11725          },
 11726  
 11727          setting: function(name, value) {
 11728            module.debug('Changing setting', name, value);
 11729            if( $.isPlainObject(name) ) {
 11730              $.extend(true, settings, name);
 11731            }
 11732            else if(value !== undefined) {
 11733              settings[name] = value;
 11734            }
 11735            else {
 11736              return settings[name];
 11737            }
 11738          },
 11739          internal: function(name, value) {
 11740            if( $.isPlainObject(name) ) {
 11741              $.extend(true, module, name);
 11742            }
 11743            else if(value !== undefined) {
 11744              module[name] = value;
 11745            }
 11746            else {
 11747              return module[name];
 11748            }
 11749          },
 11750          debug: function() {
 11751            if(settings.debug) {
 11752              if(settings.performance) {
 11753                module.performance.log(arguments);
 11754              }
 11755              else {
 11756                module.debug = Function.prototype.bind.call(console.info, console, settings.name + ':');
 11757                module.debug.apply(console, arguments);
 11758              }
 11759            }
 11760          },
 11761          verbose: function() {
 11762            if(settings.verbose && settings.debug) {
 11763              if(settings.performance) {
 11764                module.performance.log(arguments);
 11765              }
 11766              else {
 11767                module.verbose = Function.prototype.bind.call(console.info, console, settings.name + ':');
 11768                module.verbose.apply(console, arguments);
 11769              }
 11770            }
 11771          },
 11772          error: function() {
 11773            module.error = Function.prototype.bind.call(console.error, console, settings.name + ':');
 11774            module.error.apply(console, arguments);
 11775          },
 11776          performance: {
 11777            log: function(message) {
 11778              var
 11779                currentTime,
 11780                executionTime,
 11781                previousTime
 11782              ;
 11783              if(settings.performance) {
 11784                currentTime   = new Date().getTime();
 11785                previousTime  = time || currentTime;
 11786                executionTime = currentTime - previousTime;
 11787                time          = currentTime;
 11788                performance.push({
 11789                  'Name'           : message[0],
 11790                  'Arguments'      : [].slice.call(message, 1) || '',
 11791                  'Element'        : element,
 11792                  'Execution Time' : executionTime
 11793                });
 11794              }
 11795              clearTimeout(module.performance.timer);
 11796              module.performance.timer = setTimeout(module.performance.display, 100);
 11797            },
 11798            display: function() {
 11799              var
 11800                title = settings.name + ':',
 11801                totalTime = 0
 11802              ;
 11803              time = false;
 11804              clearTimeout(module.performance.timer);
 11805              $.each(performance, function(index, data) {
 11806                totalTime += data['Execution Time'];
 11807              });
 11808              title += ' ' + totalTime + 'ms';
 11809              if(moduleSelector) {
 11810                title += ' \'' + moduleSelector + '\'';
 11811              }
 11812              if( (console.group !== undefined || console.table !== undefined) && performance.length > 0) {
 11813                console.groupCollapsed(title);
 11814                if(console.table) {
 11815                  console.table(performance);
 11816                }
 11817                else {
 11818                  $.each(performance, function(index, data) {
 11819                    console.log(data['Name'] + ': ' + data['Execution Time']+'ms');
 11820                  });
 11821                }
 11822                console.groupEnd();
 11823              }
 11824              performance = [];
 11825            }
 11826          },
 11827          invoke: function(query, passedArguments, context) {
 11828            var
 11829              object = instance,
 11830              maxDepth,
 11831              found,
 11832              response
 11833            ;
 11834            passedArguments = passedArguments || queryArguments;
 11835            context         = element         || context;
 11836            if(typeof query == 'string' && object !== undefined) {
 11837              query    = query.split(/[\. ]/);
 11838              maxDepth = query.length - 1;
 11839              $.each(query, function(depth, value) {
 11840                var camelCaseValue = (depth != maxDepth)
 11841                  ? value + query[depth + 1].charAt(0).toUpperCase() + query[depth + 1].slice(1)
 11842                  : query
 11843                ;
 11844                if( $.isPlainObject( object[camelCaseValue] ) && (depth != maxDepth) ) {
 11845                  object = object[camelCaseValue];
 11846                }
 11847                else if( object[camelCaseValue] !== undefined ) {
 11848                  found = object[camelCaseValue];
 11849                  return false;
 11850                }
 11851                else if( $.isPlainObject( object[value] ) && (depth != maxDepth) ) {
 11852                  object = object[value];
 11853                }
 11854                else if( object[value] !== undefined ) {
 11855                  found = object[value];
 11856                  return false;
 11857                }
 11858                else {
 11859                  module.error(error.method, query);
 11860                  return false;
 11861                }
 11862              });
 11863            }
 11864            if ( $.isFunction( found ) ) {
 11865              response = found.apply(context, passedArguments);
 11866            }
 11867            else if(found !== undefined) {
 11868              response = found;
 11869            }
 11870            if($.isArray(returnedValue)) {
 11871              returnedValue.push(response);
 11872            }
 11873            else if(returnedValue !== undefined) {
 11874              returnedValue = [returnedValue, response];
 11875            }
 11876            else if(response !== undefined) {
 11877              returnedValue = response;
 11878            }
 11879            return found;
 11880          }
 11881        }
 11882      ;
 11883  
 11884      if(methodInvoked) {
 11885        if(instance === undefined) {
 11886          module.initialize();
 11887        }
 11888        module.invoke(query);
 11889      }
 11890      else {
 11891        if(instance !== undefined) {
 11892          module.invoke('destroy');
 11893        }
 11894        module.initialize();
 11895      }
 11896    });
 11897  
 11898    return (returnedValue !== undefined)
 11899      ? returnedValue
 11900      : this
 11901    ;
 11902  };
 11903  
 11904  $.fn.sidebar.settings = {
 11905  
 11906    name              : 'Sidebar',
 11907    namespace         : 'sidebar',
 11908  
 11909    debug             : false,
 11910    verbose           : true,
 11911    performance       : true,
 11912  
 11913    transition        : 'auto',
 11914    mobileTransition  : 'auto',
 11915  
 11916    defaultTransition : {
 11917      computer: {
 11918        left   : 'uncover',
 11919        right  : 'uncover',
 11920        top    : 'overlay',
 11921        bottom : 'overlay'
 11922      },
 11923      mobile: {
 11924        left   : 'uncover',
 11925        right  : 'uncover',
 11926        top    : 'overlay',
 11927        bottom : 'overlay'
 11928      }
 11929    },
 11930  
 11931    context           : 'body',
 11932    exclusive         : false,
 11933    closable          : true,
 11934    dimPage           : true,
 11935    scrollLock        : false,
 11936    returnScroll      : false,
 11937    delaySetup        : false,
 11938  
 11939    useLegacy         : 'auto',
 11940    duration          : 500,
 11941    easing            : 'easeInOutQuint',
 11942  
 11943    onChange          : function(){},
 11944    onShow            : function(){},
 11945    onHide            : function(){},
 11946  
 11947    onHidden          : function(){},
 11948    onVisible         : function(){},
 11949  
 11950    className         : {
 11951      active    : 'active',
 11952      animating : 'animating',
 11953      dimmed    : 'dimmed',
 11954      ios       : 'ios',
 11955      pushable  : 'pushable',
 11956      pushed    : 'pushed',
 11957      right     : 'right',
 11958      top       : 'top',
 11959      left      : 'left',
 11960      bottom    : 'bottom',
 11961      visible   : 'visible'
 11962    },
 11963  
 11964    selector: {
 11965      fixed   : '.fixed',
 11966      omitted : 'script, link, style, .ui.modal, .ui.dimmer, .ui.nag, .ui.fixed',
 11967      pusher  : '.pusher',
 11968      sidebar : '.ui.sidebar'
 11969    },
 11970  
 11971    regExp: {
 11972      ios    : /(iPad|iPhone|iPod)/g,
 11973      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
 11974    },
 11975  
 11976    error   : {
 11977      method       : 'The method you called is not defined.',
 11978      pusher       : 'Had to add pusher element. For optimal performance make sure body content is inside a pusher element',
 11979      movedSidebar : 'Had to move sidebar. For optimal performance make sure sidebar and pusher are direct children of your body tag',
 11980      overlay      : 'The overlay setting is no longer supported, use animation: overlay',
 11981      notFound     : 'There were no elements that matched the specified selector'
 11982    }
 11983  
 11984  };
 11985  
 11986  // Adds easing
 11987  $.extend( $.easing, {
 11988    easeInOutQuint: function (x, t, b, c, d) {
 11989      if ((t/=d/2) < 1) return c/2*t*t*t*t*t + b;
 11990      return c/2*((t-=2)*t*t*t*t + 2) + b;
 11991    }
 11992  });
 11993  
 11994  
 11995  })( jQuery, window , document );
 11996  
 11997  /*!
 11998   * # Semantic UI x.x - Sticky
 11999   * http://github.com/semantic-org/semantic-ui/
 12000   *
 12001   *
 12002   * Copyright 2014 Contributorss
 12003   * Released under the MIT license
 12004   * http://opensource.org/licenses/MIT
 12005   *
 12006   */
 12007  
 12008  ;(function ( $, window, document, undefined ) {
 12009  
 12010  "use strict";
 12011  
 12012  $.fn.sticky = function(parameters) {
 12013    var
 12014      $allModules    = $(this),
 12015      moduleSelector = $allModules.selector || '',
 12016  
 12017      time           = new Date().getTime(),
 12018      performance    = [],
 12019  
 12020      query          = arguments[0],
 12021      methodInvoked  = (typeof query == 'string'),
 12022      queryArguments = [].slice.call(arguments, 1),
 12023      returnedValue
 12024    ;
 12025  
 12026    $allModules
 12027      .each(function() {
 12028        var
 12029          settings              = ( $.isPlainObject(parameters) )
 12030            ? $.extend(true, {}, $.fn.sticky.settings, parameters)
 12031            : $.extend({}, $.fn.sticky.settings),
 12032  
 12033          className             = settings.className,
 12034          namespace             = settings.namespace,
 12035          error                 = settings.error,
 12036  
 12037          eventNamespace        = '.' + namespace,
 12038          moduleNamespace       = 'module-' + namespace,
 12039  
 12040          $module               = $(this),
 12041          $window               = $(window),
 12042          $container            = $module.offsetParent(),
 12043          $scroll               = $(settings.scrollContext),
 12044          $context,
 12045  
 12046          selector              = $module.selector || '',
 12047          instance              = $module.data(moduleNamespace),
 12048  
 12049          requestAnimationFrame = window.requestAnimationFrame
 12050            || window.mozRequestAnimationFrame
 12051            || window.webkitRequestAnimationFrame
 12052            || window.msRequestAnimationFrame
 12053            || function(callback) { setTimeout(callback, 0); },
 12054  
 12055          element         = this,
 12056          observer,
 12057          module
 12058        ;
 12059  
 12060        module      = {
 12061  
 12062          initialize: function() {
 12063  
 12064            module.determineContext();
 12065            module.verbose('Initializing sticky', settings, $container);
 12066  
 12067            module.save.positions();
 12068            module.checkErrors();
 12069            module.bind.events();
 12070  
 12071            if(settings.observeChanges) {
 12072              module.observeChanges();
 12073            }
 12074            module.instantiate();
 12075          },
 12076  
 12077          instantiate: function() {
 12078            module.verbose('Storing instance of module', module);
 12079            instance = module;
 12080            $module
 12081              .data(moduleNamespace, module)
 12082            ;
 12083          },
 12084  
 12085          destroy: function() {
 12086            module.verbose('Destroying previous module');
 12087            module.reset();
 12088            if(observer) {
 12089              observer.disconnect();
 12090            }
 12091            $window.off('resize' + eventNamespace, module.event.resize);
 12092            $scroll.off('scroll' + eventNamespace, module.event.scroll);
 12093            $module.removeData(moduleNamespace);
 12094          },
 12095  
 12096          observeChanges: function() {
 12097            var
 12098              context = $context[0]
 12099            ;
 12100            if('MutationObserver' in window) {
 12101              observer = new MutationObserver(function(mutations) {
 12102                clearTimeout(module.timer);
 12103                module.timer = setTimeout(function() {
 12104                  module.verbose('DOM tree modified, updating sticky menu');
 12105                  module.refresh();
 12106                }, 20);
 12107              });
 12108              observer.observe(element, {
 12109                childList : true,
 12110                subtree   : true
 12111              });
 12112              observer.observe(context, {
 12113                childList : true,
 12114                subtree   : true
 12115              });
 12116              module.debug('Setting up mutation observer', observer);
 12117            }
 12118          },
 12119  
 12120          determineContext: function() {
 12121            if(settings.context) {
 12122              $context = $(settings.context);
 12123            }
 12124            else {
 12125              $context = $container;
 12126            }
 12127            if($context.length === 0) {
 12128              module.error(error.invalidContext, settings.context, $module);
 12129              return;
 12130            }
 12131          },
 12132  
 12133          checkErrors: function() {
 12134            if( module.is.hidden() ) {
 12135              module.error(error.visible, $module);
 12136            }
 12137            if(module.cache.element.height > module.cache.context.height) {
 12138              module.reset();
 12139              module.error(error.elementSize, $module);
 12140              return;
 12141            }
 12142          },
 12143  
 12144          bind: {
 12145            events: function() {
 12146              $window.on('resize' + eventNamespace, module.event.resize);
 12147              $scroll.on('scroll' + eventNamespace, module.event.scroll);
 12148            }
 12149          },
 12150  
 12151          event: {
 12152            resize: function() {
 12153              requestAnimationFrame(function() {
 12154                module.refresh();
 12155                module.stick();
 12156              });
 12157            },
 12158            scroll: function() {
 12159              requestAnimationFrame(function() {
 12160                module.stick();
 12161                settings.onScroll.call(element);
 12162              });
 12163            }
 12164          },
 12165  
 12166          refresh: function(hardRefresh) {
 12167            module.reset();
 12168            if(hardRefresh) {
 12169              $container = $module.offsetParent();
 12170            }
 12171            module.save.positions();
 12172            module.stick();
 12173            settings.onReposition.call(element);
 12174          },
 12175  
 12176          supports: {
 12177            sticky: function() {
 12178              var
 12179                $element = $('<div/>'),
 12180                element = $element.get()
 12181              ;
 12182              $element.addClass(className.supported);
 12183              return($element.css('position').match('sticky'));
 12184            }
 12185          },
 12186  
 12187          save: {
 12188            scroll: function(scroll) {
 12189              module.lastScroll = scroll;
 12190            },
 12191            positions: function() {
 12192              var
 12193                window = {
 12194                  height: $window.height()
 12195                },
 12196                element = {
 12197                  margin: {
 12198                    top    : parseInt($module.css('margin-top'), 10),
 12199                    bottom : parseInt($module.css('margin-bottom'), 10),
 12200                  },
 12201                  offset : $module.offset(),
 12202                  width  : $module.outerWidth(),
 12203                  height : $module.outerHeight()
 12204                },
 12205                context = {
 12206                  offset        : $context.offset(),
 12207                  height        : $context.outerHeight(),
 12208                  bottomPadding : parseInt($context.css('padding-bottom'), 10)
 12209                }
 12210              ;
 12211              module.cache = {
 12212                fits : ( element.height < window.height ),
 12213                window: {
 12214                  height: window.height
 12215                },
 12216                element: {
 12217                  margin : element.margin,
 12218                  top    : element.offset.top - element.margin.top,
 12219                  left   : element.offset.left,
 12220                  width  : element.width,
 12221                  height : element.height,
 12222                  bottom : element.offset.top + element.height
 12223                },
 12224                context: {
 12225                  top           : context.offset.top,
 12226                  height        : context.height,
 12227                  bottomPadding : context.bottomPadding,
 12228                  bottom        : context.offset.top + context.height - context.bottomPadding
 12229                }
 12230              };
 12231              module.set.containerSize();
 12232              module.set.size();
 12233              module.stick();
 12234              module.debug('Caching element positions', module.cache);
 12235            }
 12236          },
 12237  
 12238          get: {
 12239            direction: function(scroll) {
 12240              var
 12241                direction = 'down'
 12242              ;
 12243              scroll = scroll || $scroll.scrollTop();
 12244              if(module.lastScroll !== undefined) {
 12245                if(module.lastScroll < scroll) {
 12246                  direction = 'down';
 12247                }
 12248                else if(module.lastScroll > scroll) {
 12249                  direction = 'up';
 12250                }
 12251              }
 12252              return direction;
 12253            },
 12254            scrollChange: function(scroll) {
 12255              scroll = scroll || $scroll.scrollTop();
 12256              return (module.lastScroll)
 12257                ? (scroll - module.lastScroll)
 12258                : 0
 12259              ;
 12260            },
 12261            currentElementScroll: function() {
 12262              return ( module.is.top() )
 12263                ? Math.abs(parseInt($module.css('top'), 10))    || 0
 12264                : Math.abs(parseInt($module.css('bottom'), 10)) || 0
 12265              ;
 12266            },
 12267            elementScroll: function(scroll) {
 12268              scroll = scroll || $scroll.scrollTop();
 12269              var
 12270                element        = module.cache.element,
 12271                window         = module.cache.window,
 12272                delta          = module.get.scrollChange(scroll),
 12273                maxScroll      = (element.height - window.height + settings.offset),
 12274                currentScroll  = module.get.currentElementScroll(),
 12275                possibleScroll = (currentScroll + delta),
 12276                elementScroll
 12277              ;
 12278              if(module.cache.fits || possibleScroll < 0) {
 12279                elementScroll = 0;
 12280              }
 12281              else if (possibleScroll > maxScroll ) {
 12282                elementScroll = maxScroll;
 12283              }
 12284              else {
 12285                elementScroll = possibleScroll;
 12286              }
 12287              return elementScroll;
 12288            }
 12289          },
 12290  
 12291          remove: {
 12292            offset: function() {
 12293              $module.css('margin-top', '');
 12294            }
 12295          },
 12296  
 12297          set: {
 12298            offset: function() {
 12299              module.verbose('Setting offset on element', settings.offset);
 12300              $module.css('margin-top', settings.offset);
 12301            },
 12302            containerSize: function() {
 12303              var
 12304                tagName = $container.get(0).tagName
 12305              ;
 12306              if(tagName === 'HTML' || tagName == 'body') {
 12307                // this can trigger for too many reasons
 12308                //module.error(error.container, tagName, $module);
 12309                $container = $module.offsetParent();
 12310              }
 12311              else {
 12312                module.debug('Settings container size', module.cache.context.height);
 12313                if( Math.abs($container.height() - module.cache.context.height) > 5) {
 12314                  $container.css({
 12315                    height: module.cache.context.height
 12316                  });
 12317                }
 12318              }
 12319            },
 12320            scroll: function(scroll) {
 12321              module.debug('Setting scroll on element', scroll);
 12322              if( module.is.top() ) {
 12323                $module
 12324                  .css('bottom', '')
 12325                  .css('top', -scroll)
 12326                ;
 12327              }
 12328              if( module.is.bottom() ) {
 12329                $module
 12330                  .css('top', '')
 12331                  .css('bottom', scroll)
 12332                ;
 12333              }
 12334            },
 12335            size: function() {
 12336              if(module.cache.element.height !== 0 && module.cache.element.width !== 0) {
 12337                $module
 12338                  .css({
 12339                    width  : module.cache.element.width,
 12340                    height : module.cache.element.height
 12341                  })
 12342                ;
 12343              }
 12344            }
 12345          },
 12346  
 12347          is: {
 12348            top: function() {
 12349              return $module.hasClass(className.top);
 12350            },
 12351            bottom: function() {
 12352              return $module.hasClass(className.bottom);
 12353            },
 12354            initialPosition: function() {
 12355              return (!module.is.fixed() && !module.is.bound());
 12356            },
 12357            hidden: function() {
 12358              return (!$module.is(':visible'));
 12359            },
 12360            bound: function() {
 12361              return $module.hasClass(className.bound);
 12362            },
 12363            fixed: function() {
 12364              return $module.hasClass(className.fixed);
 12365            }
 12366          },
 12367  
 12368          stick: function() {
 12369            var
 12370              cache          = module.cache,
 12371              fits           = cache.fits,
 12372              element        = cache.element,
 12373              window         = cache.window,
 12374              context        = cache.context,
 12375              offset         = (module.is.bottom() && settings.pushing)
 12376                ? settings.bottomOffset
 12377                : settings.offset,
 12378              scroll         = {
 12379                top    : $scroll.scrollTop() + offset,
 12380                bottom : $scroll.scrollTop() + offset + window.height
 12381              },
 12382              direction      = module.get.direction(scroll.top),
 12383              elementScroll  = module.get.elementScroll(scroll.top),
 12384  
 12385              // shorthand
 12386              doesntFit      = !fits,
 12387              elementVisible = (element.height !== 0)
 12388            ;
 12389  
 12390            // save current scroll for next run
 12391            module.save.scroll(scroll.top);
 12392  
 12393            if(elementVisible) {
 12394  
 12395              if( module.is.initialPosition() ) {
 12396                if(scroll.top >= context.bottom) {
 12397                  console.log(scroll.top, context.bottom);
 12398                  module.debug('Element bottom of container');
 12399                  module.bindBottom();
 12400                }
 12401                else if(scroll.top >= element.top) {
 12402                  module.debug('Element passed, fixing element to page');
 12403                  module.fixTop();
 12404                }
 12405              }
 12406              else if( module.is.fixed() ) {
 12407  
 12408                // currently fixed top
 12409                if( module.is.top() ) {
 12410                  if( scroll.top < element.top ) {
 12411                    module.debug('Fixed element reached top of container');
 12412                    module.setInitialPosition();
 12413                  }
 12414                  else if( (element.height + scroll.top - elementScroll) > context.bottom ) {
 12415                    module.debug('Fixed element reached bottom of container');
 12416                    module.bindBottom();
 12417                  }
 12418                  // scroll element if larger than screen
 12419                  else if(doesntFit) {
 12420                    module.set.scroll(elementScroll);
 12421                  }
 12422                }
 12423  
 12424                // currently fixed bottom
 12425                else if(module.is.bottom() ) {
 12426  
 12427                  // top edge
 12428                  if( (scroll.bottom - element.height) < element.top) {
 12429                    module.debug('Bottom fixed rail has reached top of container');
 12430                    module.setInitialPosition();
 12431                  }
 12432                  // bottom edge
 12433                  else if(scroll.bottom > context.bottom) {
 12434                    module.debug('Bottom fixed rail has reached bottom of container');
 12435                    module.bindBottom();
 12436                  }
 12437                  // scroll element if larger than screen
 12438                  else if(doesntFit) {
 12439                    module.set.scroll(elementScroll);
 12440                  }
 12441  
 12442                }
 12443              }
 12444              else if( module.is.bottom() ) {
 12445                if(settings.pushing) {
 12446                  if(module.is.bound() && scroll.bottom < context.bottom ) {
 12447                    module.debug('Fixing bottom attached element to bottom of browser.');
 12448                    module.fixBottom();
 12449                  }
 12450                }
 12451                else {
 12452                  if(module.is.bound() && (scroll.top < context.bottom - element.height) ) {
 12453                    module.debug('Fixing bottom attached element to top of browser.');
 12454                    module.fixTop();
 12455                  }
 12456                }
 12457              }
 12458            }
 12459          },
 12460  
 12461          bindTop: function() {
 12462            module.debug('Binding element to top of parent container');
 12463            module.remove.offset();
 12464            $module
 12465              .css('left' , '')
 12466              .css('top' , '')
 12467              .css('margin-bottom' , '')
 12468              .removeClass(className.fixed)
 12469              .removeClass(className.bottom)
 12470              .addClass(className.bound)
 12471              .addClass(className.top)
 12472            ;
 12473            settings.onTop.call(element);
 12474            settings.onUnstick.call(element);
 12475          },
 12476          bindBottom: function() {
 12477            module.debug('Binding element to bottom of parent container');
 12478            module.remove.offset();
 12479            $module
 12480              .css('left' , '')
 12481              .css('top' , '')
 12482              .css('margin-bottom' , module.cache.context.bottomPadding)
 12483              .removeClass(className.fixed)
 12484              .removeClass(className.top)
 12485              .addClass(className.bound)
 12486              .addClass(className.bottom)
 12487            ;
 12488            settings.onBottom.call(element);
 12489            settings.onUnstick.call(element);
 12490          },
 12491  
 12492          setInitialPosition: function() {
 12493            module.unfix();
 12494            module.unbind();
 12495          },
 12496  
 12497  
 12498          fixTop: function() {
 12499            module.debug('Fixing element to top of page');
 12500            module.set.offset();
 12501            $module
 12502              .css('left', module.cache.element.left)
 12503              .css('bottom' , '')
 12504              .removeClass(className.bound)
 12505              .removeClass(className.bottom)
 12506              .addClass(className.fixed)
 12507              .addClass(className.top)
 12508            ;
 12509            settings.onStick.call(element);
 12510          },
 12511  
 12512          fixBottom: function() {
 12513            module.debug('Sticking element to bottom of page');
 12514            module.set.offset();
 12515            $module
 12516              .css('left', module.cache.element.left)
 12517              .css('bottom' , '')
 12518              .removeClass(className.bound)
 12519              .removeClass(className.top)
 12520              .addClass(className.fixed)
 12521              .addClass(className.bottom)
 12522            ;
 12523            settings.onStick.call(element);
 12524          },
 12525  
 12526          unbind: function() {
 12527            module.debug('Removing absolute position on element');
 12528            module.remove.offset();
 12529            $module
 12530              .removeClass(className.bound)
 12531              .removeClass(className.top)
 12532              .removeClass(className.bottom)
 12533            ;
 12534          },
 12535  
 12536          unfix: function() {
 12537            module.debug('Removing fixed position on element');
 12538            module.remove.offset();
 12539            $module
 12540              .removeClass(className.fixed)
 12541              .removeClass(className.top)
 12542              .removeClass(className.bottom)
 12543            ;
 12544            settings.onUnstick.call(element);
 12545          },
 12546  
 12547          reset: function() {
 12548            module.debug('Reseting elements position');
 12549            module.unbind();
 12550            module.unfix();
 12551            module.resetCSS();
 12552          },
 12553  
 12554          resetCSS: function() {
 12555            $module
 12556              .css({
 12557                top    : '',
 12558                bottom : '',
 12559                width  : '',
 12560                height : ''
 12561              })
 12562            ;
 12563            $container
 12564              .css({
 12565                height: ''
 12566              })
 12567            ;
 12568          },
 12569  
 12570          setting: function(name, value) {
 12571            if( $.isPlainObject(name) ) {
 12572              $.extend(true, settings, name);
 12573            }
 12574            else if(value !== undefined) {
 12575              settings[name] = value;
 12576            }
 12577            else {
 12578              return settings[name];
 12579            }
 12580          },
 12581          internal: function(name, value) {
 12582            if( $.isPlainObject(name) ) {
 12583              $.extend(true, module, name);
 12584            }
 12585            else if(value !== undefined) {
 12586              module[name] = value;
 12587            }
 12588            else {
 12589              return module[name];
 12590            }
 12591          },
 12592          debug: function() {
 12593            if(settings.debug) {
 12594              if(settings.performance) {
 12595                module.performance.log(arguments);
 12596              }
 12597              else {
 12598                module.debug = Function.prototype.bind.call(console.info, console, settings.name + ':');
 12599                module.debug.apply(console, arguments);
 12600              }
 12601            }
 12602          },
 12603          verbose: function() {
 12604            if(settings.verbose && settings.debug) {
 12605              if(settings.performance) {
 12606                module.performance.log(arguments);
 12607              }
 12608              else {
 12609                module.verbose = Function.prototype.bind.call(console.info, console, settings.name + ':');
 12610                module.verbose.apply(console, arguments);
 12611              }
 12612            }
 12613          },
 12614          error: function() {
 12615            module.error = Function.prototype.bind.call(console.error, console, settings.name + ':');
 12616            module.error.apply(console, arguments);
 12617          },
 12618          performance: {
 12619            log: function(message) {
 12620              var
 12621                currentTime,
 12622                executionTime,
 12623                previousTime
 12624              ;
 12625              if(settings.performance) {
 12626                currentTime   = new Date().getTime();
 12627                previousTime  = time || currentTime;
 12628                executionTime = currentTime - previousTime;
 12629                time          = currentTime;
 12630                performance.push({
 12631                  'Name'           : message[0],
 12632                  'Arguments'      : [].slice.call(message, 1) || '',
 12633                  'Element'        : element,
 12634                  'Execution Time' : executionTime
 12635                });
 12636              }
 12637              clearTimeout(module.performance.timer);
 12638              module.performance.timer = setTimeout(module.performance.display, 0);
 12639            },
 12640            display: function() {
 12641              var
 12642                title = settings.name + ':',
 12643                totalTime = 0
 12644              ;
 12645              time = false;
 12646              clearTimeout(module.performance.timer);
 12647              $.each(performance, function(index, data) {
 12648                totalTime += data['Execution Time'];
 12649              });
 12650              title += ' ' + totalTime + 'ms';
 12651              if(moduleSelector) {
 12652                title += ' \'' + moduleSelector + '\'';
 12653              }
 12654              if( (console.group !== undefined || console.table !== undefined) && performance.length > 0) {
 12655                console.groupCollapsed(title);
 12656                if(console.table) {
 12657                  console.table(performance);
 12658                }
 12659                else {
 12660                  $.each(performance, function(index, data) {
 12661                    console.log(data['Name'] + ': ' + data['Execution Time']+'ms');
 12662                  });
 12663                }
 12664                console.groupEnd();
 12665              }
 12666              performance = [];
 12667            }
 12668          },
 12669          invoke: function(query, passedArguments, context) {
 12670            var
 12671              object = instance,
 12672              maxDepth,
 12673              found,
 12674              response
 12675            ;
 12676            passedArguments = passedArguments || queryArguments;
 12677            context         = element         || context;
 12678            if(typeof query == 'string' && object !== undefined) {
 12679              query    = query.split(/[\. ]/);
 12680              maxDepth = query.length - 1;
 12681              $.each(query, function(depth, value) {
 12682                var camelCaseValue = (depth != maxDepth)
 12683                  ? value + query[depth + 1].charAt(0).toUpperCase() + query[depth + 1].slice(1)
 12684                  : query
 12685                ;
 12686                if( $.isPlainObject( object[camelCaseValue] ) && (depth != maxDepth) ) {
 12687                  object = object[camelCaseValue];
 12688                }
 12689                else if( object[camelCaseValue] !== undefined ) {
 12690                  found = object[camelCaseValue];
 12691                  return false;
 12692                }
 12693                else if( $.isPlainObject( object[value] ) && (depth != maxDepth) ) {
 12694                  object = object[value];
 12695                }
 12696                else if( object[value] !== undefined ) {
 12697                  found = object[value];
 12698                  return false;
 12699                }
 12700                else {
 12701                  return false;
 12702                }
 12703              });
 12704            }
 12705            if ( $.isFunction( found ) ) {
 12706              response = found.apply(context, passedArguments);
 12707            }
 12708            else if(found !== undefined) {
 12709              response = found;
 12710            }
 12711            if($.isArray(returnedValue)) {
 12712              returnedValue.push(response);
 12713            }
 12714            else if(returnedValue !== undefined) {
 12715              returnedValue = [returnedValue, response];
 12716            }
 12717            else if(response !== undefined) {
 12718              returnedValue = response;
 12719            }
 12720            return found;
 12721          }
 12722        };
 12723  
 12724        if(methodInvoked) {
 12725          if(instance === undefined) {
 12726            module.initialize();
 12727          }
 12728          module.invoke(query);
 12729        }
 12730        else {
 12731          if(instance !== undefined) {
 12732            instance.invoke('destroy');
 12733          }
 12734          module.initialize();
 12735        }
 12736      })
 12737    ;
 12738  
 12739    return (returnedValue !== undefined)
 12740      ? returnedValue
 12741      : this
 12742    ;
 12743  };
 12744  
 12745  $.fn.sticky.settings = {
 12746  
 12747    name           : 'Sticky',
 12748    namespace      : 'sticky',
 12749  
 12750    debug          : false,
 12751    verbose        : false,
 12752    performance    : false,
 12753  
 12754    pushing        : false,
 12755    context        : false,
 12756    scrollContext  : window,
 12757  
 12758    offset         : 0,
 12759    bottomOffset   : 0,
 12760  
 12761    observeChanges : true,
 12762  
 12763    onReposition   : function(){},
 12764    onScroll       : function(){},
 12765    onStick        : function(){},
 12766    onUnstick      : function(){},
 12767    onTop          : function(){},
 12768    onBottom       : function(){},
 12769  
 12770    error         : {
 12771      container      : 'Sticky element must be inside a relative container',
 12772      visible        : 'Element is hidden, you must call refresh after element becomes visible',
 12773      method         : 'The method you called is not defined.',
 12774      invalidContext : 'Context specified does not exist',
 12775      elementSize    : 'Sticky element is larger than its container, cannot create sticky.'
 12776    },
 12777  
 12778    className : {
 12779      bound     : 'bound',
 12780      fixed     : 'fixed',
 12781      supported : 'native',
 12782      top       : 'top',
 12783      bottom    : 'bottom'
 12784    }
 12785  
 12786  };
 12787  
 12788  })( jQuery, window , document );
 12789  
 12790  /*!
 12791   * # Semantic UI x.x - Tab
 12792   * http://github.com/semantic-org/semantic-ui/
 12793   *
 12794   *
 12795   * Copyright 2014 Contributorss
 12796   * Released under the MIT license
 12797   * http://opensource.org/licenses/MIT
 12798   *
 12799   */
 12800  
 12801  ;(function ($, window, document, undefined) {
 12802  
 12803  "use strict";
 12804  
 12805  $.fn.tab = function(parameters) {
 12806  
 12807    var
 12808      // use window context if none specified
 12809      $allModules     = $.isFunction(this)
 12810          ? $(window)
 12811          : $(this),
 12812  
 12813      settings        = ( $.isPlainObject(parameters) )
 12814        ? $.extend(true, {}, $.fn.tab.settings, parameters)
 12815        : $.extend({}, $.fn.tab.settings),
 12816  
 12817      moduleSelector  = $allModules.selector || '',
 12818      time            = new Date().getTime(),
 12819      performance     = [],
 12820  
 12821      query           = arguments[0],
 12822      methodInvoked   = (typeof query == 'string'),
 12823      queryArguments  = [].slice.call(arguments, 1),
 12824  
 12825      module,
 12826      returnedValue
 12827    ;
 12828  
 12829    $allModules
 12830      .each(function() {
 12831        var
 12832  
 12833          className          = settings.className,
 12834          metadata           = settings.metadata,
 12835          selector           = settings.selector,
 12836          error              = settings.error,
 12837  
 12838          eventNamespace     = '.' + settings.namespace,
 12839          moduleNamespace    = 'module-' + settings.namespace,
 12840  
 12841          $module            = $(this),
 12842  
 12843          cache              = {},
 12844          firstLoad          = true,
 12845          recursionDepth     = 0,
 12846  
 12847          $context,
 12848          $tabs,
 12849          activeTabPath,
 12850          parameterArray,
 12851          historyEvent,
 12852  
 12853          element         = this,
 12854          instance        = $module.data(moduleNamespace)
 12855        ;
 12856  
 12857        module = {
 12858  
 12859          initialize: function() {
 12860            module.debug('Initializing tab menu item', $module);
 12861  
 12862            module.determineTabs();
 12863            module.debug('Determining tabs', settings.context, $tabs);
 12864  
 12865            // set up automatic routing
 12866            if(settings.auto) {
 12867              module.set.auto();
 12868            }
 12869  
 12870            // attach events if navigation wasn't set to window
 12871            if( !$.isWindow( element ) ) {
 12872              module.debug('Attaching tab activation events to element', $module);
 12873              $module
 12874                .on('click' + eventNamespace, module.event.click)
 12875              ;
 12876            }
 12877            module.instantiate();
 12878          },
 12879  
 12880          determineTabs: function() {
 12881            var
 12882              $reference
 12883            ;
 12884  
 12885            // determine tab context
 12886            if(settings.context === 'parent') {
 12887              if($module.closest(selector.ui).length > 0) {
 12888                $reference = $module.closest(selector.ui);
 12889                module.verbose('Using closest UI element for determining parent', $reference);
 12890              }
 12891              else {
 12892                $reference = $module;
 12893              }
 12894              $context = $reference.parent();
 12895              module.verbose('Determined parent element for creating context', $context);
 12896            }
 12897            else if(settings.context) {
 12898              $context = $(settings.context);
 12899              module.verbose('Using selector for tab context', settings.context, $context);
 12900            }
 12901            else {
 12902              $context = $('body');
 12903            }
 12904  
 12905            // find tabs
 12906            if(settings.childrenOnly) {
 12907              $tabs = $context.children(selector.tabs);
 12908              module.debug('Searching tab context children for tabs', $context, $tabs);
 12909            }
 12910            else {
 12911              $tabs = $context.find(selector.tabs);
 12912              module.debug('Searching tab context for tabs', $context, $tabs);
 12913            }
 12914          },
 12915  
 12916          initializeHistory: function() {
 12917            if(settings.history) {
 12918              module.debug('Initializing page state');
 12919              if( $.address === undefined ) {
 12920                module.error(error.state);
 12921                return false;
 12922              }
 12923              else {
 12924                if(settings.historyType == 'state') {
 12925                  module.debug('Using HTML5 to manage state');
 12926                  if(settings.path !== false) {
 12927                    $.address
 12928                      .history(true)
 12929                      .state(settings.path)
 12930                    ;
 12931                  }
 12932                  else {
 12933                    module.error(error.path);
 12934                    return false;
 12935                  }
 12936                }
 12937                $.address
 12938                  .bind('change', module.event.history.change)
 12939                ;
 12940              }
 12941            }
 12942          },
 12943  
 12944          instantiate: function () {
 12945            module.verbose('Storing instance of module', module);
 12946            instance = module;
 12947            $module
 12948              .data(moduleNamespace, module)
 12949            ;
 12950          },
 12951  
 12952          destroy: function() {
 12953            module.debug('Destroying tabs', $module);
 12954            $module
 12955              .removeData(moduleNamespace)
 12956              .off(eventNamespace)
 12957            ;
 12958          },
 12959  
 12960          event: {
 12961            click: function(event) {
 12962              var
 12963                tabPath = $(this).data(metadata.tab)
 12964              ;
 12965              if(tabPath !== undefined) {
 12966                if(settings.history) {
 12967                  module.verbose('Updating page state', event);
 12968                  $.address.value(tabPath);
 12969                }
 12970                else {
 12971                  module.verbose('Changing tab', event);
 12972                  module.changeTab(tabPath);
 12973                }
 12974                event.preventDefault();
 12975              }
 12976              else {
 12977                module.debug('No tab specified');
 12978              }
 12979            },
 12980            history: {
 12981              change: function(event) {
 12982                var
 12983                  tabPath   = event.pathNames.join('/') || module.get.initialPath(),
 12984                  pageTitle = settings.templates.determineTitle(tabPath) || false
 12985                ;
 12986                module.performance.display();
 12987                module.debug('History change event', tabPath, event);
 12988                historyEvent = event;
 12989                if(tabPath !== undefined) {
 12990                  module.changeTab(tabPath);
 12991                }
 12992                if(pageTitle) {
 12993                  $.address.title(pageTitle);
 12994                }
 12995              }
 12996            }
 12997          },
 12998  
 12999          refresh: function() {
 13000            if(activeTabPath) {
 13001              module.debug('Refreshing tab', activeTabPath);
 13002              module.changeTab(activeTabPath);
 13003            }
 13004          },
 13005  
 13006          cache: {
 13007  
 13008            read: function(cacheKey) {
 13009              return (cacheKey !== undefined)
 13010                ? cache[cacheKey]
 13011                : false
 13012              ;
 13013            },
 13014            add: function(cacheKey, content) {
 13015              cacheKey = cacheKey || activeTabPath;
 13016              module.debug('Adding cached content for', cacheKey);
 13017              cache[cacheKey] = content;
 13018            },
 13019            remove: function(cacheKey) {
 13020              cacheKey = cacheKey || activeTabPath;
 13021              module.debug('Removing cached content for', cacheKey);
 13022              delete cache[cacheKey];
 13023            }
 13024          },
 13025  
 13026          set: {
 13027            auto: function() {
 13028              var
 13029                url = (typeof settings.path == 'string')
 13030                  ? settings.path.replace(/\/$/, '') + '/{$tab}'
 13031                  : '/{$tab}'
 13032              ;
 13033              module.verbose('Setting up automatic tab retrieval from server', url);
 13034              if($.isPlainObject(settings.apiSettings)) {
 13035                settings.apiSettings.url = url;
 13036              }
 13037              else {
 13038                settings.apiSettings = {
 13039                  url: url
 13040                };
 13041              }
 13042            },
 13043            state: function(state) {
 13044              $.address.value(state);
 13045            }
 13046          },
 13047  
 13048          changeTab: function(tabPath) {
 13049            var
 13050              pushStateAvailable = (window.history && window.history.pushState),
 13051              shouldIgnoreLoad   = (pushStateAvailable && settings.ignoreFirstLoad && firstLoad),
 13052              remoteContent      = (settings.auto || $.isPlainObject(settings.apiSettings) ),
 13053              // only get default path if not remote content
 13054              pathArray = (remoteContent && !shouldIgnoreLoad)
 13055                ? module.utilities.pathToArray(tabPath)
 13056                : module.get.defaultPathArray(tabPath)
 13057            ;
 13058            tabPath = module.utilities.arrayToPath(pathArray);
 13059            $.each(pathArray, function(index, tab) {
 13060              var
 13061                currentPathArray   = pathArray.slice(0, index + 1),
 13062                currentPath        = module.utilities.arrayToPath(currentPathArray),
 13063  
 13064                isTab              = module.is.tab(currentPath),
 13065                isLastIndex        = (index + 1 == pathArray.length),
 13066  
 13067                $tab               = module.get.tabElement(currentPath),
 13068                $anchor,
 13069                nextPathArray,
 13070                nextPath,
 13071                isLastTab
 13072              ;
 13073              module.verbose('Looking for tab', tab);
 13074              if(isTab) {
 13075  
 13076                module.verbose('Tab was found', tab);
 13077                // scope up
 13078                activeTabPath  = currentPath;
 13079                parameterArray = module.utilities.filterArray(pathArray, currentPathArray);
 13080  
 13081                if(isLastIndex) {
 13082                  isLastTab = true;
 13083                }
 13084                else {
 13085                  nextPathArray = pathArray.slice(0, index + 2);
 13086                  nextPath      = module.utilities.arrayToPath(nextPathArray);
 13087                  isLastTab     = ( !module.is.tab(nextPath) );
 13088                  if(isLastTab) {
 13089                    module.verbose('Tab parameters found', nextPathArray);
 13090                  }
 13091                }
 13092                if(isLastTab && remoteContent) {
 13093                  if(!shouldIgnoreLoad) {
 13094                    module.activate.navigation(currentPath);
 13095                    module.content.fetch(currentPath, tabPath);
 13096                  }
 13097                  else {
 13098                    module.debug('Ignoring remote content on first tab load', currentPath);
 13099                    firstLoad = false;
 13100                    module.cache.add(tabPath, $tab.html());
 13101                    module.activate.all(currentPath);
 13102                    settings.onTabInit.call($tab, currentPath, parameterArray, historyEvent);
 13103                    settings.onTabLoad.call($tab, currentPath, parameterArray, historyEvent);
 13104                  }
 13105                  return false;
 13106                }
 13107                else {
 13108                  module.debug('Opened local tab', currentPath);
 13109                  module.activate.all(currentPath);
 13110                  if( !module.cache.read(currentPath) ) {
 13111                    module.cache.add(currentPath, true);
 13112                    module.debug('First time tab loaded calling tab init');
 13113                    settings.onTabInit.call($tab, currentPath, parameterArray, historyEvent);
 13114                  }
 13115                  settings.onTabLoad.call($tab, currentPath, parameterArray, historyEvent);
 13116                }
 13117              }
 13118              else if(tabPath.search('/') == -1 && tabPath !== '') {
 13119                // look for in page anchor
 13120                $anchor     = $('#' + tabPath + ', a[name="' + tabPath + '"]'),
 13121                currentPath = $anchor.closest('[data-tab]').data('tab');
 13122                $tab        = module.get.tabElement(currentPath);
 13123                // if anchor exists use parent tab
 13124                if($anchor && $anchor.length > 0 && currentPath) {
 13125                  module.debug('No tab found, but deep anchor link present, opening parent tab');
 13126                  module.activate.all(currentPath);
 13127                  if( !module.cache.read(currentPath) ) {
 13128                    module.cache.add(currentPath, true);
 13129                    module.debug('First time tab loaded calling tab init');
 13130                    settings.onTabInit.call($tab, currentPath, parameterArray, historyEvent);
 13131                  }
 13132                  return false;
 13133                }
 13134              }
 13135              else {
 13136                module.error(error.missingTab, $module, $context, currentPath);
 13137                return false;
 13138              }
 13139            });
 13140          },
 13141  
 13142          content: {
 13143  
 13144            fetch: function(tabPath, fullTabPath) {
 13145              var
 13146                $tab        = module.get.tabElement(tabPath),
 13147                apiSettings = {
 13148                  dataType : 'html',
 13149                  on       : 'now',
 13150                  onSuccess    : function(response) {
 13151                    module.cache.add(fullTabPath, response);
 13152                    module.content.update(tabPath, response);
 13153                    if(tabPath == activeTabPath) {
 13154                      module.debug('Content loaded', tabPath);
 13155                      module.activate.tab(tabPath);
 13156                    }
 13157                    else {
 13158                      module.debug('Content loaded in background', tabPath);
 13159                    }
 13160                    settings.onTabInit.call($tab, tabPath, parameterArray, historyEvent);
 13161                    settings.onTabLoad.call($tab, tabPath, parameterArray, historyEvent);
 13162                  },
 13163                  urlData: { tab: fullTabPath }
 13164                },
 13165                request         = $tab.api('get request') || false,
 13166                existingRequest = ( request && request.state() === 'pending' ),
 13167                requestSettings,
 13168                cachedContent
 13169              ;
 13170  
 13171              fullTabPath   = fullTabPath || tabPath;
 13172              cachedContent = module.cache.read(fullTabPath);
 13173  
 13174  
 13175              module.activate.tab(tabPath);
 13176  
 13177              if(settings.cache && cachedContent) {
 13178                module.debug('Showing existing content', fullTabPath);
 13179                module.content.update(tabPath, cachedContent);
 13180                settings.onTabLoad.call($tab, tabPath, parameterArray, historyEvent);
 13181              }
 13182              else if(existingRequest) {
 13183                module.debug('Content is already loading', fullTabPath);
 13184                $tab.addClass(className.loading);
 13185              }
 13186              else if($.api !== undefined) {
 13187                requestSettings = $.extend(true, {
 13188                  headers: { 'X-Remote': true }
 13189                }, settings.apiSettings, apiSettings);
 13190                module.debug('Retrieving remote content', fullTabPath, requestSettings);
 13191                $tab.api( requestSettings );
 13192              }
 13193              else {
 13194                module.error(error.api);
 13195              }
 13196            },
 13197  
 13198            update: function(tabPath, html) {
 13199              module.debug('Updating html for', tabPath);
 13200              var
 13201                $tab = module.get.tabElement(tabPath)
 13202              ;
 13203              $tab
 13204                .html(html)
 13205              ;
 13206            }
 13207          },
 13208  
 13209          activate: {
 13210            all: function(tabPath) {
 13211              module.activate.tab(tabPath);
 13212              module.activate.navigation(tabPath);
 13213            },
 13214            tab: function(tabPath) {
 13215              var
 13216                $tab = module.get.tabElement(tabPath)
 13217              ;
 13218              module.verbose('Showing tab content for', $tab);
 13219              $tab
 13220                .addClass(className.active)
 13221                .siblings($tabs)
 13222                  .removeClass(className.active + ' ' + className.loading)
 13223              ;
 13224            },
 13225            navigation: function(tabPath) {
 13226              var
 13227                $navigation = module.get.navElement(tabPath)
 13228              ;
 13229              module.verbose('Activating tab navigation for', $navigation, tabPath);
 13230              $navigation
 13231                .addClass(className.active)
 13232                .siblings($allModules)
 13233                  .removeClass(className.active + ' ' + className.loading)
 13234              ;
 13235            }
 13236          },
 13237  
 13238          deactivate: {
 13239            all: function() {
 13240              module.deactivate.navigation();
 13241              module.deactivate.tabs();
 13242            },
 13243            navigation: function() {
 13244              $allModules
 13245                .removeClass(className.active)
 13246              ;
 13247            },
 13248            tabs: function() {
 13249              $tabs
 13250                .removeClass(className.active + ' ' + className.loading)
 13251              ;
 13252            }
 13253          },
 13254  
 13255          is: {
 13256            tab: function(tabName) {
 13257              return (tabName !== undefined)
 13258                ? ( module.get.tabElement(tabName).length > 0 )
 13259                : false
 13260              ;
 13261            }
 13262          },
 13263  
 13264          get: {
 13265            initialPath: function() {
 13266              return $allModules.eq(0).data(metadata.tab) || $tabs.eq(0).data(metadata.tab);
 13267            },
 13268            path: function() {
 13269              return $.address.value();
 13270            },
 13271            // adds default tabs to tab path
 13272            defaultPathArray: function(tabPath) {
 13273              return module.utilities.pathToArray( module.get.defaultPath(tabPath) );
 13274            },
 13275            defaultPath: function(tabPath) {
 13276              var
 13277                $defaultNav = $allModules.filter('[data-' + metadata.tab + '^="' + tabPath + '/"]').eq(0),
 13278                defaultTab  = $defaultNav.data(metadata.tab) || false
 13279              ;
 13280              if( defaultTab ) {
 13281                module.debug('Found default tab', defaultTab);
 13282                if(recursionDepth < settings.maxDepth) {
 13283                  recursionDepth++;
 13284                  return module.get.defaultPath(defaultTab);
 13285                }
 13286                module.error(error.recursion);
 13287              }
 13288              else {
 13289                module.debug('No default tabs found for', tabPath, $tabs);
 13290              }
 13291              recursionDepth = 0;
 13292              return tabPath;
 13293            },
 13294            navElement: function(tabPath) {
 13295              tabPath = tabPath || activeTabPath;
 13296              return $allModules.filter('[data-' + metadata.tab + '="' + tabPath + '"]');
 13297            },
 13298            tabElement: function(tabPath) {
 13299              var
 13300                $fullPathTab,
 13301                $simplePathTab,
 13302                tabPathArray,
 13303                lastTab
 13304              ;
 13305              tabPath        = tabPath || activeTabPath;
 13306              tabPathArray   = module.utilities.pathToArray(tabPath);
 13307              lastTab        = module.utilities.last(tabPathArray);
 13308              $fullPathTab   = $tabs.filter('[data-' + metadata.tab + '="' + lastTab + '"]');
 13309              $simplePathTab = $tabs.filter('[data-' + metadata.tab + '="' + tabPath + '"]');
 13310              return ($fullPathTab.length > 0)
 13311                ? $fullPathTab
 13312                : $simplePathTab
 13313              ;
 13314            },
 13315            tab: function() {
 13316              return activeTabPath;
 13317            }
 13318          },
 13319  
 13320          utilities: {
 13321            filterArray: function(keepArray, removeArray) {
 13322              return $.grep(keepArray, function(keepValue) {
 13323                return ( $.inArray(keepValue, removeArray) == -1);
 13324              });
 13325            },
 13326            last: function(array) {
 13327              return $.isArray(array)
 13328                ? array[ array.length - 1]
 13329                : false
 13330              ;
 13331            },
 13332            pathToArray: function(pathName) {
 13333              if(pathName === undefined) {
 13334                pathName = activeTabPath;
 13335              }
 13336              return typeof pathName == 'string'
 13337                ? pathName.split('/')
 13338                : [pathName]
 13339              ;
 13340            },
 13341            arrayToPath: function(pathArray) {
 13342              return $.isArray(pathArray)
 13343                ? pathArray.join('/')
 13344                : false
 13345              ;
 13346            }
 13347          },
 13348  
 13349          setting: function(name, value) {
 13350            module.debug('Changing setting', name, value);
 13351            if( $.isPlainObject(name) ) {
 13352              $.extend(true, settings, name);
 13353            }
 13354            else if(value !== undefined) {
 13355              settings[name] = value;
 13356            }
 13357            else {
 13358              return settings[name];
 13359            }
 13360          },
 13361          internal: function(name, value) {
 13362            if( $.isPlainObject(name) ) {
 13363              $.extend(true, module, name);
 13364            }
 13365            else if(value !== undefined) {
 13366              module[name] = value;
 13367            }
 13368            else {
 13369              return module[name];
 13370            }
 13371          },
 13372          debug: function() {
 13373            if(settings.debug) {
 13374              if(settings.performance) {
 13375                module.performance.log(arguments);
 13376              }
 13377              else {
 13378                module.debug = Function.prototype.bind.call(console.info, console, settings.name + ':');
 13379                module.debug.apply(console, arguments);
 13380              }
 13381            }
 13382          },
 13383          verbose: function() {
 13384            if(settings.verbose && settings.debug) {
 13385              if(settings.performance) {
 13386                module.performance.log(arguments);
 13387              }
 13388              else {
 13389                module.verbose = Function.prototype.bind.call(console.info, console, settings.name + ':');
 13390                module.verbose.apply(console, arguments);
 13391              }
 13392            }
 13393          },
 13394          error: function() {
 13395            module.error = Function.prototype.bind.call(console.error, console, settings.name + ':');
 13396            module.error.apply(console, arguments);
 13397          },
 13398          performance: {
 13399            log: function(message) {
 13400              var
 13401                currentTime,
 13402                executionTime,
 13403                previousTime
 13404              ;
 13405              if(settings.performance) {
 13406                currentTime   = new Date().getTime();
 13407                previousTime  = time || currentTime;
 13408                executionTime = currentTime - previousTime;
 13409                time          = currentTime;
 13410                performance.push({
 13411                  'Name'           : message[0],
 13412                  'Arguments'      : [].slice.call(message, 1) || '',
 13413                  'Element'        : element,
 13414                  'Execution Time' : executionTime
 13415                });
 13416              }
 13417              clearTimeout(module.performance.timer);
 13418              module.performance.timer = setTimeout(module.performance.display, 100);
 13419            },
 13420            display: function() {
 13421              var
 13422                title = settings.name + ':',
 13423                totalTime = 0
 13424              ;
 13425              time = false;
 13426              clearTimeout(module.performance.timer);
 13427              $.each(performance, function(index, data) {
 13428                totalTime += data['Execution Time'];
 13429              });
 13430              title += ' ' + totalTime + 'ms';
 13431              if(moduleSelector) {
 13432                title += ' \'' + moduleSelector + '\'';
 13433              }
 13434              if( (console.group !== undefined || console.table !== undefined) && performance.length > 0) {
 13435                console.groupCollapsed(title);
 13436                if(console.table) {
 13437                  console.table(performance);
 13438                }
 13439                else {
 13440                  $.each(performance, function(index, data) {
 13441                    console.log(data['Name'] + ': ' + data['Execution Time']+'ms');
 13442                  });
 13443                }
 13444                console.groupEnd();
 13445              }
 13446              performance = [];
 13447            }
 13448          },
 13449          invoke: function(query, passedArguments, context) {
 13450            var
 13451              object = instance,
 13452              maxDepth,
 13453              found,
 13454              response
 13455            ;
 13456            passedArguments = passedArguments || queryArguments;
 13457            context         = element         || context;
 13458            if(typeof query == 'string' && object !== undefined) {
 13459              query    = query.split(/[\. ]/);
 13460              maxDepth = query.length - 1;
 13461              $.each(query, function(depth, value) {
 13462                var camelCaseValue = (depth != maxDepth)
 13463                  ? value + query[depth + 1].charAt(0).toUpperCase() + query[depth + 1].slice(1)
 13464                  : query
 13465                ;
 13466                if( $.isPlainObject( object[camelCaseValue] ) && (depth != maxDepth) ) {
 13467                  object = object[camelCaseValue];
 13468                }
 13469                else if( object[camelCaseValue] !== undefined ) {
 13470                  found = object[camelCaseValue];
 13471                  return false;
 13472                }
 13473                else if( $.isPlainObject( object[value] ) && (depth != maxDepth) ) {
 13474                  object = object[value];
 13475                }
 13476                else if( object[value] !== undefined ) {
 13477                  found = object[value];
 13478                  return false;
 13479                }
 13480                else {
 13481                  module.error(error.method, query);
 13482                  return false;
 13483                }
 13484              });
 13485            }
 13486            if ( $.isFunction( found ) ) {
 13487              response = found.apply(context, passedArguments);
 13488            }
 13489            else if(found !== undefined) {
 13490              response = found;
 13491            }
 13492            if($.isArray(returnedValue)) {
 13493              returnedValue.push(response);
 13494            }
 13495            else if(returnedValue !== undefined) {
 13496              returnedValue = [returnedValue, response];
 13497            }
 13498            else if(response !== undefined) {
 13499              returnedValue = response;
 13500            }
 13501            return found;
 13502          }
 13503        };
 13504        if(methodInvoked) {
 13505          if(instance === undefined) {
 13506            module.initialize();
 13507          }
 13508          module.invoke(query);
 13509        }
 13510        else {
 13511          if(instance !== undefined) {
 13512            instance.invoke('destroy');
 13513          }
 13514          module.initialize();
 13515        }
 13516      })
 13517    ;
 13518    if(module && !methodInvoked) {
 13519      module.initializeHistory();
 13520    }
 13521    return (returnedValue !== undefined)
 13522      ? returnedValue
 13523      : this
 13524    ;
 13525  
 13526  };
 13527  
 13528  // shortcut for tabbed content with no defined navigation
 13529  $.tab = function() {
 13530    $(window).tab.apply(this, arguments);
 13531  };
 13532  
 13533  $.fn.tab.settings = {
 13534  
 13535    name            : 'Tab',
 13536    namespace       : 'tab',
 13537  
 13538    debug           : false,
 13539    verbose         : true,
 13540    performance     : true,
 13541  
 13542    auto            : false,  // uses pjax style endpoints fetching content from same url with remote-content headers
 13543    history         : false,  // use browser history
 13544    historyType     : 'hash', // #/ or html5 state
 13545    path            : false,  // base path of url
 13546  
 13547    context         : false,  // specify a context that tabs must appear inside
 13548    childrenOnly    : false,  // use only tabs that are children of context
 13549    maxDepth        : 25,     // max depth a tab can be nested
 13550  
 13551    alwaysRefresh   : false,  // load tab content new every tab click
 13552    cache           : true,   // cache the content requests to pull locally
 13553    ignoreFirstLoad : false,  // don't load remote content on first load
 13554    apiSettings     : false,  // settings for api call
 13555  
 13556    onTabInit    : function(tabPath, parameterArray, historyEvent) {}, // called first time loaded
 13557    onTabLoad    : function(tabPath, parameterArray, historyEvent) {}, // called on every load
 13558  
 13559    templates    : {
 13560      determineTitle: function(tabArray) {} // returns page title for path
 13561    },
 13562  
 13563    error: {
 13564      api        : 'You attempted to load content without API module',
 13565      method     : 'The method you called is not defined',
 13566      missingTab : 'Activated tab cannot be found for this context.',
 13567      noContent  : 'The tab you specified is missing a content url.',
 13568      path       : 'History enabled, but no path was specified',
 13569      recursion  : 'Max recursive depth reached',
 13570      state      : 'History requires Asual\'s Address library <https://github.com/asual/jquery-address>'
 13571    },
 13572  
 13573    metadata : {
 13574      tab    : 'tab',
 13575      loaded : 'loaded',
 13576      promise: 'promise'
 13577    },
 13578  
 13579    className   : {
 13580      loading : 'loading',
 13581      active  : 'active'
 13582    },
 13583  
 13584    selector    : {
 13585      tabs : '.ui.tab',
 13586      ui   : '.ui'
 13587    }
 13588  
 13589  };
 13590  
 13591  })( jQuery, window , document );
 13592  /*!
 13593   * # Semantic UI x.x - Transition
 13594   * http://github.com/semantic-org/semantic-ui/
 13595   *
 13596   *
 13597   * Copyright 2014 Contributors
 13598   * Released under the MIT license
 13599   * http://opensource.org/licenses/MIT
 13600   *
 13601   */
 13602  
 13603  ;(function ( $, window, document, undefined ) {
 13604  
 13605  "use strict";
 13606  
 13607  $.fn.transition = function() {
 13608    var
 13609      $allModules     = $(this),
 13610      moduleSelector  = $allModules.selector || '',
 13611  
 13612      time            = new Date().getTime(),
 13613      performance     = [],
 13614  
 13615      moduleArguments = arguments,
 13616      query           = moduleArguments[0],
 13617      queryArguments  = [].slice.call(arguments, 1),
 13618      methodInvoked   = (typeof query === 'string'),
 13619  
 13620      requestAnimationFrame = window.requestAnimationFrame
 13621        || window.mozRequestAnimationFrame
 13622        || window.webkitRequestAnimationFrame
 13623        || window.msRequestAnimationFrame
 13624        || function(callback) { setTimeout(callback, 0); },
 13625  
 13626      returnedValue
 13627    ;
 13628    $allModules
 13629      .each(function(index) {
 13630        var
 13631          $module  = $(this),
 13632          element  = this,
 13633  
 13634          // set at run time
 13635          settings,
 13636          instance,
 13637  
 13638          error,
 13639          className,
 13640          metadata,
 13641          animationStart,
 13642          animationEnd,
 13643          animationName,
 13644  
 13645          namespace,
 13646          moduleNamespace,
 13647          eventNamespace,
 13648          module
 13649        ;
 13650  
 13651        module = {
 13652  
 13653          initialize: function() {
 13654  
 13655            // get full settings
 13656            settings        = module.get.settings.apply(element, moduleArguments);
 13657  
 13658            // shorthand
 13659            className       = settings.className;
 13660            error           = settings.error;
 13661            metadata        = settings.metadata;
 13662  
 13663            // define namespace
 13664            eventNamespace  = '.' + settings.namespace;
 13665            moduleNamespace = 'module-' + settings.namespace;
 13666            instance        = $module.data(moduleNamespace) || module;
 13667  
 13668            // get vendor specific events
 13669            animationEnd    = module.get.animationEndEvent();
 13670            animationName   = module.get.animationName();
 13671            animationStart  = module.get.animationStartEvent();
 13672  
 13673            if(methodInvoked) {
 13674              methodInvoked = module.invoke(query);
 13675            }
 13676  
 13677            // method not invoked, lets run an animation
 13678            if(methodInvoked === false) {
 13679              module.verbose('Converted arguments into settings object', settings);
 13680              if(settings.interval) {
 13681                module.delay(settings.animate);
 13682              }
 13683              else  {
 13684                module.animate();
 13685              }
 13686              module.instantiate();
 13687            }
 13688          },
 13689  
 13690          instantiate: function() {
 13691            module.verbose('Storing instance of module', module);
 13692            instance = module;
 13693            $module
 13694              .data(moduleNamespace, instance)
 13695            ;
 13696          },
 13697  
 13698          destroy: function() {
 13699            module.verbose('Destroying previous module for', element);
 13700            $module
 13701              .removeData(moduleNamespace)
 13702            ;
 13703          },
 13704  
 13705          refresh: function() {
 13706            module.verbose('Refreshing display type on next animation');
 13707            delete module.displayType;
 13708          },
 13709  
 13710          forceRepaint: function() {
 13711            module.verbose('Forcing element repaint');
 13712            var
 13713              $parentElement = $module.parent(),
 13714              $nextElement = $module.next()
 13715            ;
 13716            if($nextElement.length === 0) {
 13717              $module.detach().appendTo($parentElement);
 13718            }
 13719            else {
 13720              $module.detach().insertBefore($nextElement);
 13721            }
 13722          },
 13723  
 13724          repaint: function() {
 13725            module.verbose('Repainting element');
 13726            var
 13727              fakeAssignment = element.offsetWidth
 13728            ;
 13729          },
 13730  
 13731          delay: function(interval) {
 13732            var
 13733              isReverse = (settings.reverse === true),
 13734              shouldReverse = (settings.reverse == 'auto' && module.get.direction() == className.outward),
 13735              delay
 13736            ;
 13737            interval = (typeof interval !== undefined)
 13738              ? interval
 13739              : settings.interval
 13740            ;
 13741            delay = (isReverse || shouldReverse)
 13742              ? ($allModules.length - index) * settings.interval
 13743              : index * settings.interval
 13744            ;
 13745            module.debug('Delaying animation by', delay);
 13746            setTimeout(module.animate, delay);
 13747          },
 13748  
 13749          animate: function(overrideSettings) {
 13750            settings = overrideSettings || settings;
 13751            if(!module.is.supported()) {
 13752              module.error(error.support);
 13753              return false;
 13754            }
 13755            module.debug('Preparing animation', settings.animation);
 13756            if(module.is.animating()) {
 13757              if(settings.queue) {
 13758                if(!settings.allowRepeats && module.has.direction() && module.is.occurring() && module.queuing !== true) {
 13759                  module.debug('Animation is currently occurring, preventing queueing same animation', settings.animation);
 13760                }
 13761                else {
 13762                  module.queue(settings.animation);
 13763                }
 13764                return false;
 13765              }
 13766              else if(!settings.allowRepeats && module.is.occurring()) {
 13767                module.debug('Animation is already occurring, will not execute repeated animation', settings.animation);
 13768                return false;
 13769              }
 13770              else {
 13771                module.debug('New animation started, completing previous early', settings.animation);
 13772                module.complete();
 13773              }
 13774            }
 13775            if( module.can.animate() ) {
 13776              module.set.animating(settings.animation);
 13777            }
 13778            else {
 13779              module.error(error.noAnimation, settings.animation, element);
 13780            }
 13781          },
 13782  
 13783          reset: function() {
 13784            module.debug('Resetting animation to beginning conditions');
 13785            module.remove.animationCallbacks();
 13786            module.restore.conditions();
 13787            module.remove.animating();
 13788          },
 13789  
 13790          queue: function(animation) {
 13791            module.debug('Queueing animation of', animation);
 13792            module.queuing = true;
 13793            $module
 13794              .one(animationEnd + '.queue' + eventNamespace, function() {
 13795                module.queuing = false;
 13796                module.repaint();
 13797                module.animate.apply(this, settings);
 13798              })
 13799            ;
 13800          },
 13801  
 13802          complete: function (event) {
 13803            module.debug('Animation complete', settings.animation);
 13804            module.remove.completeCallback();
 13805            module.remove.failSafe();
 13806            if(!module.is.looping()) {
 13807              if( module.is.outward() ) {
 13808                module.verbose('Animation is outward, hiding element');
 13809                module.restore.conditions();
 13810                module.hide();
 13811                settings.onHide.call(this);
 13812              }
 13813              else if( module.is.inward() ) {
 13814                module.verbose('Animation is outward, showing element');
 13815                module.restore.conditions();
 13816                module.show();
 13817                settings.onShow.call(this);
 13818              }
 13819              else {
 13820                module.restore.conditions();
 13821              }
 13822              module.remove.animation();
 13823              module.remove.animating();
 13824            }
 13825            settings.onComplete.call(this);
 13826          },
 13827  
 13828          has: {
 13829            direction: function(animation) {
 13830              var
 13831                hasDirection = false
 13832              ;
 13833              animation = animation || settings.animation;
 13834              if(typeof animation === 'string') {
 13835                animation = animation.split(' ');
 13836                $.each(animation, function(index, word){
 13837                  if(word === className.inward || word === className.outward) {
 13838                    hasDirection = true;
 13839                  }
 13840                });
 13841              }
 13842              return hasDirection;
 13843            },
 13844            inlineDisplay: function() {
 13845              var
 13846                style = $module.attr('style') || ''
 13847              ;
 13848              return $.isArray(style.match(/display.*?;/, ''));
 13849            }
 13850          },
 13851  
 13852          set: {
 13853            animating: function(animation) {
 13854              animation = animation || settings.animation;
 13855              if(!module.is.animating()) {
 13856                module.save.conditions();
 13857              }
 13858              module.remove.direction();
 13859              module.remove.completeCallback();
 13860              if(module.can.transition() && !module.has.direction()) {
 13861                module.set.direction();
 13862              }
 13863              module.remove.hidden();
 13864              module.set.display();
 13865              $module
 13866                .addClass(className.animating + ' ' + className.transition + ' ' + animation)
 13867                .addClass(animation)
 13868                .one(animationEnd + '.complete' + eventNamespace, module.complete)
 13869              ;
 13870              if(settings.useFailSafe) {
 13871                module.add.failSafe();
 13872              }
 13873              module.set.duration(settings.duration);
 13874              settings.onStart.call(this);
 13875              module.debug('Starting tween', animation, $module.attr('class'));
 13876            },
 13877            duration: function(animationName, duration) {
 13878              duration = duration || settings.duration;
 13879              duration = (typeof duration == 'number')
 13880                ? duration + 'ms'
 13881                : duration
 13882              ;
 13883              if(duration || duration === 0) {
 13884                module.verbose('Setting animation duration', duration);
 13885                $module
 13886                  .css({
 13887                    '-webkit-animation-duration': duration,
 13888                    '-moz-animation-duration': duration,
 13889                    '-ms-animation-duration': duration,
 13890                    '-o-animation-duration': duration,
 13891                    'animation-duration':  duration
 13892                  })
 13893                ;
 13894              }
 13895            },
 13896            display: function() {
 13897              var
 13898                style              = module.get.style(),
 13899                displayType        = module.get.displayType(),
 13900                overrideStyle      = style + 'display: ' + displayType + ' !important;'
 13901              ;
 13902              $module.css('display', '');
 13903              module.refresh();
 13904              if( $module.css('display') !== displayType ) {
 13905                module.verbose('Setting inline visibility to', displayType);
 13906                $module
 13907                  .attr('style', overrideStyle)
 13908                ;
 13909              }
 13910            },
 13911            direction: function() {
 13912              if($module.is(':visible') && !module.is.hidden()) {
 13913                module.debug('Automatically determining the direction of animation', 'Outward');
 13914                $module
 13915                  .removeClass(className.inward)
 13916                  .addClass(className.outward)
 13917                ;
 13918              }
 13919              else {
 13920                module.debug('Automatically determining the direction of animation', 'Inward');
 13921                $module
 13922                  .removeClass(className.outward)
 13923                  .addClass(className.inward)
 13924                ;
 13925              }
 13926            },
 13927            looping: function() {
 13928              module.debug('Transition set to loop');
 13929              $module
 13930                .addClass(className.looping)
 13931              ;
 13932            },
 13933            hidden: function() {
 13934              if(!module.is.hidden()) {
 13935                $module
 13936                  .addClass(className.transition)
 13937                  .addClass(className.hidden)
 13938                ;
 13939              }
 13940              if($module.css('display') !== 'none') {
 13941                module.verbose('Overriding default display to hide element');
 13942                $module
 13943                  .css('display', 'none')
 13944                ;
 13945              }
 13946            },
 13947            visible: function() {
 13948              $module
 13949                .addClass(className.transition)
 13950                .addClass(className.visible)
 13951              ;
 13952            }
 13953          },
 13954  
 13955          save: {
 13956            displayType: function(displayType) {
 13957              $module.data(metadata.displayType, displayType);
 13958            },
 13959            transitionExists: function(animation, exists) {
 13960              $.fn.transition.exists[animation] = exists;
 13961              module.verbose('Saving existence of transition', animation, exists);
 13962            },
 13963            conditions: function() {
 13964              var
 13965                clasName = $module.attr('class') || false,
 13966                style    = $module.attr('style') || ''
 13967              ;
 13968              $module.removeClass(settings.animation);
 13969              module.remove.direction();
 13970              module.cache = {
 13971                className : $module.attr('class'),
 13972                style     : module.get.style()
 13973              };
 13974              module.verbose('Saving original attributes', module.cache);
 13975            }
 13976          },
 13977  
 13978          restore: {
 13979            conditions: function() {
 13980              if(module.cache === undefined) {
 13981                return false;
 13982              }
 13983              if(module.cache.className) {
 13984                $module.attr('class', module.cache.className);
 13985              }
 13986              else {
 13987                $module.removeAttr('class');
 13988              }
 13989              if(module.cache.style) {
 13990                module.verbose('Restoring original style attribute', module.cache.style);
 13991                $module.attr('style', module.cache.style);
 13992              }
 13993              else {
 13994                module.verbose('Clearing style attribute');
 13995                $module.removeAttr('style');
 13996              }
 13997              module.verbose('Restoring original attributes', module.cache);
 13998            }
 13999          },
 14000  
 14001          add: {
 14002            failSafe: function() {
 14003              var
 14004                duration = module.get.duration()
 14005              ;
 14006              module.timer = setTimeout(function() {
 14007                $module.trigger(animationEnd);
 14008              }, duration + settings.failSafeDelay);
 14009              module.verbose('Adding fail safe timer', module.timer);
 14010            }
 14011          },
 14012  
 14013          remove: {
 14014            animating: function() {
 14015              $module.removeClass(className.animating);
 14016            },
 14017            animation: function() {
 14018              $module
 14019                .css({
 14020                  '-webkit-animation' : '',
 14021                  '-moz-animation'    : '',
 14022                  '-ms-animation'     : '',
 14023                  '-o-animation'      : '',
 14024                  'animation'         : ''
 14025                })
 14026              ;
 14027            },
 14028            animationCallbacks: function() {
 14029              module.remove.queueCallback();
 14030              module.remove.completeCallback();
 14031            },
 14032            queueCallback: function() {
 14033              $module.off('.queue' + eventNamespace)
 14034            },
 14035            completeCallback: function() {
 14036              $module.off('.complete' + eventNamespace);
 14037            },
 14038            display: function() {
 14039              $module.css('display', '');
 14040            },
 14041            direction: function() {
 14042              $module
 14043                .removeClass(className.inward)
 14044                .removeClass(className.outward)
 14045              ;
 14046            },
 14047            failSafe: function() {
 14048              module.verbose('Removing fail safe timer', module.timer);
 14049              if(module.timer) {
 14050                clearTimeout(module.timer);
 14051              }
 14052            },
 14053            hidden: function() {
 14054              $module.removeClass(className.hidden);
 14055            },
 14056            visible: function() {
 14057              $module.removeClass(className.visible);
 14058            },
 14059            looping: function() {
 14060              module.debug('Transitions are no longer looping');
 14061              if( module.is.looping() ) {
 14062                module.reset();
 14063                $module
 14064                  .removeClass(className.looping)
 14065                ;
 14066              }
 14067            },
 14068            transition: function() {
 14069              $module
 14070                .removeClass(className.visible)
 14071                .removeClass(className.hidden)
 14072              ;
 14073            }
 14074          },
 14075          get: {
 14076            settings: function(animation, duration, onComplete) {
 14077              // single settings object
 14078              if(typeof animation == 'object') {
 14079                return $.extend(true, {}, $.fn.transition.settings, animation);
 14080              }
 14081              // all arguments provided
 14082              else if(typeof onComplete == 'function') {
 14083                return $.extend({}, $.fn.transition.settings, {
 14084                  animation  : animation,
 14085                  onComplete : onComplete,
 14086                  duration   : duration
 14087                });
 14088              }
 14089              // only duration provided
 14090              else if(typeof duration == 'string' || typeof duration == 'number') {
 14091                return $.extend({}, $.fn.transition.settings, {
 14092                  animation : animation,
 14093                  duration  : duration
 14094                });
 14095              }
 14096              // duration is actually settings object
 14097              else if(typeof duration == 'object') {
 14098                return $.extend({}, $.fn.transition.settings, duration, {
 14099                  animation : animation
 14100                });
 14101              }
 14102              // duration is actually callback
 14103              else if(typeof duration == 'function') {
 14104                return $.extend({}, $.fn.transition.settings, {
 14105                  animation  : animation,
 14106                  onComplete : duration
 14107                });
 14108              }
 14109              // only animation provided
 14110              else {
 14111                return $.extend({}, $.fn.transition.settings, {
 14112                  animation : animation
 14113                });
 14114              }
 14115              return $.fn.transition.settings;
 14116            },
 14117            direction: function(animation) {
 14118              // quickest manually specified direction
 14119              animation = animation || settings.animation;
 14120              if(typeof animation === 'string') {
 14121                animation = animation.split(' ');
 14122                $.each(animation, function(index, word){
 14123                  if(word === className.inward) {
 14124                    return className.inward;
 14125                  }
 14126                  else if(word === className.outward) {
 14127                    return className.outward;
 14128                  }
 14129                });
 14130              }
 14131              // slower backup
 14132              if( !module.can.transition() ) {
 14133                return 'static';
 14134              }
 14135              if($module.is(':visible') && !module.is.hidden()) {
 14136                return className.outward;
 14137              }
 14138              else {
 14139                return className.inward;
 14140              }
 14141            },
 14142            duration: function(duration) {
 14143              duration = duration || settings.duration;
 14144              if(duration === false) {
 14145                duration = $module.css('animation-duration') || 0;
 14146              }
 14147              return (typeof duration === 'string')
 14148                ? (duration.indexOf('ms') > -1)
 14149                  ? parseFloat(duration)
 14150                  : parseFloat(duration) * 1000
 14151                : duration
 14152              ;
 14153            },
 14154            displayType: function() {
 14155              if(settings.displayType) {
 14156                return settings.displayType;
 14157              }
 14158              if($module.data(metadata.displayType) === undefined) {
 14159                // create fake element to determine display state
 14160                module.can.transition(true);
 14161              }
 14162              return $module.data(metadata.displayType);
 14163            },
 14164            style: function() {
 14165              var
 14166                style = $module.attr('style') || ''
 14167              ;
 14168              return style.replace(/display.*?;/, '');
 14169            },
 14170            transitionExists: function(animation) {
 14171              return $.fn.transition.exists[animation];
 14172            },
 14173            animationName: function() {
 14174              var
 14175                element     = document.createElement('div'),
 14176                animations  = {
 14177                  'animation'       :'animationName',
 14178                  'OAnimation'      :'oAnimationName',
 14179                  'MozAnimation'    :'mozAnimationName',
 14180                  'WebkitAnimation' :'webkitAnimationName'
 14181                },
 14182                animation
 14183              ;
 14184              for(animation in animations){
 14185                if( element.style[animation] !== undefined ){
 14186                  return animations[animation];
 14187                }
 14188              }
 14189              return false;
 14190            },
 14191            animationStartEvent: function() {
 14192              var
 14193                element     = document.createElement('div'),
 14194                animations  = {
 14195                  'animation'       :'animationstart',
 14196                  'OAnimation'      :'oAnimationStart',
 14197                  'MozAnimation'    :'mozAnimationStart',
 14198                  'WebkitAnimation' :'webkitAnimationStart'
 14199                },
 14200                animation
 14201              ;
 14202              for(animation in animations){
 14203                if( element.style[animation] !== undefined ){
 14204                  return animations[animation];
 14205                }
 14206              }
 14207              return false;
 14208            },
 14209            animationEndEvent: function() {
 14210              var
 14211                element     = document.createElement('div'),
 14212                animations  = {
 14213                  'animation'       :'animationend',
 14214                  'OAnimation'      :'oAnimationEnd',
 14215                  'MozAnimation'    :'mozAnimationEnd',
 14216                  'WebkitAnimation' :'webkitAnimationEnd'
 14217                },
 14218                animation
 14219              ;
 14220              for(animation in animations){
 14221                if( element.style[animation] !== undefined ){
 14222                  return animations[animation];
 14223                }
 14224              }
 14225              return false;
 14226            }
 14227  
 14228          },
 14229  
 14230          can: {
 14231            transition: function(forced) {
 14232              var
 14233                elementClass      = $module.attr('class'),
 14234                tagName           = $module.prop('tagName'),
 14235                animation         = settings.animation,
 14236                transitionExists  = module.get.transitionExists(animation),
 14237                $clone,
 14238                currentAnimation,
 14239                inAnimation,
 14240                directionExists,
 14241                displayType
 14242              ;
 14243              if( transitionExists === undefined || forced) {
 14244                module.verbose('Determining whether animation exists');
 14245                $clone = $('<' + tagName + ' />').addClass( elementClass ).insertAfter($module);
 14246                currentAnimation = $clone
 14247                  .addClass(animation)
 14248                  .removeClass(className.inward)
 14249                  .removeClass(className.outward)
 14250                  .addClass(className.animating)
 14251                  .addClass(className.transition)
 14252                  .css(animationName)
 14253                ;
 14254                inAnimation = $clone
 14255                  .addClass(className.inward)
 14256                  .css(animationName)
 14257                ;
 14258                displayType = $clone
 14259                  .attr('class', elementClass)
 14260                  .removeAttr('style')
 14261                  .removeClass(className.hidden)
 14262                  .removeClass(className.visible)
 14263                  .show()
 14264                  .css('display')
 14265                ;
 14266                module.verbose('Determining final display state', displayType);
 14267                module.save.displayType(displayType);
 14268  
 14269                $clone.remove();
 14270                if(currentAnimation != inAnimation) {
 14271                  module.debug('Direction exists for animation', animation);
 14272                  directionExists = true;
 14273                }
 14274                else if(currentAnimation == 'none' || !currentAnimation) {
 14275                  module.debug('No animation defined in css', animation);
 14276                  return;
 14277                }
 14278                else {
 14279                  module.debug('Static animation found', animation, displayType);
 14280                  directionExists = false;
 14281                }
 14282                module.save.transitionExists(animation, directionExists);
 14283              }
 14284              return (transitionExists !== undefined)
 14285                ? transitionExists
 14286                : directionExists
 14287              ;
 14288            },
 14289            animate: function() {
 14290              // can transition does not return a value if animation does not exist
 14291              return (module.can.transition() !== undefined);
 14292            }
 14293          },
 14294  
 14295          is: {
 14296            animating: function() {
 14297              return $module.hasClass(className.animating);
 14298            },
 14299            inward: function() {
 14300              return $module.hasClass(className.inward);
 14301            },
 14302            outward: function() {
 14303              return $module.hasClass(className.outward);
 14304            },
 14305            looping: function() {
 14306              return $module.hasClass(className.looping);
 14307            },
 14308            occurring: function(animation) {
 14309              animation = animation || settings.animation;
 14310              animation = '.' + animation.replace(' ', '.');
 14311              return ( $module.filter(animation).length > 0 );
 14312            },
 14313            visible: function() {
 14314              return $module.is(':visible');
 14315            },
 14316            hidden: function() {
 14317              return $module.css('visibility') === 'hidden';
 14318            },
 14319            supported: function() {
 14320              return(animationName !== false && animationEnd !== false);
 14321            }
 14322          },
 14323  
 14324          hide: function() {
 14325            module.verbose('Hiding element');
 14326            if( module.is.animating() ) {
 14327              module.reset();
 14328            }
 14329            module.remove.display();
 14330            module.remove.visible();
 14331            module.set.hidden();
 14332            module.repaint();
 14333          },
 14334  
 14335          show: function(display) {
 14336            module.verbose('Showing element', display);
 14337            module.remove.hidden();
 14338            module.set.visible();
 14339            module.set.display();
 14340            module.repaint();
 14341          },
 14342  
 14343          toggle: function() {
 14344            if( module.is.visible() ) {
 14345              module.hide();
 14346            }
 14347            else {
 14348              module.show();
 14349            }
 14350          },
 14351  
 14352          stop: function() {
 14353            module.debug('Stopping current animation');
 14354            $module.trigger(animationEnd);
 14355          },
 14356  
 14357          stopAll: function() {
 14358            module.debug('Stopping all animation');
 14359            module.remove.queueCallback();
 14360            $module.trigger(animationEnd);
 14361          },
 14362  
 14363          clear: {
 14364            queue: function() {
 14365              module.debug('Clearing animation queue')
 14366              module.remove.queueCallback();
 14367            }
 14368          },
 14369  
 14370          enable: function() {
 14371            module.verbose('Starting animation');
 14372            $module.removeClass(className.disabled);
 14373          },
 14374  
 14375          disable: function() {
 14376            module.debug('Stopping animation');
 14377            $module.addClass(className.disabled);
 14378          },
 14379  
 14380          setting: function(name, value) {
 14381            module.debug('Changing setting', name, value);
 14382            if( $.isPlainObject(name) ) {
 14383              $.extend(true, settings, name);
 14384            }
 14385            else if(value !== undefined) {
 14386              settings[name] = value;
 14387            }
 14388            else {
 14389              return settings[name];
 14390            }
 14391          },
 14392          internal: function(name, value) {
 14393            if( $.isPlainObject(name) ) {
 14394              $.extend(true, module, name);
 14395            }
 14396            else if(value !== undefined) {
 14397              module[name] = value;
 14398            }
 14399            else {
 14400              return module[name];
 14401            }
 14402          },
 14403          debug: function() {
 14404            if(settings.debug) {
 14405              if(settings.performance) {
 14406                module.performance.log(arguments);
 14407              }
 14408              else {
 14409                module.debug = Function.prototype.bind.call(console.info, console, settings.name + ':');
 14410                module.debug.apply(console, arguments);
 14411              }
 14412            }
 14413          },
 14414          verbose: function() {
 14415            if(settings.verbose && settings.debug) {
 14416              if(settings.performance) {
 14417                module.performance.log(arguments);
 14418              }
 14419              else {
 14420                module.verbose = Function.prototype.bind.call(console.info, console, settings.name + ':');
 14421                module.verbose.apply(console, arguments);
 14422              }
 14423            }
 14424          },
 14425          error: function() {
 14426            module.error = Function.prototype.bind.call(console.error, console, settings.name + ':');
 14427            module.error.apply(console, arguments);
 14428          },
 14429          performance: {
 14430            log: function(message) {
 14431              var
 14432                currentTime,
 14433                executionTime,
 14434                previousTime
 14435              ;
 14436              if(settings.performance) {
 14437                currentTime   = new Date().getTime();
 14438                previousTime  = time || currentTime;
 14439                executionTime = currentTime - previousTime;
 14440                time          = currentTime;
 14441                performance.push({
 14442                  'Name'           : message[0],
 14443                  'Arguments'      : [].slice.call(message, 1) || '',
 14444                  'Element'        : element,
 14445                  'Execution Time' : executionTime
 14446                });
 14447              }
 14448              clearTimeout(module.performance.timer);
 14449              module.performance.timer = setTimeout(module.performance.display, 100);
 14450            },
 14451            display: function() {
 14452              var
 14453                title = settings.name + ':',
 14454                totalTime = 0
 14455              ;
 14456              time = false;
 14457              clearTimeout(module.performance.timer);
 14458              $.each(performance, function(index, data) {
 14459                totalTime += data['Execution Time'];
 14460              });
 14461              title += ' ' + totalTime + 'ms';
 14462              if(moduleSelector) {
 14463                title += ' \'' + moduleSelector + '\'';
 14464              }
 14465              if($allModules.length > 1) {
 14466                title += ' ' + '(' + $allModules.length + ')';
 14467              }
 14468              if( (console.group !== undefined || console.table !== undefined) && performance.length > 0) {
 14469                console.groupCollapsed(title);
 14470                if(console.table) {
 14471                  console.table(performance);
 14472                }
 14473                else {
 14474                  $.each(performance, function(index, data) {
 14475                    console.log(data['Name'] + ': ' + data['Execution Time']+'ms');
 14476                  });
 14477                }
 14478                console.groupEnd();
 14479              }
 14480              performance = [];
 14481            }
 14482          },
 14483          // modified for transition to return invoke success
 14484          invoke: function(query, passedArguments, context) {
 14485            var
 14486              object = instance,
 14487              maxDepth,
 14488              found,
 14489              response
 14490            ;
 14491            passedArguments = passedArguments || queryArguments;
 14492            context         = element         || context;
 14493            if(typeof query == 'string' && object !== undefined) {
 14494              query    = query.split(/[\. ]/);
 14495              maxDepth = query.length - 1;
 14496              $.each(query, function(depth, value) {
 14497                var camelCaseValue = (depth != maxDepth)
 14498                  ? value + query[depth + 1].charAt(0).toUpperCase() + query[depth + 1].slice(1)
 14499                  : query
 14500                ;
 14501                if( $.isPlainObject( object[camelCaseValue] ) && (depth != maxDepth) ) {
 14502                  object = object[camelCaseValue];
 14503                }
 14504                else if( object[camelCaseValue] !== undefined ) {
 14505                  found = object[camelCaseValue];
 14506                  return false;
 14507                }
 14508                else if( $.isPlainObject( object[value] ) && (depth != maxDepth) ) {
 14509                  object = object[value];
 14510                }
 14511                else if( object[value] !== undefined ) {
 14512                  found = object[value];
 14513                  return false;
 14514                }
 14515                else {
 14516                  return false;
 14517                }
 14518              });
 14519            }
 14520            if ( $.isFunction( found ) ) {
 14521              response = found.apply(context, passedArguments);
 14522            }
 14523            else if(found !== undefined) {
 14524              response = found;
 14525            }
 14526  
 14527            if($.isArray(returnedValue)) {
 14528              returnedValue.push(response);
 14529            }
 14530            else if(returnedValue !== undefined) {
 14531              returnedValue = [returnedValue, response];
 14532            }
 14533            else if(response !== undefined) {
 14534              returnedValue = response;
 14535            }
 14536            return (found !== undefined)
 14537              ? found
 14538              : false
 14539            ;
 14540          }
 14541        };
 14542        module.initialize();
 14543      })
 14544    ;
 14545    return (returnedValue !== undefined)
 14546      ? returnedValue
 14547      : this
 14548    ;
 14549  };
 14550  
 14551  // Records if CSS transition is available
 14552  $.fn.transition.exists = {};
 14553  
 14554  $.fn.transition.settings = {
 14555  
 14556    // module info
 14557    name          : 'Transition',
 14558  
 14559    // debug content outputted to console
 14560    debug         : false,
 14561  
 14562    // verbose debug output
 14563    verbose       : true,
 14564  
 14565    // performance data output
 14566    performance   : true,
 14567  
 14568    // event namespace
 14569    namespace     : 'transition',
 14570  
 14571    // delay between animations in group
 14572    interval      : 0,
 14573  
 14574    // whether group animations should be reversed
 14575    reverse       : 'auto',
 14576  
 14577    // animation callback event
 14578    onStart       : function() {},
 14579    onComplete    : function() {},
 14580    onShow        : function() {},
 14581    onHide        : function() {},
 14582  
 14583    // whether timeout should be used to ensure callback fires in cases animationend does not
 14584    useFailSafe   : true,
 14585  
 14586    // delay in ms for fail safe
 14587    failSafeDelay : 100,
 14588  
 14589    // whether EXACT animation can occur twice in a row
 14590    allowRepeats  : false,
 14591  
 14592    // Override final display type on visible
 14593    displayType   : false,
 14594  
 14595    // animation duration
 14596    animation     : 'fade',
 14597    duration      : false,
 14598  
 14599    // new animations will occur after previous ones
 14600    queue         : true,
 14601  
 14602    metadata : {
 14603      displayType: 'display'
 14604    },
 14605  
 14606    className   : {
 14607      animating  : 'animating',
 14608      disabled   : 'disabled',
 14609      hidden     : 'hidden',
 14610      inward     : 'in',
 14611      loading    : 'loading',
 14612      looping    : 'looping',
 14613      outward    : 'out',
 14614      transition : 'transition',
 14615      visible    : 'visible'
 14616    },
 14617  
 14618    // possible errors
 14619    error: {
 14620      noAnimation : 'There is no css animation matching the one you specified.',
 14621      repeated    : 'That animation is already occurring, cancelling repeated animation',
 14622      method      : 'The method you called is not defined',
 14623      support     : 'This browser does not support CSS animations'
 14624    }
 14625  
 14626  };
 14627  
 14628  
 14629  })( jQuery, window , document );
 14630  
 14631  /*!
 14632   * # Semantic UI x.x - Video
 14633   * http://github.com/semantic-org/semantic-ui/
 14634   *
 14635   *
 14636   * Copyright 2014 Contributorss
 14637   * Released under the MIT license
 14638   * http://opensource.org/licenses/MIT
 14639   *
 14640   */
 14641  
 14642  ;(function ($, window, document, undefined) {
 14643  
 14644  "use strict";
 14645  
 14646  $.fn.video = function(parameters) {
 14647  
 14648    var
 14649      $allModules     = $(this),
 14650  
 14651      moduleSelector  = $allModules.selector || '',
 14652  
 14653      time            = new Date().getTime(),
 14654      performance     = [],
 14655  
 14656      query           = arguments[0],
 14657      methodInvoked   = (typeof query == 'string'),
 14658      queryArguments  = [].slice.call(arguments, 1),
 14659  
 14660      requestAnimationFrame = window.requestAnimationFrame
 14661        || window.mozRequestAnimationFrame
 14662        || window.webkitRequestAnimationFrame
 14663        || window.msRequestAnimationFrame
 14664        || function(callback) { setTimeout(callback, 0); },
 14665  
 14666      returnedValue
 14667    ;
 14668  
 14669    $allModules
 14670      .each(function() {
 14671        var
 14672          settings        = ( $.isPlainObject(parameters) )
 14673            ? $.extend(true, {}, $.fn.video.settings, parameters)
 14674            : $.extend({}, $.fn.video.settings),
 14675  
 14676          selector        = settings.selector,
 14677          className       = settings.className,
 14678          error           = settings.error,
 14679          metadata        = settings.metadata,
 14680          namespace       = settings.namespace,
 14681          templates       = settings.templates,
 14682  
 14683          eventNamespace  = '.' + namespace,
 14684          moduleNamespace = 'module-' + namespace,
 14685  
 14686          $window         = $(window),
 14687          $module         = $(this),
 14688          $placeholder    = $module.find(selector.placeholder),
 14689          $playButton     = $module.find(selector.playButton),
 14690          $embed          = $module.find(selector.embed),
 14691  
 14692          element         = this,
 14693          instance        = $module.data(moduleNamespace),
 14694          module
 14695        ;
 14696  
 14697        module = {
 14698  
 14699          initialize: function() {
 14700            module.debug('Initializing video');
 14701            module.create();
 14702            $placeholder
 14703              .on('click' + eventNamespace, module.play)
 14704            ;
 14705            $playButton
 14706              .on('click' + eventNamespace, module.play)
 14707            ;
 14708            module.instantiate();
 14709          },
 14710  
 14711          instantiate: function() {
 14712            module.verbose('Storing instance of module', module);
 14713            instance = module;
 14714            $module
 14715              .data(moduleNamespace, module)
 14716            ;
 14717          },
 14718  
 14719          create: function() {
 14720            var
 14721              image = $module.data(metadata.image),
 14722              html = templates.video(image)
 14723            ;
 14724            $module.html(html);
 14725            module.refresh();
 14726            if(!image) {
 14727              module.play();
 14728            }
 14729            module.debug('Creating html for video element', html);
 14730          },
 14731  
 14732          destroy: function() {
 14733            module.verbose('Destroying previous instance of video');
 14734            module.reset();
 14735            $module
 14736              .removeData(moduleNamespace)
 14737              .off(eventNamespace)
 14738            ;
 14739            $placeholder
 14740              .off(eventNamespace)
 14741            ;
 14742            $playButton
 14743              .off(eventNamespace)
 14744            ;
 14745          },
 14746  
 14747          refresh: function() {
 14748            module.verbose('Refreshing selector cache');
 14749            $placeholder    = $module.find(selector.placeholder);
 14750            $playButton     = $module.find(selector.playButton);
 14751            $embed          = $module.find(selector.embed);
 14752          },
 14753  
 14754          // sets new video
 14755          change: function(source, id, url) {
 14756            module.debug('Changing video to ', source, id, url);
 14757            $module
 14758              .data(metadata.source, source)
 14759              .data(metadata.id, id)
 14760              .data(metadata.url, url)
 14761            ;
 14762            settings.onChange();
 14763          },
 14764  
 14765          // clears video embed
 14766          reset: function() {
 14767            module.debug('Clearing video embed and showing placeholder');
 14768            $module
 14769              .removeClass(className.active)
 14770            ;
 14771            $embed
 14772              .html(' ')
 14773            ;
 14774            $placeholder
 14775              .show()
 14776            ;
 14777            settings.onReset();
 14778          },
 14779  
 14780          // plays current video
 14781          play: function() {
 14782            module.debug('Playing video');
 14783            var
 14784              source = $module.data(metadata.source) || false,
 14785              url    = $module.data(metadata.url)    || false,
 14786              id     = $module.data(metadata.id)     || false
 14787            ;
 14788            $embed
 14789              .html( module.generate.html(source, id, url) )
 14790            ;
 14791            $module
 14792              .addClass(className.active)
 14793            ;
 14794            settings.onPlay();
 14795          },
 14796  
 14797          get: {
 14798            source: function(url) {
 14799              if(typeof url !== 'string') {
 14800                return false;
 14801              }
 14802              if(url.search('youtube.com') !== -1) {
 14803                return 'youtube';
 14804              }
 14805              else if(url.search('vimeo.com') !== -1) {
 14806                return 'vimeo';
 14807              }
 14808              return false;
 14809            },
 14810            id: function(url) {
 14811              if(url.match(settings.regExp.youtube)) {
 14812                return url.match(settings.regExp.youtube)[1];
 14813              }
 14814              else if(url.match(settings.regExp.vimeo)) {
 14815                return url.match(settings.regExp.vimeo)[2];
 14816              }
 14817              return false;
 14818            }
 14819          },
 14820  
 14821          generate: {
 14822            // generates iframe html
 14823            html: function(source, id, url) {
 14824              module.debug('Generating embed html');
 14825              var
 14826                html
 14827              ;
 14828              // allow override of settings
 14829              source = source || settings.source;
 14830              id     = id     || settings.id;
 14831              if((source && id) || url) {
 14832                if(!source || !id) {
 14833                  source = module.get.source(url);
 14834                  id     = module.get.id(url);
 14835                }
 14836                if(source == 'vimeo') {
 14837                  html = ''
 14838                    + '<iframe src="//player.vimeo.com/video/' + id + '?=' + module.generate.url(source) + '"'
 14839                    + ' width="100%" height="100%"'
 14840                    + ' frameborder="0" webkitAllowFullScreen mozallowfullscreen allowFullScreen></iframe>'
 14841                  ;
 14842                }
 14843                else if(source == 'youtube') {
 14844                  html = ''
 14845                    + '<iframe src="//www.youtube.com/embed/' + id + '?=' + module.generate.url(source) + '"'
 14846                    + ' width="100%" height="100%"'
 14847                    + ' frameborder="0" webkitAllowFullScreen mozallowfullscreen allowFullScreen></iframe>'
 14848                  ;
 14849                }
 14850              }
 14851              else {
 14852                module.error(error.noVideo);
 14853              }
 14854              return html;
 14855            },
 14856  
 14857            // generate url parameters
 14858            url: function(source) {
 14859              var
 14860                api      = (settings.api)
 14861                  ? 1
 14862                  : 0,
 14863                autoplay = (settings.autoplay === 'auto')
 14864                  ? ($module.data('image') !== undefined)
 14865                  : settings.autoplay,
 14866                hd       = (settings.hd)
 14867                  ? 1
 14868                  : 0,
 14869                showUI   = (settings.showUI)
 14870                  ? 1
 14871                  : 0,
 14872                // opposite used for some params
 14873                hideUI   = !(settings.showUI)
 14874                  ? 1
 14875                  : 0,
 14876                url = ''
 14877              ;
 14878              if(source == 'vimeo') {
 14879                url = ''
 14880                  +      'api='      + api
 14881                  + '&amp;title='    + showUI
 14882                  + '&amp;byline='   + showUI
 14883                  + '&amp;portrait=' + showUI
 14884                  + '&amp;autoplay=' + autoplay
 14885                ;
 14886                if(settings.color) {
 14887                  url += '&amp;color=' + settings.color;
 14888                }
 14889              }
 14890              if(source == 'ustream') {
 14891                url = ''
 14892                  + 'autoplay=' + autoplay
 14893                ;
 14894                if(settings.color) {
 14895                  url += '&amp;color=' + settings.color;
 14896                }
 14897              }
 14898              else if(source == 'youtube') {
 14899                url = ''
 14900                  + 'enablejsapi='      + api
 14901                  + '&amp;autoplay='    + autoplay
 14902                  + '&amp;autohide='    + hideUI
 14903                  + '&amp;hq='          + hd
 14904                  + '&amp;modestbranding=1'
 14905                ;
 14906                if(settings.color) {
 14907                  url += '&amp;color=' + settings.color;
 14908                }
 14909              }
 14910              return url;
 14911            }
 14912          },
 14913  
 14914          setting: function(name, value) {
 14915            module.debug('Changing setting', name, value);
 14916            if( $.isPlainObject(name) ) {
 14917              $.extend(true, settings, name);
 14918            }
 14919            else if(value !== undefined) {
 14920              settings[name] = value;
 14921            }
 14922            else {
 14923              return settings[name];
 14924            }
 14925          },
 14926          internal: function(name, value) {
 14927            if( $.isPlainObject(name) ) {
 14928              $.extend(true, module, name);
 14929            }
 14930            else if(value !== undefined) {
 14931              module[name] = value;
 14932            }
 14933            else {
 14934              return module[name];
 14935            }
 14936          },
 14937          debug: function() {
 14938            if(settings.debug) {
 14939              if(settings.performance) {
 14940                module.performance.log(arguments);
 14941              }
 14942              else {
 14943                module.debug = Function.prototype.bind.call(console.info, console, settings.name + ':');
 14944                module.debug.apply(console, arguments);
 14945              }
 14946            }
 14947          },
 14948          verbose: function() {
 14949            if(settings.verbose && settings.debug) {
 14950              if(settings.performance) {
 14951                module.performance.log(arguments);
 14952              }
 14953              else {
 14954                module.verbose = Function.prototype.bind.call(console.info, console, settings.name + ':');
 14955                module.verbose.apply(console, arguments);
 14956              }
 14957            }
 14958          },
 14959          error: function() {
 14960            module.error = Function.prototype.bind.call(console.error, console, settings.name + ':');
 14961            module.error.apply(console, arguments);
 14962          },
 14963          performance: {
 14964            log: function(message) {
 14965              var
 14966                currentTime,
 14967                executionTime,
 14968                previousTime
 14969              ;
 14970              if(settings.performance) {
 14971                currentTime   = new Date().getTime();
 14972                previousTime  = time || currentTime;
 14973                executionTime = currentTime - previousTime;
 14974                time          = currentTime;
 14975                performance.push({
 14976                  'Name'           : message[0],
 14977                  'Arguments'      : [].slice.call(message, 1) || '',
 14978                  'Element'        : element,
 14979                  'Execution Time' : executionTime
 14980                });
 14981              }
 14982              clearTimeout(module.performance.timer);
 14983              module.performance.timer = setTimeout(module.performance.display, 100);
 14984            },
 14985            display: function() {
 14986              var
 14987                title = settings.name + ':',
 14988                totalTime = 0
 14989              ;
 14990              time = false;
 14991              clearTimeout(module.performance.timer);
 14992              $.each(performance, function(index, data) {
 14993                totalTime += data['Execution Time'];
 14994              });
 14995              title += ' ' + totalTime + 'ms';
 14996              if(moduleSelector) {
 14997                title += ' \'' + moduleSelector + '\'';
 14998              }
 14999              if($allModules.length > 1) {
 15000                title += ' ' + '(' + $allModules.length + ')';
 15001              }
 15002              if( (console.group !== undefined || console.table !== undefined) && performance.length > 0) {
 15003                console.groupCollapsed(title);
 15004                if(console.table) {
 15005                  console.table(performance);
 15006                }
 15007                else {
 15008                  $.each(performance, function(index, data) {
 15009                    console.log(data['Name'] + ': ' + data['Execution Time']+'ms');
 15010                  });
 15011                }
 15012                console.groupEnd();
 15013              }
 15014              performance = [];
 15015            }
 15016          },
 15017          invoke: function(query, passedArguments, context) {
 15018            var
 15019              object = instance,
 15020              maxDepth,
 15021              found,
 15022              response
 15023            ;
 15024            passedArguments = passedArguments || queryArguments;
 15025            context         = element         || context;
 15026            if(typeof query == 'string' && object !== undefined) {
 15027              query    = query.split(/[\. ]/);
 15028              maxDepth = query.length - 1;
 15029              $.each(query, function(depth, value) {
 15030                var camelCaseValue = (depth != maxDepth)
 15031                  ? value + query[depth + 1].charAt(0).toUpperCase() + query[depth + 1].slice(1)
 15032                  : query
 15033                ;
 15034                if( $.isPlainObject( object[camelCaseValue] ) && (depth != maxDepth) ) {
 15035                  object = object[camelCaseValue];
 15036                }
 15037                else if( object[camelCaseValue] !== undefined ) {
 15038                  found = object[camelCaseValue];
 15039                  return false;
 15040                }
 15041                else if( $.isPlainObject( object[value] ) && (depth != maxDepth) ) {
 15042                  object = object[value];
 15043                }
 15044                else if( object[value] !== undefined ) {
 15045                  found = object[value];
 15046                  return false;
 15047                }
 15048                else {
 15049                  module.error(error.method, query);
 15050                  return false;
 15051                }
 15052              });
 15053            }
 15054            if ( $.isFunction( found ) ) {
 15055              response = found.apply(context, passedArguments);
 15056            }
 15057            else if(found !== undefined) {
 15058              response = found;
 15059            }
 15060            if($.isArray(returnedValue)) {
 15061              returnedValue.push(response);
 15062            }
 15063            else if(returnedValue !== undefined) {
 15064              returnedValue = [returnedValue, response];
 15065            }
 15066            else if(response !== undefined) {
 15067              returnedValue = response;
 15068            }
 15069            return found;
 15070          }
 15071        };
 15072  
 15073        if(methodInvoked) {
 15074          if(instance === undefined) {
 15075            module.initialize();
 15076          }
 15077          module.invoke(query);
 15078        }
 15079        else {
 15080          if(instance !== undefined) {
 15081            instance.invoke('destroy');
 15082          }
 15083          module.initialize();
 15084        }
 15085      })
 15086    ;
 15087    return (returnedValue !== undefined)
 15088      ? returnedValue
 15089      : this
 15090    ;
 15091  };
 15092  
 15093  $.fn.video.settings = {
 15094  
 15095    name        : 'Video',
 15096    namespace   : 'video',
 15097  
 15098    debug       : false,
 15099    verbose     : true,
 15100    performance : true,
 15101  
 15102    metadata    : {
 15103      id     : 'id',
 15104      image  : 'image',
 15105      source : 'source',
 15106      url    : 'url'
 15107    },
 15108  
 15109    source      : false,
 15110    url         : false,
 15111    id          : false,
 15112  
 15113    aspectRatio : (16/9),
 15114  
 15115    onPlay   : function(){},
 15116    onReset  : function(){},
 15117    onChange : function(){},
 15118  
 15119    // callbacks not coded yet (needs to use jsapi)
 15120    onPause  : function() {},
 15121    onStop   : function() {},
 15122  
 15123    width    : 'auto',
 15124    height   : 'auto',
 15125  
 15126    autoplay : 'auto',
 15127    color    : '#442359',
 15128    hd       : true,
 15129    showUI   : false,
 15130    api      : true,
 15131  
 15132    regExp : {
 15133      youtube : /^(?:https?:\/\/)?(?:www\.)?(?:youtu\.be\/|youtube\.com\/(?:embed\/|v\/|watch\?v=|watch\?.+&v=))((\w|-){11})(?:\S+)?$/,
 15134      vimeo   : /http:\/\/(www\.)?vimeo.com\/(\d+)($|\/)/
 15135    },
 15136  
 15137    error      : {
 15138      noVideo     : 'No video specified',
 15139      method      : 'The method you called is not defined'
 15140    },
 15141  
 15142    className   : {
 15143      active      : 'active'
 15144    },
 15145  
 15146    selector    : {
 15147      embed       : '.embed',
 15148      placeholder : '.placeholder',
 15149      playButton  : '.play'
 15150    }
 15151  };
 15152  
 15153  $.fn.video.settings.templates = {
 15154    video: function(image) {
 15155      var
 15156        html = ''
 15157      ;
 15158      if(image) {
 15159        html += ''
 15160          + '<i class="video play icon"></i>'
 15161          + '<img class="placeholder" src="' + image + '">'
 15162        ;
 15163      }
 15164      html += '<div class="embed"></div>';
 15165      return html;
 15166    }
 15167  };
 15168  
 15169  
 15170  })( jQuery, window , document );
 15171  
 15172  /*!
 15173   * # Semantic UI x.x - API
 15174   * http://github.com/semantic-org/semantic-ui/
 15175   *
 15176   *
 15177   * Copyright 2014 Contributors
 15178   * Released under the MIT license
 15179   * http://opensource.org/licenses/MIT
 15180   *
 15181   */
 15182  
 15183  ;(function ( $, window, document, undefined ) {
 15184  
 15185  "use strict";
 15186  
 15187  $.api = $.fn.api = function(parameters) {
 15188  
 15189    var
 15190      // use window context if none specified
 15191      $allModules     = $.isFunction(this)
 15192          ? $(window)
 15193          : $(this),
 15194      moduleSelector = $allModules.selector || '',
 15195      time           = new Date().getTime(),
 15196      performance    = [],
 15197  
 15198      query          = arguments[0],
 15199      methodInvoked  = (typeof query == 'string'),
 15200      queryArguments = [].slice.call(arguments, 1),
 15201  
 15202      returnedValue
 15203    ;
 15204  
 15205    $allModules
 15206      .each(function() {
 15207        var
 15208          settings          = ( $.isPlainObject(parameters) )
 15209            ? $.extend(true, {}, $.fn.api.settings, parameters)
 15210            : $.extend({}, $.fn.api.settings),
 15211  
 15212          // internal aliases
 15213          namespace       = settings.namespace,
 15214          metadata        = settings.metadata,
 15215          selector        = settings.selector,
 15216          error           = settings.error,
 15217          className       = settings.className,
 15218  
 15219          // define namespaces for modules
 15220          eventNamespace  = '.' + namespace,
 15221          moduleNamespace = 'module-' + namespace,
 15222  
 15223          // element that creates request
 15224          $module         = $(this),
 15225          $form           = $module.closest(selector.form),
 15226  
 15227          // context used for state
 15228          $context        = (settings.stateContext)
 15229            ? $(settings.stateContext)
 15230            : $module,
 15231  
 15232          // request details
 15233          ajaxSettings,
 15234          requestSettings,
 15235          url,
 15236          data,
 15237  
 15238          // standard module
 15239          element         = this,
 15240          context         = $context.get(),
 15241          instance        = $module.data(moduleNamespace),
 15242          module
 15243        ;
 15244  
 15245        module = {
 15246  
 15247          initialize: function() {
 15248            var
 15249              triggerEvent = module.get.event()
 15250            ;
 15251            // bind events
 15252            if(!methodInvoked) {
 15253              if( triggerEvent ) {
 15254                module.debug('Attaching API events to element', triggerEvent);
 15255                $module
 15256                  .on(triggerEvent + eventNamespace, module.event.trigger)
 15257                ;
 15258              }
 15259              else if(settings.on == 'now') {
 15260                module.debug('Querying API now', triggerEvent);
 15261                module.query();
 15262              }
 15263            }
 15264            module.instantiate();
 15265          },
 15266  
 15267          instantiate: function() {
 15268            module.verbose('Storing instance of module', module);
 15269            instance = module;
 15270            $module
 15271              .data(moduleNamespace, instance)
 15272            ;
 15273          },
 15274  
 15275          destroy: function() {
 15276            module.verbose('Destroying previous module for', element);
 15277            $module
 15278              .removeData(moduleNamespace)
 15279              .off(eventNamespace)
 15280            ;
 15281          },
 15282  
 15283          query: function() {
 15284  
 15285            if(module.is.disabled()) {
 15286              module.debug('Element is disabled API request aborted');
 15287              return;
 15288            }
 15289            // determine if an api event already occurred
 15290            if(module.is.loading() && settings.throttle === 0 ) {
 15291              module.debug('Cancelling request, previous request is still pending');
 15292              return;
 15293            }
 15294  
 15295            // pass element metadata to url (value, text)
 15296            if(settings.defaultData) {
 15297              $.extend(true, settings.urlData, module.get.defaultData());
 15298            }
 15299  
 15300            // Add form content
 15301            if(settings.serializeForm !== false || $context.is('form')) {
 15302              if(settings.serializeForm == 'json') {
 15303                $.extend(true, settings.data, module.get.formData());
 15304              }
 15305              else {
 15306                settings.data = module.get.formData();
 15307              }
 15308            }
 15309  
 15310            // call beforesend and get any settings changes
 15311            requestSettings         = module.get.settings();
 15312  
 15313            // check if before send cancelled request
 15314            if(requestSettings === false) {
 15315              module.cancelled = true;
 15316              module.error(error.beforeSend);
 15317              return;
 15318            }
 15319            else {
 15320              module.cancelled = false;
 15321            }
 15322  
 15323            if(settings.url) {
 15324              // override with url if specified
 15325              module.debug('Using specified url', url);
 15326              url = module.add.urlData( settings.url );
 15327            }
 15328            else {
 15329              // otherwise find url from api endpoints
 15330              url = module.add.urlData( module.get.templateURL() );
 15331              module.debug('Added URL Data to url', url);
 15332            }
 15333  
 15334            // exit conditions reached, missing url parameters
 15335            if( !url ) {
 15336              if( module.is.form() ) {
 15337                url = $module.attr('action') || '';
 15338                module.debug('No url or action specified, defaulting to form action', url);
 15339              }
 15340              else {
 15341                module.error(error.missingURL, settings.action);
 15342                return;
 15343              }
 15344            }
 15345  
 15346            // add loading state
 15347            module.set.loading();
 15348  
 15349            // look for jQuery ajax parameters in settings
 15350            ajaxSettings = $.extend(true, {}, settings, {
 15351              type       : settings.method || settings.type,
 15352              data       : data,
 15353              url        : settings.base + url,
 15354              beforeSend : settings.beforeXHR,
 15355              success    : function() {},
 15356              failure    : function() {},
 15357              complete   : function() {}
 15358            });
 15359  
 15360            module.debug('Querying URL', ajaxSettings.url);
 15361            module.debug('Sending data', data, ajaxSettings.method);
 15362            module.verbose('Using AJAX settings', ajaxSettings);
 15363  
 15364            if( module.is.loading() ) {
 15365              // throttle additional requests
 15366              module.timer = setTimeout(function() {
 15367                module.request = module.create.request();
 15368                module.xhr     = module.create.xhr();
 15369                settings.onRequest.call(context, module.request, module.xhr);
 15370              }, settings.throttle);
 15371            }
 15372            else {
 15373              // immediately on first request
 15374              module.request = module.create.request();
 15375              module.xhr     = module.create.xhr();
 15376              settings.onRequest.call(context, module.request, module.xhr);
 15377            }
 15378  
 15379          },
 15380  
 15381  
 15382          is: {
 15383            disabled: function() {
 15384              return ($module.filter(settings.filter).length > 0);
 15385            },
 15386            form: function() {
 15387              return $module.is('form');
 15388            },
 15389            input: function() {
 15390              return $module.is('input');
 15391            },
 15392            loading: function() {
 15393              return (module.request && module.request.state() == 'pending');
 15394            }
 15395          },
 15396  
 15397          was: {
 15398            cancelled: function() {
 15399              return (module.cancelled || false);
 15400            },
 15401            succesful: function() {
 15402              return (module.request && module.request.state() == 'resolved');
 15403            },
 15404            failure: function() {
 15405              return (module.request && module.request.state() == 'rejected');
 15406            },
 15407            complete: function() {
 15408              return (module.request && (module.request.state() == 'resolved' || module.request.state() == 'rejected') );
 15409            }
 15410          },
 15411  
 15412          add: {
 15413            urlData: function(url, urlData) {
 15414              var
 15415                requiredVariables,
 15416                optionalVariables
 15417              ;
 15418              if(url) {
 15419                requiredVariables = url.match(settings.regExp.required);
 15420                optionalVariables = url.match(settings.regExp.optional);
 15421                urlData           = urlData || settings.urlData;
 15422                if(requiredVariables) {
 15423                  module.debug('Looking for required URL variables', requiredVariables);
 15424                  $.each(requiredVariables, function(index, templatedString) {
 15425                    var
 15426                      // allow legacy {$var} style
 15427                      variable = (templatedString.indexOf('$') !== -1)
 15428                        ? templatedString.substr(2, templatedString.length - 3)
 15429                        : templatedString.substr(1, templatedString.length - 2),
 15430                      value   = ($.isPlainObject(urlData) && urlData[variable] !== undefined)
 15431                        ? urlData[variable]
 15432                        : ($module.data(variable) !== undefined)
 15433                          ? $module.data(variable)
 15434                          : ($context.data(variable) !== undefined)
 15435                            ? $context.data(variable)
 15436                            : urlData[variable]
 15437                    ;
 15438                    // remove value
 15439                    if(value === undefined) {
 15440                      module.error(error.requiredParameter, variable, url);
 15441                      url = false;
 15442                      return false;
 15443                    }
 15444                    else {
 15445                      module.verbose('Found required variable', variable, value);
 15446                      url = url.replace(templatedString, value);
 15447                    }
 15448                  });
 15449                }
 15450                if(optionalVariables) {
 15451                  module.debug('Looking for optional URL variables', requiredVariables);
 15452                  $.each(optionalVariables, function(index, templatedString) {
 15453                    var
 15454                      // allow legacy {/$var} style
 15455                      variable = (templatedString.indexOf('$') !== -1)
 15456                        ? templatedString.substr(3, templatedString.length - 4)
 15457                        : templatedString.substr(2, templatedString.length - 3),
 15458                      value   = ($.isPlainObject(urlData) && urlData[variable] !== undefined)
 15459                        ? urlData[variable]
 15460                        : ($module.data(variable) !== undefined)
 15461                          ? $module.data(variable)
 15462                          : ($context.data(variable) !== undefined)
 15463                            ? $context.data(variable)
 15464                            : urlData[variable]
 15465                    ;
 15466                    // optional replacement
 15467                    if(value !== undefined) {
 15468                      module.verbose('Optional variable Found', variable, value);
 15469                      url = url.replace(templatedString, value);
 15470                    }
 15471                    else {
 15472                      module.verbose('Optional variable not found', variable);
 15473                      // remove preceding slash if set
 15474                      if(url.indexOf('/' + templatedString) !== -1) {
 15475                        url = url.replace('/' + templatedString, '');
 15476                      }
 15477                      else {
 15478                        url = url.replace(templatedString, '');
 15479                      }
 15480                    }
 15481                  });
 15482                }
 15483              }
 15484              return url;
 15485            }
 15486          },
 15487  
 15488          event: {
 15489            trigger: function(event) {
 15490              module.query();
 15491              if(event.type == 'submit' || event.type == 'click') {
 15492                event.preventDefault();
 15493              }
 15494            },
 15495            xhr: {
 15496              always: function() {
 15497                // calculate if loading time was below minimum threshold
 15498              },
 15499              done: function(response) {
 15500                var
 15501                  context      = this,
 15502                  elapsedTime  = (new Date().getTime() - time),
 15503                  timeLeft     = (settings.loadingDuration - elapsedTime)
 15504                ;
 15505                timeLeft = (timeLeft > 0)
 15506                  ? timeLeft
 15507                  : 0
 15508                ;
 15509                setTimeout(function() {
 15510                  module.request.resolveWith(context, [response]);
 15511                }, timeLeft);
 15512              },
 15513              fail: function(xhr, status, httpMessage) {
 15514                var
 15515                  context     = this,
 15516                  elapsedTime = (new Date().getTime() - time),
 15517                  timeLeft    = (settings.loadingDuration - elapsedTime)
 15518                ;
 15519                timeLeft = (timeLeft > 0)
 15520                  ? timeLeft
 15521                  : 0
 15522                ;
 15523                // page triggers abort on navigation, dont show error
 15524                setTimeout(function() {
 15525                  if(status !== 'abort') {
 15526                    module.request.rejectWith(context, [xhr, status, httpMessage]);
 15527                  }
 15528                  else {
 15529                    module.reset();
 15530                  }
 15531                }, timeLeft);
 15532              }
 15533            },
 15534            request: {
 15535              complete: function(response) {
 15536                module.remove.loading();
 15537                settings.onComplete.call(context, response, $module);
 15538              },
 15539              done: function(response) {
 15540                module.debug('API Response Received', response);
 15541                if(settings.dataType == 'json') {
 15542                  if( $.isFunction(settings.successTest) ) {
 15543                    module.debug('Checking JSON returned success', settings.successTest, response);
 15544                    if( settings.successTest(response) ) {
 15545                      settings.onSuccess.call(context, response, $module);
 15546                    }
 15547                    else {
 15548                      module.debug('JSON test specified by user and response failed', response);
 15549                      settings.onFailure.call(context, response, $module);
 15550                    }
 15551                  }
 15552                  else {
 15553                    settings.onSuccess.call(context, response, $module);
 15554                  }
 15555                }
 15556                else {
 15557                  settings.onSuccess.call(context, response, $module);
 15558                }
 15559              },
 15560              error: function(xhr, status, httpMessage) {
 15561                var
 15562                  errorMessage = (settings.error[status] !== undefined)
 15563                    ? settings.error[status]
 15564                    : httpMessage,
 15565                  response
 15566                ;
 15567                // let em know unless request aborted
 15568                if(xhr !== undefined) {
 15569                  // readyState 4 = done, anything less is not really sent
 15570                  if(xhr.readyState !== undefined && xhr.readyState == 4) {
 15571  
 15572                    // if http status code returned and json returned error, look for it
 15573                    if( xhr.status != 200 && httpMessage !== undefined && httpMessage !== '') {
 15574                      module.error(error.statusMessage + httpMessage, ajaxSettings.url);
 15575                    }
 15576                    else {
 15577                      if(status == 'error' && settings.dataType == 'json') {
 15578                        try {
 15579                          response = $.parseJSON(xhr.responseText);
 15580                          if(response && response.error !== undefined) {
 15581                            errorMessage = response.error;
 15582                          }
 15583                        }
 15584                        catch(e) {
 15585                          module.error(error.JSONParse);
 15586                        }
 15587                      }
 15588                    }
 15589                    module.remove.loading();
 15590                    module.set.error();
 15591                    // show error state only for duration specified in settings
 15592                    if(settings.errorDuration) {
 15593                      setTimeout(module.remove.error, settings.errorDuration);
 15594                    }
 15595                    module.debug('API Request error:', errorMessage);
 15596                    settings.onError.call(context, errorMessage, $module);
 15597                  }
 15598                  else {
 15599                    settings.onAbort.call(context, errorMessage, $module);
 15600                    module.debug('Request Aborted (Most likely caused by page change or CORS Policy)', status, httpMessage);
 15601                  }
 15602                }
 15603              }
 15604            }
 15605          },
 15606  
 15607          create: {
 15608            request: function() {
 15609              return $.Deferred()
 15610                .always(module.event.request.complete)
 15611                .done(module.event.request.done)
 15612                .fail(module.event.request.error)
 15613              ;
 15614            },
 15615            xhr: function() {
 15616              return $.ajax(ajaxSettings)
 15617                .always(module.event.xhr.always)
 15618                .done(module.event.xhr.done)
 15619                .fail(module.event.xhr.fail)
 15620              ;
 15621            }
 15622          },
 15623  
 15624          set: {
 15625            error: function() {
 15626              module.verbose('Adding error state to element', $context);
 15627              $context.addClass(className.error);
 15628            },
 15629            loading: function() {
 15630              module.verbose('Adding loading state to element', $context);
 15631              $context.addClass(className.loading);
 15632            }
 15633          },
 15634  
 15635          remove: {
 15636            error: function() {
 15637              module.verbose('Removing error state from element', $context);
 15638              $context.removeClass(className.error);
 15639            },
 15640            loading: function() {
 15641              module.verbose('Removing loading state from element', $context);
 15642              $context.removeClass(className.loading);
 15643            }
 15644          },
 15645  
 15646          get: {
 15647            request: function() {
 15648              return module.request || false;
 15649            },
 15650            xhr: function() {
 15651              return module.xhr || false;
 15652            },
 15653            settings: function() {
 15654              var
 15655                runSettings
 15656              ;
 15657              runSettings = settings.beforeSend.call($module, settings);
 15658              if(runSettings) {
 15659                if(runSettings.success !== undefined) {
 15660                  module.debug('Legacy success callback detected', runSettings);
 15661                  module.error(error.legacyParameters, runSettings.success);
 15662                  runSettings.onSuccess = runSettings.success;
 15663                }
 15664                if(runSettings.failure !== undefined) {
 15665                  module.debug('Legacy failure callback detected', runSettings);
 15666                  module.error(error.legacyParameters, runSettings.failure);
 15667                  runSettings.onFailure = runSettings.failure;
 15668                }
 15669                if(runSettings.complete !== undefined) {
 15670                  module.debug('Legacy complete callback detected', runSettings);
 15671                  module.error(error.legacyParameters, runSettings.complete);
 15672                  runSettings.onComplete = runSettings.complete;
 15673                }
 15674              }
 15675              if(runSettings === undefined) {
 15676                module.error(error.noReturnedValue);
 15677              }
 15678              return (runSettings !== undefined)
 15679                ? runSettings
 15680                : settings
 15681              ;
 15682            },
 15683            defaultData: function() {
 15684              var
 15685                data = {}
 15686              ;
 15687              if( !$.isWindow(element) ) {
 15688                if( module.is.input() ) {
 15689                  data.value = $module.val();
 15690                }
 15691                else if( !module.is.form() ) {
 15692  
 15693                }
 15694                else {
 15695                  data.text = $module.text();
 15696                }
 15697              }
 15698              return data;
 15699            },
 15700            event: function() {
 15701              if( $.isWindow(element) || settings.on == 'now' ) {
 15702                module.debug('API called without element, no events attached');
 15703                return false;
 15704              }
 15705              else if(settings.on == 'auto') {
 15706                if( $module.is('input') ) {
 15707                  return (element.oninput !== undefined)
 15708                    ? 'input'
 15709                    : (element.onpropertychange !== undefined)
 15710                      ? 'propertychange'
 15711                      : 'keyup'
 15712                  ;
 15713                }
 15714                else if( $module.is('form') ) {
 15715                  return 'submit';
 15716                }
 15717                else {
 15718                  return 'click';
 15719                }
 15720              }
 15721              else {
 15722                return settings.on;
 15723              }
 15724            },
 15725            formData: function() {
 15726              var
 15727                formData
 15728              ;
 15729              if($module.serializeObject !== undefined) {
 15730                formData = $form.serializeObject();
 15731              }
 15732              else {
 15733                module.error(error.missingSerialize);
 15734                formData = $form.serialize();
 15735              }
 15736              module.debug('Retrieved form data', formData);
 15737              return formData;
 15738            },
 15739            templateURL: function(action) {
 15740              var
 15741                url
 15742              ;
 15743              action = action || $module.data(metadata.action) || settings.action || false;
 15744              if(action) {
 15745                module.debug('Looking up url for action', action, settings.api);
 15746                if(settings.api[action] !== undefined) {
 15747                  url = settings.api[action];
 15748                  module.debug('Found template url', url);
 15749                }
 15750                else if( !module.is.form() ) {
 15751                  module.error(error.missingAction, settings.action, settings.api);
 15752                }
 15753              }
 15754              return url;
 15755            }
 15756          },
 15757  
 15758          abort: function() {
 15759            var
 15760              xhr = module.get.xhr()
 15761            ;
 15762            if( xhr && xhr.state() !== 'resolved') {
 15763              module.debug('Cancelling API request');
 15764              xhr.abort();
 15765              module.request.rejectWith(settings.apiSettings);
 15766            }
 15767          },
 15768  
 15769          // reset state
 15770          reset: function() {
 15771            module.remove.error();
 15772            module.remove.loading();
 15773          },
 15774  
 15775          setting: function(name, value) {
 15776            module.debug('Changing setting', name, value);
 15777            if( $.isPlainObject(name) ) {
 15778              $.extend(true, settings, name);
 15779            }
 15780            else if(value !== undefined) {
 15781              settings[name] = value;
 15782            }
 15783            else {
 15784              return settings[name];
 15785            }
 15786          },
 15787          internal: function(name, value) {
 15788            if( $.isPlainObject(name) ) {
 15789              $.extend(true, module, name);
 15790            }
 15791            else if(value !== undefined) {
 15792              module[name] = value;
 15793            }
 15794            else {
 15795              return module[name];
 15796            }
 15797          },
 15798          debug: function() {
 15799            if(settings.debug) {
 15800              if(settings.performance) {
 15801                module.performance.log(arguments);
 15802              }
 15803              else {
 15804                module.debug = Function.prototype.bind.call(console.info, console, settings.name + ':');
 15805                module.debug.apply(console, arguments);
 15806              }
 15807            }
 15808          },
 15809          verbose: function() {
 15810            if(settings.verbose && settings.debug) {
 15811              if(settings.performance) {
 15812                module.performance.log(arguments);
 15813              }
 15814              else {
 15815                module.verbose = Function.prototype.bind.call(console.info, console, settings.name + ':');
 15816                module.verbose.apply(console, arguments);
 15817              }
 15818            }
 15819          },
 15820          error: function() {
 15821            module.error = Function.prototype.bind.call(console.error, console, settings.name + ':');
 15822            module.error.apply(console, arguments);
 15823          },
 15824          performance: {
 15825            log: function(message) {
 15826              var
 15827                currentTime,
 15828                executionTime,
 15829                previousTime
 15830              ;
 15831              if(settings.performance) {
 15832                currentTime   = new Date().getTime();
 15833                previousTime  = time || currentTime;
 15834                executionTime = currentTime - previousTime;
 15835                time          = currentTime;
 15836                performance.push({
 15837                  'Name'           : message[0],
 15838                  'Arguments'      : [].slice.call(message, 1) || '',
 15839                  //'Element'        : element,
 15840                  'Execution Time' : executionTime
 15841                });
 15842              }
 15843              clearTimeout(module.performance.timer);
 15844              module.performance.timer = setTimeout(module.performance.display, 100);
 15845            },
 15846            display: function() {
 15847              var
 15848                title = settings.name + ':',
 15849                totalTime = 0
 15850              ;
 15851              time = false;
 15852              clearTimeout(module.performance.timer);
 15853              $.each(performance, function(index, data) {
 15854                totalTime += data['Execution Time'];
 15855              });
 15856              title += ' ' + totalTime + 'ms';
 15857              if(moduleSelector) {
 15858                title += ' \'' + moduleSelector + '\'';
 15859              }
 15860              if( (console.group !== undefined || console.table !== undefined) && performance.length > 0) {
 15861                console.groupCollapsed(title);
 15862                if(console.table) {
 15863                  console.table(performance);
 15864                }
 15865                else {
 15866                  $.each(performance, function(index, data) {
 15867                    console.log(data['Name'] + ': ' + data['Execution Time']+'ms');
 15868                  });
 15869                }
 15870                console.groupEnd();
 15871              }
 15872              performance = [];
 15873            }
 15874          },
 15875          invoke: function(query, passedArguments, context) {
 15876            var
 15877              object = instance,
 15878              maxDepth,
 15879              found,
 15880              response
 15881            ;
 15882            passedArguments = passedArguments || queryArguments;
 15883            context         = element         || context;
 15884            if(typeof query == 'string' && object !== undefined) {
 15885              query    = query.split(/[\. ]/);
 15886              maxDepth = query.length - 1;
 15887              $.each(query, function(depth, value) {
 15888                var camelCaseValue = (depth != maxDepth)
 15889                  ? value + query[depth + 1].charAt(0).toUpperCase() + query[depth + 1].slice(1)
 15890                  : query
 15891                ;
 15892                if( $.isPlainObject( object[camelCaseValue] ) && (depth != maxDepth) ) {
 15893                  object = object[camelCaseValue];
 15894                }
 15895                else if( object[camelCaseValue] !== undefined ) {
 15896                  found = object[camelCaseValue];
 15897                  return false;
 15898                }
 15899                else if( $.isPlainObject( object[value] ) && (depth != maxDepth) ) {
 15900                  object = object[value];
 15901                }
 15902                else if( object[value] !== undefined ) {
 15903                  found = object[value];
 15904                  return false;
 15905                }
 15906                else {
 15907                  module.error(error.method, query);
 15908                  return false;
 15909                }
 15910              });
 15911            }
 15912            if ( $.isFunction( found ) ) {
 15913              response = found.apply(context, passedArguments);
 15914            }
 15915            else if(found !== undefined) {
 15916              response = found;
 15917            }
 15918            if($.isArray(returnedValue)) {
 15919              returnedValue.push(response);
 15920            }
 15921            else if(returnedValue !== undefined) {
 15922              returnedValue = [returnedValue, response];
 15923            }
 15924            else if(response !== undefined) {
 15925              returnedValue = response;
 15926            }
 15927            return found;
 15928          }
 15929        };
 15930  
 15931        if(methodInvoked) {
 15932          if(instance === undefined) {
 15933            module.initialize();
 15934          }
 15935          module.invoke(query);
 15936        }
 15937        else {
 15938          if(instance !== undefined) {
 15939            instance.invoke('destroy');
 15940          }
 15941          module.initialize();
 15942        }
 15943      })
 15944    ;
 15945  
 15946    return (returnedValue !== undefined)
 15947      ? returnedValue
 15948      : this
 15949    ;
 15950  };
 15951  
 15952  $.api.settings = {
 15953  
 15954    name            : 'API',
 15955    namespace       : 'api',
 15956  
 15957    debug           : true,
 15958    verbose         : false,
 15959    performance     : true,
 15960  
 15961    // event binding
 15962    on              : 'auto',
 15963    filter          : '.disabled',
 15964    stateContext    : false,
 15965  
 15966    // state
 15967    loadingDuration : 0,
 15968    errorDuration   : 2000,
 15969  
 15970    // templating
 15971    action          : false,
 15972    url             : false,
 15973    base            : '',
 15974  
 15975    // data
 15976    urlData         : {},
 15977  
 15978    // ui
 15979    defaultData     : true,
 15980    serializeForm   : false,
 15981    throttle        : 0,
 15982  
 15983    // jQ ajax
 15984    method          : 'get',
 15985    data            : {},
 15986    dataType        : 'json',
 15987  
 15988    // callbacks
 15989    beforeSend  : function(settings) { return settings; },
 15990    beforeXHR   : function(xhr) {},
 15991  
 15992    onRequest   : function(promise, xhr) {},
 15993    onSuccess   : function(response, $module) {},
 15994    onComplete  : function(response, $module) {},
 15995    onFailure   : function(errorMessage, $module) {},
 15996    onError     : function(errorMessage, $module) {},
 15997    onAbort     : function(errorMessage, $module) {},
 15998  
 15999    successTest : false,
 16000  
 16001    // errors
 16002    error : {
 16003      beforeSend        : 'The before send function has aborted the request',
 16004      error             : 'There was an error with your request',
 16005      exitConditions    : 'API Request Aborted. Exit conditions met',
 16006      JSONParse         : 'JSON could not be parsed during error handling',
 16007      legacyParameters  : 'You are using legacy API success callback names',
 16008      method            : 'The method you called is not defined',
 16009      missingAction     : 'API action used but no url was defined',
 16010      missingSerialize  : 'Required dependency jquery-serialize-object missing, using basic serialize',
 16011      missingURL        : 'No URL specified for api event',
 16012      noReturnedValue   : 'The beforeSend callback must return a settings object, beforeSend ignored.',
 16013      parseError        : 'There was an error parsing your request',
 16014      requiredParameter : 'Missing a required URL parameter: ',
 16015      statusMessage     : 'Server gave an error: ',
 16016      timeout           : 'Your request timed out'
 16017    },
 16018  
 16019    regExp  : {
 16020      required: /\{\$*[A-z0-9]+\}/g,
 16021      optional: /\{\/\$*[A-z0-9]+\}/g,
 16022    },
 16023  
 16024    className: {
 16025      loading : 'loading',
 16026      error   : 'error'
 16027    },
 16028  
 16029    selector: {
 16030      form: 'form'
 16031    },
 16032  
 16033    metadata: {
 16034      action  : 'action'
 16035    }
 16036  };
 16037  
 16038  
 16039  $.api.settings.api = {};
 16040  
 16041  
 16042  })( jQuery, window , document );
 16043  /*!
 16044   * # Semantic UI x.x - Form Validation
 16045   * http://github.com/semantic-org/semantic-ui/
 16046   *
 16047   *
 16048   * Copyright 2014 Contributors
 16049   * Released under the MIT license
 16050   * http://opensource.org/licenses/MIT
 16051   *
 16052   */
 16053  
 16054  ;(function ( $, window, document, undefined ) {
 16055  
 16056  "use strict";
 16057  
 16058  $.fn.form = function(fields, parameters) {
 16059    var
 16060      $allModules     = $(this),
 16061  
 16062      settings        = $.extend(true, {}, $.fn.form.settings, parameters),
 16063      validation      = $.extend({}, $.fn.form.settings.defaults, fields),
 16064  
 16065      namespace       = settings.namespace,
 16066      metadata        = settings.metadata,
 16067      selector        = settings.selector,
 16068      className       = settings.className,
 16069      error           = settings.error,
 16070  
 16071      eventNamespace  = '.' + namespace,
 16072      moduleNamespace = 'module-' + namespace,
 16073  
 16074      moduleSelector  = $allModules.selector || '',
 16075  
 16076      time            = new Date().getTime(),
 16077      performance     = [],
 16078  
 16079      query           = arguments[0],
 16080      methodInvoked   = (typeof query == 'string'),
 16081      queryArguments  = [].slice.call(arguments, 1),
 16082      returnedValue
 16083    ;
 16084    $allModules
 16085      .each(function() {
 16086        var
 16087          $module     = $(this),
 16088          $field      = $(this).find(selector.field),
 16089          $group      = $(this).find(selector.group),
 16090          $message    = $(this).find(selector.message),
 16091          $prompt     = $(this).find(selector.prompt),
 16092  
 16093          $submit     = $(this).find(selector.submit),
 16094          $clear      = $(this).find(selector.clear),
 16095          $reset      = $(this).find(selector.reset),
 16096  
 16097          formErrors  = [],
 16098          keyHeldDown = false,
 16099  
 16100          element     = this,
 16101          instance    = $module.data(moduleNamespace),
 16102          module
 16103        ;
 16104  
 16105        module      = {
 16106  
 16107          initialize: function() {
 16108            module.verbose('Initializing form validation', $module, validation, settings);
 16109            module.bindEvents();
 16110            module.set.defaults();
 16111            module.instantiate();
 16112          },
 16113  
 16114          instantiate: function() {
 16115            module.verbose('Storing instance of module', module);
 16116            instance = module;
 16117            $module
 16118              .data(moduleNamespace, module)
 16119            ;
 16120          },
 16121  
 16122          destroy: function() {
 16123            module.verbose('Destroying previous module', instance);
 16124            module.removeEvents();
 16125            $module
 16126              .removeData(moduleNamespace)
 16127            ;
 16128          },
 16129  
 16130          refresh: function() {
 16131            module.verbose('Refreshing selector cache');
 16132            $field = $module.find(selector.field);
 16133          },
 16134  
 16135          submit: function() {
 16136            module.verbose('Submitting form', $module);
 16137            $module
 16138              .submit()
 16139            ;
 16140          },
 16141  
 16142          attachEvents: function(selector, action) {
 16143            action = action || 'submit';
 16144            $(selector)
 16145              .on('click', function(event) {
 16146                module[action]();
 16147                event.preventDefault();
 16148              })
 16149            ;
 16150          },
 16151  
 16152          bindEvents: function() {
 16153            if(settings.keyboardShortcuts) {
 16154              $field
 16155                .on('keydown' + eventNamespace, module.event.field.keydown)
 16156              ;
 16157            }
 16158            $module
 16159              .on('submit' + eventNamespace, module.validate.form)
 16160            ;
 16161            $field
 16162              .on('blur' + eventNamespace, module.event.field.blur)
 16163            ;
 16164  
 16165            // attach events to common elements
 16166            module.attachEvents($submit, 'submit');
 16167            module.attachEvents($reset, 'reset');
 16168            module.attachEvents($clear, 'clear');
 16169  
 16170            $field
 16171              .each(function() {
 16172                var
 16173                  type       = $(this).prop('type'),
 16174                  inputEvent = module.get.changeEvent(type)
 16175                ;
 16176                $(this)
 16177                  .on(inputEvent + eventNamespace, module.event.field.change)
 16178                ;
 16179              })
 16180            ;
 16181          },
 16182  
 16183          clear: function() {
 16184            $field
 16185              .each(function () {
 16186                var
 16187                  $field       = $(this),
 16188                  $element     = $field.parent(),
 16189                  $fieldGroup  = $field.closest($group),
 16190                  $prompt      = $fieldGroup.find(selector.prompt),
 16191                  defaultValue = $field.data(metadata.defaultValue) || '',
 16192                  isCheckbox   = $element.is(selector.uiCheckbox),
 16193                  isDropdown   = $element.is(selector.uiDropdown),
 16194                  isErrored    = $fieldGroup.hasClass(className.error)
 16195                ;
 16196                if(isErrored) {
 16197                  module.verbose('Resetting error on field', $fieldGroup);
 16198                  $fieldGroup.removeClass(className.error);
 16199                  $prompt.remove();
 16200                }
 16201                if(isDropdown) {
 16202                  module.verbose('Resetting dropdown value', $element, defaultValue);
 16203                  $element.dropdown('clear');
 16204                }
 16205                else if(isCheckbox) {
 16206                  $element.checkbox('uncheck');
 16207                }
 16208                else {
 16209                  module.verbose('Resetting field value', $field, defaultValue);
 16210                  $field.val('');
 16211                }
 16212              })
 16213            ;
 16214          },
 16215  
 16216          reset: function() {
 16217            $field
 16218              .each(function () {
 16219                var
 16220                  $field       = $(this),
 16221                  $element     = $field.parent(),
 16222                  $fieldGroup  = $field.closest($group),
 16223                  $prompt      = $fieldGroup.find(selector.prompt),
 16224                  defaultValue = $field.data(metadata.defaultValue) || '',
 16225                  isCheckbox   = $element.is(selector.uiCheckbox),
 16226                  isDropdown   = $element.is(selector.uiDropdown),
 16227                  isErrored    = $fieldGroup.hasClass(className.error)
 16228                ;
 16229                if(isErrored) {
 16230                  module.verbose('Resetting error on field', $fieldGroup);
 16231                  $fieldGroup.removeClass(className.error);
 16232                  $prompt.remove();
 16233                }
 16234                if(isDropdown) {
 16235                  module.verbose('Resetting dropdown value', $element, defaultValue);
 16236                  $element.dropdown('restore defaults');
 16237                }
 16238                else if(isCheckbox) {
 16239                  module.verbose('Resetting checkbox value', $element, defaultValue);
 16240                  if(defaultValue === true) {
 16241                    $element.checkbox('check');
 16242                  }
 16243                  else {
 16244                    $element.checkbox('uncheck');
 16245                  }
 16246                }
 16247                else {
 16248                  module.verbose('Resetting field value', $field, defaultValue);
 16249                  $field.val(defaultValue);
 16250                }
 16251              })
 16252            ;
 16253          },
 16254  
 16255          removeEvents: function() {
 16256            $module
 16257              .off(eventNamespace)
 16258            ;
 16259            $field
 16260              .off(eventNamespace)
 16261            ;
 16262            $submit
 16263              .off(eventNamespace)
 16264            ;
 16265            $field
 16266              .off(eventNamespace)
 16267            ;
 16268          },
 16269  
 16270          event: {
 16271            field: {
 16272              keydown: function(event) {
 16273                var
 16274                  $field  = $(this),
 16275                  key     = event.which,
 16276                  keyCode = {
 16277                    enter  : 13,
 16278                    escape : 27
 16279                  }
 16280                ;
 16281                if( key == keyCode.escape) {
 16282                  module.verbose('Escape key pressed blurring field');
 16283                  $field
 16284                    .blur()
 16285                  ;
 16286                }
 16287                if(!event.ctrlKey && key == keyCode.enter && $field.is(selector.input) && $field.not(selector.checkbox).length > 0 ) {
 16288                  $submit
 16289                    .addClass(className.pressed)
 16290                  ;
 16291                  if(!keyHeldDown) {
 16292                    $field
 16293                      .one('keyup' + eventNamespace, module.event.field.keyup)
 16294                    ;
 16295                    module.submit();
 16296                    module.debug('Enter pressed on input submitting form');
 16297                  }
 16298                  keyHeldDown = true;
 16299                }
 16300              },
 16301              keyup: function() {
 16302                keyHeldDown = false;
 16303                $submit.removeClass(className.pressed);
 16304              },
 16305              blur: function() {
 16306                var
 16307                  $field      = $(this),
 16308                  $fieldGroup = $field.closest($group)
 16309                ;
 16310                if( $fieldGroup.hasClass(className.error) ) {
 16311                  module.debug('Revalidating field', $field,  module.get.validation($field));
 16312                  module.validate.field( module.get.validation($field) );
 16313                }
 16314                else if(settings.on == 'blur' || settings.on == 'change') {
 16315                  module.validate.field( module.get.validation($field) );
 16316                }
 16317              },
 16318              change: function() {
 16319                var
 16320                  $field      = $(this),
 16321                  $fieldGroup = $field.closest($group)
 16322                ;
 16323                if(settings.on == 'change' || ( $fieldGroup.hasClass(className.error) && settings.revalidate) ) {
 16324                  clearTimeout(module.timer);
 16325                  module.timer = setTimeout(function() {
 16326                    module.debug('Revalidating field', $field,  module.get.validation($field));
 16327                    module.validate.field( module.get.validation($field) );
 16328                  }, settings.delay);
 16329                }
 16330              }
 16331            }
 16332  
 16333          },
 16334  
 16335          get: {
 16336            changeEvent: function(type) {
 16337              if(type == 'checkbox' || type == 'radio' || type == 'hidden') {
 16338                return 'change';
 16339              }
 16340              else {
 16341                return module.get.inputEvent();
 16342              }
 16343            },
 16344            inputEvent: function() {
 16345              return (document.createElement('input').oninput !== undefined)
 16346                ? 'input'
 16347                : (document.createElement('input').onpropertychange !== undefined)
 16348                  ? 'propertychange'
 16349                  : 'keyup'
 16350              ;
 16351            },
 16352            field: function(identifier) {
 16353              module.verbose('Finding field with identifier', identifier);
 16354              if( $field.filter('#' + identifier).length > 0 ) {
 16355                return $field.filter('#' + identifier);
 16356              }
 16357              else if( $field.filter('[name="' + identifier +'"]').length > 0 ) {
 16358                return $field.filter('[name="' + identifier +'"]');
 16359              }
 16360              else if( $field.filter('[name="' + identifier +'[]"]').length > 0 ) {
 16361                return $field.filter('[name="' + identifier +'[]"]');
 16362              }
 16363              else if( $field.filter('[data-' + metadata.validate + '="'+ identifier +'"]').length > 0 ) {
 16364                return $field.filter('[data-' + metadata.validate + '="'+ identifier +'"]');
 16365              }
 16366              return $('<input/>');
 16367            },
 16368            fields: function(fields) {
 16369              var
 16370                $fields = $()
 16371              ;
 16372              $.each(fields, function(index, name) {
 16373                $fields = $fields.add( module.get.field(name) );
 16374              });
 16375              return $fields;
 16376            },
 16377            validation: function($field) {
 16378              var
 16379                rules
 16380              ;
 16381              $.each(validation, function(fieldName, field) {
 16382                if( module.get.field(field.identifier).get(0) == $field.get(0) ) {
 16383                  rules = field;
 16384                }
 16385              });
 16386              return rules || false;
 16387            },
 16388            value: function (field) {
 16389              var
 16390                fields = [],
 16391                results
 16392              ;
 16393              fields.push(field);
 16394              results = module.get.values.call(element, fields);
 16395              return results[field];
 16396            },
 16397            values: function (fields) {
 16398              var
 16399                $fields = $.isArray(fields)
 16400                  ? module.get.fields(fields)
 16401                  : $field,
 16402                values = {}
 16403              ;
 16404              $fields.each(function(index, field) {
 16405                var
 16406                  $field     = $(field),
 16407                  type       = $field.prop('type'),
 16408                  name       = $field.prop('name'),
 16409                  value      = $field.val(),
 16410                  isCheckbox = $field.is(selector.checkbox),
 16411                  isRadio    = $field.is(selector.radio),
 16412                  isMultiple = (name.indexOf('[]') !== -1),
 16413                  isChecked  = (isCheckbox)
 16414                    ? $field.is(':checked')
 16415                    : false
 16416                ;
 16417                if(name) {
 16418                  if(isMultiple) {
 16419                    name = name.replace('[]', '');
 16420                    if(!values[name]) {
 16421                      values[name] = [];
 16422                    }
 16423                    if(isCheckbox) {
 16424                      if(isChecked) {
 16425                        values[name].push(value)
 16426                      }
 16427                      else {
 16428                        module.debug('Omitted unchecked checkbox', $field);
 16429                        return true;
 16430                      }
 16431                    }
 16432                    else {
 16433                      values[name].push(value);
 16434                    }
 16435                  }
 16436                  else {
 16437                    if(isRadio) {
 16438                      if(isChecked) {
 16439                        values[name] = value;
 16440                      }
 16441                    }
 16442                    else if(isCheckbox) {
 16443                      if(isChecked) {
 16444                        values[name] = true;
 16445                      }
 16446                      else {
 16447                        module.debug('Omitted unchecked checkbox', $field);
 16448                        return true;
 16449                      }
 16450                    }
 16451                    else {
 16452                      values[name] = value;
 16453                    }
 16454                  }
 16455                }
 16456              });
 16457              return values;
 16458            }
 16459          },
 16460  
 16461          has: {
 16462  
 16463            field: function(identifier) {
 16464              module.verbose('Checking for existence of a field with identifier', identifier);
 16465              if( $field.filter('#' + identifier).length > 0 ) {
 16466                return true;
 16467              }
 16468              else if( $field.filter('[name="' + identifier +'"]').length > 0 ) {
 16469                return true;
 16470              }
 16471              else if( $field.filter('[data-' + metadata.validate + '="'+ identifier +'"]').length > 0 ) {
 16472                return true;
 16473              }
 16474              return false;
 16475            }
 16476  
 16477          },
 16478  
 16479          add: {
 16480            prompt: function(identifier, errors) {
 16481              var
 16482                $field       = module.get.field(identifier),
 16483                $fieldGroup  = $field.closest($group),
 16484                $prompt      = $fieldGroup.children(selector.prompt),
 16485                promptExists = ($prompt.length !== 0)
 16486              ;
 16487              errors = (typeof errors == 'string')
 16488                ? [errors]
 16489                : errors
 16490              ;
 16491              module.verbose('Adding field error state', identifier);
 16492              $fieldGroup
 16493                .addClass(className.error)
 16494              ;
 16495              if(settings.inline) {
 16496                if(!promptExists) {
 16497                  $prompt = settings.templates.prompt(errors);
 16498                  $prompt
 16499                    .appendTo($fieldGroup)
 16500                  ;
 16501                }
 16502                $prompt
 16503                  .html(errors[0])
 16504                ;
 16505                if(!promptExists) {
 16506                  if(settings.transition && $.fn.transition !== undefined && $module.transition('is supported')) {
 16507                    module.verbose('Displaying error with css transition', settings.transition);
 16508                    $prompt.transition(settings.transition + ' in', settings.duration);
 16509                  }
 16510                  else {
 16511                    module.verbose('Displaying error with fallback javascript animation');
 16512                    $prompt
 16513                      .fadeIn(settings.duration)
 16514                    ;
 16515                  }
 16516                }
 16517                else {
 16518                  module.verbose('Inline errors are disabled, no inline error added', identifier);
 16519                }
 16520              }
 16521            },
 16522            errors: function(errors) {
 16523              module.debug('Adding form error messages', errors);
 16524              $message
 16525                .html( settings.templates.error(errors) )
 16526              ;
 16527            }
 16528          },
 16529  
 16530          remove: {
 16531            prompt: function(field) {
 16532              var
 16533                $field      = module.get.field(field.identifier),
 16534                $fieldGroup = $field.closest($group),
 16535                $prompt     = $fieldGroup.children(selector.prompt)
 16536              ;
 16537              $fieldGroup
 16538                .removeClass(className.error)
 16539              ;
 16540              if(settings.inline && $prompt.is(':visible')) {
 16541                module.verbose('Removing prompt for field', field);
 16542                if(settings.transition && $.fn.transition !== undefined && $module.transition('is supported')) {
 16543                  $prompt.transition(settings.transition + ' out', settings.duration, function() {
 16544                    $prompt.remove();
 16545                  });
 16546                }
 16547                else {
 16548                  $prompt
 16549                    .fadeOut(settings.duration, function(){
 16550                      $prompt.remove();
 16551                    })
 16552                  ;
 16553                }
 16554              }
 16555            }
 16556          },
 16557  
 16558          set: {
 16559            success: function() {
 16560              $module
 16561                .removeClass(className.error)
 16562                .addClass(className.success)
 16563              ;
 16564            },
 16565            defaults: function () {
 16566              $field
 16567                .each(function () {
 16568                  var
 16569                    $field     = $(this),
 16570                    isCheckbox = ($field.filter(selector.checkbox).length > 0),
 16571                    value      = (isCheckbox)
 16572                      ? $field.is(':checked')
 16573                      : $field.val()
 16574                  ;
 16575                  $field.data(metadata.defaultValue, value);
 16576                })
 16577              ;
 16578            },
 16579            error: function() {
 16580              $module
 16581                .removeClass(className.success)
 16582                .addClass(className.error)
 16583              ;
 16584            },
 16585            value: function (field, value) {
 16586              var
 16587                fields = {}
 16588              ;
 16589              fields[field] = value;
 16590              return module.set.values.call(element, fields);
 16591            },
 16592            values: function (fields) {
 16593              if($.isEmptyObject(fields)) {
 16594                return;
 16595              }
 16596              $.each(fields, function(key, value) {
 16597                var
 16598                  $field      = module.get.field(key),
 16599                  $element    = $field.parent(),
 16600                  isMultiple  = $.isArray(value),
 16601                  isCheckbox  = $element.is(selector.uiCheckbox),
 16602                  isDropdown  = $element.is(selector.uiDropdown),
 16603                  isRadio     = ($field.is(selector.radio) && isCheckbox),
 16604                  fieldExists = ($field.length > 0),
 16605                  $multipleField
 16606                ;
 16607                if(fieldExists) {
 16608                  if(isMultiple && isCheckbox) {
 16609                    module.verbose('Selecting multiple', value, $field);
 16610                    $element.checkbox('uncheck');
 16611                    $.each(value, function(index, value) {
 16612                      $multipleField = $field.filter('[value="' + value + '"]');
 16613                      $element       = $multipleField.parent();
 16614                      if($multipleField.length > 0) {
 16615                        $element.checkbox('check');
 16616                      }
 16617                    });
 16618                  }
 16619                  else if(isRadio) {
 16620                    module.verbose('Selecting radio value', value, $field);
 16621                    $field.filter('[value="' + value + '"]')
 16622                      .parent(selector.uiCheckbox)
 16623                        .checkbox('check')
 16624                    ;
 16625                  }
 16626                  else if(isCheckbox) {
 16627                    module.verbose('Setting checkbox value', value, $element);
 16628                    if(value === true) {
 16629                      $element.checkbox('check');
 16630                    }
 16631                    else {
 16632                      $element.checkbox('uncheck');
 16633                    }
 16634                  }
 16635                  else if(isDropdown) {
 16636                    module.verbose('Setting dropdown value', value, $element);
 16637                    $element.dropdown('set selected', value);
 16638                  }
 16639                  else {
 16640                    module.verbose('Setting field value', value, $field);
 16641                    $field.val(value);
 16642                  }
 16643                }
 16644              });
 16645              module.validate.form();
 16646            }
 16647          },
 16648  
 16649          validate: {
 16650  
 16651            form: function(event) {
 16652              var
 16653                allValid = true,
 16654                apiRequest
 16655              ;
 16656  
 16657              // input keydown event will fire submit repeatedly by browser default
 16658              if(keyHeldDown) {
 16659                return false;
 16660              }
 16661  
 16662              // reset errors
 16663              formErrors = [];
 16664              $.each(validation, function(fieldName, field) {
 16665                if( !( module.validate.field(field) ) ) {
 16666                  allValid = false;
 16667                }
 16668              });
 16669              if(allValid) {
 16670                module.debug('Form has no validation errors, submitting');
 16671                module.set.success();
 16672                return settings.onSuccess.call(element, event);
 16673              }
 16674              else {
 16675                module.debug('Form has errors');
 16676                module.set.error();
 16677                if(!settings.inline) {
 16678                  module.add.errors(formErrors);
 16679                }
 16680                // prevent ajax submit
 16681                if($module.data('moduleApi') !== undefined) {
 16682                  event.stopImmediatePropagation();
 16683                }
 16684                return settings.onFailure.call(element, formErrors);
 16685              }
 16686            },
 16687  
 16688            // takes a validation object and returns whether field passes validation
 16689            field: function(field) {
 16690              var
 16691                $field      = module.get.field(field.identifier),
 16692                fieldValid  = true,
 16693                fieldErrors = []
 16694              ;
 16695              if($field.prop('disabled')) {
 16696                module.debug('Field is disabled. Skipping', field.identifier);
 16697                fieldValid = true;
 16698              }
 16699              else if(field.optional && $.trim($field.val()) === ''){
 16700                module.debug('Field is optional and empty. Skipping', field.identifier);
 16701                fieldValid = true;
 16702              }
 16703              else if(field.rules !== undefined) {
 16704                $.each(field.rules, function(index, rule) {
 16705                  if( module.has.field(field.identifier) && !( module.validate.rule(field, rule) ) ) {
 16706                    module.debug('Field is invalid', field.identifier, rule.type);
 16707                    fieldErrors.push(rule.prompt);
 16708                    fieldValid = false;
 16709                  }
 16710                });
 16711              }
 16712              if(fieldValid) {
 16713                module.remove.prompt(field, fieldErrors);
 16714                settings.onValid.call($field);
 16715              }
 16716              else {
 16717                formErrors = formErrors.concat(fieldErrors);
 16718                module.add.prompt(field.identifier, fieldErrors);
 16719                settings.onInvalid.call($field, fieldErrors);
 16720                return false;
 16721              }
 16722              return true;
 16723            },
 16724  
 16725            // takes validation rule and returns whether field passes rule
 16726            rule: function(field, validation) {
 16727              var
 16728                $field        = module.get.field(field.identifier),
 16729                type          = validation.type,
 16730                value         = $.trim($field.val() + ''),
 16731  
 16732                bracketRegExp = /\[(.*)\]/i,
 16733                bracket       = bracketRegExp.exec(type),
 16734                isValid       = true,
 16735                ancillary,
 16736                functionType
 16737              ;
 16738              // if bracket notation is used, pass in extra parameters
 16739              if(bracket !== undefined && bracket !== null) {
 16740                ancillary    = '' + bracket[1];
 16741                functionType = type.replace(bracket[0], '');
 16742                isValid      = settings.rules[functionType].call(element, value, ancillary);
 16743              }
 16744              // normal notation
 16745              else {
 16746                isValid = settings.rules[type].call($field, value);
 16747              }
 16748              return isValid;
 16749            }
 16750          },
 16751  
 16752          setting: function(name, value) {
 16753            if( $.isPlainObject(name) ) {
 16754              $.extend(true, settings, name);
 16755            }
 16756            else if(value !== undefined) {
 16757              settings[name] = value;
 16758            }
 16759            else {
 16760              return settings[name];
 16761            }
 16762          },
 16763          internal: function(name, value) {
 16764            if( $.isPlainObject(name) ) {
 16765              $.extend(true, module, name);
 16766            }
 16767            else if(value !== undefined) {
 16768              module[name] = value;
 16769            }
 16770            else {
 16771              return module[name];
 16772            }
 16773          },
 16774          debug: function() {
 16775            if(settings.debug) {
 16776              if(settings.performance) {
 16777                module.performance.log(arguments);
 16778              }
 16779              else {
 16780                module.debug = Function.prototype.bind.call(console.info, console, settings.name + ':');
 16781                module.debug.apply(console, arguments);
 16782              }
 16783            }
 16784          },
 16785          verbose: function() {
 16786            if(settings.verbose && settings.debug) {
 16787              if(settings.performance) {
 16788                module.performance.log(arguments);
 16789              }
 16790              else {
 16791                module.verbose = Function.prototype.bind.call(console.info, console, settings.name + ':');
 16792                module.verbose.apply(console, arguments);
 16793              }
 16794            }
 16795          },
 16796          error: function() {
 16797            module.error = Function.prototype.bind.call(console.error, console, settings.name + ':');
 16798            module.error.apply(console, arguments);
 16799          },
 16800          performance: {
 16801            log: function(message) {
 16802              var
 16803                currentTime,
 16804                executionTime,
 16805                previousTime
 16806              ;
 16807              if(settings.performance) {
 16808                currentTime   = new Date().getTime();
 16809                previousTime  = time || currentTime;
 16810                executionTime = currentTime - previousTime;
 16811                time          = currentTime;
 16812                performance.push({
 16813                  'Name'           : message[0],
 16814                  'Arguments'      : [].slice.call(message, 1) || '',
 16815                  'Element'        : element,
 16816                  'Execution Time' : executionTime
 16817                });
 16818              }
 16819              clearTimeout(module.performance.timer);
 16820              module.performance.timer = setTimeout(module.performance.display, 100);
 16821            },
 16822            display: function() {
 16823              var
 16824                title = settings.name + ':',
 16825                totalTime = 0
 16826              ;
 16827              time = false;
 16828              clearTimeout(module.performance.timer);
 16829              $.each(performance, function(index, data) {
 16830                totalTime += data['Execution Time'];
 16831              });
 16832              title += ' ' + totalTime + 'ms';
 16833              if(moduleSelector) {
 16834                title += ' \'' + moduleSelector + '\'';
 16835              }
 16836              if($allModules.length > 1) {
 16837                title += ' ' + '(' + $allModules.length + ')';
 16838              }
 16839              if( (console.group !== undefined || console.table !== undefined) && performance.length > 0) {
 16840                console.groupCollapsed(title);
 16841                if(console.table) {
 16842                  console.table(performance);
 16843                }
 16844                else {
 16845                  $.each(performance, function(index, data) {
 16846                    console.log(data['Name'] + ': ' + data['Execution Time']+'ms');
 16847                  });
 16848                }
 16849                console.groupEnd();
 16850              }
 16851              performance = [];
 16852            }
 16853          },
 16854          invoke: function(query, passedArguments, context) {
 16855            var
 16856              object = instance,
 16857              maxDepth,
 16858              found,
 16859              response
 16860            ;
 16861            passedArguments = passedArguments || queryArguments;
 16862            context         = element         || context;
 16863            if(typeof query == 'string' && object !== undefined) {
 16864              query    = query.split(/[\. ]/);
 16865              maxDepth = query.length - 1;
 16866              $.each(query, function(depth, value) {
 16867                var camelCaseValue = (depth != maxDepth)
 16868                  ? value + query[depth + 1].charAt(0).toUpperCase() + query[depth + 1].slice(1)
 16869                  : query
 16870                ;
 16871                if( $.isPlainObject( object[camelCaseValue] ) && (depth != maxDepth) ) {
 16872                  object = object[camelCaseValue];
 16873                }
 16874                else if( object[camelCaseValue] !== undefined ) {
 16875                  found = object[camelCaseValue];
 16876                  return false;
 16877                }
 16878                else if( $.isPlainObject( object[value] ) && (depth != maxDepth) ) {
 16879                  object = object[value];
 16880                }
 16881                else if( object[value] !== undefined ) {
 16882                  found = object[value];
 16883                  return false;
 16884                }
 16885                else {
 16886                  return false;
 16887                }
 16888              });
 16889            }
 16890            if( $.isFunction( found ) ) {
 16891              response = found.apply(context, passedArguments);
 16892            }
 16893            else if(found !== undefined) {
 16894              response = found;
 16895            }
 16896            if($.isArray(returnedValue)) {
 16897              returnedValue.push(response);
 16898            }
 16899            else if(returnedValue !== undefined) {
 16900              returnedValue = [returnedValue, response];
 16901            }
 16902            else if(response !== undefined) {
 16903              returnedValue = response;
 16904            }
 16905            return found;
 16906          }
 16907        };
 16908        if(methodInvoked) {
 16909          if(instance === undefined) {
 16910            module.initialize();
 16911          }
 16912          module.invoke(query);
 16913        }
 16914        else {
 16915          if(instance !== undefined) {
 16916            instance.invoke('destroy');
 16917          }
 16918          module.initialize();
 16919        }
 16920  
 16921      })
 16922    ;
 16923  
 16924    return (returnedValue !== undefined)
 16925      ? returnedValue
 16926      : this
 16927    ;
 16928  };
 16929  
 16930  $.fn.form.settings = {
 16931  
 16932    name              : 'Form',
 16933    namespace         : 'form',
 16934  
 16935    debug             : false,
 16936    verbose           : true,
 16937    performance       : true,
 16938  
 16939  
 16940    keyboardShortcuts : true,
 16941    on                : 'submit',
 16942    inline            : false,
 16943  
 16944    delay             : 200,
 16945    revalidate        : true,
 16946  
 16947    transition        : 'scale',
 16948    duration          : 200,
 16949  
 16950    onValid           : function() {},
 16951    onInvalid         : function() {},
 16952    onSuccess         : function() { return true; },
 16953    onFailure         : function() { return false; },
 16954  
 16955    metadata : {
 16956      defaultValue : 'default',
 16957      validate     : 'validate'
 16958    },
 16959  
 16960    selector : {
 16961      checkbox   : 'input[type="checkbox"], input[type="radio"]',
 16962      clear      : '.clear',
 16963      field      : 'input, textarea, select',
 16964      group      : '.field',
 16965      input      : 'input',
 16966      message    : '.error.message',
 16967      prompt     : '.prompt.label',
 16968      radio      : 'input[type="radio"]',
 16969      reset      : '.reset',
 16970      submit     : '.submit',
 16971      uiCheckbox : '.ui.checkbox',
 16972      uiDropdown : '.ui.dropdown'
 16973    },
 16974  
 16975    className : {
 16976      error   : 'error',
 16977      label   : 'ui prompt label',
 16978      pressed : 'down',
 16979      success : 'success'
 16980    },
 16981  
 16982    error: {
 16983      method   : 'The method you called is not defined.'
 16984    },
 16985  
 16986    templates: {
 16987  
 16988      // template that produces error message
 16989      error: function(errors) {
 16990        var
 16991          html = '<ul class="list">'
 16992        ;
 16993        $.each(errors, function(index, value) {
 16994          html += '<li>' + value + '</li>';
 16995        });
 16996        html += '</ul>';
 16997        return $(html);
 16998      },
 16999  
 17000      // template that produces label
 17001      prompt: function(errors) {
 17002        return $('<div/>')
 17003          .addClass('ui red pointing prompt label')
 17004          .html(errors[0])
 17005        ;
 17006      }
 17007    },
 17008  
 17009    rules: {
 17010  
 17011      // checkbox checked
 17012      checked: function() {
 17013        return ($(this).filter(':checked').length > 0);
 17014      },
 17015  
 17016      // value contains text (insensitive)
 17017      contains: function(value, text) {
 17018        // escape regex characters
 17019        text = text.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&");
 17020        return (value.search( new RegExp(text, 'i') ) !== -1);
 17021      },
 17022  
 17023      // value contains text (case sensitive)
 17024      containsExactly: function(value, text) {
 17025        // escape regex characters
 17026        text = text.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&");
 17027        return (value.search( new RegExp(text) ) !== -1);
 17028      },
 17029  
 17030      // is most likely an email
 17031      email: function(value){
 17032        var
 17033          emailRegExp = new RegExp("[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?", "i")
 17034        ;
 17035        return emailRegExp.test(value);
 17036      },
 17037  
 17038      // is not empty or blank string
 17039      empty: function(value) {
 17040        return !(value === undefined || '' === value);
 17041      },
 17042  
 17043      // is valid integer
 17044      integer: function(value, range) {
 17045        var
 17046          intRegExp = /^\-?\d+$/,
 17047          min,
 17048          max,
 17049          parts
 17050        ;
 17051        if(range === undefined || range === '' || range === '..') {
 17052          // do nothing
 17053        }
 17054        else if(range.indexOf('..') == -1) {
 17055          if(intRegExp.test(range)) {
 17056            min = max = range - 0;
 17057          }
 17058        }
 17059        else {
 17060          parts = range.split('..', 2);
 17061          if(intRegExp.test(parts[0])) {
 17062            min = parts[0] - 0;
 17063          }
 17064          if(intRegExp.test(parts[1])) {
 17065            max = parts[1] - 0;
 17066          }
 17067        }
 17068        return (
 17069          intRegExp.test(value) &&
 17070          (min === undefined || value >= min) &&
 17071          (max === undefined || value <= max)
 17072        );
 17073      },
 17074  
 17075      // is value (case insensitive)
 17076      is: function(value, text) {
 17077        text = (typeof text == 'string')
 17078          ? text.toLowerCase()
 17079          : text
 17080        ;
 17081        value = (typeof value == 'string')
 17082          ? value.toLowerCase()
 17083          : value
 17084        ;
 17085        return (value == text);
 17086      },
 17087  
 17088      // is value
 17089      isExactly: function(value, text) {
 17090        return (value == text);
 17091      },
 17092  
 17093      // is at least string length
 17094      length: function(value, requiredLength) {
 17095        return (value !== undefined)
 17096          ? (value.length >= requiredLength)
 17097          : false
 17098        ;
 17099      },
 17100  
 17101      // matches another field
 17102      match: function(value, fieldIdentifier) {
 17103        // use either id or name of field
 17104        var
 17105          $form = $(this),
 17106          matchingValue
 17107        ;
 17108        if($form.find('#' + fieldIdentifier).length > 0) {
 17109          matchingValue = $form.find('#' + fieldIdentifier).val();
 17110        }
 17111        else if($form.find('[name="' + fieldIdentifier +'"]').length > 0) {
 17112          matchingValue = $form.find('[name="' + fieldIdentifier + '"]').val();
 17113        }
 17114        else if( $form.find('[data-validate="'+ fieldIdentifier +'"]').length > 0 ) {
 17115          matchingValue = $form.find('[data-validate="'+ fieldIdentifier +'"]').val();
 17116        }
 17117        return (matchingValue !== undefined)
 17118          ? ( value.toString() == matchingValue.toString() )
 17119          : false
 17120        ;
 17121      },
 17122  
 17123      // string length is less than max length
 17124      maxLength: function(value, maxLength) {
 17125        return (value !== undefined)
 17126          ? (value.length <= maxLength)
 17127          : false
 17128        ;
 17129      },
 17130  
 17131      // value is not value (case insensitive)
 17132      not: function(value, notValue) {
 17133        value = (typeof value == 'string')
 17134          ? value.toLowerCase()
 17135          : value
 17136        ;
 17137        notValue = (typeof notValue == 'string')
 17138          ? notValue.toLowerCase()
 17139          : notValue
 17140        ;
 17141        return (value != notValue);
 17142      },
 17143  
 17144      // value is not value (case sensitive)
 17145      notExactly: function(value, notValue) {
 17146        return (value != notValue);
 17147      },
 17148  
 17149      // value is most likely url
 17150      url: function(value) {
 17151        var
 17152          urlRegExp = /(ftp|http|https):\/\/(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?/
 17153        ;
 17154        return urlRegExp.test(value);
 17155      }
 17156    }
 17157  
 17158  };
 17159  
 17160  })( jQuery, window , document );
 17161  
 17162  /*!
 17163   * # Semantic UI x.x - State
 17164   * http://github.com/semantic-org/semantic-ui/
 17165   *
 17166   *
 17167   * Copyright 2014 Contributors
 17168   * Released under the MIT license
 17169   * http://opensource.org/licenses/MIT
 17170   *
 17171   */
 17172  
 17173  ;(function ( $, window, document, undefined ) {
 17174  
 17175  "use strict";
 17176  
 17177  $.fn.state = function(parameters) {
 17178    var
 17179      $allModules     = $(this),
 17180  
 17181      moduleSelector  = $allModules.selector || '',
 17182  
 17183      hasTouch        = ('ontouchstart' in document.documentElement),
 17184      time            = new Date().getTime(),
 17185      performance     = [],
 17186  
 17187      query           = arguments[0],
 17188      methodInvoked   = (typeof query == 'string'),
 17189      queryArguments  = [].slice.call(arguments, 1),
 17190  
 17191      returnedValue
 17192    ;
 17193    $allModules
 17194      .each(function() {
 17195        var
 17196          settings          = ( $.isPlainObject(parameters) )
 17197            ? $.extend(true, {}, $.fn.state.settings, parameters)
 17198            : $.extend({}, $.fn.state.settings),
 17199  
 17200          error           = settings.error,
 17201          metadata        = settings.metadata,
 17202          className       = settings.className,
 17203          namespace       = settings.namespace,
 17204          states          = settings.states,
 17205          text            = settings.text,
 17206  
 17207          eventNamespace  = '.' + namespace,
 17208          moduleNamespace = namespace + '-module',
 17209  
 17210          $module         = $(this),
 17211  
 17212          element         = this,
 17213          instance        = $module.data(moduleNamespace),
 17214  
 17215          module
 17216        ;
 17217        module = {
 17218  
 17219          initialize: function() {
 17220            module.verbose('Initializing module');
 17221  
 17222            // allow module to guess desired state based on element
 17223            if(settings.automatic) {
 17224              module.add.defaults();
 17225            }
 17226  
 17227            // bind events with delegated events
 17228            if(settings.context && moduleSelector !== '') {
 17229              $(settings.context)
 17230                .on(moduleSelector, 'mouseenter' + eventNamespace, module.change.text)
 17231                .on(moduleSelector, 'mouseleave' + eventNamespace, module.reset.text)
 17232                .on(moduleSelector, 'click'      + eventNamespace, module.toggle.state)
 17233              ;
 17234            }
 17235            else {
 17236              $module
 17237                .on('mouseenter' + eventNamespace, module.change.text)
 17238                .on('mouseleave' + eventNamespace, module.reset.text)
 17239                .on('click'      + eventNamespace, module.toggle.state)
 17240              ;
 17241            }
 17242            module.instantiate();
 17243          },
 17244  
 17245          instantiate: function() {
 17246            module.verbose('Storing instance of module', module);
 17247            instance = module;
 17248            $module
 17249              .data(moduleNamespace, module)
 17250            ;
 17251          },
 17252  
 17253          destroy: function() {
 17254            module.verbose('Destroying previous module', instance);
 17255            $module
 17256              .off(eventNamespace)
 17257              .removeData(moduleNamespace)
 17258            ;
 17259          },
 17260  
 17261          refresh: function() {
 17262            module.verbose('Refreshing selector cache');
 17263            $module = $(element);
 17264          },
 17265  
 17266          add: {
 17267            defaults: function() {
 17268              var
 17269                userStates = parameters && $.isPlainObject(parameters.states)
 17270                  ? parameters.states
 17271                  : {}
 17272              ;
 17273              $.each(settings.defaults, function(type, typeStates) {
 17274                if( module.is[type] !== undefined && module.is[type]() ) {
 17275                  module.verbose('Adding default states', type, element);
 17276                  $.extend(settings.states, typeStates, userStates);
 17277                }
 17278              });
 17279            }
 17280          },
 17281  
 17282          is: {
 17283  
 17284            active: function() {
 17285              return $module.hasClass(className.active);
 17286            },
 17287            loading: function() {
 17288              return $module.hasClass(className.loading);
 17289            },
 17290            inactive: function() {
 17291              return !( $module.hasClass(className.active) );
 17292            },
 17293            state: function(state) {
 17294              if(className[state] === undefined) {
 17295                return false;
 17296              }
 17297              return $module.hasClass( className[state] );
 17298            },
 17299  
 17300            enabled: function() {
 17301              return !( $module.is(settings.filter.active) );
 17302            },
 17303            disabled: function() {
 17304              return ( $module.is(settings.filter.active) );
 17305            },
 17306            textEnabled: function() {
 17307              return !( $module.is(settings.filter.text) );
 17308            },
 17309  
 17310            // definitions for automatic type detection
 17311            button: function() {
 17312              return $module.is('.button:not(a, .submit)');
 17313            },
 17314            input: function() {
 17315              return $module.is('input');
 17316            },
 17317            progress: function() {
 17318              return $module.is('.ui.progress');
 17319            }
 17320          },
 17321  
 17322          allow: function(state) {
 17323            module.debug('Now allowing state', state);
 17324            states[state] = true;
 17325          },
 17326          disallow: function(state) {
 17327            module.debug('No longer allowing', state);
 17328            states[state] = false;
 17329          },
 17330  
 17331          allows: function(state) {
 17332            return states[state] || false;
 17333          },
 17334  
 17335          enable: function() {
 17336            $module.removeClass(className.disabled);
 17337          },
 17338  
 17339          disable: function() {
 17340            $module.addClass(className.disabled);
 17341          },
 17342  
 17343          setState: function(state) {
 17344            if(module.allows(state)) {
 17345              $module.addClass( className[state] );
 17346            }
 17347          },
 17348  
 17349          removeState: function(state) {
 17350            if(module.allows(state)) {
 17351              $module.removeClass( className[state] );
 17352            }
 17353          },
 17354  
 17355          toggle: {
 17356            state: function() {
 17357              var
 17358                apiRequest,
 17359                requestCancelled
 17360              ;
 17361              if( module.allows('active') && module.is.enabled() ) {
 17362                module.refresh();
 17363                if($.fn.api !== undefined) {
 17364                  apiRequest       = $module.api('get request');
 17365                  requestCancelled = $module.api('was cancelled');
 17366                  if( requestCancelled ) {
 17367                    module.debug('API Request cancelled by beforesend');
 17368                    settings.activateTest   = function(){ return false; };
 17369                    settings.deactivateTest = function(){ return false; };
 17370                  }
 17371                  else if(apiRequest) {
 17372                    module.listenTo(apiRequest);
 17373                    return;
 17374                  }
 17375                }
 17376                module.change.state();
 17377              }
 17378            }
 17379          },
 17380  
 17381          listenTo: function(apiRequest) {
 17382            module.debug('API request detected, waiting for state signal', apiRequest);
 17383            if(apiRequest) {
 17384              if(text.loading) {
 17385                module.update.text(text.loading);
 17386              }
 17387              $.when(apiRequest)
 17388                .then(function() {
 17389                  if(apiRequest.state() == 'resolved') {
 17390                    module.debug('API request succeeded');
 17391                    settings.activateTest   = function(){ return true; };
 17392                    settings.deactivateTest = function(){ return true; };
 17393                  }
 17394                  else {
 17395                    module.debug('API request failed');
 17396                    settings.activateTest   = function(){ return false; };
 17397                    settings.deactivateTest = function(){ return false; };
 17398                  }
 17399                  module.change.state();
 17400                })
 17401              ;
 17402            }
 17403          },
 17404  
 17405          // checks whether active/inactive state can be given
 17406          change: {
 17407  
 17408            state: function() {
 17409              module.debug('Determining state change direction');
 17410              // inactive to active change
 17411              if( module.is.inactive() ) {
 17412                module.activate();
 17413              }
 17414              else {
 17415                module.deactivate();
 17416              }
 17417              if(settings.sync) {
 17418                module.sync();
 17419              }
 17420              settings.onChange.call(element);
 17421            },
 17422  
 17423            text: function() {
 17424              if( module.is.textEnabled() ) {
 17425                if(module.is.disabled() ) {
 17426                  module.verbose('Changing text to disabled text', text.hover);
 17427                  module.update.text(text.disabled);
 17428                }
 17429                else if( module.is.active() ) {
 17430                  if(text.hover) {
 17431                    module.verbose('Changing text to hover text', text.hover);
 17432                    module.update.text(text.hover);
 17433                  }
 17434                  else if(text.deactivate) {
 17435                    module.verbose('Changing text to deactivating text', text.deactivate);
 17436                    module.update.text(text.deactivate);
 17437                  }
 17438                }
 17439                else {
 17440                  if(text.hover) {
 17441                    module.verbose('Changing text to hover text', text.hover);
 17442                    module.update.text(text.hover);
 17443                  }
 17444                  else if(text.activate){
 17445                    module.verbose('Changing text to activating text', text.activate);
 17446                    module.update.text(text.activate);
 17447                  }
 17448                }
 17449              }
 17450            }
 17451  
 17452          },
 17453  
 17454          activate: function() {
 17455            if( settings.activateTest.call(element) ) {
 17456              module.debug('Setting state to active');
 17457              $module
 17458                .addClass(className.active)
 17459              ;
 17460              module.update.text(text.active);
 17461              settings.onActivate.call(element);
 17462            }
 17463          },
 17464  
 17465          deactivate: function() {
 17466            if( settings.deactivateTest.call(element) ) {
 17467              module.debug('Setting state to inactive');
 17468              $module
 17469                .removeClass(className.active)
 17470              ;
 17471              module.update.text(text.inactive);
 17472              settings.onDeactivate.call(element);
 17473            }
 17474          },
 17475  
 17476          sync: function() {
 17477            module.verbose('Syncing other buttons to current state');
 17478            if( module.is.active() ) {
 17479              $allModules
 17480                .not($module)
 17481                  .state('activate');
 17482            }
 17483            else {
 17484              $allModules
 17485                .not($module)
 17486                  .state('deactivate')
 17487              ;
 17488            }
 17489          },
 17490  
 17491          get: {
 17492            text: function() {
 17493              return (settings.selector.text)
 17494                ? $module.find(settings.selector.text).text()
 17495                : $module.html()
 17496              ;
 17497            },
 17498            textFor: function(state) {
 17499              return text[state] || false;
 17500            }
 17501          },
 17502  
 17503          flash: {
 17504            text: function(text, duration, callback) {
 17505              var
 17506                previousText = module.get.text()
 17507              ;
 17508              module.debug('Flashing text message', text, duration);
 17509              text     = text     || settings.text.flash;
 17510              duration = duration || settings.flashDuration;
 17511              callback = callback || function() {};
 17512              module.update.text(text);
 17513              setTimeout(function(){
 17514                module.update.text(previousText);
 17515                callback.call(element);
 17516              }, duration);
 17517            }
 17518          },
 17519  
 17520          reset: {
 17521            // on mouseout sets text to previous value
 17522            text: function() {
 17523              var
 17524                activeText   = text.active   || $module.data(metadata.storedText),
 17525                inactiveText = text.inactive || $module.data(metadata.storedText)
 17526              ;
 17527              if( module.is.textEnabled() ) {
 17528                if( module.is.active() && activeText) {
 17529                  module.verbose('Resetting active text', activeText);
 17530                  module.update.text(activeText);
 17531                }
 17532                else if(inactiveText) {
 17533                  module.verbose('Resetting inactive text', activeText);
 17534                  module.update.text(inactiveText);
 17535                }
 17536              }
 17537            }
 17538          },
 17539  
 17540          update: {
 17541            text: function(text) {
 17542              var
 17543                currentText = module.get.text()
 17544              ;
 17545              if(text && text !== currentText) {
 17546                module.debug('Updating text', text);
 17547                if(settings.selector.text) {
 17548                  $module
 17549                    .data(metadata.storedText, text)
 17550                    .find(settings.selector.text)
 17551                      .text(text)
 17552                  ;
 17553                }
 17554                else {
 17555                  $module
 17556                    .data(metadata.storedText, text)
 17557                    .html(text)
 17558                  ;
 17559                }
 17560              }
 17561              else {
 17562                module.debug('Text is already set, ignoring update', text);
 17563              }
 17564            }
 17565          },
 17566  
 17567          setting: function(name, value) {
 17568            module.debug('Changing setting', name, value);
 17569            if( $.isPlainObject(name) ) {
 17570              $.extend(true, settings, name);
 17571            }
 17572            else if(value !== undefined) {
 17573              settings[name] = value;
 17574            }
 17575            else {
 17576              return settings[name];
 17577            }
 17578          },
 17579          internal: function(name, value) {
 17580            if( $.isPlainObject(name) ) {
 17581              $.extend(true, module, name);
 17582            }
 17583            else if(value !== undefined) {
 17584              module[name] = value;
 17585            }
 17586            else {
 17587              return module[name];
 17588            }
 17589          },
 17590          debug: function() {
 17591            if(settings.debug) {
 17592              if(settings.performance) {
 17593                module.performance.log(arguments);
 17594              }
 17595              else {
 17596                module.debug = Function.prototype.bind.call(console.info, console, settings.name + ':');
 17597                module.debug.apply(console, arguments);
 17598              }
 17599            }
 17600          },
 17601          verbose: function() {
 17602            if(settings.verbose && settings.debug) {
 17603              if(settings.performance) {
 17604                module.performance.log(arguments);
 17605              }
 17606              else {
 17607                module.verbose = Function.prototype.bind.call(console.info, console, settings.name + ':');
 17608                module.verbose.apply(console, arguments);
 17609              }
 17610            }
 17611          },
 17612          error: function() {
 17613            module.error = Function.prototype.bind.call(console.error, console, settings.name + ':');
 17614            module.error.apply(console, arguments);
 17615          },
 17616          performance: {
 17617            log: function(message) {
 17618              var
 17619                currentTime,
 17620                executionTime,
 17621                previousTime
 17622              ;
 17623              if(settings.performance) {
 17624                currentTime   = new Date().getTime();
 17625                previousTime  = time || currentTime;
 17626                executionTime = currentTime - previousTime;
 17627                time          = currentTime;
 17628                performance.push({
 17629                  'Name'           : message[0],
 17630                  'Arguments'      : [].slice.call(message, 1) || '',
 17631                  'Element'        : element,
 17632                  'Execution Time' : executionTime
 17633                });
 17634              }
 17635              clearTimeout(module.performance.timer);
 17636              module.performance.timer = setTimeout(module.performance.display, 100);
 17637            },
 17638            display: function() {
 17639              var
 17640                title = settings.name + ':',
 17641                totalTime = 0
 17642              ;
 17643              time = false;
 17644              clearTimeout(module.performance.timer);
 17645              $.each(performance, function(index, data) {
 17646                totalTime += data['Execution Time'];
 17647              });
 17648              title += ' ' + totalTime + 'ms';
 17649              if(moduleSelector) {
 17650                title += ' \'' + moduleSelector + '\'';
 17651              }
 17652              if( (console.group !== undefined || console.table !== undefined) && performance.length > 0) {
 17653                console.groupCollapsed(title);
 17654                if(console.table) {
 17655                  console.table(performance);
 17656                }
 17657                else {
 17658                  $.each(performance, function(index, data) {
 17659                    console.log(data['Name'] + ': ' + data['Execution Time']+'ms');
 17660                  });
 17661                }
 17662                console.groupEnd();
 17663              }
 17664              performance = [];
 17665            }
 17666          },
 17667          invoke: function(query, passedArguments, context) {
 17668            var
 17669              object = instance,
 17670              maxDepth,
 17671              found,
 17672              response
 17673            ;
 17674            passedArguments = passedArguments || queryArguments;
 17675            context         = element         || context;
 17676            if(typeof query == 'string' && object !== undefined) {
 17677              query    = query.split(/[\. ]/);
 17678              maxDepth = query.length - 1;
 17679              $.each(query, function(depth, value) {
 17680                var camelCaseValue = (depth != maxDepth)
 17681                  ? value + query[depth + 1].charAt(0).toUpperCase() + query[depth + 1].slice(1)
 17682                  : query
 17683                ;
 17684                if( $.isPlainObject( object[camelCaseValue] ) && (depth != maxDepth) ) {
 17685                  object = object[camelCaseValue];
 17686                }
 17687                else if( object[camelCaseValue] !== undefined ) {
 17688                  found = object[camelCaseValue];
 17689                  return false;
 17690                }
 17691                else if( $.isPlainObject( object[value] ) && (depth != maxDepth) ) {
 17692                  object = object[value];
 17693                }
 17694                else if( object[value] !== undefined ) {
 17695                  found = object[value];
 17696                  return false;
 17697                }
 17698                else {
 17699                  module.error(error.method, query);
 17700                  return false;
 17701                }
 17702              });
 17703            }
 17704            if ( $.isFunction( found ) ) {
 17705              response = found.apply(context, passedArguments);
 17706            }
 17707            else if(found !== undefined) {
 17708              response = found;
 17709            }
 17710            if($.isArray(returnedValue)) {
 17711              returnedValue.push(response);
 17712            }
 17713            else if(returnedValue !== undefined) {
 17714              returnedValue = [returnedValue, response];
 17715            }
 17716            else if(response !== undefined) {
 17717              returnedValue = response;
 17718            }
 17719            return found;
 17720          }
 17721        };
 17722  
 17723        if(methodInvoked) {
 17724          if(instance === undefined) {
 17725            module.initialize();
 17726          }
 17727          module.invoke(query);
 17728        }
 17729        else {
 17730          if(instance !== undefined) {
 17731            instance.invoke('destroy');
 17732          }
 17733          module.initialize();
 17734        }
 17735      })
 17736    ;
 17737  
 17738    return (returnedValue !== undefined)
 17739      ? returnedValue
 17740      : this
 17741    ;
 17742  };
 17743  
 17744  $.fn.state.settings = {
 17745  
 17746    // module info
 17747    name           : 'State',
 17748  
 17749    // debug output
 17750    debug          : false,
 17751  
 17752    // verbose debug output
 17753    verbose        : true,
 17754  
 17755    // namespace for events
 17756    namespace      : 'state',
 17757  
 17758    // debug data includes performance
 17759    performance    : true,
 17760  
 17761    // callback occurs on state change
 17762    onActivate     : function() {},
 17763    onDeactivate   : function() {},
 17764    onChange       : function() {},
 17765  
 17766    // state test functions
 17767    activateTest   : function() { return true; },
 17768    deactivateTest : function() { return true; },
 17769  
 17770    // whether to automatically map default states
 17771    automatic      : true,
 17772  
 17773    // activate / deactivate changes all elements instantiated at same time
 17774    sync           : false,
 17775  
 17776    // default flash text duration, used for temporarily changing text of an element
 17777    flashDuration  : 1000,
 17778  
 17779    // selector filter
 17780    filter     : {
 17781      text   : '.loading, .disabled',
 17782      active : '.disabled'
 17783    },
 17784  
 17785    context    : false,
 17786  
 17787    // error
 17788    error: {
 17789      beforeSend : 'The before send function has cancelled state change',
 17790      method     : 'The method you called is not defined.'
 17791    },
 17792  
 17793    // metadata
 17794    metadata: {
 17795      promise    : 'promise',
 17796      storedText : 'stored-text'
 17797    },
 17798  
 17799    // change class on state
 17800    className: {
 17801      active   : 'active',
 17802      disabled : 'disabled',
 17803      error    : 'error',
 17804      loading  : 'loading',
 17805      success  : 'success',
 17806      warning  : 'warning'
 17807    },
 17808  
 17809    selector: {
 17810      // selector for text node
 17811      text: false
 17812    },
 17813  
 17814    defaults : {
 17815      input: {
 17816        disabled : true,
 17817        loading  : true,
 17818        active   : true
 17819      },
 17820      button: {
 17821        disabled : true,
 17822        loading  : true,
 17823        active   : true,
 17824      },
 17825      progress: {
 17826        active   : true,
 17827        success  : true,
 17828        warning  : true,
 17829        error    : true
 17830      }
 17831    },
 17832  
 17833    states     : {
 17834      active   : true,
 17835      disabled : true,
 17836      error    : true,
 17837      loading  : true,
 17838      success  : true,
 17839      warning  : true
 17840    },
 17841  
 17842    text     : {
 17843      disabled   : false,
 17844      flash      : false,
 17845      hover      : false,
 17846      active     : false,
 17847      inactive   : false,
 17848      activate   : false,
 17849      deactivate : false
 17850    }
 17851  
 17852  };
 17853  
 17854  
 17855  
 17856  })( jQuery, window , document );
 17857  
 17858  /*!
 17859   * # Semantic UI x.x - Visibility
 17860   * http://github.com/semantic-org/semantic-ui/
 17861   *
 17862   *
 17863   * Copyright 2014 Contributors
 17864   * Released under the MIT license
 17865   * http://opensource.org/licenses/MIT
 17866   *
 17867   */
 17868  
 17869  ;(function ( $, window, document, undefined ) {
 17870  
 17871  "use strict";
 17872  
 17873  $.fn.visibility = function(parameters) {
 17874    var
 17875      $allModules    = $(this),
 17876      moduleSelector = $allModules.selector || '',
 17877  
 17878      time           = new Date().getTime(),
 17879      performance    = [],
 17880  
 17881      query          = arguments[0],
 17882      methodInvoked  = (typeof query == 'string'),
 17883      queryArguments = [].slice.call(arguments, 1),
 17884      returnedValue
 17885    ;
 17886  
 17887    $allModules
 17888      .each(function() {
 17889        var
 17890          settings        = ( $.isPlainObject(parameters) )
 17891            ? $.extend(true, {}, $.fn.visibility.settings, parameters)
 17892            : $.extend({}, $.fn.visibility.settings),
 17893  
 17894          className       = settings.className,
 17895          namespace       = settings.namespace,
 17896          error           = settings.error,
 17897  
 17898          eventNamespace  = '.' + namespace,
 17899          moduleNamespace = 'module-' + namespace,
 17900  
 17901          $window         = $(window),
 17902          $module         = $(this),
 17903          $context        = $(settings.context),
 17904          $images         = $module.find('img'),
 17905  
 17906          selector        = $module.selector || '',
 17907          instance        = $module.data(moduleNamespace),
 17908  
 17909          requestAnimationFrame = window.requestAnimationFrame
 17910            || window.mozRequestAnimationFrame
 17911            || window.webkitRequestAnimationFrame
 17912            || window.msRequestAnimationFrame
 17913            || function(callback) { setTimeout(callback, 0); },
 17914  
 17915          element         = this,
 17916          observer,
 17917          module
 17918        ;
 17919  
 17920        module = {
 17921  
 17922          initialize: function() {
 17923            module.debug('Initializing', settings);
 17924  
 17925            module.setup.cache();
 17926            module.save.position();
 17927  
 17928            if( module.should.trackChanges() ) {
 17929              module.bind.events();
 17930              if(settings.type == 'image') {
 17931                module.setup.image();
 17932              }
 17933              if(settings.type == 'fixed') {
 17934                module.setup.fixed();
 17935              }
 17936            }
 17937            if(settings.initialCheck) {
 17938              module.checkVisibility();
 17939            }
 17940            if(settings.observeChanges) {
 17941              module.observeChanges();
 17942            }
 17943            module.instantiate();
 17944          },
 17945  
 17946          instantiate: function() {
 17947            module.debug('Storing instance', module);
 17948            $module
 17949              .data(moduleNamespace, module)
 17950            ;
 17951            instance = module;
 17952          },
 17953  
 17954          destroy: function() {
 17955            module.verbose('Destroying previous module');
 17956            $module
 17957              .off(eventNamespace)
 17958              .removeData(moduleNamespace)
 17959            ;
 17960            $window.off('resize' + eventNamespace, module.event.refresh);
 17961            $context.off('scroll' + eventNamespace, module.event.scroll);
 17962          },
 17963  
 17964          observeChanges: function() {
 17965            var
 17966              context = $context[0]
 17967            ;
 17968            if('MutationObserver' in window) {
 17969              observer = new MutationObserver(function(mutations) {
 17970                module.verbose('DOM tree modified, updating visibility calculations');
 17971                module.refresh();
 17972              });
 17973              observer.observe(element, {
 17974                childList : true,
 17975                subtree   : true
 17976              });
 17977              module.debug('Setting up mutation observer', observer);
 17978            }
 17979          },
 17980  
 17981          bind: {
 17982            events: function() {
 17983              module.verbose('Binding visibility events to scroll and resize');
 17984              $window
 17985                .on('resize' + eventNamespace, module.event.refresh)
 17986              ;
 17987              $context
 17988                .on('scroll' + eventNamespace, module.event.scroll)
 17989              ;
 17990              if($images.length > 0) {
 17991                module.bind.imageLoad();
 17992              }
 17993            },
 17994            imageLoad: function() {
 17995              var
 17996                imageCount    = $images.length,
 17997                index         = imageCount,
 17998                loadedCount   = 0,
 17999                images        = [],
 18000                cache         = [],
 18001                cacheImage    = document.createElement('img'),
 18002                handleLoad    = function() {
 18003                  loadedCount++;
 18004                  if(loadedCount >= imageCount) {
 18005                    module.debug('Images finished loading inside element, refreshing position');
 18006                    module.refresh();
 18007                  }
 18008                }
 18009              ;
 18010              $images
 18011                .each(function() {
 18012                  images.push( $(this).attr('src') );
 18013                })
 18014              ;
 18015              while(index--) {
 18016                cacheImage         = document.createElement('img');
 18017                cacheImage.onload  = handleLoad;
 18018                cacheImage.onerror = handleLoad;
 18019                cacheImage.src     = images[index];
 18020                cache.push(cacheImage);
 18021              }
 18022            }
 18023          },
 18024  
 18025          event: {
 18026            refresh: function() {
 18027              requestAnimationFrame(module.refresh);
 18028            },
 18029            scroll: function() {
 18030              module.verbose('Scroll position changed');
 18031              if(settings.throttle) {
 18032                clearTimeout(module.timer);
 18033                module.timer = setTimeout(function() {
 18034                  module.checkVisibility();
 18035                }, settings.throttle);
 18036              }
 18037              else {
 18038                requestAnimationFrame(function() {
 18039                  module.checkVisibility();
 18040                });
 18041              }
 18042            }
 18043          },
 18044  
 18045          should: {
 18046            trackChanges: function() {
 18047              if(methodInvoked && queryArguments.length > 0) {
 18048                module.debug('One time query, no need to bind events');
 18049                return false;
 18050              }
 18051              module.debug('Callbacks being attached');
 18052              return true;
 18053            }
 18054          },
 18055  
 18056          setup: {
 18057            cache: function() {
 18058              module.cache = {
 18059                occurred : {},
 18060                screen   : {},
 18061                element  : {},
 18062              };
 18063            },
 18064            image: function() {
 18065              var
 18066                src = $module.data('src')
 18067              ;
 18068              if(src) {
 18069                module.verbose('Lazy loading image', src);
 18070                settings.observeChanges = false;
 18071                // show when top visible
 18072                module.topVisible(function() {
 18073                  module.debug('Image top visible', element);
 18074                  module.precache(src, function() {
 18075                    module.set.image(src);
 18076                    settings.onTopVisible = false;
 18077                  });
 18078                });
 18079              }
 18080            },
 18081            fixed: function() {
 18082              module.verbose('Setting up fixed on element pass');
 18083              settings.once = false;
 18084              settings.onTopPassed = function() {
 18085                $module
 18086                  .addClass(className.fixed)
 18087                  .css({
 18088                    top: settings.offset + 'px'
 18089                  })
 18090                ;
 18091                if(settings.transition) {
 18092                  if($.fn.transition !== undefined) {
 18093                    $module.transition(settings.transition, settings.duration);
 18094                  }
 18095                }
 18096              };
 18097              settings.onTopPassedReverse = function() {
 18098                $module
 18099                  .removeClass(className.fixed)
 18100                  .css({
 18101                    position: '',
 18102                    top: ''
 18103                  })
 18104                ;
 18105              };
 18106            }
 18107          },
 18108  
 18109          set: {
 18110            image: function(src) {
 18111              var
 18112                offScreen = (module.cache.screen.bottom < module.cache.element.top)
 18113              ;
 18114              $module
 18115                .attr('src', src)
 18116              ;
 18117              if(offScreen) {
 18118                module.verbose('Image outside browser, no show animation');
 18119                $module.show();
 18120              }
 18121              else {
 18122                if(settings.transition) {
 18123                  if( $.fn.transition !== undefined ) {
 18124                    $module.transition(settings.transition, settings.duration);
 18125                  }
 18126                  else {
 18127                    $module.fadeIn(settings.duration);
 18128                  }
 18129                }
 18130                else {
 18131                  $module.show();
 18132                }
 18133              }
 18134            }
 18135          },
 18136  
 18137          is: {
 18138            visible: function() {
 18139              if(module.cache && module.cache.element) {
 18140                return (module.cache.element.width > 0);
 18141              }
 18142              return false;
 18143            }
 18144          },
 18145  
 18146          refresh: function() {
 18147            module.debug('Refreshing constants (element width/height)');
 18148            module.reset();
 18149            module.save.position();
 18150            module.checkVisibility();
 18151            settings.onRefresh.call(element);
 18152          },
 18153  
 18154          reset: function() {
 18155            module.verbose('Reseting all cached values');
 18156            if( $.isPlainObject(module.cache) ) {
 18157              module.cache.screen = {};
 18158              module.cache.element = {};
 18159            }
 18160          },
 18161  
 18162          checkVisibility: function() {
 18163            module.verbose('Checking visibility of element', module.cache.element);
 18164  
 18165            if( module.is.visible() ) {
 18166  
 18167              // update calculations derived from scroll
 18168              module.save.calculations();
 18169  
 18170              // percentage
 18171              module.passed();
 18172  
 18173              // reverse (must be first)
 18174              module.passingReverse();
 18175              module.topVisibleReverse();
 18176              module.bottomVisibleReverse();
 18177              module.topPassedReverse();
 18178              module.bottomPassedReverse();
 18179  
 18180              // one time
 18181              module.passing();
 18182              module.topVisible();
 18183              module.bottomVisible();
 18184              module.topPassed();
 18185              module.bottomPassed();
 18186  
 18187              // on update callback
 18188              if(settings.onUpdate) {
 18189                settings.onUpdate.call(element, module.get.elementCalculations());
 18190              }
 18191            }
 18192          },
 18193  
 18194          passed: function(amount, newCallback) {
 18195            var
 18196              calculations   = module.get.elementCalculations(),
 18197              amountInPixels
 18198            ;
 18199            // assign callback
 18200            if(amount !== undefined && newCallback !== undefined) {
 18201              settings.onPassed[amount] = newCallback;
 18202            }
 18203            else if(amount !== undefined) {
 18204              return (module.get.pixelsPassed(amount) > calculations.pixelsPassed);
 18205            }
 18206            else if(calculations.passing) {
 18207              $.each(settings.onPassed, function(amount, callback) {
 18208                if(calculations.bottomVisible || calculations.pixelsPassed > module.get.pixelsPassed(amount)) {
 18209                  module.execute(callback, amount);
 18210                }
 18211                else if(!settings.once) {
 18212                  module.remove.occurred(callback);
 18213                }
 18214              });
 18215            }
 18216          },
 18217  
 18218          passing: function(newCallback) {
 18219            var
 18220              calculations = module.get.elementCalculations(),
 18221              callback     = newCallback || settings.onPassing,
 18222              callbackName = 'passing'
 18223            ;
 18224            if(newCallback) {
 18225              module.debug('Adding callback for passing', newCallback);
 18226              settings.onPassing = newCallback;
 18227            }
 18228            if(calculations.passing) {
 18229              module.execute(callback, callbackName);
 18230            }
 18231            else if(!settings.once) {
 18232              module.remove.occurred(callbackName);
 18233            }
 18234            if(newCallback !== undefined) {
 18235              return calculations.passing;
 18236            }
 18237          },
 18238  
 18239  
 18240          topVisible: function(newCallback) {
 18241            var
 18242              calculations = module.get.elementCalculations(),
 18243              callback     = newCallback || settings.onTopVisible,
 18244              callbackName = 'topVisible'
 18245            ;
 18246            if(newCallback) {
 18247              module.debug('Adding callback for top visible', newCallback);
 18248              settings.onTopVisible = newCallback;
 18249            }
 18250            if(calculations.topVisible) {
 18251              module.execute(callback, callbackName);
 18252            }
 18253            else if(!settings.once) {
 18254              module.remove.occurred(callbackName);
 18255            }
 18256            if(newCallback === undefined) {
 18257              return calculations.topVisible;
 18258            }
 18259          },
 18260  
 18261          bottomVisible: function(newCallback) {
 18262            var
 18263              calculations = module.get.elementCalculations(),
 18264              callback     = newCallback || settings.onBottomVisible,
 18265              callbackName = 'bottomVisible'
 18266            ;
 18267            if(newCallback) {
 18268              module.debug('Adding callback for bottom visible', newCallback);
 18269              settings.onBottomVisible = newCallback;
 18270            }
 18271            if(calculations.bottomVisible) {
 18272              module.execute(callback, callbackName);
 18273            }
 18274            else if(!settings.once) {
 18275              module.remove.occurred(callbackName);
 18276            }
 18277            if(newCallback === undefined) {
 18278              return calculations.bottomVisible;
 18279            }
 18280          },
 18281  
 18282          topPassed: function(newCallback) {
 18283            var
 18284              calculations = module.get.elementCalculations(),
 18285              callback     = newCallback || settings.onTopPassed,
 18286              callbackName = 'topPassed'
 18287            ;
 18288            if(newCallback) {
 18289              module.debug('Adding callback for top passed', newCallback);
 18290              settings.onTopPassed = newCallback;
 18291            }
 18292            if(calculations.topPassed) {
 18293              module.execute(callback, callbackName);
 18294            }
 18295            else if(!settings.once) {
 18296              module.remove.occurred(callbackName);
 18297            }
 18298            if(newCallback === undefined) {
 18299              return calculations.topPassed;
 18300            }
 18301          },
 18302  
 18303          bottomPassed: function(newCallback) {
 18304            var
 18305              calculations = module.get.elementCalculations(),
 18306              callback     = newCallback || settings.onBottomPassed,
 18307              callbackName = 'bottomPassed'
 18308            ;
 18309            if(newCallback) {
 18310              module.debug('Adding callback for bottom passed', newCallback);
 18311              settings.onBottomPassed = newCallback;
 18312            }
 18313            if(calculations.bottomPassed) {
 18314              module.execute(callback, callbackName);
 18315            }
 18316            else if(!settings.once) {
 18317              module.remove.occurred(callbackName);
 18318            }
 18319            if(newCallback === undefined) {
 18320              return calculations.bottomPassed;
 18321            }
 18322          },
 18323  
 18324          passingReverse: function(newCallback) {
 18325            var
 18326              calculations = module.get.elementCalculations(),
 18327              callback     = newCallback || settings.onPassingReverse,
 18328              callbackName = 'passingReverse'
 18329            ;
 18330            if(newCallback) {
 18331              module.debug('Adding callback for passing reverse', newCallback);
 18332              settings.onPassingReverse = newCallback;
 18333            }
 18334            if(!calculations.passing) {
 18335              if(module.get.occurred('passing')) {
 18336                module.execute(callback, callbackName);
 18337              }
 18338            }
 18339            else if(!settings.once) {
 18340              module.remove.occurred(callbackName);
 18341            }
 18342            if(newCallback !== undefined) {
 18343              return !calculations.passing;
 18344            }
 18345          },
 18346  
 18347  
 18348          topVisibleReverse: function(newCallback) {
 18349            var
 18350              calculations = module.get.elementCalculations(),
 18351              callback     = newCallback || settings.onTopVisibleReverse,
 18352              callbackName = 'topVisibleReverse'
 18353            ;
 18354            if(newCallback) {
 18355              module.debug('Adding callback for top visible reverse', newCallback);
 18356              settings.onTopVisibleReverse = newCallback;
 18357            }
 18358            if(!calculations.topVisible) {
 18359              if(module.get.occurred('topVisible')) {
 18360                module.execute(callback, callbackName);
 18361              }
 18362            }
 18363            else if(!settings.once) {
 18364              module.remove.occurred(callbackName);
 18365            }
 18366            if(newCallback === undefined) {
 18367              return !calculations.topVisible;
 18368            }
 18369          },
 18370  
 18371          bottomVisibleReverse: function(newCallback) {
 18372            var
 18373              calculations = module.get.elementCalculations(),
 18374              callback     = newCallback || settings.onBottomVisibleReverse,
 18375              callbackName = 'bottomVisibleReverse'
 18376            ;
 18377            if(newCallback) {
 18378              module.debug('Adding callback for bottom visible reverse', newCallback);
 18379              settings.onBottomVisibleReverse = newCallback;
 18380            }
 18381            if(!calculations.bottomVisible) {
 18382              if(module.get.occurred('bottomVisible')) {
 18383                module.execute(callback, callbackName);
 18384              }
 18385            }
 18386            else if(!settings.once) {
 18387              module.remove.occurred(callbackName);
 18388            }
 18389            if(newCallback === undefined) {
 18390              return !calculations.bottomVisible;
 18391            }
 18392          },
 18393  
 18394          topPassedReverse: function(newCallback) {
 18395            var
 18396              calculations = module.get.elementCalculations(),
 18397              callback     = newCallback || settings.onTopPassedReverse,
 18398              callbackName = 'topPassedReverse'
 18399            ;
 18400            if(newCallback) {
 18401              module.debug('Adding callback for top passed reverse', newCallback);
 18402              settings.onTopPassedReverse = newCallback;
 18403            }
 18404            if(!calculations.topPassed) {
 18405              if(module.get.occurred('topPassed')) {
 18406                module.execute(callback, callbackName);
 18407              }
 18408            }
 18409            else if(!settings.once) {
 18410              module.remove.occurred(callbackName);
 18411            }
 18412            if(newCallback === undefined) {
 18413              return !calculations.onTopPassed;
 18414            }
 18415          },
 18416  
 18417          bottomPassedReverse: function(newCallback) {
 18418            var
 18419              calculations = module.get.elementCalculations(),
 18420              callback     = newCallback || settings.onBottomPassedReverse,
 18421              callbackName = 'bottomPassedReverse'
 18422            ;
 18423            if(newCallback) {
 18424              module.debug('Adding callback for bottom passed reverse', newCallback);
 18425              settings.onBottomPassedReverse = newCallback;
 18426            }
 18427            if(!calculations.bottomPassed) {
 18428              if(module.get.occurred('bottomPassed')) {
 18429                module.execute(callback, callbackName);
 18430              }
 18431            }
 18432            else if(!settings.once) {
 18433              module.remove.occurred(callbackName);
 18434            }
 18435            if(newCallback === undefined) {
 18436              return !calculations.bottomPassed;
 18437            }
 18438          },
 18439  
 18440          execute: function(callback, callbackName) {
 18441            var
 18442              calculations = module.get.elementCalculations(),
 18443              screen       = module.get.screenCalculations()
 18444            ;
 18445            callback = callback || false;
 18446            if(callback) {
 18447              if(settings.continuous) {
 18448                module.debug('Callback being called continuously', callbackName, calculations);
 18449                callback.call(element, calculations, screen);
 18450              }
 18451              else if(!module.get.occurred(callbackName)) {
 18452                module.debug('Conditions met', callbackName, calculations);
 18453                callback.call(element, calculations, screen);
 18454              }
 18455            }
 18456            module.save.occurred(callbackName);
 18457          },
 18458  
 18459          remove: {
 18460            occurred: function(callback) {
 18461              if(callback) {
 18462                if(module.cache.occurred[callback] !== undefined && module.cache.occurred[callback] === true) {
 18463                  module.debug('Callback can now be called again', callback);
 18464                  module.cache.occurred[callback] = false;
 18465                }
 18466              }
 18467              else {
 18468                module.cache.occurred = {};
 18469              }
 18470            }
 18471          },
 18472  
 18473          save: {
 18474            calculations: function() {
 18475              module.verbose('Saving all calculations necessary to determine positioning');
 18476              module.save.scroll();
 18477              module.save.direction();
 18478              module.save.screenCalculations();
 18479              module.save.elementCalculations();
 18480            },
 18481            occurred: function(callback) {
 18482              if(callback) {
 18483                if(module.cache.occurred[callback] === undefined || (module.cache.occurred[callback] !== true)) {
 18484                  module.verbose('Saving callback occurred', callback);
 18485                  module.cache.occurred[callback] = true;
 18486                }
 18487              }
 18488            },
 18489            scroll: function() {
 18490              module.cache.scroll = $context.scrollTop() + settings.offset;
 18491            },
 18492            direction: function() {
 18493              var
 18494                scroll     = module.get.scroll(),
 18495                lastScroll = module.get.lastScroll(),
 18496                direction
 18497              ;
 18498              if(scroll > lastScroll && lastScroll) {
 18499                direction = 'down';
 18500              }
 18501              else if(scroll < lastScroll && lastScroll) {
 18502                direction = 'up';
 18503              }
 18504              else {
 18505                direction = 'static';
 18506              }
 18507              module.cache.direction = direction;
 18508              return module.cache.direction;
 18509            },
 18510            elementPosition: function() {
 18511              var
 18512                element = module.cache.element,
 18513                screen  = module.get.screenSize()
 18514              ;
 18515              module.verbose('Saving element position');
 18516              // (quicker than $.extend)
 18517              element.fits          = (element.height < screen.height);
 18518              element.offset        = $module.offset();
 18519              element.width         = $module.outerWidth();
 18520              element.height        = $module.outerHeight();
 18521              // store
 18522              module.cache.element = element;
 18523              return element;
 18524            },
 18525            elementCalculations: function() {
 18526              var
 18527                screen     = module.get.screenCalculations(),
 18528                element    = module.get.elementPosition()
 18529              ;
 18530              // offset
 18531              if(settings.includeMargin) {
 18532                element.margin        = {};
 18533                element.margin.top    = parseInt($module.css('margin-top'), 10);
 18534                element.margin.bottom = parseInt($module.css('margin-bottom'), 10);
 18535                element.top    = element.offset.top - element.margin.top;
 18536                element.bottom = element.offset.top + element.height + element.margin.bottom;
 18537              }
 18538              else {
 18539                element.top    = element.offset.top;
 18540                element.bottom = element.offset.top + element.height;
 18541              }
 18542  
 18543              // visibility
 18544              element.topVisible       = (screen.bottom >= element.top);
 18545              element.topPassed        = (screen.top >= element.top);
 18546              element.bottomVisible    = (screen.bottom >= element.bottom);
 18547              element.bottomPassed     = (screen.top >= element.bottom);
 18548              element.pixelsPassed     = 0;
 18549              element.percentagePassed = 0;
 18550  
 18551              // meta calculations
 18552              element.visible = (element.topVisible || element.bottomVisible);
 18553              element.passing = (element.topPassed && !element.bottomPassed);
 18554              element.hidden  = (!element.topVisible && !element.bottomVisible);
 18555  
 18556              // passing calculations
 18557              if(element.passing) {
 18558                element.pixelsPassed     = (screen.top - element.top);
 18559                element.percentagePassed = (screen.top - element.top) / element.height;
 18560              }
 18561              module.cache.element = element;
 18562              module.verbose('Updated element calculations', element);
 18563              return element;
 18564            },
 18565            screenCalculations: function() {
 18566              var
 18567                scroll = module.get.scroll()
 18568              ;
 18569              module.save.direction();
 18570              module.cache.screen.top    = scroll;
 18571              module.cache.screen.bottom = scroll + module.cache.screen.height;
 18572              return module.cache.screen;
 18573            },
 18574            screenSize: function() {
 18575              module.verbose('Saving window position');
 18576              module.cache.screen = {
 18577                height: $context.height()
 18578              };
 18579            },
 18580            position: function() {
 18581              module.save.screenSize();
 18582              module.save.elementPosition();
 18583            }
 18584          },
 18585  
 18586          get: {
 18587            pixelsPassed: function(amount) {
 18588              var
 18589                element = module.get.elementCalculations()
 18590              ;
 18591              if(amount.search('%') > -1) {
 18592                return ( element.height * (parseInt(amount, 10) / 100) );
 18593              }
 18594              return parseInt(amount, 10);
 18595            },
 18596            occurred: function(callback) {
 18597              return (module.cache.occurred !== undefined)
 18598                ? module.cache.occurred[callback] || false
 18599                : false
 18600              ;
 18601            },
 18602            direction: function() {
 18603              if(module.cache.direction === undefined) {
 18604                module.save.direction();
 18605              }
 18606              return module.cache.direction;
 18607            },
 18608            elementPosition: function() {
 18609              if(module.cache.element === undefined) {
 18610                module.save.elementPosition();
 18611              }
 18612              return module.cache.element;
 18613            },
 18614            elementCalculations: function() {
 18615              if(module.cache.element === undefined) {
 18616                module.save.elementCalculations();
 18617              }
 18618              return module.cache.element;
 18619            },
 18620            screenCalculations: function() {
 18621              if(module.cache.screen === undefined) {
 18622                module.save.screenCalculations();
 18623              }
 18624              return module.cache.screen;
 18625            },
 18626            screenSize: function() {
 18627              if(module.cache.screen === undefined) {
 18628                module.save.screenSize();
 18629              }
 18630              return module.cache.screen;
 18631            },
 18632            scroll: function() {
 18633              if(module.cache.scroll === undefined) {
 18634                module.save.scroll();
 18635              }
 18636              return module.cache.scroll;
 18637            },
 18638            lastScroll: function() {
 18639              if(module.cache.screen === undefined) {
 18640                module.debug('First scroll event, no last scroll could be found');
 18641                return false;
 18642              }
 18643              return module.cache.screen.top;
 18644            }
 18645          },
 18646  
 18647          setting: function(name, value) {
 18648            if( $.isPlainObject(name) ) {
 18649              $.extend(true, settings, name);
 18650            }
 18651            else if(value !== undefined) {
 18652              settings[name] = value;
 18653            }
 18654            else {
 18655              return settings[name];
 18656            }
 18657          },
 18658          internal: function(name, value) {
 18659            if( $.isPlainObject(name) ) {
 18660              $.extend(true, module, name);
 18661            }
 18662            else if(value !== undefined) {
 18663              module[name] = value;
 18664            }
 18665            else {
 18666              return module[name];
 18667            }
 18668          },
 18669          debug: function() {
 18670            if(settings.debug) {
 18671              if(settings.performance) {
 18672                module.performance.log(arguments);
 18673              }
 18674              else {
 18675                module.debug = Function.prototype.bind.call(console.info, console, settings.name + ':');
 18676                module.debug.apply(console, arguments);
 18677              }
 18678            }
 18679          },
 18680          verbose: function() {
 18681            if(settings.verbose && settings.debug) {
 18682              if(settings.performance) {
 18683                module.performance.log(arguments);
 18684              }
 18685              else {
 18686                module.verbose = Function.prototype.bind.call(console.info, console, settings.name + ':');
 18687                module.verbose.apply(console, arguments);
 18688              }
 18689            }
 18690          },
 18691          error: function() {
 18692            module.error = Function.prototype.bind.call(console.error, console, settings.name + ':');
 18693            module.error.apply(console, arguments);
 18694          },
 18695          performance: {
 18696            log: function(message) {
 18697              var
 18698                currentTime,
 18699                executionTime,
 18700                previousTime
 18701              ;
 18702              if(settings.performance) {
 18703                currentTime   = new Date().getTime();
 18704                previousTime  = time || currentTime;
 18705                executionTime = currentTime - previousTime;
 18706                time          = currentTime;
 18707                performance.push({
 18708                  'Name'           : message[0],
 18709                  'Arguments'      : [].slice.call(message, 1) || '',
 18710                  'Element'        : element,
 18711                  'Execution Time' : executionTime
 18712                });
 18713              }
 18714              clearTimeout(module.performance.timer);
 18715              module.performance.timer = setTimeout(module.performance.display, 100);
 18716            },
 18717            display: function() {
 18718              var
 18719                title = settings.name + ':',
 18720                totalTime = 0
 18721              ;
 18722              time = false;
 18723              clearTimeout(module.performance.timer);
 18724              $.each(performance, function(index, data) {
 18725                totalTime += data['Execution Time'];
 18726              });
 18727              title += ' ' + totalTime + 'ms';
 18728              if(moduleSelector) {
 18729                title += ' \'' + moduleSelector + '\'';
 18730              }
 18731              if( (console.group !== undefined || console.table !== undefined) && performance.length > 0) {
 18732                console.groupCollapsed(title);
 18733                if(console.table) {
 18734                  console.table(performance);
 18735                }
 18736                else {
 18737                  $.each(performance, function(index, data) {
 18738                    console.log(data['Name'] + ': ' + data['Execution Time']+'ms');
 18739                  });
 18740                }
 18741                console.groupEnd();
 18742              }
 18743              performance = [];
 18744            }
 18745          },
 18746          invoke: function(query, passedArguments, context) {
 18747            var
 18748              object = instance,
 18749              maxDepth,
 18750              found,
 18751              response
 18752            ;
 18753            passedArguments = passedArguments || queryArguments;
 18754            context         = element         || context;
 18755            if(typeof query == 'string' && object !== undefined) {
 18756              query    = query.split(/[\. ]/);
 18757              maxDepth = query.length - 1;
 18758              $.each(query, function(depth, value) {
 18759                var camelCaseValue = (depth != maxDepth)
 18760                  ? value + query[depth + 1].charAt(0).toUpperCase() + query[depth + 1].slice(1)
 18761                  : query
 18762                ;
 18763                if( $.isPlainObject( object[camelCaseValue] ) && (depth != maxDepth) ) {
 18764                  object = object[camelCaseValue];
 18765                }
 18766                else if( object[camelCaseValue] !== undefined ) {
 18767                  found = object[camelCaseValue];
 18768                  return false;
 18769                }
 18770                else if( $.isPlainObject( object[value] ) && (depth != maxDepth) ) {
 18771                  object = object[value];
 18772                }
 18773                else if( object[value] !== undefined ) {
 18774                  found = object[value];
 18775                  return false;
 18776                }
 18777                else {
 18778                  module.error(error.method, query);
 18779                  return false;
 18780                }
 18781              });
 18782            }
 18783            if ( $.isFunction( found ) ) {
 18784              response = found.apply(context, passedArguments);
 18785            }
 18786            else if(found !== undefined) {
 18787              response = found;
 18788            }
 18789            if($.isArray(returnedValue)) {
 18790              returnedValue.push(response);
 18791            }
 18792            else if(returnedValue !== undefined) {
 18793              returnedValue = [returnedValue, response];
 18794            }
 18795            else if(response !== undefined) {
 18796              returnedValue = response;
 18797            }
 18798            return found;
 18799          }
 18800        };
 18801  
 18802        if(methodInvoked) {
 18803          if(instance === undefined) {
 18804            module.initialize();
 18805          }
 18806          module.invoke(query);
 18807        }
 18808        else {
 18809          if(instance !== undefined) {
 18810            instance.invoke('destroy');
 18811          }
 18812          module.initialize();
 18813        }
 18814      })
 18815    ;
 18816  
 18817    return (returnedValue !== undefined)
 18818      ? returnedValue
 18819      : this
 18820    ;
 18821  };
 18822  
 18823  $.fn.visibility.settings = {
 18824  
 18825    name                   : 'Visibility',
 18826    namespace              : 'visibility',
 18827  
 18828    debug                  : false,
 18829    verbose                : false,
 18830    performance            : true,
 18831  
 18832    // whether to use mutation observers to follow changes
 18833    observeChanges         : true,
 18834  
 18835    // callback should only occur one time
 18836    once                   : true,
 18837  
 18838    // callback should fire continuously whe evaluates to true
 18839    continuous             : false,
 18840  
 18841    // offset to use with scroll top
 18842    offset                 : 0,
 18843  
 18844    // whether to include margin in elements position
 18845    includeMargin          : false,
 18846  
 18847    // scroll context for visibility checks
 18848    context                : window,
 18849  
 18850    // check position immediately on init
 18851    initialCheck           : true,
 18852  
 18853    // visibility check delay in ms (defaults to animationFrame)
 18854    throttle               : false,
 18855  
 18856    // special visibility type (image, fixed)
 18857    type                   : false,
 18858  
 18859    // image only animation settings
 18860    transition             : false,
 18861    duration               : 1000,
 18862  
 18863    // array of callbacks for percentage
 18864    onPassed               : {},
 18865  
 18866    // standard callbacks
 18867    onPassing              : false,
 18868    onTopVisible           : false,
 18869    onBottomVisible        : false,
 18870    onTopPassed            : false,
 18871    onBottomPassed         : false,
 18872  
 18873    // reverse callbacks
 18874    onPassingReverse       : false,
 18875    onTopVisibleReverse    : false,
 18876    onBottomVisibleReverse : false,
 18877    onTopPassedReverse     : false,
 18878    onBottomPassedReverse  : false,
 18879  
 18880    // utility callbacks
 18881    onUpdate               : false, // disabled by default for performance
 18882    onRefresh              : function(){},
 18883  
 18884    className: {
 18885      fixed: 'fixed'
 18886    },
 18887  
 18888    error : {
 18889      method : 'The method you called is not defined.'
 18890    }
 18891  
 18892  };
 18893  
 18894  })( jQuery, window , document );