| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167 | 
							- /*!
 
-  * # Semantic UI 2.3.3 - API
 
-  * http://github.com/semantic-org/semantic-ui/
 
-  *
 
-  *
 
-  * Released under the MIT license
 
-  * http://opensource.org/licenses/MIT
 
-  *
 
-  */
 
- ;(function ($, window, document, undefined) {
 
- 'use strict';
 
- var
 
-   window = (typeof window != 'undefined' && window.Math == Math)
 
-     ? window
 
-     : (typeof self != 'undefined' && self.Math == Math)
 
-       ? self
 
-       : Function('return this')()
 
- ;
 
- $.api = $.fn.api = function(parameters) {
 
-   var
 
-     // use window context if none specified
 
-     $allModules     = $.isFunction(this)
 
-         ? $(window)
 
-         : $(this),
 
-     moduleSelector = $allModules.selector || '',
 
-     time           = new Date().getTime(),
 
-     performance    = [],
 
-     query          = arguments[0],
 
-     methodInvoked  = (typeof query == 'string'),
 
-     queryArguments = [].slice.call(arguments, 1),
 
-     returnedValue
 
-   ;
 
-   $allModules
 
-     .each(function() {
 
-       var
 
-         settings          = ( $.isPlainObject(parameters) )
 
-           ? $.extend(true, {}, $.fn.api.settings, parameters)
 
-           : $.extend({}, $.fn.api.settings),
 
-         // internal aliases
 
-         namespace       = settings.namespace,
 
-         metadata        = settings.metadata,
 
-         selector        = settings.selector,
 
-         error           = settings.error,
 
-         className       = settings.className,
 
-         // define namespaces for modules
 
-         eventNamespace  = '.' + namespace,
 
-         moduleNamespace = 'module-' + namespace,
 
-         // element that creates request
 
-         $module         = $(this),
 
-         $form           = $module.closest(selector.form),
 
-         // context used for state
 
-         $context        = (settings.stateContext)
 
-           ? $(settings.stateContext)
 
-           : $module,
 
-         // request details
 
-         ajaxSettings,
 
-         requestSettings,
 
-         url,
 
-         data,
 
-         requestStartTime,
 
-         // standard module
 
-         element         = this,
 
-         context         = $context[0],
 
-         instance        = $module.data(moduleNamespace),
 
-         module
 
-       ;
 
-       module = {
 
-         initialize: function() {
 
-           if(!methodInvoked) {
 
-             module.bind.events();
 
-           }
 
-           module.instantiate();
 
-         },
 
-         instantiate: function() {
 
-           module.verbose('Storing instance of module', module);
 
-           instance = module;
 
-           $module
 
-             .data(moduleNamespace, instance)
 
-           ;
 
-         },
 
-         destroy: function() {
 
-           module.verbose('Destroying previous module for', element);
 
-           $module
 
-             .removeData(moduleNamespace)
 
-             .off(eventNamespace)
 
-           ;
 
-         },
 
-         bind: {
 
-           events: function() {
 
-             var
 
-               triggerEvent = module.get.event()
 
-             ;
 
-             if( triggerEvent ) {
 
-               module.verbose('Attaching API events to element', triggerEvent);
 
-               $module
 
-                 .on(triggerEvent + eventNamespace, module.event.trigger)
 
-               ;
 
-             }
 
-             else if(settings.on == 'now') {
 
-               module.debug('Querying API endpoint immediately');
 
-               module.query();
 
-             }
 
-           }
 
-         },
 
-         decode: {
 
-           json: function(response) {
 
-             if(response !== undefined && typeof response == 'string') {
 
-               try {
 
-                response = JSON.parse(response);
 
-               }
 
-               catch(e) {
 
-                 // isnt json string
 
-               }
 
-             }
 
-             return response;
 
-           }
 
-         },
 
-         read: {
 
-           cachedResponse: function(url) {
 
-             var
 
-               response
 
-             ;
 
-             if(window.Storage === undefined) {
 
-               module.error(error.noStorage);
 
-               return;
 
-             }
 
-             response = sessionStorage.getItem(url);
 
-             module.debug('Using cached response', url, response);
 
-             response = module.decode.json(response);
 
-             return response;
 
-           }
 
-         },
 
-         write: {
 
-           cachedResponse: function(url, response) {
 
-             if(response && response === '') {
 
-               module.debug('Response empty, not caching', response);
 
-               return;
 
-             }
 
-             if(window.Storage === undefined) {
 
-               module.error(error.noStorage);
 
-               return;
 
-             }
 
-             if( $.isPlainObject(response) ) {
 
-               response = JSON.stringify(response);
 
-             }
 
-             sessionStorage.setItem(url, response);
 
-             module.verbose('Storing cached response for url', url, response);
 
-           }
 
-         },
 
-         query: function() {
 
-           if(module.is.disabled()) {
 
-             module.debug('Element is disabled API request aborted');
 
-             return;
 
-           }
 
-           if(module.is.loading()) {
 
-             if(settings.interruptRequests) {
 
-               module.debug('Interrupting previous request');
 
-               module.abort();
 
-             }
 
-             else {
 
-               module.debug('Cancelling request, previous request is still pending');
 
-               return;
 
-             }
 
-           }
 
-           // pass element metadata to url (value, text)
 
-           if(settings.defaultData) {
 
-             $.extend(true, settings.urlData, module.get.defaultData());
 
-           }
 
-           // Add form content
 
-           if(settings.serializeForm) {
 
-             settings.data = module.add.formData(settings.data);
 
-           }
 
-           // call beforesend and get any settings changes
 
-           requestSettings = module.get.settings();
 
-           // check if before send cancelled request
 
-           if(requestSettings === false) {
 
-             module.cancelled = true;
 
-             module.error(error.beforeSend);
 
-             return;
 
-           }
 
-           else {
 
-             module.cancelled = false;
 
-           }
 
-           // get url
 
-           url = module.get.templatedURL();
 
-           if(!url && !module.is.mocked()) {
 
-             module.error(error.missingURL);
 
-             return;
 
-           }
 
-           // replace variables
 
-           url = module.add.urlData( url );
 
-           // missing url parameters
 
-           if( !url && !module.is.mocked()) {
 
-             return;
 
-           }
 
-           requestSettings.url = settings.base + url;
 
-           // look for jQuery ajax parameters in settings
 
-           ajaxSettings = $.extend(true, {}, settings, {
 
-             type       : settings.method || settings.type,
 
-             data       : data,
 
-             url        : settings.base + url,
 
-             beforeSend : settings.beforeXHR,
 
-             success    : function() {},
 
-             failure    : function() {},
 
-             complete   : function() {}
 
-           });
 
-           module.debug('Querying URL', ajaxSettings.url);
 
-           module.verbose('Using AJAX settings', ajaxSettings);
 
-           if(settings.cache === 'local' && module.read.cachedResponse(url)) {
 
-             module.debug('Response returned from local cache');
 
-             module.request = module.create.request();
 
-             module.request.resolveWith(context, [ module.read.cachedResponse(url) ]);
 
-             return;
 
-           }
 
-           if( !settings.throttle ) {
 
-             module.debug('Sending request', data, ajaxSettings.method);
 
-             module.send.request();
 
-           }
 
-           else {
 
-             if(!settings.throttleFirstRequest && !module.timer) {
 
-               module.debug('Sending request', data, ajaxSettings.method);
 
-               module.send.request();
 
-               module.timer = setTimeout(function(){}, settings.throttle);
 
-             }
 
-             else {
 
-               module.debug('Throttling request', settings.throttle);
 
-               clearTimeout(module.timer);
 
-               module.timer = setTimeout(function() {
 
-                 if(module.timer) {
 
-                   delete module.timer;
 
-                 }
 
-                 module.debug('Sending throttled request', data, ajaxSettings.method);
 
-                 module.send.request();
 
-               }, settings.throttle);
 
-             }
 
-           }
 
-         },
 
-         should: {
 
-           removeError: function() {
 
-             return ( settings.hideError === true || (settings.hideError === 'auto' && !module.is.form()) );
 
-           }
 
-         },
 
-         is: {
 
-           disabled: function() {
 
-             return ($module.filter(selector.disabled).length > 0);
 
-           },
 
-           expectingJSON: function() {
 
-             return settings.dataType === 'json' || settings.dataType === 'jsonp';
 
-           },
 
-           form: function() {
 
-             return $module.is('form') || $context.is('form');
 
-           },
 
-           mocked: function() {
 
-             return (settings.mockResponse || settings.mockResponseAsync || settings.response || settings.responseAsync);
 
-           },
 
-           input: function() {
 
-             return $module.is('input');
 
-           },
 
-           loading: function() {
 
-             return (module.request)
 
-               ? (module.request.state() == 'pending')
 
-               : false
 
-             ;
 
-           },
 
-           abortedRequest: function(xhr) {
 
-             if(xhr && xhr.readyState !== undefined && xhr.readyState === 0) {
 
-               module.verbose('XHR request determined to be aborted');
 
-               return true;
 
-             }
 
-             else {
 
-               module.verbose('XHR request was not aborted');
 
-               return false;
 
-             }
 
-           },
 
-           validResponse: function(response) {
 
-             if( (!module.is.expectingJSON()) || !$.isFunction(settings.successTest) ) {
 
-               module.verbose('Response is not JSON, skipping validation', settings.successTest, response);
 
-               return true;
 
-             }
 
-             module.debug('Checking JSON returned success', settings.successTest, response);
 
-             if( settings.successTest(response) ) {
 
-               module.debug('Response passed success test', response);
 
-               return true;
 
-             }
 
-             else {
 
-               module.debug('Response failed success test', response);
 
-               return false;
 
-             }
 
-           }
 
-         },
 
-         was: {
 
-           cancelled: function() {
 
-             return (module.cancelled || false);
 
-           },
 
-           succesful: function() {
 
-             return (module.request && module.request.state() == 'resolved');
 
-           },
 
-           failure: function() {
 
-             return (module.request && module.request.state() == 'rejected');
 
-           },
 
-           complete: function() {
 
-             return (module.request && (module.request.state() == 'resolved' || module.request.state() == 'rejected') );
 
-           }
 
-         },
 
-         add: {
 
-           urlData: function(url, urlData) {
 
-             var
 
-               requiredVariables,
 
-               optionalVariables
 
-             ;
 
-             if(url) {
 
-               requiredVariables = url.match(settings.regExp.required);
 
-               optionalVariables = url.match(settings.regExp.optional);
 
-               urlData           = urlData || settings.urlData;
 
-               if(requiredVariables) {
 
-                 module.debug('Looking for required URL variables', requiredVariables);
 
-                 $.each(requiredVariables, function(index, templatedString) {
 
-                   var
 
-                     // allow legacy {$var} style
 
-                     variable = (templatedString.indexOf('$') !== -1)
 
-                       ? templatedString.substr(2, templatedString.length - 3)
 
-                       : templatedString.substr(1, templatedString.length - 2),
 
-                     value   = ($.isPlainObject(urlData) && urlData[variable] !== undefined)
 
-                       ? urlData[variable]
 
-                       : ($module.data(variable) !== undefined)
 
-                         ? $module.data(variable)
 
-                         : ($context.data(variable) !== undefined)
 
-                           ? $context.data(variable)
 
-                           : urlData[variable]
 
-                   ;
 
-                   // remove value
 
-                   if(value === undefined) {
 
-                     module.error(error.requiredParameter, variable, url);
 
-                     url = false;
 
-                     return false;
 
-                   }
 
-                   else {
 
-                     module.verbose('Found required variable', variable, value);
 
-                     value = (settings.encodeParameters)
 
-                       ? module.get.urlEncodedValue(value)
 
-                       : value
 
-                     ;
 
-                     url = url.replace(templatedString, value);
 
-                   }
 
-                 });
 
-               }
 
-               if(optionalVariables) {
 
-                 module.debug('Looking for optional URL variables', requiredVariables);
 
-                 $.each(optionalVariables, function(index, templatedString) {
 
-                   var
 
-                     // allow legacy {/$var} style
 
-                     variable = (templatedString.indexOf('$') !== -1)
 
-                       ? templatedString.substr(3, templatedString.length - 4)
 
-                       : templatedString.substr(2, templatedString.length - 3),
 
-                     value   = ($.isPlainObject(urlData) && urlData[variable] !== undefined)
 
-                       ? urlData[variable]
 
-                       : ($module.data(variable) !== undefined)
 
-                         ? $module.data(variable)
 
-                         : ($context.data(variable) !== undefined)
 
-                           ? $context.data(variable)
 
-                           : urlData[variable]
 
-                   ;
 
-                   // optional replacement
 
-                   if(value !== undefined) {
 
-                     module.verbose('Optional variable Found', variable, value);
 
-                     url = url.replace(templatedString, value);
 
-                   }
 
-                   else {
 
-                     module.verbose('Optional variable not found', variable);
 
-                     // remove preceding slash if set
 
-                     if(url.indexOf('/' + templatedString) !== -1) {
 
-                       url = url.replace('/' + templatedString, '');
 
-                     }
 
-                     else {
 
-                       url = url.replace(templatedString, '');
 
-                     }
 
-                   }
 
-                 });
 
-               }
 
-             }
 
-             return url;
 
-           },
 
-           formData: function(data) {
 
-             var
 
-               canSerialize = ($.fn.serializeObject !== undefined),
 
-               formData     = (canSerialize)
 
-                 ? $form.serializeObject()
 
-                 : $form.serialize(),
 
-               hasOtherData
 
-             ;
 
-             data         = data || settings.data;
 
-             hasOtherData = $.isPlainObject(data);
 
-             if(hasOtherData) {
 
-               if(canSerialize) {
 
-                 module.debug('Extending existing data with form data', data, formData);
 
-                 data = $.extend(true, {}, data, formData);
 
-               }
 
-               else {
 
-                 module.error(error.missingSerialize);
 
-                 module.debug('Cant extend data. Replacing data with form data', data, formData);
 
-                 data = formData;
 
-               }
 
-             }
 
-             else {
 
-               module.debug('Adding form data', formData);
 
-               data = formData;
 
-             }
 
-             return data;
 
-           }
 
-         },
 
-         send: {
 
-           request: function() {
 
-             module.set.loading();
 
-             module.request = module.create.request();
 
-             if( module.is.mocked() ) {
 
-               module.mockedXHR = module.create.mockedXHR();
 
-             }
 
-             else {
 
-               module.xhr = module.create.xhr();
 
-             }
 
-             settings.onRequest.call(context, module.request, module.xhr);
 
-           }
 
-         },
 
-         event: {
 
-           trigger: function(event) {
 
-             module.query();
 
-             if(event.type == 'submit' || event.type == 'click') {
 
-               event.preventDefault();
 
-             }
 
-           },
 
-           xhr: {
 
-             always: function() {
 
-               // nothing special
 
-             },
 
-             done: function(response, textStatus, xhr) {
 
-               var
 
-                 context            = this,
 
-                 elapsedTime        = (new Date().getTime() - requestStartTime),
 
-                 timeLeft           = (settings.loadingDuration - elapsedTime),
 
-                 translatedResponse = ( $.isFunction(settings.onResponse) )
 
-                   ? module.is.expectingJSON()
 
-                     ? settings.onResponse.call(context, $.extend(true, {}, response))
 
-                     : settings.onResponse.call(context, response)
 
-                   : false
 
-               ;
 
-               timeLeft = (timeLeft > 0)
 
-                 ? timeLeft
 
-                 : 0
 
-               ;
 
-               if(translatedResponse) {
 
-                 module.debug('Modified API response in onResponse callback', settings.onResponse, translatedResponse, response);
 
-                 response = translatedResponse;
 
-               }
 
-               if(timeLeft > 0) {
 
-                 module.debug('Response completed early delaying state change by', timeLeft);
 
-               }
 
-               setTimeout(function() {
 
-                 if( module.is.validResponse(response) ) {
 
-                   module.request.resolveWith(context, [response, xhr]);
 
-                 }
 
-                 else {
 
-                   module.request.rejectWith(context, [xhr, 'invalid']);
 
-                 }
 
-               }, timeLeft);
 
-             },
 
-             fail: function(xhr, status, httpMessage) {
 
-               var
 
-                 context     = this,
 
-                 elapsedTime = (new Date().getTime() - requestStartTime),
 
-                 timeLeft    = (settings.loadingDuration - elapsedTime)
 
-               ;
 
-               timeLeft = (timeLeft > 0)
 
-                 ? timeLeft
 
-                 : 0
 
-               ;
 
-               if(timeLeft > 0) {
 
-                 module.debug('Response completed early delaying state change by', timeLeft);
 
-               }
 
-               setTimeout(function() {
 
-                 if( module.is.abortedRequest(xhr) ) {
 
-                   module.request.rejectWith(context, [xhr, 'aborted', httpMessage]);
 
-                 }
 
-                 else {
 
-                   module.request.rejectWith(context, [xhr, 'error', status, httpMessage]);
 
-                 }
 
-               }, timeLeft);
 
-             }
 
-           },
 
-           request: {
 
-             done: function(response, xhr) {
 
-               module.debug('Successful API Response', response);
 
-               if(settings.cache === 'local' && url) {
 
-                 module.write.cachedResponse(url, response);
 
-                 module.debug('Saving server response locally', module.cache);
 
-               }
 
-               settings.onSuccess.call(context, response, $module, xhr);
 
-             },
 
-             complete: function(firstParameter, secondParameter) {
 
-               var
 
-                 xhr,
 
-                 response
 
-               ;
 
-               // have to guess callback parameters based on request success
 
-               if( module.was.succesful() ) {
 
-                 response = firstParameter;
 
-                 xhr      = secondParameter;
 
-               }
 
-               else {
 
-                 xhr      = firstParameter;
 
-                 response = module.get.responseFromXHR(xhr);
 
-               }
 
-               module.remove.loading();
 
-               settings.onComplete.call(context, response, $module, xhr);
 
-             },
 
-             fail: function(xhr, status, httpMessage) {
 
-               var
 
-                 // pull response from xhr if available
 
-                 response     = module.get.responseFromXHR(xhr),
 
-                 errorMessage = module.get.errorFromRequest(response, status, httpMessage)
 
-               ;
 
-               if(status == 'aborted') {
 
-                 module.debug('XHR Aborted (Most likely caused by page navigation or CORS Policy)', status, httpMessage);
 
-                 settings.onAbort.call(context, status, $module, xhr);
 
-                 return true;
 
-               }
 
-               else if(status == 'invalid') {
 
-                 module.debug('JSON did not pass success test. A server-side error has most likely occurred', response);
 
-               }
 
-               else if(status == 'error') {
 
-                 if(xhr !== undefined) {
 
-                   module.debug('XHR produced a server error', status, httpMessage);
 
-                   // make sure we have an error to display to console
 
-                   if( xhr.status != 200 && httpMessage !== undefined && httpMessage !== '') {
 
-                     module.error(error.statusMessage + httpMessage, ajaxSettings.url);
 
-                   }
 
-                   settings.onError.call(context, errorMessage, $module, xhr);
 
-                 }
 
-               }
 
-               if(settings.errorDuration && status !== 'aborted') {
 
-                 module.debug('Adding error state');
 
-                 module.set.error();
 
-                 if( module.should.removeError() ) {
 
-                   setTimeout(module.remove.error, settings.errorDuration);
 
-                 }
 
-               }
 
-               module.debug('API Request failed', errorMessage, xhr);
 
-               settings.onFailure.call(context, response, $module, xhr);
 
-             }
 
-           }
 
-         },
 
-         create: {
 
-           request: function() {
 
-             // api request promise
 
-             return $.Deferred()
 
-               .always(module.event.request.complete)
 
-               .done(module.event.request.done)
 
-               .fail(module.event.request.fail)
 
-             ;
 
-           },
 
-           mockedXHR: function () {
 
-             var
 
-               // xhr does not simulate these properties of xhr but must return them
 
-               textStatus     = false,
 
-               status         = false,
 
-               httpMessage    = false,
 
-               responder      = settings.mockResponse      || settings.response,
 
-               asyncResponder = settings.mockResponseAsync || settings.responseAsync,
 
-               asyncCallback,
 
-               response,
 
-               mockedXHR
 
-             ;
 
-             mockedXHR = $.Deferred()
 
-               .always(module.event.xhr.complete)
 
-               .done(module.event.xhr.done)
 
-               .fail(module.event.xhr.fail)
 
-             ;
 
-             if(responder) {
 
-               if( $.isFunction(responder) ) {
 
-                 module.debug('Using specified synchronous callback', responder);
 
-                 response = responder.call(context, requestSettings);
 
-               }
 
-               else {
 
-                 module.debug('Using settings specified response', responder);
 
-                 response = responder;
 
-               }
 
-               // simulating response
 
-               mockedXHR.resolveWith(context, [ response, textStatus, { responseText: response }]);
 
-             }
 
-             else if( $.isFunction(asyncResponder) ) {
 
-               asyncCallback = function(response) {
 
-                 module.debug('Async callback returned response', response);
 
-                 if(response) {
 
-                   mockedXHR.resolveWith(context, [ response, textStatus, { responseText: response }]);
 
-                 }
 
-                 else {
 
-                   mockedXHR.rejectWith(context, [{ responseText: response }, status, httpMessage]);
 
-                 }
 
-               };
 
-               module.debug('Using specified async response callback', asyncResponder);
 
-               asyncResponder.call(context, requestSettings, asyncCallback);
 
-             }
 
-             return mockedXHR;
 
-           },
 
-           xhr: function() {
 
-             var
 
-               xhr
 
-             ;
 
-             // ajax request promise
 
-             xhr = $.ajax(ajaxSettings)
 
-               .always(module.event.xhr.always)
 
-               .done(module.event.xhr.done)
 
-               .fail(module.event.xhr.fail)
 
-             ;
 
-             module.verbose('Created server request', xhr, ajaxSettings);
 
-             return xhr;
 
-           }
 
-         },
 
-         set: {
 
-           error: function() {
 
-             module.verbose('Adding error state to element', $context);
 
-             $context.addClass(className.error);
 
-           },
 
-           loading: function() {
 
-             module.verbose('Adding loading state to element', $context);
 
-             $context.addClass(className.loading);
 
-             requestStartTime = new Date().getTime();
 
-           }
 
-         },
 
-         remove: {
 
-           error: function() {
 
-             module.verbose('Removing error state from element', $context);
 
-             $context.removeClass(className.error);
 
-           },
 
-           loading: function() {
 
-             module.verbose('Removing loading state from element', $context);
 
-             $context.removeClass(className.loading);
 
-           }
 
-         },
 
-         get: {
 
-           responseFromXHR: function(xhr) {
 
-             return $.isPlainObject(xhr)
 
-               ? (module.is.expectingJSON())
 
-                 ? module.decode.json(xhr.responseText)
 
-                 : xhr.responseText
 
-               : false
 
-             ;
 
-           },
 
-           errorFromRequest: function(response, status, httpMessage) {
 
-             return ($.isPlainObject(response) && response.error !== undefined)
 
-               ? response.error // use json error message
 
-               : (settings.error[status] !== undefined) // use server error message
 
-                 ? settings.error[status]
 
-                 : httpMessage
 
-             ;
 
-           },
 
-           request: function() {
 
-             return module.request || false;
 
-           },
 
-           xhr: function() {
 
-             return module.xhr || false;
 
-           },
 
-           settings: function() {
 
-             var
 
-               runSettings
 
-             ;
 
-             runSettings = settings.beforeSend.call(context, settings);
 
-             if(runSettings) {
 
-               if(runSettings.success !== undefined) {
 
-                 module.debug('Legacy success callback detected', runSettings);
 
-                 module.error(error.legacyParameters, runSettings.success);
 
-                 runSettings.onSuccess = runSettings.success;
 
-               }
 
-               if(runSettings.failure !== undefined) {
 
-                 module.debug('Legacy failure callback detected', runSettings);
 
-                 module.error(error.legacyParameters, runSettings.failure);
 
-                 runSettings.onFailure = runSettings.failure;
 
-               }
 
-               if(runSettings.complete !== undefined) {
 
-                 module.debug('Legacy complete callback detected', runSettings);
 
-                 module.error(error.legacyParameters, runSettings.complete);
 
-                 runSettings.onComplete = runSettings.complete;
 
-               }
 
-             }
 
-             if(runSettings === undefined) {
 
-               module.error(error.noReturnedValue);
 
-             }
 
-             if(runSettings === false) {
 
-               return runSettings;
 
-             }
 
-             return (runSettings !== undefined)
 
-               ? $.extend(true, {}, runSettings)
 
-               : $.extend(true, {}, settings)
 
-             ;
 
-           },
 
-           urlEncodedValue: function(value) {
 
-             var
 
-               decodedValue   = window.decodeURIComponent(value),
 
-               encodedValue   = window.encodeURIComponent(value),
 
-               alreadyEncoded = (decodedValue !== value)
 
-             ;
 
-             if(alreadyEncoded) {
 
-               module.debug('URL value is already encoded, avoiding double encoding', value);
 
-               return value;
 
-             }
 
-             module.verbose('Encoding value using encodeURIComponent', value, encodedValue);
 
-             return encodedValue;
 
-           },
 
-           defaultData: function() {
 
-             var
 
-               data = {}
 
-             ;
 
-             if( !$.isWindow(element) ) {
 
-               if( module.is.input() ) {
 
-                 data.value = $module.val();
 
-               }
 
-               else if( module.is.form() ) {
 
-               }
 
-               else {
 
-                 data.text = $module.text();
 
-               }
 
-             }
 
-             return data;
 
-           },
 
-           event: function() {
 
-             if( $.isWindow(element) || settings.on == 'now' ) {
 
-               module.debug('API called without element, no events attached');
 
-               return false;
 
-             }
 
-             else if(settings.on == 'auto') {
 
-               if( $module.is('input') ) {
 
-                 return (element.oninput !== undefined)
 
-                   ? 'input'
 
-                   : (element.onpropertychange !== undefined)
 
-                     ? 'propertychange'
 
-                     : 'keyup'
 
-                 ;
 
-               }
 
-               else if( $module.is('form') ) {
 
-                 return 'submit';
 
-               }
 
-               else {
 
-                 return 'click';
 
-               }
 
-             }
 
-             else {
 
-               return settings.on;
 
-             }
 
-           },
 
-           templatedURL: function(action) {
 
-             action = action || $module.data(metadata.action) || settings.action || false;
 
-             url    = $module.data(metadata.url) || settings.url || false;
 
-             if(url) {
 
-               module.debug('Using specified url', url);
 
-               return url;
 
-             }
 
-             if(action) {
 
-               module.debug('Looking up url for action', action, settings.api);
 
-               if(settings.api[action] === undefined && !module.is.mocked()) {
 
-                 module.error(error.missingAction, settings.action, settings.api);
 
-                 return;
 
-               }
 
-               url = settings.api[action];
 
-             }
 
-             else if( module.is.form() ) {
 
-               url = $module.attr('action') || $context.attr('action') || false;
 
-               module.debug('No url or action specified, defaulting to form action', url);
 
-             }
 
-             return url;
 
-           }
 
-         },
 
-         abort: function() {
 
-           var
 
-             xhr = module.get.xhr()
 
-           ;
 
-           if( xhr && xhr.state() !== 'resolved') {
 
-             module.debug('Cancelling API request');
 
-             xhr.abort();
 
-           }
 
-         },
 
-         // reset state
 
-         reset: function() {
 
-           module.remove.error();
 
-           module.remove.loading();
 
-         },
 
-         setting: function(name, value) {
 
-           module.debug('Changing setting', name, value);
 
-           if( $.isPlainObject(name) ) {
 
-             $.extend(true, settings, name);
 
-           }
 
-           else if(value !== undefined) {
 
-             if($.isPlainObject(settings[name])) {
 
-               $.extend(true, settings[name], value);
 
-             }
 
-             else {
 
-               settings[name] = value;
 
-             }
 
-           }
 
-           else {
 
-             return settings[name];
 
-           }
 
-         },
 
-         internal: function(name, value) {
 
-           if( $.isPlainObject(name) ) {
 
-             $.extend(true, module, name);
 
-           }
 
-           else if(value !== undefined) {
 
-             module[name] = value;
 
-           }
 
-           else {
 
-             return module[name];
 
-           }
 
-         },
 
-         debug: function() {
 
-           if(!settings.silent && settings.debug) {
 
-             if(settings.performance) {
 
-               module.performance.log(arguments);
 
-             }
 
-             else {
 
-               module.debug = Function.prototype.bind.call(console.info, console, settings.name + ':');
 
-               module.debug.apply(console, arguments);
 
-             }
 
-           }
 
-         },
 
-         verbose: function() {
 
-           if(!settings.silent && settings.verbose && settings.debug) {
 
-             if(settings.performance) {
 
-               module.performance.log(arguments);
 
-             }
 
-             else {
 
-               module.verbose = Function.prototype.bind.call(console.info, console, settings.name + ':');
 
-               module.verbose.apply(console, arguments);
 
-             }
 
-           }
 
-         },
 
-         error: function() {
 
-           if(!settings.silent) {
 
-             module.error = Function.prototype.bind.call(console.error, console, settings.name + ':');
 
-             module.error.apply(console, arguments);
 
-           }
 
-         },
 
-         performance: {
 
-           log: function(message) {
 
-             var
 
-               currentTime,
 
-               executionTime,
 
-               previousTime
 
-             ;
 
-             if(settings.performance) {
 
-               currentTime   = new Date().getTime();
 
-               previousTime  = time || currentTime;
 
-               executionTime = currentTime - previousTime;
 
-               time          = currentTime;
 
-               performance.push({
 
-                 'Name'           : message[0],
 
-                 'Arguments'      : [].slice.call(message, 1) || '',
 
-                 //'Element'        : element,
 
-                 'Execution Time' : executionTime
 
-               });
 
-             }
 
-             clearTimeout(module.performance.timer);
 
-             module.performance.timer = setTimeout(module.performance.display, 500);
 
-           },
 
-           display: function() {
 
-             var
 
-               title = settings.name + ':',
 
-               totalTime = 0
 
-             ;
 
-             time = false;
 
-             clearTimeout(module.performance.timer);
 
-             $.each(performance, function(index, data) {
 
-               totalTime += data['Execution Time'];
 
-             });
 
-             title += ' ' + totalTime + 'ms';
 
-             if(moduleSelector) {
 
-               title += ' \'' + moduleSelector + '\'';
 
-             }
 
-             if( (console.group !== undefined || console.table !== undefined) && performance.length > 0) {
 
-               console.groupCollapsed(title);
 
-               if(console.table) {
 
-                 console.table(performance);
 
-               }
 
-               else {
 
-                 $.each(performance, function(index, data) {
 
-                   console.log(data['Name'] + ': ' + data['Execution Time']+'ms');
 
-                 });
 
-               }
 
-               console.groupEnd();
 
-             }
 
-             performance = [];
 
-           }
 
-         },
 
-         invoke: function(query, passedArguments, context) {
 
-           var
 
-             object = instance,
 
-             maxDepth,
 
-             found,
 
-             response
 
-           ;
 
-           passedArguments = passedArguments || queryArguments;
 
-           context         = element         || context;
 
-           if(typeof query == 'string' && object !== undefined) {
 
-             query    = query.split(/[\. ]/);
 
-             maxDepth = query.length - 1;
 
-             $.each(query, function(depth, value) {
 
-               var camelCaseValue = (depth != maxDepth)
 
-                 ? value + query[depth + 1].charAt(0).toUpperCase() + query[depth + 1].slice(1)
 
-                 : query
 
-               ;
 
-               if( $.isPlainObject( object[camelCaseValue] ) && (depth != maxDepth) ) {
 
-                 object = object[camelCaseValue];
 
-               }
 
-               else if( object[camelCaseValue] !== undefined ) {
 
-                 found = object[camelCaseValue];
 
-                 return false;
 
-               }
 
-               else if( $.isPlainObject( object[value] ) && (depth != maxDepth) ) {
 
-                 object = object[value];
 
-               }
 
-               else if( object[value] !== undefined ) {
 
-                 found = object[value];
 
-                 return false;
 
-               }
 
-               else {
 
-                 module.error(error.method, query);
 
-                 return false;
 
-               }
 
-             });
 
-           }
 
-           if ( $.isFunction( found ) ) {
 
-             response = found.apply(context, passedArguments);
 
-           }
 
-           else if(found !== undefined) {
 
-             response = found;
 
-           }
 
-           if($.isArray(returnedValue)) {
 
-             returnedValue.push(response);
 
-           }
 
-           else if(returnedValue !== undefined) {
 
-             returnedValue = [returnedValue, response];
 
-           }
 
-           else if(response !== undefined) {
 
-             returnedValue = response;
 
-           }
 
-           return found;
 
-         }
 
-       };
 
-       if(methodInvoked) {
 
-         if(instance === undefined) {
 
-           module.initialize();
 
-         }
 
-         module.invoke(query);
 
-       }
 
-       else {
 
-         if(instance !== undefined) {
 
-           instance.invoke('destroy');
 
-         }
 
-         module.initialize();
 
-       }
 
-     })
 
-   ;
 
-   return (returnedValue !== undefined)
 
-     ? returnedValue
 
-     : this
 
-   ;
 
- };
 
- $.api.settings = {
 
-   name              : 'API',
 
-   namespace         : 'api',
 
-   debug             : false,
 
-   verbose           : false,
 
-   performance       : true,
 
-   // object containing all templates endpoints
 
-   api               : {},
 
-   // whether to cache responses
 
-   cache             : true,
 
-   // whether new requests should abort previous requests
 
-   interruptRequests : true,
 
-   // event binding
 
-   on                : 'auto',
 
-   // context for applying state classes
 
-   stateContext      : false,
 
-   // duration for loading state
 
-   loadingDuration   : 0,
 
-   // whether to hide errors after a period of time
 
-   hideError         : 'auto',
 
-   // duration for error state
 
-   errorDuration     : 2000,
 
-   // whether parameters should be encoded with encodeURIComponent
 
-   encodeParameters  : true,
 
-   // API action to use
 
-   action            : false,
 
-   // templated URL to use
 
-   url               : false,
 
-   // base URL to apply to all endpoints
 
-   base              : '',
 
-   // data that will
 
-   urlData           : {},
 
-   // whether to add default data to url data
 
-   defaultData          : true,
 
-   // whether to serialize closest form
 
-   serializeForm        : false,
 
-   // how long to wait before request should occur
 
-   throttle             : 0,
 
-   // whether to throttle first request or only repeated
 
-   throttleFirstRequest : true,
 
-   // standard ajax settings
 
-   method            : 'get',
 
-   data              : {},
 
-   dataType          : 'json',
 
-   // mock response
 
-   mockResponse      : false,
 
-   mockResponseAsync : false,
 
-   // aliases for mock
 
-   response          : false,
 
-   responseAsync     : false,
 
-   // callbacks before request
 
-   beforeSend  : function(settings) { return settings; },
 
-   beforeXHR   : function(xhr) {},
 
-   onRequest   : function(promise, xhr) {},
 
-   // after request
 
-   onResponse  : false, // function(response) { },
 
-   // response was successful, if JSON passed validation
 
-   onSuccess   : function(response, $module) {},
 
-   // request finished without aborting
 
-   onComplete  : function(response, $module) {},
 
-   // failed JSON success test
 
-   onFailure   : function(response, $module) {},
 
-   // server error
 
-   onError     : function(errorMessage, $module) {},
 
-   // request aborted
 
-   onAbort     : function(errorMessage, $module) {},
 
-   successTest : false,
 
-   // errors
 
-   error : {
 
-     beforeSend        : 'The before send function has aborted the request',
 
-     error             : 'There was an error with your request',
 
-     exitConditions    : 'API Request Aborted. Exit conditions met',
 
-     JSONParse         : 'JSON could not be parsed during error handling',
 
-     legacyParameters  : 'You are using legacy API success callback names',
 
-     method            : 'The method you called is not defined',
 
-     missingAction     : 'API action used but no url was defined',
 
-     missingSerialize  : 'jquery-serialize-object is required to add form data to an existing data object',
 
-     missingURL        : 'No URL specified for api event',
 
-     noReturnedValue   : 'The beforeSend callback must return a settings object, beforeSend ignored.',
 
-     noStorage         : 'Caching responses locally requires session storage',
 
-     parseError        : 'There was an error parsing your request',
 
-     requiredParameter : 'Missing a required URL parameter: ',
 
-     statusMessage     : 'Server gave an error: ',
 
-     timeout           : 'Your request timed out'
 
-   },
 
-   regExp  : {
 
-     required : /\{\$*[A-z0-9]+\}/g,
 
-     optional : /\{\/\$*[A-z0-9]+\}/g,
 
-   },
 
-   className: {
 
-     loading : 'loading',
 
-     error   : 'error'
 
-   },
 
-   selector: {
 
-     disabled : '.disabled',
 
-     form      : 'form'
 
-   },
 
-   metadata: {
 
-     action  : 'action',
 
-     url     : 'url'
 
-   }
 
- };
 
- })( jQuery, window, document );
 
 
  |